Get nibbles before-hand for clarity
This commit is contained in:
parent
174259f1ea
commit
821c327ed3
106
src/cpu.ts
106
src/cpu.ts
@ -11,7 +11,7 @@ const REGISTERS = 16;
|
|||||||
class CPU {
|
class CPU {
|
||||||
pc: number; // 16b
|
pc: number; // 16b
|
||||||
indexReg: number; // 16b
|
indexReg: number; // 16b
|
||||||
registers: Uint8Array;
|
regs: Uint8Array;
|
||||||
|
|
||||||
delayTimer: number; // 8b
|
delayTimer: number; // 8b
|
||||||
soundTimer: number; // 8b
|
soundTimer: number; // 8b
|
||||||
@ -33,7 +33,7 @@ class CPU {
|
|||||||
this.stack = new Array<number>(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.regs = new Uint8Array(REGISTERS);
|
||||||
|
|
||||||
this.rng = new RNG(0);
|
this.rng = new RNG(0);
|
||||||
|
|
||||||
@ -48,7 +48,7 @@ class CPU {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearRegisters() {
|
clearRegisters() {
|
||||||
this.registers.fill(0);
|
this.regs.fill(0);
|
||||||
this.pc = 0x200; // Start of the program on normal programs
|
this.pc = 0x200; // Start of the program on normal programs
|
||||||
this.indexReg = 0;
|
this.indexReg = 0;
|
||||||
this.stackPointer = 0;
|
this.stackPointer = 0;
|
||||||
@ -105,10 +105,12 @@ class CPU {
|
|||||||
let opcode: number = firstOpcode << 8 | secondOpcode;
|
let opcode: number = firstOpcode << 8 | secondOpcode;
|
||||||
|
|
||||||
// Decode opcode
|
// Decode opcode
|
||||||
// X000
|
let nib1 = firstOpcode >> 4; // X000
|
||||||
let firstNibble = firstOpcode >> 4;
|
let nib2 = firstOpcode & 0xF; // 0X00
|
||||||
|
let nib3 = secondOpcode >> 4; // 00X0
|
||||||
|
let nib4 = secondOpcode & 0xF; // 000X
|
||||||
|
|
||||||
switch(firstNibble) {
|
switch(nib1) {
|
||||||
case 0x0:
|
case 0x0:
|
||||||
if(opcode == 0x00E0) {
|
if(opcode == 0x00E0) {
|
||||||
// Clear the screen
|
// Clear the screen
|
||||||
@ -134,9 +136,8 @@ class CPU {
|
|||||||
case 0x3: {
|
case 0x3: {
|
||||||
// 3XNN
|
// 3XNN
|
||||||
// Skips the next instruction if VX equals NN
|
// Skips the next instruction if VX equals NN
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
|
||||||
let val = opcode & 0x00FF; //0x00NN
|
let val = opcode & 0x00FF; //0x00NN
|
||||||
if(this.registers[secondNibble] == val){
|
if(this.regs[nib2] == val){
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
@ -145,9 +146,8 @@ class CPU {
|
|||||||
case 0x4: {
|
case 0x4: {
|
||||||
// 4XNN
|
// 4XNN
|
||||||
// Skips the next instruction if VX NOT equals NN
|
// Skips the next instruction if VX NOT equals NN
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
|
||||||
let val = opcode & 0x00FF; //0x00NN
|
let val = opcode & 0x00FF; //0x00NN
|
||||||
if(this.registers[secondNibble] != val){
|
if(this.regs[nib2] != val){
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
@ -156,9 +156,7 @@ class CPU {
|
|||||||
case 0x5: {
|
case 0x5: {
|
||||||
// 5XY0
|
// 5XY0
|
||||||
// Skips the next instruction if VX == VY
|
// Skips the next instruction if VX == VY
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
if(this.regs[nib2] == this.regs[nib3]) {
|
||||||
let thirdNibble = secondOpcode >> 4; //00Y0
|
|
||||||
if(this.registers[secondNibble] == this.registers[thirdNibble]) {
|
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
@ -167,76 +165,71 @@ class CPU {
|
|||||||
case 0x6: {
|
case 0x6: {
|
||||||
// 6XNN
|
// 6XNN
|
||||||
// Sets VX to NN
|
// Sets VX to NN
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
this.regs[nib2] = secondOpcode;
|
||||||
this.registers[secondNibble] = secondOpcode;
|
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x7: {
|
case 0x7: {
|
||||||
// 7XNN
|
// 7XNN
|
||||||
// Adds NN to VX
|
// Adds NN to VX
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
this.regs[nib2] = secondOpcode;
|
||||||
this.registers[secondNibble] = secondOpcode;
|
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x8: {
|
case 0x8: {
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
if(nib4 == 0x0) {
|
||||||
let thirdNibble = secondOpcode >> 4; //00Y0
|
|
||||||
let lastNibble = secondOpcode & 0xF; //000N
|
|
||||||
if(lastNibble == 0x0) {
|
|
||||||
// 8XY0
|
// 8XY0
|
||||||
// Vx |= Vy
|
// Vx |= Vy
|
||||||
this.registers[secondNibble] = this.registers[thirdNibble];
|
this.regs[nib2] = this.regs[nib3];
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0x1) {
|
}else if(nib4 == 0x1) {
|
||||||
// 8XY1
|
// 8XY1
|
||||||
// Vx |= Vy
|
// Vx |= Vy
|
||||||
this.registers[secondNibble] |= this.registers[thirdNibble];
|
this.regs[nib2] |= this.regs[nib3];
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0x2) {
|
}else if(nib4 == 0x2) {
|
||||||
// 8XY2
|
// 8XY2
|
||||||
// Vx &= Vy
|
// Vx &= Vy
|
||||||
this.registers[secondNibble] &= this.registers[thirdNibble];
|
this.regs[nib2] &= this.regs[nib3];
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0x3) {
|
}else if(nib4 == 0x3) {
|
||||||
// 8XY3
|
// 8XY3
|
||||||
// Vx ^= Vy
|
// Vx ^= Vy
|
||||||
this.registers[secondNibble] ^= this.registers[thirdNibble];
|
this.regs[nib2] ^= this.regs[nib3];
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0x4) {
|
}else if(nib4 == 0x4) {
|
||||||
// 8XY4
|
// 8XY4
|
||||||
// Vx += Vy
|
// Vx += Vy
|
||||||
let sum = this.registers[secondNibble] + this.registers[thirdNibble];
|
let sum = this.regs[nib2] + this.regs[nib3];
|
||||||
this.registers[0xF] = sum > 255 ? 1 : 0; // Set carry flag
|
this.regs[0xF] = sum > 255 ? 1 : 0; // Set carry flag
|
||||||
this.registers[secondNibble] = sum & 0xFF; // Get only the first byte
|
this.regs[nib2] = sum & 0xFF; // Get only the first byte
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0x5) {
|
}else if(nib4 == 0x5) {
|
||||||
// 8XY5
|
// 8XY5
|
||||||
// Vx -= Vy
|
// Vx -= Vy
|
||||||
this.registers[0xF] = this.registers[secondNibble] > this.registers[thirdNibble] ? 1 : 0;
|
this.regs[0xF] = this.regs[nib2] > this.regs[nib3] ? 1 : 0;
|
||||||
let subs = this.registers[secondNibble] - this.registers[thirdNibble];
|
let subs = this.regs[nib2] - this.regs[nib3];
|
||||||
this.registers[secondNibble] = subs;
|
this.regs[nib2] = subs;
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0x6) {
|
}else if(nib4 == 0x6) {
|
||||||
// 8XY6
|
// 8XY6
|
||||||
// Vx >>= 1
|
// Vx >>= 1
|
||||||
this.registers[0xF] = this.registers[0xF] & 1; // ???? // Store the least significant bit of VX prior
|
this.regs[0xF] = this.regs[0xF] & 1; // ???? // Store the least significant bit of VX prior
|
||||||
this.registers[secondNibble] >>= 1;
|
this.regs[nib2] >>= 1;
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0x7) {
|
}else if(nib4 == 0x7) {
|
||||||
// 8XY7
|
// 8XY7
|
||||||
// Vx = Vy - Vx
|
// Vx = Vy - Vx
|
||||||
this.registers[0xF] = this.registers[thirdNibble] > this.registers[secondNibble] ? 1 : 0;
|
this.regs[0xF] = this.regs[nib3] > this.regs[nib2] ? 1 : 0;
|
||||||
let subs = this.registers[thirdNibble] - this.registers[secondNibble];
|
let subs = this.regs[nib3] - this.regs[nib2];
|
||||||
this.registers[secondNibble] = subs;
|
this.regs[nib2] = subs;
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}else if(lastNibble == 0xE) {
|
}else if(nib4 == 0xE) {
|
||||||
// 8XYE
|
// 8XYE
|
||||||
// Vx <<= 1
|
// Vx <<= 1
|
||||||
// Set VF to 1 if the most significant bit of VX prior to that shift was set
|
// Set VF to 1 if the most significant bit of VX prior to that shift was set
|
||||||
this.registers[0xF] = this.registers[0xF] >> 3;
|
this.regs[0xF] = this.regs[0xF] >> 3;
|
||||||
this.registers[secondNibble] <<= 1;
|
this.regs[nib2] <<= 1;
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -245,9 +238,7 @@ class CPU {
|
|||||||
case 0x9: {
|
case 0x9: {
|
||||||
// 9XY0
|
// 9XY0
|
||||||
// Skips the next instruction if VX != VY
|
// Skips the next instruction if VX != VY
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
if(this.regs[nib2] != this.regs[nib3]) {
|
||||||
let thirdNibble = secondOpcode >> 4; //00Y0
|
|
||||||
if(this.registers[secondNibble] != this.registers[thirdNibble]) {
|
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
@ -264,31 +255,26 @@ class CPU {
|
|||||||
case 0xB:{
|
case 0xB:{
|
||||||
// BNNN
|
// BNNN
|
||||||
// Jumps to the address NNN plus V0
|
// Jumps to the address NNN plus V0
|
||||||
this.pc = this.registers[0] + opcode & 0x0FFF;
|
this.pc = this.regs[0] + opcode & 0x0FFF;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xC: {
|
case 0xC: {
|
||||||
// CXNN
|
// CXNN
|
||||||
// Vx = rand() & NN
|
// Vx = rand() & NN
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
this.regs[nib2] = this.rng.next255() & secondOpcode;
|
||||||
this.registers[secondNibble] = this.rng.next255() & secondOpcode;
|
|
||||||
this.incrementPC();
|
this.incrementPC();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xD: {
|
case 0xD: {
|
||||||
// DXYN
|
// DXYN
|
||||||
// draw(Vx, Vy, N)
|
// draw(Vx, Vy, N)
|
||||||
let secondNibble = firstOpcode & 0xF; //0X00
|
this.regs[0xF] = 0;
|
||||||
let thirdNibble = secondOpcode >> 4; //00Y0
|
|
||||||
let fourthNibble = secondOpcode & 0xF;
|
|
||||||
|
|
||||||
this.registers[0xF] = 0;
|
|
||||||
|
|
||||||
let regX = this.registers[secondNibble];
|
let regX = this.regs[nib2];
|
||||||
let regY = this.registers[thirdNibble];
|
let regY = this.regs[nib3];
|
||||||
|
|
||||||
let y = 0;
|
let y = 0;
|
||||||
while(y < fourthNibble) {
|
while(y < nib4) {
|
||||||
// A sprite is always 8 bits horizontal
|
// A sprite is always 8 bits horizontal
|
||||||
let pixel = this.memory[this.indexReg + y];
|
let pixel = this.memory[this.indexReg + y];
|
||||||
let x = 0;
|
let x = 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user