mirror of
https://github.com/pevans/erc-c.git
synced 2024-12-25 03:32:22 +00:00
Reformat and annotate disk II controller code
This commit is contained in:
parent
0d1e949d13
commit
7c2c6d5d54
386
data/disk2.asm
386
data/disk2.asm
@ -1,145 +1,245 @@
|
||||
GBASL EQU $26
|
||||
GBASH EQU $27
|
||||
BAS2H EQU $2B
|
||||
A1L EQU $3C
|
||||
A1H EQU $3D
|
||||
A3L EQU $40
|
||||
A3H EQU $41
|
||||
STACK EQU $0100
|
||||
OFFPH0 EQU $C080
|
||||
ONPH0 EQU $C081
|
||||
TURNON EQU $C089
|
||||
SLCTD1 EQU $C08A
|
||||
READ EQU $C08C
|
||||
SETRD EQU $C08E
|
||||
WAIT EQU $FCA8
|
||||
IMMRTS EQU $FF58
|
||||
00:A2 20 LDX #$20
|
||||
02:A0 00 LDY #$00
|
||||
04:A2 03 LDX #$03
|
||||
06:86 3C SAVTMP STX A1L
|
||||
08:8A TXA
|
||||
09:0A ASL A
|
||||
0A:24 3C BIT A1L
|
||||
0C:F0 10 BEQ INCX
|
||||
0E:05 3C ORA A1L
|
||||
10:49 FF EOR #$FF
|
||||
12:29 7E AND #$7E
|
||||
14:B0 08 HASCRY BCS INCX
|
||||
16:4A LSR A
|
||||
17:D0 FB BNE HASCRY
|
||||
19:98 TYA
|
||||
1A:9D 56 03 STA $0356,X
|
||||
1D:C8 INY
|
||||
1E:E8 INCX INX
|
||||
1F:10 E5 BPL SAVTMP
|
||||
21:20 58 FF JSR IMMRTS
|
||||
24:BA TSX
|
||||
25:BD 00 01 LDA STACK,X
|
||||
28:0A ASL
|
||||
29:0A ASL
|
||||
2A:0A ASL
|
||||
2B:0A ASL
|
||||
2C:85 2B STA $2B
|
||||
2E:AA TAX
|
||||
2F:BD 8E C0 LDA SETRD,X
|
||||
32:BD 8C C0 LDA READ,X
|
||||
35:BD 8A C0 LDA SLCTD1,X
|
||||
38:BD 89 C0 LDA TURNON,X
|
||||
3B:A0 50 LDY #$50
|
||||
3D:BD 80 C0 LDA OFFPH0,X
|
||||
40:98 TYA
|
||||
41:29 03 AND #$03
|
||||
43:0A ASL
|
||||
44:05 2B ORA $2B
|
||||
46:AA TAX
|
||||
47:BD 81 C0 LDA ONPH0,X
|
||||
4A:A9 56 LDA #$56
|
||||
4C:20 A8 FC JSR WAIT
|
||||
4F:88 DEY
|
||||
50:10 EB BPL [3d]
|
||||
52:85 26 STA GBASL
|
||||
54:85 3D STA A1H
|
||||
56:85 41 STA A3H
|
||||
58:A9 08 LDA #$08
|
||||
5A:85 27 STA GBASH
|
||||
5C:18 CLC
|
||||
5D:08 PHP
|
||||
5E:BD 8C C0 LDA READ,X
|
||||
61:10 FB BPL [5e]
|
||||
63:49 D5 EOR #$D5
|
||||
65:D0 F7 BNE [5e]
|
||||
67:BD 8C C0 LDA READ,X
|
||||
6A:10 FB BPL [67]
|
||||
6C:C9 AA CMP #$AA
|
||||
6E:D0 F3 BNE [63]
|
||||
70:EA NOP
|
||||
71:BD 8C C0 LDA READ,X
|
||||
74:10 FB BPL [71]
|
||||
76:C9 96 CMP #$96
|
||||
78:F0 09 BEQ [83]
|
||||
7A:28 PLP
|
||||
7B:90 DF BCC [5c]
|
||||
7D:49 AD EOR #$AD
|
||||
7F:F0 25 BEQ [a6]
|
||||
81:D0 D9 BNE [5c]
|
||||
; disk2.asm
|
||||
;
|
||||
; This is the DISASSEMBLED source code for the Disk II controller ROM.
|
||||
; It adds up to 256 bytes of program code, which is all any peripheral
|
||||
; card was afforded.
|
||||
;
|
||||
; NOTE THAT THIS SOURCE CODE IS NOT ORIGINAL TO APPLE. I translated by
|
||||
; hand from the machine code in the ROM. Any comments, etc. you see
|
||||
; here, are from me--NOT APPLE.
|
||||
|
||||
83:A0 03 LDY #$03
|
||||
85:85 40 STA A3L
|
||||
87:BD 8C C0 LDA READ,X
|
||||
8A:10 FB BPL [87]
|
||||
8C:2A ROL A
|
||||
8D:85 3C STA A1L
|
||||
8F:BD 8C C0 LDA READ,X
|
||||
92:10 FB BPL [8f]
|
||||
94:25 3C AND A1L
|
||||
96:88 DEY
|
||||
97:D0 EC BNE [85]
|
||||
99:28 PLP
|
||||
9A:C5 3D CMP A1H
|
||||
9C:D0 BE BNE [5c]
|
||||
9E:A5 40 LDA A3L
|
||||
A0:C5 41 CMP A3H
|
||||
A2:D0 B8 BNE [5c]
|
||||
A4:B0 B7 BCS [5d] ;; weird
|
||||
; Our definitions for this little program
|
||||
GBASL EQU $26
|
||||
GBASH EQU $27
|
||||
BAS2H EQU $2B
|
||||
A1L EQU $3C
|
||||
A1H EQU $3D
|
||||
A3L EQU $40
|
||||
A3H EQU $41
|
||||
STACK EQU $0100
|
||||
GCRALT EQU $02D6
|
||||
XORSAV EQU $0300
|
||||
GCRTAB EQU $0356
|
||||
ENTRY EQU $0800
|
||||
PHASEOFF EQU $C080
|
||||
PHASEON EQU $C081
|
||||
TURNON EQU $C089
|
||||
SLCTD1 EQU $C08A
|
||||
READ EQU $C08C
|
||||
SETRD EQU $C08E
|
||||
WAIT EQU $FCA8
|
||||
FINDSLOT EQU $FF58
|
||||
|
||||
A6:A0 56 LDY #$56
|
||||
A8:84 3C STY A1L
|
||||
AA:BC 8C C0 LDY READ,X
|
||||
AD:10 FB BPL [aa]
|
||||
AF:59 D6 02 EOR $02D6,X
|
||||
B2:A4 3C LDY A1L
|
||||
B4:88 DEY
|
||||
B5:99 00 03 STA $0300,Y
|
||||
B8:D0 EE BNE [a8]
|
||||
BA:84 3C STY A1L
|
||||
BC:BC 8C C0 LDY READ,X
|
||||
BF:10 FB BPL [bc]
|
||||
C1:59 D6 02 EOR $02D6,X
|
||||
C4:A4 3C LDY A1L
|
||||
C6:91 26 STA (GBASL),Y
|
||||
C8:C8 INY
|
||||
C9:D0 EF BNE [ba]
|
||||
CB:BC 8C C0 LDY READ,X
|
||||
CE:10 FB BPL [cb]
|
||||
D0:59 D6 02 EOR $02D6,X
|
||||
D3:D0 87 BNE [5c]
|
||||
D5:A0 00 LDY #$00
|
||||
D7:A2 56 LDX #$56
|
||||
D9:CA DEX
|
||||
DA:30 FB BMI [d7]
|
||||
DC:B1 26 LDA (GBASL),Y
|
||||
DE:5E 00 03 LSR $0300,X
|
||||
E1:2A ROL A
|
||||
E2:5E 00 03 STA (GBASL),Y
|
||||
E5:2A ROL A
|
||||
E6:91 26 STA (GBASL),Y
|
||||
E8:C8 INY
|
||||
E9:D0 EE BNE [d9]
|
||||
EB:E6 27 INC GBASH
|
||||
ED:E6 3D INC A1H
|
||||
EF:A5 3D LDA A1H
|
||||
F1:CD 00 08 CMP $0800
|
||||
F4:A6 2B LDX $2B
|
||||
F6:90 DB BCC [d3]
|
||||
F8:4C 01 08 JMP $0801
|
||||
; This is not needed by the disk controller program itself, but is used
|
||||
; by the system ROM to determine if there is a valid controller program
|
||||
; here. (There is!)
|
||||
00:A2 20 LDX #$20
|
||||
|
||||
; Here we will write the group coded recording table for our decode
|
||||
; process, which is in the GCRTAB address.
|
||||
02:A0 00 LDY #$00
|
||||
04:A2 03 LDX #$03 ; our loop begins at $03
|
||||
06:86 3C NEXTGCR STX A1L ; A1L tracks the loop counter
|
||||
08:8A TXA
|
||||
09:0A ASL A
|
||||
0A:24 3C BIT A1L ; if X and X<<1 have no bits in common
|
||||
0C:F0 10 BEQ CONTGCR ; then X will not be written into GCRTAB
|
||||
|
||||
; This sequence of operations will prime A for the VALIDENT check. Any
|
||||
; valid X register value (from which A is derived) will be one where
|
||||
; these three operations results in $40; after we loop on VALIDENT and
|
||||
; shift A to the right a bunch of times, we'll end up with $00 and exit
|
||||
; the loop without tripping the BCS (because none of the first 6 bits
|
||||
; were ever high).
|
||||
0E:05 3C ORA A1L
|
||||
10:49 FF EOR #$FF
|
||||
12:29 7E AND #$7E
|
||||
14:B0 08 VALIDENT BCS CONTGCR
|
||||
16:4A LSR A
|
||||
17:D0 FB BNE VALIDENT
|
||||
|
||||
; Only certain X register values will be written via the STA
|
||||
; instruction; what we do write is an iteration of Y from $00..$3F.
|
||||
19:98 TYA
|
||||
1A:9D 56 03 STA GCRTAB,X
|
||||
1D:C8 INY
|
||||
1E:E8 CONTGCR INX
|
||||
1F:10 E5 BPL NEXTGCR
|
||||
|
||||
; All this wrangling is here to make a record of the slot number.
|
||||
; Because JSR will push the calling address into the stack, we can find
|
||||
; the MSB of that address with the LDA STACK,X instruction. All of the
|
||||
; ASLs will essentially push the 7 one hex digit over, so $C7 becomes
|
||||
; $70. And we store that in BAS2H so we can use it to run operations on
|
||||
; the peripheral.
|
||||
21:20 58 FF JSR FINDSLOT
|
||||
24:BA TSX
|
||||
25:BD 00 01 LDA STACK,X ; this will load $C7 into A
|
||||
28:0A ASL
|
||||
29:0A ASL
|
||||
2A:0A ASL
|
||||
2B:0A ASL ; and now we have $70
|
||||
2C:85 2B STA BAS2H
|
||||
|
||||
; Ok, with that done, we're going to get everything set up to copy the
|
||||
; zero track into RAM. NOTE: I'm not entirely sure why we're doing a
|
||||
; READ from the drive before we know we have drive 1 selected and turned
|
||||
; on.
|
||||
2E:AA TAX
|
||||
2F:BD 8E C0 LDA SETRD,X
|
||||
32:BD 8C C0 LDA READ,X
|
||||
35:BD 8A C0 LDA SLCTD1,X
|
||||
38:BD 89 C0 LDA TURNON,X
|
||||
|
||||
; This loop is going to go through the stepper motor phases, flipping
|
||||
; them off and on again. To begin with, X is $70, so we're going to work
|
||||
; with phase 0 at the start.
|
||||
3B:A0 50 LDY #$50
|
||||
3D:BD 80 C0 PHASELOOP LDA PHASEOFF,X
|
||||
40:98 TYA
|
||||
41:29 03 AND #$03 ; drop all but the first 2 bits
|
||||
43:0A ASL ; and shift over
|
||||
44:05 2B ORA BAS2H ; and add that to $70
|
||||
46:AA TAX
|
||||
47:BD 81 C0 LDA PHASEON,X
|
||||
4A:A9 56 LDA #$56
|
||||
4C:20 A8 FC JSR WAIT ; wait for the motor
|
||||
4F:88 DEY
|
||||
50:10 EB BPL PHASELOOP
|
||||
|
||||
; We're setting things up so we can start writing our decoded data into
|
||||
; the $08 page in memory, which is where we will ultimately jump to once
|
||||
; we finish going through track zero.
|
||||
52:85 26 STA GBASL ; A is $00 by this point
|
||||
54:85 3D STA A1H
|
||||
56:85 41 STA A3H
|
||||
58:A9 08 LDA #$08
|
||||
5A:85 27 STA GBASH ; so GBASH/L will hold $0800
|
||||
|
||||
; We're going to check to see if we are at a header marker.
|
||||
5C:18 CHKHD CLC
|
||||
5D:08 CHKHDC PHP ; hang onto the status for later
|
||||
|
||||
; Read byte from the disk (BPL is used here because anything that
|
||||
; doesn't have bit 7 high is bad data in 6-and-2 encoding).
|
||||
5E:BD 8C C0 READHD1 LDA READ,X
|
||||
61:10 FB BPL READHD1
|
||||
63:49 D5 CHKHD1 EOR #$D5
|
||||
65:D0 F7 BNE READHD1 ; try again
|
||||
|
||||
; Look for the second header byte
|
||||
67:BD 8C C0 READHD2 LDA READ,X
|
||||
6A:10 FB BPL READHD2
|
||||
6C:C9 AA CHKHD2 CMP #$AA
|
||||
6E:D0 F3 BNE CHKHD1
|
||||
70:EA NOP ; I don't know why we NOP here
|
||||
|
||||
; Third header byte
|
||||
71:BD 8C C0 READHD3 LDA READ,X
|
||||
74:10 FB BPL READHD3
|
||||
76:C9 96 CMP #$96 ; is this the end of a track marker?
|
||||
78:F0 09 BEQ METADATA ; seems to be!
|
||||
7A:28 PLP
|
||||
7B:90 DF BCC CHKHD ; if A < $96, keep seeking for a header byte
|
||||
7D:49 AD EOR #$AD ; if NOT, then this might be the end of a sector header
|
||||
7F:F0 25 BEQ DECODE ; so let's get decoding!
|
||||
81:D0 D9 BNE CHKHD ; Some other byte we didn't expect...
|
||||
|
||||
; The metadata is 4-and-4 encoded, which are two bytes that are read in
|
||||
; sequence and then AND'd together. The second in the sequence is what
|
||||
; will stay behind in A3L; we'll read 3 sequences in all.
|
||||
83:A0 03 METADATA LDY #$03
|
||||
85:85 40 AGAIN44 STA A3L
|
||||
87:BD 8C C0 FIRST44 LDA READ,X ; read a byte
|
||||
8A:10 FB BPL FIRST44
|
||||
8C:2A ROL A
|
||||
8D:85 3C STA A1L
|
||||
8F:BD 8C C0 SECOND44 LDA READ,X ; read another byte
|
||||
92:10 FB BPL SECOND44
|
||||
94:25 3C AND A1L ; intersect with the shifted FIRST44
|
||||
96:88 DEY
|
||||
97:D0 EC BNE AGAIN44
|
||||
|
||||
; This is going to pull from before we began checking for a header
|
||||
99:28 PLP
|
||||
9A:C5 3D CMP A1H
|
||||
9C:D0 BE BNE CHKHD
|
||||
|
||||
; A3H can only be $00, and A3L will have been $96 from the last header
|
||||
; byte we read; since $96 - $00 will of course not be zero, this will
|
||||
; force a branch back to CHKHD. Why we have this code here is unclear to
|
||||
; me.
|
||||
9E:A5 40 LDA A3L
|
||||
A0:C5 41 CMP A3H
|
||||
A2:D0 B8 BNE CHKHD
|
||||
|
||||
; If C is set, we will jump back to read the next header, _but_ we will
|
||||
; not execute the CLC instruction.
|
||||
A4:B0 B7 BCS CHKHDC
|
||||
|
||||
; As we decode bytes, we're referencing the GCRTAB entries we built
|
||||
; earlier but from a slightly different address point (hence GCRALT).
|
||||
; But make no mistake--we're EORing with GCRTAB data. Note that XORSAV
|
||||
; is an entry point ($0300) which is conveniently(!) $56 less than
|
||||
; GCRTAB ($0356). It is, though, really just a place to stash the
|
||||
; intermediate data.
|
||||
A6:A0 56 DECODE LDY #$56 ; loop this many times...
|
||||
A8:84 3C SAV2BITS STY A1L ; save in A1L, because we use Y to read
|
||||
AA:BC 8C C0 DECBYTE2 LDY READ,X
|
||||
AD:10 FB BPL DECBYTE
|
||||
AF:59 D6 02 EOR GCRALT,Y
|
||||
B2:A4 3C LDY A1L
|
||||
B4:88 DEY ; decrement the loop counter
|
||||
B5:99 00 03 STA XORSAV,Y ; hang onto the EOR data
|
||||
B8:D0 EE BNE SAV2BITS
|
||||
|
||||
; Looping from zero, now, we're going to write all that intermediate
|
||||
; data into the $0800 page (which is what (GBASL),Y resolves to),
|
||||
; counting up from $0800..$08FF.
|
||||
BA:84 3C SAV6BITS STY A1L
|
||||
BC:BC 8C C0 DECBYTE6 LDY READ,X
|
||||
BF:10 FB BPL DECBYTE6
|
||||
C1:59 D6 02 EOR GCRALT,Y
|
||||
C4:A4 3C LDY A1L
|
||||
C6:91 26 STA (GBASL),Y
|
||||
C8:C8 INY
|
||||
C9:D0 EF BNE SAV6BITS
|
||||
|
||||
; We read ONE more byte, then determine if we need to check for another
|
||||
; header again.
|
||||
CB:BC 8C C0 FINBYTE LDY READ,X
|
||||
CE:10 FB BPL FINBYTE
|
||||
D0:59 D6 02 EOR XORTMP,Y
|
||||
|
||||
; We may also get to here because it looks like we didn't write data
|
||||
; properly into the ENTRY page.
|
||||
D3:D0 87 BADDATA BNE CHKHD ; another sector?
|
||||
|
||||
; We're using the first 89 ($56) bytes in XORSAV (which, remember, is
|
||||
; $56 less than the GCRTAB address point); if we go below $00 (rolling
|
||||
; over to $FF), start over.
|
||||
;
|
||||
; The bytes we've already written into the ENTRY page need to have those
|
||||
; 2 bits we compiled into those 89 bytes pushed back into the data.
|
||||
D5:A0 00 LDY #$00
|
||||
D7:A2 56 BITLOOP LDX #$56
|
||||
D9:CA WRITELOOP DEX
|
||||
DA:30 FB BMI BITLOOP ; start over if we went past $00
|
||||
DC:B1 26 LDA (GBASL),Y ; load $0800 + Y
|
||||
DE:5E 00 03 LSR XORSAV,X ; move bit 0 into carry
|
||||
E1:2A ROL A ; now load carry into A, plus the orig contents
|
||||
E2:5E 00 03 LSR XORSAV,X ; shift the former bit 1 (now bit 0) into carry again
|
||||
E5:2A ROL A ; and again load into A; now we have all 8 bits
|
||||
E6:91 26 STA (GBASL),Y ; and save it back to $0800 + Y
|
||||
E8:C8 INY
|
||||
E9:D0 EE BNE WRITELOOP ; we'll loop here 256 times
|
||||
|
||||
; We're in the home stretch... we're just double-checking if we copied
|
||||
; things into the ENTRY page properly.
|
||||
EB:E6 27 INC GBASH ; so now GBASL/H is $0801
|
||||
ED:E6 3D INC A1H
|
||||
EF:A5 3D LDA A1H
|
||||
F1:CD 00 08 CMP ENTRY ; if A < ENTRY
|
||||
F4:A6 2B LDX BAS2H
|
||||
F6:90 DB BCC BADDATA ; then go back and try again
|
||||
F8:4C 01 08 JMP ENTRY+1 ; otherwise, let's boot the software!
|
||||
|
Loading…
Reference in New Issue
Block a user