HD6301V1

From NeoGeo Development Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
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