Anthoer
This commit is contained in:
parent
7c2676433d
commit
7a9bfc4c79
54
index.html
54
index.html
@ -8,32 +8,48 @@
|
|||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
color: #EEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
#emulator-screen{
|
||||||
|
border: 1px solid pink;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<script src="./dist/revuelto8ts.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="emulator-container"></div>
|
|
||||||
<script src="./dist/revuelto8ts.js"></script>
|
|
||||||
<script>
|
|
||||||
// Assuming your library exposes an Emulator class
|
|
||||||
console.log(Revuelto8ts);
|
|
||||||
console.log(Revuelto8ts.Chip8Emulator);
|
|
||||||
const emulator = new Revuelto8ts.Chip8Emulator();
|
|
||||||
|
|
||||||
// Load ROM (you'll need to implement this method in your emulator)
|
<h1>Chip 8 emulator</h1>
|
||||||
|
<!-- Original screen is 64x32 -->
|
||||||
fetch('./roms/Maze[David Winter, 199x].ch8')
|
<canvas id="emulator-screen" width="256" height="128"></canvas>
|
||||||
.then(response => response.arrayBuffer())
|
|
||||||
.then(buffer => {
|
<script>
|
||||||
//emulator.loadROM(new Uint8Array(buffer));
|
// Assuming your library exposes an Emulator class
|
||||||
// Load and start
|
console.log(Revuelto8ts);
|
||||||
const uint8Array = new Uint8Array(buffer);
|
console.log(Revuelto8ts.Chip8Emulator);
|
||||||
const string = String.fromCharCode.apply(null, uint8Array);
|
const emulator = new Revuelto8ts.Chip8Emulator();
|
||||||
console.log(string);
|
|
||||||
console.log(string.length);
|
// Load ROM (you'll need to implement this method in your emulator)
|
||||||
|
|
||||||
|
fetch('./roms/1-chip8-logo.ch8')
|
||||||
|
.then(response => response.arrayBuffer())
|
||||||
|
.then(buffer => {
|
||||||
|
//emulator.loadROM(new Uint8Array(buffer));
|
||||||
|
// Load and start
|
||||||
|
emulator.loadRom(buffer);
|
||||||
});
|
});
|
||||||
|
|
||||||
</script>
|
const emulatorCanvas = document.getElementById('emulator-screen');
|
||||||
|
|
||||||
|
// Loop
|
||||||
|
while(true) {
|
||||||
|
emulator.emulateCycle();
|
||||||
|
|
||||||
|
emulator.drawGraphics();
|
||||||
|
emulator.drawToCanvas(emulatorCanvas, 4);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
23
src/RNG.ts
Normal file
23
src/RNG.ts
Normal file
@ -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;
|
@ -1,17 +1,23 @@
|
|||||||
import CPU from './cpu';
|
import CPU from './cpu';
|
||||||
import Keyboard from './keyboard'
|
import Keyboard from './keyboard'
|
||||||
|
import RNG from './RNG'
|
||||||
|
|
||||||
class Chip8Emulator {
|
class Chip8Emulator {
|
||||||
|
|
||||||
cpu: CPU;
|
cpu: CPU;
|
||||||
keyboard: Keyboard;
|
keyboard: Keyboard;
|
||||||
|
|
||||||
|
rom: Uint8Array;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
this.cpu = new CPU();
|
this.cpu = new CPU();
|
||||||
this.keyboard = new Keyboard();
|
this.keyboard = new Keyboard();
|
||||||
|
this.rom = new Uint8Array();
|
||||||
}
|
}
|
||||||
|
|
||||||
loadRom(rom: Uint8Array) {
|
loadRom(rom: Uint8Array) {
|
||||||
|
this.rom = rom;
|
||||||
}
|
}
|
||||||
|
|
||||||
emulateCycle() {
|
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;
|
export default Chip8Emulator;
|
45
src/cpu.ts
45
src/cpu.ts
@ -1,3 +1,5 @@
|
|||||||
|
import RNG from './RNG'
|
||||||
|
|
||||||
const SCREEN_WIDTH = 64;
|
const SCREEN_WIDTH = 64;
|
||||||
const SCREEN_HEIGHT = 32;
|
const SCREEN_HEIGHT = 32;
|
||||||
|
|
||||||
@ -7,29 +9,33 @@ const STACK_SIZE = 16;
|
|||||||
const REGISTERS = 16;
|
const REGISTERS = 16;
|
||||||
|
|
||||||
class CPU {
|
class CPU {
|
||||||
pc: number;
|
pc: number; // 16b
|
||||||
indexReg: number;
|
indexReg: number; // 16b
|
||||||
registers: Uint8Array;
|
registers: Uint8Array;
|
||||||
|
|
||||||
delayTimer: number;
|
delayTimer: number; // 8b
|
||||||
soundTimer: number;
|
soundTimer: number; // 8b
|
||||||
|
|
||||||
stackPointer: number;
|
stackPointer: number; // 16b
|
||||||
stack: Array<Function>;
|
stack: Array<number>;
|
||||||
|
|
||||||
memory: Uint8Array;
|
memory: Uint8Array;
|
||||||
displayMemory: Uint8Array;
|
displayMemory: Uint8Array;
|
||||||
|
|
||||||
|
rng: RNG;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.memory = new Uint8Array(MEMORY_SIZE);
|
this.memory = new Uint8Array(MEMORY_SIZE);
|
||||||
this.displayMemory = new Uint8Array(SCREEN_WIDTH*SCREEN_HEIGHT);
|
this.displayMemory = new Uint8Array(SCREEN_WIDTH*SCREEN_HEIGHT);
|
||||||
this.pc = 0;
|
this.pc = 0x200;
|
||||||
this.indexReg = 0;
|
this.indexReg = 0;
|
||||||
this.stackPointer = 0;
|
this.stackPointer = 0;
|
||||||
this.stack = new Array<Function>(STACK_SIZE);
|
this.stack = new Array<number>(STACK_SIZE);
|
||||||
this.delayTimer = 0;
|
this.delayTimer = 0;
|
||||||
this.soundTimer = 0;
|
this.soundTimer = 0;
|
||||||
this.registers = new Uint8Array(REGISTERS);
|
this.registers = new Uint8Array(REGISTERS);
|
||||||
|
|
||||||
|
this.rng = new RNG(0);
|
||||||
|
|
||||||
this.clearMemory();
|
this.clearMemory();
|
||||||
this.clearDisplay();
|
this.clearDisplay();
|
||||||
@ -43,11 +49,13 @@ class CPU {
|
|||||||
|
|
||||||
clearRegisters() {
|
clearRegisters() {
|
||||||
this.registers.fill(0);
|
this.registers.fill(0);
|
||||||
this.pc = 0;
|
this.pc = 0x200; // Start of the program on normal programs
|
||||||
this.indexReg = 0;
|
this.indexReg = 0;
|
||||||
this.stackPointer = 0;
|
this.stackPointer = 0;
|
||||||
this.delayTimer = 0;
|
this.delayTimer = 0;
|
||||||
this.soundTimer = 0;
|
this.soundTimer = 0;
|
||||||
|
|
||||||
|
this.rng = new RNG(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearMemory() {
|
clearMemory() {
|
||||||
@ -59,7 +67,7 @@ class CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
setupFont() {
|
private setupFont() {
|
||||||
// Using address from 050 - 09F ??
|
// Using address from 050 - 09F ??
|
||||||
let addressFont = 0x050;
|
let addressFont = 0x050;
|
||||||
|
|
||||||
@ -86,9 +94,24 @@ class CPU {
|
|||||||
this.memory.set(characters, addressFont);
|
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) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import Chip8Emulator from './chip8Emulator'
|
import Chip8Emulator from './chip8Emulator'
|
||||||
|
|
||||||
console.log("initialize library??");
|
|
||||||
|
|
||||||
export default { Chip8Emulator };
|
export default { Chip8Emulator };
|
Loading…
Reference in New Issue
Block a user