-
Notifications
You must be signed in to change notification settings - Fork 33
Home
How do emulators work? That is the goal of this project. Just learn the rough process to emulate a Gameboy. The first step is to setup a basic game loop as you might for any other game. This should initialize your render library (SDL2 in this case). In the game loop you will then want to execute one video frame of CPU cycles, then render the screen, and then wait any extra time to ensure your processor and video are running at the correct speed.
Key Links: http://problemkaputt.de/pandocs.htm
How long is one frame on the Gameboy? If you look in the link above and find the "Game Boy Technical Data" section, you will see that vertical sync is 59.73 Hz. This means, we need to render about 60 frames per second.
How may cycles does the Gameboy CPU process in one frame? If you look in the link above and find the "LCD Status Register" section, you will see that a complete screen refresh occurs every 70,244 clock cycles. The CPU should continue processing OpCodes until it meet or exceeds 70,244 clock cycles and then return to allow the emulator to refresh the screen.
A CPU is the brain of the emulator. It is responsible for tracking the state of memory, registers and executing code. CPU Register and Flags are fundamental. They are accessed often and change regularly. The first part of CPU implementation is getting the registers and flags setup.
CPU Specifications PDF - This contains more details than we need to implement, but contains VERY detailed description of everything related to the CPU. If you go to page 22 of the PDF you will see details on these registers. All page numbers in PDF are the GOTO page, not the page printed on the sheet.
There are 6 registers on the Gameboy CPU. Each is 16 bits and most can be accessed by the HIGH and LOW bits.
- AF: Accumulator and Flags
- BC: General purpose
- DE: General purpose
- HL: General purpose
- SP: Stack pointer
- PC: Program counter
All 8 bit arithmetic output is stored in the accumulator (A). This is often used for small values because it takes less CPU cycles.
Flags store state of the last operation such as CARRY, ZERO, ADD, SUBTRACT. These are detailed in the PDF on page 94. For now, we'll start by setting the initial PC as per the info at Powerup Sequence. It says it will start by running the first instruction at 0x0000. Eventually this will be a hidden chuck of BIOS memory that is 256 bytes long. For now, just create a 64k (0xFFFF) byte array that will act as the memory. Be sure to initialize this memory to all zeros.
Now, let's implement our first opcode, NOP (0x00). In the PDF referenced above, you can find the instruction for the NOP. It basically does nothing and uses 4 clock cycles. So, read from the PC (0x0000), to get the OpCode (0x00/NOP), then read for an array of function pointers. This should map to one for NOP. All that function does is increase the total cycles by 4 and increment the PC by 1.