new learnigns
This commit is contained in:
@@ -196,6 +196,60 @@ class SerialPseudocodeTest(unittest.TestCase):
|
||||
self.assertIn("case 0x01u:", text)
|
||||
self.assertIn("candidate_read_value(logical_index, value);", text)
|
||||
|
||||
def test_protocol_pseudocode_surfaces_dispatcher_split(self):
|
||||
payload = candidate_payload()
|
||||
payload["instructions"] = [
|
||||
{"address": 0xBC08, "mnemonic": "MOV:G.B", "operands": "@H'F860, R0", "references": [{"address": 0xF860}], "targets": []},
|
||||
{"address": 0xBC0C, "mnemonic": "AND.B", "operands": "#H'07, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC0F, "mnemonic": "TST.B", "operands": "@H'FAA2", "references": [{"address": 0xFAA2}], "targets": []},
|
||||
{"address": 0xBC13, "mnemonic": "BNE", "operands": "loc_BC3A", "references": [], "targets": [0xBC3A]},
|
||||
{"address": 0xBC19, "mnemonic": "BTST.B", "operands": "#7, @H'F861", "references": [{"address": 0xF861}], "targets": []},
|
||||
{"address": 0xBC20, "mnemonic": "CMP:E", "operands": "#H'00, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC22, "mnemonic": "BEQ", "operands": "loc_BC69", "references": [], "targets": [0xBC69]},
|
||||
{"address": 0xBC24, "mnemonic": "CMP:E", "operands": "#H'01, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC26, "mnemonic": "BEQ", "operands": "loc_BCD7", "references": [], "targets": [0xBCD7]},
|
||||
{"address": 0xBC29, "mnemonic": "CMP:E", "operands": "#H'02, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC2B, "mnemonic": "BEQ", "operands": "loc_BD04", "references": [], "targets": [0xBD04]},
|
||||
{"address": 0xBC2E, "mnemonic": "CMP:E", "operands": "#H'07, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC30, "mnemonic": "BEQ", "operands": "loc_BE05", "references": [], "targets": [0xBE05]},
|
||||
{"address": 0xBC45, "mnemonic": "CMP:E", "operands": "#H'04, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC47, "mnemonic": "BEQ", "operands": "loc_BD0E", "references": [], "targets": [0xBD0E]},
|
||||
{"address": 0xBC4A, "mnemonic": "CMP:E", "operands": "#H'05, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC4C, "mnemonic": "BEQ", "operands": "loc_BD80", "references": [], "targets": [0xBD80]},
|
||||
{"address": 0xBC4F, "mnemonic": "CMP:E", "operands": "#H'06, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC51, "mnemonic": "BEQ", "operands": "loc_BDDB", "references": [], "targets": [0xBDDB]},
|
||||
{"address": 0xBC54, "mnemonic": "CMP:E", "operands": "#H'07, R0", "references": [], "targets": []},
|
||||
{"address": 0xBC56, "mnemonic": "BEQ", "operands": "loc_BE05", "references": [], "targets": [0xBE05]},
|
||||
]
|
||||
|
||||
text = generate_serial_pseudocode(payload)
|
||||
|
||||
self.assertIn("dispatcher split: FAA2 == 0 accepts initial/idle commands H'00, H'01, H'02, H'07; FAA2 != 0 accepts continuation commands H'04, H'05, H'06, H'07", text)
|
||||
self.assertIn("bool session_active = MEM8[0xFAA2u] != 0u;", text)
|
||||
self.assertIn("Initial/idle dispatcher", text)
|
||||
self.assertIn("Continuation dispatcher", text)
|
||||
self.assertIn("availability: valid checksum/no RX physical error && FAA2 == 0 && F861.bit7 == 0", text)
|
||||
|
||||
def test_protocol_pseudocode_surfaces_retry_echo_schema(self):
|
||||
payload = candidate_payload()
|
||||
payload["instructions"] = [
|
||||
{"address": 0xBE4B, "mnemonic": "BRA", "operands": "loc_BE6D", "references": [], "targets": [0xBE6D]},
|
||||
{"address": 0xBE4D, "mnemonic": "MOV:G.B", "operands": "#H'07, @H'F850", "references": [{"address": 0xF850}], "targets": []},
|
||||
{"address": 0xBE52, "mnemonic": "MOV:G.B", "operands": "@H'F861, R0", "references": [{"address": 0xF861}], "targets": []},
|
||||
{"address": 0xBE56, "mnemonic": "MOV:G.B", "operands": "R0, @H'F851", "references": [{"address": 0xF851}], "targets": []},
|
||||
{"address": 0xBE5A, "mnemonic": "MOV:G.W", "operands": "@H'F862, R0", "references": [{"address": 0xF862}], "targets": []},
|
||||
{"address": 0xBE5E, "mnemonic": "MOV:G.W", "operands": "R0, @H'F852", "references": [{"address": 0xF852}], "targets": []},
|
||||
{"address": 0xBE62, "mnemonic": "MOV:G.B", "operands": "@H'F864, R0", "references": [{"address": 0xF864}], "targets": []},
|
||||
{"address": 0xBE66, "mnemonic": "MOV:G.B", "operands": "R0, @H'F854", "references": [{"address": 0xF854}], "targets": []},
|
||||
{"address": 0xBE6A, "mnemonic": "BSR", "operands": "loc_BA26", "references": [], "targets": [0xBA26]},
|
||||
]
|
||||
|
||||
text = generate_serial_pseudocode(payload)
|
||||
|
||||
self.assertIn("response_at_BE6A: byte0=0x07; byte1=rx[1]; byte2=rx[2]; byte3=rx[3]; byte4=rx[4]", text)
|
||||
self.assertIn("Observed 07 80 40 20 90 2D echoes RX payload bytes 80 40 20 90", text)
|
||||
self.assertIn("not a table-derived value", text)
|
||||
|
||||
def test_surfaces_refined_semantic_candidates(self):
|
||||
analysis = {
|
||||
"protocol_semantics": [
|
||||
|
||||
@@ -288,6 +288,8 @@ class SerialSemanticsTest(unittest.TestCase):
|
||||
command_1_text = semantic_text(command_1)
|
||||
self.assertIn("read", command_1_text)
|
||||
self.assertIn("response", command_1_text)
|
||||
self.assertIn("initial/idle", command_1_text)
|
||||
self.assertIn("f852", command_1_text)
|
||||
|
||||
command_6 = command_item(effects, 0x06)
|
||||
self.assertIsNotNone(command_6)
|
||||
@@ -295,6 +297,13 @@ class SerialSemanticsTest(unittest.TestCase):
|
||||
self.assertIn("write", command_6_text)
|
||||
self.assertIn("secondary_value_table", command_6_text)
|
||||
|
||||
command_5 = command_item(effects, 0x05)
|
||||
self.assertIsNotNone(command_5)
|
||||
command_5_text = semantic_text(command_5)
|
||||
self.assertIn("faa2 != 0", command_5_text)
|
||||
self.assertIn("0040", command_5_text)
|
||||
self.assertIn("no response", command_5_text)
|
||||
|
||||
def test_planned_response_schema_tracks_immediates_and_rx_copies(self):
|
||||
semantics = only_semantics(self, planned_semantics_payload())
|
||||
|
||||
@@ -391,10 +400,105 @@ class SerialSemanticsTest(unittest.TestCase):
|
||||
self.assertIn("be9e", gate_text)
|
||||
self.assertIn("bed5", gate_text)
|
||||
self.assertIn("f9c5", gate_text)
|
||||
self.assertIn("commands 0x05", gate_text)
|
||||
self.assertIn("0x06", gate_text)
|
||||
self.assertIn("command 0x05", gate_text)
|
||||
self.assertIn("selector 0x0040 has no response", gate_text)
|
||||
self.assertIn("faa2 == 0", gate_text)
|
||||
self.assertIn("not rom constants", gate_text)
|
||||
|
||||
def test_actual_dispatch_split_marks_initial_and_continuation_commands(self):
|
||||
semantics = only_semantics(
|
||||
self,
|
||||
base_payload(
|
||||
[
|
||||
instruction(0xBC08, "MOV:G.B", "@H'F860, R0", [0xF860]),
|
||||
instruction(0xBC0C, "AND.B", "#H'07, R0"),
|
||||
instruction(0xBC0F, "TST.B", "@H'FAA2", [0xFAA2]),
|
||||
instruction(0xBC13, "BNE", "loc_BC3A", targets=[0xBC3A]),
|
||||
instruction(0xBC19, "BTST.B", "#7, @H'F861", [0xF861]),
|
||||
instruction(0xBC20, "CMP:E", "#H'00, R0"),
|
||||
instruction(0xBC22, "BEQ", "loc_BC69", targets=[0xBC69]),
|
||||
instruction(0xBC24, "CMP:E", "#H'01, R0"),
|
||||
instruction(0xBC26, "BEQ", "loc_BCD7", targets=[0xBCD7]),
|
||||
instruction(0xBC29, "CMP:E", "#H'02, R0"),
|
||||
instruction(0xBC2B, "BEQ", "loc_BD04", targets=[0xBD04]),
|
||||
instruction(0xBC2E, "CMP:E", "#H'07, R0"),
|
||||
instruction(0xBC30, "BEQ", "loc_BE05", targets=[0xBE05]),
|
||||
instruction(0xBC45, "CMP:E", "#H'04, R0"),
|
||||
instruction(0xBC47, "BEQ", "loc_BD0E", targets=[0xBD0E]),
|
||||
instruction(0xBC4A, "CMP:E", "#H'05, R0"),
|
||||
instruction(0xBC4C, "BEQ", "loc_BD80", targets=[0xBD80]),
|
||||
instruction(0xBC4F, "CMP:E", "#H'06, R0"),
|
||||
instruction(0xBC51, "BEQ", "loc_BDDB", targets=[0xBDDB]),
|
||||
instruction(0xBC54, "CMP:E", "#H'07, R0"),
|
||||
instruction(0xBC56, "BEQ", "loc_BE05", targets=[0xBE05]),
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
split = semantics["command_dispatch"]["state_split"]
|
||||
self.assertEqual(split["initial_idle_commands"], [0, 1, 2, 7])
|
||||
self.assertEqual(split["continuation_commands"], [4, 5, 6, 7])
|
||||
|
||||
command_1 = command_item(semantics["commands"], 0x01)
|
||||
self.assertIn("FAA2 == 0", command_1["availability_conditions"])
|
||||
self.assertIn("F861.bit7 == 0", command_1["availability_conditions"])
|
||||
|
||||
command_5 = command_item(semantics["commands"], 0x05)
|
||||
self.assertIn("FAA2 != 0", command_5["availability_conditions"])
|
||||
|
||||
def test_actual_bcd7_command1_response_marks_f852_stale(self):
|
||||
semantics = only_semantics(
|
||||
self,
|
||||
base_payload(
|
||||
[
|
||||
instruction(0xBCD4, "BRA", "loc_BE6F", targets=[0xBE6F]),
|
||||
instruction(0xBCD7, "MOV:G.B", "#H'04, @H'F850", [0xF850]),
|
||||
instruction(0xBCDC, "MOV:G.B", "@H'F861, R0", [0xF861]),
|
||||
instruction(0xBCE0, "MOV:G.B", "R0, @H'F851", [0xF851]),
|
||||
instruction(0xBCE4, "MOV:G.B", "@H'F862, R0", [0xF862]),
|
||||
instruction(0xBCE8, "MOV:G.B", "R0, @H'F851", [0xF851]),
|
||||
instruction(0xBCEC, "MOV:G.W", "@(-H'2000,R4), R0"),
|
||||
instruction(0xBCF0, "MOV:G.B", "R0, @H'F854", [0xF854]),
|
||||
instruction(0xBCF4, "SWAP.B", "R0"),
|
||||
instruction(0xBCF6, "MOV:G.B", "R0, @H'F853", [0xF853]),
|
||||
instruction(0xBCFA, "BSR", "loc_BA26", targets=[0xBA26]),
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
schema = semantics["response_schema"][0]
|
||||
byte_sources = {item["offset"]: item["source_expression"] for item in schema["bytes"]}
|
||||
self.assertEqual(byte_sources[0], "0x04")
|
||||
self.assertEqual(byte_sources[1], "rx[2]")
|
||||
self.assertEqual(byte_sources[2], "stale/unchanged")
|
||||
self.assertEqual(byte_sources[3], "primary_value_table_candidate")
|
||||
self.assertEqual(byte_sources[4], "primary_value_table_candidate")
|
||||
self.assertIn("avoid a fixed 04 00 qq hi lo", semantic_text(schema))
|
||||
|
||||
def test_actual_be4d_retry_error_echo_copies_rx_payload(self):
|
||||
semantics = only_semantics(
|
||||
self,
|
||||
base_payload(
|
||||
[
|
||||
instruction(0xBE4B, "BRA", "loc_BE6D", targets=[0xBE6D]),
|
||||
instruction(0xBE4D, "MOV:G.B", "#H'07, @H'F850", [0xF850]),
|
||||
instruction(0xBE52, "MOV:G.B", "@H'F861, R0", [0xF861]),
|
||||
instruction(0xBE56, "MOV:G.B", "R0, @H'F851", [0xF851]),
|
||||
instruction(0xBE5A, "MOV:G.W", "@H'F862, R0", [0xF862]),
|
||||
instruction(0xBE5E, "MOV:G.W", "R0, @H'F852", [0xF852]),
|
||||
instruction(0xBE62, "MOV:G.B", "@H'F864, R0", [0xF864]),
|
||||
instruction(0xBE66, "MOV:G.B", "R0, @H'F854", [0xF854]),
|
||||
instruction(0xBE6A, "BSR", "loc_BA26", targets=[0xBA26]),
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
schema = semantics["response_schema"][0]
|
||||
byte_sources = {item["offset"]: item["source_expression"] for item in schema["bytes"]}
|
||||
self.assertEqual(byte_sources, {0: "0x07", 1: "rx[1]", 2: "rx[2]", 3: "rx[3]", 4: "rx[4]"})
|
||||
self.assertIn("80 40 20 90", semantic_text(schema))
|
||||
self.assertIn("not a table", semantic_text(schema))
|
||||
|
||||
def test_timer_interrupt_model_surfaces_frt2_idle_heartbeat_counter(self):
|
||||
semantics = only_semantics(
|
||||
self,
|
||||
|
||||
Reference in New Issue
Block a user