HD6301V1
Jump to navigation
Jump to search
![](/images/thumb/0/0e/Crt_hd6301.jpg/300px-Crt_hd6301.jpg)
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