;; Pogostick Olympics - Silverbird
;;
;; Firebird counter loader '88
;;
;; This was dissassembled from a snapshot that was taken 
;; when "Searching 00" was displayed.
;; 
;; This does not necessarily represent the structure of the 
;; loader stored cassette.

3e00 cd4c3f    call    $3f4c			;; enable cassette motor
	
;; select text window 1
3e03 3e01      ld      a,$01
3e05 cdb4bb    call    $bbb4			;; firmware function: txt str select

;; clear text window 1
3e08 cd6cbb    call    $bb6c			;; firmware function: txt clear window

;; select text window 2
3e0b 3e02      ld      a,$02
3e0d cdb4bb    call    $bbb4			;; firmware function: txt str select

;; select pen 2 for displaying text
3e10 3e02      ld      a,$02
3e12 cd90bb    call    $bb90			;; firmware function: txt set pen

3e15 1600      ld      d,$00			;; block number
3e17 cdab3f    call    $3fab			;; display "Searching xx"

3e1a 3e08      ld      a,$08
3e1c 3246a1    ld      ($a146),a
3e1f cd123f    call    $3f12			;; delay & calc data size
3e22 cd8a3e    call    $3e8a			;; read data
3e25 3a32a1    ld      a,($a132)		; current block number
3e28 ba        cp      d				; number of block found
3e29 2805      jr      z,$3e30          ; block found

;; incorrect block found
3e2b cd7c3f    call    $3f7c			; display "Block ?  " 
3e2e 18ea      jr      $3e1a            ;

;;------------------------------------------------------------
;; block number is correct....
;; check if data is correct

3e30 cd1d3f    call    $3f1d			;; checksum block data
3e33 be        cp      (hl)				;; matches stored checksum?
3e34 2821      jr      z,$3e57          ;; Z = yes, matches checksum, NZ = no, doesn't match checksum

;; checksum doesn't match
3e36 cd7c3f    call    $3f7c			; display "Block ?  "
3e39 18df      jr      $3e1a            ; 

;;------------------------------------------------------------
;; calls back to here for each block

;; block number is correct, checksum is correct
3e3b cd123f    call    $3f12			;; delay & calc data size
3e3e cd8a3e    call    $3e8a			;; read data
3e41 3a32a1    ld      a,($a132)		; current block number
3e44 ba        cp      d				; number of block found
3e45 2805      jr      z,$3e4c          ; 

;; found data for wrong block
3e47 cd7c3f    call    $3f7c			; display "Block ?  "
3e4a 18ef      jr      $3e3b            ; (-$11)

;;------------------------------------------------------------
;; found data for correct block

3e4c cd1d3f    call    $3f1d			;; checksum block data
3e4f be        cp      (hl)				;; matches stored checksum?
3e50 2805      jr      z,$3e57          

;; block data checksum failed
3e52 cd7c3f    call    $3f7c			; display "Block ?  "
3e55 18e4      jr      $3e3b            ; (-$1c)


;;------------------------------------------------------------
3e57 cd753e    call    $3e75			; move loaded block data
										; to correct destination
										; location

3e5a cd543f    call    $3f54			; display "Loading xx"

;;
3e5d 2135a1    ld      hl,$a135
3e60 7e        ld      a,(hl)
3e61 23        inc     hl				
3e62 3d        dec     a
3e63 20fc      jr      nz,$3e61         ; (-$04)

3e65 23        inc     hl
3e66 23        inc     hl
3e67 23        inc     hl
3e68 23        inc     hl
3e69 7e        ld      a,(hl)
3e6a 2b        dec     hl
3e6b 2b        dec     hl
3e6c 2b        dec     hl

3e6d e607      and     $07
3e6f 3c        inc     a
3e70 3246a1    ld      ($a146),a		; extra bytes to read

3e73 14        inc     d				; new block number

3e74 e9        jp      (hl)				; execute or continue loading!

;;---------------------------------------------------------------
;; move loaded block data to correct destination location

3e75 d5        push    de
3e76 e5        push    hl
3e77 ed5b33a1  ld      de,($a133)		; destination
3e7b 2132a0    ld      hl,$a032			; location of loaded block data
3e7e 010001    ld      bc,$0100			; length of loaded block data
3e81 edb0      ldir    
3e83 e1        pop     hl
3e84 d1        pop     de
3e85 fde1      pop     iy
3e87 fde5      push    iy
3e89 c9        ret     

;;---------------------------------------------------------------
;; read data
;; BC = length of data
3e8a f3        di      
3e8b d5        push    de
3e8c e5        push    hl
3e8d c5        push    bc

;; look for leader
;; must be 256 pulses long 
3e8e 0600      ld      b,$00

3e90 cdf73e    call    $3ef7			; time signal transition
3e93 cdf93e    call    $3ef9			; time signal transition

3e96 3e36      ld      a,$36			; 54
3e98 cb3f      srl     a				; /2 = 27
3e9a ce36      adc     a,$36			; 54 = 81
										; ~2916 T
3e9c bb        cp      e
3e9d 30ef      jr      nc,$3e8e         ; 
;; pulse is within range
3e9f 10ef      djnz    $3e90            ; (-$11)

3ea1 2636      ld      h,$36			; 54

;; loops here a bit

3ea3 53        ld      d,e				; last measured pulse

3ea4 7b        ld      a,e
3ea5 94        sub     h
3ea6 4f        ld      c,a				; difference between last measured pulse and ideal

3ea7 9f        sbc     a,a				
3ea8 47        ld      b,a				

3ea9 cb21      sla     c

3eab 09        add     hl,bc

3eac cdf73e    call    $3ef7			; time signal transition

3eaf 7c        ld      a,h				; 
3eb0 cb3f      srl     a				; 
3eb2 cb3f      srl     a				; 
3eb4 8c        adc     a,h				; A = H * 5/4

3eb5 92        sub     d
3eb6 38eb      jr      c,$3ea3          ; (-$15)

3eb8 93        sub     e
3eb9 38e8      jr      c,$3ea3          ; (-$18)


3ebb 7c        ld      a,h
3ebc cb1f      rr      a				;
3ebe 8c        adc     a,h				; A = H * 3
3ebf 32f3a1    ld      ($a1f3),a		; store time constant

										; $51/$53

3ec2 cddd3e    call    $3edd			; read a byte
3ec5 fe64      cp      $64				; sync byte?
3ec7 20c5      jr      nz,$3e8e         ; (-$3b)

;; read some data
3ec9 2132a0    ld      hl,$a032
3ecc c1        pop     bc


;; BC = length of data to read
;; HL = location to load data to
3ecd c5        push    bc
3ece cddd3e    call    $3edd			; read a byte
3ed1 77        ld      (hl),a			; store data byte
3ed2 23        inc     hl				; increment load pointer
3ed3 0b        dec     bc				; decrement byte count
3ed4 78        ld      a,b
3ed5 b1        or      c
3ed6 20f6      jr      nz,$3ece         

3ed8 c1        pop     bc
3ed9 e1        pop     hl
3eda d1        pop     de
3edb fb        ei      
3edc c9        ret     


;;-------------------------------------------------------------
;; read a byte of data
;; A = data byte
3edd d5        push    de
3ede cdf73e    call    $3ef7			; time signal transition
3ee1 cdf93e    call    $3ef9			; time signal transition

;; a bit mask to indicate number of bits to transfer
;; AND will be the data-byte after all bits have been transfered
3ee4 1601      ld      d,$01			; transfer 8 bits

3ee6 cdf73e    call    $3ef7			; time signal transition
3ee9 cdf93e    call    $3ef9			; time signal transition

3eec 3af3a1    ld      a,($a1f3)		; time constant
3eef bb        cp      e				; time measured
										; set state of carry
										; nc = greater or equal, c = less

3ef0 cb12      rl      d				; shift carry into data, and shift old bit 7 into carry

3ef2 30f2      jr      nc,$3ee6         ; if bit shifted into carry is 1, then stop
										; reading bits, otherwise continue to read bits
										; this looks for the mask bit

3ef4 7a        ld      a,d
3ef5 d1        pop     de
3ef6 c9        ret     

;;-------------------------------------------------------------
;; time signal transition
3ef7 1e00      ld      e,$00

;;-------------------------------------------------------------
3ef9 c5        push    bc			;; [4]
3efa ed5f      ld      a,r			;; [2]			
3efc cb3f      srl     a			;; [2]
3efe cb3f      srl     a			;; [2]
3f00 83        add     a,e			;; [1]
3f01 5f        ld      e,a			;; [1]

3f02 06f5      ld      b,$f5		;; PPI port B input
3f04 ed48      in      c,(c)		;; get PPI port B inputs 
									;; (includes cassette input data)

3f06 1c        inc     e			;; [1] update time between 
									;; signal transitions

3f07 ed78      in      a,(c)		;; [4] get PPI port B inputs
									;; (includes cassette input data)

3f09 a9        xor     c			;; [1] any bit that has changed state will be 1
									;; any bit that has not changed state will be 0 

3f0a f2063f    jp      p,$3f06		;; [3] check for bit 7 changing state
									; 4+1+1+3 = 9us per test
									; 9*4 = 36T per test

;; at this point: signal state has changed.i.e. there is a signal transition (low->high or high->low)
;; E = "time" between transitions

3f0d c1        pop     bc			;; [3]
3f0e af        xor     a			;; [1]
3f0f ed4f      ld      r,a			;; [2]
3f11 c9        ret     

;;-------------------------------------------------------
;; delay & calc block size
;; block has 256 bytes of data, a 1 byte checksum

3f12 3a46a1    ld      a,($a146)
3f15 010801    ld      bc,$0108
3f18 03        inc     bc
3f19 3d        dec     a
3f1a 20fc      jr      nz,$3f18         ; (-$04)
3f1c c9        ret     

;;-------------------------------------------------------
;; checksum loaded block

3f1d d5        push    de
3f1e cd123f    call    $3f12			;; delay & calc block size
3f21 0b        dec     bc

3f22 2132a0    ld      hl,$a032			;; block pointer

3f25 ae        xor     (hl)				;; combine data byte with
										;; checksum
3f26 5f        ld      e,a
3f27 23        inc     hl				;; increment data pointer
3f28 0b        dec     bc				;; decrement count
3f29 78        ld      a,b
3f2a b1        or      c
3f2b 7b        ld      a,e
3f2c 20f7      jr      nz,$3f25         
3f2e d1        pop     de
3f2f c9        ret     

;;-------------------------------------------------
;; display current block number and increment
3f30 2132a1    ld      hl,$a132
3f33 7e        ld      a,(hl)			;; get current block number
3f34 34        inc     (hl)				;; increment

;;-------------------------------------------------
;; display a hex number
3f35 f5        push    af
3f36 07        rlca    
3f37 07        rlca    
3f38 07        rlca    
3f39 07        rlca    
3f3a cd3e3f    call    $3f3e			;; display upper nibble
3f3d f1        pop     af
										;; display lower nibble
;; display a nibble
3f3e e60f      and     $0f
3f40 f630      or      $30
3f42 fe3a      cp      $3a
3f44 3802      jr      c,$3f48          
3f46 c607      add     a,$07
3f48 cd5abb    call    $bb5a			; firmware function: txt output
3f4b c9        ret     

;;-------------------------------------------------
;; enable cassette motor
3f4c c5        push    bc
3f4d 0110f6    ld      bc,$f610
3f50 ed49      out     (c),c
3f52 c1        pop     bc
3f53 c9        ret     

;;-------------------------------------------------
;; display "Loading xx"

3f54 e5        push    hl
3f55 d5        push    de

;; select text window 2
3f56 3e02      ld      a,$02
3f58 cdb4bb    call    $bbb4			; firmware function: txt str select

;; clear window
3f5b cd6cbb    call    $bb6c			; firmware function: txt clear window

;; select text window 1
3f5e 3e01      ld      a,$01
3f60 cdb4bb    call    $bbb4			; firmware function: txt str select

;; select pen 2 for displaying text
3f63 3e02      ld      a,$02
3f65 cd90bb    call    $bb90			; firmware function: txt set pen

3f68 cdd43f    call    $3fd4			; display string following

defb &0d,"Loading   ",0

3f77 d1        pop     de
3f78 e1        pop     hl
3f79 c3303f    jp      $3f30			; display current block number and increment

;;-------------------------------------------------
;; display "Block ?  "

3f7c e5        push    hl
3f7d 5f        ld      e,a
3f7e d5        push    de

;; select text window 1
3f7f 3e01      ld      a,$01
3f81 cdb4bb    call    $bbb4			; firmware function: txt str select

;; select pen 3 for displaying text
3f84 3e03      ld      a,$03
3f86 cd90bb    call    $bb90			; firmware function: txt set pen

3f89 cdd43f    call    $3fd4			; display string following

defb &0d,"Block ?   ",0

3f98 cd303f    call    $3f30			; display current block number and increment

;; select text window 2
3f9b 3e02      ld      a,$02
3f9d cdb4bb    call    $bbb4			; firmware function: txt str select

;; select pen 3 for displaying text
3fa0 3e03      ld      a,$03
3fa2 cd90bb    call    $bb90			; firmware function: txt set pen

3fa5 d1        pop     de
3fa6 7b        ld      a,e
3fa7 ba        cp      d
3fa8 3016      jr      nc,$3fc0         ; display "Rewind to xx"
3faa e1        pop     hl

;;--------------------------------------------------
;; display "Searching xx"

3fab e5        push    hl
3fac cdd43f    call    $3fd4			; display string following

defb &0d,"Searching ",0

3fbb 7a        ld      a,d
3fbc e1        pop     hl
3fbd c3353f    jp      $3f35			; display block number (in A register)

;;-------------------------------------------------
;; display "Rewind to xx"

3fc0 cdd43f    call    $3fd4			; display string following

defb &0d,"Rewind to ",0

3fcf 7a        ld      a,d
3fd0 e1        pop     hl
3fd1 c3353f    jp      $3f35			; display block number (in A register)

;;-----------------------------------
;; display a null terminated string
;; 
;; the string is following the original call
3fd4 e1        pop     hl				;; get address of string from stack
3fd5 7e        ld      a,(hl)
3fd6 23        inc     hl
3fd7 fe00      cp      $00
3fd9 c45abb    call    nz,$bb5a			;; firmware function: txt output
3fdc 20f7      jr      nz,$3fd5         ; (-$09)
3fde e5        push    hl				;; fix up return address (address following end of string)

3fdf c9        ret     
;;-----------------------------------


