An updated version of a simple print routine that scrolls if it overflows the display.
Call from BASIC using:
PRINT USR 16514;"HELLO "
This version allows you to use a semicolon or comma to separate strings.
A trailing ; or , will suppress the newline.
;
; Print Scroll 2
; Steven Reid (c) 2024
;
; A simple print routine that scrolls if too long.
; Call from BASIC using PRINT USR 16514;"HELLO "
;
; This version allows you to use a semicolon
; or comma to separate strings.
; A trailing ";" or "," will suppress the newline.
;
; Example usess:
; PRINT USR 16514 ; scrolls
; PRINT USR 16514;"HI" ; print HI+newline
; PRINT USR 16514;"HI "; ; print HI
; PRINT USR 16514;"$";A$ ; print $+A$+newline
; PRINT USR 16514;"$";A$;" "; ; print $+A$
;
; This is a complete ZX81 program allowing hybrid
; BASIC and machine code. Here is how I assembled it:
;
; z80asm -b -r16393 -oprtscrl2.p prtscrl2.asm
;
; +++
;
; Header and startup
;
; start up stuff
org 16393 ; start of .p file
; system variables
db $00 ; VERSN
dw $0001 ; E_PPC
d_file: dw df_loc ; D_FILE
df_cc: dw df_loc+1 ; DF_CC
dw vars ; VARS
dw $0000 ; DEST
dw vars+1 ; E_LINE
dw vars+5 ; CH_ADD
dw $0000 ; X_PTR
dw vars+6,vars+6 ; STKBOT, STKEND
db $00 ; BERG
dw membot ; MEM
db $00 ; spare
db $02 ; DF_SZ
dw $0001 ; S_TOP
dw $0000 ; LAST_K
db $ff ; DB_ST
db $37 ; MARGIN (1F=NTSC, 37 = PAL)
dw 16509 ; NXTLIN (16509 to autorun, df_loc otherwise)
dw $0000 ; OLDPPC
db $00 ; FLAGX
dw $0000 ; STRLEN
dw $0c8d ; T_ADDR
dw $0000 ; SEED
frames: dw $0000 ; FRAMES
dw $0000 ; COORDS
db $21 ; PR_CC
s_posn: dw $1821 ; S_POSN
db $40 ; CDFLAG
db $00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00,$76
membot: db $00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00
db $00,$00,$00,$00,$00,$00,$00,$00
; end header and startup
;
; ---
; +++
;
; Start of BASIC
; 1 REM **PRTSCRL2*SLR/2024**
db $00,$01,$19,$00,$ea
jr ml_start ; USR 16514 (start)
db _as,_as,_p_,_r_,_t_,_s_,_c_,_r_,_l_,_2_
db _as,_s_,_l_,_r_,_sl,_2_,_0_,_2_,_4_,_as
db _as,$76
; 2 REM ^...ML CODE...^
db $00,$02 ; line number
dw ml_end-ml_start+1 ; length
db $ea ; REM
; Start of Machine Language
ml_start:
;
; +++
; get print line
call check_end ; at end of line?
call print_scroll ; print string with scroll
jr ml_start ; test next print
; end print line
; ---
; Check End
check_end:
rst $18 ; get next char
cp $76 ; newline?
jr nz,skip_over_semi ; no, skip ahead
; at end of line without semicolon
call print_return ; will check if last line
jr abort_basic ; and abort!
skip_over_semi:
rst $20 ; skip semi-colon
cp $76 ; at newline?
jr z,abort_basic ; yes, abort
; otherwise, convert to string
call scanning ; deal with parameters
call stkfetch ; pop details off calc stack
; de now holds pointer to string parameter
; bc holds string length
ld a,(flags) ; load flags
bit 6,a ; check if number
ret z ; not set, is a string
abort_error:
pop bc ; clear return
rst $08 ; report error
db $0b ; REPORT-C
abort_basic:
pop bc ; clear return
rst $08 ; abort basic line
db $ff ; will continue to next line
; ---
; Print Return
; this prints a return line, scrolling if at end of
; display
print_return:
; check if on last line
ld a,(s_posn+1) ; get line position
sub 4 ; on line 4?
jr z,scroll ; yes! scroll
jp $0b87 ; print return using ROM routine
; ---
; Print Scroll
; this prints a string at DE, stopping when BC is zero
; scrolls on display overflow
print_scroll:
ld a,b ; out of characters?
or c ; check if bc is zero
ret z ; return if done
call check_bottom ; scroll if at bottom
; print a character
ld a,(de) ; load character
rst $10 ; print it!
inc de ; increment de
dec bc ; decrement length
jp print_scroll ; loop if not zero
; ---
; Check bottom
check_bottom:
push de ; save state
push bc
ld bc,693 ; set to last char (33*21)
ld hl,(d_file) ; grab screen position
add hl,bc ; get character location
ex de,hl ; put in de
ld hl,(df_cc) ; grab character position
xor a ; clear carry
sbc hl,de ; subtract screen location
ld a,h ; check if hl
or l ; if zero
call z,scroll ; yes! scroll
pop bc ; restore state
pop de
ret
; ---
; Scroll screen
scroll:
ld hl,(d_file) ; get top of screen memory
inc hl ; move to top of screen
ld d,h ; copy value into
ld e,l ; de
ld bc,33 ; set hl to next line
add hl,bc ; by adding 33
ld bc,693 ; prepare to copy lines 1-23
ldir ; starting at top
ld bc,661 ; set new position
ld hl,(d_file) ; grab screen location
add hl,bc ; calculate new position
ld (df_cc),hl ; and set it
ld a,33 ; set column
ld (s_posn),a ; and reset column position
ld a,4 ; set line
ld (s_posn+1),a ; and reset line position
ret
; ---
; End of BASIC line 2
db $76
ml_end: ; end of machine code!
; 10 CLS
db $00,$0a,$02,$00,$fb,$76
; 20 LET T$="**WELCOME TO THE 80S TEXT DEMO**"
db $00,$14,$27,$00,$f1,$39,$0d,$14
db $0b,$17,$17,$3c,$2a,$31,$28,$34
db $32,$2a,$00,$39,$34,$00,$39,$2d
db $2a,$00,$24,$1c,$38,$00,$39,$2a
db $3d,$39,$00,$29,$2a,$32,$34,$17
db $17,$0b,$76
; 30 PRINT USR 16514;T$;
db $00,$1e,$12,$00,$f5,$d4,$1d,$22
db $21,$1d,$20,$7e,$8f,$01,$04,$00
db $00,$19,$39,$0d,$19,$76
; 40 LET T$=T$(2 TO )+T$(1)
db $00,$28,$1d,$00,$f1,$39,$0d,$14
db $39,$0d,$10,$1e,$7e,$82,$00,$00
db $00,$00,$df,$11,$15,$39,$0d,$10
db $1d,$7e,$81,$00,$00,$00,$00,$11
db $76
; 50 GOTO 30
db $00,$32,$0a,$00,$ec,$1f,$1c,$7e
db $85,$70,$00,$00,$00,$76
; end of BASIC
;
; ---
; +++
;
; Display file and variable space (minimal, make sure to CLS or RUN to expand)
df_loc: db $76
db $76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76
db $76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76,$76
vars: db $80
; ---
; +++
;
; Defines
;
; ZX81 ROM functions
kscan: equ $02bb
findchar: equ $07bd
stop: equ $0cdc
slow: equ $0f2b
fast: equ $02e7
save: equ $02f9
printat: equ $08f5
pause: equ $0f35
cls: equ $0a2a
flags: equ $4001
scanning: equ $0F55
stkfetch: equ $13f8
; ZX81 Characters (not ASCII)
_sp: equ $00
_qu: equ $0b
_lb: equ $0c
_dl: equ $0d
_cl: equ $0e
_lp: equ $10
_rp: equ $11
_gt: equ $12
_lt: equ $13
_eq: equ $14
_pl: equ $15
_mi: equ $16
_as: equ $17
_sl: equ $18
_sc: equ $19
_cm: equ $1a
_pr: equ $1b
_0_: equ $1c
_1_: equ $1d
_2_: equ $1e
_3_: equ $1f
_4_: equ $20
_5_: equ $21
_6_: equ $22
_7_: equ $23
_8_: equ $24
_9_: equ $25
_a_: equ $26
_b_: equ $27
_c_: equ $28
_d_: equ $29
_e_: equ $2a
_f_: equ $2b
_g_: equ $2c
_h_: equ $2d
_i_: equ $2e
_j_: equ $2f
_k_: equ $30
_l_: equ $31
_m_: equ $32
_n_: equ $33
_o_: equ $34
_p_: equ $35
_q_: equ $36
_r_: equ $37
_s_: equ $38
_t_: equ $39
_u_: equ $3a
_v_: equ $3b
_w_: equ $3c
_x_: equ $3d
_y_: equ $3e
_z_: equ $3f
; end defines
;
; ---