Inspiration

I wanted to play some retro games and I wanted to learn how people develop their own emulators to play these games on them. This hackathon I decided to learn to build my own emulator - Chip8its (pronounced as Chipbits) or as I like to call it "Chip-ate-its-bits!".

What it does

Chip8its is an emulator to play games written in 1970s' CHIP-8 programming language. These games used to be played on a monochromatic systems with only a limited memory of just 4 kilobytes of RAM. It can be accessed through the link provided where a player can upload their choice of ROM and press Start button to begin playing. (Note: For legal purposes, I did not put any ROMs on my github. However, a user/player can download their choice of ROMs available online and upload and play the games in their browser.)

How I built it

I built this emulator using Canvas and Javascript to deploy it on the server so that it can be used anywhere by anyone. I created a rudimentary webpage to upload a ROM and begin playing the games. The focus of this project was to write a homebrew emulator that would allow users to play old-school CHIP-8 games in their browser. The CHIP-8 had following specifications:

  • 4 kilobytes of RAM
  • 64 x 32 pixels of Display
  • Stack for 16-bit addresses
  • A program counter (a pointer to the address in memory of an instruction)
  • 16 8-bit (one byte) general-purpose variable registers
  • 16-bit index register
  • Two 8-bit timers (sound timer and delay timer)

This emulator performs following functions:

  • Read ROM files to buffer
  • Memory management - to store ROM content and fonts
  • Keyboard mapping - 16 keys are mapped to qwerty keyboard
  • Opcode fetch-decode-execute cycle - write my own CPU to handle opcode instructions
  • Update display and sound based on the instructions

This is short snippet of ALU from the CPU written to interpret the opcodes.

// ALU
case 0x8000: 
    switch (oc & 0x000F) {
        case 0x0000: // 8XY0 - LD Vx, Vy
            this.v[x] = this.v[y];
            break;
        case 0x0001: // 8XY1 - OR Vx, Vy
            this.v[x] = this.v[x] | this.v[y];
            break;
    }
break;      

I developed this project using wonderful resources that I found online such as the following:

Challenges I ran into

I had no experience working with assembly language but it was required to understand how to implement CHIP-8 architecture. Reading hardware specification has always been difficult for me. Working with variables registers and performing bitwise operations on opcodes and the values stored and read from the memory was quite challenging at first. I spent a lot of time on debugging things to understand what and why something went wrong during instruction execution loop (turns out even a single bit of incorrect value can cause the entire program to crash).

Accomplishments that I'm proud of

  • Created my very first hardware emulator
  • Got over my fear of reading hardware technical specification/manual

What I learned

  • Got better understanding of Hexadecimal and Binary
  • Learned to work with assembly language to process machine code instructions
  • Learned to decode opcodes and built my own small CPU

What's next for Chip8its

  • Add extensions to the emulator to support SCHIP (Super CHIP) and XO-CHIP
  • Create my own CHIP-8 game

What's next for me

Create other modern emulators such as GameBoy, SNES, and PS.

Built With

Share this project:

Updates