F256K2e Optical Keyboard Support

This commit is contained in:
Peter Weingartner 2024-09-19 20:54:59 -04:00
parent ef473f74ac
commit 257f41bd2f
42 changed files with 3077 additions and 1138 deletions

View file

@ -58,6 +58,7 @@ 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);
@ -113,6 +114,7 @@ chan_read .namespace
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);
@ -128,6 +130,7 @@ chan_readline .namespace
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);
@ -142,6 +145,7 @@ 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);
@ -157,6 +161,7 @@ chan_write .namespace
buffer .dword ? ;
size .word ? ;
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_status(short channel);
@ -192,6 +197,7 @@ chan_seek .namespace
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);
@ -208,6 +214,7 @@ 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);
@ -223,6 +230,7 @@ chan_open .namespace
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);
@ -247,6 +255,7 @@ chan_swap .namespace
.virtual 1,s
channel2 .word ? ; the ID of the other channel
.endv
.endn
;
; extern SYSTEMCALL short sys_chan_device(short channel);
@ -293,6 +302,7 @@ 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);
@ -309,6 +319,7 @@ 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);
@ -345,6 +356,7 @@ 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);
@ -359,6 +371,7 @@ 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);
@ -423,6 +436,7 @@ 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);
@ -438,6 +452,7 @@ fsys_findfirst .namespace
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);
@ -452,6 +467,7 @@ 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);
@ -466,6 +482,7 @@ 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);
@ -480,6 +497,7 @@ 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);
@ -514,6 +532,7 @@ 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);
@ -538,6 +557,7 @@ 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);
@ -553,6 +573,7 @@ fsys_load .namespace
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);
@ -567,6 +588,7 @@ 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);
@ -581,6 +603,7 @@ 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();
@ -660,6 +683,7 @@ proc_run .namespace
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);
@ -674,6 +698,7 @@ 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);
@ -689,6 +714,7 @@ txt_set_xy .namespace
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);
@ -703,6 +729,7 @@ 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);
@ -717,6 +744,7 @@ 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);
@ -731,6 +759,7 @@ 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);
@ -746,6 +775,7 @@ txt_set_color .namespace
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);
@ -761,6 +791,7 @@ txt_get_color .namespace
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);
@ -775,6 +806,7 @@ 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);
@ -791,6 +823,7 @@ 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);
@ -806,6 +839,7 @@ txt_get_sizes .namespace
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);
@ -821,6 +855,7 @@ txt_set_border .namespace
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);
@ -837,6 +872,7 @@ 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);
@ -851,6 +887,7 @@ 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);
@ -865,3 +902,4 @@ txt_print .namespace
.virtual 1,s
message .dword ? ; the ASCII Z string to print
.endv
.endn

View file

@ -188,6 +188,7 @@ class Function:
parameter.emit_asm(output)
output.write(" .endv\n")
output.write(" .endn\n")
comments = []

BIN
roms/f256k.zip Normal file

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.

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -70,7 +70,7 @@ endif
INCLUDES=-I. -I./include
CFLAGS=$(INCLUDES) $(CFLAGS_FOR_UNIT) -l # -l -D_CALYPSI_MCP_DEBUGGER
ASFLAGS=$(INCLUDES) --data-model large --code-model large
ASFLAGS=$(INCLUDES) --data-model large --code-model large -l
ifeq ($(MEMORY),ROM)
LDFLAGS=--rom-code $(LDFLAGS_FOR_UNIT) --list-file toolbox.map

View file

@ -518,7 +518,6 @@ void boot_screen() {
jiffies_target = timers_jiffies() + 60 * 15;
while (jiffies_target > timers_jiffies()) {
// kbd_handle_irq();
unsigned short scancode = kbd_get_scancode();
if (scancode > 0) {
short selected = sc_to_function(scancode);

View file

@ -50,7 +50,7 @@ endif
INCLUDES=-I.. -I../include
CFLAGS=$(INCLUDES) $(CFLAGS_FOR_UNIT) -l
ASFLAGS=$(INCLUDES)
ASFLAGS=$(INCLUDES) -l
SRCS = block.c channel.c console.c fsys.c sprites.c tiles.c txt_screen.c rtc.c uart.c $(SRCS_FOR_UNIT) # pata.c bitmap.c dma.c ps2.c sdc.c
OBJS = $(patsubst %.c,%.o,$(SRCS))

View file

@ -471,6 +471,8 @@ SYSTEMCALL void int_clear(unsigned short n) {
}
}
#define vky_text_matrix ((volatile __attribute__((far)) char *)0xf04000)
/**
* @brief Handle incomming IRQ signal
*
@ -482,11 +484,15 @@ SYSTEMCALL void int_clear(unsigned short n) {
void int_handle_irq() {
uint8_t mask_bits = 0;
if (*irq_ram_vector != 0) {
p_int_handler handler = (p_int_handler)(*irq_ram_vector);
handler();
return;
}
// vky_text_matrix[0] += 1;
// if (*irq_ram_vector != 0) {
// p_int_handler handler = (p_int_handler)(*irq_ram_vector);
// handler();
// return;
// }
// vky_text_matrix[1] += 1;
// Process any pending interrupts in group 0
mask_bits = *PENDING_GRP0;
@ -544,9 +550,9 @@ void int_handle_irq() {
* __attribute__((interrupt(0xffea)))
*/
void int_handle_nmi() {
if (*nmi_ram_vector != 0) {
p_int_handler handler = (p_int_handler)(*nmi_ram_vector);
handler();
return;
}
// if (*nmi_ram_vector != 0) {
// p_int_handler handler = (p_int_handler)(*nmi_ram_vector);
// handler();
// return;
// }
}

View file

@ -19,6 +19,7 @@
#include "ring_buffer.h"
#include "dev/kbd_f256k.h"
#include "F256/via_f256.h"
#include "F256/kbd_opt_f256.h"
#include "gabe_reg.h"
#include "simpleio.h"
#include "vicky_general.h"
@ -81,6 +82,7 @@ static const uint8_t kbd_scan_codes[KBD_ROWS][KBD_COLUMNS] = {
// Driver variables
//
static bool is_optical = false;
static uint16_t kbd_stat[KBD_MATRIX_SIZE];
static short counter = 0;
static uint8_t last_press = 0;
@ -216,10 +218,10 @@ unsigned short kbd_get_scancode() {
}
/**
* @brief Handle an IRQ to query the keyboard
* @brief Scan the state of the keys on the mechanical keyboard
*
*/
void kbd_handle_irq() {
void kbd_scan_mechanical() {
uint8_t ifr = via0->ifr;
uint8_t counter_low = via0->t1c_l;
@ -245,6 +247,69 @@ void kbd_handle_irq() {
}
}
/**
* @brief Query the optical keyboard to get the scanned keyboard matrix (if it has any pending data)
*
*/
void kbd_scan_optical() {
if ((KBD_OPTICAL->status & KBD_OPT_STAT_EMPTY) == 0) {
// If there is data pending in the keyboard buffer...
// Read in all the bytes available and fill out the column matrix
uint16_t count = KBD_OPTICAL->count;
for (int x = 0; x < count; x += 2) {
// Get two data bytes
uint8_t byte_hi = KBD_OPTICAL->data;
uint8_t byte_low = KBD_OPTICAL->data;
// Separate out the row number and the column status bits
uint8_t row = (byte_hi >> 4) & 0x07;
uint16_t columns_stat = ((uint16_t)byte_hi << 8 | (uint16_t)byte_low) & 0x01ff;
// Determine which columns have changed on this row
uint16_t columns_eor = kbd_stat[row] ^ columns_stat;
if (columns_eor != 0) {
// If columns have changed...
short column = 0;
// Record the new column values
kbd_stat[row] = columns_stat;
while (columns_eor != 0) {
if (columns_eor & 0x01) {
// Current key changed
kbd_process_key(column, row, columns_stat & 0x01);
}
columns_stat = columns_stat >> 1;
columns_eor = columns_eor >> 1;
column++;
}
}
}
}
}
/**
* @brief Handle an IRQ to query the keyboard
*
*/
void kbd_handle_irq() {
// The scanning process is different depending on the keyboard type:
//
// The mechanical keyboard is a simple matrix of keys, and we need to scan it to see
// which keys are pressed and which are not.
//
// The optical keyboard does more processing for us. If it detects a change, it will
// indicate that it has data for us and then let us read the entire state of the matrix
// as a sequence of bytes.
if (is_optical) {
kbd_scan_optical();
} else {
kbd_scan_mechanical();
}
}
/*
* Check to see if a BREAK code has been pressed recently
* If so, return true and reset the internal flag.
@ -265,6 +330,12 @@ bool kbd_break() {
*
*/
short kbd_sc_init() {
if (KBD_OPTICAL->status & KBD_OPT_STAT_MECH) {
is_optical = false;
} else {
is_optical = true;
}
// Initialize VIA0 -- we'll just read from PB7
via0->ddra = 0x00;
via0->ddrb = 0x00;
@ -272,8 +343,13 @@ short kbd_sc_init() {
via0->pcr = 0x00;
via0->ier = 0x00;
// Initialize VIA1 -- we'll write to all of PB
// Initialize VIA1 -- we'll write to all of PB only if the keyboard is mechanical
if (is_optical) {
// For an optical keyboard, make it read only just to be safe
via1->ddra = 0x00;
} else {
via1->ddra = 0xff;
}
via1->ddrb = 0x00;
via1->acr = 0x00;
via1->pcr = 0x00;
@ -291,14 +367,16 @@ short kbd_sc_init() {
// Set up and clear out the buffer for the scan codes
rb_word_init(&scan_code_buffer);
int_register(INT_VIA0, kbd_handle_irq);
// int_register(INT_VIA0, kbd_handle_irq);
int_register(INT_SOF_A, kbd_handle_irq);
via0->acr = 0x40; // Timer #0 in free running mode
via0->ier = VIA_INT_TIMER1 | VIA_INT_IRQ; // Allow timer #0 interrupts
via0->t1c_l = 0xff; // Set timer count
via0->t1c_h = 0xff;
// via0->acr = 0x40; // Timer #0 in free running mode
// via0->ier = VIA_INT_TIMER1 | VIA_INT_IRQ; // Allow timer #0 interrupts
// via0->t1c_l = 0xff; // Set timer count
// via0->t1c_h = 0xff;
int_enable(INT_VIA0);
// int_enable(INT_VIA0);
int_enable(INT_SOF_A);
return 1;
}

View file

@ -0,0 +1,39 @@
/**
* @file kbd_opt_f256.h
* @brief Define the optical keyboard registers
* @version 0.1
* @date 2024-09-15
*
* @copyright Copyright (c) 2024
*
*/
#ifndef __kbd_opt_f256_h__
#define __kbd_opt_f256_h__
#include <stdint.h>
/**
* @brief Structure representing the F256 optical keyboard
*
* NOTE: data bytes are read consecutively and represent 16-bit words.
* The 4 most significant bits encode the row number (0 - 7).
* The 9 least significant bits contain the column bitfield (a 1
* indicates the key at that column and row is currently pressed).
*
*/
typedef struct s_kbd_optical {
uint8_t data; // Data bytes to read from the keyboard
uint8_t status; // Indicate keyboard type and if the buffer is empty
uint16_t count; // Number of bytes in the keyboard buffer
} t_kbd_optical, *p_kbd_optical;
/*
* Status bit flags
*/
#define KBD_OPT_STAT_MECH 0x80
#define KBD_OPT_STAT_EMPTY 0x01
#define KBD_OPTICAL ((volatile p_kbd_optical)0xf01dc0)
#endif

0
src/monitor.c Normal file
View file

View file

@ -412,9 +412,9 @@ void test_kbd_sc() {
}
void test_kbd() {
printf("Keyboard test... press RUN/STOP or CTRL-C for boot:\n");
printf("> ");
do {
kbd_handle_irq();
char c = kbd_getc();
if (c != 0) {
txt_put(0, c);
@ -476,74 +476,13 @@ int main(int argc, char * argv[]) {
char message[256];
initialize();
kbd_init();
test_sysinfo();
// printf("Foenix Toolbox v%d.%04d.%04d\n", VER_MAJOR, VER_MINOR, VER_BUILD);
// const char * test_data = "Hello, world!";
// volatile uint8_t * cartridge = ((volatile uint8_t *)0xf40000);
// short cartridge_id = cart_id();
// switch(cartridge_id) {
// case CART_ID_NONE:
// printf("No cartridge detected.\n");
// break;
// case CART_ID_RAM:
// printf("RAM cartridge detected.\n");
// break;
// case CART_ID_FLASH:
// printf("FLASH cartridge detected.\n");
// // printf("Attempting to erase the flash cartridge.\n");
// // cart_erase();
// // printf("Attempting to program the flash cartridge.\n");
// // for (int i = 0; i < strlen(test_data); i++) {
// // cart_write(0xf40000 + i, test_data[i]);
// // }
// // for (int j = 0; j < strlen(test_data); j++) {
// // txt_put(0, cartridge[j]);
// // }
// // printf("\n");
// break;
// default:
// printf("Unable to determine whether a cartridge is present.\n");
// break;
// }
// test_kbd();
boot_screen();
while (1) ;
// printf("Initializing IEC\n");
// result = iec_init();
// if (result != 0) {
// printf("Error initializing IEC.\n");
// }
// printf("Attempting to get status for IEC drive #8: ");
// short n = iec_status(8, message, 256);
// printf("\"%s\"\n", message);
// printf("Attempting to write to the printer.\n");
// iec_print(4, "\e1THIS IS PRINTED FROM AN F256K OVER THE IEC PORT!\r");
// Attempt to start up the user code
// log(LOG_INFO, "Looking for user startup code:");
// boot_launch();
printf("Done.\n");
#ifdef _CALYPSI_MCP_DEBUGGER
extern int CalypsiDebugger(void);
CalypsiDebugger(); // This will not return

View file

@ -7,6 +7,6 @@
#define VER_MAJOR 1
#define VER_MINOR 0
#define VER_BUILD 17
#define VER_BUILD 24
#endif

8
tests/kbd_opt/Makefile Normal file
View file

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

1
tests/kbd_opt/README.md Normal file
View file

@ -0,0 +1 @@
# F256K2e Optical Keyboard Test

885
tests/kbd_opt/bindings.s Normal file
View file

@ -0,0 +1,885 @@
;
; extern SYSTEMCALL void sys_exit(short result);
;
; result goes in A[15..0]
;
; 0 bytes needed for the stack parameters
;
sys_exit = $000000
;
; 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

@ -0,0 +1,283 @@
#
# 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)
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)

255
tests/kbd_opt/hello.lst Normal file
View file

@ -0,0 +1,255 @@
; 64tass Turbo Assembler Macro V1.58.2974 listing file
; 64tass --nostart --flat --s-record --list=hello.lst -o optical.s37 optical.s
; Sun Sep 15 20:17:28 2024
;Offset ;Hex ;Monitor ;Source
;****** Processing input file: optical.s
;****** Processing file: toolbox.s
;****** Processing file: bindings.s
=$000000 sys_exit = $000000
=$ffe004 sys_int_enable_all = $ffe004
=$ffe008 sys_int_disable_all = $ffe008
=$ffe00c sys_int_disable = $ffe00c
=$ffe010 sys_int_enable = $ffe010
=$ffe014 sys_int_register = $ffe014
>0001 handler .dword ? ; pointer to the interrupt handler to register
=$ffe018 sys_int_pending = $ffe018
=$ffe01c sys_get_info = $ffe01c
=$ffe020 sys_int_clear = $ffe020
=$ffe024 sys_chan_read_b = $ffe024
=$ffe028 sys_chan_read = $ffe028
>0001 buffer .dword ? ; the buffer into which to copy the channel data
>0005 size .word ? ; the size of the buffer.
=$ffe02c sys_chan_readline = $ffe02c
>0001 buffer .dword ? ; the buffer into which to copy the channel data
>0005 size .word ? ; the size of the buffer
=$ffe030 sys_chan_write_b = $ffe030
>0001 b .byte ? ; the byte to write
=$ffe034 sys_chan_write = $ffe034
>0001 buffer .dword ? ;
>0005 size .word ? ;
=$ffe038 sys_chan_status = $ffe038
=$ffe03c sys_chan_flush = $ffe03c
=$ffe040 sys_chan_seek = $ffe040
>0001 position .dword ? ; the position of the cursor
>0005 base .word ? ; whether the position is absolute or relative to the current position
=$ffe044 sys_chan_ioctrl = $ffe044
>0001 command .word ? ; the number of the command to send
>0003 buffer .dword ? ; pointer to bytes of additional data for the command
>0007 size .word ? ; the size of the buffer
=$ffe048 sys_chan_open = $ffe048
>0001 path .dword ? ; a "path" describing how the device is to be open
>0005 mode .word ? ; s the device to be read, written, both? (0x01 = READ flag, 0x02 = WRITE flag, 0x03 = READ and WRITE)
=$ffe04c sys_chan_close = $ffe04c
=$ffe050 sys_chan_swap = $ffe050
>0001 channel2 .word ? ; the ID of the other channel
=$ffe054 sys_chan_device = $ffe054
=$000000 sys_text_setsizes = $000000
=$ffe05c sys_bdev_register = $ffe05c
=$ffe060 sys_bdev_read = $ffe060
>0001 lba .dword ? ; the logical block address of the block to read
>0005 buffer .dword ? ; the buffer into which to copy the block data
>0009 size .word ? ; the size of the buffer.
=$ffe064 sys_bdev_write = $ffe064
>0001 lba .dword ? ; the logical block address of the block to write
>0005 buffer .dword ? ; the buffer containing the data to write
>0009 size .word ? ; the size of the buffer.
=$ffe068 sys_bdev_status = $ffe068
=$ffe06c sys_bdev_flush = $ffe06c
=$ffe070 sys_bdev_ioctrl = $ffe070
>0001 command .word ? ; the number of the command to send
>0003 buffer .dword ? ; pointer to bytes of additional data for the command
>0007 size .word ? ; the size of the buffer
=$ffe074 sys_fsys_open = $ffe074
>0001 mode .word ? ; the mode (e.g. r/w/create)
=$ffe078 sys_fsys_close = $ffe078
=$ffe07c sys_fsys_opendir = $ffe07c
=$ffe080 sys_fsys_closedir = $ffe080
=$ffe084 sys_fsys_readdir = $ffe084
>0001 file .dword ? ; pointer to the t_file_info structure to fill out.
=$ffe088 sys_fsys_findfirst = $ffe088
>0001 pattern .dword ? ; the file name pattern to search for
>0005 file .dword ? ; pointer to the t_file_info structure to fill out
=$ffe08c sys_fsys_findnext = $ffe08c
>0001 file .dword ? ; pointer to the t_file_info structure to fill out
=$ffe090 sys_fsys_get_label = $ffe090
>0001 label .dword ? ; buffer that will hold the label... should be at least 35 bytes
=$ffe094 sys_fsys_set_label = $ffe094
>0001 label .dword ? ; buffer that holds the label
=$ffe098 sys_fsys_mkdir = $ffe098
=$ffe09c sys_fsys_delete = $ffe09c
=$ffe0a0 sys_fsys_rename = $ffe0a0
>0001 new_path .dword ? ; the new path for the file
=$ffe0a4 sys_fsys_set_cwd = $ffe0a4
=$ffe0a8 sys_fsys_get_cwd = $ffe0a8
>0001 size .word ? ; the size of the buffer in bytes
=$ffe0ac sys_fsys_load = $ffe0ac
>0001 destination .dword ? ; the destination address (0 for use file's address)
>0005 start .dword ? ; pointer to the long variable to fill with the starting address
=$ffe0b0 sys_fsys_register_loader = $ffe0b0
>0001 loader .dword ? ; pointer to the file load routine to add
=$ffe0b4 sys_fsys_stat = $ffe0b4
>0001 file .dword ? ; pointer to a file info record to fill in, if the file is found.
=$ffe0b8 sys_mem_get_ramtop = $ffe0b8
=$ffe0bc sys_mem_reserve = $ffe0bc
=$ffe0c0 sys_time_jiffies = $ffe0c0
=$ffe0c4 sys_rtc_set_time = $ffe0c4
=$ffe0c8 sys_rtc_get_time = $ffe0c8
=$ffe0cc sys_kbd_scancode = $ffe0cc
=$ffe0d4 sys_kbd_layout = $ffe0d4
=$ffe0d8 sys_proc_run = $ffe0d8
>0001 argc .dword ? ; the number of arguments passed
>0005 argv .dword ? ; the array of string arguments
=$ffe0e0 sys_txt_set_mode = $ffe0e0
>0001 mode .word ? ; a bitfield of desired display mode options
=$ffe0e8 sys_txt_set_xy = $ffe0e8
>0001 x .word ? ; the column for the cursor
>0003 y .word ? ; the row for the cursor
=$ffe0ec sys_txt_get_xy = $ffe0ec
>0001 position .dword ? ; pointer to a t_point record to fill out
=$ffe0f0 sys_txt_get_region = $ffe0f0
>0001 region .dword ? ; pointer to a t_rect describing the rectangular region (using character cells for size and size)
=$ffe0f4 sys_txt_set_region = $ffe0f4
>0001 region .dword ? ; pointer to a t_rect describing the rectangular region (using character cells for size and size)
=$ffe0f8 sys_txt_set_color = $ffe0f8
>0001 foreground .byte ? ; the Text LUT index of the new current foreground color (0 - 15)
>0002 background .byte ? ; the Text LUT index of the new current background color (0 - 15)
=$ffe0fc sys_txt_get_color = $ffe0fc
>0001 foreground .dword ? ; the Text LUT index of the new current foreground color (0 - 15)
>0005 background .dword ? ; the Text LUT index of the new current background color (0 - 15)
=$ffe100 sys_txt_set_cursor_visible = $ffe100
>0001 is_visible .word ? ; TRUE if the cursor should be visible, FALSE (0) otherwise
=$ffe104 sys_txt_set_font = $ffe104
>0001 width .word ? ; width of a character in pixels
>0003 height .word ? ; of a character in pixels
>0005 data .dword ? ; pointer to the raw font data to be loaded
=$ffe108 sys_txt_get_sizes = $ffe108
>0001 text_size .dword ? ; the size of the screen in visible characters (may be null)
>0005 pixel_size .dword ? ; the size of the screen in pixels (may be null)
=$ffe10c sys_txt_set_border = $ffe10c
>0001 width .word ? ; the horizontal size of one side of the border (0 - 32 pixels)
>0003 height .word ? ; the vertical size of one side of the border (0 - 32 pixels)
=$ffe110 sys_txt_set_border_color = $ffe110
>0001 red .byte ? ; the red component of the color (0 - 255)
>0002 green .byte ? ; the green component of the color (0 - 255)
>0003 blue .byte ? ; the blue component of the color (0 - 255)
=$ffe114 sys_txt_put = $ffe114
>0001 c .byte ? ; the character to print
=$ffe118 sys_txt_print = $ffe118
>0001 message .dword ? ; the ASCII Z string to print
;****** Return to file: toolbox.s
;****** Return to file: optical.s
;****** Processing file: macros.s
;****** Return to file: optical.s
=$f01dc0 kbd_opt_data = $f01dc0 ; 8-bit
=$f01dc1 kbd_opt_stat = $f01dc1 ; 8-bit
=$f01dc2 kbd_opt_cnt = $f01dc2 ; 16-bit
=$f04000 vky_text = $f04000
>0000 save_a .word ?
>0002 kbd_stat .byte ?
>0003 scancode .word ?
>0005 offset .word ?
>0007 code .word ?
>0009 count .word ?
>000b tmp .word ?
>010000 f8 16 header: .byte $f8, $16 ; Signature
>010002 00 .byte 0 ; Version
>010003 17 00 01 00 .dword start ; Starting address
>010007 00 00 00 00 .dword 0 ; Icon address
>01000b 00 00 00 00 .dword 0 ; Icon palette address
>01000f 6f 70 74 69 63 61 6c 00 .null "optical" ; Name of the file
.010017 18 clc start: clc
.010018 fb xce xce
.010019 f4 01 01 pea #$0101 PEA #((`start) * 256) + (`start)
.01001c ab plb PLB
.01001d ab plb PLB
.01001e c2 30 rep #$30 REP #$30 ; set A&X long
.010020 a9 50 00 lda #$0050 wait_line: lda #80
.010023 85 05 sta $05 sta offset
.010025 e2 20 sep #$20 SEP #$20 ; set A short
.010027 af c1 1d f0 lda $f01dc1 lda @l kbd_opt_stat
.01002b 20 9b 00 jsr $01009b jsr puthex8
.01002e a9 20 lda #$20 lda #' '
.010030 20 6d 00 jsr $01006d jsr putc
.010033 wait:
.010033 e2 20 sep #$20 SEP #$20 ; set A short
.010035 af c1 1d f0 lda $f01dc1 lda @l kbd_opt_stat
.010039 29 01 and #$01 and #$01
.01003b c9 01 cmp #$01 cmp #$01
.01003d f0 f4 beq $010033 beq wait
.01003f c2 20 rep #$20 REP #$20 ; set A long
.010041 af c2 1d f0 lda $f01dc2 lda @l kbd_opt_cnt
.010045 85 09 sta $09 sta count
.010047 e2 20 sep #$20 SEP #$20 ; set A short
.010049 af c0 1d f0 lda $f01dc0 lda @l kbd_opt_data
.01004d 20 9b 00 jsr $01009b jsr puthex8
.010050 e2 20 sep #$20 SEP #$20 ; set A short
.010052 af c0 1d f0 lda $f01dc0 lda @l kbd_opt_data
.010056 20 9b 00 jsr $01009b jsr puthex8
.010059 e2 20 sep #$20 SEP #$20 ; set A short
.01005b a9 20 lda #$20 lda #' '
.01005d 20 6d 00 jsr $01006d jsr putc
.010060 c2 20 rep #$20 REP #$20 ; set A long
.010062 c6 09 dec $09 dec count
.010064 c6 09 dec $09 dec count
.010066 f0 b8 beq $010020 beq wait_line
.010068 80 c9 bra $010033 bra wait
.01006a ea nop loop: nop
.01006b 80 fd bra $01006a bra loop
.01006d putc:
.01006d 08 php php
.01006e da phx phx
.01006f a6 05 ldx $05 ldx offset
.010071 9f 00 40 f0 sta $f04000,x sta vky_text,x
.010075 e6 05 inc $05 inc offset
.010077 fa plx plx
.010078 28 plp plp
.010079 60 rts rts
>01007a 30 31 32 33 34 35 36 37 hexdigits: .null '0123456789ABCDEF'
>010082 38 39 41 42 43 44 45 46 00
.01008b puthex4:
.01008b da phx phx
.01008c 08 php php
.01008d e2 30 sep #$30 SEP #$30 ; set A&X short
.01008f 29 0f and #$0f and #$0f
.010091 aa tax tax
.010092 bd 7a 00 lda $01007a,x lda hexdigits,x
.010095 20 6d 00 jsr $01006d jsr putc
.010098 28 plp plp
.010099 fa plx plx
.01009a 60 rts rts
.01009b puthex8:
.01009b 08 php php
.01009c e2 20 sep #$20 SEP #$20 ; set A short
.01009e 85 00 sta $00 sta save_a
.0100a0 4a lsr a lsr a
.0100a1 4a lsr a lsr a
.0100a2 4a lsr a lsr a
.0100a3 4a lsr a lsr a
.0100a4 29 0f and #$0f and #$0f
.0100a6 20 8b 00 jsr $01008b jsr puthex4
.0100a9 a5 00 lda $00 lda save_a
.0100ab 29 0f and #$0f and #$0f
.0100ad 20 8b 00 jsr $01008b jsr puthex4
.0100b0 28 plp plp
.0100b1 60 rts rts
>0100b2 48 65 6c 6c 6f 2c 20 46 message: .null "Hello, Foenix Toolbox (64TASS)!",13,10
>0100ba 6f 65 6e 69 78 20 54 6f 6f 6c 62 6f 78 20 28 36
>0100ca 34 54 41 53 53 29 21 0d 0a 00
;****** End of listing

52
tests/kbd_opt/macros.s Normal file
View file

@ -0,0 +1,52 @@
; Set 8-bit accumulator
setaxs .macro
SEP #$30 ; set A&X short
.as
.xs
.endm
; Set 16-bit accumulator
setaxl .macro
REP #$30 ; set A&X long
.al
.xl
.endm
; Set 8-bit accumulator
setas .macro
SEP #$20 ; set A short
.as
.endm
; Set 16-bit accumulator
setal .macro
REP #$20 ; set A long
.al
.endm
; Set 8 bit index registers
setxs .macro
SEP #$10 ; set X short
.xs
.endm
; Set 16-bit index registers
setxl .macro
REP #$10 ; set X long
.xl
.endm
; Set the direct page.
; Note: This uses the accumulator and leaves A set to 16 bits.
setdp .macro
PEA #\1 ; set DP to page 0
PLD
.dpage \1
.endm
setdbr .macro ; Set the B (Data bank) register
PEA #((\1) * 256) + (\1)
PLB
PLB
.databank \1
.endm

170
tests/kbd_opt/optical.s Normal file
View file

@ -0,0 +1,170 @@
;;;
;;; A simple client program for the Foenix Toolbox using 64TASS
;;;
.cpu "65816"
.include "toolbox.s"
.include "macros.s"
kbd_opt_data = $f01dc0 ; 8-bit
kbd_opt_stat = $f01dc1 ; 8-bit
kbd_opt_cnt = $f01dc2 ; 16-bit
vky_text = $f04000
* = $10000
.virtual 0,d
save_a .word ?
kbd_stat .byte ?
scancode .word ?
offset .word ?
code .word ?
count .word ?
tmp .word ?
.endv
header: .byte $f8, $16 ; Signature
.byte 0 ; Version
.dword start ; Starting address
.dword 0 ; Icon address
.dword 0 ; Icon palette address
.null "optical" ; Name of the file
start: clc
xce
setdbr `start
setaxl
wait_line: lda #80
sta offset
setas
lda @l kbd_opt_stat
jsr puthex8
lda #' '
jsr putc
wait: setas
lda @l kbd_opt_stat
and #$01
cmp #$01
beq wait
setal
lda @l kbd_opt_cnt
sta count
setas
lda @l kbd_opt_data
jsr puthex8
setas
lda @l kbd_opt_data
jsr puthex8
setas
lda #' '
jsr putc
setal
dec count
dec count
beq wait_line
bra wait
loop: nop
bra loop
;
; Print the character in A
;
putc: .proc
php
phx
ldx offset
sta vky_text,x
inc offset
plx
plp
rts
.pend
hexdigits: .null '0123456789ABCDEF'
;
; Print the 4-bit hex digit in A
;
puthex4: .proc
phx
php
setaxs
and #$0f
tax
lda hexdigits,x
jsr putc
plp
plx
rts
.pend
;
; Print the 8-bit hex number in A
;
puthex8: .proc
php
setas
sta save_a
lsr a
lsr a
lsr a
lsr a
and #$0f
jsr puthex4
lda save_a
and #$0f
jsr puthex4
plp
rts
.pend
;
; Print the 16-bit hex number in A
;
puthex16: .proc
php
setaxl
sta code
.rept 8
lsr a
.next
and #$00ff
jsr puthex8
setaxl
lda code
and #$00ff
jsr puthex8
plp
rts
.pend
message: .null "Hello, Foenix Toolbox (64TASS)!",13,10

10
tests/kbd_opt/optical.s37 Normal file
View file

@ -0,0 +1,10 @@
S00600004844521B
S224010000F816001700010000000000000000006F70746963616C0018FBF40101ABABC23077
S224010020A950008505E220AFC11DF0209B00A920206D00E220AFC11DF02901C901F0F4C28E
S22401004020AFC21DF08509E220AFC01DF0209B00E220AFC01DF0209B00E220A920206D00A4
S224010060C220C609C609F0B880C9EA80FD08DAA6059F0040F0E605FA2860303132333435AA
S2240100803637383941424344454600DA08E230290FAABD7A00206D0028FA6008E22085003C
S2240100A04A4A4A4A290F208B00A500290F208B00286048656C6C6F2C20466F656E69782056
S2180100C0546F6F6C626F78202836345441535329210D0A00F1
S5030007F5
S804010000FA

69
tests/kbd_opt/toolbox.s Normal file
View file

@ -0,0 +1,69 @@
;;;
;;; 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

100
tests/kbd_opt/types.s Normal file
View file

@ -0,0 +1,100 @@
;;;
;;; 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