2022-01-05 12:59:22 +00:00
|
|
|
#include "../uxn.h"
|
2022-01-05 13:28:22 +00:00
|
|
|
#include "system.h"
|
2022-01-05 12:59:22 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copyright (c) 2022 Devine Lu Linvega, Andrew Alderwick
|
|
|
|
|
|
|
|
Permission to use, copy, modify, and distribute this software for any
|
|
|
|
purpose with or without fee is hereby granted, provided that the above
|
|
|
|
copyright notice and this permission notice appear in all copies.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
WITH REGARD TO THIS SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2022-01-05 13:06:22 +00:00
|
|
|
static const char *errors[] = {
|
|
|
|
"Working-stack underflow",
|
|
|
|
"Return-stack underflow",
|
|
|
|
"Working-stack overflow",
|
|
|
|
"Return-stack overflow",
|
|
|
|
"Working-stack division by zero",
|
|
|
|
"Return-stack division by zero"};
|
2022-01-05 12:59:22 +00:00
|
|
|
|
2022-01-13 16:25:59 +00:00
|
|
|
static void
|
2022-01-13 18:25:31 +00:00
|
|
|
system_print(Stack *s, char *name)
|
2022-01-13 16:25:59 +00:00
|
|
|
{
|
2022-01-13 18:25:31 +00:00
|
|
|
Uint8 i;
|
|
|
|
fprintf(stderr, "<%s> ", name);
|
|
|
|
for(i = 0; i < s->ptr; i++)
|
2022-01-13 22:52:37 +00:00
|
|
|
fprintf(stderr, "%02x ", s->dat[i]);
|
2022-01-13 18:25:31 +00:00
|
|
|
if(!i)
|
|
|
|
fprintf(stderr, "empty");
|
|
|
|
fprintf(stderr, "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
system_inspect(Uxn *u)
|
|
|
|
{
|
|
|
|
system_print(&u->wst, "wst");
|
|
|
|
system_print(&u->rst, "rst");
|
2022-01-13 16:25:59 +00:00
|
|
|
}
|
|
|
|
|
2022-01-05 12:59:22 +00:00
|
|
|
int
|
2022-01-05 13:06:22 +00:00
|
|
|
uxn_halt(Uxn *u, Uint8 error, Uint16 addr)
|
2022-01-05 12:59:22 +00:00
|
|
|
{
|
2022-01-05 17:27:01 +00:00
|
|
|
Device *d = &u->dev[0];
|
2022-01-08 00:46:50 +00:00
|
|
|
Uint16 vec = GETVECTOR(d);
|
2022-01-06 22:32:28 +00:00
|
|
|
DEVPOKE16(0x4, addr);
|
|
|
|
d->dat[0x6] = error;
|
2022-01-05 17:27:01 +00:00
|
|
|
if(vec) {
|
2022-01-08 00:46:50 +00:00
|
|
|
/* need to rearm to run System/vector again */
|
|
|
|
d->dat[0] = 0;
|
|
|
|
d->dat[1] = 0;
|
2022-01-05 17:27:01 +00:00
|
|
|
if(error != 2) /* working stack overflow has special treatment */
|
|
|
|
vec += 0x0004;
|
|
|
|
return uxn_eval(u, vec);
|
|
|
|
}
|
2022-01-13 18:25:31 +00:00
|
|
|
system_inspect(u);
|
2022-01-05 13:06:22 +00:00
|
|
|
fprintf(stderr, "Halted: %s#%04x, at 0x%04x\n", errors[error], u->ram[addr], addr);
|
2022-01-05 12:59:22 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2022-01-05 13:28:22 +00:00
|
|
|
|
|
|
|
/* IO */
|
|
|
|
|
|
|
|
Uint8
|
|
|
|
system_dei(Device *d, Uint8 port)
|
|
|
|
{
|
|
|
|
switch(port) {
|
2022-01-13 02:40:51 +00:00
|
|
|
case 0x2: return d->u->wst.ptr;
|
|
|
|
case 0x3: return d->u->rst.ptr;
|
2022-01-05 13:28:22 +00:00
|
|
|
default: return d->dat[port];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
system_deo(Device *d, Uint8 port)
|
|
|
|
{
|
|
|
|
switch(port) {
|
2022-01-13 02:40:51 +00:00
|
|
|
case 0x2: d->u->wst.ptr = d->dat[port]; break;
|
|
|
|
case 0x3: d->u->rst.ptr = d->dat[port]; break;
|
2022-01-13 16:34:32 +00:00
|
|
|
case 0xe: system_inspect(d->u); break;
|
2022-01-05 13:28:22 +00:00
|
|
|
default: system_deo_special(d, port);
|
|
|
|
}
|
|
|
|
}
|