sedge-WL-v1.tap
SEDGE.WAV
As a kid I always wondered how it was possible to have animated graphics during loading. The first time I saw such loaders was during loading on Mastertronics 'Future Games'.
After examining the ROM loader routine (thanks to skoolkid.github.io) I noticed a perfect opportunity for squeezing in 358 T-states worth of graphics code.
Code: Select all
LD_EDGE_1 LD A,$16 ;Wait 358 T states before entering the sampling loop.
LD_DELAY DEC A
JR NZ,LD_DELAY
Code: Select all
ld_edge_1:
push hl ; 11T [11]
ld a,l ; 4T [15]
and %00000001 ; 7T [22]
ld a,(counter) ; 13T [35]
jp z,padding ; 10T [45] ;if last loaded bit is set, skip increment
inc a ; 4T [49]
jp tests ; 10T [59]
padding:
ld a,a ; 4T [49] ; keep T-states regular
jp tests ; 10T [59]
tests:
ld (counter),a ; 17T [76]
cp 127 ; 7T [83]
jp nz,next_check ; 10T [93]
;;; open beak 195T
ld hl,22823
ld a,%00111000 ; change attributes to reveal open beak
ld (hl),a
inc l
ld (hl),a
inc l
ld (hl),a
ld hl,22791
ld a,%00111111 ; change attributes to hide closed beak
ld (hl),a
inc l
ld (hl),a
ld hl,18953
ld a,%00000111
ld (hl),a
inc h
ld a,%00000001
ld (hl),a
inc h
ld a,%00000111
ld (hl),a
inc h
ld a,%00011101
ld (hl),a
inc h
ld a,%00110110
ld (hl),a
inc h
ld a,%01100100
ld (hl),a
;;; end of open beak
ld a,a ; 4T [292]
ld a,3 ; 7T [299]
jp common ; 10T [309]
next_check:
cp 255 ; 7T [100]
jp nz,no_change ; 10T [110]
;;; close beak 195T
ld hl,22791
ld a,%00111000 ; change attributes to reveal closed beak
ld (hl),a
inc l
ld (hl),a
ld hl,22823
ld a,%00111111 ; change attributes to conceal open beak
ld (hl),a
inc l
ld (hl),a
inc l
ld (hl),a
ld hl,18953 ; ovewrite 6 screen bytes
ld a,%11111111
ld (hl),a
inc h
ld a,%00001110
ld (hl),a
inc h
ld a,%00011000
ld (hl),a
inc h
ld a,%11000000
ld (hl),a
inc h
ld a,%00111111
ld (hl),a
inc h
ld a,%00000011
ld (hl),a
;;; end close beak
ld a,a ; 4T [309]
ld a,1 ; 7T [316]
jp common ; 10T [326]
no_change:
ld a,15 ; 7T [117]
common:
pop hl ; 10T
;;; open beak = 319T
;;; closed beak = 336T
;;; no-change = 127T
ld_delay:
dec a ; 4T
jr nz,ld_delay ; 7T | 12T ; delay of 359 T States
;;; open beak = 358T
;;; closed beak = 359T
;;; no-change = 358T
Full asm source :
Code: Select all
;;;; Custom loader
org 40000
ld ix,dummy_header ;set IX to point to dummy header location
ld de,17 ;load header bytes
xor a ;zero A for header
scf ;set carry for LOAD not VERIFY
call ld_bytes ;call load ROM routine
ld ix,(dummy_header+13) ;set IX to data block destination from header
ld de,(dummy_header+11) ;set DE to data block length from header
ld a,255 ;set A to FF for data block
scf ;set CF for LOAD
call ld_bytes ;call ROM routine
ret
ld_bytes:
inc d
ex af,af'
dec d
di
ld a,$0F ; BIN 00010000
out ($FE),a
ld hl,$053F
push hl
in a,($FE)
rra
and $20
or $02
ld c,a
cp a
ld_break:
ret nz
ld_start:
call ld_edge_1
jr nc,ld_break
ld hl,$0415
ld_wait:
djnz ld_wait
dec hl
ld a,h
or l
jr nz,ld_wait
call ld_edge_2
jr nc,ld_break
ld_leader:
ld b,$9C
call ld_edge_2
jr nc,ld_break
ld a,$C6
cp b
jr nc,ld_start
inc h
jr nz,ld_leader
ld_sync:
ld b,$C9
call ld_edge_1
jr nc,ld_break
ld a,b
cp $D4
jr nc,ld_sync
call ld_edge_1
ret nc
;;; load bytes
ld a,c
xor $03
ld c,a
ld h,$00
ld b,$B0
jr ld_marker
ld_loop:
ex af,af'
jr nz,ld_flag
jr nc,ld_verify
ld (ix+$00),l
jr ld_next
ld_flag:
rl c
xor l
ret nz
ld a,c
rra
ld c,a
inc de
jr ld_dec
ld_verify:
ld a,(ix+$00)
xor l
ret nz
ld_next:
inc ix
ld_dec:
dec de
ex af,af'
ld b,$B2
ld_marker:
ld l,$01
ld_8_bits:
call ld_edge_2
ret nc
ld a,$CB
cp b
rl l
ld b,$B0
jp nc,ld_8_bits
ld a,h
xor l
ld h,a
ld a,d
or e
jr nz,ld_loop
ld a,h
cp $01
ret
ld_edge_2:
call ld_edge_1
ret nc
ld_edge_1:
push hl ; 11T [11]
ld a,l ; 4T [15]
and %00000001 ; 7T [22]
ld a,(counter) ; 13T [35]
jp z,padding ; 10T [45] ;if A<>7, skip increment
inc a ; 4T [49]
jp tests ; 10T [59]
padding:
ld a,a ; 4T [49] ; keep T-states regular
jp tests ; 10T [59]
tests:
ld (counter),a ; 17T [76]
cp 127 ; 7T [83]
jp nz,next_check ; 10T [93]
;;; open beak 195T
ld hl,22823
ld a,%00111000 ; change attributes to reveal open beak
ld (hl),a
inc l
ld (hl),a
inc l
ld (hl),a
ld hl,22791
ld a,%00111111 ; change attributes to hide closed beak
ld (hl),a
inc l
ld (hl),a
ld hl,18953
ld a,%00000111
ld (hl),a
inc h
ld a,%00000001
ld (hl),a
inc h
ld a,%00000111
ld (hl),a
inc h
ld a,%00011101
ld (hl),a
inc h
ld a,%00110110
ld (hl),a
inc h
ld a,%01100100
ld (hl),a
;;; end of open beak
ld a,a ; 4T [292]
ld a,3 ; 7T [299]
jp common ; 10T [309]
next_check:
cp 255 ; 7T [100]
jp nz,no_change ; 10T [110]
;;; close beak 195T
ld hl,22791
ld a,%00111000 ; change attributes to reveal closed beak
ld (hl),a
inc l
ld (hl),a
ld hl,22823
ld a,%00111111 ; change attributes to conceal open beak
ld (hl),a
inc l
ld (hl),a
inc l
ld (hl),a
ld hl,18953 ; ovewrite 6 screen bytes
ld a,%11111111
ld (hl),a
inc h
ld a,%00001110
ld (hl),a
inc h
ld a,%00011000
ld (hl),a
inc h
ld a,%11000000
ld (hl),a
inc h
ld a,%00111111
ld (hl),a
inc h
ld a,%00000011
ld (hl),a
;;; end close beak
ld a,a ; 4T [309]
ld a,1 ; 7T [316]
jp common ; 10T [326]
no_change:
ld a,15 ; 7T [117]
common:
pop hl ; 10T
;;; open beak = 319T
;;; closed beak = 336T
;;; no-change = 127T
ld_delay:
dec a ; 4T
jr nz,ld_delay ; 7T | 12T ; delay of 359 T States
;;; open beak = 358T
;;; closed beak = 359T
;;; no-change = 358T
and a
ld_sample:
inc b
ret z
ld a,$7F
in a,($FE)
rra
ret nc
xor c
and $20
jr z,ld_sample
ld a,c
cpl
ld c,a
and $07
or $08
out ($FE),a
scf
ret
counter:
defb 0
dummy_header: