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 ; ; ---