Better PPU design
This commit is contained in:
parent
56ca1091b4
commit
17578d8bbb
12
build.sh
12
build.sh
|
@ -15,14 +15,14 @@ clang-format -i uxn.c
|
||||||
|
|
||||||
# Cli
|
# Cli
|
||||||
clang-format -i cli.c
|
clang-format -i cli.c
|
||||||
rm -f ./bin/cli
|
# rm -f ./bin/cli
|
||||||
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 cli.c -o bin/cli
|
# 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 cli.c -o bin/cli
|
||||||
|
|
||||||
# Emulator
|
# Emulator
|
||||||
clang-format -i emulator.c
|
clang-format -i emulator.c
|
||||||
# rm -f ./bin/emulator
|
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/hello.usm bin/boot.rom
|
./bin/assembler examples/pixel.usm bin/boot.rom
|
||||||
./bin/cli bin/boot.rom
|
./bin/emulator bin/boot.rom
|
||||||
|
|
6
cli.c
6
cli.c
|
@ -21,15 +21,17 @@ error(char *msg, const char *err)
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8
|
Uint8
|
||||||
console_onread(Uint8 b)
|
console_onread(Device *d, Uint8 b)
|
||||||
{
|
{
|
||||||
|
(void)d;
|
||||||
(void)b;
|
(void)b;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Uint8
|
Uint8
|
||||||
console_onwrite(Uint8 b)
|
console_onwrite(Device *d, Uint8 b)
|
||||||
{
|
{
|
||||||
|
(void)d;
|
||||||
if(b)
|
if(b)
|
||||||
printf("%c", b);
|
printf("%c", b);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
71
emulator.c
71
emulator.c
|
@ -53,6 +53,13 @@ clear(Uint32 *dst)
|
||||||
dst[v * WIDTH + h] = theme[0];
|
dst[v * WIDTH + h] = theme[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
redraw(Uint32 *dst)
|
redraw(Uint32 *dst)
|
||||||
{
|
{
|
||||||
|
@ -149,34 +156,46 @@ dokey(SDL_Event *event)
|
||||||
|
|
||||||
#pragma mark - Devices
|
#pragma mark - Devices
|
||||||
|
|
||||||
void
|
Uint8
|
||||||
console_onread(Uint8 *b)
|
console_onread(Device *d, Uint8 b)
|
||||||
{
|
{
|
||||||
(void)b;
|
(void)b;
|
||||||
|
(void)d;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
Uint8
|
||||||
console_onwrite(Uint8 *b)
|
console_onwrite(Device *d, Uint8 b)
|
||||||
{
|
{
|
||||||
if(b) {
|
(void)d;
|
||||||
printf("%c", *b);
|
if(b)
|
||||||
fflush(stdout);
|
printf("%c", b);
|
||||||
*b = 0x00;
|
fflush(stdout);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint8
|
||||||
|
ppur(Device *d, Uint8 b)
|
||||||
|
{
|
||||||
|
(void)b;
|
||||||
|
(void)d;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint8
|
||||||
|
ppuw(Device *d, Uint8 b)
|
||||||
|
{
|
||||||
|
d->mem[d->len++] = b;
|
||||||
|
if(d->len > 5) {
|
||||||
|
putpixel(pixels,
|
||||||
|
(d->mem[0] << 8) + d->mem[1],
|
||||||
|
(d->mem[2] << 8) + d->mem[3],
|
||||||
|
d->mem[4]);
|
||||||
|
if(d->mem[5])
|
||||||
|
redraw(pixels);
|
||||||
|
d->len = 0;
|
||||||
}
|
}
|
||||||
}
|
return 0;
|
||||||
|
|
||||||
Uint8 ppumem[5];
|
|
||||||
|
|
||||||
void
|
|
||||||
ppur(Uint8 *b)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ppuw(Uint8 *b)
|
|
||||||
{
|
|
||||||
|
|
||||||
printf("%02x\n", *b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -207,11 +226,11 @@ start(Uxn *u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Uxn u;
|
|
||||||
|
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
Uxn u;
|
||||||
|
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
return error("Input", "Missing");
|
return error("Input", "Missing");
|
||||||
if(!bootuxn(&u))
|
if(!bootuxn(&u))
|
||||||
|
@ -221,8 +240,8 @@ main(int argc, char **argv)
|
||||||
if(!init())
|
if(!init())
|
||||||
return error("Init", "Failed");
|
return error("Init", "Failed");
|
||||||
|
|
||||||
portuxn(&u, 0xfff0, console_onread, console_onwrite);
|
portuxn(&u, "console", console_onread, console_onwrite);
|
||||||
portuxn(&u, 0xfff2, ppur, ppuw);
|
portuxn(&u, "PPU", ppur, ppuw);
|
||||||
|
|
||||||
start(&u);
|
start(&u);
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
@word1 "hello_word ( len: 0x0b )
|
@word1 "hello_world ( len: 0x0b )
|
||||||
|
|
||||||
@loop
|
@loop
|
||||||
,00 IOW ( write to device#0 )
|
,00 IOW ( write to device#0 )
|
||||||
|
|
|
@ -1,17 +1,27 @@
|
||||||
( hello world )
|
( draw pixel )
|
||||||
|
|
||||||
:stdr FFF0
|
|
||||||
:stdw FFF1
|
|
||||||
:ppur FFF2
|
|
||||||
:ppuw FFF3
|
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
,11 ,ppuw STR ( x0 )
|
,0001 IOW ( x0 )
|
||||||
,23 ,ppuw STR ( x1 )
|
,0001 IOW ( x1 )
|
||||||
,12 ,ppuw STR ( y0 )
|
,0001 IOW ( y0 )
|
||||||
,34 ,ppuw STR ( y1 )
|
,0001 IOW ( y1 )
|
||||||
,01 ,ppuw STR ( clr )
|
,0101 IOW ( clr )
|
||||||
|
,0001 IOW ( noredraw )
|
||||||
|
|
||||||
|
,0001 IOW ( x0 )
|
||||||
|
,0101 IOW ( x1 )
|
||||||
|
,0001 IOW ( y0 )
|
||||||
|
,0001 IOW ( y1 )
|
||||||
|
,0201 IOW ( clr )
|
||||||
|
,0001 IOW ( noredraw )
|
||||||
|
|
||||||
|
,0001 IOW ( x0 )
|
||||||
|
,0201 IOW ( x1 )
|
||||||
|
,0001 IOW ( y0 )
|
||||||
|
,0001 IOW ( y1 )
|
||||||
|
,0301 IOW ( clr )
|
||||||
|
,0101 IOW ( redraw! )
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
|
|
7
uxn.c
7
uxn.c
|
@ -33,8 +33,8 @@ Uint16 mempeek16(Uxn *u, Uint16 s) { return (u->ram.dat[s] << 8) + (u->ram.dat[s
|
||||||
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
|
void op_brk(Uxn *u) { setflag(&u->status,FLAG_HALT, 1); }
|
||||||
void op_lit(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
|
void op_lit(Uxn *u) { u->literal += u->ram.dat[u->ram.ptr++]; }
|
||||||
void op_nop(Uxn *u) { printf("NOP"); (void)u; }
|
void op_nop(Uxn *u) { printf("NOP"); (void)u; }
|
||||||
void op_ior(Uxn *u) { Uint8 devid = wspop8(u); Uint8 devop = wspop8(u); Device *dev = &u->dev[devid]; if(dev) wspush8(u, dev->rfn(devop)); }
|
void op_ior(Uxn *u) { Uint8 devid = wspop8(u); Uint16 devop = wspop8(u); Device *dev = &u->dev[devid]; if(devid < u->devices) wspush8(u, dev->rfn(dev,devop)); }
|
||||||
void op_iow(Uxn *u) { Uint8 devid = wspop8(u); Uint8 devop = wspop8(u); Device *dev = &u->dev[devid]; if(dev) dev->wfn(devop); }
|
void op_iow(Uxn *u) { Uint8 devid = wspop8(u); Uint16 devop = wspop8(u); Device *dev = &u->dev[devid]; if(devid < u->devices) dev->wfn(dev,devop); }
|
||||||
void op_ldr(Uxn *u) { Uint16 a = wspop16(u); wspush8(u, u->ram.dat[a]); }
|
void op_ldr(Uxn *u) { Uint16 a = wspop16(u); wspush8(u, u->ram.dat[a]); }
|
||||||
void op_str(Uxn *u) { Uint16 a = wspop16(u); Uint8 b = wspop8(u); u->ram.dat[a] = b; }
|
void op_str(Uxn *u) { Uint16 a = wspop16(u); Uint8 b = wspop8(u); u->ram.dat[a] = b; }
|
||||||
/* Logic */
|
/* Logic */
|
||||||
|
@ -187,11 +187,12 @@ loaduxn(Uxn *u, char *filepath)
|
||||||
/* to start: evaluxn(u, u->vreset); */
|
/* to start: evaluxn(u, u->vreset); */
|
||||||
|
|
||||||
int
|
int
|
||||||
portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8))
|
portuxn(Uxn *u, char *name, Uint8 (*onread)(Device *, Uint8), Uint8 (*onwrite)(Device *, Uint8))
|
||||||
{
|
{
|
||||||
Device *d = &u->dev[u->devices++];
|
Device *d = &u->dev[u->devices++];
|
||||||
d->rfn = onread;
|
d->rfn = onread;
|
||||||
d->wfn = onwrite;
|
d->wfn = onwrite;
|
||||||
|
d->len = 0;
|
||||||
printf("Device#%d: %s \n", u->devices, name);
|
printf("Device#%d: %s \n", u->devices, name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
10
uxn.h
10
uxn.h
|
@ -34,10 +34,10 @@ typedef struct {
|
||||||
Uint8 dat[65536];
|
Uint8 dat[65536];
|
||||||
} Memory;
|
} Memory;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct Device {
|
||||||
Uint16 index;
|
Uint8 len, mem[8];
|
||||||
Uint8 (*rfn)(Uint8);
|
Uint8 (*rfn)(struct Device *, Uint8);
|
||||||
Uint8 (*wfn)(Uint8);
|
Uint8 (*wfn)(struct Device *, Uint8);
|
||||||
} Device;
|
} Device;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -54,4 +54,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);
|
||||||
int portuxn(Uxn *u, char *name, Uint8 (*onread)(Uint8), Uint8 (*onwrite)(Uint8));
|
int portuxn(Uxn *u, char *name, Uint8 (*onread)(Device *, Uint8), Uint8 (*onwrite)(Device *, Uint8));
|
||||||
|
|
Loading…
Reference in New Issue