Snapshot của taniarascia/chip8: 474★ · JavaScript · Frontend. 🎮 A Chip-8 emulator written in JavaScript for web, CLI, and native UI.
Tóm tắt dựng từ metadata GitHub của chính dự án — chưa có bài review TopGit. Trang sẽ tự động cập nhật khi bài review đầy đủ được xuất bản.
VÌ SAO CHƯA CÓ REVIEW
TopGit viết bài đầy đủ cho repo có nhiều sao nhất và được yêu cầu nhiều nhất. Trang này là snapshot trong thời gian chờ — xem README gốc ở tab READ ME.
Chip8.js can be run on the web, in a terminal, or using native keybindings.
Web
Chip8.js emulator for the web
Development
Spin up a local server during development.
# watch for changes and rebuild
npm run watch:web
# spin up server on localhost:8080
cd web && http-server
Deployment
Build and bundle the code for the web.
npm run build:web
Deploy to GitHub.
# remove web/bundle.js from .gitignore
git add web && git commit -m "update web version"
# delete gh-pages branch from origin before push
git subtree push --prefix web origin gh-pages
Terminal
Run Chip8.js in the terminal by selecting a ROM.
npm run play:terminal roms/<ROM>
Native
Run Chip8.js natively with raylib (experimental).
npm run play:native roms/<ROM>
Motivation
Chip8.js is a project to write a Chip-8 emulator in JavaScript. The main motivation is to learn lower level programming concepts and to increase familiarity with the Node.js environment.
Here are some of the concepts I learned while writing this program:
The base system: specifically base 2 (binary), base 10 (decimal), base 16 (hexadecimal), how they interact with each other and the concept of abstract numbers in programming
Bits, nibbles, bytes, ASCII encoding, and big and little endian values
Bitwise operators - AND (&), OR (|), XOR (^), left shift (<<), right shift (>>) and how to use them for masking, setting, and testing values
Using the Node built-in file system (fs)
The concept of a raw data buffer and how to work with it, how to convert an 8-bit buffer to a 16-bit big endian array
Writing and understanding a 8-bit and 16-bit hex dump
How to disassemble and decode an opcode into instructions a CPU can use
How a CPU can utilize memory, stack, program counters, stack pointers, memory addresses, and registers
How a CPU implements fetch, decode, and execute
And here are some articles I wrote based on those concepts:
Understanding Bits, Bytes, Bases, and Writing a Hex Dump in JavaScript (Node)
Writing an Emulator in JavaScript (with Multiple UIs)
Testing
The unit tests for Chip8.js use the Jest testing framework. You can run all test suites with or without displaying coverage.
# Run test suites
npm run test
# Run test suites and view coverage
npm run test --coverage
Chip8.js has two suites of unit tests:
Opcode instruction masks and arguments
CPU implementation of instructions
Instruction tests
The instruction tests cover the INSTRUCTION_SET found in data/instructionSet.js. Each instruction has:
A key: for internal use
An id: for a unique name
A name: for the type of instruction)
A mask: to filter out arguments from instruction signifiers)
A pattern: to match the mask to the specific instruction pattern
Each unit test checks an opcode to an instruction and tests:
The unique id to ensure the correct instruction is running for the mask/pattern
The number of arguments
The value of the arguments
// tests/instructions.test.js
test('6: Expect disassembler to match opcode 3xnn to instruction SE_VX_NN', () => {
expect(Disassembler.disassemble(0x3abb).instruction).toHaveProperty('id', 'SE_VX_NN')
expect(Disassembler.disassemble(0x3abb).args).toHaveLength(2)
expect(Disassembler.disassemble(0x3abb).args[0]).toBe(0xa)
expect(Disassembler.disassemble(0x3abb).args[1]).toBe(0xbb)
})
There are 35 instruction tests for 35 opcodes (the first instruction, CLS, is no longer implemented).
CPU tests
The CPU decodes the opcode and returns the instruction object from data/instructionSet.js. Each instruction performs a specific, unique action in the case. The CPU tests test the state of the CPU after an executing an instruction.
In the below example, the instruction is skipping an instruction if Vx === nn, otherwise it's going to the next instruction as usual.
// classes/CPU.js
case 'SE_VX_NN':
// Skip next instruction if Vx = nn.
if (this.registers[args[0]] === args[1]) {
this._skipInstruction()
} else {
this._nextInstruction()
}
break
Each CPU test:
Loads a RomBuffer containing the data of a single opcode
Sets up the state to make the instruction testable (if necessary)
Executes the step method
Tests all possible outcomes of an instruction and state updates
In this example, the instruction can either be skipped or not skipped depending on the arguments, and both cases are tested.
// tests/cpu.test.js
test('6: SE_VX_NN (3xnn) - Program counter should increment by two bytes if register x is not equal to nn argument', () => {
cpu.load({ data: [0x3abb] })
cpu.step()
expect(cpu.PC).toBe(0x202)
})
test('6: SE_VX_NN (3xnn) - Program counter should increment by four bytes if register x is equal to nn argument', () => {
cpu.load({ data: [0x3abb] })
cpu.registers[0xa] = 0xbb
cpu.step()
expect(cpu.PC).toBe(0x204)
})
Acknowledgements
Inspiration, guidance, and mentorship from Vanya Sergeev.
Cowgod's Chip-8 Technical Reference, made by Thomas P. Greene.
CHIP-8 - Wikipedia.
Author
Tania Rascia
License
This project is open source and available under the MIT License.
taniarascia/chip8 thuộc nhóm Frontend trên TopGit, cùng 5 topic GitHub. Trang Trending và Topics liệt kê các repo cùng số sao và cùng ngôn ngữ để so sánh.
Đọc thêm về taniarascia/chip8 ở đâu?
Trang TopGit này là một snapshot — tab "Readme" hiển thị nguyên văn README của repo (đã bỏ link, giữ ảnh). Repo GitHub ở github.com/taniarascia/chip8 là nguồn chính thức.
taniarascia/chip8 có bao nhiêu sao?
taniarascia/chip8 có 474 sao GitHub — tải lại trang để xem số mới nhất, hoặc xem trực tiếp github.com/taniarascia/chip8. TopGit phản chiếu số sao của GitHub nhưng không cam kết đến từng phút.
taniarascia/chip8 có những chủ đề gì?
GitHub topics của taniarascia/chip8: "chip-8", "chip-8-emulator", "emulator", "javascript", "node". TopGit xếp repo vào nhóm Frontend.
taniarascia/chip8 có phải mã nguồn mở không?
Có — taniarascia/chip8 phát hành theo license MIT, nghĩa là mã nguồn mở để đọc, fork và (tùy license) tái sử dụng. Mã: github.com/taniarascia/chip8.
taniarascia/chip8 có trang demo không?
Dự án có trang chủ ở https://taniarascia.github.io/chip8/. Tab "Readme" ở trang này thường có ảnh chụp và hướng dẫn bắt đầu nhanh.
taniarascia/chip8 còn đang phát triển không?
Commit gần nhất trên taniarascia/chip8 là 4.3 năm trước (theo timestamp GitHub). Repo có 44 fork — một chỉ báo về mức độ quan tâm của cộng đồng.
Đọc đầy đủ README ở tab phía trên.
Muốn nghe thêm một ý kiến về chip8?
Hỏi một AI đọc được trang này — một cú bấm là có ngay nhận định về chip8.