61 lines
No EOL
1.9 KiB
Python
61 lines
No EOL
1.9 KiB
Python
from abc import ABC, abstractmethod
|
|
import crcmod # pyright: ignore[reportMissingTypeStubs]
|
|
from queue import Queue
|
|
from flash.shared import FlashChip
|
|
|
|
class DCCEmulatedHost(ABC):
|
|
def __init__(self, loader: bytes | bytearray, loader_offset: int, loader_ram_size: int, breakpoint_loader: bool=False):
|
|
self._is_bp_loader: bool = breakpoint_loader
|
|
self._bp_loader_buf_in: Queue[int] = Queue()
|
|
self._bp_loader_buf_out: list[int] = []
|
|
|
|
self._loader_data: bytes = bytes(loader)
|
|
self._loader_start: int = loader_offset
|
|
|
|
@abstractmethod
|
|
def run(self):
|
|
pass
|
|
|
|
@abstractmethod
|
|
def mount_flash_chip(self, chip: FlashChip, chip_offset: int, chip_size: int):
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _dcc_read(self) -> int:
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _dcc_write(self, data: int):
|
|
pass
|
|
|
|
@abstractmethod
|
|
def _dcc_flush_buffer(self):
|
|
pass
|
|
|
|
def dcc_read_packet(self, progress: bool=False):
|
|
read_item_count = self._dcc_read()
|
|
crc_hash_func = crcmod.mkCrcFun(0x104c11db7, 0xffffffff, False, 0) # pyright: ignore[reportUnknownVariableType, reportUnknownMemberType]
|
|
read_data = bytearray()
|
|
|
|
for i in range(read_item_count):
|
|
get_data = self._dcc_read()
|
|
get_index = i + 1
|
|
|
|
if progress and (((get_index % 50) == 0)):
|
|
print(f"got {get_index} out of {read_item_count}", end="\r")
|
|
|
|
read_data += get_data.to_bytes(4, "little")
|
|
|
|
crc32_sum = self._dcc_read()
|
|
|
|
crc32_hash = crc_hash_func(read_data) # pyright: ignore[reportUnknownVariableType]
|
|
assert crc32_sum == crc32_hash, f"Packet checksum is invalid! 0x{crc32_sum:08x} != 0x{crc32_hash:08x}"
|
|
|
|
return read_data
|
|
|
|
def dcc_write_packet(self, data: list[int]):
|
|
for p in data:
|
|
self._dcc_write(p)
|
|
|
|
if self._is_bp_loader:
|
|
self._dcc_flush_buffer() |