Dringtendo is a simple games console based on a Harvard CPU architecture. The CPU has a similar instruction set to a Little Man Computer (LMC) which has been extended to support immediate, indirect and indexed addressing modes as well as direct.
There are 256 bytes of data memory, some of which are mapped to hardware devices such as 64 sprite tiles and 5 buttons.
It's designed for A Level Computer Science students who want to get past the limitations of LMC and explore different addressing modes, interrupts and an alternative to a Von Neumann CPU.
All Little Man Computer instructions should work on the Dringtendo:
Instruction | Example | Explanation |
---|---|---|
ADD data | ADD 1 | Add value at data memory address 1 to ACC |
SUB data | SUB 2 | Subtract value at data memory address 2 from ACC |
STA data | STA 3 | Save ACC to data memory address 3 |
LDA data | LDA 4 | Load value at data memory address 4 into ACC |
BRA instruction | BRA 5 | Branch to instruction memory address 5 (always) |
BRZ instruction | BRZ 6 | Branch to instruction memory address 6 (if ACC is zero) |
BRP instruction | BRP 7 | Branch to instruction memory address 7 (if ACC is positive) |
INP | INP | Input to ACC |
OUT | OUT | Output ACC value |
HLT | HLT | Stop program |
There four addressing modes supported:
Addressing mode | Example | Explanation |
---|---|---|
Immediate | LDA #100 | Load 100 into ACC |
Direct | LDA @100 | Load value from data memory address 100 into ACC |
Indirect | LDA ~100 | Use address in data memory address 100 to load value into ACC |
Indexed (immediate offset) | LDA [100] | Load value from data memory address IR+100 into ACC |
Indexed (direct offset) | LDA [Label] | Load offset from labelled data memory location and set ACC to data value at IR+offset |
As well as the Little Man Computer instruction set, there are some additional instructions:
Instruction | Example | Explanation |
---|---|---|
LDIR data | LDIR #69 | Load immediate value 69 into Index Register |
LDISR instruction | LDISR #0 | Set interrupt service routine address to 0 (disable interrupts) |
LDISR instruction | LDISR #40 | Set interrupt service routine address to 40 (interrupt calls instruction at address 40) |
PUSH | PUSH | Push value in ACC on to the stack |
POP | POP | Pop value from stack into ACC |
CALL instruction | CALL 23 | Push PC on to stack then set PC to instruction |
RET | RET | Return from sub routine (pop address from stack into PC) |
RND | RND #5 | Place a random number between 0 and 5 (inclusive) into the accumulator register |
Mnemonic | Example | Explanation |
---|---|---|
ORG | ORG 69 | Set the next data memory address to 69 (after all sprite and button memory locations) |
DAT | DAT 3 DAT 2 | Stores the literal value 3 at the next available data location (69) then the value 2 into location 70 |
// Display HELLO WORLD ORG 25 // set next data memory address to 25 Letters: DAT 72 // ASCII 72 is 'H' DAT 69 DAT 76 DAT 76 DAT 79 DAT 0 DAT 0 DAT 0 DAT 87 DAT 79 DAT 82 DAT 76 DAT 68 DAT 0 DAT 0 DAT 0
// Caesar cipher (no wrapping around alphabet) INP // input the caesar shift STA Shift CALL CaesarShift // shift HELLO LDA #33 STA StartPos LDA #4 STA CharCount CALL CaesarShift // shift WORLD HLT CaesarShift: LDIR StartPos LDA [CharCount] ADD Shift STA [CharCount] LDA CharCount SUB #1 STA CharCount BRP CaesarShift RET ORG 69 Shift: DAT CharCount: DAT 4 StartPos: DAT 25 ORG 25 // set next data memory address to 25 Hello: DAT 72 // ASCII 72 is 'H' DAT 69 DAT 76 DAT 76 DAT 79 DAT 0 DAT 0 DAT 0 World: DAT 87 DAT 79 DAT 82 DAT 76 DAT 68 DAT 0 DAT 0 DAT 0
// Fill screen with smiles LDA #97 // Smiley face STA BackgroundSprite CALL FillScreen LDA #98 // Sad face STA BackgroundSprite CALL FillScreen HLT FillScreen: LDA #63 // Copy BackgroundSprite into 0-63 STA i ScreenLoop: LDA BackgroundSprite STA ~i // indirect addressing (i stores an address) LDA i SUB #1 // decrease address STA i BRP ScreenLoop // repeat for each screen cell RET ORG 69 // set next memory address to 69 (after screen and buttons) BackgroundSprite: DAT 5 i: DAT 63
// Move a sprite around the screen using interrupts LDISR Button // Set interrupt handler CALL UpdateScreen // Clear background and draw player HLT Button: LDA Up // Interrupt handler BRZ NoBtnUp // Check if up button was pressed LDA pos SUB #8 STA pos LDA #0 STA Up NoBtnUp:LDA Down // Check if Down button was pressed BRZ NoBtnDown LDA pos ADD #8 STA pos LDA #0 STA Down NoBtnDown: LDA Left // Check if Left button was pressed BRZ NoBtnLeft LDA pos SUB #1 STA pos LDA #0 STA Left NoBtnLeft: LDA Right // Check if right button was pressed BRZ NoBtnRight LDA pos ADD #1 STA pos LDA #0 STA Right NoBtnRight: CALL UpdateScreen // Update screen RET UpdateScreen: CALL ClearScreen // Display game LDA player STA ~pos RET ClearScreen: LDA #63 // Clear game background STA i ScreenLoop: LDA Background STA ~i LDA i SUB #1 STA i BRP ScreenLoop RET ORG 64 // Start putting labels at address 64 (mapped to up button) Up:DAT // Buttons Down:DAT Left:DAT Right:DAT i: DAT // Used for looping through each pixel pos: DAT // Player position background: DAT 50 // Background sprite player: DAT 41 // Player sprite