commit b88d2adc3d8c3193a5e61f35b91a3e50ca08596e
parent 19e84072d86d59e0347941e4a740ceb3ab63bc77
Author: Andrew Alderwick <andrew@alderwick.co.uk>
Date: Tue, 7 Sep 2021 22:11:52 +0100
Halt when talk function returns false, since setting ram.ptr no longer works
Diffstat:
5 files changed, 52 insertions(+), 34 deletions(-)
diff --git a/src/uxn-fast.c b/src/uxn-fast.c
@@ -30,11 +30,11 @@ See etc/mkuxn-fast.moon for instructions.
/* clang-format off */
static void poke8(Uint8 *m, Uint16 a, Uint8 b) { m[a] = b; }
static Uint8 peek8(Uint8 *m, Uint16 a) { return m[a]; }
-static void devw8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; d->talk(d, a & 0x0f, 1); }
+static int devw8(Device *d, Uint8 a, Uint8 b) { d->dat[a & 0xf] = b; return d->talk(d, a & 0x0f, 1); }
static Uint8 devr8(Device *d, Uint8 a) { d->talk(d, a & 0x0f, 0); return d->dat[a & 0xf]; }
void poke16(Uint8 *m, Uint16 a, Uint16 b) { poke8(m, a, b >> 8); poke8(m, a + 1, b); }
Uint16 peek16(Uint8 *m, Uint16 a) { return (peek8(m, a) << 8) + peek8(m, a + 1); }
-static void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); }
+static int devw16(Device *d, Uint8 a, Uint16 b) { return devw8(d, a, b >> 8) && devw8(d, a + 1, b); }
/* clang-format on */
@@ -379,7 +379,8 @@ uxn_eval(Uxn *u, Uint16 vec)
case 0x17: /* DEO */
{
Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
- devw8(&u->dev[a >> 4], a, b);
+ if(!devw8(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 2, 0)) {
u->wst.error = 1;
@@ -854,7 +855,8 @@ uxn_eval(Uxn *u, Uint16 vec)
{
Uint8 a = u->wst.dat[u->wst.ptr - 1];
Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
- devw16(&u->dev[a >> 4], a, b);
+ if(!devw16(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 3, 0)) {
u->wst.error = 1;
@@ -1310,7 +1312,8 @@ uxn_eval(Uxn *u, Uint16 vec)
case 0x57: /* DEOr */
{
Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
- devw8(&u->dev[a >> 4], a, b);
+ if(!devw8(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 2, 0)) {
u->rst.error = 1;
@@ -1785,7 +1788,8 @@ uxn_eval(Uxn *u, Uint16 vec)
{
Uint8 a = u->rst.dat[u->rst.ptr - 1];
Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
- devw16(&u->dev[a >> 4], a, b);
+ if(!devw16(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 3, 0)) {
u->rst.error = 1;
@@ -2273,7 +2277,8 @@ uxn_eval(Uxn *u, Uint16 vec)
case 0x97: /* DEOk */
{
Uint8 a = u->wst.dat[u->wst.ptr - 1], b = u->wst.dat[u->wst.ptr - 2];
- devw8(&u->dev[a >> 4], a, b);
+ if(!devw8(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 2, 0)) {
u->wst.error = 1;
@@ -2799,7 +2804,8 @@ uxn_eval(Uxn *u, Uint16 vec)
{
Uint8 a = u->wst.dat[u->wst.ptr - 1];
Uint16 b = (u->wst.dat[u->wst.ptr - 2] | (u->wst.dat[u->wst.ptr - 3] << 8));
- devw16(&u->dev[a >> 4], a, b);
+ if(!devw16(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->wst.ptr < 3, 0)) {
u->wst.error = 1;
@@ -3318,7 +3324,8 @@ uxn_eval(Uxn *u, Uint16 vec)
case 0xd7: /* DEOkr */
{
Uint8 a = u->rst.dat[u->rst.ptr - 1], b = u->rst.dat[u->rst.ptr - 2];
- devw8(&u->dev[a >> 4], a, b);
+ if(!devw8(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 2, 0)) {
u->rst.error = 1;
@@ -3844,7 +3851,8 @@ uxn_eval(Uxn *u, Uint16 vec)
{
Uint8 a = u->rst.dat[u->rst.ptr - 1];
Uint16 b = (u->rst.dat[u->rst.ptr - 2] | (u->rst.dat[u->rst.ptr - 3] << 8));
- devw16(&u->dev[a >> 4], a, b);
+ if(!devw16(&u->dev[a >> 4], a, b))
+ return 1;
#ifndef NO_STACK_CHECKS
if(__builtin_expect(u->rst.ptr < 3, 0)) {
u->rst.error = 1;
@@ -4029,7 +4037,7 @@ uxn_boot(Uxn *u)
}
Device *
-uxn_port(Uxn *u, Uint8 id, void (*talkfn)(Device *d, Uint8 b0, Uint8 w))
+uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *d, Uint8 b0, Uint8 w))
{
Device *d = &u->dev[id];
d->addr = id * 0x10;
diff --git a/src/uxn.c b/src/uxn.c
@@ -36,7 +36,7 @@ static Uint16 pop8k(Stack *s) { if(s->kptr == 0) { s->error = 1; return 0; } ret
static Uint16 pop8d(Stack *s) { if(s->ptr == 0) { s->error = 1; return 0; } return s->dat[--s->ptr]; }
static void poke8(Uint8 *m, Uint16 a, Uint16 b) { m[a] = b; }
static Uint16 peek8(Uint8 *m, Uint16 a) { return m[a]; }
-static void devw8(Device *d, Uint8 a, Uint16 b) { d->dat[a & 0xf] = b; d->talk(d, a & 0x0f, 1); }
+static int devw8(Device *d, Uint8 a, Uint16 b) { d->dat[a & 0xf] = b; return d->talk(d, a & 0x0f, 1); }
static Uint16 devr8(Device *d, Uint8 a) { d->talk(d, a & 0x0f, 0); return d->dat[a & 0xf]; }
static void warp8(Uxn *u, Uint16 a){ u->ram.ptr += (Sint8)a; }
static void pull8(Uxn *u){ push8(u->src, peek8(u->ram.dat, u->ram.ptr++)); }
@@ -45,7 +45,7 @@ static void push16(Stack *s, Uint16 a) { push8(s, a >> 8); push8(s, a); }
static Uint16 pop16(Stack *s) { Uint8 a = pop8(s), b = pop8(s); return a + (b << 8); }
void poke16(Uint8 *m, Uint16 a, Uint16 b) { poke8(m, a, b >> 8); poke8(m, a + 1, b); }
Uint16 peek16(Uint8 *m, Uint16 a) { return (peek8(m, a) << 8) + peek8(m, a + 1); }
-static void devw16(Device *d, Uint8 a, Uint16 b) { devw8(d, a, b >> 8); devw8(d, a + 1, b); }
+static int devw16(Device *d, Uint8 a, Uint16 b) { return devw8(d, a, b >> 8) && devw8(d, a + 1, b); }
static Uint16 devr16(Device *d, Uint8 a) { return (devr8(d, a) << 8) + devr8(d, a + 1); }
static void warp16(Uxn *u, Uint16 a){ u->ram.ptr = a; }
static void pull16(Uxn *u){ push16(u->src, peek16(u->ram.dat, u->ram.ptr++)); u->ram.ptr++; }
@@ -116,7 +116,7 @@ uxn_eval(Uxn *u, Uint16 vec)
case 0x14: /* LDA */ a = pop16(u->src); push(u->src, peek(u->ram.dat, a)); break;
case 0x15: /* STA */ a = pop16(u->src); b = pop(u->src); poke(u->ram.dat, a, b); break;
case 0x16: /* DEI */ a = pop8(u->src); push(u->src, devr(&u->dev[a >> 4], a)); break;
- case 0x17: /* DEO */ a = pop8(u->src); b = pop(u->src); devw(&u->dev[a >> 4], a, b); break;
+ case 0x17: /* DEO */ a = pop8(u->src); b = pop(u->src); if (!devw(&u->dev[a >> 4], a, b)) return 1; break;
/* Arithmetic */
case 0x18: /* ADD */ a = pop(u->src), b = pop(u->src); push(u->src, b + a); break;
case 0x19: /* SUB */ a = pop(u->src), b = pop(u->src); push(u->src, b - a); break;
@@ -148,7 +148,7 @@ uxn_boot(Uxn *u)
}
Device *
-uxn_port(Uxn *u, Uint8 id, void (*talkfn)(Device *d, Uint8 b0, Uint8 w))
+uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *d, Uint8 b0, Uint8 w))
{
Device *d = &u->dev[id];
d->addr = id * 0x10;
diff --git a/src/uxn.h b/src/uxn.h
@@ -29,7 +29,7 @@ typedef struct {
typedef struct Device {
struct Uxn *u;
Uint8 addr, dat[16], *mem;
- void (*talk)(struct Device *d, Uint8, Uint8);
+ int (*talk)(struct Device *d, Uint8, Uint8);
} Device;
typedef struct Uxn {
@@ -46,4 +46,4 @@ Uint16 peek16(Uint8 *m, Uint16 a);
int uxn_boot(Uxn *c);
int uxn_eval(Uxn *u, Uint16 vec);
int uxn_halt(Uxn *u, Uint8 error, char *name, int id);
-Device *uxn_port(Uxn *u, Uint8 id, void (*talkfn)(Device *, Uint8, Uint8));
+Device *uxn_port(Uxn *u, Uint8 id, int (*talkfn)(Device *, Uint8, Uint8));
diff --git a/src/uxncli.c b/src/uxncli.c
@@ -44,7 +44,7 @@ inspect(Stack *s, char *name)
#pragma mark - Devices
-static void
+static int
system_talk(Device *d, Uint8 b0, Uint8 w)
{
if(!w) { /* read */
@@ -60,19 +60,21 @@ system_talk(Device *d, Uint8 b0, Uint8 w)
inspect(&d->u->wst, "Working-stack");
inspect(&d->u->rst, "Return-stack");
break;
- case 0xf: d->u->ram.ptr = 0x0000; break;
+ case 0xf: return 0;
}
}
+ return 1;
}
-static void
+static int
console_talk(Device *d, Uint8 b0, Uint8 w)
{
if(w && b0 > 0x7)
write(b0 - 0x7, (char *)&d->dat[b0], 1);
+ return 1;
}
-static void
+static int
file_talk(Device *d, Uint8 b0, Uint8 w)
{
Uint8 read = b0 == 0xd;
@@ -89,9 +91,10 @@ file_talk(Device *d, Uint8 b0, Uint8 w)
}
poke16(d->dat, 0x2, result);
}
+ return 1;
}
-static void
+static int
datetime_talk(Device *d, Uint8 b0, Uint8 w)
{
time_t seconds = time(NULL);
@@ -108,14 +111,16 @@ datetime_talk(Device *d, Uint8 b0, Uint8 w)
d->dat[0xa] = t->tm_isdst;
(void)b0;
(void)w;
+ return 1;
}
-static void
+static int
nil_talk(Device *d, Uint8 b0, Uint8 w)
{
(void)d;
(void)b0;
(void)w;
+ return 1;
}
#pragma mark - Generics
@@ -126,7 +131,6 @@ int
uxn_halt(Uxn *u, Uint8 error, char *name, int id)
{
fprintf(stderr, "Halted: %s %s#%04x, at 0x%04x\n", name, errors[error - 1], id, u->ram.ptr);
- u->ram.ptr = 0;
return 0;
}
diff --git a/src/uxnemu.c b/src/uxnemu.c
@@ -289,7 +289,7 @@ docolors(Device *d)
#pragma mark - Devices
-static void
+static int
system_talk(Device *d, Uint8 b0, Uint8 w)
{
if(!w) { /* read */
@@ -301,21 +301,23 @@ system_talk(Device *d, Uint8 b0, Uint8 w)
switch(b0) {
case 0x2: d->u->wst.ptr = d->dat[0x2]; break;
case 0x3: d->u->rst.ptr = d->dat[0x3]; break;
- case 0xf: d->u->ram.ptr = 0x0000; break;
+ case 0xf: return 0;
}
if(b0 > 0x7 && b0 < 0xe)
docolors(d);
}
+ return 1;
}
-static void
+static int
console_talk(Device *d, Uint8 b0, Uint8 w)
{
if(w && b0 > 0x7)
write(b0 - 0x7, (char *)&d->dat[b0], 1);
+ return 1;
}
-static void
+static int
screen_talk(Device *d, Uint8 b0, Uint8 w)
{
if(w && b0 == 0xe) {
@@ -335,9 +337,10 @@ screen_talk(Device *d, Uint8 b0, Uint8 w)
ppu_1bpp(&ppu, layer, x, y, addr, d->dat[0xf] & 0xf, d->dat[0xf] >> 0x4 & 0x1, d->dat[0xf] >> 0x5 & 0x1);
reqdraw = 1;
}
+ return 1;
}
-static void
+static int
file_talk(Device *d, Uint8 b0, Uint8 w)
{
Uint8 read = b0 == 0xd;
@@ -356,13 +359,14 @@ file_talk(Device *d, Uint8 b0, Uint8 w)
}
poke16(d->dat, 0x2, result);
}
+ return 1;
}
-static void
+static int
audio_talk(Device *d, Uint8 b0, Uint8 w)
{
Apu *c = &apu[d - devaudio0];
- if(!audio_id) return;
+ if(!audio_id) return 1;
if(!w) {
if(b0 == 0x2)
poke16(d->dat, 0x2, c->i);
@@ -379,9 +383,10 @@ audio_talk(Device *d, Uint8 b0, Uint8 w)
SDL_UnlockAudioDevice(audio_id);
SDL_PauseAudioDevice(audio_id, 0);
}
+ return 1;
}
-static void
+static int
datetime_talk(Device *d, Uint8 b0, Uint8 w)
{
time_t seconds = time(NULL);
@@ -398,14 +403,16 @@ datetime_talk(Device *d, Uint8 b0, Uint8 w)
d->dat[0xa] = t->tm_isdst;
(void)b0;
(void)w;
+ return 1;
}
-static void
+static int
nil_talk(Device *d, Uint8 b0, Uint8 w)
{
(void)d;
(void)b0;
(void)w;
+ return 1;
}
#pragma mark - Generics
@@ -435,7 +442,6 @@ int
uxn_halt(Uxn *u, Uint8 error, char *name, int id)
{
fprintf(stderr, "Halted: %s %s#%04x, at 0x%04x\n", name, errors[error - 1], id, u->ram.ptr);
- u->ram.ptr = 0;
return 0;
}