A ZX81 alternative PRINT function that scrolls when at the bottom of the display. The intent is to show how to call machine language functions from BASIC and passing parameters on the same line. https://youtu.be/tQwA9HgaTJM
;
; Print Scroll
; v3 Steven Reid (c) 2024
; A simple print routine that scrolls if too long.
; Call from BASIC using PRINT USR 16514;"HELLO "
;
; This is a complete ZX81 program allowing hybrid
; BASIC and machine code. Here is how I assembled it:
;
; z80asm -b -r16393 -oprtscrl.p prtscrl.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
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 **PRTSCRL**SLR/2024**
db $00,$01,$17,$00,$ea
db _as,_as,_p_,_r_,_t_,_s_,_c_,_r_,_l_,_as
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: ; USR 16541
;
; +++
; get print line
rst $20 ; skip semi-colon
call scanning ; deal with parameters
call stkfetch ; pop details off calc stack
; de now holds pointer to string parameter
; bc holds string length
call print_scroll
; all done
rst $08 ; abort basic line
db $ff ; will continue to next line
; end print line
; ---
; Print Scroll
; this prints a string at DE, stopping when BC is zero
; scrolls on display overflow
print_scroll:
ld a,(de) ; load character
rst $10 ; print it!
call check_bottom ; at bottom of screen?
inc de ; increment de
dec bc ; decrement length
ld a,b
or c ; check if bc is zero
jr nz,print_scroll ; loop if not zero
ret ; else we are done
; ---
; Check bottom
check_bottom:
push de
push bc
ld bc,693
ld hl,(d_file)
add hl,bc
ex de,hl
ld hl,(df_cc)
xor a
sbc hl,de
ld a,h
or l
call z,scroll
pop bc
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
ld hl,(d_file)
add hl,bc
ld (df_cc),hl
ret
; ---
; End of BASIC line 2
db $76
ml_end: ; end of machine code!
; 10 DIM S$(3)
db $00,$0a,$15,$00,$e9,$38,$0d,$10
db $1f,$7e,$82,$40,$00,$00,$00,$1a
db $22,$7e,$83,$40,$00,$00,$00,$11
db $76
; 20 LET S$(1)="HELLO/"
db $00,$14,$16,$00,$f1,$38,$0d,$10
db $1d,$7e,$81,$00,$00,$00,$00,$11
db $14,$0b,$2d,$2a,$31,$31,$34,$18
db $0b,$76
; 30 LET S$(2)="LATER."
db $00,$1e,$16,$00,$f1,$38,$0d,$10
db $1e,$7e,$82,$00,$00,$00,$00,$11
db $14,$0b,$31,$26,$39,$2a,$37,$1b
db $0b,$76
; 40 LET S$(3)="ALOHA*"
db $00,$28,$16,$00,$f1,$38,$0d,$10
db $1f,$7e,$82,$40,$00,$00,$00,$11
db $14,$0b,$26,$31,$34,$2d,$26,$17
db $0b,$76
; 50 CLS
db $00,$32,$02,$00,$fb,$76
; 60 PRINT USR 16541;S$(INT(RND*3)+1)
db $00,$3c,$2b,$00,$f5,$d4,$1d,$22
db $21,$20,$1d,$7e,$8f,$01,$3a,$00
db $00,$19,$38,$0d,$10,$cf,$10,$40
db $17,$1f,$7e,$82,$40,$00,$00,$00
db $11,$15,$1d,$7e,$81,$00,$00,$00
db $00,$11,$15,$0b,$00,$0b,$76
; 70 GOTO 60
db $00,$46,$0a,$00,$ec,$22,$1c,$7e
db $86,$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
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
;
; ---