HD6301V1: Difference between revisions

From NeoGeo Development Wiki
Jump to navigation Jump to search
No edit summary
 
(3 intermediate revisions by 2 users not shown)
Line 1: Line 1:
[[File:crt_hd6301.jpg|right|thumb|HD6301 chip. Picture courtesy of [[http://www.mvs-scans.com MVS-Scans]].]]
[[File:crt_hd6301.jpg|right|thumb|HD6301 chip. Picture courtesy of [[http://www.mvs-scans.com MVS-Scans]].]]


8bit microcontroller used for [[multiplayer]] communication in [[cartridges]] like [[League Bowling]].
8bit Hitachi microcontroller used for [[multiplayer]] communication in [[cartridges]] like [[League Bowling]].


Clocked at 1Mhz using the {{Sig|4MB|4MB}} signal (divided by 4 internally).
Compatible with the Motorola 6803 but has additionnal instructions.
 
Clocked at 1MHz using the {{Sig|4MB|4MB}} signal (divided by 4 internally).


==Datasheet==
==Datasheet==


Official datasheet: [[http://www.datasheetcatalog.org/datasheets2/15/1588588_1.pdf]]
Official datasheet: [[http://www.datasheetcatalog.org/datasheets2/15/1588588_1.pdf]]
[[Category:Chips]]
[[Category:Cartridge systems]]


==Code==
==Code==
Line 18: Line 17:
A dump is available, coming from a prototype Riding Hero cart: [[File:HD6301.zip]] (2x overdump) - Credits to NeoTurfMasta
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...):
Commented source code (still some work left...): https://github.com/neogeodev/COM-HD6301
 
Another take on it:


<syntaxhighlight>
<syntaxhighlight>
;Vectors:
;Memory map (mode 7 operation):
;TRAP: F4D6 (error)
;
;SC1: F4BA (link receive)
;0000-001F: internal registers
;TOF: F4D6 (error)
;00 - Port 1 data direction *
;OCF: F4D6 (error)
;01 - Port 2 data direction *
;ICF: F4D6 (error)
;02 - Port 1 data
;IRQ1: F4CB (CPU write)
;03 - Port 2 data
;SWI: F4D6 (error)
;04 - Port 3 data direction *
;NMI: F4D6 (error)
;05 - Port 4 data direction *
;RESET: F000 (start)
;06 - Port 3 data
;07 - Port 4 data
;08 - Timer control and status
;09 - Counter (MSB)
;0a - Counter (LSB)
;0b - Output compare (MSB)
;0c - Output compare (LSB)
;0d - Input capture (MSB)
;0e - Input capture (LSB)
;0f - Port 3 control and status
; {/IS3 flag|/IS3 /IRQ1 enable|-|OSS|latch enable|-|-|-}
;10 - Rate and mode control
; {-|-|-|-|CC1|CC0|SS1|SS0}
; SSx: SCI bit times & transfer rate
; CCx: SCI format  & clock source
;11 - Transmit/receive control and status
; {RDRF|ORFE|TDRE|RIE|RE|TIE|TE|WU}
; WU: wake up
; TE: transmit enable
; TIE: transmit interrupt enable
; RE: receive enable
; RIE: receive interrupt enable
; TDRE: transmit data register empty
; ORFE: over run framing error
; RDRF: receive data register full
;12 - Receive data
;13 - Transmit data
;14 - RAM control
; {Standby|RAME|-|-|-|-|-|-}
;15-1F: reserved
; * 1=output 0=input
;-------------------------
;0080-00FF: RAM (128B)
;-------------------------
;F000-FFFF: ROM (4KB)
 
;RAM map:
 
;$80-$8c: 13 bytes buffer
;$8d-$99: 13 bytes buffer
;$9a-$a6: 13 bytes buffer
;$a7-$b3: 13 bytes buffer
;storage buffers


;RAM:
;$b4-$c1: 1+13 bytes SCI data transmit buffer
;$C2 start of message buffer (14 bytes ?)
;$c2-$cf: 1+13 bytes SCI data receive buffer
;data is moved from/to storage buffers, 1st byte holds storage buffer #


;$D0~$D1
;$d0-$dd: 14 bytes 68k comm buffer
;$D2~$D3
;writes are done $d0 to $de, reads $d1 to $df
;$D4~$D5
;$D6~$D7
;$D8~$D9
;$DA~$DB
;$DC


;$E2 is an error counter ?
;$de: buffer #0 status //0xff=free
;$E3 some counter ? -----------------
;$df: buffer #1 status
;$E4 some bitmask ? -----------------
;$e0: buffer #2 status
;$E5 is receive byte counter
;$e1: buffer #3 status
;$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)
;$e2: error count? (increased by framing error or TRAP)
;Status bit 2 (D10) is overrun receive error
;$e3: buffers table index (0-3). next buffer #?
;$e4: buffers in use bitflag (bit0-3) [0x01 / 0x02 / 0x04 / 0x08 ]
;$e5: receipt buffer ($c2) index
;$e6: store port3 lower 2 bits in cmd#5, seemingly unused?
;$e7: current buffer #? (0-3, 0xff init)
;$e8: 68k comm buffer index?
;$e9: port3 written data
;$ea: transmit buffer ($b4) index
;$eb: bitflags
; #0: IS3# occured (data written on port3)
; #1: RDRF/ORFE occured (data received / framing error)
; #2: ? (tr related) byte added in buffer for trasmission flag?
;$ec: SCI transmit/receive status ($11 copy)
;$ed :SCI received data ($12 copy)
;$ee(word) : current buffer address? (0x0080 / 0x008d / 0x009a / 0x00a7)
;$f0: main loop counter (SCI irq cleared)
;$f1: port1 data, bitflags
; #0: 75176 DE pin
; #4: general error report
; #5: ? 68k comm buffer processing related
; #6: framing error report
; #7: 68k acknowledge bit (toggled after each processed write to port 3)
;$f2: port3 related flags. data is a cmd when 0x00 / 0xff=write buffer? / 0xfe=read buffer?
;$f3: port 3 related - read/write data count
;$f4-$f7: buffer indexes? SCI receive related?
;$f8-$ff: stack


org $F000
;entry point
; RESET
F000: 0F        sei ;disable interrupts
LF000:
F001: 8E 00 FF  lds    #$00FF ;stack pointer = 0x00ff
sei


lds #$00FF ; Clear RAM
;clear ram
ldx #$0080
F004: CE 00 80  ldx     #$0080 ;x=0x0080
LF007:
F007: 6F 7F      clr     (x+$7F) ;$(x+0x7f)=0x00
clr $7F,x
F009: 09        dex ;x--
dex
F00A: 26 FB      bne    $F007 ;loop if x>0
bne LF007


ldaa #$40 ; Enable RAM (lol)
;init stage (timer regs 08 09 0a 0b 0c 0d 0e unused)
staa X0014
F00C: 86 40      lda    #$40
ldaa #$04 ; 62500bps internal clock
F00E: 97 14      sta    $14 ;$14=0x40 //enable RAM (after clearing it, lolz)
staa X0010
F010: 86 04      lda    #$04
ldaa #$1A ; RIE, RXE, TXE
F012: 97 10      sta    $10 ;$10=0x04 //rate/mode settings: 62.500 bauds?, NRZ format, internal clock, P22 unused, P23=serial input, P24=serial output
staa X0011
F014: 86 1A      lda    #$1A
ldaa #$48 ; Port3 IS3/IRQ1 enable, latch enable
F016: 97 11      sta    $11 ;$11=0x1a //transmit/receive settings: receive enable, receive interrupt enable, transmit enable, transmit interrupt disable
staa X000F
F018: 86 48      lda    #$48
ldaa X0011  ; Clear TRCS flags
F01A: 97 0F      sta    $0F ;$0f=0x48 //port3 settings: enable /IS3, output strobe on port3 read, latch enable
ldaa X0012 ; Receive register
F01C: 96 11      lda    $11 ;a=$11
ldaa #$F1 ; Port1 direction 11110001
F01E: 96 12      lda    $12 ;a=$12 //read t/r status register & data to clear flags
staa X0000
F020: 86 F1      lda    #$F1
ldaa #$00 ; Port1 data
F022: 97 00      sta    $00 ;$00=0xf1 //port1 bits 76540 as output, 321 as input
staa X0002
F024: 86 00      lda    #$00
ldaa #$00 ; Port3 direction (inputs)
F026: 97 02      sta    $02 ;$02=0x00 //port1 = 0x00
staa X0004
F028: 86 00      lda    #$00
ldaa #$FF ; Port4 direction (outputs)
F02A: 97 04      sta    $04 ;$04=0x00 //port3 as input
staa X0005
F02C: 86 FF      lda    #$FF
ldaa X0006 ; Clear port3 latch
F02E: 97 05      sta    $05 ;$05=0xff //port4 as output
ldaa #$FF ; $FF to RAM $E9, $DE, $DF, $E0, $E1, $B4, $C2, $E9, $E7
F030: 96 06      lda    $06 ;a=$06 //read port3 to release latch
staa X00E9 ; Input code
F032: 86 FF      lda    #$FF
staa X00DE
F034: B7 00 E9  sta    $00E9 ;$e9=0xff
staa X00DF
F037: B7 00 DE  sta    $00DE ;$de=0xff
staa X00E0
F03A: B7 00 DF  sta    $00DF ;$df=0xff
staa X00E1
F03D: B7 00 E0   sta    $00E0 ;$e0=0xff
staa X00B4
F040: B7 00 E1   sta    $00E1 ;$e1=0xff
staa X00C2
F043: B7 00 B4   sta    $00B4 ;$b4=0xff
staa X00E9 ; Input code (again...)
F046: B7 00 C2   sta    $00C2 ;$c2=0xff
staa X00E7 ; Output code
F049: B7 00 E9  sta    $00E9 ;$e9=0xff
ldd #$0080
F04C: B7 00 E7  sta    $00E7 ;$e7=0xff
std X00EE ; RAM $EE = $0080
F04F: CC 00 80  ldd     #$0080
cli
F052: FD 00 EE  std    $00EE ;(word)$ee=0x0080
F055: 0E        cli ;enable interrupts


LF056:
;main loop
ldaa X0002 ; Read port1
F056: 96 02      lda    $02 ;a=port1 data
bita #$02   ; P11 is nSLOTCS ($02 is a mask, not a bit number)
F058: 85 02      bita   #$02 ;bit#1 set?
beq LF08F  ; Slot is enabled ->
F05A: 27 33      beq     $F08F ;not set? =>branch $f08f
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
;resets+idle microcontroller while P11 is high (SLOTCS on MVS, grounded on NEOGEO)
LF08F:
F05C: 4F        clra
inc X00F0 ; $F0 starts at 0, now 1
F05D: 97 02      sta    $02
ldaa X00EB ; Got a byte from CPU ?
F05F: B7 00 E2  sta    $00E2 ;$e2=0x02
bita #$01
F062: B7 00 E5  sta    $00E5 ;$e5=0x02
bne LF09C   ; Yup ->
F065: B7 00 E8  sta    $00E8 ;$e8=0x02
jmp LF193 ; Nope ->
F068: B7 00 EA  sta    $00EA ;$ea=0x02
F06B: B7 00 EB  sta    $00EB ;$eb=0x02
F06E: B7 00 F1  sta    $00F1 ;$f1=0x02
F071: B7 00 F2  sta    $00F2 ;$f2=0x02
F074: B7 00 F3  sta    $00F3 ;$f3=0x02
F077: 4A        deca
F078: B7 00 B4  sta    $00B4 ;$b4=0x01
F07B: B7 00 C2  sta    $00C2 ;$b2=0x01
F07E: B7 00 DE  sta    $00DE ;$de=0x01
F081: B7 00 DF  sta    $00DF ;$df=0x01
F084: B7 00 E0  sta    $00E0 ;$e0=0x01
F087: B7 00 E1  sta    $00E1 ;$e1=0x01
F08A: B7 00 E9   sta    $00E9 ;$e9=0x01
F08D: 20 C7      bra    $F056 ;loop to main


; Process CPU write
;bit #1 not set
LF09C:
F08F: 7C 00 F0  inc    $00F0 ;$f0++
; AIM AND Immediate $FE with RAM $EB (clear CPU write flag)
F092: B6 00 EB  lda    $00EB ;a=$eb
; EIM XOR Immediate $80 with RAM $F1 (toggle status bit 3)
F095: 85 01      bita   #$01 ;bit #0 set? (port3 received data?)
ldaa X00F2
F097: 26 03      bne    $F09C ;yes? =>branch $f09c
bne LF0B7
F099: 7E F1 93  jmp     $F193
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:
;****************** 68k comm processing (port 3) *******************
; AIM AND Immediate $FD (11111101) with RAM $EB
;*******************************************************************
ldab X00EC
;data has been written to port 3
bitb #$40 ; Overrun framing error ?
F09C: 71 FE EB  aim    #$FE,$EB ;$eb &= 0xfe //clear data_in flag
bne LF1AE ; Yup ->
F09F: 75 80 F1  eim    #$80,$F1 ;$f1 ^= 0x80 //toggle bit#7 to ack
bitb #$80 ; Receive data register full ?
F0A2: B6 00 F2  lda    $00F2 ;a=$f2
bne LF1CE ; Yup ->
F0A5: 26 10      bne    $F0B7 ;not 0? => branch $f0b7
jmp LF257
 
;************ received byte is a command **************
F0A7: F6 00 E9  ldb    $00E9 ;b=$e9 //byte that has been written to port3
F0AA: C4 F0      andb    #$F0 ;b &= 0xf0
F0AC: CE F4 DA  ldx    #$F4DA ;x=pointers table
F0AF: 54        lsrb
F0B0: 54        lsrb
F0B1: 54        lsrb ;b>>=3 //not >>=4 because word table
F0B2: 3A        abx ;x+=b
F0B3: EE 00      ldx    (x+$00) ;x=pointer data
F0B5: 6E 00      jmp    (x+$00) ;jump to ptr value //jump fo funcs[port3 data upper nibble]
 
;************ received byte isn't a command ($f2!=0x00) **************
;(a holds $f2)
F0B7: 85 01      bita    #$01 ;a bit#0?
F0B9: 27 23      beq    $F0DE ;not set? => branch $f0de
 
;$f2 bit#0 set (0xff) - buffer write ops
F0BB: F6 00 E8  ldb    $00E8 ;b=$e8
F0BE: F1 00 F3  cmpb    $00F3 ;b==$f3?
F0C1: 27 54      beq    $F117 ;yes? => branch $f117
;$f2bit#0 set (0xff), $e8!=$f3
F0C3: CE 00 D0  ldx    #$00D0 ;x=0x00d0
F0C6: 3A        abx ;x+=b //x=0x00d0+$e8 (0xd0[$e8])
F0C7: B6 00 E9  lda    $00E9 ;a=$e9 (port3 data)
F0CA: A7 00      sta    (x+$00) ;$x=a //0xd0[$e8]=port3 data
F0CC: A6 01      lda    (x+$01) ;a=$x+1
F0CE: 97 07      sta    $07 ;port4=a //outputs 0xd0[$e8+1] to 68k
F0D0: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F0D3: B6 00 F1  lda    $00F1 ;a=$f1
F0D6: 97 02      sta    $02 ;port1=a //update status
F0D8: 7C 00 E8  inc    $00E8 ;$e8++ //index++
F0DB: 7E F1 93  jmp    $F193 ;branch $f193
 
;----------
;$f2 bit#0 not set (0xfe) - buffer read ops
F0DE: F6 00 E8  ldb    $00E8 ;b=$e8
F0E1: F1 00 F3  cmpb    $00F3 ;b==$f3?
F0E4: 27 16      beq    $F0FC ;yes? => branch $f0fc
;$f2 bit#0 not set (0xfe), $e8!=$f3
F0E6: CE 00 D0  ldx    #$00D0 ;x=0x00d0
F0E9: 3A        abx ;x+=b //x=0x00d0+$e8  (0xd0[$e8])
F0EA: A6 01      lda    (x+$01) ;a=$x+1
F0EC: 97 07      sta    $07 ;port4=a //outputs 0xd0[$e8+1] to 68k
F0EE: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F0F1: B6 00 F1  lda    $00F1 ;a=$f1
F0F4: 97 02      sta    $02 ;port1=a //status update
F0F6: 7C 00 E8  inc    $00E8 ;$e8++ //increase index
F0F9: 7E F1 93  jmp    $F193 ;branch $f193
;$f2 bit#0 not set (0xfe), $e8==$f3 (last read)
F0FC: CE 00 D0  ldx    #$00D0 ;x=0x00d0
F0FF: 3A        abx ;x+=b //x=0x00d0+$e8  (0xd0[$e8])
F100: A6 00      lda    (x+$00) ;a=$x
F102: 43        coma ;a=~a
F103: 97 07      sta    $07 ;port4=a //outputs ~(0xd0[$e8]) to 68k
F105: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F108: B6 00 F1  lda    $00F1 ;a=$f1
F10B: 97 02      sta    $02 ;port1=a //status update
F10D: 4F        clra ;a=0x00
F10E: B7 00 E8  sta    $00E8 ;$e8=0x00 //index=0
F111: B7 00 F2  sta    $00F2 ;$f2=0x00 //next port3 write is a command
F114: 7E F1 93  jmp    $F193 ;branch $f193
;----------
 
;$f2 bit#0 set (0xff), $e8==$f3 (last write)
F117: 4F        clra ;a=0x00
F118: B7 00 F2  sta    $00F2 ;$f2=0x00 //next port3 write is a command
F11B: CE 00 CF  ldx    #$00CF ;x=0x00cf
F11E: 3A        abx ;x+=b //x+=$e8 content  0xcf[$e8]
F11F: A6 00      lda    (x+$00) ;a=(x) //a=0xcf[$e8]
F121: 43        coma ;a=~a
F122: B1 00 E9  cmpa    $00E9 ;a==$e9? //port3 written data==~a ?
F125: 27 16      beq    $F13D ;yes? => branch $f13d
;port3 written data!=~a
F127: A6 01      lda    (x+$01) ;a=(x+1) //a=0xcf[$e8+1]
F129: 43        coma ;a=~a
F12A: 97 07      sta    $07 ;$07=a //port4=a  outputs ~(0xcf[$e8+1]) to 68k
F12C: 72 20 F1  oim    #$20,$F1 ;$f1|=0x20 //set bit#5
F12F: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xf1 //clear bit#123
F132: B6 00 F1  lda    $00F1 ;a=$f1
F135: 97 02      sta    $02 ;port1=a //status update
F137: 7F 00 E8  clr    $00E8 ;$e8=0x00 //index=0
F13A: 7E F1 93  jmp    $F193 ;branch $f193 //SCI block
 
;data==~a
F13D: F6 00 E7  ldb    $00E7 ;b=$e7
F140: C1 FF      cmpb    #$FF ;b==0xff?
F142: 26 15      bne    $F159 ;nope? => branch $f159
;need to pick a buffer
F144: A6 01      lda    (x+$01) ;a=$x+1
F146: 97 07      sta    $07 ;port4=a //output data
F148: 72 20 F1  oim    #$20,$F1 ;$f1|=0x20 //set bit#5
F14B: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F14E: B6 00 F1  lda    $00F1 ;a=$f1
F151: 97 02      sta    $02 ;port1=a //update status port
F153: 7F 00 E8  clr    $00E8 ;$e8=0
F156: 7E F1 93  jmp    $F193 ;branch $f193
;$e7!=0xff
F159: A6 01      lda    (x+$01) ;a=$x+1
F15B: 43        coma ;a=~a
F15C: 97 07      sta    $07 ;port4=a //output data
F15E: 4F        clra ;a=0x00
F15F: 18        xgdx ;d<->x
F160: 6F DE      clr    (x+$DE) ;$x+0xde=0x00
F162: 71 CF F1  aim    #$CF,$F1 ;$f1&=0xcf //clear bit#4 & bit #5
F165: B6 00 F1  lda    $00F1 ;a=$f1
F168: 97 02      sta    $02 ;port1=a //update status port
F16A: 7F 00 E8  clr    $00E8 ;$e8=0x00 //index=0
F16D: FE 00 EE  ldx    $00EE ;x=$ee
 
F170: FC 00 D0  ldd    $00D0 ;d=$d0
F173: ED 00      std    (x+$00) ;$x=d
F175: FC 00 D2  ldd    $00D2 ;d=$d2
F178: ED 02      std    (x+$02) ;$x+2=d
F17A: FC 00 D4  ldd    $00D4 ;d=$d4
F17D: ED 04      std    (x+$04) ;$x+4=d
F17F: FC 00 D6  ldd    $00D6 ;d=$d6
F182: ED 06      std    (x+$06) ;$x+6=d
F184: FC 00 D8  ldd    $00D8 ;d=$d8
F187: ED 08      std    (x+$08) ;$x+8=d
F189: FC 00 DA  ldd    $00DA ;d=$da
F18C: ED 0A      std    (x+$0A) ;$x+0x0a=d
F18E: B6 00 DC  lda    $00DC ;a=$dc
F191: A7 0C      sta    (x+$0C) ;$x+0x0c=a //copy 13 bytes
 
 
;*******************************************************************
;************************* SCI processing **************************
;*******************************************************************
 
F193: B6 00 EB  lda    $00EB ;a=$eb
F196: 85 02      bita    #$02 ;a bit#1 set?  (RDRF/ORFE occured)
F198: 26 03      bne    $F19D ;set? => branch $f19d
F19A: 7E F2 57  jmp    $F257
 
;RDRF/ORFE occured ($eb bit#1 set)
F19D: 71 FD EB  aim    #$FD,$EB ;$eb&=0xfd //clear bit#1
F1A0: F6 00 EC  ldb    $00EC ;b=$ec //load status byte
F1A3: C5 40      bitb    #$40 ;b bit#6? //ORFE ?
F1A5: 26 07      bne    $F1AE ;set? => branch $f1ae
F1A7: C5 80      bitb   #$80 ;b bit#7? //RDRF ?
F1A9: 26 23      bne    $F1CE ;set? => branch $f1ce
F1AB: 7E F2 57  jmp    $F257 ;branch $f257 //something else occured, skipping
 
;ORFE processing (framing error) //resets SCI transmit and receive buffers
F1AE: 4F        clra ;a=0x00
F1AF: B7 00 E5  sta    $00E5 ;$e5=a //$e5=0x00
F1B2: B7 00 EA  sta    $00EA ;$ea=a //$ea=0x00 T/R indexes=0
F1B5: 4A        deca ;a=0xff
F1B6: B7 00 C2  sta    $00C2 ;$c2=a //$c2=0xff
F1B9: B7 00 B4  sta    $00B4 ;$b4=a //$b4=0xff clear buffer links
F1BC: 7C 00 E2  inc    $00E2 ;$e2++ //error count++
F1BF: B6 00 F1  lda    $00F1 ;a=$f1
F1C2: 8A 40     ora    #$40 ;a|=0x40 //set bit#6
F1C4: 84 FE      anda    #$FE ;a&=0xfe //clear bit#0
F1C6: B7 00 F1  sta    $00F1 ;$f1=a
F1C9: 97 02      sta    $02 ;port1=a //update status (clear 75176 DE pin, report framing error)
F1CB: 7E F2 57  jmp    $F257 ;branch $f257
 
;RDRF processing (receive register full)
F1CE: F6 00 E5  ldb    $00E5 ;b=$e5 //receive buffer index
F1D1: C1 0D      cmpb    #$0D ;b==0x0d? //going to fill last buffer space?
F1D3: 27 10      beq    $F1E5 ;yes? => branch $f1e5
 
F1D5: 4F        clra ;a=0x00
F1D6: 18        xgdx ; d<->x //x=buffer index
F1D7: B6 00 ED  lda    $00ED ;a=$ed //SCI received data
F1DA: A7 C2      sta    (x+$C2) ;$x+0xc2=a //receive buffer[index]=received data
F1DC: 7C 00 E5  inc    $00E5 ;$e5++ //increase index
F1DF: 72 04 EB  oim    #$04,$EB ;$eb|=0x04 //set bit#2
F1E2: 7E F2 57  jmp    $F257 ;branch $f257
 
;receive register full and receive buffer full
F1E5: 71 FE F1  aim    #$FE,$F1 ;$f1&=0xfe //clear bit#0
F1E8: B6 00 F1  lda    $00F1 ;a=$f1
F1EB: 97 02      sta    $02 ;port1=a //update status (clear 75176 DE pin)
F1ED: 4F        clra ;a=0x00
F1EE: 18        xgdx ;d<->x //x=0x000d
F1EF: B6 00 ED  lda    $00ED ;a=$ed //SCI received data
F1F2: A7 C2      sta    (x+$C2) ;$x+0xc2=a //$cf=received data (buffer now full)
F1F4: 4F        clra ;a=0x00
F1F5: B7 00 EA  sta    $00EA ;$ea=a //$ea=0x00
F1F8: B7 00 E5  sta    $00E5 ;$e5=a //$e5=0x00
F1FB: 4A        deca ;a=0xff
F1FC: B7 00 B4  sta    $00B4 ;$b4=a //$b4=0xff, reset transmit buffer
F1FF: B6 00 C2  lda    $00C2 ;a=$c2 //a=receive buffer status
 
F202: 84 03      anda    #$03 ;a&=0x03
F204: 4C        inca ;a++ //a=($c2&0x03)+1
F205: C6 01      ldb    #$01 ;b=0x01
 
F207: 58        aslb ;b<<=1
F208: 4A        deca ;a--
F209: 26 FC      bne     $F207 ;loop 4 times //b<<=4
F20B: 54        lsrb ;b>>=1 //b>>=1
F20C: FA 00 E4  orb    $00E4 ;b|=$e4
F20F: F7 00 E4  stb    $00E4 ;$e4=b //$e4|=b update buffer usage bit set
F212: F6 00 C2  ldb    $00C2 ;b=$c2
F215: C4 03      andb    #$03 ;b&=0x03 //b=$c2&0x03
F217: CE 00 F4  ldx    #$00F4 ;x=0x00f4
F21A: 3A        abx ;x+=b
F21B: 6F 00      clr    (x+$00) ;$x=0x00 //$f4[b]=0x00
F21D: F1 00 E7  cmpb    $00E7 ;b==$e7?
F220: 27 30      beq    $F252 ;yes? => branch $f252
 
F222: CE F4 FA  ldx    #$F4FA ;x=data table
F225: 3A        abx ;x+=b
F226: 3A        abx ;x+=b
F227: 5C        incb ;b++
F228: C4 03      andb    #$03 ;b&=0x03
F22A: F7 00 E3  stb    $00E3 ;$e3=b //store updated buffer#
F22D: EE 00      ldx    (x+$00) ;x=(word)data[b] //x=buffer addr
F22F: FC 00 C3  ldd    $00C3 ;d=$c3
F232: ED 00      std    (x+$00) ;(word)buffer[0]=d
F234: FC 00 C5  ldd    $00C5 ;d=$c5
F237: ED 02      std    (x+$02) ;(word)buffer[1]=d
F239: FC 00 C7  ldd    $00C7 ;d=$c7
F23C: ED 04      std    (x+$04) ;(word)buffer[2]=d
F23E: FC 00 C9  ldd    $00C9 ;d=$c9
F241: ED 06      std    (x+$06) ;(word)buffer[3]=d
F243: FC 00 CB  ldd    $00CB ;d=$cb
F246: ED 08      std    (x+$08) ;(word)buffer[4]=d
F248: FC 00 CD  ldd    $00CD ;d=$cd
F24B: ED 0A      std    (x+$0A) ;(word)buffer[5]=d
F24D: B6 00 CF  lda    $00CF ;a=$cf
F250: A7 0C      sta    (x+$0C) ;(byte)buffer[0xc]=a //copy receive buffer to storage buffer (13 bytes)
F252: 86 FF      lda    #$FF ;a=0xff
F254: B7 00 C2  sta    $00C2 ;$c2=a //$c2=0xff  (untie storage buffer)
 
;RDRF/ORFE didn't occur ($eb bit#1 not set) / after processing it
F257: B6 00 F0  lda    $00F0 ;a=$f0
F25A: 81 28      cmpa    #$28 ;a-0x28 (40)
F25C: 25 38      bcs    $F296 ;a<0x28 ? => branch $f296
 
;main looped more than 40 times (after last RDRF/ORFE interrupt)
F25E: CE 00 F4  ldx    #$00F4 ;x=0x00f4
F261: F6 00 E3  ldb    $00E3 ;b=$e3
F264: 3A        abx ;x+=b //x=0x00f4 + buffer table index (f4-f7)
F265: A6 00      lda    (x+$00) ;a=(x)
F267: 4C        inca ;a++
F268: 81 0A      cmpa    #$0A ;a==0x0a? //index == 0x0a ?
F26A: 26 10      bne    $F27C ;nope? => branch $f27c
 
F26C: 86 01      lda    #$01 ;a=0x01
F26E: 5C        incb ;b++
F26F: 48        asla ;a<<=1
F270: 5A        decb ;b--
F271: 26 FC      bne    $F26F ;!=0? => branch $f26f
F273: 44        lsra ;a>>=1 //a=buffer bitflag (0x08 / 0x04 / 0x02 / 0x01)
F274: 43        coma ;a=~a
F275: B4 00 E4  anda    $00E4 ;a&=$e4
F278: B7 00 E4  sta    $00E4 ;$e4=a //clear buffer usage bit
F27B: 4F        clra ;a=0x00
 
F27C: A7 00      sta    (x+$00) ;(x)=a //update index
F27E: 7C 00 E3  inc    $00E3 ;$e3++ //next buffer#
F281: 71 03 E3  aim    #$03,$E3 ;$e3&=0x03 //crop buffer#
F284: 4F        clra ;a=0x00
F285: B7 00 E5  sta    $00E5 ;$e5=0x00 //$e5=0
F288: B7 00 EA  sta    $00EA ;$ea=0x00 //$ea=0
F28B: B7 00 F0  sta    $00F0 ;$f0=0x00 //reset counter
F28E: 71 FE F1  aim    #$FE,$F1 ;$f1&=0xfe //clear bit#0 (75176 DE pin)
F291: B6 00 F1  lda    $00F1 ;a=$f1
F294: 97 02      sta    $02 ;port1=a //update status
 
;$f0<=0x28
;main looped less than 40 times / continue
F296: 96 11      lda    $11 ;t/r control & status
F298: 85 20      bita    #$20 ;TDRE?
F29A: 27 6D      beq    $F309 ;nope? => branch $f309 //transmit register not empty, exit
;transmit data register is empty, check for next byte to transmit
F29C: B6 00 B4  lda    $00B4 ;a=$b4
F29F: 81 FF      cmpa    #$FF ;a==0xff?
F2A1: 26 66      bne    $F309 ;no? => branch $f309 //transmit buffer not ready, exit
 
F2A3: 4F        clra ;a=0
F2A4: F6 00 E7  ldb    $00E7 ;b=$e7 //current buffer#
F2A7: C1 FF      cmpb    #$FF ;b==$ff?
F2A9: 27 5E      beq    $F309 ;yes? => branch $f309 //no current buffer selected, exit
 
F2AB: 18        xgdx ;d<->x
F2AC: E6 DE      ldb    (x+$DE) ;b=(x+0xde) //b=$de[current buffer] (current buffer status)
F2AE: 26 59      bne    $F309 ;!=0? branch $f309 //buffer status!=0, exit
 
F2B0: FA 00 EA  orb    $00EA ;b|=$ea
F2B3: FA 00 E5  orb    $00E5 ;b|=$e5
F2B6: 26 51      bne    $F309 ;!=0? branch $f309 //transmit/receive buffers index!=0, exit
 
F2B8: 18        xgdx ;d<->x
F2B9: F8 00 E3  eorb    $00E3 ;b|=$e3 //b=$e7|$e3
F2BC: 26 4B      bne    $F309 ;!=0? branch $f309 //not both 0, exit
 
F2BE: FE 00 EE  ldx    $00EE ;x=$00ee //buffer addr
F2C1: EC 00      ldd    (x+$00) ;d=(word)buffer[0]
F2C3: FD 00 B5  std    $00B5 ;$b5=d
F2C6: EC 02      ldd    (x+$02) ;d=(word)buffer[1]
F2C8: FD 00 B7  std    $00B7 ;$b7=d
F2CB: EC 04      ldd    (x+$04) ;d=(word)buffer[2]
F2CD: FD 00 B9  std    $00B9 ;$b9=d
F2D0: EC 06      ldd    (x+$06) ;d=(word)buffer[3]
F2D2: FD 00 BB  std    $00BB ;$bb=d
F2D5: EC 08      ldd    (x+$08) ;d=(word)buffer[4]
F2D7: FD 00 BD  std    $00BD ;$bd=d
F2DA: EC 0A      ldd    (x+$0A) ;d=(word)buffer[5]
F2DC: FD 00 BF  std    $00BF ;$bf=d
F2DF: A6 0C      lda    (x+$0C) ;a=(byte)buffer[0xc]
F2E1: B7 00 C1  sta    $00C1 ;$c1=a //copy work buffer into transmit buffer (13bytes)
F2E4: B6 00 E7  lda    $00E7 ;a=$e7
F2E7: B7 00 B4  sta    $00B4 ;$b4=a //store buffer # we are holding
 
F2EA: 72 01 F1  oim    #$01,$F1 ;$f1|=0x01 //set bit#0
F2ED: F6 00 F1  ldb    $00F1 ;b=$f1
F2F0: D7 02      stb    $02 ;port1=b //update status (enable 75176 DE)
 
F2F2: 97 13      sta    $13 ;transmit data=a //transmit buffer #?
F2F4: 71 FB EB  aim    #$FB,$EB ;$eb&=0xfb //clear bit#2
F2F7: 7C 00 EA  inc    $00EA ;$ea++ //inc index
F2FA: 7C 00 E3  inc    $00E3 ;$e3++ //inc buffer#
F2FD: 71 03 E3  aim    #$03,$E3 ;$e3&=0x03 //trim buffer#
F300: 4F        clra ;a=0x00
F301: F6 00 E7  ldb    $00E7 ;$e7=b
F304: 18        xgdx ;d<->x
F305: 86 FF      lda    #$FF ;a=0xff
F307: A7 DE      sta    (x+$DE) ;(x+0xde)=0xff //buffer status[buffer that was copied]=0xff
 
;transmits a byte if available then loop
F309: B6 00 EB  lda    $00EB ;a=$eb
F30C: 85 04      bita    #$04 ;bit#2 set? //new byte received?
F30E: 27 2F      beq    $F33F ;not set? => f33f //loop back to main
 
F310: B6 00 F0  lda    $00F0 ;a=$f0
F313: 81 0F      cmpa    #$0F ;a-0x0f //main looped > 15 times without SCI irq?
F315: 25 28      bcs    $F33F ;a<0x0f? =>branch $f33f //loop back to main
 
F317: B6 00 B4  lda    $00B4 ;a=$b4
F31A: 81 FF      cmpa    #$FF ;a==0xff? //nothing to transmit?
F31C: 27 21      beq    $F33F ;yes? => branch $f33f //loop back to main
 
F31E: 96 11      lda    $11 ;a= t/r status
F320: 85 20      bita    #$20 ;TDRE set? //transmit register available?
F322: 27 1B      beq    $F33F ;nope? => branch $f33f //loop back to main
 
F324: F6 00 EA  ldb    $00EA ;b=$ea
F327: C1 0E      cmpb    #$0E ;b==0x0e? //buffer fully transmitted?
F329: 27 14      beq    $F33F ;yes? => branch $f33f //loop back to main
 
F32B: 71 FB EB  aim    #$FB,$EB ;$eb&=0xfb //clear bit#2
F32E: 4F        clra ;a=0
F32F: 18        xgdx ;d<->x
F330: A6 B4      lda    (x+$B4) ;a=$x+0xb4 //a=transmit buffer[$ea]
F332: 7C 00 EA  inc    $00EA ;$ea++ //inc transmit buffer index
F335: 72 01 F1  oim    #$01,$F1 ;$f1|=0x01 //set bit#0
F338: F6 00 F1  ldb    $00F1 ;b=$f1
F33B: D7 02      stb    $02 ;port1=b //update status (enable 75176 DE)
F33D: 97 13      sta    $13 ;transmit=a //transmit a
F33F: 7E F0 56  jmp    $F056 ;branch $f056 //loop back to main
 
 
;*******************************************************************
;**************************** commands *****************************
;*******************************************************************
;lbowl: 00 00 00.. 20 51
;command 0x9* - reset microcontroller
F342: 0F        sei ;disable interrupts
F343: CE 00 80  ldx    #$0080 ;x=0x80
F346: 6F 7F      clr    (x+$7F) ;(x+0x7f)=0x00
F348: 09        dex ;x--
F349: 26 FB      bne    $F346 ;loop of x>0 //clear RAM
F34B: 7E F0 00  jmp    $F000 ;restart
 
;command 0x0* - dummy / clear error flag
F34E: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F351: B6 00 F1  lda    $00F1 ;a=$f1
F354: 97 02      sta    $02 ;port1=a
F356: 7E F1 93  jmp    $F193 ;branch $f193
 
;command 0x2* - write $e7 to port4 (buffer# currently in use?)
F359: B6 00 E7  lda    $00E7 ;a=$e7
F35C: 97 07      sta    $07 ;port4=a
F35E: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F361: B6 00 F1  lda    $00F1 ;a=$f1
F364: 97 02      sta    $02 ;port1=a
F366: 7E F1 93  jmp    $F193 ;branch $f193
 
;command 0x1* - select buffer[lower 2 bits] ?
F369: B6 00 E9  lda    $00E9 ;a=$e9 //port3 data
F36C: 16        tab ;b=a
F36D: 84 0C      anda    #$0C ;a&=0x0c //keep bit#3 & bit#2
F36F: 26 65      bne     $F3D6 ;!=0? => branch $f3d6 //error if buffer#>3
F371: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F374: B6 00 F1  lda    $00F1 ;a=$f1
F377: 97 02      sta    $02 ;port1=a //update status port
 
F379: C4 03      andb    #$03 ;b&=0x03 //beep bit#1 & bit#0
F37B: F7 00 E7  stb    $00E7 ;$e7=b //store buffer# in use?
F37E: CE F4 FA  ldx    #$F4FA ;x=data table
F381: 3A        abx ;x+=b
F382: 3A        abx ;x+=b
F383: EC 00      ldd    (x+$00) ;d=(word)data[b] //x=buffer[lower 2 bits]
F385: FD 00 EE  std    $00EE ;(word)$ee=d //store current buffer addr
F388: C6 01      ldb    #$01 ;b=0x01
F38A: B6 00 E9  lda    $00E9 ;a=$e9 //port3 data
F38D: 84 03      anda    #$03 ;a&=0x03 //keep bit#1 & bit#0
F38F: 4A        deca ;a--
F390: 2B 04      bmi    $F396 ;<0? => branch $f396
F392: 58        aslb ;b<<=1
F393: 7E F3 8F  jmp    $F38F ;loop
F396: FA 00 E4  orb    $00E4 ;b|=$e4
F399: F7 00 E4  stb    $00E4 ;$e4=b //$e4|=(0x01<<buffer#) flag as in use
F39C: 7E F1 93  jmp    $F193 ;branch $f193
 
;command 0x4* - $f3=lower nibble, $f2=0xfe
;sets up a read of x (lower nibble) values?
F39F: B6 00 E9  lda    $00E9 ;a=$e9 //port 3 data
F3A2: 84 0F      anda    #$0F ;a&=0x0f
F3A4: B7 00 F3  sta    $00F3 ;$f3=a //store lower nibble
F3A7: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F3AA: B6 00 F1  lda    $00F1 ;a=$f1
F3AD: 97 02      sta    $02 ;port1=a //update status port
F3AF: 86 FE      lda    #$FE ;a=0xfe
F3B1: B7 00 F2  sta    $00F2 ;$f2=a //$f2=0xfe
F3B4: 7E F1 93  jmp    $F193 ;branch $f193
 
;command 0x3*, 0xa* - if($e7!=0xff) $f3=lower nibble, $f2=0xff
;sets up a write of x (lower nibble) values?
F3B7: B6 00 E7  lda    $00E7 ;a=$e7
F3BA: 81 FF      cmpa    #$FF ;==0xff?
F3BC: 27 18      beq    $F3D6 ;yes? => branch $f3d6 //branch to error if $e7==0xff (no buffer selected)
F3BE: B6 00 E9  lda    $00E9 ;a=$e9 //port3 data
F3C1: 84 0F      anda    #$0F ;a&=0x0f
F3C3: B7 00 F3  sta    $00F3 ;$f3=a //store lower nibble
F3C6: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
F3C9: B6 00 F1  lda    $00F1 ;a=$f1
F3CC: 97 02      sta    $02 ;port1=a //update status port
F3CE: 86 FF      lda    #$FF ;a=0xff
F3D0: B7 00 F2  sta    $00F2 ;$f2=a //$f2=0xff
F3D3: 7E F1 93  jmp     $F193 ;branch $f193


; Overrun framing error
;command 0xd*, 0xe*, 0xf* - issue error
LF1AE:
F3D6: 72 10 F1  oim    #$10,$F1 ;$f1|=0x10 //sets bit#4
clra
F3D9: B6 00 F1  lda    $00F1 ;a=$f1
staa X00E5 ; Reset byte counter
F3DC: 97 02      sta    $02 ;port1=a
staa X00EA
F3DE: 7E F1 93  jmp    $F193 ;branch $f193
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
;command 0x5* - copy storage buffer[lower 2 bits] to 68k comm buffer
LF1CE:
F3E1: B6 00 E9  lda    $00E9 ;a=$e9 //port 3 data
ldab X00E5 ; Byte counter
F3E4: 16        tab ;b=a
cmpb #$0D
F3E5: 84 0C      anda    #$0C ;a&=0x0c //keep bit#3 & bit#2
beq LF1E5 ; Already got 13 bytes ? ->
F3E7: 26 ED      bne    $F3D6 ;!=0? => branch $f3d6 //error
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
F3E9: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
LF1E5:
F3EC: B6 00 F1  lda    $00F1 ;a=$f1
; AIM AND Immediate $FE with RAM $F1
F3EF: 97 02      sta    $02 ;port1=a //update status port
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
F3F1: C4 03      andb    #$03 ;b&=0x03 //keep bit#1 & bit#0
anda #$03
F3F3: F7 00 E6  stb    $00E6 ;$e6=b
inca
F3F6: CE F4 FA  ldx    #$F4FA ;x=data table
ldab #$01
F3F9: 3A        abx ;x+=b
LF207:
F3FA: 3A        abx ;x+=b
aslb
F3FB: EE 00      ldx    (x+$00) ;x=(word)data[b] //buffer addr
deca
bne LF207
lsrb ; B=$01,$02,$04,$08
orab X00E4
stab X00E4


ldab X00C2
F3FD: EC 00      ldd    (x+$00) ;d=(word)buffer[0]
andb #$03
F3FF: FD 00 D1  std    $00D1 ;$d1=d
ldx #$00F4
F402: EC 02      ldd     (x+$02) ;d=(word)buffer[1]
abx    ; X = $00F4 + (RAM $C2 & 3)
F404: FD 00 D3  std     $00D3 ;$d3=d
clr $00,x
F407: EC 04      ldd     (x+$04) ;d=(word)buffer[2]
cmpb X00E7 ; Output code
F409: FD 00 D5  std    $00D5 ;$d5=d
beq LF252
F40C: EC 06      ldd    (x+$06) ;d=(word)buffer[3]
ldx #$F4FA
F40E: FD 00 D7   std    $00D7 ;$d7=d
abx    ; B+X -> X
F411: EC 08      ldd    (x+$08) ;d=(word)buffer[4]
abx    ; B+X -> X
F413: FD 00 D9  std     $00D9 ;$d9=d
incb
F416: EC 0A      ldd     (x+$0A) ;d=(word)buffer[5]
andb #$03
F418: FD 00 DB  std     $00DB ;$db=d
stab X00E3
F41B: A6 0C     lda    (x+$0C) ;a=(byte)buffer[0xc]
ldx $00,x
F41D: B7 00 DD  sta     $00DD ;$dd=a //copy 13 bytes data do $d1
ldd X00C3
F420: 7F 00 E8  clr    $00E8 ;$e8=0x00 //index=0
std $00,x
F423: 7E F1 93  jmp    $F193 ;branch $f193
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 ?????
;command 0xc* - copy storage buffer[lower 2 bits] to 68k comm buffer, plus sets up for 0x0d data write
ldaa $B4,x
F426: B6 00 E7  lda    $00E7 ;a=$e7
inc X00EA
F429: 81 FF      cmpa    #$FF ;a==0xff?
; OIM OR Immediate $01 with RAM $F1 (P10 high, enable TX buffer in 75176)
F42B: 27 A9      beq    $F3D6 ;yes? => branch f3d6 //error
ldab X00F1 ; Status ?
stab X0002 ; Port1 data
staa X0013 ; Transmit register
LF33F:
jmp LF056


Command9:
F42D: B6 00 E9  lda    $00E9 ;a=$e9 //port3 data
sei
F430: 16        tab ;b=a
ldx #$0080
F431: 84 0C      anda    #$0C ;a&=0x0c //keep bit#3 & bit#2
LF346:
F433: 26 A1      bne     $F3D6 ;!=0? => branch $f3d6 //error
clr $7F,x
dex
bne LF346
jmp LF000


Command0:
F435: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
; AIM AND Immediate $EF with RAM $F1
F438: B6 00 F1  lda    $00F1 ;$a=f1
ldaa X00F1 ; Status ?
F43B: 97 02      sta    $02 ;port1=a //update status port
staa X0002 ; Port1 data
jmp LF193


Command2:
F43D: C4 03      andb    #$03 ;b&=0x03 //keep bit#1 & bit#0
ldaa X00E7 ; Output code
F43F: CE F4 FA  ldx    #$F4FA ;x=data table
staa X0007 ; Port4 data (output code)
F442: 3A        abx ;x+=b
; AIM AND Immediate $EF with RAM $F1
F443: 3A        abx ;x+=b
ldaa X00F1 ; Status ?
F444: EE 00      ldx    (x+$00) ;x=(word)data[b] //buffer addr
staa X0002 ; Port1 data
jmp LF193


Command1:
F446: EC 00      ldd    (x+$00) ;d=(word)buffer[0]
ldaa X00E9 ; Input code
F448: FD 00 D1  std    $00D1 ;$d1=d
tab
F44B: EC 02      ldd    (x+$02) ;d=(word)buffer[1]
anda #$0C    ; Bits 2 and 3
F44D: FD 00 D3  std    $00D3 ;$d3=d
bne LF3D6
F450: EC 04      ldd    (x+$04) ;d=(word)buffer[2]
; AIM AND Immediate $EF with RAM $F1
F452: FD 00 D5  std    $00D5 ;$d5=d
ldaa X00F1 ; Status ?
F455: EC 06      ldd    (x+$06) ;d=(word)buffer[3]
staa X0002 ; Port1 data
F457: FD 00 D7  std    $00D7 ;$d7=d
andb #$03
F45A: EC 08      ldd    (x+$08) ;d=(word)buffer[4]
stab X00E7 ; Output code
F45C: FD 00 D9  std    $00D9 ;$d9=d
ldx #$F4FA
F45F: EC 0A      ldd     (x+$0A) ;d=(word)buffer[5]
abx    ; B+X -> X
F461: FD 00 DB  std    $00DB ;$db=d
abx    ; B+X -> X
F464: A6 0C      lda    (x+$0C) ;a=(byte)buffer[0xc]
ldd $00,x
F466: B7 00 DD  sta    $00DD ;$dd=a //copy 13 bytes data do $d1
std X00EE ; RAM $EE = $F4FA + X*2
F469: 4F        clra ;a=0x00
ldab #$01
F46A: B7 00 E8  sta    $00E8 ;$e8=a //index=0
ldaa X00E9 ; Input code
F46D: 4A        deca ;a=0xff
anda #$03
F46E: B7 00 F2  sta    $00F2 ;$f2=a //$f2=0xff
LF38F:
F471: 86 0D      lda    #$0D ;a=0x0d
deca
F473: B7 00 F3  sta    $00F3 ;f3=a //$f3=0x0d  sets up a write of 0x0d bytes
bmi LF396
F476: 7E F1 93  jmp    $F193 ;branch $f193
aslb
jmp LF38F
;
LF396:
orab X00E4
stab X00E4
jmp LF193


Command4:
;command 0x6* - move port3 data to $e8
ldaa X00E9 ; Input code
F479: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
anda #$0F
F47C: B6 00 F1  lda    $00F1 ;a=$f1
staa X00F3 ; RAM $F3 is lower nibble of input code
F47F: 97 02      sta    $02 ;port1=a //update status port
; AIM AND Immediate $EF with RAM $F1
F481: B6 00 E9  lda    $00E9 ;a=$e9 //port3 data
ldaa X00F1 ; Status ?
F484: B7 00 E8  sta    $00E8 ;$e8=a //buffer index=port3 data (0x6?), quite an overflow, supposed to be lower nibble only?
staa X0002 ; Port1 data
F487: 7E F1 93  jmp    $F193 ;branch $f193
ldaa #$FE
staa X00F2 ; RAM $F2 = $FE
jmp LF193


Command3/CommandA:
;command 0x7* - write $e4 to port4 (buffers usage bitflags)
ldaa X00E7 ; Output code
F48A: B6 00 E4  lda    $00E4 ;a=$e4
cmpa #$FF
F48D: 97 07      sta    $07 ;port4=a
beq LF3D6 ; Is $FF ? ->
F48F: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
ldaa X00E9 ; Input code
F492: B6 00 F1  lda    $00F1 ;a=$f1
anda #$0F
F495: 97 02      sta    $02 ;port1=a
staa X00F3 ; RAM $F3 is lower nibble of input code
F497: 7E F1 93  jmp    $F193 ;branch $f193
; 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:
;command 0x8* - write $e2 to port4 (error count)
; OIM OR Immediate $10 with RAM $F1 (set status bit 0)
F49A: B6 00 E2  lda    $00E2 ;a=$e2
ldaa X00F1 ; Status ?
F49D: 97 07      sta    $07 ;port4=a
staa X0002 ; Port1 data
F49F: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //clear bit#4
jmp LF193
F4A2: B6 00 F1  lda    $00F1 ;a=$f1
F4A5: 97 02      sta    $02 ;port1=a
F4A7: 7E F1 93  jmp    $F193 ;branch $f193


Command5: ; Similar to command 1
;command 0xb* - clear status bit#6 (framing error flag)
ldaa X00E9 ; Input code
F4AA: B6 00 F1   lda    $00F1 ;a=$f1
tab
F4AD: 84 BF      anda    #$BF ;a&=0xbf //clear bit#6
anda #$0C    ; Bits 2 and 3
F4AF: 71 EF F1  aim    #$EF,$F1 ;$f1&=0xef //useless - value overwritten on next instruction
bne LF3D6
F4B2: B7 00 F1  sta    $00F1 ;$f1=a
; AIM AND Immediate $EF with RAM $F1
F4B5: 97 02      sta    $02 ;port1=a
ldaa X00F1 ; Status ?
F4B7: 7E F1 93  jmp    $F193 ;branch $f193
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
;**************************** IRQ subs *****************************
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:
;SCI (RDRF + ORFE + TDRE) interrupt
; AIM AND Immediate $EF with RAM $F1
;in this program configuration, RDRF (8bit receive register is full) & ORFE (framing error) only
ldaa X00F1 ; Status ?
F4BA: 96 11      lda    $11 ;a=transmit/receive status (also clears flag)
staa X0002 ; Port1 data
F4BC: B7 00 EC  sta    $00EC ;$ec=a //$ec=SCI status
ldaa X00E9 ; Input code
F4BF: 96 12      lda    $12 ;a=received data
staa X00E8
F4C1: B7 00 ED  sta    $00ED ;$ed=a //$ed=SCI data
jmp LF193
F4C4: 7F 00 F0  clr    $00F0 ;$f0=0x00
F4C7: 72 02 EB  oim    #$02,$EB ;$eb|=0x02 //flag event
F4CA: 3B        rti ;return


Command7:
;/IRQ1 (or /IS3) interrupt
XF48A:
;/PORTWEL wired, basically triggers on 68000 data write to microcontroller (odd address)
ldaa X00E4
F4CB: 96 0F      lda    $0F ;a=port3 status (read to clear flag)
staa X0007 ; Port4 data (output code)
F4CD: 96 06      lda    $06 ;a=port3 data
; AIM AND Immediate $EF with RAM $F1
F4CF: B7 00 E9  sta    $00E9 ;$00e9=a //store written value
ldaa X00F1 ; Status ?
F4D2: 72 01 EB  oim    #$01,$EB ;$eb|=0x01 //flag event
staa X0002 ; Port1 data
F4D5: 3B        rti ;return
jmp LF193


Command8:
;/NMI / TRAP / TOF (timer overflow) / OCF (timer output compare) / ICF (timer interrupt capture) / Software interrupt (SW1)  interrupt
ldaa X00E2 ; Error counter ?
;TRAP only in this configuration?
staa X0007 ; Port4 data (output code)
F4D6: 7C 00 E2  inc    $00E2 ;$e2++
; AIM AND Immediate $EF with RAM $F1
F4D9: 3B        rti ;return
ldaa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193


CommandB:
;*******************************************************************
ldaa X00F1 ; Status ?
;****************************** Data *******************************
anda #$BF
;*******************************************************************
; AIM AND Immediate $EF with RAM $F1
staa X00F1 ; Status ?
staa X0002 ; Port1 data
jmp LF193


SC1:
;data, commands pointers (*16)
ldaa X0011 ; Read TRCS
F4DA: F3 4E
staa X00EC  ; Store
F4DC: F3 69
ldaa X0012 ; Receive register
F4DE: F3 59
staa X00ED ; Store received code
F4E0: F3 B7
clr X00F0
F4E2: F3 9F
; OIM OR Immediate $02 with RAM $EB (link receive flag)
F4E4: F3 E1
rti
F4E6: F4 79
F4E8: F4 8A
F4EA: F4 9A
F4EC: F3 42
F4EE: F3 B7
F4F0: F4 AA
F4F2: F4 26
F4F4: F3 D6
F4F6: F3 D6
F4F8: F3 D6


IRQ1:
;data, ram pointers
ldaa X000F  ; Clear port3 latch flag
F4FA: 00 80
ldaa X0006 ; Port3 data (input code)
F4FC: 00 8D
staa X00E9 ; Input code
F4FE: 00 9A
; OIM OR Immediate $01 with RAM $EB (CPU write flag)
F500: 00 A7
rti
F502: 00 B4
F504: 00 C2


XF4D6:
;F506 - FFED: FF fill
inc X00E2 ; Error counter ?
rti


XF4DA:
;*******************************************************************
; CPU command 0: $F34E Update status
;**************************** Vectors  *****************************
; 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:
FFEE: F4 D6 ;TRAP (opcode error)
;0080 008D 009A 00A7 00B4 00C2 FF...
FFF0: F4 BA ;SCI (RDRF + ORFE + TDRE)
FFF2: F4 D6 ;TOF (timer overflow)
FFF4: F4 D6 ;OCF (timer output compare)
FFF6: F4 D6 ;ICF (timer interrupt capture)
FFF8: F4 CB ;/IRQ1 (or /IS3)
FFFA: F4 D6 ;Software interrupt (SW1)
FFFC: F4 D6 ;/NMI
FFFE: F0 00 ;/RES


</syntaxhighlight>
</syntaxhighlight>
[[Category:Chips]]
[[Category:Cartridge systems]]

Latest revision as of 20:36, 2 March 2019

HD6301 chip. Picture courtesy of [MVS-Scans].

8bit Hitachi microcontroller used for multiplayer communication in cartridges like League Bowling.

Compatible with the Motorola 6803 but has additionnal instructions.

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...): https://github.com/neogeodev/COM-HD6301

Another take on it:

;Memory map (mode 7 operation):
;
;0000-001F: internal registers
;00 - Port 1 data direction *
;01 - Port 2 data direction *
;02 - Port 1 data
;03 - Port 2 data
;04 - Port 3 data direction *
;05 - Port 4 data direction *
;06 - Port 3 data
;07 - Port 4 data
;08 - Timer control and status
;09 - Counter (MSB)
;0a - Counter (LSB)
;0b - Output compare (MSB)
;0c - Output compare (LSB)
;0d - Input capture (MSB)
;0e - Input capture (LSB)
;0f - Port 3 control and status
;		{/IS3 flag|/IS3 /IRQ1 enable|-|OSS|latch enable|-|-|-}
;10 - Rate and mode control
;		{-|-|-|-|CC1|CC0|SS1|SS0}
;			SSx: SCI bit times & transfer rate
;			CCx: SCI format  & clock source
;11 - Transmit/receive control and status
;		{RDRF|ORFE|TDRE|RIE|RE|TIE|TE|WU}
;			WU: wake up
;			TE: transmit enable
;			TIE: transmit interrupt enable
;			RE: receive enable
;			RIE: receive interrupt enable
;			TDRE: transmit data register empty
;			ORFE: over run framing error
;			RDRF: receive data register full
;12 - Receive data
;13 - Transmit data
;14 - RAM control
;		{Standby|RAME|-|-|-|-|-|-}
;15-1F: reserved
;	* 1=output 0=input
;-------------------------
;0080-00FF: RAM (128B)
;-------------------------
;F000-FFFF: ROM (4KB)

;RAM map:

;$80-$8c: 13 bytes buffer
;$8d-$99: 13 bytes buffer
;$9a-$a6: 13 bytes buffer
;$a7-$b3: 13 bytes buffer
;storage buffers

;$b4-$c1: 1+13 bytes SCI data transmit buffer	
;$c2-$cf: 1+13 bytes SCI data receive buffer
;data is moved from/to storage buffers, 1st byte holds storage buffer #

;$d0-$dd: 14 bytes 68k comm buffer
;writes are done $d0 to $de, reads $d1 to $df

;$de: buffer #0 status	//0xff=free
;$df: buffer #1 status
;$e0: buffer #2 status
;$e1: buffer #3 status

;$e2: error count? (increased by framing error or TRAP)
;$e3: buffers table index (0-3). next buffer #?
;$e4: buffers in use bitflag (bit0-3) [0x01 / 0x02 / 0x04 / 0x08 ]
;$e5:	receipt buffer ($c2) index
;$e6: store port3 lower 2 bits in cmd#5, seemingly unused?
;$e7: current buffer #? (0-3, 0xff init)
;$e8: 68k comm buffer index?
;$e9: port3 written data
;$ea: transmit buffer ($b4) index
;$eb: bitflags
;		#0: IS3# occured (data written on port3)
;		#1: RDRF/ORFE occured (data received / framing error)
;		#2: ? (tr related) byte added in buffer for trasmission flag?
;$ec: SCI transmit/receive status ($11 copy)
;$ed :SCI received data ($12 copy)
;$ee(word) : current buffer address? (0x0080 / 0x008d / 0x009a / 0x00a7)
;$f0: main loop counter (SCI irq cleared)
;$f1: port1 data, bitflags
;		#0: 75176 DE pin
;		#4: general error report
;		#5: ? 68k comm buffer processing related
;		#6: framing error report
;		#7: 68k acknowledge bit (toggled after each processed write to port 3)
;$f2: port3 related flags. data is a cmd when 0x00 / 0xff=write buffer? / 0xfe=read buffer?
;$f3: port 3 related - read/write data count
;$f4-$f7: buffer indexes? SCI receive related?
;$f8-$ff: stack

;entry point
F000: 0F         sei				;disable interrupts
F001: 8E 00 FF   lds     #$00FF		;stack pointer = 0x00ff

;clear ram
F004: CE 00 80   ldx     #$0080		;x=0x0080
F007: 6F 7F      clr     (x+$7F)	;$(x+0x7f)=0x00
F009: 09         dex				;x--
F00A: 26 FB      bne     $F007		;loop if x>0

;init stage (timer regs 08 09 0a 0b 0c 0d 0e unused)
F00C: 86 40      lda     #$40
F00E: 97 14      sta     $14		;$14=0x40				//enable RAM (after clearing it, lolz)
F010: 86 04      lda     #$04
F012: 97 10      sta     $10		;$10=0x04				//rate/mode settings: 62.500 bauds?, NRZ format, internal clock, P22 unused, P23=serial input, P24=serial output
F014: 86 1A      lda     #$1A
F016: 97 11      sta     $11		;$11=0x1a				//transmit/receive settings: receive enable, receive interrupt enable, transmit enable, transmit interrupt disable
F018: 86 48      lda     #$48
F01A: 97 0F      sta     $0F		;$0f=0x48				//port3 settings: enable /IS3, output strobe on port3 read, latch enable
F01C: 96 11      lda     $11		;a=$11
F01E: 96 12      lda     $12		;a=$12 					//read t/r status register & data to clear flags
F020: 86 F1      lda     #$F1
F022: 97 00      sta     $00		;$00=0xf1				//port1 bits 76540 as output, 321 as input
F024: 86 00      lda     #$00
F026: 97 02      sta     $02		;$02=0x00				//port1 = 0x00
F028: 86 00      lda     #$00
F02A: 97 04      sta     $04		;$04=0x00				//port3 as input
F02C: 86 FF      lda     #$FF
F02E: 97 05      sta     $05		;$05=0xff				//port4 as output
F030: 96 06      lda     $06		;a=$06 					//read port3 to release latch
F032: 86 FF      lda     #$FF
F034: B7 00 E9   sta     $00E9		;$e9=0xff
F037: B7 00 DE   sta     $00DE		;$de=0xff
F03A: B7 00 DF   sta     $00DF		;$df=0xff
F03D: B7 00 E0   sta     $00E0		;$e0=0xff
F040: B7 00 E1   sta     $00E1		;$e1=0xff
F043: B7 00 B4   sta     $00B4		;$b4=0xff
F046: B7 00 C2   sta     $00C2		;$c2=0xff
F049: B7 00 E9   sta     $00E9		;$e9=0xff
F04C: B7 00 E7   sta     $00E7		;$e7=0xff
F04F: CC 00 80   ldd     #$0080
F052: FD 00 EE   std     $00EE		;(word)$ee=0x0080
F055: 0E         cli				;enable interrupts

;main loop
F056: 96 02      lda     $02		;a=port1 data
F058: 85 02      bita    #$02		;bit#1 set?
F05A: 27 33      beq     $F08F		;not set? =>branch $f08f

;resets+idle microcontroller while P11 is high (SLOTCS on MVS, grounded on NEOGEO)
F05C: 4F         clra
F05D: 97 02      sta     $02
F05F: B7 00 E2   sta     $00E2		;$e2=0x02
F062: B7 00 E5   sta     $00E5		;$e5=0x02
F065: B7 00 E8   sta     $00E8		;$e8=0x02
F068: B7 00 EA   sta     $00EA		;$ea=0x02
F06B: B7 00 EB   sta     $00EB		;$eb=0x02
F06E: B7 00 F1   sta     $00F1		;$f1=0x02
F071: B7 00 F2   sta     $00F2		;$f2=0x02
F074: B7 00 F3   sta     $00F3		;$f3=0x02
F077: 4A         deca
F078: B7 00 B4   sta     $00B4		;$b4=0x01
F07B: B7 00 C2   sta     $00C2		;$b2=0x01
F07E: B7 00 DE   sta     $00DE		;$de=0x01
F081: B7 00 DF   sta     $00DF		;$df=0x01
F084: B7 00 E0   sta     $00E0		;$e0=0x01
F087: B7 00 E1   sta     $00E1		;$e1=0x01
F08A: B7 00 E9   sta     $00E9		;$e9=0x01
F08D: 20 C7      bra     $F056		;loop to main

;bit #1 not set
F08F: 7C 00 F0   inc     $00F0		;$f0++
F092: B6 00 EB   lda     $00EB		;a=$eb
F095: 85 01      bita    #$01		;bit #0 set?		(port3 received data?)
F097: 26 03      bne     $F09C		;yes? =>branch $f09c
F099: 7E F1 93   jmp     $F193


;*******************************************************************
;****************** 68k comm processing (port 3) *******************
;*******************************************************************
;data has been written to port 3
F09C: 71 FE EB   aim     #$FE,$EB	;$eb &= 0xfe			//clear data_in flag
F09F: 75 80 F1   eim     #$80,$F1	;$f1 ^= 0x80			//toggle bit#7 to ack
F0A2: B6 00 F2   lda     $00F2		;a=$f2
F0A5: 26 10      bne     $F0B7		;not 0? => branch $f0b7

;************ received byte is a command **************
F0A7: F6 00 E9   ldb     $00E9		;b=$e9					//byte that has been written to port3
F0AA: C4 F0      andb    #$F0		;b &= 0xf0
F0AC: CE F4 DA   ldx     #$F4DA		;x=pointers table
F0AF: 54         lsrb
F0B0: 54         lsrb
F0B1: 54         lsrb				;b>>=3					//not >>=4 because word table
F0B2: 3A         abx				;x+=b
F0B3: EE 00      ldx     (x+$00)	;x=pointer data
F0B5: 6E 00      jmp     (x+$00)	;jump to ptr value		//jump fo funcs[port3 data upper nibble]

;************ received byte isn't a command ($f2!=0x00) **************
;(a holds $f2)
F0B7: 85 01      bita    #$01		;a bit#0?
F0B9: 27 23      beq     $F0DE		;not set? => branch $f0de

;$f2 bit#0 set (0xff) - buffer write ops
F0BB: F6 00 E8   ldb     $00E8		;b=$e8
F0BE: F1 00 F3   cmpb    $00F3		;b==$f3?
F0C1: 27 54      beq     $F117		;yes? => branch $f117
;$f2bit#0 set (0xff), $e8!=$f3
F0C3: CE 00 D0   ldx     #$00D0		;x=0x00d0
F0C6: 3A         abx				;x+=b					//x=0x00d0+$e8 (0xd0[$e8])
F0C7: B6 00 E9   lda     $00E9		;a=$e9 (port3 data)
F0CA: A7 00      sta     (x+$00)	;$x=a					//0xd0[$e8]=port3 data
F0CC: A6 01      lda     (x+$01)	;a=$x+1
F0CE: 97 07      sta     $07		;port4=a				//outputs 0xd0[$e8+1] to 68k
F0D0: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F0D3: B6 00 F1   lda     $00F1		;a=$f1
F0D6: 97 02      sta     $02		;port1=a				//update status
F0D8: 7C 00 E8   inc     $00E8		;$e8++					//index++
F0DB: 7E F1 93   jmp     $F193		;branch $f193

;----------
;$f2 bit#0 not set (0xfe) - buffer read ops
F0DE: F6 00 E8   ldb     $00E8		;b=$e8
F0E1: F1 00 F3   cmpb    $00F3		;b==$f3?
F0E4: 27 16      beq     $F0FC		;yes? => branch $f0fc
;$f2 bit#0 not set (0xfe), $e8!=$f3
F0E6: CE 00 D0   ldx     #$00D0		;x=0x00d0
F0E9: 3A         abx				;x+=b					//x=0x00d0+$e8  (0xd0[$e8])
F0EA: A6 01      lda     (x+$01)	;a=$x+1
F0EC: 97 07      sta     $07		;port4=a				//outputs 0xd0[$e8+1] to 68k
F0EE: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F0F1: B6 00 F1   lda     $00F1		;a=$f1
F0F4: 97 02      sta     $02		;port1=a				//status update
F0F6: 7C 00 E8   inc     $00E8		;$e8++					//increase index
F0F9: 7E F1 93   jmp     $F193		;branch $f193
;$f2 bit#0 not set (0xfe), $e8==$f3 (last read)
F0FC: CE 00 D0   ldx     #$00D0		;x=0x00d0
F0FF: 3A         abx				;x+=b					//x=0x00d0+$e8  (0xd0[$e8])
F100: A6 00      lda     (x+$00)	;a=$x			
F102: 43         coma				;a=~a
F103: 97 07      sta     $07		;port4=a				//outputs ~(0xd0[$e8]) to 68k
F105: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F108: B6 00 F1   lda     $00F1		;a=$f1
F10B: 97 02      sta     $02		;port1=a				//status update
F10D: 4F         clra				;a=0x00
F10E: B7 00 E8   sta     $00E8		;$e8=0x00				//index=0
F111: B7 00 F2   sta     $00F2		;$f2=0x00				//next port3 write is a command
F114: 7E F1 93   jmp     $F193		;branch $f193
;----------

;$f2 bit#0 set (0xff), $e8==$f3 (last write)
F117: 4F         clra				;a=0x00
F118: B7 00 F2   sta     $00F2		;$f2=0x00				//next port3 write is a command
F11B: CE 00 CF   ldx     #$00CF		;x=0x00cf
F11E: 3A         abx				;x+=b					//x+=$e8 content  0xcf[$e8]
F11F: A6 00      lda     (x+$00)	;a=(x)					//a=0xcf[$e8]
F121: 43         coma				;a=~a
F122: B1 00 E9   cmpa    $00E9		;a==$e9?				//port3 written data==~a ?
F125: 27 16      beq     $F13D		;yes? => branch $f13d
	;port3 written data!=~a
F127: A6 01      lda     (x+$01)	;a=(x+1)				//a=0xcf[$e8+1]
F129: 43         coma				;a=~a
F12A: 97 07      sta     $07		;$07=a					//port4=a   outputs ~(0xcf[$e8+1]) to 68k
F12C: 72 20 F1   oim     #$20,$F1	;$f1|=0x20				//set bit#5
F12F: 71 EF F1   aim     #$EF,$F1	;$f1&=0xf1				//clear bit#123
F132: B6 00 F1   lda     $00F1		;a=$f1
F135: 97 02      sta     $02		;port1=a				//status update
F137: 7F 00 E8   clr     $00E8		;$e8=0x00				//index=0
F13A: 7E F1 93   jmp     $F193		;branch $f193			//SCI block

;data==~a
F13D: F6 00 E7   ldb     $00E7		;b=$e7
F140: C1 FF      cmpb    #$FF		;b==0xff?
F142: 26 15      bne     $F159		;nope? => branch $f159
;need to pick a buffer
F144: A6 01      lda     (x+$01)	;a=$x+1
F146: 97 07      sta     $07		;port4=a				//output data
F148: 72 20 F1   oim     #$20,$F1	;$f1|=0x20				//set bit#5
F14B: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F14E: B6 00 F1   lda     $00F1		;a=$f1
F151: 97 02      sta     $02		;port1=a				//update status port
F153: 7F 00 E8   clr     $00E8		;$e8=0
F156: 7E F1 93   jmp     $F193		;branch $f193
;$e7!=0xff
F159: A6 01      lda     (x+$01)	;a=$x+1
F15B: 43         coma				;a=~a
F15C: 97 07      sta     $07		;port4=a				//output data
F15E: 4F         clra				;a=0x00
F15F: 18         xgdx				;d<->x
F160: 6F DE      clr     (x+$DE)	;$x+0xde=0x00
F162: 71 CF F1   aim     #$CF,$F1	;$f1&=0xcf				//clear bit#4 & bit #5
F165: B6 00 F1   lda     $00F1		;a=$f1
F168: 97 02      sta     $02		;port1=a				//update status port
F16A: 7F 00 E8   clr     $00E8		;$e8=0x00				//index=0
F16D: FE 00 EE   ldx     $00EE		;x=$ee

F170: FC 00 D0   ldd     $00D0		;d=$d0
F173: ED 00      std     (x+$00)	;$x=d
F175: FC 00 D2   ldd     $00D2		;d=$d2
F178: ED 02      std     (x+$02)	;$x+2=d
F17A: FC 00 D4   ldd     $00D4		;d=$d4
F17D: ED 04      std     (x+$04)	;$x+4=d
F17F: FC 00 D6   ldd     $00D6		;d=$d6
F182: ED 06      std     (x+$06)	;$x+6=d
F184: FC 00 D8   ldd     $00D8		;d=$d8
F187: ED 08      std     (x+$08)	;$x+8=d
F189: FC 00 DA   ldd     $00DA		;d=$da
F18C: ED 0A      std     (x+$0A)	;$x+0x0a=d
F18E: B6 00 DC   lda     $00DC		;a=$dc
F191: A7 0C      sta     (x+$0C)	;$x+0x0c=a				//copy 13 bytes


;*******************************************************************
;************************* SCI processing **************************
;*******************************************************************

F193: B6 00 EB   lda     $00EB		;a=$eb
F196: 85 02      bita    #$02		;a bit#1 set?  (RDRF/ORFE occured)
F198: 26 03      bne     $F19D		;set? => branch $f19d
F19A: 7E F2 57   jmp     $F257

;RDRF/ORFE occured ($eb bit#1 set)
F19D: 71 FD EB   aim     #$FD,$EB	;$eb&=0xfd				//clear bit#1
F1A0: F6 00 EC   ldb     $00EC		;b=$ec					//load status byte
F1A3: C5 40      bitb    #$40		;b bit#6?				//ORFE ?
F1A5: 26 07      bne     $F1AE		;set? => branch $f1ae
F1A7: C5 80      bitb    #$80		;b bit#7?				//RDRF ?
F1A9: 26 23      bne     $F1CE		;set? => branch $f1ce
F1AB: 7E F2 57   jmp     $F257		;branch $f257			//something else occured, skipping

;ORFE processing (framing error)			//resets SCI transmit and receive buffers
F1AE: 4F         clra				;a=0x00
F1AF: B7 00 E5   sta     $00E5		;$e5=a					//$e5=0x00
F1B2: B7 00 EA   sta     $00EA		;$ea=a					//$ea=0x00		T/R indexes=0
F1B5: 4A         deca				;a=0xff
F1B6: B7 00 C2   sta     $00C2		;$c2=a					//$c2=0xff
F1B9: B7 00 B4   sta     $00B4		;$b4=a					//$b4=0xff		clear buffer links
F1BC: 7C 00 E2   inc     $00E2		;$e2++					//error count++
F1BF: B6 00 F1   lda     $00F1		;a=$f1
F1C2: 8A 40      ora     #$40		;a|=0x40				//set bit#6
F1C4: 84 FE      anda    #$FE		;a&=0xfe				//clear bit#0
F1C6: B7 00 F1   sta     $00F1		;$f1=a
F1C9: 97 02      sta     $02		;port1=a				//update status (clear 75176 DE pin, report framing error)
F1CB: 7E F2 57   jmp     $F257		;branch $f257

;RDRF processing (receive register full)
F1CE: F6 00 E5   ldb     $00E5		;b=$e5					//receive buffer index
F1D1: C1 0D      cmpb    #$0D		;b==0x0d?				//going to fill last buffer space?
F1D3: 27 10      beq     $F1E5		;yes? => branch $f1e5

F1D5: 4F         clra				;a=0x00
F1D6: 18         xgdx				; d<->x					//x=buffer index
F1D7: B6 00 ED   lda     $00ED		;a=$ed					//SCI received data
F1DA: A7 C2      sta     (x+$C2)	;$x+0xc2=a				//receive buffer[index]=received data
F1DC: 7C 00 E5   inc     $00E5		;$e5++					//increase index
F1DF: 72 04 EB   oim     #$04,$EB	;$eb|=0x04				//set bit#2
F1E2: 7E F2 57   jmp     $F257		;branch $f257

;receive register full and receive buffer full
F1E5: 71 FE F1   aim     #$FE,$F1	;$f1&=0xfe				//clear bit#0
F1E8: B6 00 F1   lda     $00F1		;a=$f1
F1EB: 97 02      sta     $02		;port1=a				//update status (clear 75176 DE pin)
F1ED: 4F         clra				;a=0x00
F1EE: 18         xgdx				;d<->x					//x=0x000d
F1EF: B6 00 ED   lda     $00ED		;a=$ed					//SCI received data
F1F2: A7 C2      sta     (x+$C2)	;$x+0xc2=a				//$cf=received data (buffer now full)
F1F4: 4F         clra				;a=0x00
F1F5: B7 00 EA   sta     $00EA		;$ea=a					//$ea=0x00
F1F8: B7 00 E5   sta     $00E5		;$e5=a					//$e5=0x00
F1FB: 4A         deca				;a=0xff
F1FC: B7 00 B4   sta     $00B4		;$b4=a					//$b4=0xff, reset transmit buffer
F1FF: B6 00 C2   lda     $00C2		;a=$c2					//a=receive buffer status

F202: 84 03      anda    #$03		;a&=0x03
F204: 4C         inca				;a++					//a=($c2&0x03)+1
F205: C6 01      ldb     #$01		;b=0x01

F207: 58         aslb				;b<<=1
F208: 4A         deca				;a--
F209: 26 FC      bne     $F207		;loop 4 times			//b<<=4
F20B: 54         lsrb				;b>>=1					//b>>=1
F20C: FA 00 E4   orb     $00E4		;b|=$e4
F20F: F7 00 E4   stb     $00E4		;$e4=b					//$e4|=b		update buffer usage bit set
F212: F6 00 C2   ldb     $00C2		;b=$c2
F215: C4 03      andb    #$03		;b&=0x03				//b=$c2&0x03
F217: CE 00 F4   ldx     #$00F4		;x=0x00f4
F21A: 3A         abx				;x+=b
F21B: 6F 00      clr     (x+$00)	;$x=0x00				//$f4[b]=0x00
F21D: F1 00 E7   cmpb    $00E7		;b==$e7?
F220: 27 30      beq     $F252		;yes? => branch $f252

F222: CE F4 FA   ldx     #$F4FA		;x=data table
F225: 3A         abx				;x+=b
F226: 3A         abx				;x+=b
F227: 5C         incb				;b++
F228: C4 03      andb    #$03		;b&=0x03
F22A: F7 00 E3   stb     $00E3		;$e3=b					//store updated buffer#
F22D: EE 00      ldx     (x+$00)	;x=(word)data[b]		//x=buffer addr
F22F: FC 00 C3   ldd     $00C3		;d=$c3
F232: ED 00      std     (x+$00)	;(word)buffer[0]=d
F234: FC 00 C5   ldd     $00C5		;d=$c5
F237: ED 02      std     (x+$02)	;(word)buffer[1]=d
F239: FC 00 C7   ldd     $00C7		;d=$c7
F23C: ED 04      std     (x+$04)	;(word)buffer[2]=d
F23E: FC 00 C9   ldd     $00C9		;d=$c9
F241: ED 06      std     (x+$06)	;(word)buffer[3]=d
F243: FC 00 CB   ldd     $00CB		;d=$cb
F246: ED 08      std     (x+$08)	;(word)buffer[4]=d
F248: FC 00 CD   ldd     $00CD		;d=$cd
F24B: ED 0A      std     (x+$0A)	;(word)buffer[5]=d
F24D: B6 00 CF   lda     $00CF		;a=$cf
F250: A7 0C      sta     (x+$0C)	;(byte)buffer[0xc]=a	//copy receive buffer to storage buffer (13 bytes)
F252: 86 FF      lda     #$FF		;a=0xff
F254: B7 00 C2   sta     $00C2		;$c2=a					//$c2=0xff  (untie storage buffer)

;RDRF/ORFE didn't occur ($eb bit#1 not set) / after processing it
F257: B6 00 F0   lda     $00F0		;a=$f0
F25A: 81 28      cmpa    #$28		;a-0x28 (40)
F25C: 25 38      bcs     $F296		;a<0x28 ? => branch $f296

;main looped more than 40 times (after last RDRF/ORFE interrupt)
F25E: CE 00 F4   ldx     #$00F4		;x=0x00f4
F261: F6 00 E3   ldb     $00E3		;b=$e3
F264: 3A         abx				;x+=b					//x=0x00f4 + buffer table index (f4-f7)
F265: A6 00      lda     (x+$00)	;a=(x)
F267: 4C         inca				;a++
F268: 81 0A      cmpa    #$0A		;a==0x0a?				//index == 0x0a ?
F26A: 26 10      bne     $F27C		;nope? => branch $f27c

F26C: 86 01      lda     #$01		;a=0x01
F26E: 5C         incb				;b++
F26F: 48         asla				;a<<=1
F270: 5A         decb				;b--
F271: 26 FC      bne     $F26F		;!=0? => branch $f26f
F273: 44         lsra				;a>>=1					//a=buffer bitflag (0x08 / 0x04 / 0x02 / 0x01)
F274: 43         coma				;a=~a
F275: B4 00 E4   anda    $00E4		;a&=$e4
F278: B7 00 E4   sta     $00E4		;$e4=a					//clear buffer usage bit
F27B: 4F         clra				;a=0x00

F27C: A7 00      sta     (x+$00)	;(x)=a					//update index
F27E: 7C 00 E3   inc     $00E3		;$e3++					//next buffer#
F281: 71 03 E3   aim     #$03,$E3	;$e3&=0x03				//crop buffer#
F284: 4F         clra				;a=0x00
F285: B7 00 E5   sta     $00E5		;$e5=0x00				//$e5=0
F288: B7 00 EA   sta     $00EA		;$ea=0x00				//$ea=0
F28B: B7 00 F0   sta     $00F0		;$f0=0x00				//reset counter
F28E: 71 FE F1   aim     #$FE,$F1	;$f1&=0xfe				//clear bit#0	(75176 DE pin)
F291: B6 00 F1   lda     $00F1		;a=$f1
F294: 97 02      sta     $02		;port1=a				//update status

;$f0<=0x28
;main looped less than 40 times / continue
F296: 96 11      lda     $11		;t/r control & status
F298: 85 20      bita    #$20		;TDRE?
F29A: 27 6D      beq     $F309		;nope? => branch $f309	//transmit register not empty, exit
;transmit data register is empty, check for next byte to transmit
F29C: B6 00 B4   lda     $00B4		;a=$b4
F29F: 81 FF      cmpa    #$FF		;a==0xff?
F2A1: 26 66      bne     $F309		;no? => branch $f309	//transmit buffer not ready, exit

F2A3: 4F         clra				;a=0
F2A4: F6 00 E7   ldb     $00E7		;b=$e7					//current buffer#
F2A7: C1 FF      cmpb    #$FF		;b==$ff?
F2A9: 27 5E      beq     $F309		;yes? => branch $f309	//no current buffer selected, exit

F2AB: 18         xgdx				;d<->x
F2AC: E6 DE      ldb     (x+$DE)	;b=(x+0xde)				//b=$de[current buffer] (current buffer status)
F2AE: 26 59      bne     $F309		;!=0? branch $f309		//buffer status!=0, exit

F2B0: FA 00 EA   orb     $00EA		;b|=$ea
F2B3: FA 00 E5   orb     $00E5		;b|=$e5
F2B6: 26 51      bne     $F309		;!=0? branch $f309		//transmit/receive buffers index!=0, exit

F2B8: 18         xgdx				;d<->x
F2B9: F8 00 E3   eorb    $00E3		;b|=$e3					//b=$e7|$e3
F2BC: 26 4B      bne     $F309		;!=0? branch $f309		//not both 0, exit

F2BE: FE 00 EE   ldx     $00EE		;x=$00ee				//buffer addr
F2C1: EC 00      ldd     (x+$00)	;d=(word)buffer[0]
F2C3: FD 00 B5   std     $00B5		;$b5=d
F2C6: EC 02      ldd     (x+$02)	;d=(word)buffer[1]
F2C8: FD 00 B7   std     $00B7		;$b7=d
F2CB: EC 04      ldd     (x+$04)	;d=(word)buffer[2]
F2CD: FD 00 B9   std     $00B9		;$b9=d
F2D0: EC 06      ldd     (x+$06)	;d=(word)buffer[3]
F2D2: FD 00 BB   std     $00BB		;$bb=d
F2D5: EC 08      ldd     (x+$08)	;d=(word)buffer[4]
F2D7: FD 00 BD   std     $00BD		;$bd=d
F2DA: EC 0A      ldd     (x+$0A)	;d=(word)buffer[5]
F2DC: FD 00 BF   std     $00BF		;$bf=d
F2DF: A6 0C      lda     (x+$0C)	;a=(byte)buffer[0xc]
F2E1: B7 00 C1   sta     $00C1		;$c1=a					//copy work buffer into transmit buffer (13bytes)
F2E4: B6 00 E7   lda     $00E7		;a=$e7
F2E7: B7 00 B4   sta     $00B4		;$b4=a					//store buffer # we are holding

F2EA: 72 01 F1   oim     #$01,$F1	;$f1|=0x01				//set bit#0
F2ED: F6 00 F1   ldb     $00F1		;b=$f1
F2F0: D7 02      stb     $02		;port1=b				//update status (enable 75176 DE)

F2F2: 97 13      sta     $13		;transmit data=a		//transmit buffer #?
F2F4: 71 FB EB   aim     #$FB,$EB	;$eb&=0xfb				//clear bit#2
F2F7: 7C 00 EA   inc     $00EA		;$ea++					//inc index
F2FA: 7C 00 E3   inc     $00E3		;$e3++					//inc buffer#
F2FD: 71 03 E3   aim     #$03,$E3	;$e3&=0x03				//trim buffer#
F300: 4F         clra				;a=0x00
F301: F6 00 E7   ldb     $00E7		;$e7=b
F304: 18         xgdx				;d<->x
F305: 86 FF      lda     #$FF		;a=0xff
F307: A7 DE      sta     (x+$DE)	;(x+0xde)=0xff			//buffer status[buffer that was copied]=0xff

;transmits a byte if available then loop
F309: B6 00 EB   lda     $00EB		;a=$eb
F30C: 85 04      bita    #$04		;bit#2 set?				//new byte received?
F30E: 27 2F      beq     $F33F		;not set? => f33f		//loop back to main

F310: B6 00 F0   lda     $00F0		;a=$f0
F313: 81 0F      cmpa    #$0F		;a-0x0f					//main looped > 15 times without SCI irq?
F315: 25 28      bcs     $F33F		;a<0x0f? =>branch $f33f	//loop back to main

F317: B6 00 B4   lda     $00B4		;a=$b4
F31A: 81 FF      cmpa    #$FF		;a==0xff?				//nothing to transmit?
F31C: 27 21      beq     $F33F		;yes? => branch $f33f	//loop back to main

F31E: 96 11      lda     $11		;a= t/r status
F320: 85 20      bita    #$20		;TDRE set?				//transmit register available?
F322: 27 1B      beq     $F33F		;nope? => branch $f33f	//loop back to main

F324: F6 00 EA   ldb     $00EA		;b=$ea
F327: C1 0E      cmpb    #$0E		;b==0x0e?				//buffer fully transmitted?
F329: 27 14      beq     $F33F		;yes? => branch $f33f	//loop back to main

F32B: 71 FB EB   aim     #$FB,$EB	;$eb&=0xfb				//clear bit#2
F32E: 4F         clra				;a=0
F32F: 18         xgdx				;d<->x
F330: A6 B4      lda     (x+$B4)	;a=$x+0xb4				//a=transmit buffer[$ea]
F332: 7C 00 EA   inc     $00EA		;$ea++					//inc transmit buffer index
F335: 72 01 F1   oim     #$01,$F1	;$f1|=0x01				//set bit#0
F338: F6 00 F1   ldb     $00F1		;b=$f1
F33B: D7 02      stb     $02		;port1=b				//update status (enable 75176 DE)
F33D: 97 13      sta     $13		;transmit=a				//transmit a
F33F: 7E F0 56   jmp     $F056		;branch $f056			//loop back to main


;*******************************************************************
;**************************** commands *****************************
;*******************************************************************
;lbowl: 00 00 00.. 20 51
;command 0x9* - reset microcontroller
F342: 0F         sei				;disable interrupts
F343: CE 00 80   ldx     #$0080		;x=0x80
F346: 6F 7F      clr     (x+$7F)	;(x+0x7f)=0x00
F348: 09         dex				;x--
F349: 26 FB      bne     $F346		;loop of x>0			//clear RAM
F34B: 7E F0 00   jmp     $F000		;restart

;command 0x0* - dummy / clear error flag
F34E: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F351: B6 00 F1   lda     $00F1		;a=$f1
F354: 97 02      sta     $02		;port1=a
F356: 7E F1 93   jmp     $F193		;branch $f193

;command 0x2* - write $e7 to port4 (buffer# currently in use?)
F359: B6 00 E7   lda     $00E7		;a=$e7
F35C: 97 07      sta     $07		;port4=a
F35E: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F361: B6 00 F1   lda     $00F1		;a=$f1
F364: 97 02      sta     $02		;port1=a
F366: 7E F1 93   jmp     $F193		;branch $f193

;command 0x1* - select buffer[lower 2 bits] ?
F369: B6 00 E9   lda     $00E9		;a=$e9					//port3 data
F36C: 16         tab				;b=a
F36D: 84 0C      anda    #$0C		;a&=0x0c				//keep bit#3 & bit#2
F36F: 26 65      bne     $F3D6		;!=0? => branch $f3d6	//error if buffer#>3
F371: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F374: B6 00 F1   lda     $00F1		;a=$f1
F377: 97 02      sta     $02		;port1=a				//update status port

F379: C4 03      andb    #$03		;b&=0x03				//beep bit#1 & bit#0
F37B: F7 00 E7   stb     $00E7		;$e7=b					//store buffer# in use?
F37E: CE F4 FA   ldx     #$F4FA		;x=data table
F381: 3A         abx				;x+=b
F382: 3A         abx				;x+=b
F383: EC 00      ldd     (x+$00)	;d=(word)data[b]		//x=buffer[lower 2 bits]
F385: FD 00 EE   std     $00EE		;(word)$ee=d			//store current buffer addr
F388: C6 01      ldb     #$01		;b=0x01
F38A: B6 00 E9   lda     $00E9		;a=$e9					//port3 data
F38D: 84 03      anda    #$03		;a&=0x03				//keep bit#1 & bit#0
F38F: 4A         deca				;a--
F390: 2B 04      bmi     $F396		;<0? => branch $f396
F392: 58         aslb				;b<<=1
F393: 7E F3 8F   jmp     $F38F		;loop
F396: FA 00 E4   orb     $00E4		;b|=$e4
F399: F7 00 E4   stb     $00E4		;$e4=b					//$e4|=(0x01<<buffer#)	flag as in use
F39C: 7E F1 93   jmp     $F193		;branch $f193

;command 0x4* - $f3=lower nibble, $f2=0xfe
;sets up a read of x (lower nibble) values?
F39F: B6 00 E9   lda     $00E9		;a=$e9					//port 3 data
F3A2: 84 0F      anda    #$0F		;a&=0x0f
F3A4: B7 00 F3   sta     $00F3		;$f3=a					//store lower nibble
F3A7: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F3AA: B6 00 F1   lda     $00F1		;a=$f1
F3AD: 97 02      sta     $02		;port1=a				//update status port
F3AF: 86 FE      lda     #$FE		;a=0xfe
F3B1: B7 00 F2   sta     $00F2		;$f2=a					//$f2=0xfe
F3B4: 7E F1 93   jmp     $F193		;branch $f193

;command 0x3*, 0xa* - if($e7!=0xff) $f3=lower nibble, $f2=0xff
;sets up a write of x (lower nibble) values?
F3B7: B6 00 E7   lda     $00E7		;a=$e7
F3BA: 81 FF      cmpa    #$FF		;==0xff?
F3BC: 27 18      beq     $F3D6		;yes? => branch $f3d6	//branch to error if $e7==0xff (no buffer selected)
F3BE: B6 00 E9   lda     $00E9		;a=$e9					//port3 data
F3C1: 84 0F      anda    #$0F		;a&=0x0f
F3C3: B7 00 F3   sta     $00F3		;$f3=a					//store lower nibble
F3C6: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F3C9: B6 00 F1   lda     $00F1		;a=$f1
F3CC: 97 02      sta     $02		;port1=a				//update status port
F3CE: 86 FF      lda     #$FF		;a=0xff
F3D0: B7 00 F2   sta     $00F2		;$f2=a					//$f2=0xff
F3D3: 7E F1 93   jmp     $F193		;branch $f193

;command 0xd*, 0xe*, 0xf* - issue error
F3D6: 72 10 F1   oim     #$10,$F1	;$f1|=0x10				//sets bit#4
F3D9: B6 00 F1   lda     $00F1		;a=$f1
F3DC: 97 02      sta     $02		;port1=a
F3DE: 7E F1 93   jmp     $F193		;branch $f193

;command 0x5* - copy storage buffer[lower 2 bits] to 68k comm buffer
F3E1: B6 00 E9   lda     $00E9		;a=$e9					//port 3 data
F3E4: 16         tab				;b=a
F3E5: 84 0C      anda    #$0C		;a&=0x0c				//keep bit#3 & bit#2
F3E7: 26 ED      bne     $F3D6		;!=0? => branch $f3d6	//error

F3E9: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F3EC: B6 00 F1   lda     $00F1		;a=$f1
F3EF: 97 02      sta     $02		;port1=a				//update status port

F3F1: C4 03      andb    #$03		;b&=0x03				//keep bit#1 & bit#0
F3F3: F7 00 E6   stb     $00E6		;$e6=b
F3F6: CE F4 FA   ldx     #$F4FA		;x=data table
F3F9: 3A         abx				;x+=b
F3FA: 3A         abx				;x+=b
F3FB: EE 00      ldx     (x+$00)	;x=(word)data[b]		//buffer addr

F3FD: EC 00      ldd     (x+$00)	;d=(word)buffer[0]
F3FF: FD 00 D1   std     $00D1		;$d1=d
F402: EC 02      ldd     (x+$02)	;d=(word)buffer[1]
F404: FD 00 D3   std     $00D3		;$d3=d
F407: EC 04      ldd     (x+$04)	;d=(word)buffer[2]
F409: FD 00 D5   std     $00D5		;$d5=d
F40C: EC 06      ldd     (x+$06)	;d=(word)buffer[3]
F40E: FD 00 D7   std     $00D7		;$d7=d
F411: EC 08      ldd     (x+$08)	;d=(word)buffer[4]
F413: FD 00 D9   std     $00D9		;$d9=d
F416: EC 0A      ldd     (x+$0A)	;d=(word)buffer[5]
F418: FD 00 DB   std     $00DB		;$db=d
F41B: A6 0C      lda     (x+$0C)	;a=(byte)buffer[0xc]
F41D: B7 00 DD   sta     $00DD		;$dd=a					//copy 13 bytes data do $d1
F420: 7F 00 E8   clr     $00E8		;$e8=0x00				//index=0
F423: 7E F1 93   jmp     $F193		;branch $f193

;command 0xc* - copy storage buffer[lower 2 bits] to 68k comm buffer, plus sets up for 0x0d data write
F426: B6 00 E7   lda     $00E7		;a=$e7
F429: 81 FF      cmpa    #$FF		;a==0xff?
F42B: 27 A9      beq     $F3D6		;yes? => branch f3d6	//error

F42D: B6 00 E9   lda     $00E9		;a=$e9					//port3 data
F430: 16         tab				;b=a
F431: 84 0C      anda    #$0C		;a&=0x0c				//keep bit#3 & bit#2
F433: 26 A1      bne     $F3D6		;!=0? => branch $f3d6	//error

F435: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F438: B6 00 F1   lda     $00F1		;$a=f1
F43B: 97 02      sta     $02		;port1=a				//update status port

F43D: C4 03      andb    #$03		;b&=0x03				//keep bit#1 & bit#0
F43F: CE F4 FA   ldx     #$F4FA		;x=data table
F442: 3A         abx				;x+=b
F443: 3A         abx				;x+=b
F444: EE 00      ldx     (x+$00)	;x=(word)data[b]		//buffer addr

F446: EC 00      ldd     (x+$00)	;d=(word)buffer[0]
F448: FD 00 D1   std     $00D1		;$d1=d
F44B: EC 02      ldd     (x+$02)	;d=(word)buffer[1]
F44D: FD 00 D3   std     $00D3		;$d3=d
F450: EC 04      ldd     (x+$04)	;d=(word)buffer[2]
F452: FD 00 D5   std     $00D5		;$d5=d
F455: EC 06      ldd     (x+$06)	;d=(word)buffer[3]
F457: FD 00 D7   std     $00D7		;$d7=d
F45A: EC 08      ldd     (x+$08)	;d=(word)buffer[4]
F45C: FD 00 D9   std     $00D9		;$d9=d
F45F: EC 0A      ldd     (x+$0A)	;d=(word)buffer[5]
F461: FD 00 DB   std     $00DB		;$db=d
F464: A6 0C      lda     (x+$0C)	;a=(byte)buffer[0xc]
F466: B7 00 DD   sta     $00DD		;$dd=a					//copy 13 bytes data do $d1
F469: 4F         clra				;a=0x00
F46A: B7 00 E8   sta     $00E8		;$e8=a					//index=0
F46D: 4A         deca				;a=0xff
F46E: B7 00 F2   sta     $00F2		;$f2=a					//$f2=0xff
F471: 86 0D      lda     #$0D		;a=0x0d
F473: B7 00 F3   sta     $00F3		;f3=a					//$f3=0x0d  sets up a write of 0x0d bytes
F476: 7E F1 93   jmp     $F193		;branch $f193

;command 0x6* - move port3 data to $e8
F479: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F47C: B6 00 F1   lda     $00F1		;a=$f1
F47F: 97 02      sta     $02		;port1=a				//update status port
F481: B6 00 E9   lda     $00E9		;a=$e9					//port3 data
F484: B7 00 E8   sta     $00E8		;$e8=a					//buffer index=port3 data (0x6?), quite an overflow, supposed to be lower nibble only?
F487: 7E F1 93   jmp     $F193		;branch $f193

;command 0x7* - write $e4 to port4 (buffers usage bitflags)
F48A: B6 00 E4   lda     $00E4		;a=$e4
F48D: 97 07      sta     $07		;port4=a
F48F: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F492: B6 00 F1   lda     $00F1		;a=$f1
F495: 97 02      sta     $02		;port1=a
F497: 7E F1 93   jmp     $F193		;branch $f193

;command 0x8* - write $e2 to port4 (error count)
F49A: B6 00 E2   lda     $00E2		;a=$e2
F49D: 97 07      sta     $07		;port4=a
F49F: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//clear bit#4
F4A2: B6 00 F1   lda     $00F1		;a=$f1
F4A5: 97 02      sta     $02		;port1=a
F4A7: 7E F1 93   jmp     $F193		;branch $f193

;command 0xb* - clear status bit#6 (framing error flag)
F4AA: B6 00 F1   lda     $00F1		;a=$f1
F4AD: 84 BF      anda    #$BF		;a&=0xbf				//clear bit#6
F4AF: 71 EF F1   aim     #$EF,$F1	;$f1&=0xef				//useless - value overwritten on next instruction
F4B2: B7 00 F1   sta     $00F1		;$f1=a
F4B5: 97 02      sta     $02		;port1=a
F4B7: 7E F1 93   jmp     $F193		;branch $f193

;*******************************************************************
;**************************** IRQ subs *****************************
;*******************************************************************

;SCI (RDRF + ORFE + TDRE) interrupt
;in this program configuration, RDRF (8bit receive register is full) & ORFE (framing error) only
F4BA: 96 11      lda     $11		;a=transmit/receive status (also clears flag)
F4BC: B7 00 EC   sta     $00EC		;$ec=a					//$ec=SCI status
F4BF: 96 12      lda     $12		;a=received data
F4C1: B7 00 ED   sta     $00ED		;$ed=a					//$ed=SCI data
F4C4: 7F 00 F0   clr     $00F0		;$f0=0x00
F4C7: 72 02 EB   oim     #$02,$EB	;$eb|=0x02				//flag event
F4CA: 3B         rti				;return

;/IRQ1 (or /IS3) interrupt
;/PORTWEL wired, basically triggers on 68000 data write to microcontroller (odd address)
F4CB: 96 0F      lda     $0F		;a=port3 status (read to clear flag)
F4CD: 96 06      lda     $06		;a=port3 data
F4CF: B7 00 E9   sta     $00E9		;$00e9=a				//store written value
F4D2: 72 01 EB   oim     #$01,$EB	;$eb|=0x01				//flag event
F4D5: 3B         rti				;return

;/NMI / TRAP / TOF (timer overflow) / OCF (timer output compare) / ICF (timer interrupt capture) / Software interrupt (SW1)  interrupt
;TRAP only in this configuration?
F4D6: 7C 00 E2   inc     $00E2		;$e2++
F4D9: 3B         rti				;return

;*******************************************************************
;****************************** Data *******************************
;*******************************************************************

;data, commands pointers (*16)
F4DA: F3 4E
F4DC: F3 69
F4DE: F3 59
F4E0: F3 B7
F4E2: F3 9F
F4E4: F3 E1
F4E6: F4 79
F4E8: F4 8A
F4EA: F4 9A
F4EC: F3 42
F4EE: F3 B7
F4F0: F4 AA
F4F2: F4 26
F4F4: F3 D6
F4F6: F3 D6
F4F8: F3 D6

;data, ram pointers
F4FA: 00 80
F4FC: 00 8D
F4FE: 00 9A
F500: 00 A7
F502: 00 B4
F504: 00 C2

;F506 - FFED:  FF fill

;*******************************************************************
;**************************** Vectors  *****************************
;*******************************************************************

FFEE: F4 D6		;TRAP (opcode error)
FFF0: F4 BA		;SCI (RDRF + ORFE + TDRE)
FFF2: F4 D6		;TOF (timer overflow)
FFF4: F4 D6		;OCF (timer output compare)
FFF6: F4 D6		;ICF (timer interrupt capture)
FFF8: F4 CB		;/IRQ1 (or /IS3) 
FFFA: F4 D6		;Software interrupt (SW1)
FFFC: F4 D6		;/NMI
FFFE: F0 00		;/RES