Chip16 Architecture - Jimmer1/Chip16 GitHub Wiki
Chip16 Architecture Specification
Data Registers
Chip16 has 16 16-bit registers which are denoted r0 ... r15. The r15 register also functions as a carry flag for some opcodes. Each register has an undefined value at the beginning of the program so it is necessary to manually initialise each register with the value you require. All register values are represented as unsigned integers, which means that all register values are in the range 0 <= r < 2^16.
Memory
Chip16 has 4KB of memory all of which is available to the programmer. There is an additional 12-bit register denoted M which contains a memory address for use with instructions that directly read or write to/from memory. There is no defined value for memory bytes to have when the program starts. It is necessary to initialise memory before you attempt to read from it otherwise you will encounter bugs in your program.
Program Stack
Chip16 has an address stack which is used by branching instructions. Each value in the stack is 12-bits wide and the stack can hold 8 values. At the program start, all stack values are undefined.
Program Counter
Chip16 has a 12-bit program counter which holds the address of the instruction currently being executed. The program counter can be modified by jump and function call instructions. At the start of the program, the program counter is defined to have the value of 0. The program counter is denoted PC.
Instruction Format
Chip16 uses a fixed width 16-bit instruction format stored high byte first. This means that the instruction 81E1 is represented as:
81 E1
Note: All values are represented in hexadecimal for consistency.
Some opcodes use this format to encode operands in different ways, here are all of the different ways that opcodes may use this format:
- PXYQ - P and Q indicate the operation and X and Y encode the register operands.
- PXNN - P indicates the operation, X encodes the register operand and NN is a code embedded constant.
- PNNN - P encodes the operation, NNN is a code embedded pointer value.
- PX0Q - P and Q encode the operation, X encodes the register operand.
- PXRR - P and RR encode the operation, X encodes the register operand.
Chip16 Devices
Chip16 offers an interface for extending the functionality of the Chip16 architecture through the use of Devices. A Device is a 'thing' that offers a simple interface and does something which is defined by the specification of the Device. This explanation is purposefully vague to allow a wide variety of Devices to offer exotic functionality. There are a number of standard devices which every Chip16 programmer can choose to use. There are enough ports for up to 16 Devices. Using Devices is completely optional but you will be unable to access data from Chip16 without one. Use of a multiple of the same Device is permitted, but each Device maintains its own state so what you do to one will not carry over to the others.
Device Interface
A Device's interface consists of a 16-bit value and something else, the something else could be 64KB of memory, a terminal output or even a whole other computer architecture if someone has written a Device that implements one.
The fundamental operations of a Device are the following 4:
- Writing data to the Device.
- Reading data from the Device.
- Setting the Device's internal pointer.
- Getting the Device's internal pointer.
The way these operations are defined will be covered on the Device Opcodes page.
Standard Devices
Currently there are 3 standard devices which are as follows:
- ConsoleIO - This Device allows the programmer to input and output hexadecimal numeric values and ASCII characters through the console.
- MemoryDevice - This Device allows the programmer to access 64KB of extra memory. The values of the cells is undefined.
- RomDevice - This Device allows the programmer to access 64KB of read only memory. The use of this Device will be focused on later in the course when we start executing byte-code from files.
Note: By default, the initial value of the Device's internal pointer is 0.
Including Devices
Creating a Chip16 object with Devices is done as follows:
import chip16
import chip16_devices as c16d
devices = [
c16d.ConsoleIO,
c16d.MemoryDevice,
c16d.MemoryDevice
]
code = [
# ... Just some byte-code
]
c16 = chip16.Chip16(code, devices)
If no Devices are explicitly specified then the programmer will have access to the ConsoleIO Device by default.