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