Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

chip8js

Package Overview
Dependencies
Maintainers
1
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

chip8js - npm Package Compare versions

Comparing version 0.1.5 to 0.1.6

classes/interfaces/CpuInterface.js

70

classes/CPU.js

@@ -5,2 +5,5 @@ const { Disassembler } = require('./Disassembler')

class CPU {
constructor(cpuInterface) {
this.interface = cpuInterface
}
/**

@@ -32,4 +35,2 @@ * Set or reset the state to initial values.

this.reset()
const romData = romBuffer.data
let memoryStart = 0x200

@@ -41,2 +42,5 @@ // 0-80 in memory is reserved for font set

const romData = romBuffer.data
let memoryStart = 0x200
// Place ROM data in memory starting at 0x200

@@ -49,9 +53,22 @@ for (let i = 0; i < romData.length; i++) {

run() {
while (true) {
this.step()
tick() {
if (this.DT > 0) {
this.DT--
} else {
console.log('fixme')
}
if (this.ST > 0) {
this.ST--
} else {
console.log('fixme')
}
}
step() {
if (this.halted) {
throw new Error(
'A problem has been detected and Chip-8 has been shut down to prevent damage to your computer.'
)
}
const opcode = this._fetch()

@@ -80,2 +97,7 @@ const instruction = this._decode(opcode)

_fetch() {
if (this.PC > 4094) {
this.halted = true
throw new Error('Memory out of bounds.')
}
return (this.memory[this.PC] << 8) | (this.memory[this.PC + 1] << 0)

@@ -100,2 +122,7 @@ }

// Return from a subroutine.
if (this.SP === -1) {
this.halted = true
throw new Error('Stack underflow.')
}
this.PC = this.stack[this.SP]

@@ -110,2 +137,7 @@ this.SP--

// Call subroutine at nnn.
if (this.SP === 15) {
this.halted = true
throw new Error('Stack overflow.')
}
this.SP++

@@ -229,2 +261,7 @@ this.stack[this.SP] = this.PC + 2

// The interpreter reads n bytes from memory, starting at the address stored in I.
if (this.I > 4095 - args[2]) {
this.halted = true
throw new Error('Memory out of bounds.')
}
let sprite = ''

@@ -295,2 +332,7 @@

// Set I = location of sprite for digit Vx.
if (this.registers[args[1]] > 0xf) {
this.halted = true
throw new Error('Invalid digit.')
}
this.I = this.registers[args[1]] * 5

@@ -301,2 +343,7 @@ this._nextInstruction()

// Store BCD representation of Vx in memory locations I, I+1, and I+2.
if (this.I > 4093) {
this.halted = true
throw new Error('Memory out of bounds.')
}
let x = this.registers[args[1]]

@@ -317,2 +364,7 @@ const a = Math.floor(x / 100)

// Store registers V0 through Vx in memory starting at location I.
if (this.I > 4095 - args[1]) {
this.halted = true
throw new Error('Memory out of bounds.')
}
for (let i = 0; i <= args[1]; i++) {

@@ -325,2 +377,7 @@ this.memory[this.I + i] = this.registers[i]

// Read registers V0 through Vx from memory starting at location I.
if (this.I > 4095 - args[0]) {
this.halted = true
throw new Error('Memory out of bounds.')
}
for (let i = 0; i <= args[1]; i++) {

@@ -333,3 +390,4 @@ this.registers[i] = this.memory[this.I + i]

// Data word
console.log(args[0])
this.halted = true
throw new Error('Illegal instruction.')
}

@@ -336,0 +394,0 @@ }

6

package.json
{
"name": "chip8js",
"version": "0.1.5",
"version": "0.1.6",
"description": "A Chip-8 emulator written in JavaScript (Node.js).",

@@ -16,3 +16,3 @@ "author": {

"hexdump": "node scripts/hexdump",
"example": "node index.js roms/CONNECT4",
"example": "node scripts/run roms/CONNECT4",
"test": "jest"

@@ -31,3 +31,3 @@ },

"license": "MIT",
"public": true
"private": false
}

@@ -99,2 +99,8 @@ # Chip8.js [![Build Status](https://travis-ci.org/taniarascia/chip8.svg?branch=master)](https://travis-ci.org/taniarascia/chip8) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

### Run example ROM
```
yarn example
```
## Reference

@@ -214,5 +220,14 @@

- [ ] Check for halts, throw errors and reset
- [ ] Begin I/O
- [x] Tests: Errors: 8
- [x] RET
- [x] CALL_ADDR
- [x] DRW_VX_VY_N
- [x] LD_F_VX
- [x] LD_B_VX
- [x] LD_I_VX
- [x] LD_VX_I
- [x] DW
- [ ] Create Interface Classes
## Acknowledgements

@@ -226,3 +241,3 @@

I'm [Tania Rascia](https://www.taniarascia.com). I write articles and tutorials about programming.
- [Tania Rascia](https://www.taniarascia.com)

@@ -229,0 +244,0 @@ ## License

const filename = process.argv.slice(2)[0]
const { RomBuffer } = require('../classes/RomBuffer')
const romBuffer = new RomBuffer(filename)
const romBuffer = new RomBuffer(filename)
console.log(romBuffer.dump())
describe('CPU tests', () => {
const { CPU } = require('../classes/CPU')
const cpu = new CPU()
const cpu = new CPU(null)
test.skip('test cpu 02: CLS', () => {})
test('CPU does not execute after halting', () => {
cpu.load({ data: 0x0000 })
cpu.halted = true
expect(() => {
cpu.step()
}).toThrowError(
'A problem has been detected and Chip-8 has been shut down to prevent damage to your computer.'
)
})
// test.skip('test cpu 02: CLS', () => {})
test('test cpu 03: RET', () => {
cpu.load({ data: [0x00ee] })
cpu.load({ data: [ 0x00ee ] })
cpu.SP = 2

@@ -15,6 +26,12 @@ cpu.stack[2] = 0xf

expect(cpu.SP).toBe(0x1)
cpu.load({ data: [ 0x00ee ] })
expect(() => {
cpu.step()
}).toThrowError('Stack underflow.')
})
test('test cpu 04: 1nnn - JP addr', () => {
cpu.load({ data: [0x1333] })
cpu.load({ data: [ 0x1333 ] })
cpu.step()

@@ -26,3 +43,3 @@

test('test cpu 05: 2nnn - CALL addr', () => {
cpu.load({ data: [0x2062] })
cpu.load({ data: [ 0x2062 ] })
const PC = cpu.PC

@@ -34,6 +51,13 @@ cpu.step()

expect(cpu.PC).toBe(0x062)
cpu.load({ data: [ 0x2062 ] })
cpu.SP = 15
expect(() => {
cpu.step()
}).toThrowError('Stack overflow.')
})
test('test cpu 06: 3xkk - SE Vx, byte', () => {
cpu.load({ data: [0x3abb] })
cpu.load({ data: [ 0x3abb ] })
cpu.step()

@@ -43,3 +67,3 @@

cpu.load({ data: [0x3abb] })
cpu.load({ data: [ 0x3abb ] })
cpu.registers[0xa] = 0xbb

@@ -52,3 +76,3 @@ cpu.step()

test('test cpu 07: 4xkk - SNE Vx, byte', () => {
cpu.load({ data: [0x4acc] })
cpu.load({ data: [ 0x4acc ] })
cpu.step()

@@ -58,3 +82,3 @@

cpu.load({ data: [0x4acc] })
cpu.load({ data: [ 0x4acc ] })
cpu.registers[0xa] = 0xcc

@@ -67,3 +91,3 @@ cpu.step()

test('test cpu 08: 5xy0 - SE Vx, Vy', () => {
cpu.load({ data: [0x5ab0] })
cpu.load({ data: [ 0x5ab0 ] })
cpu.step()

@@ -73,3 +97,3 @@

cpu.load({ data: [0x5ab0] })
cpu.load({ data: [ 0x5ab0 ] })
cpu.registers[0xa] = 0x5

@@ -82,3 +106,3 @@ cpu.step()

test('test cpu 09: 6xkk - LD Vx, byte', () => {
cpu.load({ data: [0x6abb] })
cpu.load({ data: [ 0x6abb ] })
cpu.registers[0xa] = 0x10

@@ -91,3 +115,3 @@ cpu.step()

test('test cpu 10: 7xkk - ADD Vx, byte', () => {
cpu.load({ data: [0x7abb] })
cpu.load({ data: [ 0x7abb ] })
cpu.registers[0xa] = 0x10

@@ -100,3 +124,3 @@ cpu.step()

test('test cpu 11: 8xy0 - LD Vx, Vy', () => {
cpu.load({ data: [0x8ab0] })
cpu.load({ data: [ 0x8ab0 ] })
cpu.registers[0xb] = 0x8

@@ -109,3 +133,3 @@ cpu.step()

test('test cpu 12: 8xy1 - OR Vx, Vy', () => {
cpu.load({ data: [0x8ab1] })
cpu.load({ data: [ 0x8ab1 ] })
cpu.registers[0xa] = 0x3

@@ -119,3 +143,3 @@ cpu.registers[0xb] = 0x4

test('test cpu 13: 8xy2 - AND Vx, Vy', () => {
cpu.load({ data: [0x8ab2] })
cpu.load({ data: [ 0x8ab2 ] })
cpu.registers[0xa] = 0x3

@@ -129,3 +153,3 @@ cpu.registers[0xb] = 0x4

test('test cpu 14: 8xy3 - XOR Vx, Vy', () => {
cpu.load({ data: [0x8ab3] })
cpu.load({ data: [ 0x8ab3 ] })
cpu.registers[0xa] = 0x3

@@ -139,3 +163,3 @@ cpu.registers[0xb] = 0x3

test('test cpu 15: 8xy4 - ADD Vx, Vy', () => {
cpu.load({ data: [0x8ab4] })
cpu.load({ data: [ 0x8ab4 ] })
cpu.registers[0xa] = 0x3

@@ -148,3 +172,3 @@ cpu.registers[0xb] = 0x4

cpu.load({ data: [0x8ab4] })
cpu.load({ data: [ 0x8ab4 ] })
cpu.registers[0xa] = 0xff

@@ -159,3 +183,3 @@ cpu.registers[0xb] = 0xff

test('test cpu 16: 8xy5 - SUB Vx, Vy', () => {
cpu.load({ data: [0x8ab5] })
cpu.load({ data: [ 0x8ab5 ] })
cpu.registers[0xa] = 0x4

@@ -168,3 +192,3 @@ cpu.registers[0xb] = 0x2

cpu.load({ data: [0x8ab5] })
cpu.load({ data: [ 0x8ab5 ] })
cpu.registers[0xa] = 0x2

@@ -179,3 +203,3 @@ cpu.registers[0xb] = 0x3

test('test cpu 17: 8xy6 - SHR Vx {, Vy}', () => {
cpu.load({ data: [0x8ab6] })
cpu.load({ data: [ 0x8ab6 ] })
cpu.registers[0xa] = 0x3

@@ -189,3 +213,3 @@ cpu.step()

test('test cpu 18: 8xy7 - SUBN Vx, Vy', () => {
cpu.load({ data: [0x8ab7] })
cpu.load({ data: [ 0x8ab7 ] })
cpu.registers[0xa] = 0x3

@@ -198,3 +222,3 @@ cpu.registers[0xb] = 0x2

cpu.load({ data: [0x8ab7] })
cpu.load({ data: [ 0x8ab7 ] })
cpu.registers[0xa] = 0x2

@@ -209,3 +233,3 @@ cpu.registers[0xb] = 0x3

test('test cpu 19: 8xyE - SHL Vx, {, Vy}', () => {
cpu.load({ data: [0x8abe] })
cpu.load({ data: [ 0x8abe ] })
cpu.registers[0xa] = 0x3

@@ -219,3 +243,3 @@ cpu.step()

test('test cpu 20: 9xy0 - SNE Vx, Vy', () => {
cpu.load({ data: [0x9ab0] })
cpu.load({ data: [ 0x9ab0 ] })
cpu.registers[0xa] = 0x3

@@ -227,3 +251,3 @@ cpu.registers[0xb] = 0x4

cpu.load({ data: [0x9ab0] })
cpu.load({ data: [ 0x9ab0 ] })
cpu.registers[0xa] = 0x3

@@ -237,3 +261,3 @@ cpu.registers[0xb] = 0x3

test('test cpu 21: Annn - LD I, addr', () => {
cpu.load({ data: [0xa999] })
cpu.load({ data: [ 0xa999 ] })
cpu.step()

@@ -245,3 +269,3 @@

test('test cpu 22: Bnnn - JP V0, addr', () => {
cpu.load({ data: [0xb300] })
cpu.load({ data: [ 0xb300 ] })
cpu.registers[0] = 0x2

@@ -253,29 +277,46 @@ cpu.step()

test.skip('test cpu 23: Cxkk - RND Vx, byte', () => {
// untestable
// test.skip('test cpu 23: Cxkk - RND Vx, byte', () => {})
test('test cpu 24: Dxyn - DRW Vx, Vy, nibble', () => {
cpu.load({ data: [ 0xdab5 ] })
cpu.I = 4091
expect(() => {
cpu.step()
}).toThrowError('Memory out of bounds.')
// todo: passing test
})
test.skip('test cpu 24: Dxyn - DRW Vx, Vy, nibble', () => {
cpu.load({ data: [0xdab5] })
test('test cpu 25: Ex9E - SKP Vx', () => {
// todo
cpu.load({ data: [ 0xea9e ] })
cpu.registers[0xa] = 0
cpu.step()
// cpu.registers[0xa] = 0
// cpu.registers[0xb] = 0
// cpu.I = 0x300
// cpu.memory[0x300] = 0b11110000
// cpu.memory[0x301] = 0b11100000
// cpu.step()
// expect(cpu.memory[0x300]).toBe(0)
// I'll get back to this one
expect(cpu.PC).toBe(0x204)
cpu.load({ data: [ 0xea9e ] })
cpu.registers[0xa] = 1
cpu.step()
expect(cpu.PC).toBe(0x202)
})
test.skip('test cpu 25: Ex9E - SKP Vx', () => {
test('test cpu 26: ExA1 - SKNP Vx', () => {
// todo
})
cpu.load({ data: [ 0xeba1 ] })
cpu.registers[0xb] = 0
cpu.step()
test.skip('test cpu 26: ExA1 - SKNP Vx', () => {
// todo
expect(cpu.PC).toBe(0x202)
cpu.load({ data: [ 0xea9e ] })
cpu.registers[0xb] = 1
cpu.step()
expect(cpu.PC).toBe(0x204)
})
test('test cpu 27: Fx07 - LD Vx, DT', () => {
cpu.load({ data: [0xfa07] })
cpu.load({ data: [ 0xfa07 ] })
cpu.DT = 0xf

@@ -287,8 +328,12 @@ cpu.step()

test.skip('test cpu 28: Fx0A - LD Vx, K', () => {
test('test cpu 28: Fx0A - LD Vx, K', () => {
// todo
cpu.load({ data: [ 0xfb0a ] })
cpu.step()
expect(cpu.registers[0xb]).toBe(0)
})
test('test cpu 29: Fx15 - LD DT, Vx', () => {
cpu.load({ data: [0xfb15] })
cpu.load({ data: [ 0xfb15 ] })
cpu.registers[0xb] = 0xf

@@ -301,3 +346,3 @@ cpu.step()

test('test cpu 30: Fx18 - LD ST, Vx', () => {
cpu.load({ data: [0xfa18] })
cpu.load({ data: [ 0xfa18 ] })
cpu.registers[0xa] = 0xf

@@ -310,3 +355,3 @@ cpu.step()

test('test cpu 31: Fx1E - ADD I, Vx', () => {
cpu.load({ data: [0xfa1e] })
cpu.load({ data: [ 0xfa1e ] })
cpu.I = 0xe

@@ -319,12 +364,25 @@ cpu.registers[0xa] = 0xf

test.skip('test cpu 32: Fx29 - LD F, Vx', () => {
cpu.load({ data: [0xfa29] })
test('test cpu 32: Fx29 - LD F, Vx', () => {
cpu.load({ data: [ 0xfa29 ] })
cpu.registers[0xa] = 16
expect(() => {
cpu.step()
}).toThrowError('Invalid digit.')
cpu.load({ data: [ 0xfa29 ] })
cpu.registers[0xa] = 0xa
cpu.step()
expect(cpu.I).toBe(0xa * 5)
expect(this.memory[0xa * 50]).toBe(0xf0)
// todo print a to console for now
cpu.load({ data: [ 0xfa29, 0xdab5 ] })
cpu.registers[0xa] = 0xa
cpu.step()
cpu.step()
})
test('test cpu 33: Fx33 - LD B, Vx', () => {
cpu.load({ data: [0xfa33] })
cpu.load({ data: [ 0xfa33 ] })
cpu.registers[0xa] = 0x7b

@@ -337,6 +395,14 @@ cpu.I = 0x300

expect(cpu.memory[0x302]).toBe(3)
cpu.load({ data: [ 0xfa33 ] })
cpu.registers[0xa] = 0x7b
cpu.I = 4094
expect(() => {
cpu.step()
}).toThrowError('Memory out of bounds.')
})
test('test cpu 34: Fx55 - LD [I], Vx', () => {
cpu.load({ data: [0xfb55] })
cpu.load({ data: [ 0xfb55 ] })
cpu.I = 0x400

@@ -353,6 +419,13 @@

expect(cpu.memory[cpu.I + 0xc]).toBe(0)
cpu.load({ data: [ 0xfb55 ] })
cpu.I = 4085
expect(() => {
cpu.step()
}).toThrowError('Memory out of bounds.')
})
test('test cpu 35: Fx65 - LD Vx, [I]', () => {
cpu.load({ data: [0xfa65] })
cpu.load({ data: [ 0xfa65 ] })
cpu.I = 0x400

@@ -369,8 +442,18 @@

expect(cpu.registers[0xb]).toBe(0)
cpu.load({ data: [ 0xfa65 ] })
cpu.I = 4086
expect(() => {
cpu.step()
}).toThrowError('Memory out of bounds.')
})
test.skip('test data word', () => {
cpu.load({ data: [0x5154] })
// todo
test('test data word', () => {
cpu.load({ data: [ 0x5154 ] })
expect(() => {
cpu.step()
}).toThrowError('Illegal instruction.')
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc