Browse code

Added helper for LDR/STR

neauoire authored on 15/02/2021 01:00:17
Showing 12 changed files
... ...
@@ -30,11 +30,6 @@ evaluxn(u, u->vframe); /* Each frame
30 30
 - `;variable 2`, assign an address to a label automatically.
31 31
 - `:const 1a2b`, assign an address to a label manually.
32 32
 
33
-### Read
34
-
35
-- `,literal`, push label value to stack, prefixed with `LIT LEN`.
36
-- `.pointer`, push label value to stack.
37
-
38 33
 ### Write
39 34
 
40 35
 - `ADD`, an opcode.
... ...
@@ -46,18 +41,22 @@ evaluxn(u, u->vframe); /* Each frame
46 41
 - `-12ef`, a literal signed short(negative).
47 42
 - `.ab`, a raw byte in memory.
48 43
 - `.abcd`, a raw short in memory.
44
+- `,literal`, push label address to stack, prefixed with `LIT LEN`.
49 45
 
50 46
 ### Special
51 47
 
52 48
 - `( comment )`, toggle parsing on/off.
53 49
 - `|0010`, move to position in the program.
54 50
 - `"hello`, push literal bytes for word "hello".
51
+- `=label`, helper to STR, equivalent to `,label STR`, or `label STR2`.
52
+- `~label`, helper to LDR, equivalent to `,label LDR2`, or `,label LDR2`.
55 53
 
56 54
 ### Operator modes
57 55
 
58 56
 - `#1234 #0001 ADD2`, 16-bits operators have the short flag `2`.
59 57
 - `#12 #11 GTH JMP?`, conditional operators have the cond flag `?`.
60 58
 - `+21 -03 MULS`, signed operators have the cond flag `S`.
59
+- `ADDS2?`, modes can be combined.
61 60
 
62 61
 ```
63 62
 ( comment )
... ...
@@ -66,8 +65,7 @@ evaluxn(u, u->vframe); /* Each frame
66 65
 
67 66
 |0100 @RESET 
68 67
 
69
-	#00 ,dev/w STR                        ( set dev/write to console ) 
70
-	,string                               ( add string pointer to stack )
68
+	,string                                  ( add string pointer to stack )
71 69
 	@loop
72 70
 		DUP2 LDR IOW                         ( write pointer value to console )
73 71
 		#0001 ADD2                           ( increment string pointer )
... ...
@@ -75,7 +73,7 @@ evaluxn(u, u->vframe); /* Each frame
75 73
 
76 74
 BRK
77 75
 
78
-@string " Hello World "                ( add string to memory )
76
+@string " Hello World "                      ( add string to memory )
79 77
 
80 78
 |c000 @FRAME BRK
81 79
 |d000 @ERROR BRK 
... ...
@@ -89,28 +87,28 @@ BRK
89 87
 
90 88
 A device that works like a NES controller, each button is a bit from a single byte.
91 89
 
92
-- Ctrl
93
-- Alt
94
-- Escape
95
-- Return
96
-- Up
97
-- Down
98
-- Left
99
-- Right
90
+- `0x01` Ctrl
91
+- `0x02` Alt
92
+- `0x04` Escape
93
+- `0x08` Return
94
+- `0x10` Up
95
+- `0x20` Down
96
+- `0x40` Left
97
+- `0x80` Right
100 98
 
101 99
 ## TODOs
102 100
 
103
-- Defines?
104 101
 - LDR/STR helpers
105
-- Keyboard example
106
-- PPU chr device
107 102
 - Line routine
108 103
 - On-screen debugger.
109
-- Auto-advance ldr?
110 104
 - Getting rid of IOR/IOW would be nice..
111
-- Sending from the wst to the rst, balance mode/flag?
112
-- Device that works like an extra memory bank
113
-- [debug]Print unused labels
105
+- Sending from the wst to the rst, balance counter?
106
+
107
+### Misc TODOs
108
+
109
+- Includes
110
+- Defines
111
+- Lint, print unused labels
114 112
 
115 113
 ## Refs
116 114
 
... ...
@@ -22,6 +22,7 @@ typedef struct {
22 22
 } Program;
23 23
 
24 24
 typedef struct {
25
+	Uint8 len;
25 26
 	Uint16 addr;
26 27
 	char name[64];
27 28
 } Label;
... ...
@@ -33,7 +34,7 @@ Program p;
33 34
 /* clang-format off */
34 35
 
35 36
 char ops[][4] = {
36
-	"BRK", "NOP", "LIT", "LIX", "IOR", "IOW", "LDR", "STR",
37
+	"BRK", "NOP", "LIT", "---", "IOR", "IOW", "LDR", "STR",
37 38
 	"JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---",
38 39
 	"POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL",
39 40
 	"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH"
... ...
@@ -108,7 +109,7 @@ error(char *name, char *id)
108 109
 }
109 110
 
110 111
 int
111
-makelabel(char *name, Uint16 addr)
112
+makelabel(char *name, Uint16 addr, Uint8 len)
112 113
 {
113 114
 	Label *l;
114 115
 	if(findlabel(name))
... ...
@@ -119,8 +120,9 @@ makelabel(char *name, Uint16 addr)
119 120
 		return error("Label name is invalid", name);
120 121
 	l = &labels[labelslen++];
121 122
 	l->addr = addr;
123
+	l->len = len;
122 124
 	scpy(name, l->name, 64);
123
-	printf("New label: %s[0x%02x]\n", l->name, l->addr);
125
+	printf("New label: %s, at 0x%02x[%d]\n", l->name, l->addr, l->len);
124 126
 	return 1;
125 127
 }
126 128
 
... ...
@@ -129,7 +131,7 @@ makeconst(char *id, FILE *f)
129 131
 {
130 132
 	char wv[64];
131 133
 	fscanf(f, "%s", wv);
132
-	return makelabel(id, shex(wv));
134
+	return makelabel(id, shex(wv), 1);
133 135
 }
134 136
 
135 137
 int
... ...
@@ -140,7 +142,7 @@ makevariable(char *id, Uint16 *addr, FILE *f)
140 142
 	fscanf(f, "%s", wv);
141 143
 	origin = *addr;
142 144
 	*addr += shex(wv);
143
-	return makelabel(id, origin);
145
+	return makelabel(id, origin, shex(wv));
144 146
 }
145 147
 
146 148
 int
... ...
@@ -200,7 +202,7 @@ pass1(FILE *f)
200 202
 		if(skipcomment(w, &ccmnt)) continue;
201 203
 		if(skipstring(w, &cstrg, &addr)) continue;
202 204
 		if(w[0] == '@') {
203
-			if(!makelabel(w + 1, addr))
205
+			if(!makelabel(w + 1, addr, 0))
204 206
 				return error("Pass1 failed", w);
205 207
 		} else if(w[0] == ';') {
206 208
 			if(!makevariable(w + 1, &addr, f))
... ...
@@ -213,6 +215,8 @@ pass1(FILE *f)
213 215
 		else {
214 216
 			switch(w[0]) {
215 217
 			case '|': addr = shex(w + 1); break;
218
+			case '=': addr += 4; break; /* STR helper */
219
+			case '~': addr += 4; break; /* LDR helper */
216 220
 			case ',': addr += 3; break;
217 221
 			case '.': addr += (slen(w + 1) == 2 ? 1 : 2); break;
218 222
 			case '+': /* signed positive */
... ...
@@ -250,6 +254,8 @@ pass2(FILE *f)
250 254
 		else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
251 255
 		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
252 256
 		else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
257
+		else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "STR2" : "STR"),0); }
258
+		else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "LDR2" : "LDR"),0); }
253 259
 		else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
254 260
 		else return error("Unknown label in second pass", w);
255 261
 		/* clang-format on */
... ...
@@ -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/controller.usm bin/boot.rom
27
+./bin/assembler examples/sprite.usm bin/boot.rom
28 28
 ./bin/emulator bin/boot.rom
... ...
@@ -54,7 +54,7 @@ void
54 54
 putpixel(Uint32 *dst, int x, int y, int color)
55 55
 {
56 56
 	if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8)
57
-		dst[(y + PAD * 8) * WIDTH + (x + PAD * 8)] = theme[color];
57
+		dst[y * WIDTH + x] = theme[color];
58 58
 }
59 59
 
60 60
 void
... ...
@@ -190,6 +190,7 @@ domouse(SDL_Event *event)
190 190
 void
191 191
 dokey(SDL_Event *event)
192 192
 {
193
+	(void)event;
193 194
 }
194 195
 
195 196
 void
... ...
@@ -218,16 +219,18 @@ consoler(Device *d, Memory *m, Uint8 b)
218 219
 {
219 220
 	(void)b;
220 221
 	(void)d;
222
+	(void)m;
221 223
 	return 0;
222 224
 }
223 225
 
224 226
 Uint8
225 227
 consolew(Device *d, Memory *m, Uint8 b)
226 228
 {
227
-	(void)d;
228 229
 	if(b)
229 230
 		printf("%c", b);
230 231
 	fflush(stdout);
232
+	(void)d;
233
+	(void)m;
231 234
 	return 0;
232 235
 }
233 236
 
... ...
@@ -7,12 +7,10 @@
7 7
 
8 8
 |0100 @RESET 
9 9
 
10
-	#05 ,dev/r STR                           ( set dev/read to ctrl ) 
11
-	#04 ,dev/w STR                           ( set dev/write to ppu-sprite ) 
12
-
13
-	#0080 ,x STR2
14
-	#0040 ,y STR2
15
-	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
10
+	#05 =dev/r ( set dev/read to ctrl ) 
11
+	#04 =dev/w ( set dev/write to ppu-sprite ) 
12
+	#0080 =x #0040 =y ( origin )
13
+	#01 ,cursor_icn ~x ~y ,putsprite JSR ( draw sprite )
16 14
 
17 15
 BRK
18 16
 
... ...
@@ -26,19 +24,23 @@ BRK
26 24
 |c000 @FRAME 
27 25
 
28 26
 	#00 IOR #10 NEQ ,next0 ROT JMP? POP2
29
-	,y LDR2 #0001 SUB2 ,y STR2
27
+		~y #0001 SUB2 =y
30 28
 	@next0
29
+
31 30
 	#00 IOR #20 NEQ ,next1 ROT JMP? POP2
32
-	,y LDR2 #0001 ADD2 ,y STR2
31
+		~y #0001 ADD2 =y
32
+
33 33
 	@next1
34 34
 	#00 IOR #40 NEQ ,next2 ROT JMP? POP2
35
-	,x LDR2 #0001 SUB2 ,x STR2
35
+		~x #0001 SUB2 =x
36
+
36 37
 	@next2
37
-	#00 IOR #80 NEQ ,next3 ROT JMP? POP2
38
-	,x LDR2 #0001 ADD2 ,x STR2
39
-	@next3
38
+	#00 IOR #80 NEQ ,end ROT JMP? POP2
39
+		~x #0001 ADD2 =x
40
+
41
+	@end
40 42
 	( redraw )
41
-	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
43
+	#01 ,cursor_icn ~x ~y ,putsprite JSR
42 44
 
43 45
 BRK
44 46
 
... ...
@@ -4,7 +4,6 @@
4 4
 
5 5
 |0100 @RESET 
6 6
 
7
-	#00 ,dev/w STR                           ( set dev/write to console ) 
8 7
 	,string                                  ( add string pointer to stack )
9 8
 	@loop
10 9
 		DUP2 LDR IOW                         ( write pointer value to console )
... ...
@@ -18,4 +17,4 @@ BRK
18 17
 |c000 @FRAME BRK
19 18
 |d000 @ERROR BRK 
20 19
 
21
-|FFFA .RESET .FRAME .ERROR
20
+|FFFA .RESET .FRAME .ERROR
22 21
\ No newline at end of file
... ...
@@ -5,8 +5,8 @@
5 5
 
6 6
 |0100 @RESET 
7 7
 	
8
-	#02 ,dev/r STR ( set dev/read mouse#02 )
9
-	#01 ,dev/w STR ( set dev/write screen#01 )
8
+	#02 =dev/r ( set dev/read mouse#02 )
9
+	#01 =dev/w ( set dev/write screen#01 )
10 10
 
11 11
 BRK
12 12
 
... ...
@@ -7,29 +7,28 @@
7 7
 
8 8
 |0100 @RESET 
9 9
 	
10
-	#01 ,dev/w STR ( set dev/write to screen ) 
11
-	#01 ,color STR ( set color ) 	
12
-	#0020 ,x STR2 ( set x-pos )
13
-	#0030 ,y STR2 ( set y-pos )
14
-	#01 ,alive STR ( set alive = true )
10
+	#01 =dev/w ( set dev/write to screen ) 
11
+	#01 =color ( set color ) 	
12
+	#0020 =x #0030 =y ( set origin )
13
+	#01 =alive ( set alive = true )
15 14
 
16 15
 BRK
17 16
 
18 17
 |c000 @FRAME 
19 18
 
20
-	,alive LDR #00 EQU BRK?
21
-	#01 ,color LDR ,x LDR2 ,y LDR2 ,putpixel JSR
19
+	~alive #00 EQU BRK?
20
+	#01 ~color ~x ~y ,putpixel JSR
22 21
 	,move JSR
23 22
 
24 23
 BRK
25 24
 
26 25
 @move
27
-	,x LDR2 #0001 ADD2 ,x STR2 ( incr x )
28
-	,x LDR2 #0040 LTH2 RTS?    ( if x > 60 )
29
-	#0020 ,x STR2              ( x = 0x0020 )
30
-	,y LDR2 #0001 ADD2 ,y STR2 ( incr y )
31
-	,y LDR2 #0050 LTH2 RTS?    ( y > 50 )
32
-	#00 ,alive STR             ( alive = 0 )
26
+	~x #0001 ADD2 =x      ( incr x )
27
+	~x #0040 LTH2 RTS?    ( if x > 60 )
28
+	#0020 =x              ( x = 0x0020 )
29
+	~y #0001 ADD2 =y      ( incr y )
30
+	~y #0050 LTH2 RTS?    ( y > 50 )
31
+	#00 ,alive STR        ( alive = 0 )
33 32
 	RTS
34 33
 
35 34
 @putpixel 
... ...
@@ -2,22 +2,22 @@
2 2
 
3 3
 :dev/r fff8 ( std read port )
4 4
 :dev/w fff9 ( std write port )
5
-;width 2
6
-;height 2
5
+
6
+;width 2 ;height 2
7 7
 
8 8
 |0100 @RESET 
9 9
 	
10 10
 	( set read/write to dev/screen )
11
-	#01 DUP ,dev/r STR ,dev/w STR 
11
+	#01 DUP =dev/r =dev/w 
12 12
 
13 13
 	( load screen size )
14
-	#00 IOR2 ,width STR2
15
-	#02 IOR2 ,height STR2
14
+	#00 IOR2 =width
15
+	#02 IOR2 =height
16 16
 
17 17
 	( draw pixel at screen center )
18 18
 	#0101 
19
-	,width LDR2 #0002 DIV2 
20
-	,height LDR2 #0002 DIV2 
19
+	~width #0002 DIV2 
20
+	~height #0002 DIV2 
21 21
 	,putpixel JSR
22 22
 
23 23
 BRK
... ...
@@ -4,14 +4,10 @@
4 4
 
5 5
 |0100 @RESET 
6 6
 
7
-	#01 ,dev/w STR                           ( set dev/write to screen ) 
7
+	#01 =dev/w                           ( set dev/write to screen ) 
8
+	#04 =dev/w                           ( set dev/write to ppu-sprite ) 
8 9
 
9
-	( draw 1 pixel )
10
-	#00 #01 #0021 #0021 ,putpixel JSR
11
-
12
-	#04 ,dev/w STR                           ( set dev/write to screen ) 
13
-
14
-	#00 ,star_icn #0001 #0001 ,putsprite JSR
10
+	#00 ,star_icn #0041 #0041 ,putsprite JSR
15 11
 	#00 ,star_icn #0031 #0021 ,putsprite JSR
16 12
 	#00 ,cursor_icn #0021 #0016 ,putsprite JSR
17 13
 	#00 ,star_icn #0055 #0042 ,putsprite JSR
... ...
@@ -1,54 +1,24 @@
1
-( comment )
1
+( blank )
2 2
 
3
-:dev/r fff8 ( const read port )
4
-:dev/w fff9 ( const write port )
3
+:dev/r fff8 ( std read port )
4
+:dev/w fff9 ( std write port )
5 5
 
6
-;x 2 ;y 2
6
+:test 0010
7 7
 
8
-|0100 @RESET 
8
+;x 1 ;y 2
9 9
 
10
-	#05 ,dev/r STR                           ( set dev/read to ctrl ) 
11
-	#04 ,dev/w STR                           ( set dev/write to ppu-sprite ) 
10
+|0100 @RESET
12 11
 
13
-	#0080 ,x STR2
14
-	#0040 ,y STR2
15
-	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
12
+	#12 =x
13
+	#1234 =y
14
+	~x
15
+	~y
16 16
 
17
-BRK
18
-
19
-|0200 @SPRITESHEET
20
-
21
-@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
22
-@star_icn   .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
17
+	#ef =test
23 18
 
24 19
 BRK
25 20
 
26
-|c000 @FRAME 
27
-
28
-	#00 IOR #10 NEQ ,next0 ROT JMP? POP2
29
-	,y LDR2 #0001 SUB2 ,y STR2
30
-	@next0
31
-	#00 IOR #20 NEQ ,next1 ROT JMP? POP2
32
-	,y LDR2 #0001 ADD2 ,y STR2
33
-	@next1
34
-	#00 IOR #40 NEQ ,next2 ROT JMP? POP2
35
-	,x LDR2 #0001 SUB2 ,x STR2
36
-	@next2
37
-	#00 IOR #80 NEQ ,next3 ROT JMP? POP2
38
-	,x LDR2 #0001 ADD2 ,x STR2
39
-	@next3
40
-	( redraw )
41
-	#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
42
-
43
-BRK
44
-
45
-@putsprite
46
-	IOW2 ( y short )
47
-	IOW2 ( x short )
48
-	IOW2 ( sprite address )
49
-	IOW  ( redraw byte )
50
-	RTS
51
-
21
+|c000 @FRAME BRK 
52 22
 |d000 @ERROR BRK 
53 23
 
54 24
 |FFFA .RESET .FRAME .ERROR
... ...
@@ -16,7 +16,6 @@ WITH REGARD TO THIS SOFTWARE.
16 16
 #pragma mark - Operations
17 17
 
18 18
 /* clang-format off */
19
-
20 19
 void   setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *a &= (~flag); }
21 20
 int    getflag(Uint8 *a, char flag) { return *a & flag; }
22 21
 void   mempoke8(Memory *m, Uint16 a, Uint8 b) { m->dat[a] = b; }