Microprocessor Emulation Mini-Tutorial

This is a project designed to help people understand the inner workings of the 
CPU inside a computer.

The CPU I am going to emulate is a 16 bit machine with 31 instructions.

The instructions are setup like that:

A : B : C : D

Instruction class: A
Instruction: B
Destination: C
Source: D

Where each is 4 bits, which leads to 16 instruction classes ..etc.

Here are the instruction classes:

0: Control
1: Load
2: Store
3: Math
4: Function calling
5: Stack manipulation
6: Branching
7: Input / Output

The system has 16 registers, r[0]-r[f], with the last three reserved like so:

R[D] Status register
R[E] Program counter
R[F] Stack pointer

The status register has two flags:

Z: zero (located in bit 0)
N: negative (located in bit 1)

The status register is updated after each load or math instruction.

Here is the instruction set

Control:
NOP 0x00 Do nothing
HALT 0x01 Stop emulation

Load:
LDI 0x10 Load the next value in memory into the dest register
LDR 0x11 Register to register copy
LDP 0x12 Load the memory value at source into dest
LDA 0x13 Load an absolute address into dest

Store:
STA 0x20 Store the value in source at the memory location
STP 0x21 Stop the values in source at the memory pointed to by dest

Math:
ADD 0x30 Add source to dest, store result in source
SUB 0x31 Subtract
MUL 0x32 Multiply
DIV 0x33 Integer divide
MOD 0x34 Integer remainder
SHR 0x35 Shift right
SHL 0x36 Shift left
AND 0x37 Bitwise and
OR 0x38 Bitwise or
XOR 0x39 Bitwise xor

Function:
CALLA 0x40 Jump to the subroutine in the next memory location (save registers)
CALLP 0x41 Just to the subroutine in the dest register (also save)
RET 0x42 Return from a call, restore registers

Stack:
PUSH 0x50 Put the values in source on the stack
PULL 0x51 Put the values in dest on the stack

Branch:
CMP 0x60 Compare dest – source, set status flags
BE 0x61 Branch if equal
BL 0x62 Branch if less
BG 0x63 Branch if greater
BAA 0x64 Branch to absolute address in the next memory location
BAP 0x65 Brach to the address in the source register

Input/ Output:
IN 0x70 Get a char from the keyboard
OUT 0x71 Display a char on the screen

With just these instructions it is possible to write any program.

The memory is 16 bit as is addressable by 16 bits, this means that we
 have 32k locations, each containing two bytes.

Initially the stack is set at 0xffff, and grows down.

Programs are loaded into address 0000, and start running from there.

The emulation code Grabs the instruction at PC, increments PC, and applies
 the instruction.

Repeat until a halt instruction is found.

Sample program in this assembly language:

LDI R0, 'A’ // start char
LDI R1, 'Z' + 1 // last char to display (Z) + 1
LDI R2, 1 // add this value each time
OUT R0 // display register 0
ADD R0, R2 // add r2 to r0
CMP R0, R1 // set the status reg
BL -3 // jump is N flag set (back 3 instructions)
HALT

This program displays the uppercase letters from A to Z and exits

I’m still finding bugs in the code and updating as needed.

Depending on the response to this, I plan on writing an assembler and 
small C compiler for it.