devices/system.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include "../xyw.h"
#define SYSTEM_STATE 0x00
#define SYSTEM_ERROR 0x01
#define SYSTEM_PAGE 0x02
#define SYSTEM_RANDOM 0x03
#define SYSTEM_ON_ERROR 0x04
#define SYSTEM_IMAGE_EXEC 0x06
#define SYSTEM_STATE_RUNNING 0x01
#define SYSTEM_STATE_ERROR 0x80
#define XYW_ERROR_NONE 0
/// Error handler tracking (accessible by xywrun.c for snapshot/reset)
xyw_byte error_handler_entry_s = 0;
void system_setup(xyw_byte *data)
{
(void)data;
srand(time(NULL));
error_handler_entry_s = 0;
}
xyw_byte system_input(xyw_byte *data, xyw_byte addr, xyw_byte *error)
{
if (addr == SYSTEM_RANDOM)
return (xyw_byte)(rand() & 0xFF);
(void)error;
return data[addr];
}
void system_output(xyw_byte *data, xyw_byte addr, xyw_byte *error)
{
(void)error;
if (addr == SYSTEM_IMAGE_EXEC + 1)
{
xyw_word target = XYW_PEEKW(&data[SYSTEM_IMAGE_EXEC]);
if (target != 0)
xyw_request_exec(target);
}
}
void system_tick(xyw_byte *data)
{
// Check if returning from error handler (after RTS popped the frame)
if ((data[SYSTEM_STATE] & SYSTEM_STATE_ERROR) &&
error_handler_entry_s != 0 &&
xyw_vm_get_system_depth() == error_handler_entry_s)
{
data[SYSTEM_STATE] &= ~SYSTEM_STATE_ERROR;
error_handler_entry_s = 0;
}
// Check for new error condition
if (data[SYSTEM_ERROR] != XYW_ERROR_NONE && !(data[SYSTEM_STATE] & SYSTEM_STATE_ERROR))
{
xyw_word on_error_handler = XYW_PEEKW(&data[SYSTEM_ON_ERROR]);
if (on_error_handler != 0)
{
XYW_DBG("Error occurred: %02X, jumping to error handler at %04X\n", data[SYSTEM_ERROR], on_error_handler);
data[SYSTEM_STATE] |= SYSTEM_STATE_ERROR;
error_handler_entry_s = xyw_vm_get_system_depth();
xyw_vm_push_frame(*pc);
*pc = on_error_handler;
}
else
{
// No error handler: halt execution
data[SYSTEM_STATE] &= ~SYSTEM_STATE_RUNNING;
}
}
}
|