├── circuit ├── v2 │ ├── RAM │ ├── OPCODE_A │ ├── OPCODE_B │ └── TEST └── v1 │ ├── 16bit_Adder.circ │ ├── PC.circ │ ├── REGISTER.circ │ ├── LED8x8.circ │ ├── ALU.circ │ ├── CPU_ALU.circ │ ├── CPU_Test_001.circ │ └── CPU_Test_002.circ ├── .gitignore ├── notes ├── FLAGS.md ├── ALU.md ├── LED.md ├── BRANCH.md ├── MEMORY.md ├── OPCODES.md └── MICROCODE.md ├── asm ├── test.out ├── snake.out ├── test.asm ├── 6502-test.asm └── snake.asm ├── README.md ├── microcode ├── microcode-raw.txt └── microcode.txt └── tools ├── microcode-editor └── microcode-editor.html └── assembler └── assembler.c /circuit/v2/RAM: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | c 21 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # binaries 2 | tools/assembler/assembler 3 | -------------------------------------------------------------------------------- /circuit/v2/OPCODE_A: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 80 0 0 0 c0 80 0 0 3 | c0 0 1 0 4 0 22 4 | -------------------------------------------------------------------------------- /circuit/v2/OPCODE_B: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 10 22 0 80 0 10 22 0 3 | 0 0 80 0 80 0 80 4 | -------------------------------------------------------------------------------- /notes/FLAGS.md: -------------------------------------------------------------------------------- 1 | # Flags 2 | 3 | * C = Carry 4 | * Z = Zero 5 | * N = Negative 6 | -------------------------------------------------------------------------------- /asm/test.out: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 06 00 2c c0 b8 12 08 fe a4 02 9e 22 a4 04 9e 38 3 | b8 06 08 c0 12 ff 36 e5 b8 06 08 c0 12 00 36 e5 4 | d1 00 d7 00 be 1a 08 c0 6a 00 a4 ff 9e 32 2c c0 5 | b8 12 06 00 2c c0 b8 12 d7 00 be 1a 08 c0 67 00 6 | a4 19 9e 48 2c c0 b8 12 06 18 2c c0 b8 12 -------------------------------------------------------------------------------- /circuit/v2/TEST: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 801000 3 | 002200 4 | 000002 5 | 008040 6 | C00030 7 | 801000 8 | 002200 9 | 000002 10 | C00030 11 | 000080 12 | 018000 13 | 000080 14 | 048000 15 | 000080 16 | 048000 17 | 801000 18 | 002200 19 | 000002 20 | 108000 21 | 201000 22 | 082020 23 | 000002 24 | 018000 25 | 000080 26 | 048000 27 | 082020 28 | 000002 29 | 018000 30 | 000080 31 | 048000 32 | 801000 33 | 002200 34 | 000002 35 | 108000 36 | 600000 37 | 080100 38 | 000080 -------------------------------------------------------------------------------- /notes/ALU.md: -------------------------------------------------------------------------------- 1 | # ALU 2 | 3 | * **X**: Variable X (8bit) 4 | * **Y**: Variable Y (AX) (8bit) 5 | * **Z**: Result Z (8bit) 6 | * **1**: Constant 1 on X Flag (1bit) 7 | * **C/I**: Carry Flag (1bit) 8 | * **C/O**: Carry Out Flag (1bit) 9 | * **OP**: Operation (4bit) 10 | 11 | ## Operations 12 | 13 | * `0001` Z = X + Y 14 | * `0010` Z = X - Y 15 | * `0011` Z = X AND Y 16 | * `0100` Z = X OR Y 17 | * `0101` Z = X XOR Y 18 | * `0110` Z = Y logically shifted left 19 | * `0111` Z = Y logically shifted right 20 | * `1000` Z = Y arithmetically shifted left 21 | * `1001` Z = Y rotated left 22 | * `1010` Z = Y rotated right 23 | -------------------------------------------------------------------------------- /notes/LED.md: -------------------------------------------------------------------------------- 1 | # LED 2 | 3 | ## Activate 4 | 5 | ``` 6 | 0000 0000 1111 0000 1100 0000 0 (register) 7 | 8 | A = 00011 (3) 9 | D = $FF 10 | D' = 1 11 | ``` 12 | 13 | ``` 14 | 0000 0000 0000 0000 0000 0010 0 (mask) 15 | 0000 0000 1111 0000 1100 0000 0 (register) 16 | =============================== OR 17 | 0000 0000 1111 0000 1100 0010 0 (register') 18 | ``` 19 | 20 | ## Deactivate 21 | 22 | ``` 23 | 0000 0000 0000 0000 0000 0010 0 (mask) 24 | 1111 1111 1111 1111 1111 1101 1 (mask NOT) 25 | 0000 0000 1111 0000 1100 0010 0 (register') 26 | =============================== AND 27 | 0000 0000 1111 0000 1100 0000 0 (register'') 28 | ``` 29 | -------------------------------------------------------------------------------- /asm/snake.out: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 06 eb 2c d0 06 ec 2c d1 06 ed 2c d2 06 02 2c de 3 | be b2 be c8 08 fe a4 00 9e 14 be 34 be 9a be 26 4 | be bc be c8 b8 14 08 de 6a 00 d9 d0 36 d1 6a 00 5 | 94 2a d1 00 08 fe a4 01 9e 48 a4 02 9e 5a a4 03 6 | 9e 6c a4 04 9e 88 d1 00 08 d0 5f 05 2c d0 a4 e5 7 | 98 54 d1 00 57 19 2c d0 d1 00 08 d0 6a 00 2c d0 8 | a4 e4 9e 66 d1 00 06 e9 2c d0 d1 00 08 d0 57 05 9 | 2c d0 a4 fe 9a 7c a4 04 98 82 d1 00 5f 19 2c d0 10 | d1 00 57 e7 2c d0 d1 00 08 d0 67 00 2c d0 a4 fe 11 | 9e 94 d1 00 06 f9 2c d0 d1 00 08 df a6 d0 9c aa 12 | 08 de 67 00 2c de be b2 d1 00 0c d0 a4 ff 9e ce 13 | d1 00 08 ff 6d 18 57 e5 2c df d1 00 08 de 12 00 14 | 4c d0 12 ff 3f d0 d1 00 12 ff 3f df d1 00 b8 ce 15 | -------------------------------------------------------------------------------- /notes/BRANCH.md: -------------------------------------------------------------------------------- 1 | # CCR 2 | 3 | * **OP**: Operation (3bit) 4 | * **BM**: Branch Mode Flag (1bit) 5 | * **SEC**: Set Carry Flag (8bit) 6 | * **CLR**: Clear Carry Flag (1bit) 7 | * **I**: ALU Result (from Z) (8bit) 8 | * **CLK**: Clock (1bit) 9 | * **RST**: Reset (1bit) 10 | * **BI**: Branch Instruction Flag (1bit) 11 | * **C**: Carry Flag (1bit) 12 | * **Z**: Zero Flag (1bit) 13 | * **N**: Negative Flag (1bit) 14 | 15 | ## Operations 16 | 17 | * `000` BPL Branch on plus (N) 18 | * `001` BMI Branch on minus (N) 19 | * `010` BCC Branch on carry clear (C) 20 | * `011` BCS Branch on carry set (C) 21 | * `100` BNE Branch on not equal (Z) 22 | * `101` BEQ Branch on equal (Z) 23 | * `110` SEC Set carry flag 24 | * `111` CLC Clear carry flag 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 8bit 2 | 3 | These are my notes on building a 8bit computer. The circuit is simulated with the great [Logisim](http://www.cburch.com/logisim/de/), I've also written a converter for my [assembly language](https://github.com/adzialocha/8bit/blob/master/tools/assembler/assembler.c) and a helper to write [micro instructions](https://github.com/adzialocha/8bit/blob/master/tools/microcode-editor/microcode-editor.html). 4 | 5 | ### Folder structure 6 | 7 | * `asm` contains sketches and final programs written in 6502 or my own assembler. 8 | * `circuit` holds all Logisim projects, `v3` is the latest. 9 | * `microcode` the microcode program for the circuits control unit (can be read, edited and saved by the microcode editor tool). 10 | * `notes` different notes on the architecture, memory organisation, opcodes etc. 11 | * `tools` small software projects to help me designing the computer. 12 | -------------------------------------------------------------------------------- /asm/test.asm: -------------------------------------------------------------------------------- 1 | ; Beispielprogramm für fiktive 8bit CPU 2 | 3 | ; Initialisierung 4 | 5 | lda #$00 6 | sta $c0 ; Spieler Position 7 | 8 | jmp draw ; Zeichne initiale Spieler-Position 9 | 10 | ; Haupt-Routine 11 | 12 | main: 13 | lda $fe ; Tastaturbuffer abfragen 14 | cmp #$02 ; "<"? 15 | beq left 16 | cmp #$04 ; ">"? 17 | beq right 18 | jmp main 19 | 20 | ; Routine: Spieler zeichnen 21 | 22 | draw: 23 | lda $c0 ; Lade Spieler-Position in AX 24 | ldb #$ff ; Lade Farbe Weiß in BX 25 | stb $e5,a ; Zeiche Spieler mit Farbe aus BX an Position AX 26 | jmp main 27 | 28 | ; Routine: Spieler löschen 29 | 30 | clear: 31 | lda $c0 ; Lade Spieler-Position in AX 32 | ldb #$00 ; Lade Farbe Schwarz in BX 33 | stb $e5,a ; Schreibe schwarz (leer) an Stelle des Spielers 34 | rts 35 | 36 | ; Routine: Spieler nach links oder rechts bewegen 37 | 38 | left: 39 | cib ; Clear input buffer 40 | jsr clear ; Lösche letzte Position auf Bildschirm 41 | lda $c0 ; Lade aktuelle Position in A 42 | dec ; .. um Position um 1 zu verringern 43 | cmp #$ff ; Haben wir den linken Rand erreicht? 44 | beq left_border 45 | sta $c0 ; Speichere neue Position 46 | jmp draw 47 | left_border: 48 | lda #$00 ; Setze Position auf maximalen linken Rand 49 | sta $c0 50 | jmp draw 51 | 52 | right: 53 | cib ; Clear input buffer 54 | jsr clear ; Lösche letzte Position auf Bildschirm 55 | lda $c0 ; Lade aktuelle Position in A 56 | inc ; .. um Position um 1 zu erhöhen 57 | cmp #$19 ; haben wir den rechten Rand erreicht? 58 | beq right_border 59 | sta $c0 ; Speichere neue Position 60 | jmp draw 61 | right_border: 62 | lda #$18 ; Setze Position auf maximalen rechten Rand 63 | sta $c0 64 | jmp draw 65 | -------------------------------------------------------------------------------- /asm/6502-test.asm: -------------------------------------------------------------------------------- 1 | ; Beispielprogramm in 6502 Assembler 2 | 3 | ; Initialisierung 4 | 5 | LDA #$00 6 | STA $01 ; Spieler Position 7 | 8 | ; Haupt-Routine 9 | 10 | main: 11 | JSR draw ; Zeichne aktuelle Spieler Position 12 | JMP check_input ; Überprüfe Tastatur-Eingaben 13 | JMP main 14 | 15 | ; Routine: Spieler zeichnen 16 | 17 | draw: 18 | LDX $01 ; Lade Spieler-Position in X 19 | LDA #$01 ; Lade Farbe Weiß in A 20 | STA $0200,X ; Zeiche Spieler mit Farbe aus A an Position X 21 | RTS 22 | 23 | ; Routine: Spieler löschen 24 | 25 | clear: 26 | LDX $01 ; Lade Spieler-Position in X 27 | LDA #$00 ; Lade Farbe Schwarz in A 28 | STA $0200,X ; Schreibe schwarz (leer) an Stelle des Spielers 29 | RTS 30 | 31 | ; Routine: Überprüfe Tastatur-Eingabe 32 | 33 | check_input: 34 | LDA $FF ; Tastaturbuffer abfragen 35 | CMP #$61 ; "A"? 36 | BEQ left 37 | CMP #$64 ; "D"? 38 | BEQ right 39 | JMP main ; .. zurück zum Hauptprogramm wenn nichts passiert ist 40 | 41 | ; Routine: Tastaturbuffer löschen 42 | 43 | clear_input: 44 | LDA #0 ; Tastaturbuffer .. 45 | STA $ff ; .. löschen 46 | RTS 47 | 48 | ; Routine: Spieler nach links bewegen 49 | 50 | left: 51 | JSR clear_input 52 | JSR clear ; Lösche letzte Position auf Bildschirm 53 | LDA $01 ; Lade aktuelle Position in A und 54 | TAX ; .. kopiere nach X 55 | DEX ; .. um Zahl um 1 zu verringern 56 | CPX #$ff ; Haben wir den linken Rand erreicht? 57 | BEQ left_border 58 | STX $01 ; Speichere neue Position 59 | JMP main 60 | left_border: 61 | LDA #$0 ; Setze Position auf maximalen linken Rand 62 | STA $01 63 | JMP main 64 | 65 | ; Routine: Spieler nach rechts bewegen 66 | 67 | right: 68 | JSR clear_input 69 | JSR clear ; Lösche letzte Position auf Bildschirm 70 | LDA $01 ; Lade aktuelle Position in A und 71 | TAX ; .. kopiere nach X 72 | INX ; .. um Zahl um 1 zu erhöhen 73 | CPX #$0f ; haben wir den rechten Rand erreicht? 74 | BEQ right_border 75 | STX $01 ; Speichere neue Position 76 | JMP main 77 | right_border: 78 | LDA #$0e ; Setze Position auf maximalen rechten Rand 79 | STA $01 80 | JMP main 81 | -------------------------------------------------------------------------------- /notes/MEMORY.md: -------------------------------------------------------------------------------- 1 | # Memory 2 | 3 | ## Register 4 | 5 | Arbeitsregister um 8bit Werte kurzzeitig festzuhalten. 6 | 7 | * I: Eingabewert welcher im Register gespeichert werden soll (8bit) 8 | * O: Ausgabewert welcher aus Register ausgelesen wurde (8bit) 9 | * R/I: Schreiben-Flag, um Eingabewert in Register zu speichern (1bit) 10 | * R/O: Lesen-Flag, um aktuellen Registerwert auszugeben (1bit) 11 | * CLK: Takt 12 | * RST: Zurücksetzen-Flag 13 | 14 | ## RAM 15 | 16 | 8bit addressierbarer 2048bit (256x8bit) Arbeitsspeicher. 17 | 18 | - 256 words by 8 bits (word-length) 19 | - 2048bit total 20 | - Adressen: $00 - $ff (000 - 255) 21 | 22 | * AR/I: Speicher-Adresse-Schreiben Flag (1bit) 23 | * DR/I: Datenregister-Schreiben-Flag (1bit) 24 | * DR/O: Datenregister-Lesen-Flag (1bit) 25 | * R: Lese bit aus Arbeitsspeicher aus gegebener Adresse (1bit) 26 | * W: Schreibe bit an die Adresse in Arbeitsspeicher (1bit) 27 | * D/I: Datenbus Eingang (8bit) 28 | * D/O: Datenbus Ausgang (8bit) 29 | * CLK: Takt 30 | * RST: Zurücksetzen-Flag 31 | 32 | ## Organisation 33 | 34 | - $00 - $DF (000 - 223) free usable memory (224 Byte) 35 | - $E0 - $E4 (224 - 228) stack (5 Byte) 36 | - $E5 - $FD (229 - 253) 5x5 Pixel Display (25 Byte) 37 | - $FE (254) currently pressed key (1 Byte) [read-only] 38 | - $FF (255) random number (1 Byte) [read-only] 39 | 40 | ### Free memory 41 | 42 | ``` 43 | 00 01 02 03 04 05 06 07 44 | 08 09 0A 0B 0C 0D 0E 0F 45 | 10 11 12 13 14 15 16 17 46 | 18 19 1A 1B 1C 1D 1E 1F 47 | 20 21 22 23 24 25 26 27 48 | 28 29 2A 2B 2C 2D 2E 2F 49 | 30 31 32 33 34 35 36 37 50 | 38 39 3A 3B 3C 3D 3E 3F 51 | 40 41 42 43 44 45 46 47 52 | 48 49 4A 4B 4C 4D 4E 4F 53 | 50 51 52 53 54 55 56 57 54 | 58 59 5A 5B 5C 5D 5E 5F 55 | 60 61 62 63 64 65 66 67 56 | 68 69 6A 6B 6C 6D 6E 6F 57 | 70 71 72 73 74 75 76 77 58 | 78 79 7A 7B 7C 7D 7E 7F 59 | 80 81 82 83 84 85 86 87 60 | 88 89 8A 8B 8C 8D 8E 8F 61 | 90 91 92 93 94 95 96 97 62 | 98 99 9A 9B 9C 9D 9E 9F 63 | A0 A1 A2 A3 A4 A5 A6 A7 64 | A8 A9 AA AB AC AD AE AF 65 | B0 B1 B2 B3 B4 B5 B6 B7 66 | B8 B9 BA BB BC BD BE BF 67 | C0 C1 C2 C3 C4 C5 C6 C7 68 | C8 C9 CA CB CC CD CE CF 69 | D0 D1 D2 D3 D4 D5 D6 D7 70 | D8 D9 DA DB DC DD DE DF 71 | ``` 72 | 73 | ### Special purpose 74 | 75 | ``` 76 | E0 E1 E2 E3 E4 | E5 E6 E7 77 | E8 E9 EA EB EC ED EE EF 78 | F0 F1 F2 F3 F4 F5 F6 F7 79 | F8 F9 FA FB FC FD | FE FF 80 | ``` 81 | 82 | ### Screen cheatsheet 83 | 84 | ``` 85 | E5 E6 E7 E8 E9 86 | EA EB EC ED EE 87 | EF F0 F1 F2 F3 88 | F4 F5 F6 F7 F8 89 | F9 FA FB FC FD 90 | ``` 91 | 92 | ## Tasten 93 | 94 | - $01 (001) : Pfeil Oben 95 | - $02 (010) : Pfeil Links 96 | - $03 (011) : Pfeil Unten 97 | - $04 (100) : Pfeil Rechts 98 | - $05 (101) : Taste B 99 | - $06 (110) : Taste A 100 | -------------------------------------------------------------------------------- /microcode/microcode-raw.txt: -------------------------------------------------------------------------------- 1 | v2.0 raw 2 | 280000 3 | 050000 4 | 908000 5 | 280000 6 | 150000 7 | ffffff 8 | 008080 9 | 000000 10 | 088000 11 | 050000 12 | 008080 13 | 000000 14 | 088000 15 | 050000 16 | 088000 17 | 050000 18 | 008080 19 | 000000 20 | 008020 21 | 000000 22 | 088000 23 | 050000 24 | 008020 25 | 000000 26 | 088000 27 | 050000 28 | 088000 29 | 050000 30 | 008020 31 | 000000 32 | 088000 33 | 050000 34 | 008102 35 | 080001 36 | 050000 37 | 008020 38 | 000000 39 | 008102 40 | 080001 41 | 050000 42 | 088000 43 | 050000 44 | 008020 45 | 000000 46 | 088000 47 | 010040 48 | 028000 49 | 000000 50 | 088000 51 | 050000 52 | 088000 53 | 050000 54 | 008080 55 | 000000 56 | 008102 57 | 080001 58 | 010010 59 | 028000 60 | 000000 61 | 088000 62 | 010010 63 | 028000 64 | 000000 65 | 088000 66 | 050000 67 | 088000 68 | 010010 69 | 028000 70 | 000000 71 | 088000 72 | 050000 73 | 008102 74 | 080001 75 | 010010 76 | 028000 77 | 000000 78 | 008102 79 | 080001 80 | 050000 81 | 088000 82 | 010010 83 | 028000 84 | 000000 85 | 000060 86 | 000000 87 | 000090 88 | 000000 89 | 008102 90 | 000081 91 | 000000 92 | 088000 93 | 050000 94 | 008102 95 | 000081 96 | 000000 97 | 008202 98 | 000081 99 | 000000 100 | 088000 101 | 050000 102 | 008202 103 | 000081 104 | 000000 105 | 001102 106 | 000081 107 | 000000 108 | 001202 109 | 000081 110 | 000000 111 | 008302 112 | 000081 113 | 000000 114 | 088000 115 | 050000 116 | 008302 117 | 000081 118 | 000000 119 | 008402 120 | 000081 121 | 000000 122 | 088000 123 | 050000 124 | 008402 125 | 000081 126 | 000000 127 | 008502 128 | 000081 129 | 000000 130 | 088000 131 | 050000 132 | 008502 133 | 000081 134 | 000000 135 | 000602 136 | 000081 137 | 000000 138 | 000702 139 | 000081 140 | 000000 141 | 000802 142 | 000081 143 | 000000 144 | 000902 145 | 000081 146 | 000000 147 | 000a02 148 | 000081 149 | 000000 150 | 004000 151 | 000000 152 | 004100 153 | 000000 154 | 004200 155 | 000000 156 | 004300 157 | 000000 158 | 004400 159 | 000000 160 | 004500 161 | 000000 162 | 004600 163 | 000000 164 | 004700 165 | 000000 166 | 008202 167 | 000000 168 | 088000 169 | 050000 170 | 008202 171 | 000000 172 | 080004 173 | 010040 174 | 028000 175 | 000084 176 | 001102 177 | 000009 178 | 008080 179 | 000000 180 | 000084 181 | 001202 182 | 080009 183 | 050000 184 | 008080 185 | 000000 186 | 400000 187 | 000000 188 | 088000 189 | 050000 190 | 400000 191 | 000000 192 | 008080 193 | 080004 194 | 210000 195 | 028000 196 | 010040 197 | 400000 198 | 000084 199 | 001102 200 | 000009 201 | 000000 202 | 088000 203 | 050000 204 | 200080 205 | 400000 206 | 010040 207 | 080084 208 | 001102 209 | 000009 210 | 000000 211 | 000084 212 | 001202 213 | 080009 214 | 050000 215 | 400000 216 | 000000 217 | 002000 218 | 000000 219 | 008102 220 | 080001 221 | 050000 222 | 008020 223 | 000000 224 | -------------------------------------------------------------------------------- /notes/OPCODES.md: -------------------------------------------------------------------------------- 1 | # Opcodes 2 | 3 | ## Layout 4 | 5 | 16bit (instruction [+ operand]) 6 | 7 | ``` 8 | | --------- | --------- | 9 | | 0000 0000 | Adresse | 10 | | 0000 0000 | Operand | 11 | | --------- | --------- | 12 | ``` 13 | 14 | ## Addressing modes 15 | 16 | * Implicit 17 | * Absolute `$nn` 18 | * Immediate `#$nn` 19 | * Indexed `$nn,a` 20 | * Indexed indirect `($nn,a)` 21 | * Indirect `($nn)` 22 | * Indirect indexed `($nn),a` 23 | 24 | ## Opcodes 25 | 26 | ### Storage 27 | 28 | * `lda #$nn` 29 | * `lda $nn` 30 | * `lda ($nn)` 31 | * `ldb #$nn` 32 | * `ldb $nn` 33 | * `ldb ($nn)` 34 | * `sta $nn` 35 | * `sta ($nn)` 36 | * `stb $nn` 37 | * `stb $nn,a` 38 | * `stb ($nn),a` 39 | * `stb ($nn,a)` 40 | * `tab` transfer from AX to BX 41 | * `tba` transfer from BX to AX 42 | 43 | ### Math 44 | 45 | * `adc #$nn` AX = AX + $nn 46 | * `adc $nn` AX = AX + {$nn} 47 | * `sbc #$nn` AX = AX - $nn 48 | * `sbc $nn` AX = AX - {$nn} 49 | * `inc` AX = AX + 1 50 | * `dec` AX = AX - 1 51 | 52 | ### Bitwise 53 | 54 | * `and #$nn` AX = AX AND $nn 55 | * `and $nn` AX = AX AND {$nn} 56 | * `ora #$nn` AX = AX OR $nn 57 | * `ora $nn` AX = AX OR {$nn} 58 | * `eor #$nn` AX = AX XOR $nn 59 | * `eor $nn` AX = AX XOR {$nn} 60 | * `lsl` AX logical shift left 61 | * `lsr` AX logical shift right 62 | * `asl` AX arithmetic shift left 63 | * `rol` AX rotate left one bit 64 | * `ror` AX rotate right one bit 65 | 66 | ### Branch 67 | 68 | * `bpl $nn` branch on plus (N) 69 | * `bmi $nn` branch on minus (N) 70 | * `bcc $nn` branch on carry clear (C) 71 | * `bcs $nn` branch on carry set (C) 72 | * `bne $nn` branch on not equal (Z) 73 | * `beq $nn` branch on equal (Z) 74 | 75 | ### Flags 76 | 77 | * `sec` set carry flag 78 | * `clc` clear carry flag 79 | 80 | ### Registers 81 | 82 | * `cmp #$nn` compare $nn to AX 83 | * `cmp $nn` compare {$nn} to AX 84 | 85 | ### Stack 86 | 87 | * `pha` push AX on stack 88 | * `pop` pop stack top to AX 89 | 90 | ### Jump 91 | 92 | * `jmp #$nn` jump to location $nn 93 | * `jmp $nn` jump to location {$nn} 94 | * `jsr $nn` jump to location $nn and save return address 95 | * `jsr {$nn}` jump to location {$nn} and save return address 96 | * `rts` return from subroutine 97 | 98 | ### Input 99 | 100 | * `cib` clear input buffer 101 | 102 | ## Microcode addresses 103 | 104 | ``` 105 | adc #$nn - $57 106 | adc $nn - $5a 107 | and #$nn - $6d 108 | and $nn - $70 109 | asl - $8b 110 | bcc - $98 111 | bcs - $9a 112 | beq - $9e 113 | bmi - $96 114 | bne - $9c 115 | bpl - $94 116 | cib - $d7 117 | clc - $a2 118 | cmp #$nn - $a4 119 | cmp $nn - $a6 120 | dec - $6a 121 | eor #$nn - $7d 122 | eor $nn - $80 123 | inc - $67 124 | jmp #$nn - $b8 125 | jmp $nn - $ba 126 | jsr #$nn - $be 127 | jsr $nn - $c8 128 | lda #$nn - $06 129 | lda $nn - $08 130 | lda ($nn) - $0c 131 | ldb #$nn - $12 132 | ldb $nn - $14 133 | ldb ($nn) - $18 134 | ldb ($nn),a - $1e 135 | ldb ($nn,a) - $25 136 | lsl - $85 137 | lsr - $88 138 | ora #$nn - $75 139 | ora $nn - $78 140 | pha - $aa 141 | pop - $b2 142 | rol - $8e 143 | ror - $91 144 | rts - $d1 145 | sbc #$nn - $5f 146 | sbc $nn - $62 147 | sec - $a0 148 | sta $nn - $2c 149 | sta ($nn) - $30 150 | stb $nn - $3b 151 | stb $nn,a - $36 152 | stb ($nn) - $3f 153 | stb ($nn),a - $45 154 | stb ($nn,a) - $4c 155 | tab - $53 156 | tba - $55 157 | ``` 158 | -------------------------------------------------------------------------------- /asm/snake.asm: -------------------------------------------------------------------------------- 1 | ; snake clone for my 8bit cpu 2 | 3 | ; ▄▄▄▄▄ ▄ ██ █ █▀ ▄███▄ 4 | ; █ ▀▄ █ █ █ █▄█ █▀ ▀ 5 | ; ▄ ▀▀▀▀▄ ██ █ █▄▄█ █▀▄ ██▄▄ 6 | ; ▀▄▄▄▄▀ █ █ █ █ █ █ █ █▄ ▄▀ 7 | ; █ █ █ █ █ ▀███▀ 8 | ; █ ██ █ ▀ 9 | ; ▀ 10 | 11 | ; variables 12 | 13 | ; the following variables describe the 14 | ; snakes position on our 5x5 pixel screen 15 | ; 16 | ; note: the screen is organized as follows: 17 | ; 18 | ; e5 e6 e7 e8 e9 19 | ; ea eb ec ed ee 20 | ; ef f0 f1 f2 f3 21 | ; f4 f5 f6 f7 f8 22 | ; f9 fa fb fc fd 23 | ; 24 | ; the segment positions of the snake are 25 | ; pointers to the screen positions. 26 | ; 27 | ; prepare the following variables: 28 | 29 | lda #$eb ; position 30 | sta $d0 ; ... of snake head 31 | 32 | lda #$ec ; first segment 33 | sta $d1 ; ... of snake body 34 | 35 | lda #$ed ; second segment 36 | sta $d2 ; ... of snake body 37 | 38 | lda #$02 ; length 39 | sta $de ; ... of snake body 40 | 41 | ; note: the machine only gives 224 byte of free 42 | ; memory. We need 2 bytes for variables ($de, $df) 43 | ; plus a maximum of 14 bytes for the snake head 44 | ; & body ($d0-$dd) which restricts the whole 45 | ; program size to 208 bytes ($00-$cf)! 46 | 47 | ; initial routines 48 | 49 | jsr apple ; generate a random apple position 50 | jsr draw_apple ; ... & draw the apple 51 | 52 | ; main loop routine 53 | 54 | ; note: the program jumps directly to game 55 | ; over after executing the main routine for 56 | ; the second time, if there is no moving- 57 | ; direction defined. To avoid this we do not 58 | ; start the game when the user didn't press 59 | ; any arrow keys yet. 60 | 61 | main: 62 | lda $fe ; check the pressed key 63 | cmp #$00 ; ... when nothing was pressed yet 64 | beq main ; ... then do nothing! 65 | 66 | jsr move 67 | jsr collision 68 | jsr update 69 | jsr draw_snake 70 | jsr draw_apple 71 | 72 | jmp main 73 | 74 | ; routine: pass over body segments to next position ahead 75 | 76 | update: 77 | lda $de ; get snake length 78 | dec 79 | update_loop: 80 | ldb $d0,a ; get body segment 81 | stb $d1,a ; ... store it one address after 82 | dec 83 | bpl update_loop 84 | rts 85 | 86 | ; routine: check pressed keys & check if the move is maybe illegal 87 | 88 | ; note: we do not check for wall collisions 89 | ; to let the snake run infinitely. Also when leaving 90 | ; right or left the snake appears on a different 91 | ; line on the other side than before. Both decisions 92 | ; are mainly design restrictions due to the 93 | ; small memory size. 94 | 95 | move: 96 | lda $fe ; get currently pressed key 97 | 98 | cmp #$01 ; [up] pressed? 99 | beq move_up 100 | cmp #$02 ; [left] pressed? 101 | beq move_left 102 | cmp #$03 ; [down] pressed? 103 | beq move_down 104 | cmp #$04 ; [right] pressed? 105 | beq move_right 106 | rts 107 | 108 | move_up: 109 | lda $d0 ; load snake head position 110 | sbc #$05 ; ... substract a whole screen line 111 | sta $d0 ; ... store it again 112 | 113 | cmp #$e5 ; did we reach the top? 114 | bcc move_up_end ; ... then ... 115 | rts 116 | 117 | move_up_end: 118 | adc #$19 ; ... come up from the bottom again 119 | sta $d0 120 | rts 121 | 122 | move_left: 123 | lda $d0 ; load snake head position 124 | dec ; ... decrement it by one 125 | sta $d0 ; ... store it again 126 | 127 | cmp #$e4 ; did we reach the up left border? 128 | beq move_left_end ; ... then 129 | rts 130 | 131 | move_left_end: 132 | lda #$e9 ; ... come out on the right corner 133 | sta $d0 134 | rts 135 | 136 | move_down: 137 | lda $d0 ; load snake head position 138 | adc #$05 ; ... add a whole screen line 139 | sta $d0 ; ... store it again 140 | 141 | cmp #$fe ; did we reach the border? 142 | bcs move_down_endh 143 | 144 | cmp #$04 ; we also have to check for this since 145 | bcc move_down_endl ; the screen memory is (weirdly) organized 146 | rts 147 | 148 | move_down_endh: 149 | sbc #$19 ; come up from the top again 150 | sta $d0 151 | rts 152 | 153 | move_down_endl: 154 | adc #$e7 ; ... same here 155 | sta $d0 156 | rts 157 | 158 | move_right: 159 | lda $d0 ; load snake head position 160 | inc ; ... increment it by one 161 | sta $d0 ; ... store it again 162 | 163 | cmp #$fe ; did we reach the bottom right? 164 | beq move_right_end ; ... then 165 | rts 166 | 167 | move_right_end: 168 | lda #$f9 ; ... come out on the left corner 169 | sta $d0 170 | rts 171 | 172 | ; routine: check if snake collided with apple or itself 173 | 174 | ; note: we check first if the snake's head sits 175 | ; on the same address as the apple. if not 176 | ; then any set pixel must be a part of the snake. 177 | 178 | collision: 179 | lda $df ; load apple position 180 | cmp $d0 ; ... check if its the heads position 181 | bne collision_snake 182 | 183 | lda $de ; increase snake length 184 | inc ; ... by one 185 | sta $de ; ... & store it again 186 | 187 | jsr apple ; find new apple position 188 | rts 189 | 190 | collision_snake: 191 | lda ($d0) ; load pixel at snake head 192 | cmp #$ff ; check if its set 193 | beq game_over 194 | rts 195 | 196 | ; routine: place an apple randomly on the screen 197 | 198 | apple: 199 | lda $ff ; load a random number into AX 200 | and #$18 ; limit range to 0-24 201 | adc #$e5 ; add start screen address 202 | sta $df ; ... & store it as the new apple position 203 | rts 204 | 205 | ; routine: draw snake on screen 206 | 207 | draw_snake: 208 | lda $de ; get snake length 209 | ldb #$00 ; prepare clear pixel 210 | stb ($d0,a) 211 | 212 | ldb #$ff ; prepare set pixel for display 213 | stb ($d0) ; draw head at screen position 214 | rts 215 | 216 | draw_apple: 217 | ldb #$ff ; pixel to set 218 | stb ($df) ; ... & store at screen location 219 | rts 220 | 221 | ; routine: game over 222 | 223 | game_over: 224 | jmp game_over ; ... is an endless loop 225 | -------------------------------------------------------------------------------- /circuit/v1/16bit_Adder.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | addr/data: 8 8 46 | 0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /circuit/v1/PC.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | -------------------------------------------------------------------------------- /tools/microcode-editor/microcode-editor.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Micro instructions editor 5 | 134 | 135 | 136 |
137 |

Micro instructions editor

138 |
139 | 140 | 141 | 142 | 143 |
144 |
145 |
    146 | 147 | 148 | 423 | 424 | 425 | -------------------------------------------------------------------------------- /microcode/microcode.txt: -------------------------------------------------------------------------------- 1 | $00 $280000 001010000000000000000000 AR := PC ; fetch addr 2 | $01 $050000 000001010000000000000000 DR := {AR} 3 | $02 $908000 100100001000000000000000 OP := DR & PC := PC+1 4 | $03 $280000 001010000000000000000000 AR := PC ; fetch op 5 | $04 $150000 000101010000000000000000 DR := {AR} & PC := PC+1 6 | $05 $ffffff 111111111111111111111111 ; decode 7 | $06 $008080 000000001000000010000000 [lda #$nn] AX := DR 8 | $07 $000000 000000000000000000000000 ; execute 9 | $08 $088000 000010001000000000000000 [lda $nn] AR := DR 10 | $09 $050000 000001010000000000000000 DR := {AR} 11 | $0a $008080 000000001000000010000000 AX := DR 12 | $0b $000000 000000000000000000000000 ; execute 13 | $0c $088000 000010001000000000000000 [lda ($nn)] AR := DR 14 | $0d $050000 000001010000000000000000 DR := {AR} 15 | $0e $088000 000010001000000000000000 AR := DR 16 | $0f $050000 000001010000000000000000 DR := {AR} 17 | $10 $008080 000000001000000010000000 AX := DR 18 | $11 $000000 000000000000000000000000 ; execute 19 | $12 $008020 000000001000000000100000 [ldb #$nn] BX := DR 20 | $13 $000000 000000000000000000000000 ; execute 21 | $14 $088000 000010001000000000000000 [ldb $nn] AR := DR 22 | $15 $050000 000001010000000000000000 DR := {AR} 23 | $16 $008020 000000001000000000100000 BX := DR 24 | $17 $000000 000000000000000000000000 ; execute 25 | $18 $088000 000010001000000000000000 [ldb ($nn)] AR := DR 26 | $19 $050000 000001010000000000000000 DR := {AR} 27 | $1a $088000 000010001000000000000000 AR := DR 28 | $1b $050000 000001010000000000000000 DR := {AR} 29 | $1c $008020 000000001000000000100000 BX := DR 30 | $1d $000000 000000000000000000000000 ; execute 31 | $1e $088000 000010001000000000000000 [ldb ($nn),a] AR := DR 32 | $1f $050000 000001010000000000000000 DR := {AR} 33 | $20 $008102 000000001000000100000010 Z := AX + DR 34 | $21 $080001 000010000000000000000001 AR := Z 35 | $22 $050000 000001010000000000000000 DR := {AR} 36 | $23 $008020 000000001000000000100000 BX := DR 37 | $24 $000000 000000000000000000000000 ; execute 38 | $25 $008102 000000001000000100000010 [ldb ($nn,a)] Z := DR + AX 39 | $26 $080001 000010000000000000000001 AR := Z 40 | $27 $050000 000001010000000000000000 DR := {AR} 41 | $28 $088000 000010001000000000000000 AR := DR 42 | $29 $050000 000001010000000000000000 DR := {AR} 43 | $2a $008020 000000001000000000100000 BX := DR 44 | $2b $000000 000000000000000000000000 ; execute 45 | $2c $088000 000010001000000000000000 [sta $nn] AR := DR 46 | $2d $010040 000000010000000001000000 DR := AX 47 | $2e $028000 000000101000000000000000 {AR} := DR 48 | $2f $000000 000000000000000000000000 ; execute 49 | $30 $088000 000010001000000000000000 [sta ($nn)] AR := DR 50 | $31 $050000 000001010000000000000000 DR := {AR} 51 | $32 $088000 000010001000000000000000 AR := DR 52 | $33 $050000 000001010000000000000000 DR := {AR} 53 | $34 $008080 000000001000000010000000 AX := DR 54 | $35 $000000 000000000000000000000000 ; execute 55 | $36 $008102 000000001000000100000010 [stb $nn,a] Z := DR + AX 56 | $37 $080001 000010000000000000000001 AR := Z 57 | $38 $010010 000000010000000000010000 DR := BX 58 | $39 $028000 000000101000000000000000 {AR} := DR 59 | $3a $000000 000000000000000000000000 ; execute 60 | $3b $088000 000010001000000000000000 [stb $nn] AR := DR 61 | $3c $010010 000000010000000000010000 DR := BX 62 | $3d $028000 000000101000000000000000 {AR} := DR 63 | $3e $000000 000000000000000000000000 ; execute 64 | $3f $088000 000010001000000000000000 [stb ($nn)] AR := DR 65 | $40 $050000 000001010000000000000000 DR := {AR} 66 | $41 $088000 000010001000000000000000 AR := DR 67 | $42 $010010 000000010000000000010000 DR := BX 68 | $43 $028000 000000101000000000000000 {AR} := DR 69 | $44 $000000 000000000000000000000000 ; execute 70 | $45 $088000 000010001000000000000000 [stb ($nn),a] AR := DR 71 | $46 $050000 000001010000000000000000 DR := {AR} 72 | $47 $008102 000000001000000100000010 Z := AX + DR 73 | $48 $080001 000010000000000000000001 AR := Z 74 | $49 $010010 000000010000000000010000 DR := BX 75 | $4a $028000 000000101000000000000000 {AR} := DR 76 | $4b $000000 000000000000000000000000 ; execute 77 | $4c $008102 000000001000000100000010 [stb ($nn,a)] Z := DR + AX 78 | $4d $080001 000010000000000000000001 AR := Z 79 | $4e $050000 000001010000000000000000 DR := {AR} 80 | $4f $088000 000010001000000000000000 AR := DR 81 | $50 $010010 000000010000000000010000 DR := BX 82 | $51 $028000 000000101000000000000000 {AR} := DR 83 | $52 $000000 000000000000000000000000 ; execute 84 | $53 $000060 000000000000000001100000 [tab] BX := AX 85 | $54 $000000 000000000000000000000000 ; execute 86 | $55 $000090 000000000000000010010000 [tba] AX := BX 87 | $56 $000000 000000000000000000000000 ; execute 88 | $57 $008102 000000001000000100000010 [adc #$nn] Z := AX + DR 89 | $58 $000081 000000000000000010000001 AX := Z 90 | $59 $000000 000000000000000000000000 ; execute 91 | $5a $088000 000010001000000000000000 [adc $nn] AR := DR 92 | $5b $050000 000001010000000000000000 DR := {AR} 93 | $5c $008102 000000001000000100000010 Z := AX + DR 94 | $5d $000081 000000000000000010000001 AX := Z 95 | $5e $000000 000000000000000000000000 ; execute 96 | $5f $008202 000000001000001000000010 [sbc #$nn] Z := AX - DR 97 | $60 $000081 000000000000000010000001 AX := Z 98 | $61 $000000 000000000000000000000000 ; execute 99 | $62 $088000 000010001000000000000000 [sbc $nn] AR := DR 100 | $63 $050000 000001010000000000000000 DR := {AR} 101 | $64 $008202 000000001000001000000010 Z := AX - DR 102 | $65 $000081 000000000000000010000001 AX := Z 103 | $66 $000000 000000000000000000000000 ; execute 104 | $67 $001102 000000000001000100000010 [inc] Z := AX + 1 105 | $68 $000081 000000000000000010000001 AX := Z 106 | $69 $000000 000000000000000000000000 ; execute 107 | $6a $001202 000000000001001000000010 [dec] Z := AX - 1 108 | $6b $000081 000000000000000010000001 AX := Z 109 | $6c $000000 000000000000000000000000 ; execute 110 | $6d $008302 000000001000001100000010 [and #$nn] Z = AX AND DR 111 | $6e $000081 000000000000000010000001 AX := Z 112 | $6f $000000 000000000000000000000000 ; execute 113 | $70 $088000 000010001000000000000000 [and $nn] AR := DR 114 | $71 $050000 000001010000000000000000 DR := {AR} 115 | $72 $008302 000000001000001100000010 Z := AX AND DR 116 | $73 $000081 000000000000000010000001 AX := Z 117 | $74 $000000 000000000000000000000000 ; execute 118 | $75 $008402 000000001000010000000010 [ora #$nn] Z = AX OR DR 119 | $76 $000081 000000000000000010000001 AX := Z 120 | $77 $000000 000000000000000000000000 ; execute 121 | $78 $088000 000010001000000000000000 [ora $nn] AR := DR 122 | $79 $050000 000001010000000000000000 DR := {AR} 123 | $7a $008402 000000001000010000000010 Z := AX OR DR 124 | $7b $000081 000000000000000010000001 AX := Z 125 | $7c $000000 000000000000000000000000 ; execute 126 | $7d $008502 000000001000010100000010 [eor #$nn] Z = AX XOR DR 127 | $7e $000081 000000000000000010000001 AX := Z 128 | $7f $000000 000000000000000000000000 ; execute 129 | $80 $088000 000010001000000000000000 [eor $nn] AR := DR 130 | $81 $050000 000001010000000000000000 DR := {AR} 131 | $82 $008502 000000001000010100000010 Z := AX XOR DR 132 | $83 $000081 000000000000000010000001 AX := Z 133 | $84 $000000 000000000000000000000000 ; execute 134 | $85 $000602 000000000000011000000010 [lsl] Z = AX LSL 135 | $86 $000081 000000000000000010000001 AX := Z 136 | $87 $000000 000000000000000000000000 ; execute 137 | $88 $000702 000000000000011100000010 [lsr] Z = AX LSR 138 | $89 $000081 000000000000000010000001 AX := Z 139 | $8a $000000 000000000000000000000000 ; execute 140 | $8b $000802 000000000000100000000010 [asl] Z = AX ASL 141 | $8c $000081 000000000000000010000001 AX := Z 142 | $8d $000000 000000000000000000000000 ; execute 143 | $8e $000902 000000000000100100000010 [rol] Z = AX ROL 144 | $8f $000081 000000000000000010000001 AX := Z 145 | $90 $000000 000000000000000000000000 ; execute 146 | $91 $000a02 000000000000101000000010 [ror] Z = AX ROR 147 | $92 $000081 000000000000000010000001 AX := Z 148 | $93 $000000 000000000000000000000000 ; execute 149 | $94 $004000 000000000100000000000000 [bpl] 150 | $95 $000000 000000000000000000000000 ; execute 151 | $96 $004100 000000000100000100000000 [bmi] 152 | $97 $000000 000000000000000000000000 ; execute 153 | $98 $004200 000000000100001000000000 [bcc] 154 | $99 $000000 000000000000000000000000 ; execute 155 | $9a $004300 000000000100001100000000 [bcs] 156 | $9b $000000 000000000000000000000000 ; execute 157 | $9c $004400 000000000100010000000000 [bne] 158 | $9d $000000 000000000000000000000000 ; execute 159 | $9e $004500 000000000100010100000000 [beq] 160 | $9f $000000 000000000000000000000000 ; execute 161 | $a0 $004600 000000000100011000000000 [sec] 162 | $a1 $000000 000000000000000000000000 ; execute 163 | $a2 $004700 000000000100011100000000 [clc] 164 | $a3 $000000 000000000000000000000000 ; execute 165 | $a4 $008202 000000001000001000000010 [cmp #$nn] Z := AX - DR 166 | $a5 $000000 000000000000000000000000 ; execute 167 | $a6 $088000 000010001000000000000000 [cmp $nn] AR := DR 168 | $a7 $050000 000001010000000000000000 DR := {AR} 169 | $a8 $008202 000000001000001000000010 Z := AX - DR 170 | $a9 $000000 000000000000000000000000 ; execute 171 | $aa $080004 000010000000000000000100 [pha] AR := SP 172 | $ab $010040 000000010000000001000000 DR := AX 173 | $ac $028000 000000101000000000000000 {AR} := DR 174 | $ad $000084 000000000000000010000100 AX := SP 175 | $ae $001102 000000000001000100000010 Z := AX + 1 176 | $af $000009 000000000000000000001001 SP := Z 177 | $b0 $008080 000000001000000010000000 AX := DR 178 | $b1 $000000 000000000000000000000000 ; execute 179 | $b2 $000084 000000000000000010000100 [pop] AX := SP 180 | $b3 $001202 000000000001001000000010 Z = AX - 1 181 | $b4 $080009 000010000000000000001001 SP := Z & AR := Z 182 | $b5 $050000 000001010000000000000000 DR := {AR} 183 | $b6 $008080 000000001000000010000000 AX := DR 184 | $b7 $000000 000000000000000000000000 ; execute 185 | $b8 $400000 010000000000000000000000 [jmp #$nn] PC := DR 186 | $b9 $000000 000000000000000000000000 ; execute 187 | $ba $088000 000010001000000000000000 [jmp $nn] AR := DR 188 | $bb $050000 000001010000000000000000 DR := {AR} 189 | $bc $400000 010000000000000000000000 PC := DR 190 | $bd $000000 000000000000000000000000 ; execute 191 | $be $008080 000000001000000010000000 [jsr #$nn] AX := DR ; keep operand 192 | $bf $080004 000010000000000000000100 AR := SP ; save sp 193 | $c0 $210000 001000010000000000000000 DR := PC 194 | $c1 $028000 000000101000000000000000 {AR} := DR 195 | $c2 $010040 000000010000000001000000 DR := AX ; change pc 196 | $c3 $400000 010000000000000000000000 PC := DR 197 | $c4 $000084 000000000000000010000100 AX := SP ; increase sp 198 | $c5 $001102 000000000001000100000010 Z := AX + 1 199 | $c6 $000009 000000000000000000001001 SP := Z 200 | $c7 $000000 000000000000000000000000 ; execute 201 | $c8 $088000 000010001000000000000000 [jsr $nn] AR := DR ; read jump address 202 | $c9 $050000 000001010000000000000000 DR := {AR} 203 | $ca $200080 001000000000000010000000 AX := PC ; store pc 204 | $cb $400000 010000000000000000000000 PC := DR ; jump to address 205 | $cc $010040 000000010000000001000000 DR := AX 206 | $cd $080084 000010000000000010000100 AR := SP & AX := SP 207 | $ce $001102 000000000001000100000010 Z := AX + 1 208 | $cf $000009 000000000000000000001001 SP := Z 209 | $d0 $000000 000000000000000000000000 ; execute 210 | $d1 $000084 000000000000000010000100 [rts] AX := SP 211 | $d2 $001202 000000000001001000000010 Z := AX - 1 212 | $d3 $080009 000010000000000000001001 SP := Z & AR := Z 213 | $d4 $050000 000001010000000000000000 DR := {AR} 214 | $d5 $400000 010000000000000000000000 PC := DR 215 | $d6 $000000 000000000000000000000000 ; execute 216 | $d7 $002000 000000000010000000000000 [cib] ; clear input buffer 217 | $d8 $000000 000000000000000000000000 ; execute 218 | $d9 $008102 000000001000000100000010 [ldb $nn,a] Z := DR + AX 219 | $da $080001 000010000000000000000001 AR := Z 220 | $db $050000 000001010000000000000000 DR := {AR} 221 | $dc $008020 000000001000000000100000 BX := DR 222 | $dd $000000 000000000000000000000000 ; execute 223 | -------------------------------------------------------------------------------- /notes/MICROCODE.md: -------------------------------------------------------------------------------- 1 | # Microcode 2 | 3 | ## Address bus 4 | 5 | Length: 24 bit (3 byte) 6 | 7 | ``` 8 | * 23 OP/I (CU) 9 | * 22 PC/I (PC) 10 | * 21 PC/O (PC) 11 | * 20 +1 (PC) 12 | * 19 AR/I (RAM) 13 | * 18 R (RAM) 14 | * 17 W (RAM) 15 | * 16 DR/I (RAM) 16 | 17 | * 15 DR/O (RAM) 18 | * 14 BM (Branch Mode Flag *) 19 | * 13 I/CLR (Clear I/O buffer *) 20 | * 12 1 (ALU) 21 | * 11 OP3 (ALU) 22 | * 10 OP2 (ALU / CCR when BM set) 23 | * 09 OP1 (ALU / CCR when BM set) 24 | * 08 OP0 (ALU / CCR when BM set) 25 | 26 | * 07 AX/I (AX) 27 | * 06 AX/O (AX) 28 | * 05 BX/I (BX) 29 | * 04 BX/O (BX) 30 | * 03 SP/I (SP) 31 | * 02 SP/O (SP) 32 | * 01 Z/I (Z) 33 | * 00 Z/O (Z) 34 | ``` 35 | 36 | ## Instructions 37 | 38 | ``` 39 | $00 $280000 001010000000000000000000 AR := PC ; fetch addr 40 | $01 $050000 000001010000000000000000 DR := {AR} 41 | $02 $908000 100100001000000000000000 OP := DR & PC := PC+1 42 | $03 $280000 001010000000000000000000 AR := PC ; fetch op 43 | $04 $150000 000101010000000000000000 DR := {AR} & PC := PC+1 44 | $05 $ffffff 111111111111111111111111 ; decode 45 | 46 | $06 $008080 000000001000000010000000 [lda #$nn] AX := DR 47 | $07 $000000 000000000000000000000000 ; execute 48 | 49 | $08 $088000 000010001000000000000000 [lda $nn] AR := DR 50 | $09 $050000 000001010000000000000000 DR := {AR} 51 | $0a $008080 000000001000000010000000 AX := DR 52 | $0b $000000 000000000000000000000000 ; execute 53 | 54 | $0c $088000 000010001000000000000000 [lda ($nn)] AR := DR 55 | $0d $050000 000001010000000000000000 DR := {AR} 56 | $0e $088000 000010001000000000000000 AR := DR 57 | $0f $050000 000001010000000000000000 DR := {AR} 58 | $10 $008080 000000001000000010000000 AX := DR 59 | $11 $000000 000000000000000000000000 ; execute 60 | 61 | $12 $008020 000000001000000000100000 [ldb #$nn] BX := DR 62 | $13 $000000 000000000000000000000000 ; execute 63 | 64 | $14 $088000 000010001000000000000000 [ldb $nn] AR := DR 65 | $15 $050000 000001010000000000000000 DR := {AR} 66 | $16 $008020 000000001000000000100000 BX := DR 67 | $17 $000000 000000000000000000000000 ; execute 68 | 69 | $18 $088000 000010001000000000000000 [ldb ($nn)] AR := DR 70 | $19 $050000 000001010000000000000000 DR := {AR} 71 | $1a $088000 000010001000000000000000 AR := DR 72 | $1b $050000 000001010000000000000000 DR := {AR} 73 | $1c $008020 000000001000000000100000 BX := DR 74 | $1d $000000 000000000000000000000000 ; execute 75 | 76 | $1e $088000 000010001000000000000000 [ldb ($nn),a] AR := DR 77 | $1f $050000 000001010000000000000000 DR := {AR} 78 | $20 $008002 000000001000000000000010 Z := AX + DR 79 | $21 $080001 000010000000000000000001 AR := Z 80 | $22 $050000 000001010000000000000000 DR := {AR} 81 | $23 $008020 000000001000000000100000 BX := DR 82 | $24 $000000 000000000000000000000000 ; execute 83 | 84 | $25 $008002 000000001000000000000010 [ldb ($nn,a)] Z := DR + AX 85 | $26 $080001 000010000000000000000001 AR := Z 86 | $27 $050000 000001010000000000000000 DR := {AR} 87 | $28 $088000 000010001000000000000000 AR := DR 88 | $29 $050000 000001010000000000000000 DR := {AR} 89 | $2a $008020 000000001000000000100000 BX := DR 90 | $2b $000000 000000000000000000000000 ; execute 91 | 92 | $2c $088000 000010001000000000000000 [sta $nn] AR := DR 93 | $2d $010040 000000010000000001000000 DR := AX 94 | $2e $028000 000000101000000000000000 {AR} := DR 95 | $2f $000000 000000000000000000000000 ; execute 96 | 97 | $30 $088000 000010001000000000000000 [sta ($nn)] AR := DR 98 | $31 $050000 000001010000000000000000 DR := {AR} 99 | $32 $088000 000010001000000000000000 AR := DR 100 | $33 $050000 000001010000000000000000 DR := {AR} 101 | $34 $008080 000000001000000010000000 AX := DR 102 | $35 $000000 000000000000000000000000 ; execute 103 | 104 | $36 $008002 000000001000000000000010 [stb $nn,a] Z := DR + AX 105 | $37 $080001 000010000000000000000001 AR := Z 106 | $38 $010010 000000010000000000010000 DR := BX 107 | $39 $028000 000000101000000000000000 {AR} := DR 108 | $3a $000000 000000000000000000000000 ; execute 109 | 110 | $3b $088000 000010001000000000000000 [stb $nn] AR := DR 111 | $3c $010010 000000010000000000010000 DR := BX 112 | $3d $028000 000000101000000000000000 {AR} := DR 113 | $3e $000000 000000000000000000000000 ; execute 114 | 115 | $3f $088000 000010001000000000000000 [stb ($nn)] AR := DR 116 | $40 $050000 000001010000000000000000 DR := {AR} 117 | $41 $088000 000010001000000000000000 AR := DR 118 | $42 $050000 000001010000000000000000 DR := {AR} 119 | $43 $008020 000000001000000000100000 BX := DR 120 | $44 $000000 000000000000000000000000 ; execute 121 | 122 | $45 $088000 000010001000000000000000 [stb ($nn),a] AR := DR 123 | $46 $050000 000001010000000000000000 DR := {AR} 124 | $47 $008002 000000001000000000000010 Z := AX + DR 125 | $48 $080001 000010000000000000000001 AR := Z 126 | $49 $010010 000000010000000000010000 DR := BX 127 | $4a $028000 000000101000000000000000 {AR} := DR 128 | $4b $000000 000000000000000000000000 ; execute 129 | 130 | $4c $008002 000000001000000000000010 [stb ($nn,a)] Z := DR + AX 131 | $4d $080001 000010000000000000000001 AR := Z 132 | $4e $050000 000001010000000000000000 DR := {AR} 133 | $4f $088000 000010001000000000000000 AR := DR 134 | $50 $010010 000000010000000000010000 DR := BX 135 | $51 $028000 000000101000000000000000 {AR} := DR 136 | $52 $000000 000000000000000000000000 ; execute 137 | 138 | $53 $000060 000000000000000001100000 [tab] BX := AX 139 | $54 $000000 000000000000000000000000 ; execute 140 | 141 | $55 $000090 000000000000000010010000 [tba] AX := BX 142 | $56 $000000 000000000000000000000000 ; execute 143 | 144 | $57 $008002 000000001000000000000010 [adc #$nn] Z := AX + DR 145 | $58 $000081 000000000000000010000001 AX := Z 146 | $59 $000000 000000000000000000000000 ; execute 147 | 148 | $5a $088000 000010001000000000000000 [adc $nn] AR := DR 149 | $5b $050000 000001010000000000000000 DR := {AR} 150 | $5c $008002 000000001000000000000010 Z := AX + DR 151 | $5d $000081 000000000000000010000001 AX := Z 152 | $5e $000000 000000000000000000000000 ; execute 153 | 154 | $5f $008102 000000001000000100000010 [sbc #$nn] Z := AX - DR 155 | $60 $000081 000000000000000010000001 AX := Z 156 | $61 $000000 000000000000000000000000 ; execute 157 | 158 | $62 $088000 000010001000000000000000 [sbc $nn] AR := DR 159 | $63 $050000 000001010000000000000000 DR := {AR} 160 | $64 $008102 000000001000000100000010 Z := AX - DR 161 | $65 $000081 000000000000000010000001 AX := Z 162 | $66 $000000 000000000000000000000000 ; execute 163 | 164 | $67 $001002 000000000001000000000010 [inc] Z := AX + 1 165 | $68 $000081 000000000000000010000001 AX := Z 166 | $69 $000000 000000000000000000000000 ; execute 167 | 168 | $6a $001102 000000000001000100000010 [dec] Z := AX - 1 169 | $6b $000081 000000000000000010000001 AX := Z 170 | $6c $000000 000000000000000000000000 ; execute 171 | 172 | $6d $008202 000000001000001000000010 [and #$nn] Z = AX AND DR 173 | $6e $000081 000000000000000010000001 AX := Z 174 | $6f $000000 000000000000000000000000 ; execute 175 | 176 | $70 $088000 000010001000000000000000 [and $nn] AR := DR 177 | $71 $050000 000001010000000000000000 DR := {AR} 178 | $72 $008202 000000001000001000000010 Z := AX AND DR 179 | $73 $000081 000000000000000010000001 AX := Z 180 | $74 $000000 000000000000000000000000 ; execute 181 | 182 | $75 $008302 000000001000001100000010 [ora #$nn] Z = AX OR DR 183 | $76 $000081 000000000000000010000001 AX := Z 184 | $77 $000000 000000000000000000000000 ; execute 185 | 186 | $78 $088000 000010001000000000000000 [ora $nn] AR := DR 187 | $79 $050000 000001010000000000000000 DR := {AR} 188 | $7a $008302 000000001000001100000010 Z := AX OR DR 189 | $7b $000081 000000000000000010000001 AX := Z 190 | $7c $000000 000000000000000000000000 ; execute 191 | 192 | $7d $008402 000000001000010000000010 [eor #$nn] Z = AX XOR DR 193 | $7e $000081 000000000000000010000001 AX := Z 194 | $7f $000000 000000000000000000000000 ; execute 195 | 196 | $80 $088000 000010001000000000000000 [eor $nn] AR := DR 197 | $81 $050000 000001010000000000000000 DR := {AR} 198 | $82 $008402 000000001000010000000010 Z := AX XOR DR 199 | $83 $000081 000000000000000010000001 AX := Z 200 | $84 $000000 000000000000000000000000 ; execute 201 | 202 | $85 $000502 000000000000010100000010 [lsl] Z = AX LSL 203 | $86 $000081 000000000000000010000001 AX := Z 204 | $87 $000000 000000000000000000000000 ; execute 205 | 206 | $88 $000602 000000000000011000000010 [lsr] Z = AX LSR 207 | $89 $000081 000000000000000010000001 AX := Z 208 | $8a $000000 000000000000000000000000 ; execute 209 | 210 | $8b $000702 000000000000011100000010 [asl] Z = AX ASL 211 | $8c $000081 000000000000000010000001 AX := Z 212 | $8d $000000 000000000000000000000000 ; execute 213 | 214 | $8e $000802 000000000000100000000010 [rol] Z = AX ROL 215 | $8f $000081 000000000000000010000001 AX := Z 216 | $90 $000000 000000000000000000000000 ; execute 217 | 218 | $91 $000902 000000000000100100000010 [ror] Z = AX ROR 219 | $92 $000081 000000000000000010000001 AX := Z 220 | $93 $000000 000000000000000000000000 ; execute 221 | 222 | $94 $004000 000000000100000000000000 [bpl] 223 | $95 $000000 000000000000000000000000 ; execute 224 | 225 | $96 $004100 000000000100000100000000 [bmi] 226 | $97 $000000 000000000000000000000000 ; execute 227 | 228 | $98 $004200 000000000100001000000000 [bcc] 229 | $99 $000000 000000000000000000000000 ; execute 230 | 231 | $9a $004300 000000000100001100000000 [bcs] 232 | $9b $000000 000000000000000000000000 ; execute 233 | 234 | $9c $004400 000000000100010000000000 [bne] 235 | $9d $000000 000000000000000000000000 ; execute 236 | 237 | $9e $004500 000000000100010100000000 [beq] 238 | $9f $000000 000000000000000000000000 ; execute 239 | 240 | $a0 $004600 000000000100011000000000 [sec] 241 | $a1 $000000 000000000000000000000000 ; execute 242 | 243 | $a2 $004700 000000000100011100000000 [clc] 244 | $a3 $000000 000000000000000000000000 ; execute 245 | 246 | $a4 $008102 000000001000000100000010 [cmp #$nn] Z := AX - DR 247 | $a5 $000000 000000000000000000000000 ; execute 248 | 249 | $a6 $088000 000010001000000000000000 [cmp $nn] AR := DR 250 | $a7 $050000 000001010000000000000000 DR := {AR} 251 | $a8 $008102 000000001000000100000010 Z := AX - DR 252 | $a9 $000000 000000000000000000000000 ; execute 253 | 254 | $aa $080004 000010000000000000000100 [pha] AR := SP 255 | $ab $010040 000000010000000001000000 DR := AX 256 | $ac $028000 000000101000000000000000 {AR} := DR 257 | $ad $000084 000000000000000010000100 AX := SP 258 | $ae $001002 000000000001000000000010 Z := AX + 1 259 | $af $000009 000000000000000000001001 SP := Z 260 | $b0 $008080 000000001000000010000000 AX := DR 261 | $b1 $000000 000000000000000000000000 ; execute 262 | 263 | $b2 $000084 000000000000000010000100 [pop] AX := SP 264 | $b3 $001102 000000000001000100000010 Z = AX - 1 265 | $b4 $080009 000010000000000000001001 SP := Z & AR := Z 266 | $b5 $050000 000001010000000000000000 DR := {AR} 267 | $b6 $008080 000000001000000010000000 AX := DR 268 | $b7 $000000 000000000000000000000000 ; execute 269 | 270 | $b8 $400000 010000000000000000000000 [jmp #$nn] PC := DR 271 | $b9 $000000 000000000000000000000000 ; execute 272 | 273 | $ba $088000 000010001000000000000000 [jmp $nn] AR := DR 274 | $bb $050000 000001010000000000000000 DR := {AR} 275 | $bc $400000 010000000000000000000000 PC := DR 276 | $bd $000000 000000000000000000000000 ; execute 277 | 278 | $be $008080 000000001000000010000000 [jsr #$nn] AX := DR ; keep operand 279 | $bf $080004 000010000000000000000100 AR := SP ; save sp 280 | $c0 $210000 001000010000000000000000 DR := PC 281 | $c1 $028000 000000101000000000000000 {AR} := DR 282 | $c2 $010040 000000010000000001000000 DR := AX ; change pc 283 | $c3 $400000 010000000000000000000000 PC := DR 284 | $c4 $000084 000000000000000010000100 AX := SP ; increase sp 285 | $c5 $001002 000000000001000000000010 Z := AX + 1 286 | $c6 $000009 000000000000000000001001 SP := Z 287 | $c7 $000000 000000000000000000000000 ; execute 288 | 289 | $c8 $088000 000010001000000000000000 [jsr $nn] AR := DR ; read jump address 290 | $c9 $050000 000001010000000000000000 DR := {AR} 291 | $ca $200080 001000000000000010000000 AX := PC ; store pc 292 | $cb $400000 010000000000000000000000 PC := DR ; jump to address 293 | $cc $010040 000000010000000001000000 DR := AX 294 | $cd $080084 000010000000000010000100 AR := SP & AX := SP 295 | $ce $001002 000000000001000000000010 Z := AX + 1 296 | $cf $000009 000000000000000000001001 SP := Z 297 | $d0 $000000 000000000000000000000000 ; execute 298 | 299 | $d1 $000084 000000000000000010000100 [rts] AX := SP 300 | $d2 $001102 000000000001000100000010 Z := AX - 1 301 | $d3 $080009 000010000000000000001001 SP := Z & AR := Z 302 | $d4 $050000 000001010000000000000000 DR := {AR} 303 | $d5 $400000 010000000000000000000000 PC := DR 304 | $d6 $000000 000000000000000000000000 ; execute 305 | 306 | $d7 $002000 000000000010000000000000 [cib] ; clear input buffer 307 | $d8 $000000 000000000000000000000000 ; execute 308 | 309 | $d9 $008002 000000001000000000000010 [ldb $nn,a] Z := DR + AX 310 | $da $080001 000010000000000000000001 AR := Z 311 | $db $050000 000001010000000000000000 DR := {AR} 312 | $dc $008020 000000001000000000100000 BX := DR 313 | $dd $000000 000000000000000000000000 ; execute 314 | ``` 315 | -------------------------------------------------------------------------------- /circuit/v1/REGISTER.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 |
    7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | addr/data: 8 8 49 | 0 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | -------------------------------------------------------------------------------- /circuit/v1/LED8x8.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | addr/data: 8 8 49 | 0 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
    63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | -------------------------------------------------------------------------------- /circuit/v1/ALU.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | addr/data: 8 8 46 | 0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | -------------------------------------------------------------------------------- /circuit/v1/CPU_ALU.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | addr/data: 8 8 46 | 0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 |
    60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | -------------------------------------------------------------------------------- /tools/assembler/assembler.c: -------------------------------------------------------------------------------- 1 | /* 2 | * assembler.c 3 | * ------ 4 | * Reads a 8bit cpu assembler file and writes a compiled executable 5 | * for our architecture. 6 | * 7 | * Compile project via: clang assembler.c -o assembler 8 | * 9 | * Usage: ./assembler program.asm program.out 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #define VERSION "0.2" 19 | 20 | #define PROGRAM_MEMORY_SIZE 256 21 | 22 | #define MAX_JUMP_COUNT 64 23 | #define MAX_LABEL_COUNT 32 24 | #define MAX_LABEL_LENGTH 32 25 | #define MAX_LINE_LENGTH 128 26 | #define OPCODE_COUNT 33 27 | 28 | 29 | /* 30 | * Struct: label 31 | * ------ 32 | * Placeholder for occurring label and jump declaration, mapping 33 | * the address in the program memory to the label name. 34 | */ 35 | 36 | struct label 37 | { 38 | int memory_addr; 39 | char label[MAX_LABEL_LENGTH]; 40 | }; 41 | 42 | 43 | /* 44 | * Struct: opcode 45 | * ------ 46 | * Holds data about opcode mnemonic and its microcode addresses 47 | * for the regarding addressing modes. 48 | */ 49 | 50 | typedef struct 51 | { 52 | char mnemonic[3]; // Mnemonic of opcode 53 | 54 | int a; // Implicit / single-byte instruction (no operand) 55 | 56 | int a_abs; // Absolute $nn 57 | int a_imm; // Immediate #$nn 58 | int a_idx; // Indexed $nn,a 59 | int a_idx_ind; // Indexed Indirect ($nn,a) 60 | int a_ind; // Indirect ($nn) 61 | int a_ind_idx; // Indirect Indexed ($nn),a 62 | 63 | int a_label; // Labelled (internal) 64 | } opcode; 65 | 66 | 67 | /* 68 | * Table: OPCODES[] 69 | * ------ 70 | * Lists all given opcodes of our architecture defining 71 | * their microcode addresses in the control unit (CU). 72 | */ 73 | 74 | static const opcode OPCODES[] = 75 | { 76 | { "adc", 0x00, 0x5a, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00 }, 77 | { "and", 0x00, 0x70, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00 }, 78 | { "asl", 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 79 | { "bcc", 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x98 }, 80 | { "bcs", 0x00, 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x9a }, 81 | { "beq", 0x00, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, 0x9e }, 82 | { "bmi", 0x00, 0x00, 0x96, 0x00, 0x00, 0x00, 0x00, 0x96 }, 83 | { "bne", 0x00, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x9c }, 84 | { "bpl", 0x00, 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x94 }, 85 | { "cib", 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 86 | { "clc", 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 87 | { "cmp", 0x00, 0xa6, 0xa4, 0x00, 0x00, 0x00, 0x00, 0x00 }, 88 | { "dec", 0x6a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 89 | { "eor", 0x00, 0x80, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00 }, 90 | { "inc", 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 91 | { "jmp", 0x00, 0xba, 0xb8, 0x00, 0x00, 0x00, 0x00, 0xb8 }, 92 | { "jsr", 0x00, 0xc8, 0xbe, 0x00, 0x00, 0x00, 0x00, 0xbe }, 93 | { "lda", 0x00, 0x08, 0x06, 0x00, 0x00, 0x0c, 0x00, 0x00 }, 94 | { "ldb", 0x00, 0x14, 0x12, 0xd9, 0x25, 0x18, 0x1e, 0x00 }, 95 | { "lsl", 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 96 | { "lsr", 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 97 | { "ora", 0x00, 0x78, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00 }, 98 | { "pha", 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 99 | { "pop", 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 100 | { "rol", 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 101 | { "ror", 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 102 | { "rts", 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 103 | { "sbc", 0x00, 0x62, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00 }, 104 | { "sec", 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 105 | { "sta", 0x00, 0x2c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00 }, 106 | { "stb", 0x00, 0x3b, 0x00, 0x36, 0x4c, 0x3f, 0x45, 0x00 }, 107 | { "tab", 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, 108 | { "tba", 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } 109 | }; 110 | 111 | 112 | /* 113 | * Function: print_syntax_error 114 | * ------ 115 | * Prints a formatted error message for the user. 116 | * 117 | * message: Error message string 118 | * token: Related artefact 119 | * line_index: Line number in code (-1 when not given) 120 | */ 121 | 122 | void print_syntax_error (char *message, char *token, int line_index) 123 | { 124 | if (line_index > -1) 125 | { 126 | printf( 127 | "Found syntax error in '%s' @ line %i (%s)!\n", 128 | token, 129 | line_index, 130 | message 131 | ); 132 | } 133 | else 134 | { 135 | printf( 136 | "Found syntax error in '%s' (%s)!\n", 137 | token, 138 | message 139 | ); 140 | } 141 | } 142 | 143 | 144 | /* 145 | * Function: remove_comments 146 | * ------ 147 | * Removes all assembler-style comments (;) from a string 148 | * 149 | * str: The processed string 150 | */ 151 | 152 | void remove_comments (char *str) 153 | { 154 | int i; 155 | 156 | for (i = 0; str[i] != 00; i++) 157 | { 158 | if (str[i] == ';') 159 | { 160 | str[i] = 00; 161 | break; 162 | } 163 | } 164 | } 165 | 166 | 167 | /* 168 | * Function: is_hex_str 169 | * ------ 170 | * Checks if string holds only symbols describing a hexadecimal number 171 | * 172 | * str: The processed string 173 | * 174 | * returns: 1 if string represents a hexadecimal number, otherwise 0 175 | */ 176 | 177 | bool is_hex_str (char *str) 178 | { 179 | int i; 180 | bool result = 1; 181 | 182 | for (i = 0; str[i] != 00; i++) 183 | { 184 | if (!isxdigit(str[i])) 185 | { 186 | result = 0; 187 | break; 188 | } 189 | } 190 | 191 | return result; 192 | } 193 | 194 | 195 | /* 196 | * Function: is_abs, is_idx, is_imm, is_idx_ind, is_ind, is_ind_idx 197 | * ------ 198 | * Checks if address string uses an specific addressing mode 199 | * 200 | * token: The string to check against 201 | * 202 | * returns: 1 if string uses the adressing mode, otherwise 0 203 | */ 204 | 205 | bool is_abs (char *token) 206 | { 207 | if ( 208 | token[0] == '$' && 209 | token[strlen(token) - 2] != ',' 210 | ) 211 | { 212 | return 1; 213 | } 214 | 215 | return 0; 216 | } 217 | 218 | 219 | bool is_idx (char *token) 220 | { 221 | if ( 222 | token[0] == '$' && 223 | token[strlen(token) - 2] == ',' && 224 | token[strlen(token) - 1] == 'a' 225 | ) 226 | { 227 | return 1; 228 | } 229 | 230 | return 0; 231 | } 232 | 233 | 234 | bool is_imm (char *token) 235 | { 236 | if (token[0] == '#') 237 | { 238 | return 1; 239 | } 240 | 241 | return 0; 242 | } 243 | 244 | 245 | bool is_idx_ind (char *token) 246 | { 247 | if ( 248 | token[0] == '(' && 249 | token[1] == '$' && 250 | token[strlen(token) - 3] == ',' && 251 | token[strlen(token) - 2] == 'a' && 252 | token[strlen(token) - 1] == ')' 253 | ) 254 | { 255 | return 1; 256 | } 257 | 258 | return 0; 259 | } 260 | 261 | 262 | bool is_ind (char *token) 263 | { 264 | if ( 265 | token[0] == '(' && 266 | token[1] == '$' && 267 | token[strlen(token) - 3] != ',' && 268 | token[strlen(token) - 2] != 'a' && 269 | token[strlen(token) - 1] == ')' 270 | ) 271 | { 272 | return 1; 273 | } 274 | 275 | return 0; 276 | } 277 | 278 | 279 | bool is_ind_idx (char *token) 280 | { 281 | if ( 282 | token[0] == '(' && 283 | token[1] == '$' && 284 | token[strlen(token) - 3] != ')' && 285 | token[strlen(token) - 2] != ',' && 286 | token[strlen(token) - 1] == 'a' 287 | ) 288 | { 289 | return 1; 290 | } 291 | 292 | return 0; 293 | } 294 | 295 | 296 | /* 297 | * Function: is_valid_address 298 | * ------ 299 | * Checks if token is a correct address mode 300 | * 301 | * opcode_index: Used opcode 302 | * str: The processed string 303 | * 304 | * returns: 1 if string is a valid address, otherwise 0 305 | */ 306 | 307 | bool is_valid_address (int opcode_index, char *str) 308 | { 309 | if ( 310 | (OPCODES[opcode_index].a_abs && is_abs(str)) || 311 | (OPCODES[opcode_index].a_ind && is_ind(str)) || 312 | (OPCODES[opcode_index].a_imm && is_imm(str)) || 313 | (OPCODES[opcode_index].a_ind_idx && is_ind_idx(str)) || 314 | (OPCODES[opcode_index].a_idx_ind && is_idx_ind(str)) || 315 | (OPCODES[opcode_index].a_idx && is_idx(str)) 316 | ) 317 | { 318 | return 1; 319 | } 320 | 321 | return 0; 322 | } 323 | 324 | /* 325 | * Function: find_opcode_index 326 | * ------ 327 | * Returns the index of the opcode lookup table 328 | * 329 | * mnemonic: The mnemonic of the opcode 330 | * 331 | * returns: index of opcode in lookup table 332 | */ 333 | 334 | int find_opcode_index (char *mnemonic) 335 | { 336 | int i; 337 | int found_index = -1; 338 | 339 | for (i = 0; i < OPCODE_COUNT; i++) 340 | { 341 | if (strncmp(OPCODES[i].mnemonic, mnemonic, 3) == 0) 342 | { 343 | found_index = i; 344 | break; 345 | } 346 | } 347 | 348 | return found_index; 349 | } 350 | 351 | 352 | /* 353 | * Function: handle_opcode 354 | * ------ 355 | * Adds the single opcode (1byte) microcode instruction to the program. 356 | * 357 | * program: The program 358 | * index: Index of the current line in program 359 | * op: Index of the opcode in lookup-table 360 | */ 361 | 362 | void handle_opcode (int *program, int index, int op) 363 | { 364 | program[index] = OPCODES[op].a; 365 | program[index + 1] = 0x00; 366 | } 367 | 368 | 369 | /* 370 | * Function: handle_opcode_and_operand 371 | * ------ 372 | * Adds the opcode + operand (2byte) microcode instruction to the program. 373 | * 374 | * program: The program 375 | * index: Index of the current line in program 376 | * op: Index of the opcode in lookup-table 377 | * addr: Operand / address 378 | */ 379 | 380 | void handle_opcode_and_operand (int *program, int index, int op, char *addr) 381 | { 382 | char* stripped_addr; 383 | 384 | if (is_imm(addr)) 385 | { 386 | // Immediate adressing mode 387 | program[index] = OPCODES[op].a_imm; 388 | stripped_addr = addr + 2; 389 | } 390 | else if (is_idx(addr)) 391 | { 392 | // Indexed adressing mode 393 | program[index] = OPCODES[op].a_idx; 394 | stripped_addr = addr + 1; 395 | stripped_addr[strlen(stripped_addr) - 2] = 0; 396 | } 397 | else if (is_abs(addr)) 398 | { 399 | // Absolute adressing mode 400 | program[index] = OPCODES[op].a_abs; 401 | stripped_addr = addr + 1; 402 | } 403 | else if (is_ind(addr)) 404 | { 405 | // Indirect adressing mode 406 | program[index] = OPCODES[op].a_ind; 407 | stripped_addr = addr + 2; 408 | stripped_addr[strlen(stripped_addr) - 1] = 0; 409 | } 410 | else if (is_ind_idx(addr)) 411 | { 412 | // Indirect indexed adressing mode 413 | program[index] = OPCODES[op].a_ind_idx; 414 | stripped_addr = addr + 2; 415 | stripped_addr[strlen(stripped_addr) - 3] = 0; 416 | } 417 | else if (is_idx_ind(addr)) 418 | { 419 | // Indexed indirect adressing mode 420 | program[index] = OPCODES[op].a_idx_ind; 421 | stripped_addr = addr + 2; 422 | stripped_addr[strlen(stripped_addr) - 3] = 0; 423 | } 424 | 425 | if (!is_hex_str(stripped_addr)) 426 | { 427 | print_syntax_error("Invalid address format", addr, 0); 428 | exit(EXIT_FAILURE); 429 | } 430 | 431 | int hex_int = (int) strtol(stripped_addr, NULL, 16); 432 | 433 | if (hex_int < 0 || hex_int > PROGRAM_MEMORY_SIZE - 1) 434 | { 435 | print_syntax_error("Invalid address range", addr, 0); 436 | exit(EXIT_FAILURE); 437 | } 438 | 439 | program[index + 1] = hex_int; 440 | } 441 | 442 | 443 | /* 444 | * Function: print_and_save_program 445 | * ------ 446 | * Writes the compiled program to a file and 447 | * prints the result to the screen. 448 | * 449 | * file: Write file 450 | * program: The compiled program 451 | * size: Length of the program (in bytes) 452 | */ 453 | 454 | void print_and_save_program (FILE *file, int *program, int size) 455 | { 456 | int i; 457 | 458 | // Header for Logisim 459 | fprintf(file, "v2.0 raw\n"); 460 | 461 | for (i = 0; i < size; i++) 462 | { 463 | fprintf(file, "%02x", program[i]); 464 | printf("%02x", program[i]); 465 | 466 | // Pretty print for screen 467 | if (i % 16 == 15) 468 | { 469 | fprintf(file, "\n"); 470 | printf("\n"); 471 | } 472 | else 473 | { 474 | fprintf(file, " "); 475 | printf(" "); 476 | } 477 | } 478 | } 479 | 480 | 481 | /* 482 | * Function: main 483 | * ------ 484 | * Reads a 8bit cpu assembler file and writes a compiled executable 485 | * for our architecture. 486 | * 487 | * Usage: ./assembler program.asm program.out 488 | */ 489 | 490 | int main (int argc, char **argv) 491 | { 492 | printf("===============================================\n"); 493 | printf(" 8bit cpu assembler v%s\n", VERSION); 494 | printf("===============================================\n"); 495 | 496 | // Get input file 497 | char *file_path = argv[1]; 498 | FILE *file; 499 | 500 | file = fopen(file_path, "r"); 501 | 502 | if (file == 0) 503 | { 504 | printf("Error: Please specify a valid file path.\n"); 505 | exit(EXIT_FAILURE); 506 | } 507 | 508 | // Check output file 509 | char *write_file_path = argv[2]; 510 | 511 | if (!write_file_path) 512 | { 513 | printf("Error: Please specify a valid out file path.\n"); 514 | exit(EXIT_FAILURE); 515 | } 516 | 517 | // Variables for stream reading 518 | char line[MAX_LINE_LENGTH]; 519 | char *token = NULL; 520 | 521 | // Variables for parsing and error output 522 | int opcode_index = -1; 523 | int current_line_index = 1; 524 | 525 | // The compiled program variables 526 | int program[PROGRAM_MEMORY_SIZE]; 527 | int program_adr = 0; 528 | 529 | // Lookup table for labels 530 | struct label label_table[MAX_LABEL_COUNT]; 531 | int label_table_count = 0; 532 | 533 | // Lookup table for labelled jump instructions 534 | struct label jump_table[MAX_JUMP_COUNT]; 535 | int jump_table_count = 0; 536 | 537 | // Read file line by line 538 | while (fgets(line, sizeof line, file) != NULL) 539 | { 540 | remove_comments(line); 541 | token = strtok(line, "\n\t\r "); 542 | 543 | while (token) 544 | { 545 | // Expects operand (address or label) of two-byte instruction 546 | if (opcode_index > -1) 547 | { 548 | if (is_valid_address(opcode_index, token)) 549 | { 550 | // Found an address 551 | handle_opcode_and_operand( 552 | program, 553 | program_adr, 554 | opcode_index, 555 | token 556 | ); 557 | } 558 | else if (OPCODES[opcode_index].a_label) 559 | { 560 | // Found a label 561 | if (jump_table_count > MAX_JUMP_COUNT) 562 | { 563 | print_syntax_error( 564 | "Exceeded jump count", 565 | token, 566 | current_line_index 567 | ); 568 | 569 | exit(EXIT_FAILURE); 570 | } 571 | else if (strlen(token) > MAX_LABEL_LENGTH) 572 | { 573 | print_syntax_error( 574 | "Label name is too long", 575 | token, 576 | current_line_index 577 | ); 578 | 579 | exit(EXIT_FAILURE); 580 | } 581 | 582 | // Write instruction to program with placeholder 583 | program[program_adr] = OPCODES[opcode_index].a_label; 584 | program[program_adr + 1] = 0x00; 585 | 586 | // Store position for final processing 587 | jump_table[jump_table_count].memory_addr = program_adr + 1; 588 | strcpy(jump_table[jump_table_count].label, token); 589 | jump_table_count += 1; 590 | } 591 | else 592 | { 593 | print_syntax_error( 594 | "Invalid or missing operand", 595 | token, 596 | current_line_index 597 | ); 598 | 599 | exit(EXIT_FAILURE); 600 | } 601 | 602 | opcode_index = -1; 603 | program_adr += 2; 604 | } 605 | else 606 | { 607 | // Handle label or opcode 608 | int op = find_opcode_index(token); 609 | 610 | // Is token an opcode? 611 | if (op > -1) 612 | { 613 | // Will an operand be expected in next token? 614 | if (!OPCODES[op].a) 615 | { 616 | // Prepare two-byte instruction 617 | opcode_index = op; 618 | } 619 | else 620 | { 621 | // Handle single byte instruction 622 | handle_opcode( 623 | program, 624 | program_adr, 625 | op 626 | ); 627 | 628 | program_adr += 2; 629 | } 630 | } 631 | else if (token[(strlen(token) - 1)] == ':') 632 | { 633 | // Token is a label, strip the last character (:) 634 | token[strlen(token) - 1] = 0; 635 | 636 | if (label_table_count > MAX_LABEL_COUNT) 637 | { 638 | print_syntax_error( 639 | "Exceeded label count", 640 | token, 641 | current_line_index 642 | ); 643 | 644 | exit(EXIT_FAILURE); 645 | } 646 | else if (strlen(token) > MAX_LABEL_LENGTH) 647 | { 648 | print_syntax_error( 649 | "Label name is too long", 650 | token, 651 | current_line_index 652 | ); 653 | 654 | exit(EXIT_FAILURE); 655 | } 656 | 657 | // Store it in table for later processing 658 | label_table[label_table_count].memory_addr = program_adr; 659 | strcpy(label_table[label_table_count].label, token); 660 | 661 | label_table_count += 1; 662 | } 663 | else 664 | { 665 | print_syntax_error( 666 | "Unkown opcode", 667 | token, 668 | current_line_index 669 | ); 670 | 671 | exit(EXIT_FAILURE); 672 | } 673 | } 674 | 675 | if (program_adr > PROGRAM_MEMORY_SIZE) 676 | { 677 | print_syntax_error( 678 | "Program exceeds memory size", 679 | token, 680 | current_line_index 681 | ); 682 | 683 | exit(EXIT_FAILURE); 684 | } 685 | 686 | token = strtok(NULL, "\n\t\r "); 687 | } 688 | 689 | current_line_index += 1; 690 | } 691 | 692 | fclose(file); 693 | 694 | // Finally replace labels with memory addresses 695 | int i, n; 696 | bool found_label; 697 | 698 | for (i = 0; i < jump_table_count; i++) 699 | { 700 | found_label = 0; 701 | 702 | for (n = 0; n < label_table_count; n++) 703 | { 704 | if (strcmp(jump_table[i].label, label_table[n].label) == 0) 705 | { 706 | // Replace label with actual memory location in program 707 | program[jump_table[i].memory_addr] = label_table[n].memory_addr; 708 | found_label = 1; 709 | break; 710 | } 711 | } 712 | 713 | if (!found_label) 714 | { 715 | print_syntax_error("Could not find label", jump_table[i].label, -1); 716 | exit(EXIT_FAILURE); 717 | } 718 | } 719 | 720 | // Save binary to file and print result 721 | printf( 722 | "Successfully compiled program (%i bytes):\n\n", 723 | program_adr 724 | ); 725 | 726 | FILE * write_file = fopen(write_file_path, "w+"); 727 | print_and_save_program(write_file, program, program_adr); 728 | fclose(write_file); 729 | 730 | printf("\n\nWrite output to '%s'.\n", write_file_path); 731 | 732 | return 0; 733 | } 734 | -------------------------------------------------------------------------------- /circuit/v1/CPU_Test_001.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | addr/data: 8 8 46 | 0 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
    61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | addr/data: 8 32 318 | 1000000 2004003 6 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | -------------------------------------------------------------------------------- /circuit/v1/CPU_Test_002.circ: -------------------------------------------------------------------------------- 1 | 2 | 3 | This file is intended to be loaded by Logisim (http://www.cburch.com/logisim/). 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | addr/data: 8 8 49 | 0 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 |
    65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | addr/data: 8 8 481 | 10 22 0 80 0 10 22 0 482 | 0 0 80 0 80 0 80 0 483 | 80 0 80 10 20 0 80 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | 540 | 541 | 542 | 543 | 544 | 545 | 546 | 547 | 548 | 549 | 550 | 551 | 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | 565 | 566 | 567 | 568 | 569 | 570 | 571 | 572 | 573 | 574 | 575 | 576 | 577 | 578 | 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | 683 | 684 | 685 | 686 | 687 | 688 | 689 | 690 | 691 | 692 | 693 | 694 | 695 | 696 | 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | 711 | 712 | 713 | 714 | 715 | 716 | 717 | 718 | 719 | 720 | 721 | 722 | 723 | 724 | 725 | 726 | 727 | 728 | 729 | addr/data: 8 8 730 | 80 0 0 0 c0 80 0 0 731 | c0 0 1 0 4 0 12 0 732 | 4 c0 10 8 20 0 1 733 | 734 | 735 | 736 | 737 | 738 | 739 | 740 | 741 | 742 | 743 | 744 | 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 | 770 | 771 | 772 | 773 | addr/data: 8 8 774 | 0 0 2 40 30 0 0 2 775 | 30 80 0 80 0 80 10 80 776 | 0 30 0 0 0 2 0 80 777 | 778 | 779 | 780 | 781 | 782 | 783 | 784 | 785 | 786 | 787 | 788 | 789 | 790 | 791 | 792 | 793 | 794 | 795 | 796 | 797 | 798 | 799 | 800 | --------------------------------------------------------------------------------