ZX81 Assembly Listing for prtscrl2.asm


ZX81 assembly listing for **PRTSCRL2*SLR/2024**

**PRTSCRL2*SLR/2024** (prtscrl2.asm)

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.


ASSEMBLY PROGRAM LISTING

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