Table of Contents
FLOS v612 Kernal Manual
The following FLOS kernal routines can be executed simply by using a “CALL name” instruction, with registers pre-set to the routines requirements (Remember to INCLUDE the labels definitions from the equates folder.)
EG: --------------------------------------------------------------------------------- LD HL, my_text CALL kjt_print_string [rest of program..] my_text DB "HELLO WORLD!",0 ----------------------------------------------------------------------------------
Notes
- Kernal calls should not be made when the Video RAM is paged in. The only routine that is guaranteed to work in that situation is “kjt_page_out_video”
- It should be assumed that Kernal calls trash all registers, unless a routine's documentation says otherwise.
Kernal Call Index
File System Routines
kjt_change_dir | Change to subdirectory |
kjt_change_volume | Selects drives VOL0: to VOL7: |
kjt_check_volume_format | Checks if current volume is formatted to FAT16. |
kjt_continue_file_read | Same as KJT_READ_FROM_FILE except this does not set the load address/bank (uses working values instead) |
kjt_create_file | Makes a new file stub |
kjt_delete_dir | Deletes an (empty) directory |
kjt_dir_list_first_entry | Find first entry in current directory |
kjt_dir_list_get_entry | Returns data from directory list (see output registers) |
kjt_dir_list_next_entry | Moves directory list pointer to the next entry |
kjt_erase_file | Deletes a file |
kjt_format_device | Formats entire SD card to FAT16 |
kjt_get_device_info | Returns info about the storage devices |
kjt_get_dir_name | Returns the name of the current directory |
kjt_get_dir_cluster | Returns the cluster address of the current dir |
kjt_get_fs_vars_location | Returns address of Filesystem's control variables |
kjt_get_total_sectors | Returns total sectors on current volume |
kjt_get_volume_info | Returns data about the volumes mounted |
kjt_load_file | Loads a file in its entirety from disk to RAM |
kjt_make_dir | Creates a new sub directory in current directory |
kjt_mount_volumes | Initializes the attached disk list |
kjt_open_file | Looks for a file on current disk, resets file pointer etc |
kjt_parent_dir | Move up a directory level |
kjt_root_dir | Go to root directory of drive |
kjt_read_from_file | Reads data from the opened file to RAM |
kjt_rename_file | Renames files and directories |
kjt_restore_dir_position | Legacy routine: In preference, use KJT_SET_DIR_CLUSTER with previously saved value in DE |
kjt_save_file | Creates and saves a file from RAM to disk |
kjt_set_dir_cluster | Sets the dir from a cluster address |
kjt_set_file_pointer | Moves the read point from the start of a file |
kjt_set_load_address | Specifies the load address and bank for a file read (when using KJT_continue_file_read) |
kjt_set_read_length | Sets the read length of a file transfer to a certain value |
kjt_store_dir_position | Legacy routine: In preference, Use KJT_GET_DIR_CLUSTER and save DE externally |
kjt_write_to_file | Appends new data to an existing file |
kjt_parse_path | Changes volume / directory according to a path string (basically, run the CD command) |
Low-Level Sector Access Routines
kjt_file_sector_list | To list the disk sectors that files occupy |
kjt_get_sector_read_addr | Returns data and pointers allowing sector buffer relocation etc |
kjt_read_sector | Loads 512 byte sector to the sector buffer |
kjt_write_sector | Writes 512 byte sector to the current device |
Kernal Serial Comms Routines
kjt_serial_receive_header | Waits for a file header from serial port |
kjt_serial_receive_file | Receives serial file data |
kjt_serial_rx_byte | Wait for a byte from serial port |
kjt_serial_send_file | Sends a file to serial port (Serial Link App format) |
kjt_serial_tx_byte | Send a byte to serial port |
Kernal Keyboard And Mouse Routines
kjt_enable_mouse | Activates mouse driver (enables IRQ etc) |
kjt_get_key | Returns value of key, if one has been pressed (does not wait) |
kjt_get_key_buffer | Allows monitoring of the keyboard without affecting the buffer |
kjt_get_key_mod_flags | Returns status of the shift, ctrl, alt etc keys |
kjt_get_mouse_position | Returns absolute mouse position and button data |
kjt_get_mouse_motion | Returns relative mouse displacement |
kjt_keyboard_irq_code | Allows external apps to invoke FLOS keybaord IRQ code |
kjt_mouse_irq_code | Allows external apps to invoke FLOS mouse IRQ code |
kjt_wait_key_press | Pauses until a key is pressed |
Kernal Text and Display Routines
kjt_clear_screen | Clears OS screen and sets cursor position to top left (0,0) |
kjt_draw_cursor | Draws (or removes) the cursor at the current cursor position |
kjt_flos_display | Renamed to kjt_flos_settings |
kjt_get_colours | Returns RGB values of the FLOS border, paper, cursor and colour list location |
kjt_get_cursor_position | Returns the current cursor position |
kjt_get_display_size | Returns size of OS_window |
kjt_get_charmap_addr_xy | Returns the charmap address of coordinates x,y |
kjt_get_input_string | Waits for user to enter a string of characters |
kjt_get_pen | Returns current pen colour |
kjt_patch_font | Allows easy (and individual) user defined characters in the FLOS font |
kjt_plot_char | Prints character at given coords using current pen colours |
kjt_print_string | Prints ASCII text string at the current cursor position |
kjt_scroll_up | Scrolls the screen (and character map) up a line |
kjt_set_colours | Sets FLOS border, paper and cursor colours and writes to the pen colour list |
kjt_set_cursor_position | Repositions the text printing (cursor) position |
kjt_set_pen | Changes current pen colour |
kjt_wait_vrt | Wait for vertical retrace (IE: last scanline of display) |
Kernal Memory Management Routines
kjt_inc_bank | Change to the next bank |
kjt_get_bank | Returns the current bank number in A |
kjt_get_flos_bank | Returns the bank seelcted by FLOS before the current command executed |
kjt_page_in_video | Pages video memory into $2000-$3FFF |
kjt_page_out_video | Pages system memory into $2000-$3FFF |
kjt_read_sysram_flat | Read flat system memory location (E:HL) into A |
kjt_read_baddr | Reads a byte into A from address BANK:ADDRESS |
kjt_set_bank | Switches the upper RAM page to a specific bank |
kjt_write_baddr | Writes a byte from A into address BANK:ADDRESS |
kjt_write_sysram_flat | Write A into flat system memory location (E:HL) |
Kernal Misc Routines
kjt_ascii_to_hex_word | Converts ASCII hex number at HL to numeric 16bit hex in DE |
kjt_ascii_to_hex32 | Converts ASCII hex number at HL to numeric 32bit hex in BC:DE |
kjt_bchl_memfill | Fill memory with value in accumulator |
kjt_compare_strings | Compares two ASCII strings |
kjt_dont_store_registers | Stops FLOS updating the stored register values when program quits |
kjt_get_version | Returns FLOS and OSCA version |
kjt_hex_byte_to_ascii | Makes ASCII version of a numeric hex byte |
kjt_set_commander | Specifies a command string to be run when programs exit |
kjt_timer_wait | Waits n periods of 16 microseconds and returns |
kjt_flos_settings | Restores the FLOS video mode, sets up FLOS IRQs, clears keyboard buffer etc |
Environment Variable Routines
kjt_delete_envar | Deletes an environment variable |
kjt_get_envar | Gets (address of) value of an environment variable |
kjt_set_envar | Sets/updates an environment variable |
File System Related Calls
Some Details:
There are two main ways to load a file, a simple single-call approach and a more flexible random-access approach.
To do a simple file load, set HL to a zero terminated ASCII filename string, IX to the destination address and B to the destination bank, then call “kjt_load_file” Check the return code - see table below - if the zero flag is set, everything is OK.
The more flexible way to load file data is as follows: Set HL to a zero terminated ASCII filename string and call “kjt_open_file”. If the zero flag is set on return, the file was found and the length of the file will be in IX:IY (if the zero flag is not set, check the error code).
Next, the following two routines can be called *if required*
“kjt_set_file_pointer” - This allows data to be read from anywhere within a file,
instead of right from the start. Registers required:
- IX:IY = Offset in bytes from start of file
“kjt_set_read_length” - This allows the length of transfer to be set. Registers required:
- IX:IY = Bytes to load
Finally, call “kjt_read_from_file” to transfer the data to memory. Registers required:
- HL = Load address
- B = Bank of load address
Again, on return, if the zero flag is set then the operation completed OK.
The file pointer is automatically incremented by the number of bytes transferred, therefore it is not necessary call “kjt_set_file_pointer” each time if chunks of a file are required sequentially. Attempting to read beyond the end of a file will return an error (code $1B). The load length MUST be set for each read (and load address and bank set appropriately each call).
To maintain speed, a fresh seek from the start of the file is not performed each time “kjt_read_from_file” is called unless the file pointer has been changed. Internal variables must be maintained, therefore do not perform any other disk / serial operations (or anything that changes the sector buffer) between successive calls to this routine.
Whenever a disk file transfer reaches address $FFFF, it wraps around to $8000 and continues on into the next bank.
Most of the file system kernal calls return one of these standard error codes:
- If the zero flag is set, the operation was a success
- If the zero flag is not set, there was an error. A = error code:
$01 | disk full |
$02 | file not found |
$03 | (root) dir table is full |
$04 | directory requested is actually a file |
$05 | can't delete dir, it is not empty |
$06 | not a file |
$07 | file length is zero |
$08 | address error (file too big for memory) |
$09 | filename already exists |
$0a | already at root directory |
$0e | invalid volume |
$13 | unknown/incorrect disk format |
$1b | requested bytes beyond end of file |
$22 | device not present |
$23 | directory not found |
$24 | end of directory list |
$2e | device does not use MBR |
Advanced:
In FLOS v599 the following routines were added to allow external programs to hook into the filesystem variables used by FLOS:
The data at the returned location (see link for format) can be backed up and restored by a user program, allowing multiple open files to managed etc.
Notes:
- When restoring altered variable data, the first byte “fs_filepointer_valid” should always be cleared so that filesystem correctly re-seeks from the start of files.
- The current volume number must be handled seperarately if files on multiple volumes are to be handled.
Additionally, the following two new routines were added:
kjt_continue_file_read
kjt_set_load_address
The normal file read call kjt_read_from_file requires the bank and address to be specified, which may be a nuisance when working with multiple files. With the kjt_continue_file_read routine, the file bytes are written to an address from the end of the last read operation. kjt_set_load_address sets the address and bank to a specific location.
kjt_check_volume_format
Action: Checks if current volume is available and formatted to FAT16
Input Registers :
- None
Output Registers :
- Standard error codes
kjt_change_volume
Action: Selects a new volume (the directory will be that which was last selected in the new volume)
Input Registers :
- A = volume to select
Output Registers :
- Standard error codes
Note: Will not allow a change to an invalid Volume (non-FAT16 etc)
kjt_format_device
Action: Formats a device (entire drive as single partition, no MBR)
Input Registers :
- A = Device to format (0 = DEV0: (SD_Card), 1 = DEV1: (user driver 1)
- HL = Address of desired disk label ASCII string
Output Registers :
- Standard error codes
Note: It is highly recommended that “kjt_mount_volumes” is called after this routine.
kjt_make_dir
Action: Creates a new sub directory in current directory
Input Registers :
- HL = zero terminated dir name
Output Registers :
- Standard error codes
kjt_change_dir
Action: Change to subdirectory
Input Registers :
- HL = zero terminated dir name
Output Registers :
- Standard error codes
kjt_parent_dir
Action: Move up a directory level
Input Registers :
- None
Output Registers :
- Standard error codes
kjt_root_dir
Action: Go to root directory of volume
Input Registers :
- None
Output Registers :
- Standard error codes
kjt_delete_dir
Action: Deletes an (empty) subdirectory
Input Registers :
- HL = zero terminated dir name
Output Registers :
- Standard error codes
kjt_erase_file
Action: Deletes a file in the current directory
Input Registers:
- HL = zero terminated file name
Output Registers :
- Standard error codes
kjt_get_total_sectors
Action: Returns total sectors on current volume
Input Registers :
- none
Output Registers :
- C:DE = number of sectors
kjt_load_file
Action: Loads the specified file from current directory in its entirity to the specifed address.
Input registers :
- IX = address to load to
- B = bank to load to
- HL = zero terminated filename
Output registers :
- Standard error codes
Note: This routine both opens a file and reads all the data to RAM - for more flexibility use “kjt_open_file”, “kjt_set_file_pointer”, “kjt_set_read_length” and “kjt_read_file_data“
kjt_save_file
Action: Saves a file to current directory.
Input registers:
- IX = Source data start address
- B = bank to save data from
- C:DE = number of bytes to save
- HL = zero terminated filename
Output registers:
- Standard error codes
Note: This routine both creates a new file and saves data to it - it cannot be used append new data to an existing file (will return “file already exists” error if attempted).
kjt_open_file
Action: Looks for a file in current directory and sets internal registers ready for ”kjt_read_from_file” call.
Input Registers :
- HL = pointer to zero terminated filename to look for
Output Registers :
If the Zero Flag is set: All OK. Registers are:
- IX:IY = Length of file
- DE = First disk cluster used by file
If zero flag is not set: standard error codes.
Note: File pointer is set to 0, default transfer length = total file size
kjt_set_file_pointer
Action: Moves the read point from the start of a file
Input Registers :
- IX:IY = Offset in bytes from start of file.
Output Registers :
- none
Note: Use after “kjt_open_file” (if required)
kjt_set_read_length
Action: Forces the read length of the file transfer to a certain value
Input Registers :
- IX:IY = Bytes to load
Output Registers :
- none
Note: Use after kjt_find_file (if desired)
kjt_read_from_file
Action: Loads data (from the previously opened file) to a specified address.
Input Registers :
- HL = Destination address
- B = Destination bank
Output Registers :
- Standard error codes
Notes
- “kjt_open_file” MUST be called first before using this routine.
- Whenever a disk file transfer reaches address $FFFF, it wraps around to $8000 and continues onto the next bank.
kjt_create_file
Action: Makes a file stub for a new file in current directory.
Input Registers :
- HL = address of zero-terminated filename
Output Registers :
- Standard error codes
kjt_write_to_file
Action: Appends new data to an existing file in current directory.
Input Registers :
- HL = null-terminated ascii filename of file to be appended to
- IX = address of source data
- B = bank of source data
- C:DE = number of bytes to write
Output Registers :
- Standard error codes
Note: Returns “file not found” error if the file has not been previously created with “kjt_create_file” or “kjt_save_file“
kjt_dir_list_first_entry
Action: Finds the first listing of current directory, returns info.
Input registers:
- None
Output registers:
If zero flag is set:
- HL = Location of null terminated filename string
- IX:IY = Length of file (if applicable)
- B = File flag (1 = directory, 0 = file)
If zero flag is not set, standard error codes (EG: $24 = Reached end of directory)
kjt_dir_list_get_entry
Action: Returns data about the entry at the current position in the directory list.
Input registers :
- None
Output registers :
If zero flag is set:
- HL = Location of null terminated filename string
- IX:IY = Length of file (if applicable)
- B = File flag (1 = directory, 0 = file)
If zero flag is not set, standard error codes (EG: $24 = Reached end of directory)
kjt_dir_list_next_entry
Action: Moves the internal directory list pointer to the next entry and returns details about the entry found
Input registers :
- None
Output registers:
If zero flag is set:
- HL = Location of null terminated filename string
- IX:IY = Length of file (if applicable)
- B = File flag (1 = directory, 0 = file)
If zero flag is not set, standard error codes (EG: $24 = Reached end of directory)
kjt_get_dir_name
Action: Returns ascii string of current directory name (null terminated)
Input registers :
- None
Output registers :
If zero flag set:
- HL = ascii string
If zero flag is not set, standard error codes
kjt_mount_volumes
Action: Reinitializes the drives and mount list
Input registers :
- If A = 1, mount quietly (no text output)
Output registers :
- None
Note: Also attempts to create the assign Envar 'EX0' for VOL0:COMMANDS (FLOS v609+)
kjt_get_volume_info
Action: Returns info about the volumes mounted.
Input Registers :
- None
Output Registers :
- HL = address of volume mount list
- B = Number of volumes mounted
- A = currently Selected volume
kjt_get_device_info
Action: Returns info from the device list.
Input Registers :
- None
Output Registers :
- HL = address of device info table
- DE = address of driver table
- B = number of devices initialized
- A = current active driver number
kjt_get_dir_cluster
Action: Returns the location of the directory cluster
Input Registers :
- None
Output Registers :
- DE = cluster pointed at by current directory
kjt_set_dir_cluster
Action: Sets the directory cluster (for use with above command)
Input Registers :
- DE = desired cluster number to be used as current dir
Output Registers :
- None
Note: The routine attempts to validate the dir by looking for the directory name, if this fails, the dir is set to ROOT and error code $23 is returned (DIR not found).
kjt_rename_file
Action: Rename files / folders.
Input Registers :
- HL = Pointer to filename to change (null terminated ASCII)
- DE = Pointer to replacement filename (null terminated ASCII)
Output Registers :
- Standard error codes
kjt_get_fs_vars_location
Action: Sets HL to the address of the filesystem's control variables.
Input Registers :
- None
Output Registers :
- HL = location of the following data structure:
$00 byte | fs_filepointer_valid |
$01 longword | fs_file_pointer |
$05 longword | fs_file_length |
$09 longword | fs_bytes_to_go |
$0d word | fs_file_start_cluster |
$0f word | fs_file_working_cluster |
$11 word | fs_z80_address |
$13 byte | fs_z80_bank |
Note: When restoring altered data, the first byte “fs_filepointer_valid” should always be cleared. This causes the read operations to cleanly seek from the beginning of files when file transfer (re)commences. (Access will be noticeably slower than a single continuous load.)
kjt_continue_file_read
Action: Same as kjt_read_from_file except this does not set the load address/bank
Input Registers :
- None
Output Registers :
- Standard error codes
kjt_set_load_address
Action: Specifies the load address and bank for a file read (when using kjt_continue_file_read)
Input Registers :
- HL = Z80 address where data should load
- B = FLOS bank where data should load
Output Registers :
- None
kjt_parse_path
(added in FLOS v607)
Action: Changes volume and directory according to the path string supplied. This is basically the same as the “CD” command.
Input Registers :
- HL = Address of path string
Output Registers :
- Standard error codes
Note: If the path is invalid (dir or volume not found) an error code is returned and the dir remains unchanged.
Low-Level Disk Sector Access Routines
kjt_read_sector
Action: Loads a 512 byte sector from the device and address selected to the sector buffer
Input registers :
- A = Device number to access (normally 0)
- BC:DE = absolute LBA address for desired sector
Output registers :
- Standard error codes (relevant errrors: $1e, $22)
kjt_write_sector
Action: Writes a 512 byte sector from the sector buffer to the device and address selected
Input registers :
- A = Device number to access (normally 0)
- BC:DE = absolute LBA address for desired sector
Output registers :
- Standard error codes (relevant errrors: $1e, $22)
kjt_file_sector_list
Action: Retrieves the location of the (next) disk sector that a file occupies.
Input registers:
- A = Sector offset (within current cluster)
- DE = Cluster number
Output registers:
- A = Next sector offset
- DE = Updated cluster
- HL = Memory address of LSB of 4 byte sector location
How to use:
To obtain the list of sectors that a file uses, first call ”kjt_find_file” with the filename in HL as normal. On exit, DE will be equal the first cluster that the file occupies. Clear the accumulator (as we're starting at the first sector of this cluster), and call “kjt_file_sector_list”. On return A and DE are updated to the values required for the next time the routine is called and HL points to the lowest significant byte of the sector address (LBA0). Next, copy the 4 bytes from HL to HL+3 to your sector list buffer and loop around, calling “kjt_file_sector_list” for as many sectors as are used by the file (simply subtract 512 from a variable holding the file size every call until variable is = < 0)
kjt_get_sector_read_addr
Action: Returns the address of the selected drive's sector read routine, also LBA variable and sector_location_variable
Input Registers :
- A = Device to access (normally 0)
Output Registers :
- HL = Address of sector read routine
- DE = Address of the LSB of the 32bit LBA variable
- BC = Address of the sector buffer location variable
Notes
- This routine can be used to allow programs to read sectors directly to an arbitrary location in memory (IE: A program can write to the sector LBA and sector buffer location variables, and then call the low-level sector read routine using the data obtained).
- The sector buffer location is automatically reset to the location that the OS requires whenever a filesystem routine is called (this includes the KJT read/write sector calls above.) Similarly, altering the LBA variable manually should not affect normal operation of the filesystem.
Serial I/O Routines
To load a file serially you would call: kjt_serial_receive_header, setting A and HL as appropriate (see docs below). Once it has been received, kjt_serial_receive_file may be called (setting B and HL appropriately).
As with the disk routines, whenever a serial file transfer command reaches address $FFFF, it wraps around to $8000 and continues onto the next bank.
kjt_serial_receive_header
Action: Waits for a file header from serial port.
Input Registers :
- HL = Location of null terminated filename (filename can be “*” if any file is to be accepted).
- A = described in following table
Bits 5:0 | Waiting time in seconds before time out error |
Bit 6 | Allow abort with Enter Key (if 1) |
Bit 7 | Allow abort with ESC Key (if 1) |
Output Registers :
Zero Flag: If set, all OK
- IX = location of serial file header (see Serial Link Info for details)
If Zero Flag is NOT set, A = serial error code:
$07 | Save length is zero |
$08 | File too big (IE: Memory address out of range) |
$0f | Checksum bad |
$11 | Comms error |
$14 | Time out error |
$25 | Filename mismatch |
$2A | Aborted with ESC / Enter key |
kjt_serial_receive_file
Action: Receives serial file data
Input Registers :
- HL = Address to load file to
- B = Bank to load file into
Output Registers :
Zero Flag: If set, all OK
- IX = location of of serial file header
If Zero Flag is NOT set, A = serial error code:
$07 | Save length is zero |
$08 | File too big (IE: Memory address out of range) |
$0f | Checksum bad |
$11 | Comms error |
$14 | Time out error |
$25 | Filename mismatch |
Note: “kjt_serial_receive_header” MUST be called before this routine!
kjt_serial_send_file
Action: Sends a file to serial port (Serial Link App format)
Input Registers :
- HL = filename
- C:DE = length of file
- B = Bank number that file starts in
- IX = Start address
Output Registers :
Zero flag, set if all OK.
If zero flag not set, A = serial error code:
$07 | Save length is zero |
$08 | File too big (IE: Memory address out of range) |
$0f | Checksum bad |
$11 | Comms error |
$14 | Time out error |
$25 | Filename mismatch |
kjt_serial_rx_byte
Action: Wait for a byte from serial port
Input Registers :
- A. Bits described in following table:
[0:5] | max time to wait in seconds |
[6] | If set, the wait can be aborted with the ENTER key |
[7] | If set, the wait can be aborted with ESCAPE key |
Output Registers :
If Carry flag is clear all OK, A = byte received.
If Carry flag is set, error code in A as follows:
A = $14 - Timed out
A = $2A - Aborted with key
Note: All registers except A are preserved.
kjt_serial_tx_byte
Action: Send a byte to serial port
Input Registers :
- none
Output Registers :
- A = byte to send
Note: All registers except A preserved.
Keyboard And Mouse Routines
kjt_wait_key_press
Action: Pauses until a key is pressed (and returns value)
Input Registers :
- None
Output Registers :
- A = Scancode of key pressed
- B = ASCII code (B=$00 if no valid ascii char equivalent.)
Note: ASCII code is modified by shift / Alt key status
kjt_get_key
Action: Returns value of key, if one has been pressed (does not wait)
Input Registers :
- None
Output Registers :
- A = Scancode of key pressed (A = $00 if no key pressed)
- B = ASCII code (B=$00 if no valid ascii char equivalent.)
Note: ASCII code is modified by shift / Alt key status
kjt_get_key_mod_flags
Action: Returns current status of key modifiers
Input Registers :
- None
Output Registers :
- A, bits:
[0] | left shift |
[1] | left/right ctrl |
[2] | left GUI |
[3] | left/right alt |
[4] | right shift |
[5] | right GUI |
[6] | Apps |
kjt_keyboard_irq_code
Action: Keyboard IRQ handler.
When a custom interrupt handler is set up but kernal-based keyboard handling is required, this routine can be called when the keyboard IRQ flag is set. The above kernal keyboard routines will then still work. (The call
clears the relevant IRQ flag).
kjt_enable_mouse
Action: Activates mouse pointer (called by MOUSE.EXE) and sets x/y boundaries
Input Registers :
- HL = Window size X
- DE = Window size Y
Output Registers :
- None
kjt_get_mouse_position
Action: Returns absolute mouse position and button data
Input Registers : none
Output Registers : Zero Flag - If not set, the mouse driver was not enabled, otherwise: HL = x coordinate DE = y coordinate A = buttons status
The x and y coordinates cannot overflow from the boundaries set with “kjt_enable_mouse“
Note: the mouse driver is currently somewhat primative - it may become out of sync with the three-byte packets that the mouse sends if say, interrupts are disabled)
kjt_get_mouse_motion
Action: Returns relative mouse motion and button data
Input Registers :
- none
Output Registers :
Zero Flag: if not set, the mouse driver was not enabled, Otherwise:
- HL = x motion since last called
- DE = y motion since last called
- A = buttons status
Note: the mouse driver is currently somewhat primitive - it may become out of sync with the three-byte packets that the mouse sends if say, interrupts are disabled
kjt_mouse_irq_code
Action: Mouse IRQ handler
When a custom interrupt handler is set up but kernal-based mouse handling is required, this routine can be called when the mouse IRQ flag is set. The above kernal mouse routines will then still work. (The call clears the relevant IRQ flag).
kjt_get_key_buffer
Action: Returns values for monitoring the keyboard buffer
Input Registers :
- None
Output Registers :
* HL = Location of the keyboard buffer WRITE index variable (The actual keyboard buffer starts 32 bytes lower in memory)
* A = The value of the keyboard READ index variable.
Note: On return, if A = (HL) no key has been pressed (IE: the keyboard buffer is empty)
Memory Mamagement Routines
Under FLOS, Z80 Address space $5000-$FFFF is available for user programs. FLOS allows the upper 32KB of Z80 address space ($8000-$FFFF) to be paged. 15 pages of system RAM can appear in this region, starting at system RAM address $08000 (FLOS does not normally allow the first 32KB of system RAM to be paged into $8000-$FFFF). Therefore, when using the KJT routines for bank management, the figures are as follows:
Bank | SYSTEM RAM | Z80 ADDRESS |
---|---|---|
$00 | $08000-$0ffff | $8000-$ffff |
$01 | $10000-$17fff | $8000-$ffff |
$02 | $18000-$1ffff | $8000-$ffff |
$03 | $20000-$27fff | $8000-$ffff |
$04 | $28000-$2ffff | $8000-$ffff |
$05 | $30000-$37fff | $8000-$ffff |
$06 | $38000-$3ffff | $8000-$ffff |
$07 | $40000-$47fff | $8000-$ffff |
$08 | $48000-$4ffff | $8000-$ffff |
$09 | $50000-$57fff | $8000-$ffff |
$0a | $58000-$5ffff | $8000-$ffff |
$0b | $60000-$67fff | $8000-$ffff |
$0c | $68000-$6ffff | $8000-$ffff |
$0d | $70000-$77fff | $8000-$ffff |
$0e | $78000-$7ffff | $8000-$ffff |
(Notice that the figures are different to the values used if writing directly to the bank selection hardware port: sys_mem_select).
kjt_set_bank
Action: Changes the currently selected upper RAM page
Input Registers : A = bank number $00 to $0e
Output Registers : none
Trashes:
A
kjt_get_bank
Action: Returns the upper bank number in A
Input Registers : none
Output Registers : A = current bank number ($00 to $0e)
Trashes:
none
kjt_inc_bank
Action: change to the next bank
Input Registers : none
Output Registers :
If Zero flag set: all OK,
If Zero is not set: A = $08 - bank out of range
kjt_page_in_video
Action: Pages 8KB of video memory specified by (hardware register vreg_vidpage) into Z80 address space $2000-$3FFF.
CAUTION: This area is used by part of FLOS so ideally no other FLOS call should be made until kjt_page_out_video is called.
Input Registers :
- none
Output Registers :
- none
Trashes :
- A
kjt_page_out_video
Action: Pages normal system memory (part of the FLOS!) back into $2000-$3FFF
Input Registers :
- none
Output Registers :
- none
Trashes :
- A
kjt_read_sysram_flat
Action: Reads system memory in a flat, linear addressing mode
Input Registers :
- E:HL = $00000 - $7FFFF (address to read)
Output Registers :
- A (byte read from address)
Trashes :
- BC
- DE
- HL
Notes
- The routine saves and restores the entire port byte ”sys_mem_select” around the read so make sure any interrupt service routine is in unpaged memory (<$8000) or disable interrupts to avoid problems.
- As this routine is very slow, only use if convenience is more important than speed.
kjt_write_sysram_flat
Action: Writes to system memory in a flat, linear addressing mode
Input Registers :
- E:HL = $00000 - $7FFFF (address to write),
- A = byte to write
Output Registers :
- None (but see below)
Trashes :
- BC
- DE
- HL
Notes
- The routine saves and restores the entire port byte “sys_mem_select” around the write so make sure any interrupt service routine is in unpaged memory (<$8000) or disable interrupts to avoid problems.
- As this routine is not fast, only use if convenience is more important than speed.
kjt_read_baddr
Action: Reads a byte from system memory (allows programs in paged RAM (8000-FFFF) to easily read data from a different bank)
Input Registers :
- B = Bank
- HL = Address
Output registers :
- A = byte from memory location specified
Notes
- The routine saves and restores the entire port byte “sys_mem_select” around the read so make sure any interrupt service routine is in unpaged memory (<$8000) or disable interrupts to avoid problems.
- As this routine is not fast, only use if convenience is more important than speed.
kjt_write_baddr
Action: Writes a byte to system memory, allows programs in paged RAM (8000-FFFF) to write data to a different bank
Input Registers :
- B = Bank
- HL = Address
- A = Byte to writes
Output Registers :
- None
Notes
- The routine saves and restores the entire port byte “sys_mem_select” around the write so make sure any interrupt service routine is in unpaged memory (<$8000) or disable interrupts to avoid problems.
- As this routine is not fast, only use if convenience is more important than speed.
- Hardware support for writing to alternative pages in provided via the port sys_alt_write_page (see hardware manual)
kjt_get_flos_bank
Action: Returns the value of the bank being used by FLOS before the current command executed.
This is useful when a location header places a program in paged memory ($8000-$FFFF) thus changing the bank selection to that of the program, but the program wants to act on the memory in the bank selected by FLOS as if it were an internal command.
Input Registers :
- None
Output Registers :
- A - The bank which FLOS was referencing.
Text And Display Routines
kjt_print_string
Action: Prints null-terminated ASCII text string at cursor position
Input Registers :
- HL address of string (zero terminated)
Output Registers :
- None
Notes
- ASCII Char $0a = Line Feed
- ASCII Char $0d = Carriage Return
- ASCII Char $0b = Line Feed and Carriage return
- HL returns pointing to the zero byte at end of the string
All other registers are preserved by this routine.
This routine moves the current cursor position.
kjt_clear_screen
Action: clears OS screen and set cursor position to top left (0,0)
Input Registers :
- None
Output Registers :
- None
kjt_plot_char
Action: Prints ASCII character at supplied coordinates using current pen colours
Input Registers :
- A = ASCII character
- B = x coord
- C = y coord
Output Registers :
- None
Notes
- Plot_char does not change the current cursor position.
- If a coordinate is outside the window, it is taken as zero
kjt_get_pen
Action: Returns current pen colour
Input Registers :
- None
Output Registers :
- A = $nm where “n” is the background and “m” is the foreground colour (see table)
Available (default) colours:
0 | transparent (shows UI “paper” colour) |
1 | black |
2 | blue |
3 | red |
4 | magenta |
5 | green |
6 | cyan |
7 | yellow |
8 | white |
9 | dark grey |
a | mid grey |
b | light grey |
c | orange |
d | light blue |
e | light green |
f | brown |
kjt_set_pen
Action: Changes current pen colour
Input Registers :
- A = $nm where “n” is the background and “m” is the foreground colour (see table)
Available (default) colours:
0 | transparent (shows UI “paper” colour) |
1 | black |
2 | blue |
3 | red |
4 | magenta |
5 | green |
6 | cyan |
7 | yellow |
8 | white |
9 | dark grey |
a | mid grey |
b | light grey |
c | orange |
d | light blue |
e | light green |
f | brown |
Output Registers :
- None
kjt_get_colours
Action: Returns the location of the FLOS colour list.
Input registers :
- none
Output registers :
- HL = location of colour list: 18 words (RGB values).
Colour List :
+$00 - Paper
+$02 - Border
+$04 - Cursor
+$06 - 15 pen colours starting with pen 1
Note: FLOS stores its colour list under the hardware registers so system memory needs to paged into that region if writing directly to the address returned from this call. (Simply reading the list poses no such problem). In all cases, kjt_set_colours needs to be called to actually change the palette (unless writing directly to the Hardware Palette Registers)
kjt_set_colours
Action: Sets FLOS border, paper and cursor colours and updates the pen colour list
Input registers :
- HL = location of the colour palette list (18 RGB words)
Colour List :
+$00 - Paper
+$02 - Border
+$04 - Cursor
+$06 - 15 pen colours starting with pen 1
Output registers :
- None
Input registers are trashed.
Note: Changes persist until FLOS restarts (whereas any changes made with the FLOS command “COLOUR” are permanent until reset)
kjt_draw_cursor
Action: Draws (or removes) the cursor at the current cursor position
Input Registers :
- HL = Offset of cursor char image within VRAM font data:
$0000 - $07FF | All zeroes |
$0800 - $0FFF | Raster font image (256 horizontal bytes * 8 vertical bytes) |
$1000 - $17FF | As above but with the bits inverted |
$1800 - $1FFF | All ones |
EG: HL = $0000 : No data, IE: Delete the cursor HL = $085f : Underscore cursor ($800-$8ff = top line of ASCII chars 0-255) HL= $1800 : Solid block cursor
Output Registers :
- None
Note: Remember, kjt_print_string moves the cursor position so the cursor image should be deleted before that routine is called.
kjt_get_input_string
Action: waits for user to enter a string of characters followed by Enter (characters appear on screen)
Input Registers :
- A - maximum characters allowed (set to 255 if dont care)
Output Registers :
- HL = string location (zero terminated)
- A = number of characters of entered string (zero if aborted by pressing ESCAPE)
kjt_set_cursor_position
Action: Repositions the text printing (cursor) position. If a coordinate is out of range it will be set to 0.
Input Registers :
- B = X coord
- C = Y coord
Output Registers :
- Zero flag set if all OK
- If zero flag not set: Invalid coordinates
kjt_get_cursor_position
Action: Returns the current cursor position
Input Registers :
- None
Output registers :
- B = x coord
- C = y coord
kjt_scroll_up
Action: Scrolls the screen (and character map) up a line, inserting a blank line at the bottom of the screen.
Input Registers :
- None
Output registers :
- None
kjt_get_display_size
Action: Returns size of OS_window.
Input registers :
- None
Output registers :
- B = x width (usually 40)
- C = y height (usually 25)
Note: All other registers preserved.
kjt_get_charmap_addr_xy
Action: Returns the charmap address of the character at coordinates x,y
Input registers :
- B = x coord
- C = y coord
Output registers :
- HL = character map address of coords
Note: All other registers are preserved.
kjt_wait_vrt
Action: Wait for last scanline of display
Input Registers :
- none
Output Registers :
- none
Trashes:
- A
kjt_patch_font
Action: Change an individual character in the FLOS font.
Input registers :
- A = char number (must be 0-255, but note: Some chars < 32 are unprintable using “kjt_print_string")
- HL = address of new character pattern (8 bytes)
Output registers :
- None
Misc Routines
kjt_hex_byte_to_ascii
Action: puts ASCII version of the hex byte value in A at HL (two chars), HL=HL+2
Input Registers :
- A = Hex number to convert
Output Registers :
- None
Note: HL=HL+2
Trashes :
- A
kjt_ascii_to_hex_word
Action: converts text string version of hex number at HL to actual hex word in DE
Input Registers :
- HL = source text (the routine scans from this location to the first character that is not a space)
Output Registers :
- DE = result
- HL = If result OK, location of first space character after the hex string (IE: usually a space or null character)
- Zero Flag = set if all OK (also A=$00), Else:
A = $0c | Bad chars for hex |
A = $1A | Number is greater than $FFFF |
A = $1F | No chars found |
kjt_ascii_to_hex32
Action: converts text string version of hex number at HL to actual hex word in BC:DE
Input Registers :
- HL = source text (the routine scans from this location to the first character that is not a space)
Output Registers :
- BC:DE = Result
- HL = If result OK, location of first space character after the hex string (IE: usually a space or null character)
- Zero Flag = set if all OK (also A=$00), Else:
A = $0c | Bad chars for hex |
A = $1A | Number is greater than $FFFFFFFF |
A = $1F | No chars found |
kjt_dont_store_registers
Action: Prevents the OS from noting the register values when a program exits and returns to OS.
Input Registers :
- None
Output Registers :
- None
Trashes :
- A
kjt_get_version
Action: Returns FLOS / OSCA / BOOTCODE version values (also reports the V6Z80P PCB version if OSCA > version $673.)
Input Registers :
- none
Output Registers :
- HL = OS version word
- DE = Hardware version word
- B = V6Z80P PCB version
0 | Data is not available (because OSCA < 674 or FLOS < 610) |
1 | Original V6Z80P |
2 | V6Z80P+ |
3 | V6Z80P+ V1.1 |
Also, if C = 0:
- IX = Location of bootcode info data structure:
$0 [WORD] | Bootcode version (BCD) (if $0000 = Bootcode is < version $617) |
$2 [BYTE] | Devices available at boot time (Bit 0 = SD card) |
$3 [BYTE] | Device OS booted from (1=SD CARD, 2=EEPROM, 3=SERIAL) |
If C <> 0 : FLOS < 610 = data not available
kjt_compare_strings
Action: Compares two ASCII strings (not case sensitive)
Input Registers :
- DE = address of string 1
- HL = address of string 2
- B = maximum number characters to compare
Output Registers :
- Carry flag: Only set if strings are the same.
Notes
- Both strings should be zero terminated.
- Compare fails if string lengths are different unless count is reached first.
- Original HL/DE values are preserved.
kjt_bchl_memfill
Action: Fill memory with value in accumulator
Input Registers :
- HL = start address
- BC = number of bytes to write
- A = value to write
Output Registers :
- none
Trashes :
- HL
- BC
- A
Note: Does NOT overflow from $FFFF into next bank.
kjt_timer_wait
Action: Waits n x 16 microseconds and returns.
Input Registers :
- A = number of 16 microsecond periods to wait
Output Registers:
- None
Note: Preserves all registers except A
kjt_set_commander
Action: Sets a “permanent” command string that is to be launched when progams exit
Input Registers :
- HL = location of command string (40 chars max)
Output Registers :
- None
Notes\
- The string at HL will be parsed as a command whenever a program exits back to FLOS unless that program specifically tells FLOS to launch some other program (with A=$FE on exit). In this case, the commander program will eventually launch when controlis passed back to FLOS (IE: A <> $FE on exit)
- To remove the commander string, point HL at a null string (a zero byte in memory) and call the routine.
- To cancel the commander, press CTRL+C
kjt_flos_settings
Action: Restores the video registers and IRQ vectors/enables to the state used by the OS. Also clears the keyboard buffer. Can be called by programs that have changed the display mode etc before exit so that FLOS does not have to be completely restarted.
Note: This does not restore the data in the Video RAM area used by FLOS ($10000-$1ffff).
Input registers :
- None
Output registers :
- None
Environment Variable Related Calls
kjt_set_envar
Action: Sets an environment variable (or updates a variable if it already exists)
Input Registers :
- HL = name of variable (4 chars max, zero-termination required if less than 4 chars)
- DE = address of data for variable (4 bytes)
Output Registers :
- Zero Flag = set if all OK, not set if no space for new variable (A = $2c)
kjt_get_envar
Action: gets (address of) value of an environment variable
Input Registers :
- HL = name of variable (4 chars max, zero-termination required if less than 4 chars)
Output Registers :
- Zero Flag = Set : all OK, HL = address of data for variable (4 bytes)
- Zero Flag = Not set: variable was not found, (A = $2b, hl = location of envar list, b = max envars)
kjt_delete_envar
Action: deletes an environment variable
Input Registers :
- HL = name of variable (4 chars max, zero-termination required if less than 4 chars)
Output Registers :
- Zero flag = set if all OK, not set if named variable not found