Started migrating examples to new devices setup
This commit is contained in:
parent
3c04e1ece1
commit
b014a73bcd
2
build.sh
2
build.sh
|
@ -20,5 +20,5 @@ cc -std=c89 -DDEBUG -Wall -Wno-unknown-pragmas -Wpedantic -Wshadow -Wextra -Werr
|
|||
# cc uxn.c emulator.c -std=c89 -Os -DNDEBUG -g0 -s -Wall -Wno-unknown-pragmas -L/usr/local/lib -lSDL2 -o bin/emulator
|
||||
|
||||
# run
|
||||
./bin/assembler examples/gui.shapes.usm bin/boot.rom
|
||||
./bin/assembler examples/dev.mouse.usm bin/boot.rom
|
||||
./bin/emulator bin/boot.rom
|
||||
|
|
111
emulator.c
111
emulator.c
|
@ -253,30 +253,31 @@ init(void)
|
|||
}
|
||||
|
||||
void
|
||||
domouse(SDL_Event *event)
|
||||
domouse(Uxn *u, SDL_Event *event)
|
||||
{
|
||||
Uint8 flag = 0x00;
|
||||
Uint16 addr = 0xff50; /* TODO: get dynamically */
|
||||
Uint16 x = clamp(event->motion.x / ZOOM - PAD * 8, 0, HOR * 8 - 1);
|
||||
Uint16 y = clamp(event->motion.y / ZOOM - PAD * 8, 0, VER * 8 - 1);
|
||||
devmouse->mem[0] = (x >> 8) & 0xff;
|
||||
devmouse->mem[1] = x & 0xff;
|
||||
devmouse->mem[2] = (y >> 8) & 0xff;
|
||||
devmouse->mem[3] = y & 0xff;
|
||||
devmouse->mem[5] = 0x00;
|
||||
u->ram.dat[addr + 0] = (x >> 8) & 0xff;
|
||||
u->ram.dat[addr + 1] = x & 0xff;
|
||||
u->ram.dat[addr + 2] = (y >> 8) & 0xff;
|
||||
u->ram.dat[addr + 3] = y & 0xff;
|
||||
u->ram.dat[addr + 5] = 0x00;
|
||||
switch(event->button.button) {
|
||||
case SDL_BUTTON_LEFT: flag = 0x01; break;
|
||||
case SDL_BUTTON_RIGHT: flag = 0x10; break;
|
||||
}
|
||||
switch(event->type) {
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
setflag(&devmouse->mem[4], flag, 0);
|
||||
setflag(&u->ram.dat[addr + 4], flag, 0);
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
setflag(&devmouse->mem[4], flag, 1);
|
||||
if(flag == 0x01 && getflag(&devmouse->mem[4], 0x10))
|
||||
devmouse->mem[5] = 0x01;
|
||||
if(flag == 0x10 && getflag(&devmouse->mem[4], 0x01))
|
||||
devmouse->mem[5] = 0x10;
|
||||
setflag(&u->ram.dat[addr + 4], flag, 1);
|
||||
if(flag == 0x01 && getflag(&u->ram.dat[addr + 4], 0x10))
|
||||
u->ram.dat[addr + 5] = 0x01;
|
||||
if(flag == 0x10 && getflag(&u->ram.dat[addr + 4], 0x01))
|
||||
u->ram.dat[addr + 5] = 0x10;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -325,19 +326,23 @@ doctrl(SDL_Event *event, int z)
|
|||
#pragma mark - Devices
|
||||
|
||||
Uint8
|
||||
console_poke(Uint8 *m, Uint8 b0, Uint8 b1)
|
||||
console_poke(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1)
|
||||
{
|
||||
printf("%c", b1);
|
||||
fflush(stdout);
|
||||
(void)m;
|
||||
(void)ptr;
|
||||
(void)b0;
|
||||
return b1;
|
||||
}
|
||||
|
||||
Uint8
|
||||
screen_poke(Uint8 *m, Uint8 b0, Uint8 b1)
|
||||
screen_poke(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1)
|
||||
{
|
||||
if(b0 == 0x04) {
|
||||
Uint16 x = (*(m + 2) << 8) + *(m + 3);
|
||||
Uint16 y = (*m << 8) + *(m + 1);
|
||||
ptr += 8;
|
||||
if(b0 == 0x0c) {
|
||||
Uint16 x = (m[ptr] << 8) + m[ptr + 1];
|
||||
Uint16 y = (m[ptr + 2] << 8) + m[ptr + 3];
|
||||
paintpixel(b1 >> 4 & 0xf ? screen.fg : screen.bg, x, y, b1 & 0xf);
|
||||
screen.reqdraw = 1;
|
||||
}
|
||||
|
@ -345,16 +350,30 @@ screen_poke(Uint8 *m, Uint8 b0, Uint8 b1)
|
|||
}
|
||||
|
||||
Uint8
|
||||
peek1(Uint8 *m, Uint8 b0, Uint8 b1)
|
||||
sprite_poke(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1)
|
||||
{
|
||||
printf("PEEK! %02x\n", b1);
|
||||
ptr += 8;
|
||||
if(b0 == 0x0e) {
|
||||
Uint16 x = (m[ptr] << 8) + m[ptr + 1];
|
||||
Uint16 y = (m[ptr + 2] << 8) + m[ptr + 3];
|
||||
Uint16 a = (m[ptr + 4] << 8) + m[ptr + 5];
|
||||
Uint8 source = (b1 >> 4) & 0xf;
|
||||
Uint8 *layer = source % 2 ? screen.fg : screen.bg;
|
||||
if(source / 2)
|
||||
paintchr(layer, x, y, &m[a]);
|
||||
else
|
||||
painticn(layer, x, y, &m[a], b1 & 0xf);
|
||||
screen.reqdraw = 1;
|
||||
}
|
||||
return b1;
|
||||
}
|
||||
|
||||
Uint8
|
||||
poke1(Uint8 *m, Uint8 b0, Uint8 b1)
|
||||
ppnil(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1)
|
||||
{
|
||||
printf("POKE! %02x\n", b1);
|
||||
(void)m;
|
||||
(void)ptr;
|
||||
(void)b0;
|
||||
return b1;
|
||||
}
|
||||
|
||||
|
@ -376,37 +395,6 @@ consolew(Device *d, Memory *m, Uint8 b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
Uint8
|
||||
screenr(Device *d, Memory *m, Uint8 b)
|
||||
{
|
||||
loadtheme(m->dat + 0xfff0);
|
||||
switch(b) {
|
||||
case 0: return (HOR * 8 >> 8) & 0xff;
|
||||
case 1: return HOR * 8 & 0xff;
|
||||
case 2: return (VER * 8 >> 8) & 0xff;
|
||||
case 3: return VER * 8 & 0xff;
|
||||
}
|
||||
(void)m;
|
||||
return d->mem[b];
|
||||
}
|
||||
|
||||
Uint8
|
||||
screenw(Device *d, Memory *m, Uint8 b)
|
||||
{
|
||||
d->mem[d->ptr++] = b;
|
||||
if(d->ptr > 4) {
|
||||
Uint16 x = (d->mem[2] << 8) + d->mem[3];
|
||||
Uint16 y = (d->mem[0] << 8) + d->mem[1];
|
||||
Uint8 clr = d->mem[4] & 0xf;
|
||||
Uint8 layer = d->mem[4] >> 4 & 0xf;
|
||||
paintpixel(layer ? screen.fg : screen.bg, x, y, clr);
|
||||
screen.reqdraw = 1;
|
||||
d->ptr = 0;
|
||||
}
|
||||
(void)m;
|
||||
return 0;
|
||||
}
|
||||
|
||||
Uint8
|
||||
spritew(Device *d, Memory *m, Uint8 b)
|
||||
{
|
||||
|
@ -449,7 +437,7 @@ start(Uxn *u)
|
|||
case SDL_QUIT: quit(); break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEMOTION: domouse(&event); break;
|
||||
case SDL_MOUSEMOTION: domouse(u, &event); break;
|
||||
case SDL_TEXTINPUT: dotext(&event); break;
|
||||
case SDL_KEYDOWN: doctrl(&event, 1); break;
|
||||
case SDL_KEYUP: doctrl(&event, 0); break;
|
||||
|
@ -479,12 +467,17 @@ main(int argc, char **argv)
|
|||
if(!init())
|
||||
return error("Init", "Failed");
|
||||
|
||||
devconsole = portuxn(&u, "console", defaultrw, consolew, peek1, console_poke);
|
||||
devscreen = portuxn(&u, "screen", screenr, screenw, peek1, screen_poke);
|
||||
devsprite = portuxn(&u, "sprite", screenr, spritew, peek1, poke1);
|
||||
devcontroller = portuxn(&u, "controller", defaultrw, defaultrw, peek1, poke1);
|
||||
devkey = portuxn(&u, "key", defaultrw, consolew, peek1, poke1);
|
||||
devmouse = portuxn(&u, "mouse", defaultrw, defaultrw, peek1, poke1);
|
||||
devconsole = portuxn(&u, "console", defaultrw, consolew, ppnil, console_poke);
|
||||
devscreen = portuxn(&u, "screen", defaultrw, defaultrw, ppnil, screen_poke);
|
||||
devsprite = portuxn(&u, "sprite", defaultrw, spritew, ppnil, sprite_poke);
|
||||
devcontroller = portuxn(&u, "controller", defaultrw, defaultrw, ppnil, ppnil);
|
||||
devkey = portuxn(&u, "key", defaultrw, consolew, ppnil, ppnil);
|
||||
devmouse = portuxn(&u, "mouse", defaultrw, defaultrw, ppnil, ppnil);
|
||||
|
||||
u.ram.dat[0xff10] = (HOR * 8 >> 8) & 0xff;
|
||||
u.ram.dat[0xff11] = HOR * 8 & 0xff;
|
||||
u.ram.dat[0xff12] = (VER * 8 >> 8) & 0xff;
|
||||
u.ram.dat[0xff13] = VER * 8 & 0xff;
|
||||
|
||||
start(&u);
|
||||
quit();
|
||||
|
|
|
@ -1,11 +1,18 @@
|
|||
( blank )
|
||||
|
||||
:dev/r fff8 ( std read port )
|
||||
:dev/w fff9 ( std write port )
|
||||
&Console { pad 8 stdio 1 }
|
||||
&Screen { width 2 height 2 pad 4 y 2 x 2 color 1 }
|
||||
&Sprite { pad 8 y 2 x 2 addr 2 color 1 }
|
||||
&Mouse { x 2 y 2 state 1 chord 1 }
|
||||
|
||||
|0100 @RESET BRK
|
||||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
|
||||
|FF00 ;dev/console Console
|
||||
|FF10 ;dev/screen Screen
|
||||
|FF20 ;dev/sprite Sprite
|
||||
|FF50 ;dev/mouse Mouse
|
||||
|
||||
|FFF0 [ f2ac 35bb 2b53 ] ( palette )
|
||||
|FFFA .RESET .FRAME .ERROR
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
( hello world )
|
||||
|
||||
&Console { stdio 1 }
|
||||
&Console { pad 8 stdio 1 }
|
||||
|
||||
|0100 @RESET
|
||||
|
|
@ -1,45 +1,37 @@
|
|||
( mouse )
|
||||
|
||||
:dev/r fff8 ( std read port )
|
||||
:dev/w fff9 ( std write port )
|
||||
&Screen { width 2 height 2 pad 4 y 2 x 2 color 1 }
|
||||
&Sprite { pad 8 y 2 x 2 addr 2 color 1 }
|
||||
&Mouse { x 2 y 2 state 1 chord 1 }
|
||||
|
||||
&Point2d { x 2 y 2 }
|
||||
|
||||
;mouse Point2d
|
||||
;cat Point2d
|
||||
;cat Point2d ;mouse Point2d
|
||||
|
||||
;state 1 ;timer 1
|
||||
;timer 1
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
#01 =dev/r ( set dev/read screen )
|
||||
|
||||
( position cat )
|
||||
#00 IOR2 #0002 DIV2 =cat.x
|
||||
#02 IOR2 #0038 SUB2 =cat.y
|
||||
|
||||
#05 =dev/r ( set dev/read mouse )
|
||||
#02 =dev/w ( set dev/write to sprite )
|
||||
|
||||
~dev/screen.width #0002 DIV2 =cat.x
|
||||
~dev/screen.height #0038 SUB2 =cat.y
|
||||
( draw polycat )
|
||||
,draw-polycat JSR
|
||||
|
||||
BRK
|
||||
|
||||
|c000 @FRAME
|
||||
|
||||
|
||||
( clear last cursor )
|
||||
#10 ,clear_icn ~mouse.x ~mouse.y ,draw-sprite JSR
|
||||
( record mouse positions )
|
||||
#00 IOR2 =mouse.x #02 IOR2 =mouse.y
|
||||
( record mouse state )
|
||||
#04 IOR #11 ADD =state
|
||||
~dev/mouse.x =mouse.x ~dev/mouse.y =mouse.y
|
||||
( detect click )
|
||||
#04 IOR #01 NEQ ,no-click ROT JMP? POP2
|
||||
~dev/mouse.state #01 NEQ ,no-click ROT JMP? POP2
|
||||
#50 =timer
|
||||
@no-click
|
||||
( draw mouse )
|
||||
~state ,cursor_icn ~mouse.x ~mouse.y ,draw-sprite JSR
|
||||
~dev/mouse.state #11 ADD ,cursor_icn ~mouse.x ~mouse.y ,draw-sprite JSR
|
||||
( animate )
|
||||
,animate-polycat JSR
|
||||
( update last pos )
|
||||
|
@ -99,17 +91,17 @@ RTS
|
|||
RTS
|
||||
|
||||
@draw-sprite
|
||||
IOW2 ( y byte )
|
||||
IOW2 ( x byte )
|
||||
IOW2 ( sprite address )
|
||||
IOW ( layer-color )
|
||||
=dev/sprite.x
|
||||
=dev/sprite.y
|
||||
=dev/sprite.addr
|
||||
=dev/sprite.color
|
||||
RTS
|
||||
|
||||
@draw-sprite-chr
|
||||
IOW2 ( y byte )
|
||||
IOW2 ( x byte )
|
||||
IOW2 ( sprite address )
|
||||
#20 IOW ( layer-color )
|
||||
=dev/sprite.x
|
||||
=dev/sprite.y
|
||||
=dev/sprite.addr
|
||||
#20 =dev/sprite.color
|
||||
RTS
|
||||
|
||||
@clear_icn [ 0000 0000 0000 0000 ]
|
||||
|
@ -132,6 +124,10 @@ RTS
|
|||
c0f0 f0e0 e080 8000 c0f1 faf9 fef8 b000
|
||||
]
|
||||
|
||||
|FF10 ;dev/screen Screen
|
||||
|FF20 ;dev/sprite Sprite
|
||||
|FF50 ;dev/mouse Mouse
|
||||
|
||||
|d000 @ERROR BRK
|
||||
|FFF0 [ 0f85 0fd5 0fb5 ] ( palette )
|
||||
|FFFA .RESET .FRAME .ERROR
|
|
@ -0,0 +1,40 @@
|
|||
( screen )
|
||||
|
||||
&Screen { width 2 height 2 pad 4 x 2 y 2 color 1 }
|
||||
|
||||
;centerx 2 ;centery 2 ;i 2
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
( find screen center )
|
||||
~dev/screen.width #0002 DIV2 =centerx
|
||||
~dev/screen.height #0002 DIV2 =centery
|
||||
|
||||
( draw hor line )
|
||||
#0000 =i
|
||||
~centery =dev/screen.y
|
||||
@draw-hor
|
||||
#03 ~i =dev/screen.x =dev/screen.color
|
||||
~i #0002 ADD2 =i ( increment )
|
||||
~i ~dev/screen.width LTH2 ,draw-hor ROT JMP? POP2
|
||||
|
||||
( draw ver line )
|
||||
#0000 =i
|
||||
~centerx =dev/screen.x
|
||||
@draw-ver
|
||||
#03 ~i =dev/screen.y =dev/screen.color
|
||||
~i #0002 ADD2 =i ( increment )
|
||||
~i ~dev/screen.width LTH2 ,draw-ver ROT JMP? POP2
|
||||
|
||||
( draw pixel in the middle )
|
||||
#01 ~centerx ~centery =dev/screen.y =dev/screen.x =dev/screen.color
|
||||
|
||||
BRK
|
||||
|
||||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
|
||||
|FF10 ;dev/screen Screen
|
||||
|
||||
|FFF0 [ f0ac f0bb f053 ] ( palette )
|
||||
|FFFA .RESET .FRAME .ERROR ( vectors )
|
|
@ -1,45 +0,0 @@
|
|||
( screen )
|
||||
|
||||
:dev/r fff8 ( std read port )
|
||||
:dev/w fff9 ( std write port )
|
||||
|
||||
;centerx 2 ;centery 2 ;i 2
|
||||
|
||||
|0100 @RESET
|
||||
|
||||
( set read/write to dev/screen )
|
||||
#01 DUP =dev/r =dev/w
|
||||
|
||||
( find screen center )
|
||||
#00 IOR2 #0002 DIV2 =centerx
|
||||
#02 IOR2 #0002 DIV2 =centery
|
||||
|
||||
( draw hor line )
|
||||
#0000 =i
|
||||
@draw-hor
|
||||
#03 ~i ~centery ,draw-pixel JSR
|
||||
~i #0002 ADD2 =i ( increment )
|
||||
~i #00 IOR2 LTH2 ,draw-hor ROT JMP? POP2
|
||||
|
||||
( draw ver line )
|
||||
#0000 =i
|
||||
@draw-ver
|
||||
#03 ~centerx ~i ,draw-pixel JSR
|
||||
~i #0002 ADD2 =i ( increment )
|
||||
~i #02 IOR2 LTH2 ,draw-ver ROT JMP? POP2
|
||||
|
||||
( draw pixel in the middle )
|
||||
#01 ~centerx ~centery ,draw-pixel JSR
|
||||
|
||||
BRK
|
||||
|
||||
@draw-pixel
|
||||
IOW2 ( y short )
|
||||
IOW2 ( x short )
|
||||
IOW ( color byte )
|
||||
RTS
|
||||
|
||||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
|FFF0 [ f0ac f0bb f053 ] ( palette )
|
||||
|FFFA .RESET .FRAME .ERROR ( vectors )
|
|
@ -1,6 +1,6 @@
|
|||
( draw routines )
|
||||
|
||||
&Screen { y 2 x 2 color 1 }
|
||||
&Screen { width 2 height 2 pad 4 y 2 x 2 color 1 red 1 green 1 blue 1 }
|
||||
|
||||
;color 1 ;x1 2 ;x2 2 ;y1 2 ;y2 2
|
||||
|
||||
|
@ -53,7 +53,7 @@ RTS
|
|||
|c000 @FRAME BRK
|
||||
|d000 @ERROR BRK
|
||||
|
||||
|FF08 ;dev/screen Screen
|
||||
|FF10 ;dev/screen Screen
|
||||
|
||||
|FFF0 [ 0f0f 0fff 0ff0 ] ( palette )
|
||||
|FFFA .RESET .FRAME .ERROR ( vectors )
|
8
uxn.c
8
uxn.c
|
@ -18,9 +18,9 @@ WITH REGARD TO THIS SOFTWARE.
|
|||
/* 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; }
|
||||
Uint8 devpoke8(Uxn *u, Uint8 id, Uint8 b0, Uint8 b1){ return id < u->devices ? u->dev[id].poke(&u->ram.dat[0xff00 + id * 8], b0, b1) : b1; }
|
||||
Uint8 devpeek8(Uxn *u, Uint8 id, Uint8 b0, Uint8 b1){ return id < u->devices ? u->dev[id].peek(&u->ram.dat[0xff00 + id * 8], b0, b1) : b1; }
|
||||
void mempoke8(Uxn *u, Uint16 a, Uint8 b) { u->ram.dat[a] = a >= 0xff00 ? devpoke8(u, (a & 0xff) >> 3, (a & 0xf) % 8, b) : b; }
|
||||
Uint8 devpoke8(Uxn *u, Uint8 id, Uint8 b0, Uint8 b1){ return id < u->devices ? u->dev[id].poke(u->ram.dat, 0xff00 + id * 0x10, b0, b1) : b1; }
|
||||
Uint8 devpeek8(Uxn *u, Uint8 id, Uint8 b0, Uint8 b1){ return id < u->devices ? u->dev[id].peek(u->ram.dat, 0xff00 + id * 0x10, b0, b1) : b1; }
|
||||
void mempoke8(Uxn *u, Uint16 a, Uint8 b) { u->ram.dat[a] = a >= 0xff00 ? devpoke8(u, (a & 0xff) >> 4, a & 0xf, b) : b; }
|
||||
Uint8 mempeek8(Uxn *u, Uint16 a) { return a >= 0xff00 ? devpeek8(u, (a & 0xff) >> 4, a & 0xf, u->ram.dat[a]) : u->ram.dat[a]; }
|
||||
void mempoke16(Uxn *u, Uint16 a, Uint16 b) { mempoke8(u, a, b >> 8); mempoke8(u, a + 1, b); }
|
||||
Uint16 mempeek16(Uxn *u, Uint16 a) { return (mempeek8(u, a) << 8) + mempeek8(u, a + 1); }
|
||||
|
@ -211,7 +211,7 @@ loaduxn(Uxn *u, char *filepath)
|
|||
}
|
||||
|
||||
Device *
|
||||
portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8), Uint8 (*pefn)(Uint8 *m, Uint8 b0, Uint8 b1), Uint8 (*pofn)(Uint8 *m, Uint8 b0, Uint8 b1))
|
||||
portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8), Uint8 (*pefn)(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1), Uint8 (*pofn)(Uint8 *m, Uint16 ptr, Uint8 b0, Uint8 b1))
|
||||
{
|
||||
Device *d = &u->dev[u->devices++];
|
||||
d->read = rfn;
|
||||
|
|
6
uxn.h
6
uxn.h
|
@ -35,8 +35,8 @@ typedef struct Device {
|
|||
Uint8 ptr, mem[8];
|
||||
Uint8 (*read)(struct Device *, Memory *, Uint8);
|
||||
Uint8 (*write)(struct Device *, Memory *, Uint8);
|
||||
Uint8 (*peek)(Uint8 *, Uint8, Uint8);
|
||||
Uint8 (*poke)(Uint8 *, Uint8, Uint8);
|
||||
Uint8 (*peek)(Uint8 *, Uint16, Uint8, Uint8);
|
||||
Uint8 (*poke)(Uint8 *, Uint16, Uint8, Uint8);
|
||||
} Device;
|
||||
|
||||
typedef struct {
|
||||
|
@ -52,4 +52,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 *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8), Uint8 (*pefn)(Uint8 *, Uint8, Uint8), Uint8 (*pofn)(Uint8 *, Uint8, Uint8));
|
||||
Device *portuxn(Uxn *u, char *name, Uint8 (*rfn)(Device *, Memory *, Uint8), Uint8 (*wfn)(Device *, Memory *, Uint8), Uint8 (*pefn)(Uint8 *, Uint16, Uint8, Uint8), Uint8 (*pofn)(Uint8 *, Uint16, Uint8, Uint8));
|
||||
|
|
Loading…
Reference in New Issue