Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions src/tiny8/cpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
instruction handlers by defining methods named ``op_<mnemonic>`` on ``CPU``.
"""

from typing import Dict, List, Optional, Tuple
from typing import Optional

from .memory import Memory

Expand All @@ -29,18 +29,18 @@ class CPU:
currently-loaded program.

Attributes:
regs (List[int]): 32 8-bit general purpose registers (R0..R31).
regs (list[int]): 32 8-bit general purpose registers (R0..R31).
pc (int): Program counter (index into ``program``).
sp (int): Stack pointer (index into RAM in the associated
:class:`tiny8.memory.Memory`).
sreg (int): Status register bits stored in a single integer (I, T,
H, S, V, N, Z, C).
cycle (int): Instruction execution counter.
reg_trace (List[Tuple[int, int, int]]): Per-cycle register change
reg_trace (list[tuple[int, int, int]]): Per-cycle register change
trace entries of the form ``(cycle, reg, new_value)``.
mem_trace (List[Tuple[int, int, int]]): Per-cycle memory change
mem_trace (list[tuple[int, int, int]]): Per-cycle memory change
trace entries of the form ``(cycle, addr, new_value)``.
step_trace (List[dict]): Full per-step snapshots useful for
step_trace (list[dict]): Full per-step snapshots useful for
visualization and debugging.

Note:
Expand All @@ -52,7 +52,7 @@ class CPU:
def __init__(self, memory: Optional[Memory] = None):
self.mem = memory or Memory()
# 32 general purpose 8-bit registers R0-R31
self.regs: List[int] = [0] * 32
self.regs: [int] = [0] * 32
# Program Counter (word-addressable for AVR) - we use byte addressing for simplicity
self.pc: int = 0
# Stack Pointer - point into RAM
Expand All @@ -62,16 +62,16 @@ def __init__(self, memory: Optional[Memory] = None):
# Cycle counter
self.cycle: int = 0
# Simple interrupt vector table (addr->enabled)
self.interrupts: Dict[int, bool] = {}
self.interrupts: dict[int, bool] = {}
# Execution trace of register/memory changes per cycle
self.reg_trace: List[Tuple[int, int, int]] = [] # (cycle, reg, newval)
self.mem_trace: List[Tuple[int, int, int]] = [] # (cycle, addr, newval)
self.reg_trace: list[tuple[int, int, int]] = [] # (cycle, reg, newval)
self.mem_trace: list[tuple[int, int, int]] = [] # (cycle, addr, newval)
# Full step trace: list of dicts with cycle, pc, instr_text, regs snapshot, optional mem snapshot
self.step_trace: List[dict] = []
self.step_trace: list[dict] = []
# Program area - list of instructions as tuples: (mnemonic, *operands)
self.program: List[Tuple[str, Tuple]] = []
self.program: list[tuple[str, tuple]] = []
# Labels -> pc
self.labels: Dict[str, int] = {}
self.labels: dict[str, int] = {}
# Running state
self.running = False

Expand Down Expand Up @@ -289,11 +289,11 @@ def write_ram(self, addr: int, val: int) -> None:
self.mem_trace.append((self.cycle, addr, val & 0xFF))

# Program loading
def load_program(self, program: List[Tuple[str, Tuple]], labels: Dict[str, int]):
def load_program(self, program: list[tuple[str, tuple]], labels: dict[str, int]):
"""Load an assembled program into the CPU.

Args:
program: List of ``(mnemonic, operands)`` tuples returned by the
program: list of ``(mnemonic, operands)`` tuples returned by the
assembler.
labels: Mapping of label strings to instruction indices.

Expand Down
12 changes: 5 additions & 7 deletions src/tiny8/memory.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
"""Memory model for tiny8 - simple RAM and ROM with change tracking."""

from typing import List, Tuple


class Memory:
"""
Expand Down Expand Up @@ -42,8 +40,8 @@ def __init__(self, ram_size: int = 2048, rom_size: int = 2048):
self.ram = [0] * ram_size
self.rom = [0] * rom_size
# change logs: list of (addr, old, new, cycle)
self.ram_changes: List[Tuple[int, int, int, int]] = []
self.rom_changes: List[Tuple[int, int, int, int]] = []
self.ram_changes: list[tuple[int, int, int, int]] = []
self.rom_changes: list[tuple[int, int, int, int]] = []

def read_ram(self, addr: int) -> int:
"""Read and return the value stored in RAM at the specified address.
Expand Down Expand Up @@ -87,7 +85,7 @@ def write_ram(self, addr: int, value: int, cycle: int = 0) -> None:
if old != self.ram[addr]:
self.ram_changes.append((addr, old, self.ram[addr], cycle))

def load_rom(self, data: List[int]) -> None:
def load_rom(self, data: list[int]) -> None:
"""Load a ROM image into the emulator's ROM buffer.

Args:
Expand Down Expand Up @@ -128,7 +126,7 @@ def read_rom(self, addr: int) -> int:
raise IndexError("ROM address out of range")
return self.rom[addr]

def snapshot_ram(self) -> List[int]:
def snapshot_ram(self) -> list[int]:
"""Return a snapshot copy of the emulator's RAM.

Returns:
Expand All @@ -139,7 +137,7 @@ def snapshot_ram(self) -> List[int]:
"""
return list(self.ram)

def snapshot_rom(self) -> List[int]:
def snapshot_rom(self) -> list[int]:
"""Return a snapshot copy of the ROM contents.

Returns:
Expand Down