;; Elite - Gold Edition
;;
;; Firebird '86


3b00 1600      ld      d,$00
3b02 cd463c    call    $3c46		;; start cassette motor

;; select text window 1
3b05 3e01      ld      a,$01
3b07 cdb4bb    call    $bbb4		;; firmware function: txt str select

;; select pen 2 for displaying text
3b0a 3e01      ld      a,$01
3b0c cd90bb    call    $bb90		;; firmware function: txt set pen

3b0f cda53c    call    $3ca5		;; display "Searching xx"

;; sync byte
3b12 3e0f      ld      a,$0f
3b14 32305a    ld      ($5a30),a

;; block additional data count
3b17 3e08      ld      a,$08
3b19 32465b    ld      ($5b46),a

;;---------------------------------------------

3b1c cdfc3b    call    $3bfc		;; delay and calc block size
3b1f cd903b    call    $3b90		;; read block
3b22 3a325b    ld      a,($5b32)	;; block number
3b25 ba        cp      d			;; matches loaded block number?
3b26 2805      jr      z,$3b2d
         
;; block number doesn't match
3b28 cd763c    call    $3c76		;; display "Block ?  xx"
;; restart
3b2b 18e5      jr      $3b12        

;;------------------------------------

3b2d cd073c    call    $3c07		;; checksum data
3b30 be        cp      (hl)			;; checksum matches?
3b31 2805      jr      z,$3b38

3b33 cd763c    call    $3c76		;; display "Block ? xx"
;; restart
3b36 18da      jr      $3b12            ; (-$26)

;;-------------------------------------

;; checksum byte defines next sync byte value
3b38 e67f      and     $7f
3b3a f608      or      $08
3b3c 32305a    ld      ($5a30),a
3b3f 181c      jr      $3b5d            ; display loading

3b41 cdfc3b    call    $3bfc			;; delay and calc block size
3b44 cd903b    call    $3b90			;; read block
3b47 3a325b    ld      a,($5b32)		;; block number
3b4a ba        cp      d				;; same as block number read?
3b4b 2805      jr      z,$3b52          ; 

3b4d cd763c    call    $3c76			;; display "Block ?  xx"
3b50 18ef      jr      $3b41            ; restart

;;-------------------------------------------
;; valid block loaded
3b52 cd073c    call    $3c07			;; checksum data
3b55 be        cp      (hl)				;; matches stored checksum?
3b56 2805      jr      z,$3b5d          ;

3b58 cd763c    call    $3c76			;; display "Block ?  xx"
3b5b 18e4      jr      $3b41            ;; restart


;;-------------------------------------------
;; checksum matches
3b5d cd7b3b    call    $3b7b			;; copy loaded data to correct location
3b60 cd4e3c    call    $3c4e			;; display "Loading xx"

3b63 21355b    ld      hl,$5b35
3b66 7e        ld      a,(hl)
3b67 23        inc     hl
3b68 3d        dec     a
3b69 20fc      jr      nz,$3b67         ; (-$04)
3b6b 23        inc     hl
3b6c 23        inc     hl
3b6d 23        inc     hl
3b6e 23        inc     hl
3b6f 7e        ld      a,(hl)
3b70 2b        dec     hl
3b71 2b        dec     hl
3b72 2b        dec     hl
3b73 e607      and     $07
3b75 3c        inc     a
3b76 32465b    ld      ($5b46),a
3b79 14        inc     d
3b7a e9        jp      (hl)

;;-----------------------------------------------------------------------
;; copy loaded data to correct location

3b7b d5        push    de
3b7c e5        push    hl
3b7d ed5b335b  ld      de,($5b33)		;; destination for block
3b81 21325a    ld      hl,$5a32			;; address block has been loaded to
3b84 010001    ld      bc,$0100			;; length of block
3b87 edb0      ldir    
3b89 e1        pop     hl
3b8a d1        pop     de
3b8b fde1      pop     iy
3b8d fde5      push    iy
3b8f c9        ret     
;;--------------------------------------------------------

;; data structure:
;; 
;; offset	length			description

;; 0		256				data
;; 256		1				block id
;; 257		2				destination address
;; .. extra bytes unknown
;; 

;; Each block has the following composition:
;;
;; - the pilot/leader is composed of a byte stream
;; 
;; - there must be at least 5 pilot bytes
;;   for the loader to sync to the pilot
;;   
;;   additional pilot bytes are read but not required
;;
;; - following the pilot byte there is sync byte 1
;;
;; - following sync byte 1 there is sync byte 2
;;
;; - following sync byte 2 there is the data
;;  
;;   (additional bytes ARE read; the purpose of these is to be discovered)
;;
;; in this loader:
;; sync_byte2 = ($5a30)
;; pilot = sync_byte2
;; sync_byte1 = NOT sync_byte2

3b90 f3        di      
3b91 c5        push    bc
3b92 d5        push    de
3b93 e5        push    hl

3b94 3a305a    ld      a,($5a30) ;; sync byte 2
3b97 2f        cpl     
3b98 67        ld      h,a		;; sync byte 1

3b99 2f        cpl     
3b9a 6f        ld      l,a		;; sync byte 2

;; sync_byte_2 = NOT sync_byte_1

3b9b 57        ld      d,a		

3b9c cdd33b    call    $3bd3	;; read a byte
3b9f ba        cp      d		;; matches pilot/leader byte
3ba0 2805      jr      z,$3ba7          

3ba2 cdef3b    call    $3bef	;; wait for cassette data input to change state
3ba5 18f5      jr      $3b9c            ; (-$0b)

3ba7 1e04      ld      e,$04
3ba9 cdd33b    call    $3bd3	;; read a byte
3bac ba        cp      d
3bad 20ed      jr      nz,$3b9c         ; (-$13)
3baf 1d        dec     e
3bb0 20f7      jr      nz,$3ba9         ; (-$09)

;; keep looping while pilot byte is found
3bb2 cdd33b    call    $3bd3			;; read a byte
3bb5 ba        cp      d
3bb6 28fa      jr      z,$3bb2          ;; keep looping while pilot byte is read

;; found sync byte 1?
3bb8 bc        cp      h
3bb9 20e1      jr      nz,$3b9c         ;; no, try again

;; read sync byte 2
3bbb cdd33b    call    $3bd3			;; read a byte
3bbe bd        cp      l				;; sync byte 2?
3bbf 20db      jr      nz,$3b9c         ;; no try again

;; read data block
3bc1 21325a    ld      hl,$5a32

3bc4 cdd33b    call    $3bd3			;; read a byte
3bc7 77        ld      (hl),a			;; store byte
3bc8 23        inc     hl				;; increment pointer
3bc9 0b        dec     bc				;; decrement count
3bca 78        ld      a,b
3bcb b1        or      c
3bcc 20f6      jr      nz,$3bc4         ;; repeat for all bytes

3bce e1        pop     hl
3bcf d1        pop     de
3bd0 c1        pop     bc
3bd1 fb        ei      
3bd2 c9        ret     

;;------------------------------------------------------
;; read a byte
3bd3 c5        push    bc
3bd4 d5        push    de

3bd5 06f5      ld      b,$f5			;; PPI port B input 
										;; (includes cassette input data)

3bd7 1601      ld      d,$01

3bd9 1e00      ld      e,$00			;; reset duration count

3bdb ed48      in      c,(c)			;; get initial state

3bdd 1c        inc     e				;; increment duration
3bde ed78      in      a,(c)			;; get current state
3be0 a9        xor     c				;; any bit that has changed state will be 1
										;; any bit that has not changed state will be 0 

3be1 f2dd3b    jp      p,$3bdd			;; has bit 7 (cassette data input) changed?

3be4 3e3f      ld      a,$3f			;; bit timing constant
3be6 bb        cp      e
										;; no carry = greater than equal comparison = bit 0
										;; carry = less = bit 1

3be7 cb12      rl      d				;; shift bit into data
3be9 30ee      jr      nc,$3bd9         ;; found 

3beb 7a        ld      a,d
3bec d1        pop     de
3bed c1        pop     bc
3bee c9        ret     

;;-------------------------------------------------------------------
;; wait for cassette input to change state

3bef c5        push    bc
3bf0 06f5      ld      b,$f5			;; PPI port B input 
										;; (includes cassette input data)

3bf2 ed48      in      c,(c)			;; get initial state

3bf4 ed78      in      a,(c)			;; get current state
3bf6 a9        xor     c				;; if a bit has changed, it will be 1, if a bit hasn't changed
										;; it will be 0
3bf7 f2f43b    jp      p,$3bf4			;; has bit 7 (cassette data input) changed?


3bfa c1        pop     bc
3bfb c9        ret     

;;-------------------------------------------------------------------------
;; delay & calc block size
;; block has 256 bytes of data, a 1 byte checksum

3bfc 3a465b    ld      a,($5b46)
3bff 010801    ld      bc,$0108
3c02 03        inc     bc
3c03 3d        dec     a
3c04 20fc      jr      nz,$3c02         ; (-$04)
3c06 c9        ret     
;;-------------------------------------------------------------------------
;; checksum block data

3c07 d5        push    de
3c08 cdfc3b    call    $3bfc			;; delay and calc block size
3c0b 0b        dec     bc

3c0c 21325a    ld      hl,$5a32

3c0f ae        xor     (hl)
3c10 5f        ld      e,a
3c11 23        inc     hl
3c12 0b        dec     bc
3c13 78        ld      a,b
3c14 b1        or      c
3c15 7b        ld      a,e
3c16 20f7      jr      nz,$3c0f         ; (-$09)
3c18 d1        pop     de
3c19 c9        ret     

;;---------------------------------------------------
;; display current block number and increment block
3c1a 21325b    ld      hl,$5b32				;; block number
3c1d 7e        ld      a,(hl)
3c1e 34        inc     (hl)

;; display a number as hex (A = number)
3c1f f5        push    af
3c20 07        rlca    
3c21 07        rlca    
3c22 07        rlca    
3c23 07        rlca				
   
3c24 cd283c    call    $3c28
3c27 f1        pop     af

;; display hex digit
3c28 e60f      and     $0f			; isolate lower nibble
3c2a f630      or      $30			; convert to ASCII
3c2c fe3a      cp      $3a
3c2e 3802      jr      c,$3c32          ; (+$02)
3c30 c607      add     a,$07
3c32 cd5abb    call    $bb5a		; firmware function: txt output
3c35 c9        ret     

;;----------------------------------------------------


3c36 c5        push    bc
3c37 d5        push    de
3c38 57        ld      d,a
3c39 4f        ld      c,a
3c3a 47        ld      b,a
3c3b 10fe      djnz    $3c3b            ; (-$02)
3c3d 0d        dec     c
3c3e 20fa      jr      nz,$3c3a         ; (-$06)
3c40 15        dec     d
3c41 20f6      jr      nz,$3c39         ; (-$0a)
3c43 d1        pop     de
3c44 c1        pop     bc
3c45 c9        ret     

;;----------------------------------------------------
;; start cassette motor

3c46 c5        push    bc
3c47 0110f6    ld      bc,$f610
3c4a ed49      out     (c),c
3c4c c1        pop     bc
3c4d c9        ret     

;;-----------------------------------------------------
;; display "Loading xx"

3c4e e5        push    hl
3c4f d5        push    de

;; select text window 2
3c50 3e02      ld      a,$02
3c52 cdb4bb    call    $bbb4			;; firmware function: txt str select

;; clear text window 2
3c55 cd6cbb    call    $bb6c			;; firmware function: txt clear window

;; select text window 1
3c58 3e01      ld      a,$01
3c5a cdb4bb    call    $bbb4			;; firmware function: txt str select

;; select pen 1 for displaying text
3c5d 3e01      ld      a,$01
3c5f cd90bb    call    $bb90			;; firmware function: txt set pen

3c62 cdce3c    call    $3cce			;; display string following this
										;; function call
defb &0d,"Loading   ",0

3c71 d1        pop     de
3c72 e1        pop     hl
3c73 c31a3c    jp      $3c1a			;; display current block number and increment

;;-----------------------------------------------------
;; display "Block ?  xx"

3c76 e5        push    hl
3c77 5f        ld      e,a
3c78 d5        push    de

;; select text window 1
3c79 3e01      ld      a,$01
3c7b cdb4bb    call    $bbb4			;; firmware function: txt str select

;; set pen 3 for displaying text
3c7e 3e03      ld      a,$03
3c80 cd90bb    call    $bb90			;; firmware function: txt set pen

3c83 cdce3c    call    $3cce			;; display string following this
										;; function call
defb &0d,"Block ?  ",0

3c92 cd1a3c    call    $3c1a			;; display current block number and increment

;; select text window 2
3c95 3e02      ld      a,$02
3c97 cdb4bb    call    $bbb4			;; firmware function: txt str select

;; select pen 3 for displaying text
3c9a 3e03      ld      a,$03
3c9c cd90bb    call    $bb90			;; firmware function: txt set pen

3c9f d1        pop     de
3ca0 7b        ld      a,e
3ca1 ba        cp      d
3ca2 3016      jr      nc,$3cba         ; (+$16)
3ca4 e1        pop     hl


;;-------------------------------------------------------------
;; display "Searching xx"
3ca5 e5        push    hl
3ca6 cdce3c    call    $3cce			;; display string following this
										;; function call
defb &0d,"Searching ",0

3cb5 7a        ld      a,d
3cb6 e1        pop     hl
3cb7 c31f3c    jp      $3c1f			;; display hex number in register A


;;-------------------------------------------------------------
;; display "Rewind to xx"

3cba cdce3c    call    $3cce			;; display string following this
										;; function call
defb &0d,"Rewind to ",0

3cc9 7a        ld      a,d
3cca e1        pop     hl
3ccb c31f3c    jp      $3c1f

;;-----------------------------------------------------------------------
;; display null terminated string
;; the string location is on the stack

3cce e1        pop     hl
3ccf 7e        ld      a,(hl)			;; read ASCII character
3cd0 23        inc     hl				;; increment pointer
3cd1 fe00      cp      $00				;; end of string marker?
3cd3 c45abb    call    nz,$bb5a			;; firmware function: txt output
3cd6 20f7      jr      nz,$3ccf         ;;
3cd8 e5        push    hl
3cd9 c9        ret     

;;---------------------------------------------------------------
;; end of dissassembly