emualtor working
This commit is contained in:
36
tests/test_consistency.py
Normal file
36
tests/test_consistency.py
Normal file
@@ -0,0 +1,36 @@
|
||||
import unittest
|
||||
|
||||
from h8536.consistency import analyze_decompiler_consistency, format_consistency_report
|
||||
|
||||
|
||||
class ConsistencyTest(unittest.TestCase):
|
||||
def test_flags_byte_immediate_word_destination_cases(self):
|
||||
payload = {
|
||||
"instructions": [
|
||||
{
|
||||
"address": 0x4067,
|
||||
"text": "MOV:G.W #H'00, @(-H'0790,R2)",
|
||||
"mnemonic": "MOV:G.W",
|
||||
"operands": "#H'00, @(-H'0790,R2)",
|
||||
},
|
||||
{
|
||||
"address": 0x5000,
|
||||
"text": "MOV:I.W #H'1234, R0",
|
||||
"mnemonic": "MOV:I.W",
|
||||
"operands": "#H'1234, R0",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
analysis = analyze_decompiler_consistency(payload)
|
||||
|
||||
self.assertEqual(len(analysis["checks"]), 1)
|
||||
check = analysis["checks"][0]
|
||||
self.assertEqual(check["address"], 0x4067)
|
||||
self.assertEqual(check["zero_extended_value_hex"], "0x0000")
|
||||
self.assertIn("zero-extended word", check["summary"])
|
||||
self.assertIn("H'4067", format_consistency_report(analysis))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -47,6 +47,17 @@ class EmulatorAddressingTest(unittest.TestCase):
|
||||
self.assertEqual(emulator.cpu.regs[0], 0x00C7)
|
||||
self.assertEqual(emulator.cpu.pc, 0x1006)
|
||||
|
||||
def test_byte_immediate_to_word_destination_writes_zero_extended_word(self):
|
||||
rom = rom_with_reset()
|
||||
rom[0x1000:0x1005] = b"\x1D\xF8\x70\x06\xAB" # MOV:G.W #H'AB, @H'F870
|
||||
|
||||
emulator = H8536Emulator(bytes(rom))
|
||||
emulator.memory.write16(0xF870, 0xFFFF)
|
||||
emulator.step()
|
||||
|
||||
self.assertEqual(emulator.memory.read16(0xF870), 0x00AB)
|
||||
self.assertEqual(emulator.cpu.pc, 0x1005)
|
||||
|
||||
def test_signed_byte_displacement_addresses_below_base(self):
|
||||
rom = rom_with_reset()
|
||||
rom[0x1000:0x1003] = b"\xE1\xFE\x81" # MOV:G.B @(H'-02,R1), R1
|
||||
|
||||
@@ -352,7 +352,7 @@ class EmulatorProbeTest(unittest.TestCase):
|
||||
self.assertEqual(decisions[0x4046], "f9c4_zero_continue")
|
||||
self.assertEqual(decisions[0x4050], "enqueue_candidate_faa5_clear")
|
||||
self.assertEqual(decisions[0x4063], "enqueue_zero_report")
|
||||
self.assertEqual(decisions[0x4067], "write_report_00ff_to_queue_slot")
|
||||
self.assertEqual(decisions[0x4067], "write_report_0000_to_queue_slot")
|
||||
self.assertTrue(any("recent_report_gates:" == line for line in report.lines()))
|
||||
|
||||
|
||||
|
||||
@@ -121,6 +121,41 @@ class PseudocodeTest(unittest.TestCase):
|
||||
self.assertIn("loc_0110:", text)
|
||||
self.assertIn("return;", text)
|
||||
|
||||
def test_zero_extends_byte_immediate_to_word_destination(self):
|
||||
payload = {
|
||||
"vectors": [{"address": 0, "name": "reset", "target": 0x4067, "target_label": "loc_4067"}],
|
||||
"call_graph": {
|
||||
"nodes": [
|
||||
{
|
||||
"start": 0x4067,
|
||||
"end": 0x4067,
|
||||
"label": "loc_4067",
|
||||
"sources": ["reset"],
|
||||
"instruction_count": 1,
|
||||
"calls": [],
|
||||
},
|
||||
],
|
||||
"edges": [],
|
||||
},
|
||||
"instructions": [
|
||||
{
|
||||
"address": 0x4067,
|
||||
"text": "MOV:G.W #H'00, @(-H'0790,R2)",
|
||||
"mnemonic": "MOV:G.W",
|
||||
"operands": "#H'00, @(-H'0790,R2)",
|
||||
"kind": "normal",
|
||||
"targets": [],
|
||||
"references": [],
|
||||
"comment": "",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
text = generate_pseudocode(payload, options=PseudocodeOptions(structured=False))
|
||||
|
||||
self.assertIn("zero_extend8_to16(0x00)", text)
|
||||
self.assertIn("byte immediate zero-extended into word destination", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
@@ -334,6 +334,21 @@ class SerialPseudocodeTest(unittest.TestCase):
|
||||
"observed_frames_hex": ["00 00 07 80 00 DD"],
|
||||
},
|
||||
],
|
||||
"runtime_confirmed_paths": [
|
||||
{
|
||||
"name": "idle_heartbeat_report_runtime_confirmation",
|
||||
"report_id_hex": "H'0000",
|
||||
"queue_write_semantics": "MOV:G.W #H'00 writes H'0000 to the queue slot",
|
||||
"emitted_frame_hex": "00 00 00 00 80 DA",
|
||||
}
|
||||
],
|
||||
"consistency_checks": [
|
||||
{
|
||||
"name": "idle_heartbeat_report_id_width",
|
||||
"status": "pass",
|
||||
"summary": "MOV:G.W zero-extends the H'00 immediate.",
|
||||
}
|
||||
],
|
||||
"observed_autonomous_output_caveat": "Observed autonomous output is limited to heartbeat/call/cam-power; other controls may require host/device requests first.",
|
||||
"evidence_addresses_hex": ["H'BB20", "H'BB43"],
|
||||
},
|
||||
@@ -404,10 +419,13 @@ class SerialPseudocodeTest(unittest.TestCase):
|
||||
self.assertIn("static bool sci1_candidate_main_report_gate_open(void)", text)
|
||||
self.assertIn("static bool sci1_candidate_report_queue_nonempty(void)", text)
|
||||
self.assertIn("static bool sci1_candidate_idle_heartbeat_enqueue_gate_open(void)", text)
|
||||
self.assertIn("candidate_enqueue_report(0x0000u);", text)
|
||||
self.assertIn("static bool sci1_candidate_periodic_resend_gate_open(void)", text)
|
||||
self.assertIn("TX/autonomous report model candidate:", text)
|
||||
self.assertIn("loc_BB43 -> loc_BA26: bytes 0..2 encode candidate logical index/report id; bytes 3..4 come from current_value_table_candidate", text)
|
||||
self.assertIn("heartbeat_or_idle_report_candidate: 00 00 00 00 80 DA", text)
|
||||
self.assertIn("runtime confirmation: idle_heartbeat_report_runtime_confirmation: report H'0000 emits 00 00 00 00 80 DA", text)
|
||||
self.assertIn("consistency idle_heartbeat_report_id_width: pass", text)
|
||||
self.assertIn("heartbeat/periodic resend candidate:", text)
|
||||
self.assertIn("F9C6 reload H'01F4", text)
|
||||
self.assertIn("BED5 resend path", text)
|
||||
|
||||
@@ -354,6 +354,8 @@ class SerialSemanticsTest(unittest.TestCase):
|
||||
self.assertIn("bytes 0..2", report_text)
|
||||
self.assertIn("current_value_table", report_text)
|
||||
self.assertIn("00 00 15 80 00 cf", report_text)
|
||||
self.assertIn("idle_heartbeat_report_runtime_confirmation", report_text)
|
||||
self.assertIn("idle_heartbeat_report_id_width", report_text)
|
||||
self.assertIn("host/device request", report_text)
|
||||
|
||||
def test_periodic_resend_model_marks_heartbeat_constants(self):
|
||||
@@ -381,7 +383,9 @@ class SerialSemanticsTest(unittest.TestCase):
|
||||
self.assertIn("faa2 == 0", gate_text)
|
||||
self.assertIn("f9c0 == 0", gate_text)
|
||||
self.assertIn("f9c4 == 0", gate_text)
|
||||
self.assertIn("h'00ff", gate_text)
|
||||
self.assertIn("h'0000", gate_text)
|
||||
self.assertIn("zero-extended", gate_text)
|
||||
self.assertIn("00 00 00 00 80 da", gate_text)
|
||||
self.assertIn("f9b5 != f9b0", gate_text)
|
||||
self.assertIn("bb43", gate_text)
|
||||
self.assertIn("be9e", gate_text)
|
||||
|
||||
Reference in New Issue
Block a user