diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..4b2b149 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,28 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/local/bin/cc65816", + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64" + }, + { + "name": "Calypsi", + "includePath": [ + "${workspaceFolder}/**", + "/usr/local/lib/calypsi-65816/include/" + ], + "defines": [], + "compilerPath": "/usr/local/bin/cc65816", + "cStandard": "c11", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-clang-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..679f05a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "C_Cpp.errorSquiggles": "disabled" +} \ No newline at end of file diff --git a/include/config.h b/include/config.h index 833fce0..24521e3 100755 --- a/include/config.h +++ b/include/config.h @@ -1,8 +1,9 @@ -//***************************************************************************** -// 65X-DOS +// SPDX-License-Identifier: MIT // -// include/config.h -//***************************************************************************** +// include/kernel/config.h +// Global configuration header for 65X-DOS kernel +// +// Copyright © 2024 Kyle J Cardoza #pragma once diff --git a/include/kernel/device.h b/include/kernel/device.h deleted file mode 100755 index 7425546..0000000 --- a/include/kernel/device.h +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// kernel/device.h -// Driver declarations. -// -// Copyright © 2024 Kyle J Cardoza - -#pragma once - -#ifdef __CALYPSI_CC__ - -#include -#include -#include - -// This symbol determines the maximum number of device drivers which -// can be in memory. -#ifndef DEVICE_MAX -#define DEVICE_MAX 32 -#endif - -// This symbol determines the maximum number of device map entries which -// ca be in memory. -#ifndef DEVICE_MAP_MAX -#define DEVICE_MAP_MAX 32 -#endif - -// Forward declaration. -struct file; - -// A device, in this context, is a code module which exposes a defined set -// of functions for interacting with files and file-like data. It is not specific -// as to the nature of the underlying data storage. It is equally valid for a -// device to use a block of RAM or a serial device as it is a hard drive -// or SD card. -// -// None of these functions are required to actually do anyting if it is not -// sensible for the kind of device being used; for example, it is not -// sensible for an inherently read-only device to support moving or -// renaming files. -typedef struct { - // Initialize the device. - int (*init)(void); - - // Opens a file, given a pathname. - int (*open)(struct file *file); - - // Closes an open file, given a unique ID. - int (*close)(struct file *file); - - // Seeks within an open file, given a unique ID and a length. - int (*seek)(struct file *file, long length); - - // Reads data from the specified file. - int (*read)(struct file *file, void *dest, size_t length); - - // Writes data to the specified file. - int (*write)(struct file *file, void *src, size_t length); - - // Perform driver-specific operations. - int (*ioctl)(struct file *file, - unsigned short operation, - void *arg); - - // Creates the specified file given a pathname. - int (*create)(struct file *file); - - // Copies the specified file using the specified names. - int (*copy)(struct file *src, - struct file *dest); - - // Moves the specified file using the specified names. - int (*move)(struct file *src, - struct file *dest); - - // Gets the size of the file. - int (*get_file_size)(struct file *file, size_t *size); - - // Fills out the metadata in the specified file from the pathname - // in the provided file. - int (*init_file)(struct file *file); -} Device; - -// The device map is a table that maps device names, such as SD0: or -// TTY2: to the device driver that manages the device. -struct device_map { - char *name; - unsigned short major_number; - unsigned short minor_number; -}; - -// The global table of device drivers. -extern Device *device[DEVICE_MAX]; - -// The global map of device names to device modules. -extern struct device_map *device_map[DEVICE_MAP_MAX]; - -// Initialize all the device drivers. This is called once, at boot. -// It protects itself against being called again without a reset. -void device_init_all(void); - -// Binds a device name to a device. -int device_bind_name(char *name, - unsigned short major_number, - unsigned short minor_number); - -// Unbinds a bound device name. -int device_unbind_name(char *name); - -// Get a bound device by its name. -int device_get_by_name(char *name, Device **device); - -#endif diff --git a/include/kernel/file.h b/include/kernel/file.h deleted file mode 100755 index bb98f32..0000000 --- a/include/kernel/file.h +++ /dev/null @@ -1,79 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// kernel/file.h -// File related declarations -// -// Copyright © 2024 Kyle J Cardoza - -#pragma once - -#include -#include - -#include "kernel/device.h" - -enum file_type { - FILE_TYPE_NORMAL, - FILE_TYPE_DIRECTORY, - FILE_TYPE_DEVICE -}; - -struct file { - // The full path of the file, including its volume and basename. - char *pathname; - - // The basename of the file. This usually points to - // the begining of the basename of the file in the - // pathname string. - char *basename; - - // The type of the file. - enum file_type type; - - bool open; - - // Generic driver-specific data pointer - void *userdata; - - // The major number identifies the device driver responsible for - // the file. - uint8_t major_number; - - // The minor number identifies the device, among those the driver - // controls, which this file represents or is associated with. - uint8_t minor_number; -}; - -// Using the pathname in the provided file stucture, identify the device which manages -// the file and have that device populate the file structure. -int file_init(char *pathname, struct file *file); - -int file_open(struct file *file); - -int file_ioctl(struct file *file, - unsigned short operation, - void *arg); - -// Closes an open file, given a unique ID. -int file_close(struct file *file); - -// Seeks within an open file, given a unique ID and a length. -int file_seek(struct file *file, int32_t length); - -// Reads data from the specified file. -int file_read(struct file *file, void *dest, size_t length); - -// Writes data to the specified file. -int file_write(struct file *file, void *src, size_t length); - -// Creates the specified file given a pathname. -int file_create(struct file *file); - -// Copies the specified file using the specified names. -int file_copy(struct file *src, struct file *dest); - -// Moves the specified file using the specified names. -int file_move(struct file *src, struct file *dest); - -// Gets the size of the file. -int file_get_file_size(struct file *file, size_t *size); diff --git a/include/65c816.h b/include/kernel/hardware/65c816.h similarity index 100% rename from include/65c816.h rename to include/kernel/hardware/65c816.h diff --git a/include/kernel/hardware/led.h b/include/kernel/hardware/led.h new file mode 100644 index 0000000..944aeb6 --- /dev/null +++ b/include/kernel/hardware/led.h @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +// +// bios/main.c +// Sentinel 65X BIOS: main() function +// +// Copyright © 2024 Kyle J Cardoza + +#pragma once + +void led_init(void); + +void led_red_off(void); + +void led_red_on(void); + +void led_green_off(void); + +void led_green_on(void); + +void led_blue_off(void); + +void led_blue_on(void); diff --git a/include/vera.h b/include/kernel/hardware/vera.h similarity index 100% rename from include/vera.h rename to include/kernel/hardware/vera.h diff --git a/include/w65c265s.h b/include/kernel/hardware/w65c265s.h similarity index 100% rename from include/w65c265s.h rename to include/kernel/hardware/w65c265s.h diff --git a/include/kernel/device/null.h b/include/kernel/util/delay.h old mode 100755 new mode 100644 similarity index 50% rename from include/kernel/device/null.h rename to include/kernel/util/delay.h index ddf3ac3..105c6bf --- a/include/kernel/device/null.h +++ b/include/kernel/util/delay.h @@ -1,12 +1,10 @@ // SPDX-License-Identifier: MIT // -// kernel/device/null.h -// NULL driver declaration. +// include/kernel/util/delay.k +// 65X-DOS Kernel: delay() function // // Copyright © 2024 Kyle J Cardoza #pragma once -#include "kernel/device.h" - -extern Device NullDevice; +void delay(uint16_t count); diff --git a/include/macros.h b/include/macros.h index 96844e9..cac1f50 100755 --- a/include/macros.h +++ b/include/macros.h @@ -1,3 +1,8 @@ +// SPDX-License-Identifier: MIT +// +// include/macros.h +// Utility macros for Calypsi compiler and assembler + #ifndef __MACROS_H #define __MACROS_H diff --git a/include/sentinel65x.h b/include/sentinel65x.h deleted file mode 100755 index 54e1547..0000000 --- a/include/sentinel65x.h +++ /dev/null @@ -1,16 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// boot/sentinel65x.h -// Toplevel header for Sentinel 65X ROM firmware boot module -// -// Copyright © 2024 Kyle J Cardoza - -#pragma once - -#define CPU_SPEED_HZ 8000000 -#define UART3_BAUD_RATE 9600 -#define UART3_TIMER_VALUE (CPU_SPEED_HZ / (16 * UART3_BAUD_RATE) - 1) - -#include "65c816.h" -#include "w65c265s.h" -#include "vera.h" \ No newline at end of file diff --git a/src/kernel/cop_trampoline.s b/src/kernel/cop_trampoline.s index e4191ef..9d3bda9 100644 --- a/src/kernel/cop_trampoline.s +++ b/src/kernel/cop_trampoline.s @@ -1,3 +1,10 @@ +; SPDX-License-Identifier: MIT +; +; src/kernel/cop_trampoline.s +; Trampoline function for COP interrupt handler +; +; Copyright © 2024 Kyle J Cardoza + #include "macros.h" .section znear,bss diff --git a/src/kernel/cstartup.s b/src/kernel/cstartup.s index 92ddf24..f7f191e 100755 --- a/src/kernel/cstartup.s +++ b/src/kernel/cstartup.s @@ -1,3 +1,10 @@ +; SPDX-License-Identifier: MIT +; +; src/kernel/cstartup.s +; Critical boot and init code before calling main() +; +; Copyright © 2024 Kyle J Cardoza + ;;; Startup variant, change attribute value if you make your own .rtmodel cstartup,"sentinel65x" @@ -18,9 +25,8 @@ #endif #include "macros.h" -#include "65c816.h" -#include "w65c265s.h" -#include "65c816.h" +#include "kernel/hardware/65c816.h" +#include "kernel/hardware/w65c265s.h" .section boot, noreorder .pubweak __program_root_section @@ -45,6 +51,10 @@ w65c265s_init: trb PD4 tsb PDD4 + fclk_start + + fclk_select + ; Now we delay a while. ldy ##0x0FFF delay_y @@ -61,18 +71,6 @@ delay_y ; Disable the on-CPU RAM w65c265s_sram_off - ; Set P5.4 and P5.5 as output - lda #0b00110000 - trb PDD5 - tsb PDD5 - trb PD5 - - ; Set P6.1 as output - lda #0b00000010 - trb PDD6 - tsb PDD6 - trb PD6 - clc xce ; native 16-bit mode rep #0x38 ; 16-bit registers, no decimal mode diff --git a/src/kernel/device.c b/src/kernel/device.c deleted file mode 100755 index 4b58a5c..0000000 --- a/src/kernel/device.c +++ /dev/null @@ -1,123 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// kernel/device.c -// Device drivers. -// -// Copyright © 2024 Kyle J Cardoza - -#include -#include -#include - -#include "kernel/device.h" -#include "kernel/file.h" -#include "kernel/device/null.h" - -static bool device_init_all_run = false; - -Device *device[DEVICE_MAX] = { - &NullDevice -}; - -struct device_map *device_map[DEVICE_MAP_MAX] = {0}; - -static short get_lowest_free_device(void); - -void device_init_all(void) -{ - if (device_init_all_run == true) { - return; - } - - for (int i = 0; i < DEVICE_MAX; i += 1) { - if (device[i] != NULL) { - if (device[i]->init != NULL) { - device[i]->init(); - } - } - } - - device_init_all_run = true; -} - -int device_bind_name(char *name, - unsigned short major_number, - unsigned short minor_number) -{ - if (name == NULL) { - return -1; - } - - // It is not permissible to have the same name attached to two - // devices. - for (int i = 0; i < DEVICE_MAP_MAX; i += 1) { - if (strcmp(device_map[i]->name, name) == 0) { - return -1; - } - } - - short device_index = get_lowest_free_device(); - if (device_index == -1) { - return -1; - } - - char *device_name = strdup(name); - if (name == NULL) { - return -1; - } - - device_map[device_index] = calloc(1, sizeof(struct device_map)); - if (device_map[device_index] == NULL) { - free(device_name); - return -1; - } else { - device_map[device_index]->major_number = major_number; - device_map[device_index]->minor_number = minor_number; - device_map[device_index]->name = device_name; - return 0; - } -} - -int device_unbind_name(char *name) -{ - if (name == NULL) { - return -1; - } - - for (int i = 0; i < DEVICE_MAP_MAX; i += 1) { - if (strcmp(device_map[i]->name, name) == 0) { - free(device_map[i]->name); - free(device_map[i]); - device_map[i] = NULL; - return 0; - } - } - - return -1; -} - -int device_get_by_name(char *name, Device **device) -{ - if (name == NULL || device == NULL) { - return -1; - } - - for (int i = 0; i < DEVICE_MAP_MAX; i += 1) { - if (strcmp(device_map[i]->name, name) == 0) { - unsigned short major_number = device_map[i]->major_number; - *device = device[major_number]; - return 0; - } - } - return -1; -} - -static short get_lowest_free_device(void) -{ - for (int i = 0; i < DEVICE_MAP_MAX; i += 1) { - if (device_map[i] == NULL) { - return i; - } - } - return -1; -} diff --git a/src/kernel/device/null.c b/src/kernel/device/null.c deleted file mode 100755 index 44df7b8..0000000 --- a/src/kernel/device/null.c +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// kernel/device/null.c -// NULL device implementation. -// -// Copyright © 2024 Kyle J Cardoza - -#include - -#include "kernel/device/null.h" -#include "kernel/device.h" -#include "kernel/file.h" - -static int null_init(void); - -static int null_open(struct file *file); - -static int null_close(struct file *file); - -static int null_read(struct file *file, void *dest, size_t length); - -static int null_write(struct file *file, void *src, size_t length); - -static int null_get_file_size(struct file *file, size_t *size); - -static int null_init_file(struct file *file); - -Device NullDevice = { - .init = null_init, - .open = null_open, - .close = null_close, - .read = null_read, - .write = null_write, - .get_file_size = null_get_file_size, - .init_file = null_init_file -}; - -static int null_init(void) -{ - device_bind_name("zero", 0, 0); - device_bind_name("null", 0, 1); - return 0; -} - -static int null_open(struct file *file) -{ - switch (file->minor_number) { - case 0 ... 1: - file->open = true; - return 0; - default: - return -1; - } -} - -static int null_close(struct file *file) -{ - switch (file->minor_number) { - case 0 ... 1: - file->open = false; - return 0; - default: - return -1; - } -} - -static int null_read(struct file *file, - void *dest, - size_t length) -{ - if (file->open == false) { - return -1; - } - - switch (file->minor_number) { - case 0: - memset(dest, 0x00, length); - return length; - default: - return -1; - } -} - -static int null_write(struct file *file, - void *src, - size_t length) -{ - if (file->open == false) { - return -1; - } - - (void) src; - if (file->minor_number != 1) { - return -1; - } else { - return length; - } -} - -static int null_get_file_size(struct file *file, - size_t *size) -{ - switch (file->minor_number) { - case 0 ... 1: - *size = 0; - return 0; - default: - return -1; - } -} - -static int null_init_file(struct file *file) -{ - if (file->major_number != 0) { - return -1; - } - - switch (file->minor_number) { - case 0 ... 1: - file->open = false; - file->type = FILE_TYPE_DEVICE; - return 0; - default: - return -1; - } -} diff --git a/src/kernel/file.c b/src/kernel/file.c deleted file mode 100755 index 34a5cc1..0000000 --- a/src/kernel/file.c +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-License-Identifier: MIT -// -// kernel/file.c -// File definitions. -// -// Copyright © 2024 Kyle J Cardoza - -#include -#include - -#include "kernel/file.h" -#include "kernel/device.h" - -// Using the pathname string, identify the major/minor device for -// the file, and have that device initialize the file control -// block. -int file_init(char *pathname, struct file *file) -{ - // First thing, we need to identify the device. The pathname - // is to be fully-qualified; this means it must have the - // device name, followed by a colon, followed by an optional - // file path. If the file path part is empty, then the file - // refers to the device itself. We perform the identification - // by first copying the pathname, then tokenizing the copy on - // the ":" character. The first token must be a string which - // matches a registered device in the device map. - // Then we populate the located major and minor numbers and copy - // the pathname into the FCB, and pass it along to the device - // driver for more initialization. - - char *path = strdup(pathname); - if (path == NULL) { - return -1; - } - - char *dev = strtok(path, ":"); - - for (unsigned short i = 0; i < DEVICE_MAP_MAX; i += 1) { - if (strcmp(dev, device_map[i]->name) == 0) { - file->pathname = strdup(pathname); - free(path); - - if (file->pathname == NULL) { - return -1; - } - - file->major_number = device_map[i]->major_number; - file->minor_number = device_map[i]->minor_number; - - return device[file->major_number]->init_file(file); - } - } - - free(path); - - return -1; -} diff --git a/src/kernel/hardware/led.s b/src/kernel/hardware/led.s new file mode 100644 index 0000000..f9fd88e --- /dev/null +++ b/src/kernel/hardware/led.s @@ -0,0 +1,126 @@ +; SPDX-License-Identifier: MIT +; +; src/kernel/hardware/led.s +; Defines for the VERA chip +; +; Copyright © 2024 Kyle J Cardoza + +#include "macros.h" +#include "kernel/hardware/65c816.h" +#include "kernel/hardware/w65c265s.h" + + .section code + .public led_init + .public led_red_off + .public led_red_on + .public led_green_off + .public led_green_on + .public led_blue_off + .public led_blue_on + +led_init: + long_a + long_i + pha + short_a + + ; Set P5.4 and P5.5 as output + lda #0b00110000 + trb PDD5 + tsb PDD5 + trb PD5 + + ; Set P6.1 as output + lda #0b00000010 + trb PDD6 + tsb PDD6 + trb PD6 + + long_a + long_i + pla + rtl + +led_red_off: + long_a + long_i + pha + short_a + + lda #(1 << 4) + trb PD5 + + long_a + long_i + pla + rtl + +led_red_on: + long_a + long_i + pha + short_a + + lda #(1 << 4) + tsb PD5 + + long_a + long_i + pla + rtl + +led_green_off: + long_a + long_i + pha + short_a + + lda #(1 << 5) + trb PD5 + + long_a + long_i + pla + rtl + +led_green_on: + long_a + long_i + pha + short_a + + lda #(1 << 5) + tsb PD5 + + long_a + long_i + pla + rtl + +led_blue_off: + long_a + long_i + pha + short_a + + lda #(1 << 1) + trb PD6 + + long_a + long_i + pla + rtl + +led_blue_on: + long_a + long_i + pha + short_a + + lda #(1 << 1) + tsb PD6 + + long_a + long_i + pla + rtl \ No newline at end of file diff --git a/src/kernel/irq.c b/src/kernel/irq.c index 171037e..494a6aa 100755 --- a/src/kernel/irq.c +++ b/src/kernel/irq.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // -// bios/stubs.c -// Stub functions for Calypsi's C library +// src/kernel/irq.c +// IRQ handlers // // Copyright © 2024 Kyle J Cardoza diff --git a/src/kernel/main.c b/src/kernel/main.c index c7ad618..c12c2c6 100755 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -1,19 +1,35 @@ // SPDX-License-Identifier: MIT // -// bios/main.c +// src/kernel/main.c // Sentinel 65X BIOS: main() function // // Copyright © 2024 Kyle J Cardoza +#include +#include + +#include "kernel/util/delay.h" +#include "kernel/hardware/led.h" + void main(void) { -// Light Red LED - __asm( -" sep #0x20\n" -" lda #0b00010000\n" -" tsb 0x00DF21\n" -" rep #0x20\n" - ); + led_init(); - for (;;) {} + for (;;) { + + led_red_on(); + delay(1); + led_red_off(); + + led_green_on(); + delay(1); + led_green_off(); + + led_blue_on(); + delay(1); + led_blue_off(); + + delay(1); + + } } diff --git a/src/kernel/stubs.c b/src/kernel/stubs.c index c4b22c6..f9192a3 100755 --- a/src/kernel/stubs.c +++ b/src/kernel/stubs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MIT // -// bios/stubs.c +// src/kernel/stubs.c // Stub functions for Calypsi's C library // // Copyright © 2024 Kyle J Cardoza diff --git a/src/kernel/util/delay.c b/src/kernel/util/delay.c new file mode 100644 index 0000000..0c00b60 --- /dev/null +++ b/src/kernel/util/delay.c @@ -0,0 +1,15 @@ +// SPDX-License-Identifier: MIT +// +// src/kernel/util/delay.c +// 65X-DOS Kernel: delay() function +// +// Copyright © 2024 Kyle J Cardoza + +#include +#include + +void delay(uint16_t count) { + for (uint16_t i = 0; i < count; i += 1) { + for (uint16_t j = 0; j < 0xFFFF; j += 1) {} + } +}