diff --git a/index.html b/index.html index 6a8e543..7b43ee2 100644 --- a/index.html +++ b/index.html @@ -27,7 +27,8 @@ \ No newline at end of file diff --git a/src/audio.ts b/src/audio.ts new file mode 100644 index 0000000..2cb68f4 --- /dev/null +++ b/src/audio.ts @@ -0,0 +1,41 @@ +class Chip8Audio { + audioBrowserContext: AudioContext | null; + oscillator: OscillatorNode | null; + gainNode: GainNode | null; + + volume: number; + + constructor() { + this.audioBrowserContext = null; + this.oscillator = null; + this.gainNode = null; + this.volume = 0.1; + } + + startAudio(audioContext: AudioContext, volume: number) { + this.volume = volume; + this.audioBrowserContext = audioContext; + this.gainNode = this.audioBrowserContext.createGain(); + this.gainNode.connect(this.audioBrowserContext.destination); + this.gainNode.gain.setValueAtTime(this.volume, this.audioBrowserContext.currentTime); + } + + startBeep() { + if(this.oscillator == null && this.audioBrowserContext && this.gainNode) { + this.oscillator = this.audioBrowserContext.createOscillator(); + this.oscillator.type = 'square'; + this.oscillator.frequency.setValueAtTime(440, this.audioBrowserContext.currentTime); // 440 Hz (A4 note) + this.oscillator.connect(this.gainNode); + this.oscillator.start(); + } + } + + stopBeep() { + if(this.oscillator) { + this.oscillator.stop(); + this.oscillator = null; + } + } +} + +export default Chip8Audio; diff --git a/src/chip8Emulator.ts b/src/chip8Emulator.ts index b77fba5..2ea1c96 100644 --- a/src/chip8Emulator.ts +++ b/src/chip8Emulator.ts @@ -1,18 +1,22 @@ import CPU from './cpu'; import Keyboard from './keyboard' import RNG from './RNG' +import Chip8Audio from './audio' class Chip8Emulator { cpu: CPU; keyboard: Keyboard; rom: Uint8Array; + audio: Chip8Audio; romLoaded: boolean; constructor() { this.keyboard = new Keyboard(); - this.cpu = new CPU(this.keyboard); + this.audio = new Chip8Audio(); + this.cpu = new CPU(this.keyboard, this.audio); + this.rom = new Uint8Array(); this.romLoaded = false; } @@ -57,6 +61,14 @@ class Chip8Emulator { } } + setUserKey(userKey: number, key: number) { + this.keyboard.setUserKey(userKey, key); + } + + startAudio(audioContext: AudioContext, volume: number) { + this.audio.startAudio(audioContext, volume); + } + keyDownEvent(key: number) { this.keyboard.userKeyPressedDown(key); } @@ -64,9 +76,6 @@ class Chip8Emulator { 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 3b85f97..53d827c 100644 --- a/src/cpu.ts +++ b/src/cpu.ts @@ -1,4 +1,5 @@ import RNG from './RNG' +import Chip8Audio from './audio'; import Keyboard from './keyboard'; const SCREEN_WIDTH = 64; @@ -24,11 +25,13 @@ class CPU { displayMemory: Uint8Array; keyboard: Keyboard; + audio: Chip8Audio; + rng: RNG; - constructor(keyboard: Keyboard) { + constructor(keyboard: Keyboard, audio: Chip8Audio) { this.memory = new Uint8Array(MEMORY_SIZE); this.displayMemory = new Uint8Array(SCREEN_WIDTH*SCREEN_HEIGHT); this.pc = 0x200; @@ -39,6 +42,7 @@ class CPU { this.soundTimer = 0; this.regs = new Uint8Array(REGISTERS); this.keyboard = keyboard; + this.audio = audio; this.rng = new RNG(0); @@ -249,8 +253,14 @@ class CPU { }else if(nib4 == 0x5) { // 8XY5 // Vx -= Vy - let subs = this.regs[nib2] - this.regs[nib3]; - this.regs[0xF] = this.regs[nib2] > this.regs[nib3] ? 1 : 0; + let subs = 0; + if(this.regs[nib2] >= this.regs[nib3]) { + subs = this.regs[nib2] - this.regs[nib3]; + }else{ + subs = this.regs[nib2] - this.regs[nib3]; + //subs = 0xFF - subs; + } + this.regs[0xF] = this.regs[nib2] >= this.regs[nib3] ? 1 : 0; this.regs[nib2] = subs & 0xFF; this.incrementPC(); }else if(nib4 == 0x6) { @@ -258,8 +268,8 @@ class CPU { // Vx >>= 1 // Stores the least significant bit of VX prior to the shift in VF // Then. Shift Vx by 1 to the right. - this.regs[0xF] = this.regs[nib2] & 1; // Get the least significat bit - this.regs[nib2] = this.regs[nib2] >> 1; + this.regs[0xF] = this.regs[nib2] & 0x1; // Get the least significat bit + this.regs[nib2] = (this.regs[nib2] >> 1) & 0xFF; this.incrementPC(); }else if(nib4 == 0x7) { // 8XY7 @@ -273,8 +283,8 @@ class CPU { // Vx <<= 1 // Set VF to 1 if the most significant bit of VX. // Then shift to the left Vx - this.regs[0xF] = this.regs[nib2] >> 7; - this.regs[nib2] = (this.regs[nib2] << 1) & 0xFF; + this.regs[0xF] = (this.regs[nib2]) >> 7; + this.regs[nib2] = (this.regs[nib2] << 1); this.incrementPC(); } @@ -439,8 +449,16 @@ class CPU { break; } - if(this.delayTimer > 0)this.delayTimer--; - if(this.soundTimer > 0)this.soundTimer--; // Should I play a sound??? + // Timers + if(this.delayTimer > 0) { + this.delayTimer--; + } + if(this.soundTimer > 0) { + this.audio.startBeep(); + this.soundTimer--; + }else{ + this.audio.stopBeep(); + } }