A quick introduction to a CPU

If you are already comfortable with this, feel free to skip this topic.

A CPU is a machine built to execute a program. The fundamental blocks of a CPU are registers and instructions. As a software person, you can think of those registers as variables. Our 8080 has, among its registers, 8-bit registers named A, B, C, D, and E. You might think of those registers as this C code:

unsigned char A, B, C, D, E;

CPUS also all have a Program Counter (PC). You can think of this as a pointer.

unsigned char* pc;

To the CPU, a program is a sequence of hexadecimal numbers. Each assembly language instruction on the 8080 corresponds to 1-3 bytes in the program. Learning about which number corresponds to which instructions is where the processor data book (or any of the other 8080 info on the internet comes in handy).

Instruction names are often nemonic for what the instruction actually does. The 8080's nemonic for load is MOV (move), and ADD does just what you think it should.


The current value of memory pointed to by the Program Counter was 0x79 which corresponds to the 8080 MOV A,C instruction. This is the assembly code to a line of C code like A=C;.

If instead, the value at the PC was 0x80, the processor would instead perform ADD B. This would correspond to a line of C like A = A + B;.

A full list of 8080 instructions can be found in the "8080 reference" link at the top of the page. We will use information like this to implement our emulator.


On a CPU, each instruction takes a certain amount of time to execute and is measured in cycles. On modern processors, this information can be hard to come by as the timing depends on so many things. But on the older processors like the 8080, the timing was constant and this information was often provided by the manufacturer. For instance, a register to register MOV instruction takes 1 cycle.

Timing information is useful for writing efficient code on the processor. A programmer might try to avoid instructions that take many cycles to complete.

More importantly for us, we use timing information to emulate the processor. Instructions have to execute at the correct speed for the game to play true to the original. Some emulators go to great pains to get this correct, but we'll have to figure out how accurate we really need to be when we get that far.

← Prev: introduction-to-binary-and-hex   Next: logical-operations →

Post questions or comments on Twitter @realemulator101, or if you find issues in the code, file them on the github repository.