diff --git a/index.html b/index.html index 7b31015..c6924f3 100644 --- a/index.html +++ b/index.html @@ -8,32 +8,48 @@ + + -
- - + const emulatorCanvas = document.getElementById('emulator-screen'); + + // Loop + while(true) { + emulator.emulateCycle(); + + emulator.drawGraphics(); + emulator.drawToCanvas(emulatorCanvas, 4); + } + \ No newline at end of file diff --git a/src/RNG.ts b/src/RNG.ts new file mode 100644 index 0000000..5776003 --- /dev/null +++ b/src/RNG.ts @@ -0,0 +1,23 @@ +class RNG { + private seed: number; + + constructor(seed: number) { + this.seed = seed; + } + + private static readonly A: number = 1664525; + private static readonly C: number = 1013904223; + private static readonly MOD: number = Math.pow(2, 32); + + // Returns a floating point num from 0 to 1 + next(): number { + this.seed = (RNG.A * this.seed + RNG.C) % RNG.MOD; + return this.seed / RNG.MOD; + } + + nextInt(min: number, max: number): number { + return Math.floor(this.next() * (max - min + 1)) + min; + } +} + +export default RNG; \ No newline at end of file diff --git a/src/chip8Emulator.ts b/src/chip8Emulator.ts index 51cfc50..93f01c2 100644 --- a/src/chip8Emulator.ts +++ b/src/chip8Emulator.ts @@ -1,17 +1,23 @@ import CPU from './cpu'; import Keyboard from './keyboard' +import RNG from './RNG' class Chip8Emulator { + cpu: CPU; keyboard: Keyboard; + rom: Uint8Array; + constructor() { + this.cpu = new CPU(); this.keyboard = new Keyboard(); + this.rom = new Uint8Array(); } loadRom(rom: Uint8Array) { - + this.rom = rom; } emulateCycle() { @@ -26,10 +32,38 @@ class Chip8Emulator { } - setKeys() { + drawToCanvas(canvas: HTMLCanvasElement, size: number) { + let ctx = canvas.getContext('2d') as CanvasRenderingContext2D; + let width = 64*size; + let height = 32*size; + // Clear screen + ctx.fillStyle = "BLACK"; + ctx.fillRect(0, 0, width, height); + + // Draw rectangles as pixels + for(let i = 0; i < this.cpu.displayMemory.length; i++) { + let isOn: number = this.cpu.displayMemory[i]; + if(isOn === 1) { + let y = Math.floor(i/width); + let x = i - (y*width); + + ctx.fillStyle = "WHITE"; + ctx.fillRect(x, y, 1, 1); + } + } } + keyDownEvent(key: number) { + this.keyboard.userKeyPressedDown(key); + } + + keyUpEvent(key: number) { + this.keyboard.userKeyPressedUp(key); + } + + + } export default Chip8Emulator; \ No newline at end of file diff --git a/src/cpu.ts b/src/cpu.ts index 802a9ef..74813ec 100644 --- a/src/cpu.ts +++ b/src/cpu.ts @@ -1,3 +1,5 @@ +import RNG from './RNG' + const SCREEN_WIDTH = 64; const SCREEN_HEIGHT = 32; @@ -7,29 +9,33 @@ const STACK_SIZE = 16; const REGISTERS = 16; class CPU { - pc: number; - indexReg: number; + pc: number; // 16b + indexReg: number; // 16b registers: Uint8Array; - delayTimer: number; - soundTimer: number; + delayTimer: number; // 8b + soundTimer: number; // 8b - stackPointer: number; - stack: Array; + stackPointer: number; // 16b + stack: Array; memory: Uint8Array; displayMemory: Uint8Array; + rng: RNG; + constructor() { this.memory = new Uint8Array(MEMORY_SIZE); this.displayMemory = new Uint8Array(SCREEN_WIDTH*SCREEN_HEIGHT); - this.pc = 0; + this.pc = 0x200; this.indexReg = 0; this.stackPointer = 0; - this.stack = new Array(STACK_SIZE); + this.stack = new Array(STACK_SIZE); this.delayTimer = 0; this.soundTimer = 0; this.registers = new Uint8Array(REGISTERS); + + this.rng = new RNG(0); this.clearMemory(); this.clearDisplay(); @@ -43,11 +49,13 @@ class CPU { clearRegisters() { this.registers.fill(0); - this.pc = 0; + this.pc = 0x200; // Start of the program on normal programs this.indexReg = 0; this.stackPointer = 0; this.delayTimer = 0; this.soundTimer = 0; + + this.rng = new RNG(0); } clearMemory() { @@ -59,7 +67,7 @@ class CPU { } - setupFont() { + private setupFont() { // Using address from 050 - 09F ?? let addressFont = 0x050; @@ -86,9 +94,24 @@ class CPU { this.memory.set(characters, addressFont); } - + private incrementPC() { + this.pc += 2; + } + private cycle() { + // Fetch opcode + let firstOpcode: number = this.memory[this.pc]; + let secondtOpcode: number = this.memory[this.pc + 1]; + let opcode: number = firstOpcode << 8 | secondtOpcode; + + // Decode opcode + let firstNibble = opcode >> 12; + + switch(firstNibble) { + + } + } } diff --git a/src/index.ts b/src/index.ts index b182f6e..da3890b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,3 @@ import Chip8Emulator from './chip8Emulator' -console.log("initialize library??"); - export default { Chip8Emulator }; \ No newline at end of file