HD6301V1

From NeoGeo Development Wiki
(Redirected from HD6301)
Jump to: navigation, 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).

Datasheet

Official datasheet: [[1]]

Code

The HD6301 has an internal 4KB ROM section holding program data.

A dump is available, coming from a prototype Riding Hero cart: File:HD6301.zip (2x overdump) - Credits to NeoTurfMasta

Commented source code (still some work left...):

;Vectors:
;TRAP:	F4D6 (error)
;SC1:	F4BA (link receive)
;TOF:	F4D6 (error)
;OCF:	F4D6 (error)
;ICF:	F4D6 (error)
;IRQ1:	F4CB (CPU write)
;SWI:	F4D6 (error)
;NMI:	F4D6 (error)
;RESET:	F000 (start)

;RAM:
;$C2 start of message buffer (14 bytes ?)

;$D0~$D1
;$D2~$D3
;$D4~$D5
;$D6~$D7
;$D8~$D9
;$DA~$DB
;$DC

;$E2 is an error counter ?
;$E3 some counter ? -----------------
;$E4 some bitmask ? -----------------
;$E5 is receive byte counter
;$E6 ?
;$E7 is the output code (read by CPU)
;$E8 related to $F3 ?
;$E9 is the input code (wrote by CPU)
;$EA another byte counter ?
;$EB bit 0 is CPU write flag ? (data ready in $E9), bit 1 is link receive flag
;$EC is TRCS register copy
;$ED is the received code (link)
;$EE~$EF buffer (FIFO ?) pointer
;$F0 receive timeout timer
;$F1 is status code/port1 mirror
;$F2 some bitmask ? -----------------
;$F3 is lower nibble of input code (parameter ?)
;$F4 start of some short buffer ?

;Status bit 0 (D8) is command error (D,E,F: wrong command)
;Status bit 2 (D10) is overrun receive error

	org	$F000
; RESET
LF000:
	sei

	lds	#$00FF	; Clear RAM
	ldx	#$0080
LF007:
	clr	$7F,x
	dex
	bne	LF007

	ldaa	#$40	; Enable RAM (lol)
	staa	X0014
	ldaa	#$04	; 62500bps internal clock
	staa	X0010
	ldaa	#$1A	; RIE, RXE, TXE
	staa	X0011
	ldaa	#$48	; Port3 IS3/IRQ1 enable, latch enable
	staa	X000F
	ldaa	X0011   ; Clear TRCS flags
	ldaa	X0012	; Receive register
	ldaa	#$F1	; Port1 direction 11110001
	staa	X0000
	ldaa	#$00	; Port1 data
	staa	X0002
	ldaa	#$00	; Port3 direction (inputs)
	staa	X0004
	ldaa	#$FF	; Port4 direction (outputs)
	staa	X0005
	ldaa	X0006	; Clear port3 latch
	ldaa	#$FF	; $FF to RAM $E9, $DE, $DF, $E0, $E1, $B4, $C2, $E9, $E7
	staa	X00E9	; Input code
	staa	X00DE
	staa	X00DF
	staa	X00E0
	staa	X00E1
	staa	X00B4
	staa	X00C2
	staa	X00E9	; Input code (again...)
	staa	X00E7	; Output code
	ldd	#$0080
	std	X00EE	; RAM $EE = $0080
	cli

LF056:
	ldaa	X0002	; Read port1
	bita	#$02    ; P11 is nSLOTCS ($02 is a mask, not a bit number)
	beq	LF08F   ; Slot is enabled ->
	clra
	staa	X0002	; Clear port1
	staa	X00E2	; Clear error counter ?
	staa	X00E5	; Reset byte counter
	staa	X00E8
	staa	X00EA
	staa	X00EB	; Clear flags
	staa	X00F1	; Clear status ?
	staa	X00F2
	staa	X00F3
	deca
	staa	X00B4	; $FF in RAM...
	staa	X00C2
	staa	X00DE
	staa	X00DF
	staa	X00E0
	staa	X00E1
	staa	X00E9	; Input code
	bra	LF056	; Loop until slot is enabled

; Slot enabled
LF08F:
	inc	X00F0	; $F0 starts at 0, now 1
	ldaa	X00EB	; Got a byte from CPU ?
	bita	#$01
	bne	LF09C   ; Yup ->
	jmp	LF193	; Nope ->

; Process CPU write
LF09C:
	; AIM AND Immediate $FE with RAM $EB (clear CPU write flag)
	; EIM XOR Immediate $80 with RAM $F1 (toggle status bit 3)
	ldaa	X00F2
	bne	LF0B7
	ldab	X00E9	; Input code
	andb	#$F0    ; Upper nibble is index in jump table
	ldx	#$F4DA
	lsrb            ; 0BBBB000
	lsrb            ; 00BBBB00
	lsrb            ; 000BBBB0
	abx     	; B+X -> X
	ldx	$00,x
	jmp	$00,x	; Index jump

;
LF0B7:
	bita	#$01
	beq	LF0DE
	ldab	X00E8
	cmpb	X00F3
	beq	LF117
	ldx	#$00D0
	abx     	; B+X -> X
	ldaa	X00E9	; Input code
	staa	$00,x
	ldaa	$01,x
	staa	X0007	; Port4 data (output code)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	inc	X00E8
	jmp	LF193
;
LF0DE:
	ldab	X00E8
	cmpb	X00F3
	beq	LF0FC
	ldx	#$00D0
	abx     	; B+X -> X
	ldaa	$01,x
	staa	X0007	; Port4 data (output code)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	inc	X00E8
	jmp	LF193
;
LF0FC:
	ldx	#$00D0
	abx     	; B+X -> X
	ldaa	$00,x
	coma
	staa	X0007	; Port4 data (output code)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	clra
	staa	X00E8
	staa	X00F2
	jmp	LF193
;
LF117:
	clra
	staa	X00F2
	ldx	#$00CF
	abx     	; B+X -> X
	ldaa	$00,x
	coma
	cmpa	X00E9	; Input code
	beq	LF13D
	ldaa	$01,x
	coma
	staa	X0007	; Port4 data (output code)
	; OIM OR Immediate $20 with RAM $F1 (set status bit 1)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	clr	X00E8
	jmp	LF193
;
LF13D:
	ldab	X00E7	; Output code
	cmpb	#$FF
	bne	LF159
	ldaa	$01,x
	staa	X0007	; Port4 data (output code)
	; OIM OR Immediate $20 with RAM $F1 (set status bit 1)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	clr	X00E8
	jmp	LF193
;
LF159:
	ldaa	$01,x
	coma
	staa	X0007	; Port4 data (output code)
	clra
	xgdx	?????
	clr	$DE,x
;
	; AIM AND Immediate $CF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	clr	X00E8
	ldx	X00EE
	ldd	X00D0
	std	$00,x
	ldd	X00D2
	std	$02,x
	ldd	X00D4
	std	$04,x
	ldd	X00D6
	std	$06,x
	ldd	X00D8
	std	$08,x
	ldd	X00DA
	std	$0A,x
	ldaa	X00DC
	staa	$0C,x
LF193:
	ldaa	X00EB	; Got a byte from link ?
	bita	#$02
	bne	LF19D	; Yup ->
	jmp	LF257   ; Nope ->

; Process link receive
LF19D:
	; AIM AND Immediate $FD (11111101) with RAM $EB
	ldab	X00EC
	bitb	#$40	; Overrun framing error ?
	bne	LF1AE	; Yup ->
	bitb	#$80	; Receive data register full ?
	bne	LF1CE	; Yup ->
	jmp	LF257

; Overrun framing error
LF1AE:
	clra
	staa	X00E5	; Reset byte counter
	staa	X00EA
	deca
	staa	X00C2
	staa	X00B4
	inc	X00E2	; Error counter ?
	ldaa	X00F1	; Status ?
	oraa	#$40    ; Set status bit 2
	anda	#$FE	; Mask out P10, just in case (transmit enable, not status)
	staa	X00F1	; Status ?
	staa	X0002	; Port1 data
	jmp	LF257

; Got byte ok
LF1CE:
	ldab	X00E5	; Byte counter
	cmpb	#$0D
	beq	LF1E5	; Already got 13 bytes ? ->
	clra
	xgdx	?????
	ldaa	X00ED	; Received code
	staa	$C2,x	; Store in list @ $C2+x
	inc	X00E5	; Byte counter
	; OIM OR Immediate $04 with RAM $EB
	jmp	LF257

; Got message OK
LF1E5:
	; AIM AND Immediate $FE with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	clra
	xgdx	?????
	ldaa	X00ED	; Received code
	staa	$C2,x   ; Store 14th byte (the last)
	clra
	staa	X00EA
	staa	X00E5	; Reset byte counter
	deca
	staa	X00B4

	ldaa	X00C2	; RAM $C2 (first byte of message) & 3: 0~3 -> 1~4, gives B=$02,$04,$08,$10
	anda	#$03
	inca
	ldab	#$01
LF207:
	aslb
	deca
	bne	LF207
	lsrb		; B=$01,$02,$04,$08
	orab	X00E4
	stab	X00E4

	ldab	X00C2
	andb	#$03
	ldx	#$00F4
	abx     	; X = $00F4 + (RAM $C2 & 3)
	clr	$00,x
	cmpb	X00E7	; Output code
	beq	LF252
	ldx	#$F4FA
	abx     	; B+X -> X
	abx     	; B+X -> X
	incb
	andb	#$03
	stab	X00E3
	ldx	$00,x
	ldd	X00C3
	std	$00,x
	ldd	X00C5
	std	$02,x
	ldd	X00C7
	std	$04,x
	ldd	X00C9
	std	$06,x
	ldd	X00CB
	std	$08,x
	ldd	X00CD
	std	$0A,x
	ldaa	X00CF
	staa	$0C,x
LF252:
	ldaa	#$FF
	staa	X00C2
LF257:
	ldaa	X00F0
	cmpa	#$28
	bcs	LF296
	ldx	#$00F4
	ldab	X00E3
	abx     	; B+X -> X
	ldaa	$00,x
	inca
	cmpa	#$0A
	bne	LF27C
	ldaa	#$01
	incb
LF26F:
	asla
	decb
	bne	LF26F
	lsra
	coma
	anda	X00E4
	staa	X00E4
	clra
LF27C:
	staa	$00,x
	inc	X00E3
	; AIM AND Immediate $03 with RAM $E3
	clra
	staa	X00E5	; Reset byte counter
	staa	X00EA
	staa	X00F0
	; AIM AND Immediate $FE with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
LF296:
	ldaa	X0011	; Read TRCS
	bita	#$20    ; Transmit register empty ?
	beq	LF309   ; Nope ->
	ldaa	X00B4
	cmpa	#$FF
	bne	LF309
	clra
	ldab	X00E7	; Output code
	cmpb	#$FF
	beq	LF309
	xgdx	?????
	ldab	$DE,x
	bne	LF309
	orab	X00EA
	orab	X00E5	; Byte counter
	bne	LF309
	xgdx	?????
	eorb	X00E3
	bne	LF309
	ldx	X00EE	; X=$00EE
	ldd	$00,x
	std	X00B5	; RAM $B5 <- RAM $EE
	ldd	$02,x
	std	X00B7	; RAM $B7 <- RAM $F0
	ldd	$04,x
	std	X00B9	; RAM $B9 <- RAM $F2
	ldd	$06,x
	std	X00BB	; RAM $BB <- RAM $F4
	ldd	$08,x
	std	X00BD	; RAM $BD <- RAM $F6
	ldd	$0A,x
	std	X00BF	; RAM $BF <- RAM $F8
	ldaa	$0C,x
	staa	X00C1	; RAM $C1 <- RAM $FA
	ldaa	X00E7	; Output code
	staa	X00B4
	; OIM OR Immediate $01 with RAM $F1 (P10 high, enable TX buffer in 75176)
	ldab	X00F1	; Status ?
	stab	X0002	; Port1 data
	staa	X0013	; Transmit register
;
	; AIM AND Immediate $FB with RAM $EB
	inc     X00EA
	inc     X00E3
	; AIM AND Immediate $03 with RAM $E3
	clra
	ldab	X00E7	; Output code
	xgdx	?????
	ldaa	#$FF
	staa	$DE,x
LF309:
	ldaa	X00EB
	bita	#$04
	beq	LF33F
	ldaa	X00F0
	cmpa	#$0F
	bcs	LF33F
	ldaa	X00B4
	cmpa	#$FF
	beq	LF33F
	ldaa	X0011	; Read TRCS
	bita	#$20    ; Transmit register empty ?
	beq	LF33F	; Nope ->
	ldab	X00EA
	cmpb	#$0E
	beq	LF33F
;
	; AIM AND Immediate $FB with RAM $EB
	clra

	xgdx	?????
	ldaa	$B4,x
	inc	X00EA
	; OIM OR Immediate $01 with RAM $F1 (P10 high, enable TX buffer in 75176)
	ldab	X00F1	; Status ?
	stab	X0002	; Port1 data
	staa	X0013	; Transmit register
LF33F:
	jmp	LF056

Command9:
	sei
	ldx	#$0080
LF346:
	clr	$7F,x
	dex
	bne	LF346
	jmp	LF000

Command0:
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	jmp	LF193

Command2:
	ldaa	X00E7	; Output code
	staa	X0007	; Port4 data (output code)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	jmp	LF193

Command1:
	ldaa	X00E9	; Input code
	tab
	anda	#$0C    ; Bits 2 and 3
	bne	LF3D6
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	andb	#$03
	stab	X00E7	; Output code
	ldx	#$F4FA
	abx     	; B+X -> X
	abx     	; B+X -> X
	ldd	$00,x
	std	X00EE	; RAM $EE = $F4FA + X*2
	ldab	#$01
	ldaa	X00E9	; Input code
	anda	#$03
LF38F:
	deca
	bmi	LF396
	aslb
	jmp	LF38F
;
LF396:
	orab	X00E4
	stab	X00E4
	jmp	LF193

Command4:
	ldaa	X00E9	; Input code
	anda	#$0F
	staa	X00F3	; RAM $F3 is lower nibble of input code
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	ldaa	#$FE
	staa	X00F2	; RAM $F2 = $FE
	jmp	LF193

Command3/CommandA:
	ldaa	X00E7	; Output code
	cmpa	#$FF
	beq	LF3D6	; Is $FF ? ->
	ldaa	X00E9	; Input code
	anda	#$0F
	staa	X00F3	; RAM $F3 is lower nibble of input code
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	ldaa	#$FF
	staa	X00F2	; RAM $F2 = $FF
	jmp	LF193

CommandD/E/F:
	; OIM OR Immediate $10 with RAM $F1 (set status bit 0)
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	jmp	LF193

Command5:		; Similar to command 1
	ldaa	X00E9	; Input code
	tab
	anda	#$0C    ; Bits 2 and 3
	bne	LF3D6
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	andb	#$03
	stab	X00E6
	ldx	#$F4FA
	abx     	; B+X -> X
	abx     	; B+X -> X
	ldx	$00,x
	ldd	$00,x
	std	X00D1	; RAM $D1 = $F4FA + X*2 (word)
	ldd	$02,x
	std	X00D3	; RAM $D3 = $F4FA + X*2 + 2 (word)
	ldd	$04,x
	std	X00D5	; RAM $D5 = $F4FA + X*2 + 4 (word)
	ldd	$06,x
	std	X00D7	; RAM $D7 = $F4FA + X*2 + 6 (word)
	ldd	$08,x
	std	X00D9	; RAM $D9 = $F4FA + X*2 + 8 (word)
	ldd	$0A,x
	std	X00DB	; RAM $DB = $F4FA + X*2 + A (word)
	ldaa	$0C,x
	staa	X00DD	; RAM $DD = $F4FA + X*2 + C (byte) always $FF ?
	clr	X00E8
	jmp	LF193

CommandC:
	ldaa	X00E7	; Output code
	cmpa	#$FF
	beq	LF3D6
	ldaa	X00E9	; Input code
	tab
	anda	#$0C
	bne	LF3D6
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	andb	#$03
	ldx	#$F4FA
	abx     	; B+X -> X
	abx     	; B+X -> X
	ldx	$00,x
	ldd	$00,x
	std	X00D1
	ldd	$02,x
	std	X00D3
	ldd	$04,x
	std	X00D5
	ldd	$06,x
	std	X00D7
	ldd	$08,x
	std	X00D9
	ldd	$0A,x
	std	X00DB
	ldaa	$0C,x
	staa	X00DD
	clra
	staa	X00E8
	deca
	staa	X00F2
	ldaa	#$0D
	staa	X00F3
	jmp	LF193

Command6:
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	ldaa	X00E9	; Input code
	staa	X00E8
	jmp	LF193

Command7:
XF48A:
	ldaa	X00E4
	staa	X0007	; Port4 data (output code)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	jmp	LF193

Command8:
	ldaa	X00E2	; Error counter ?
	staa	X0007	; Port4 data (output code)
	; AIM AND Immediate $EF with RAM $F1
	ldaa	X00F1	; Status ?
	staa	X0002	; Port1 data
	jmp	LF193

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

SC1:
	ldaa	X0011	; Read TRCS
	staa	X00EC   ; Store
	ldaa	X0012	; Receive register
	staa	X00ED	; Store received code
	clr	X00F0
	; OIM OR Immediate $02 with RAM $EB (link receive flag)
	rti

IRQ1:
	ldaa	X000F   ; Clear port3 latch flag
	ldaa	X0006	; Port3 data (input code)
	staa	X00E9	; Input code
	; OIM OR Immediate $01 with RAM $EB (CPU write flag)
	rti

XF4D6:
	inc	X00E2	; Error counter ?
	rti

XF4DA:
; CPU command 0: $F34E	Update status
; CPU command 1: $F369
; CPU command 2: $F359	Read output code
; CPU command 3: $F3B7
; CPU command 4: $F39F
; CPU command 5: $F3E1
; CPU command 6: $F479	Put $E9 in $E8 ?
; CPU command 7: $F48A
; CPU command 8: $F49A	Read error counter
; CPU command 9: $F342	Reset
; CPU command A: $F3B7	Same as command 3
; CPU command B: $F4AA	Ack something ?
; CPU command C: $F426
; CPU command D: $F3D6	Invalid
; CPU command E: $F3D6	Invalid
; CPU command F: $F3D6	Invalid

XF4FA:
;0080 008D 009A 00A7 00B4 00C2 FF...

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