commit b3ff7af8a382c216502c140c1a77e15734773b83
parent 812148c2916e5aa177bcb91cd0cd761f48a316f9
Author: neauoire <aliceffekt@gmail.com>
Date: Sun, 14 Feb 2021 10:22:42 -0800
Added chr/icn parser to PPU
Diffstat:
6 files changed, 116 insertions(+), 36 deletions(-)
diff --git a/assembler.c b/assembler.c
@@ -213,8 +213,8 @@ pass1(FILE *f)
else {
switch(w[0]) {
case '|': addr = shex(w + 1); break;
- case '.': addr += 2; break;
case ',': addr += 3; break;
+ case '.': addr += (slen(w + 1) == 2 ? 1 : 2); break;
case '+': /* signed positive */
case '-': /* signed negative */
case '#': addr += (slen(w + 1) == 2 ? 2 : 3); break;
@@ -242,8 +242,10 @@ pass2(FILE *f)
else if((op = findopcode(w)) || scmp(w, "BRK")) pushbyte(op, 0);
else if(w[0] == ':') fscanf(f, "%s", w);
else if(w[0] == ';') fscanf(f, "%s", w);
- else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w), 1);
- else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w), 1);
+ else if(w[0] == '.' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 0);
+ else if(w[0] == '.' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), 0);
+ else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 2) pushbyte(shex(w + 1), 1);
+ else if(w[0] == '#' && sihx(w + 1) && slen(w + 1) == 4) pushshort(shex(w + 1), 1);
else if(w[0] == '+' && sihx(w + 1) && slen(w + 1) == 2) pushbyte((Sint8)shex(w + 1), 1);
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);
diff --git a/build.sh b/build.sh
@@ -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/line.usm bin/boot.rom
+./bin/assembler examples/test.usm bin/boot.rom
./bin/emulator bin/boot.rom
diff --git a/emulator.c b/emulator.c
@@ -37,14 +37,9 @@ SDL_Renderer *gRenderer;
SDL_Texture *gTexture;
Uint32 *pixels;
-Device *devconsole, *devscreen, *devmouse, *devkey;
+Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite;
-int
-error(char *msg, const char *err)
-{
- printf("Error %s: %s\n", msg, err);
- return 0;
-}
+#pragma mark - Helpers
void
clear(Uint32 *dst)
@@ -59,7 +54,41 @@ void
putpixel(Uint32 *dst, int x, int y, int color)
{
if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8)
- dst[y * WIDTH + x] = theme[color];
+ dst[(y + PAD * 8) * WIDTH + (x + PAD * 8)] = theme[color];
+}
+
+void
+drawchr(Uint32 *dst, int x, int y, Uint8 *sprite)
+{
+ int v, h;
+ for(v = 0; v < 8; v++)
+ for(h = 0; h < 8; h++) {
+ int ch1 = ((sprite[v] >> h) & 0x1);
+ int ch2 = (((sprite[v + 8] >> h) & 0x1) << 1);
+ int clr = ch1 + ch2;
+ int guides = GUIDES && !clr && ((x + y) / 8) % 2;
+ putpixel(dst, x + 7 - h, y + v, guides ? 4 : clr);
+ }
+}
+
+void
+drawicn(Uint32 *dst, int x, int y, Uint8 *sprite, int fg, int bg)
+{
+ int v, h;
+ for(v = 0; v < 8; v++)
+ for(h = 0; h < 8; h++) {
+ int ch1 = (sprite[v] >> (7 - h)) & 0x1;
+ putpixel(dst, x + h, y + v, ch1 ? fg : bg);
+ }
+}
+
+#pragma mark - Core
+
+int
+error(char *msg, const char *err)
+{
+ printf("Error %s: %s\n", msg, err);
+ return 0;
}
void
@@ -170,7 +199,7 @@ dokey(SDL_Event *event)
#pragma mark - Devices
Uint8
-consoler(Device *d, Uint8 b)
+consoler(Device *d, Memory *m, Uint8 b)
{
(void)b;
(void)d;
@@ -178,7 +207,7 @@ consoler(Device *d, Uint8 b)
}
Uint8
-consolew(Device *d, Uint8 b)
+consolew(Device *d, Memory *m, Uint8 b)
{
(void)d;
if(b)
@@ -188,7 +217,7 @@ consolew(Device *d, Uint8 b)
}
Uint8
-screenr(Device *d, Uint8 b)
+ppur(Device *d, Memory *m, Uint8 b)
{
switch(b) {
case 0: return (WIDTH >> 8) & 0xff;
@@ -200,7 +229,7 @@ screenr(Device *d, Uint8 b)
}
Uint8
-screenw(Device *d, Uint8 b)
+ppuw(Device *d, Memory *m, Uint8 b)
{
d->mem[d->len++] = b;
if(d->len > 5) {
@@ -216,13 +245,35 @@ screenw(Device *d, Uint8 b)
}
Uint8
-mouser(Device *d, Uint8 b)
+ppusr(Device *d, Memory *m, Uint8 b)
+{
+ return 0;
+}
+
+Uint8
+ppusw(Device *d, Memory *m, Uint8 b)
+{
+ d->mem[d->len++] = b;
+ if(d->len > 6) {
+ Uint16 x = (d->mem[2] << 8) + d->mem[3];
+ Uint16 y = (d->mem[0] << 8) + d->mem[1];
+ Uint8 *chr = &m->dat[(d->mem[4] << 8) + d->mem[5]];
+ drawchr(pixels, x, y, chr);
+ if(d->mem[6])
+ redraw(pixels);
+ d->len = 0;
+ }
+ return 0;
+}
+
+Uint8
+mouser(Device *d, Memory *m, Uint8 b)
{
return d->mem[b];
}
Uint8
-mousew(Device *d, Uint8 b)
+mousew(Device *d, Memory *m, Uint8 b)
{
(void)d;
(void)b;
@@ -230,7 +281,7 @@ mousew(Device *d, Uint8 b)
}
Uint8
-keyr(Device *d, Uint8 b)
+keyr(Device *d, Memory *m, Uint8 b)
{
(void)d;
(void)b;
@@ -238,7 +289,7 @@ keyr(Device *d, Uint8 b)
}
Uint8
-keyw(Device *d, Uint8 b)
+keyw(Device *d, Memory *m, Uint8 b)
{
(void)d;
(void)b;
@@ -295,9 +346,10 @@ main(int argc, char **argv)
return error("Init", "Failed");
devconsole = portuxn(&u, "console", consoler, consolew);
- devscreen = portuxn(&u, "screen", screenr, screenw);
+ devscreen = portuxn(&u, "ppu", ppur, ppuw);
devmouse = portuxn(&u, "mouse", mouser, mousew);
devkey = portuxn(&u, "key", keyr, keyw);
+ devsprite = portuxn(&u, "ppu-sprite", ppusr, ppusw);
start(&u);
diff --git a/examples/test.usm b/examples/test.usm
@@ -4,16 +4,42 @@
|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 )
- #0001 ADD2 ( increment string pointer )
- DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop )
+ #01 ,dev/w STR ( set dev/write to screen )
+
+ ( 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 #0031 #0021 ,putsprite JSR
+ #00 ,cursor_icn #0021 #0016 ,putsprite JSR
+ #00 ,star_icn #0055 #0042 ,putsprite JSR
+ #01 ,cursor_icn #0067 #0031 ,putsprite JSR
BRK
-@string " Hello World " ( add string to memory )
+@putsprite
+ IOW2 ( y short )
+ IOW2 ( x short )
+ IOW2 ( sprite address )
+ IOW ( redraw byte )
+ RTS
+
+@putpixel
+ IOW2 ( y short )
+ IOW2 ( x short )
+ IOW ( color byte )
+ IOW ( redraw byte )
+ RTS
+
+|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 BRK
|d000 @ERROR BRK
diff --git a/uxn.c b/uxn.c
@@ -34,8 +34,8 @@ void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
void op_lit(Uxn *u) { u->literal += 1; }
void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
void op_nop(Uxn *u) { printf("0x%02x ", pop8(&u->wst)); }
-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))); }
-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); }
+void op_ior(Uxn *u) { Device *dev = &u->dev[mempeek8(&u->ram, u->devr)]; if(dev) push8(&u->wst, dev->read(dev, &u->ram, pop8(&u->wst))); }
+void op_iow(Uxn *u) { Uint8 a = pop8(&u->wst); Device *dev = &u->dev[mempeek8(&u->ram, u->devw)]; if(dev) dev->write(dev, &u->ram, a); }
void op_ldr(Uxn *u) { Uint16 a = pop16(&u->wst); push8(&u->wst, mempeek8(&u->ram, a)); }
void op_str(Uxn *u) { Uint16 a = pop16(&u->wst); Uint8 b = pop8(&u->wst); mempoke8(&u->ram, a, b); }
/* Logic */
@@ -63,8 +63,8 @@ void op_lth(Uxn *u) { Uint8 a = pop8(&u->wst), b = pop8(&u->wst); push8(&u->wst,
/* --- */
void op_lit16(Uxn *u) { u->literal += 2; }
void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); }
-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)); }
-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); } }
+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, &u->ram, a) << 8) + dev->read(dev, &u->ram, a + 1)); }
+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, &u->ram, b); dev->write(dev, &u->ram, a); } }
void op_ldr16(Uxn *u) { Uint16 a = pop16(&u->wst); push16(&u->wst, mempeek16(&u->ram, a)); }
void op_str16(Uxn *u) { Uint16 a = pop16(&u->wst); Uint16 b = pop16(&u->wst); mempoke16(&u->ram, a, b); }
/* Stack(16-bits) */
@@ -202,7 +202,7 @@ loaduxn(Uxn *u, char *filepath)
}
Device *
-portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Uint8), Uint8 (*wfn)(Device *, Uint8))
+portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8))
{
Device *d = &u->dev[u->devices++];
d->read = rfn;
diff --git a/uxn.h b/uxn.h
@@ -33,8 +33,8 @@ typedef struct {
typedef struct Device {
Uint8 len, mem[8];
- Uint8 (*read)(struct Device *, Uint8);
- Uint8 (*write)(struct Device *, Uint8);
+ Uint8 (*read)(struct Device *, Memory *, Uint8);
+ Uint8 (*write)(struct Device *, Memory *, Uint8);
} Device;
typedef struct {
@@ -50,4 +50,4 @@ int getflag(Uint8 *status, char flag);
int loaduxn(Uxn *c, char *filepath);
int bootuxn(Uxn *c);
int evaluxn(Uxn *u, Uint16 vec);
-Device *portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Uint8), Uint8 (*wfn)(Device *, Uint8));
+Device *portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8));