Commit 558d73061cc2a5655546a849bf949c9890153cb9

Commits
[COMMIT BEGIN]
commit 558d73061cc2a5655546a849bf949c9890153cb9
Author: 0x4248 <[email protected]>
Date:   Fri Mar 6 21:59:06 2026 +0000

    Photon: add libary

diff --git a/systems/IBM-PC/PhotonX/FONT.C b/systems/IBM-PC/PhotonX/FONT.C
new file mode 100644
index 0000000..bb17165
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/FONT.C
@@ -0,0 +1,130 @@
+char font8x8_basic[128][8] = {
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00},
+    { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00},
+    { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00},
+    { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00},
+    { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00},
+    { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00},
+    { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00},
+    { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00},
+    { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06},
+    { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00},
+    { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00},
+    { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00},
+    { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00},
+    { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00},
+    { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00},
+    { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00},
+    { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00},
+    { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00},
+    { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00},
+    { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},
+    { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},
+    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},
+    { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},
+    { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},
+    { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},
+    { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},
+    { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00},
+    { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00},
+    { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00},
+    { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00},
+    { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00},
+    { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00},
+    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00},
+    { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00},
+    { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00},
+    { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00},
+    { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
+    { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00},
+    { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00},
+    { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00},
+    { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00},
+    { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00},
+    { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00},
+    { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00},
+    { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00},
+    { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00},
+    { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00},
+    { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
+    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00},
+    { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},
+    { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00},
+    { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00},
+    { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00},
+    { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00},
+    { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00},
+    { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00},
+    { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00},
+    { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF},
+    { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00},
+    { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00},
+    { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00},
+    { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00},
+    { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00},
+    { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00},
+    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F},
+    { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00},
+    { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
+    { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E},
+    { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00},
+    { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},
+    { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00},
+    { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00},
+    { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00},
+    { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F},
+    { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78},
+    { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00},
+    { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00},
+    { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00},
+    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00},
+    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00},
+    { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00},
+    { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00},
+    { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F},
+    { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00},
+    { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00},
+    { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},
+    { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},
+    { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} 
+};
\ No newline at end of file
diff --git a/systems/IBM-PC/PhotonX/VGA.C b/systems/IBM-PC/PhotonX/VGA.C
new file mode 100644
index 0000000..d18f3f7
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/VGA.C
@@ -0,0 +1,262 @@
+#include <dos.h>
+#include <conio.h>
+#include "VGA.H"
+
+unsigned char far *vga = (unsigned char far *)MK_FP(VGA_SEG, 0);
+static uint8_t g_cls_color = 0;
+extern char font8x8_basic[128][8];
+
+static int in_gfx_bounds(int x, int y)
+{
+    if (x < 0 || x >= 320)
+        return 0;
+    if (y < 0 || y >= 200)
+        return 0;
+    return 1;
+}
+
+static void swap_u16(uint16_t *a, uint16_t *b)
+{
+    uint16_t temp = *a;
+    *a = *b;
+    *b = temp;
+}
+
+void vga_set_mode(uint8_t mode)
+{
+    union REGS regs;
+    regs.h.ah = 0x00;
+    regs.h.al = mode;
+    int86(0x10, &regs, &regs);
+}
+
+void vga_beep(int freq, int ms)
+{
+    sound(freq);
+    delay(ms);
+    nosound();
+}
+
+void vga_wait_key(void)
+{
+    getch();
+}
+
+void vga_text_setcolor(uint8_t fg, uint8_t bg)
+{
+    textcolor(fg & 0x0F);
+    textbackground(bg & 0x0F);
+}
+
+void vga_text_gotoxy(uint8_t x, uint8_t y)
+{
+    gotoxy((int)x + 1, (int)y + 1);
+}
+
+void vga_text_putch(char c)
+{
+    putch(c);
+}
+
+void vga_text_puts(const char *str)
+{
+    cputs(str);
+}
+
+void vga_text_cls(void)
+{
+    clrscr();
+}
+
+void vga_set_palette(uint8_t index, uint8_t r, uint8_t g, uint8_t b)
+{
+    outp(0x3C8, index);
+    outp(0x3C9, r);
+    outp(0x3C9, g);
+    outp(0x3C9, b);
+}
+
+void vga_gfx_setclscolor(uint8_t color)
+{
+    g_cls_color = color;
+}
+
+void vga_gfx_cls(void)
+{
+    int i;
+    for (i = 0; i < 320 * 200; i++)
+        vga[i] = g_cls_color;
+}
+
+void vga_gfx_putpixel(uint16_t x, uint16_t y, uint8_t color)
+{
+    if (!in_gfx_bounds((int)x, (int)y))
+        return;
+
+    vga[(unsigned int)y * 320u + (unsigned int)x] = color;
+}
+
+void vga_gfx_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color)
+{
+    int dx, dy, sx, sy, err, e2;
+    int cx = (int)x1;
+    int cy = (int)y1;
+    int tx = (int)x2;
+    int ty = (int)y2;
+
+    dx = (tx > cx) ? (tx - cx) : (cx - tx);
+    dy = (ty > cy) ? (ty - cy) : (cy - ty);
+    sx = (cx < tx) ? 1 : -1;
+    sy = (cy < ty) ? 1 : -1;
+    err = dx - dy;
+
+    for (;;)
+    {
+        if (in_gfx_bounds(cx, cy))
+            vga[cy * 320 + cx] = color;
+
+        if (cx == tx && cy == ty)
+            break;
+
+        e2 = err << 1;
+        if (e2 > -dy)
+        {
+            err -= dy;
+            cx += sx;
+        }
+        if (e2 < dx)
+        {
+            err += dx;
+            cy += sy;
+        }
+    }
+}
+
+void vga_gfx_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color)
+{
+    if (x2 < x1)
+        swap_u16(&x1, &x2);
+    if (y2 < y1)
+        swap_u16(&y1, &y2);
+
+    vga_gfx_line(x1, y1, x2, y1, color);
+    vga_gfx_line(x2, y1, x2, y2, color);
+    vga_gfx_line(x2, y2, x1, y2, color);
+    vga_gfx_line(x1, y2, x1, y1, color);
+}
+
+void vga_gfx_circle(uint16_t x, uint16_t y, uint16_t radius, uint8_t color)
+{
+    int cx = (int)x;
+    int cy = (int)y;
+    int r = (int)radius;
+    int px = r;
+    int py = 0;
+    int err = 0;
+
+    while (px >= py)
+    {
+        vga_gfx_putpixel((uint16_t)(cx + px), (uint16_t)(cy + py), color);
+        vga_gfx_putpixel((uint16_t)(cx + py), (uint16_t)(cy + px), color);
+        vga_gfx_putpixel((uint16_t)(cx - py), (uint16_t)(cy + px), color);
+        vga_gfx_putpixel((uint16_t)(cx - px), (uint16_t)(cy + py), color);
+        vga_gfx_putpixel((uint16_t)(cx - px), (uint16_t)(cy - py), color);
+        vga_gfx_putpixel((uint16_t)(cx - py), (uint16_t)(cy - px), color);
+        vga_gfx_putpixel((uint16_t)(cx + py), (uint16_t)(cy - px), color);
+        vga_gfx_putpixel((uint16_t)(cx + px), (uint16_t)(cy - py), color);
+
+        if (err <= 0)
+        {
+            py++;
+            err += (py << 1) + 1;
+        }
+        if (err > 0)
+        {
+            px--;
+            err -= (px << 1) + 1;
+        }
+    }
+}
+
+void vga_gfx_putch(char c, int x, int y, uint8_t color)
+{
+    int row;
+    int col;
+    uint8_t bits;
+    uint8_t glyph = (uint8_t)c;
+
+    if (glyph >= 128)
+        glyph = (uint8_t)'?';
+
+    for (row = 0; row < 8; row++)
+    {
+        bits = (uint8_t)font8x8_basic[glyph][row];
+        for (col = 0; col < 8; col++)
+        {
+            if (bits & (1u << col))
+                vga_gfx_putpixel((uint16_t)(x + col), (uint16_t)(y + row), color);
+        }
+    }
+}
+
+void vga_gfx_puts(const char *str, int x, int y, uint8_t color)
+{
+    int cx = x;
+
+    while (*str)
+    {
+        if (*str == '\n')
+        {
+            cx = x;
+            y += 8;
+        }
+        else
+        {
+            vga_gfx_putch(*str, cx, y, color);
+            cx += 8;
+        }
+        str++;
+    }
+}
+
+void set_mode(unsigned char mode)
+{
+    vga_set_mode((uint8_t)mode);
+}
+
+void beep(int freq, int ms)
+{
+    vga_beep(freq, ms);
+}
+
+void set_palette(unsigned char index, unsigned char r, unsigned char g, unsigned char b)
+{
+    vga_set_palette((uint8_t)index, (uint8_t)r, (uint8_t)g, (uint8_t)b);
+}
+
+void clear_screen(unsigned char color)
+{
+    vga_gfx_setclscolor((uint8_t)color);
+    vga_gfx_cls();
+}
+
+void put_pixel(int x, int y, unsigned char color)
+{
+    if (x < 0 || y < 0)
+        return;
+
+    vga_gfx_putpixel((uint16_t)x, (uint16_t)y, (uint8_t)color);
+}
+
+void wait_key(void)
+{
+    vga_wait_key();
+}
+
+void vga_reset(void)
+{
+    vga_set_mode(VGA_MODE_TEXT_80x25);
+    clrscr();
+    textcolor(15);
+    textbackground(0);
+}
\ No newline at end of file
diff --git a/systems/IBM-PC/PhotonX/VGA.H b/systems/IBM-PC/PhotonX/VGA.H
new file mode 100644
index 0000000..2e402f3
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/VGA.H
@@ -0,0 +1,46 @@
+#ifndef VGA_H
+#define VGA_H
+
+#include <dos.h>
+
+#define VGA_SEG 0xA000
+#define VGA_MODE_TEXT_80x25 0x03
+#define VGA_MODE_320x200x256 0x13
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+
+extern unsigned char far *vga;
+
+/* Core mode + utility */
+void vga_set_mode(uint8_t mode);
+void vga_beep(int freq, int ms);
+void vga_wait_key(void);
+
+/* Text mode API (whitepaper-aligned) */
+void vga_text_setcolor(uint8_t fg, uint8_t bg);
+void vga_text_gotoxy(uint8_t x, uint8_t y);
+void vga_text_putch(char c);
+void vga_text_puts(const char *str);
+void vga_text_cls(void);
+
+/* Graphics mode API (whitepaper-aligned) */
+void vga_set_palette(uint8_t index, uint8_t r, uint8_t g, uint8_t b);
+void vga_gfx_setclscolor(uint8_t color);
+void vga_gfx_cls(void);
+void vga_gfx_putpixel(uint16_t x, uint16_t y, uint8_t color);
+void vga_gfx_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color);
+void vga_gfx_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color);
+void vga_gfx_circle(uint16_t x, uint16_t y, uint16_t radius, uint8_t color);
+void vga_gfx_putch(char c, int x, int y, uint8_t color);
+void vga_gfx_puts(const char *str, int x, int y, uint8_t color);
+
+/* Compatibility names for existing code */
+void set_mode(unsigned char mode);
+void beep(int freq, int ms);
+void set_palette(unsigned char index, unsigned char r, unsigned char g, unsigned char b);
+void clear_screen(unsigned char color);
+void put_pixel(int x, int y, unsigned char color);
+void wait_key(void);
+
+#endif
\ No newline at end of file
diff --git a/systems/IBM-PC/PhotonX/demos/HELLO.C b/systems/IBM-PC/PhotonX/demos/HELLO.C
new file mode 100644
index 0000000..4d7ed3a
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/demos/HELLO.C
@@ -0,0 +1,26 @@
+#include "VGA.H"
+
+int main()
+{
+    vga_set_mode(VGA_MODE_TEXT_80x25);
+    vga_text_setcolor(15, 1);
+    vga_text_cls();
+    vga_text_gotoxy(0, 0);
+    vga_text_puts("PhotonX Demo: Hello World\r\n");
+    vga_text_setcolor(14, 0);
+    vga_text_puts("Press any key to continue...\r\n");
+    vga_wait_key();
+
+    vga_set_mode(VGA_MODE_320x200x256);
+    vga_gfx_setclscolor(1);
+    vga_gfx_cls();
+    vga_gfx_puts("HELLO WORLD", 108, 96, 15);
+    vga_gfx_puts("PRESS KEY", 116, 110, 14);
+    vga_wait_key();
+
+    vga_set_mode(VGA_MODE_TEXT_80x25);
+    vga_text_setcolor(15, 0);
+    vga_text_cls();
+
+    return 0;
+}
diff --git a/systems/IBM-PC/PhotonX/demos/RANDOM.C b/systems/IBM-PC/PhotonX/demos/RANDOM.C
new file mode 100644
index 0000000..92cf5af
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/demos/RANDOM.C
@@ -0,0 +1,36 @@
+#include "VGA.H"
+#include <time.h>
+#include <stdlib.h>
+
+int rand_range(int min, int max)
+{
+    return (rand() % (max - min + 1)) + min;
+}
+
+int main()
+{
+    int i = 0;
+    int x;
+    int y;
+    int lastx = 160;
+    int lasty = 100;
+    srand((unsigned int)time(NULL));
+    vga_set_mode(VGA_MODE_320x200x256);
+    vga_gfx_setclscolor(1);
+    vga_gfx_cls();
+
+    while (i++ < 100)
+    {
+        x = rand_range(0, 20);
+        y = rand_range(0, 20);
+        vga_gfx_line((uint16_t)lastx, (uint16_t)lasty, (uint16_t)x, (uint16_t)y, (uint8_t)(i % 256));
+        lastx = x;
+        lasty = y;
+        vga_beep(rand_range(100, 500), 40);
+        delay(40);
+        if (kbhit())
+            break;
+    }
+
+    return 0;
+}
\ No newline at end of file
diff --git a/systems/IBM-PC/PhotonX/demos/REDSCRN.C b/systems/IBM-PC/PhotonX/demos/REDSCRN.C
new file mode 100644
index 0000000..7bcf455
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/demos/REDSCRN.C
@@ -0,0 +1,27 @@
+#include "VGA.H"
+
+int main()
+{
+    int x;
+    int y;
+
+    vga_set_mode(VGA_MODE_320x200x256);
+
+    for (x = 0; x < 64; x++)
+        vga_set_palette((uint8_t)x, (uint8_t)x, 0, 0);
+
+    vga_gfx_setclscolor(63);
+    vga_gfx_cls();
+
+    for (x = 0; x < 320; x++)
+        for (y = 0; y < 200; y++)
+            vga_gfx_putpixel((uint16_t)x, (uint16_t)y, 63);
+
+    vga_gfx_puts("RED SCREEN", 120, 96, 0);
+    vga_gfx_puts("PRESS KEY", 124, 108, 0);
+    vga_wait_key();
+
+    vga_set_mode(VGA_MODE_TEXT_80x25);
+
+    return 0;
+}
diff --git a/systems/IBM-PC/PhotonX/demos/TESTUTIL.C b/systems/IBM-PC/PhotonX/demos/TESTUTIL.C
new file mode 100644
index 0000000..c195c6a
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/demos/TESTUTIL.C
@@ -0,0 +1,202 @@
+#include <conio.h>
+#include <dos.h>
+#include "VGA.H"
+
+static void red_lines_test(void)
+{
+	int x;
+	int y;
+	int i;
+
+	vga_gfx_setclscolor(0);
+	vga_gfx_cls();
+
+	for (i = 0; i < 64; i++)
+		vga_set_palette((uint8_t)i, (uint8_t)i, 0, 0);
+
+	for (x = 0; x < 320; x++)
+		for (y = 0; y < 200; y++)
+			vga_gfx_putpixel((uint16_t)x, (uint16_t)y, (uint8_t)(x % 64));
+
+	vga_gfx_puts("RED TEST", 8, 8, 63);
+	vga_wait_key();
+}
+
+static void green_lines_test(void)
+{
+	int x;
+	int y;
+	int i;
+
+	vga_gfx_setclscolor(0);
+	vga_gfx_cls();
+
+	for (i = 0; i < 64; i++)
+		vga_set_palette((uint8_t)i, 0, (uint8_t)i, 0);
+
+	for (x = 0; x < 320; x++)
+		for (y = 0; y < 200; y++)
+			vga_gfx_putpixel((uint16_t)x, (uint16_t)y, (uint8_t)(x % 64));
+
+	vga_gfx_puts("GREEN TEST", 8, 8, 63);
+	vga_wait_key();
+}
+
+static void blue_lines_test(void)
+{
+	int x;
+	int y;
+	int i;
+
+	vga_gfx_setclscolor(0);
+	vga_gfx_cls();
+
+	for (i = 0; i < 64; i++)
+		vga_set_palette((uint8_t)i, 0, 0, (uint8_t)i);
+
+	for (x = 0; x < 320; x++)
+		for (y = 0; y < 200; y++)
+			vga_gfx_putpixel((uint16_t)x, (uint16_t)y, (uint8_t)(x % 64));
+
+	vga_gfx_puts("BLUE TEST", 8, 8, 63);
+	vga_wait_key();
+}
+
+static void grid_test(void)
+{
+	int x;
+	int y;
+
+	vga_gfx_setclscolor(0);
+	vga_gfx_cls();
+
+	for (x = 0; x < 320; x++)
+		for (y = 0; y < 200; y++)
+			if (x % 10 == 0 || y % 10 == 0)
+				vga_gfx_putpixel((uint16_t)x, (uint16_t)y, 63);
+			else
+				vga_gfx_putpixel((uint16_t)x, (uint16_t)y, 10);
+
+	vga_gfx_puts("GRID TEST", 8, 8, 63);
+	vga_wait_key();
+}
+
+static void full_color_test(void)
+{
+	int x;
+	int y;
+	int i;
+
+	vga_gfx_setclscolor(0);
+	vga_gfx_cls();
+
+	for (i = 0; i < 64; i++)
+		vga_set_palette((uint8_t)i, (uint8_t)i, 0, 0);
+
+	for (i = 0; i < 64; i++)
+		vga_set_palette((uint8_t)(i + 64), 63, (uint8_t)i, 0);
+
+	for (i = 0; i < 64; i++)
+		vga_set_palette((uint8_t)(i + 128), (uint8_t)(63 - i), 63, (uint8_t)i);
+
+	for (i = 0; i < 64; i++)
+		vga_set_palette((uint8_t)(i + 192), 0, (uint8_t)(63 - i), 63);
+
+	for (x = 0; x < 320; x++)
+		for (y = 0; y < 200; y++)
+			vga_gfx_putpixel((uint16_t)x, (uint16_t)y, (uint8_t)(x % 256));
+
+	vga_gfx_puts("FULL COLOR TEST", 8, 8, 15);
+	vga_wait_key();
+}
+
+static void math_spiral_test(void)
+{
+	int x = 160;
+	int y = 100;
+	int nx = x;
+	int ny = y;
+	int len = 4;
+	int dir = 0;
+	uint8_t color = 1;
+
+	vga_gfx_setclscolor(0);
+	vga_gfx_cls();
+
+	while (len < 220)
+	{
+		switch (dir)
+		{
+			case 0: nx = x + len; ny = y; break;
+			case 1: nx = x; ny = y - len; break;
+			case 2: nx = x - len; ny = y; break;
+			default: nx = x; ny = y + len; break;
+		}
+
+		vga_gfx_line((uint16_t)x, (uint16_t)y, (uint16_t)nx, (uint16_t)ny, color);
+
+		x = nx;
+		y = ny;
+		dir = (dir + 1) & 3;
+		color = (uint8_t)(color + 2);
+		if (dir == 0 || dir == 2)
+			len += 6;
+	}
+
+	vga_gfx_puts("MATH SPIRAL", 8, 8, 63);
+	vga_gfx_puts("PRESS KEY", 8, 18, 63);
+	vga_wait_key();
+}
+
+int main()
+{
+	char start_key;
+
+	vga_set_mode(VGA_MODE_TEXT_80x25);
+	vga_text_setcolor(15, 1);
+	vga_text_cls();
+	vga_text_gotoxy(0, 0);
+	vga_text_puts("PhotonX VGA Library Demo\r\n");
+	vga_text_setcolor(14, 1);
+	vga_text_puts("Whitepaper API: text + graphics\r\n");
+	vga_text_setcolor(15, 0);
+	vga_text_puts("Press N to cancel, any other key to start...\r\n");
+
+	vga_beep(1200, 80);
+	vga_beep(1400, 80);
+	start_key = getch();
+	if (start_key == 'N' || start_key == 'n')
+	{
+		vga_text_puts("\r\nCancelled.\r\n");
+		vga_beep(300, 160);
+		return 0;
+	}
+
+	vga_set_mode(VGA_MODE_320x200x256);
+	vga_gfx_setclscolor(0);
+	vga_gfx_cls();
+
+	vga_gfx_rect(10, 10, 309, 189, 12);
+	vga_gfx_line(10, 10, 309, 189, 10);
+	vga_gfx_line(309, 10, 10, 189, 10);
+	vga_gfx_circle(160, 100, 50, 14);
+	vga_gfx_puts("PhotonX VGA", 108, 96, 15);
+	vga_gfx_puts("Press any key", 104, 112, 11);
+
+	vga_wait_key();
+	red_lines_test();
+	green_lines_test();
+	blue_lines_test();
+	grid_test();
+	full_color_test();
+	math_spiral_test();
+
+	vga_set_mode(VGA_MODE_TEXT_80x25);
+	vga_text_setcolor(10, 0);
+	vga_text_cls();
+	vga_text_puts("Demo complete.\r\n");
+	vga_beep(1000, 120);
+	vga_beep(1400, 120);
+
+	return 0;
+}
diff --git a/systems/IBM-PC/PhotonX/demos/VGA.H b/systems/IBM-PC/PhotonX/demos/VGA.H
new file mode 100644
index 0000000..a2ed438
--- /dev/null
+++ b/systems/IBM-PC/PhotonX/demos/VGA.H
@@ -0,0 +1,43 @@
+#ifndef VGA_H
+#define VGA_H
+
+#include <dos.h>
+
+#define VGA_SEG 0xA000
+#define VGA_MODE_TEXT_80x25 0x03
+#define VGA_MODE_320x200x256 0x13
+#define VGA_MODE_640x480x16 0x12
+
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+
+extern unsigned char far *vga;
+
+void vga_set_mode(uint8_t mode);
+void vga_beep(int freq, int ms);
+void vga_wait_key(void);
+
+void vga_text_setcolor(uint8_t fg, uint8_t bg);
+void vga_text_gotoxy(uint8_t x, uint8_t y);
+void vga_text_putch(char c);
+void vga_text_puts(const char *str);
+void vga_text_cls(void);
+
+void vga_set_palette(uint8_t index, uint8_t r, uint8_t g, uint8_t b);
+void vga_gfx_setclscolor(uint8_t color);
+void vga_gfx_cls(void);
+void vga_gfx_putpixel(uint16_t x, uint16_t y, uint8_t color);
+void vga_gfx_line(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color);
+void vga_gfx_rect(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint8_t color);
+void vga_gfx_circle(uint16_t x, uint16_t y, uint16_t radius, uint8_t color);
+void vga_gfx_putch(char c, int x, int y, uint8_t color);
+void vga_gfx_puts(const char *str, int x, int y, uint8_t color);
+
+void set_mode(unsigned char mode);
+void beep(int freq, int ms);
+void set_palette(unsigned char index, unsigned char r, unsigned char g, unsigned char b);
+void clear_screen(unsigned char color);
+void put_pixel(int x, int y, unsigned char color);
+void wait_key(void);
+
+#endif
diff --git a/systems/IBM-PC/PhotonX/vga.c b/systems/IBM-PC/PhotonX/vga.c
deleted file mode 100644
index 0044c64..0000000
--- a/systems/IBM-PC/PhotonX/vga.c
+++ /dev/null
@@ -1,212 +0,0 @@
-#include <dos.h>
-#include <conio.h>
-#include <stdio.h>
-#define VGA_SEG 0xA000
-
-unsigned char far *vga = (unsigned char far *)MK_FP(VGA_SEG, 0);
-
-/* Prototypes */
-void set_mode(unsigned char mode);
-void set_palette(unsigned char index, unsigned char r, unsigned char g, unsigned char b);
-void clear_screen(unsigned char color);
-void put_pixel(int x, int y, unsigned char color);
-void wait_key(void);
-
-void red_lines(void);
-void green_lines(void);
-void blue_lines(void);
-void grid_with_corners(void);
-void full_color_test(void);
-
-/* BIOS video mode */
-void set_mode(unsigned char mode)
-{
-    union REGS regs;
-    regs.h.ah = 0x00;
-    regs.h.al = mode;
-    int86(0x10, &regs, &regs);
-}
-
-void beep(int freq, int ms)
-{
-	sound(freq);
-	delay(ms);
-	nosound();
-}
-
-/* VGA DAC */
-void set_palette(unsigned char index, unsigned char r, unsigned char g, unsigned char b)
-{
-    outp(0x3C8, index);
-    outp(0x3C9, r);
-    outp(0x3C9, g);
-    outp(0x3C9, b);
-}
-
-void clear_screen(unsigned char color)
-{
-    int i;
-    for (i = 0; i < 320 * 200; i++)
-        vga[i] = color;
-}
-
-void put_pixel(int x, int y, unsigned char color)
-{
-    vga[y * 320 + x] = color;
-}
-
-void wait_key(void)
-{
-    getch();
-    clear_screen(0);
-}
-
-void red_lines(void)
-{
-    int i, x;
-
-    for (i = 0; i < 64; i++)
-        set_palette(i, i, 0, 0);
-
-    for (x = 0; x < 320; x++)
-        for (i = 0; i < 200; i++)
-            put_pixel(x, i, x % 64);
-
-    wait_key();
-}
-
-void green_lines(void)
-{
-    int i, x;
-
-    for (i = 0; i < 64; i++)
-        set_palette(i, 0, i, 0);
-
-    for (x = 0; x < 320; x++)
-        for (i = 0; i < 200; i++)
-            put_pixel(x, i, x % 64);
-
-    wait_key();
-}
-
-void blue_lines(void)
-{
-    int i, x;
-
-    for (i = 0; i < 64; i++)
-        set_palette(i, 0, 0, i);
-
-    for (x = 0; x < 320; x++)
-        for (i = 0; i < 200; i++)
-            put_pixel(x, i, x % 64);
-
-    wait_key();
-}
-
-void grid_with_corners(void)
-{
-    int x, y;
-
-    for (x = 0; x < 320; x++)
-	for (y = 0; y < 200; y++)
-	    if (x % 10 == 0 || y % 10 == 0)
-                put_pixel(x, y, 63); /* White */
-            else
-                put_pixel(x, y, 10); /* Light blue */
-    wait_key();
-}
-
-void full_color_test(void)
-{
-    int x, y, i;
-    for (x = 0; x < 320; x++)
-	for (y = 0; y < 200; y++)
-		put_pixel(x,y, 0);
-
-    /* Build full rainbow palette */
-    for (i = 0; i < 64; i++)
-        set_palette(i, i, 0, 0);
-
-    for (i = 0; i < 64; i++)
-        set_palette(i + 64, 63, i, 0);
-
-    for (i = 0; i < 64; i++)
-        set_palette(i + 128, 63 - i, 63, i);
-
-    for (i = 0; i < 64; i++)
-        set_palette(i + 192, 0, 63 - i, 63);
-
-    for (x = 0; x < 320; x++)
-        for (y = 0; y < 200; y++)
-            put_pixel(x, y, x % 256);
-
-    wait_key();
-}
-
-
-
-/* ================= MAIN ================= */
-
-int main()
-{
-	beep(700,100);
-    cprintf("\r\n");
-    cprintf("    `7MMF'     \r\n");
-	beep(750,100);
-	cprintf(" ,mmmmMMmmmm.  \r\n");
-	beep(800,100);
-	cprintf("6MP   MM   YMb \r\n");
-	beep(850,100);
-	cprintf("8M    MM    M8 \r\n");
-	beep(900,100);
-	cprintf("YMb   MM   dM9 \r\n");
-	beep(950,100);
-	cprintf(" `YmmmMMmmmP'  \r\n");
-	beep(1000,100);
-	cprintf("    .JMML.     \r\n");
-	cprintf("=====================================\r\n");
-    cprintf(" PhotonX VGA Test\r\n");
-    cprintf(" Copyright (C) 2026 4248 Systems\r\n");
-    cprintf("=====================================\r\n");
-	beep(1500,200);
-	cprintf(" Press N to cancel, any other key to start...\r\n");
-    if (getch() == 'N' || getch() == 'n')
-    {
-		beep(1000,200);
-		beep(800,200);
-		beep(600,200);
-		beep(400,200);
-		beep(200,200);
-		cprintf(" Test cancelled.\r\n");
-        return 0;
-    }
-
-    set_mode(0x13);
-	beep(500,400);
-    red_lines();
-	beep(600,400);
-    green_lines();
-	beep(700,400);
-    blue_lines();
-	beep(800,400);
-    grid_with_corners();
-	beep(900,400);
-    full_color_test();
-	beep(1000,1000);
-	delay(200);
-	beep(700,200);
-	beep(800,200);
-	beep(900,200);
-	beep(1000,200);
-	beep(800,100);
-	beep(700,100);
-	beep(600,100);
-	beep(500,100);
-	beep(400,100);
-	beep(300,100);
-	beep(200,100);
-	beep(100,100);
-	set_mode(0x03);
-
-    return 0;
-}
\ No newline at end of file
diff --git a/systems/IBM-PC/Storyteller/STORY.C b/systems/IBM-PC/Storyteller/STORY.C
new file mode 100644
index 0000000..a89fb0b
--- /dev/null
+++ b/systems/IBM-PC/Storyteller/STORY.C
@@ -0,0 +1,184 @@
+/* Takes in a .st file and reads it to the user like its a storybook */
+
+/*Example file:
+@bg <VGA_COLOR>
+@fg <VGA_COLOR>
+@cls
+The quick brown fox jumps over the lazy dog.
+@pause
+@cls
+There was always a lazy dog.
+@pause
+@cls
+The end.
+*/
+
+#include <dos.h>
+#include <conio.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+/*Borland C style code for MSDOS 5*/
+
+void beep(int freq, int ms)
+{
+    sound(freq);
+    delay(ms);
+    nosound();
+}
+
+
+int main(int argc, char *argv[])
+{
+    FILE *file;
+    char line[256];
+    int color;
+    int waiting;
+    int i;
+    int beeponlineonly=0;
+    char *p;
+
+    if (argc < 2)
+    {
+        cprintf("Usage: STORY <filename.st>\r\n");
+        return 1;
+    }
+
+    beep(500, 100);
+    beep(700, 100);
+    beep(900, 100);
+    beep(1100, 100);
+    cprintf("Loading story from %s...\r\n", argv[1]);
+
+    file = fopen(argv[1], "r");
+    if (!file)
+    {
+        cprintf("Error: Could not open file %s\r\n", argv[1]);
+        return 1;
+    }
+
+    clrscr();
+
+    while (fgets(line, sizeof(line), file))
+    {
+        if (line[0] == '@')
+        {
+            /* Handle commands */
+            if (strncmp(line, "@bg ", 4) == 0)
+            {
+                /* Set background color */
+                color = atoi(line + 4);
+                textbackground(color);
+            }
+            else if (strncmp(line, "@fg ", 4) == 0)
+            {
+                /* Set foreground color */
+                color = atoi(line + 4);
+                textcolor(color);
+            }
+            else if (strncmp(line, "@soundcls", 10) == 0)
+            {
+                for (i = 0; i < 25; i++)
+                {
+                    beep(100 + i * 50, 50);
+                    cprintf("\r\n");
+                }
+                clrscr();
+            }
+
+            else if (strncmp(line, "@cls", 4) == 0)
+            {
+                clrscr();
+            }
+
+
+            else if (strncmp(line, "@pause", 6) == 0)
+            {
+                beep(1000, 200);
+                /* animate 3 dots until a key is pressed */
+                waiting = 1;
+                while (waiting)
+                {
+                    for (i = 0; i < 3; i++)
+                    {
+                        beep(100 + i * 100, 100);
+                        cprintf(".");
+                        delay(500);
+
+                        if (kbhit())
+                        {
+                            getch();
+                            waiting = 0;
+                            beep(1200, 200);
+                            beep(1000, 200);
+                            break;
+                        }
+                    }
+                    cprintf("\b\b\b   \b\b\b"); /* Clear the dots */
+                }
+            }
+
+            else if (strncmp(line, "@linebeep", 9) == 0)
+            {
+                beeponlineonly = 1;
+            }
+            else if (strncmp(line, "@charbeep", 9) == 0)
+            {
+                beeponlineonly = 0;
+            }
+        }
+        else
+        {
+            /* print each char with typing delay and punctuation pauses */
+            if (beeponlineonly)
+            {
+                beep(600, 50);
+            }
+
+            for (p = line; *p; p++)
+            {
+                if (*p == '\n')
+                {
+                    putch('\r');
+                    putch('\n');
+                    continue;
+                }
+
+                if (*p == '\r')
+                {
+                    continue;
+                }
+
+                putch(*p);
+                if (beeponlineonly)
+                {
+                    delay(1);
+                }
+                if (!beeponlineonly)
+                {
+                    if (*p == '.' || *p == '!' || *p == '?' || *p == ',')
+                    {
+                        beep(800, 200);
+                        delay(300);
+                    }
+                    if (*p == ' ')
+                    {
+                        delay(100);
+                    }
+                    else
+                    {
+                        beep(600, 50);
+                        delay(50);
+                    }
+                }
+            }
+        }
+    }
+
+    fclose(file);
+    beep(1200, 500);
+    clrscr();
+    return 0;
+}
[COMMIT END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.