Difference between revisions of "Foenix Kernel Documentation"

From C256 Foenix Wiki
Jump to navigation Jump to search
(Interrupt Vector Table)
(Kernel Calls)
 
(22 intermediate revisions by 2 users not shown)
Line 4: Line 4:
 
Source Code: https://github.com/Trinity-11/Kernel_FMX
 
Source Code: https://github.com/Trinity-11/Kernel_FMX
  
On the FMX, the Foenix Kernel resides in bank $39 of the system RAM. It provides for the initialization of the hardware and a certain minimalist level of access to the hardware.
+
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.
 
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.
 
All kernel routines must be called using the JSL instruction (long, or 24-bit subroutine call), since they all terminate with an RTL.
Line 17: Line 17:
 
| BOOT || $00:1000 || Cold boot routine
 
| BOOT || $00:1000 || Cold boot routine
 
|-
 
|-
| PUTC || $00:1018 || Print a character to the currently selected channel
+
| PUTC || $00:1018 || Print a character to the currently selected channel. [See [[ANSI Support]] for more details.]
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
Line 34: Line 34:
 
| X || 16 || Address within that bank of the first character 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
 
| SETIN || $00:1038 || Set the current input channel used by the GET subroutines
Line 55: Line 59:
 
* 1 = COM1 (external serial)
 
* 1 = COM1 (external serial)
 
* 2 = COM2 (internal serial)
 
* 2 = COM2 (internal serial)
 +
* 4 = EVID video expansion card (if present)
 
|}
 
|}
 +
|-
 +
| GETCH || $00:1048 || 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
 
| GETCHW || $00:104C || Get a character from the input channel. Waits until data received. A=0 and Carry=1 if no data is waiting
Line 98: Line 105:
 
|-
 
|-
 
| SCROLLUP || $00:10A4 || Scroll the screen up one line. Creates an empty line at the bottom.
 
| SCROLLUP || $00:10A4 || Scroll the screen up one line. Creates an empty line at the bottom.
 +
|-
 +
| SETSIZES || $00:112C || Recompute the size of the text screen given the current screen resolution and border size. This should be called whenever the screen size changes but text mode is being used so that the kernel's text routines work properly.
 
|-
 
|-
 
| CLRSCREEN || $00:10B0 || Clear the screen
 
| CLRSCREEN || $00:10B0 || Clear the screen
Line 198: Line 207:
 
|}
 
|}
 
|-
 
|-
| 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_RUN || $00:1124 || Load and run an [[executable 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_MOUNT || $00:1128 || Mount the designated block device. BIOS_DEV is the device number to mount.
Line 209: Line 218:
 
| 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
 
| 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.
 
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.
 +
|-
 +
| IP_INIT || $00:1150 || [v0.5] Initialize network stack; B:Y->ip, mask, default_route.  buffer_ptr below is 24 of 32 bits.
 +
|-
 +
| UDP_SEND || $00:1154|| [v0.5] Send a UDP packet:  0:X->local_port, remote_ip, remote_port, buffer_ptr, size, copied
 +
|-
 +
| UDP_RECV || $00:1158|| [v0.5] Receive a UDP packet:  0:X->local_port, remote_ip, remote_port, buffer_ptr, size, copied
 +
 
|}
 
|}
  
Line 283: Line 310:
 
| MODIFIED_TIME || 28 || 2 || The modification time in the same format as used by FAT.
 
| MODIFIED_TIME || 28 || 2 || The modification time in the same format as used by FAT.
 
|}
 
|}
 +
 +
=== Network Calls ===
 +
 +
Networking support includes three functions and two structures below. All networking kernel calls are processor mode agnostic, return status in the condition codes, and leave all other registers unchanged. The calls are neither re-entrant nor thread-safe; don't attempt to call any of them concurrently. The stack will respond to pings (ICMP ECHO requests), but only so long as UDP_SEND and/or UDP_RECV is being called regularly.  The stack does nothing in the background and does not use interrupts.  The ARP timer works by polling the NIC's internal timer-expired flag.
 +
 +
<pre>
 +
IP_INIT
 +
  IN:    B:Y->ip_info (below)
 +
  OUT:    Carry set on error (ethernet card not found or won't init)
 +
  NOTES:  A default route in the 0.x.x.x range is formally unroutable.
 +
</pre>
 +
 +
<pre>
 +
UDP_SEND
 +
  IN:    0:X->udp_info (below)
 +
  OUT:    Carry set on error (not initialized, no route to host, EOM)
 +
  NOTES:  "No route to host" is usually temporary while the stack is
 +
          awaiting an ARP response from the target or the router;
 +
          callers are expected to retry the send.  The stack rate-
 +
          limits ARP requests to approximately 2/s per address.
 +
          Sends to your IPv4 broadcast address will be sent to the
 +
          broadcast MAC (ff:ff:ff:ff:ff:ff).  An EOM should only occur
 +
          if you aren't calling UDP_RECV often enough to drain the
 +
          incoming UDP packet queue. 
 +
</pre>
 +
 +
<pre>
 +
UDP_RECV
 +
  IN:    0:X->udp_info (below)
 +
  OUT:    Carry set on error (not initialized), Z set on queue empty.
 +
  NOTES:  You MUST call UDP_RECV semi-regularly; if you don't, the
 +
          receive queue will eventually fill with garbage.  The net
 +
          is a messy place, and random devices on your lan are always
 +
          spamming the local network.  Broadcast UDP packets are
 +
          accepted and queued like any other UDP packets.
 +
</pre>
 +
 +
==== Network Data Structures ====
 +
 +
<pre>
 +
ip_info    .struct
 +
ip          .fill  4  ; Local ipv4 address in network order
 +
mask        .fill  4  ; Local ipv4 netmask in network order
 +
default    .fill  4  ; Default ipv4 route in network order
 +
size        .ends
 +
 +
udp_info    .struct
 +
local_port  .word  ?  ; local port #, little-endian
 +
remote_ip  .fill  4  ; ipv4 address of remote machine, network order
 +
remote_port .word  ?  ; remote port #, little endian
 +
buffer      .dword  ?  ; 24-bit address of your data
 +
buflen      .word  ?  ; length of the above buffer in bytes
 +
copied      .word  ?  ; number of bytes copied in/out of the above buffer
 +
size        .ends
 +
</pre>
  
 
== Interrupt Jump Table ==
 
== Interrupt Jump Table ==
Line 292: Line 374:
  
 
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).
 
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.
+
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.
  
 
{| class="wikitable"
 
{| class="wikitable"
 
|-
 
|-
! Interrupt || Address || Purpose
+
! Interrupt !! Block !! Number !!  Address !! Purpose
 
|-
 
|-
| VEC_INT00_SOF || $00:1700 || Start Of Frame (vertical blank)
+
| VEC_INT00_SOF || 0 || 0 || $00:1700 || Start Of Frame (vertical blank, used by floppy drive code)
 
|-
 
|-
| VEC_INT01_SOL || $00:1704 || Start Of Line (horizontal blank)
+
| VEC_INT01_SOL || 0 || 1 || $00:1704 || Start Of Line (horizontal blank)
 
|-
 
|-
| VEC_INT02_TMR0 || $00:1708 || Timer 0
+
| VEC_INT02_TMR0 || 0 || 2 || $00:1708 || Timer 0 (used by floppy drive code and DELAY call)
 
|-
 
|-
| VEC_INT03_TMR1 || $00:170C || Timer 1
+
| VEC_INT03_TMR1 || 0 || 3 || $00:170C || Timer 1
 
|-
 
|-
| VEC_INT04_TMR2 || $00:1710 || Timer 2
+
| VEC_INT04_TMR2 || 0 || 4 || $00:1710 || Timer 2
|}
+
|-
 
+
| VEC_INT05_RTC      || 0 || 5 || $00:1714 || Real Time Clock interrupt
== Console Special Characters ==
+
|-
 
+
| VEC_INT06_FDC      || 0 || 6 || $00:1718 || Floppy Drive Controller interrupt
The console routines support several special control codes for both input and output.
+
|-
When the key on the keyboard is pressed, the associated code is returned by the GET routines.
+
| VEC_INT07_MOUSE    || 0 || 7 || $00:171C || Mouse interrupt (used by kernel to handle mouse)
If the code is printed through the PUTC or PUTS, the associated operation will be performed on the screen.
+
|-
Note that this means that any graphics characters associated with those code points will not be displayed by PUTC or PUTS.
+
| VEC_INT10_KBD      || 1 || 0 || $00:1720 || Keyboard interrupt (used by kernel to handle keyboard input)
If those characters must be displayed, they would have to be written to the text memory directly.
+
|-
 
+
| VEC_INT11_COL0      || 1 || 1 || $00:1724 || VICKY_II (INT2) Sprite Collision
{| class="wikitable"
+
|-
! Code !! Name !! Keyboard !! Description
+
| 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
 
|-
 
|-
| $08 || BS || Backspace || Deletes the character to the left of the cursor, pulling characters in from the right.
+
| VEC_INT21_GABE0    || 2 || 1 || $00:1744 || GABE (INT0) - TBD
 
|-
 
|-
| $09 || TAB || TAB || Moves the cursor right to the next tabulated column (every eight columns).
+
| VEC_INT22_GABE1    || 2 || 2 || $00:1748 || GABE (INT1) - TBD
 
|-
 
|-
| $0A || LF || N/A || Puts the cursor at column 0 on the next line on the same column.
+
| VEC_INT23_VDMA      || 2 || 3 || $00:174C || VICKY_II (INT4) - VDMA Interrupt
 
|-
 
|-
| $0D || CR || RETURN || Creates a newline on the screen. Puts the cursor at column 0 on the next line.
+
| VEC_INT24_COL2      || 2 || 4 || $00:1750 || VICKY_II (INT5) Tile Collision
 
|-
 
|-
| $0F || INS || Insert || Inserts a blank space under the cursor (pushing characters to the right).
+
| VEC_INT25_GABE2    || 2 || 5 || $00:1754 || GABE (INT2) - TBD
 
|-
 
|-
| $11 || UP || Up Arrow || Moves the cursor up one row.
+
| VEC_INT26_EXT      || 2 || 6 || $00:1758 || External Expansion
 
|-
 
|-
| $1D || RIGHT || Right Arrow || Moves the cursor right one column. May wrap to the next line.
+
| VEC_INT17_SDINS    || 2 || 7 || $00:175C || SDCARD Insertion
 
|-
 
|-
| $7F || DEL || Delete || Deletes the character under the cursor, pulling characters in from the right.
+
| VEC_INT30_OPN2      || 3 || 0 || $00:1760 || OPN2
 
|-
 
|-
| $91 || DOWN || Down Arrow || Moves the cursor down one row. May scroll the screen.
+
| VEC_INT31_OPM      || 3 || 1 || $00:1764 || OPM
 
|-
 
|-
| $9D || LEFT || Left Arrow || Moves the cursor left one column.
+
| VEC_INT32_IDE      || 3 || 2 || $00:1768 || HDD IDE Interrupt
 
|}
 
|}
  
Line 367: Line 463:
 
|-
 
|-
 
| $00:001F || $00:0020 || COLORPOS || RO || The address of the text color cell under the cursor
 
| $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.
 +
 +
{| class="wikitable"
 +
|-
 +
! Name !! Code !! Description
 +
|-
 +
| N/A || $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:
 +
 +
{| class="wikitable"
 +
|-
 +
! Name !! Code !! Description
 +
|-
 +
| N/A || 0 || 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
 
|}
 
|}

Latest revision as of 10:27, 19 July 2023

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 $00:1048 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.
SETSIZES $00:112C Recompute the size of the text screen given the current screen resolution and border size. This should be called whenever the screen size changes but text mode is being used so that the kernel's text routines work properly.
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 an executable 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.
IP_INIT $00:1150 [v0.5] Initialize network stack; B:Y->ip, mask, default_route. buffer_ptr below is 24 of 32 bits.
UDP_SEND $00:1154 [v0.5] Send a UDP packet: 0:X->local_port, remote_ip, remote_port, buffer_ptr, size, copied
UDP_RECV $00:1158 [v0.5] Receive a UDP packet: 0:X->local_port, remote_ip, remote_port, buffer_ptr, size, copied

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.

Network Calls

Networking support includes three functions and two structures below. All networking kernel calls are processor mode agnostic, return status in the condition codes, and leave all other registers unchanged. The calls are neither re-entrant nor thread-safe; don't attempt to call any of them concurrently. The stack will respond to pings (ICMP ECHO requests), but only so long as UDP_SEND and/or UDP_RECV is being called regularly. The stack does nothing in the background and does not use interrupts. The ARP timer works by polling the NIC's internal timer-expired flag.

IP_INIT
  IN:     B:Y->ip_info (below)
  OUT:    Carry set on error (ethernet card not found or won't init)
  NOTES:  A default route in the 0.x.x.x range is formally unroutable.
UDP_SEND
  IN:     0:X->udp_info (below)
  OUT:    Carry set on error (not initialized, no route to host, EOM)
  NOTES:  "No route to host" is usually temporary while the stack is 
          awaiting an ARP response from the target or the router;
          callers are expected to retry the send.  The stack rate-
          limits ARP requests to approximately 2/s per address.
          Sends to your IPv4 broadcast address will be sent to the
          broadcast MAC (ff:ff:ff:ff:ff:ff).  An EOM should only occur 
          if you aren't calling UDP_RECV often enough to drain the 
          incoming UDP packet queue.  
UDP_RECV
  IN:     0:X->udp_info (below)
  OUT:    Carry set on error (not initialized), Z set on queue empty.
  NOTES:  You MUST call UDP_RECV semi-regularly; if you don't, the
          receive queue will eventually fill with garbage.  The net
          is a messy place, and random devices on your lan are always
          spamming the local network.  Broadcast UDP packets are
          accepted and queued like any other UDP packets.

Network Data Structures

ip_info     .struct
ip          .fill   4   ; Local ipv4 address in network order
mask        .fill   4   ; Local ipv4 netmask in network order
default     .fill   4   ; Default ipv4 route in network order
size        .ends

udp_info    .struct
local_port  .word   ?   ; local port #, little-endian
remote_ip   .fill   4   ; ipv4 address of remote machine, network order
remote_port .word   ?   ; remote port #, little endian
buffer      .dword  ?   ; 24-bit address of your data
buflen      .word   ?   ; length of the above buffer in bytes
copied      .word   ?   ; number of bytes copied in/out of the above buffer
size        .ends

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
N/A $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 0 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