all repos — xyw @ ca15c1d9da2f541927648bdb313bf1081f87bd63

A minimal virtual machine and assembler for terminals.

Implemented clock device.
h3rald h3rald@h3rald.com
Mon, 08 Dec 2025 23:17:10 +0100
commit

ca15c1d9da2f541927648bdb313bf1081f87bd63

parent

cee77120edf0966b1a596d3de734e9efbcc12390

6 files changed, 90 insertions(+), 10 deletions(-)

jump to
M MakefileMakefile

@@ -1,8 +1,8 @@

CC = gcc CFLAGS = -Wall -Wextra -g LDFLAGS = -SOURCES = xyw.c xywasm.c xywrun.c devices/console.c -OBJS = xyw.o xywasm.o xywrun.o devices/console.o +SOURCES = xyw.c xywasm.c xywrun.c devices/console.c devices/clock.c +OBJS = xyw.o xywasm.o xywrun.o devices/console.o devices/clock.o .PHONY: clean

@@ -20,6 +20,9 @@ $(CC) $(CFLAGS) -c xywasm.c -o xywasm.o

devices/console.o: devices/console.c xyw.h $(CC) $(CFLAGS) -c devices/console.c -o devices/console.o + +devices/clock.o: devices/clock.c xyw.h + $(CC) $(CFLAGS) -c devices/clock.c -o devices/clock.o clean: rm -f xyw xyw.exe $(OBJS)
M devices.xywdevices.xyw

@@ -15,12 +15,12 @@

;clock .macro clock.year $FF20 .macro clock.month $FF22 -.macro clock.week $FF23 -.macro clock.monthday $FF24 -.macro clock.weekday $FF25 -.macro clock.hour $FF26 -.macro clock.minute $FF27 -.macro clock.second $FF28 +.macro clock.monthday $FF23 +.macro clock.weekday $FF24 +.macro clock.hour $FF25 +.macro clock.minute $FF26 +.macro clock.second $FF27 +.macro clock.random $FF28 .macro clock.timer $FF29 .macro clock.on_timer_elapsed $FF2b
A devices/clock.c

@@ -0,0 +1,60 @@

+#include <time.h> +#include <stdlib.h> +#include <stdio.h> +#include "../xyw.h" + +/* clock device */ +#define CLOCK_YEAR 0x0 +#define CLOCK_MONTH 0x2 +#define CLOCK_MONTHDAY 0x3 +#define CLOCK_WEEKDAY 0x4 +#define CLOCK_CLOCK_HOUR 0x5 +#define CLOCK_MINUTE 0x6 +#define CLOCK_SECOND 0x7 +#define CLOCK_RANDOM 0x8 +#define CLOCK_TIMER 0x9 +#define CLOCK_ON_TIMER_ELAPSED 0x9 +void clock_init(xyw_byte *data) +{ + (void)data; + // Initialize random generator seed + srand(time(NULL)); +} + +xyw_byte clock_input(xyw_byte *data, xyw_byte addr, xyw_byte *error) +{ + (void)error; + (void)data; + srand(time(NULL)); + + time_t now = time(NULL); + struct tm *lt = localtime(&now); + if (!lt) + return 0; + + switch (addr) + { + case CLOCK_YEAR: + return (xyw_byte)((lt->tm_year + 1900) % 100); + case CLOCK_MONTH: + // 1-12 + return (xyw_byte)(lt->tm_mon + 1); + case CLOCK_MONTHDAY: + // 1-31 + return (xyw_byte)lt->tm_mday; + case CLOCK_WEEKDAY: + // 0=Sunday ... 6=Saturday + return (xyw_byte)lt->tm_wday; + case CLOCK_CLOCK_HOUR: + // 0-23 + return (xyw_byte)lt->tm_hour; + case CLOCK_MINUTE: + return (xyw_byte)lt->tm_min; + case CLOCK_SECOND: + return (xyw_byte)lt->tm_sec; + case CLOCK_RANDOM: + return (xyw_byte)(rand() & 0xFF); + default: + return 0; + } +}
A devices/clock.h

@@ -0,0 +1,4 @@

+#include "../xyw.h" + +void clock_init(xyw_byte *data); +xyw_byte clock_input(xyw_byte *data, xyw_byte addr, xyw_byte *error);
M xyw.hxyw.h

@@ -17,10 +17,12 @@ typedef unsigned short xyw_word;

typedef xyw_byte (*xyw_input)(xyw_byte *data, xyw_byte addr, xyw_byte *error); typedef void (*xyw_output)(xyw_byte *data, xyw_byte addr, xyw_byte *error); +typedef void (*xyw_init)(xyw_byte *data); typedef struct xyw_device { xyw_byte *data; + xyw_init init; xyw_input input; xyw_output output; } xyw_device;
M xywrun.cxywrun.c

@@ -2,6 +2,7 @@ #include <stdio.h>

#include "xyw.h" #include "devices/console.h" +#include "devices/clock.h" #define MEMORY_SIZE 0xffff #define STACK_SIZE 0xff

@@ -250,9 +251,11 @@ //// Initialize devices

xyw_device xyw_devices[XYW_TOTAL_DEVICES] = { // System device (not implemented yet) - {&xyw_memory[0xff00], 0, 0}, + {&xyw_memory[0xff00], 0, 0, 0}, // Console device - {&xyw_memory[0xff10], 0, console_output}, + {&xyw_memory[0xff10], 0, 0, console_output}, + // Clock device + {&xyw_memory[0xff20], clock_init, clock_input, 0}, // ... }; // clang-format on

@@ -277,6 +280,14 @@ }

xyw_dbg("Loaded %zu bytes into memory\n", bytes_read); fclose(fp); xyw_memory[SYSTEM_STATE] = 1; + // Initialize devices + for (int i = 0; i < XYW_TOTAL_DEVICES; i++) + { + if (xyw_devices[i].init) + { + xyw_devices[i].init(xyw_devices[i].data); + } + } while (xyw_memory[SYSTEM_STATE] && *pc < SYSTEM_MEMORY_START) { xyw_dbg("PC: %04X -> %02X (%s) [U:%02X|S:%02X|X:%02X|Y:%02X|XW:%04X|YW:%04X]\n", *pc, xyw_memory[*pc], xyw_instructions[xyw_memory[*pc] & 0x1F], *u, *s, *x, *y, *xw, *yw);