Merge pull request #2 from neuschaefer/doc
fox32 architecture documentation
This commit is contained in:
commit
a1d1e34e59
242
docs/cpu.md
Normal file
242
docs/cpu.md
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
# Fox32 CPU
|
||||||
|
|
||||||
|
This document aims to describe the CPU in the the Fox32 architecture.
|
||||||
|
Peripherals such as the disk controller are described elsewhere.
|
||||||
|
|
||||||
|
|
||||||
|
## Endianness
|
||||||
|
|
||||||
|
All 16-bit or 32-bit values are stored in memory in little-endian order.
|
||||||
|
|
||||||
|
|
||||||
|
## Registers
|
||||||
|
|
||||||
|
The Fox32 CPU has the following registers:
|
||||||
|
|
||||||
|
- **r0-r31**: 32-bit general-purpose registers
|
||||||
|
- **rsp**: current stack pointer
|
||||||
|
- **resp**: exception stack pointer
|
||||||
|
- **rfp**: frame pointer
|
||||||
|
- **rip**: instruction pointer
|
||||||
|
- condition flags, which are updated after some operations
|
||||||
|
- **zero flag**
|
||||||
|
- **carry flag**
|
||||||
|
- other flags
|
||||||
|
- enable use of exception stack pointer (**swap sp**)
|
||||||
|
- **interrupt flag**, to enable interrupt handling
|
||||||
|
- MMU state
|
||||||
|
- **MMU enabled** flag
|
||||||
|
- **page directory pointer**
|
||||||
|
|
||||||
|
|
||||||
|
## External buses
|
||||||
|
|
||||||
|
There are two kinds of external bus that the Fox32 CPU can address:
|
||||||
|
|
||||||
|
- **Memory**: Data is read from and written to memory with the `mov` instruction,
|
||||||
|
instructions are fetch from memory.
|
||||||
|
- **I/O bus**: Peripherals are connected to the I/O bus. Peripheral registers
|
||||||
|
can be read using the `in` instruction and written using the `out` instruction.
|
||||||
|
|
||||||
|
|
||||||
|
## Instruction encoding
|
||||||
|
|
||||||
|
All instructions start with a 16-bit control word, which is optionally followed
|
||||||
|
by a source operand, or by source and target operands, depending on the opcode.
|
||||||
|
|
||||||
|
|
||||||
|
| bits | name | description
|
||||||
|
|--------|--------|---------------------------------------------------
|
||||||
|
| 1:0 | source | source operand type
|
||||||
|
| 3:2 | target | target operand type
|
||||||
|
| 6:4 | cond | condition code
|
||||||
|
| 7 | --- | reserved, must be zero
|
||||||
|
| 13:8 | opcode | operation code/type, e.g. `mov` or `add`
|
||||||
|
| 15:14 | size | operation size, e.g. 32 bits
|
||||||
|
|
||||||
|
|
||||||
|
### Operand types
|
||||||
|
|
||||||
|
| value | description | size of operand | what's actually stored?
|
||||||
|
|-------|-----------------------|------------------|--------------------------
|
||||||
|
| 0 | register | 8 bits | register number
|
||||||
|
| 1 | register pointer | 8 bits | register number
|
||||||
|
| 2 | immediate | operation size | value
|
||||||
|
| 3 | immediate pointer | 32 bits | pointer to memory location
|
||||||
|
|
||||||
|
|
||||||
|
### Register numbers
|
||||||
|
|
||||||
|
| value | register
|
||||||
|
|-------|---------------------------------------------------------------------
|
||||||
|
| 0-31 | r0-r31
|
||||||
|
| 32 | rsp
|
||||||
|
| 33 | resp
|
||||||
|
| 34 | rfp
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### Condition codes
|
||||||
|
|
||||||
|
| value | name | description
|
||||||
|
|-------|--------|-----------------------------------------------------
|
||||||
|
| 0 | always | execute unconditionally
|
||||||
|
| 1 | ifz | execute if zero flag is set
|
||||||
|
| 2 | ifnz | execute if zero flag is not set
|
||||||
|
| 3 | ifc | execute if carry flag is set
|
||||||
|
| 4 | ifnc | execute if carry flag is not set
|
||||||
|
| 5 | ifgt | execute if neither zero flag nor carry flag is set
|
||||||
|
| 6 | iflteq | execute if zero flag or carry flag is set
|
||||||
|
|
||||||
|
|
||||||
|
### Operation codes
|
||||||
|
|
||||||
|
| value | name | operands | op sizes| description
|
||||||
|
|-------|--------|----------|---------|-----------------------------------------------------
|
||||||
|
| 0x00 | NOP | none | 8/16/32 | no operation
|
||||||
|
| 0x01 | ADD | src+tgt | 8/16/32 | add
|
||||||
|
| 0x02 | MUL | src+tgt | 8/16/32 | multiply (unsigned)
|
||||||
|
| 0x03 | AND | src+tgt | 8/16/32 | bitwise AND
|
||||||
|
| 0x04 | SLA | src+tgt | 8/16/32 | shift left
|
||||||
|
| 0x05 | SRA | src+tgt | 8/16/32 | shift right arithmetic (with sign extension)
|
||||||
|
| 0x06 | BSE | src+tgt | 8/16/32 | bit set
|
||||||
|
| 0x07 | CMP | src+tgt | 8/16/32 | compare
|
||||||
|
| 0x08 | JMP | src | 32 | absolute jump
|
||||||
|
| 0x09 | RJMP | src | 32 | relative jump
|
||||||
|
| 0x0A | PUSH | src | 8/16/32 | push value to stack
|
||||||
|
| 0x0B | IN | src+tgt | 32 | get input from I/O bus
|
||||||
|
| 0x0C | ISE | none | 32 | set interrupt enable flag
|
||||||
|
| 0x0D | MSE | none | 32 | set MMU enable flag
|
||||||
|
| 0x10 | HALT | none | 8/16/32 | halt CPU
|
||||||
|
| 0x11 | INC | src | 8/16/32 | increment (add 1)
|
||||||
|
| 0x13 | OR | src+tgt | 8/16/32 | bitwise OR
|
||||||
|
| 0x14 | IMUL | src+tgt | 8/16/32 | multiply (signed)
|
||||||
|
| 0x15 | SRL | src+tgt | 8/16/32 | shift right logical (with zero extension)
|
||||||
|
| 0x16 | BCL | src+tgt | 8/16/32 | bit clear
|
||||||
|
| 0x17 | MOV | src+tgt | 8/16/32 | move value
|
||||||
|
| 0x18 | CALL | src | 32 | absolute call
|
||||||
|
| 0x19 | RCALL | src | 32 | relative call
|
||||||
|
| 0x1A | POP | src | 8/16/32 | pop value from stack
|
||||||
|
| 0x1B | OUT | src+tgt | 32 | output on I/O bus
|
||||||
|
| 0x1C | ICL | none | 32 | clear interrupt enable flag
|
||||||
|
| 0x1D | MCL | none | 32 | clear MMU enable flag
|
||||||
|
| 0x20 | BRK | none | 8/16/32 | debug breakpoint
|
||||||
|
| 0x21 | SUB | src+tgt | 8/16/32 | subtract
|
||||||
|
| 0x22 | DIV | src+tgt | 8/16/32 | divide (unsigned)
|
||||||
|
| 0x23 | XOR | src+tgt | 8/16/32 | bitwise XOR
|
||||||
|
| 0x24 | ROL | src+tgt | 8/16/32 | rotate left
|
||||||
|
| 0x25 | ROR | src+tgt | 8/16/32 | rotate right
|
||||||
|
| 0x26 | BTS | src+tgt | 8/16/32 | test if bit set
|
||||||
|
| 0x27 | MOVZ | src+tgt | 8/16/32 | move value and clear upper bits in target register
|
||||||
|
| 0x28 | LOOP | src | 32 | absolute loop
|
||||||
|
| 0x29 | RLOOP | src | 32 | relative loop
|
||||||
|
| 0x2A | RET | none | 32 | return from function
|
||||||
|
| 0x2C | INT | src | 32 | raise interrupt
|
||||||
|
| 0x2D | TLB | src | 32 | flush TLB and set page directory pointer
|
||||||
|
| 0x31 | DEC | src | 8/16/32 | decrement (subtract 1)
|
||||||
|
| 0x32 | REM | src+tgt | 8/16/32 | calculate remainder of division (unsigned)
|
||||||
|
| 0x33 | NOT | src | 8/16/32 | bitwise NOT
|
||||||
|
| 0x34 | IDIV | src+tgt | 8/16/32 | divide (signed)
|
||||||
|
| 0x35 | IREM | src+tgt | 8/16/32 | remainder (signed)
|
||||||
|
| 0x39 | RTA | src+tgt | 32 | calculate address relative to instruction pointer
|
||||||
|
| 0x3A | RETI | none | 32 | return from interrupt
|
||||||
|
| 0x3D | FLP | src | 32 | flush page from TLB
|
||||||
|
|
||||||
|
|
||||||
|
### Operation sizes
|
||||||
|
|
||||||
|
| value | description
|
||||||
|
|-------|--------------------------------------------------------------
|
||||||
|
| 0 | byte (8 bits)
|
||||||
|
| 1 | half (16 bits)
|
||||||
|
| 2 | word (32 bits)
|
||||||
|
| 3 | reserved
|
||||||
|
|
||||||
|
|
||||||
|
## Interrupts and Exceptions
|
||||||
|
|
||||||
|
Interrupts indicate asynchronous hardware events (such as VSYNC) or execution
|
||||||
|
of the `int` instruction, while exceptions indicate various synchronous errors.
|
||||||
|
|
||||||
|
There are 0x100 interrupt vectors and 5 exception vectors. Interrupt vectors
|
||||||
|
are at 0x000 to 0x3FC, and exception vectors at 0x400 to 0x410. These memory
|
||||||
|
locations simply store the address of the interrupt/exception handler,
|
||||||
|
or 0x0 when no handler has been installed.
|
||||||
|
|
||||||
|
(TODO: what should the hardware do when a handler is missing?)
|
||||||
|
|
||||||
|
| type | vector | description
|
||||||
|
|-----------|----------|-------------------------------------------
|
||||||
|
| interrupt | 0 - 0xF0 | free for software use
|
||||||
|
| interrupt | 0xFB | audio channel 3 refill
|
||||||
|
| interrupt | 0xFC | audio channel 2 refill
|
||||||
|
| interrupt | 0xFD | audio channel 1 refill
|
||||||
|
| interrupt | 0xFE | audio channel 0 refill
|
||||||
|
| interrupt | 0xFF | display VSYNC
|
||||||
|
| exception | 0x00 | divide by zero
|
||||||
|
| exception | 0x01 | invalid opcode
|
||||||
|
| exception | 0x02 | page fault during read
|
||||||
|
| exception | 0x03 | page fault during write
|
||||||
|
| exception | 0x04 | breakpoint
|
||||||
|
|
||||||
|
|
||||||
|
Upon interrupt/exception entry, the CPU performs the following operations:
|
||||||
|
|
||||||
|
- read handler address from vector
|
||||||
|
- if *swap sp* is enabled:
|
||||||
|
- switch to the exception stack pointer, and push the old stack pointer
|
||||||
|
- push current instruction pointer
|
||||||
|
- push flags (8 bits)
|
||||||
|
- push interrupt vector (0x00-0xff) or exception operand
|
||||||
|
- clear interrupt flag and *swap sp* flag
|
||||||
|
- jump to handler
|
||||||
|
|
||||||
|
|
||||||
|
Interrupt/exception handlers are exited through the `reti` instruction, which
|
||||||
|
performs the following operations:
|
||||||
|
|
||||||
|
- pop and restore flags
|
||||||
|
- pop instruction pointer
|
||||||
|
- if *swap sp* flag is set, pop stack pointer
|
||||||
|
|
||||||
|
|
||||||
|
The flags are stored in the following format:
|
||||||
|
|
||||||
|
| bit | description
|
||||||
|
|--------|-----------------------------------------------
|
||||||
|
| 0 | zero flag
|
||||||
|
| 1 | carry flag
|
||||||
|
| 2 | interrupt flag
|
||||||
|
| 3 | *swap sp* flag
|
||||||
|
|
||||||
|
|
||||||
|
## MMU
|
||||||
|
|
||||||
|
If the MMU is enabled, two-level page tables are used to translate virtual
|
||||||
|
addresses to physical addresses.
|
||||||
|
|
||||||
|
The address of the page directory can be set using the `tlb` instruction.
|
||||||
|
|
||||||
|
| virtual address bits | purpose
|
||||||
|
|-----------------------|--------------------------------------------------
|
||||||
|
| 11:0 | lowest 12 bits of physical address
|
||||||
|
| 21:12 | page table index
|
||||||
|
| 31:22 | page directory index
|
||||||
|
|
||||||
|
|
||||||
|
Page directories and page tables are arrays of 1024 elements of the following format:
|
||||||
|
|
||||||
|
| bits | bit mask ts | purpose
|
||||||
|
|-------|---------------|--------------------------------------------------
|
||||||
|
| 31:12 | 0xfffff000 | address of page table or page
|
||||||
|
| 1 | 0x00000002 | page is writable
|
||||||
|
| 0 | 0x00000001 | page table or page is present
|
||||||
|
|
||||||
|
|
||||||
|
A page table walk is performed as follows:
|
||||||
|
|
||||||
|
- read page directory entry at page directory index in page directory
|
||||||
|
- abort if page table is not present
|
||||||
|
- read page table entry at page table index in page table
|
||||||
|
- abort of page is not present
|
||||||
|
- use physical page address and writability information from page table entry
|
53
docs/instructions.md
Normal file
53
docs/instructions.md
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
# Fox32 instructions
|
||||||
|
|
||||||
|
This file describes every Fox32 instruction in detail. For a general
|
||||||
|
description of the Fox32 CPU, see cpu.md.
|
||||||
|
|
||||||
|
## NOP: no operation
|
||||||
|
## ADD: add
|
||||||
|
## MUL: multiply (unsigned)
|
||||||
|
## AND: bitwise AND
|
||||||
|
## SLA: shift left
|
||||||
|
## SRA: shift right arithmetic (with sign extension)
|
||||||
|
## BSE: bit set
|
||||||
|
## CMP: compare
|
||||||
|
## JMP: absolute jump
|
||||||
|
## RJMP: relative jump
|
||||||
|
## PUSH: push value to stack
|
||||||
|
## IN: get input from I/O bus
|
||||||
|
## ISE: set interrupt enable flag
|
||||||
|
## MSE: set MMU enable flag
|
||||||
|
## HALT: halt CPU
|
||||||
|
## INC: increment (add 1)
|
||||||
|
## OR: bitwise OR
|
||||||
|
## IMUL: multiply (signed)
|
||||||
|
## SRL: shift right logical (with zero extension)
|
||||||
|
## BCL: bit clear
|
||||||
|
## MOV: move value
|
||||||
|
## CALL: absolute call
|
||||||
|
## RCALL: relative call
|
||||||
|
## POP: pop value from stack
|
||||||
|
## OUT: output on I/O bus
|
||||||
|
## ICL: clear interrupt enable flag
|
||||||
|
## MCL: clear MMU enable flag
|
||||||
|
## BRK: debug breakpoint
|
||||||
|
## SUB: subtract
|
||||||
|
## DIV: divide (unsigned)
|
||||||
|
## XOR: bitwise XOR
|
||||||
|
## ROL: rotate left
|
||||||
|
## ROR: rotate right
|
||||||
|
## BTS: test if bit set
|
||||||
|
## MOVZ: move value and clear upper bits in target register
|
||||||
|
## LOOP: absolute loop
|
||||||
|
## RLOOP: relative loop
|
||||||
|
## RET: return from function
|
||||||
|
## INT: raise interrupt
|
||||||
|
## TLB: flush TLB and set page directory pointer
|
||||||
|
## DEC: decrement (subtract 1)
|
||||||
|
## REM: calculate remainder of division (unsigned)
|
||||||
|
## NOT: bitwise NOT
|
||||||
|
## IDIV: divide (signed)
|
||||||
|
## IREM: remainder (signed)
|
||||||
|
## RTA: calculate address relative to instruction pointer
|
||||||
|
## RETI: return from interrupt
|
||||||
|
## FLP: flush page from TLB
|
15
docs/io_bus.md
Normal file
15
docs/io_bus.md
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# I/O bus
|
||||||
|
|
||||||
|
| start | end | description
|
||||||
|
|------------|------------|---------------------------------------
|
||||||
|
| 0x00000000 | 0x00000000 | debug serial port
|
||||||
|
| 0x80000000 | 0x8000031f | display overlay
|
||||||
|
| 0x80000400 | 0x80000401 | mouse
|
||||||
|
| 0x80000500 | 0x80000500 | keyboard
|
||||||
|
| 0x80000600 | 0x80000600 | audio
|
||||||
|
| 0x80000700 | 0x80000706 | RTC
|
||||||
|
| 0x80001000 | 0x80005003 | disk
|
||||||
|
| 0x80010000 | 0x80010000 | power off
|
||||||
|
|
||||||
|
|
||||||
|
TODO: details
|
8
docs/memory.md
Normal file
8
docs/memory.md
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
# Memory
|
||||||
|
|
||||||
|
The memory in a Fox32 system is laid out as follows:
|
||||||
|
|
||||||
|
| start | end | size | description
|
||||||
|
|------------|------------|---------|---------------------------------------
|
||||||
|
| 0x00000000 | 0x04000000 | 64 MiB | RAM
|
||||||
|
| 0xf0000000 | 0xf0080000 | 512 KiB | ROM
|
|
@ -246,7 +246,7 @@ static const asm_iinfo_t asm_iinfos[256] = {
|
||||||
[OP_IREM ] = { "IREM ", 2 },
|
[OP_IREM ] = { "IREM ", 2 },
|
||||||
[OP_RTA ] = { "RTA ", 2 },
|
[OP_RTA ] = { "RTA ", 2 },
|
||||||
[OP_RETI ] = { "RETI ", 0 },
|
[OP_RETI ] = { "RETI ", 0 },
|
||||||
[OP_FLP ] = { "FLP ", 0 }
|
[OP_FLP ] = { "FLP ", 1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static const asm_iinfo_t *asm_iinfo_get(uint8_t opcode) {
|
static const asm_iinfo_t *asm_iinfo_get(uint8_t opcode) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user