Browse code

Merged LIT and BRK into opcode zero, added INC opcode

Andrew Alderwick authored on 17/08/2021 21:48:48
Showing 5 changed files
... ...
@@ -323,8 +323,7 @@ uxn_eval(Uxn *u, Uint16 vec)
323 323
 		return 0;
324 324
 	u->ram.ptr = vec;
325 325
 	if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
326
-	while(u->ram.ptr) {
327
-		instr = u->ram.dat[u->ram.ptr++];
326
+	while((instr = u->ram.dat[u->ram.ptr++])) {
328 327
 		switch(instr) {
329 328
 #pragma GCC diagnostic push
330 329
 #pragma GCC diagnostic ignored "-Wunused-value"
... ...
@@ -232,8 +232,7 @@ uxn_eval(Uxn *u, Uint16 vec)
232 232
 		return 0;
233 233
 	u->ram.ptr = vec;
234 234
 	if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
235
-	while(u->ram.ptr) {
236
-		instr = u->ram.dat[u->ram.ptr++];
235
+	while((instr = u->ram.dat[u->ram.ptr++])) {
237 236
 		switch(instr) {
238 237
 #pragma GCC diagnostic push
239 238
 #pragma GCC diagnostic ignored "-Wunused-value"
... ...
@@ -48,28 +48,14 @@ uxn_eval(Uxn *u, Uint16 vec)
48 48
 		return 0;
49 49
 	u->ram.ptr = vec;
50 50
 	if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
51
-	while(u->ram.ptr) {
52
-		instr = u->ram.dat[u->ram.ptr++];
51
+	while((instr = u->ram.dat[u->ram.ptr++])) {
53 52
 		switch(instr) {
54 53
 #pragma GCC diagnostic push
55 54
 #pragma GCC diagnostic ignored "-Wunused-value"
56 55
 #pragma GCC diagnostic ignored "-Wunused-variable"
57
-		case 0x00: /* BRK */
58
-		case 0x20: /* BRK2 */
59
-		case 0x40: /* BRKr */
60
-		case 0x60: /* BRK2r */
61
-		case 0x80: /* BRKk */
62
-		case 0xa0: /* BRK2k */
63
-		case 0xc0: /* BRKkr */
64
-		case 0xe0: /* BRK2kr */
65
-			__asm__("evaluxn_00_BRK:");
66
-			{
67
-				u->ram.ptr = 0;
68
-			}
69
-			break;
70
-		case 0x01: /* LIT */
71
-		case 0x81: /* LITk */
72
-			__asm__("evaluxn_01_LIT:");
56
+		case 0x00: /* LIT */
57
+		case 0x80: /* LITk */
58
+			__asm__("evaluxn_00_LIT:");
73 59
 			{
74 60
 				u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
75 61
 #ifndef NO_STACK_CHECKS
... ...
@@ -81,6 +67,19 @@ uxn_eval(Uxn *u, Uint16 vec)
81 67
 				u->wst.ptr += 1;
82 68
 			}
83 69
 			break;
70
+		case 0x01: /* INC */
71
+			__asm__("evaluxn_01_INC:");
72
+			{
73
+				Uint8 a = u->wst.dat[u->wst.ptr - 1];
74
+				u->wst.dat[u->wst.ptr - 1] = a + 1;
75
+#ifndef NO_STACK_CHECKS
76
+				if(__builtin_expect(u->wst.ptr < 1, 0)) {
77
+					u->wst.error = 1;
78
+					goto error;
79
+				}
80
+#endif
81
+			}
82
+			break;
84 83
 		case 0x02: /* POP */
85 84
 			__asm__("evaluxn_02_POP:");
86 85
 			{
... ...
@@ -533,9 +532,9 @@ uxn_eval(Uxn *u, Uint16 vec)
533 532
 				u->wst.ptr -= 1;
534 533
 			}
535 534
 			break;
536
-		case 0x21: /* LIT2 */
537
-		case 0xa1: /* LIT2k */
538
-			__asm__("evaluxn_21_LIT2:");
535
+		case 0x20: /* LIT2 */
536
+		case 0xa0: /* LIT2k */
537
+			__asm__("evaluxn_20_LIT2:");
539 538
 			{
540 539
 				u->wst.dat[u->wst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
541 540
 				u->wst.dat[u->wst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++);
... ...
@@ -548,6 +547,20 @@ uxn_eval(Uxn *u, Uint16 vec)
548 547
 				u->wst.ptr += 2;
549 548
 			}
550 549
 			break;
550
+		case 0x21: /* INC2 */
551
+			__asm__("evaluxn_21_INC2:");
552
+			{
553
+				Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
554
+				u->wst.dat[u->wst.ptr - 2] = (a + 1) >> 8;
555
+				u->wst.dat[u->wst.ptr - 1] = (a + 1) & 0xff;
556
+#ifndef NO_STACK_CHECKS
557
+				if(__builtin_expect(u->wst.ptr < 2, 0)) {
558
+					u->wst.error = 1;
559
+					goto error;
560
+				}
561
+#endif
562
+			}
563
+			break;
551 564
 		case 0x22: /* POP2 */
552 565
 			__asm__("evaluxn_22_POP2:");
553 566
 			{
... ...
@@ -1035,9 +1048,9 @@ uxn_eval(Uxn *u, Uint16 vec)
1035 1048
 				u->wst.ptr -= 1;
1036 1049
 			}
1037 1050
 			break;
1038
-		case 0x41: /* LITr */
1039
-		case 0xc1: /* LITkr */
1040
-			__asm__("evaluxn_41_LITr:");
1051
+		case 0x40: /* LITr */
1052
+		case 0xc0: /* LITkr */
1053
+			__asm__("evaluxn_40_LITr:");
1041 1054
 			{
1042 1055
 				u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
1043 1056
 #ifndef NO_STACK_CHECKS
... ...
@@ -1049,6 +1062,19 @@ uxn_eval(Uxn *u, Uint16 vec)
1049 1062
 				u->rst.ptr += 1;
1050 1063
 			}
1051 1064
 			break;
1065
+		case 0x41: /* INCr */
1066
+			__asm__("evaluxn_41_INCr:");
1067
+			{
1068
+				Uint8 a = u->rst.dat[u->rst.ptr - 1];
1069
+				u->rst.dat[u->rst.ptr - 1] = a + 1;
1070
+#ifndef NO_STACK_CHECKS
1071
+				if(__builtin_expect(u->rst.ptr < 1, 0)) {
1072
+					u->rst.error = 1;
1073
+					goto error;
1074
+				}
1075
+#endif
1076
+			}
1077
+			break;
1052 1078
 		case 0x42: /* POPr */
1053 1079
 			__asm__("evaluxn_42_POPr:");
1054 1080
 			{
... ...
@@ -1501,9 +1527,9 @@ uxn_eval(Uxn *u, Uint16 vec)
1501 1527
 				u->rst.ptr -= 1;
1502 1528
 			}
1503 1529
 			break;
1504
-		case 0x61: /* LIT2r */
1505
-		case 0xe1: /* LIT2kr */
1506
-			__asm__("evaluxn_61_LIT2r:");
1530
+		case 0x60: /* LIT2r */
1531
+		case 0xe0: /* LIT2kr */
1532
+			__asm__("evaluxn_60_LIT2r:");
1507 1533
 			{
1508 1534
 				u->rst.dat[u->rst.ptr] = mempeek8(u->ram.dat, u->ram.ptr++);
1509 1535
 				u->rst.dat[u->rst.ptr + 1] = mempeek8(u->ram.dat, u->ram.ptr++);
... ...
@@ -1516,6 +1542,20 @@ uxn_eval(Uxn *u, Uint16 vec)
1516 1542
 				u->rst.ptr += 2;
1517 1543
 			}
1518 1544
 			break;
1545
+		case 0x61: /* INC2r */
1546
+			__asm__("evaluxn_61_INC2r:");
1547
+			{
1548
+				Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
1549
+				u->rst.dat[u->rst.ptr - 2] = (a + 1) >> 8;
1550
+				u->rst.dat[u->rst.ptr - 1] = (a + 1) & 0xff;
1551
+#ifndef NO_STACK_CHECKS
1552
+				if(__builtin_expect(u->rst.ptr < 2, 0)) {
1553
+					u->rst.error = 1;
1554
+					goto error;
1555
+				}
1556
+#endif
1557
+			}
1558
+			break;
1519 1559
 		case 0x62: /* POP2r */
1520 1560
 			__asm__("evaluxn_62_POP2r:");
1521 1561
 			{
... ...
@@ -2003,6 +2043,24 @@ uxn_eval(Uxn *u, Uint16 vec)
2003 2043
 				u->rst.ptr -= 1;
2004 2044
 			}
2005 2045
 			break;
2046
+		case 0x81: /* INCk */
2047
+			__asm__("evaluxn_81_INCk:");
2048
+			{
2049
+				Uint8 a = u->wst.dat[u->wst.ptr - 1];
2050
+				u->wst.dat[u->wst.ptr] = a + 1;
2051
+#ifndef NO_STACK_CHECKS
2052
+				if(__builtin_expect(u->wst.ptr < 1, 0)) {
2053
+					u->wst.error = 1;
2054
+					goto error;
2055
+				}
2056
+				if(__builtin_expect(u->wst.ptr > 254, 0)) {
2057
+					u->wst.error = 2;
2058
+					goto error;
2059
+				}
2060
+#endif
2061
+				u->wst.ptr += 1;
2062
+			}
2063
+			break;
2006 2064
 		case 0x82: /* POPk */
2007 2065
 			__asm__("evaluxn_82_POPk:");
2008 2066
 			{
... ...
@@ -2526,6 +2584,25 @@ uxn_eval(Uxn *u, Uint16 vec)
2526 2584
 				u->wst.ptr += 1;
2527 2585
 			}
2528 2586
 			break;
2587
+		case 0xa1: /* INC2k */
2588
+			__asm__("evaluxn_a1_INC2k:");
2589
+			{
2590
+				Uint16 a = (u->wst.dat[u->wst.ptr - 1] | (u->wst.dat[u->wst.ptr - 2] << 8));
2591
+				u->wst.dat[u->wst.ptr] = (a + 1) >> 8;
2592
+				u->wst.dat[u->wst.ptr + 1] = (a + 1) & 0xff;
2593
+#ifndef NO_STACK_CHECKS
2594
+				if(__builtin_expect(u->wst.ptr < 2, 0)) {
2595
+					u->wst.error = 1;
2596
+					goto error;
2597
+				}
2598
+				if(__builtin_expect(u->wst.ptr > 253, 0)) {
2599
+					u->wst.error = 2;
2600
+					goto error;
2601
+				}
2602
+#endif
2603
+				u->wst.ptr += 2;
2604
+			}
2605
+			break;
2529 2606
 		case 0xa2: /* POP2k */
2530 2607
 			__asm__("evaluxn_a2_POP2k:");
2531 2608
 			{
... ...
@@ -3073,6 +3150,24 @@ uxn_eval(Uxn *u, Uint16 vec)
3073 3150
 				u->wst.ptr += 2;
3074 3151
 			}
3075 3152
 			break;
3153
+		case 0xc1: /* INCkr */
3154
+			__asm__("evaluxn_c1_INCkr:");
3155
+			{
3156
+				Uint8 a = u->rst.dat[u->rst.ptr - 1];
3157
+				u->rst.dat[u->rst.ptr] = a + 1;
3158
+#ifndef NO_STACK_CHECKS
3159
+				if(__builtin_expect(u->rst.ptr < 1, 0)) {
3160
+					u->rst.error = 1;
3161
+					goto error;
3162
+				}
3163
+				if(__builtin_expect(u->rst.ptr > 254, 0)) {
3164
+					u->rst.error = 2;
3165
+					goto error;
3166
+				}
3167
+#endif
3168
+				u->rst.ptr += 1;
3169
+			}
3170
+			break;
3076 3171
 		case 0xc2: /* POPkr */
3077 3172
 			__asm__("evaluxn_c2_POPkr:");
3078 3173
 			{
... ...
@@ -3596,6 +3691,25 @@ uxn_eval(Uxn *u, Uint16 vec)
3596 3691
 				u->rst.ptr += 1;
3597 3692
 			}
3598 3693
 			break;
3694
+		case 0xe1: /* INC2kr */
3695
+			__asm__("evaluxn_e1_INC2kr:");
3696
+			{
3697
+				Uint16 a = (u->rst.dat[u->rst.ptr - 1] | (u->rst.dat[u->rst.ptr - 2] << 8));
3698
+				u->rst.dat[u->rst.ptr] = (a + 1) >> 8;
3699
+				u->rst.dat[u->rst.ptr + 1] = (a + 1) & 0xff;
3700
+#ifndef NO_STACK_CHECKS
3701
+				if(__builtin_expect(u->rst.ptr < 2, 0)) {
3702
+					u->rst.error = 1;
3703
+					goto error;
3704
+				}
3705
+				if(__builtin_expect(u->rst.ptr > 253, 0)) {
3706
+					u->rst.error = 2;
3707
+					goto error;
3708
+				}
3709
+#endif
3710
+				u->rst.ptr += 2;
3711
+			}
3712
+			break;
3599 3713
 		case 0xe2: /* POP2kr */
3600 3714
 			__asm__("evaluxn_e2_POP2kr:");
3601 3715
 			{
... ...
@@ -33,8 +33,8 @@ Uint16 mempeek16(Uint8 *m, Uint16 a) { return (mempeek8(m, a) << 8) + mempeek8(m
33 33
 static void   devpoke16(Device *d, Uint8 a, Uint16 b) { devpoke8(d, a, b >> 8); devpoke8(d, a + 1, b); }
34 34
 static Uint16 devpeek16(Device *d, Uint16 a) { return (devpeek8(d, a) << 8) + devpeek8(d, a + 1); }
35 35
 /* Stack */
36
-static void op_brk(Uxn *u) { u->ram.ptr = 0; }
37 36
 static void op_lit(Uxn *u) { push8(u->src, mempeek8(u->ram.dat, u->ram.ptr++)); }
37
+static void op_inc(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, a + 1); }
38 38
 static void op_pop(Uxn *u) { pop8(u->src); }
39 39
 static void op_dup(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, a); push8(u->src, a); }
40 40
 static void op_nip(Uxn *u) { Uint8 a = pop8(u->src); pop8(u->src); push8(u->src, a); }
... ...
@@ -70,6 +70,7 @@ static void op_eor(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->
70 70
 static void op_sft(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b >> (a & 0x07) << ((a & 0x70) >> 4)); }
71 71
 /* Stack */
72 72
 static void op_lit16(Uxn *u) { push16(u->src, mempeek16(u->ram.dat, u->ram.ptr++)); u->ram.ptr++; }
73
+static void op_inc16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->src, a + 1); }
73 74
 static void op_pop16(Uxn *u) { pop16(u->src); }
74 75
 static void op_dup16(Uxn *u) { Uint16 a = pop16(u->src); push16(u->src, a); push16(u->src, a); }
75 76
 static void op_nip16(Uxn *u) { Uint16 a = pop16(u->src); pop16(u->src); push16(u->src, a); }
... ...
@@ -105,12 +106,12 @@ static void op_eor16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push
105 106
 static void op_sft16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); push16(u->src, b >> (a & 0x0f) << ((a & 0xf0) >> 4)); }
106 107
 
107 108
 static void (*ops[])(Uxn *u) = {
108
-	op_brk, op_lit, op_pop, op_dup, op_nip, op_swp, op_ovr, op_rot,
109
+	op_lit, op_inc, op_pop, op_dup, op_nip, op_swp, op_ovr, op_rot,
109 110
 	op_equ, op_neq, op_gth, op_lth, op_jmp, op_jnz, op_jsr, op_sth, 
110 111
 	op_pek, op_pok, op_ldr, op_str, op_lda, op_sta, op_dei, op_deo,
111 112
 	op_add, op_sub, op_mul, op_div, op_and, op_ora, op_eor, op_sft,
112 113
 	/* 16-bit */
113
-	op_brk,   op_lit16, op_pop16, op_dup16, op_nip16, op_swp16, op_ovr16, op_rot16,
114
+	op_lit16, op_inc16, op_pop16, op_dup16, op_nip16, op_swp16, op_ovr16, op_rot16,
114 115
 	op_equ16, op_neq16, op_gth16, op_lth16, op_jmp16, op_jnz16, op_jsr16, op_sth16, 
115 116
 	op_pek16, op_pok16, op_ldr16, op_str16, op_lda16, op_sta16, op_dei16, op_deo16, 
116 117
 	op_add16, op_sub16, op_mul16, op_div16, op_and16, op_ora16, op_eor16, op_sft16
... ...
@@ -123,12 +124,12 @@ static void (*ops[])(Uxn *u) = {
123 124
 int
124 125
 uxn_eval(Uxn *u, Uint16 vec)
125 126
 {
127
+	Uint8 instr;
126 128
 	if(u->dev[0].dat[0xf])
127 129
 		return 0;
128 130
 	u->ram.ptr = vec;
129 131
 	if(u->wst.ptr > 0xf8) u->wst.ptr = 0xf8;
130
-	while(u->ram.ptr) {
131
-		Uint8 instr = u->ram.dat[u->ram.ptr++];
132
+	while((instr = u->ram.dat[u->ram.ptr++])) {
132 133
 		/* Return Mode */
133 134
 		if(instr & MODE_RETURN) {
134 135
 			u->src = &u->rst;
... ...
@@ -40,7 +40,7 @@ Program p;
40 40
 /* clang-format off */
41 41
 
42 42
 static char ops[][4] = {
43
-	"BRK", "LIT", "POP", "DUP", "NIP", "SWP", "OVR", "ROT",
43
+	"LIT", "INC", "POP", "DUP", "NIP", "SWP", "OVR", "ROT",
44 44
 	"EQU", "NEQ", "GTH", "LTH", "JMP", "JCN", "JSR", "STH",
45 45
 	"LDZ", "STZ", "LDR", "STR", "LDA", "STA", "DEI", "DEO",
46 46
 	"ADD", "SUB", "MUL", "DIV", "AND", "ORA", "EOR", "SFT"
... ...
@@ -62,7 +62,7 @@ static char *scat(char *dst, const char *src) { char *ptr = dst + slen(dst); whi
62 62
 static void
63 63
 pushbyte(Uint8 b, int lit)
64 64
 {
65
-	if(lit) pushbyte(0x01, 0);
65
+	if(lit) pushbyte(0x80, 0);
66 66
 	p.data[p.ptr++] = b;
67 67
 	p.length = p.ptr;
68 68
 }
... ...
@@ -70,7 +70,7 @@ pushbyte(Uint8 b, int lit)
70 70
 static void
71 71
 pushshort(Uint16 s, int lit)
72 72
 {
73
-	if(lit) pushbyte(0x21, 0);
73
+	if(lit) pushbyte(0x20, 0);
74 74
 	pushbyte((s >> 8) & 0xff, 0);
75 75
 	pushbyte(s & 0xff, 0);
76 76
 }
... ...
@@ -123,6 +123,7 @@ findopcode(char *s)
123 123
 				return 0; /* failed to match */
124 124
 			m++;
125 125
 		}
126
+		if(!i) i |= (1 << 7); /* force LIT nonzero (keep is ignored) */
126 127
 		return i;
127 128
 	}
128 129
 	return 0;
... ...
@@ -152,7 +153,7 @@ makemacro(char *name, FILE *f)
152 153
 		return error("Macro duplicate", name);
153 154
 	if(sihx(name) && slen(name) % 2 == 0)
154 155
 		return error("Macro name is hex number", name);
155
-	if(findopcode(name) || !slen(name))
156
+	if(findopcode(name) || scmp(name, "BRK", 4) || !slen(name))
156 157
 		return error("Macro name is invalid", name);
157 158
 	m = &p.macros[p.mlen++];
158 159
 	scpy(name, m->name, 64);
... ...
@@ -176,7 +177,7 @@ makelabel(char *name, Uint16 addr)
176 177
 		return error("Label duplicate", name);
177 178
 	if(sihx(name) && slen(name) % 2 == 0)
178 179
 		return error("Label name is hex number", name);
179
-	if(findopcode(name) || !slen(name))
180
+	if(findopcode(name) || scmp(name, "BRK", 4) || !slen(name))
180 181
 		return error("Label name is invalid", name);
181 182
 	l = &p.labels[p.llen++];
182 183
 	l->addr = addr;
... ...
@@ -246,7 +247,10 @@ parsetoken(char *w)
246 247
 	} else if(w[0] == ';' && (l = findlabel(w + 1))) { /* absolute */
247 248
 		pushshort(l->addr, 1);
248 249
 		return ++l->refs;
249
-	} else if(findopcode(w) || scmp(w, "BRK", 4)) { /* opcode */
250
+	} else if(scmp(w, "BRK", 4)) { /* special BRK opcode */
251
+		pushbyte(0, 0);
252
+		return 1;
253
+	} else if(findopcode(w)) { /* opcode */
250 254
 		pushbyte(findopcode(w), 0);
251 255
 		return 1;
252 256
 	} else if(w[0] == '"') { /* string */