From e64f109f2f56f8da9644fe24a51a7be3cd678f54 Mon Sep 17 00:00:00 2001 From: Peter Weingartner Date: Sat, 22 Jun 2024 17:12:47 -0400 Subject: [PATCH] Initial Text Driver Text driver is starting to work. --- misc/experimental/vfs.c | 82 ++++ misc/experimental/vfs.h | 92 +++++ src/C256/jumptable.s | 60 --- src/C256/ld_lc_f256.scm | 24 ++ src/C256/syscalls.txt | 36 +- src/Makefile | 13 +- src/dev/Makefile | 11 +- src/dev/kbd_f256k.c | 157 ++++++++ src/dev/kbd_f256k.h | 27 ++ src/dev/txt_f256.c | 685 +++++++++++++++++++++++++++++++++ src/dev/txt_f256.h | 19 + src/dev/uart.c | 16 + src/dev/uart.h | 10 + src/include/C256/README.md | 3 + src/include/F256/README.md | 5 + src/include/F256/dma_f256.h | 35 ++ src/include/F256/gabe_f256.h | 95 +++++ src/include/F256/iec_f256.h | 14 + src/include/F256/ps2_f256.h | 27 ++ src/include/F256/sdc_f256.h | 14 + src/include/F256/sound_f256.h | 27 ++ src/include/F256/timers_f256.h | 52 +++ src/include/F256/via_f256.h | 59 +++ src/include/F256/vicky_ii.h | 137 +++++++ src/include/features.h | 3 + src/include/gabe_reg.h | 3 + src/include/ps2_reg.h | 4 + src/include/rtc_reg.h | 20 + src/include/sound_reg.h | 3 + src/include/timers_reg.h | 4 + src/include/uart_reg.h | 16 + src/include/vicky_general.h | 4 + src/log.c | 38 +- src/sys_general.h | 5 +- src/toolbox.c | 255 ++++++------ 35 files changed, 1832 insertions(+), 223 deletions(-) create mode 100644 misc/experimental/vfs.c create mode 100644 misc/experimental/vfs.h create mode 100644 src/C256/ld_lc_f256.scm create mode 100644 src/dev/kbd_f256k.c create mode 100644 src/dev/kbd_f256k.h create mode 100644 src/dev/txt_f256.c create mode 100644 src/dev/txt_f256.h create mode 100644 src/include/C256/README.md create mode 100644 src/include/F256/README.md create mode 100644 src/include/F256/dma_f256.h create mode 100644 src/include/F256/gabe_f256.h create mode 100644 src/include/F256/iec_f256.h create mode 100644 src/include/F256/ps2_f256.h create mode 100644 src/include/F256/sdc_f256.h create mode 100644 src/include/F256/sound_f256.h create mode 100644 src/include/F256/timers_f256.h create mode 100644 src/include/F256/via_f256.h create mode 100644 src/include/F256/vicky_ii.h diff --git a/misc/experimental/vfs.c b/misc/experimental/vfs.c new file mode 100644 index 0000000..34502fc --- /dev/null +++ b/misc/experimental/vfs.c @@ -0,0 +1,82 @@ +/** + * @file vfs.c + * @author your name (you@domain.com) + * @brief Implement the top-level virtual file system that supports multiple low-level file systems + * @version 0.1 + * @date 2024-06-13 + * + * @copyright Copyright (c) 2024 + * + */ + +#include +#include +#include "vfs.h" + +#define MAX_FILE_SYSTEMS 4 +#define MAX_FILE_DESCRIPTORS 8 +#define MAX_DRIVES 8 + +static file_system_t file_systems[MAX_FILE_SYSTEMS]; +static short file_system_count = 0; + +static v_file_desc_t file_descriptors[MAX_FILE_DESCRIPTORS]; +static short file_descriptor_count = 0; + +static v_drive_binding_t drive_bindings[MAX_DRIVES]; +static short drive_binding_count = 0; + +/** + * @brief Intialize the virtual file system + * + * @return short 0 on success, any other number is an error + */ +short vfs_init() { + // Clear out all the file descriptors + for (short i = 0; i < MAX_FILE_DESCRIPTORS; i++) { + file_descriptors[i].status = 0; + file_descriptors[i].public_id = i; + file_descriptors[i].local_id = 0; + file_descriptors[i].file_system = 0; + } + + return 0; +} + +/** + * @brief Register a file system with the virutal file system + * + * @param fs pointer to the file system driver + * @return short 0 on success, any other number is an error + */ +short vfs_register_fs(file_system_p fs) { + return 0; +} + +/** + * @brief Bind a drive name to a file system + * + * @param drive the name of the drive (e.g. "sd0", "fd1") + * @param id the ID of the drive in the file system + * @param fs the file system driver + * @return short 0 on success, any other number is an error + */ +short vfs_bind_drive(const char * drive, short id, file_system_p fs) { + return 0; +} + +short fsys_close(short fd) { + short result = 0; + + if (fd < MAX_FILE_DESCRIPTORS) { + v_file_desc_p desc = &file_descriptors[fd]; + if (desc->status != 0) { + result = desc->file_system->close(desc->local_id); + desc->status = 0; + desc->local_id = 0; + desc->file_system = 0; + } + } + + return result; +} \ No newline at end of file diff --git a/misc/experimental/vfs.h b/misc/experimental/vfs.h new file mode 100644 index 0000000..6e739e3 --- /dev/null +++ b/misc/experimental/vfs.h @@ -0,0 +1,92 @@ +/** + * @file vfs.h + * @author your name (you@domain.com) + * @brief Implement the top-level virtual file system that supports multiple low-level file systems + * @version 0.1 + * @date 2024-06-13 + * + * @copyright Copyright (c) 2024 + * + */ + +#ifndef __vfs_h__ +#define __vfs_h__ + +#include "sys_types.h" + +// +// Structures +// + +/** + * @brief Define the structure for a file system driver + * + */ +typedef struct file_system_s { + const char * name; + + short (* open)(const char * path, short mode); + short (* close)(short fd); + short (* opendir)(const char * path); + short (* closedir)(short dir); + short (* readdir)(short dir, p_file_info file); + short (* findfirst)(const char * path, const char * pattern, p_file_info file); + short (* findnext)(short dir, p_file_info file); + short (* stat)(const char * path, p_file_info file); + short (* getlabel)(char * path, char * label); + short (* setlabel)(short drive, const char * label); + short (* mkfs)(short drive, char * label); + short (* mkdir)(const char * path); + short (* unlink)(const char * path); + short (* rename)(const char * old_path, const char * new_path); +} file_system_t, *file_system_p; + +/** + * @brief Structure defining a top-level file descriptor + * + */ +typedef struct v_file_desc_s { + short status; // 0 = closed, 1 = open + short public_id; // The ID of this file descriptor as used by callers + short local_id; // The ID of the matching file descriptor in the file system + file_system_p file_system; // The file system handling this file descriptor +} v_file_desc_t, *v_file_desc_p; + +/** + * @brief Structure to bind a drive to a file system + * + */ +typedef struct v_drive_binding_s { + const char * drive; // The name of the drive (e.g. "sd0", "fd1", "rom") + short drive_id; // The ID of the drive in the file system + file_system_p file_system; // The file system that handles the drive +} v_drive_binding_t, *v_drive_binding_p; + +// +// Calls +// + +/** + * @brief Intialize the virtual file system + * + * @return short 0 on success, any other number is an error + */ +extern short vfs_init(); + +/** + * @brief Register a file system with the virutal file system + * + * @param fs pointer to the file system driver + * @return short 0 on success, any other number is an error + */ +extern short vfs_register_fs(file_system_p fs); + +/** + * @brief Bind a drive name to a file system + * + * @param drive the name of the drive (e.g. "sd0", "fd1") + * @param id the ID of the drive in the file system + * @param fs the file system driver + * @return short 0 on success, any other number is an error + */ +extern short vfs_bind_drive(const char * drive, short id, file_system_p fs); \ No newline at end of file diff --git a/src/C256/jumptable.s b/src/C256/jumptable.s index 9a47089..73df7ba 100644 --- a/src/C256/jumptable.s +++ b/src/C256/jumptable.s @@ -1,12 +1,4 @@ .public sys_proc_exit - .public sys_int_enable_all - .public sys_int_disable_all - .public sys_int_disable - .public sys_int_enable - .public sys_int_register - .public sys_int_pending - .public sys_get_info - .public sys_int_clear .public sys_chan_read_b .public sys_chan_read .public sys_chan_readline @@ -20,7 +12,6 @@ .public sys_chan_close .public sys_chan_swap .public sys_chan_device - .public sys_cdev_register .public sys_bdev_register .public sys_bdev_read .public sys_bdev_write @@ -34,8 +25,6 @@ .public sys_fsys_readdir .public sys_fsys_findfirst .public sys_fsys_findnext - .public sys_fsys_get_label - .public sys_fsys_set_label .public sys_fsys_mkdir .public sys_fsys_delete .public sys_fsys_rename @@ -46,15 +35,8 @@ .public sys_fsys_stat .public sys_mem_get_ramtop .public sys_mem_reserve - .public sys_time_jiffies - .public sys_rtc_set_time - .public sys_rtc_get_time - .public sys_kbd_scancode .public sys_err_message - .public sys_kbd_layout .public sys_proc_run - .public sys_var_set - .public sys_var_get .public sys_txt_get_capabilities .public sys_txt_set_mode .public sys_txt_setsizes @@ -73,14 +55,6 @@ .public sys_txt_print .extern proc_exit - .extern int_enable_all - .extern int_disable_all - .extern int_disable - .extern int_enable - .extern int_register - .extern int_pending - .extern sys_get_information - .extern int_clear .extern chan_read_b .extern chan_read .extern chan_readline @@ -94,7 +68,6 @@ .extern chan_close .extern chan_swap .extern chan_device - .extern cdev_register .extern bdev_register .extern bdev_read .extern bdev_write @@ -108,8 +81,6 @@ .extern fsys_readdir .extern fsys_findfirst .extern fsys_findnext - .extern fsys_getlabel - .extern fsys_setlabel .extern fsys_mkdir .extern fsys_delete .extern fsys_rename @@ -120,15 +91,8 @@ .extern fsys_stat .extern mem_get_ramtop .extern mem_reserve - .extern timers_jiffies - .extern rtc_set_time - .extern rtc_get_time - .extern kbd_get_scancode .extern err_message - .extern kbd_layout .extern proc_run - ; .extern var_set - ; .extern var_get .extern txt_get_capabilities .extern txt_set_mode .extern txt_setsizes @@ -149,14 +113,6 @@ .section jumptable sys_proc_exit: jmp long:proc_exit -sys_int_enable_all: jmp long:int_enable_all -sys_int_disable_all: jmp long:int_disable_all -sys_int_disable: jmp long:int_disable -sys_int_enable: jmp long:int_enable -sys_int_register: jmp long:int_register -sys_int_pending: jmp long:int_pending -sys_get_info: jmp long:sys_get_information -sys_int_clear: jmp long:int_clear sys_chan_read_b: jmp long:chan_read_b sys_chan_read: jmp long:chan_read sys_chan_readline: jmp long:chan_readline @@ -170,7 +126,6 @@ sys_chan_open: jmp long:chan_open sys_chan_close: jmp long:chan_close sys_chan_swap: jmp long:chan_swap sys_chan_device: jmp long:chan_device -sys_cdev_register: jmp long:cdev_register sys_bdev_register: jmp long:bdev_register sys_bdev_read: jmp long:bdev_read sys_bdev_write: jmp long:bdev_write @@ -184,8 +139,6 @@ sys_fsys_closedir: jmp long:fsys_closedir sys_fsys_readdir: jmp long:fsys_readdir sys_fsys_findfirst: jmp long:fsys_findfirst sys_fsys_findnext: jmp long:fsys_findnext -sys_fsys_get_label: jmp long:fsys_getlabel -sys_fsys_set_label: jmp long:fsys_setlabel sys_fsys_mkdir: jmp long:fsys_mkdir sys_fsys_delete: jmp long:fsys_delete sys_fsys_rename: jmp long:fsys_rename @@ -196,21 +149,8 @@ sys_fsys_register_loader: jmp long:fsys_register_loader sys_fsys_stat: jmp long:fsys_stat sys_mem_get_ramtop: jmp long:mem_get_ramtop sys_mem_reserve: jmp long:mem_reserve -sys_time_jiffies: jmp long:timers_jiffies -sys_rtc_set_time: jmp long:rtc_set_time -sys_rtc_get_time: jmp long:rtc_get_time -sys_kbd_scancode: jmp long:kbd_get_scancode sys_err_message: jmp long:err_message -sys_kbd_layout: jmp long:kbd_layout sys_proc_run: jmp long:proc_run -sys_var_set: brk ; jmp long:var_set - brk - brk - brk -sys_var_get: brk ; jmp long:var_get - brk - brk - brk sys_txt_get_capabilities: jmp long:txt_get_capabilities sys_txt_set_mode: jmp long:txt_set_mode sys_txt_setsizes: jmp long:txt_setsizes diff --git a/src/C256/ld_lc_f256.scm b/src/C256/ld_lc_f256.scm new file mode 100644 index 0000000..eba4002 --- /dev/null +++ b/src/C256/ld_lc_f256.scm @@ -0,0 +1,24 @@ +(define memories + '((memory flash (address (#x040000 . #x07ffff)) + (type rom)) + (memory DirectPage (address (#x00c000 . #x00c0ff)) + (section (registers ztiny))) + (memory LoRAM (address (#x00c100 . #x00efff)) + (section stack data zdata data heap)) + (memory NearRAM1 (address (#x010000 . #x017fff)) + (section znear near)) + (memory NearRAM2 (address (#x018000 . #x01ffff)) + (section cnear)) + (memory FarRAM1 (address (#x020000 . #x02ffff)) + (section far huge)) + (memory FarRAM2 (address (#x030000 . #x03ffff)) + (section zfar zhuge )) + (memory LoCODE (address (#x00f000 . #x00ffdf)) + (section code cdata (jumptable #x00f000))) + (memory Vector (address (#x00ffe0 . #x00ffff)) + (section (reset #xfffc))) + (block stack (size #x1000)) + (block heap (size #x1000)) + (base-address _DirectPageStart DirectPage 0) + (base-address _NearBaseAddress NearRAM1 0) +)) diff --git a/src/C256/syscalls.txt b/src/C256/syscalls.txt index cd5beaf..abc7d66 100644 --- a/src/C256/syscalls.txt +++ b/src/C256/syscalls.txt @@ -1,14 +1,14 @@ # A list of system calls to be used to autogenerate the various jump tables and sys calls stubs\ proc_exit -int_enable_all -int_disable_all -int_disable -int_enable -int_register -int_pending -get_info -int_clear +# int_enable_all +# int_disable_all +# int_disable +# int_enable +# int_register +# int_pending +# get_info +# int_clear chan_read_b chan_read @@ -23,7 +23,7 @@ chan_open chan_close chan_swap chan_device -chan_register +# chan_register bdev_register bdev_read @@ -39,8 +39,8 @@ fsys_closedir fsys_readdir fsys_findfirst fsys_findnext -fsys_get_label -fsys_set_label +# fsys_get_label +# fsys_set_label fsys_mkdir fsys_delete fsys_rename @@ -52,15 +52,15 @@ fsys_stat mem_get_ramtop mem_reserve -time_jiffies -rtc_set_time -rtc_get_time -kbd_scancode +# time_jiffies +# rtc_set_time +# rtc_get_time +# kbd_scancode err_message -kbd_layout +# kbd_layout proc_run -var_set -var_get +# var_set +# var_get txt_get_capabilities txt_set_mode diff --git a/src/Makefile b/src/Makefile index 51fb672..ece8038 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,7 +1,7 @@ # VPATH=.:../../module/Calypsi-remote-debug/src DEBUGGER=../module/Calypsi-remote-debug/src -UNIT := C256U_PLUS +UNIT := F256 MEMORY := RAM # Define OS-dependent variables @@ -37,6 +37,17 @@ else ifeq ($(UNIT),C256_FMX) SRCS_FOR_UNIT= CFLAGS_FOR_UNIT=-DMODEL=0 -DCPU=255 --code-model large --data-model large LDFLAGS_FOR_UNIT=C256/ld_lc_c256_fmx.scm clib-lc-ld.a +else ifeq ($(UNIT),F256) + CPU=w65816 + C_SRCS_DEBUGGER=$(DEBUGGER)/agent.c $(DEBUGGER)/c256-uart.c $(DEBUGGER)/low_level_WDC65816.s + SRCS_FOR_UNIT=C256/jumptable.s C256/io_stubs.c C256/extras.s + CFLAGS_FOR_UNIT=-DMODEL=2 -DCPU=255 --code-model large --data-model large + + ifeq ($(MEMORY),ROM) + LDFLAGS_FOR_UNIT=C256/flash-f256.scm clib-lc-ld.a --rtattr printf=medium + else + LDFLAGS_FOR_UNIT=C256/ld_lc_f256.scm clib-lc-ld.a --rtattr printf=medium + endif endif ifeq ($(CPU),w65816) diff --git a/src/dev/Makefile b/src/dev/Makefile index a9de706..8be95bc 100644 --- a/src/dev/Makefile +++ b/src/dev/Makefile @@ -1,5 +1,5 @@ -UNIT := C256U_PLUS +UNIT := F256 # Define OS-dependent variables @@ -32,13 +32,20 @@ else ifeq ($(UNIT),C256_FMX) SRCS_FOR_UNIT=txt_c256.c txt_evid.c indicators_c256.c interrupts_c256.c timers_c256.c CFLAGS_FOR_UNIT=-DMODEL=0 -DCPU=255 --target Foenix --code-model large --data-model large +else ifeq ($(UNIT),F256) + CC=cc65816 + AS=as65816 + AR=nlib + + SRCS_FOR_UNIT=txt_f256.c # indicators_c256.c interrupts_c256.c timers_c256.c + CFLAGS_FOR_UNIT=-DMODEL=2 -DCPU=255 --code-model large --data-model large # --target Foenix endif INCLUDES=-I.. -I../include CFLAGS=$(INCLUDES) $(CFLAGS_FOR_UNIT) -l ASFLAGS=$(INCLUDES) -SRCS = bitmap.c block.c channel.c console.c dma.c fsys.c ps2.c sdc.c rtc.c txt_screen.c $(SRCS_FOR_UNIT) # pata.c +SRCS = block.c channel.c console.c fsys.c txt_screen.c uart.c $(SRCS_FOR_UNIT) # pata.c bitmap.c dma.c ps2.c sdc.c rtc.c OBJS = $(patsubst %.c,%.o,$(SRCS)) OBJS4RM = $(subst /,\\,$(OBJS)) diff --git a/src/dev/kbd_f256k.c b/src/dev/kbd_f256k.c new file mode 100644 index 0000000..20507d2 --- /dev/null +++ b/src/dev/kbd_f256k.c @@ -0,0 +1,157 @@ +/** + * @file kbd_f256k.c + * @author your name (you@domain.com) + * @brief + * @version 0.1 + * @date 2024-06-17 + * + * @copyright Copyright (c) 2024 + * + */ + +#include "dev/kbd_f256k.h" +#include "F256/via_f256.h" +#include +#include + +// +// Constants +// + +#define KBD_MATRIX_SIZE 9 +#define KBD_COLUMNS 9 +#define KBD_ROWS 8 + +// +// Map a key's matrix position to its scan code (FoenixMCP scan codes are used here) +// + +static const uint8_t kbd_scan_codes[KBD_COLUMNS][KBD_ROWS] = { + {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} +}; + +// +// Driver variables +// + +static uint8_t kbd_stat[KBD_MATRIX_SIZE]; +static short counter = 0; +static uint8_t last_press = 0; + +// PB0 PB1 PB2 PB3 PB4 PB5 PB6 PB7 PB8 +// PA7 1 <== CTRL RUN SPC F Q 2 +// PA1 3 W A L-SHIFT Z S E 4 +// PA2 5 R D X C F T 6 +// PA3 7 Y G V B H U 8 +// PA4 9 I J N M K O 0 +// PA5 + P L , . : @ CAPS +// PA6 - * ; / R-SHIFT ALT TAB HOME RIGHT +// PA0 DEL RETURN LEFT UP F1 F3 F5 F7 DOWN + +/** + * @brief Get the keys selected in a given column + * + * @param column the number of the column (0 - 8) + * @return uint8_t a bitfield representing the keys in that column (0 = released, 1 = pressed) + */ +static uint8_t kbd_get_rows(short column) { + uint8_t result = 0x00; + + if (column > 7) { + via0->pb = 0x80; + result = via1->pa; + via0->pb = 0; + } else { + via1->pb = 0x01 << column; + result = via1->pa; + via1->pb = 0; + } + + return result; +} + +/** + * @brief Handle a key MAKE or BREAK event... set up for auto repeat and queue the MAKE/BREAK scan code + * + * @param column the number of the column (0 - 8) + * @param row the number of the row (0 - 7) + * @param is_pressed TRUE, the key is down... FALSE, the key is up + */ +static void kbd_process_key(short column, short row, bool is_pressed) { + uint8_t scan_code = kbd_scan_codes[column][row]; + if (scan_code != 0) { + if (!is_pressed) { + if (last_press == scan_code) { + // If we released the last key pressed, remove it from the typematic variables + last_press = 0; + } + + // Convert the scan code to a BREAK scan code + scan_code |= 0x80; + } else { + // Set the key press information for the key press event + counter = 0; + last_press = scan_code; + } + + // TODO: queue the scan code + } +} + +/** + * @brief Handle an IRQ to query the keyboard + * + */ +void kbd_handle_irq() { + for (short column = 0; column < 8; column++) { + // Check each column to see if any key is pressed + uint8_t rows_stat = kbd_get_rows(column); + uint8_t rows_eor = kbd_stat[column] ^ rows_stat; + if (rows_eor != 0) { + short row = 0; + + kbd_stat[column] = rows_stat; + while (rows_eor != 0) { + if (rows_eor & 0x01) { + // Current key changed + kbd_process_key(column, row, rows_stat && 0x01); + } + + rows_stat = rows_stat >> 1; + rows_eor = rows_eor >> 1; + row++; + } + } + } +} + +/* + * Initialize the matrix keyboard + * + */ +short kbd_init() { + // Initialize VIA0 -- we'll just write to PB7 + via0->ddra = 0x00; + via0->ddrb = 0x80; + via0->acr = 0x00; + via0->pcr = 0x00; + via0->ier = 0x00; + + // Initialize VIA1 -- we'll write to all of PB + via1->ddra = 0x00; + via1->ddrb = 0xff; + via1->acr = 0x00; + via1->pcr = 0x00; + via1->ier = 0x00; + + for (short i = 0; i < KBD_MATRIX_SIZE; i++) { + kbd_stat[i] = 0; + } +} diff --git a/src/dev/kbd_f256k.h b/src/dev/kbd_f256k.h new file mode 100644 index 0000000..8876ee8 --- /dev/null +++ b/src/dev/kbd_f256k.h @@ -0,0 +1,27 @@ +/** + * @file kbd_f256k.h + * @author your name (you@domain.com) + * @brief Driver for the F256K and F256K2 matrix keyboard + * @version 0.1 + * @date 2024-06-17 + * + * @copyright Copyright (c) 2024 + * + */ + +#ifndef __kbd_f256k_h__ +#define __kbd_f256k_h__ + +/** + * @brief Handle an IRQ to query the keyboard + * + */ +extern void kbd_handle_irq(); + +/* + * Initialize the matrix keyboard + * + */ +extern short kbd_init(); + +#endif \ No newline at end of file diff --git a/src/dev/txt_f256.c b/src/dev/txt_f256.c new file mode 100644 index 0000000..ffd30d5 --- /dev/null +++ b/src/dev/txt_f256.c @@ -0,0 +1,685 @@ +/** @file txt_f256.c + * + * Text screen driver for f256 + */ + +#include +#include + +#include "log.h" +#include "log_level.h" +#include "F256/vicky_ii.h" +#include "dev/txt_f256.h" +#include "dev/txt_screen.h" +#include "dev/uart.h" + +#ifndef DEFAULT_LOG_LEVEL + #define DEFAULT_LOG_LEVEL LOG_TRACE +#endif + +extern const unsigned char MSX_CP437_8x8_bin[]; + +const t_color4 f256_clut[] = { + {0, 0, 0}, // 0: Black + {0, 0, 128}, // 1: Red + {0, 128, 0}, // 2: Green + {0, 128, 128}, // 3: Yellow + {128, 0, 0}, // 4: Blue + {128, 0, 128}, // 5: Magenta + {128, 128, 0}, // 6: Cyan + {192, 192, 192}, // 7: White + {128, 128, 128}, // 8: Bright Gray + {0, 0, 255}, // 9: Bright Red + {0, 255, 0}, // A: Bright Green + {0, 255, 255}, // B: Bright Yellow + {255, 0, 0}, // C: Bright Blue + {255, 0, 255}, // D: Bright Magenta + {255, 255, 0}, // E: Bright Cyan + {255, 255, 255} // F: Bright White +}; + +/* + * Driver level variables for the screen + */ + +unsigned char f256_enable_set_sizes; /* Flag to enable set_sizes to actually do its computation */ + +t_txt_capabilities f256_caps; /* The capabilities of Channel A */ + +t_extent f256_resolutions[] = { /* The list of display resolutions */ + { 640, 480 }, + { 640, 400 }, + { 320, 240 }, + { 320, 200 } +}; + +t_extent f256_fonts[] = { /* The list of supported font resolutions */ + { 8, 8 } +}; + +t_rect f256_region; /* The current region */ +t_point f256_cursor; /* The current cursor position */ +t_extent f256_resolution; /* The current display resolution */ +t_extent f256_font_size; /* The current font size */ +t_extent f256_max_size; /* The size of the screen in characters (without border removed) */ +t_extent f256_visible_size; /* The size of the visible screen in characters (with border removed) */ +uint8_t f256_border_width; /* Width of the border on one side */ +uint8_t f256_border_height; /* Height of the border on one side */ +uint8_t f256_color; /* The current color */ +uint16_t msr_shadow; /* A shadow register for the Master Control Register */ + +/** + * Gets the description of a screen's capabilities + * + * @return a pointer to the read-only description (0 on error) + */ +const p_txt_capabilities txt_f256_get_capabilities() { + return &f256_caps; +} + +/** + * Calculate the size of the text screen in rows and columns so that + * the kernel printing routines can work correctly. + * + * NOTE: this should be called whenever the VKY3 registers are changed + */ +static void txt_f256_set_sizes() { + TRACE("txt_f256_set_sizes"); + + if (f256_enable_set_sizes) { + /* Only recalculate after initialization is mostly completed */ + + /* + * Calculate the maximum number of characters visible on the screen + * This controls text layout in memory + */ + f256_max_size.width = (int)((long)f256_resolution.width / (long)f256_font_size.width); + f256_max_size.height = (int)((long)f256_resolution.height / (long)f256_font_size.height); + + /* + * Calculate the characters that are visible in whole or in part + */ + if ((f256_border_width != 0) && (f256_border_height != 0)) { + short border_width = (int)((long)(2 * f256_border_width) / (long)f256_font_size.width); + short border_height = (int)((long)(2 * f256_border_height) / (long)f256_font_size.height); + + f256_visible_size.width = f256_max_size.width - border_width; + f256_visible_size.height = f256_max_size.height - border_height; + } else { + f256_visible_size.width = f256_max_size.width; + f256_visible_size.height = f256_max_size.height; + } + + // DEBUG4("txt_f256_set_sizes max:%d,%d, visible:%d,%d", f256_max_size.width, f256_max_size.height, f256_visible_size.width, f256_visible_size.height); + } +} + +/** + * Get the display resolutions + * + * @param text_size the size of the screen in visible characters (may be null) + * @param pixel_size the size of the screen in pixels (may be null) + */ +static void txt_f256_get_sizes(p_extent text_size, p_extent pixel_size) { + if (text_size) { + text_size->width = f256_visible_size.width; + text_size->height = f256_visible_size.height; + } + + if (pixel_size) { + pixel_size->width = f256_resolution.width; + pixel_size->height = f256_resolution.height; + } +} + +/** + * Set the display mode for the screen + * + * @param mode a bitfield of desired display mode options + * + * @return 0 on success, any other number means the mode is invalid for the screen + */ +static short txt_f256_set_mode(short mode) { + /* Turn off anything not set */ + msr_shadow &= ~(TXT_MODE_SLEEP | TXT_MODE_TEXT); + + if (mode & TXT_MODE_SLEEP) { + /* Put the monitor to sleep */ + msr_shadow |= VKY_MCR_SLEEP; + *tvky_mstr_ctrl = msr_shadow; + return 0; + + } else if (mode & TXT_MODE_TEXT) { + /* Put on text mode */ + msr_shadow |= VKY_MCR_TEXT; + *tvky_mstr_ctrl = msr_shadow; + return 0; + + } else { + /* Unsupported mode */ + return -1; + } +} + +/** + * Set the display resolution of the screen + * + * @param width the desired horizontal resolution in pixels + * @param height the desired veritical resolution in pixels + * + * @return 0 on success, any other number means the resolution is unsupported + */ +static short txt_f256_set_resolution(short width, short height) { + // TODO: If no size specified, set it based on the DIP switch + + /* Turn off resolution bits */ + /* TODO: there gotta be a better way to do that */ + msr_shadow &= ~(VKY_MCR_RES_MASK); + + if ((width == 640) && (height == 480)) { + msr_shadow |= VKY_MCR_RES_640x480; + f256_resolution.width = width; + f256_resolution.height = height; + + // Recalculate the size of the screen + txt_f256_set_sizes(); + + *tvky_mstr_ctrl = msr_shadow; + return 0; + } + else if ((width == 640) && (height == 400)) { + msr_shadow |= VKY_MCR_RES_640x400; + f256_resolution.width = width; + f256_resolution.height = height; + + // Recalculate the size of the screen + txt_f256_set_sizes(); + + *tvky_mstr_ctrl = msr_shadow; + return 0; + } + else if ((width == 320) && (height == 240)) { + msr_shadow |= VKY_MCR_RES_320x240; + f256_resolution.width = width; + f256_resolution.height = height; + + // Recalculate the size of the screen + txt_f256_set_sizes(); + + *tvky_mstr_ctrl = msr_shadow; + return 0; + } + else if ((width == 320) && (height == 200)) { + msr_shadow |= VKY_MCR_RES_320x200; + f256_resolution.width = width; + f256_resolution.height = height; + + // Recalculate the size of the screen + txt_f256_set_sizes(); + + *tvky_mstr_ctrl = msr_shadow; + return 0; + } + + else { + /* Unsupported resolution */ + return -1; + } +} + +/** + * Set the size of the border of the screen (if supported) + * + * @param width the horizontal size of one side of the border (0 - 32 pixels) + * @param height the vertical size of one side of the border (0 - 32 pixels) + */ +static void txt_f256_set_border(short width, short height) { + if ((width > 0) || (height > 0)) { + f256_border_width = width; + f256_border_height = height; + tvky_brdr_ctrl->control = 0x01; + tvky_brdr_ctrl->size_x = width; + tvky_brdr_ctrl->sizy_y = height; + + } else { + tvky_brdr_ctrl->control = 0; + tvky_brdr_ctrl->size_x = 0; + tvky_brdr_ctrl->sizy_y = 0; + } + + // Recalculate the size of the screen + txt_f256_set_sizes(); +} + +/** + * Set the size of the border of the screen (if supported) + * + * @param red the red component of the color (0 - 255) + * @param green the green component of the color (0 - 255) + * @param blue the blue component of the color (0 - 255) + */ +static void txt_f256_set_border_color(unsigned char red, unsigned char green, unsigned char blue) { + tvky_brdr_ctrl->color.red = red; + tvky_brdr_ctrl->color.green = green; + tvky_brdr_ctrl->color.blue = blue; +} + +/** + * Load a font as the current font for the screen + * + * @param width width of a character in pixels + * @param height of a character in pixels + * @param data pointer to the raw font data to be loaded + */ +static short txt_f256_set_font(short width, short height, const unsigned char * data) { + if (width == 8 && height == 8) { + int i; + + /* The size is valid... set the font */ + f256_font_size.width = width; + f256_font_size.height = height; + + /* Copy the font data... this assumes a width of one byte! */ + /* TODO: generalize this for all possible font sizes */ + for (i = 0; i < 256 * height; i++) { + tvky_font_set_0[i] = data[i]; + } + + // Recalculate the size of the screen + txt_f256_set_sizes(); + + return 0; + + } else { + return -1; + } +} + +/** + * Set the appearance of the cursor + * + * @param enable 0 to hide, any other number to make visible + * @param rate the blink rate for the cursor (0=1s, 1=0.5s, 2=0.25s, 3=1/5s) + * @param c the character in the current font to use as a cursor + */ +static void txt_f256_set_cursor(short enable, short rate, char c) { + tvky_crsr_ctrl->control = ((rate & 0x03) << 1) | ((enable) ? 1 : 0); + tvky_crsr_ctrl->character = c; +} + +/** + * Set if the cursor is visible or not + * + * @param enable 0 to hide, any other number to make visible + */ +static void txt_f256_set_cursor_visible(short enable) { + if (enable) { + tvky_crsr_ctrl->control |= 0x01; + } else { + tvky_crsr_ctrl->control &= ~0x01; + } +} + +/** + * get the current region + * + * @param region pointer to a t_rect describing the rectangular region (using character cells for size and size) + * + * @return 0 on success, any other number means the region was invalid + */ +static short txt_f256_get_region(p_rect region) { + region->origin.x = f256_region.origin.x; + region->origin.y = f256_region.origin.y; + region->size.width = f256_region.size.width; + region->size.height = f256_region.size.height; + + return 0; +} + +/** + * Set a region to restrict further character display, scrolling, etc. + * Note that a region of zero size will reset the region to the full size of the screen. + * + * @param region pointer to a t_rect describing the rectangular region (using character cells for size and size) + * + * @return 0 on success, any other number means the region was invalid + */ +static short txt_f256_set_region(const p_rect region) { + if ((region->size.width == 0) || (region->size.height == 0)) { + /* Set the region to the default (full screen) */ + f256_region.origin.x = 0; + f256_region.origin.y = 0; + f256_region.size.width = f256_visible_size.width; + f256_region.size.height = f256_visible_size.height; + } else { + f256_region.origin.x = region->origin.x; + f256_region.origin.y = region->origin.y; + f256_region.size.width = region->size.width; + f256_region.size.height = region->size.height; + } + + return 0; +} + +/** + * Get the default foreground and background colors for printing + * + * @param pointer to the foreground the Text LUT index of the new current foreground color (0 - 15) + * @param pointer to the background the Text LUT index of the new current background color (0 - 15) + */ +static short txt_f256_get_color(unsigned char * foreground, unsigned char * background) { + *foreground = (f256_color & 0xf0) >> 4; + *background = f256_color & 0x0f; + return 0; +} + +/** + * Set the default foreground and background colors for printing + * + * @param foreground the Text LUT index of the new current foreground color (0 - 15) + * @param background the Text LUT index of the new current background color (0 - 15) + */ +static short txt_f256_set_color(unsigned char foreground, unsigned char background) { + f256_color = ((foreground & 0x0f) << 4) + (background & 0x0f); + return 0; +} + +/** + * Scroll the text in the current region + * + * @param screen the number of the text device + * @param horizontal the number of columns to scroll (negative is left, positive is right) + * @param vertical the number of rows to scroll (negative is down, positive is up) + */ +static void txt_f256_scroll(short horizontal, short vertical) { + short x, x0, x1, x2, x3, dx; + short y, y0, y1, y2, y3, dy; + + /* + * Determine limits of rectangles to move and fill and directions of loops + * x0 and y0 are the positions of the first cell to be over-written + * x1 and y1 are the positions of the first cell to be copied... TEXT[x0,y0] := TEXT[x1,y1] + * x2 and y2 are the position of the last cell to be over-written + * x3 and y3 are the position of the last cell to be copied... TEXT[x2,y2] := TEXT[x3,y3] + * + * When blanking, the rectangles (x2,y0) - (x3,y3) and (x0,y2) - (x2,y3) are cleared + */ + + // Determine the row limits + + if (vertical >= 0) { + y0 = f256_region.origin.y; + y1 = y0 + vertical; + y3 = f256_region.origin.y + f256_region.size.height; + y2 = y3 - vertical; + dy = 1; + } else { + y0 = f256_region.origin.y + f256_region.size.height - 1; + y1 = y0 + vertical; + y3 = f256_region.origin.y - 1; + y2 = y3 - vertical; + dy = -1; + } + + // Determine the column limits + + if (horizontal >= 0) { + x0 = f256_region.origin.x; + x1 = x0 + horizontal; + x3 = f256_region.origin.x + f256_region.size.width; + x2 = x3 - horizontal; + dx = 1; + } else { + x0 = f256_region.origin.x + f256_region.size.width - 1; + x1 = x0 + horizontal; + x3 = f256_region.origin.x - 1; + x2 = x3 - horizontal; + dx = -1; + } + + /* Copy the rectangle. */ + int delta_y = dy * f256_max_size.width; + int row_dst = y0 * f256_max_size.width - delta_y; + int row_src = y0 * f256_max_size.width + vertical * f256_max_size.width - delta_y; + for (y = y0; y != y2; y += dy) { + row_dst += delta_y; + row_src += delta_y; + int offset_dst = row_dst + x0 - dx; + int offset_src = row_src + horizontal + x0 - dx; + for (x = x0; x != x2; x += dx) { + offset_dst += dx; + offset_src += dx; + tvky_text_matrix[offset_dst] = tvky_text_matrix[offset_src]; + tvky_color_matrix[offset_dst] = tvky_color_matrix[offset_src]; + } + } + + /* Clear the rectangles */ + if (horizontal != 0) { + row_dst = y0 * f256_max_size.width - delta_y; + for (y = y0; y != y3; y += dy) { + row_dst += delta_y; + for (x = x2; x != x3; x += dx) { + tvky_text_matrix[row_dst + x] = ' '; + tvky_color_matrix[row_dst + x] = f256_color; + } + } + } + + if (vertical != 0) { + row_dst = y2 * f256_max_size.width - delta_y; + for (y = y2; y != y3; y += dy) { + row_dst += delta_y; + for (x = x0; x != x3; x += dx) { + tvky_text_matrix[row_dst + x] = ' '; + tvky_color_matrix[row_dst + x] = f256_color; + } + } + } +} + +/** + * Fill the current region with a character in the current color + * + * @param screen the number of the text device + * @param c the character to fill the region with + */ +static void txt_f256_fill(char c) { + int x; + int y; + + for (y = 0; y < f256_region.size.height; y++) { + int offset_row = ((f256_region.origin.y + y) * (int)f256_max_size.width); + for (x = 0; x < f256_region.size.width; x++) { + int offset = offset_row + f256_region.origin.x + x; + tvky_text_matrix[offset] = c; + tvky_color_matrix[offset] = f256_color; + } + } +} + +/** + * Set the position of the cursor to (x, y) relative to the current region + * If the (x, y) coordinate is outside the region, it will be clipped to the region. + * If y is greater than the height of the region, the region will scroll until that relative + * position would be within view. + * + * @param x the column for the cursor + * @param y the row for the cursor + */ +static void txt_f256_set_xy(short x, short y) { + /* Make sure X is within range for the current region... "print" a newline if not */ + if (x < 0) { + x = 0; + } else if (x >= f256_region.size.width) { + x = 0; + y++; + } + + /* Make sure Y is within range for the current region... scroll if not */ + if (y < 0) { + y = 0; + } else if (y >= f256_region.size.height) { + txt_f256_scroll(0, y - f256_region.size.height + 1); + y = f256_region.size.height - 1; + } + + f256_cursor.x = x; + f256_cursor.y = y; + + /* Set register */ + tvky_crsr_ctrl->column = f256_region.origin.x + x; + tvky_crsr_ctrl->row = f256_region.origin.y + y; +} + +/** + * Get the position of the cursor (x, y) relative to the current region + * + * @param screen the number of the text device + * @param position pointer to a t_point record to fill out + */ +static void txt_f256_get_xy(p_point position) { + position->x = f256_cursor.x; + position->y = f256_cursor.y; +} + +/** + * Print a character to the current cursor position in the current color + * + * @param c the character to print + */ +static void txt_f256_put(char c) { + short x; + short y; + unsigned int offset; + + x = f256_region.origin.x + f256_cursor.x; + y = f256_region.origin.y + f256_cursor.y; + offset = y * f256_max_size.width + x; + tvky_text_matrix[offset] = c; + tvky_color_matrix[offset] = f256_color; + + txt_f256_set_xy(f256_cursor.x + 1, f256_cursor.y); +} + +/** + * Initialize the screen + */ +static void txt_f256_init() { + TRACE("txt_f256_init"); + + char buffer[255]; + t_rect region; + int i; + + f256_resolution.width = 0; + f256_resolution.height = 0; + f256_visible_size.width = 0; + f256_visible_size.height = 0; + f256_font_size.width = 0; + f256_font_size.height = 0; + + /* Disable the set_sizes call for now, to avoid computing transcient unnecessary values */ + f256_enable_set_sizes = 0; + + /* Start with nothing on */ + msr_shadow = 0; + + /* Define the capabilities */ + + /* Specify the screen number. We have only one so... */ + f256_caps.number = TXT_SCREEN_F256; + + /* This screen can be text, bitmap or can be put to sleep */ + f256_caps.supported_modes = TXT_MODE_TEXT | TXT_MODE_SPRITE | TXT_MODE_BITMAP | TXT_MODE_TILE | TXT_MODE_SLEEP; + + /* Supported resolutions */ + f256_caps.resolution_count = sizeof(f256_resolutions) / sizeof(t_extent); + f256_caps.resolutions = f256_resolutions; + + /* Only 8x8 on the U */ + f256_caps.font_size_count = sizeof(f256_fonts) / sizeof(t_extent); + f256_caps.font_sizes = f256_fonts; + + /* Initialize the color lookup tables */ + for (i = 0; i < sizeof(f256_clut)/sizeof(t_color4); i++) { + tvky_text_fg_color[i] = f256_clut[i]; + tvky_text_bg_color[i] = f256_clut[i]; + } + + /* Set the mode to text */ + txt_f256_set_mode(TXT_MODE_TEXT); + + /* Set the resolution */ + txt_f256_set_resolution(640, 480); + + /* Set the default color: light grey on blue */ + txt_f256_set_color(0x07, 0x04); + + /* Set the font */ + txt_f256_set_font(8, 8, MSX_CP437_8x8_bin); /* Use 8x8 font */ + + /* Set the cursor */ + txt_f256_set_cursor(1, 0, 0xB1); + + /* Set the border */ + txt_f256_set_border(8, 8); /* Set up the border */ + txt_f256_set_border_color(0xf0, 0, 0); + + INFO("Border set"); + + /* + * Enable set_sizes, now that everything is set up initially + * And calculate the size of the screen + */ + f256_enable_set_sizes = 1; + txt_f256_set_sizes(); + + /* Set region to default */ + region.origin.x = 0; + region.origin.y = 0; + region.size.width = 0; + region.size.height = 0; + txt_f256_set_region(®ion); + + /* Clear the screen */ + txt_f256_fill(' '); + + /* Home the cursor */ + txt_f256_set_xy(0, 0); +} + +/** + * Initialize and install the driver + * + * @return 0 on success, any other number is an error + */ +short txt_f256_install() { + t_txt_device device; + + device.number = TXT_SCREEN_F256; + device.name = "SCREEN"; + + device.init = txt_f256_init; + device.get_capabilities = txt_f256_get_capabilities; + device.set_mode = txt_f256_set_mode; + device.set_sizes = txt_f256_set_sizes; + device.set_resolution = txt_f256_set_resolution; + device.set_border = txt_f256_set_border; + device.set_border_color = txt_f256_set_border_color; + device.set_font = txt_f256_set_font; + device.set_cursor = txt_f256_set_cursor; + device.set_cursor_visible = txt_f256_set_cursor_visible; + device.get_region = txt_f256_get_region; + device.set_region = txt_f256_set_region; + device.get_color = txt_f256_get_color; + device.set_color = txt_f256_set_color; + device.set_xy = txt_f256_set_xy; + device.get_xy = txt_f256_get_xy; + device.put = txt_f256_put; + device.scroll = txt_f256_scroll; + device.fill = txt_f256_fill; + device.get_sizes = txt_f256_get_sizes; + + return txt_register(&device); +} diff --git a/src/dev/txt_f256.h b/src/dev/txt_f256.h new file mode 100644 index 0000000..3b10161 --- /dev/null +++ b/src/dev/txt_f256.h @@ -0,0 +1,19 @@ +/** @file txt_f256.h + * + * Text screen driver for the F256 (JR and K) + */ + +#ifndef __TXT_F256_H +#define __TXT_F256_H + +/* We only have one screen */ +#define TXT_SCREEN_F256 0 + +/** + * Initialize and install the driver + * + * @return 0 on success, any other number is an error + */ +extern short txt_f256_install(); + +#endif diff --git a/src/dev/uart.c b/src/dev/uart.c index 2991340..64e1133 100644 --- a/src/dev/uart.c +++ b/src/dev/uart.c @@ -173,6 +173,22 @@ unsigned char uart_get(short uart) { } } +/* + * Write a string to the UART with a newline at the end + * + * Inputs: + * uart = the number of the UART: 0 for COM1, 1 for COM2 + * message = the ASCIIZ string to print + * + */ +void uart_writeln(short uart, char * message) { + for (char * x = message; *x != 0; x++) { + uart_put(0, *x); + } + uart_put(0, '\n'); + uart_put(0, '\r'); +} + /** * Return the status of the UART * diff --git a/src/dev/uart.h b/src/dev/uart.h index 52575f0..3418095 100644 --- a/src/dev/uart.h +++ b/src/dev/uart.h @@ -58,6 +58,16 @@ extern bool uart_has_bytes(short uart); */ extern void uart_put(short uart, unsigned char b); +/* + * Write a string to the UART with a newline at the end + * + * Inputs: + * uart = the number of the UART: 0 for COM1, 1 for COM2 + * message = the ASCIIZ string to print + * + */ +extern void uart_writeln(short uart, char * message); + /* * Get a byte from the UART. Blocks until there is data to read. * diff --git a/src/include/C256/README.md b/src/include/C256/README.md new file mode 100644 index 0000000..9d3e81a --- /dev/null +++ b/src/include/C256/README.md @@ -0,0 +1,3 @@ +# C256 Includes + +This directory contains the include files for the C256 family of computers (C256 FMX, C256 U, C256 U+) and defines the registers for the various I/O devices that the Foenix Toolbox needs. diff --git a/src/include/F256/README.md b/src/include/F256/README.md new file mode 100644 index 0000000..743b6cc --- /dev/null +++ b/src/include/F256/README.md @@ -0,0 +1,5 @@ +# F256 Includes + +This directory contains the include files for the F256 family of computers and defines the registers for the various I/O devices that the Foenix Toolbox needs. + +NOTE: Foenix Toolbox supports only those F256 computers that have a 65816 processor and the linear memory map. diff --git a/src/include/F256/dma_f256.h b/src/include/F256/dma_f256.h new file mode 100644 index 0000000..320e37e --- /dev/null +++ b/src/include/F256/dma_f256.h @@ -0,0 +1,35 @@ +/** + * @file dma_f256.h + * @brief Definitions of the video and system DMA registers + * @version 0.1 + * @date 2023-10-02 + * + */ + +#ifndef __DMA_F256_H_ +#define __DMA_F256_H_ + +// +// Video RAM DMA Registers +// + +#define DMA_CTRL ((volatile __attribute__((far)) uint8_t *)0xf01f00) +#define DMA_CTRL_EN 0x01 +#define DMA_CTRL_2D 0x02 +#define DMA_CTRL_FILL 0x04 +#define DMA_CTRL_IEN 0x08 // Interrupt Enable +#define DMA_CTRL_TRF 0x80 + +#define DMA_STAT ((volatile __attribute__((far)) uint8_t *)0xf01f01) +#define DMA_STAT_TFR_BUSY 0x80 + +#define DMA_FILL_VALUE ((volatile __attribute__((far)) uint8_t *)0xf01f01) +#define DMA_SRC_ADDR ((volatile __attribute__((far)) uint8_t *)0xf01f04) +#define DMA_DST_ADDR ((volatile __attribute__((far)) uint8_t *)0xf01f08) +#define DMA_SIZE ((volatile __attribute__((far)) uint8_t *)0xf01f0c) +#define DMA_SIZE_X ((volatile __attribute__((far)) uint16_t *)0xf01f0c) +#define DMA_SIZE_Y ((volatile __attribute__((far)) uint16_t *)0xf01f0e) +#define DMA_SRC_STRIDE ((volatile __attribute__((far)) uint16_t *)0xf01f10) +#define DMA_DST_STRIDE ((volatile __attribute__((far)) uint16_t *)0xf01f12) + +#endif diff --git a/src/include/F256/gabe_f256.h b/src/include/F256/gabe_f256.h new file mode 100644 index 0000000..b428542 --- /dev/null +++ b/src/include/F256/gabe_f256.h @@ -0,0 +1,95 @@ +/** + * @file gabe.h + * @brief Definitions for the GABE chip + * @version 0.1 + * @date 2023-08-30 + * + */ + +#ifndef __GABE_H_ +#define __GABE_H_ + +#include +#include "sys_types.h" + +#define GABE_MSTR_CTRL ((volatile __attribute__((far)) uint8_t *)0xf016a0) +#define GABE_CTRL_PWR_LED 0x01 // Controls the LED in the Front of the case (Next to the reset button) +#define GABE_CTRL_SDC_LED 0x02 // Controls the LED in the Front of the Case (Next to SDCard) +#define GABE_CTRL_STS_LED0 0x04 // Control Status LED0 (General Use) - C256 Foenix U Only +#define GABE_CTRL_STS_LED1 0x08 // Control Status LED0 (General Use) - C256 Foenix U Only +#define GABE_CTRL_BUZZER 0x10 // Controls the Buzzer +#define GABE_SD_CD 0x20 // SD card detect +#define GABE_SD_WP 0x40 // SD card write protect +#define GABE_CTRL_WRM_RST 0x80 // Warm Reset (needs to Setup other registers) + +#define GABE_LED_FLASH_CTRL ((volatile __attribute__((far)) uint8_t *)0xf016a1) +#define GABE_LED0_FLASH_CTRL 0x01 +#define GABE_LED1_FLASH_CTRL 0x02 +#define GABE_CTRL_LED0_RATE 0x30 +#define GABE_CTRL_LED1_RATE 0xc0 + +#define GABE_LD0_FLASH_FRQ_MASK 0x30 +#define GABE_LD0_FLASH_FRQ_1HZ 0x00 // LD0 flashes at 1Hz +#define GABE_LD0_FLASH_FRQ_2HZ 0x10 // LD0 flashes at 2Hz +#define GABE_LD0_FLASH_FRQ_4HZ 0x20 // LD0 flashes at 4Hz +#define GABE_LD0_FLASH_FRQ_5HZ 0x30 // LD0 flashes at 5Hz + +#define GABE_LD1_FLASH_FRQ_MASK 0xc0 +#define GABE_LD1_FLASH_FRQ_1HZ 0x00 // LD1 flashes at 2Hz +#define GABE_LD1_FLASH_FRQ_2HZ 0x40 // LD1 flashes at 4Hz +#define GABE_LD1_FLASH_FRQ_4HZ 0x80 // LD1 flashes at 5Hz +#define GABE_LD1_FLASH_FRQ_5HZ 0xc0 // LD1 flashes at 1Hz + +#define GABE_RST_AUTH ((volatile __attribute__((far)) uint16_t *)0xf016a2) // Set to 0xDEAD to enable reset + +#define GABE_RNG_DATA ((volatile __attribute__((far)) uint16_t *)0xf016a4) // Random Number Generator (read for data, write for seed) +#define GABE_RNG_SEED ((volatile __attribute__((far)) uint16_t *)0xf016a4) // Random Number Generator (read for data, write for seed) +#define GABE_RNG_STAT ((volatile __attribute__((far)) uint16_t *)0xf016a6) // Random Number Generator Status (read) +#define GABE_RNG_LFSR_DONE 0x80 +#define GABE_RNG_CTRL ((volatile __attribute__((far)) uint16_t *)0xf016a6) // Random Number Generator Control (write) +#define GABE_RNG_CTRL_EN 0x01 // Enable the LFSR block +#define GABE_RNG_CTRL_LD_SEED 0x02 // Toggle after setting seed to load seed + +#define GABE_DIP_REG ((volatile __attribute__((far)) uint8_t *)0xf01670) // User and boot mode DIP switches +#define DIP_GAMMA_EN 0x80 +#define DIP_640_400 0x40 +#define DIP_BOOT_RAM 0x01 + +/** + * @brief Structure to represent the machine ID and expansion card info + * + */ +union gabe_sys_stat_u { + struct { + uint8_t machine_id:5; + }; + uint8_t reg; +}; + +#define GABE_SYS_STAT ((volatile __attribute__((far)) union gabe_sys_stat_u *)0xf016a7) + +/** + * @brief Structure to respresent the version of the GABE chip + * + */ +struct gabe_version_s { + uint16_t subversion; + uint16_t version; + uint16_t model; +}; + +#define GABE_VERSION ((volatile __attribute__((far)) struct gabe_version_s *)0xf016aa) + +struct pcb_revision_s { + char major; + char minor; + uint8_t day; + uint8_t month; + uint8_t year; +}; + +#define PCB_ID_LABEL ((volatile __attribute__((far)) char *)0xf016a8) +#define PCB_VERSION ((volatile __attribute__((far)) struct pcb_revision_s *)0xf016aa) + +#endif + diff --git a/src/include/F256/iec_f256.h b/src/include/F256/iec_f256.h new file mode 100644 index 0000000..c10091e --- /dev/null +++ b/src/include/F256/iec_f256.h @@ -0,0 +1,14 @@ +/** + * Define the registers for the IEC (Commodore Serial) interface + */ + +#ifndef __iec_f256_h__ +#define __iec_f256_h__ + +#include + +#define IEC_BASE ((volatile uint8_t *)0xf01680) + +// TODO: fill out with the actual registers + +#endif \ No newline at end of file diff --git a/src/include/F256/ps2_f256.h b/src/include/F256/ps2_f256.h new file mode 100644 index 0000000..7756d70 --- /dev/null +++ b/src/include/F256/ps2_f256.h @@ -0,0 +1,27 @@ +#ifndef __PS2_F256_H +#define __PS2_F256_H + +#include + +/* + * Ports for the PS/2 keyboard and mouse on the F256jr + */ + +#define PS2_CTRL ((volatile __attribute__((far)) uint8_t *)0xf01640) +#define PS2_CTRL_KBD_WR 0x02 +#define PS2_CTRL_MOUSE_WR 0x08 +#define PS2_CTRL_KBD_CLR 0x10 +#define PS2_CTRL_MOUSE_CLR 0x20 + +#define PS2_OUT ((volatile __attribute__((far)) uint8_t *)0xf01641) +#define PS2_KBD_IN ((volatile __attribute__((far)) uint8_t *)0xf01642) +#define PS2_MOUSE_IN ((volatile __attribute__((far)) uint8_t *)0xf01643) +#define PS2_STAT ((volatile __attribute__((far)) uint8_t *)0xf01644) +#define PS2_STAT_KBD_ACK 0x80 // 1: Keyboard success +#define PS2_STAT_KBD_NAK 0x40 // 1: Keyboard error +#define PS2_STAT_MOUSE_ACK 0x20 // 1: Mouse success +#define PS2_STAT_MOUSE_NAK 0x10 // 1: Mouse error +#define PS2_STAT_MOUSE_EMP 0x02 // 1: Mouse FIFO empty +#define PS2_STAT_KBD_EMP 0x01 // 1: Keyboard FIFO empty + +#endif diff --git a/src/include/F256/sdc_f256.h b/src/include/F256/sdc_f256.h new file mode 100644 index 0000000..e147846 --- /dev/null +++ b/src/include/F256/sdc_f256.h @@ -0,0 +1,14 @@ +/* + * Definitions for access to the SDC controller + */ + +#ifndef __SDC_C256_H +#define __SDC_C256_H + +#include + +#define SDC_BASE ((volatile uint8_t *)0xf01d00) + +// TODO: fill out with the actual registers + +#endif diff --git a/src/include/F256/sound_f256.h b/src/include/F256/sound_f256.h new file mode 100644 index 0000000..ed25345 --- /dev/null +++ b/src/include/F256/sound_f256.h @@ -0,0 +1,27 @@ +/* + * Sound device register definitions for the F256K + */ + +#ifndef __SOUND_C256_H +#define __SOUND_C256_H + +#include + +#define PSG_PORT ((volatile __attribute__((far)) uint8_t *)0xf01608) /* Control register for the SN76489 */ +#define PSG_PORT_L ((volatile __attribute__((far)) uint8_t *)0xf01600) /* Control register for the SN76489 */ +#define PSG_PORT_R ((volatile __attribute__((far)) uint8_t *)0xf01610) /* Control register for the SN76489 */ + +#define OPL3_PORT ((volatile unsigned char *)0xf01580) /* Access port for the OPL3 */ + +#define CODEC ((volatile __attribute__((far)) uint16_t *)0xf01620) /* Data register for the CODEC */ +#define CODEC_WR_CTRL ((volatile __attribute__((far)) uint8_t *)0xf01622) /* Data register for the CODEC */ + +/* + * Internal SID + */ + +#define SID_INT_N_V1_FREQ_LO ((volatile __attribute__((far)) uint8_t *)0xf01480) +#define SID_INT_L_V1_FREQ_LO ((volatile __attribute__((far)) uint8_t *)0xf01400) +#define SID_INT_R_V1_FREQ_LO ((volatile __attribute__((far)) uint8_t *)0xf01500) + +#endif diff --git a/src/include/F256/timers_f256.h b/src/include/F256/timers_f256.h new file mode 100644 index 0000000..f01b301 --- /dev/null +++ b/src/include/F256/timers_f256.h @@ -0,0 +1,52 @@ +/** + * @file timers_c256.h + * + * Define timer registers on the C256 + */ + +#ifndef __C256_TIMERS_H +#define __C256_TIMERS_H + +// +// TIMER_CTRL_* flags +// + +#define TIMER_CTRL_EN 0x01 // Set to enable timer +#define TIMER_CTRL_SCLR 0x02 // Set to clear the timer for counting up +#define TIMER_CTRL_SLOAD 0x04 // Set to load the timer for counting down +#define TIMER_CTRL_CNT_UP 0x08 // Set to count up, clear to count down + +// +// TIMER_CMP_* flags +// + +#define TIMER_CMP_RECLR 0x01 // Set to reclear the register on reaching the comparison value +#define TIMER_CMP_RELOAD 0x02 // Set to reload the charge value on reaching 0 + +// +// Timer 0 -- Based on system clock (14318180Hz) +// + +#define TIMER_CTRL_0 ((volatile __attribute__((far)) uint8_t *)0xf01650) +#define TIMER_CHG_L_0 ((volatile __attribute__((far)) uint8_t *)0xf01651) +#define TIMER_CHG_M_0 ((volatile __attribute__((far)) uint8_t *)0xf01652) +#define TIMER_CHG_H_0 ((volatile __attribute__((far)) uint8_t *)0xf01653) +#define TIMER_CMPC_0 ((volatile __attribute__((far)) uint8_t *)0xf01654) +#define TIMER_CMP_L_0 ((volatile __attribute__((far)) uint8_t *)0xf01655) +#define TIMER_CMP_M_0 ((volatile __attribute__((far)) uint8_t *)0xf01656) +#define TIMER_CMP_H_0 ((volatile __attribute__((far)) uint8_t *)0xf01657) + +// +// Timer 1 -- Based on start of frame clock (60/70 Hz) +// + +#define TIMER_CTRL_1 ((volatile __attribute__((far)) uint8_t *)0xf01658) +#define TIMER_CHG_L_1 ((volatile __attribute__((far)) uint8_t *)0xf01659) +#define TIMER_CHG_M_1 ((volatile __attribute__((far)) uint8_t *)0xf0165a) +#define TIMER_CHG_H_1 ((volatile __attribute__((far)) uint8_t *)0xf0165b) +#define TIMER_CMPC_1 ((volatile __attribute__((far)) uint8_t *)0xf0165c) +#define TIMER_CMP_L_1 ((volatile __attribute__((far)) uint8_t *)0xf0165d) +#define TIMER_CMP_M_1 ((volatile __attribute__((far)) uint8_t *)0xf0165e) +#define TIMER_CMP_H_1 ((volatile __attribute__((far)) uint8_t *)0xf0165f) + +#endif diff --git a/src/include/F256/via_f256.h b/src/include/F256/via_f256.h new file mode 100644 index 0000000..65daefb --- /dev/null +++ b/src/include/F256/via_f256.h @@ -0,0 +1,59 @@ +/** + * @file via_f256.h + * @author your name (you@domain.com) + * @brief Register definitions for the VIA 65C22 chips + * @version 0.1 + * @date 2024-06-17 + * + * @copyright Copyright (c) 2024 + * + */ + +#ifndef __via_f256_h__ +#define __via_f256_h__ + +#include + +typedef struct via_s { + uint8_t pb; // Port B data + uint8_t pa; // Port A data + uint8_t ddrb; // Port B data-direction + uint8_t ddra; // Port a data-direction + + uint8_t t1c_l; // Timer 1 Counter/Latch low-byte + uint8_t t1c_h; // Timer 1 Counter high-byte + uint8_t t1l_l; // Timer 1 Latch low-byte + uint8_t t1l_h; // Timer 1 Latch high-byte + + uint8_t t2c_l; // Timer 2 Counter low-byte + uint8_t t2c_h; // Timer 2 Counter high-byte + + uint8_t sr; // Shift register + + uint8_t acr; // Auxiliary Control Register + uint8_t pcr; // Peripheral Control Register + uint8_t ifr; // Interrupt Flag Register + uint8_t ier; // Interrupt Enable Register + + uint8_t pa_nh; // Port A -- No Handshake +} via_t, *via_p; + +// +// VIA Interrupt Flags +// + +#define VIA_INT_CA2 0x01 +#define VIA_INT_CA1 0x02 +#define VIA_INT_SR 0x04 +#define VIA_INT_CB2 0x08 +#define VIA_INT_CB1 0x10 +#define VIA_INT_TIMER2 0x20 +#define VIA_INT_TIMER1 0x40 +#define VIA_INT_IRQ 0x80 + +#define via0 ((volatile __attribute__((far)) via_p)0xf01c00) +#if MODEL == MODEL_FOENIX_F256K || MODEL ==MODEL_FOENIX_F256K2 +#define via1 ((volatile __attribute__((far)) via_p)0xf01b00) +#endif + +#endif diff --git a/src/include/F256/vicky_ii.h b/src/include/F256/vicky_ii.h new file mode 100644 index 0000000..c5b1c0f --- /dev/null +++ b/src/include/F256/vicky_ii.h @@ -0,0 +1,137 @@ +/** + * @file f256_tinyvicky.h + * @author Peter Weingartner (pjw@tailrecursive.org) + * @brief Define the registers for Tiny Vicky on the F256 computers. + * @version 0.1 + * @date 2023-08-07 + * + * @copyright Copyright (c) 2023 + * + */ + +#ifndef __f256_tinyvicky__ +#define __f256_tinyvicky__ + +#include "sys_types.h" +#include + +/** + * @brief Vicky II Border Control Registers + * + */ +typedef struct tvky_border_ctrl_s { + uint8_t control; + t_color3 color; + uint8_t size_x; + uint8_t sizy_y; +} *tvky_border_ctrl_p; + +/** + * @brief Vicky II Cursor Control Registers + * + */ +typedef struct tvky_crsr_ctrl_s { + uint8_t control; + uint8_t start_address; + char character; + uint8_t reserved; + uint16_t column; + uint16_t row; +} *tvky_crsr_ctrl_p; + +#define VKY_CRSR_ENABLE 0x01 +#define VKY_CRSR_FLASH_RATE_1S 0x00 +#define VKY_CRSR_FLASH_RATE_12S 0x02 +#define VKY_CRSR_FLASH_RATE_14S 0x04 +#define VKY_CRSR_FLASH_RATE_15S 0x06 +#define VKY_CRSR_FLASH_DIS 0x08 + +// +// Define the locations of the registers +// + +#define tvky_mstr_ctrl ((volatile __attribute__((far)) uint16_t *)0xf01000) +#define VKY_MCR_TEXT 0x0001 +#define VKY_MCR_TEXT_OVERLAY 0x0002 +#define VKY_MCR_GRAPHICS 0x0004 +#define VKY_MCR_BITMAP 0x0008 +#define VKY_MCR_TILE 0x0010 +#define VKY_MCR_SPRITE 0x0020 +#define VKY_MCR_GAMMA 0x0040 +#define VKY_MCR_CLK_70 0x0100 +#define VKY_MCR_DBL_X 0x0200 +#define VKY_MCR_DBL_Y 0x0400 +#define VKY_MCR_SLEEP 0x0800 +#define VKY_MCR_FONT_OVERLAY 0x1000 +#define VKY_MCR_FONT_SET 0x2000 + +#define VKY_MCR_RES_MASK 0x0700 +#define VKY_MCR_RES_640x480 0x0000 +#define VKY_MCR_RES_640x400 0x0100 +#define VKY_MCR_RES_320x240 0x0600 +#define VKY_MCR_RES_320x200 0x0700 + +#define tvky_brdr_ctrl ((volatile tvky_border_ctrl_p)0xf01004) + +#define vky_brdr_ctrl ((volatile __attribute__((far)) uint8_t *)0xf01004) +#define vky_brdr_col_blue ((volatile __attribute__((far)) uint8_t *)0xf01005) +#define vky_brdr_col_green ((volatile __attribute__((far)) uint8_t *)0xf01006) +#define vky_brdr_col_red ((volatile __attribute__((far)) uint8_t *)0xf01007) +#define vky_brdr_size_x ((volatile __attribute__((far)) uint8_t *)0xf01008) +#define vky_brdr_size_y ((volatile __attribute__((far)) uint8_t *)0xf01009) + + +#define tvky_bg_color ((volatile __attribute__((far)) t_color3 *)0xf0100d) +#define tvky_crsr_ctrl ((volatile __attribute__((far)) tvky_crsr_ctrl_p)0xf01010) + +// +// Text Color Lookup Tables +// +#define tvky_text_fg_color ((volatile __attribute__((far)) t_color4 *)0xf01800) +#define tvky_text_bg_color ((volatile __attribute__((far)) t_color4 *)0xf01840) + +// +// Text Fonts Sets 0 and 1 +// +#define tvky_font_set_0 ((volatile __attribute__((far)) uint8_t *)0xf02000) + +// +// Graphics Color Lookup Tables +// +#define VKY_GR_CLUT_0 ((volatile __attribute__((far)) uint8_t *)0xf03000) +#define VKY_GR_CLUT_1 ((volatile __attribute__((far)) uint8_t *)0xf03400) +#define VKY_GR_CLUT_2 ((volatile __attribute__((far)) uint8_t *)0xf03800) +#define VKY_GR_CLUT_3 ((volatile __attribute__((far)) uint8_t *)0xf03c00) + +// +// Text mode text and color matrixes +// +#define tvky_text_matrix ((volatile __attribute__((far)) char *)0xf04000) +#define tvky_color_matrix ((volatile __attribute__((far)) char *)0xf06000) + +// +// Bitmap graphics registers +// + +typedef volatile __attribute__((far24)) uint8_t *p_far24; + +#define bm0_control ((volatile __attribute__((far)) uint8_t *)0xf01100) +#define bm0_address ((volatile __attribute__((far)) uint8_t *)0xf01101) + +#define MousePointer_Mem_A ((volatile __attribute__((far)) uint8_t *)0xf00c00) +#define MousePtr_A_CTRL_Reg ((volatile __attribute__((far)) uint8_t *)0xf016e0) +#define MousePtr_En 0x0001 + +#define MousePtr_A_X_Pos ((volatile __attribute__((far)) uint16_t *)0xf016e2) +#define MousePtr_A_Y_Pos ((volatile __attribute__((far)) uint16_t *)0xf016e4) +#define MousePtr_A_Mouse0 ((volatile __attribute__((far)) uint8_t *)0xf016e6) +#define MousePtr_A_Mouse1 ((volatile __attribute__((far)) uint8_t *)0xf016e7) +#define MousePtr_A_Mouse2 ((volatile __attribute__((far)) uint8_t *)0xf016e8) + +// +// Video RAM +// + +#define vram_base ((volatile p_far24)0) + +#endif diff --git a/src/include/features.h b/src/include/features.h index d7f92c2..ee35863 100644 --- a/src/include/features.h +++ b/src/include/features.h @@ -35,6 +35,9 @@ #define HAS_MIDI_PORTS 1 #define HAS_EXTERNAL_SIDS 1 #define HAS_OPL3 1 +#elif MODEL == MODEL_FOENIX_F256KE + #define HAS_EXTERNAL_SIDS 1 + #define HAS_OPL3 1 #endif diff --git a/src/include/gabe_reg.h b/src/include/gabe_reg.h index 848b125..1786455 100644 --- a/src/include/gabe_reg.h +++ b/src/include/gabe_reg.h @@ -18,4 +18,7 @@ #elif MODEL == MODEL_FOENIX_FMX || MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS #include "C256/gabe_c256.h" +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 +#include "F256/gabe_f256.h" + #endif diff --git a/src/include/ps2_reg.h b/src/include/ps2_reg.h index 278eb1c..aeca665 100644 --- a/src/include/ps2_reg.h +++ b/src/include/ps2_reg.h @@ -16,6 +16,10 @@ #elif MODEL == MODEL_FOENIX_FMX || MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS #include "C256/ps2_c256.h" + +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 +#include "F256/ps2_f256.h" + #endif /* diff --git a/src/include/rtc_reg.h b/src/include/rtc_reg.h index 79114e0..1359ef8 100644 --- a/src/include/rtc_reg.h +++ b/src/include/rtc_reg.h @@ -67,6 +67,26 @@ #define RTC_CTRL ((volatile unsigned char *)0xaf080e) #define RTC_CENTURY ((volatile unsigned char *)0xaf080f) +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 + +#define RTC_BASE ((volatile unsigned char *)0xf01690) +#define RTC_SEC ((volatile unsigned char *)0xf01690) +#define RTC_ALRM_SEC ((volatile unsigned char *)0xf01691) +#define RTC_MIN ((volatile unsigned char *)0xf01692) +#define RTC_ALRM_MIN ((volatile unsigned char *)0xf01693) +#define RTC_HOUR ((volatile unsigned char *)0xf01694) +#define RTC_ALRM_HOUR ((volatile unsigned char *)0xf01695) +#define RTC_DAY ((volatile unsigned char *)0xf01696) +#define RTC_ALRM_DAY ((volatile unsigned char *)0xf01697) +#define RTC_DAY_OF_WEEK ((volatile unsigned char *)0xf01698) +#define RTC_MONTH ((volatile unsigned char *)0xf01699) +#define RTC_YEAR ((volatile unsigned char *)0xf0169a) +#define RTC_RATES ((volatile unsigned char *)0xf0169b) +#define RTC_ENABLES ((volatile unsigned char *)0xf0169c) +#define RTC_FLAGS ((volatile unsigned char *)0xf0169d) +#define RTC_CTRL ((volatile unsigned char *)0xf0169e) +#define RTC_CENTURY ((volatile unsigned char *)0xf0169f) + #endif /* Rate fields and settings */ diff --git a/src/include/sound_reg.h b/src/include/sound_reg.h index 46dcd64..f177d44 100644 --- a/src/include/sound_reg.h +++ b/src/include/sound_reg.h @@ -15,6 +15,9 @@ #elif MODEL == MODEL_FOENIX_FMX || MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS #include "C256/sound_c256.h" + +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 +#include "F256/sound_f256.h" #endif #endif diff --git a/src/include/timers_reg.h b/src/include/timers_reg.h index adc410a..fd65363 100644 --- a/src/include/timers_reg.h +++ b/src/include/timers_reg.h @@ -15,6 +15,10 @@ #elif MODEL == MODEL_FOENIX_FMX || MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS #include "C256/timers_c256.h" + +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 +#include "F256/timers_f256.h" + #endif #endif diff --git a/src/include/uart_reg.h b/src/include/uart_reg.h index e4ee3a3..3cd52f3 100644 --- a/src/include/uart_reg.h +++ b/src/include/uart_reg.h @@ -15,6 +15,10 @@ #define UART1_BASE 0x00B028F8 /* Base address for UART 1 (COM1) */ #define UART2_BASE 0x00B028F9 /* Base address for UART 2 (COM2) */ +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 +#define UART1_BASE 0x00F01630 /* Base address for UART 1 (COM1) */ +#define UART2_BASE 0x00F01630 /* Base address for UART 2 (COM2) */ + #endif /* @@ -91,6 +95,18 @@ #define UART_57600 21 /* Code for 57600 bps */ #define UART_115200 10 /* Code for 115200 bps */ +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 + +#define UART_300 5244 /* Code for 300 bps */ +#define UART_1200 1311 /* Code for 1200 bps */ +#define UART_2400 655 /* Code for 2400 bps */ +#define UART_4800 327 /* Code for 4800 bps */ +#define UART_9600 163 /* Code for 9600 bps */ +#define UART_19200 81 /* Code for 19200 bps */ +#define UART_38400 40 /* Code for 28400 bps */ +#define UART_57600 27 /* Code for 57600 bps */ +#define UART_115200 13 /* Code for 115200 bps */ + #else #define UART_300 384 /* Code for 300 bps */ diff --git a/src/include/vicky_general.h b/src/include/vicky_general.h index d83c637..6535d40 100644 --- a/src/include/vicky_general.h +++ b/src/include/vicky_general.h @@ -16,6 +16,10 @@ #elif MODEL == MODEL_FOENIX_FMX || MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS #include "C256/vicky_ii.h" + +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 +#include "F256/vicky_ii.h" + #endif diff --git a/src/log.c b/src/log.c index 9acaca9..52780b0 100644 --- a/src/log.c +++ b/src/log.c @@ -13,19 +13,14 @@ #include "dev/uart.h" #include "dev/txt_screen.h" +#include "gabe_reg.h" -#if MODEL == MODEL_FOENIX_A2560U || MODEL == MODEL_FOENIX_A2560U_PLUS -#include "A2560U/gabe_a2560u.h" -#elif (MODEL == MODEL_FOENIX_A2560K || MODEL == MODEL_FOENIX_GENX || MODEL == MODEL_FOENIX_A2560X) -#include "A2560K/gabe_a2560k.h" -#endif - /* Channel to which the logging output should go. * Positive: screen number * -1: UART. */ -static short log_channel = LOG_CHANNEL; +static short log_channel = -1; short log_level; // do_log either points to log_to_uart or log_to_screen. @@ -49,14 +44,14 @@ void buzzer_off(void) { void log_init(void) { log_setlevel(DEFAULT_LOG_LEVEL); - // TODO: bring back // if (log_channel == LOG_CHANNEL_UART0) { - // uart_init(UART_COM1); - // do_log = log_to_uart; - // //log(LOG_INFO,"FOENIX DEBUG OUTPUT------------"); + uart_init(UART_COM1); + do_log = log_to_uart; + log(LOG_INFO,"FOENIX DEBUG OUTPUT------------"); // } - // else - do_log = log_to_screen; + // else { + // do_log = log_to_screen; + // } } unsigned short panic_number; /* The number of the kernel panic */ @@ -250,12 +245,12 @@ void log_setlevel(short level) { static void log_to_uart(const char *message) { - // TODO: bring back - // char *c = (char*)message; - // while (*c) - // uart_put(UART_COM1, *c++); - // uart_put(UART_COM1,'\r'); - // uart_put(UART_COM1,'\n'); + char *c = (char*)message; + while (*c) { + uart_put(UART_COM1, *c++); + } + uart_put(UART_COM1,'\r'); + uart_put(UART_COM1,'\n'); } static void log_to_screen(const char *message) { @@ -284,8 +279,9 @@ void log(short level, const char * message, ...) { vsprintf(buf, message, args); va_end(args); - txt_print(0, buf); - txt_print(0, "\n"); + (*do_log)(buf); +// txt_print(0, buf); +// txt_print(0, "\n"); } void trace(const char * message, ...) { diff --git a/src/sys_general.h b/src/sys_general.h index 082ebb3..ecf8ddc 100644 --- a/src/sys_general.h +++ b/src/sys_general.h @@ -14,13 +14,16 @@ #define MODEL_FOENIX_FMX 0 #define MODEL_FOENIX_C256U 1 +#define MODEL_FOENIX_F256 2 #define MODEL_FOENIX_GENX 4 #define MODEL_FOENIX_C256U_PLUS 5 #define MODEL_FOENIX_A2560U_PLUS 6 #define MODEL_FOENIX_A2560X 8 #define MODEL_FOENIX_A2560U 9 +#define MODEL_FOENIX_A2560M 10 #define MODEL_FOENIX_A2560K 11 -#define MODEL_FOENIX_A2560M 12 +#define MODEL_FOENIX_F256K 18 +#define MODEL_FOENIX_F256K2 17 /* IDs for the CPUs supported */ diff --git a/src/toolbox.c b/src/toolbox.c index d39e0d8..6f514a5 100644 --- a/src/toolbox.c +++ b/src/toolbox.c @@ -3,8 +3,8 @@ */ #include "log_level.h" -#define DEFAULT_LOG_LEVEL LOG_DEBUG -#define LOG_CHANNEL LOG_CHANNEL_CHANNEL_A +#define DEFAULT_LOG_LEVEL LOG_INFO +#define LOG_CHANNEL LOG_CHANNEL_UART0 #include #include @@ -32,6 +32,8 @@ #elif MODEL == MODEL_FOENIX_C256U || MODEL == MODEL_FOENIX_C256U_PLUS || MODEL == MODEL_FOENIX_FMX #include "dev/txt_c256.h" #include "dev/txt_evid.h" +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 +#include "dev/txt_f256.h" #endif #include "syscalls.h" @@ -64,14 +66,6 @@ const char* VolumeStr[FF_VOLUMES] = { "sd0" }; extern unsigned long __memory_start; -void print_error(short channel, char * message, short code) { - // TODO: bring back... - // print(channel, message); - // print(channel, ": "); - // print_hex_16(channel, code); - // print(channel, "\n"); -} - t_sys_info info; /* @@ -81,10 +75,18 @@ void initialize() { long target_jiffies; int i; short res; + + *vky_brdr_ctrl = 0x01; + *vky_brdr_col_red = 0x80; + *vky_brdr_col_green = 0x00; + *vky_brdr_col_blue = 0x00; + *vky_brdr_size_x = 0x08; + *vky_brdr_size_y = 0x08; /* Setup logging early */ log_init(); log_setlevel(DEFAULT_LOG_LEVEL); + INFO3("\n\rFoenix Toolbox v%d.%02d.%04d starting up...", VER_MAJOR, VER_MINOR, VER_BUILD); /* Fill out the system information */ sys_get_information(&info); @@ -92,15 +94,15 @@ void initialize() { /* Initialize the memory system */ mem_init(0x3d0000); - /* Hide the mouse */ - mouse_set_visible(0); + // /* Hide the mouse */ + // mouse_set_visible(0); /* Initialize the text channels */ + INFO("Initializing the text system..."); txt_init(); #if HAS_DUAL_SCREEN txt_a2560k_a_install(); txt_a2560k_b_install(); - log(LOG_INFO, "Initializing screens..."); txt_init_screen(TXT_SCREEN_A2560K_A); txt_init_screen(TXT_SCREEN_A2560K_B); @@ -119,129 +121,142 @@ void initialize() { txt_init_screen(TXT_SCREEN_EVID); } +#elif MODEL == MODEL_FOENIX_F256 || MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2 + *vky_brdr_col_red = 0x80; + *vky_brdr_col_green = 0x00; + *vky_brdr_col_blue = 0x80; + + txt_f256_install(); + + txt_init_screen(TXT_SCREEN_F256); #else #error Cannot identify screen setup #endif - INFO("Text system initialized..."); + txt_set_border_color(0, 0x80, 0x80, 0x80); + txt_print(0, "Foenix Toolbox starting up...\n"); - // Initialize the bitmap system - bm_init(); - INFO("Bitmap system initialized..."); + INFO("Text system initialized."); - /* Initialize the indicators */ - ind_init(); - INFO("Indicators initialized"); + while (1) ; - /* Initialize the interrupt system */ - int_init(); - INFO("Interrupts initialized"); +// // Initialize the bitmap system +// bm_init(); +// INFO("Bitmap system initialized..."); - /* Mute the PSG */ - psg_mute_all(); +// /* Initialize the indicators */ +// ind_init(); +// INFO("Indicators initialized"); - /* Initialize and mute the SID chips */ - sid_init_all(); +// /* Initialize the interrupt system */ +// int_init(); +// INFO("Interrupts initialized"); -// /* Initialize the Yamaha sound chips (well, turn their volume down at least) */ -// ym_init(); +// /* Mute the PSG */ +// psg_mute_all(); - /* Initialize the CODEC */ - init_codec(); +// /* Initialize and mute the SID chips */ +// sid_init_all(); - cdev_init_system(); // Initialize the channel device system - INFO("Channel device system ready."); +// // /* Initialize the Yamaha sound chips (well, turn their volume down at least) */ +// // ym_init(); - bdev_init_system(); // Initialize the channel device system - INFO("Block device system ready."); +// /* Initialize the CODEC */ +// init_codec(); - if ((res = con_install())) { - log_num(LOG_ERROR, "FAILED: Console installation", res); - } else { - INFO("Console installed."); - } +// cdev_init_system(); // Initialize the channel device system +// INFO("Channel device system ready."); - /* Initialize the timers the MCP uses */ - timers_init(); - INFO("Timers initialized"); +// bdev_init_system(); // Initialize the channel device system +// INFO("Block device system ready."); - /* Initialize the real time clock */ - rtc_init(); - INFO("Real time clock initialized"); - - target_jiffies = sys_time_jiffies() + 300; /* 5 seconds minimum */ - DEBUG1("target_jiffies assigned: %d", target_jiffies); - - /* Enable all interrupts */ - int_enable_all(); - TRACE("Interrupts enabled"); - -// /* Play the SID test bong on the Gideon SID implementation */ -// sid_test_internal(); - - // if ((res = pata_install())) { - // log_num(LOG_ERROR, "FAILED: PATA driver installation", res); - // } else { - // INFO("PATA driver installed."); - // } - - if ((res = sdc_install())) { - ERROR1("FAILED: SDC driver installation %d", res); - } else { - INFO("SDC driver installed."); - } - -#if HAS_FLOPPY - if ((res = fdc_install())) { - ERROR1("FAILED: Floppy drive initialization %d", res); - } else { - INFO("Floppy drive initialized."); - } -#endif - - // At this point, we should be able to call into to console to print to the screens - - if ((res = ps2_init())) { - print_error(0, "FAILED: PS/2 keyboard initialization", res); - } else { - log(LOG_INFO, "PS/2 keyboard initialized."); - } - -#if MODEL == MODEL_FOENIX_A2560K - if ((res = kbdmo_init())) { - log_num(LOG_ERROR, "FAILED: A2560K built-in keyboard initialization", res); - } else { - log(LOG_INFO, "A2560K built-in keyboard initialized."); - } -#endif - -#if HAS_PARALLEL_PORT - if ((res = lpt_install())) { - log_num(LOG_ERROR, "FAILED: LPT installation", res); - } else { - log(LOG_INFO, "LPT installed."); - } -#endif - -#if HAS_MIDI_PORTS - if ((res = midi_install())) { - log_num(LOG_ERROR, "FAILED: MIDI installation", res); - } else { - log(LOG_INFO, "MIDI installed."); - } -#endif - -// if (res = uart_install()) { -// log_num(LOG_ERROR, "FAILED: serial port initialization", res); +// if ((res = con_install())) { +// log_num(LOG_ERROR, "FAILED: Console installation", res); // } else { -// log(LOG_INFO, "Serial ports initialized."); +// INFO("Console installed."); // } - if ((res = fsys_init())) { - log_num(LOG_ERROR, "FAILED: file system initialization", res); - } else { - INFO("File system initialized."); - } +// /* Initialize the timers the MCP uses */ +// timers_init(); +// INFO("Timers initialized"); + +// /* Initialize the real time clock */ +// rtc_init(); +// INFO("Real time clock initialized"); + +// target_jiffies = sys_time_jiffies() + 300; /* 5 seconds minimum */ +// DEBUG1("target_jiffies assigned: %d", target_jiffies); + +// /* Enable all interrupts */ +// int_enable_all(); +// TRACE("Interrupts enabled"); + +// // /* Play the SID test bong on the Gideon SID implementation */ +// // sid_test_internal(); + +// // if ((res = pata_install())) { +// // log_num(LOG_ERROR, "FAILED: PATA driver installation", res); +// // } else { +// // INFO("PATA driver installed."); +// // } + +// if ((res = sdc_install())) { +// ERROR1("FAILED: SDC driver installation %d", res); +// } else { +// INFO("SDC driver installed."); +// } + +// #if HAS_FLOPPY +// if ((res = fdc_install())) { +// ERROR1("FAILED: Floppy drive initialization %d", res); +// } else { +// INFO("Floppy drive initialized."); +// } +// #endif + +// // At this point, we should be able to call into to console to print to the screens + +// if ((res = ps2_init())) { +// ERROR1("FAILED: PS/2 keyboard initialization", res); +// } else { +// log(LOG_INFO, "PS/2 keyboard initialized."); +// } + +// #if MODEL == MODEL_FOENIX_A2560K +// if ((res = kbdmo_init())) { +// log_num(LOG_ERROR, "FAILED: A2560K built-in keyboard initialization", res); +// } else { +// log(LOG_INFO, "A2560K built-in keyboard initialized."); +// } +// #endif + +// #if HAS_PARALLEL_PORT +// if ((res = lpt_install())) { +// log_num(LOG_ERROR, "FAILED: LPT installation", res); +// } else { +// log(LOG_INFO, "LPT installed."); +// } +// #endif + +// #if HAS_MIDI_PORTS +// if ((res = midi_install())) { +// log_num(LOG_ERROR, "FAILED: MIDI installation", res); +// } else { +// log(LOG_INFO, "MIDI installed."); +// } +// #endif + +// // if (res = uart_install()) { +// // log_num(LOG_ERROR, "FAILED: serial port initialization", res); +// // } else { +// // log(LOG_INFO, "Serial ports initialized."); +// // } + +// if ((res = fsys_init())) { +// log_num(LOG_ERROR, "FAILED: file system initialization", res); +// } else { +// INFO("File system initialized."); +// } } int main(int argc, char * argv[]) { @@ -252,10 +267,10 @@ int main(int argc, char * argv[]) { initialize(); // Attempt to start up the user code - log(LOG_INFO, "Looking for user startup code:"); - boot_launch(); + // log(LOG_INFO, "Looking for user startup code:"); + // boot_launch(); - printf("Done.\n"); + INFO("Done."); #ifdef _CALYPSI_MCP_DEBUGGER extern int CalypsiDebugger(void);