reChip8
As the main entry point for re:Chip8 emulator, this class takes care of interfacing with the user and the internal devices.
Source code in rechip8/__main__.py
class reChip8:
"""
As the main entry point for re:Chip8 emulator,
this class takes care of interfacing with the user and
the internal devices.
"""
__slots__ = ("cpu", "display", "keypad", "memory")
def __init__(self, rom: str, mul: int) -> None:
"""
reChip8 Constructor.
The constructor is responsible for loading font and rom, and also initializing other
devices.
Args:
rom: Path to the ROM file.
mul: The screen size multiplier.
Attributes:
memory (Memory): Primary Memory of size 4096 bytes.
display (Display): Display Handler for rendering sprites.
keypad (Keypad): 16-key hexadecimal keypad for taking input.
cpu (CPU): Object representing Central Processing Unit of the emulator.
"""
self.memory: Memory = Memory()
self.load_font()
self.load_rom(rom)
self.display: Display = Display.create(multiplier=mul)
self.keypad: Keypad = Keypad()
self.cpu: CPU = CPU(
display=self.display, memory=self.memory, keypad=self.keypad
)
def load_font(self) -> None:
"""
Load Font from the `/bin/FONT` file in memory from location `0x0`
"""
self.memory.load_binary(files("rechip8.bin").joinpath("FONT").read_bytes())
logging.info(f"{TICK} Successfully loaded Fontset at location 0x0")
def load_rom(self, rom: str) -> None:
"""
Load ROM in memory from location `0x200` (512)
Args:
rom: Path to the ROM file.
"""
self.memory.load_binary(open(rom, "rb").read(), offset=INIT_LOC_CONSTANT)
logging.info(
f"{TICK} Successfully loaded ROM at location {hex(INIT_LOC_CONSTANT)}"
)
def tick(self) -> None:
"""
Method representing a single tick from the emulator.
"""
for ic in range(10):
if not self.cpu.halt:
self.cpu.cycle()
self.cpu.sync = not ic
self.display.render()
self.cpu.handle_timers()
def run(self) -> None:
"""
Step through the emulation indefinitely.
"""
is_running = True
while is_running:
self.tick()
for event in pygame.event.get():
if event.type == pygame.QUIT:
is_running = False
if event.type == pygame.KEYDOWN:
self.keypad.handle(event)
if event.type == pygame.KEYUP:
if event.key in self.keypad.keymap:
key = self.cpu.keypad.keymap[event.key]
if self.cpu.halt:
self.cpu.V[self.cpu.op.x] = key
self.cpu.halt = False
self.keypad.unset(key)
self.display.destroy()
__init__(self, rom, mul)
special
+
reChip8 Constructor. The constructor is responsible for loading font and rom, and also initializing other devices.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
rom |
str |
Path to the ROM file. |
required |
mul |
int |
The screen size multiplier. |
required |
Attributes:
Name | Type | Description |
---|---|---|
memory |
Memory |
Primary Memory of size 4096 bytes. |
display |
Display |
Display Handler for rendering sprites. |
keypad |
Keypad |
16-key hexadecimal keypad for taking input. |
cpu |
CPU |
Object representing Central Processing Unit of the emulator. |
Source code in rechip8/__main__.py
def __init__(self, rom: str, mul: int) -> None:
"""
reChip8 Constructor.
The constructor is responsible for loading font and rom, and also initializing other
devices.
Args:
rom: Path to the ROM file.
mul: The screen size multiplier.
Attributes:
memory (Memory): Primary Memory of size 4096 bytes.
display (Display): Display Handler for rendering sprites.
keypad (Keypad): 16-key hexadecimal keypad for taking input.
cpu (CPU): Object representing Central Processing Unit of the emulator.
"""
self.memory: Memory = Memory()
self.load_font()
self.load_rom(rom)
self.display: Display = Display.create(multiplier=mul)
self.keypad: Keypad = Keypad()
self.cpu: CPU = CPU(
display=self.display, memory=self.memory, keypad=self.keypad
)
load_font(self)
+
Load Font from the /bin/FONT
file in memory from location 0x0
Source code in rechip8/__main__.py
def load_font(self) -> None:
"""
Load Font from the `/bin/FONT` file in memory from location `0x0`
"""
self.memory.load_binary(files("rechip8.bin").joinpath("FONT").read_bytes())
logging.info(f"{TICK} Successfully loaded Fontset at location 0x0")
load_rom(self, rom)
+
Load ROM in memory from location 0x200
(512)
Parameters:
Name | Type | Description | Default |
---|---|---|---|
rom |
str |
Path to the ROM file. |
required |
Source code in rechip8/__main__.py
def load_rom(self, rom: str) -> None:
"""
Load ROM in memory from location `0x200` (512)
Args:
rom: Path to the ROM file.
"""
self.memory.load_binary(open(rom, "rb").read(), offset=INIT_LOC_CONSTANT)
logging.info(
f"{TICK} Successfully loaded ROM at location {hex(INIT_LOC_CONSTANT)}"
)
tick(self)
+
Method representing a single tick from the emulator.
Source code in rechip8/__main__.py
def tick(self) -> None:
"""
Method representing a single tick from the emulator.
"""
for ic in range(10):
if not self.cpu.halt:
self.cpu.cycle()
self.cpu.sync = not ic
self.display.render()
self.cpu.handle_timers()
run(self)
+
Step through the emulation indefinitely.
Source code in rechip8/__main__.py
def run(self) -> None:
"""
Step through the emulation indefinitely.
"""
is_running = True
while is_running:
self.tick()
for event in pygame.event.get():
if event.type == pygame.QUIT:
is_running = False
if event.type == pygame.KEYDOWN:
self.keypad.handle(event)
if event.type == pygame.KEYUP:
if event.key in self.keypad.keymap:
key = self.cpu.keypad.keymap[event.key]
if self.cpu.halt:
self.cpu.V[self.cpu.op.x] = key
self.cpu.halt = False
self.keypad.unset(key)
self.display.destroy()