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