1
0

Emulator learnings folded back into decompiler

This commit is contained in:
Aiden
2026-05-25 19:11:22 +10:00
parent 1fabf6587d
commit d2e7609bbf
16 changed files with 1468 additions and 87 deletions

View File

@@ -61,6 +61,17 @@ class SerialReconstructionTest(unittest.TestCase):
self.assertEqual(candidate["checksum_address"], 0xF85D)
self.assertEqual(candidate["tx_index_address"], 0xF9C2)
self.assertEqual(candidate["checksum_seed"], 0x5A)
self.assertEqual(
[role["name"] for role in candidate["roles"]],
["tx_frame", "tx_checksum", "tx_index"],
)
self.assertEqual(candidate["roles"][0]["address"], 0xF858)
self.assertEqual(candidate["roles"][1]["address"], 0xF85D)
self.assertEqual(candidate["roles"][2]["address"], 0xF9C2)
self.assertEqual(candidate["tx_path"]["kind"], "interrupt_driven_txi")
self.assertEqual(candidate["tx_path"]["initial_tdr_write_address"], 0x3008)
self.assertEqual(candidate["tx_path"]["txi_indexed_tdr_write_address"], 0x3108)
self.assertIn("TDRE", candidate["tx_path"]["summary"])
self.assertEqual(candidate["confidence"], "high")
self.assertEqual(candidate["confidence_score"], 0.95)
self.assertEqual(candidate["missing_evidence"], [])
@@ -84,8 +95,43 @@ class SerialReconstructionTest(unittest.TestCase):
payload = serial_reconstruction_json_payload(analysis)
self.assertEqual(payload["candidates"][0]["frame_length"], 6)
self.assertEqual(payload["candidates"][0]["roles"][1]["name"], "tx_checksum")
json.dumps(payload)
def test_candidate_timer_ram_roles_from_frt1_ocia_tick(self):
instructions = {
0xBEEA: ins(0xBEEA, "BCLR.B", "#5, @FRT1_TCSR", [0xFE91]),
0xBEEE: ins(0xBEEE, "TST.B", "@H'F9C0", [0xF9C0]),
0xBEF4: ins(0xBEF4, "ADD:Q.B", "#-1, @H'F9C0", [0xF9C0]),
0xBEF8: ins(0xBEF8, "TST.B", "@H'F9C1", [0xF9C1]),
0xBEFE: ins(0xBEFE, "ADD:Q.B", "#-1, @H'F9C1", [0xF9C1]),
0xBF02: ins(0xBF02, "TST.W", "@H'F9C6", [0xF9C6]),
0xBF08: ins(0xBF08, "ADD:Q.W", "#-1, @H'F9C6", [0xF9C6]),
}
analysis = analyze_serial_reconstruction(instructions)
self.assertEqual(analysis["candidates"], [])
roles = {role["name"]: role for role in analysis["ram_roles"]}
self.assertEqual(set(roles), {"post_tx_report_delay", "secondary_tx_report_delay", "periodic_report_countdown"})
self.assertEqual(roles["post_tx_report_delay"]["address"], 0xF9C0)
self.assertEqual(roles["secondary_tx_report_delay"]["address"], 0xF9C1)
self.assertEqual(roles["periodic_report_countdown"]["address"], 0xF9C6)
self.assertEqual(roles["periodic_report_countdown"]["width_bits"], 16)
self.assertIn("candidate/evidence-supported", roles["post_tx_report_delay"]["confidence"])
self.assertIn("emulator-guided timer behavior", roles["post_tx_report_delay"]["caveat"])
payload = serial_reconstruction_json_payload(analysis)
self.assertEqual(payload["ram_roles"][0]["name"], "post_tx_report_delay")
json.dumps(payload)
decrement_comment = serial_reconstruction_comment_for_instruction(analysis, 0xBEF4)
self.assertIn("RAM role post_tx_report_delay", decrement_comment)
self.assertIn("FRT1 OCIA periodic tick ISR", decrement_comment)
metadata = serial_reconstruction_metadata_for_instruction(analysis, 0xBF08)
self.assertEqual(metadata[0]["action"], "serial_reconstruction_ram_role")
self.assertEqual(metadata[0]["role_name"], "periodic_report_countdown")
def test_candidate_sci1_rx_frame_length_and_checksum_validation_pattern(self):
instructions = {
0x4FF0: ins(0x4FF0, "BSET.B", "#7, @H'FAA4", [0xFAA4]),