Foenix Kernel Documentation
Kernel Essentials
Source Code: https://github.com/Trinity-11/Kernel_FMX
The Foenix Kernel resides in bank $19 (U) or bank $39 (U+/FMX) of the system RAM. It provides for the initialization of the hardware and a certain minimalist level of access to the hardware.
Kernel routines are called through a kernel jump table that starts at $00:1000.
All kernel routines must be called using the JSL instruction (long, or 24-bit subroutine call), since they all terminate with an RTL.
This allows the kernel routines to be called from anywhere in system memory.
Kernel Calls
Name |
Address |
Description
|
BOOT |
$00:1000 |
Cold boot routine
|
PUTC |
$00:1018 |
Print a character to the currently selected channel. [See ANSI Support for more details.]
Register |
Width |
Contents
|
A |
8 |
ASCII code of the character to print
|
|
PUTS |
$00:101C |
Print a null-terminated ASCII string to the currently selected channel
Register |
Width |
Contents
|
B |
8 |
Bank containing the data to print
|
X |
16 |
Address within that bank of the first character to print
|
|
GETSCANCODE |
$00:1028 |
[v0.4] Get the next scancode from the keyboard (A = scancode, 0 if none available). See C256 Keyboard for details.
|
GETLOCKS |
$00:102C |
[v0.4] Get the state of the lock keys on the keyboard (A[2] = CAPS, A[1] = NUM, A[0] = SCROLL). See C256 Keyboard for details.
|
SETIN |
$00:1038 |
Set the current input channel used by the GET subroutines
Register |
Width |
Contents
|
A |
8 |
Input channel to use
- 0 = Keyboard
- 1 = COM1 (external serial)
- 2 = COM2 (internal serial)
|
|
SETOUT |
$00:103C |
Set the current output channel used by the PUT subroutines
Register |
Width |
Contents
|
A |
8 |
Input channel to use
- 0 = Screen
- 1 = COM1 (external serial)
- 2 = COM2 (internal serial)
- 4 = EVID video expansion card (if present)
|
|
GETCH |
Get a character from the input channel. A=0 and Carry=1 if no data is waiting.
|
GETCHW |
$00:104C |
Get a character from the input channel. Waits until data received. A=0 and Carry=1 if no data is waiting
|
GETCHE |
$00:1050 |
Get a character from the input channel and echo to the screen. Wait if data is not ready.
|
PRINTCR |
$00:106C |
Print Carriage Return
|
PRINTH |
$00:1078 |
Print hex value in memory.
Register |
Width |
Contents
|
B |
8 |
Bank containing the data to print
|
X |
16 |
Address within that bank of the last byte to print
|
Y |
16 |
Number of bytes to print
|
|
PRINTAH |
$00:1080 |
Prints hex value in A. Printed value is 2 wide if M flag is 1, 4 wide if M
|
LOCATE |
$00:1084 |
Move the cursor to a new position on the screen.
Register |
Width |
Contents
|
X |
16 |
The column for the cursor
|
Y |
16 |
The row for the cursor
|
|
CSRRIGHT |
$00:1090 |
Move the cursor one position to the right
|
CSRLEFT |
$00:1094 |
Move the cursor one position to the left
|
CSRUP |
$00:1098 |
Move the cursor up one row
|
CSRDOWN |
$00:109C |
Move the cursor down one row
|
CSRHOME |
$00:10A0 |
Move the cursor to the upper-left corner
|
SCROLLUP |
$00:10A4 |
Scroll the screen up one line. Creates an empty line at the bottom.
|
CLRSCREEN |
$00:10B0 |
Clear the screen
|
INITCHLUT |
$00:10B4 |
Init character look-up table
|
INITSUPERIO |
$00:10B8 |
Init Super-IO chip
|
INITKEYBOARD |
$00:10BC |
Init keyboard
|
INITRTC |
$00:10C0 |
Init Real-Time Clock
|
INITCURSOR |
$00:10C4 |
Init the Cursors registers
|
INITFONTSET |
$00:10C8 |
Init the Internal FONT Memory
|
INITGAMMATABLE |
$00:10CC |
Init the RGB GAMMA Look Up Table
|
INITALLLUT |
$00:10D0 |
Init the Graphic Engine (Bitmap/Tile/Sprites) LUT
|
INITVKYTXTMODE |
$00:10D4 |
Init the Text Mode @ Reset Time
|
INITVKYGRPMODE |
$00:10D8 |
Init the Basic Registers for the Graphic Mode
|
F_OPEN |
$00:10F0 |
Open a file for reading/writing. DOS_FD_PTR points to a file descriptor for the file.
|
F_CREATE |
$00:10F4 |
Create a new file and write its first cluster. DOS_FD_PTR points to a file descriptor for the file.
|
F_CLOSE |
$00:10F8 |
Close a file (make sure last cluster is written). DOS_FD_PTR points to a file descriptor for the file.
|
F_WRITE |
$00:10FC |
Write the current cluster to the file. DOS_FD_PTR points to a file descriptor for the file.
|
F_READ |
$00:1100 |
Read the next cluster from the file. DOS_FD_PTR points to a file descriptor for the file.
|
F_DELETE |
$00:1104 |
Delete a file / directory. DOS_PATH_BUFF = a buffer containing the full path to the file (NULL terminated).
|
F_DIROPEN |
$00:1108 |
Open a directory and seek the first directory entry. NOTE: currently only works with the root directory.
Variable |
Direction |
Contents
|
DOS_FD_PTR |
IN |
Points to a file descriptor for the path to lookup. NOTE: currently unused.
|
DOS_DIR_PTR |
OUT |
Pointer to the first FAT directory entry in that directory.
|
|
F_DIRNEXT |
$00:110C |
seek to the next directory of an open directory
Variable |
Direction |
Contents
|
DOS_DIR_PTR |
IN |
Pointer to the current FAT directory entry.
|
DOS_DIR_PTR |
OUT |
Pointer to the next FAT directory entry.
|
|
F_DIRREAD |
$00:1110 |
Read the directory entry for the specified file
Variable |
Direction |
Contents
|
DOS_PATH_BUFF |
IN |
The buffer containing the path to the file to lookup.
|
DOS_DIR_PTR |
OUT |
Pointer to the FAT directory entry for that file.
|
|
F_DIRWRITE |
$00:1114 |
Write any changes in the current directory cluster back to the drive
|
F_LOAD |
$00:1118 |
load a binary file into memory, supports multiple file formats
Variable |
Contents
|
DOS_FD_PTR |
Points to a file descriptor for the file to lookup.
|
DOS_DST_PTR |
Pointer to the location to load the file (any value > $3F:FFFF to load the file where the file specifies).
|
|
F_SAVE |
$00:111C |
Save memory to a binary file
Variable |
Contents
|
DOS_FD_PTR |
Points to a file descriptor for the file to create.
|
DOS_SRC_PTR |
Address of the first byte to save.
|
DOS_END_PTR |
Address of the last byte to save.
|
|
CMDBLOCK |
$00:1120 |
Send a command to a block device.
Variable |
Contents
|
BIOS_DEV |
The target device
|
X |
The number of the command to send. Command numbers are device dependent, but typical examples are: 1 = Turn on spindle motor, 2 = Turn off spindle motor, 3 = Recalibrate.
|
|
F_RUN |
$00:1124 |
Load and run a binary file from a block device. DOS_RUN_PARAMS is a pointer to the ASCIIZ string specifying the path of the file to execute and any parameters to it.
|
F_MOUNT |
$00:1128 |
Mount the designated block device. BIOS_DEV is the device number to mount.
|
F_COPY |
$00:1130 |
Copy a file. DOS_STR1_PTR is the path of the source file to copy. DOS_STR2_PTR is the path of the destination.
|
F_ALLOCFD |
$00:1134 |
Allocate a file descriptor from the kernel. DOS_FD_PTR will point to the file descriptor allocated, if one is available. There
is a limit of 8 file descriptors that can be allocated at any one time.
|
F_FREEFD |
$00:1138 |
Return a file descriptor to the kernel. DOS_FD_PTR points to the file descriptor to return to the kernel. It must have been
allocated previously through F_ALLOCFD.
|
TESTBREAK |
$00:113C |
[v0.4] Check if BREAK was pressed recently by the user (C is set if true, clear if false)
|
SETTABLE |
$00:1140 |
[v0.4] Set the keyboard scan code -> character translation tables (B:X points to the new tables). See C256 Keyboard for details.
|
READVRAM |
$00:1144 |
[v0.4] Read a byte from video RAM at B:X. Result in A. C clear on success, set on failure (timeout).
|
SETHANDLER |
$00:1148 |
[v0.4] Set the handler for the interrupt # in A (A[7..4] = block number, A[3..0] = interrupt) to the FAR routine at Y:X
|
DELAY |
$00:114C |
[v0.4] Wait at least Y:X ticks of the system clock.
|
DOS Calling Conventions
The DOS file routines use several variables to communicate with the calling program. All DOS routines will return with the carry bit set on success.
If the routine was unable to complete successfully or needs to return a negative condition, the carry bit will be clear and DOS_STATUS and BIOS_STATUS
variables may contain non-zero status codes describing the nature of the failure.
Variable |
Address |
Width (bytes) |
Purpose
|
DOS_FD_PTR |
$00:0340 |
4 |
A pointer to a file descriptor structure (defined below).
|
DOS_PATH_BUFF |
$00:0400 |
256 |
A buffer space for storing a path to a file or directory.
|
DOS_DIR_PTR |
$00:0338 |
4 |
A pointer to a directory entry. The layout of the entry is identical to that used in the FAT file system.
|
DOS_DST_PTR |
$00:0354 |
4 |
A pointer to a block of memory to be filled from the disk.
|
DOS_SRC_PTR |
$00:0350 |
4 |
A pointer to a block of memory to write to disk.
|
DOS_END_PTR |
$00:0358 |
4 |
A pointer to the last byte of a block of memory.
|
DOS_STATUS |
$00:032E |
1 |
A status code for DOS operations. $00 = success
|
BIOS_STATUS |
$00:0320 |
1 |
A status code for sector level operations. $00 = success
|
File Descriptor
Most DOS subroutines take a pointer to a file descriptor as an argument. This file descriptor contains several elements needed to manage a file,
including the buffer containing the current cluster of the file:
Name |
Offset |
Width (bytes) |
Purpose
|
STATUS |
0 |
1 |
A special status byte containing information about the file's state
Name |
Value |
Purpose
|
FD_STAT_READ |
$01 |
The file is open for reading
|
FD_STAT_WRITE |
$02 |
The file is open for writing
|
FD_STAT_OPEN |
$40 |
The file is open.
|
FD_STAT_ERROR |
$60 |
There is an error with the file.
|
FD_STAT_EOF |
$80 |
The file is being read and has reach the end of the file.
|
|
DEV |
1 |
1 |
A byte containing the device number for the file (should not be modified by the user program).
|
PATH |
2 |
4 |
A pointer to a null-terminated string containing the path to the file. Set by the user program.
|
CLUSTER |
6 |
4 |
The ID of the current cluster being read or written. Usually set by DOS.
|
FIRST_CLUSTER |
10 |
4 |
The ID of the first cluster of the file. Usually set by DOS.
|
BUFFER |
14 |
4 |
Pointer to the buffer containing a cluster's worth of data. Provided by the user program. Used by DOS to read or write the disk.
|
SIZE |
18 |
4 |
The size of the file in bytes.
|
CREATE_DATE |
22 |
2 |
The creation date in the same format as used by FAT.
|
CREATE_TIME |
24 |
2 |
The creation time in the same format as used by FAT.
|
MODIFIED_DATE |
26 |
2 |
The modification date in the same format as used by FAT.
|
MODIFIED_TIME |
28 |
2 |
The modification time in the same format as used by FAT.
|
Interrupt Jump Table
The kernel provides a jump table for interrupt handler support. When an interrupt is triggered of any particular type, the kernel interrupt handler will
jump to the vector for that interrupt. The vector should point to a subroutine that returns to the caller through an RTL instruction.
Each vector entry is four bytes long. The first byte is a JML opcode. The next three bytes are the long (24-bit) address of the interrupt handler routine.
Currently, the kernel only supports a few interrupts in this manner. All system interrupts will eventually have an entry in this table.
A program needing to take control of one of these interrupts can replace the 24-bit address of the appropriate jump table entry (with interrupts disabled).
It is recommended to save the previous value and restore it before quitting. As of v0.4, the kernel includes a convenience routine SETHANDLER which will set the
vector to an address provided. The vector is specified in Y:X (Y contains the bank of the handler, X contains the 16-bit address within the bank). The
number of the interrupt is provided in A, with A[7..4] containing the block number, and A[3..0] containing the interrupt number.
Interrupt |
Block |
Number |
Address |
Purpose
|
VEC_INT00_SOF |
0 |
0 |
$00:1700 |
Start Of Frame (vertical blank, used by floppy drive code)
|
VEC_INT01_SOL |
0 |
1 |
$00:1704 |
Start Of Line (horizontal blank)
|
VEC_INT02_TMR0 |
0 |
2 |
$00:1708 |
Timer 0 (used by floppy drive code and DELAY call)
|
VEC_INT03_TMR1 |
0 |
3 |
$00:170C |
Timer 1
|
VEC_INT04_TMR2 |
0 |
4 |
$00:1710 |
Timer 2
|
VEC_INT05_RTC |
0 |
5 |
$00:1714 |
Real Time Clock interrupt
|
VEC_INT06_FDC |
0 |
6 |
$00:1718 |
Floppy Drive Controller interrupt
|
VEC_INT07_MOUSE |
0 |
7 |
$00:171C |
Mouse interrupt (used by kernel to handle mouse)
|
VEC_INT10_KBD |
1 |
0 |
$00:1720 |
Keyboard interrupt (used by kernel to handle keyboard input)
|
VEC_INT11_COL0 |
1 |
1 |
$00:1724 |
VICKY_II (INT2) Sprite Collision
|
VEC_INT12_COL1 |
1 |
2 |
$00:1728 |
VICKY_II (INT3) Bitmap Collision
|
VEC_INT13_COM2 |
1 |
3 |
$00:172C |
Serial port #2 interrupt
|
VEC_INT14_COM1 |
1 |
4 |
$00:1730 |
Serial port #1 interrupt
|
VEC_INT15_MIDI |
1 |
5 |
$00:1734 |
MIDI controller interrupt
|
VEC_INT16_LPT |
1 |
6 |
$00:1738 |
Parallel port interrupt
|
VEC_INT17_SDC |
1 |
7 |
$00:173C |
SD Card Controller interrupt (no longer used)
|
VEC_INT20_OPL |
2 |
0 |
$00:1740 |
OPL3
|
VEC_INT21_GABE0 |
2 |
1 |
$00:1744 |
GABE (INT0) - TBD
|
VEC_INT22_GABE1 |
2 |
2 |
$00:1748 |
GABE (INT1) - TBD
|
VEC_INT23_VDMA |
2 |
3 |
$00:174C |
VICKY_II (INT4) - VDMA Interrupt
|
VEC_INT24_COL2 |
2 |
4 |
$00:1750 |
VICKY_II (INT5) Tile Collision
|
VEC_INT25_GABE2 |
2 |
5 |
$00:1754 |
GABE (INT2) - TBD
|
VEC_INT26_EXT |
2 |
6 |
$00:1758 |
External Expansion
|
VEC_INT17_SDINS |
2 |
7 |
$00:175C |
SDCARD Insertion
|
VEC_INT30_OPN2 |
3 |
0 |
$00:1760 |
OPN2
|
VEC_INT31_OPM |
3 |
1 |
$00:1764 |
OPM
|
VEC_INT32_IDE |
3 |
2 |
$00:1768 |
HDD IDE Interrupt
|
Special Kernel Variables
The kernel keeps track of several variables.
Most kernel variables should be left alone by applications, but there are some which an application might want to set or read.
Start Address |
End Address |
Name |
R/W |
Description
|
$00:000C |
$00:000E |
SCREENBEGIN |
RO |
Address of the first character of the text display
|
$00:000C |
$00:000E |
SCREENBEGIN |
RO |
Address of the first character of the text display
|
$00:000F |
$00:0010 |
COLS_VISIBLE |
RW |
The number of columns currently displayed
|
$00:0013 |
$00:0014 |
LINES_VISIBLE |
RW |
The number of rows currently displayed
|
$00:0017 |
$00:0018 |
CURSORPOS |
RO |
The address of the text character under the cursor
|
$00:001A |
$00:001B |
CURSORX |
RO |
The address of the text character under the cursor
|
$00:001C |
$00:001D |
CURSORY |
RO |
The address of the text character under the cursor
|
$00:001E |
|
CURCOLOR |
RW |
The foreground and background colors to be used when printing via PUTC and PUTS
|
$00:001F |
$00:0020 |
COLORPOS |
RO |
The address of the text color cell under the cursor
|
BIOS_STATUS ($00:320)
This status variable records any error condition related to the low level block level BIOS routines.
Name |
Code |
Description
|
BIOS_OK |
$00 |
The last BIOS operation was successful
|
BIOS_ERR_BADDEV |
$80 |
BIOS bad device # error
|
BIOS_ERR_MOUNT |
$81 |
BIOS failed to mount the device
|
BIOS_ERR_READ |
$82 |
BIOS failed to read from a device
|
BIOS_ERR_WRITE |
$83 |
BIOS failed to write to a device
|
BIOS_ERR_TRACK |
$84 |
BIOS failed to seek to the correct track
|
BIOS_ERR_CMD |
$85 |
A general block device command error
|
BIOS_ERR_WRITEPROT |
$86 |
The media was write-protected
|
BIOS_ERR_NOMEDIA |
$87 |
No media detected... unable to read/write in time
|
BIOS_ERR_RESULT |
$88 |
Couldn't get the result bytes for some reason
|
BIOS_ERR_OOS |
$89 |
FDC state is somehow out of sync with the driver.
|
BIOS_ERR_NOTATA |
$8A |
IDE drive is not ATA
|
BIOS_ERR_NOTINIT |
$8B |
Could not initilize the device
|
BIOS_ERR_TIMEOUT |
$8C |
Timeout error
|
FDC_ST0 ($00:326)
This status variable records hardware level status codes.
For FDC access, it represents the first status byte of the floppy drive controller.
For SDC and HDD access, it records the SDC and IDE level hardware status, respectively.
The meaning of the bits will vary depending on the hardware accessed, and you should refer
to the documentation on that specific device for details.
DOS_STATUS ($00:32E)
This status variable records any error condition related to the DOS and FAT level code:
Name |
Code |
Description
|
N/A |
$00 |
The last DOS operation was successful
|
DOS_ERR_READ |
1 |
We could not read a sector, check BIOS_STATUS for details
|
DOS_ERR_NOTMBR |
2 |
We could not find the MBR
|
DOS_ERR_NOFAT32 |
3 |
We could not find a FAT32 parition using LBA
|
DOS_ERR_NOINIT |
4 |
We could not INIT the block device
|
DOS_ERR_VOLID |
5 |
Volume ID sector could not be loaded
|
DOS_ERR_FAT |
6 |
Can't scan the FAT for some reason
|
DOS_ERR_BADPATH |
7 |
The path was badly formatted
|
DOS_ERR_NODIR |
8 |
Could not read the directory
|
DOS_ERR_NOTFOUND |
9 |
File/directory requested was not found
|
DOS_ERR_NOCLUSTER |
10 |
There are no more clusters
|
DOS_ERR_FILEEXISTS |
11 |
There is already a file of that name
|
DOS_ERR_NOTOPEN |
12 |
File has not been open
|
DOS_ERR_NOTREAD |
13 |
File is not open for reading
|
DOS_ERR_NOTWRITE |
14 |
File is not open for writing
|
DOS_ERR_OPEN |
15 |
File is already open
|
DOS_ERR_PGXSIG |
16 |
File does not have the PGX signature
|
DOS_ERR_NOEXEC |
17 |
File does is not an executable format
|
DOS_ERR_MEDIAFULL |
18 |
There are no more free clusters on the drive
|
DOS_ERR_WRITEPROT |
19 |
The medium is write-protected
|
DOS_ERR_FATUPDATE |
20 |
Can't update the FAT
|
DOS_ERR_DIRFULL |
21 |
The directory is full
|
DOS_ERR_NOFD |
22 |
No file descriptors are available for allocation
|
DOS_ERR_NOMEDIA |
23 |
No media was present
|
DOS_ERR_EOF |
24 |
At end of file
|
DOS_ERR_PGZSIG |
25 |
File does not have the PGZ signature
|