Source code for src.tutorial.04.1_display

from typing import List
import pygame

ZOOM = 10
SCREEN_WIDTH = 64
SCREEN_HEIGHT = 32

BG_COLOR = (0xa0, 0xe6, 0xfa)
FG_COLOR = (0xff, 0xff, 0xff)
START_ADDR = 0x200
_MEM_SIZE = 4 * 1024
_FONTSET = [0xF0, 0x90, 0x90, 0x90, 0xF0,  # 0
            0x20, 0x60, 0x20, 0x20, 0x70,  # 1
            0xF0, 0x10, 0xF0, 0x80, 0xF0,  # 2
            0xF0, 0x10, 0xF0, 0x10, 0xF0,  # 3
            0x90, 0x90, 0xF0, 0x10, 0x10,  # 4
            0xF0, 0x80, 0xF0, 0x10, 0xF0,  # 5
            0xF0, 0x80, 0xF0, 0x90, 0xF0,  # 6
            0xF0, 0x10, 0x20, 0x40, 0x40,  # 7
            0xF0, 0x90, 0xF0, 0x90, 0xF0,  # 8
            0xF0, 0x90, 0xF0, 0x10, 0xF0,  # 9
            0xF0, 0x90, 0xF0, 0x90, 0x90,  # A
            0xE0, 0x90, 0xE0, 0x90, 0xE0,  # B
            0xF0, 0x80, 0x80, 0x80, 0xF0,  # C
            0xE0, 0x90, 0x90, 0x90, 0xE0,  # D
            0xF0, 0x80, 0xF0, 0x80, 0xF0,  # E
            0xF0, 0x80, 0xF0, 0x80, 0x80]  # F

_KEYS = {
    pygame.K_1: 0x1, pygame.K_2: 0x2, pygame.K_3: 0x3, pygame.K_4: 0xC,
    pygame.K_q: 0x4, pygame.K_w: 0x5, pygame.K_e: 0x6, pygame.K_r: 0xD,
    pygame.K_a: 0x7, pygame.K_s: 0x8, pygame.K_d: 0x9, pygame.K_f: 0xE,
    pygame.K_z: 0xA, pygame.K_x: 0x0, pygame.K_c: 0xB, pygame.K_v: 0xF
}


class Memory:

    def __init__(self):
        # 4KB memory
        self._ram = [0] * 4 * 1024
        # stack
        self._stack = []
        for i in range(len(_FONTSET)):
            self._ram[i] = _FONTSET[i]

    def stack_pop(self):
        return self._stack.pop()

    def stack_push(self, x: int):
        return self._stack.append(x)


[docs]class Display: def __init__(self): pygame.init() pygame.display.set_caption("CHIP8") self.canvas = pygame.display.set_mode((SCREEN_WIDTH * ZOOM, SCREEN_HEIGHT * ZOOM)) self.canvas.fill(BG_COLOR) pygame.display.update()
[docs] def render(self, screen_buf: List[List[int]]): self.draw_frame(screen_buf) pygame.display.update()
[docs] def draw_frame(self, screen_buf: List[List[int]]): self.canvas.fill(BG_COLOR) for y in range(SCREEN_HEIGHT): for x in range(SCREEN_WIDTH): if screen_buf[y][x] == 1: self.draw_pixel(x, y)
[docs] def draw_pixel(self, x: int, y: int): pygame.draw.rect( self.canvas, FG_COLOR, (x * ZOOM, y * ZOOM, ZOOM, ZOOM), 0 )
def quit(self): pygame.quit()
class Keyboard: def poll_event(self): pass class CPU: def __init__(self): self.memory = Memory() # 8 bits register self._reg_V = [0] * 16 # 16 bits register self._reg_PC = START_ADDR self._reg_I = 0 self.draw_flag = False self._screen_buf = [[0 for _ in range(640)] for _ in range(320)] self._keys_pressed_buf = [0] * 16 self._delay_timer = 0 self._sound_timer = 0 def cycle(self): pass class Machine: def __init__(self): self.display = Display() self.keyboard = Keyboard() self.cpu = CPU() def run(self): while True: self.cpu.cycle() self.keyboard.poll_event() self.display.render([]) def main(): machine = Machine() machine.run() if __name__ == '__main__': main()