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