my_computer.md 10 KB

My Computer Architecture

This is a WIP of my own ISA.

General

The architecture is:

  • RISC
  • purely load/store
  • 8 bit with 16 bit addressing (the amount of memory available is dependent on implementation)
  • non-constant CPI (instructions take variable number of clock cycles to execute)
  • purely Von Neumann (instructions and data in the same memory)
  • memory mapped I/O
  • for multiple-byte values little endian is used
  • no CPU modes, memory protection and similar BS
  • no interrupts
  • ascending stack

Registers

There are 12 8 bit registers: R0 to R11 (corresponding to numbers 0 to 11). Some registers for pairs which are denoted as RX:RY where RX is the register storing the upper 8 bits and RY register storing the lower 8 bits.

  • R0 - R4: general purpose registers
  • R5 = FL: flag register, starting with LSB:
    • x: reserved
    • x: reserved
    • x: reserved
    • x: reserved
    • x: reserved
    • Z (zero): set by operations if the result was 0
    • C (carry): is set by addition and similar instructions on over flow.
    • T (test): is set by test operations, affect conditional jumps.
  • R6:R7 = AP: addressing pointer
  • R8:R9 = SP: stack pointer
  • R10:R11 = IP: instruction pointer

Operation

Upon start/reset the computer clears all registers to 0 except for IP which is set to 2. Instructions then start to be executed until either halting instruction is encountered, in which cases the computer sets the corresponding exit code and then stops executing instructions.

The stack pointer should be initialized by the program, typically as one of the first operations.

During execution of instruction X IP will contain the address of instruction X. The instruction itself may or may not modify the value of IP. When execution of X has finished, IP is incremented by 2.

As long as the computer is running the clock tick counter (see memory layout) is incremented after every clock tick (note that execution of one instruction may take more than one clock tick).

Instruction Set

The instruction size is fixed at 16 bits. The first 8 bits are the opcode, the following 8 bits hold the arguments.

Instruction arguments are always numerical. Bits that aren't used for arguments should always be 0 and bits used for arguments may only contain allowed values, otherwise the instruction may be considered malformed.

In the following table argument are specified from the LSB with the number of bits in the brackets.

abbr. name opcode arguments description flags
ARITHMETIC
ADD add r1(4) r2(4) CLC; ADD r1 r2 CZ
ADC add with carry r1(4) r2(4) r1 := r1 + r2 + FL[C]; CZ
SUB substract r1(4) r2(4) NEG r2; ADD r1 r2 CZ
SUC substract with carry r1(4) r2(4) NEG r2; ADC r1 r2 CZ
NEG arithmetic neg. r(4) r := -r (two's complement) Z
MUL multiply
INC increment r(4) CZ
DEC decrement r(4) CZ
ADI add immediate n(8) r1 := r1 + n; FL[C] = carry CZ
SUI substract immediate n(8) r1 := r1 + neg(n); FL[C] = carry CZ
LOGIC
ORR bitwise OR Z
AND bitwise AND Z
XOR bitwise XOR Z
NOT bitwise NOT r(4) r := bitwise_not(r) Z
TOL to logical value r1(4) r2(4) r1 := 1 if r2 != 0 else 0 Z
MEMORY
LDM load from memory 00000010 r(4) r := mem[AP]
STM store to memory 00000011 r(4) mem[AP] := r
PSH push onto stack 00000010 r(4) mem[SP] := r; SP++
POP pop from stack 00000011 r(4) r := mem[SP]; SP--
LI0 load immediate to R0 v(8) R0 := v
LI1 load immediate to R1 v(8) R1 := v
MOV move 00000001 r1(4) r2(4) r1 := r2
BST set bit r(4) b(3) r[b] := 1 Z
BCL clear bit r(4) b(3) r[b] := 0 Z
BNO negate bit r(4) b(3) r[b] := not(r[b]) Z
TESTS
TST test bit r(4) b(3) FL[T] := r[b] T
LUU compare less uns. uns. T
LUS compare less uns. sig. T
LSS compare less sig. sig. T
EQU equals r1(4) r2(4) FL[T] := R1 == R2 T
OTHER
SR0 shift right 0 CZ
SRC shift right copy CZ
SL0 shift left 0 r := r << n (LSB := 0); FL[C] := r[MSB] CZ
SLC shift left copy r := r << n (keep LSB); FL[C] := r[MSB] CZ
SWP swap r1(4) r2(4) swap(r1,r2)
CONTROL
JIF jump if if (FL[T]) IP := AP - 2
JIN jump if not if (!FL[T]) IP := AP - 2
SIF skip if n(8) if (FL[T]) IP := IP + offset(n)
SIN skip if n(8) if (!FL[T]) IP := IP + offset(n)
END end 11111111
NOP no operation 00000000 do nothing, waste a cycle

offset(n) = 2 * (n <= 127 ? n + 1 : n - 256)

pseudo instructions:

abbr. parameter name definition
JMP jump MOV 10 6; MOV 11 7
CLC clear carry BLC 5 6

TODO: instructions have to be aligned???

Memory

The memory model is Von Neumann (same memory for data and program instructions). Memory also serves for I/O mapping.

Every byte has access priviledges, R (reading allowed), W (writing allowed), RW (both reading and writing allowed) or none (inaccessible). Violating the priviledge results in program halting immediately and corresponding exit code being set.

The memory layout follows:

addresses (hex) type description
0000 NULL address, inaccessible, allows definition of NULL pointer to be 0.
0001 Unusable, exists to make instructions word-aligned.
0002 RW Start of program instructions.
PRG_END RW Last program instruction (has to be END), this is program-specific.
RW Stack memory.
STACK_END RW Highest possible stack address (configurable).
RW Program working memory
MEM_END RW Highest address of a continuous RW block since 0001, platform specific.
SPECIAL MEMORY FOLLOWS (available regardless of memory amount)
ff00 ... ff7f ??? Platform-specific (including priviledges) I/O mapped ports.
Reserved.
fff9 fffa WR STACK_END, if R12:R13 == this number, program halts. Can be 0 (unlimited stack).
fffb fffc R RAM amount, contains the number MEM_END.
fffd fffe R Tick count, counts (with overflow) clock ticks since program start.
ffff R After program contains the exit code (see below).

TODO: STACK???

Exits codes (at least the values 0xff and 0x00 have to be implemented):

  • 0x00: No error, program ended normally with the END instruction.
  • 0x01: Read from inaccessible memory address error.
  • 0x02: Write to inaccessible or read-only memory address error.
  • 0x03: Invalid instruction encountered.
  • 0x04: Stack overflow.
  • 0xff: Error without further specified details.

Assembler