A new machine language version of a person running with a moving sky and score.
; ; Run 2 ML ; v1.03 Steven Reid (c) 2022 ; ; A simple little running animation and moving sky. ; ; 1.00 - 2/16/2022 - Initial build. ; 1.01 - 3/19/2022 - Added pixel movement with more skys. ; 1.02 - 3/20/2022 - Adding in some objects. Too slow. ; 1.03 - 3/20/2022 - Moved score to back side. ; ; +++ ; ; 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 $17,$17,$37,$3a,$33,$00,$32,$31,$17,$17 db $17,$38,$31,$37,$18,$1e,$1c,$1e,$1e,$17 db $17,$76 ; **RUN ML***SLR/2022** start: call slow ; SLOW is required. ; end header and startup ; ; --- ; +++ ; ; Main Loop ; mainloop: ; reset variables xor a ; ld a,0 ld (runframe),a ; reset run frame ld (skycopy),a ; reset sky copy time inc a ; ld a,1 ld (skyframe),a ; reset sky frame ld (worldnum),a ; reset world number ld (worldframe),a ; reset world frame ld hl,skybuf0upper ; clear buffers ld bc,320 clearskyloop: ld (hl),$00 inc hl dec bc ld a,b ; test 16-bit counter or c jr nz,clearskyloop ; print static elements call cls ld bc,$0302 ; head call printat ld a,$80 rst $10 ld bc,$0700 ; floor call printat ld b,32 ld a,3 floorlp: rst $10 djnz floorlp animate: ; deal with runner ld hl,runner ld (runframe),hl ld b,4 runloop: push bc call printrunner call printsky call printscore ; call printbox ; call printcoins ld hl,50 call newpause pop bc djnz runloop jp animate ; End of loop! ; ; +++ ; ; Routines ; printrunner: ld b,4 ; load position ld c,1 call printrunrow call printrunrow call printrunrow ret printrunrow: push bc call printat ; print location ld hl,(runframe) ; load run location ld b,3 ; print row printrunrowlp: ld a,(hl) rst $10 inc hl djnz printrunrowlp ld (runframe),hl ; save next row pop bc inc b ; move down a row ret printbox: ld bc,$0519 call printat ld hl,boxtop call print ld bc,$0618 call printat ld hl,boxbottom jp print boxtop: db $b1,$ff boxbottom: db $b1,$b1,$b1,$ff printscore: ; since we don't have movement yet, clear score area ld a,3 ld bc,$0204 blankloop: push af push bc call printat ld hl,blank call print pop bc inc b pop af dec a jr nz,blankloop ld a,(scoreframe) dec a cp 1 jr z,scoreframe1 cp 2 jr z,scoreframe2 cp 3 jr z,scoreframe3 cp 4 jr z,scoreframe4 ; no frame, reset counter ld a,5 ; reset scoreframe anex return ld (scoreframe),a ret scoreframe4: ld bc,$0404 ld hl,score20_1 jr printscoreframe scoreframe3: ld bc,$0405 ld hl,score20_1 jr printscoreframe scoreframe2: ld bc,$0305 ld hl,score20_2 jr printscoreframe scoreframe1: ld bc,$0206 ld hl,score20_2 printscoreframe: ld (scoreframe),a push hl call printat pop hl jp print scoreframe: db 0 score20_1: db $95,$9e,$9c,$ff score20_2: db $15,$1e,$1c,$ff blank: db $00,$00,$00,$00,$00,$ff printcoins: ld bc,$0410 call printat ld hl,coinsrot0 ld a,(skyframe) and a ; is a 0? jr nz,printcoinstring ld hl,coinsrot1 printcoinstring: jp print coinsrot0: db $34,$00,$34,$00,$34,$ff coinsrot1: db $2e,$00,$2e,$00,$2e,$ff ; this is the new routine printsky: ld a,(skycopy) and a ; is a 0? jr nz,getskyframe ; no ; yes, copy in screen call copysky ; copy sky into buffer ld a,80 ; and reset sky counter (double due to frames) getskyframe: dec a ; decrement a ld (skycopy),a ; and save it ld a,(skyframe) ; get sky frame (0 or 1) xor 1 ; flip it (0 to 1, 1 to 0) ld (skyframe),a ; and save it! and a ; is it 0? jr nz,printskyframe1 printskyframe0: ; print sky from buffer 0 ld hl,skybuf0upper call shiftsky ld hl,skybuf0lower call shiftsky ; trying to poke screen instead of print it ld hl,skybuf0upper ld de,(d_file) inc de ; set to 0,0 of screen (1st row) ld bc,32 ; 32 characters to copy ldir ; copy row into screen ld hl,skybuf0lower inc de ; set to 1,0 of screen (2nd row) ld bc,32 ; 32 characters to copy ldir ; copy row into screen ret ; ld bc,$0000 ; call printat ; ld hl,skybuf0upper ; call printskyrow ; ld bc,$0100 ; call printat ; ld hl,skybuf0lower ; jp printskyrow printskyframe1: ; print sky from buffer 1 ld hl,skybuf1upper call shiftsky ld hl,skybuf1lower call shiftsky ; trying to poke screen instead of print it ld hl,skybuf1upper ld de,(d_file) inc de ; set to 0,0 of screen (1st row) ld bc,32 ; 32 characters to copy ldir ; copy row into screen ld hl,skybuf1lower inc de ; set to 1,0 of screen (2nd row) ld bc,32 ; 32 characters to copy ldir ; copy row into screen ret ; ld bc,$0000 ; call printat ; ld hl,skybuf1upper ; call printskyrow ; ld bc,$0100 ; call printat ; ld hl,skybuf1lower ; jp printskyrow ; old routine... printskyrow: ld b,32 printskyrowlp: ld a,(hl) rst $10 inc hl djnz printskyrowlp ret shiftsky: ld a,(hl) ; grab first character ld de,hl inc hl ld bc,79 ldir ; shift line to the left ld (de),a ; replace last char with first ret ; copy sky (hl) into sky buffer (de) copysky: ; first, check routines ld a,(worldframe) ; get which frame of world we are on dec a jr nz,saveworldframe ; not zero, keep going ; is zero, update world ld hl,(world) ; load in world ld bc,10 ; skip transition and 4 addresses (10 bytes) add hl,bc ; set new world address ld (world),hl ; and then save it ld a,(worldnum) ; check world number dec a jr nz,getnextworld ; not zero, get next world ; is zero, reset worlds ld hl,worlds ld (world),hl ; set address to world start ld a,numworlds ; reset world number getnextworld: ld (worldnum),a ; save new world number ld hl,(world) ; load in new sky ld e,(hl) ; sky upper frame 0 inc hl ld d,(hl) inc hl ex de,hl ld (skyupper0),hl ex de,hl ld e,(hl) ; sky lower frame 0 inc hl ld d,(hl) inc hl ex de,hl ld (skylower0),hl ex de,hl ld e,(hl) ; sky upper frame 1 inc hl ld d,(hl) inc hl ex de,hl ld (skyupper1),hl ex de,hl ld e,(hl) ; sky lower frame 1 inc hl ld d,(hl) inc hl ex de,hl ld (skylower1),hl ex de,hl ; okay, copy in transition ld e,(hl) ; get upper transition byte inc hl ld d,(hl) ; get lower transition byte ld hl,skybuf1uppertrans ld (hl),e ; set upper transition ld hl,skybuf1lowertrans ld (hl),d ; set lower transition ld a,worldrepeat ; reset world frame saveworldframe: ld (worldframe),a ld hl,(skyupper0) ld de,skybuf0uppercopy ld bc,40 ; 40 characters to copy ldir ld hl,(skylower0) ld de,skybuf0lowercopy ld bc,40 ; 40 characters to copy ldir ld hl,(skyupper1) ld de,skybuf1uppercopy ld bc,40 ; 40 characters to copy ldir ld hl,(skylower1) ld de,skybuf1lowercopy ld bc,40 ; 40 characters to copy ldir ; shift line to the left ret ; ; 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 ; ; 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 ; +++ ; ; 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 ; ; ; constants ; worldrepeat: equ 2 ; repeate each world's sky 10 times numworlds: equ 4 ; currently two worlds ; ; vars ; runframe: dw 0 ; runner frame to display (0-3) skyframe: db 0 ; sky frame to display (0-1) skycopy: db 0 ; time to copy in sky world: dw 0 ; world we are on worldnum: db 0 ; at first world worldframe: db 0 ; frames to display ; these determe sky to use skyupper0: dw 0 skylower0: dw 0 skyupper1: dw 0 skylower1: dw 0 worlds: dw skyupper0_cloudy dw skylower0_cloudy dw skyupper1_cloudy dw skylower1_cloudy db $00,$00 ; transition from day dw skyupper0_mountain dw skylower0_mountain dw skyupper1_mountain dw skylower1_mountain db $00,$87 ; transition from cloudy dw skyupper0_dark dw skylower0_dark dw skyupper1_dark dw skylower1_dark db $85,$85 ; transition from mountain dw skyupper0_day dw skylower0_day dw skyupper1_day dw skylower1_day db $05,$05 ; transition from dark ; ; runner ; runner: db $87, $82, $04, $01, $05, $00, $06, $02, $04 db $87, $82, $00, $02, $05, $01, $87, $84, $00 db $87, $82, $00, $00, $07, $00, $00, $07, $00 db $87, $82, $00, $02, $05, $01, $87, $84, $00 ; ; sky ; skyupper0_cloudy: db $00, $00, $01, $03, $80, $07, $01, $01, $00, $00 db $00, $00, $83, $00, $00, $87, $07, $04, $00, $00 db $83, $00, $00, $00, $00, $00, $87, $07, $04, $00 db $87, $04, $00, $00, $00, $00, $00, $87, $07, $04 skylower0_cloudy: db $00, $00, $87, $01, $87, $00, $86, $00, $00, $00 db $83, $81, $82, $01, $03, $03, $03, $00, $87, $81 db $82, $01, $00, $00, $00, $02, $03, $03, $87, $83 db $80, $06, $00, $00, $00, $00, $03, $03, $03, $00 skyupper1_cloudy: db $00, $02, $02, $84, $80, $03, $02, $00, $00, $00 db $00, $87, $04, $00, $00, $81, $86, $00, $00, $87 db $04, $00, $00, $00, $00, $00, $81, $86, $00, $00 db $83, $00, $00, $00, $00, $00, $00, $81, $86, $00 skylower1_cloudy: db $00, $00, $06, $00, $04, $02, $04, $00, $00, $87 db $83, $80, $06, $02, $03, $03, $01, $00, $83, $80 db $06, $00, $00, $00, $00, $03, $03, $01, $83, $81 db $82, $01, $00, $00, $00, $02, $03, $03, $01, $00 ; old cloud sky ;skyupper0_cloudy: ; db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; db $83, $00, $00, $87, $07, $04, $00, $00, $00, $00 ; db $00, $02, $04, $02, $00, $06, $00, $00, $00, $00 ; db $00, $00, $00, $00, $00, $00, $00, $87, $07, $04 ;skylower0_cloudy: ; db $00, $00, $00, $00, $00, $00, $00, $00, $83, $81 ; db $82, $01, $03, $03, $03, $00, $00, $00, $00, $00 ; db $00, $04, $83, $80, $82, $04, $04, $00, $00, $00 ; db $00, $00, $00, $00, $00, $00, $03, $03, $03, $00 ;skyupper1_cloudy: ; db $00, $00, $00, $00, $00, $00, $00, $00, $00, $87 ; db $04, $00, $00, $81, $86, $00, $00, $00, $00, $00 ; db $00, $86, $00, $01, $87, $01, $00, $00, $00, $00 ; db $00, $00, $00, $00, $00, $00, $00, $81, $86, $00 ;skylower1_cloudy: ; db $00, $00, $00, $00, $00, $00, $00, $87, $83, $80 ; db $06, $02, $03, $03, $01, $00, $00, $00, $00, $00 ; db $87, $87, $81, $80, $83, $87, $00, $00, $00, $00 ; db $00, $00, $00, $00, $00, $02, $03, $03, $01, $00 skyupper0_mountain: db $00, $06, $83, $00, $02, $04, $00, $01, $00, $06 db $00, $87, $06, $86, $04, $87, $86, $00, $00, $06 db $86, $00, $87, $86, $87, $86, $00, $00, $87, $87 db $03, $04, $00, $00, $87, $03, $83, $87, $04, $00 skylower0_mountain: db $06, $00, $00, $03, $83, $87, $81, $80, $83, $87 db $06, $01, $00, $00, $02, $86, $04, $86, $06, $00 db $00, $86, $01, $00, $86, $00, $86, $87, $01, $86 db $00, $85, $00, $87, $01, $00, $87, $01, $02, $04 skyupper1_mountain: db $87, $86, $04, $00, $86, $00, $02, $00, $87, $01 db $00, $83, $03, $83, $00, $06, $04, $00, $87, $03 db $04, $00, $06, $04, $06, $04, $00, $00, $04, $06 db $86, $00, $00, $00, $06, $86, $04, $83, $00, $00 skylower1_mountain: db $01, $00, $02, $86, $04, $83, $80, $82, $04, $83 db $03, $00, $00, $00, $03, $83, $02, $83, $01, $00 db $02, $06, $00, $02, $04, $02, $04, $06, $02, $04 db $00, $05, $00, $06, $00, $00, $06, $00, $86, $87 skyupper0_dark: db $80, $84, $80, $07, $80, $07, $87, $02, $80, $80 db $03, $80, $80, $84, $80, $07, $80, $80, $80, $80 db $03, $07, $01, $83, $80, $07, $84, $80, $80, $80 db $82, $80, $84, $80, $07, $01, $83, $07, $84, $80 skylower0_dark: db $80, $80, $81, $80, $80, $00, $01, $04, $85, $83 db $81, $80, $81, $80, $80, $80, $80, $81, $80, $83 db $81, $80, $80, $80, $83, $83, $80, $80, $81, $07 db $80, $80, $80, $81, $80, $80, $82, $83, $80, $84 skyupper1_dark: db $07, $80, $80, $84, $80, $01, $04, $84, $80, $07 db $84, $80, $07, $80, $80, $84, $80, $80, $80, $07 db $84, $03, $87, $81, $80, $03, $80, $80, $80, $80 db $81, $07, $80, $80, $03, $87, $81, $03, $80, $80 skylower1_dark: db $80, $82, $80, $80, $05, $02, $87, $00, $82, $83 db $80, $82, $80, $80, $80, $80, $82, $80, $82, $83 db $80, $80, $80, $82, $83, $81, $80, $82, $80, $84 db $80, $80, $82, $80, $80, $80, $83, $81, $07, $80 skyupper0_day: db $00, $00, $00, $02, $04, $00, $02, $00, $00, $06 db $00, $00, $00, $00, $00, $87, $81, $03, $00, $83 db $83, $00, $00, $00, $00, $87, $81, $01, $00, $87 db $83, $00, $00, $00, $00, $00, $03, $84, $83, $04 skylower0_day: db $00, $00, $87, $83, $00, $83, $80, $82, $04, $87 db $83, $00, $00, $00, $00, $00, $00, $02, $03, $01 db $00, $00, $00, $03, $84, $83, $00, $00, $02, $03 db $00, $00, $00, $87, $83, $81, $03, $00, $00, $00 skyupper1_day: db $00, $00, $00, $86, $00, $00, $01, $00, $87, $01 db $00, $00, $00, $00, $00, $83, $07, $01, $87, $83 db $04, $00, $00, $00, $00, $83, $07, $00, $00, $83 db $04, $00, $00, $00, $00, $02, $03, $82, $83, $00 skylower1_day: db $00, $00, $83, $04, $87, $81, $80, $83, $00, $83 db $04, $00, $00, $00, $00, $00, $00, $03, $03, $00 db $00, $00, $02, $03, $82, $04, $00, $00, $03, $01 db $00, $00, $00, $83, $83, $07, $01, $00, $00, $00 ; ; Buffers ; skybuf0upper: 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, $00, $00, $00, $00, $00, $00, $00, $00 skybuf0uppercopy: 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, $00, $00, $00, $00, $00, $00, $00, $00 skybuf0lower: 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, $00, $00, $00, $00, $00, $00, $00, $00 skybuf0lowercopy: 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, $00, $00, $00, $00, $00, $00, $00, $00 skybuf1upper: 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, $00, $00, $00, $00, $00, $00, $00 skybuf1uppertrans: db $00 skybuf1uppercopy: 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, $00, $00, $00, $00, $00, $00, $00, $00 skybuf1lower: 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, $00, $00, $00, $00, $00, $00, $00 skybuf1lowertrans: db $00 skybuf1lowercopy: 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, $00, $00, $00, $00, $00, $00, $00, $00 ; end data ; ---