HD6301V1: Difference between revisions
Jump to navigation
Jump to search
mNo edit summary |
No edit summary |
||
Line 3: | Line 3: | ||
8bit microcontroller used for [[multiplayer]] communication in [[cartridges]] like [[League Bowling]]. | 8bit microcontroller used for [[multiplayer]] communication in [[cartridges]] like [[League Bowling]]. | ||
Clocked at 1Mhz using the 4MB signal ( | Clocked at 1Mhz using the {{Sig|4MB|4MB}} signal (divided by 4 internally). | ||
==Datasheet== | ==Datasheet== | ||
Line 14: | Line 14: | ||
==Code== | ==Code== | ||
HD6301 has | The HD6301 has an internal 4KB ROM section holding program data. | ||
A dump is available, coming from a prototype Riding Hero cart: [[File:HD6301.zip]] (2x overdump) - Credits to NeoTurfMasta | |||
Commented source code (still some work left...): | |||
<syntaxhighlight> | |||
;Vectors: | |||
;TRAP: F4D6 (error) | |||
;SC1: F4BA (link receive) | |||
;TOF: F4D6 (error) | |||
;OCF: F4D6 (error) | |||
;ICF: F4D6 (error) | |||
;IRQ1: F4CB (CPU write) | |||
;SWI: F4D6 (error) | |||
;NMI: F4D6 (error) | |||
;RESET: F000 (start) | |||
;RAM: | |||
;$C2 start of message buffer (14 bytes ?) | |||
;$D0~$D1 | |||
;$D2~$D3 | |||
;$D4~$D5 | |||
;$D6~$D7 | |||
;$D8~$D9 | |||
;$DA~$DB | |||
;$DC | |||
;$E2 is an error counter ? | |||
;$E3 some counter ? ----------------- | |||
;$E4 some bitmask ? ----------------- | |||
;$E5 is receive byte counter | |||
;$E6 ? | |||
;$E7 is the output code (read by CPU) | |||
;$E8 related to $F3 ? | |||
;$E9 is the input code (wrote by CPU) | |||
;$EA another byte counter ? | |||
;$EB bit 0 is CPU write flag ? (data ready in $E9), bit 1 is link receive flag | |||
;$EC is TRCS register copy | |||
;$ED is the received code (link) | |||
;$EE~$EF buffer (FIFO ?) pointer | |||
;$F0 receive timeout timer | |||
;$F1 is status code/port1 mirror | |||
;$F2 some bitmask ? ----------------- | |||
;$F3 is lower nibble of input code (parameter ?) | |||
;$F4 start of some short buffer ? | |||
;Status bit 0 (D8) is command error (D,E,F: wrong command) | |||
;Status bit 2 (D10) is overrun receive error | |||
org $F000 | |||
; RESET | |||
LF000: | |||
sei | |||
lds #$00FF ; Clear RAM | |||
ldx #$0080 | |||
LF007: | |||
clr $7F,x | |||
dex | |||
bne LF007 | |||
ldaa #$40 ; Enable RAM (lol) | |||
staa X0014 | |||
ldaa #$04 ; 62500bps internal clock | |||
staa X0010 | |||
ldaa #$1A ; RIE, RXE, TXE | |||
staa X0011 | |||
ldaa #$48 ; Port3 IS3/IRQ1 enable, latch enable | |||
staa X000F | |||
ldaa X0011 ; Clear TRCS flags | |||
ldaa X0012 ; Receive register | |||
ldaa #$F1 ; Port1 direction 11110001 | |||
staa X0000 | |||
ldaa #$00 ; Port1 data | |||
staa X0002 | |||
ldaa #$00 ; Port3 direction (inputs) | |||
staa X0004 | |||
ldaa #$FF ; Port4 direction (outputs) | |||
staa X0005 | |||
ldaa X0006 ; Clear port3 latch | |||
ldaa #$FF ; $FF to RAM $E9, $DE, $DF, $E0, $E1, $B4, $C2, $E9, $E7 | |||
staa X00E9 ; Input code | |||
staa X00DE | |||
staa X00DF | |||
staa X00E0 | |||
staa X00E1 | |||
staa X00B4 | |||
staa X00C2 | |||
staa X00E9 ; Input code (again...) | |||
staa X00E7 ; Output code | |||
ldd #$0080 | |||
std X00EE ; RAM $EE = $0080 | |||
cli | |||
LF056: | |||
ldaa X0002 ; Read port1 | |||
bita #$02 ; P11 is nSLOTCS ($02 is a mask, not a bit number) | |||
beq LF08F ; Slot is enabled -> | |||
clra | |||
staa X0002 ; Clear port1 | |||
staa X00E2 ; Clear error counter ? | |||
staa X00E5 ; Reset byte counter | |||
staa X00E8 | |||
staa X00EA | |||
staa X00EB ; Clear flags | |||
staa X00F1 ; Clear status ? | |||
staa X00F2 | |||
staa X00F3 | |||
deca | |||
staa X00B4 ; $FF in RAM... | |||
staa X00C2 | |||
staa X00DE | |||
staa X00DF | |||
staa X00E0 | |||
staa X00E1 | |||
staa X00E9 ; Input code | |||
bra LF056 ; Loop until slot is enabled | |||
; Slot enabled | |||
LF08F: | |||
inc X00F0 ; $F0 starts at 0, now 1 | |||
ldaa X00EB ; Got a byte from CPU ? | |||
bita #$01 | |||
bne LF09C ; Yup -> | |||
jmp LF193 ; Nope -> | |||
; Process CPU write | |||
LF09C: | |||
; AIM AND Immediate $FE with RAM $EB (clear CPU write flag) | |||
; EIM XOR Immediate $80 with RAM $F1 (toggle status bit 3) | |||
ldaa X00F2 | |||
bne LF0B7 | |||
ldab X00E9 ; Input code | |||
andb #$F0 ; Upper nibble is index in jump table | |||
ldx #$F4DA | |||
lsrb ; 0BBBB000 | |||
lsrb ; 00BBBB00 | |||
lsrb ; 000BBBB0 | |||
abx ; B+X -> X | |||
ldx $00,x | |||
jmp $00,x ; Index jump | |||
; | |||
LF0B7: | |||
bita #$01 | |||
beq LF0DE | |||
ldab X00E8 | |||
cmpb X00F3 | |||
beq LF117 | |||
ldx #$00D0 | |||
abx ; B+X -> X | |||
ldaa X00E9 ; Input code | |||
staa $00,x | |||
ldaa $01,x | |||
staa X0007 ; Port4 data (output code) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
inc X00E8 | |||
jmp LF193 | |||
; | |||
LF0DE: | |||
ldab X00E8 | |||
cmpb X00F3 | |||
beq LF0FC | |||
ldx #$00D0 | |||
abx ; B+X -> X | |||
ldaa $01,x | |||
staa X0007 ; Port4 data (output code) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
inc X00E8 | |||
jmp LF193 | |||
; | |||
LF0FC: | |||
ldx #$00D0 | |||
abx ; B+X -> X | |||
ldaa $00,x | |||
coma | |||
staa X0007 ; Port4 data (output code) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
clra | |||
staa X00E8 | |||
staa X00F2 | |||
jmp LF193 | |||
; | |||
LF117: | |||
clra | |||
staa X00F2 | |||
ldx #$00CF | |||
abx ; B+X -> X | |||
ldaa $00,x | |||
coma | |||
cmpa X00E9 ; Input code | |||
beq LF13D | |||
ldaa $01,x | |||
coma | |||
staa X0007 ; Port4 data (output code) | |||
; OIM OR Immediate $20 with RAM $F1 (set status bit 1) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
clr X00E8 | |||
jmp LF193 | |||
; | |||
LF13D: | |||
ldab X00E7 ; Output code | |||
cmpb #$FF | |||
bne LF159 | |||
ldaa $01,x | |||
staa X0007 ; Port4 data (output code) | |||
; OIM OR Immediate $20 with RAM $F1 (set status bit 1) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
clr X00E8 | |||
jmp LF193 | |||
; | |||
LF159: | |||
ldaa $01,x | |||
coma | |||
staa X0007 ; Port4 data (output code) | |||
clra | |||
xgdx ????? | |||
clr $DE,x | |||
; | |||
; AIM AND Immediate $CF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
clr X00E8 | |||
ldx X00EE | |||
ldd X00D0 | |||
std $00,x | |||
ldd X00D2 | |||
std $02,x | |||
ldd X00D4 | |||
std $04,x | |||
ldd X00D6 | |||
std $06,x | |||
ldd X00D8 | |||
std $08,x | |||
ldd X00DA | |||
std $0A,x | |||
ldaa X00DC | |||
staa $0C,x | |||
LF193: | |||
ldaa X00EB ; Got a byte from link ? | |||
bita #$02 | |||
bne LF19D ; Yup -> | |||
jmp LF257 ; Nope -> | |||
; Process link receive | |||
LF19D: | |||
; AIM AND Immediate $FD (11111101) with RAM $EB | |||
ldab X00EC | |||
bitb #$40 ; Overrun framing error ? | |||
bne LF1AE ; Yup -> | |||
bitb #$80 ; Receive data register full ? | |||
bne LF1CE ; Yup -> | |||
jmp LF257 | |||
; Overrun framing error | |||
LF1AE: | |||
clra | |||
staa X00E5 ; Reset byte counter | |||
staa X00EA | |||
deca | |||
staa X00C2 | |||
staa X00B4 | |||
inc X00E2 ; Error counter ? | |||
ldaa X00F1 ; Status ? | |||
oraa #$40 ; Set status bit 2 | |||
anda #$FE ; Mask out P10, just in case (transmit enable, not status) | |||
staa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
jmp LF257 | |||
; Got byte ok | |||
LF1CE: | |||
ldab X00E5 ; Byte counter | |||
cmpb #$0D | |||
beq LF1E5 ; Already got 13 bytes ? -> | |||
clra | |||
xgdx ????? | |||
ldaa X00ED ; Received code | |||
staa $C2,x ; Store in list @ $C2+x | |||
inc X00E5 ; Byte counter | |||
; OIM OR Immediate $04 with RAM $EB | |||
jmp LF257 | |||
; Got message OK | |||
LF1E5: | |||
; AIM AND Immediate $FE with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
clra | |||
xgdx ????? | |||
ldaa X00ED ; Received code | |||
staa $C2,x ; Store 14th byte (the last) | |||
clra | |||
staa X00EA | |||
staa X00E5 ; Reset byte counter | |||
deca | |||
staa X00B4 | |||
ldaa X00C2 ; RAM $C2 (first byte of message) & 3: 0~3 -> 1~4, gives B=$02,$04,$08,$10 | |||
anda #$03 | |||
inca | |||
ldab #$01 | |||
LF207: | |||
aslb | |||
deca | |||
bne LF207 | |||
lsrb ; B=$01,$02,$04,$08 | |||
orab X00E4 | |||
stab X00E4 | |||
ldab X00C2 | |||
andb #$03 | |||
ldx #$00F4 | |||
abx ; X = $00F4 + (RAM $C2 & 3) | |||
clr $00,x | |||
cmpb X00E7 ; Output code | |||
beq LF252 | |||
ldx #$F4FA | |||
abx ; B+X -> X | |||
abx ; B+X -> X | |||
incb | |||
andb #$03 | |||
stab X00E3 | |||
ldx $00,x | |||
ldd X00C3 | |||
std $00,x | |||
ldd X00C5 | |||
std $02,x | |||
ldd X00C7 | |||
std $04,x | |||
ldd X00C9 | |||
std $06,x | |||
ldd X00CB | |||
std $08,x | |||
ldd X00CD | |||
std $0A,x | |||
ldaa X00CF | |||
staa $0C,x | |||
LF252: | |||
ldaa #$FF | |||
staa X00C2 | |||
LF257: | |||
ldaa X00F0 | |||
cmpa #$28 | |||
bcs LF296 | |||
ldx #$00F4 | |||
ldab X00E3 | |||
abx ; B+X -> X | |||
ldaa $00,x | |||
inca | |||
cmpa #$0A | |||
bne LF27C | |||
ldaa #$01 | |||
incb | |||
LF26F: | |||
asla | |||
decb | |||
bne LF26F | |||
lsra | |||
coma | |||
anda X00E4 | |||
staa X00E4 | |||
clra | |||
LF27C: | |||
staa $00,x | |||
inc X00E3 | |||
; AIM AND Immediate $03 with RAM $E3 | |||
clra | |||
staa X00E5 ; Reset byte counter | |||
staa X00EA | |||
staa X00F0 | |||
; AIM AND Immediate $FE with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
LF296: | |||
ldaa X0011 ; Read TRCS | |||
bita #$20 ; Transmit register empty ? | |||
beq LF309 ; Nope -> | |||
ldaa X00B4 | |||
cmpa #$FF | |||
bne LF309 | |||
clra | |||
ldab X00E7 ; Output code | |||
cmpb #$FF | |||
beq LF309 | |||
xgdx ????? | |||
ldab $DE,x | |||
bne LF309 | |||
orab X00EA | |||
orab X00E5 ; Byte counter | |||
bne LF309 | |||
xgdx ????? | |||
eorb X00E3 | |||
bne LF309 | |||
ldx X00EE ; X=$00EE | |||
ldd $00,x | |||
std X00B5 ; RAM $B5 <- RAM $EE | |||
ldd $02,x | |||
std X00B7 ; RAM $B7 <- RAM $F0 | |||
ldd $04,x | |||
std X00B9 ; RAM $B9 <- RAM $F2 | |||
ldd $06,x | |||
std X00BB ; RAM $BB <- RAM $F4 | |||
ldd $08,x | |||
std X00BD ; RAM $BD <- RAM $F6 | |||
ldd $0A,x | |||
std X00BF ; RAM $BF <- RAM $F8 | |||
ldaa $0C,x | |||
staa X00C1 ; RAM $C1 <- RAM $FA | |||
ldaa X00E7 ; Output code | |||
staa X00B4 | |||
; OIM OR Immediate $01 with RAM $F1 (P10 high, enable TX buffer in 75176) | |||
ldab X00F1 ; Status ? | |||
stab X0002 ; Port1 data | |||
staa X0013 ; Transmit register | |||
; | |||
; AIM AND Immediate $FB with RAM $EB | |||
inc X00EA | |||
inc X00E3 | |||
; AIM AND Immediate $03 with RAM $E3 | |||
clra | |||
ldab X00E7 ; Output code | |||
xgdx ????? | |||
ldaa #$FF | |||
staa $DE,x | |||
LF309: | |||
ldaa X00EB | |||
bita #$04 | |||
beq LF33F | |||
ldaa X00F0 | |||
cmpa #$0F | |||
bcs LF33F | |||
ldaa X00B4 | |||
cmpa #$FF | |||
beq LF33F | |||
ldaa X0011 ; Read TRCS | |||
bita #$20 ; Transmit register empty ? | |||
beq LF33F ; Nope -> | |||
ldab X00EA | |||
cmpb #$0E | |||
beq LF33F | |||
; | |||
; AIM AND Immediate $FB with RAM $EB | |||
clra | |||
xgdx ????? | |||
ldaa $B4,x | |||
inc X00EA | |||
; OIM OR Immediate $01 with RAM $F1 (P10 high, enable TX buffer in 75176) | |||
ldab X00F1 ; Status ? | |||
stab X0002 ; Port1 data | |||
staa X0013 ; Transmit register | |||
LF33F: | |||
jmp LF056 | |||
Command9: | |||
sei | |||
ldx #$0080 | |||
LF346: | |||
clr $7F,x | |||
dex | |||
bne LF346 | |||
jmp LF000 | |||
Command0: | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
jmp LF193 | |||
Command2: | |||
ldaa X00E7 ; Output code | |||
staa X0007 ; Port4 data (output code) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
jmp LF193 | |||
Command1: | |||
ldaa X00E9 ; Input code | |||
tab | |||
anda #$0C ; Bits 2 and 3 | |||
bne LF3D6 | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
andb #$03 | |||
stab X00E7 ; Output code | |||
ldx #$F4FA | |||
abx ; B+X -> X | |||
abx ; B+X -> X | |||
ldd $00,x | |||
std X00EE ; RAM $EE = $F4FA + X*2 | |||
ldab #$01 | |||
ldaa X00E9 ; Input code | |||
anda #$03 | |||
LF38F: | |||
deca | |||
bmi LF396 | |||
aslb | |||
jmp LF38F | |||
; | |||
LF396: | |||
orab X00E4 | |||
stab X00E4 | |||
jmp LF193 | |||
Command4: | |||
ldaa X00E9 ; Input code | |||
anda #$0F | |||
staa X00F3 ; RAM $F3 is lower nibble of input code | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
ldaa #$FE | |||
staa X00F2 ; RAM $F2 = $FE | |||
jmp LF193 | |||
Command3/CommandA: | |||
ldaa X00E7 ; Output code | |||
cmpa #$FF | |||
beq LF3D6 ; Is $FF ? -> | |||
ldaa X00E9 ; Input code | |||
anda #$0F | |||
staa X00F3 ; RAM $F3 is lower nibble of input code | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
ldaa #$FF | |||
staa X00F2 ; RAM $F2 = $FF | |||
jmp LF193 | |||
CommandD/E/F: | |||
; OIM OR Immediate $10 with RAM $F1 (set status bit 0) | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
jmp LF193 | |||
Command5: ; Similar to command 1 | |||
ldaa X00E9 ; Input code | |||
tab | |||
anda #$0C ; Bits 2 and 3 | |||
bne LF3D6 | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
andb #$03 | |||
stab X00E6 | |||
ldx #$F4FA | |||
abx ; B+X -> X | |||
abx ; B+X -> X | |||
ldx $00,x | |||
ldd $00,x | |||
std X00D1 ; RAM $D1 = $F4FA + X*2 (word) | |||
ldd $02,x | |||
std X00D3 ; RAM $D3 = $F4FA + X*2 + 2 (word) | |||
ldd $04,x | |||
std X00D5 ; RAM $D5 = $F4FA + X*2 + 4 (word) | |||
ldd $06,x | |||
std X00D7 ; RAM $D7 = $F4FA + X*2 + 6 (word) | |||
ldd $08,x | |||
std X00D9 ; RAM $D9 = $F4FA + X*2 + 8 (word) | |||
ldd $0A,x | |||
std X00DB ; RAM $DB = $F4FA + X*2 + A (word) | |||
ldaa $0C,x | |||
staa X00DD ; RAM $DD = $F4FA + X*2 + C (byte) always $FF ? | |||
clr X00E8 | |||
jmp LF193 | |||
CommandC: | |||
ldaa X00E7 ; Output code | |||
cmpa #$FF | |||
beq LF3D6 | |||
ldaa X00E9 ; Input code | |||
tab | |||
anda #$0C | |||
bne LF3D6 | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
andb #$03 | |||
ldx #$F4FA | |||
abx ; B+X -> X | |||
abx ; B+X -> X | |||
ldx $00,x | |||
ldd $00,x | |||
std X00D1 | |||
ldd $02,x | |||
std X00D3 | |||
ldd $04,x | |||
std X00D5 | |||
ldd $06,x | |||
std X00D7 | |||
ldd $08,x | |||
std X00D9 | |||
ldd $0A,x | |||
std X00DB | |||
ldaa $0C,x | |||
staa X00DD | |||
clra | |||
staa X00E8 | |||
deca | |||
staa X00F2 | |||
ldaa #$0D | |||
staa X00F3 | |||
jmp LF193 | |||
Command6: | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
ldaa X00E9 ; Input code | |||
staa X00E8 | |||
jmp LF193 | |||
Command7: | |||
XF48A: | |||
ldaa X00E4 | |||
staa X0007 ; Port4 data (output code) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
jmp LF193 | |||
Command8: | |||
ldaa X00E2 ; Error counter ? | |||
staa X0007 ; Port4 data (output code) | |||
; AIM AND Immediate $EF with RAM $F1 | |||
ldaa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
jmp LF193 | |||
CommandB: | |||
ldaa X00F1 ; Status ? | |||
anda #$BF | |||
; AIM AND Immediate $EF with RAM $F1 | |||
staa X00F1 ; Status ? | |||
staa X0002 ; Port1 data | |||
jmp LF193 | |||
SC1: | |||
ldaa X0011 ; Read TRCS | |||
staa X00EC ; Store | |||
ldaa X0012 ; Receive register | |||
staa X00ED ; Store received code | |||
clr X00F0 | |||
; OIM OR Immediate $02 with RAM $EB (link receive flag) | |||
rti | |||
IRQ1: | |||
ldaa X000F ; Clear port3 latch flag | |||
ldaa X0006 ; Port3 data (input code) | |||
staa X00E9 ; Input code | |||
; OIM OR Immediate $01 with RAM $EB (CPU write flag) | |||
rti | |||
XF4D6: | |||
inc X00E2 ; Error counter ? | |||
rti | |||
XF4DA: | |||
; CPU command 0: $F34E Update status | |||
; CPU command 1: $F369 | |||
; CPU command 2: $F359 Read output code | |||
; CPU command 3: $F3B7 | |||
; CPU command 4: $F39F | |||
; CPU command 5: $F3E1 | |||
; CPU command 6: $F479 Put $E9 in $E8 ? | |||
; CPU command 7: $F48A | |||
; CPU command 8: $F49A Read error counter | |||
; CPU command 9: $F342 Reset | |||
; CPU command A: $F3B7 Same as command 3 | |||
; CPU command B: $F4AA Ack something ? | |||
; CPU command C: $F426 | |||
; CPU command D: $F3D6 Invalid | |||
; CPU command E: $F3D6 Invalid | |||
; CPU command F: $F3D6 Invalid | |||
XF4FA: | |||
;0080 008D 009A 00A7 00B4 00C2 FF... | |||
</syntaxhighlight> |
Revision as of 14:13, 21 September 2016
8bit microcontroller used for multiplayer communication in cartridges like League Bowling.
Clocked at 1Mhz using the 4MB signal (divided by 4 internally).
Datasheet
Official datasheet: [[1]]
Code
The HD6301 has an internal 4KB ROM section holding program data.
A dump is available, coming from a prototype Riding Hero cart: File:HD6301.zip (2x overdump) - Credits to NeoTurfMasta
Commented source code (still some work left...):
;Vectors:
;TRAP: F4D6 (error)
;SC1: F4BA (link receive)
;TOF: F4D6 (error)
;OCF: F4D6 (error)
;ICF: F4D6 (error)
;IRQ1: F4CB (CPU write)
;SWI: F4D6 (error)
;NMI: F4D6 (error)
;RESET: F000 (start)
;RAM:
;$C2 start of message buffer (14 bytes ?)
;$D0~$D1
;$D2~$D3
;$D4~$D5
;$D6~$D7
;$D8~$D9
;$DA~$DB
;$DC
;$E2 is an error counter ?
;$E3 some counter ? -----------------
;$E4 some bitmask ? -----------------
;$E5 is receive byte counter
;$E6 ?
;$E7 is the output code (read by CPU)
;$E8 related to $F3 ?
;$E9 is the input code (wrote by CPU)
;$EA another byte counter ?
;$EB bit 0 is CPU write flag ? (data ready in $E9), bit 1 is link receive flag
;$EC is TRCS register copy
;$ED is the received code (link)
;$EE~$EF buffer (FIFO ?) pointer
;$F0 receive timeout timer
;$F1 is status code/port1 mirror
;$F2 some bitmask ? -----------------
;$F3 is lower nibble of input code (parameter ?)
;$F4 start of some short buffer ?
;Status bit 0 (D8) is command error (D,E,F: wrong command)
;Status bit 2 (D10) is overrun receive error
org $F000
; RESET
LF000:
sei
lds #$00FF ; Clear RAM
ldx #$0080
LF007:
clr $7F,x
dex
bne LF007
ldaa #$40 ; Enable RAM (lol)
staa X0014
ldaa #$04 ; 62500bps internal clock
staa X0010
ldaa #$1A ; RIE, RXE, TXE
staa X0011
ldaa #$48 ; Port3 IS3/IRQ1 enable, latch enable
staa X000F
ldaa X0011 ; Clear TRCS flags
ldaa X0012 ; Receive register
ldaa #$F1 ; Port1 direction 11110001
staa X0000
ldaa #$00 ; Port1 data
staa X0002
ldaa #$00 ; Port3 direction (inputs)
staa X0004
ldaa #$FF ; Port4 direction (outputs)
staa X0005
ldaa X0006 ; Clear port3 latch
ldaa #$FF ; $FF to RAM $E9, $DE, $DF, $E0, $E1, $B4, $C2, $E9, $E7
staa X00E9 ; Input code
staa X00DE
staa X00DF
staa X00E0
staa X00E1
staa X00B4
staa X00C2
staa X00E9 ; Input code (again...)
staa X00E7 ; Output code
ldd #$0080
std X00EE ; RAM $EE = $0080
cli
LF056:
ldaa X0002 ; Read port1
bita #$02 ; P11 is nSLOTCS ($02 is a mask, not a bit number)
beq LF08F ; Slot is enabled ->
clra
staa X0002 ; Clear port1
staa X00E2 ; Clear error counter ?
staa X00E5 ; Reset byte counter
staa X00E8
staa X00EA
staa X00EB ; Clear flags
staa X00F1 ; Clear status ?
staa X00F2
staa X00F3
deca
staa X00B4 ; $FF in RAM...
staa X00C2
staa X00DE
staa X00DF
staa X00E0
staa X00E1
staa X00E9 ; Input code
bra LF056 ; Loop until slot is enabled
; Slot enabled
LF08F:
inc X00F0 ; $F0 starts at 0, now 1
ldaa X00EB ; Got a byte from CPU ?
bita #$01
bne LF09C ; Yup ->
jmp LF193 ; Nope ->
; Process CPU write
LF09C:
; AIM AND Immediate $FE with RAM $EB (clear CPU write flag)
; EIM XOR Immediate $80 with RAM $F1 (toggle status bit 3)
ldaa X00F2
bne LF0B7
ldab X00E9 ; Input code
andb #$F0 ; Upper nibble is index in jump table
ldx #$F4DA
lsrb ; 0BBBB000
lsrb ; 00BBBB00
lsrb ; 000BBBB0
abx ; B+X -> X
ldx $00,x
jmp $00,x ; Index jump
;
LF0B7:
bita #$01
beq LF0DE
ldab X00E8
cmpb X00F3
beq LF117
ldx #$00D0
abx ; B+X -> X
ldaa X00E9 ; Input code
staa $00,x
ldaa $01,x
staa X0007 ; Port4 data (output code)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
inc X00E8
jmp LF193
;
LF0DE:
ldab X00E8
cmpb X00F3
beq LF0FC
ldx #$00D0
abx ; B+X -> X
ldaa $01,x
staa X0007 ; Port4 data (output code)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
inc X00E8
jmp LF193
;
LF0FC:
ldx #$00D0
abx ; B+X -> X
ldaa $00,x
coma
staa X0007 ; Port4 data (output code)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
clra
staa X00E8
staa X00F2
jmp LF193
;
LF117:
clra
staa X00F2
ldx #$00CF
abx ; B+X -> X
ldaa $00,x
coma
cmpa X00E9 ; Input code
beq LF13D
ldaa $01,x
coma
staa X0007 ; Port4 data (output code)
; OIM OR Immediate $20 with RAM $F1 (set status bit 1)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
clr X00E8
jmp LF193
;
LF13D:
ldab X00E7 ; Output code
cmpb #$FF
bne LF159
ldaa $01,x
staa X0007 ; Port4 data (output code)
; OIM OR Immediate $20 with RAM $F1 (set status bit 1)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
clr X00E8
jmp LF193
;
LF159:
ldaa $01,x
coma
staa X0007 ; Port4 data (output code)
clra
xgdx ?????
clr $DE,x
;
; AIM AND Immediate $CF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
clr X00E8
ldx X00EE
ldd X00D0
std $00,x
ldd X00D2
std $02,x
ldd X00D4
std $04,x
ldd X00D6
std $06,x
ldd X00D8
std $08,x
ldd X00DA
std $0A,x
ldaa X00DC
staa $0C,x
LF193:
ldaa X00EB ; Got a byte from link ?
bita #$02
bne LF19D ; Yup ->
jmp LF257 ; Nope ->
; Process link receive
LF19D:
; AIM AND Immediate $FD (11111101) with RAM $EB
ldab X00EC
bitb #$40 ; Overrun framing error ?
bne LF1AE ; Yup ->
bitb #$80 ; Receive data register full ?
bne LF1CE ; Yup ->
jmp LF257
; Overrun framing error
LF1AE:
clra
staa X00E5 ; Reset byte counter
staa X00EA
deca
staa X00C2
staa X00B4
inc X00E2 ; Error counter ?
ldaa X00F1 ; Status ?
oraa #$40 ; Set status bit 2
anda #$FE ; Mask out P10, just in case (transmit enable, not status)
staa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF257
; Got byte ok
LF1CE:
ldab X00E5 ; Byte counter
cmpb #$0D
beq LF1E5 ; Already got 13 bytes ? ->
clra
xgdx ?????
ldaa X00ED ; Received code
staa $C2,x ; Store in list @ $C2+x
inc X00E5 ; Byte counter
; OIM OR Immediate $04 with RAM $EB
jmp LF257
; Got message OK
LF1E5:
; AIM AND Immediate $FE with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
clra
xgdx ?????
ldaa X00ED ; Received code
staa $C2,x ; Store 14th byte (the last)
clra
staa X00EA
staa X00E5 ; Reset byte counter
deca
staa X00B4
ldaa X00C2 ; RAM $C2 (first byte of message) & 3: 0~3 -> 1~4, gives B=$02,$04,$08,$10
anda #$03
inca
ldab #$01
LF207:
aslb
deca
bne LF207
lsrb ; B=$01,$02,$04,$08
orab X00E4
stab X00E4
ldab X00C2
andb #$03
ldx #$00F4
abx ; X = $00F4 + (RAM $C2 & 3)
clr $00,x
cmpb X00E7 ; Output code
beq LF252
ldx #$F4FA
abx ; B+X -> X
abx ; B+X -> X
incb
andb #$03
stab X00E3
ldx $00,x
ldd X00C3
std $00,x
ldd X00C5
std $02,x
ldd X00C7
std $04,x
ldd X00C9
std $06,x
ldd X00CB
std $08,x
ldd X00CD
std $0A,x
ldaa X00CF
staa $0C,x
LF252:
ldaa #$FF
staa X00C2
LF257:
ldaa X00F0
cmpa #$28
bcs LF296
ldx #$00F4
ldab X00E3
abx ; B+X -> X
ldaa $00,x
inca
cmpa #$0A
bne LF27C
ldaa #$01
incb
LF26F:
asla
decb
bne LF26F
lsra
coma
anda X00E4
staa X00E4
clra
LF27C:
staa $00,x
inc X00E3
; AIM AND Immediate $03 with RAM $E3
clra
staa X00E5 ; Reset byte counter
staa X00EA
staa X00F0
; AIM AND Immediate $FE with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
LF296:
ldaa X0011 ; Read TRCS
bita #$20 ; Transmit register empty ?
beq LF309 ; Nope ->
ldaa X00B4
cmpa #$FF
bne LF309
clra
ldab X00E7 ; Output code
cmpb #$FF
beq LF309
xgdx ?????
ldab $DE,x
bne LF309
orab X00EA
orab X00E5 ; Byte counter
bne LF309
xgdx ?????
eorb X00E3
bne LF309
ldx X00EE ; X=$00EE
ldd $00,x
std X00B5 ; RAM $B5 <- RAM $EE
ldd $02,x
std X00B7 ; RAM $B7 <- RAM $F0
ldd $04,x
std X00B9 ; RAM $B9 <- RAM $F2
ldd $06,x
std X00BB ; RAM $BB <- RAM $F4
ldd $08,x
std X00BD ; RAM $BD <- RAM $F6
ldd $0A,x
std X00BF ; RAM $BF <- RAM $F8
ldaa $0C,x
staa X00C1 ; RAM $C1 <- RAM $FA
ldaa X00E7 ; Output code
staa X00B4
; OIM OR Immediate $01 with RAM $F1 (P10 high, enable TX buffer in 75176)
ldab X00F1 ; Status ?
stab X0002 ; Port1 data
staa X0013 ; Transmit register
;
; AIM AND Immediate $FB with RAM $EB
inc X00EA
inc X00E3
; AIM AND Immediate $03 with RAM $E3
clra
ldab X00E7 ; Output code
xgdx ?????
ldaa #$FF
staa $DE,x
LF309:
ldaa X00EB
bita #$04
beq LF33F
ldaa X00F0
cmpa #$0F
bcs LF33F
ldaa X00B4
cmpa #$FF
beq LF33F
ldaa X0011 ; Read TRCS
bita #$20 ; Transmit register empty ?
beq LF33F ; Nope ->
ldab X00EA
cmpb #$0E
beq LF33F
;
; AIM AND Immediate $FB with RAM $EB
clra
xgdx ?????
ldaa $B4,x
inc X00EA
; OIM OR Immediate $01 with RAM $F1 (P10 high, enable TX buffer in 75176)
ldab X00F1 ; Status ?
stab X0002 ; Port1 data
staa X0013 ; Transmit register
LF33F:
jmp LF056
Command9:
sei
ldx #$0080
LF346:
clr $7F,x
dex
bne LF346
jmp LF000
Command0:
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193
Command2:
ldaa X00E7 ; Output code
staa X0007 ; Port4 data (output code)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193
Command1:
ldaa X00E9 ; Input code
tab
anda #$0C ; Bits 2 and 3
bne LF3D6
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
andb #$03
stab X00E7 ; Output code
ldx #$F4FA
abx ; B+X -> X
abx ; B+X -> X
ldd $00,x
std X00EE ; RAM $EE = $F4FA + X*2
ldab #$01
ldaa X00E9 ; Input code
anda #$03
LF38F:
deca
bmi LF396
aslb
jmp LF38F
;
LF396:
orab X00E4
stab X00E4
jmp LF193
Command4:
ldaa X00E9 ; Input code
anda #$0F
staa X00F3 ; RAM $F3 is lower nibble of input code
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
ldaa #$FE
staa X00F2 ; RAM $F2 = $FE
jmp LF193
Command3/CommandA:
ldaa X00E7 ; Output code
cmpa #$FF
beq LF3D6 ; Is $FF ? ->
ldaa X00E9 ; Input code
anda #$0F
staa X00F3 ; RAM $F3 is lower nibble of input code
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
ldaa #$FF
staa X00F2 ; RAM $F2 = $FF
jmp LF193
CommandD/E/F:
; OIM OR Immediate $10 with RAM $F1 (set status bit 0)
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193
Command5: ; Similar to command 1
ldaa X00E9 ; Input code
tab
anda #$0C ; Bits 2 and 3
bne LF3D6
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
andb #$03
stab X00E6
ldx #$F4FA
abx ; B+X -> X
abx ; B+X -> X
ldx $00,x
ldd $00,x
std X00D1 ; RAM $D1 = $F4FA + X*2 (word)
ldd $02,x
std X00D3 ; RAM $D3 = $F4FA + X*2 + 2 (word)
ldd $04,x
std X00D5 ; RAM $D5 = $F4FA + X*2 + 4 (word)
ldd $06,x
std X00D7 ; RAM $D7 = $F4FA + X*2 + 6 (word)
ldd $08,x
std X00D9 ; RAM $D9 = $F4FA + X*2 + 8 (word)
ldd $0A,x
std X00DB ; RAM $DB = $F4FA + X*2 + A (word)
ldaa $0C,x
staa X00DD ; RAM $DD = $F4FA + X*2 + C (byte) always $FF ?
clr X00E8
jmp LF193
CommandC:
ldaa X00E7 ; Output code
cmpa #$FF
beq LF3D6
ldaa X00E9 ; Input code
tab
anda #$0C
bne LF3D6
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
andb #$03
ldx #$F4FA
abx ; B+X -> X
abx ; B+X -> X
ldx $00,x
ldd $00,x
std X00D1
ldd $02,x
std X00D3
ldd $04,x
std X00D5
ldd $06,x
std X00D7
ldd $08,x
std X00D9
ldd $0A,x
std X00DB
ldaa $0C,x
staa X00DD
clra
staa X00E8
deca
staa X00F2
ldaa #$0D
staa X00F3
jmp LF193
Command6:
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
ldaa X00E9 ; Input code
staa X00E8
jmp LF193
Command7:
XF48A:
ldaa X00E4
staa X0007 ; Port4 data (output code)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193
Command8:
ldaa X00E2 ; Error counter ?
staa X0007 ; Port4 data (output code)
; AIM AND Immediate $EF with RAM $F1
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193
CommandB:
ldaa X00F1 ; Status ?
anda #$BF
; AIM AND Immediate $EF with RAM $F1
staa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193
SC1:
ldaa X0011 ; Read TRCS
staa X00EC ; Store
ldaa X0012 ; Receive register
staa X00ED ; Store received code
clr X00F0
; OIM OR Immediate $02 with RAM $EB (link receive flag)
rti
IRQ1:
ldaa X000F ; Clear port3 latch flag
ldaa X0006 ; Port3 data (input code)
staa X00E9 ; Input code
; OIM OR Immediate $01 with RAM $EB (CPU write flag)
rti
XF4D6:
inc X00E2 ; Error counter ?
rti
XF4DA:
; CPU command 0: $F34E Update status
; CPU command 1: $F369
; CPU command 2: $F359 Read output code
; CPU command 3: $F3B7
; CPU command 4: $F39F
; CPU command 5: $F3E1
; CPU command 6: $F479 Put $E9 in $E8 ?
; CPU command 7: $F48A
; CPU command 8: $F49A Read error counter
; CPU command 9: $F342 Reset
; CPU command A: $F3B7 Same as command 3
; CPU command B: $F4AA Ack something ?
; CPU command C: $F426
; CPU command D: $F3D6 Invalid
; CPU command E: $F3D6 Invalid
; CPU command F: $F3D6 Invalid
XF4FA:
;0080 008D 009A 00A7 00B4 00C2 FF...