Added controller example
This commit is contained in:
parent
b3ff7af8a3
commit
1cc7abea54
17
README.md
17
README.md
|
@ -44,6 +44,8 @@ evaluxn(u, u->vframe); /* Each frame
|
||||||
- `+12ef`, a literal signed short.
|
- `+12ef`, a literal signed short.
|
||||||
- `-1a`, a literal signed byte(negative).
|
- `-1a`, a literal signed byte(negative).
|
||||||
- `-12ef`, a literal signed short(negative).
|
- `-12ef`, a literal signed short(negative).
|
||||||
|
- `.ab`, a raw byte in memory.
|
||||||
|
- `.abcd`, a raw short in memory.
|
||||||
|
|
||||||
### Special
|
### Special
|
||||||
|
|
||||||
|
@ -81,6 +83,21 @@ BRK
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|FFFA .RESET .FRAME .ERROR
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Emulator
|
||||||
|
|
||||||
|
### Controller(dev/ctrl)
|
||||||
|
|
||||||
|
A device that works like a NES controller, each button is a bit from a single byte.
|
||||||
|
|
||||||
|
- Ctrl
|
||||||
|
- Alt
|
||||||
|
- Escape
|
||||||
|
- Return
|
||||||
|
- Up
|
||||||
|
- Down
|
||||||
|
- Left
|
||||||
|
- Right
|
||||||
|
|
||||||
## TODOs
|
## TODOs
|
||||||
|
|
||||||
- Defines?
|
- Defines?
|
||||||
|
|
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/test.usm bin/boot.rom
|
./bin/assembler examples/controller.usm bin/boot.rom
|
||||||
./bin/emulator bin/boot.rom
|
./bin/emulator bin/boot.rom
|
||||||
|
|
47
emulator.c
47
emulator.c
|
@ -37,7 +37,7 @@ SDL_Renderer *gRenderer;
|
||||||
SDL_Texture *gTexture;
|
SDL_Texture *gTexture;
|
||||||
Uint32 *pixels;
|
Uint32 *pixels;
|
||||||
|
|
||||||
Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite;
|
Device *devconsole, *devscreen, *devmouse, *devkey, *devsprite, *devctrl;
|
||||||
|
|
||||||
#pragma mark - Helpers
|
#pragma mark - Helpers
|
||||||
|
|
||||||
|
@ -65,9 +65,7 @@ drawchr(Uint32 *dst, int x, int y, Uint8 *sprite)
|
||||||
for(h = 0; h < 8; h++) {
|
for(h = 0; h < 8; h++) {
|
||||||
int ch1 = ((sprite[v] >> h) & 0x1);
|
int ch1 = ((sprite[v] >> h) & 0x1);
|
||||||
int ch2 = (((sprite[v + 8] >> h) & 0x1) << 1);
|
int ch2 = (((sprite[v + 8] >> h) & 0x1) << 1);
|
||||||
int clr = ch1 + ch2;
|
putpixel(dst, x + 7 - h, y + v, ch1 + ch2);
|
||||||
int guides = GUIDES && !clr && ((x + y) / 8) % 2;
|
|
||||||
putpixel(dst, x + 7 - h, y + v, guides ? 4 : clr);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,8 +190,25 @@ domouse(SDL_Event *event)
|
||||||
void
|
void
|
||||||
dokey(SDL_Event *event)
|
dokey(SDL_Event *event)
|
||||||
{
|
{
|
||||||
(void)event;
|
}
|
||||||
/* printf("key\n"); */
|
|
||||||
|
void
|
||||||
|
doctrl(SDL_Event *event, int z)
|
||||||
|
{
|
||||||
|
Uint8 flag = 0x00;
|
||||||
|
if(SDL_GetModState() & KMOD_LCTRL || SDL_GetModState() & KMOD_RCTRL)
|
||||||
|
flag = 0x01;
|
||||||
|
if(SDL_GetModState() & KMOD_LALT || SDL_GetModState() & KMOD_RALT)
|
||||||
|
flag = 0x02;
|
||||||
|
switch(event->key.keysym.sym) {
|
||||||
|
case SDLK_ESCAPE: flag = 0x04; break;
|
||||||
|
case SDLK_RETURN: flag = 0x08; break;
|
||||||
|
case SDLK_UP: flag = 0x10; break;
|
||||||
|
case SDLK_DOWN: flag = 0x20; break;
|
||||||
|
case SDLK_LEFT: flag = 0x40; break;
|
||||||
|
case SDLK_RIGHT: flag = 0x80; break;
|
||||||
|
}
|
||||||
|
setflag(&devctrl->mem[0], flag, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Devices
|
#pragma mark - Devices
|
||||||
|
@ -296,6 +311,20 @@ keyw(Device *d, Memory *m, Uint8 b)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Uint8
|
||||||
|
ctrlr(Device *d, Memory *m, Uint8 b)
|
||||||
|
{
|
||||||
|
return d->mem[b];
|
||||||
|
}
|
||||||
|
|
||||||
|
Uint8
|
||||||
|
ctrlw(Device *d, Memory *m, Uint8 b)
|
||||||
|
{
|
||||||
|
(void)d;
|
||||||
|
(void)b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark - Generics
|
#pragma mark - Generics
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -314,20 +343,21 @@ start(Uxn *u)
|
||||||
if(tick < ticknext)
|
if(tick < ticknext)
|
||||||
SDL_Delay(ticknext - tick);
|
SDL_Delay(ticknext - tick);
|
||||||
ticknext = tick + (1000 / FPS);
|
ticknext = tick + (1000 / FPS);
|
||||||
evaluxn(u, u->vframe);
|
|
||||||
while(SDL_PollEvent(&event) != 0) {
|
while(SDL_PollEvent(&event) != 0) {
|
||||||
switch(event.type) {
|
switch(event.type) {
|
||||||
case SDL_QUIT: quit(); break;
|
case SDL_QUIT: quit(); break;
|
||||||
case SDL_MOUSEBUTTONUP:
|
case SDL_MOUSEBUTTONUP:
|
||||||
case SDL_MOUSEBUTTONDOWN:
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
case SDL_MOUSEMOTION: domouse(&event); break;
|
case SDL_MOUSEMOTION: domouse(&event); break;
|
||||||
case SDL_KEYDOWN: dokey(&event); break;
|
case SDL_KEYDOWN: doctrl(&event, 1); break;
|
||||||
|
case SDL_KEYUP: doctrl(&event, 0); break;
|
||||||
case SDL_WINDOWEVENT:
|
case SDL_WINDOWEVENT:
|
||||||
if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
|
if(event.window.event == SDL_WINDOWEVENT_EXPOSED)
|
||||||
redraw(pixels);
|
redraw(pixels);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
evaluxn(u, u->vframe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -350,6 +380,7 @@ main(int argc, char **argv)
|
||||||
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);
|
devsprite = portuxn(&u, "ppu-sprite", ppusr, ppusw);
|
||||||
|
devctrl = portuxn(&u, "ctrl", ctrlr, ctrlw);
|
||||||
|
|
||||||
start(&u);
|
start(&u);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
( comment )
|
||||||
|
|
||||||
|
:dev/r fff8 ( const read port )
|
||||||
|
:dev/w fff9 ( const write port )
|
||||||
|
|
||||||
|
;x 2 ;y 2
|
||||||
|
|
||||||
|
|0100 @RESET
|
||||||
|
|
||||||
|
#05 ,dev/r STR ( set dev/read to ctrl )
|
||||||
|
#04 ,dev/w STR ( set dev/write to ppu-sprite )
|
||||||
|
|
||||||
|
#0080 ,x STR2
|
||||||
|
#0040 ,y STR2
|
||||||
|
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
|
||||||
|
|
||||||
|
BRK
|
||||||
|
|
||||||
|
|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
|
||||||
|
|
||||||
|
#00 IOR #10 NEQ ,next0 ROT JMP? POP2
|
||||||
|
,y LDR2 #0001 SUB2 ,y STR2
|
||||||
|
@next0
|
||||||
|
#00 IOR #20 NEQ ,next1 ROT JMP? POP2
|
||||||
|
,y LDR2 #0001 ADD2 ,y STR2
|
||||||
|
@next1
|
||||||
|
#00 IOR #40 NEQ ,next2 ROT JMP? POP2
|
||||||
|
,x LDR2 #0001 SUB2 ,x STR2
|
||||||
|
@next2
|
||||||
|
#00 IOR #80 NEQ ,next3 ROT JMP? POP2
|
||||||
|
,x LDR2 #0001 ADD2 ,x STR2
|
||||||
|
@next3
|
||||||
|
( redraw )
|
||||||
|
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
|
||||||
|
|
||||||
|
BRK
|
||||||
|
|
||||||
|
@putsprite
|
||||||
|
IOW2 ( y short )
|
||||||
|
IOW2 ( x short )
|
||||||
|
IOW2 ( sprite address )
|
||||||
|
IOW ( redraw byte )
|
||||||
|
RTS
|
||||||
|
|
||||||
|
|d000 @ERROR BRK
|
||||||
|
|
||||||
|
|FFFA .RESET .FRAME .ERROR
|
|
@ -0,0 +1,46 @@
|
||||||
|
( comment )
|
||||||
|
|
||||||
|
:dev/w fff9 ( const write port )
|
||||||
|
|
||||||
|
|0100 @RESET
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
@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
|
||||||
|
|
||||||
|
|FFFA .RESET .FRAME .ERROR
|
|
@ -1,22 +1,44 @@
|
||||||
( comment )
|
( comment )
|
||||||
|
|
||||||
|
:dev/r fff8 ( const read port )
|
||||||
:dev/w fff9 ( const write port )
|
:dev/w fff9 ( const write port )
|
||||||
|
|
||||||
|
;x 2 ;y 2
|
||||||
|
|
||||||
|0100 @RESET
|
|0100 @RESET
|
||||||
|
|
||||||
#01 ,dev/w STR ( set dev/write to screen )
|
#05 ,dev/r STR ( set dev/read to ctrl )
|
||||||
|
#04 ,dev/w STR ( set dev/write to ppu-sprite )
|
||||||
|
|
||||||
( draw 1 pixel )
|
#0080 ,x STR2
|
||||||
#00 #01 #0021 #0021 ,putpixel JSR
|
#0040 ,y STR2
|
||||||
|
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
|
||||||
|
|
||||||
#04 ,dev/w STR ( set dev/write to screen )
|
BRK
|
||||||
|
|
||||||
#00 ,star_icn #0001 #0001 ,putsprite JSR
|
|0200 @SPRITESHEET
|
||||||
|
|
||||||
#00 ,star_icn #0031 #0021 ,putsprite JSR
|
@cursor_icn .80c0 .e0f0 .f8e0 .1000 .0000 .0000 .0000 .0000
|
||||||
#00 ,cursor_icn #0021 #0016 ,putsprite JSR
|
@star_icn .1054 .28c6 .2854 .1000 .0000 .0000 .0000 .0000
|
||||||
#00 ,star_icn #0055 #0042 ,putsprite JSR
|
|
||||||
#01 ,cursor_icn #0067 #0031 ,putsprite JSR
|
BRK
|
||||||
|
|
||||||
|
|c000 @FRAME
|
||||||
|
|
||||||
|
#00 IOR #10 NEQ ,next0 ROT JMP? POP2
|
||||||
|
,y LDR2 #0001 SUB2 ,y STR2
|
||||||
|
@next0
|
||||||
|
#00 IOR #20 NEQ ,next1 ROT JMP? POP2
|
||||||
|
,y LDR2 #0001 ADD2 ,y STR2
|
||||||
|
@next1
|
||||||
|
#00 IOR #40 NEQ ,next2 ROT JMP? POP2
|
||||||
|
,x LDR2 #0001 SUB2 ,x STR2
|
||||||
|
@next2
|
||||||
|
#00 IOR #80 NEQ ,next3 ROT JMP? POP2
|
||||||
|
,x LDR2 #0001 ADD2 ,x STR2
|
||||||
|
@next3
|
||||||
|
( redraw )
|
||||||
|
#01 ,cursor_icn ,x LDR2 ,y LDR2 ,putsprite JSR
|
||||||
|
|
||||||
BRK
|
BRK
|
||||||
|
|
||||||
|
@ -27,21 +49,6 @@ BRK
|
||||||
IOW ( redraw byte )
|
IOW ( redraw byte )
|
||||||
RTS
|
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
|
|d000 @ERROR BRK
|
||||||
|
|
||||||
|FFFA .RESET .FRAME .ERROR
|
|FFFA .RESET .FRAME .ERROR
|
||||||
|
|
4
uxn.c
4
uxn.c
|
@ -30,10 +30,10 @@ void push16(St8 *s, Uint16 a) { push8(s, a >> 8); push8(s, a); }
|
||||||
Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); }
|
Uint16 pop16(St8 *s) { return pop8(s) + (pop8(s) << 8); }
|
||||||
Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
|
Uint16 peek16(St8 *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); }
|
||||||
/* I/O */
|
/* I/O */
|
||||||
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 += 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 \n", pop8(&u->wst)); fflush(stdout); }
|
||||||
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_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_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)); }
|
||||||
|
|
Loading…
Reference in New Issue