Added chr/icn parser to PPU
This commit is contained in:
parent
812148c291
commit
b3ff7af8a3
|
@ -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);
|
||||||
|
|
2
build.sh
2
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
|
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
|
||||||
|
|
86
emulator.c
86
emulator.c
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
10
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_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
6
uxn.h
|
@ -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));
|
||||||
|
|
Loading…
Reference in New Issue