Added chr/icn parser to PPU

This commit is contained in:
neauoire 2021-02-14 10:22:42 -08:00
parent 812148c291
commit b3ff7af8a3
6 changed files with 116 additions and 36 deletions

View File

@ -213,8 +213,8 @@ pass1(FILE *f)
else { else {
switch(w[0]) { switch(w[0]) {
case '|': addr = shex(w + 1); break; case '|': addr = shex(w + 1); break;
case '.': addr += 2; break;
case ',': addr += 3; break; case ',': addr += 3; break;
case '.': addr += (slen(w + 1) == 2 ? 1 : 2); break;
case '+': /* signed positive */ case '+': /* signed positive */
case '-': /* signed negative */ case '-': /* signed negative */
case '#': addr += (slen(w + 1) == 2 ? 2 : 3); break; 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((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] == ';') 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) == 2) pushbyte(shex(w + 1), 0);
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) == 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) == 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) == 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) == 2) pushbyte((Sint8)(shex(w + 1) * -1), 1);

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 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 # run
./bin/assembler examples/line.usm bin/boot.rom ./bin/assembler examples/test.usm bin/boot.rom
./bin/emulator bin/boot.rom ./bin/emulator bin/boot.rom

View File

@ -37,14 +37,9 @@ SDL_Renderer *gRenderer;
SDL_Texture *gTexture; SDL_Texture *gTexture;
Uint32 *pixels; Uint32 *pixels;
Device *devconsole, *devscreen, *devmouse, *devkey; Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite;
int #pragma mark - Helpers
error(char *msg, const char *err)
{
printf("Error %s: %s\n", msg, err);
return 0;
}
void void
clear(Uint32 *dst) clear(Uint32 *dst)
@ -59,7 +54,41 @@ void
putpixel(Uint32 *dst, int x, int y, int color) putpixel(Uint32 *dst, int x, int y, int color)
{ {
if(x >= 0 && x < WIDTH - 8 && y >= 0 && y < HEIGHT - 8) 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 void
@ -170,7 +199,7 @@ dokey(SDL_Event *event)
#pragma mark - Devices #pragma mark - Devices
Uint8 Uint8
consoler(Device *d, Uint8 b) consoler(Device *d, Memory *m, Uint8 b)
{ {
(void)b; (void)b;
(void)d; (void)d;
@ -178,7 +207,7 @@ consoler(Device *d, Uint8 b)
} }
Uint8 Uint8
consolew(Device *d, Uint8 b) consolew(Device *d, Memory *m, Uint8 b)
{ {
(void)d; (void)d;
if(b) if(b)
@ -188,7 +217,7 @@ consolew(Device *d, Uint8 b)
} }
Uint8 Uint8
screenr(Device *d, Uint8 b) ppur(Device *d, Memory *m, Uint8 b)
{ {
switch(b) { switch(b) {
case 0: return (WIDTH >> 8) & 0xff; case 0: return (WIDTH >> 8) & 0xff;
@ -200,7 +229,7 @@ screenr(Device *d, Uint8 b)
} }
Uint8 Uint8
screenw(Device *d, Uint8 b) ppuw(Device *d, Memory *m, Uint8 b)
{ {
d->mem[d->len++] = b; d->mem[d->len++] = b;
if(d->len > 5) { if(d->len > 5) {
@ -216,13 +245,35 @@ screenw(Device *d, Uint8 b)
} }
Uint8 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]; return d->mem[b];
} }
Uint8 Uint8
mousew(Device *d, Uint8 b) mousew(Device *d, Memory *m, Uint8 b)
{ {
(void)d; (void)d;
(void)b; (void)b;
@ -230,7 +281,7 @@ mousew(Device *d, Uint8 b)
} }
Uint8 Uint8
keyr(Device *d, Uint8 b) keyr(Device *d, Memory *m, Uint8 b)
{ {
(void)d; (void)d;
(void)b; (void)b;
@ -238,7 +289,7 @@ keyr(Device *d, Uint8 b)
} }
Uint8 Uint8
keyw(Device *d, Uint8 b) keyw(Device *d, Memory *m, Uint8 b)
{ {
(void)d; (void)d;
(void)b; (void)b;
@ -295,9 +346,10 @@ main(int argc, char **argv)
return error("Init", "Failed"); return error("Init", "Failed");
devconsole = portuxn(&u, "console", consoler, consolew); devconsole = portuxn(&u, "console", consoler, consolew);
devscreen = portuxn(&u, "screen", screenr, screenw); devscreen = portuxn(&u, "ppu", ppur, ppuw);
devmouse = portuxn(&u, "mouse", mouser, mousew); devmouse = portuxn(&u, "mouse", mouser, mousew);
devkey = portuxn(&u, "key", keyr, keyw); devkey = portuxn(&u, "key", keyr, keyw);
devsprite = portuxn(&u, "ppu-sprite", ppusr, ppusw);
start(&u); start(&u);

View File

@ -4,16 +4,42 @@
|0100 @RESET |0100 @RESET
#00 ,dev/w STR ( set dev/write to console ) #01 ,dev/w STR ( set dev/write to screen )
,string ( add string pointer to stack )
@loop ( draw 1 pixel )
DUP2 LDR IOW ( write pointer value to console ) #00 #01 #0021 #0021 ,putpixel JSR
#0001 ADD2 ( increment string pointer )
DUP2 LDR #00 NEQ ,loop ROT JMP? POP2 ( while *ptr!=0 goto loop ) #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 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 |c000 @FRAME BRK
|d000 @ERROR BRK |d000 @ERROR BRK

10
uxn.c
View File

@ -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_lit(Uxn *u) { u->literal += 1; }
void op_lix(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; } 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_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_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, a); } 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_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); } void op_str(Uxn *u) { Uint16 a = pop16(&u->wst); Uint8 b = pop8(&u->wst); mempoke8(&u->ram, a, b); }
/* Logic */ /* 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_lit16(Uxn *u) { u->literal += 2; }
void op_nop16(Uxn *u) { printf("%04x\n", pop16(&u->wst)); } 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_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, b); dev->write(dev, a); } } 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_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); } void op_str16(Uxn *u) { Uint16 a = pop16(&u->wst); Uint16 b = pop16(&u->wst); mempoke16(&u->ram, a, b); }
/* Stack(16-bits) */ /* Stack(16-bits) */
@ -202,7 +202,7 @@ loaduxn(Uxn *u, char *filepath)
} }
Device * 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++]; Device *d = &u->dev[u->devices++];
d->read = rfn; d->read = rfn;

6
uxn.h
View File

@ -33,8 +33,8 @@ typedef struct {
typedef struct Device { typedef struct Device {
Uint8 len, mem[8]; Uint8 len, mem[8];
Uint8 (*read)(struct Device *, Uint8); Uint8 (*read)(struct Device *, Memory *, Uint8);
Uint8 (*write)(struct Device *, Uint8); Uint8 (*write)(struct Device *, Memory *, Uint8);
} Device; } Device;
typedef struct { typedef struct {
@ -50,4 +50,4 @@ int getflag(Uint8 *status, char flag);
int loaduxn(Uxn *c, char *filepath); int loaduxn(Uxn *c, char *filepath);
int bootuxn(Uxn *c); int bootuxn(Uxn *c);
int evaluxn(Uxn *u, Uint16 vec); 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));