An attempt at making an 8 bit CPU in TUNG (The Ultimate Nerd Game)
Due to TUNG being a buggy game, I will not be able to add anything to my CPU until a few months from now (when Logic World is released). The game frequently neglects to save my progress, which can cause a whole day of progress to be lost. When Logic World is released, I'll start a new CPU in it. Until then, I'm going to have to stop working on this project.
Yesterday, I added a zero flag, a carry flag, a negative flag, and the compliments of all three. Before today, I didn't have anything that used these flags. Today, I added instructions to jump if certain flags were set and instructions to compare numbers to the A register.
In order to test these instructions, I made a small program to count to four and then halt.
In assembly, this program looks something like this:
LDA 0 ;Reset A Loop: ;Counting loop STA 0xFF ;Write to display ADD 0x01 ;Adds 1 to A CMP 0x05 ;Checks if A=5 JMP NZ Loop ;Loops if A!=5 HLT ;Stops if A=5
Because it never displays after A=5, the program only counts to four.
The instruction STA, which is used in the demo, writes to a location in memory. Although I haven't added the instructions for locations pointed to by registers, they will be implemented soon. I will also be adding instructions for reading from memory, which will allow for a program to take input and use RAM.
I also fixed a bug in the hardware that caused the ADD instruction to act extremely weirdly. Instead of adding the numbers it was supposed to, it would often add the wrong numbers, or the right numbers at the wrong time. In fixing this, I was also able to fix some problems I was having with the flags.
Finally, I added one new instruction that serves no purpose whatsoever. HCF, or Halt and Catch Fire, permanently disconnects the clock from the CPU. There is no way outside of the CPU to recover from an HCF. The only way to fix the CPU after an HCF is to go into the CPU and press a button to reconnect the clock.
Here's a current list of all opcodes and instructions:
0x00 - NOP 0x01 - LDA (immediate) 0x02 - LDB (immediate) 0x03 - LDC (immediate) 0x04 - LDD (immediate) 0x05 - LDE (immediate) 0x06 - JMP (immediate) 0x08 - ADD B 0x09 - ADD C 0x0A - ADD D 0x0B - ADD E 0x0C - ADD (immediate) 0x10 - CMP (immediate) 0x11 - CMP A 0x12 - CMP B 0x13 - CMP C 0x14 - CMP D 0x15 - CMP E 0x16 - JMP Z (immediate) 0x17 - JMP NZ (immediate) 0x20 - STA (immediate) 0x26 - JMP C (immediate) 0x27 - JMP NC (immediate) 0x36 - JMP P (immediate) 0x37 - JMP N (immediate) 0xFE - HCF 0xFF - HLT
And a current image:
Sadly, I may not be able to work on the CPU tomorrow or the next day, but I will come back to it as soon as I can and continue posting.
Today, I've added a few more instructions, and tested them in a simple program. The new instruction set looks like this:
0x00 - NOP 0x01 - LD A (immediate) 0x02 - LD B (immediate) 0x03 - LD C (immediate) 0x04 - LD D (immediate) 0x05 - LD E (immediate) 0x06 - JMP (immediate) 0x07 - NOP 0x08 - ADD B 0x08 - NOP ... 0xFE - NOP 0xFF - HALT
In order to test the functionality of each instruction and the hardware, I created a simple looping program to repeatedly increment the A register.
LD A, 0 ;resets the A register LD B, 1 ;Loads 1 into B for incrementing (no inc instruction yet) Loop: ADD B ;adds A and B, then loads the result into A JMP Loop ;Loops to increment A
I did end up coming across a few bugs in the hardware and my instruction decoding, so I'm glad I tested before the CPU became more complicated/difficult to debug.
I'll continue adding more instructions for now, and I'll give another update at some point tomorrow.
Currently, the CPU has an ALU, an accumulator, a program counter, 4 general purpose registers, and circuitry for reading from specific addresses in memory. The CPU lacks a flags register, though this will be added later. I've began work on the instruction decoding, and have managed to get a few instructions to work.
The ALU is identical to the one in the NAND Game, only instead of the default logic operation being NAND, it's OR. This means it can only add, OR, invert and/or zero A/B, and invert the output. The zeroing and inverting of the inputs and outputs does allow this ALU to do any necessary operation for basic programs. It does not yet support flags/comparisons.
The program counter, accumulator, and general purpose registers are all 8 bit. Maybe later I will make the program counter 16 bit, but for now it will remain at 8.
So far I've only had time to add 3 instructions.
0x00 - NOP 0x01 - LDA (Number) 0x02 - NOP ... 0xFE - NOP 0xFF - Halt
Each instruction is given 4 clock cycles to run. The first is used to load the opcode, and the others can be used to actually execute instructions. This does decrease the speed of the CPU by a bit, so I may make a way to skip the unused clock cycles later.
That's all for now, but I will be working on it as often as I can, so expect to see an update within a week.