Browse code

Started implementing signed operations

neauoire authored on 13/02/2021 00:18:52
Showing 9 changed files
... ...
@@ -34,6 +34,8 @@ evaluxn(u, u->vframe); /* Each frame
34 34
 
35 35
 - `,literal`, push label value to stack, prefixed with `LIT LEN`.
36 36
 - `.pointer`, push label value to stack.
37
+- `+1234`, push positive lit signed value to stack.
38
+- `-abcd`, push negative lit signed value to stack.
37 39
 
38 40
 ### Special
39 41
 
... ...
@@ -82,14 +84,12 @@ BRK
82 84
 
83 85
 ## TODOs
84 86
 
85
-- Implement signed flag to operators.
87
+- Line routine
86 88
 - On-screen debugger.
87 89
 - Auto-advance ldr?
88 90
 - Getting rid of IOR/IOW would be nice..
89 91
 - Sending from the wst to the rst, balance mode/flag?
90 92
 - Device that works like an extra memory bank
91
-- Line routine
92
-- LineRect routine
93 93
 - Draw a chr sprite.
94 94
 
95 95
 ## Refs
... ...
@@ -12,7 +12,9 @@ WITH REGARD TO THIS SOFTWARE.
12 12
 */
13 13
 
14 14
 typedef unsigned char Uint8;
15
+typedef signed char Sint8;
15 16
 typedef unsigned short Uint16;
17
+typedef signed short Sint16;
16 18
 
17 19
 typedef struct {
18 20
 	int ptr;
... ...
@@ -61,6 +63,7 @@ pushbyte(Uint8 b, int lit)
61 63
 void
62 64
 pushshort(Uint16 s, int lit)
63 65
 {
66
+	printf("%04x[%d]\n", s, lit);
64 67
 	if(lit) {
65 68
 		pushbyte(0x03, 0);
66 69
 		pushbyte(0x02, 0);
... ...
@@ -100,7 +103,7 @@ findoperator(char *s)
100 103
 			continue;
101 104
 		while(s[3 + m]) {
102 105
 			if(s[3 + m] == '^') i |= (1 << 5); /* mode: 16 bits */
103
-			if(s[3 + m] == '~') i |= (1 << 6); /* mode: signed */
106
+			if(s[3 + m] == '!') i |= (1 << 6); /* mode: signed */
104 107
 			if(s[3 + m] == '?') i |= (1 << 7); /* mode: conditional */
105 108
 			m++;
106 109
 		}
... ...
@@ -124,6 +127,8 @@ makelabel(char *name, Uint16 addr)
124 127
 	Label *l;
125 128
 	if(findlabel(name))
126 129
 		return error("Label duplicate", name);
130
+	if(sihx(name))
131
+		return error("Label name is hex number", name);
127 132
 	l = &labels[labelslen++];
128 133
 	l->addr = addr;
129 134
 	scpy(name, l->name, 64);
... ...
@@ -176,6 +181,8 @@ pass1(FILE *f)
176 181
 			case '"': addr += slen(w + 1) + 2; break;
177 182
 			case '#': addr += 4; break;
178 183
 			case '.': addr += 2; break;
184
+			case '+': /* signed positive */
185
+			case '-': /* signed negative */
179 186
 			case ',':
180 187
 				addr += (sihx(w + 1) && slen(w + 1) == 2 ? 1 : 2);
181 188
 				addr += (sihx(w + 1) ? slen(w + 1) / 2 : 2);
... ...
@@ -198,26 +205,22 @@ pass2(FILE *f)
198 205
 		Label *l;
199 206
 		if(w[0] == '@') continue;
200 207
 		if(cmnt(w, &skip)) continue;
201
-		if(w[0] == '|')
202
-			p.ptr = shex(w + 1);
203
-		else if(w[0] == ':')
204
-			fscanf(f, "%s", w);
205
-		else if(w[0] == ';')
206
-			fscanf(f, "%s", w);
207
-		else if(w[0] == '"')
208
-			pushtext(w + 1);
209
-		else if(w[0] == '#')
210
-			pushshort(shex(w + 1) & 0xff, 1);
211
-		else if((l = findlabel(w + 1)))
212
-			pushshort(l->addr, w[0] == ',');
213
-		else if((op = findoperator(w)) || scmp(w, "BRK"))
214
-			pushbyte(op, 0);
215
-		else if(sihx(w + 1) && slen(w + 1) == 2)
216
-			pushbyte(shex(w + 1), w[0] == ',');
217
-		else if(sihx(w + 1) && slen(w + 1) == 4)
218
-			pushshort(shex(w + 1), w[0] == ',');
219
-		else
220
-			return error("Unknown label", w);
208
+		/* clang-format off */
209
+		if(w[0] == '|') p.ptr = shex(w + 1);
210
+		else if(w[0] == ':') fscanf(f, "%s", w);
211
+		else if(w[0] == ';') fscanf(f, "%s", w);
212
+		else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);
213
+		else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
214
+		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
215
+		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
216
+		else if(w[0] == '"') pushtext(w + 1);
217
+		else if(w[0] == '#') pushshort(shex(w + 1) & 0xff, 1);
218
+		else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
219
+		else if((op = findoperator(w)) || scmp(w, "BRK")) pushbyte(op, 0);
220
+		else if(sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), w[0] == ',');
221
+		else if(sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), w[0] == ',');
222
+		else return error("Unknown label", w);
223
+		/* clang-format on */
221 224
 	}
222 225
 	return 1;
223 226
 }
... ...
@@ -24,5 +24,5 @@ rm -f ./bin/emulator
24 24
 cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Wvla -g -Og -fsanitize=address -fsanitize=undefined uxn.c emulator.c -L/usr/local/lib -lSDL2 -o bin/emulator
25 25
 
26 26
 # run
27
-./bin/assembler examples/test.usm bin/boot.rom
27
+./bin/assembler examples/line.usm bin/boot.rom
28 28
 ./bin/emulator bin/boot.rom
... ...
@@ -21,6 +21,12 @@ contexts:
21 21
     - match: '\|(\S+)\s?'
22 22
       scope: punctuation.definition
23 23
       pop: true
24
+    - match: '\+(\S+)\s?'
25
+      scope: keyword.control
26
+      pop: true
27
+    - match: '\-(\S+)\s?'
28
+      scope: keyword.control
29
+      pop: true
24 30
 
25 31
   strings:
26 32
     - match: '\:(\S+)\s?'
... ...
@@ -35,6 +41,9 @@ contexts:
35 41
     - match: '\,(\S+)\s?'
36 42
       scope: keyword.control
37 43
       pop: true
44
+    - match: '\#(\S+)\s?'
45
+      scope: keyword.control
46
+      pop: true
38 47
     - match: '\.(\S+)\s?'
39 48
       scope: keyword.control
40 49
       pop: true
... ...
@@ -22,6 +22,18 @@
22 22
 ,1234 ,1233 GTH^ #0e STR
23 23
 ,1234 ,1235 LTH^ #0f STR
24 24
 
25
+BRK
26
+
27
+@diff8 ( result of abs sub )
28
+	OVR OVR GTH ,diff8sub ROT JMP? POP^
29
+	SWP @diff8sub SUB
30
+RTS
31
+
32
+@diff16 ( result of abs sub16 )
33
+	OVR^ OVR^ GTH^ ,diff16sub ROT JMP? POP^
34
+	SWP^ @diff16sub SUB^
35
+RTS
36
+
25 37
 |c000 @FRAME BRK 
26 38
 |d000 @ERROR BRK 
27 39
 |FFFA .RESET .FRAME .ERROR
... ...
@@ -5,6 +5,8 @@
5 5
 
6 6
 ;x_ 2 ;y_ 2 ;x0 2 ;y0 2 ;x1 2 ;y1 2 ;color 1
7 7
 
8
+;dx 2 ;dy 2 ;err 2 ;err2 2
9
+
8 10
 |0100 @RESET
9 11
 
10 12
 	( set dev/write to screen ) 
... ...
@@ -13,9 +15,10 @@
13 15
 
14 16
 	( init positions )
15 17
 	,0020 ,x0 STR^ ,0018 ,y0 STR^
16
-	,0030 ,x1 STR^ ,0048 ,y1 STR^
18
+	,0060 ,x1 STR^ ,0048 ,y1 STR^
17 19
 	,x0 LDR^ ,x_ STR^ ,y0 LDR^ ,y_ STR^
18 20
 
21
+
19 22
 	( draw control points )
20 23
 	,02 ,color STR
21 24
 	,x0 LDR^ ,y0 LDR^ ,putpixel JSR
... ...
@@ -39,6 +42,11 @@ BRK
39 42
 	,00 IOW  ( redraw byte )
40 43
 	RTS
41 44
 
45
+@diff16
46
+	OVR^ OVR^ GTH^ ,diff16sub ROT JMP? POP^
47
+	SWP^ @diff16sub SUB^
48
+RTS
49
+
42 50
 |c000 @FRAME BRK 
43 51
 |d000 @ERROR BRK 
44 52
 |FFFA .RESET .FRAME .ERROR
... ...
@@ -3,13 +3,17 @@
3 3
 :dev/r fff8 ( std read port )
4 4
 :dev/w fff9 ( std write port )
5 5
 
6
+;x 2
7
+
6 8
 |0100 @RESET 
7 9
 
8
-	,00 ,dev/w STR ( set dev/write to console ) 
10
+	,00 ,dev/w STR ( set dev/write to console )
9 11
 
12
+	-12 +02 LTH!
10 13
 
11 14
 BRK
12 15
 
16
+
13 17
 |c000 @FRAME BRK
14 18
 |d000 @ERROR BRK 
15 19
 |FFFA .RESET .FRAME .ERROR
... ...
@@ -33,7 +33,7 @@ Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) <
33 33
 void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
34 34
 void op_li1(Uxn *u) { u->literal += 1; }
35 35
 void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
36
-void op_nop(Uxn *u) { printf("%02x\n", pop8(&u->wst)); }
36
+void op_nop(Uxn *u) { printf("0x%02x ", pop8(&u->wst)); }
37 37
 void op_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, pop8(&u->wst))); }
38 38
 void op_iow(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) dev->write(dev, a); }
39 39
 void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram, a)); }
... ...
@@ -52,14 +52,14 @@ void op_and(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst,
52 52
 void op_ora(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b | a); }
53 53
 void op_rol(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b << a); }
54 54
 /* Arithmetic */
55
-void op_add(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b + a); }
56
-void op_sub(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b - a); }
57
-void op_mul(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b * a); }
58
-void op_div(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b / a); }
59
-void op_equ(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b == a); }
60
-void op_neq(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b != a); }
61
-void op_gth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b > a); }
62
-void op_lth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, b < a); }
55
+void op_add(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b + (Sint8)a : b + a); }
56
+void op_sub(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b - (Sint8)a : b - a); }
57
+void op_mul(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b * (Sint8)a : b * a); }
58
+void op_div(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b / (Sint8)a : b / a); }
59
+void op_equ(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b == (Sint8)a : b == a); }
60
+void op_neq(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b != (Sint8)a : b != a); }
61
+void op_gth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b > (Sint8)a : b > a); }
62
+void op_lth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b < (Sint8)a : b < a); }
63 63
 /* --- */
64 64
 void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); }
65 65
 void op_ior16(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push16(&u->wst, (dev->read(dev, a) << 8) + dev->read(dev, a + 1)); }
... ...
@@ -76,14 +76,14 @@ void op_and16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u
76 76
 void op_ora16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b | a); }
77 77
 void op_rol16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b << a); }
78 78
 /* Arithmetic(16-bits) */
79
-void op_add16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b + a); }
80
-void op_sub16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b - a); }
81
-void op_mul16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b * a); }
82
-void op_div16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, b / a); }
83
-void op_equ16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b == a); }
84
-void op_neq16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b != a); }
85
-void op_gth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b > a); }
86
-void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, b < a); }
79
+void op_add16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b + (Sint8)a : b + a); }
80
+void op_sub16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b - (Sint8)a : b - a); }
81
+void op_mul16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b * (Sint8)a : b * a); }
82
+void op_div16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push16(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b / (Sint8)a : b / a); }
83
+void op_equ16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b == (Sint8)a : b == a); }
84
+void op_neq16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b != (Sint8)a : b != a); }
85
+void op_gth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b > (Sint8)a : b > a); }
86
+void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint8)b < (Sint8)a : b < a); }
87 87
 
88 88
 void (*ops[])(Uxn *u) = {
89 89
 	op_brk, op_nop, op_li1, op_lix, op_ior, op_iow, op_ldr, op_str, 
... ...
@@ -133,7 +133,7 @@ opcuxn(Uxn *u, Uint8 instr)
133 133
 {
134 134
 	Uint8 op = instr & 0x1f;
135 135
 	setflag(&u->status, FLAG_SHORT, (instr >> 5) & 1);
136
-	setflag(&u->status, FLAG_SIGN, (instr >> 6) & 1); /* usused */
136
+	setflag(&u->status, FLAG_SIGN, (instr >> 6) & 1);
137 137
 	setflag(&u->status, FLAG_COND, (instr >> 7) & 1);
138 138
 	if(getflag(&u->status, FLAG_SHORT))
139 139
 		op += 32;
... ...
@@ -12,7 +12,9 @@ WITH REGARD TO THIS SOFTWARE.
12 12
 */
13 13
 
14 14
 typedef unsigned char Uint8;
15
+typedef signed char Sint8;
15 16
 typedef unsigned short Uint16;
17
+typedef signed short Sint16;
16 18
 
17 19
 #define FLAG_HALT 0x01
18 20
 #define FLAG_SHORT 0x02