From edfd5e5aee7af7d8d567045b1203dd90b63ff3c7 Mon Sep 17 00:00:00 2001 From: Scott Duensing Date: Thu, 11 Jan 2024 19:25:58 -0600 Subject: [PATCH] Very basic kernel support working. --- examples/cube-pre/cube-pre.c | 2 - examples/cube/cube.c | 2 - examples/pgztest/pgztest.c | 9 ++- f256lib/api.h | 58 +++++++++------- f256lib/bitmap.c | 66 ++++++++++++++++-- f256lib/f256.c | 6 +- f256lib/f256.h | 2 +- f256lib/kernel.c | 127 +++++++++++++++++++++++++++-------- f256lib/kernel.h | 29 ++++---- 9 files changed, 217 insertions(+), 84 deletions(-) diff --git a/examples/cube-pre/cube-pre.c b/examples/cube-pre/cube-pre.c index 8fdd338..43c08b0 100644 --- a/examples/cube-pre/cube-pre.c +++ b/examples/cube-pre/cube-pre.c @@ -231,8 +231,6 @@ int main(void) { for (i=0; i<12; i++) bitmapLine(line[i][p].x1, line[i][p].y1, line[i][p].x2, line[i][p].y2); l++; p++; - - kernelUpdate(); } return 0; diff --git a/examples/cube/cube.c b/examples/cube/cube.c index e53556a..48b6924 100644 --- a/examples/cube/cube.c +++ b/examples/cube/cube.c @@ -209,8 +209,6 @@ int main(void) { bitmapSetColor(255); draw_cube(p, t); t += 2; - - kernelUpdate(); } return 0; diff --git a/examples/pgztest/pgztest.c b/examples/pgztest/pgztest.c index ca6c2cc..d6d3016 100644 --- a/examples/pgztest/pgztest.c +++ b/examples/pgztest/pgztest.c @@ -65,8 +65,6 @@ void bitmap(void) { y2 = randomRead() % my; bitmapLine(x, y, x2, y2); - - kernelUpdate(); } } @@ -85,14 +83,15 @@ void text(void) { textPrint("\nint32_t is "); textPrintInt(sizeof(int32_t)); textPrint("\n"); - textPrint("\n"); + textPrint("\nEvent Size: "); textPrintInt(sizeof(kernelEvent(key.PRESSED))); + textPrint("\n\n"); textGetXY(&x, &y); while(1) { - kernelUpdate(); + //kernelCall(NextEvent); textGotoXY(x, y); textPrint("Pending: "); - textPrintInt(kernelGetPendingEvents()); + textPrintInt(kernelGetPending()); textPrint(" "); } } diff --git a/f256lib/api.h b/f256lib/api.h index 6b4435f..1d8e772 100644 --- a/f256lib/api.h +++ b/f256lib/api.h @@ -4,7 +4,7 @@ * the Linux Kernel Exception to the GPL3, programs built to run on the * MicroKernel are expected to include this file. Doing so does not affect * their license status. - * + * * SPDX-License-Identifier: GPL-3.0-only */ @@ -19,7 +19,7 @@ #include struct call { // Mount at $ff00 - + long NextEvent; // Copy the next event into user-space. long ReadData; // Copy primary bulk event data into user-space long ReadExt; // Copy secondary bolk event data into user-space @@ -28,7 +28,7 @@ struct call { // Mount at $ff00 long Basic; // deprecated long dummy1; // reserved long dummy2; // reserved - + struct { long List; // Returns a bit-set of available block-accessible devices. long GetName; // Gets the hardware level name of the given block device or media. @@ -38,7 +38,7 @@ struct call { // Mount at $ff00 long Format; // Perform a low-level format if the media support it. long Export; // Update the FileSystem table with the partition table (if present). } BlockDevice; - + struct { long List; // Returns a bit-set of available logical devices. long GetSize; // Get the size of the partition or logical device in sectors. @@ -49,8 +49,8 @@ struct call { // Mount at $ff00 long ReadBlock; // Read a partition-local raw sector on an unmounted device. long WriteBlock; // Write a partition-local raw sector on an unmounted device. } FileSystem; - - struct { + + struct { long Open; // Open the given file for read, create, or append. long Read; // Request bytes from a file opened for reading. long Write; // Write bytes to a file opened for create or append. @@ -58,21 +58,21 @@ struct call { // Mount at $ff00 long Rename; // Rename a closed file. long Delete; // Delete a closed file. } File; - + struct { long Open; // Open a directory for reading. long Read; // Read a directory entry; may also return VOLUME and FREE events. long Close; // Close a directory once finished reading. } Directory; - - long gate; - + + long gate; + struct { long GetSize; // Returns rows/cols in kernel args. long DrawRow; // Draw text/color buffers left-to-right long DrawColumn; // Draw text/color buffers top-to-bottom } Display; - + struct { long GetIP; // Get the local IP address. long SetIP; // Set the local IP address. @@ -83,7 +83,7 @@ struct call { // Mount at $ff00 long GetSysInfo; // long SetBPS; // Set the serial BPS (should match the SLIP router's speed). } Config; - + struct { long InitUDP; // long SendUDP; // @@ -111,13 +111,13 @@ struct common_t { uint8_t buflen; void * internal; }; - + struct fs_mkfs_t { uint8_t drive; uint8_t cookie; // label = common.buf; label_len = common.buflen }; - + struct fs_t { union { struct fs_mkfs_t format; @@ -236,19 +236,19 @@ struct call_args { struct events { uint16_t reserved; uint16_t deprecated; - uint16_t GAME; // joystick events + uint16_t JOYSTICK; // joystick events uint16_t DEVICE; // deprecated - + struct { uint8_t PRESSED; uint8_t RELEASED; } key; - + struct { uint8_t DELTA; uint8_t CLICKS; } mouse; - + struct { uint8_t NAME; uint8_t SIZE; @@ -257,7 +257,7 @@ struct events { uint8_t FORMATTED; uint8_t ERROR; } block; - + struct { uint8_t SIZE; uint8_t CREATED; @@ -266,7 +266,7 @@ struct events { uint8_t WROTE; uint8_t ERROR; } fs; - + struct { uint8_t NOT_FOUND; uint8_t OPENED; @@ -278,7 +278,7 @@ struct events { uint8_t DELETED; uint8_t ERROR; } file; - + struct { uint8_t OPENED; uint8_t VOLUME; @@ -290,7 +290,7 @@ struct events { } directory; }; - + struct event_key_t { uint8_t keyboard; uint8_t raw; @@ -318,6 +318,11 @@ struct event_mouse_t { }; }; +struct event_joystick_t { + uint8_t joy0; + uint8_t joy1; +}; + struct event_fs_data_t { uint8_t requested; // Requested number of bytes to read uint8_t delivered; // Number of bytes actually read @@ -370,10 +375,11 @@ struct event_t { uint8_t buf; // kernel's buf page ID uint8_t ext; // kernel's ext page ID union { - struct event_key_t key; - struct event_mouse_t mouse; - struct event_file_t file; - struct event_dir_t directory; + struct event_key_t key; + struct event_mouse_t mouse; + struct event_joystick_t joystick; + struct event_file_t file; + struct event_dir_t directory; }; }; #endif diff --git a/f256lib/bitmap.c b/f256lib/bitmap.c index 3371126..6d73923 100644 --- a/f256lib/bitmap.c +++ b/f256lib/bitmap.c @@ -37,6 +37,9 @@ static byte _color; static byte _active; // Current drawing page. +static void bitmapPutPixelIOSet(uint16_t x, uint16_t y); + + void bitmapClear(void) { #ifdef BOOM dmaFill(_BITMAP_BASE[_active], _PAGE_SIZE, _color); @@ -45,8 +48,18 @@ void bitmapClear(void) { byte block = _BITMAP_BASE[_active] / EIGHTK; byte x; uint16_t c; + byte mmu; + byte ram; volatile byte *mem = (byte *)SWAP_ADDR; + // Hoping the compiler optimizes this out when not needed. :-) + if (SWAP_SLOT == MMU_MEM_BANK_6) { + mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + ram = PEEK(MMU_MEM_BANK_6); // Get current slot 6 contents. + asm("sei"); + POKE(MMU_IO_CTRL, 4); // Turn off I/O window. + } + // Clear full 8k blocks. for (x=0; x<9; x++) { POKE(SWAP_SLOT, block++); @@ -55,6 +68,12 @@ void bitmapClear(void) { // Clear last partial block. POKE(SWAP_SLOT, block); for (c=0; c<5120; c++) mem[c] = _color; + + if (SWAP_SLOT == MMU_MEM_BANK_6) { + POKE(MMU_MEM_BANK_6, ram); // Restore slot 6. + POKE(MMU_IO_CTRL, mmu); // Restore MMU state. + asm("cli"); + } #endif } @@ -73,6 +92,16 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { int16_t incX; int16_t incY; int16_t balance; + byte mmu; + byte ram; + + // Hoping the compiler optimizes this out when not needed. :-) + if (SWAP_SLOT == MMU_MEM_BANK_6) { + mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + ram = PEEK(MMU_MEM_BANK_6); // Get current slot 6 contents. + asm("sei"); + POKE(MMU_IO_CTRL, 4); // Turn off I/O window. + } if (x2 >= x1) { dx = x2 - x1; @@ -98,7 +127,7 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { balance = dy - dx; dx <<= 1; while (x != x2) { - bitmapPutPixel(x, y); + bitmapPutPixelIOSet(x, y); if (balance >= 0) { y += incY; balance -= dx; @@ -106,13 +135,13 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { balance += dy; x += incX; } - bitmapPutPixel(x, y); + bitmapPutPixelIOSet(x, y); } else { dx <<= 1; balance = dx - dy; dy <<= 1; while (y != y2) { - bitmapPutPixel(x, y); + bitmapPutPixelIOSet(x, y); if (balance >= 0) { x += incX; balance -= dy; @@ -120,12 +149,41 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) { balance += dx; y += incY; } - bitmapPutPixel(x, y); + bitmapPutPixelIOSet(x, y); + } + + if (SWAP_SLOT == MMU_MEM_BANK_6) { + POKE(MMU_MEM_BANK_6, ram); // Restore slot 6. + POKE(MMU_IO_CTRL, mmu); // Restore MMU state. + asm("cli"); } } void bitmapPutPixel(uint16_t x, uint16_t y) { + byte mmu; + byte ram; + + // Hoping the compiler optimizes this out when not needed. :-) + if (SWAP_SLOT == MMU_MEM_BANK_6) { + mmu = PEEK(MMU_IO_CTRL); // Get current MMU state. + ram = PEEK(MMU_MEM_BANK_6); // Get current slot 6 contents. + asm("sei"); + POKE(MMU_IO_CTRL, 4); // Turn off I/O window. + } + + bitmapPutPixelIOSet(x, y); + + if (SWAP_SLOT == MMU_MEM_BANK_6) { + POKE(MMU_MEM_BANK_6, ram); // Restore slot 6. + POKE(MMU_IO_CTRL, mmu); // Restore MMU state. + asm("cli"); + } +} + + +// This does the actual pixel setting but depends on the I/O being umapped. +static void bitmapPutPixelIOSet(uint16_t x, uint16_t y) { uint32_t pixelRAM; byte block; diff --git a/f256lib/f256.c b/f256lib/f256.c index 4ac0b23..ffb0458 100644 --- a/f256lib/f256.c +++ b/f256lib/f256.c @@ -50,9 +50,9 @@ void f256Init(void) { POKE(MMU_MEM_BANK_2, 2); POKE(MMU_MEM_BANK_3, 3); POKE(MMU_MEM_BANK_4, 4); - POKE(MMU_MEM_BANK_5, 5); // Don't use this - it's for the library. - // MMU_MEM_BANK_6 is always mapped to I/O. - // MMU_MEM_BANK_7 belongs to the MicroKernel. + POKE(MMU_MEM_BANK_5, 5); + //POKE(MMU_MEM_BANK_6, 6); // Don't use this - it's for the micro kernel. + //POKE(MMU_MEM_BANK_7, 7); // Don't use this - it's for the micro kernel. kernelReset(); graphicsReset(); diff --git a/f256lib/f256.h b/f256lib/f256.h index 17a416f..7a2a0ae 100644 --- a/f256lib/f256.h +++ b/f256lib/f256.h @@ -57,7 +57,7 @@ typedef unsigned char bool; // Our stuff. -#define SWAP_SLOT MMU_MEM_BANK_5 //***TODO*** Move this to 6 to save 8k. +#define SWAP_SLOT MMU_MEM_BANK_5 #define SWAP_ADDR 0xa000 diff --git a/f256lib/kernel.c b/f256lib/kernel.c index 512e8ce..7bf5fe9 100644 --- a/f256lib/kernel.c +++ b/f256lib/kernel.c @@ -24,42 +24,111 @@ #include "kernel.h" -// Allocate some RAM to hold event data. -static struct event_t event; -// Create an alias for the kernel args. -static struct call_args *args = (struct call_args *)0x00f0; - -char error; +kernelEventT kernelEventData; // Allocate some RAM to hold event data. +kernelArgsT *kernelArgs; // Create an alias for the kernel args. +char kernelError; -/* -RTC_BUFFER .dstruct kernel.time_t - -kGetTimeStamp - lda #RTC_BUFFER - sta kernel.args.buf+1 - lda #size(kernel.time_t) - sta kernel.args.buflen - jsr kernel.Clock.GetTime - rts -*/ - - -byte kernelGetPendingEvents(void) { - return -args->events.pending; +byte kernelGetPending(void) { + return -kernelArgs->events.pending; } void kernelReset(void) { + // Plop this into the zero page where the kernel can find it. + kernelArgs = (kernelArgsT *)0x00f0; // Tell the kernel where our event buffer lives. - args->events.event = &event; - - kernelUpdate(); + kernelArgs->events.event = &kernelEventData; } -void kernelUpdate(void) { - CALL(NextEvent); -} +/* + case EVENT(JOYSTICK): + // Joystick + break; + + case EVENT(key.PRESSED): + // Keyboard + break; + case EVENT(key.RELEASED): + // Keyboard + break; + + case EVENT(mouse.CLICKS): + // Mouse + break; + case EVENT(mouse.DELTA): + // Mouse + break; + + case EVENT(block.NAME): + // Block + break; + case EVENT(block.SIZE): + // Block + break; + case EVENT(block.DATA): + // Block + break; + case EVENT(block.WROTE): + // Block + break; + case EVENT(block.FORMATTED): + // Block + break; + case EVENT(block.ERROR): + // Block + break; + + case EVENT(file.NOT_FOUND): + // File + break; + case EVENT(file.OPENED): + // File + break; + case EVENT(file.DATA): + // File + break; + case EVENT(file.WROTE): + // File + break; + case EVENT(file.EOF): + // File + break; + case EVENT(file.CLOSED): + // File + break; + case EVENT(file.RENAMED): + // File + break; + case EVENT(file.DELETED): + // File + break; + case EVENT(file.ERROR): + // File + break; + + case EVENT(directory.OPENED): + // Directory + break; + case EVENT(directory.VOLUME): + // Directory + break; + case EVENT(directory.FILE): + // Directory + break; + case EVENT(directory.FREE): + // Directory + break; + case EVENT(directory.EOF): + // Directory + break; + case EVENT(directory.CLOSED): + // Directory + break; + case EVENT(directory.ERROR): + // Directory + break; + + // ***TODO*** Network +*/ diff --git a/f256lib/kernel.h b/f256lib/kernel.h index 5965cf8..e5ade60 100644 --- a/f256lib/kernel.h +++ b/f256lib/kernel.h @@ -34,23 +34,28 @@ extern "C" #include "f256.h" -#define VECTOR(member) (size_t)(&((struct call *)0xff00)->member) -#define EVENT(member) (size_t)(&((struct events *)0)->member) -#define CALL(fn) \ - asm("jsr %[addy] \n" \ - "stz %[err] \n" \ - "ror %[err]" \ - : [err] "+m"(error) \ - : [addy] "i"(VECTOR(fn)) \ - : "a", "x", "y", "c", "v"); +#define kernelEvent(member) (size_t)(&((struct events *)0)->member) +#define kernelVector(member) (size_t)(&((struct call *)0xff00)->member) +#define kernelCall(fn) \ + asm("jsr %[addy] \n" \ + "stz %[err] \n" \ + "ror %[err]" \ + : [err] "+m"(kernelError) \ + : [addy] "i"(kernelVector(fn)) \ + : "a", "x", "y", "c", "v"); -extern char error; +typedef struct event_t kernelEventT; +typedef struct call_args kernelArgsT; -byte kernelGetPendingEvents(void); +extern char kernelError; +extern kernelArgsT *kernelArgs; +extern kernelEventT kernelEventData; + + +byte kernelGetPending(void); void kernelReset(void); -void kernelUpdate(void); #ifdef __cplusplus