1
0

EMualtor adjustments

This commit is contained in:
Aiden
2026-05-25 20:42:45 +10:00
parent d2e7609bbf
commit 3ab79648ff
17 changed files with 3047 additions and 83 deletions

View File

@@ -19,6 +19,7 @@ KEY_STATE_ADDRESSES: tuple[int, ...] = (
0xF9C0,
0xF9C1,
0xF9C3,
0xF9C4,
0xF9C5,
0xF9C6,
0xF9C8,
@@ -52,6 +53,7 @@ def analyze_serial_gate(payload: dict[str, Any]) -> JsonObject:
"queue_send_gate_loc_BAF2": _queue_send_gate(by_address),
"resend_gate_path": _resend_gate_path(by_address),
"rx_session_maintenance": _rx_session_maintenance(by_address),
"idle_heartbeat_gate_loc_4046": _idle_heartbeat_gate(payload, by_address),
"timer_tick_evidence": _timer_tick_evidence(payload, by_address),
}
access_summary = _state_access_summary(instructions, labels)
@@ -101,6 +103,15 @@ def format_text_report(analysis: dict[str, Any]) -> str:
lines.append(" Candidate timer roles:")
for role in roles:
lines.append(f" - {role['address_hex']}: {role['role']}")
timer = section.get("timer")
if isinstance(timer, dict):
source = timer.get("source")
handler = timer.get("handler_address_hex")
ocra = timer.get("ocra_value_hex")
period = timer.get("observed_period_ms_candidate")
timer_bits = [str(part) for part in (source, handler, f"OCRA={ocra}" if ocra else "", f"observed period ~= {period}ms" if period else "") if part]
if timer_bits:
lines.append(f" Timer: {', '.join(timer_bits)}")
lines.extend(["", "State address readers/writers:"])
for entry in analysis.get("state_accesses", []):
@@ -273,6 +284,76 @@ def _rx_session_maintenance(by_address: dict[int, JsonObject]) -> JsonObject:
}
def _idle_heartbeat_gate(payload: dict[str, Any], by_address: dict[int, JsonObject]) -> JsonObject:
vector = _vector_entry(payload, 0x006A, "frt2_ocia")
handler = _int_field(vector, "target") if vector else None
if handler is None:
handler = 0xBF23
addresses = [
0x4046,
0x404A,
0x404C,
0x4050,
0x4052,
0x4056,
0x4058,
0x4059,
0x405F,
0x4063,
0x4067,
0x406C,
0x4070,
0x40E0,
0xBA31,
handler,
0xBF27,
0xBF2D,
]
present = _has_all(by_address, (0x4046, 0x4050, 0x4067, 0x40E0, 0xBA31, handler, 0xBF2D))
return {
"title": "loc_4046 idle heartbeat/report gate",
"present": present,
"summary": (
"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."
),
"items": _items(by_address, addresses),
"gate_address_hex": h16(0x4046),
"queue_write_address_hex": h16(0x4067),
"initial_reload_address_hex": h16(0x40E0),
"post_tx_reload_address_hex": h16(0xBA31),
"tick_handler_address_hex": h16(handler),
"decrement_address_hex": h16(0xBF2D),
"initial_reload_value_hex": "H'14",
"post_tx_reload_value_hex": "H'07",
"timer": {
"source": "FRT2 OCIA",
"vector_address_hex": h16(0x006A),
"handler_address_hex": h16(handler),
"vector_target_label": str(vector.get("target_label", "")) if vector else "",
"tcr_address_hex": h16(0xFEA0),
"tcsr_address_hex": h16(0xFEA1),
"ocra_address_hex": h16(0xFEA4),
"ocra_value_hex": "H'7A12",
"clock_select": "CKS1=1 CKS0=0 => phi/32",
"observed_period_ms_candidate": 700,
"manual_reference": "Manual/0900766b802125d0.md:12038 FRT CKS1/CKS0 clock select",
},
"candidate_timer_roles": [
{
"address": 0xF9C4,
"address_hex": h16(0xF9C4),
"role": "candidate idle heartbeat/report gate countdown",
"evidence_address_hex": h16(0xBF2D),
}
],
"required_addresses_hex": [h16(address) for address in (0x4046, 0x4050, 0x4067, 0x40E0, 0xBA31, handler, 0xBF2D)],
}
def _timer_tick_evidence(payload: dict[str, Any], by_address: dict[int, JsonObject]) -> JsonObject:
vector = _vector_entry(payload, 0x0062, "frt1_ocia")
handler = _int_field(vector, "target") if vector else None