Browse code

Rewrote hello world to not use the stack

neauoire authored on 14/02/2021 00:37:03
Showing 6 changed files
... ...
@@ -58,40 +58,43 @@ evaluxn(u, u->vframe); /* Each frame
58 58
 - `+21 -03 MULS`, signed operators have the cond flag `S`.
59 59
 
60 60
 ```
61
-:dev/w fff9 ( const write port )
62
-;i 1 ( var iterator )
63
-
64
-|0100 @RESET
61
+( comment )
65 62
 
66
-	#00 ,dev/w STR              ( set dev/write to console ) 
63
+:dev/w fff9 ( const write port )
67 64
 
68
-	@word1 "hello_world         ( len: 0x0b )
65
+|0100 @RESET 
69 66
 
67
+	#00 ,dev/w STR                        ( set dev/write to console ) 
68
+	,string                               ( add string pointer to stack )
70 69
 	@loop
71
-		IOW                     ( write to device#0 )
72
-		,i LDR #01 ADD ,i STR   ( increment itr )
73
-		,i LDR                  ( a = i )
74
-		,word1 ,strlen JSR      ( b = string length )
75
-		NEQ ,loop ROT JSR? POP^ ( a != b ? loop )
70
+		DUP2 LDR IOW                         ( write pointer value to console )
71
+		#0001 ADD2                           ( increment string pointer )
72
+		DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
76 73
 
77 74
 BRK
78 75
 
79
-@strlen #0001 ADD2 LDR RTS
76
+@string " Hello World "                ( add string to memory )
80 77
 
81
-|c000 @FRAME BRK 
78
+|c000 @FRAME BRK
82 79
 |d000 @ERROR BRK 
80
+
83 81
 |FFFA .RESET .FRAME .ERROR
84 82
 ```
85 83
 
86 84
 ## TODOs
87 85
 
86
+- Li1 short mode
87
+- Defines?
88
+- LDR/STR helpers
89
+- Keyboard example
90
+- PPU chr device
88 91
 - Line routine
89 92
 - On-screen debugger.
90 93
 - Auto-advance ldr?
91 94
 - Getting rid of IOR/IOW would be nice..
92 95
 - Sending from the wst to the rst, balance mode/flag?
93 96
 - Device that works like an extra memory bank
94
-- Draw a chr sprite.
97
+- [debug]Print unused labels
95 98
 
96 99
 ## Refs
97 100
 
... ...
@@ -33,7 +33,7 @@ Program p;
33 33
 /* clang-format off */
34 34
 
35 35
 char ops[][4] = {
36
-	"BRK", "NOP", "LI1", "LIX", "IOR", "IOW", "LDR", "STR",
36
+	"BRK", "NOP", "LIT", "LIX", "IOR", "IOW", "LDR", "STR",
37 37
 	"JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---",
38 38
 	"POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL",
39 39
 	"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH"
... ...
@@ -43,7 +43,6 @@ int scmp(char *a, char *b) { int i = 0; while(a[i] == b[i]) if(!a[i++]) return 1
43 43
 int slen(char *s) { int i = 0; while(s[i] && s[++i]) ; return i; } /* string length */
44 44
 int sihx(char *s) { int i = 0; char c; while((c = s[i++])) if(!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) return 0; return 1; } /* string is hexadecimal */
45 45
 int shex(char *s) { int n = 0, i = 0; char c; while((c = s[i++])) if(c >= '0' && c <= '9') n = n * 16 + (c - '0'); else if(c >= 'A' && c <= 'F') n = n * 16 + 10 + (c - 'A'); else if(c >= 'a' && c <= 'f') n = n * 16 + 10 + (c - 'a'); return n; } /* string to num */
46
-int cmnt(char *w, int *skip) { if(w[0] == ')') { *skip = 0; return 1; } if(w[0] == '(') *skip = 1; if(*skip) return 1; return 0; } /* comment helper */
47 46
 char *scpy(char *src, char *dst, int len) { int i = 0; while((dst[i] = src[i]) && i < len - 2) i++; dst[i + 1] = '\0'; return dst; } /* string copy */
48 47
 
49 48
 #pragma mark - Helpers
... ...
@@ -63,24 +62,12 @@ pushbyte(Uint8 b, int lit)
63 62
 void
64 63
 pushshort(Uint16 s, int lit)
65 64
 {
66
-	if(lit) {
67
-		pushbyte(0x03, 0);
68
-		pushbyte(0x02, 0);
69
-	}
65
+	if(lit)
66
+		pushbyte(0x22, 0);
70 67
 	pushbyte((s >> 8) & 0xff, 0);
71 68
 	pushbyte(s & 0xff, 0);
72 69
 }
73 70
 
74
-void
75
-pushtext(char *w)
76
-{
77
-	int i = slen(w);
78
-	pushbyte(0x03, 0);
79
-	pushbyte(slen(w), 0);
80
-	while(i > 0)
81
-		pushbyte(w[--i], 0);
82
-}
83
-
84 71
 Label *
85 72
 findlabel(char *s)
86 73
 {
... ...
@@ -156,15 +143,62 @@ makevariable(char *id, Uint16 *addr, FILE *f)
156 143
 	return makelabel(id, origin);
157 144
 }
158 145
 
146
+int
147
+skipcomment(char *w, int *cap)
148
+{
149
+	if(w[0] == ')') {
150
+		*cap = 0;
151
+		return 1;
152
+	}
153
+	if(w[0] == '(') *cap = 1;
154
+	if(*cap) return 1;
155
+	return 0;
156
+}
157
+
158
+int
159
+skipstring(char *w, int *cap, Uint16 *addr)
160
+{
161
+	if(w[0] == '"') {
162
+		if(*cap)
163
+			*addr += 1;
164
+		*cap = !(*cap);
165
+		return 1;
166
+	}
167
+	if(*cap) {
168
+		*addr += slen(w) + 1;
169
+		return 1;
170
+	}
171
+	return 0;
172
+}
173
+
174
+int
175
+capturestring(char *w, int *cap)
176
+{
177
+	if(w[0] == '"') {
178
+		if(*cap)
179
+			pushbyte(0x00, 0);
180
+		*cap = !(*cap);
181
+		return 1;
182
+	}
183
+	if(*cap) {
184
+		int i;
185
+		for(i = 0; i < slen(w); ++i)
186
+			pushbyte(w[i], 0);
187
+		pushbyte(' ', 0);
188
+		return 1;
189
+	}
190
+	return 0;
191
+}
192
+
159 193
 int
160 194
 pass1(FILE *f)
161 195
 {
162
-	int skip = 0;
196
+	int ccmnt = 0, cstrg = 0;
163 197
 	Uint16 addr = 0;
164 198
 	char w[64];
165 199
 	while(fscanf(f, "%s", w) == 1) {
166
-		if(cmnt(w, &skip))
167
-			continue;
200
+		if(skipcomment(w, &ccmnt)) continue;
201
+		if(skipstring(w, &cstrg, &addr)) continue;
168 202
 		if(w[0] == '@') {
169 203
 			if(!makelabel(w + 1, addr))
170 204
 				return error("Pass1 failed", w);
... ...
@@ -179,12 +213,11 @@ pass1(FILE *f)
179 213
 		else {
180 214
 			switch(w[0]) {
181 215
 			case '|': addr = shex(w + 1); break;
182
-			case '"': addr += slen(w + 1) + 2; break;
183 216
 			case '.': addr += 2; break;
184
-			case ',': addr += 4; break;
217
+			case ',': addr += 3; break;
185 218
 			case '+': /* signed positive */
186 219
 			case '-': /* signed negative */
187
-			case '#': addr += (slen(w + 1) == 2 ? 2 : 4); break;
220
+			case '#': addr += (slen(w + 1) == 2 ? 2 : 3); break;
188 221
 			default: return error("Unknown label in first pass", w);
189 222
 			}
190 223
 		}
... ...
@@ -196,13 +229,14 @@ pass1(FILE *f)
196 229
 int
197 230
 pass2(FILE *f)
198 231
 {
199
-	int skip = 0;
232
+	int ccmnt = 0, cstrg = 0;
200 233
 	char w[64];
201 234
 	while(fscanf(f, "%s", w) == 1) {
202 235
 		Uint8 op = 0;
203 236
 		Label *l;
204 237
 		if(w[0] == '@') continue;
205
-		if(cmnt(w, &skip)) continue;
238
+		if(skipcomment(w, &ccmnt)) continue;
239
+		if(capturestring(w, &cstrg)) continue;
206 240
 		/* clang-format off */
207 241
 		if(w[0] == '|') p.ptr = shex(w + 1);
208 242
 		else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
... ...
@@ -214,7 +248,6 @@ pass2(FILE *f)
214 248
 		else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
215 249
 		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
216 250
 		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
217
-		else if(w[0] == '"') pushtext(w + 1);
218 251
 		else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
219 252
 		else return error("Unknown label in second pass", w);
220 253
 		/* clang-format on */
... ...
@@ -9,51 +9,35 @@
9 9
 |0100 @RESET
10 10
 
11 11
 	( set dev/write to screen ) 
12
-	,01 ,dev/w STR 
12
+	#01 ,dev/w STR 
13 13
 
14
-	,01 ,color STR
14
+	#01 ,color STR
15 15
 	( fill rect x y w h )
16
-	,0020 ,0020 ,0060 ,0040 ,fillrect JSR
16
+	#0020 #0020 #0060 #0040 ,fillrect JSR
17 17
 
18
-	,02 ,color STR
18
+	#02 ,color STR
19 19
 	( fill rect x y w h )
20
-	,0030 ,0030 ,0040 ,0060 ,fillrect JSR
20
+	#0030 #0030 #0040 #0060 ,fillrect JSR
21 21
 
22
-	,03 ,color STR
22
+	#03 ,color STR
23 23
 	( fill rect x y w h )
24
-	,0040 ,0040 ,0060 ,0040 ,fillrect JSR
24
+	#0040 #0040 #0060 #0040 ,fillrect JSR
25 25
 
26
-	,01 ,color STR
26
+	#01 ,color STR
27 27
 	( fill rect x y w h )
28
-	,00a0 ,0010 ,0020 ,0020 ,fillrect JSR
28
+	#00a0 #0010 #0020 #0020 ,fillrect JSR
29 29
 
30
-	,02 ,color STR
30
+	#02 ,color STR
31 31
 	( fill rect x y w h )
32
-	,00b0 ,0040 ,0020 ,0020 ,linerect JSR
32
+	#00b0 #0040 #0020 #0020 ,linerect JSR
33 33
 
34
-	,03 ,color STR
34
+	#03 ,color STR
35 35
 	( fill rect x y w h )
36
-	,0058 ,0028 ,0050 ,0050 ,linerect JSR
36
+	#0058 #0028 #0050 #0050 ,linerect JSR
37 37
 
38
-	,01 ,color STR
38
+	#01 ,color STR
39 39
 	( fill rect x y w h )
40
-	,0028 ,0038 ,0050 ,0030 ,linerect JSR
41
-
42
-	( positive )
43
-	,01 ,color STR
44
-	+0030 ,x0 STR2 +0040 ,y0 STR2
45
-	+0100 ,x1 STR2 +0060 ,y1 STR2
46
-	,line JSR
47
-
48
-	,02 ,color STR
49
-	+0020 ,x0 STR2 +0010 ,y0 STR2
50
-	+0090 ,x1 STR2 +0070 ,y1 STR2
51
-	,line JSR
52
-
53
-	,03 ,color STR
54
-	+0010 ,x0 STR2 +0040 ,y0 STR2
55
-	+0070 ,x1 STR2 +0060 ,y1 STR2
56
-	,line JSR
40
+	#0028 #0038 #0050 #0030 ,linerect JSR
57 41
 
58 42
 	,redraw JSR
59 43
 
... ...
@@ -66,9 +50,9 @@ BRK
66 50
 		,x LDR2 ,x_ STR2
67 51
 		@fillrectcol
68 52
 			( draw ) ,x_ LDR2 ,y_ LDR2 ,putpixel JSR
69
-			,x_ LDR2 ,0001 ADD2 ,x_ STR2 
53
+			,x_ LDR2 #0001 ADD2 ,x_ STR2 
70 54
 			,x_ LDR2 ,w LDR2 ,x LDR2 ADD2 LTH2 ,fillrectcol ROT JMP? POP2
71
-		,y_ LDR2 ,0001 ADD2 ,y_ STR2 
55
+		,y_ LDR2 #0001 ADD2 ,y_ STR2 
72 56
 		,y_ LDR2 ,h LDR2 ,y LDR2 ADD2 LTH2 ,fillrectrow ROT JMP? POP2
73 57
 	RTS
74 58
 
... ...
@@ -78,33 +62,13 @@ BRK
78 62
 	@linerectcol
79 63
 		( draw ) ,x LDR2 ,y_ LDR2 ,putpixel JSR
80 64
 		( draw ) ,x LDR2 ,w LDR2 ADD2 ,y_ LDR2 ,putpixel JSR
81
-		,y_ LDR2 ,0001 ADD2 ,y_ STR2 
65
+		,y_ LDR2 #0001 ADD2 ,y_ STR2 
82 66
 		,y_ LDR2 ,h LDR2 ,y LDR2 ADD2 LTH2 ,linerectcol ROT JMP? POP2
83 67
 	@linerectrow
84 68
 		( draw ) ,x_ LDR2 ,y LDR2 ,putpixel JSR
85 69
 		( draw ) ,x_ LDR2 ,y LDR2 ,h LDR2 ADD2 ,putpixel JSR
86
-		,x_ LDR2 ,0001 ADD2 ,x_ STR2 
87
-		,x_ LDR2 ,w LDR2 ,x LDR2 ADD2 ,0001 ADD2 LTH2 ,linerectrow ROT JMP? POP2
88
-	RTS
89
-
90
-@line
91
-	,x0 LDR2 ,x_ STR2 ,y0 LDR2 ,y_ STR2                   ( start at x0,y0 )
92
-	,x1 LDR2 ,x0 LDR2 ,diff16sub JSR ,dx STR2             ( int dx = abs[x1 - x0] )
93
-	,y1 LDR2 ,y0 LDR2 ,diff16sub JSR -0001 MULS2 ,dy STR2 ( int dy = -abs[y1 - y0] )
94
-	,dx LDR2 ,dy LDR2 ADDS2 ,err1 STR2                    ( int err1 = dx + dy, e2; )
95
-	@lineloop
96
-	,x_ LDR2 ,y_ LDR2 ,putpixel JSR                       ( draw )
97
-	@line-x
98
-	,err1 LDR2 +0002 MULS2 ,err2 STR2                     ( e2 = 2 * err; )
99
-	,err2 LDR2 ,dy LDR2 LTHS2 ,line-y ROT JMP? POP2 	  ( e2 >= dy )
100
-		,err1 LDR2 ,dy LDR2 ADDS2 ,err1 STR2 			  ( err1 += dy; )
101
-		,x_ LDR2 +0001 ADDS2 ,x_ STR2                     ( y0 += y0 < y1 ? 1 : -1; )
102
-	@line-y
103
-	,err2 LDR2 ,dx LDR2 GTHS2 ,line-end ROT JMP? POP2     ( e2 <= dx )
104
-		,err1 LDR2 ,dx LDR2 ADDS2 ,err1 STR2              ( err1 += dx; )
105
-		,y_ LDR2 +0001 ADDS2 ,y_ STR2                     ( y0 += y0 < y1 ? 1 : -1; )
106
-	@line-end
107
-	,x_ LDR2 ,x1 LDR2 NEQS2 ,lineloop ROT JMP? POP2       ( loop )
70
+		,x_ LDR2 #0001 ADD2 ,x_ STR2 
71
+		,x_ LDR2 ,w LDR2 ,x LDR2 ADD2 #0001 ADD2 LTH2 ,linerectrow ROT JMP? POP2
108 72
 	RTS
109 73
 
110 74
 @diff16
... ...
@@ -113,17 +77,17 @@ BRK
113 77
 RTS
114 78
 
115 79
 @redraw
116
-	,0000 IOW2
117
-	,0000 IOW2
118
-	,00 IOW
119
-	,01 IOW
80
+	#0000 IOW2
81
+	#0000 IOW2
82
+	#00 IOW
83
+	#01 IOW
120 84
 	RTS
121 85
 
122 86
 @putpixel 
123 87
 	IOW2 ( y short )
124 88
 	IOW2 ( x short )
125 89
 	,color LDR IOW  ( color byte )
126
-	,00 IOW  ( redraw byte )
90
+	#00 IOW  ( redraw byte )
127 91
 	RTS
128 92
 
129 93
 |c000 @FRAME BRK 
... ...
@@ -1,25 +1,21 @@
1
-( hello world, to console )
1
+( comment )
2 2
 
3 3
 :dev/w fff9 ( const write port )
4
-;i 1 ( var iterator )
5 4
 
6
-|0100 @RESET
7
-
8
-	#00 ,dev/w STR              ( set dev/write to console ) 
9
-
10
-	@word1 "hello_world         ( len: 0x0b )
5
+|0100 @RESET 
11 6
 
7
+	#00 ,dev/w STR                        ( set dev/write to console ) 
8
+	,string                               ( add string pointer to stack )
12 9
 	@loop
13
-		IOW                     ( write to device#0 )
14
-		,i LDR #01 ADD ,i STR   ( increment itr )
15
-		,i LDR                  ( a = i )
16
-		,word1 ,strlen JSR      ( b = string length )
17
-		NEQ ,loop ROT JSR? POP^ ( a != b ? loop )
10
+		DUP2 LDR IOW                         ( write pointer value to console )
11
+		#0001 ADD2                           ( increment string pointer )
12
+		DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
18 13
 
19 14
 BRK
20 15
 
21
-@strlen #0001 ADD2 LDR RTS
16
+@string " Hello World "                ( add string to memory )
22 17
 
23
-|c000 @FRAME BRK 
18
+|c000 @FRAME BRK
24 19
 |d000 @ERROR BRK 
20
+
25 21
 |FFFA .RESET .FRAME .ERROR
... ...
@@ -1,16 +1,21 @@
1 1
 ( comment )
2 2
 
3
-:const abcd
4
-;byte 1
5
-;short 2
3
+:dev/w fff9 ( const write port )
6 4
 
7 5
 |0100 @RESET 
8 6
 
9
-	12 34 ADD
10
-	1234 0001 ADD2
7
+	#00 ,dev/w STR                           ( set dev/write to console ) 
8
+	,string                                  ( add string pointer to stack )
9
+	@loop
10
+		DUP2 LDR IOW                         ( write pointer value to console )
11
+		#0001 ADD2                           ( increment string pointer )
12
+		DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
11 13
 
12 14
 BRK
13 15
 
16
+@string " Hello World "                      ( add string to memory )
17
+
14 18
 |c000 @FRAME BRK
15 19
 |d000 @ERROR BRK 
20
+
16 21
 |FFFA .RESET .FRAME .ERROR
... ...
@@ -31,7 +31,7 @@ Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); }
31 31
 Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
32 32
 /* I/O */
33 33
 void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
34
-void op_li1(Uxn *u) { u->literal += 1; }
34
+void op_lit(Uxn *u) { u->literal += 1; }
35 35
 void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
36 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))); }
... ...
@@ -61,6 +61,7 @@ void op_neq(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst,
61 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 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
+void op_lit16(Uxn *u) { u->literal += 2; }
64 65
 void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); }
65 66
 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)); }
66 67
 void op_iow16(Uxn *u) { Uint8 a = pop8(&u->wst); Uint8 b = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) { dev->write(dev, b); dev->write(dev, a); } }
... ...
@@ -86,12 +87,12 @@ void op_gth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u-
86 87
 void op_lth16(Uxn *u) { Uint16 a = pop16(&u->wst), b = pop16(&u->wst); push8(&u->wst, getflag(&u->status, FLAG_SIGN) ? (Sint16)b < (Sint16)a : b < a); }
87 88
 
88 89
 void (*ops[])(Uxn *u) = {
89
-	op_brk, op_nop, op_li1, op_lix, op_ior, op_iow, op_ldr, op_str, 
90
+	op_brk, op_nop, op_lit, op_lix, op_ior, op_iow, op_ldr, op_str, 
90 91
 	op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, 
91 92
 	op_pop, op_dup, op_swp, op_ovr, op_rot, op_and, op_ora, op_rol,
92 93
 	op_add, op_sub, op_mul, op_div, op_equ, op_neq, op_gth, op_lth,
93 94
 	/* 16-bit */
94
-	op_brk, op_nop16, op_li1, op_lix, op_ior16, op_iow16, op_ldr16, op_str16, 
95
+	op_brk, op_nop16, op_lit16, op_lix, op_ior16, op_iow16, op_ldr16, op_str16, 
95 96
 	op_jmp, op_jsr, op_nop, op_rts, op_nop, op_nop, op_nop, op_nop, 
96 97
 	op_pop16, op_dup16, op_swp16, op_ovr16, op_rot16, op_and16, op_ora16, op_rol16,
97 98
 	op_add16, op_sub16, op_mul16, op_div16, op_equ16, op_neq16, op_gth16, op_lth16