H8/536 Serial Gate/Queue State-Machine Reconstruction

Summary: autonomous serial TX/report queue gate
Confidence: high

Evidence:
- loc_3FD3 gate into loc_BAF2: present
  Requires FAA2 == 0, allows the FAA5.bit7 path only when F9C3 == 0, then requires F9C0 == 0 before BSR loc_BAF2.
  - H'3FD3: TST.B @H'FAA2
  - H'3FD7: BNE loc_3FEE
  - H'3FD9: BTST.B #7, @H'FAA5
  - H'3FDD: BEQ loc_3FE5
  - H'3FDF: TST.B @H'F9C3
  - H'3FE3: BNE loc_3FEE
  - H'3FE5: TST.B @H'F9C0
  - H'3FE9: BNE loc_3FEE
  - H'3FEB: BSR loc_BAF2
- loc_BAF2 queue send gate: present
  F9B5 is compared against F9B0; inequality enters the send path, reads a queued word via the F9B5-derived index around F870, stages F850-F854, and calls BA26 at BB43.
  - H'BAF2: MOV:G.B @H'F9B5, R1
  - H'BAF8: CMP:G.B @H'F9B0, R1
  - H'BAFC: BNE loc_BB00
  - H'BAFE: BRA loc_BB56
  - H'BB00: BSET.B #3, @H'FAA2
  - H'BB08: MOV:G.W @(-H'0790,R0), R0
  - H'BB1C: MOV:G.B R1, @H'F850
  - H'BB20: MOV:G.B R5, @H'F852
  - H'BB2B: MOV:G.B R5, @H'F851
  - H'BB39: MOV:G.B R4, @H'F854
  - H'BB3F: MOV:G.B R4, @H'F853
  - H'BB43: BSR loc_BA26
  - H'BB46: MOV:G.W #H'01F4, @H'F9C6
  - H'BB4C: MOV:G.B #H'14, @H'F9C8
  - H'BB51: MOV:G.B #H'80, @H'FAA3
- resend gate/path: present
  BE9E masks FAA5 with FAA3, waits for F9C6/F9C8 timeout gates, then if FAA3.bit7 remains set clears F9C3 and calls BA26 from BED5.
  - H'BE9E: MOV:G.B @H'FAA5, R0
  - H'BEA5: AND.B @H'FAA3, R0
  - H'BEA9: MOV:G.B R0, @H'FAA3
  - H'BEAF: CLR.B @H'FAA2
  - H'BEB5: TST.W @H'F9C6
  - H'BEBB: TST.B @H'F9C8
  - H'BEC5: MOV:G.W #H'01F4, @H'F9C6
  - H'BECB: BTST.B #7, @H'FAA3
  - H'BED1: CLR.B @H'F9C3
  - H'BED5: BSR loc_BA26
- RX/session maintenance: present
  F9C5 timeout maintenance clears F9B5/F9B0 and FAA5.bit7; RX command processing uses FAA2 as an in-session latch and paths advance F9B5/F9B0 or clear FAA3/FAA2.
  - H'3FEF: TST.B @H'F9C5
  - H'3FF5: CLR.B @H'F9B5
  - H'3FF9: CLR.B @H'F9B0
  - H'3FFD: BCLR.B #7, @H'FAA5
  - H'4007: BSET.B #7, @H'FAA5
  - H'BBCB: CLR.B @H'F9C3
  - H'BC0F: TST.B @H'FAA2
  - H'BC15: BSET.B #7, @H'FAA2
  - H'BC33: CLR.B @H'FAA2
  - H'BC5C: BCLR.B #3, @H'FAA2
  - H'BC63: CLR.B @H'FAA3
  - H'BCD0: BCLR.B #7, @H'FAA2
  - H'BCFD: BCLR.B #7, @H'FAA2
  - H'BD04: BCLR.B #7, @H'FAA2
  - H'BD6D: ADD:Q.B #1, @H'F9B5
  - H'BD71: BCLR.B #7, @H'F9B5
  - H'BD75: CLR.B @H'FAA3
  - H'BD79: CLR.B @H'FAA2
  - H'BDC8: ADD:Q.B #1, @H'F9B5
  - H'BDCC: BCLR.B #7, @H'F9B5
  - H'BDD0: CLR.B @H'FAA3
  - H'BDD4: CLR.B @H'FAA2
  - H'BDF3: ADD:Q.B #1, @H'F9B5
  - H'BDF7: BCLR.B #7, @H'F9B5
  - H'BDFB: CLR.B @H'FAA3
  - H'BDFF: CLR.B @H'FAA2
- loc_4046 idle heartbeat/report gate: present
  F9C4 gates the idle/default report enqueue. Reset/init loads H'14, each BA26 send reloads H'07, and the FRT2 OCIA handler decrements it; when it reaches zero loc_4046 can enqueue H'00FF if the queue is empty and the FAA5/F9C3 RX gate permits it. With FRT2 OCRA H'7A12 and CKS=phi/32, a phi near 10 MHz gives about 0.7s for H'07, matching the observed heartbeat cadence.
  - H'4046: TST.B @H'F9C4
  - H'404A: BNE loc_4058
  - H'404C: BTST.B #7, @H'FAA5
  - H'4050: BEQ loc_4059
  - H'4052: TST.B @H'F9C3
  - H'4056: BEQ loc_4059
  - H'4058: RTS
  - H'4059: MOV:G.B @H'F9B0, R2
  - H'405F: CMP:G.B @H'F9B5, R2
  - H'4063: BNE loc_4074
  - H'4067: MOV:G.W #H'00, @(-H'0790,R2)
  - H'406C: ADD:Q.B #1, @H'F9B0
  - H'4070: BCLR.B #7, @H'F9B0
  - H'40E0: MOV:G.B #H'14, @H'F9C4
  - H'BA31: MOV:G.B #H'07, @H'F9C4
  - H'BF23: BCLR.B #5, @FRT2_TCSR
  - H'BF27: TST.B @H'F9C4
  - H'BF2D: ADD:Q.B #-1, @H'F9C4
  Candidate timer roles:
  - H'F9C4: candidate idle heartbeat/report gate countdown
  Timer: FRT2 OCIA, H'BF23, OCRA=H'7A12, observed period ~= 700ms
- FRT1 OCIA periodic tick countdowns: present
  Static evidence links vector H'0062 to the FRT1 OCIA handler at H'BEEA; the handler clears FRT1_TCSR.OCFA and conditionally decrements H'F9C0, H'F9C1, and H'F9C6.
  - H'BEEA: BCLR.B #5, @FRT1_TCSR
  - H'BEEE: TST.B @H'F9C0
  - H'BEF4: ADD:Q.B #-1, @H'F9C0
  - H'BEF8: TST.B @H'F9C1
  - H'BEFE: ADD:Q.B #-1, @H'F9C1
  - H'BF02: TST.W @H'F9C6
  - H'BF08: ADD:Q.W #-1, @H'F9C6
  Candidate timer roles:
  - H'F9C0: candidate post-TX/report delay countdown
  - H'F9C1: candidate secondary delay countdown
  - H'F9C6: candidate periodic report/heartbeat countdown

State address readers/writers:
- H'F9B0: reads=4 writes=1 read/write=4
  H'3E60 read MOV:G.B @H'F9B0, R1; H'3E7A read_write ADD:Q.B #1, @H'F9B0; H'3E7E read_write BCLR.B #7, @H'F9B0; H'3E82 read MOV:G.B @H'F9B0, R0; H'3FF9 write CLR.B @H'F9B0; H'4059 read MOV:G.B @H'F9B0, R2
- H'F9B4: reads=3 writes=0 read/write=4
  H'280C read CMP:G.B @H'F9B4, R1; H'3EA6 read MOV:G.B @H'F9B4, R1; H'3EC3 read_write ADD:Q.B #1, @H'F9B4; H'3EC7 read_write BCLR.B #5, @H'F9B4; H'BE78 read MOV:G.B @H'F9B4, R1; H'BE95 read_write ADD:Q.B #1, @H'F9B4
- H'F9B5: reads=4 writes=1 read/write=6
  H'3E58 read MOV:G.B @H'F9B5, R0; H'3E8B read CMP:G.B @H'F9B5, R0; H'3FF5 write CLR.B @H'F9B5; H'405F read CMP:G.B @H'F9B5, R2; H'BAF2 read MOV:G.B @H'F9B5, R1; H'BD6D read_write ADD:Q.B #1, @H'F9B5
- H'F9B9: reads=3 writes=1 read/write=0
  H'2806 read MOV:G.B @H'F9B9, R1; H'2822 write MOV:G.B R1, @H'F9B9; H'3E9E read MOV:G.B @H'F9B9, R0; H'BE70 read MOV:G.B @H'F9B9, R3
- H'F9C0: reads=3 writes=7 read/write=1
  H'3FE5 read TST.B @H'F9C0; H'BA26 read TST.B @H'F9C0; H'BA2C write MOV:G.B #H'64, @H'F9C0; H'BAA2 write MOV:G.B #H'1F, @H'F9C0; H'BADA write MOV:G.B #H'09, @H'F9C0; H'BAE1 write MOV:G.B #H'09, @H'F9C0
- H'F9C1: reads=2 writes=2 read/write=1
  H'BAED write CLR.B @H'F9C1; H'BB71 read TST.B @H'F9C1; H'BBA3 write MOV:G.B #H'05, @H'F9C1; H'BEF8 read TST.B @H'F9C1; H'BEFE read_write ADD:Q.B #-1, @H'F9C1
- H'F9C3: reads=6 writes=4 read/write=0
  H'3FDF read TST.B @H'F9C3; H'4052 read TST.B @H'F9C3; H'BA90 read TST.B @H'F9C3; H'BB77 write CLR.B @H'F9C3; H'BB7D read CMP:G.B #H'05, @H'F9C3; H'BB8A read MOV:G.B @H'F9C3, R1
- H'F9C4: reads=2 writes=2 read/write=1
  H'4046 read TST.B @H'F9C4; H'40E0 write MOV:G.B #H'14, @H'F9C4; H'BA31 write MOV:G.B #H'07, @H'F9C4; H'BF27 read TST.B @H'F9C4; H'BF2D read_write ADD:Q.B #-1, @H'F9C4
- H'F9C5: reads=2 writes=2 read/write=1
  H'3FEF read TST.B @H'F9C5; H'BB9E write MOV:G.B #H'14, @H'F9C5; H'BEE4 write CLR.B @H'F9C5; H'BF31 read TST.B @H'F9C5; H'BF37 read_write ADD:Q.B #-1, @H'F9C5
- H'F9C6: reads=2 writes=2 read/write=1
  H'BB46 write MOV:G.W #H'01F4, @H'F9C6; H'BEB5 read TST.W @H'F9C6; H'BEC5 write MOV:G.W #H'01F4, @H'F9C6; H'BF02 read TST.W @H'F9C6; H'BF08 read_write ADD:Q.W #-1, @H'F9C6
- H'F9C8: reads=1 writes=1 read/write=1
  H'BB4C write MOV:G.B #H'14, @H'F9C8; H'BEBB read TST.B @H'F9C8; H'BEC1 read_write ADD:Q.B #-1, @H'F9C8
- H'FAA2: reads=6 writes=6 read/write=7
  H'3FD3 read TST.B @H'FAA2; H'BA84 read BTST.B #3, @H'FAA2; H'BA96 read_write BCLR.B #3, @H'FAA2; H'BB00 read_write BSET.B #3, @H'FAA2; H'BC0F read TST.B @H'FAA2; H'BC15 read_write BSET.B #7, @H'FAA2
- H'FAA3: reads=2 writes=8 read/write=0
  H'BA9A write CLR.B @H'FAA3; H'BB51 write MOV:G.B #H'80, @H'FAA3; H'BC63 write CLR.B @H'FAA3; H'BD75 write CLR.B @H'FAA3; H'BDD0 write CLR.B @H'FAA3; H'BDFB write CLR.B @H'FAA3
- H'FAA5: reads=5 writes=0 read/write=2
  H'3FD9 read BTST.B #7, @H'FAA5; H'3FFD read_write BCLR.B #7, @H'FAA5; H'4007 read_write BSET.B #7, @H'FAA5; H'404C read BTST.B #7, @H'FAA5; H'BA8A read BTST.B #7, @H'FAA5; H'BE2D read BTST.B #7, @H'FAA5

Caveats:
- Observed report indexes 0x0007 and 0x0015 are capture overlays/runtime queue entries; this analyzer does not treat them as statically proven ROM constants.
- Queue entries near F870 are reached through RAM-indexed addressing; static JSON proves the access pattern, not the runtime queue contents.
- Branch predicates are summarized from local instruction order and targets; this is not an emulator trace.
