Very basic kernel support working.

This commit is contained in:
Scott Duensing 2024-01-11 19:25:58 -06:00
parent 6c21d5cac9
commit edfd5e5aee
9 changed files with 217 additions and 84 deletions

View file

@ -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); for (i=0; i<12; i++) bitmapLine(line[i][p].x1, line[i][p].y1, line[i][p].x2, line[i][p].y2);
l++; l++;
p++; p++;
kernelUpdate();
} }
return 0; return 0;

View file

@ -209,8 +209,6 @@ int main(void) {
bitmapSetColor(255); bitmapSetColor(255);
draw_cube(p, t); draw_cube(p, t);
t += 2; t += 2;
kernelUpdate();
} }
return 0; return 0;

View file

@ -65,8 +65,6 @@ void bitmap(void) {
y2 = randomRead() % my; y2 = randomRead() % my;
bitmapLine(x, y, x2, y2); bitmapLine(x, y, x2, y2);
kernelUpdate();
} }
} }
@ -85,14 +83,15 @@ void text(void) {
textPrint("\nint32_t is "); textPrintInt(sizeof(int32_t)); textPrint("\nint32_t is "); textPrintInt(sizeof(int32_t));
textPrint("\n"); textPrint("\n");
textPrint("\n"); textPrint("\nEvent Size: "); textPrintInt(sizeof(kernelEvent(key.PRESSED)));
textPrint("\n\n");
textGetXY(&x, &y); textGetXY(&x, &y);
while(1) { while(1) {
kernelUpdate(); //kernelCall(NextEvent);
textGotoXY(x, y); textGotoXY(x, y);
textPrint("Pending: "); textPrint("Pending: ");
textPrintInt(kernelGetPendingEvents()); textPrintInt(kernelGetPending());
textPrint(" "); textPrint(" ");
} }
} }

View file

@ -4,7 +4,7 @@
* the Linux Kernel Exception to the GPL3, programs built to run on the * 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 * MicroKernel are expected to include this file. Doing so does not affect
* their license status. * their license status.
* *
* SPDX-License-Identifier: GPL-3.0-only * SPDX-License-Identifier: GPL-3.0-only
*/ */
@ -19,7 +19,7 @@
#include <stdint.h> #include <stdint.h>
struct call { // Mount at $ff00 struct call { // Mount at $ff00
long NextEvent; // Copy the next event into user-space. long NextEvent; // Copy the next event into user-space.
long ReadData; // Copy primary bulk event data into user-space long ReadData; // Copy primary bulk event data into user-space
long ReadExt; // Copy secondary bolk 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 Basic; // deprecated
long dummy1; // reserved long dummy1; // reserved
long dummy2; // reserved long dummy2; // reserved
struct { struct {
long List; // Returns a bit-set of available block-accessible devices. 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. 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 Format; // Perform a low-level format if the media support it.
long Export; // Update the FileSystem table with the partition table (if present). long Export; // Update the FileSystem table with the partition table (if present).
} BlockDevice; } BlockDevice;
struct { struct {
long List; // Returns a bit-set of available logical devices. long List; // Returns a bit-set of available logical devices.
long GetSize; // Get the size of the partition or logical device in sectors. 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 ReadBlock; // Read a partition-local raw sector on an unmounted device.
long WriteBlock; // Write a partition-local raw sector on an unmounted device. long WriteBlock; // Write a partition-local raw sector on an unmounted device.
} FileSystem; } FileSystem;
struct { struct {
long Open; // Open the given file for read, create, or append. long Open; // Open the given file for read, create, or append.
long Read; // Request bytes from a file opened for reading. long Read; // Request bytes from a file opened for reading.
long Write; // Write bytes to a file opened for create or append. 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 Rename; // Rename a closed file.
long Delete; // Delete a closed file. long Delete; // Delete a closed file.
} File; } File;
struct { struct {
long Open; // Open a directory for reading. long Open; // Open a directory for reading.
long Read; // Read a directory entry; may also return VOLUME and FREE events. long Read; // Read a directory entry; may also return VOLUME and FREE events.
long Close; // Close a directory once finished reading. long Close; // Close a directory once finished reading.
} Directory; } Directory;
long gate; long gate;
struct { struct {
long GetSize; // Returns rows/cols in kernel args. long GetSize; // Returns rows/cols in kernel args.
long DrawRow; // Draw text/color buffers left-to-right long DrawRow; // Draw text/color buffers left-to-right
long DrawColumn; // Draw text/color buffers top-to-bottom long DrawColumn; // Draw text/color buffers top-to-bottom
} Display; } Display;
struct { struct {
long GetIP; // Get the local IP address. long GetIP; // Get the local IP address.
long SetIP; // Set the local IP address. long SetIP; // Set the local IP address.
@ -83,7 +83,7 @@ struct call { // Mount at $ff00
long GetSysInfo; // long GetSysInfo; //
long SetBPS; // Set the serial BPS (should match the SLIP router's speed). long SetBPS; // Set the serial BPS (should match the SLIP router's speed).
} Config; } Config;
struct { struct {
long InitUDP; // long InitUDP; //
long SendUDP; // long SendUDP; //
@ -111,13 +111,13 @@ struct common_t {
uint8_t buflen; uint8_t buflen;
void * internal; void * internal;
}; };
struct fs_mkfs_t { struct fs_mkfs_t {
uint8_t drive; uint8_t drive;
uint8_t cookie; uint8_t cookie;
// label = common.buf; label_len = common.buflen // label = common.buf; label_len = common.buflen
}; };
struct fs_t { struct fs_t {
union { union {
struct fs_mkfs_t format; struct fs_mkfs_t format;
@ -236,19 +236,19 @@ struct call_args {
struct events { struct events {
uint16_t reserved; uint16_t reserved;
uint16_t deprecated; uint16_t deprecated;
uint16_t GAME; // joystick events uint16_t JOYSTICK; // joystick events
uint16_t DEVICE; // deprecated uint16_t DEVICE; // deprecated
struct { struct {
uint8_t PRESSED; uint8_t PRESSED;
uint8_t RELEASED; uint8_t RELEASED;
} key; } key;
struct { struct {
uint8_t DELTA; uint8_t DELTA;
uint8_t CLICKS; uint8_t CLICKS;
} mouse; } mouse;
struct { struct {
uint8_t NAME; uint8_t NAME;
uint8_t SIZE; uint8_t SIZE;
@ -257,7 +257,7 @@ struct events {
uint8_t FORMATTED; uint8_t FORMATTED;
uint8_t ERROR; uint8_t ERROR;
} block; } block;
struct { struct {
uint8_t SIZE; uint8_t SIZE;
uint8_t CREATED; uint8_t CREATED;
@ -266,7 +266,7 @@ struct events {
uint8_t WROTE; uint8_t WROTE;
uint8_t ERROR; uint8_t ERROR;
} fs; } fs;
struct { struct {
uint8_t NOT_FOUND; uint8_t NOT_FOUND;
uint8_t OPENED; uint8_t OPENED;
@ -278,7 +278,7 @@ struct events {
uint8_t DELETED; uint8_t DELETED;
uint8_t ERROR; uint8_t ERROR;
} file; } file;
struct { struct {
uint8_t OPENED; uint8_t OPENED;
uint8_t VOLUME; uint8_t VOLUME;
@ -290,7 +290,7 @@ struct events {
} directory; } directory;
}; };
struct event_key_t { struct event_key_t {
uint8_t keyboard; uint8_t keyboard;
uint8_t raw; 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 { struct event_fs_data_t {
uint8_t requested; // Requested number of bytes to read uint8_t requested; // Requested number of bytes to read
uint8_t delivered; // Number of bytes actually 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 buf; // kernel's buf page ID
uint8_t ext; // kernel's ext page ID uint8_t ext; // kernel's ext page ID
union { union {
struct event_key_t key; struct event_key_t key;
struct event_mouse_t mouse; struct event_mouse_t mouse;
struct event_file_t file; struct event_joystick_t joystick;
struct event_dir_t directory; struct event_file_t file;
struct event_dir_t directory;
}; };
}; };
#endif #endif

View file

@ -37,6 +37,9 @@ static byte _color;
static byte _active; // Current drawing page. static byte _active; // Current drawing page.
static void bitmapPutPixelIOSet(uint16_t x, uint16_t y);
void bitmapClear(void) { void bitmapClear(void) {
#ifdef BOOM #ifdef BOOM
dmaFill(_BITMAP_BASE[_active], _PAGE_SIZE, _color); dmaFill(_BITMAP_BASE[_active], _PAGE_SIZE, _color);
@ -45,8 +48,18 @@ void bitmapClear(void) {
byte block = _BITMAP_BASE[_active] / EIGHTK; byte block = _BITMAP_BASE[_active] / EIGHTK;
byte x; byte x;
uint16_t c; uint16_t c;
byte mmu;
byte ram;
volatile byte *mem = (byte *)SWAP_ADDR; 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. // Clear full 8k blocks.
for (x=0; x<9; x++) { for (x=0; x<9; x++) {
POKE(SWAP_SLOT, block++); POKE(SWAP_SLOT, block++);
@ -55,6 +68,12 @@ void bitmapClear(void) {
// Clear last partial block. // Clear last partial block.
POKE(SWAP_SLOT, block); POKE(SWAP_SLOT, block);
for (c=0; c<5120; c++) mem[c] = _color; 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 #endif
} }
@ -73,6 +92,16 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
int16_t incX; int16_t incX;
int16_t incY; int16_t incY;
int16_t balance; 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) { if (x2 >= x1) {
dx = 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; balance = dy - dx;
dx <<= 1; dx <<= 1;
while (x != x2) { while (x != x2) {
bitmapPutPixel(x, y); bitmapPutPixelIOSet(x, y);
if (balance >= 0) { if (balance >= 0) {
y += incY; y += incY;
balance -= dx; balance -= dx;
@ -106,13 +135,13 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
balance += dy; balance += dy;
x += incX; x += incX;
} }
bitmapPutPixel(x, y); bitmapPutPixelIOSet(x, y);
} else { } else {
dx <<= 1; dx <<= 1;
balance = dx - dy; balance = dx - dy;
dy <<= 1; dy <<= 1;
while (y != y2) { while (y != y2) {
bitmapPutPixel(x, y); bitmapPutPixelIOSet(x, y);
if (balance >= 0) { if (balance >= 0) {
x += incX; x += incX;
balance -= dy; balance -= dy;
@ -120,12 +149,41 @@ void bitmapLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2) {
balance += dx; balance += dx;
y += incY; 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) { 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; uint32_t pixelRAM;
byte block; byte block;

View file

@ -50,9 +50,9 @@ void f256Init(void) {
POKE(MMU_MEM_BANK_2, 2); POKE(MMU_MEM_BANK_2, 2);
POKE(MMU_MEM_BANK_3, 3); POKE(MMU_MEM_BANK_3, 3);
POKE(MMU_MEM_BANK_4, 4); POKE(MMU_MEM_BANK_4, 4);
POKE(MMU_MEM_BANK_5, 5); // Don't use this - it's for the library. POKE(MMU_MEM_BANK_5, 5);
// MMU_MEM_BANK_6 is always mapped to I/O. //POKE(MMU_MEM_BANK_6, 6); // Don't use this - it's for the micro kernel.
// MMU_MEM_BANK_7 belongs to the MicroKernel. //POKE(MMU_MEM_BANK_7, 7); // Don't use this - it's for the micro kernel.
kernelReset(); kernelReset();
graphicsReset(); graphicsReset();

View file

@ -57,7 +57,7 @@ typedef unsigned char bool;
// Our stuff. // 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 #define SWAP_ADDR 0xa000

View file

@ -24,42 +24,111 @@
#include "kernel.h" #include "kernel.h"
// Allocate some RAM to hold event data. kernelEventT kernelEventData; // Allocate some RAM to hold event data.
static struct event_t event; kernelArgsT *kernelArgs; // Create an alias for the kernel args.
// Create an alias for the kernel args. char kernelError;
static struct call_args *args = (struct call_args *)0x00f0;
char error;
/* byte kernelGetPending(void) {
RTC_BUFFER .dstruct kernel.time_t return -kernelArgs->events.pending;
kGetTimeStamp
lda #<RTC_BUFFER
sta kernel.args.buf
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;
} }
void kernelReset(void) { 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. // Tell the kernel where our event buffer lives.
args->events.event = &event; kernelArgs->events.event = &kernelEventData;
kernelUpdate();
} }
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
*/

View file

@ -34,23 +34,28 @@ extern "C"
#include "f256.h" #include "f256.h"
#define VECTOR(member) (size_t)(&((struct call *)0xff00)->member) #define kernelEvent(member) (size_t)(&((struct events *)0)->member)
#define EVENT(member) (size_t)(&((struct events *)0)->member) #define kernelVector(member) (size_t)(&((struct call *)0xff00)->member)
#define CALL(fn) \ #define kernelCall(fn) \
asm("jsr %[addy] \n" \ asm("jsr %[addy] \n" \
"stz %[err] \n" \ "stz %[err] \n" \
"ror %[err]" \ "ror %[err]" \
: [err] "+m"(error) \ : [err] "+m"(kernelError) \
: [addy] "i"(VECTOR(fn)) \ : [addy] "i"(kernelVector(fn)) \
: "a", "x", "y", "c", "v"); : "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 kernelReset(void);
void kernelUpdate(void);
#ifdef __cplusplus #ifdef __cplusplus