ZX81 Assembly Listing for prtscrl.asm


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

**PRTSCRL**SLR/2024** (prtscrl.asm)

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


ASSEMBLY PROGRAM LISTING

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