Added helper for LDR/STR

This commit is contained in:
neauoire 2021-02-14 17:00:17 -08:00
parent 1cc7abea54
commit 256d72e340
12 changed files with 92 additions and 120 deletions

View File

@ -30,11 +30,6 @@ evaluxn(u, u->vframe); /* Each frame
- `;variable 2`, assign an address to a label automatically.
- `:const 1a2b`, assign an address to a label manually.
### Read
- `,literal`, push label value to stack, prefixed with `LIT LEN`.
- `.pointer`, push label value to stack.
### Write
- `ADD`, an opcode.
@ -46,18 +41,22 @@ evaluxn(u, u->vframe); /* Each frame
- `-12ef`, a literal signed short(negative).
- `.ab`, a raw byte in memory.
- `.abcd`, a raw short in memory.
- `,literal`, push label address to stack, prefixed with `LIT LEN`.
### Special
- `( comment )`, toggle parsing on/off.
- `|0010`, move to position in the program.
- `"hello`, push literal bytes for word "hello".
- `=label`, helper to STR, equivalent to `,label STR`, or `label STR2`.
- `~label`, helper to LDR, equivalent to `,label LDR2`, or `,label LDR2`.
### Operator modes
- `#1234 #0001 ADD2`, 16-bits operators have the short flag `2`.
- `#12 #11 GTH JMP?`, conditional operators have the cond flag `?`.
- `+21 -03 MULS`, signed operators have the cond flag `S`.
- `ADDS2?`, modes can be combined.
```
( comment )
@ -66,8 +65,7 @@ evaluxn(u, u->vframe); /* Each frame
|0100 @RESET
#00 ,dev/w STR ( set dev/write to console )
,string ( add string pointer to stack )
,string ( add string pointer to stack )
@loop
DUP2 LDR IOW ( write pointer value to console )
#0001 ADD2 ( increment string pointer )
@ -75,7 +73,7 @@ evaluxn(u, u->vframe); /* Each frame
BRK
@string " Hello World " ( add string to memory )
@string " Hello World " ( add string to memory )
|c000 @FRAME BRK
|d000 @ERROR BRK
@ -89,28 +87,28 @@ BRK
A device that works like a NES controller, each button is a bit from a single byte.
- Ctrl
- Alt
- Escape
- Return
- Up
- Down
- Left
- Right
- `0x01` Ctrl
- `0x02` Alt
- `0x04` Escape
- `0x08` Return
- `0x10` Up
- `0x20` Down
- `0x40` Left
- `0x80` Right
## TODOs
- Defines?
- LDR/STR helpers
- Keyboard example
- PPU chr device
- Line routine
- On-screen debugger.
- Auto-advance ldr?
- Getting rid of IOR/IOW would be nice..
- Sending from the wst to the rst, balance mode/flag?
- Device that works like an extra memory bank
- [debug]Print unused labels
- Sending from the wst to the rst, balance counter?
### Misc TODOs
- Includes
- Defines
- Lint, print unused labels
## Refs

View File

@ -22,6 +22,7 @@ typedef struct {
} Program;
typedef struct {
Uint8 len;
Uint16 addr;
char name[64];
} Label;
@ -33,7 +34,7 @@ Program p;
/* clang-format off */
char ops[][4] = {
"BRK", "NOP", "LIT", "LIX", "IOR", "IOW", "LDR", "STR",
"BRK", "NOP", "LIT", "---", "IOR", "IOW", "LDR", "STR",
"JMP", "JSR", "RTI", "RTS", "---", "---", "---", "---",
"POP", "DUP", "SWP", "OVR", "ROT", "AND", "ORA", "ROL",
"ADD", "SUB", "MUL", "DIV", "EQU", "NEQ", "GTH", "LTH"
@ -108,7 +109,7 @@ error(char *name, char *id)
}
int
makelabel(char *name, Uint16 addr)
makelabel(char *name, Uint16 addr, Uint8 len)
{
Label *l;
if(findlabel(name))
@ -119,8 +120,9 @@ makelabel(char *name, Uint16 addr)
return error("Label name is invalid", name);
l = &labels[labelslen++];
l->addr = addr;
l->len = len;
scpy(name, l->name, 64);
printf("New label: %s[0x%02x]\n", l->name, l->addr);
printf("New label: %s, at 0x%02x[%d]\n", l->name, l->addr, l->len);
return 1;
}
@ -129,7 +131,7 @@ makeconst(char *id, FILE *f)
{
char wv[64];
fscanf(f, "%s", wv);
return makelabel(id, shex(wv));
return makelabel(id, shex(wv), 1);
}
int
@ -140,7 +142,7 @@ makevariable(char *id, Uint16 *addr, FILE *f)
fscanf(f, "%s", wv);
origin = *addr;
*addr += shex(wv);
return makelabel(id, origin);
return makelabel(id, origin, shex(wv));
}
int
@ -200,7 +202,7 @@ pass1(FILE *f)
if(skipcomment(w, &ccmnt)) continue;
if(skipstring(w, &cstrg, &addr)) continue;
if(w[0] == '@') {
if(!makelabel(w + 1, addr))
if(!makelabel(w + 1, addr, 0))
return error("Pass1 failed", w);
} else if(w[0] == ';') {
if(!makevariable(w + 1, &addr, f))
@ -213,6 +215,8 @@ pass1(FILE *f)
else {
switch(w[0]) {
case '|': addr = shex(w + 1); break;
case '=': addr += 4; break; /* STR helper */
case '~': addr += 4; break; /* LDR helper */
case ',': addr += 3; break;
case '.': addr += (slen(w + 1) == 2 ? 1 : 2); break;
case '+': /* signed positive */
@ -250,6 +254,8 @@ pass2(FILE *f)
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)shex(w + 1), 1);
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);
else if(w[0] == '-' && sihx(w + 1) && slen(w + 1) == 4) pushshort((Sint16)(shex(w + 1) * -1), 1);
else if(w[0] == '=' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "STR2" : "STR"),0); }
else if(w[0] == '~' && (l = findlabel(w + 1)) && l->len){ pushshort(l->addr, 1); pushbyte(findopcode(l->len == 2 ? "LDR2" : "LDR"),0); }
else if((l = findlabel(w + 1))) pushshort(l->addr, w[0] == ',');
else return error("Unknown label in second pass", w);
/* clang-format on */

View File

@ -24,5 +24,5 @@ rm -f ./bin/emulator
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
# run
./bin/assembler examples/controller.usm bin/boot.rom
./bin/assembler examples/sprite.usm bin/boot.rom
./bin/emulator bin/boot.rom

View File

@ -54,7 +54,7 @@ void
putpixel(Uint32 *dst, int x, int y, int color)
{
if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8)
dst[(y + PAD * 8) * WIDTH + (x + PAD * 8)] = theme[color];
dst[y * WIDTH + x] = theme[color];
}
void
@ -190,6 +190,7 @@ domouse(SDL_Event *event)
void
dokey(SDL_Event *event)
{
(void)event;
}
void
@ -218,16 +219,18 @@ consoler(Device *d, Memory *m, Uint8 b)
{
(void)b;
(void)d;
(void)m;
return 0;
}
Uint8
consolew(Device *d, Memory *m, Uint8 b)
{
(void)d;
if(b)
printf("%c", b);
fflush(stdout);
(void)d;
(void)m;
return 0;
}

View File

@ -7,12 +7,10 @@
|0100 @RESET
#05 ,dev/r STR ( set dev/read to ctrl )
#04 ,dev/w STR ( set dev/write to ppu-sprite )
#0080 ,x STR2
#0040 ,y STR2
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
#05 =dev/r ( set dev/read to ctrl )
#04 =dev/w ( set dev/write to ppu-sprite )
#0080 =x #0040 =y ( origin )
#01 ,cursor_icn ~x ~y ,putsprite JSR ( draw sprite )
BRK
@ -26,19 +24,23 @@ BRK
|c000 @FRAME
#00 IOR #10 NEQ ,next0 ROT JMP? POP2
,y LDR2 #0001 SUB2 ,y STR2
~y #0001 SUB2 =y
@next0
#00 IOR #20 NEQ ,next1 ROT JMP? POP2
,y LDR2 #0001 ADD2 ,y STR2
~y #0001 ADD2 =y
@next1
#00 IOR #40 NEQ ,next2 ROT JMP? POP2
,x LDR2 #0001 SUB2 ,x STR2
~x #0001 SUB2 =x
@next2
#00 IOR #80 NEQ ,next3 ROT JMP? POP2
,x LDR2 #0001 ADD2 ,x STR2
@next3
#00 IOR #80 NEQ ,end ROT JMP? POP2
~x #0001 ADD2 =x
@end
( redraw )
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
#01 ,cursor_icn ~x ~y ,putsprite JSR
BRK

View File

@ -4,7 +4,6 @@
|0100 @RESET
#00 ,dev/w STR ( set dev/write to console )
,string ( add string pointer to stack )
@loop
DUP2 LDR IOW ( write pointer value to console )
@ -18,4 +17,4 @@ BRK
|c000 @FRAME BRK
|d000 @ERROR BRK
|FFFA .RESET .FRAME .ERROR
|FFFA .RESET .FRAME .ERROR

View File

@ -5,8 +5,8 @@
|0100 @RESET
#02 ,dev/r STR ( set dev/read mouse#02 )
#01 ,dev/w STR ( set dev/write screen#01 )
#02 =dev/r ( set dev/read mouse#02 )
#01 =dev/w ( set dev/write screen#01 )
BRK

View File

@ -7,29 +7,28 @@
|0100 @RESET
#01 ,dev/w STR ( set dev/write to screen )
#01 ,color STR ( set color )
#0020 ,x STR2 ( set x-pos )
#0030 ,y STR2 ( set y-pos )
#01 ,alive STR ( set alive = true )
#01 =dev/w ( set dev/write to screen )
#01 =color ( set color )
#0020 =x #0030 =y ( set origin )
#01 =alive ( set alive = true )
BRK
|c000 @FRAME
,alive LDR #00 EQU BRK?
#01 ,color LDR ,x LDR2 ,y LDR2 ,putpixel JSR
~alive #00 EQU BRK?
#01 ~color ~x ~y ,putpixel JSR
,move JSR
BRK
@move
,x LDR2 #0001 ADD2 ,x STR2 ( incr x )
,x LDR2 #0040 LTH2 RTS? ( if x > 60 )
#0020 ,x STR2 ( x = 0x0020 )
,y LDR2 #0001 ADD2 ,y STR2 ( incr y )
,y LDR2 #0050 LTH2 RTS? ( y > 50 )
#00 ,alive STR ( alive = 0 )
~x #0001 ADD2 =x ( incr x )
~x #0040 LTH2 RTS? ( if x > 60 )
#0020 =x ( x = 0x0020 )
~y #0001 ADD2 =y ( incr y )
~y #0050 LTH2 RTS? ( y > 50 )
#00 ,alive STR ( alive = 0 )
RTS
@putpixel

View File

@ -2,22 +2,22 @@
:dev/r fff8 ( std read port )
:dev/w fff9 ( std write port )
;width 2
;height 2
;width 2 ;height 2
|0100 @RESET
( set read/write to dev/screen )
#01 DUP ,dev/r STR ,dev/w STR
#01 DUP =dev/r =dev/w
( load screen size )
#00 IOR2 ,width STR2
#02 IOR2 ,height STR2
#00 IOR2 =width
#02 IOR2 =height
( draw pixel at screen center )
#0101
,width LDR2 #0002 DIV2
,height LDR2 #0002 DIV2
~width #0002 DIV2
~height #0002 DIV2
,putpixel JSR
BRK

View File

@ -4,14 +4,10 @@
|0100 @RESET
#01 ,dev/w STR ( set dev/write to screen )
#01 =dev/w ( set dev/write to screen )
#04 =dev/w ( set dev/write to ppu-sprite )
( draw 1 pixel )
#00 #01 #0021 #0021 ,putpixel JSR
#04 ,dev/w STR ( set dev/write to screen )
#00 ,star_icn #0001 #0001 ,putsprite JSR
#00 ,star_icn #0041 #0041 ,putsprite JSR
#00 ,star_icn #0031 #0021 ,putsprite JSR
#00 ,cursor_icn #0021 #0016 ,putsprite JSR
#00 ,star_icn #0055 #0042 ,putsprite JSR

View File

@ -1,54 +1,24 @@
( comment )
( blank )
:dev/r fff8 ( const read port )
:dev/w fff9 ( const write port )
:dev/r fff8 ( std read port )
:dev/w fff9 ( std write port )
;x 2 ;y 2
:test 0010
|0100 @RESET
;x 1 ;y 2
#05 ,dev/r STR ( set dev/read to ctrl )
#04 ,dev/w STR ( set dev/write to ppu-sprite )
|0100 @RESET
#0080 ,x STR2
#0040 ,y STR2
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
#12 =x
#1234 =y
~x
~y
#ef =test
BRK
|0200 @SPRITESHEET
@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
@star_icn .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
BRK
|c000 @FRAME
#00 IOR #10 NEQ ,next0 ROT JMP? POP2
,y LDR2 #0001 SUB2 ,y STR2
@next0
#00 IOR #20 NEQ ,next1 ROT JMP? POP2
,y LDR2 #0001 ADD2 ,y STR2
@next1
#00 IOR #40 NEQ ,next2 ROT JMP? POP2
,x LDR2 #0001 SUB2 ,x STR2
@next2
#00 IOR #80 NEQ ,next3 ROT JMP? POP2
,x LDR2 #0001 ADD2 ,x STR2
@next3
( redraw )
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
BRK
@putsprite
IOW2 ( y short )
IOW2 ( x short )
IOW2 ( sprite address )
IOW ( redraw byte )
RTS
|c000 @FRAME BRK
|d000 @ERROR BRK
|FFFA .RESET .FRAME .ERROR

1
uxn.c
View File

@ -16,7 +16,6 @@ WITH REGARD TO THIS SOFTWARE.
#pragma mark - Operations
/* clang-format off */
void setflag(Uint8 *a, char flag, int b) { if(b) *a |= flag; else *a &= (~flag); }
int getflag(Uint8 *a, char flag) { return *a & flag; }
void mempoke8(Memory *m, Uint16 a, Uint8 b) { m->dat[a] = b; }