├── 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 |
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 |
--------------------------------------------------------------------------------