non-volatile storage emulation
This commit is contained in:
@@ -3,6 +3,8 @@ from __future__ import annotations
|
||||
from dataclasses import dataclass
|
||||
from typing import Iterable
|
||||
|
||||
from .x24164 import X24164Bus
|
||||
|
||||
|
||||
P9_ACK_BIT = 0x80
|
||||
P9_STROBE_BIT = 0x02
|
||||
@@ -27,6 +29,7 @@ class P9TraceEvent:
|
||||
source: str | None = None
|
||||
success: bool | None = None
|
||||
queue_depth: int | None = None
|
||||
message: str | None = None
|
||||
|
||||
def line(self) -> str:
|
||||
parts = [self.kind, f"ddr={self.ddr:02X}", f"dr={self.dr:02X}"]
|
||||
@@ -40,11 +43,18 @@ class P9TraceEvent:
|
||||
parts.append(f"source={self.source}")
|
||||
if self.queue_depth is not None:
|
||||
parts.append(f"queued={self.queue_depth}")
|
||||
if self.message is not None:
|
||||
parts.append(self.message)
|
||||
return " ".join(parts)
|
||||
|
||||
|
||||
class P9Bus:
|
||||
"""Small model for the ROM's P9 bit-banged serial handshake."""
|
||||
"""Small model for the ROM's P9 bit-banged serial handshake.
|
||||
|
||||
Board tracing ties P91/P97 to X24164 SCL/SDA. The legacy bit queue is
|
||||
retained for tests and exploratory scripts, while the X24164 model now
|
||||
drives SDA during recognized EEPROM transactions.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -52,6 +62,7 @@ class P9Bus:
|
||||
dr: int = 0x00,
|
||||
input_bits: Iterable[int] = (),
|
||||
wrapper_results: Iterable[bool] = (),
|
||||
x24164_bus: X24164Bus | None = None,
|
||||
) -> None:
|
||||
self.ddr = ddr & 0xFF
|
||||
self.dr_latch = dr & 0xFF
|
||||
@@ -64,6 +75,8 @@ class P9Bus:
|
||||
self.trace_events: list[P9TraceEvent] = []
|
||||
self.transmitted_bits: list[int] = []
|
||||
self.byte_candidates: list[int] = []
|
||||
self.x24164_bus = x24164_bus if x24164_bus is not None else X24164Bus()
|
||||
self._x24164_trace_index = 0
|
||||
|
||||
def write_ddr(self, value: int) -> int:
|
||||
self.ddr = value & 0xFF
|
||||
@@ -72,6 +85,7 @@ class P9Bus:
|
||||
|
||||
def write_dr(self, value: int) -> int:
|
||||
previous = self.dr_latch
|
||||
previous_ddr = self.ddr
|
||||
self.dr_latch = value & 0xFF
|
||||
self.trace_events.append(P9TraceEvent("write_dr", self.ddr, self.dr_latch, value=self.dr_latch))
|
||||
|
||||
@@ -86,6 +100,14 @@ class P9Bus:
|
||||
if edge == "rising" and bit7_output:
|
||||
self._record_transmitted_bit(data_bit)
|
||||
|
||||
self.x24164_bus.observe(
|
||||
previous_scl=bool(previous & P9_STROBE_BIT),
|
||||
previous_master_sda=bool(previous & P9_ACK_BIT) if previous_ddr & P9_ACK_BIT else True,
|
||||
current_scl=bool(self.dr_latch & P9_STROBE_BIT),
|
||||
current_master_sda=bool(self.dr_latch & P9_ACK_BIT) if self.ddr & P9_ACK_BIT else True,
|
||||
master_sda_output=bool(self.ddr & P9_ACK_BIT),
|
||||
)
|
||||
self._append_x24164_trace()
|
||||
return self.dr_latch
|
||||
|
||||
def read_ddr(self) -> int:
|
||||
@@ -96,9 +118,13 @@ class P9Bus:
|
||||
input_bit = None
|
||||
source = None
|
||||
if not (self.ddr & P9_ACK_BIT):
|
||||
x24164_bit = self.x24164_bus.sda_bit()
|
||||
if self.input_bits:
|
||||
input_bit = self.input_bits.pop(0)
|
||||
source = "queued_bit"
|
||||
elif x24164_bit is not None:
|
||||
input_bit = x24164_bit
|
||||
source = "x24164"
|
||||
else:
|
||||
input_bit = self.default_input_bit
|
||||
source = "default_bit"
|
||||
@@ -145,6 +171,72 @@ class P9Bus:
|
||||
events = self.trace_events if limit is None else self.trace_events[-limit:]
|
||||
return [event.line() for event in events]
|
||||
|
||||
def fast_start(self) -> None:
|
||||
self.x24164_bus.fast_start()
|
||||
self._append_x24164_trace()
|
||||
|
||||
def fast_stop(self) -> None:
|
||||
self.x24164_bus.fast_stop()
|
||||
self._append_x24164_trace()
|
||||
|
||||
def fast_master_ack(self, ack: bool = True) -> None:
|
||||
self.x24164_bus.fast_master_ack(ack)
|
||||
self._append_x24164_trace()
|
||||
|
||||
def fast_write_byte(self, value: int) -> bool:
|
||||
success = self.x24164_bus.fast_write_byte(value)
|
||||
self.trace_events.append(
|
||||
P9TraceEvent(
|
||||
"fast_write_byte",
|
||||
self.ddr,
|
||||
self.dr_latch,
|
||||
value=value & 0xFF,
|
||||
success=success,
|
||||
source="x24164",
|
||||
)
|
||||
)
|
||||
self._append_x24164_trace()
|
||||
return success
|
||||
|
||||
def fast_read_byte(self) -> int | None:
|
||||
value = self.x24164_bus.fast_read_byte()
|
||||
if value is not None:
|
||||
self.trace_events.append(P9TraceEvent("fast_read_byte", self.ddr, self.dr_latch, value=value, source="x24164"))
|
||||
self._append_x24164_trace()
|
||||
return value
|
||||
|
||||
def fast_read_word(self, address: int) -> tuple[bool, int]:
|
||||
success, value = self.x24164_bus.read_linear_word(address)
|
||||
self.trace_events.append(
|
||||
P9TraceEvent(
|
||||
"fast_read_word",
|
||||
self.ddr,
|
||||
self.dr_latch,
|
||||
value=(value >> 8) & 0xFF,
|
||||
success=success,
|
||||
source="x24164",
|
||||
message=f"addr={address & 0x0FFF:03X} word={value & 0xFFFF:04X}",
|
||||
)
|
||||
)
|
||||
self._append_x24164_trace()
|
||||
return success, value
|
||||
|
||||
def fast_write_word(self, address: int, value: int) -> bool:
|
||||
success = self.x24164_bus.write_linear_word(address, value)
|
||||
self.trace_events.append(
|
||||
P9TraceEvent(
|
||||
"fast_write_word",
|
||||
self.ddr,
|
||||
self.dr_latch,
|
||||
value=(value >> 8) & 0xFF,
|
||||
success=success,
|
||||
source="x24164",
|
||||
message=f"addr={address & 0x0FFF:03X} word={value & 0xFFFF:04X}",
|
||||
)
|
||||
)
|
||||
self._append_x24164_trace()
|
||||
return success
|
||||
|
||||
def _record_transmitted_bit(self, bit: int) -> None:
|
||||
self.transmitted_bits.append(bit)
|
||||
self.trace_events.append(P9TraceEvent("tx_bit", self.ddr, self.dr_latch, bit=bit))
|
||||
@@ -154,3 +246,9 @@ class P9Bus:
|
||||
byte = (byte << 1) | data_bit
|
||||
self.byte_candidates.append(byte)
|
||||
self.trace_events.append(P9TraceEvent("tx_byte", self.ddr, self.dr_latch, value=byte))
|
||||
|
||||
def _append_x24164_trace(self) -> None:
|
||||
new_events = self.x24164_bus.trace_events[self._x24164_trace_index :]
|
||||
self._x24164_trace_index = len(self.x24164_bus.trace_events)
|
||||
for event in new_events:
|
||||
self.trace_events.append(P9TraceEvent("x24164", self.ddr, self.dr_latch, message=event.line()))
|
||||
|
||||
Reference in New Issue
Block a user