Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # NumPy-8! Version 1.0 coded by nonogamer9 (c) 2025
- # https://my.numworks.com/python/nonogamer9/numpyeight
- # This is a CHIP-8 Emulator For Stock Numworks! So Performance can be abysmal!!
- from kandinsky import fill_rect, color
- from ion import keydown
- import time
- import random
- class Chip8:
- def __init__(self):
- self.memory = [0] * 4096
- self.V = [0] * 16
- self.I = 0
- self.pc = 0x200
- self.stack = []
- self.delay_timer = 0
- self.sound_timer = 0
- self.keypad = [False] * 16
- self.display = [[False for _ in range(64)] for _ in range(32)]
- self.opcode = 0
- self.draw_flag = False
- self.load_font_set()
- def load_font_set(self):
- font_set = [
- 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
- ]
- for i, byte in enumerate(font_set):
- self.memory[i] = byte
- def emulate_cycle(self):
- self.opcode = (self.memory[self.pc] << 8) | self.memory[self.pc + 1]
- self.pc += 2
- x = (self.opcode & 0x0F00) >> 8
- y = (self.opcode & 0x00F0) >> 4
- nnn = self.opcode & 0x0FFF
- nn = self.opcode & 0x00FF
- n = self.opcode & 0x000F
- if self.opcode & 0xF000 == 0x0000:
- if nn == 0xE0:
- self.display = [[False for _ in range(64)] for _ in range(32)]
- self.draw_flag = True
- elif nn == 0xEE:
- self.pc = self.stack.pop()
- elif self.opcode & 0xF000 == 0x1000:
- self.pc = nnn
- elif self.opcode & 0xF000 == 0x2000:
- self.stack.append(self.pc)
- self.pc = nnn
- elif self.opcode & 0xF000 == 0x3000:
- if self.V[x] == nn:
- self.pc += 2
- elif self.opcode & 0xF000 == 0x4000:
- if self.V[x] != nn:
- self.pc += 2
- elif self.opcode & 0xF000 == 0x5000:
- if self.V[x] == self.V[y]:
- self.pc += 2
- elif self.opcode & 0xF000 == 0x6000:
- self.V[x] = nn
- elif self.opcode & 0xF000 == 0x7000:
- self.V[x] = (self.V[x] + nn) & 0xFF
- elif self.opcode & 0xF000 == 0x8000:
- if n == 0x0:
- self.V[x] = self.V[y]
- elif n == 0x1:
- self.V[x] |= self.V[y]
- elif n == 0x2:
- self.V[x] &= self.V[y]
- elif n == 0x3:
- self.V[x] ^= self.V[y]
- elif n == 0x4:
- sum = self.V[x] + self.V[y]
- self.V[0xF] = 1 if sum > 255 else 0
- self.V[x] = sum & 0xFF
- elif n == 0x5:
- self.V[0xF] = 1 if self.V[x] > self.V[y] else 0
- self.V[x] = (self.V[x] - self.V[y]) & 0xFF
- elif n == 0x6:
- self.V[0xF] = self.V[x] & 0x1
- self.V[x] >>= 1
- elif n == 0x7:
- self.V[0xF] = 1 if self.V[y] > self.V[x] else 0
- self.V[x] = (self.V[y] - self.V[x]) & 0xFF
- elif n == 0xE:
- self.V[0xF] = (self.V[x] & 0x80) >> 7
- self.V[x] = (self.V[x] << 1) & 0xFF
- elif self.opcode & 0xF000 == 0x9000:
- if self.V[x] != self.V[y]:
- self.pc += 2
- elif self.opcode & 0xF000 == 0xA000:
- self.I = nnn
- elif self.opcode & 0xF000 == 0xB000:
- self.pc = nnn + self.V[0]
- elif self.opcode & 0xF000 == 0xC000:
- self.V[x] = random.randint(0, 255) & nn
- elif self.opcode & 0xF000 == 0xD000:
- self.V[0xF] = 0
- for row in range(n):
- sprite_byte = self.memory[self.I + row]
- for col in range(8):
- if sprite_byte & (0x80 >> col) != 0:
- if self.display[(self.V[y] + row) % 32][(self.V[x] + col) % 64]:
- self.V[0xF] = 1
- self.display[(self.V[y] + row) % 32][(self.V[x] + col) % 64] ^= True
- self.draw_flag = True
- elif self.opcode & 0xF000 == 0xE000:
- if nn == 0x9E:
- if self.keypad[self.V[x]]:
- self.pc += 2
- elif nn == 0xA1:
- if not self.keypad[self.V[x]]:
- self.pc += 2
- elif self.opcode & 0xF000 == 0xF000:
- if nn == 0x07:
- self.V[x] = self.delay_timer
- elif nn == 0x0A:
- key_pressed = False
- for i in range(16):
- if self.keypad[i]:
- self.V[x] = i
- key_pressed = True
- break
- if not key_pressed:
- self.pc -= 2
- elif nn == 0x15:
- self.delay_timer = self.V[x]
- elif nn == 0x18:
- self.sound_timer = self.V[x]
- elif nn == 0x1E:
- self.I += self.V[x]
- elif nn == 0x29:
- self.I = self.V[x] * 5
- elif nn == 0x33:
- self.memory[self.I] = self.V[x] // 100
- self.memory[self.I + 1] = (self.V[x] % 100) // 10
- self.memory[self.I + 2] = self.V[x] % 10
- elif nn == 0x55:
- for i in range(x + 1):
- self.memory[self.I + i] = self.V[i]
- elif nn == 0x65:
- for i in range(x + 1):
- self.V[i] = self.memory[self.I + i]
- if self.delay_timer > 0:
- self.delay_timer -= 1
- if self.sound_timer > 0:
- self.sound_timer -= 1
- def update_screen(self):
- for y in range(32):
- for x in range(64):
- if self.display[y][x]:
- fill_rect(x*2, y*2, 2, 2, color(255,255,255))
- else:
- fill_rect(x*2, y*2, 2, 2, color(0,0,0))
- def handle_input(self):
- key_map = {
- 0: 4, 1: 5, 2: 6, 3: 7,
- 4: 8, 5: 9, 6: 10, 7: 11,
- 8: 12, 9: 13, 10: 14, 11: 15,
- 12: 0, 13: 1, 14: 2, 15: 3
- }
- for nw_key, chip8_key in key_map.items():
- self.keypad[chip8_key] = keydown(nw_key)
- def load_rom(self, rom_data):
- for i, byte in enumerate(rom_data):
- self.memory[0x200 + i] = byte
- def run(self):
- while True:
- self.emulate_cycle()
- self.handle_input()
- if self.draw_flag:
- self.update_screen()
- self.draw_flag = False
- time.sleep(1/60)
- # this is where you put your converted roms to! Just use this pastebin script and your chip8 roms and they will work! : https://pastebin.com/UR6xg0jc
- rom_data = [
- 0x00, 0xE0, 0xA2, 0x48, 0x60, 0x00, 0x61, 0x1E, 0x62, 0x00, 0xD2, 0x02, 0xD2, 0x12, 0x72, 0x08,
- 0x32, 0x40, 0x12, 0x0A, 0x60, 0x00, 0x61, 0x3E, 0x62, 0x02, 0xA2, 0x4A, 0xD0, 0x2E, 0xD1, 0x2E,
- 0x72, 0x0E, 0xD0, 0x2E, 0xD1, 0x2E, 0xA2, 0x58, 0x60, 0x0B, 0x61, 0x08, 0xD0, 0x1F, 0x70, 0x0A,
- 0xA2, 0x67, 0xD0, 0x1F, 0x70, 0x0A, 0xA2, 0x76, 0xD0, 0x1F, 0x70, 0x03, 0xA2, 0x85, 0xD0, 0x1F,
- 0x70, 0x0A, 0xA2, 0x94, 0xD0, 0x1F, 0x12, 0x46, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
- 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0xFF, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0xFF, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0xFF, 0xFF,
- ]
- chip8 = Chip8()
- chip8.load_rom(rom_data)
- chip8.run()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement