Merge pull request #2 from pweingar/v1.01

V1.01
This commit is contained in:
pweingar 2024-12-03 14:13:28 -05:00 committed by GitHub
commit bced1b694c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
156 changed files with 6869 additions and 6592 deletions

View file

@ -1,8 +0,0 @@
AS = 64tass
ASFLAGS = --nostart --flat --s-record
# Build the object files from assembly
hello.s37: hello.s
$(AS) $(ASFLAGS) --list=hello.lst -o hello.s37 hello.s

View file

@ -1,30 +0,0 @@
# Foenix Toolbox Function Bindings for the 64TASS Assembler
This folder contains the assembly (*.s) files needed to call into the Foenix Toolbox using 64TASS assembly.
## Foenix Toolbox Assembly ABI
Foenix Toolbox functions are called using the Calypsi "simplecall" calling convention.
1. The first parameter is passed using the accumulator for 8 and 16 bit quantities, and the X register and accumulator for 24 and 32 bit quantities (with the X register holding the most significant bits).
2. Additional parameters are passed on the stack, pushed so that the left-most parameter is at the top of the stack before the call.
3. The return value is passed in the accumulator for 8 and 16 bit values or the X register and accumulator for 24 and 32 bit values.
4. The caller is responsible for removing the parameters from the stack (if any) after the call returns.
5. The Foenix Toolbox will preserve the caller's direct page and data bank registers at the start of the call and restore them just before returning to the caller.
6. All functions are accessed using long calls (`JSL`).
## Files
The files that are included as part of the client bindings are:
* `toolbox.s`: the main include file. This file includes `bindings.s` automatically and also defines the `alloc` and `free` macros that can be used to help manage the stack. NOTE: the `free` macro uses the first two bytes in the caller's direct page as scratch storage to preserve the return value from the function while cleaning up the stack.
* `types.s`: this include file defines some structures to match the data structures used by some of the Toolbox functions.
* `bindings.s`: this include file defines all the function labels as well as labels that may be used to treat the parameters as locations in memory, rather than as values on the stack. This may simplify coding in some cases.
* `genbindings.py`: this Python script is used to generate the `bindings.s` file in the case that Toolbox functions are removed, altered, or added. It uses the files in the Calypsi bindings folder as the source for what functions are present. The general user of the 64TASS client files will probably never use this script.
* `hello.s`: A simple "Hello, world" example. It also demonstrates using the program header for programs to run from RAM, flash, or the cartridge.

View file

@ -1,885 +0,0 @@
;
; extern SYSTEMCALL void sys_proc_exit(short result);
;
; result goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_proc_exit = $ffe000
;
; extern SYSTEMCALL void sys_int_enable_all();
;
; 0 bytes needed for the stack parameters
;
sys_int_enable_all = $ffe004
;
; extern SYSTEMCALL void sys_int_disable_all();
;
; 0 bytes needed for the stack parameters
;
sys_int_disable_all = $ffe008
;
; extern SYSTEMCALL void sys_int_disable(unsigned short n);
;
; n goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_int_disable = $ffe00c
;
; extern SYSTEMCALL void sys_int_enable(unsigned short n);
;
; n goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_int_enable = $ffe010
;
; extern SYSTEMCALL p_int_handler sys_int_register(unsigned short n, p_int_handler handler);
;
; n goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_int_register = $ffe014
int_register .namespace
.virtual 1,s
handler .dword ? ; pointer to the interrupt handler to register
.endv
.endn
;
; extern SYSTEMCALL short sys_int_pending(unsigned short n);
;
; n goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_int_pending = $ffe018
;
; extern SYSTEMCALL void sys_get_info(p_sys_info info);
;
; info goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_get_info = $ffe01c
;
; extern SYSTEMCALL void sys_int_clear(unsigned short n);
;
; n goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_int_clear = $ffe020
;
; extern SYSTEMCALL short sys_chan_read_b(short channel);
;
; channel goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_chan_read_b = $ffe024
;
; extern SYSTEMCALL short sys_chan_read(short channel, unsigned char * buffer, short size);
;
; channel goes in A[15..0]
;
; 6 bytes needed for the stack parameters
;
sys_chan_read = $ffe028
chan_read .namespace
.virtual 1,s
buffer .dword ? ; the buffer into which to copy the channel data
size .word ? ; the size of the buffer.
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_readline(short channel, unsigned char * buffer, short size);
;
; channel goes in A[15..0]
;
; 6 bytes needed for the stack parameters
;
sys_chan_readline = $ffe02c
chan_readline .namespace
.virtual 1,s
buffer .dword ? ; the buffer into which to copy the channel data
size .word ? ; the size of the buffer
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_write_b(short channel, uint8_t b);
;
; channel goes in A[15..0]
;
; 1 bytes needed for the stack parameters
;
sys_chan_write_b = $ffe030
chan_write_b .namespace
.virtual 1,s
b .byte ? ; the byte to write
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_write(short channel, const uint8_t * buffer, short size);
;
; channel goes in A[15..0]
;
; 6 bytes needed for the stack parameters
;
sys_chan_write = $ffe034
chan_write .namespace
.virtual 1,s
buffer .dword ? ;
size .word ? ;
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_status(short channel);
;
; channel goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_chan_status = $ffe038
;
; extern SYSTEMCALL short sys_chan_flush(short channel);
;
; channel goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_chan_flush = $ffe03c
;
; extern SYSTEMCALL short sys_chan_seek(short channel, long position, short base);
;
; channel goes in A[15..0]
;
; 6 bytes needed for the stack parameters
;
sys_chan_seek = $ffe040
chan_seek .namespace
.virtual 1,s
position .dword ? ; the position of the cursor
base .word ? ; whether the position is absolute or relative to the current position
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_ioctrl(short channel, short command, uint8_t * buffer, short size);
;
; channel goes in A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_chan_ioctrl = $ffe044
chan_ioctrl .namespace
.virtual 1,s
command .word ? ; the number of the command to send
buffer .dword ? ; pointer to bytes of additional data for the command
size .word ? ; the size of the buffer
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_open(short dev, const char * path, short mode);
;
; dev goes in A[15..0]
;
; 6 bytes needed for the stack parameters
;
sys_chan_open = $ffe048
chan_open .namespace
.virtual 1,s
path .dword ? ; a "path" describing how the device is to be open
mode .word ? ; s the device to be read, written, both? (0x01 = READ flag, 0x02 = WRITE flag, 0x03 = READ and WRITE)
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_close(short chan);
;
; chan goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_chan_close = $ffe04c
;
; extern SYSTEMCALL short sys_chan_swap(short channel1, short channel2);
;
; channel1 goes in A[15..0]
;
; 2 bytes needed for the stack parameters
;
sys_chan_swap = $ffe050
chan_swap .namespace
.virtual 1,s
channel2 .word ? ; the ID of the other channel
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_device(short channel);
;
; channel goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_chan_device = $ffe054
;
; extern SYSTEMCALL void sys_text_setsizes(short chan);
;
; chan goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_text_setsizes = $000000
;
; extern SYSTEMCALL short sys_bdev_register(p_dev_block device);
;
; device goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_bdev_register = $ffe05c
;
; extern SYSTEMCALL short sys_bdev_read(short dev, long lba, uint8_t * buffer, short size);
;
; dev goes in A[15..0]
;
; 10 bytes needed for the stack parameters
;
sys_bdev_read = $ffe060
bdev_read .namespace
.virtual 1,s
lba .dword ? ; the logical block address of the block to read
buffer .dword ? ; the buffer into which to copy the block data
size .word ? ; the size of the buffer.
.endv
.endn
;
; extern SYSTEMCALL short sys_bdev_write(short dev, long lba, const uint8_t * buffer, short size);
;
; dev goes in A[15..0]
;
; 10 bytes needed for the stack parameters
;
sys_bdev_write = $ffe064
bdev_write .namespace
.virtual 1,s
lba .dword ? ; the logical block address of the block to write
buffer .dword ? ; the buffer containing the data to write
size .word ? ; the size of the buffer.
.endv
.endn
;
; extern SYSTEMCALL short sys_bdev_status(short dev);
;
; dev goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_bdev_status = $ffe068
;
; extern SYSTEMCALL short sys_bdev_flush(short dev);
;
; dev goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_bdev_flush = $ffe06c
;
; extern SYSTEMCALL short sys_bdev_ioctrl(short dev, short command, uint8_t * buffer, short size);
;
; dev goes in A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_bdev_ioctrl = $ffe070
bdev_ioctrl .namespace
.virtual 1,s
command .word ? ; the number of the command to send
buffer .dword ? ; pointer to bytes of additional data for the command
size .word ? ; the size of the buffer
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_open(const char * path, short mode);
;
; path goes in X[15..0]:A[15..0]
;
; 2 bytes needed for the stack parameters
;
sys_fsys_open = $ffe074
fsys_open .namespace
.virtual 1,s
mode .word ? ; the mode (e.g. r/w/create)
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_close(short fd);
;
; fd goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_fsys_close = $ffe078
;
; extern SYSTEMCALL short sys_fsys_opendir(const char * path);
;
; path goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_fsys_opendir = $ffe07c
;
; extern SYSTEMCALL short sys_fsys_closedir(short dir);
;
; dir goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_fsys_closedir = $ffe080
;
; extern SYSTEMCALL short sys_fsys_readdir(short dir, p_file_info file);
;
; dir goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_fsys_readdir = $ffe084
fsys_readdir .namespace
.virtual 1,s
file .dword ? ; pointer to the t_file_info structure to fill out.
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_findfirst(const char * path, const char * pattern, p_file_info file);
;
; path goes in X[15..0]:A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_fsys_findfirst = $ffe088
fsys_findfirst .namespace
.virtual 1,s
pattern .dword ? ; the file name pattern to search for
file .dword ? ; pointer to the t_file_info structure to fill out
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_findnext(short dir, p_file_info file);
;
; dir goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_fsys_findnext = $ffe08c
fsys_findnext .namespace
.virtual 1,s
file .dword ? ; pointer to the t_file_info structure to fill out
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_get_label(const char * path, char * label);
;
; path goes in X[15..0]:A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_fsys_get_label = $ffe090
fsys_get_label .namespace
.virtual 1,s
label .dword ? ; buffer that will hold the label... should be at least 35 bytes
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_set_label(short drive, const char * label);
;
; drive goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_fsys_set_label = $ffe094
fsys_set_label .namespace
.virtual 1,s
label .dword ? ; buffer that holds the label
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_mkdir(const char * path);
;
; path goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_fsys_mkdir = $ffe098
;
; extern SYSTEMCALL short sys_fsys_delete(const char * path);
;
; path goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_fsys_delete = $ffe09c
;
; extern SYSTEMCALL short sys_fsys_rename(const char * old_path, const char * new_path);
;
; old_path goes in X[15..0]:A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_fsys_rename = $ffe0a0
fsys_rename .namespace
.virtual 1,s
new_path .dword ? ; the new path for the file
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_set_cwd(const char * path);
;
; path goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_fsys_set_cwd = $ffe0a4
;
; extern SYSTEMCALL short sys_fsys_get_cwd(char * path, short size);
;
; path goes in X[15..0]:A[15..0]
;
; 2 bytes needed for the stack parameters
;
sys_fsys_get_cwd = $ffe0a8
fsys_get_cwd .namespace
.virtual 1,s
size .word ? ; the size of the buffer in bytes
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_load(const char * path, uint32_t destination, uint32_t * start);
;
; path goes in X[15..0]:A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_fsys_load = $ffe0ac
fsys_load .namespace
.virtual 1,s
destination .dword ? ; the destination address (0 for use file's address)
start .dword ? ; pointer to the long variable to fill with the starting address
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_register_loader(const char * extension, p_file_loader loader);
;
; extension goes in X[15..0]:A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_fsys_register_loader = $ffe0b0
fsys_register_loader .namespace
.virtual 1,s
loader .dword ? ; pointer to the file load routine to add
.endv
.endn
;
; extern SYSTEMCALL short sys_fsys_stat(const char * path, p_file_info file);
;
; path goes in X[15..0]:A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_fsys_stat = $ffe0b4
fsys_stat .namespace
.virtual 1,s
file .dword ? ; pointer to a file info record to fill in, if the file is found.
.endv
.endn
;
; extern SYSTEMCALL uint32_t sys_mem_get_ramtop();
;
; 0 bytes needed for the stack parameters
;
sys_mem_get_ramtop = $ffe0b8
;
; extern SYSTEMCALL uint32_t sys_mem_reserve(uint32_t bytes);
;
; bytes goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_mem_reserve = $ffe0bc
;
; extern SYSTEMCALL uint32_t sys_time_jiffies();
;
; 0 bytes needed for the stack parameters
;
sys_time_jiffies = $ffe0c0
;
; extern SYSTEMCALL void sys_rtc_set_time(p_time time);
;
; time goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_rtc_set_time = $ffe0c4
;
; extern SYSTEMCALL void sys_rtc_get_time(p_time time);
;
; time goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_rtc_get_time = $ffe0c8
;
; extern SYSTEMCALL uint16_t sys_kbd_scancode();
;
; 0 bytes needed for the stack parameters
;
sys_kbd_scancode = $ffe0cc
;
; extern SYSTEMCALL short sys_kbd_layout(const char * tables);
;
; tables goes in X[15..0]:A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_kbd_layout = $ffe0d4
;
; extern SYSTEMCALL short sys_proc_run(const char * path, int argc, char * argv[]);
;
; path goes in X[15..0]:A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_proc_run = $ffe0d8
proc_run .namespace
.virtual 1,s
argc .dword ? ; the number of arguments passed
argv .dword ? ; the array of string arguments
.endv
.endn
;
; extern SYSTEMCALL short sys_txt_set_mode(short screen, short mode);
;
; screen goes in A[15..0]
;
; 2 bytes needed for the stack parameters
;
sys_txt_set_mode = $ffe0e0
txt_set_mode .namespace
.virtual 1,s
mode .word ? ; a bitfield of desired display mode options
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_set_xy(short screen, short x, short y);
;
; screen goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_txt_set_xy = $ffe0e8
txt_set_xy .namespace
.virtual 1,s
x .word ? ; the column for the cursor
y .word ? ; the row for the cursor
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_get_xy(short screen, p_point position);
;
; screen goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_txt_get_xy = $ffe0ec
txt_get_xy .namespace
.virtual 1,s
position .dword ? ; pointer to a t_point record to fill out
.endv
.endn
;
; extern SYSTEMCALL short sys_txt_get_region(short screen, p_rect region);
;
; screen goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_txt_get_region = $ffe0f0
txt_get_region .namespace
.virtual 1,s
region .dword ? ; pointer to a t_rect describing the rectangular region (using character cells for size and size)
.endv
.endn
;
; extern SYSTEMCALL short sys_txt_set_region(short screen, p_rect region);
;
; screen goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_txt_set_region = $ffe0f4
txt_set_region .namespace
.virtual 1,s
region .dword ? ; pointer to a t_rect describing the rectangular region (using character cells for size and size)
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_set_color(short screen, unsigned char foreground, unsigned char background);
;
; screen goes in A[15..0]
;
; 2 bytes needed for the stack parameters
;
sys_txt_set_color = $ffe0f8
txt_set_color .namespace
.virtual 1,s
foreground .byte ? ; the Text LUT index of the new current foreground color (0 - 15)
background .byte ? ; the Text LUT index of the new current background color (0 - 15)
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_get_color(short screen, unsigned char * foreground, unsigned char * background);
;
; screen goes in A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_txt_get_color = $ffe0fc
txt_get_color .namespace
.virtual 1,s
foreground .dword ? ; the Text LUT index of the new current foreground color (0 - 15)
background .dword ? ; the Text LUT index of the new current background color (0 - 15)
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_set_cursor_visible(short screen, short is_visible);
;
; screen goes in A[15..0]
;
; 2 bytes needed for the stack parameters
;
sys_txt_set_cursor_visible = $ffe100
txt_set_cursor_visible .namespace
.virtual 1,s
is_visible .word ? ; TRUE if the cursor should be visible, FALSE (0) otherwise
.endv
.endn
;
; extern SYSTEMCALL short sys_txt_set_font(short screen, short width, short height, unsigned char * data);
;
; screen goes in A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_txt_set_font = $ffe104
txt_set_font .namespace
.virtual 1,s
width .word ? ; width of a character in pixels
height .word ? ; of a character in pixels
data .dword ? ; pointer to the raw font data to be loaded
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_get_sizes(short screen, p_extent text_size, p_extent pixel_size);
;
; screen goes in A[15..0]
;
; 8 bytes needed for the stack parameters
;
sys_txt_get_sizes = $ffe108
txt_get_sizes .namespace
.virtual 1,s
text_size .dword ? ; the size of the screen in visible characters (may be null)
pixel_size .dword ? ; the size of the screen in pixels (may be null)
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_set_border(short screen, short width, short height);
;
; screen goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_txt_set_border = $ffe10c
txt_set_border .namespace
.virtual 1,s
width .word ? ; the horizontal size of one side of the border (0 - 32 pixels)
height .word ? ; the vertical size of one side of the border (0 - 32 pixels)
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_set_border_color(short screen, unsigned char red, unsigned char green, unsigned char blue);
;
; screen goes in A[15..0]
;
; 3 bytes needed for the stack parameters
;
sys_txt_set_border_color = $ffe110
txt_set_border_color .namespace
.virtual 1,s
red .byte ? ; the red component of the color (0 - 255)
green .byte ? ; the green component of the color (0 - 255)
blue .byte ? ; the blue component of the color (0 - 255)
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_put(short screen, char c);
;
; screen goes in A[15..0]
;
; 1 bytes needed for the stack parameters
;
sys_txt_put = $ffe114
txt_put .namespace
.virtual 1,s
c .byte ? ; the character to print
.endv
.endn
;
; extern SYSTEMCALL void sys_txt_print(short screen, const char * message);
;
; screen goes in A[15..0]
;
; 4 bytes needed for the stack parameters
;
sys_txt_print = $ffe118
txt_print .namespace
.virtual 1,s
message .dword ? ; the ASCII Z string to print
.endv
.endn

View file

@ -1,285 +0,0 @@
#
# Create the 64tass parameters structures for the Toolbox functions
#
import re
import sys
class FunctionParameter:
def __init__(self):
self._name = "UNKNOWN"
self._position = 0
self._type = ""
self._description = ""
def set_name(self, name):
if name.endswith("[]"):
name = name[0:-2]
self._name = name
def name(self):
return self._name
def set_position(self, position):
self._position = position
def position(self):
return self._position
def set_type(self, type):
self._type = type
def type(self):
return self._type
def set_description(self, description):
self._description = description
def description(self):
return self._description
def print(self):
"""Print a simple version of a parameter"""
print("\tName: {0}, Type: {1}, Comment: {2}".format(self._name, self._type, self._description))
def size(self):
"""Return the size of the parameter in bytes."""
if self.type() == "char" or self.type() == "unsigned char" or self.type() == "uint8_t":
return 1
elif self.type() == "short" or self.type() == "unsigned short" or self.type() == "uint16_t":
return 2
else:
return 4
def emit_asm(self, output):
"""Emit the assembly reference for the parameter."""
size = self.size()
if size == 1:
output.write("{0:<16}.byte ? ; {1}\n".format(self.name(), self.description()))
elif size == 2:
output.write("{0:<16}.word ? ; {1}\n".format(self.name(), self.description()))
else:
output.write("{0:<16}.dword ? ; {1}\n".format(self.name(), self.description()))
def emit_accumulator(self, output):
size = self.size()
if size == 1:
output.write("; {0} goes in A[7..0]\n".format(self.name()))
elif size == 2:
output.write("; {0} goes in A[15..0]\n".format(self.name()))
else:
output.write("; {0} goes in X[15..0]:A[15..0]\n".format(self.name()))
class Function:
def __init__(self):
self._name = "UNKNOWN"
self._brief = ""
self._description = ""
self._type = "void"
self._parameters = []
self._address = 0
self._prototype = ""
def set_name(self, name):
self._name = name
def name(self):
return self._name
def set_prototype(self, prototype):
self._prototype = prototype
def prototype(self):
return self._prototype
def set_brief(self, brief):
self._brief = brief
def brief(self):
return self._brief
def set_description(self, description):
self._description = description
def description(self):
return self._description
def set_type(self, type):
self._type = type
def type(self):
return self._type
def set_address(self, address):
self._address = address
def address(self):
return self._address
def add_parameter(self, param_name, param_type):
"""Add a parameter to the function."""
param = FunctionParameter()
param.set_name(param_name)
param.set_type(param_type)
param.set_position(len(self._parameters))
self._parameters.append(param)
def parameters(self):
return self._parameters
def stack_size(self):
"""Return the number of bytes needed on the stack for the parameters"""
size = 0
if len(self.parameters()) > 1:
for parameter in self.parameters()[1:]:
size = size + parameter.size()
return size
def add_param_comment(self, param_name, param_comment):
"""Add a comment to a parameter"""
for param in self._parameters:
if param._name == param_name:
param.set_description(param_comment)
break
def print(self):
"""Print out a simple description of the function"""
print("Name: {0}, Type: {1}".format(self._name, self._type))
print(self._description)
for parameter in self._parameters:
parameter.print()
print()
def emit_asm(self, output):
"""Emit the assembly reference for the function."""
output.write("\n;\n; {0}\n".format(self.prototype()))
if len(self.parameters()) > 0:
first = self.parameters()[0]
output.write("; \n")
first.emit_accumulator(output)
output.write(";\n")
output.write("; {0} bytes needed for the stack parameters\n;\n".format(self.stack_size()))
output.write("{0} = ${1:06x}\n\n".format(self.name(), self.address()))
if len(self.parameters()) > 1:
m = re.match("sys_(\w+)", self.name())
if m:
short_name = m.group(1)
else:
short_name = self.name()
stack_parameters = self.parameters()[1:]
output.write("{0:<16} .namespace\n".format(short_name))
output.write(" .virtual 1,s\n")
for parameter in stack_parameters:
parameter.emit_asm(output)
output.write(" .endv\n")
output.write(" .endn\n")
comments = []
functions = []
def process_comment(line):
"""Deal with a comment line while we're in the middle of a block comment."""
index = line.index("*")
if index > -1:
comment_line = line[index+1:].strip()
else:
comment_line = line.strip()
if comment_line != "":
comments.append(comment_line)
def process_definition(type, name, parameters, comments, prototype):
"""Deal with a function prototype."""
func = Function()
func.set_name(name)
func.set_type(type)
func.set_prototype(prototype)
is_in_func_comments = True
for param in func_parameters:
m1 = re.match("^\s*(.*)\s(\S+)\s*$", param)
if m1:
param_type = m1.group(1).strip()
param_name = m1.group(2).strip()
func.add_parameter(param_name, param_type)
for comment in comments:
m2 = re.match("@param\s(\w+)\s+(.*)$", comment)
if m2:
param_name = m2.group(1).strip()
param_comment = m2.group(2).strip()
func.add_param_comment(param_name, param_comment)
else:
func._description = func._description + comment
functions.append(func)
#
# Read in the C header file with the extern prototypes and parse all the function names,
# return values, and parameters
#
with open(sys.argv[1], "r") as input:
is_in_comment = False
for line in input.readlines():
line = line.strip()
if line.startswith("/**"):
is_in_comments = True
comments = []
elif line.endswith("*/"):
is_in_comments = False
if is_in_comments and line.startswith("*"):
process_comment(line)
else:
m = re.match("extern\s+SYSTEMCALL\s+(\w+)\s+(\w+)\((.*)\)", line)
if m:
func_type = m.group(1)
func_name = m.group(2)
func_parameters = str.split(m.group(3), ",")
process_definition(func_type, func_name, func_parameters, comments, line)
#
# Read in the Caylpsi Toolbox jumptable assembly file and extract the addresses
#
with open(sys.argv[2], "r") as addresses:
for line in addresses.readlines():
m = re.match("^(\w+):\s+.equlab\s+0x([0-9a-fA-F]+)", line)
if m:
func_name = m.group(1).strip()
func_address = int(m.group(2), 16)
print("Name: {0}, Address: {1}".format(func_name, func_address))
for func in functions:
if func.name() == func_name:
func.set_address(func_address)
break
#
# Create the bindings file with the relevant information
#
with open("bindings.s", "w") as bindings:
for func in functions:
func.emit_asm(bindings)

View file

@ -1,57 +0,0 @@
;;;
;;; A simple client program for the Foenix Toolbox using 64TASS
;;;
.cpu "65816"
.include "toolbox.s"
setdbr .macro ; Set the B (Data bank) register
pea #((\1) * 256) + (\1)
plb
plb
.databank \1
.endm
setaxl .macro
rep #$30 ; set A&X long
.al
.xl
.endm
* = $10000
header: .byte $f8, $16 ; Signature
.byte 0 ; Version
.dword start ; Starting address
.dword 0 ; Icon address
.dword 0 ; Icon palette address
.null "hello" ; Name of the file
start: clc
xce
setdbr `start
setaxl
alloc 6 ; Set aside parameter space for sys_chan_write
lda #33 ; Size of the message
sta tb.chan_write.size
lda #`message ; Pointer to the message
sta tb.chan_write.buffer+2
lda #<>message
sta tb.chan_write.buffer
lda #0 ; Channel #0
jsl sys_chan_write ; sys_chan_write(0, message, strlen(message))
free 6 ; Reclaim parameter space from sys_chan_write
loop: nop
bra loop
message: .null "Hello, Foenix Toolbox (64TASS)!",13,10

View file

@ -1,69 +0,0 @@
;;;
;;; Definitions to connect a 64TASS assembly program to the Foenix Toolbox
;;;
.include "bindings.s"
;
; Allocate space on the stack for parameters (count = number of bytes)
;
; Affects: A
;
alloc .macro count
.switch \count
.case 2
pea #0
.case 4
pea #0
pea #0
.case 6
pea #0
pea #0
pea #0
.default
sta #0,d
tsc
sec
sbc #(\count)
tcs
lda #0,d
.endswitch
.endm
;
; Remove space from the stack previously used for parameters (count = number of bytes)
;
; Affects: Y, #0,D, #1,D
;
free .macro count
.switch \count
.case 2
ply
.case 4
ply
ply
.case 6
ply
ply
ply
.default
sta #0,d
tsc
clc
adc #(\count)
tcs
lda #0,d
.endswitch
.endm

View file

@ -1,100 +0,0 @@
;;;
;;; Types used by the Foenix Toolbox functions
;;;
tb .namespace
;
; An extent or size of a rectangular area
;
s_extent .struct
width .word ? ; The width of the region
height .word ? ; The height of the region
.ends
;
; A point on a plane
;
s_point .struct
x .word ? ; The column of the point
y .word ? ; The row of the point
.ends
;
; A rectangle on the screen
;
s_rect .struct
origin .dstruct s_point ; The upper-left corner of the rectangle
size .dstruct s_extent ; The size of the rectangle
.ends
;
; A color (BGR)
;
s_color3 .struct
blue .byte ?
green .byte ?
red .byte ?
.ends
;
; A color entry for a color lookup table (BGRA)
;
s_color4 .struct
blue .byte ?
green .byte ?
red .byte ?
alpha .byte ?
.ends
;
; Type to describe the current time
;
s_time .struct
year .word ?
month .word ?
day .word ?
hour .word ?
minute .word ?
second .word ?
is_pm .word ?
is_24hours .word ?
.ends
;
; A description of a screen's capabilities
;
s_txt_capabilities .struct
number .word ? ; The unique ID of the screen
supported_modes .word ? ; The display modes supported on this screen
font_size_count .word ? ; The number of supported font sizes
font_sizes .dword ? ; Pointer to a list of t_extent listing all supported font sizes
resolution_count .word ? ; The number of supported display resolutions
resolutions .dword ? ; Pointer to a list of t_extent listing all supported display resolutions (in pixels)
.ends
;
; Structure to describe the hardware
;
s_sys_info .struct
mcp_version .word ? ; Current version of the MCP kernel
mcp_rev .word ? ; Current revision, or sub-version of the MCP kernel
mcp_build .word ? ; Current vuild # of the MCP kernel
model .word ? ; Code to say what model of machine this is
sub_model .word ? ; 0x00 = PB, 0x01 = LB, 0x02 = CUBE
model_name .dword ? ; Human readable name of the model of the computer
cpu .word ? ; Code to say which CPU is running
cpu_name .dword ? ; Human readable name for the CPU
cpu_clock_khz .dword ? ; Speed of the CPU clock in KHz
fpga_date .dword ? ; YYYYMMDD
fpga_model .word ? ; FPGA model number
fpga_version .word ? ; FPGA version
fpga_subver .word ? ; FPGA sub-version
system_ram_size .dword ? ; The number of bytes of system RAM on the board
has_floppy .byte ? ; TRUE if the board has a floppy drive installed
has_hard_drive .byte ? ; TRUE if the board has a PATA device installed
has_expansion_card .byte ? ; TRUE if an expansion card is installed on the device
has_ethernet .byte ? ; TRUE if an ethernet port is present
screens .word ? ; How many screens are on this computer
.endn

View file

@ -1,68 +0,0 @@
# VPATH=.:../../module/Calypsi-remote-debug/src
DEBUGGER=../module/Calypsi-remote-debug/src
UNIT := F256K
MEMORY := RAM
# Define OS-dependent variables
ifeq ($(OS),Windows_NT)
RM = del /F/Q
else
RM = rm -f
endif
# Define model-specific variables, including tools, source files, compiler flags, etc.
ifeq ($(UNIT),F256K)
CPU=w65816
C_SRCS_DEBUGGER=$(DEBUGGER)/agent.c $(DEBUGGER)/c256-uart.c $(DEBUGGER)/low_level_WDC65816.s
SRCS_FOR_UNIT=
CFLAGS_FOR_UNIT=-DMODEL=17 -DCPU=255 --code-model large --data-model large
ifeq ($(MEMORY),ROM)
LDFLAGS_FOR_UNIT=C256/f256-flash.scm clib-lc-ld.a --rtattr printf=medium
else
LDFLAGS_FOR_UNIT=C256/f256-ld_lc.scm clib-lc-ld.a --rtattr printf=medium
endif
endif
ifeq ($(CPU),w65816)
CC=cc65816
AS=as65816
LD=ln65816
AR=nlib
endif
INCLUDES=-I. -I./include
CFLAGS=$(INCLUDES) $(CFLAGS_FOR_UNIT) -l # -l -D_CALYPSI_MCP_DEBUGGER
ASFLAGS=$(INCLUDES) --data-model large --code-model large
ifeq ($(MEMORY),ROM)
LDFLAGS=--rom-code $(LDFLAGS_FOR_UNIT) --list-file toolbox.map
else
LDFLAGS=$(LDFLAGS_FOR_UNIT) --list-file toolbox.map
endif
SRCS = stubs.c bindings.s $(SRCS_FOR_UNIT) # $(C_SRCS_DEBUGGER)
OBJS = $(patsubst %.s,%.o,$(patsubst %.c,%.o,$(SRCS)))
OBJS4RM = $(subst /,\\,$(OBJS))
LIBS =
.PHONY: clean
toolbox.a: $(OBJS)
$(AR) toolbox.a $(OBJS)
# Build the object files from C
%.o: %.c
$(CC) $(CFLAGS) -o $@ $^
# Build the object files from assembly
%.o: %.s
$(AS) $(ASFLAGS) -o $@ $^
# Clean up after a build
clean:
$(RM) $(OBJS4RM) *.o *.a *.lst

View file

@ -1,147 +0,0 @@
;;;
;;; Bindings for the Foenix Toolbox public calls
;;;
.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
.public sys_chan_write_b
.public sys_chan_write
.public sys_chan_status
.public sys_chan_flush
.public sys_chan_seek
.public sys_chan_ioctrl
.public sys_chan_open
.public sys_chan_close
.public sys_chan_swap
.public sys_chan_device
.public sys_chan_register
.public sys_bdev_register
.public sys_bdev_read
.public sys_bdev_write
.public sys_bdev_status
.public sys_bdev_flush
.public sys_bdev_ioctrl
.public sys_fsys_open
.public sys_fsys_close
.public sys_fsys_opendir
.public sys_fsys_closedir
.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
.public sys_fsys_set_cwd
.public sys_fsys_get_cwd
.public sys_fsys_load
.public sys_fsys_register_loader
.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_txt_get_capabilities
.public sys_txt_set_mode
.public sys_txt_setsizes
.public sys_txt_set_xy
.public sys_txt_get_xy
.public sys_txt_get_region
.public sys_txt_set_region
.public sys_txt_set_color
.public sys_txt_get_color
.public sys_txt_set_cursor_visible
.public sys_txt_set_font
.public sys_txt_get_sizes
.public sys_txt_set_border
.public sys_txt_set_border_color
.public sys_txt_put
.public sys_txt_print
sys_proc_exit: .equlab 0xFFE000
sys_int_enable_all: .equlab 0xFFE004
sys_int_disable_all: .equlab 0xFFE008
sys_int_disable: .equlab 0xFFE00C
sys_int_enable: .equlab 0xFFE010
sys_int_register: .equlab 0xFFE014
sys_int_pending: .equlab 0xFFE018
sys_get_info: .equlab 0xFFE01C
sys_int_clear: .equlab 0xFFE020
sys_chan_read_b: .equlab 0xFFE024
sys_chan_read: .equlab 0xFFE028
sys_chan_readline: .equlab 0xFFE02C
sys_chan_write_b: .equlab 0xFFE030
sys_chan_write: .equlab 0xFFE034
sys_chan_status: .equlab 0xFFE038
sys_chan_flush: .equlab 0xFFE03C
sys_chan_seek: .equlab 0xFFE040
sys_chan_ioctrl: .equlab 0xFFE044
sys_chan_open: .equlab 0xFFE048
sys_chan_close: .equlab 0xFFE04C
sys_chan_swap: .equlab 0xFFE050
sys_chan_device: .equlab 0xFFE054
sys_chan_register: .equlab 0xFFE058
sys_bdev_register: .equlab 0xFFE05C
sys_bdev_read: .equlab 0xFFE060
sys_bdev_write: .equlab 0xFFE064
sys_bdev_status: .equlab 0xFFE068
sys_bdev_flush: .equlab 0xFFE06C
sys_bdev_ioctrl: .equlab 0xFFE070
sys_fsys_open: .equlab 0xFFE074
sys_fsys_close: .equlab 0xFFE078
sys_fsys_opendir: .equlab 0xFFE07C
sys_fsys_closedir: .equlab 0xFFE080
sys_fsys_readdir: .equlab 0xFFE084
sys_fsys_findfirst: .equlab 0xFFE088
sys_fsys_findnext: .equlab 0xFFE08C
sys_fsys_get_label: .equlab 0xFFE090
sys_fsys_set_label: .equlab 0xFFE094
sys_fsys_mkdir: .equlab 0xFFE098
sys_fsys_delete: .equlab 0xFFE09C
sys_fsys_rename: .equlab 0xFFE0A0
sys_fsys_set_cwd: .equlab 0xFFE0A4
sys_fsys_get_cwd: .equlab 0xFFE0A8
sys_fsys_load: .equlab 0xFFE0AC
sys_fsys_register_loader: .equlab 0xFFE0B0
sys_fsys_stat: .equlab 0xFFE0B4
sys_mem_get_ramtop: .equlab 0xFFE0B8
sys_mem_reserve: .equlab 0xFFE0BC
sys_time_jiffies: .equlab 0xFFE0C0
sys_rtc_set_time: .equlab 0xFFE0C4
sys_rtc_get_time: .equlab 0xFFE0C8
sys_kbd_scancode: .equlab 0xFFE0CC
sys_err_message: .equlab 0xFFE0D0
sys_kbd_layout: .equlab 0xFFE0D4
sys_proc_run: .equlab 0xFFE0D8
sys_txt_get_capabilities: .equlab 0xFFE0DC
sys_txt_set_mode: .equlab 0xFFE0E0
sys_txt_setsizes: .equlab 0xFFE0E4
sys_txt_set_xy: .equlab 0xFFE0E8
sys_txt_get_xy: .equlab 0xFFE0EC
sys_txt_get_region: .equlab 0xFFE0F0
sys_txt_set_region: .equlab 0xFFE0F4
sys_txt_set_color: .equlab 0xFFE0F8
sys_txt_get_color: .equlab 0xFFE0FC
sys_txt_set_cursor_visible: .equlab 0xFFE100
sys_txt_set_font: .equlab 0xFFE104
sys_txt_get_sizes: .equlab 0xFFE108
sys_txt_set_border: .equlab 0xFFE10C
sys_txt_set_border_color: .equlab 0xFFE110
sys_txt_put: .equlab 0xFFE114
sys_txt_print: .equlab 0xFFE118

View file

@ -1,38 +0,0 @@
###
### Generate client bindings for the Toolbox
###
# with open("toolbox_bindings.s", "w") as output:
table_entry_size = 4
table_address = 0xffe000
syscalls = {}
with open("..\..\src\C256\syscalls.txt", "r") as input:
for line in input:
# Remove comments
index = line.find("#")
if index == 0:
line = ""
elif index > 0:
line = line[index - 1:]
line = line.strip()
if line != "":
name = "sys_{}".format(line)
syscalls[name] = table_address
table_address += table_entry_size
with open("bindings.s", "w") as output:
output.write(";;;\n;;; Bindings for the Foenix Toolbox public calls\n;;;\n\n")
for name in syscalls.keys():
output.write("\t.public {}\n".format(name))
output.write("\n")
for name in syscalls.keys():
address = syscalls[name]
output.write("{0:<30} .equlab 0x{1:06X}\n".format(name + ":", address))

View file

@ -1,79 +0,0 @@
/**
* @file constants.h
* @brief Define the major public-facing constants for the Foenix Toolbox
* @version 0.1
* @date 2024-09-02
*
* @copyright Copyright (c) 2024
*
*/
#ifndef __CONSTANTS_H
#define __CONSTANTS_H
/*
* Miscellaneous definitions
*/
#define FSYS_SECTOR_SZ 512 /* Size of a sector */
#define MAX_PATH_LEN 256 /* Maximum length of a file path */
/*
* Definitions of special characters
*/
#define CHAR_ESC '\x1B' /* Escape character */
#define CHAR_TAB '\t' /* Vertical tab */
#define CHAR_CR '\x0D' /* Carriage return */
#define CHAR_NL '\x0A' /* Linefeed */
#define CHAR_BS '\b' /* Backspace */
/*
* File access mode and open method flags
*/
#define FSYS_READ 0x01
#define FSYS_WRITE 0x02
#define FSYS_OPEN_EXISTING 0x00
#define FSYS_CREATE_NEW 0x04
#define FSYS_CREATE_ALWAYS 0x08
#define FSYS_OPEN_ALWAYS 0x10
#define FSYS_OPEN_APPEND 0x30
/*
* File attribute bits for directory entry
*/
#define FSYS_AM_RDO 0x01 /* Read only */
#define FSYS_AM_HID 0x02 /* Hidden */
#define FSYS_AM_SYS 0x04 /* System */
#define FSYS_AM_DIR 0x10 /* Directory */
#define FSYS_AM_ARC 0x20 /* Archive */
/*
* Block devices
*/
#define BDEV_SD0 0 /* External SDC */
#define BDEV_SD1 1 /* Internal SDC */
/*
* Channel devices
*/
#define CDEV_CONSOLE 0
#define CDEV_EVID 1
#define CDEV_COM1 2
#define CDEV_COM2 3
#define CDEV_LPT 4
#define CDEV_MIDI 5
#define CDEV_FILE 6
/*
* Block Device IOCRTRL commands
*/
#define IOCTRL_CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
#define IOCTRL_GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
#define IOCTRL_GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
#define IOCTRL_GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
#endif

View file

@ -1,60 +0,0 @@
/**
* @file errors.h
* @brief Error codes returned by Foenix Toolbox calls
* @version 0.1
* @date 2024-09-02
*
* @copyright Copyright (c) 2024
*
*/
#ifndef __ERRORS_H
#define __ERRORS_H
// #define MAX_ERROR_NUMBER 16 // Largest (absolute value) of the error number
#define E_OK 0 // Success, no error
#define ERR_GENERAL -1 // A general error condition
#define DEV_ERR_BADDEV -2 // Device number is bad (too big or no device assigned)
#define DEV_TIMEOUT -3 // The block device function timed out
#define DEV_CANNOT_INIT -4 // The block device could not initilize
#define DEV_CANNOT_READ -5 // The device cannot complete the READ
#define DEV_CANNOT_WRITE -6 // The device cannot complete the WRITE
#define DEV_BOUNDS_ERR -7 // The buffer provided is not big enough
#define DEV_NOMEDIA -8 // There is no media present for that device
#define DEV_WRITEPROT -9 // The media is write protected
#define ERR_BADCHANNEL -10 // The channel number was bad
#define ERR_OUT_OF_HANDLES -11 // There are no available handles for channels files etc.
#define ERR_BAD_HANDLE -12 // The handle passed was not valid
#define ERR_BAD_EXTENSION -13 // The path to load did not have an extension that matched registered loaders
#define ERR_OUT_OF_MEMORY -14 // Unable to allocate more memory
#define ERR_BAD_BINARY -15 // Bad binary file format... i.e. binary format does not match expectations
#define ERR_NOT_EXECUTABLE -16 // Binary file format does not have a starting address
#define ERR_NOT_FOUND -17 // Resource not found
#define FSYS_ERR_DISK_ERR -18 /* (1) A hard error occurred in the low level disk I/O layer */
#define FSYS_ERR_INT_ERR -19 /* (2) Assertion failed */
#define FSYS_ERR_NOT_READY -20 /* (3) The physical drive cannot work */
#define FSYS_ERR_NO_FILE -21 /* (4) Could not find the file */
#define FSYS_ERR_NO_PATH -22 /* (5) Could not find the path */
#define FSYS_ERR_INVALID_NAME -23 /* (6) The path name format is invalid */
#define FSYS_ERR_DENIED -24 /* (7) Access denied due to prohibited access or directory full */
#define FSYS_ERR_EXIST -25 /* (8) Access denied due to prohibited access */
#define FSYS_ERR_INVALID_OBJECT -26 /* (9) The file/directory object is invalid */
#define FSYS_ERR_WRITE_PROTECTED -27 /* (10) The physical drive is write protected */
#define FSYS_ERR_INVALID_DRIVE -28 /* (11) The logical drive number is invalid */
#define FSYS_ERR_NOT_ENABLED -29 /* (12) The volume has no work area */
#define FSYS_ERR_NO_FILESYSTEM -30 /* (13) There is no valid FAT volume */
#define FSYS_ERR_MKFS_ABORTED -31 /* (14) The f_mkfs() aborted due to any problem */
#define FSYS_ERR_TIMEOUT -32 /* (15) Could not get a grant to access the volume within defined period */
#define FSYS_ERR_LOCKED -33 /* (16) The operation is rejected according to the file sharing policy */
#define FSYS_ERR_NOT_ENOUGH_CORE -34 /* (17) LFN working buffer could not be allocated */
#define FSYS_ERR_TOO_MANY_OPEN_FILES -35 /* (18) Number of open files > FF_FS_LOCK */
#define FSYS_ERR_INVALID_PARAMETER -36 /* (19) Given parameter is invalid */
#define ERR_NOT_SUPPORTED -37 /* Device does not support the file or operation */
#define ERR_BAD_ARGUMENT -38 /* An invalid argument was provided */
#define ERR_MEDIA_CHANGE -39 /* Removable media has changed */
#define ERR_NOT_READY -40 /* Media device is not ready */
#endif

View file

@ -1,28 +0,0 @@
/**
* @file sys_macros.h
* @brief Macros needed for the Foenix Toolbox
* @version 0.1
* @date 2024-09-02
*
* @copyright Copyright (c) 2024
*
*/
#ifndef _sys_macros_h_
#define _sys_macros_h_
/*
* Define the machine-specific system call function prefix
*/
#ifdef __CALYPSI_CORE_65816__
//
// System calls on the 65816 pass parameters primarily on stack using the Calypsi
// simple call convention and save/restore the direct page and data bank registers.
//
#define SYSTEMCALL __attribute__((simple_call)) __attribute__((saveds))
#else
#define SYSTEMCALL
#endif
#endif

View file

@ -1,163 +0,0 @@
/**
* @file sys_types.h
* @brief Public-facing ypes used by the Foenix Toolbox
* @version 0.1
* @date 2024-09-02
*
* @copyright Copyright (c) 2024
*
*/
#ifndef _sys_types_h_
#define _sys_types_h_
#include <stdbool.h>
#include <stdint.h>
#include "constants.h"
/**
* @struct s_extent
*
* An extent or size of a rectangular area
*/
typedef struct s_extent {
short width; /**< The width of the region */
short height; /**< The height of the region */
} t_extent, *p_extent;
/**
* @struct s_point
*
* A point on a plane
*/
typedef struct s_point {
short x; /**< The column of the point */
short y; /**< The row of the point */
} t_point, *p_point;
/**
* @struct s_rect
*
* A rectangle on the screen
*/
typedef struct s_rect {
t_point origin; /**< The upper-left corner of the rectangle */
t_extent size; /**< The size of the rectangle */
} t_rect, *p_rect;
//
// A color (BGR)
//
typedef struct s_color3 {
uint8_t blue;
uint8_t green;
uint8_t red;
} t_color3;
//
// A color entry for a color lookup table (BGRA)
//
typedef struct s_color4 {
uint8_t blue;
uint8_t green;
uint8_t red;
uint8_t alpha;
} t_color4;
/*
* Type declaration for an interrupt handler
*/
typedef void (*p_int_handler)();
/*
* Structure to describe the hardware
*/
typedef struct s_sys_info {
uint16_t mcp_version; /* Current version of the MCP kernel */
uint16_t mcp_rev; /* Current revision, or sub-version of the MCP kernel */
uint16_t mcp_build; /* Current vuild # of the MCP kernel */
uint16_t model; /* Code to say what model of machine this is */
uint16_t sub_model; /* 0x00 = PB, 0x01 = LB, 0x02 = CUBE */
const char * model_name; /* Human readable name of the model of the computer */
uint16_t cpu; /* Code to say which CPU is running */
const char * cpu_name; /* Human readable name for the CPU */
uint32_t cpu_clock_khz; /* Speed of the CPU clock in KHz */
unsigned long fpga_date; /* YYYYMMDD */
uint16_t fpga_model; /* FPGA model number */
uint16_t fpga_version; /* FPGA version */
uint16_t fpga_subver; /* FPGA sub-version */
uint32_t system_ram_size; /* The number of bytes of system RAM on the board */
bool has_floppy; /* TRUE if the board has a floppy drive installed */
bool has_hard_drive; /* TRUE if the board has a PATA device installed */
bool has_expansion_card; /* TRUE if an expansion card is installed on the device */
bool has_ethernet; /* TRUE if an ethernet port is present */
uint16_t screens; /* How many screens are on this computer */
} t_sys_info, *p_sys_info;
/*
* Structure defining a block device's functions
*/
typedef struct s_dev_block {
short number; // The number of the device (assigned by registration)
char * name; // The name of the device
void * data; // Device-specific data block
short (*init)(struct s_dev_block *); // Initialize the device
short (*read)(struct s_dev_block *, long lba, uint8_t * buffer, short size); // Read a block from the device
short (*write)(struct s_dev_block *, long lba, const uint8_t * buffer, short size); // Write a block to the device
short (*status)(struct s_dev_block *); // Get the status of the device
short (*flush)(struct s_dev_block *); // Ensure that any pending writes to the device have been completed
short (*ioctrl)(struct s_dev_block *, short command, unsigned char * buffer, short size); // Issue a control command to the device
} t_dev_block, *p_dev_block;
/*
* Type for directory information about a file
*/
typedef struct s_file_info {
long size;
unsigned short date;
unsigned short time;
unsigned char attributes;
char name[MAX_PATH_LEN];
} t_file_info, * p_file_info;
/*
* Pointer type for file loaders
*
* short loader(short chan, destination, start);
*/
typedef short (*p_file_loader)(short chan, long destination, long * start);
/*
* Type to describe the current time
*/
typedef struct s_time {
short year;
short month;
short day;
short hour;
short minute;
short second;
short is_pm;
short is_24hours;
} t_time, *p_time;
/*
* A description of a screen's capabilities
*/
typedef struct s_txt_capabilities {
short number; /**< The unique ID of the screen */
short supported_modes; /**< The display modes supported on this screen */
short font_size_count; /**< The number of supported font sizes */
p_extent font_sizes; /**< Pointer to a list of t_extent listing all supported font sizes */
short resolution_count; /**< The number of supported display resolutions */
p_extent resolutions; /**< Pointer to a list of t_extent listing all supported display resolutions (in pixels) */
} t_txt_capabilities, *p_txt_capabilities;
#endif

View file

@ -1,722 +0,0 @@
/**
* @file toolbox.h
* @brief Public-facing calls for the Foenix Toolbox
* @version 0.1
* @date 2024-09-02
*
* @copyright Copyright (c) 2024
*
*/
#ifndef __toolbox_h__
#define __toolbox_h__
#include <stdbool.h>
#include <stdint.h>
#include "constants.h"
#include "sys_macros.h"
#include "sys_types.h"
/**
* Quit the current user process
*
* NOTE: at the moment, this relaunches the CLI. In the future, this
* may cause execution to return to the program that started
* the user process.
*
* @param result the code to return to the kernel
*/
extern SYSTEMCALL void sys_proc_exit(short result);
/**
* Enable all interrupts
*/
extern SYSTEMCALL void sys_int_enable_all();
/**
* Disable all interrupts
*/
extern SYSTEMCALL void sys_int_disable_all();
/**
* Disable an interrupt by masking it
*
* @param n the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
extern SYSTEMCALL void sys_int_disable(unsigned short n);
/**
* Enable an interrupt
*
* @param n the number of the interrupt
*/
extern SYSTEMCALL void sys_int_enable(unsigned short n);
/**
* Register a handler for a given interrupt.
*
* @param n the number of the interrupt
* @param handler pointer to the interrupt handler to register
*
* @return the pointer to the previous interrupt handler
*/
extern SYSTEMCALL p_int_handler sys_int_register(unsigned short n, p_int_handler handler);
/**
* Return true (non-zero) if an interrupt is pending for the given interrupt
*
* @param n the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*
* @return non-zero if interrupt n is pending, 0 if not
*/
extern SYSTEMCALL short sys_int_pending(unsigned short n);
/**
* Fill out a s_sys_info structure with the information about the current system
*
* @param info pointer to a s_sys_info structure to fill out
*/
extern SYSTEMCALL void sys_get_info(p_sys_info info);
/**
* Acknowledge an interrupt (clear out its pending flag)
*
* @param n the number of the interrupt: n[7..4] = group number, n[3..0] = individual number.
*/
extern SYSTEMCALL void sys_int_clear(unsigned short n);
/***
*** Channel system calls
***/
/**
* Read a single byte from the channel
*
* @param channel the number of the channel
*
* @return the value read (if negative, error)
*/
extern SYSTEMCALL short sys_chan_read_b(short channel);
/**
* Read bytes from the channel
*
* @param channel the number of the channel
* @param buffer the buffer into which to copy the channel data
* @param size the size of the buffer.
*
* @return number of bytes read, any negative number is an error code
*/
extern SYSTEMCALL short sys_chan_read(short channel, unsigned char * buffer, short size);
/**
* Read a line of text from the channel
*
* @param channel the number of the channel
* @param buffer the buffer into which to copy the channel data
* @param size the size of the buffer
*
* @return number of bytes read, any negative number is an error code
*/
extern SYSTEMCALL short sys_chan_readline(short channel, unsigned char * buffer, short size);
/**
* Write a single byte to the device
*
* @param channel the number of the channel
* @param b the byte to write
*
* @return 0 on success, a negative value on error
*/
extern SYSTEMCALL short sys_chan_write_b(short channel, uint8_t b);
/**
* Write a byte to the channel
*
* @param channel the number of the channel
* @param b the byte to write
*
* @return number of bytes written, any negative number is an error code
*/
extern SYSTEMCALL short sys_chan_write(short channel, const uint8_t * buffer, short size);
/**
* Return the status of the channel device
*
* @param channel the number of the channel
*
* @return the status of the device
*/
extern SYSTEMCALL short sys_chan_status(short channel);
/**
* Ensure that any pending writes to teh device have been completed
*
* @param channel the number of the channel
*
* @return 0 on success, any negative number is an error code
*/
extern SYSTEMCALL short sys_chan_flush(short channel);
/**
* Attempt to set the position of the channel cursor (if supported)
*
* @param channel the number of the channel
* @param position the position of the cursor
* @param base whether the position is absolute or relative to the current position
*
* @return 0 = success, a negative number is an error.
*/
extern SYSTEMCALL short sys_chan_seek(short channel, long position, short base);
/**
* Issue a control command to the device
*
* @param channel the number of the channel
* @param command the number of the command to send
* @param buffer pointer to bytes of additional data for the command
* @param size the size of the buffer
*
* @return 0 on success, any negative number is an error code
*/
extern SYSTEMCALL short sys_chan_ioctrl(short channel, short command, uint8_t * buffer, short size);
/**
* Open a channel
*
* @param dev the device number to have a channel opened
* @param path a "path" describing how the device is to be open
* @param mode s the device to be read, written, both? (0x01 = READ flag, 0x02 = WRITE flag, 0x03 = READ and WRITE)
*
* @return the number of the channel opened, negative number on error
*/
extern SYSTEMCALL short sys_chan_open(short dev, const char * path, short mode);
/**
* Close a channel
*
* @param chan the number of the channel to close
*
* @return nothing useful
*/
extern SYSTEMCALL short sys_chan_close(short chan);
/**
* Swap the channel ID assignments for two channels
*
* Before call: channel1 = "Channel A", channel2 = "Channel B"
* After call: channel1 = "Channel B", channel2 = "Channel A"
*
* @param channel1 the ID of one of the channels
* @param channel2 the ID of the other channel
* @return 0 on success, any other number is an error
*/
extern SYSTEMCALL short sys_chan_swap(short channel1, short channel2);
/**
* Return the device associated with the channel
*
* @param channel the ID of the channel to query
* @return the ID of the device associated with the channel, negative number for error
*/
extern SYSTEMCALL short sys_chan_device(short channel);
/**
* Compute the size information for the text screen based on the current settings in VICKY
* These settings are needed to correctly position text on the screen.
*
* @param screen the screen number 0 for channel A, 1 for channel B
*/
extern SYSTEMCALL void sys_text_setsizes(short chan);
/***
*** Block device system calls
***/
/**
* Register a block device driver
*
* @param device pointer to the description of the device to register
* @return 0 on succes, negative number on error
*/
extern SYSTEMCALL short sys_bdev_register(p_dev_block device);
/**
* Read a block from the device
*
* @param dev the number of the device
* @param lba the logical block address of the block to read
* @param buffer the buffer into which to copy the block data
* @param size the size of the buffer.
* @return number of bytes read, any negative number is an error code
*/
extern SYSTEMCALL short sys_bdev_read(short dev, long lba, uint8_t * buffer, short size);
/**
* Write a block to the device
*
* @param dev the number of the device
* @param lba the logical block address of the block to write
* @param buffer the buffer containing the data to write
* @param size the size of the buffer.
* @return number of bytes written, any negative number is an error code
*/
extern SYSTEMCALL short sys_bdev_write(short dev, long lba, const uint8_t * buffer, short size);
/**
* Return the status of the block device
*
* @param dev the number of the device
* @return the status of the device
*/
extern SYSTEMCALL short sys_bdev_status(short dev);
/**
* Ensure that any pending writes to the device have been completed
*
* @param dev the number of the device
* @return 0 on success, any negative number is an error code
*/
extern SYSTEMCALL short sys_bdev_flush(short dev);
/**
* Issue a control command to the device
*
* @param dev the number of the device
* @param command the number of the command to send
* @param buffer pointer to bytes of additional data for the command
* @param size the size of the buffer
* @return 0 on success, any negative number is an error code
*/
extern SYSTEMCALL short sys_bdev_ioctrl(short dev, short command, uint8_t * buffer, short size);
/*
* File System Calls
*/
/**
* Attempt to open a file given the path to the file and the mode.
*
* @param path the ASCIIZ string containing the path to the file.
* @param mode the mode (e.g. r/w/create)
*
*@return the channel ID for the open file (negative if error)
*/
extern SYSTEMCALL short sys_fsys_open(const char * path, short mode);
/**
* Close access to a previously open file.
*
* @param fd the channel ID for the file
*
* @return 0 on success, negative number on failure
*/
extern SYSTEMCALL short sys_fsys_close(short fd);
/**
* Attempt to open a directory for scanning
*
* @param path the path to the directory to open
*
* @return the handle to the directory if >= 0. An error if < 0
*/
extern SYSTEMCALL short sys_fsys_opendir(const char * path);
/**
* Close a previously open directory
*
* @param dir the directory handle to close
*
* @return 0 on success, negative number on error
*/
extern SYSTEMCALL short sys_fsys_closedir(short dir);
/**
* Attempt to read an entry from an open directory
*
* @param dir the handle of the open directory
* @param file pointer to the t_file_info structure to fill out.
*
* @return 0 on success, negative number on failure
*/
extern SYSTEMCALL short sys_fsys_readdir(short dir, p_file_info file);
/**
* Open a directory given the path and search for the first file matching the pattern.
*
* @param path the path to the directory to search
* @param pattern the file name pattern to search for
* @param file pointer to the t_file_info structure to fill out
*
* @return the directory handle to use for subsequent calls if >= 0, error if negative
*/
extern SYSTEMCALL short sys_fsys_findfirst(const char * path, const char * pattern, p_file_info file);
/**
* Open a directory given the path and search for the first file matching the pattern.
*
* @param dir the handle to the directory (returned by fsys_findfirst) to search
* @param file pointer to the t_file_info structure to fill out
*
* @return 0 on success, error if negative
*/
extern SYSTEMCALL short sys_fsys_findnext(short dir, p_file_info file);
/**
* Get the label for the drive holding the path
*
* @param path path to the drive
* @param label buffer that will hold the label... should be at least 35 bytes
* @return 0 on success, error if negative
*/
extern SYSTEMCALL short sys_fsys_get_label(const char * path, char * label);
/**
* Set the label for the drive holding the path
*
* @param drive drive number
* @param label buffer that holds the label
* @return 0 on success, error if negative
*/
extern SYSTEMCALL short sys_fsys_set_label(short drive, const char * label);
/**
* Create a directory
*
* @param path the path of the directory to create.
*
* @return 0 on success, negative number on failure.
*/
extern SYSTEMCALL short sys_fsys_mkdir(const char * path);
/**
* Delete a file or directory
*
* @param path the path of the file or directory to delete.
*
* @return 0 on success, negative number on failure.
*/
extern SYSTEMCALL short sys_fsys_delete(const char * path);
/**
* Rename a file or directory
*
* @param old_path he current path to the file
* @param new_path the new path for the file
*
* @return 0 on success, negative number on failure.
*/
extern SYSTEMCALL short sys_fsys_rename(const char * old_path, const char * new_path);
/**
* Change the current working directory (and drive)
*
* @param path the path that should be the new current
*
* @return 0 on success, negative number on failure.
*/
extern SYSTEMCALL short sys_fsys_set_cwd(const char * path);
/**
* Get the current working drive and directory
*
* @param path the buffer in which to store the directory
* @param size the size of the buffer in bytes
*
* @return 0 on success, negative number on failure.
*/
extern SYSTEMCALL short sys_fsys_get_cwd(char * path, short size);
/**
* Load a file into memory at the designated destination address.
*
* If destination = 0, the file must be in a recognized binary format
* that specifies its own loading address.
*
* @param path the path to the file to load
* @param destination the destination address (0 for use file's address)
* @param start pointer to the long variable to fill with the starting address
* (0 if not an executable, any other number if file is executable
* with a known starting address)
*
* @return 0 on success, negative number on error
*/
extern SYSTEMCALL short sys_fsys_load(const char * path, uint32_t destination, uint32_t * start);
/**
* Register a file loading routine
*
* A file loader, takes a channel number to load from and returns a
* short that is the status of the load.
*
* @param extension the file extension to map to
* @param loader pointer to the file load routine to add
*
* @return 0 on success, negative number on error
*/
extern SYSTEMCALL short sys_fsys_register_loader(const char * extension, p_file_loader loader);
/**
* Check to see if the file is present.
* If it is not, return a file not found error.
* If it is, populate the file info record
*
* @param path the path to the file to check
* @param file pointer to a file info record to fill in, if the file is found.
* @return 0 on success, negative number on error
*/
extern SYSTEMCALL short sys_fsys_stat(const char * path, p_file_info file);
/**
* Memory
*/
/**
* Return the top of system RAM... the user program must not use any
* system memory from this address and above.
*
* @return the address of the first byte of reserved system RAM (one above the last byte the user program can use)
*/
extern SYSTEMCALL uint32_t sys_mem_get_ramtop();
/**
* Reserve a block of memory at the top of system RAM.
*
* @param bytes the number of bytes to reserve
* @return address of the first byte of the reserved block
*/
extern SYSTEMCALL uint32_t sys_mem_reserve(uint32_t bytes);
/*
* Miscellaneous
*/
/**
* Get the number of jiffies since the system last booted.
*
* NOTE: a jiffie is 1/60 of a second. This timer will not be
* 100% precise, so it should be used for timeout purposes
* where precision is not critical.
*
* @return the number of jiffies since the last reset
*/
extern SYSTEMCALL uint32_t sys_time_jiffies();
/**
* Set the time on the RTC
*
* @param time pointer to a t_time record containing the correct time
*/
extern SYSTEMCALL void sys_rtc_set_time(p_time time);
/**
* Get the time on the RTC
*
* @param time pointer to a t_time record in which to put the current time
*/
extern SYSTEMCALL void sys_rtc_get_time(p_time time);
/**
* Check for any keypress and return the scancode for the key
*
* @return the next scan code from the keyboard... 0 if nothing pending
*/
extern SYSTEMCALL uint16_t sys_kbd_scancode();
/**
* Return an error message given an error number
*
* @param err_number the error number
* @return pointer to a string describing the error
*/
extern SYSTEMCALL const char * sys_err_message(short err_number);
/**
* Set the keyboard translation tables
*
* The translation tables provided to the keyboard consist of eight
* consecutive tables of 128 characters each. Each table maps from
* the MAKE scan code of a key to its appropriate 8-bit character code.
*
* The tables included must include, in order:
* - UNMODIFIED: Used when no modifier keys are pressed or active
* - SHIFT: Used when the SHIFT modifier is pressed
* - CTRL: Used when the CTRL modifier is pressed
* - CTRL-SHIFT: Used when both CTRL and SHIFT are pressed
* - CAPSLOCK: Used when CAPSLOCK is down but SHIFT is not pressed
* - CAPSLOCK-SHIFT: Used when CAPSLOCK is down and SHIFT is pressed
* - ALT: Used when only ALT is presse
* - ALT-SHIFT: Used when ALT is pressed and either CAPSLOCK is down
* or SHIFT is pressed (but not both)
*
* @param tables pointer to the keyboard translation tables
* @return 0 on success, negative number on error
*
*/
extern SYSTEMCALL short sys_kbd_layout(const char * tables);
/**
* Load and execute an executable file
*
* @param path the path to the executable file
* @param argc the number of arguments passed
* @param argv the array of string arguments
* @return the return result of the program
*/
extern SYSTEMCALL short sys_proc_run(const char * path, int argc, char * argv[]);
//
// Text screen calls
//
/**
* Gets the description of a screen's capabilities
*
* @param screen the number of the text device
*
* @return a pointer to the read-only description (0 on error)
*/
extern SYSTEMCALL const p_txt_capabilities sys_txt_get_capabilities(short screen);
/**
* Set the display mode for the screen
*
* @param screen the number of the text device
* @param mode a bitfield of desired display mode options
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
extern SYSTEMCALL short sys_txt_set_mode(short screen, short mode);
/**
* 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 screen the number of the text device
* @param x the column for the cursor
* @param y the row for the cursor
*/
extern SYSTEMCALL void sys_txt_set_xy(short screen, short x, short 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
*/
extern SYSTEMCALL void sys_txt_get_xy(short screen, p_point position);
/**
* Get the current region.
*
* @param screen the number of the text device
* @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
*/
extern SYSTEMCALL short sys_txt_get_region(short screen, p_rect region);
/**
* 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 screen the number of the text device
* @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
*/
extern SYSTEMCALL short sys_txt_set_region(short screen, p_rect region);
/**
* Set the default foreground and background colors for printing
*
* @param screen the number of the text device
* @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)
*/
extern SYSTEMCALL void sys_txt_set_color(short screen, unsigned char foreground, unsigned char background);
/*
* Get the foreground and background color for printing
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* foreground = pointer to the foreground color number
* background = pointer to the background color number
*/
extern SYSTEMCALL void sys_txt_get_color(short screen, unsigned char * foreground, unsigned char * background);
/**
* Set if the cursor is visible or not
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @param is_visible TRUE if the cursor should be visible, FALSE (0) otherwise
*/
extern SYSTEMCALL void sys_txt_set_cursor_visible(short screen, short is_visible);
/**
* Load a font as the current font for the screen
*
* @param screen the number of the text device
* @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
*/
extern SYSTEMCALL short sys_txt_set_font(short screen, short width, short height, unsigned char * data);
/**
* Get the display resolutions
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @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)
*/
extern SYSTEMCALL void sys_txt_get_sizes(short screen, p_extent text_size, p_extent pixel_size);
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @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)
*/
extern SYSTEMCALL void sys_txt_set_border(short screen, short width, short height);
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @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)
*/
extern SYSTEMCALL void sys_txt_set_border_color(short screen, unsigned char red, unsigned char green, unsigned char blue);
/**
* Print a character to the current cursor position in the current color
*
* Most character codes will result in a glyph being displayed at the current
* cursor position, advancing the cursor one spot. There are some exceptions that
* will be treated as control codes:
*
* 0x08 - BS - Move the cursor back one position, erasing the character underneath
* 0x09 - HT - Move forward to the next TAB stop
* 0x0A - LF - Move the cursor down one line (line feed)
* 0x0D - CR - Move the cursor to column 0 (carriage return)
*
* @param screen the number of the text device
* @param c the character to print
*/
extern SYSTEMCALL void sys_txt_put(short screen, char c);
/**
* Print an ASCII Z string to the screen
*
* @param screen the number of the text device
* @param message the ASCII Z string to print
*/
extern SYSTEMCALL void sys_txt_print(short screen, const char * message);
#endif

View file

@ -1,239 +0,0 @@
/**
* @file stubs.c
* @brief Stubs for Calypsi I/O routines
* @version 0.1
* @date 2024-09-02
*
* @copyright Copyright (c) 2024
*
*/
#include "include/toolbox.h"
#include <errno.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stubs.h>
#define MAX_FD 16
struct s_file_descriptor {
bool is_open;
int public_fd;
short toolbox_fd;
};
static bool is_inited = false;
static struct s_file_descriptor file_descriptor[MAX_FD];
static void init() {
if (!is_inited) {
is_inited = true;
// Define stdin
file_descriptor[0].is_open = true;
file_descriptor[0].public_fd = 0;
file_descriptor[0].toolbox_fd = 0;
// Define stdout
file_descriptor[1].is_open = true;
file_descriptor[1].public_fd = 0;
file_descriptor[1].toolbox_fd = 0;
// Define stderr
file_descriptor[2].is_open = true;
file_descriptor[2].public_fd = 0;
file_descriptor[2].toolbox_fd = 0;
for (int i = 3; i < MAX_FD; i++) {
file_descriptor[i].is_open = false;
file_descriptor[i].public_fd = 0;
file_descriptor[i].toolbox_fd = 0;
}
}
}
/**
* @brief Find a free file descriptor
*
* @return int the index of the available (closed) file descriptor (-1 for error)
*/
static int find_fd() {
for (int i = 3; i < MAX_FD; i++) {
if (!file_descriptor[i].is_open) {
// Found one that is closed... return it's public ID
return file_descriptor[i].public_fd;
}
}
// Return an error
return -1;
}
/****************************************************************************
* Name: _Stub_open
*
* Description:
* Open a file.
* The oflag argument are POSIX style mode flags, e.g O_RDONLY which
* are defined in fcntl.h.
* This function is variadic as it optionally can take a mode_t that
* are permissions, e.g 0666. If the file system does not handle
* permissions you can ignore that this function is variadic.
* The return file descriptor shall be a positive number, larger
* than 2 (as 0-2 are used for stdin, stdout and stderr).
* The actual number does not matter and they need not to be
* consequtive, multiple numeric series with gaps between can be used.
*
* Return the obtained file descriptor or EOF (-1) on failure and set
* errno according to the error.
*
****************************************************************************/
int _Stub_open(const char *path, int oflag, ...) {
int fd = find_fd();
if (fd >= 0) {
int mode = 0;
if ((oflag & O_RDONLY) == O_RDONLY) {
mode = FSYS_READ | FSYS_OPEN_EXISTING;
}
if ((oflag & O_WRONLY) == O_WRONLY) {
mode = FSYS_WRITE;
}
if ((oflag & O_RDWR) == O_RDWR) {
mode = FSYS_READ | FSYS_WRITE;
}
if ((oflag & O_CREAT) == O_CREAT) {
mode |= FSYS_CREATE_NEW | FSYS_CREATE_ALWAYS;
}
short toolbox_fd = sys_fsys_open(path, mode);
if (toolbox_fd >= 0) {
file_descriptor[fd].is_open = true;
file_descriptor[fd].toolbox_fd = toolbox_fd;
return fd;
} else {
return -1;
}
} else {
errno = ENFILE;
return -1;
}
}
/****************************************************************************
* Name: _Stub_close
*
* Description:
* Close a file
*
* Return 0 if operation was OK, EOF otherwise and set errno according to
* the error.
* Note: This will only be invoked for streams opened by _Stub_open(),
* there is no need to check for the standard descriptor 0-2.
*
****************************************************************************/
int _Stub_close(int fd) {
if (file_descriptor[fd].is_open) {
sys_fsys_close(file_descriptor[fd].toolbox_fd);
file_descriptor[fd].toolbox_fd = 0;
file_descriptor[fd].is_open = false;
}
return 0;
}
/****************************************************************************
* Name: _Stub_lseek
*
* Description:
* Change position in a file
*
* Returns the new position in the file in bytes from the beginning of the
* file, or -1 on failure.
*
****************************************************************************/
long _Stub_lseek(int fd, long offset, int whence) {
return 0;
}
/****************************************************************************
* Name: _Stub_read
*
* Description:
* Read from a file
*
* Returns the number of characters read. Return -1 on failure and set
* errno according to the error.
*
****************************************************************************/
size_t _Stub_read(int fd, void *buf, size_t count) {
if (file_descriptor[fd].is_open) {
short n = sys_chan_read(file_descriptor[fd].toolbox_fd, (unsigned char *)buf, (short)count);
return n;
} else {
return -1;
}
}
/****************************************************************************
* Name: _Stub_write
*
* Description:
* Write to a file
*
* Returns the number of characters actually written. Return -1 on failure and
* set errno according to the error.
*
****************************************************************************/
size_t _Stub_write(int fd, const void *buf, size_t count) {
if (file_descriptor[fd].is_open) {
short n = sys_chan_write(file_descriptor[fd].toolbox_fd, (unsigned char *)buf, (short)count);
return n;
} else {
return -1;
}
}
/****************************************************************************
* Name: _Stub_rename
*
* Description:
* Rename a file or directory
*
* Return 0 on success, -1 otherwise and set errno according to the
* error.
*
****************************************************************************/
int _Stub_rename(const char *oldpath, const char *newpath) {
short result = sys_fsys_rename(oldpath, newpath);
return result;
}
/****************************************************************************
* Name: _Stub_remove
*
* Description:
* Remove a file or directory
*
* Return 0 on success, -1 otherwise and set errno according to the
* error.
*
****************************************************************************/
int _Stub_remove(const char *path) {
short result = sys_fsys_delete(path);
return result;
}

View file

@ -1,603 +0,0 @@
###############################################################################
# #
# Calypsi ISO C compiler for 65816 version 5.5 #
# 24/Sep/2024 17:04:27 #
# Command line: -I. -I./include -DMODEL=17 -DCPU=255 --code-model large #
# --data-model large -l -o stubs.o stubs.c #
# #
###############################################################################
\ 000000 .rtmodel version,"1"
\ 000000 .rtmodel codeModel,"large"
\ 000000 .rtmodel dataModel,"large"
\ 000000 .rtmodel core,"65816"
\ 000000 .rtmodel huge,"0"
\ 000000 .extern _Dp
\ 000000 .extern _Mul16
\ 000000 .extern _Vfp
\ 000000 .extern errno
\ 000000 .extern sys_chan_read
\ 000000 .extern sys_chan_write
\ 000000 .extern sys_fsys_close
\ 000000 .extern sys_fsys_delete
\ 000000 .extern sys_fsys_open
\ 000000 .extern sys_fsys_rename
0001 /**
0002 * @file stubs.c
0003 * @brief Stubs for Calypsi I/O routines
0004 * @version 0.1
0005 * @date 2024-09-02
0006 *
0007 * @copyright Copyright (c) 2024
0008 *
0009 */
0010
0011 #include "include/toolbox.h"
0012
0013 #include <errno.h>
0014 #include <fcntl.h>
0015 #include <stdbool.h>
0016 #include <stdint.h>
0017 #include <stubs.h>
0018
0019 #define MAX_FD 16
0020
0021 struct s_file_descriptor {
0022 bool is_open;
0023 int public_fd;
0024 short toolbox_fd;
0025 };
0026
0027 static bool is_inited = false;
\ 000000 .section zfar,bss
\ 000000 is_inited: .space 2
0028 static struct s_file_descriptor file_descriptor[MAX_FD];
\ 000000 .section zfar,bss
\ 000000 file_descriptor:
\ 000000 .space 96
0029
0030 static void init() {
0031 if (!is_inited) {
0032 is_inited = true;
0033
0034 // Define stdin
0035 file_descriptor[0].is_open = true;
0036 file_descriptor[0].public_fd = 0;
0037 file_descriptor[0].toolbox_fd = 0;
0038
0039 // Define stdout
0040 file_descriptor[1].is_open = true;
0041 file_descriptor[1].public_fd = 0;
0042 file_descriptor[1].toolbox_fd = 0;
0043
0044 // Define stderr
0045 file_descriptor[2].is_open = true;
0046 file_descriptor[2].public_fd = 0;
0047 file_descriptor[2].toolbox_fd = 0;
0048
0049 for (int i = 3; i < MAX_FD; i++) {
0050 file_descriptor[i].is_open = false;
0051 file_descriptor[i].public_fd = 0;
0052 file_descriptor[i].toolbox_fd = 0;
0053 }
0054 }
0055 }
0056
0057 /**
0058 * @brief Find a free file descriptor
0059 *
0060 * @return int the index of the available (closed) file descriptor (-1 for error)
0061 */
0062 static int find_fd() {
\ 000000 .section farcode,text
\ 000000 5a find_fd: phy
0063 for (int i = 3; i < MAX_FD; i++) {
\ 000001 a90300 lda ##3
\ 000004 8301 sta 1,s
\ 000006 a301 lda 1,s
\ 000008 8301 sta 1,s
\ 00000a a301 `?L15`: lda 1,s
\ 00000c 38 sec
\ 00000d e91000 sbc ##16
\ 000010 5003 bvc `?L82`
\ 000012 490080 eor ##-32768
\ 000015 3005 `?L82`: bmi `?L14`
0064 if (!file_descriptor[i].is_open) {
0065 // Found one that is closed... return it's public ID
0066 return file_descriptor[i].public_fd;
0067 }
0068 }
0069
0070 // Return an error
0071 return -1;
\ 000017 a9ffff lda ##-1
\ 00001a 8031 bra `?L13`
\ 00001c a301 `?L14`: lda 1,s
\ 00001e a20600 ldx ##6
\ 000021 22...... jsl long:_Mul16
\ 000025 aa tax
\ 000026 bf...... lda long:file_descriptor,x
\ 00002a d023 bne `?L18`
\ 00002c a9.... lda ##.word0 file_descriptor
\ 00002f 85.. sta dp:.tiny _Dp
\ 000031 a9.... lda ##.word2 file_descriptor
\ 000034 85.. sta dp:.tiny (_Dp+2)
\ 000036 a301 lda 1,s
\ 000038 a20600 ldx ##6
\ 00003b 22...... jsl long:_Mul16
\ 00003f 85.. sta dp:.tiny (_Dp+4)
\ 000041 18 clc
\ 000042 a5.. lda dp:.tiny _Dp
\ 000044 65.. adc dp:.tiny (_Dp+4)
\ 000046 85.. sta dp:.tiny _Dp
\ 000048 a00200 ldy ##2
\ 00004b b7.. lda [.tiny _Dp],y
\ 00004d `?L13`:
0072 }
\ 00004d 7a ply
\ 00004e 6b rtl
\ 00004f a301 `?L18`: lda 1,s
\ 000051 1a inc a
\ 000052 8301 sta 1,s
\ 000054 80b4 bra `?L15`
0073
0074 /****************************************************************************
0075 * Name: _Stub_open
0076 *
0077 * Description:
0078 * Open a file.
0079 * The oflag argument are POSIX style mode flags, e.g O_RDONLY which
0080 * are defined in fcntl.h.
0081 * This function is variadic as it optionally can take a mode_t that
0082 * are permissions, e.g 0666. If the file system does not handle
0083 * permissions you can ignore that this function is variadic.
0084 * The return file descriptor shall be a positive number, larger
0085 * than 2 (as 0-2 are used for stdin, stdout and stderr).
0086 * The actual number does not matter and they need not to be
0087 * consequtive, multiple numeric series with gaps between can be used.
0088 *
0089 * Return the obtained file descriptor or EOF (-1) on failure and set
0090 * errno according to the error.
0091 *
0092 ****************************************************************************/
0093
0094 int _Stub_open(const char *path, int oflag, ...) {
\ 000000 .section farcode,text
\ 000000 .public _Stub_open
\ 000000 _Stub_open:
\ 000000 d4.. pei dp:.tiny (_Dp+8)
\ 000002 d4.. pei dp:.tiny (_Dp+10)
\ 000004 5a phy
\ 000005 5a phy
\ 000006 5a phy
\ 000007 8303 sta 3,s
\ 000009 a5.. lda dp:.tiny _Dp
\ 00000b 85.. sta dp:.tiny (_Dp+8)
\ 00000d a5.. lda dp:.tiny (_Dp+2)
\ 00000f 85.. sta dp:.tiny (_Dp+10)
0095 int fd = find_fd();
\ 000011 22...... jsl long:find_fd
\ 000015 8305 sta 5,s
0096 if (fd >= 0) {
\ 000017 a305 lda 5,s
\ 000019 1003 bpl `?L103`
\ 00001b 4c.... jmp .kbank `?L26`
\ 00001e `?L103`:
0097 int mode = 0;
\ 00001e a90000 lda ##0
\ 000021 8301 sta 1,s
0098
0099 if ((oflag & O_RDONLY) == O_RDONLY) {
\ 000023 a90100 lda ##1
\ 000026 2303 and 3,s
\ 000028 c90100 cmp ##1
\ 00002b d00b bne `?L29`
0100 mode = FSYS_READ | FSYS_OPEN_EXISTING;
\ 00002d a90100 lda ##1
\ 000030 8301 sta 1,s
\ 000032 a301 lda 1,s
\ 000034 8301 sta 1,s
\ 000036 8004 bra `?L30`
\ 000038 a301 `?L29`: lda 1,s
\ 00003a 8301 sta 1,s
\ 00003c `?L30`:
0101 }
0102
0103 if ((oflag & O_WRONLY) == O_WRONLY) {
\ 00003c a90200 lda ##2
\ 00003f 2303 and 3,s
\ 000041 c90200 cmp ##2
\ 000044 d00b bne `?L32`
0104 mode = FSYS_WRITE;
\ 000046 a90200 lda ##2
\ 000049 8301 sta 1,s
\ 00004b a301 lda 1,s
\ 00004d 8301 sta 1,s
\ 00004f 8004 bra `?L33`
\ 000051 a301 `?L32`: lda 1,s
\ 000053 8301 sta 1,s
\ 000055 `?L33`:
0105 }
0106
0107 if ((oflag & O_RDWR) == O_RDWR) {
\ 000055 a90300 lda ##3
\ 000058 2303 and 3,s
\ 00005a c90300 cmp ##3
\ 00005d d00b bne `?L35`
0108 mode = FSYS_READ | FSYS_WRITE;
\ 00005f a90300 lda ##3
\ 000062 8301 sta 1,s
\ 000064 a301 lda 1,s
\ 000066 8301 sta 1,s
\ 000068 8004 bra `?L36`
\ 00006a a301 `?L35`: lda 1,s
\ 00006c 8301 sta 1,s
\ 00006e `?L36`:
0109 }
0110
0111 if ((oflag & O_CREAT) == O_CREAT) {
\ 00006e a90400 lda ##4
\ 000071 2303 and 3,s
\ 000073 c90400 cmp ##4
\ 000076 d00d bne `?L38`
0112 mode |= FSYS_CREATE_NEW | FSYS_CREATE_ALWAYS;
\ 000078 a90c00 lda ##12
\ 00007b 0301 ora 1,s
\ 00007d 8301 sta 1,s
\ 00007f a301 lda 1,s
\ 000081 8301 sta 1,s
\ 000083 8004 bra `?L39`
\ 000085 a301 `?L38`: lda 1,s
\ 000087 8301 sta 1,s
\ 000089 `?L39`:
0113 }
0114
0115 short toolbox_fd = sys_fsys_open(path, mode);
\ 000089 a301 lda 1,s
\ 00008b 48 pha
\ 00008c a6.. ldx dp:.tiny (_Dp+10)
\ 00008e a5.. lda dp:.tiny (_Dp+8)
\ 000090 22...... jsl long:sys_fsys_open
\ 000094 aa tax
\ 000095 68 pla
\ 000096 8a txa
\ 000097 8301 sta 1,s
0116 if (toolbox_fd >= 0) {
\ 000099 a301 lda 1,s
\ 00009b 3038 bmi `?L41`
0117 file_descriptor[fd].is_open = true;
\ 00009d a305 lda 5,s
\ 00009f a20600 ldx ##6
\ 0000a2 22...... jsl long:_Mul16
\ 0000a6 aa tax
\ 0000a7 a90100 lda ##1
\ 0000aa 9f...... sta long:file_descriptor,x
0118 file_descriptor[fd].toolbox_fd = toolbox_fd;
\ 0000ae a2.... ldx ##.word0 file_descriptor
\ 0000b1 86.. stx dp:.tiny _Dp
\ 0000b3 a2.... ldx ##.word2 file_descriptor
\ 0000b6 86.. stx dp:.tiny (_Dp+2)
\ 0000b8 a305 lda 5,s
\ 0000ba a20600 ldx ##6
\ 0000bd 22...... jsl long:_Mul16
\ 0000c1 85.. sta dp:.tiny (_Dp+4)
\ 0000c3 18 clc
\ 0000c4 a5.. lda dp:.tiny _Dp
\ 0000c6 65.. adc dp:.tiny (_Dp+4)
\ 0000c8 85.. sta dp:.tiny _Dp
\ 0000ca a301 lda 1,s
\ 0000cc a00400 ldy ##4
\ 0000cf 97.. sta [.tiny _Dp],y
0119
0120 return fd;
\ 0000d1 a305 lda 5,s
\ 0000d3 800f bra `?L25`
\ 0000d5 `?L41`:
0121 } else {
0122 return -1;
\ 0000d5 a9ffff lda ##-1
\ 0000d8 800a bra `?L25`
\ 0000da `?L26`:
0123 }
0124
0125 } else {
0126 errno = ENFILE;
\ 0000da a91700 lda ##23
\ 0000dd 8f...... sta long:errno
0127 return -1;
\ 0000e1 a9ffff lda ##-1
\ 0000e4 `?L25`:
0128 }
0129 }
\ 0000e4 7a ply
\ 0000e5 7a ply
\ 0000e6 7a ply
\ 0000e7 7a ply
\ 0000e8 84.. sty dp:.tiny (_Dp+10)
\ 0000ea 7a ply
\ 0000eb 84.. sty dp:.tiny (_Dp+8)
\ 0000ed 6b rtl
0130
0131 /****************************************************************************
0132 * Name: _Stub_close
0133 *
0134 * Description:
0135 * Close a file
0136 *
0137 * Return 0 if operation was OK, EOF otherwise and set errno according to
0138 * the error.
0139 * Note: This will only be invoked for streams opened by _Stub_open(),
0140 * there is no need to check for the standard descriptor 0-2.
0141 *
0142 ****************************************************************************/
0143
0144 int _Stub_close(int fd) {
\ 000000 .section farcode,text
\ 000000 .public _Stub_close
\ 000000 _Stub_close:
\ 000000 5a phy
\ 000001 8301 sta 1,s
0145 if (file_descriptor[fd].is_open) {
\ 000003 a301 lda 1,s
\ 000005 a20600 ldx ##6
\ 000008 22...... jsl long:_Mul16
\ 00000c aa tax
\ 00000d bf...... lda long:file_descriptor,x
\ 000011 f05a beq `?L50`
0146 sys_fsys_close(file_descriptor[fd].toolbox_fd);
\ 000013 a9.... lda ##.word0 file_descriptor
\ 000016 85.. sta dp:.tiny _Dp
\ 000018 a9.... lda ##.word2 file_descriptor
\ 00001b 85.. sta dp:.tiny (_Dp+2)
\ 00001d a301 lda 1,s
\ 00001f a20600 ldx ##6
\ 000022 22...... jsl long:_Mul16
\ 000026 85.. sta dp:.tiny (_Dp+4)
\ 000028 18 clc
\ 000029 a5.. lda dp:.tiny _Dp
\ 00002b 65.. adc dp:.tiny (_Dp+4)
\ 00002d 85.. sta dp:.tiny _Dp
\ 00002f a00400 ldy ##4
\ 000032 b7.. lda [.tiny _Dp],y
\ 000034 22...... jsl long:sys_fsys_close
0147 file_descriptor[fd].toolbox_fd = 0;
\ 000038 a2.... ldx ##.word0 file_descriptor
\ 00003b 86.. stx dp:.tiny _Dp
\ 00003d a2.... ldx ##.word2 file_descriptor
\ 000040 86.. stx dp:.tiny (_Dp+2)
\ 000042 a301 lda 1,s
\ 000044 a20600 ldx ##6
\ 000047 22...... jsl long:_Mul16
\ 00004b 85.. sta dp:.tiny (_Dp+4)
\ 00004d 18 clc
\ 00004e a5.. lda dp:.tiny _Dp
\ 000050 65.. adc dp:.tiny (_Dp+4)
\ 000052 85.. sta dp:.tiny _Dp
\ 000054 a90000 lda ##0
\ 000057 a00400 ldy ##4
\ 00005a 97.. sta [.tiny _Dp],y
0148 file_descriptor[fd].is_open = false;
\ 00005c a301 lda 1,s
\ 00005e a20600 ldx ##6
\ 000061 22...... jsl long:_Mul16
\ 000065 aa tax
\ 000066 a90000 lda ##0
\ 000069 9f...... sta long:file_descriptor,x
\ 00006d `?L50`:
\ 00006d `?L51`:
0149 }
0150
0151 return 0;
\ 00006d a90000 lda ##0
0152 }
\ 000070 7a ply
\ 000071 6b rtl
0153
0154 /****************************************************************************
0155 * Name: _Stub_lseek
0156 *
0157 * Description:
0158 * Change position in a file
0159 *
0160 * Returns the new position in the file in bytes from the beginning of the
0161 * file, or -1 on failure.
0162 *
0163 ****************************************************************************/
0164
0165 long _Stub_lseek(int fd, long offset, int whence) {
\ 000000 .section farcode,text
\ 000000 .public _Stub_lseek
\ 000000 _Stub_lseek:
0166 return 0;
\ 000000 a90000 lda ##0
\ 000003 a20000 ldx ##0
0167 }
\ 000006 6b rtl
0168
0169 /****************************************************************************
0170 * Name: _Stub_read
0171 *
0172 * Description:
0173 * Read from a file
0174 *
0175 * Returns the number of characters read. Return -1 on failure and set
0176 * errno according to the error.
0177 *
0178 ****************************************************************************/
0179
0180 size_t _Stub_read(int fd, void *buf, size_t count) {
\ 000000 .section farcode,text
\ 000000 .public _Stub_read
\ 000000 5a _Stub_read: phy
\ 000001 8301 sta 1,s
0181 if (file_descriptor[fd].is_open) {
\ 000003 a301 lda 1,s
\ 000005 a20600 ldx ##6
\ 000008 22...... jsl long:_Mul16
\ 00000c aa tax
\ 00000d bf...... lda long:file_descriptor,x
\ 000011 f035 beq `?L61`
0182 short n = sys_chan_read(file_descriptor[fd].toolbox_fd, (unsigned char *)buf, (short)count);
\ 000013 a5.. lda dp:.tiny (_Dp+4)
\ 000015 48 pha
\ 000016 a5.. lda dp:.tiny (_Dp+2)
\ 000018 48 pha
\ 000019 a5.. lda dp:.tiny _Dp
\ 00001b 48 pha
\ 00001c a9.... lda ##.word0 file_descriptor
\ 00001f 85.. sta dp:.tiny _Dp
\ 000021 a9.... lda ##.word2 file_descriptor
\ 000024 85.. sta dp:.tiny (_Dp+2)
\ 000026 a307 lda 7,s
\ 000028 a20600 ldx ##6
\ 00002b 22...... jsl long:_Mul16
\ 00002f 85.. sta dp:.tiny (_Dp+4)
\ 000031 18 clc
\ 000032 a5.. lda dp:.tiny _Dp
\ 000034 65.. adc dp:.tiny (_Dp+4)
\ 000036 85.. sta dp:.tiny _Dp
\ 000038 a00400 ldy ##4
\ 00003b b7.. lda [.tiny _Dp],y
\ 00003d 22...... jsl long:sys_chan_read
\ 000041 aa tax
\ 000042 68 pla
\ 000043 68 pla
\ 000044 68 pla
0183 return n;
\ 000045 8a txa
\ 000046 8003 bra `?L60`
\ 000048 `?L61`:
0184 } else {
0185 return -1;
\ 000048 a9ffff lda ##-1
\ 00004b `?L60`:
0186 }
0187 }
\ 00004b 7a ply
\ 00004c 6b rtl
0188
0189 /****************************************************************************
0190 * Name: _Stub_write
0191 *
0192 * Description:
0193 * Write to a file
0194 *
0195 * Returns the number of characters actually written. Return -1 on failure and
0196 * set errno according to the error.
0197 *
0198 ****************************************************************************/
0199
0200 size_t _Stub_write(int fd, const void *buf, size_t count) {
\ 000000 .section farcode,text
\ 000000 .public _Stub_write
\ 000000 _Stub_write:
\ 000000 5a phy
\ 000001 8301 sta 1,s
0201 if (file_descriptor[fd].is_open) {
\ 000003 a301 lda 1,s
\ 000005 a20600 ldx ##6
\ 000008 22...... jsl long:_Mul16
\ 00000c aa tax
\ 00000d bf...... lda long:file_descriptor,x
\ 000011 f035 beq `?L69`
0202 short n = sys_chan_write(file_descriptor[fd].toolbox_fd, (unsigned char *)buf, (short)count);
\ 000013 a5.. lda dp:.tiny (_Dp+4)
\ 000015 48 pha
\ 000016 a5.. lda dp:.tiny (_Dp+2)
\ 000018 48 pha
\ 000019 a5.. lda dp:.tiny _Dp
\ 00001b 48 pha
\ 00001c a9.... lda ##.word0 file_descriptor
\ 00001f 85.. sta dp:.tiny _Dp
\ 000021 a9.... lda ##.word2 file_descriptor
\ 000024 85.. sta dp:.tiny (_Dp+2)
\ 000026 a307 lda 7,s
\ 000028 a20600 ldx ##6
\ 00002b 22...... jsl long:_Mul16
\ 00002f 85.. sta dp:.tiny (_Dp+4)
\ 000031 18 clc
\ 000032 a5.. lda dp:.tiny _Dp
\ 000034 65.. adc dp:.tiny (_Dp+4)
\ 000036 85.. sta dp:.tiny _Dp
\ 000038 a00400 ldy ##4
\ 00003b b7.. lda [.tiny _Dp],y
\ 00003d 22...... jsl long:sys_chan_write
\ 000041 aa tax
\ 000042 68 pla
\ 000043 68 pla
\ 000044 68 pla
0203 return n;
\ 000045 8a txa
\ 000046 8003 bra `?L68`
\ 000048 `?L69`:
0204 } else {
0205 return -1;
\ 000048 a9ffff lda ##-1
\ 00004b `?L68`:
0206 }
0207 }
\ 00004b 7a ply
\ 00004c 6b rtl
0208
0209 /****************************************************************************
0210 * Name: _Stub_rename
0211 *
0212 * Description:
0213 * Rename a file or directory
0214 *
0215 * Return 0 on success, -1 otherwise and set errno according to the
0216 * error.
0217 *
0218 ****************************************************************************/
0219
0220 int _Stub_rename(const char *oldpath, const char *newpath) {
\ 000000 .section farcode,text
\ 000000 .public _Stub_rename
\ 000000 _Stub_rename:
0221 short result = sys_fsys_rename(oldpath, newpath);
\ 000000 a5.. lda dp:.tiny (_Dp+6)
\ 000002 48 pha
\ 000003 a5.. lda dp:.tiny (_Dp+4)
\ 000005 48 pha
\ 000006 a6.. ldx dp:.tiny (_Dp+2)
\ 000008 a5.. lda dp:.tiny _Dp
\ 00000a 22...... jsl long:sys_fsys_rename
\ 00000e aa tax
\ 00000f 68 pla
\ 000010 68 pla
0222 return result;
\ 000011 8a txa
0223 }
\ 000012 6b rtl
0224
0225 /****************************************************************************
0226 * Name: _Stub_remove
0227 *
0228 * Description:
0229 * Remove a file or directory
0230 *
0231 * Return 0 on success, -1 otherwise and set errno according to the
0232 * error.
0233 *
0234 ****************************************************************************/
0235
0236 int _Stub_remove(const char *path) {
\ 000000 .section farcode,text
\ 000000 .public _Stub_remove
\ 000000 _Stub_remove:
0237 short result = sys_fsys_delete(path);
\ 000000 a6.. ldx dp:.tiny (_Dp+2)
\ 000002 a5.. lda dp:.tiny _Dp
\ 000004 22...... jsl long:sys_fsys_delete
0238 return result;
0239 }
\ 000008 6b rtl
##########################
# #
# Memory sizes (decimal) #
# #
##########################
Executable (Text): 627 bytes
Zero initialized __far (BSS): 98 bytes

View file

@ -1,6 +1,6 @@
# ROM Files for the F256jr
# ROM Files for the F256JRe
This directory contains BIN files for programming the F256jr flash memory with the Foenix Toolbox.
This directory contains BIN files for programming the F256JRe flash memory with the Foenix Toolbox.
## How to Install

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -15,5 +15,4 @@
"2E","toolbox-2E.bin"
"2F","toolbox-2F.bin"
"30","toolbox-30.bin"
"31","toolbox-31.bin"
"3F","toolbox-3F.bin"

1 20 toolbox-20.bin
15 2E toolbox-2E.bin
16 2F toolbox-2F.bin
17 30 toolbox-30.bin
31 toolbox-31.bin
18 3F toolbox-3F.bin

View file

@ -1,6 +1,6 @@
# ROM Files for the F256K
# ROM Files for the F256Ke
This directory contains BIN files for programming the F256K flash memory with the Foenix Toolbox.
This directory contains BIN files for programming the F256Ke flash memory with the Foenix Toolbox.
## How to Install

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -15,5 +15,4 @@
"2E","toolbox-2E.bin"
"2F","toolbox-2F.bin"
"30","toolbox-30.bin"
"31","toolbox-31.bin"
"3F","toolbox-3F.bin"

1 20 toolbox-20.bin
15 2E toolbox-2E.bin
16 2F toolbox-2F.bin
17 30 toolbox-30.bin
31 toolbox-31.bin
18 3F toolbox-3F.bin

12
roms/f256k2/README.md Normal file
View file

@ -0,0 +1,12 @@
# ROM Files for the F256K2e
This directory contains BIN files for programming the F256K2e flash memory with the Foenix Toolbox.
## How to Install
Currently, the toolbox must be installed by bulk programming the flash memory.
Using the FoenixMgr Python script, this can be done with the following command (substitute the device path or name for your F256K's USB debug port):
```
python FoenixMgr.zip --port {debug device name} --flash-bulk toolbox.csv
```

BIN
roms/f256k2/toolbox-20.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-21.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-22.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-23.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-24.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-25.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-26.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-27.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-28.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-29.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-2A.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-2B.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-2C.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-2D.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-2E.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-2F.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-30.bin Normal file

Binary file not shown.

BIN
roms/f256k2/toolbox-3F.bin Normal file

Binary file not shown.

2111
roms/f256k2/toolbox.bin Normal file

File diff suppressed because one or more lines are too long

18
roms/f256k2/toolbox.csv Normal file
View file

@ -0,0 +1,18 @@
"20","toolbox-20.bin"
"21","toolbox-21.bin"
"22","toolbox-22.bin"
"23","toolbox-23.bin"
"24","toolbox-24.bin"
"25","toolbox-25.bin"
"26","toolbox-26.bin"
"27","toolbox-27.bin"
"28","toolbox-28.bin"
"29","toolbox-29.bin"
"2A","toolbox-2A.bin"
"2B","toolbox-2B.bin"
"2C","toolbox-2C.bin"
"2D","toolbox-2D.bin"
"2E","toolbox-2E.bin"
"2F","toolbox-2F.bin"
"30","toolbox-30.bin"
"3F","toolbox-3F.bin"
1 20 toolbox-20.bin
2 21 toolbox-21.bin
3 22 toolbox-22.bin
4 23 toolbox-23.bin
5 24 toolbox-24.bin
6 25 toolbox-25.bin
7 26 toolbox-26.bin
8 27 toolbox-27.bin
9 28 toolbox-28.bin
10 29 toolbox-29.bin
11 2A toolbox-2A.bin
12 2B toolbox-2B.bin
13 2C toolbox-2C.bin
14 2D toolbox-2D.bin
15 2E toolbox-2E.bin
16 2F toolbox-2F.bin
17 30 toolbox-30.bin
18 3F toolbox-3F.bin

View file

@ -6,8 +6,8 @@
"sys_int_enable","FFE014"
"sys_int_register","FFE018"
"sys_int_pending","FFE01C"
"sys_get_info","FFE020"
"sys_int_clear","FFE024"
"sys_int_clear","FFE020"
"sys_get_info","FFE024"
"sys_chan_read_b","FFE028"
"sys_chan_read","FFE02C"
"sys_chan_readline","FFE030"
@ -40,35 +40,48 @@
"sys_fsys_mkdir","FFE09C"
"sys_fsys_delete","FFE0A0"
"sys_fsys_rename","FFE0A4"
"sys_fsys_set_cwd","FFE0A8"
"sys_fsys_get_cwd","FFE0AC"
"sys_fsys_load","FFE0B0"
"sys_fsys_register_loader","FFE0B4"
"sys_fsys_stat","FFE0B8"
"sys_mem_get_ramtop","FFE0BC"
"sys_mem_reserve","FFE0C0"
"sys_time_jiffies","FFE0C4"
"sys_rtc_set_time","FFE0C8"
"sys_rtc_get_time","FFE0CC"
"sys_kbd_scancode","FFE0D0"
"sys_err_message","FFE0D4"
"sys_kbd_layout","FFE0D8"
"sys_proc_run","FFE0DC"
"sys_txt_get_capabilities","FFE0E0"
"sys_txt_set_mode","FFE0E4"
"sys_txt_set_resolution","FFE0E8"
"sys_txt_setsizes","FFE0EC"
"sys_txt_set_xy","FFE0F0"
"sys_txt_get_xy","FFE0F4"
"sys_txt_get_region","FFE0F8"
"sys_txt_set_region","FFE0FC"
"sys_txt_set_color","FFE100"
"sys_txt_get_color","FFE104"
"sys_txt_set_cursor","FFE108"
"sys_txt_set_cursor_visible","FFE10C"
"sys_txt_set_font","FFE110"
"sys_txt_get_sizes","FFE114"
"sys_txt_set_border","FFE118"
"sys_txt_set_border_color","FFE11C"
"sys_txt_put","FFE120"
"sys_txt_print","FFE124"
"sys_fsys_load","FFE0A8"
"sys_fsys_register_loader","FFE0AC"
"sys_fsys_stat","FFE0B0"
"sys_mem_get_ramtop","FFE0B4"
"sys_mem_reserve","FFE0B8"
"sys_time_jiffies","FFE0BC"
"sys_rtc_set_time","FFE0C0"
"sys_rtc_get_time","FFE0C4"
"sys_kbd_scancode","FFE0C8"
"sys_err_message","FFE0CC"
"sys_kbd_layout","FFE0D0"
"sys_proc_run","FFE0D4"
"sys_txt_get_capabilities","FFE0D8"
"sys_txt_set_mode","FFE0DC"
"sys_txt_set_resolution","FFE0E0"
"sys_txt_setsizes","FFE0E4"
"sys_txt_set_xy","FFE0E8"
"sys_txt_get_xy","FFE0EC"
"sys_txt_get_region","FFE0F0"
"sys_txt_set_region","FFE0F4"
"sys_txt_set_color","FFE0F8"
"sys_txt_get_color","FFE0FC"
"sys_txt_set_cursor","FFE100"
"sys_txt_set_cursor_visible","FFE104"
"sys_txt_set_font","FFE108"
"sys_txt_get_sizes","FFE10C"
"sys_txt_set_border","FFE110"
"sys_txt_set_border_color","FFE114"
"sys_txt_put","FFE118"
"sys_txt_print","FFE11C"
"sys_kbd_handle_irq","FFE120"
"sys_reboot","FFE124"
"sys_proc_set_shell","FFE128"
"sys_proc_get_result","FFE12C"
"sys_iecll_ioinit","FFE130"
"sys_iecll_in","FFE134"
"sys_iecll_eoi","FFE138"
"sys_iecll_out","FFE13C"
"sys_iecll_talk","FFE140"
"sys_iecll_talk_sa","FFE144"
"sys_iecll_untalk","FFE148"
"sys_iecll_listen","FFE14C"
"sys_iecll_listen_sa","FFE150"
"sys_iecll_unlisten","FFE154"
"sys_iecll_reset","FFE158"

1 sys_proc_exit FFE000
6 sys_int_enable FFE014
7 sys_int_register FFE018
8 sys_int_pending FFE01C
9 sys_get_info sys_int_clear FFE020
10 sys_int_clear sys_get_info FFE024
11 sys_chan_read_b FFE028
12 sys_chan_read FFE02C
13 sys_chan_readline FFE030
40 sys_fsys_mkdir FFE09C
41 sys_fsys_delete FFE0A0
42 sys_fsys_rename FFE0A4
43 sys_fsys_set_cwd sys_fsys_load FFE0A8
44 sys_fsys_get_cwd sys_fsys_register_loader FFE0AC
45 sys_fsys_load sys_fsys_stat FFE0B0
46 sys_fsys_register_loader sys_mem_get_ramtop FFE0B4
47 sys_fsys_stat sys_mem_reserve FFE0B8
48 sys_mem_get_ramtop sys_time_jiffies FFE0BC
49 sys_mem_reserve sys_rtc_set_time FFE0C0
50 sys_time_jiffies sys_rtc_get_time FFE0C4
51 sys_rtc_set_time sys_kbd_scancode FFE0C8
52 sys_rtc_get_time sys_err_message FFE0CC
53 sys_kbd_scancode sys_kbd_layout FFE0D0
54 sys_err_message sys_proc_run FFE0D4
55 sys_kbd_layout sys_txt_get_capabilities FFE0D8
56 sys_proc_run sys_txt_set_mode FFE0DC
57 sys_txt_get_capabilities sys_txt_set_resolution FFE0E0
58 sys_txt_set_mode sys_txt_setsizes FFE0E4
59 sys_txt_set_resolution sys_txt_set_xy FFE0E8
60 sys_txt_setsizes sys_txt_get_xy FFE0EC
61 sys_txt_set_xy sys_txt_get_region FFE0F0
62 sys_txt_get_xy sys_txt_set_region FFE0F4
63 sys_txt_get_region sys_txt_set_color FFE0F8
64 sys_txt_set_region sys_txt_get_color FFE0FC
65 sys_txt_set_color sys_txt_set_cursor FFE100
66 sys_txt_get_color sys_txt_set_cursor_visible FFE104
67 sys_txt_set_cursor sys_txt_set_font FFE108
68 sys_txt_set_cursor_visible sys_txt_get_sizes FFE10C
69 sys_txt_set_font sys_txt_set_border FFE110
70 sys_txt_get_sizes sys_txt_set_border_color FFE114
71 sys_txt_set_border sys_txt_put FFE118
72 sys_txt_set_border_color sys_txt_print FFE11C
73 sys_txt_put sys_kbd_handle_irq FFE120
74 sys_txt_print sys_reboot FFE124
75 sys_proc_set_shell FFE128
76 sys_proc_get_result FFE12C
77 sys_iecll_ioinit FFE130
78 sys_iecll_in FFE134
79 sys_iecll_eoi FFE138
80 sys_iecll_out FFE13C
81 sys_iecll_talk FFE140
82 sys_iecll_talk_sa FFE144
83 sys_iecll_untalk FFE148
84 sys_iecll_listen FFE14C
85 sys_iecll_listen_sa FFE150
86 sys_iecll_unlisten FFE154
87 sys_iecll_reset FFE158

View file

@ -1,6 +1,6 @@
.public restart_cli
.extern cli_rerepl
.extern proc_shell_address
.extern _Vfp
.extern _DirectPageStart
@ -14,7 +14,7 @@
;
; Reset the stack to the initial value.
; Reset the direct page and data bank registers
; Restart the CLI
; Transfer control to the registered shell address (if present)
;
restart_cli:
rep #0x38 ; 16-bit registers, no decimal mode
@ -33,5 +33,5 @@ restart_cli:
plb ; pop 8 dummy
plb ; set data bank
; jsl cli_rerepl
jsl proc_shell_address
bra restart_cli

62
src/C256/f256k2-flash.scm Normal file
View file

@ -0,0 +1,62 @@
(define memories
'(
(memory flash
(address (#xfc0000 . #xffdfff))
(type ROM)
(fill #xff)
(section
data_init_table
data
ifar))
(memory flash-high
(address (#xffe000 . #xfffeff))
(type ROM)
(fill #xff)
(section jumptable))
(memory flash-shadow
(address (#xffff00 . #xffffff))
(type ROM)
(fill 0)
(section
(LoCodeStorage #xffff00)
(VectorStorage #xffffe0)))
(memory LoCode
(address (#x00ff00 . #x00ffdf))
(type ROM)
(scatter-to LoCodeStorage)
(section code cdata))
(memory Vector
(address (#x00ffe0 . #x00ffff))
(type ROM)
(scatter-to VectorStorage)
(section (reset #xfffc)))
(memory hiram
(address (#x0f0000 . #x0fffff))
(type RAM)
(section heap))
(memory loram
(address (#x00d000 . #x00dfff))
(type RAM)
(placement-group nobits (section zdata znear))
(placement-group bits (section data near)))
(memory stackram
(address (#x00edeb . #xfdeb))
(type RAM)
(section stack))
(memory DirectPage
(address (#x00fe00 . #x00feff))
(section (registers ztiny)))
(block stack (size #x1000))
(block heap (size #x1000))
(base-address _DirectPageStart DirectPage 0)
(base-address _NearBaseAddress hiram 0)
))

View file

@ -102,7 +102,7 @@ release_RST: release_bit IEC_RST_o
;;
sleep_20us: phx
ldx #20
ldx #14
_loop$ dex
bne _loop$
plx
@ -635,7 +635,7 @@ iecll_eoi php
rtl
not_eoi$ plp
lda #0
lda ##0
rtl
;

View file

@ -6,8 +6,8 @@
.public sys_int_enable
.public sys_int_register
.public sys_int_pending
.public sys_get_info
.public sys_int_clear
.public sys_get_info
.public sys_chan_read_b
.public sys_chan_read
.public sys_chan_readline
@ -40,8 +40,6 @@
.public sys_fsys_mkdir
.public sys_fsys_delete
.public sys_fsys_rename
.public sys_fsys_set_cwd
.public sys_fsys_get_cwd
.public sys_fsys_load
.public sys_fsys_register_loader
.public sys_fsys_stat
@ -73,6 +71,20 @@
.public sys_txt_put
.public sys_txt_print
.public sys_kbd_handle_irq
.public sys_reboot
.public sys_proc_set_shell
.public sys_proc_get_result
.public sys_iecll_ioinit
.public sys_iecll_in
.public sys_iecll_eoi
.public sys_iecll_out
.public sys_iecll_talk
.public sys_iecll_talk_sa
.public sys_iecll_untalk
.public sys_iecll_listen
.public sys_iecll_listen_sa
.public sys_iecll_unlisten
.public sys_iecll_reset
.extern proc_exit
.extern int_enable_all
@ -82,8 +94,8 @@
.extern int_enable
.extern int_register
.extern int_pending
.extern sys_get_information
.extern int_clear
.extern sys_get_information
.extern chan_read_b
.extern chan_read
.extern chan_readline
@ -116,8 +128,6 @@
.extern fsys_mkdir
.extern fsys_delete
.extern fsys_rename
.extern fsys_set_cwd
.extern fsys_get_cwd
.extern fsys_load
.extern fsys_register_loader
.extern fsys_stat
@ -149,6 +159,20 @@
.extern txt_put
.extern txt_print
.extern kbd_handle_irq
.extern reboot
.extern proc_set_shell
.extern proc_get_result
.extern iecll_ioinit
.extern iecll_in
.extern iecll_eoi
.extern iecll_out
.extern iecll_talk
.extern iecll_talk_sa
.extern iecll_untalk
.extern iecll_listen
.extern iecll_listen_sa
.extern iecll_unlisten
.extern iecll_reset
.section jumptable
@ -160,8 +184,8 @@ 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_get_info: jmp long:sys_get_information
sys_chan_read_b: jmp long:chan_read_b
sys_chan_read: jmp long:chan_read
sys_chan_readline: jmp long:chan_readline
@ -194,8 +218,6 @@ sys_fsys_set_label: jmp long:fsys_set_label
sys_fsys_mkdir: jmp long:fsys_mkdir
sys_fsys_delete: jmp long:fsys_delete
sys_fsys_rename: jmp long:fsys_rename
sys_fsys_set_cwd: jmp long:fsys_set_cwd
sys_fsys_get_cwd: jmp long:fsys_get_cwd
sys_fsys_load: jmp long:fsys_load
sys_fsys_register_loader: jmp long:fsys_register_loader
sys_fsys_stat: jmp long:fsys_stat
@ -226,4 +248,18 @@ sys_txt_set_border: jmp long:txt_set_border
sys_txt_set_border_color: jmp long:txt_set_border_color
sys_txt_put: jmp long:txt_put
sys_txt_print: jmp long:txt_print
sys_kbd_handle_irq: jmp long:kbd_handle_irq
sys_kbd_handle_irq: jmp long:kbd_handle_irq
sys_reboot: jmp long:reboot
sys_proc_set_shell: jmp long:proc_set_shell
sys_proc_get_result: jmp long:proc_get_result
sys_iecll_ioinit: jmp long:iecll_ioinit
sys_iecll_in: jmp long:iecll_in
sys_iecll_eoi: jmp long:iecll_eoi
sys_iecll_out: jmp long:iecll_out
sys_iecll_talk: jmp long:iecll_talk
sys_iecll_talk_sa: jmp long:iecll_talk_sa
sys_iecll_untalk: jmp long:iecll_untalk
sys_iecll_listen: jmp long:iecll_listen
sys_iecll_listen_sa: jmp long:iecll_listen_sa
sys_iecll_unlisten: jmp long:iecll_unlisten
sys_iecll_reset: jmp long:iecll_reset

View file

@ -79,3 +79,18 @@ txt_put
txt_print
kbd_handle_irq
reboot
proc_set_shell
proc_get_result
iecll_ioinit
iecll_in
iecll_eoi
iecll_out
iecll_talk
iecll_talk_sa
iecll_untalk
iecll_listen
iecll_listen_sa
iecll_unlisten
iecll_reset

View file

@ -1,7 +1,7 @@
# VPATH=.:../../module/Calypsi-remote-debug/src
DEBUGGER=../module/Calypsi-remote-debug/src
UNIT := F256K
UNIT := F256K2
MEMORY := ROM
# Define OS-dependent variables
@ -52,13 +52,24 @@ else ifeq ($(UNIT),F256K)
CPU=w65816
C_SRCS_DEBUGGER=$(DEBUGGER)/agent.c $(DEBUGGER)/c256-uart.c $(DEBUGGER)/low_level_WDC65816.s
SRCS_FOR_UNIT=cartridge.c C256/jumptable.s C256/io_stubs.c C256/extras.s C256/iecll.s C256/interrupts.s C256/f256-cstartup.s
CFLAGS_FOR_UNIT=-DMODEL=17 -DCPU=255 --code-model large --data-model large --target f256
CFLAGS_FOR_UNIT=-DMODEL=18 -DCPU=255 --code-model large --data-model large --target f256
ifeq ($(MEMORY),ROM)
LDFLAGS_FOR_UNIT=C256/f256-flash.scm clib-lc-ld.a --rtattr printf=medium --cstartup=f256
else
LDFLAGS_FOR_UNIT=C256/f256-ld_lc.scm clib-lc-ld.a --rtattr printf=medium --cstartup=f256
endif
else ifeq ($(UNIT),F256K2)
CPU=w65816
C_SRCS_DEBUGGER=$(DEBUGGER)/agent.c $(DEBUGGER)/c256-uart.c $(DEBUGGER)/low_level_WDC65816.s
SRCS_FOR_UNIT=cartridge.c C256/jumptable.s C256/io_stubs.c C256/extras.s C256/iecll.s C256/interrupts.s C256/f256-cstartup.s
CFLAGS_FOR_UNIT=-DMODEL=17 -DCPU=255 --code-model large --data-model large --target f256
ifeq ($(MEMORY),ROM)
LDFLAGS_FOR_UNIT=C256/f256k2-flash.scm clib-lc-ld.a --rtattr printf=medium --cstartup=f256
else
LDFLAGS_FOR_UNIT=C256/f256-ld_lc.scm clib-lc-ld.a --rtattr printf=medium --cstartup=f256
endif
endif
ifeq ($(CPU),w65816)

25
src/README.md Normal file
View file

@ -0,0 +1,25 @@
# Toolbox Source Directory
This directory contains the main (mostly device-independent) source code for the Toolbox as well as the various sub-directories:
* C256 -- Directory for C256 and F256 low-level assembly code. (TODO: split these out into separate folders!)
* dev -- Directory for machine-specific device drivers.
* include -- Header files included by various files in the Toolbox. All register address definitions should be confined to these header files, mostly in directories and files for each specific system.
* boot.* -- Files for the boot screen
* cartridge.* -- Code to support accessing the F256 cartridge. This might need to be pushed down to the dev folder.
* indicators.* -- Files for the LEDs... indicators.c needs to be pushed to dev. indicators.h to include
* interrupt.* -- Files to support interrupts... TODO: remove or redistribute to dev and include?
* log_level.h -- Definitions of the various logging levels used by the Toolbox's internal logging code
* log.* -- Toolbox's internal logging code for TRACE/ERROR/INFO/DEBUG logging
* memory.* -- Public calls for the rudimentary memory management support
* newbuild.py -- Utility script to incriment the build number
* proc.* -- Code to support launching and exiting a user program
* ring_buffer.* -- Data type code for a ring buffer, used by a couple of drivers
* simpleio.* -- Rudimentary I/O code for printing messages before drivers are fully active
* sys_general.* -- System information, CPU and model identification, and some GABE functionality
* syscalls.c -- System call support but only relevant for m68k and m68040 systems (TODO: move elsewhere)
* timers.c -- A2560K timer code (TODO: push down to dev)
* timers.h -- Stubs for timers device code
* toolbox.c -- The main startup code for the Toolbox
* utilities.* -- Some useful functions that are needed in multiple places
* version.h -- Definitions of the version number for the current build

View file

@ -77,6 +77,8 @@ static enum boot_src_e boot_chain[MAX_BOOT_SRC];
static bool bootable[MAX_BOOT_SRC];
static short boot_src_cnt = 0;
extern t_sys_info info;
/**
* @brief A holder for empty arguments list so we have something to point to when starting a binary file
*
@ -86,6 +88,37 @@ static char * boot_args[] = {
0
};
/**
* @brief Display the system information
*
*/
static void display_sysinfo() {
// 8 x 22 region
t_rect region;
region.size.height = 8;
region.size.width = 23;
region.origin.x = 80 - region.size.width;
region.origin.y = 60 - region.size.height;
txt_set_region(0, &region);
printf("Foenix Retro Systems\n");
printf("Model %s\n", info.model_name);
printf("CPU %s\n", info.cpu_name);
printf("Clock %lu MHz\n", info.cpu_clock_khz / (long)1000);
printf("Memory %d KB\n", (int)(info.system_ram_size / ((long)1024 * (long)1024)));
printf("FPGA %04X %04X.%04X\n", info.fpga_model, info.fpga_version, info.fpga_subver);
printf("Toolbox v%d.%02d.%04d\n", info.mcp_version, info.mcp_rev, info.mcp_build);
region.size.width = 0;
region.size.height = 0;
region.origin.x = 0;
region.origin.y = 0;
txt_set_region(0, &region);
txt_set_xy(0, 0, 0);
}
/**
* @brief Check the memory indicated to validate it is a boot record... if so, launch the code indicated
*
@ -409,6 +442,17 @@ void boot_screen() {
long jiffies_target = 0;
char message[80];
// Locate the tile maps based on the top of ram
uint32_t ram_index = mem_get_ramtop();
ram_index -= 8 * 272;
tile_set_memory_base = ram_index;
ram_index -= 2 * 42 * 32;
tile_map_memory_base = ram_index;
// Locate the sprites
ram_index -= 5 * (32 * 32);
sprite_ram_base = ram_index;
// Check the DIP switches to see if we should include RAM booting
// Choose the correct boot chain accordingly
@ -428,10 +472,9 @@ void boot_screen() {
// Make sure that ANSI escape codes will be honored
chan_ioctrl(0, CON_IOCTRL_ANSI_ON, 0, 0);
// TODO: debug this
// txt_set_mode(0, TXT_MODE_TEXT | TXT_MODE_SPRITE | VKY_MCR_TILE);
*tvky_mstr_ctrl = (uint16_t)(VKY_MCR_TILE | VKY_MCR_SPRITE | VKY_MCR_GRAPHICS | VKY_MCR_TEXT_OVERLAY | VKY_MCR_TEXT);
txt_set_mode(0, TXT_MODE_TEXT | TXT_MODE_SPRITE | TXT_MODE_TILE);
txt_set_resolution(0, 640, 480);
tvky_bg_color->blue = 0;
tvky_bg_color->green = 0;
tvky_bg_color->red = 0;
@ -459,6 +502,9 @@ void boot_screen() {
*tvky_layers = 0x0444;
// Display the system information;
display_sysinfo();
// Set up the text window for the boot messaging
t_rect boot_text_window;
boot_text_window.origin.x = 14;

View file

@ -1,5 +1,5 @@
UNIT := F256K
UNIT := F256K2
# Define OS-dependent variables
@ -44,6 +44,13 @@ else ifeq ($(UNIT),F256K)
AS=as65816
AR=nlib
SRCS_FOR_UNIT=txt_f256.c kbd_f256.c kbd_f256k.c indicators_c256.c interrupts_f256.c sdc_f256.c iec.c # timers_c256.c
CFLAGS_FOR_UNIT=-DMODEL=18 -DCPU=255 --code-model large --data-model large --target f256
else ifeq ($(UNIT),F256K2)
CC=cc65816
AS=as65816
AR=nlib
SRCS_FOR_UNIT=txt_f256.c kbd_f256.c kbd_f256k.c indicators_c256.c interrupts_f256.c sdc_f256.c iec.c # timers_c256.c
CFLAGS_FOR_UNIT=-DMODEL=17 -DCPU=255 --code-model large --data-model large --target f256
endif

26
src/dev/README.md Normal file
View file

@ -0,0 +1,26 @@
# Device Drivers
This folder contains the machine-specific device driver code for the various I/O the Toolbox has to support:
* block.c -- Public functions to access block devices (currently just SDC, but could also include floppy drive and hard drive). Used by FatFS to access the drives.
* channel.c -- Public functions to access channel devices. Channel devices include the console, serial port, and open files.
* console.c -- Functions to provide a console like device for the keyboard and main screen. This is where the ANSI terminal code support is provided.
* fsys.c -- Provides the file system public functions as well as the channel device driver for open files.
* iec.c -- Provides some wrapper functions around the very lowest level Commodore serial port assembly code. Eventually, this will be used to provide Toolbox public functions for IEC (probably through the channel interface).
* indicators_*.c -- Low level access to the various indicators (LEDs) on the boards: power, media, caps-lock, etc.
* interrupts_*.c -- Machine-specific code for managing interrupts (currently, only the keyboard interrupt is used)
* kbd_f256.c -- Common code for all F256 keyboard (F256K2e mechanical and optical keyboard, F256jr PS/2)
* kbd_f256k.c -- Device specific code for F256K mechanical and optical keyboards
* kbd_f256jr.c -- Device specific code for the F256jr PS/2 keyboard
* ps2.c -- Low-level support for the PS/2 interface
* rtc.c -- Access to the realtime clock
* sdc_f256.c -- Device driver code for the F256's SD card via the SPI interface. This provides a block device driver that is used by FatFS.
* sprites.c -- Code to allow the boot screen to use sprites
* tiles.c -- Code to allow the boot screen to use tiles
* timers_c256.c -- Low-level code to set up the timers used by the C256 code
* txt_c256.c -- Channel device driver code for the C256's main screen
* txt_evid.c -- Channel device driver code for the C256's EVID expansion card
* txt_f256.c -- Channel device driver code for the F256's screen
* txt_screen.c -- Common code for all text screen drivers
* uart.c -- Channel device driver code for the serial port
NOTE: the directory `unsupported_systems` contains the original device driver files from FoenixMCP that are relevant to systems not currently supported by the Toolbox. They are left here so they could be brought back, if desired.

View file

@ -1,152 +0,0 @@
/**
* @file bitmap.c
* @author your name (you@domain.com)
* @brief Simple bitmap management code
* @version 0.1
* @date 2023-10-02
*
*/
#include <stdint.h>
#include "bitmap.h"
#include "dma.h"
#include "vicky_general.h"
#define NUM_BITMAP_PLANES 2
static uint8_t bm_visible = 0; // Track whether a given bitmap plane is visible
/**
* @brief Set the visibility of a given bitmap plane, and the CLUT to use
*
* @param plane the number of the bitmap to update
* @param clut the number of the CLUT to use for the bitmap
* @param is_visible 0 to hide the bitmap, any other number to show it
*/
void bm_set_visibility(short plane, short clut, short is_visible) {
uint8_t new_control_value = (clut & 0x03) << 1 | (is_visible) ? 1 : 0;
switch(plane) {
case 0:
*bm0_control = new_control_value;
if (is_visible) {
bm_visible |= 0x01;
} else {
bm_visible &= ~0x01;
}
break;
case 1:
*bm1_control = new_control_value;
if (is_visible) {
bm_visible |= 0x02;
} else {
bm_visible &= ~0x02;
}
break;
default:
break;
}
if (bm_visible) {
tvky_mstr_ctrl->raw = tvky_mstr_ctrl->raw | VKY_MCR_TEXT_OVERLAY | VKY_MCR_GRAPHICS | VKY_MCR_BITMAP;
} else {
tvky_mstr_ctrl->raw = tvky_mstr_ctrl->raw & ~(VKY_MCR_TEXT_OVERLAY | VKY_MCR_GRAPHICS | VKY_MCR_BITMAP);
}
}
/**
* @brief Set the
*
* @param plane the number of the bitmap to set
* @param src the address of the bitmap data to use (should be in video RAM)
*/
void bm_set_data(short plane, uint8_t * src) {
uint32_t src_raw = (uint32_t)src - (uint32_t)vram_base;
switch (plane) {
case 0:
bm0_address[0] = (uint8_t)(src_raw & 0xff);
bm0_address[1] = (uint8_t)((src_raw >> 8) & 0xff);
bm0_address[2] = (uint8_t)((src_raw >> 16) & 0xff);
break;
case 1:
bm1_address[0] = (uint8_t)(src_raw & 0xff);
bm1_address[1] = (uint8_t)((src_raw >> 8) & 0xff);
bm1_address[2] = (uint8_t)((src_raw >> 16) & 0xff);
break;
default:
break;
}
}
/**
* @brief Fill the bitmap data with a given color
*
* @param dest the area of video RAM to fill
* @param color the color index to fill it with
* @param width the width of the image in pixels
* @param height the height of the image in pixels
*/
void bm_fill(uint8_t * dest, uint8_t color, int width, int height) {
vdma_fill_linear(dest, color, (long)width * (long)height);
}
/**
* @brief Load the color lookup table
*
* @param clut number of the CLUT to load
* @param src pointer to the source data for the CLUT (in B, G, R, A order)
*/
void bm_load_clut(short clut, uint8_t * src) {
uint8_t * base = (uint8_t *)((uint32_t)VKY_GR_CLUT_0 + 4l * 256l * (uint32_t)clut);
tvky_bg_color->blue = src[0];
tvky_bg_color->green = src[1];
tvky_bg_color->red = src[2];
for (int i = 0; i < 4 * 256; i++) {
base[i] = src[i];
}
}
/**
* @brief Load RLE bitmap data into video RAM
*
* @param dest address to load with the expanded bitmap data (should be in video RAM)
* @param src address of the RLE data to expand
* @param width the width of the image in pixels
* @param height the height of the image in pixels
*/
void bm_load_rle(uint8_t * dest, uint8_t * src, int width, int height) {
uint32_t my_base = (uint32_t)dest;
// Clear the image map
bm_fill(dest, 0, width, height);
uint8_t count = *(src++);
while (count != 0) {
uint8_t value = *(src++);
if (value != 0) {
volatile uint8_t * my_pointer = (uint8_t *)my_base;
for (int i = 0; i < count; i++) {
my_pointer[i] = value;
}
}
my_base += count;
count = *(src++);
}
}
/**
* @brief Initialize the bitmap system
*
*/
void bm_init() {
bm_visible = 0;
}

View file

@ -1,62 +0,0 @@
/**
* @brief Definitions for functions to manage bitmap displays
*
*/
#ifndef __BITMAP_H__
#define __BITMAP_H__
#include <stdint.h>
/**
* @brief Set the visibility of a given bitmap plane, and the CLUT to use
*
* @param plane the number of the bitmap to update
* @param clut the number of the CLUT to use for the bitmap
* @param is_visible 0 to hide the bitmap, any other number to show it
*/
extern void bm_set_visibility(short plane, short clut, short is_visible);
/**
* @brief Set the
*
* @param plane the number of the bitmap to set
* @param src the address of the bitmap data to use (should be in video RAM)
*/
extern void bm_set_data(short plane, uint8_t * src);
/**
* @brief Fill the bitmap data with a given color
*
* @param dest the area of video RAM to fill
* @param color the color index to fill it with
* @param width the width of the image in pixels
* @param height the height of the image in pixels
*/
extern void bm_fill(uint8_t * dest, uint8_t color, int width, int height);
/**
* @brief Load the color lookup table
*
* @param clut number of the CLUT to load
* @param src pointer to the source data for the CLUT (in B, G, R, A order)
*/
extern void bm_load_clut(short clut, uint8_t * src);
/**
* @brief Load RLE bitmap data into video RAM
*
* @param dest address to load with the expanded bitmap data (should be in video RAM)
* @param src address of the RLE data to expand
* @param width the width of the image in pixels
* @param height the height of the image in pixels
*/
extern void bm_load_rle(uint8_t * dest, uint8_t * src, int width, int height);
/**
* @brief Initialize the bitmap system
*
*/
extern void bm_init();
#endif

View file

@ -1,215 +0,0 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "vicky_general.h"
/**
* @brief
*
*/
struct bmp_color_s {
uint8_t red;
uint8_t green;
uint8_t blue;
uint8_t reserved;
};
struct bmp_infoheader_s {
uint32_t infoheader_size;
uint32_t width;
uint32_t height;
uint16_t planes;
uint16_t bit_count;
uint32_t compression;
uint32_t image_size;
uint32_t x_pixels_per_m;
uint32_t y_pixels_per_m;
uint32_t colors_used;
uint32_t colors_important;
struct bmp_color_s color_table[];
};
struct bmp_header_s {
char signature[2];
uint32_t file_size;
uint32_t reserved;
uint32_t offset;
struct bmp_infoheader_s info_header;
};
const uint16_t BMP_BC_MONO = 1; // Monochrome
const uint16_t BMP_BC_INDEX_16 = 4; // 4-bit indexed color (16 colors total)
const uint16_t BMP_BC_INDEX_256 = 8; // 8-bit indexed color (256 colors total)
const uint16_t BMP_BC_RGB_16 = 16; // 16-bit RGB
const uint16_t BMP_BC_RGB_24 = 24; // 24-bit RGB (True Color)
const uint32_t BMP_RGB = 0; // No compression
const uint32_t BMP_RLE8 = 1; // 8-bit run-length-encoded
const uint32_t BMP_RLE4 = 2; // 4-bit run-length-encoded
const short BMP_OK = 0; // BMP file was processed without error
const short BMP_BAD_FILETYPE = -1; // File does not have a BMP signature
const short BMP_BAD_FORMAT = -2; // BMP file is not in a supported format (color format or compression)
/**
* @brief Set the components of a color in a graphics color lookup table
*
* NOTE: this routine might need to be swapped out for different hardware
*
* @param clut the number of the graphics CLUT to update
* @param color the number of the color to update
* @param red the red component
* @param green the green component
* @param blue the blue component
*/
static void bm_set_color(short clut, short color, uint8_t red, uint8_t green, uint8_t blue) {
volatile uint8_t * clut_p = VKY_GR_CLUT_0 + (clut * 256 * 4);
uint32_t offset = color * 4;
clut_p[offset] = blue;
clut_p[offset+1] = green;
clut_p[offset+2] = red;
clut_p[offset+3] = 0xff;
}
/**
* @brief Load a color lookup table
*
* @param src_colors pointer to the BMP color table
* @param numcolors the number of colors in the BMP color table
* @param clut the number of the color palette to load
*/
static void load_palette(struct bmp_color_s * src_colors, int numcolors, int clut) {
for (int color = 0; color < numcolors; color++) {
bm_set_color(clut, color, src_colors[color].red, src_colors[color].green, src_colors[color].blue);
}
}
/**
* @brief Decompress the BMP 256 color image data, given 8-bit RLE compression
*
* @param img_data pointer to the BMP compressed image data
* @param width the width of the image to build up
* @param height the height of the image to build up
* @param destination pointer to the destination to expand the image into
*/
static void expand_index8_rle8(char * img_data, uint32_t width, uint32_t height, char * destination) {
int i = 0;
uint32_t row = 0;
uint32_t column = 0;
uint32_t img_index = 0;
// Calculate address of the first row
char * dest_row = (char *)((uint32_t)destination + (height - row - 1) * width);
// Default the image to color 0
memset(destination, 0, width * height);
// Process the data blocks in the image data until we reach the end of the image
while (1) {
char count = img_data[img_index++];
char value = img_data[img_index++];
if (count > 0) {
// We have a run of bytes
for (i = 0; i < count; i++) {
dest_row[column++] = value;
if (column >= width) {
column = 0;
row -= 1;
dest_row = (char *)((uint32_t)destination + (height - row - 1) * width);
}
}
} else {
// Count == 0: we have to process the escape sequence
switch (value) {
case 0:
// End of line... handle padding
img_index += (3 - img_index % 4);
break;
case 1:
// End of bitmap... we're done
return;
case 2:
// Delta... adjust row and column
char dx = img_data[img_index++];
char dy = img_data[img_index++];
row += dy;
column += dx;
dest_row = (char *)((uint32_t)destination + (height - row - 1) * width);
break;
default:
// value indicates the number of bytes to copy raw
for (i = 0; i < value; i++) {
char b = img_data[img_index++];
dest_row[column++] = b;
if (column >= width) {
column = 0;
row -= 1;
dest_row = (char *)((uint32_t)destination + (height - row - 1) * width);
}
if (img_index % 2) {
// Skip over padding, if we're on an odd byte
img_index++;
}
}
break;
}
}
}
return BMP_OK;
}
/**
* @brief Render a BMP file into a destination bitmap image and a destination color palette
*
* @param bmp_data pointer to the raw BMP data
* @param dest_img pointer to the area in memory to load the expanded bitmap data
* @param clut the number of the graphics CLUT to use for the image
* @return 0 if image could be processed, any other number is an error
*/
short bm_bmp_render(char * bmp_data, char * dest_img, short clut) {
struct bmp_header_s * bmp_header = (struct bmp_header_s *)bmp_data;
if ((bmp_header->signature[0] == 'B') & (bmp_header->signature[0] == 'M')) {
// We have a BMP file... calculate the starting address of the image data
uint8_t * img_data = (uint8_t *)(bmp_data + bmp_header->offset);
// Get the statistics on the BMP image
uint32_t width = bmp_header->info_header.width;
uint32_t height = bmp_header->info_header.height;
uint32_t bit_count = bmp_header->info_header.bit_count;
uint32_t compression = bmp_header->info_header.compression;
// Dispatch to the correct expansion routine based on the color mode and the compression
switch (bit_count) {
case BMP_BC_INDEX_256:
switch (compression) {
case BMP_RLE8:
// 256 color indexed compressed using RLE8
load_palette(bmp_header->info_header.color_table, (int)bmp_header->info_header.colors_used, clut);
expand_index8_rle8(img_data, width, height, dest_img);
break;
default:
// Unsupported compression for 256 color mode
return BMP_BAD_FORMAT;
}
default:
// Unsupported color mode
return BMP_BAD_FORMAT;
}
return BMP_OK;
} else {
return BMP_BAD_FILETYPE;
}
}

View file

@ -1,29 +0,0 @@
/**
* @file bmp_expand.h
* @author your name (you@domain.com)
* @brief Provide a way to convert some BMP files to a bitmap image
* @version 0.1
* @date 2024-06-07
*
* @copyright Copyright (c) 2024
*
*/
#ifndef __bmp_expand_h__
#define __bmp_expand_h__
extern const short BMP_OK; // BMP file was processed without error
extern const short BMP_BAD_FILETYPE; // File does not have a BMP signature
extern const short BMP_BAD_FORMAT; // BMP file is not in a supported format (color format or compression)
/**
* @brief Render a BMP file into a destination bitmap image and a destination color palette
*
* @param bmp_data pointer to the raw BMP data
* @param dest_img pointer to the area in memory to load the expanded bitmap data
* @param clut the number of the graphics CLUT to use for the image
* @return 0 if image could be processed, any other number is an error
*/
extern short bm_bmp_render(char * bmp_data, char * dest_img, short clut);
#endif

View file

@ -15,9 +15,12 @@
#include <stdlib.h>
#include <string.h>
#include "features.h"
#include "constants.h"
#include "dev/channel.h"
#if HAS_FLOPPY
#include "dev/fdc.h"
#endif
#include "errors.h"
#include "elf.h"
#include "fsys.h"
@ -108,11 +111,13 @@ void fsys_update_stat(const char * path) {
}
}
#if HAS_FLOPPY
if (strncmp(buffer, "/fd", 3) == 0) {
// If the drive is the floppy drive, force the drive to spin up and check for a disk change
// this will update the fdc_status, which will be seen by FatFS and treated appropriately
sys_bdev_ioctrl(BDEV_FDC, FDC_CTRL_CHECK_CHANGE, 0, 0);
}
#endif
}
/**
@ -877,9 +882,11 @@ SYSTEMCALL short fsys_set_label(short drive, const char * label) {
// If the drive being labeled is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
#if HAS_FLOPPY
if (drive == BDEV_FDC) {
sys_bdev_ioctrl(BDEV_FDC, FDC_CTRL_CHECK_CHANGE, 0, 0);
}
#endif
sprintf(buffer, "%d:%s", drive, label);
fres = f_setlabel(buffer);

View file

@ -12,6 +12,8 @@
#ifndef __kbd_f256_h__
#define __kbd_f256_h__
#include "sys_general.h"
#if MODEL == MODEL_FOENIX_F256
#include "kbd_f256jr.h"
#elif MODEL == MODEL_FOENIX_F256K || MODEL == MODEL_FOENIX_F256K2

Some files were not shown because too many files have changed in this diff Show more