ZX81 Assembly Listing for enlarger.asm


ZX81 assembly listing for *ENLARGER ASM**SLR/22*

*ENLARGER ASM**SLR/22* (enlarger.asm)

The original enlarger was a simple BASIC program that demonstrated how to enlarge an object, but was horribly slow. This is the assembler version that drastically improves the speed and adds a couple more pictures.


ASSEMBLY PROGRAM LISTING

;
; Enlarger ASM
; v1.00 Steven Reid (c) 2022
;
; A rewrite of my old BASIC program that does a simple
; enlarge routine. Nothing exciting, just thought I'd
; try to speed it up. Will see if I can make something
; of this;
;
; 1/25/2022 - Initial build.
;

; +++
;
; Header and startup
;

        ; start up stuff
        org 16514               ; stored in REM at top (ZX81)
        jr start                ; needed for z80asm

; title and copyright (will show on listing)
copy:
        db $2a,$33,$31,$26,$37,$2c,$2a,$37,$00,$26
        db $38,$32,$17,$17,$38,$31,$37,$18,$1e,$1e
        db $17,$76,$76
        ;  **ENLARGER ASM**SLR/2022**

start:
        call slow               ; SLOW is required.

; end header and startup
;
; ---


; +++
;
; Main Loop
;

mainloop:

        ; print first screen
        call cls
        ld hl,intro
        call print
        ld hl,moon
        call print
        ld hl,intent
        call print
        ld hl,8000
        call newpause

        ; enlarge moon
        ld hl,moon
        call enlarger

        ld bc,$0000
        call printat
        ld hl,done
        call print
        ld hl,8000
        call newpause

        ; enlarge moon with crators
        ld hl,mooncrater
        call enlarger
        ld hl,8000
        call newpause

        ; enlarge a bee
        ld hl,bee
        call enlarger
        ld hl,8000
        call newpause


        jp mainloop

; End of loop!
;

; +++
;
; Routines
;

;
; Print string at HL
; stops when reaches $FF
;
print:
        ld a,(hl)               ; load character
        inc hl                  ; increment memory
        cp $ff                  ; last character?
        ret z                   ; yep, return
        rst $10                 ; nope, print it!
        jr print                ; loop

;
; Copy buffer to screen
;
copy2screen:
        ld de,(d_file)
        inc de                  ; skip initial newline
        ld hl,buffer
        ld bc,726               ; 22 lines with 32char+return
        ldir
        ret
;
; Copy screen to buffer
;
copy2buffer:
        ld de,buffer
        ld hl,(d_file)
        inc hl                  ; skip initial newline
        ld bc,726               ; 22 lines with 32char+return
        ldir
        ret

;
; Clear buffer
;
clearbuffer:
        ld de,emptyline-33
        ld hl,emptyline
        ld a,21
cbloop:
        ld bc,33
        lddr
        dec a
        jp nz,cbloop
        ret

;
; Delay
;
; set bc to speed
; press space to 

pframe: dw $0000
newpause:
        ld (pframe),hl

        call kscan              ; get key press
        inc l
        jr z,lppause            ; not yet loop
        dec l
        ld b,h
        ld c,l
        call findchar           ; yep, grab character pressed
        ld a,(hl)

        push af
        call wait
        pop af

        and a                   ; pressed space (break)
        jp z,stop               ; stop!
        ret                     ; or return!

        ; loop!
lppause:
        ld hl,(pframe)
        dec hl
        ld a,h
        or l
        jr nz,newpause          ; not zero, keep going!

        ret                     ; pause is done!

wait:   call kscan              ; Wait for human to take finger off of key.
        inc l
        jr nz,wait
        ret


;
; Enlarge
;

;
; Original basic below
;
; Really just walks the array. It assumes full
; lines (32 characters). The routine basically
; walks the first 16 characters of each line
; and expands it into 4 characters. This dobules
; each character. It then skips down and does
; the same for each line. It isn't very optimized.
;
; 110 DIM B$((LEN A$)*4)
; 130 LET L=1
; 140 FOR B=1 TO (LEN A$) STEP 32
; 145 FOR C=B TO B+15-((B+15-(
;LEN A$)) AND B+15>LEN A$)
; 150 LET B$(L)=A$(C)
; 160 LET B$(L+1)=A$(C)
; 170 LET B$(L+32)=A$(C)
; 180 LET B$(L+33)=A$(C)
; 190 LET L=L+2
; 200 NEXT C
; 210 LET L=L+32
; 220 NEXT B
;
; for the assembly version, I just assume
; I'm exapsnding from the left edge. That
; means I go 16 across and 11 down. Easy!

enlarge:
;        call clearbuffer        ; clear the buffer first

        ld de,buffer            ; enlarge to here
        ld hl,(d_file)          ; from the screen
        inc hl

        ld b,11                 ; 11 rows 
yloop:
        push bc
        ld b,16                 ; 15 cols
xloop:
        push bc

        ld a,(hl)               ; grab char (usually $80 or $00)
        inc hl                  ; next char on screen
        ex de,hl                ; exchange de and hl
        push hl                 ; save current buffer position

        ; this is the enlarge routine
        ld (hl),a               ; set hl to a
        inc hl                  ; next char
        ld (hl),a               ; set hl to a
        ld bc,32
        add hl,bc               ; skip to next row
        ld (hl),a               ; set hl to a
        inc hl                  ; next char
        ld (hl),a               ; set hl to a

        pop hl                  ; restore buffer
        inc hl                  ; and move ahead 2
        inc hl
        ex de,hl                ; exchange it back

        pop bc                  ; then loop!
        djnz xloop

        ld bc,17                ; skip to next screen line
        add hl,bc

        ex de,hl
        ld bc,34               ; jump down start of 2 lines
        add hl,bc
        ex de,hl

        pop bc                  ; then loop!
        djnz yloop

        jp copy2screen        ; copy to screen

;
; Enlarger - pass what to enlarge in hl
;

enlarger:
        ; print moon
        push hl
        call cls
        pop hl
        call print

        ld hl,500
        call newpause

        ; enlarge things!
        ld b,5
enloop:
        push bc                 ; save loop

        ; make bigg4er and print it!
        call enlarge            ; make bigger
        ld hl,500
        call newpause

        pop bc                  ; restore loop
        djnz enloop             ; loop until done

        ret


; end routines
; ---

; +++
;
; Data and Defines
;

; ZX81 system vars
d_file:         equ $400c
d_fcc:          equ 16398
frames:         equ 16436

; 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

; end defines
; ---

; +++
; Data
;

;
; messages
;

intro:
        db $3c,$2a,$00,$38,$2d,$26,$31,$31,$00,$2a
        db $33,$31,$26,$37,$2c,$2a,$00,$26,$00,$35
        db $2e,$28,$39,$3a,$37,$2a,$00,$34,$2b,$00
        db $26,$00
        ; WE SHALL ENLARGE A PICTURE OF 
        db $32,$34,$34,$33,$1b,$00,$00,$00,$00,$00
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        db $00,$00
        ; A MOON.
        db $ff
moon:
        db $00,$00,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $80,$80,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $80,$80,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $ff
mooncrater:
        db $00,$00,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$80,$80,$08,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $80,$08,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $80,$80,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$80,$08,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$80,$08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $ff
bee:
        db $80,$00,$80,$80,$00,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$80,$08,$08,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $80,$80,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$08,$08,$08,$08,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$80,$80,$80,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $80,$00,$08,$08,$00,$80,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $ff
intent:
        db $34,$30,$1a,$00,$39,$34,$00,$2a,$33,$31
        db $26,$37,$2c,$2a,$00,$39,$2d,$2a,$00,$32
        db $34,$34,$33,$00,$3c,$2a,$00,$3c,$2e,$31
        db $31,$00
        ; OK, TO ENLARGE THE MOON WE WILL 
        db $39,$26,$30,$2a,$00,$2a,$26,$28,$2d,$00
        db $38,$36,$3a,$26,$37,$2a,$00,$26,$33,$29
        db $00,$32,$3a,$31,$39,$2e,$35,$31,$3e,$00
        db $2e,$39
        ; TAKE EACH SQUARE AND MULTIPLY IT
        db $27,$3e,$00,$20,$00,$32,$26,$30,$2e,$33
        db $2c,$00,$26,$00,$31,$26,$37,$2c,$2a,$37
        db $00,$35,$2e,$28,$39,$3a,$37,$2a,$1b,$00
        db $00,$00
        ; BY 4 MAKING A LARGER PICTURE.
presskey:
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00
        db $00,$00
        db $35,$37,$2a,$38,$38,$00,$2a,$33,$39,$2a
        db $37,$00,$39,$34,$00,$27,$2a,$2c,$2e,$33
        db $1b,$1b,$1b,$ff
        ; PRESS ENTER TO BEGIN...
done:
        db $39,$2d,$26,$39,$00,$3c,$26,$38,$00,$26
        db $00,$38,$28,$26,$31,$2a,$00,$2a,$33,$31
        db $26,$37,$2c,$2a,$32,$2a,$33,$39,$00,$34
        db $2b,$00
        ; THAT WAS A SCALE ENLARGEMENT OF 
        db $26,$00,$32,$34,$34,$33,$1b,$00,$00,$33
        db $34,$39,$00,$3b,$2a,$37,$3e,$00,$38,$35
        db $2a,$28,$39,$26,$28,$3a,$31,$26,$37,$1a
        db $00,$00
        ; A MOON.  NOT VERY SPECTACULAR,  
        db $27,$3a,$39,$1a,$00,$2e,$2b,$00,$34,$33
        db $2a,$00,$28,$34,$3a,$31,$29,$00,$32,$34
        db $29,$2e,$2b,$3e,$00,$39,$2d,$2e,$38,$00
        db $00,$00
        ; BUT, IF ONE COULD MODIFY THIS   
        db $38,$2e,$32,$35,$31,$2a,$00,$35,$37,$34
        db $2c,$37,$26,$32,$1a,$00,$39,$2d,$2a,$00
        db $2a,$2b,$2b,$2a,$28,$39,$00,$28,$34,$3a
        db $31,$29
        ; SIMPLE PROGRAM, THE EFFECT COULD
        db $27,$2a,$00,$27,$34,$39,$2d,$00,$3a,$38
        db $2a,$2b,$3a,$31,$00,$26,$33,$29,$00,$38
        db $35,$2a,$28,$39,$26,$28,$3a,$31,$26,$37
        db $1b,$76
        ; BE BOTH USEFUL AND SPECTACULAR.
        db $ff

;
; screen buffer
;
buffer:
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76
emptyline:
        db $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$76

; end data
; ---