EMualtor adjustments
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user