080000 12 bytes of boot clock "stuff"

; Allocate $1600 bytes of CHIP RAM
08000C 48E7 0042              movem.l a1/a6,-(sp)
080010 7016                   moveq   #$16,d0
080012 E148                   lsl.w   #8,d0
080014 7202                   moveq   #$02,d1
080016 2400                   move.l  d0,d2
080018 4EAE FF3A              jsr     -$C6(a6)
08001C 2440                   movea.l d0,a2
08001E 200A                   move.l  a2,d0
080020 6608                   bne.b   $08002A
080022 4CDF 4200              movem.l (sp)+,a1/a6
080026 70FF                   moveq   #-$01,d0
080028 4E75                   rts
; Read track 0 i.e. sectors 0-10 
; Contains also the boot block in sectors 0-1
08002A 2257                   movea.l (sp),a1
08002C 97CB                   suba.l  a3,a3
08002E 337C 0002 001C         move.w  #$0002,$1C(a1)
080034 48E9 0C04 0024         movem.l d2/a2-a3,$24(a1)	;
08003A 4EAE FE38              jsr     -$1C8(a6)		; DoIO()
; Jump to the start of the loader code
08003E 4EEA 0054              jmp     $54(a2)
; "graphics.library",0
080042 6772                   beq.b   $0800B6
080044 6170                   bsr.b   $0800B6
080046 6869                   bvc.b   $0800B1
080048 6373                   bls.b   $0800BD
08004A 2E6C 6962              movea.l $6962(a4),sp
08004E 7261                   moveq   #$61,d1
080050 7279                   moveq   #$79,d1
080052 0000                   dc.w    $00
; Start of the loader code
; Open the graphics.library
080054 43FA FFEC              lea     $080042(pc),a1
080058 4EAE FE68              jsr     -$198(a6)		; OldOpenLibrary()
08005C 4A80                   tst.l   d0
08005E 67C2                   beq.b   $080022
; Traverse Execbase memlist - find largest RAM block beyond 512K CHIP RAM
; Returns largest memory block in:
;   D4 = memory start
;   D5 = memory size
080060 2A40                   movea.l d0,a5
080062 7800                   moveq   #$00,d4
080064 7A00                   moveq   #$00,d5
080066 41EE 0142              lea     $142(a6),a0
08006A 2268 0008              movea.l $08(a0),a1
08006E 2050                   movea.l (a0),a0
080070 3428 000E              move.w  $0E(a0),d2
080074 4CE8 0003 0014         movem.l $14(a0),d0-d1
; Check memory type
08007A 0802 0001              btst    #$01,d2
08007E 6704                   beq.b   $080084
; If the memory is CHIP then check what we got beyond first 512K
080080 7008                   moveq   #$08,d0
080082 4840                   swap    d0
080084 4240                   clr.w   d0
080086 9280                   sub.l   d0,d1
080088 B285                   cmp.l   d5,d1
08008A 6304                   bls.b   $080090
08008C 2800                   move.l  d0,d4
08008E 2A01                   move.l  d1,d5
080090 B3C8                   cmpa.l  a0,a1
080092 6704                   beq.b   $080098
080094 2050                   movea.l (a0),a0
080096 60D8                   bra.b   $080070
080098 CB4E                   exg     a6,a5
; Take over the screen using the familiar
;  LoadView(NULL)
;  WaitTOF()
;  WaitTOF()
08009A 93C9                   suba.l  a1,a1
08009C 4EAE FF22              jsr     -$DE(a6)
0800A0 4EAE FEF2              jsr     -$10E(a6)
0800A4 4EAE FEF2              jsr     -$10E(a6)
0800A8 49F9 00DFF002          lea     $DFF002,a4
; Make sure AGA stuff is "off" and we are using ECS
0800AE 7000                   moveq   #$00,d0
0800B0 3940 01FA              move.w  d0,$1FA(a4)
0800B4 397C 0C00 0104         move.w  #$0C00,$104(a4)
0800BA 397C 0011 010A         move.w  #$0011,$10A(a4)
; Force PAL - works on ECS
0800C0 397C 0020 01DA         move.w  #$0020,$1DA(a4)
0800C6 3940 017E              move.w  d0,$17E(a4)
0800CA CB4E                   exg     a6,a5
; Get Attn flags to check the CPU
0800CC 342E 0128              move.w  $128(a6),d2
; Switch to SuperVisor mode using SuperVisor()
0800D0 4BFA 0006              lea     $0800D8(pc),a5
0800D4 4EEE FFE2              jmp     -$1E(a6)
; System off
0800D8 397C 7FFF 0098         move.w  #$7FFF,$98(a4)
0800DE 397C 7FFF 0094         move.w  #$7FFF,$94(a4)
0800E4 707F                   moveq   #$7F,d0
0800E6 13C0 00BFDD00          move.b  d0,$BFDD00
0800EC 13C0 00BFED01          move.b  d0,$BFED01
0800F2 0802 0000              btst    #$00,d2
0800F6 6706                   beq.b   $0800FE
; If we got better than 68000 set VBR to $00000000
0800F8 7000                   moveq   #$00,d0
0800FA 4E7B                   ???
0800FC 0801 2004              btst    #$2004,d1
; D4=memory start, D5=memory size
; Test if we got better than 512K CHIP setup
0800FE 2004                   move.l  d4,d0
080100 6700 0066              beq.w   $080168
; $8C = start of extra mem
; $90 = size of extra mem
080104 2045                   movea.l d5,a0
080106 48F8 0101 008C         movem.l d0/a0,$8C
; SSP to top of extra memory
08010C D1C0                   adda.l  d0,a0
08010E 2E48                   movea.l a0,sp
; USP 1K below SSP
080110 41E8 FC00              lea     -$400(a0),a0
080114 4E60                   move    a0,usp
; Back to user mode
080116 46FC 0000              move    #$0000,sr
08011A 41F8 00C0              lea     $C0,a0
08011E 2648                   movea.l a0,a3
; Move loader coder to $C0
080120 43FA 0CD4              lea     $080DF6(pc),a1
080124 303C 038B              move.w  #$038B,d0
080128 30D9                   move.w  (a1)+,(a0)+
08012A 51C8 FFFC              dbf     d0,$080128
08012E 2448                   movea.l a0,a2
080130 49EA 00A8              lea     $A8(a2),a4
080134 41F9 0007B460          lea     $07B460,a0
08013A 43F9 0007E760          lea     $07E760,a1
; A0 = $7B460 -> MFM buffer ($3300 bytes)
; A1 = $7E760 -> last track buffer ($18a0 bytes)
: A2 = $7d8   -> file table
; A3 = $C0    -> loader code
; A4 = $880   -> loader code end i.e. first "free" memory address
080140 48F8 1800 0084         movem.l a3-a4,$84
; $84 = loader address
; $88 = file table
;
; Call $00(loader) -> initialize the loader
080146 4E93                   jsr     (a3)			; 
; A3 = loader code address..
; Load file table
;  D0 = drive number (DF0 = 0)
;  D1 = bytes to read
;  A1 = destination memory address
;  A2 = location in disk (bytes addressed) 
080148 7000                   moveq   #$00,d0
08014A 224A                   movea.l a2,a1
08014C 223C 000000A8          move.l  #$0000A8,d1
080152 347C 18A0              movea.w #$18A0,a2
; This calls $c8 i.e. $80DFE in this disassembly
080156 4EAB 0008              jsr     $08(a3)
;
; Load game code 
; D0 = file index in the file table
; A1 = destination memory address
08015A 2EBC 00050000          move.l  #$050000,(sp)
080160 2257                   movea.l (sp),a1
080162 7000                   moveq   #$00,d0
; This jumps to $cc i.e. $80E02 in this disassembly
; Once the loader completes the execution returns to $50000
; where the newly loaded game code is.
080164 4EEB 000C              jmp     $0C(a3)		;
; We end up here if we have only 512K CHIP RAM setup.
080168 41FA 00FC              lea     $080266(pc),a0
08016C 203C 000500D4          move.l  #$0500D4,d0
080172 7A03                   moveq   #$03,d5
080174 3140 0004              move.w  d0,$04(a0)
080178 4840                   swap    d0
08017A 3080                   move.w  d0,(a0)
08017C 4840                   swap    d0
08017E 0680 00000028          addi.l  #$000028,d0
080184 5088                   addq.l  #8,a0
080186 51CD FFEC              dbf     d5,$080174
08018A 41FA 003C              lea     $0801C8(pc),a0
08018E 43F9 00050000          lea     $050000,a1
080194 22D8                   move.l  (a0)+,(a1)+
080196 45FA 0104              lea     $08029C(pc),a2
08019A B1CA                   cmpa.l  a2,a0
08019C 6F00 FFF6              ble.w   $080194
0801A0 207C 000500D4          movea.l #$0500D4,a0
0801A6 43FA 00F4              lea     $08029C(pc),a1
; Decrunch some graphics..
0801AA 6100 0B18              bsr.w   $080CC4
; And display it "you need 1Meg" or so..
0801AE 49F9 00DFF002          lea     $DFF002,a4
0801B4 397C 8380 0094         move.w  #$8380,$94(a4)
0801BA 297C 00050000 007E     move.l  #$050000,$7E(a4)
0801C2 50EC 0086              st      $86(a4)
0801C6 60FE                   bra.b   $0801C6
.
.
.
; Vanilla S404 decruncher - ain't it beautiful ;)
080CC4 0C99 53343034          cmpi.l  #$53343034,(a1)+
080CCA 6704                   beq.b   $080CD0
080CCC 7000                   moveq   #$00,d0
080CCE 4E75                   rts
080CD0 5849                   addq.w  #4,a1
080CD2 2A48                   movea.l a0,a5
080CD4 D1D9                   adda.l  (a1)+,a0
.
.
.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Disk loader code
; At the start we got a jump table for various functions
080DF6 6000 0016              bra.w   $080E0E
080DFA 6000 0050              bra.w   $080E4C
080DFE 6000 031E              bra.w   $08111E
080E02 6000 001E              bra.w   $080E22
080E06 6000 0038              bra.w   $080E40 
080E0A 6000 05C0              bra.w   $0813CC
;	-> $00 Initialize loader
;	-> $04 Load crunched data
;	-> $08 Load any data from disk
;	-> $0c Load from file table
;	-> $10
;	-> $14 Save one track in custom format
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Initialize loader:
;  A0 = MFM buffer address ($3300 bytes)
;  A1 = Single track buffer address ($18a0 bytes)
;  A2 = File table address
080E0E 2F0B                   move.l  a3,-(sp)
080E10 47FA 06E8              lea     $0814FA(pc),a3 
080E14 48D3 0300              movem.l a0-a1,(a3)
080E18 47FA 06F0              lea     $08150A(pc),a3
080E1C 268A                   move.l  a2,(a3)
080E1E 265F                   movea.l (sp)+,a3
080E20 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Load from a file table:
;  D0 = Index to the table
;  A1 = Destination memory address
080E22 2F08                   move.l  a0,-(sp)
080E24 E748                   lsl.w   #3,d0
080E26 207A 06E2              movea.l $08150A(pc),a0
080E2A D0C0                   adda.w  d0,a0
080E2C 7000                   moveq   #$00,d0
080E2E 2458                   movea.l (a0)+,a2
080E30 2218                   move.l  (a0)+,d1
; If file length is negative -> crunched file
080E32 6A06                   bpl.b   $080E3A 
080E34 4481                   neg.l   d1
; Load a crunched file
080E36 6114                   bsr.b   $080E4C
080E38 6002                   bra.b   $080E3C
; Load a normal file
080E3A 61C2                   bsr.b   $080DFE
080E3C 205F                   movea.l (sp)+,a0
080E3E 4E75                   rts
; Invalidate ??
080E40 2F08                   move.l  a0,-(sp)
080E42 41FA 0686              lea     $0814CA(pc),a0
080E46 50D0                   st      (a0)
080E48 205F                   movea.l (sp)+,a0
080E4A 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Load a crunched file from a disk:
;  D0 = Drive number
;  D1 = Bytes to read
;  A1 = Destination memory address
;  A2 = Byte pointer to the disk
;
; This loader is capable of interleaving disk DMA reads and decrunching
; the previously read track using two buffers: one for MFM data and one
; for holding crunched data. The interleaving avoids unnecessary DMA wait
; which speeds up loading and no need to read entire crunched file at once.
080E4C 48E7 7FFE              movem.l d1-d7/a0-a6,-(sp)
080E50 4DF9 00DFF024          lea     $DFF024,a6
080E56 4BF9 00BFD100          lea     $BFD100,a5
080E5C 49ED 0F01              lea     $F01(a5),a4
080E60 47FA 0666              lea     $0814C8(pc),a3
080E64 3A3C 2909              move.w  #$2909,d5		; Sync = $2909
; Decruncher start address - reset for each new file to load
080E68 41FA 0384              lea     $0811EE(pc),a0
080E6C 2748 002E              move.l  a0,$2E(a3)
080E70 3680                   move.w  d0,(a3
; Number of retries set to 4
080E72 177C 0004 0004         move.b  #$04,$04(a3)
; Select drive and motor on
080E78 6100 00B4              bsr.w   $080F2E
080E7C 200A                   move.l  a2,d0
080E7E 80FC 18A0              divu    #$18A0,d0
080E82 2800                   move.l  d0,d4
080E84 4844                   swap    d4
; Seek to a correct track
;  D0 = Track number
;  D4 = Offset within the track
080E86 6100 015A              bsr.w   $080FE2
080E8A 1680                   move.b  d0,(a3)
080E8C 6600 0088              bne.w   $080F16
080E90 2E3C 55555555          move.l  #$55555555,d7
; Prepare to read a track
080E96 6100 01E4              bsr.w   $08107C
; Start disk DMA
; This also sets A0 to MFM buffer address.
080E9A 6100 026E              bsr.w   $08110A
; Wait for disk DMA to finish
080E9E 6100 01EA              bsr.w   $08108A
080EA2 1680                   move.b  d0,(a3)
080EA4 6670                   bne.b   $080F16
; Search for SYNC words.. up to 4 of those on a track 
080EA6 BA58                   cmp.w   (a0)+,d5
080EA8 660A                   bne.b   $080EB4
080EAA BA58                   cmp.w   (a0)+,d5
080EAC 6606                   bne.b   $080EB4
080EAE BA58                   cmp.w   (a0)+,d5
080EB0 6602                   bne.b   $080EB4
080EB2 5448                   addq.w  #2,a0
080EB4 5548                   subq.w  #2,a0
080EB6 4CD8 0041              movem.l (a0)+,d0/d6
; Get track header information
;  D0 =
;  D6 = "checksum"
080EBA CC87                   and.l   d7,d6
080EBC 6100 01EC              bsr.w   $0810AA
; Check for errors..
080EC0 BC80                   cmp.l   d0,d6
080EC2 6626                   bne.b   $080EEA
; More data to read from disk?
080EC4 307C 18A0              movea.w #$18A0,a0
080EC8 90C4                   suba.w  d4,a0
080ECA 9288                   sub.l   a0,d1
080ECC 6F04                   ble.b   $080ED2
;  Yes, advance to next disk side or track, and start disk DMA
080ECE 6100 022C              bsr.w   $0810FC
080ED2 48E7 7F8E              movem.l d1-d7/a0/a4-a6,-(sp)
; Decrunch a single track buffer to destination memory
080ED6 6100 04DE              bsr.w   $0813B6
080EDA 4CDF 71FE              movem.l (sp)+,d1-d7/a0/a4-a6
080EDE 1680                   move.b  d0,(a3)
080EE0 6634                   bne.b   $080F16
080EE2 177C 0004 0004         move.b  #$04,$04(a3)
080EE8 6020                   bra.b   $080F0A
; There was error. Retry max 4 times.
080EEA 0C2B 0001 0004         cmpi.b  #$01,$04(a3)
080EF0 660C                   bne.b   $080EFE
; On the last try seek to track 0 and retry once more.
080EF2 50EB 0002              st      $02(a3)
080EF6 102B 0003              move.b  $03(a3),d0
080EFA 6100 00E6              bsr.w   $080FE2
080EFE 532B 0004              subq.b  #1,$04(a3)
080F02 6A96                   bpl.b   $080E9A
; Track loading error.
080F04 16BC 0005              move.b  #$05,(a3)
080F08 72FF                   moveq   #-$01,d1
; Are we done? if D1 > 0 loop back to disk DMA wait + track decrunch..
080F0A 177C 0004 0004         move.b  #$04,$04(a3)
080F10 7800                   moveq   #$00,d4
080F12 4A81                   tst.l   d1
080F14 6E88                   bgt.b   $080E9E
; Disk DMA etc off
080F16 6100 0164              bsr.w   $08107C
; Drive motor off
080F1A 102B 0001              move.b  $01(a3),d0
080F1E 6154                   bsr.b   $080F74
080F20 1013                   move.b  (a3),d0
080F22 6704                   beq.b   $080F28
; If there was a loading error set track position to unknown
080F24 50EB 0002              st      $02(a3)
080F28 4CDF 7FFE              movem.l (sp)+,d1-d7/a0-a6
080F2C 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Setup disk drive, select a drive and motor on
;  D0 = drive number 
080F2E 3D7C 0002 0076         move.w  #$0002,$76(a6)
080F34 3D7C 8250 0072         move.w  #$8250,$72(a6)
080F3A 3D7C 2909 005A         move.w  #$2909,$5A(a6)
080F40 3D7C 7F00 007A         move.w  #$7F00,$7A(a6)
080F46 3D7C 8500 007A         move.w  #$8500,$7A(a6)
080F4C 50ED 0200              st      $200(a5)
080F50 2F01                   move.l  d1,-(sp)
; Select disk drive
080F52 7208                   moveq   #$08,d1
080F54 E129                   lsl.b   d0,d1
080F56 707F                   moveq   #$7F,d0
080F58 4601                   not.b   d1
080F5A C200                   and.b   d0,d1
080F5C 1A80                   move.b  d0,(a5)
080F5E 1A81                   move.b  d1,(a5)
; Check for DSKRDY or just wait ~500ms
080F60 0814 0005              btst    #$05,(a4)
080F64 6708                   beq.b   $080F6E
080F66 6100 00DC              bsr.w   $081044
080F6A 51C8 FFF4              dbf     d0,$080F60
080F6E 221F                   move.l  (sp)+,d1
080F70 7000                   moveq   #$00,d0
080F72 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Drive motor off
;  D0 = drive number
080F74 2F01                   move.l  d1,-(sp)
080F76 7208                   moveq   #$08,d1
080F78 E129                   lsl.b   d0,d1
080F7A 4601                   not.b   d1
080F7C 50D5                   st      (a5)
080F7E 1A81                   move.b  d1,(a5)
080F80 50D5                   st      (a5)
080F82 221F                   move.l  (sp)+,d1
080F84 7000                   moveq   #$00,d0
080F86 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Advance to next disk side or track
080F88 7000                   moveq   #$00,d0
; Do we need to step of just change disk side?
080F8A 012B 0003              btst    d0,$03(a3)
080F8E 6712                   beq.b   $080FA2
; Step drive head
080F90 0195                   bclr    d0,(a5)
080F92 01D5                   bset    d0,(a5)
; Check DSKCHANGE for no disk in drive
080F94 0814 0002              btst    #$02,(a4)
080F98 6744                   beq.b   $080FDE
; Wait a bit 
080F9A 6100 00A8              bsr.w   $081044
; Step counters..
080F9E 522B 0002              addq.b  #1,$02(a3)
080FA2 522B 0003              addq.b  #1,$03(a3)
; Change disk side
080FA6 0855 0002              bchg    #$02,(a5)
080FAA 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Seek to track 0
; Wait a bit..
080FAC 6100 00AE              bsr.w   $08105C
080FB0 7000                   moveq   #$00,d0
; Set direction towards track 0
080FB2 08D5 0001              bset    #$01,(a5)
; Check DSKTRACK0 - are we on track 0 ?
080FB6 0814 0004              btst    #$04,(a4)
080FBA 6710                   beq.b   $080FCC
; Nope.. step
080FBC 0195                   bclr    d0,(a5)
080FBE 01D5                   bset    d0,(a5)
; Wait
080FC0 6100 0082              bsr.w   $081044
; Check DSKCHANGE whether disk is in drive. This handles the
; case when the drive never sets the DKSRDY bit.
080FC4 0814 0002              btst    #$02,(a4)
080FC8 6714                   beq.b   $080FDE
080FCA 60EA                   bra.b   $080FB6
; Wait a bit
080FCC 6100 008E              bsr.w   $08105C
; Select disk side for "track 0 side 0", direction towards center
080FD0 0895 0001              bclr    #$01,(a5)
080FD4 08D5 0002              bset    #$02,(a5)
080FD8 426B 0002              clr.w   $02(a3)
080FDC 4E75                   rts
; Error no disk in drive
080FDE 7002                   moveq   #$02,d0
080FE0 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Seek to track
;  D0 = Track number
; Test if the loader knows on what track we are
080FE2 4A2B 0002              tst.b   $02(a3)
080FE6 6A0E                   bpl.b   $080FF6
080FE8 2F00                   move.l  d0,-(sp)
; Seek to track 0
080FEA 61C0                   bsr.b   $080FAC
080FEC 4A80                   tst.l   d0
080FEE 6704                   beq.b   $080FF4
080FF0 584F                   addq.w  #4,sp
080FF2 4E75                   rts
;
080FF4 201F                   move.l  (sp)+,d0
080FF6 1740 0003              move.b  d0,$03(a3)
; Select disk side
080FFA E208                   lsr.b   #1,d0
080FFC 6506                   bcs.b   $081004
080FFE 08D5 0002              bset    #$02,(a5)
081002 6004                   bra.b   $081008
081004 0895 0002              bclr    #$02,(a5)
; How many tracks to step and direction
081008 902B 0002              sub.b   $02(a3),d0
08100C 6728                   beq.b   $081036
08100E 6E06                   bgt.b   $081016
081010 08D5 0001              bset    #$01,(a5)
081014 6004                   bra.b   $08101A
081016 0895 0001              bclr    #$01,(a5)
08101A D12B 0002              add.b   d0,$02(a3)
08101E 4A00                   tst.b   d0
081020 6A02                   bpl.b   $081024
081022 4400                   neg.b   d0
081024 4880                   ext.w   d0
081026 6008                   bra.b   $081030
; Move the head
081028 0895 0000              bclr    #$00,(a5)
08102C 08D5 0000              bset    #$00,(a5)
081030 6112                   bsr.b   $081044
081032 51C8 FFF4              dbf     d0,$081028
; Check DSKCHANGE i.e. whether the disk is in the drive
081036 0814 0002              btst    #$02,(a4)
08103A 67A2                   beq.b   $080FDE
08103C 0895 0001              bclr    #$01,(a5)
081040 7000                   moveq   #$00,d0
081042 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Timer based wait - short
081044 197C 0002 0D00         move.b  #$02,$D00(a4)
08104A 197C 0008 0F00         move.b  #$08,$F00(a4)
081050 50EC 0600              st      $600(a4)
081054 197C 000A 0700         move.b  #$0A,$700(a4)
08105A 6016                   bra.b   $081072
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Timer based wait - long
08105C 197C 0002 0D00         move.b  #$02,$D00(a4)
081062 197C 0008 0F00         move.b  #$08,$F00(a4)
081068 50EC 0600              st      $600(a4)
08106C 197C 0029 0700         move.b  #$29,$700(a4)
081072 082C 0001 0D00         btst    #$01,$D00(a4)
081078 67F8                   beq.b   $081072
08107A 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Prepare to read a track or finish reading
; Clear disk DMA irq request, ..
08107C 3D7C 0002 0078         move.w  #$0002,$78(a6)
081082 3CBC 4000              move.w  #$4000,(a6)
081086 7000                   moveq   #$00,d0
081088 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Wait for disk DMA 
08108A 303C 00C8              move.w  #$00C8,d0
08108E 082E 0001 FFFB         btst    #$01,-$05(a6)
081094 66E6                   bne.b   $08107C
081096 0814 0002              btst    #$02,(a4)
08109A 6700 FF42              beq.w   $080FDE
08109E 61A4                   bsr.b   $081044
0810A0 51C8 FFEC              dbf     d0,$08108E
0810A4 61D6                   bsr.b   $08107C
0810A6 7006                   moveq   #$06,d0
0810A8 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; MFM decode one track to track buffer
;  A0 = MFM buffer address
; Returns D0 as "checksum"
0810AA 48E7 7EE0              movem.l d1-d6/a0-a2,-(sp)
0810AE 246B 0036              movea.l $36(a3),a2
0810B2 43E8 18A0              lea     $18A0(a0),a1
0810B6 3C3C 0313              move.w  #$0313,d6
0810BA 7000                   moveq   #$00,d0
0810BC 2418                   move.l  (a0)+,d2
0810BE B580                   eor.l   d2,d0
0810C0 2618                   move.l  (a0)+,d3
0810C2 B780                   eor.l   d3,d0
0810C4 2819                   move.l  (a1)+,d4
0810C6 B980                   eor.l   d4,d0
0810C8 2A19                   move.l  (a1)+,d5
0810CA BB80                   eor.l   d5,d0
0810CC C487                   and.l   d7,d2
0810CE C687                   and.l   d7,d3
0810D0 C887                   and.l   d7,d4
0810D2 CA87                   and.l   d7,d5
0810D4 D482                   add.l   d2,d2
0810D6 D683                   add.l   d3,d3
0810D8 8484                   or.l    d4,d2
0810DA 24C2                   move.l  d2,(a2)+
0810DC 8685                   or.l    d5,d3
0810DE 24C3                   move.l  d3,(a2)+
0810E0 51CE FFDA              dbf     d6,$0810BC
0810E4 C087                   and.l   d7,d0
0810E6 4CDF 077E              movem.l (sp)+,d1-d6/a0-a2
0810EA 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Blitter wait
0810EC 082E 0006 FFDE         btst    #$06,-$22(a6)
0810F2 082E 0006 FFDE         btst    #$06,-$22(a6)
0810F8 66F8                   bne.b   $0810F2
0810FA 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Advance to next side or track and start disk DMA
0810FC 6100 FE8A              bsr.w   $080F88
081100 1680                   move.b  d0,(a3)
081102 6706                   beq.b   $08110A
081104 584F                   addq.w  #4,sp
081106 6000 FE0E              bra.w   $080F16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Start disk DMA 
; Read a track to MFM buffer
; Returns MFM buffer address in A0
08110A 206B 0032              movea.l $32(a3),a0
08110E 2D48 FFFC              move.l  a0,-$04(a6)
081112 3CBC 9980              move.w  #$9980,(a6)
081116 3CBC 9980              move.w  #$9980,(a6)
08111A 7000                   moveq   #$00,d0
08111C 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Load "raw" data from disk
;  D0 = drive number
;  D1 = bytes to read - must be modulo 4 
;  A1 = destination memory address - must be modulo 4
;  A2 = position in the disk
08111E 48E7 7FFE              movem.l d1-d7/a0-a6,-(sp)
081122 4DF9 00DFF024          lea     $DFF024,a6
081128 4BF9 00BFD100          lea     $BFD100,a5
08112E 49ED 0F01              lea     $F01(a5),a4
081132 47FA 0394              lea     $0814C8(pc),a3
081136 363C 2909              move.w  #$2909,d3
08113A 3680                   move.w  d0,(a3)
; Select drive, motor on..
08113C 6100 FDF0              bsr.w   $080F2E
081140 200A                   move.l  a2,d0
081142 80FC 18A0              divu    #$18A0,d0
081146 2800                   move.l  d0,d4
081148 4844                   swap    d4
; Seek to track and select correct disk side
08114A 6100 FE96              bsr.w   $080FE2
08114E 1680                   move.b  d0,(a3)
081150 6600 FDC4              bne.w   $080F16
081154 2E3C 55555555          move.l  #$55555555,d7
; Prepare to read 
08115A 6100 FF20              bsr.w   $08107C
08115E 600A                   bra.b   $08116A
; Track reading loops here
081160 6100 FE26              bsr.w   $080F88
081164 1680                   move.b  d0,(a3)
081166 6600 FDAE              bne.w   $080F16
08116A 177C 0004 0004         move.b  #$04,$04(a3)
081170 48EB 0202 003A         movem.l d1/a1,$3A(a3)
; Start disk DMA to read
; Sets A0 to MFM buffer address
081176 6192                   bsr.b   $08110A
; Wait for disk DMA to finish
081178 6100 FF10              bsr.w   $08108A
08117C 1680                   move.b  d0,(a3)
08117E 663C                   bne.b   $0811BC
; Search for sync words
081180 B658                   cmp.w   (a0)+,d3
081182 660A                   bne.b   $08118E
081184 B658                   cmp.w   (a0)+,d3
081186 6606                   bne.b   $08118E
081188 B658                   cmp.w   (a0)+,d3
08118A 6602                   bne.b   $08118E
08118C 5448                   addq.w  #2,a0
08118E 5548                   subq.w  #2,a0
; Get track "checksum"
081190 4CD8 0041              movem.l (a0)+,d0/d6
081194 CC87                   and.l   d7,d6
; Decode MFM buffer to track buffer
081196 6100 FF12              bsr.w   $0810AA
08119A BC80                   cmp.l   d0,d6
08119C 661E                   bne.b   $0811BC
; Move data from track buffer to destination memory
08119E 206B 0036              movea.l $36(a3),a0
0811A2 2448                   movea.l a0,a2
0811A4 D4C4                   adda.w  d4,a2
0811A6 3A3C 0627              move.w  #$0627,d5
0811AA 2418                   move.l  (a0)+,d2
; Check if we need to skip data from the beginning of the
; track i.e. file starts in a middle of the track
0811AC B1CA                   cmpa.l  a2,a0
0811AE 6306                   bls.b   $0811B6
; There's a potential bug here. If the data first in one track and
; its size is not modulo 4 then 1 to 3 last bytes of the file are
; not transferred to the destination memory.
0811B0 5981                   subq.l  #4,d1
0811B2 6B02                   bmi.b   $0811B6
0811B4 22C2                   move.l  d2,(a1)+
0811B6 51CD FFF2              dbf     d5,$0811AA
0811BA 6026                   bra.b   $0811E2
; In a case of read error retry max 4 times.
; On the last try first seek to track 0.
0811BC 0C2B 0001 0004         cmpi.b  #$01,$04(a3)
0811C2 660C                   bne.b   $0811D0
0811C4 50EB 0002              st      $02(a3)
0811C8 102B 0003              move.b  $03(a3),d0
0811CC 6100 FE14              bsr.w   $080FE2
0811D0 4CEB 0202 003A         movem.l $3A(a3),d1/a1
0811D6 532B 0004              subq.b  #1,$04(a3)
0811DA 6A94                   bpl.b   $081170
0811DC 16BC 0005              move.b  #$05,(a3)
0811E0 72FF                   moveq   #-$01,d1
0811E2 7800                   moveq   #$00,d4
; More data to read?
0811E4 4A81                   tst.l   d1
0811E6 6E00 FF78              bgt.w   $081160
; Done - disk DMA off etc
0811EA 6000 FD2A              bra.w   $080F16
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Decrunch a crunched file from a disk
;  A0=Crunched data 
;  A3=variables
;  A6=destination
;
; This is the "start" of the decruncher.. It is a modified version
; of StoneCracker 4.10.3 which is made to decrunch one track worth
; data in one run. The data is also mirrored in the disk so that it
; can be read in sequentially.. The decruncher exits when it runs
; out of data and stores its current "context" so next time we can
; return to exactly same place and continue decrunching the file.
0811EE 2C6B 0036              movea.l $36(a3),a6
0811F2 4DEE 18A0              lea     $18A0(a6),a6
0811F6 2849                   movea.l a1,a4
0811F8 0C98 53343034          cmpi.l  #$53343034,(a0)+
0811FE 6704                   beq.b   $081204
081200 70FF                   moveq   #-$01,d0
081202 4E75                   rts
081204 BDC8                   cmpa.l  a0,a6
081206 6602                   bne.b   $08120A
081208 4E95                   jsr     (a5)
08120A 5848                   addq.w  #4,a0
08120C BDC8                   cmpa.l  a0,a6
.
.
.
0813A6 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Update decruncher position where we left off..
0813A8 275F 002E              move.l  (sp)+,$2E(a3)
0813AC 48EB 50FF 0006         movem.l d0-d7/a4/a6,$06(a3)
0813B2 7000                   moveq   #$00,d0
0813B4 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Restart decruncher from where we left off last time
0813B6 2F2B 002E              move.l  $2E(a3),-(sp)
0813BA 206B 0036              movea.l $36(a3),a0
0813BE D0C4                   adda.w  d4,a0
0813C0 4CEB 50FF 0006         movem.l $06(a3),d0-d7/a4/a6
0813C6 4BFA FFE0              lea     $0813A8(pc),a5
0813CA 4E75                   rts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Save track using Smarty's track format e.g. for hi-score
;  D0 = Track number
;  D1 = Drive number (DF0 = 0)
;  A0 = Address to data to save
;
0813CC 48E7 7FFE              movem.l d1-d7/a0-a6,-(sp)
0813D0 2E00                   move.l  d0,d7
0813D2 2C01                   move.l  d1,d6
0813D4 4DF9 00DFF024          lea     $DFF024,a6
0813DA 4BF9 00BFD100          lea     $BFD100,a5
0813E0 49ED 0F01              lea     $F01(a5),a4
0813E4 47FA 00E2              lea     $0814C8(pc),a3
; Get MFM buffer
0813E8 226B 0032              movea.l $32(a3),a1
0813EC 243C 55555555          move.l  #$55555555,d2
0813F2 2602                   move.l  d2,d3
0813F4 D683                   add.l   d3,d3
; Fill some track gap
0813F6 786A                   moveq   #$6A,d4
0813F8 22C3                   move.l  d3,(a1)+
0813FA 51CC FFFC              dbf     d4,$0813F8
; Our four sync words
0813FE 22FC 29092909          move.l  #$29092909,(a1)+
081404 22FC 29092909          move.l  #$29092909,(a1)+
; Reserve 8 bytes space for "checksum"
08140A 2F09                   move.l  a1,-(sp)
08140C 5049                   addq.w  #8,a1
08140E 7800                   moveq   #$00,d4
081410 363C 0627              move.w  #$0627,d3
; MFM encode first pass
081414 2018                   move.l  (a0)+,d0
081416 2200                   move.l  d0,d1
081418 E288                   lsr.l   #1,d0
08141A C082                   and.l   d2,d0
08141C C282                   and.l   d2,d1
08141E B184                   eor.l   d0,d4
081420 B384                   eor.l   d1,d4
081422 2341 18A0              move.l  d1,$18A0(a1)
081426 22C0                   move.l  d0,(a1)+
081428 51CB FFEA              dbf     d3,$081414
08142C 225F                   movea.l (sp)+,a1
; Store "checksum"
08142E 2004                   move.l  d4,d0
081430 2200                   move.l  d0,d1
081432 E288                   lsr.l   #1,d0
081434 C082                   and.l   d2,d0
081436 C282                   and.l   d2,d1
081438 48D1 0003              movem.l d0-d1,(a1)
; MFM encode second pass
08143C 363C 0C51              move.w  #$0C51,d3
081440 2011                   move.l  (a1),d0
081442 2800                   move.l  d0,d4
081444 B580                   eor.l   d2,d0
081446 2200                   move.l  d0,d1
081448 D281                   add.l   d1,d1
08144A E288                   lsr.l   #1,d0
08144C 0829 0000 FFFF         btst    #$00,-$01(a1)
081452 6604                   bne.b   $081458
081454 08C0 001F              bset    #$1F,d0
081458 C081                   and.l   d1,d0
08145A 8084                   or.l    d4,d0
08145C 22C0                   move.l  d0,(a1)+
08145E 51CB FFE0              dbf     d3,$081440
081462 D482                   add.l   d2,d2
081464 22C2                   move.l  d2,(a1)+
081466 2006                   move.l  d6,d0
; Setup drive, motor on etc..
081468 6100 FAC4              bsr.w   $080F2E
; Check DSKWPRO whether disk is write protected
08146C 0814 0003              btst    #$03,(a4)
081470 6606                   bne.b   $081478
081472 16BC 0001              move.b  #$01,(a3)
081476 603E                   bra.b   $0814B6
081478 3D7C 7F00 007A         move.w  #$7F00,$7A(a6)
08147E 3D7C 8100 007A         move.w  #$8100,$7A(a6)
; Check track to write
081484 0C07 0050              cmpi.b  #$50,d7
081488 6506                   bcs.b   $081490
; If track < 80 alter ADKCON speed?
08148A 3D7C A000 007A         move.w  #$A000,$7A(a6)
; Seek to correct track
081490 2007                   move.l  d7,d0
081492 6100 FB4E              bsr.w   $080FE2
081496 1680                   move.b  d0,(a3)
081498 661C                   bne.b   $0814B6
; Wait a bit..
08149A 6100 FBC0              bsr.w   $08105C
; Prepare to write
08149E 6100 FBDC              bsr.w   $08107C
; And write the MFM buffer to the disk
0814A2 2D6B 0032 FFFC         move.l  $32(a3),-$04(a6)
0814A8 3CBC D980              move.w  #$D980,(a6)
0814AC 3CBC D980              move.w  #$D980,(a6)
; Wait for DMA to finish
0814B0 6100 FBD8              bsr.w   $08108A
0814B4 1680                   move.b  d0,(a3)
; Drive off
0814B6 6100 FABC              bsr.w   $080F74
0814BA 1013                   move.b  (a3),d0
0814BC 6704                   beq.b   $0814C2
0814BE 50EB 0002              st      $02(a3)
0814C2 4CDF 7FFE              movem.l (sp)+,d1-d7/a0-a6
0814C6 4E75                   rts
