neauoire authored on 30/01/2021 22:25:48
Showing 5 changed files
... ...
@@ -1,11 +1,11 @@
1 1
 AlignAfterOpenBracket: DontAlign
2 2
 AlignEscapedNewlines: DontAlign
3 3
 AlignOperands: DontAlign
4
-AllowShortBlocksOnASingleLine: Empty
4
+AllowShortBlocksOnASingleLine: Always
5 5
 AllowShortCaseLabelsOnASingleLine: true
6 6
 AllowShortEnumsOnASingleLine: true
7
-AllowShortIfStatementsOnASingleLine: false
8
-AllowShortLoopsOnASingleLine: false
7
+AllowShortIfStatementsOnASingleLine: true
8
+AllowShortLoopsOnASingleLine: true
9 9
 AlwaysBreakAfterDefinitionReturnType: TopLevel
10 10
 BinPackArguments: false
11 11
 BinPackParameters: false
... ...
@@ -11,26 +11,23 @@ cc uxn.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -o uxn
11 11
 ## Assembly Syntax
12 12
 
13 13
 ```
14
-: 	starting a definition
15
-& 	obtaining pointers
16
-( 	stack comments
17
-` 	inlining bytecodes
18
-' 	strings
19
-# 	numbers
20
-$ 	characters
21
-~   vector
22
-[ 12 34 ] real values
23
-< 12 34 > relative values
24
-( 12 34 ) deadzone
25
-```
14
+< comment >
26 15
 
27
-```
28
-;add-two JSR
16
++01 < literal >
17
+
18
+[ 01 02 03 04 ] < block of literals >
19
+
20
+$01 < pointer8 >
21
+
22
+{ 01 02 03 04 } < block of pointer8 >
29 23
 
30
-BRK
24
+~ff0f < pointer16 >
31 25
 
32
-:add-two
33
-	[ 2 ] ADD RTS
26
+( ff00 ff01 ff02 ff03 ) < block of pointer16 >
27
+
28
+=const +ff
29
+
30
+:label ADD RTS
34 31
 ```
35 32
 
36 33
 ## Design
... ...
@@ -57,3 +54,12 @@ BRK
57 54
 ### Emulator
58 55
 
59 56
 - SDL Layer
57
+
58
+
59
+## Refs
60
+
61
+https://code.9front.org/hg/plan9front/file/a7f9946e238f/sys/src/games/nes/cpu.c
62
+http://www.w3group.de/stable_glossar.html
63
+http://www.emulator101.com/6502-addressing-modes.html
64
+http://forth.works/8f0c04f616b6c34496eb2141785b4454
65
+https://justinmeiners.github.io/lc3-vm/
60 66
\ No newline at end of file
... ...
@@ -1 +1,5 @@
1
-{ 25 26 27 28 } SWP POP DUP BRK
2 1
\ No newline at end of file
2
+< comment >
3
+
4
+[3 1 2 3 ] pop dup swp ovr rot 
5
+
6
+brk
... ...
@@ -29,19 +29,23 @@ typedef struct {
29 29
 	Uint8 address[STACK_DEPTH];
30 30
 } Computer;
31 31
 
32
+Computer cpu;
33
+
34
+#pragma mark - Helpers
35
+
32 36
 void
33
-setflag(Computer *cpu, char flag, int b)
37
+setflag(char flag, int b)
34 38
 {
35 39
 	if(b)
36
-		cpu->status |= flag;
40
+		cpu.status |= flag;
37 41
 	else
38
-		cpu->status &= (~flag);
42
+		cpu.status &= (~flag);
39 43
 }
40 44
 
41 45
 int
42
-getflag(Computer *cpu, char flag)
46
+getflag(char flag)
43 47
 {
44
-	return cpu->status & flag;
48
+	return cpu.status & flag;
45 49
 }
46 50
 
47 51
 void
... ...
@@ -57,30 +61,31 @@ echo(Uint8 *s, Uint8 len, char *name)
57 61
 	printf("\n\n");
58 62
 }
59 63
 
64
+#pragma mark - Operations
65
+
60 66
 void
61 67
 op_push(Uint8 *s, Uint8 *ptr, Uint8 v)
62 68
 {
63
-	s[*ptr] = v;
64
-	(*ptr) += 1;
69
+	s[(*ptr)++] = v;
65 70
 }
66 71
 
67
-void
72
+Uint8
68 73
 op_pop(Uint8 *s, Uint8 *ptr)
69 74
 {
70
-	s[*ptr--] = 0x00;
75
+	return s[--*ptr];
71 76
 }
72 77
 
73 78
 void
74
-reset(Computer *cpu)
79
+reset(void)
75 80
 {
76 81
 	int i;
77
-	cpu->status = 0x00;
78
-	cpu->counter = 0x00;
79
-	cpu->mptr = 0x00;
80
-	cpu->sptr = 0x00;
81
-	cpu->literal = 0x00;
82
+	cpu.status = 0x00;
83
+	cpu.counter = 0x00;
84
+	cpu.mptr = 0x00;
85
+	cpu.sptr = 0x00;
86
+	cpu.literal = 0x00;
82 87
 	for(i = 0; i < 256; i++)
83
-		cpu->stack[i] = 0x00;
88
+		cpu.stack[i] = 0x00;
84 89
 }
85 90
 
86 91
 int
... ...
@@ -91,39 +96,63 @@ error(char *name)
91 96
 }
92 97
 
93 98
 void
94
-load(Computer *cpu, FILE *f)
99
+load(FILE *f)
95 100
 {
96
-	fread(cpu->memory, sizeof(cpu->memory), 1, f);
101
+	fread(cpu.memory, sizeof(cpu.memory), 1, f);
97 102
 }
98 103
 
99 104
 void
100
-eval(Computer *cpu)
105
+eval()
101 106
 {
102
-	Uint8 instr = cpu->memory[cpu->mptr++];
103
-
104
-	if(cpu->literal > 0) {
105
-		printf("push: %02x[%d](%d)\n", instr, cpu->literal, cpu->sptr);
106
-		op_push(cpu->stack, &cpu->sptr, instr);
107
-		cpu->literal--;
107
+	Uint8 instr = cpu.memory[cpu.mptr++];
108
+	Uint8 a, b, c;
109
+	if(cpu.literal > 0) {
110
+		printf("push: %02x[%d](%d)\n", instr, cpu.literal, cpu.sptr);
111
+		op_push(cpu.stack, &cpu.sptr, instr);
112
+		cpu.literal--;
108 113
 		return;
109 114
 	}
110 115
 	switch(instr) {
111
-	case 0x0: setflag(cpu, FLAG_HALT, 1); break;
112
-	case 0x1: cpu->literal += 4; break;
116
+	case 0x0: setflag(FLAG_HALT, 1); break;
117
+	case 0x1: cpu.literal += cpu.memory[cpu.mptr++]; break;
118
+	case 0x2: printf("??\n"); break;
119
+	case 0x3: /* pop */
120
+		op_pop(cpu.stack, &cpu.sptr);
121
+		break;
122
+	case 0x4: /* dup */
123
+		op_push(cpu.stack, &cpu.sptr, cpu.stack[cpu.sptr - 1]);
124
+		break;
125
+	case 0x5: /* swp */
126
+		b = op_pop(cpu.stack, &cpu.sptr);
127
+		a = op_pop(cpu.stack, &cpu.sptr);
128
+		op_push(cpu.stack, &cpu.sptr, b);
129
+		op_push(cpu.stack, &cpu.sptr, a);
130
+		break;
131
+	case 0x6: /* ovr */
132
+		op_push(cpu.stack, &cpu.sptr, cpu.stack[cpu.sptr - 2]);
133
+		break;
134
+	case 0x7: /* rot */
135
+		c = op_pop(cpu.stack, &cpu.sptr);
136
+		b = op_pop(cpu.stack, &cpu.sptr);
137
+		a = op_pop(cpu.stack, &cpu.sptr);
138
+		op_push(cpu.stack, &cpu.sptr, b);
139
+		op_push(cpu.stack, &cpu.sptr, c);
140
+		op_push(cpu.stack, &cpu.sptr, a);
141
+		break;
113 142
 	default: printf("Unknown instruction: #%02x\n", instr);
114 143
 	}
115 144
 }
116 145
 
117 146
 void
118
-run(Computer *cpu)
147
+run(void)
119 148
 {
120 149
 	int i;
121
-	while((cpu->status & FLAG_HALT) == 0)
150
+	while((cpu.status & FLAG_HALT) == 0)
122 151
 		eval(cpu);
123 152
 	/* debug */
124
-	printf("ended @ %d  |  ", cpu->counter);
153
+	printf("ended @ %d  |  ", cpu.counter);
125 154
 	for(i = 0; i < 4; i++)
126
-		printf("%d-", (cpu->status & (1 << i)) != 0);
155
+		printf("%d-", (cpu.status & (1 << i)) != 0);
127 156
 	printf("\n\n");
128 157
 }
129 158
 
... ...
@@ -131,14 +160,13 @@ int
131 160
 main(int argc, char *argv[])
132 161
 {
133 162
 	FILE *f;
134
-	Computer cpu;
135 163
 	if(argc < 2)
136 164
 		return error("No input.");
137 165
 	if(!(f = fopen(argv[1], "rb")))
138 166
 		return error("Missing input.");
139
-	reset(&cpu);
140
-	load(&cpu, f);
141
-	run(&cpu);
167
+	reset();
168
+	load(f);
169
+	run();
142 170
 	/* print result */
143 171
 	echo(cpu.stack, 0x40, "stack");
144 172
 	echo(cpu.memory, 0x40, "memory");
... ...
@@ -16,43 +16,31 @@ WITH REGARD TO THIS SOFTWARE.
16 16
 typedef unsigned char Uint8;
17 17
 
18 18
 typedef struct {
19
-	int ptr;
19
+	int len;
20 20
 	Uint8 data[PRGLEN];
21 21
 } Program;
22 22
 
23
+char labels[256][16];
24
+
23 25
 char opcodes[][4] = {
24 26
 	"BRK",
25 27
 	"LIT",
28
+	"---",
29
+	"POP",
26 30
 	"DUP",
27
-	"DRP",
28 31
 	"SWP",
29
-	"SLP",
30
-	"PSH",
31
-	"POP", /* --- */
32
+	"OVR",
33
+	"ROT",
34
+	/* */
32 35
 	"JMP",
33 36
 	"JSR",
34
-	"RST",
35
-	"BEQ",
37
+	"JEQ",
38
+	"RTS",
36 39
 	"EQU",
37 40
 	"NEQ",
38 41
 	"LTH",
39
-	"GTH", /* --- */
40
-	"---",
41
-	"---",
42
-	"---",
43
-	"---",
44
-	"---",
45
-	"---",
46
-	"---",
47
-	"---", /* --- */
48
-	"---",
49
-	"---",
50
-	"---",
51
-	"---",
52
-	"---",
53
-	"---",
54
-	"---",
55
-	"---"};
42
+	"GTH",
43
+	/* */};
56 44
 
57 45
 Program p;
58 46
 
... ...
@@ -78,6 +66,17 @@ suca(char *s) /* string to uppercase */
78 66
 	return s;
79 67
 }
80 68
 
69
+int
70
+sihx(char *s)
71
+{
72
+	int i = 0;
73
+	char c;
74
+	while((c = s[i++]))
75
+		if(!(c >= '0' && c <= '9') && !(c >= 'A' && c <= 'F'))
76
+			return 0;
77
+	return 1;
78
+}
79
+
81 80
 int
82 81
 shex(char *s) /* string to num */
83 82
 {
... ...
@@ -86,36 +85,90 @@ shex(char *s) /* string to num */
86 85
 	while((c = s[i++]))
87 86
 		if(c >= '0' && c <= '9')
88 87
 			n = n * 16 + (c - '0');
89
-		else if(c >= 'a' && c <= 'f')
90
-			n = n * 16 + 10 + (c - 'a');
88
+		else if(c >= 'A' && c <= 'F')
89
+			n = n * 16 + 10 + (c - 'A');
91 90
 	return n;
92 91
 }
93 92
 
94
-#pragma mark - Helpers
93
+#pragma mark - Parser
94
+
95
+void
96
+addprg(Uint8 hex)
97
+{
98
+	p.data[p.len++] = hex;
99
+}
100
+
101
+void
102
+addlabel(char *id, Uint8 addr)
103
+{
104
+	printf("new label: %s=%02x\n", id, addr);
105
+}
106
+
107
+void
108
+addconst(char *id, Uint8 value)
109
+{
110
+	printf("new const: %s=%02x\n", id, value);
111
+}
95 112
 
96 113
 Uint8
97
-getopcode(char *s)
114
+findop(char *s)
98 115
 {
99 116
 	int i;
100
-	if(s[0] == '{') /* TODO catch closing */
101
-		return 0x01;
102 117
 	for(i = 0; i < 16; ++i)
103
-		if(scmp(opcodes[i], suca(s)))
118
+		if(scmp(opcodes[i], s))
104 119
 			return i;
105
-	return 0xff;
120
+	return 0;
121
+}
122
+
123
+int
124
+comment(char *w, int *skip)
125
+{
126
+	if(w[0] == '>') {
127
+		*skip = 0;
128
+		return 1;
129
+	}
130
+	if(w[0] == '<') *skip = 1;
131
+	if(*skip) return 1;
132
+	return 0;
106 133
 }
107 134
 
108 135
 void
109 136
 pass1(FILE *f)
110 137
 {
138
+	int skip = 0;
111 139
 	char word[64];
112 140
 	while(fscanf(f, "%s", word) == 1) {
113
-		int op = getopcode(word);
114
-		if(word[0] == '}')
141
+		if(comment(word, &skip))
115 142
 			continue;
116
-		if(op == 0xff)
117
-			op = shex(word);
118
-		p.data[p.ptr++] = op;
143
+	}
144
+	rewind(f);
145
+}
146
+
147
+void
148
+pass2(FILE *f)
149
+{
150
+	int skip = 0;
151
+	char word[64];
152
+	while(fscanf(f, "%s", word) == 1) {
153
+		Uint8 op;
154
+		suca(word);
155
+		if(comment(word, &skip)) continue;
156
+		if(word[0] == ']') continue;
157
+		if(word[0] == '+') {
158
+			addprg(0x01);
159
+			addprg(1);
160
+			addprg(shex(word + 1));
161
+		} else if(word[0] == '[') {
162
+			addprg(0x01);
163
+			addprg(shex(word + 1));
164
+		} else if((op = findop(word)))
165
+			addprg(op);
166
+		else if(sihx(word))
167
+			addprg(shex(word));
168
+		else if(scmp(word, "BRK"))
169
+			addprg(0x00);
170
+		else
171
+			printf("unknown: %s\n", word);
119 172
 	}
120 173
 }
121 174
 
... ...
@@ -135,6 +188,7 @@ main(int argc, char *argv[])
135 188
 	if(!(f = fopen(argv[1], "r")))
136 189
 		return error("Missing input.");
137 190
 	pass1(f);
191
+	pass2(f);
138 192
 	fwrite(p.data, sizeof(p.data), 1, fopen(argv[2], "wb"));
139 193
 	fclose(f);
140 194
 	return 0;