uxn

Varvara Ordinator, written in ANSI C(SDL2)
git clone https://git.eamoncaddigan.net/uxn.git
Log | Files | Refs | README | LICENSE

commit 04f48ec02b5b08ac01739059bb54a9e633867244
parent f06a6002319f6463ffcb54c99e8112d456623fe3
Author: Andrew Alderwick <andrew@alderwick.co.uk>
Date:   Tue, 20 Apr 2021 22:30:26 +0100

Added memory to individual devices.

Diffstat:
Mprojects/examples/dev.console.usm | 11++++++-----
Mprojects/examples/dev.controller.buttons.usm | 17+++++++++--------
Msrc/apu.c | 2+-
Msrc/apu.h | 2+-
Msrc/assembler.c | 2+-
Msrc/debugger.c | 41+++++++++++++++++------------------------
Msrc/emulator.c | 166++++++++++++++++++++++++++++++++++++++++----------------------------------------
Msrc/uxn.c | 16++++++++++------
Msrc/uxn.h | 20+++++++++++++-------
9 files changed, 141 insertions(+), 136 deletions(-)

diff --git a/projects/examples/dev.console.usm b/projects/examples/dev.console.usm @@ -2,13 +2,9 @@ %RTN { JMP2r } -( devices ) - -|0110 @Console [ &pad $8 &char $1 ] - ( program ) -|0200 +|0100 ;hello-word ;print JSR2 @@ -25,3 +21,8 @@ BRK RTN @hello-word [ 48 65 6c 6c 6f 20 57 6f 72 6c 64 21 ] + +( devices ) + +|ff10 @Console [ &pad $8 &char $1 ] + diff --git a/projects/examples/dev.controller.buttons.usm b/projects/examples/dev.controller.buttons.usm @@ -10,14 +10,7 @@ @slime $1 -( devices ) - -|0100 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] -|0110 @Console [ &pad $8 &char $1 &byte $1 &short $2 &string $2 ] -|0120 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ] -|0140 @Controller [ &vector $2 &button $1 &key $1 ] - -|0200 +|0100 ( theme ) #0daf .System/r IOW2 @@ -84,3 +77,11 @@ BRK @left_icn [ 3c7e ef1f 1fef 7e3c ] @right_icn [ 3c7e f7f8 f8f7 7e3c ] @slime_icn [ 0000 183c 3c18 0000 ] + +( devices ) + +|ff00 @System [ &vector $2 &pad $6 &r $2 &g $2 &b $2 ] +|ff10 @Console [ &pad $8 &char $1 &byte $1 &short $2 &string $2 ] +|ff20 @Screen [ &vector $2 &width $2 &height $2 &pad $2 &x $2 &y $2 &addr $2 &color $1 ] +|ff40 @Controller [ &vector $2 &button $1 &key $1 ] + diff --git a/src/apu.c b/src/apu.c @@ -45,7 +45,7 @@ render_note(Apu *apu, Uxn *u, int note_i, Sint16 *samples, int n_samples) if(apu->queue->i == apu->queue->n) { apu->queue->i = apu->queue->n = 0; if(!apu->queue->finishes) { - u->ram.dat[apu->channel_addr] = note_i; + *apu->channel_ptr = note_i; evaluxn(u, wv->vector); } } diff --git a/src/apu.h b/src/apu.h @@ -36,8 +36,8 @@ typedef struct { typedef struct { Queue *queue; Note *notes; + Uint8 *channel_ptr; int n_notes; - Uint16 channel_addr; } Apu; void apu_render(Apu *apu, Uxn *u, Sint16 *samples, int n_samples); diff --git a/src/assembler.c b/src/assembler.c @@ -11,7 +11,7 @@ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. */ -#define TRIM 0x0200 +#define TRIM 0x0100 typedef unsigned char Uint8; typedef signed char Sint8; diff --git a/src/debugger.c b/src/debugger.c @@ -38,51 +38,44 @@ printstack(Stack *s) #pragma mark - Devices Uint8 -console_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +console_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - Uint8 *m = u->ram.dat; switch(b0) { case 0x08: printf("%c", b1); break; case 0x09: printf("0x%02x\n", b1); break; - case 0x0b: printf("0x%04x\n", (m[ptr + 0x0a] << 8) + b1); break; + case 0x0b: printf("0x%04x\n", (m[0x0a] << 8) + b1); break; } fflush(stdout); - (void)m; - (void)ptr; + (void)u; (void)b0; return b1; } Uint8 -file_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +file_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - Uint8 *m = u->ram.dat; - char *name = (char *)&m[(m[ptr + 8] << 8) + m[ptr + 8 + 1]]; - Uint16 length = (m[ptr + 8 + 2] << 8) + m[ptr + 8 + 3]; - Uint16 offset = (m[ptr + 0] << 8) + m[ptr + 1]; - if(b0 == 0x0d) { - Uint16 addr = (m[ptr + 8 + 4] << 8) + b1; - FILE *f = fopen(name, "r"); - if(f && fseek(f, offset, SEEK_SET) != -1 && fread(&m[addr], length, 1, f)) { + Uint8 read = b0 == 0xd; + if(read || b0 == 0xf) { + char *name = (char *)&u->ram.dat[genpeek16(m, 0x8)]; + Uint16 result = 0, length = genpeek16(m, 0xa); + Uint16 offset = genpeek16(m, 0x4); + Uint16 addr = (m[b0 - 1] << 8) | b1; + FILE *f = fopen(name, read ? "r" : (offset ? "a" : "w")); + if(f) { + if(fseek(f, offset, SEEK_SET) != -1 && (result = read ? fread(&m[addr], 1, length, f) : fwrite(&m[addr], 1, length, f))) + printf("%s %d bytes, at %04x from %s\n", read ? "Loaded" : "Saved", length, addr, name); fclose(f); - printf("Loaded %d bytes, at %04x from %s\n", length, addr, name); - } - } else if(b0 == 0x0f) { - Uint16 addr = (m[ptr + 8 + 6] << 8) + b1; - FILE *f = fopen(name, (m[ptr + 2] & 0x1) ? "a" : "w"); - if(f && fseek(f, offset, SEEK_SET) != -1 && fwrite(&m[addr], length, 1, f)) { - fclose(f); - printf("Saved %d bytes, at %04x from %s\n", length, addr, name); } + genpoke16(m, 0x2, result); } return b1; } Uint8 -ppnil(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +ppnil(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { (void)u; - (void)ptr; + (void)m; (void)b0; return b1; } diff --git a/src/emulator.c b/src/emulator.c @@ -125,28 +125,28 @@ init(Uxn *u) } void -domouse(Uxn *u, SDL_Event *event) +domouse(SDL_Event *event) { Uint8 flag = 0x00; Uint16 x = clamp(event->motion.x / zoom - ppu.pad, 0, ppu.hor * 8 - 1); Uint16 y = clamp(event->motion.y / zoom - ppu.pad, 0, ppu.ver * 8 - 1); - mempoke16(u, devmouse->addr + 2, x); - mempoke16(u, devmouse->addr + 4, y); - u->ram.dat[devmouse->addr + 7] = 0x00; + genpoke16(devmouse->dat, 0x2, x); + genpoke16(devmouse->dat, 0x4, y); + devmouse->dat[7] = 0x00; switch(event->button.button) { case SDL_BUTTON_LEFT: flag = 0x01; break; case SDL_BUTTON_RIGHT: flag = 0x10; break; } switch(event->type) { case SDL_MOUSEBUTTONDOWN: - u->ram.dat[devmouse->addr + 6] |= flag; - if(flag == 0x10 && (u->ram.dat[devmouse->addr + 6] & 0x01)) - u->ram.dat[devmouse->addr + 7] = 0x01; - if(flag == 0x01 && (u->ram.dat[devmouse->addr + 6] & 0x10)) - u->ram.dat[devmouse->addr + 7] = 0x10; + devmouse->dat[6] |= flag; + if(flag == 0x10 && (devmouse->dat[6] & 0x01)) + devmouse->dat[7] = 0x01; + if(flag == 0x01 && (devmouse->dat[6] & 0x10)) + devmouse->dat[7] = 0x10; break; case SDL_MOUSEBUTTONUP: - u->ram.dat[devmouse->addr + 6] &= (~flag); + devmouse->dat[6] &= (~flag); break; } } @@ -172,45 +172,45 @@ doctrl(Uxn *u, SDL_Event *event, int z) case SDLK_RIGHT: flag = 0x80; break; } if(flag && z) - u->ram.dat[devctrl->addr + 2] |= flag; + devctrl->dat[2] |= flag; else if(flag) - u->ram.dat[devctrl->addr + 2] &= (~flag); + devctrl->dat[2] &= (~flag); if(z && event->key.keysym.sym < 20) - u->ram.dat[devctrl->addr + 3] = event->key.keysym.sym; + devctrl->dat[3] = event->key.keysym.sym; } #pragma mark - Devices Uint8 -system_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +system_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - getcolors(&ppu, &u->ram.dat[ptr + 0x0008]); + getcolors(&ppu, &m[0x8]); reqdraw = 1; + (void)u; (void)b0; return b1; } Uint8 -console_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +console_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - Uint8 *m = u->ram.dat; switch(b0) { - case 0x08: printf("%c", b1); break; - case 0x09: printf("0x%02x\n", b1); break; - case 0x0b: printf("0x%04x\n", (m[ptr + 0x0a] << 8) + b1); break; - case 0x0d: printf("%s\n", &m[(m[ptr + 0x0c] << 8) + b1]); break; + case 0x8: printf("%c", b1); break; + case 0x9: printf("0x%02x\n", b1); break; + case 0xb: printf("0x%04x\n", (m[0xa] << 8) + b1); break; + case 0xd: printf("%s\n", &u->ram.dat[(m[0xc] << 8) + b1]); break; } fflush(stdout); return b1; } Uint8 -screen_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +screen_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - if(b0 == 0x0e) { - Uint16 x = mempeek16(u, devscreen->addr + 0x08); - Uint16 y = mempeek16(u, devscreen->addr + 0x0a); - Uint8 *addr = &u->ram.dat[mempeek16(u, devscreen->addr + 0x0c)]; + if(b0 == 0xe) { + Uint16 x = genpeek16(m, 0x8); + Uint16 y = genpeek16(m, 0xa); + Uint8 *addr = &u->ram.dat[genpeek16(m, 0xc)]; Uint8 *layer = b1 >> 4 & 0x1 ? ppu.fg : ppu.bg; switch(b1 >> 5) { case 0: putpixel(&ppu, layer, x, y, b1 & 0x3); break; @@ -219,38 +219,36 @@ screen_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) } reqdraw = 1; } - (void)ptr; return b1; } Uint8 -file_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +file_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - Uint8 *m = u->ram.dat, read = b0 == 0x0d; - if(read || b0 == 0x0f) { - char *name = (char *)&m[mempeek16(u, ptr + 8)]; - Uint16 result = 0, length = mempeek16(u, ptr + 8 + 2); - Uint16 offset = mempeek16(u, ptr + 4); - Uint16 addr = (m[ptr + b0 - 1] << 8) | b1; + Uint8 read = b0 == 0xd; + if(read || b0 == 0xf) { + char *name = (char *)&u->ram.dat[genpeek16(m, 0x8)]; + Uint16 result = 0, length = genpeek16(m, 0xa); + Uint16 offset = genpeek16(m, 0x4); + Uint16 addr = (m[b0 - 1] << 8) | b1; FILE *f = fopen(name, read ? "r" : (offset ? "a" : "w")); if(f) { if(fseek(f, offset, SEEK_SET) != -1 && (result = read ? fread(&m[addr], 1, length, f) : fwrite(&m[addr], 1, length, f))) printf("%s %d bytes, at %04x from %s\n", read ? "Loaded" : "Saved", length, addr, name); fclose(f); } - mempoke16(u, ptr + 2, result); + genpoke16(m, 0x2, result); } return b1; } static Uint8 -audio_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +audio_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - Uint8 *m = u->ram.dat + ptr; if(b0 == 0xa) { if(b1 >= apu.n_notes) apu.notes = SDL_realloc(apu.notes, (b1 + 1) * sizeof(Note)); while(b1 >= apu.n_notes) SDL_zero(apu.notes[apu.n_notes++]); - apu_play_note(&apu.notes[b1], (m[0x0] << 8) + m[0x1], (m[0x2] << 8) + m[0x3], m[0x8], m[0x9] & 0x7f, m[0x9] > 0x7f); + apu_play_note(&apu.notes[b1], genpeek16(m, 0x0), genpeek16(m, 0x2), m[0x8], m[0x9] & 0x7f, m[0x9] > 0x7f); } else if(b0 == 0xe && apu.queue != NULL) { if(apu.queue->n == apu.queue->sz) { apu.queue->sz = apu.queue->sz < 4 ? 4 : apu.queue->sz * 2; @@ -259,48 +257,50 @@ audio_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) if(apu.queue->is_envelope) apu.queue->dat[apu.queue->n++] = (m[0xb] << 7) + (m[0xc] >> 1); else - apu.queue->dat[apu.queue->n++] = (m[0xb] << 8) + m[0xc] + 0x8000; + apu.queue->dat[apu.queue->n++] = genpeek16(m, 0xb) + 0x8000; apu.queue->dat[apu.queue->n++] = (m[0xd] << 8) + b1; } else if(b0 == 0xf && apu.queue != NULL) apu.queue->finishes = 1; + (void)u; return b1; } Uint8 -midi_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +midi_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { (void)u; - printf("%04x - %02x,%02x\n", ptr, b0, b1); + (void)m; + printf("midi - %02x,%02x\n", b0, b1); return b1; } Uint8 -datetime_poke(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +datetime_poke(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { - Uint8 *m = u->ram.dat; time_t seconds = time(NULL); struct tm *t = localtime(&seconds); t->tm_year += 1900; - m[ptr + 0] = (t->tm_year & 0xff00) >> 8; - m[ptr + 1] = t->tm_year & 0xff; - m[ptr + 2] = t->tm_mon; - m[ptr + 3] = t->tm_mday; - m[ptr + 4] = t->tm_hour; - m[ptr + 5] = t->tm_min; - m[ptr + 6] = t->tm_sec; - m[ptr + 7] = t->tm_wday; - m[ptr + 8] = (t->tm_yday & 0xff00) >> 8; - m[ptr + 9] = t->tm_yday & 0xff; - m[ptr + 10] = t->tm_isdst; + m[0x0] = (t->tm_year & 0xff00) >> 8; + m[0x1] = t->tm_year & 0xff; + m[0x2] = t->tm_mon; + m[0x3] = t->tm_mday; + m[0x4] = t->tm_hour; + m[0x5] = t->tm_min; + m[0x6] = t->tm_sec; + m[0x7] = t->tm_wday; + m[0x8] = (t->tm_yday & 0xff00) >> 8; + m[0x9] = t->tm_yday & 0xff; + m[0xa] = t->tm_isdst; + (void)u; (void)b0; return b1; } Uint8 -ppnil(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) +ppnil(Uxn *u, Uint8 *m, Uint8 b0, Uint8 b1) { (void)u; - (void)ptr; + (void)m; (void)b0; return b1; } @@ -310,7 +310,7 @@ ppnil(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1) int start(Uxn *u) { - evaluxn(u, 0x0200); + evaluxn(u, 0x0100); redraw(ppu.output, u); while(1) { SDL_Event event; @@ -323,19 +323,19 @@ start(Uxn *u) break; case SDL_TEXTINPUT: if(event.text.text[0] >= ' ' || event.text.text[0] <= '~') - u->ram.dat[devctrl->addr + 3] = event.text.text[0]; + devctrl->dat[3] = event.text.text[0]; break; case SDL_KEYDOWN: case SDL_KEYUP: doctrl(u, &event, event.type == SDL_KEYDOWN); - evaluxn(u, mempeek16(u, devctrl->addr)); - u->ram.dat[devctrl->addr + 3] = 0; + evaluxn(u, genpeek16(devctrl->dat, 0)); + devctrl->dat[3] = 0; break; case SDL_MOUSEBUTTONUP: case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEMOTION: - domouse(u, &event); - evaluxn(u, mempeek16(u, devmouse->addr)); + domouse(&event); + evaluxn(u, genpeek16(devmouse->dat, 0)); break; case SDL_WINDOWEVENT: if(event.window.event == SDL_WINDOWEVENT_EXPOSED) @@ -343,7 +343,7 @@ start(Uxn *u) break; } } - evaluxn(u, mempeek16(u, devscreen->addr)); + evaluxn(u, genpeek16(devscreen->dat, 0)); SDL_UnlockAudioDevice(audio_id); if(reqdraw) redraw(ppu.output, u); @@ -368,28 +368,28 @@ main(int argc, char **argv) if(!init(&u)) return error("Init", "Failed"); - devsystem = portuxn(&u, 0x00, "system", system_poke); - portuxn(&u, 0x01, "console", console_poke); - devscreen = portuxn(&u, 0x02, "screen", screen_poke); - devapu = portuxn(&u, 0x03, "audio", audio_poke); - devctrl = portuxn(&u, 0x04, "controller", ppnil); - portuxn(&u, 0x05, "---", ppnil); - devmouse = portuxn(&u, 0x06, "mouse", ppnil); - devfile = portuxn(&u, 0x07, "file", file_poke); - portuxn(&u, 0x08, "---", ppnil); - portuxn(&u, 0x09, "midi", ppnil); - portuxn(&u, 0x0a, "datetime", datetime_poke); - portuxn(&u, 0x0b, "---", ppnil); - portuxn(&u, 0x0c, "---", ppnil); - portuxn(&u, 0x0d, "---", ppnil); - portuxn(&u, 0x0e, "---", ppnil); - portuxn(&u, 0x0f, "---", ppnil); - - apu.channel_addr = devapu->addr + 0xa; + devsystem = portuxn(&u, 0x0, "system", system_poke); + portuxn(&u, 0x1, "console", console_poke); + devscreen = portuxn(&u, 0x2, "screen", screen_poke); + devapu = portuxn(&u, 0x3, "audio", audio_poke); + devctrl = portuxn(&u, 0x4, "controller", ppnil); + portuxn(&u, 0x5, "---", ppnil); + devmouse = portuxn(&u, 0x6, "mouse", ppnil); + devfile = portuxn(&u, 0x7, "file", file_poke); + portuxn(&u, 0x8, "---", ppnil); + portuxn(&u, 0x9, "midi", ppnil); + portuxn(&u, 0xa, "datetime", datetime_poke); + portuxn(&u, 0xb, "---", ppnil); + portuxn(&u, 0xc, "---", ppnil); + portuxn(&u, 0xd, "---", ppnil); + portuxn(&u, 0xe, "---", ppnil); + portuxn(&u, 0xf, "---", ppnil); + + apu.channel_ptr = &devapu->dat[0xa]; /* Write screen size to dev/screen */ - mempoke16(&u, devscreen->addr + 2, ppu.hor * 8); - mempoke16(&u, devscreen->addr + 4, ppu.ver * 8); + genpoke16(devscreen->dat, 2, ppu.hor * 8); + genpoke16(devscreen->dat, 4, ppu.ver * 8); start(&u); quit(); diff --git a/src/uxn.c b/src/uxn.c @@ -21,11 +21,15 @@ Uint8 pop8(Stack *s) { if (s->ptr == 0) { s->error = 1; return 0; } return s->d Uint8 peek8(Stack *s, Uint8 a) { if (s->ptr < a + 1) s->error = 1; return s->dat[s->ptr - a - 1]; } void mempoke8(Uxn *u, Uint16 a, Uint8 b) { u->ram.dat[a] = b; } Uint8 mempeek8(Uxn *u, Uint16 a) { return u->ram.dat[a]; } +void devpoke8(Uxn *u, Uint8 a, Uint8 b) { Device *dev = &u->dev[a >> 4]; dev->dat[a & 0xf] = dev->poke(u, dev->dat, a & 0x0f, b); } +Uint8 devpeek8(Uxn *u, Uint8 a) { return u->dev[a >> 4].dat[a & 0xf]; } void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); } Uint16 pop16(Stack *s) { return pop8(s) + (pop8(s) << 8); } Uint16 peek16(Stack *s, Uint8 a) { return peek8(s, a * 2) + (peek8(s, a * 2 + 1) << 8); } 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); } +void devpoke16(Uxn *u, Uint8 a, Uint16 b) { devpoke8(u, a, b >> 8); devpoke8(u, a + 1, b); } +Uint16 devpeek16(Uxn *u, Uint16 a) { return (devpeek8(u, a) << 8) + devpeek8(u, a + 1); } /* Stack */ void op_brk(Uxn *u) { u->ram.ptr = 0; } void op_nop(Uxn *u) { (void)u; } @@ -42,8 +46,8 @@ void op_gth(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b void op_lth(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, b < a); } void op_gts(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, (Sint8)b > (Sint8)a); } void op_lts(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); push8(u->src, (Sint8)b < (Sint8)a); } -void op_ior(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, mempeek8(u, PAGE_DEVICE + a)); } -void op_iow(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); mempoke8(u, PAGE_DEVICE + a, b); u->dev[(a & 0xf0) >> 4].poke(u, PAGE_DEVICE + (a & 0xf0), a & 0x0f, b); } +void op_ior(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, devpeek8(u, a)); } +void op_iow(Uxn *u) { Uint8 a = pop8(u->src), b = pop8(u->src); devpoke8(u, a, b); } /* Memory */ void op_pek(Uxn *u) { Uint8 a = pop8(u->src); push8(u->src, mempeek8(u, a)); } void op_pok(Uxn *u) { Uint8 a = pop8(u->src); Uint8 b = pop8(u->src); mempoke8(u, a, b); } @@ -76,8 +80,8 @@ void op_gth16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->sr void op_lth16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, b < a); } void op_gts16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, (Sint16)b > (Sint16)a); } void op_lts16(Uxn *u) { Uint16 a = pop16(u->src), b = pop16(u->src); push8(u->src, (Sint16)b < (Sint16)a); } -void op_ior16(Uxn *u) { Uint8 a = pop8(u->src); push16(u->src, mempeek16(u, PAGE_DEVICE + a)); } -void op_iow16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); mempoke16(u, PAGE_DEVICE + a, b); u->dev[(a & 0xf0) >> 4].poke(u, PAGE_DEVICE + (a & 0xf0), (a & 0x0f)+1, b); } +void op_ior16(Uxn *u) { Uint8 a = pop8(u->src); push16(u->src, devpeek16(u, a)); } +void op_iow16(Uxn *u) { Uint8 a = pop8(u->src); Uint16 b = pop16(u->src); devpoke16(u, a, b); } /* Memory(16-bits) */ void op_pek16(Uxn *u) { Uint16 a = pop16(u->src); push8(u->src, mempeek8(u, a)); } void op_pok16(Uxn *u) { Uint16 a = pop16(u->src); Uint8 b = pop8(u->src); mempoke8(u, a, b); } @@ -175,10 +179,10 @@ loaduxn(Uxn *u, char *filepath) } Device * -portuxn(Uxn *u, Uint8 id, char *name, Uint8 (*pofn)(Uxn *u, Uint16 ptr, Uint8 b0, Uint8 b1)) +portuxn(Uxn *u, Uint8 id, char *name, Uint8 (*pofn)(Uxn *u, Uint8 *devmem, Uint8 b0, Uint8 b1)) { Device *d = &u->dev[id]; - d->addr = PAGE_DEVICE + id * 0x10; + d->addr = id * 0x10; d->poke = pofn; printf("Device added #%02x: %s, at 0x%04x \n", id, name, d->addr); return d; diff --git a/src/uxn.h b/src/uxn.h @@ -16,9 +16,15 @@ typedef signed char Sint8; typedef unsigned short Uint16; typedef signed short Sint16; -#define PAGE_DEVICE 0x0100 -#define PAGE_PROGRAM 0x0200 -#define LOAD_OFFSET 0x0200 +#define PAGE_PROGRAM 0x0100 +#define LOAD_OFFSET 0x0100 + +#define genpeek16(ptr, i) ((ptr[i] << 8) + ptr[i + 1]) +#define genpoke16(ptr, i, v) \ + do { \ + ptr[i] = v >> 8; \ + ptr[i + 1] = v & 0xff; \ + } while(0) typedef struct { Uint8 ptr, error; @@ -33,8 +39,8 @@ typedef struct { struct Uxn; typedef struct Device { - Uint16 addr; - Uint8 (*poke)(struct Uxn *, Uint16, Uint8, Uint8); + Uint8 addr, dat[16]; + Uint8 (*poke)(struct Uxn *u, Uint8 *devmem, Uint8, Uint8); } Device; typedef struct Uxn { @@ -49,4 +55,4 @@ int evaluxn(Uxn *u, Uint16 vec); void mempoke16(Uxn *u, Uint16 a, Uint16 b); Uint16 mempeek16(Uxn *u, Uint16 a); -Device *portuxn(Uxn *u, Uint8 id, char *name, Uint8 (*pofn)(Uxn *, Uint16, Uint8, Uint8)); -\ No newline at end of file +Device *portuxn(Uxn *u, Uint8 id, char *name, Uint8 (*pofn)(Uxn *, Uint8 *, Uint8, Uint8)); +\ No newline at end of file