/* * H8/536 focused SCI RX/TX pseudocode from build\rom_decompiled.json * * This is a protocol-oriented reconstruction from decompiler JSON metadata. * It is intentionally phrased as candidate behavior: it summarizes evidence * from the ROM without claiming source-level intent or a proven packet format. */ /* Candidate summary: * - SCI1 TX 6-byte frame at H'F858-H'F85D: confidence high (0.95) * reason: all required independent evidence groups were observed * - SCI1 RX 6-byte frame captured at H'F868-H'F86D: confidence high (0.9) * reason: RX count, copy, and checksum-validation evidence were observed; no explicit header/sync byte was identified * caveat: candidate frame means six consecutive bytes within the observed RX timing/state machine, not a proven delimited packet */ /* Board path: * Board trace ties the H8/536 SCI1 pins to a MAX202 RS232 transceiver. * - TXD: H8 pin 66 P95/TXD <-> MAX202 pin 11 * evidence: MAX202 pin 11 traces to H8 pin 66 * - RXD: H8 pin 67 P96/RXD <-> MAX202 pin 12 * evidence: MAX202 pin 12 traces to H8 pin 67 */ /* Manual anchors used by the decompiler metadata: * - Manual/0900766b802125d0.md:15748 SCI register map for RDR/TDR/SCR/SSR * - Manual/0900766b802125d0.md:15794 RDR stores received data and is CPU-readable * - Manual/0900766b802125d0.md:15823 TDR holds the next byte to transmit * - Manual/0900766b802125d0.md:15976 SCR.TIE enables/disables TXI on TDRE * - Manual/0900766b802125d0.md:15993 SCR.RIE enables RXI and ERI * - Manual/0900766b802125d0.md:16008 SCR.TE enables the transmitter * - Manual/0900766b802125d0.md:16028 SCR.RE enables the receiver * - Manual/0900766b802125d0.md:16090 SSR flags are cleared by writing zero * - Manual/0900766b802125d0.md:16100 SSR.TDRE means TDR can accept the next byte * - Manual/0900766b802125d0.md:16116 SSR.RDRF means received data reached RDR * - Manual/0900766b802125d0.md:16127 SSR.ORER reports receive overrun * - Manual/0900766b802125d0.md:16140 SSR.FER reports framing errors * - Manual/0900766b802125d0.md:16147 SSR.PER reports parity errors * - Manual/0900766b802125d0.md:2417 FP-80 H8/536 pin 66 is P95/TXD * - Manual/0900766b802125d0.md:2418 FP-80 H8/536 pin 67 is P96/RXD * - Manual/0900766b802125d0.md:11192 Port 9 carries SCI1 and SCI2 serial signals * - Manual/0900766b802125d0.md:11201 P96 is RXD1 input * - Manual/0900766b802125d0.md:11202 P95 is TXD1 output * - Manual/0900766b802125d0.md:15725 SCI1 RXD input pin * - Manual/0900766b802125d0.md:15726 SCI1 TXD output pin * - Manual/0900766b802125d0.md:15750 SCI register table starts with SCI1 RDR/TDR/SMR/SCR/SSR/BRR * - Manual/0900766b802125d0.md:15758 SCI register table lists SCI2 RDR/TDR/SMR/SCR/SSR/BRR * - Manual/0900766b802125d0.md:15794 RDR receive data register * - Manual/0900766b802125d0.md:15823 TDR transmit data register * - Manual/0900766b802125d0.md:15969 SCR enables and disables SCI functions * - Manual/0900766b802125d0.md:16009 SCR.TE makes the TXD pin output * - Manual/0900766b802125d0.md:16029 SCR.RE makes the RXD pin input * - Manual/0900766b802125d0.md:16090 SSR contains transmit/receive status flags * - Manual/0900766b802125d0.md:10560 SYSCR2 controls port 9 pin functions * - Manual/0900766b802125d0.md:10631 SYSCR2.P9SCI2E controls the SCI2 functions of P92-P94 */ #include #include typedef uint8_t u8; typedef uint16_t u16; extern volatile u8 MEM8[0x10000]; #define SCI1_SCR MEM8[0xFEDAu] #define SCI1_TDR MEM8[0xFEDBu] #define SCI1_SSR MEM8[0xFEDCu] #define SCI1_RDR MEM8[0xFEDDu] #define SCI_SCR_TIE 0x80u #define SCI_SCR_RIE 0x40u #define SCI_SCR_TE 0x20u #define SCI_SCR_RE 0x10u #define SCI_SSR_TDRE 0x80u #define SCI_SSR_RDRF 0x40u #define SCI_SSR_ORER 0x20u #define SCI_SSR_FER 0x10u #define SCI_SSR_PER 0x08u #define TX_FRAME_LENGTH 6u #define TX_FRAME(n) MEM8[(u16)(0xF858u + (n))] #define TX_INDEX MEM8[0xF9C2u] #define RX_FRAME_LENGTH 6u #define RX_CAPTURE(n) MEM8[(u16)(0xF868u + (n))] #define RX_FRAME(n) MEM8[(u16)(0xF860u + (n))] #define RX_INDEX MEM8[0xF9C3u] #define RX_INTERBYTE_TIMEOUT MEM8[0xF9C1u] #define RX_COMPLETE_TIMER MEM8[0xF9C5u] /* Candidate Protocol Semantics * confidence: medium-high (0.9) * caveat: Semantic names are candidates only. The analyzer reports byte roles, command values, dispatch targets, and response staging patterns observed in code; it does not prove source-level intent or protocol documentation. * byte layout: * - byte0: op_flags (medium-high) - low three bits select a command; upper bits are preserved or gated in some paths * - byte1: addr_page_flags (medium) - candidate high/page byte for logical point/index; bit 7 is tested as a control flag * - byte2: addr_offset (medium) - candidate low/offset byte for logical point/index * - byte3: value_hi (medium) - candidate high byte of a word value * - byte4: value_lo (medium) - candidate low byte of a word value * - byte5: checksum (high) - 0x5A-seeded XOR of bytes 0..4 * dispatch: command_low3 = RX_FRAME(0) & 0x07; observed H'00, H'01, H'02, H'04, H'05, H'06, H'07 * dispatch evidence: H'BC08, H'BC0C, H'BC20, H'BC22, H'BC24, H'BC26, H'BC29, H'BC2B, H'BC2E, H'BC30, H'BC45, H'BC47, H'BC4A, H'BC4C, H'BC4F, H'BC51, H'BC54, H'BC56 * index decoder: RX[1:2] -> logical index via loc_622B (medium) * command candidates: * - H'00 set_value_acked: candidate write of RX[3:4] into primary/current tables, followed by a response; handler H'BC69; responses response_at_BCCD * - H'01 read_value: candidate read from the primary table, followed by a response carrying the value; handler H'BCD7; responses response_at_BCFA * - H'02 clear_or_abort: candidate clear/abort path with no immediate response builder; handler H'BD04; responses none * - H'04 set_value_no_immediate_reply: candidate write/update path that stores a value without an immediate serial response; handler H'BD0E; responses none * - H'05 ack_or_clear_pending: candidate pending/event acknowledgement path; handler H'BD80; responses none * - H'06 set_secondary_value: candidate secondary-table value write path; handler H'BDDB; responses none * - H'07 retransmit_or_error_reply: candidate retransmit/NAK-style path; error handling also builds command 0x07 responses; handler H'BE05; responses response_at_BE22 */ static u8 sci1_rx_candidate_command(void) { return (u8)(RX_FRAME(0) & 0x07u); } static u16 sci1_rx_candidate_value(void) { return (u16)(((u16)RX_FRAME(3) << 8) | RX_FRAME(4)); } static u16 sci1_rx_candidate_logical_index(void) { u8 page = RX_FRAME(1); u8 offset = RX_FRAME(2); if (page == 0u && offset <= 0x7Fu) { return offset; } if (page == 1u) { return (u16)(0x0080u + offset); } if (page == 2u && offset <= 0x7Fu) { return (u16)(0x0180u + offset); } return 0x01FFu; } void sci1_process_candidate_protocol_command(void) { u8 command = sci1_rx_candidate_command(); u16 logical_index = sci1_rx_candidate_logical_index(); u16 value = sci1_rx_candidate_value(); switch (command) { case 0x00u: /* set_value_acked: candidate write of RX[3:4] into primary/current tables, followed by a response * evidence: H'BC08, H'BC0C, H'BC20, H'BC22, H'BCB0, H'BCB9, H'BCC1, H'BCC9, H'BCB5, H'BCBD, H'BCC5, H'BCCD */ candidate_set_value_acked(logical_index, value); break; case 0x01u: /* read_value: candidate read from the primary table, followed by a response carrying the value * evidence: H'BC08, H'BC0C, H'BC24, H'BC26, H'BCB0, H'BCB9, H'BCC1, H'BCC9, H'BCD7, H'BCE0, H'BCE8, H'BCF0, H'BCF6, H'BCB5, H'BCBD, H'BCC5, H'BCDC, H'BCE4, H'BCFA */ candidate_read_value(logical_index, value); break; case 0x02u: /* clear_or_abort: candidate clear/abort path with no immediate response builder * evidence: H'BC08, H'BC0C, H'BC29, H'BC2B */ candidate_clear_or_abort(logical_index, value); break; case 0x04u: /* set_value_no_immediate_reply: candidate write/update path that stores a value without an immediate serial response * evidence: H'BC08, H'BC0C, H'BC45, H'BC47 */ candidate_set_value_no_immediate_reply(logical_index, value); break; case 0x05u: /* ack_or_clear_pending: candidate pending/event acknowledgement path * evidence: H'BC08, H'BC0C, H'BC4A, H'BC4C */ candidate_ack_or_clear_pending(logical_index, value); break; case 0x06u: /* set_secondary_value: candidate secondary-table value write path * evidence: H'BC08, H'BC0C, H'BC4F, H'BC51 */ candidate_set_secondary_value(logical_index, value); break; case 0x07u: /* retransmit_or_error_reply: candidate retransmit/NAK-style path; error handling also builds command 0x07 responses * evidence: H'BC08, H'BC0C, H'BC2E, H'BC30, H'BC54, H'BC56, H'BE09, H'BE11, H'BE19, H'BE22 */ candidate_retransmit_or_error_reply(logical_index, value); break; default: candidate_unknown_command(command, logical_index, value); break; } } /* * TX reconstruction evidence * candidate/evidence-supported SCI1 6-byte TX frame hypothesis using buffer H'F858-H'F85D with checksum byte H'F85D seeded by H'005A * checksum formula: checksum = 0x5A ^ byte0 ^ byte1 ^ byte2 ^ byte3 ^ byte4 * evidence addresses: * - checksum_byte: H'BA64 * - initial_send_from_buffer_start: H'BA6E, H'BA72 * - tx_buffer_region: H'BA3A, H'BA42, H'BA4A, H'BA50, H'BA54, H'BA58, H'BA5C, H'BA60, H'BA64, H'BA6E, H'BE05, H'BE0D, H'BE15 * - tx_checksum_seed: H'BA4E * - tx_index_compare_frame_length: H'BAC3 * - tx_index_increment: H'BABF * - tx_index_initialized_to_one: H'BA76 * - tx_isr_indexed_send: H'BAAB, H'BAB1, H'BAB5 * - xor_checksum_chain: H'BA50, H'BA54, H'BA58, H'BA5C, H'BA60, H'BA64 */ static u8 sci1_tx_candidate_checksum(void) { u8 checksum = 0x5Au; checksum ^= TX_FRAME(0); checksum ^= TX_FRAME(1); checksum ^= TX_FRAME(2); checksum ^= TX_FRAME(3); checksum ^= TX_FRAME(4); return checksum; } void sci1_tx_start_candidate_frame(void) { /* The ROM appears to have populated TX_FRAME(0..4) before this point. */ TX_FRAME(5) = sci1_tx_candidate_checksum(); while ((SCI1_SSR & SCI_SSR_TDRE) == 0u) { /* wait for transmit data register empty */ } SCI1_TDR = TX_FRAME(0); TX_INDEX = 1u; SCI1_SSR &= (u8)~SCI_SSR_TDRE; SCI1_SCR |= SCI_SCR_TIE; } void sci1_txi_candidate_isr(void) { if (TX_INDEX < TX_FRAME_LENGTH) { SCI1_TDR = TX_FRAME(TX_INDEX); TX_INDEX = (u8)(TX_INDEX + 1u); SCI1_SSR &= (u8)~SCI_SSR_TDRE; } if (TX_INDEX >= TX_FRAME_LENGTH) { SCI1_SCR &= (u8)~SCI_SCR_TIE; } } /* * RX reconstruction evidence * candidate/evidence-supported SCI1 6-byte RX frame hypothesis using capture buffer H'F868-H'F86D; checksum byte H'F865 is validated against XOR seeded by H'005A * checksum formula: checksum = 0x5A ^ byte0 ^ byte1 ^ byte2 ^ byte3 ^ byte4 * evidence addresses: * - rx_checksum_seed: H'BBD6 * - rx_complete_timer: H'BB9E * - rx_copy_capture_to_frame_buffer: H'BBB3, H'BBBB, H'BBC3, H'BBB7, H'BBBF, H'BBC7 * - rx_index_increment_store: H'BB94, H'BB96 * - rx_indexed_store: H'BB90 * - rx_isr_compare_frame_length: H'BB9A * - rx_processor_requires_six_bytes: H'BBAB * - rx_rdr_read: H'BB6D * - rx_xor_checksum_validation: H'BBD6, H'BBD8, H'BBDC, H'BBE0, H'BBE4, H'BBE8, H'BBEC */ static u8 sci1_rx_candidate_checksum(void) { u8 checksum = 0x5Au; checksum ^= RX_FRAME(0); checksum ^= RX_FRAME(1); checksum ^= RX_FRAME(2); checksum ^= RX_FRAME(3); checksum ^= RX_FRAME(4); return checksum; } bool sci1_process_rx_candidate_frame(void) { u8 i; if (RX_INDEX != RX_FRAME_LENGTH) { return false; } for (i = 0u; i < RX_FRAME_LENGTH; i++) { RX_FRAME(i) = RX_CAPTURE(i); } if (sci1_rx_candidate_checksum() != RX_FRAME(5)) { RX_INDEX = 0u; return false; } RX_INDEX = 0u; return true; } bool sci1_rx_byte_received_candidate_isr(void) { u8 byte; SCI1_SSR &= (u8)~SCI_SSR_RDRF; byte = SCI1_RDR; if (RX_INTERBYTE_TIMEOUT == 0u) { RX_INDEX = 0u; } RX_INTERBYTE_TIMEOUT = 5u; RX_CAPTURE(RX_INDEX) = byte; RX_INDEX = (u8)(RX_INDEX + 1u); if (RX_INDEX == RX_FRAME_LENGTH) { RX_COMPLETE_TIMER = 0x14u; return sci1_process_rx_candidate_frame(); } return false; } void sci1_rx_error_candidate_isr(void) { SCI1_SSR &= (u8)~(SCI_SSR_ORER | SCI_SSR_FER | SCI_SSR_PER); RX_INDEX = 0u; }