From NeoGeo Development Wiki
Jump to navigation Jump to search
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).


Official datasheet: [[1]]


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
;			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

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
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

;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)
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