<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.c256foenix.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=PJW</id>
	<title>C256 Foenix Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.c256foenix.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=PJW"/>
	<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Special:Contributions/PJW"/>
	<updated>2026-05-17T16:12:07Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.32.0</generator>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=967</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=967"/>
		<updated>2023-07-19T18:27:40Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Kernel Calls */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix Kernel Documentation =&lt;br /&gt;
&lt;br /&gt;
== Kernel Essentials ==&lt;br /&gt;
Source Code: https://github.com/Trinity-11/Kernel_FMX&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Kernel routines are called through a kernel jump table that starts at $00:1000.&lt;br /&gt;
All kernel routines must be called using the JSL instruction (long, or 24-bit subroutine call), since they all terminate with an RTL.&lt;br /&gt;
This allows the kernel routines to be called from anywhere in system memory.&lt;br /&gt;
&lt;br /&gt;
== Kernel Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Address !! Description&lt;br /&gt;
|-&lt;br /&gt;
| BOOT || $00:1000 || Cold boot routine&lt;br /&gt;
|-&lt;br /&gt;
| PUTC || $00:1018 || Print a character to the currently selected channel. [See [[ANSI Support]] for more details.]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || ASCII code of the character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PUTS || $00:101C || Print a null-terminated ASCII string to the currently selected channel&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the first character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETSCANCODE || $00:1028 || [v0.4] Get the next scancode from the keyboard (A = scancode, 0 if none available). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SETIN || $00:1038 || Set the current input channel used by the GET subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Keyboard&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| SETOUT || $00:103C || Set the current output channel used by the PUT subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Screen&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
* 4 = EVID video expansion card (if present)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETCH || $00:1048 || Get a character from the input channel. A=0 and Carry=1 if no data is waiting.&lt;br /&gt;
|-&lt;br /&gt;
| GETCHW || $00:104C || Get a character from the input channel. Waits until data received. A=0 and Carry=1 if no data is waiting&lt;br /&gt;
|-&lt;br /&gt;
| GETCHE || $00:1050 || Get a character from the input channel and echo to the screen. Wait if data is not ready.&lt;br /&gt;
|-&lt;br /&gt;
| PRINTCR || $00:106C || Print Carriage Return&lt;br /&gt;
|-&lt;br /&gt;
| PRINTH || $00:1078 || Print hex value in memory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the last byte to print&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || Number of bytes to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PRINTAH || $00:1080 || Prints hex value in A. Printed value is 2 wide if M flag is 1, 4 wide if M&lt;br /&gt;
|-&lt;br /&gt;
| LOCATE || $00:1084 || Move the cursor to a new position on the screen.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || The column for the cursor&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || The row for the cursor&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| CSRRIGHT || $00:1090 || Move the cursor one position to the right&lt;br /&gt;
|-&lt;br /&gt;
| CSRLEFT || $00:1094 || Move the cursor one position to the left&lt;br /&gt;
|-&lt;br /&gt;
| CSRUP || $00:1098 || Move the cursor up one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRDOWN || $00:109C || Move the cursor down one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRHOME || $00:10A0 || Move the cursor to the upper-left corner&lt;br /&gt;
|-&lt;br /&gt;
| SCROLLUP || $00:10A4 || Scroll the screen up one line. Creates an empty line at the bottom.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| CLRSCREEN || $00:10B0 || Clear the screen&lt;br /&gt;
|-&lt;br /&gt;
| INITCHLUT || $00:10B4 || Init character look-up table&lt;br /&gt;
|-&lt;br /&gt;
| INITSUPERIO || $00:10B8 || Init Super-IO chip&lt;br /&gt;
|-&lt;br /&gt;
| INITKEYBOARD || $00:10BC || Init keyboard&lt;br /&gt;
|-&lt;br /&gt;
| INITRTC || $00:10C0 || Init Real-Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| INITCURSOR || $00:10C4 || Init the Cursors registers&lt;br /&gt;
|-&lt;br /&gt;
| INITFONTSET || $00:10C8 || Init the Internal FONT Memory&lt;br /&gt;
|-&lt;br /&gt;
| INITGAMMATABLE || $00:10CC || Init the RGB GAMMA Look Up Table&lt;br /&gt;
|-&lt;br /&gt;
| INITALLLUT || $00:10D0 || Init the Graphic Engine (Bitmap/Tile/Sprites) LUT&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYTXTMODE || $00:10D4 || Init the Text Mode @ Reset Time&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYGRPMODE || $00:10D8 || Init the Basic Registers for the Graphic Mode&lt;br /&gt;
|-&lt;br /&gt;
| F_OPEN     || $00:10F0 || Open a file for reading/writing. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CREATE   || $00:10F4 || Create a new file and write its first cluster. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CLOSE    || $00:10F8 || Close a file (make sure last cluster is written). DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_WRITE   || $00:10FC || Write the current cluster to the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_READ     || $00:1100 || Read the next cluster from the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_DELETE   || $00:1104 || Delete a file / directory. DOS_PATH_BUFF = a buffer containing the full path to the file (NULL terminated).&lt;br /&gt;
|-&lt;br /&gt;
| F_DIROPEN  || $00:1108 || Open a directory and seek the first directory entry. NOTE: currently only works with the root directory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || IN || Points to a file descriptor for the path to lookup. NOTE: currently unused.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the first FAT directory entry in that directory.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRNEXT  || $00:110C || seek to the next directory of an open directory&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || IN || Pointer to the current FAT directory entry.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the next FAT directory entry.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRREAD  || $00:1110 || Read the directory entry for the specified file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || IN || The buffer containing the path to the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the FAT directory entry for that file.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRWRITE || $00:1114 || Write any changes in the current directory cluster back to the drive&lt;br /&gt;
|-&lt;br /&gt;
| F_LOAD     || $00:1118 || load a binary file into memory, supports multiple file formats&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || Pointer to the location to load the file (any value &amp;gt; $3F:FFFF to load the file where the file specifies).&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_SAVE     || $00:111C || Save memory to a binary file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to create.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || Address of the first byte to save.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || Address of the last byte to save.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| CMDBLOCK ||  $00:1120 || Send a command to a block device.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_DEV || The target device&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 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.  &lt;br /&gt;
|-&lt;br /&gt;
| F_MOUNT || $00:1128 || Mount the designated block device. BIOS_DEV is the device number to mount.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
is a limit of 8 file descriptors that can be allocated at any one time.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
allocated previously through F_ALLOCFD.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| TESTBREAK || $00:113C || [v0.4] Check if BREAK was pressed recently by the user (C is set if true, clear if false)&lt;br /&gt;
|-&lt;br /&gt;
| SETTABLE || $00:1140 || [v0.4] Set the keyboard scan code -&amp;gt; character translation tables (B:X points to the new tables). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
|-&lt;br /&gt;
| DELAY || $00:114C || [v0.4] Wait at least Y:X ticks of the system clock.&lt;br /&gt;
|-&lt;br /&gt;
| IP_INIT || $00:1150 || [v0.5] Initialize network stack; B:Y-&amp;gt;ip, mask, default_route.  buffer_ptr below is 24 of 32 bits.&lt;br /&gt;
|-&lt;br /&gt;
| UDP_SEND || $00:1154|| [v0.5] Send a UDP packet:  0:X-&amp;gt;local_port, remote_ip, remote_port, buffer_ptr, size, copied&lt;br /&gt;
|-&lt;br /&gt;
| UDP_RECV || $00:1158|| [v0.5] Receive a UDP packet:  0:X-&amp;gt;local_port, remote_ip, remote_port, buffer_ptr, size, copied&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DOS Calling Conventions ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
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&lt;br /&gt;
variables may contain non-zero status codes describing the nature of the failure.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Address !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || $00:0340 || 4 || A pointer to a file descriptor structure (defined below).&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || $00:0400 || 256 || A buffer space for storing a path to a file or directory.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || $00:0354 || 4 || A pointer to a block of memory to be filled from the disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || $00:0350 || 4 || A pointer to a block of memory to write to disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || $00:0358 || 4 || A pointer to the last byte of a block of memory.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_STATUS || $00:032E || 1 || A status code for DOS operations. $00 = success&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_STATUS || $00:0320 || 1 || A status code for sector level operations. $00 = success&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== File Descriptor ====&lt;br /&gt;
&lt;br /&gt;
Most DOS subroutines take a pointer to a file descriptor as an argument. This file descriptor contains several elements needed to manage a file,&lt;br /&gt;
including the buffer containing the current cluster of the file:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Offset !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| STATUS || 0 || 1 || A special status byte containing information about the file's state&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Value !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_READ || $01 || The file is open for reading&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_WRITE || $02 || The file is open for writing&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_OPEN || $40 || The file is open.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_ERROR || $60 || There is an error with the file.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_EOF || $80 || The file is being read and has reach the end of the file.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| DEV || 1 || 1 || A byte containing the device number for the file (should not be modified by the user program).&lt;br /&gt;
|-&lt;br /&gt;
| PATH || 2 || 4 || A pointer to a null-terminated string containing the path to the file. Set by the user program.&lt;br /&gt;
|-&lt;br /&gt;
| CLUSTER || 6 || 4 || The ID of the current cluster being read or written. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| FIRST_CLUSTER || 10 || 4 || The ID of the first cluster of the file. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SIZE || 18 || 4 || The size of the file in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_DATE || 22 || 2 || The creation date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_TIME || 24 || 2 || The creation time in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_DATE || 26 || 2 || The modification date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_TIME || 28 || 2 || The modification time in the same format as used by FAT.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Network Calls ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
IP_INIT&lt;br /&gt;
  IN:     B:Y-&amp;gt;ip_info (below)&lt;br /&gt;
  OUT:    Carry set on error (ethernet card not found or won't init)&lt;br /&gt;
  NOTES:  A default route in the 0.x.x.x range is formally unroutable.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UDP_SEND&lt;br /&gt;
  IN:     0:X-&amp;gt;udp_info (below)&lt;br /&gt;
  OUT:    Carry set on error (not initialized, no route to host, EOM)&lt;br /&gt;
  NOTES:  &amp;quot;No route to host&amp;quot; is usually temporary while the stack is &lt;br /&gt;
          awaiting an ARP response from the target or the router;&lt;br /&gt;
          callers are expected to retry the send.  The stack rate-&lt;br /&gt;
          limits ARP requests to approximately 2/s per address.&lt;br /&gt;
          Sends to your IPv4 broadcast address will be sent to the&lt;br /&gt;
          broadcast MAC (ff:ff:ff:ff:ff:ff).  An EOM should only occur &lt;br /&gt;
          if you aren't calling UDP_RECV often enough to drain the &lt;br /&gt;
          incoming UDP packet queue.  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
UDP_RECV&lt;br /&gt;
  IN:     0:X-&amp;gt;udp_info (below)&lt;br /&gt;
  OUT:    Carry set on error (not initialized), Z set on queue empty.&lt;br /&gt;
  NOTES:  You MUST call UDP_RECV semi-regularly; if you don't, the&lt;br /&gt;
          receive queue will eventually fill with garbage.  The net&lt;br /&gt;
          is a messy place, and random devices on your lan are always&lt;br /&gt;
          spamming the local network.  Broadcast UDP packets are&lt;br /&gt;
          accepted and queued like any other UDP packets.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Network Data Structures ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ip_info     .struct&lt;br /&gt;
ip          .fill   4   ; Local ipv4 address in network order&lt;br /&gt;
mask        .fill   4   ; Local ipv4 netmask in network order&lt;br /&gt;
default     .fill   4   ; Default ipv4 route in network order&lt;br /&gt;
size        .ends&lt;br /&gt;
&lt;br /&gt;
udp_info    .struct&lt;br /&gt;
local_port  .word   ?   ; local port #, little-endian&lt;br /&gt;
remote_ip   .fill   4   ; ipv4 address of remote machine, network order&lt;br /&gt;
remote_port .word   ?   ; remote port #, little endian&lt;br /&gt;
buffer      .dword  ?   ; 24-bit address of your data&lt;br /&gt;
buflen      .word   ?   ; length of the above buffer in bytes&lt;br /&gt;
copied      .word   ?   ; number of bytes copied in/out of the above buffer&lt;br /&gt;
size        .ends&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupt Jump Table ==&lt;br /&gt;
&lt;br /&gt;
The kernel provides a jump table for interrupt handler support. When an interrupt is triggered of any particular type, the kernel interrupt handler will&lt;br /&gt;
jump to the vector for that interrupt. The vector should point to a subroutine that returns to the caller through an RTL instruction.&lt;br /&gt;
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.&lt;br /&gt;
Currently, the kernel only supports a few interrupts in this manner. All system interrupts will eventually have an entry in this table.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
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&lt;br /&gt;
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&lt;br /&gt;
number of the interrupt is provided in A, with A[7..4] containing the block number, and A[3..0] containing the interrupt number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Interrupt !! Block !! Number !!  Address !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT00_SOF || 0 || 0 || $00:1700 || Start Of Frame (vertical blank, used by floppy drive code)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT01_SOL || 0 || 1 || $00:1704 || Start Of Line (horizontal blank)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT02_TMR0 || 0 || 2 || $00:1708 || Timer 0 (used by floppy drive code and DELAY call)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT03_TMR1 || 0 || 3 || $00:170C || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT04_TMR2 || 0 || 4 || $00:1710 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT05_RTC       || 0 || 5 || $00:1714 || Real Time Clock interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT06_FDC       || 0 || 6 || $00:1718 || Floppy Drive Controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT07_MOUSE     || 0 || 7 || $00:171C || Mouse interrupt (used by kernel to handle mouse)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT10_KBD       || 1 || 0 || $00:1720 || Keyboard interrupt (used by kernel to handle keyboard input)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT11_COL0      || 1 || 1 || $00:1724 || VICKY_II (INT2) Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT12_COL1      || 1 || 2 || $00:1728 || VICKY_II (INT3) Bitmap Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT13_COM2      || 1 || 3 || $00:172C || Serial port #2 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT14_COM1      || 1 || 4 || $00:1730 || Serial port #1 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT15_MIDI      || 1 || 5 || $00:1734 || MIDI controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT16_LPT       || 1 || 6 || $00:1738 || Parallel port interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDC       || 1 || 7 || $00:173C || SD Card Controller interrupt (no longer used)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT20_OPL       || 2 || 0 || $00:1740 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT21_GABE0     || 2 || 1 || $00:1744 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT22_GABE1     || 2 || 2 || $00:1748 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT23_VDMA      || 2 || 3 || $00:174C || VICKY_II (INT4) - VDMA Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT24_COL2      || 2 || 4 || $00:1750 || VICKY_II (INT5) Tile Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT25_GABE2     || 2 || 5 || $00:1754 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT26_EXT       || 2 || 6 || $00:1758 || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDINS     || 2 || 7 || $00:175C || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT30_OPN2      || 3 || 0 || $00:1760 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT31_OPM       || 3 || 1 || $00:1764 || OPM&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT32_IDE       || 3 || 2 || $00:1768 || HDD IDE Interrupt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special Kernel Variables ==&lt;br /&gt;
&lt;br /&gt;
The kernel keeps track of several variables.&lt;br /&gt;
Most kernel variables should be left alone by applications, but there are some which an application might want to set or read.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Name !! R/W || Description&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000F || $00:0010 || COLS_VISIBLE || RW || The number of columns currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0013 || $00:0014 || LINES_VISIBLE || RW || The number of rows currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0017 || $00:0018 || CURSORPOS || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001A || $00:001B || CURSORX || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001C || $00:001D || CURSORY || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001E || || CURCOLOR || RW || The foreground and background colors to be used when printing via PUTC and PUTS&lt;br /&gt;
|-&lt;br /&gt;
| $00:001F || $00:0020 || COLORPOS || RO || The address of the text color cell under the cursor&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== BIOS_STATUS ($00:320) ===&lt;br /&gt;
&lt;br /&gt;
This status variable records any error condition related to the low level block level BIOS routines.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| N/A || $00 || The last BIOS operation was successful&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_BADDEV || $80 || BIOS bad device # error&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_MOUNT || $81 || BIOS failed to mount the device&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_READ || $82 || BIOS failed to read from a device&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_WRITE || $83 || BIOS failed to write to a device&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_TRACK || $84 || BIOS failed to seek to the correct track&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_CMD || $85 || A general block device command error&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_WRITEPROT || $86 || The media was write-protected&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_NOMEDIA || $87 || No media detected... unable to read/write in time&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_RESULT || $88 || Couldn't get the result bytes for some reason&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_OOS || $89 || FDC state is somehow out of sync with the driver.&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_NOTATA || $8A || IDE drive is not ATA&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_NOTINIT || $8B || Could not initilize the device&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_ERR_TIMEOUT || $8C || Timeout error&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== FDC_ST0 ($00:326) ===&lt;br /&gt;
&lt;br /&gt;
This status variable records hardware level status codes.&lt;br /&gt;
For FDC access, it represents the first status byte of the floppy drive controller.&lt;br /&gt;
For SDC and HDD access, it records the SDC and IDE level hardware status, respectively.&lt;br /&gt;
The meaning of the bits will vary depending on the hardware accessed, and you should refer&lt;br /&gt;
to the documentation on that specific device for details.&lt;br /&gt;
&lt;br /&gt;
=== DOS_STATUS ($00:32E) ===&lt;br /&gt;
&lt;br /&gt;
This status variable records any error condition related to the DOS and FAT level code:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Code !! Description&lt;br /&gt;
|-&lt;br /&gt;
| N/A || 0 || The last DOS operation was successful&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_READ || 1 || We could not read a sector, check BIOS_STATUS for details&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOTMBR || 2 || We could not find the MBR&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOFAT32 || 3 || We could not find a FAT32 parition using LBA&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOINIT || 4 || We could not INIT the block device&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_VOLID || 5 || Volume ID sector could not be loaded&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_FAT || 6 || Can't scan the FAT for some reason&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_BADPATH || 7 || The path was badly formatted&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NODIR || 8 || Could not read the directory&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOTFOUND || 9 || File/directory requested was not found&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOCLUSTER || 10 || There are no more clusters&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_FILEEXISTS || 11 || There is already a file of that name&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOTOPEN || 12 || File has not been open&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOTREAD || 13 || File is not open for reading&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOTWRITE || 14 || File is not open for writing&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_OPEN || 15 || File is already open&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_PGXSIG || 16 || File does not have the PGX signature&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOEXEC || 17 || File does is not an executable format&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_MEDIAFULL || 18 || There are no more free clusters on the drive&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_WRITEPROT || 19 || The medium is write-protected&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_FATUPDATE || 20 || Can't update the FAT&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_DIRFULL || 21 || The directory is full&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOFD || 22 || No file descriptors are available for allocation&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_NOMEDIA || 23 || No media was present&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_EOF || 24 || At end of file&lt;br /&gt;
|-&lt;br /&gt;
| DOS_ERR_PGZSIG || 25 || File does not have the PGZ signature&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=966</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=966"/>
		<updated>2023-07-19T18:22:48Z</updated>

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

		<summary type="html">&lt;p&gt;PJW: /* Configuring the ESP8266 Router Using the F256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional Wi-Fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the [[F256K]] and [[F256JR]], both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP Wi-Fi router. This document will cover the process of configuring and installing such a Wi-Fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs.&lt;br /&gt;
&lt;br /&gt;
= Supplies Needed =&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be Wi-Fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable --- A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
= Software Needed =&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/Wi-Fi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : [Optional] Once installed, the Wi-Fi router firmware must be configured. This process requires connecting to the ESP8266's SLIP interface on a particular port and sending some commands. This can be done either through Linux or using the &amp;lt;code&amp;gt;Wi-Fi&amp;lt;/code&amp;gt; command in the TinyCore DOS.&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the Wi-Fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
= Preparing the Feather ESP8266 =&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can be done on the F256 itself using the TinyCore DOS, or it can be done through Linux and using &amp;lt;code&amp;gt;telnet&amp;lt;/code&amp;gt; to connect to the SLIP interface. Currently, Windows and MacOS X do not support SLIP networking, so they cannot be used to configure the router.&lt;br /&gt;
&lt;br /&gt;
== Installation Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools (Linux-only: If Needed)&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
== Installing the ESP_SLIP_ROUTER Firmware ==&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router Using the F256 ==&lt;br /&gt;
&lt;br /&gt;
Once you have installed the ESP router software on the Wi-Fi module and socketed it into the F256 (see below),&lt;br /&gt;
you can use the TinyCore DOS &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command to connect it to your network.&lt;br /&gt;
To use this command, you must have a recent version of TinyCore MicroKernel installed in flash (since 4 July, 2023).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Turn on the machine and wait for the SuperBASIC start screen.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Switch to the TinyCore DOS command line by entering the command:&lt;br /&gt;
&amp;lt;pre&amp;gt;/dos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Set the ssid and password for your network by entering the command:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wifi {ssid} {password}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &amp;lt;code&amp;gt;{ssid}&amp;lt;/code&amp;gt; is the name of your network, and &amp;lt;code&amp;gt;{password}&amp;lt;/code&amp;gt; is its password.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Wait the command to send the configuration data to your Wi-Fi module and reset it.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The status light on your Wi-Fi module should turn on briefly but go out after the module has connected to your Wi-Fi. If it remains on, it is not able to connect to your wireless network for some reason.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is possible that something might go wrong with your configuration, locking up the &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
The key combination CTRL-C will quit the command.&lt;br /&gt;
If a second attempt still does not work, you may need to completely turn off your system and leave it off for a few minutes to let the memory completely clear out to a random state before you try again.&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router for Your Network in Linux ==&lt;br /&gt;
&lt;br /&gt;
To configure the router using Linux, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the Wi-Fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the Wi-Fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
= Installing the Wi-Fi Module in Your F256 =&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the Wi-Fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the Wi-Fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 Wi-Fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with Wi-Fi module position highlighted|Figure 1: F256jr motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with Wi-Fi module position highlighted|Figure 2: F256k motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 Wi-Fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the Wi-Fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the Wi-Fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a Wi-Fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=964</id>
		<title>F256 WiFi Setup</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=964"/>
		<updated>2023-07-05T02:49:15Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Configuring the ESP8266 Router Using the F256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional Wi-Fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the [[F256K]] and [[F256JR]], both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP Wi-Fi router. This document will cover the process of configuring and installing such a Wi-Fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs.&lt;br /&gt;
&lt;br /&gt;
= Supplies Needed =&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be Wi-Fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable --- A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
= Software Needed =&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/Wi-Fi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : [Optional] Once installed, the Wi-Fi router firmware must be configured. This process requires connecting to the ESP8266's SLIP interface on a particular port and sending some commands. This can be done either through Linux or using the &amp;lt;code&amp;gt;Wi-Fi&amp;lt;/code&amp;gt; command in the TinyCore DOS.&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the Wi-Fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
= Preparing the Feather ESP8266 =&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can be done on the F256 itself using the TinyCore DOS, or it can be done through Linux and using &amp;lt;code&amp;gt;telnet&amp;lt;/code&amp;gt; to connect to the SLIP interface. Currently, Windows and MacOS X do not support SLIP networking, so they cannot be used to configure the router.&lt;br /&gt;
&lt;br /&gt;
== Installation Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools (Linux-only: If Needed)&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
== Installing the ESP_SLIP_ROUTER Firmware ==&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router Using the F256 ==&lt;br /&gt;
&lt;br /&gt;
Once you have installed the ESP router software on the Wi-Fi module and socketed it into the F256 (see below),&lt;br /&gt;
you can use the TinyCore DOS &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
To use this command, you must have a recent version of TinyCore MicroKernel installed in flash (since 4 July, 2023).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Turn on the machine and wait for the SuperBASIC start screen.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Switch to the TinyCore DOS command line by entering the command:&lt;br /&gt;
&amp;lt;pre&amp;gt;/dos&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Set the ssid and password for your network by entering the command:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wifi {ssid} {password}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
where &amp;lt;code&amp;gt;{ssid}&amp;lt;/code&amp;gt; is the name of your network, and &amp;lt;code&amp;gt;{password}&amp;lt;/code&amp;gt; is its password.&lt;br /&gt;
&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Wait the command to send the configuration data to your Wi-Fi module and reset it.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;The status light on your Wi-Fi module should turn on briefly but go out after the module has connected to your Wi-Fi. If it remains on, it is not able to connect to your wireless network for some reason.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is possible that something might go wrong with your configuration, locking up the &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
The key combination CTRL-C will quit the command.&lt;br /&gt;
If a second attempt still does not work, you may need to completely turn off your system and leave it off for a few minutes to let the memory completely clear out to a random state before you try again.&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router for Your Network in Linux ==&lt;br /&gt;
&lt;br /&gt;
To configure the router using Linux, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the Wi-Fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the Wi-Fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
= Installing the Wi-Fi Module in Your F256 =&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the Wi-Fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the Wi-Fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 Wi-Fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with Wi-Fi module position highlighted|Figure 1: F256jr motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with Wi-Fi module position highlighted|Figure 2: F256k motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 Wi-Fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the Wi-Fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the Wi-Fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a Wi-Fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256K&amp;diff=963</id>
		<title>F256K</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256K&amp;diff=963"/>
		<updated>2023-07-05T02:43:06Z</updated>

		<summary type="html">&lt;p&gt;PJW: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The F256K is a 65xx-based system. It's an encased form factor with a built-in keyboard. It includes the following features:&lt;br /&gt;
* 512K of Shared System &amp;amp; Video RAM&lt;br /&gt;
* 256k of flash&lt;br /&gt;
* 256k of cartridge ram/rom &lt;br /&gt;
* [[TinyVICKY]] Graphic Chip (CFP9599)&lt;br /&gt;
* Port for connecting FNX4N4S, which can be used to connect Atari-Style Joysticks or NES/SNES gamepads&lt;br /&gt;
* 1x IEC Port to interface to Commodore Drives&lt;br /&gt;
* A few sound chips: SID, PSG/SN76489, OPL3&lt;br /&gt;
* 1x Simple 3-wire UART (RS-232 Port, [[F256_WiFi|Feather ESP8266 wifi]]&lt;br /&gt;
&lt;br /&gt;
It shares many similarities to the [[F256JR]] and programs can in many cases run straightforwardly on both.&lt;br /&gt;
&lt;br /&gt;
The 'K' in the name comes from the fact that it has an integrated keyboard, unrelated to the amount of memory available in the system. The base system has 512K of system memory; with expansion cartridge brings it up to 768K.&lt;br /&gt;
&lt;br /&gt;
A common variety of the F256K uses the 6502 CPU. That said, the 65816 CPU can also be installed.&lt;br /&gt;
 &lt;br /&gt;
[[File:f256k_Secondpass.6-819x1024.png|400px]]&lt;br /&gt;
&lt;br /&gt;
= Ports and connectors =&lt;br /&gt;
&lt;br /&gt;
The back of the unit looks like this:&lt;br /&gt;
&lt;br /&gt;
[[File:f256k_rear_connectors.PNG]]&lt;br /&gt;
&lt;br /&gt;
* '''Power Switch''' is a toggle-style switch to turn the unit off and on.&lt;br /&gt;
* '''Reset Button''' reboots the system, with values in RAM persisting. If RAM has been modified using the debug interface, it stays modified.&lt;br /&gt;
* '''Power Jack''' is for plugging in A/C power. Use, for example, a +12V or +9V with 2.5mm barrel connector.&lt;br /&gt;
* '''USB Debug''' is for connection to a debug host computer, debugging F256K as a target, for example using a mini USB to USB A cable.&lt;br /&gt;
* '''PS/2''' can be used for connecting external keyboard and/or mouse.&lt;br /&gt;
* '''FNX4N4S Adapter''' provides connections to gamepads (e.g., SNES-style game controller) through the FNX4N4S adapter.&lt;br /&gt;
* '''IEC''' provides connectivity to Commodore-compatible devices that use serial interface&lt;br /&gt;
* '''DVI''' is for connecting a display.&lt;br /&gt;
* '''RS-232''' provides a standard RS-232 serial interface.&lt;br /&gt;
* '''Headphones''' is a standard 3.5mm headphone jack.&lt;br /&gt;
* '''Audio Line Out''' provides stereo audio output.&lt;br /&gt;
&lt;br /&gt;
= Switches =&lt;br /&gt;
The bottom of the unit looks like this:&lt;br /&gt;
&lt;br /&gt;
[[File:f256k_dip_switches.jpg|600px]]&lt;br /&gt;
&lt;br /&gt;
There are eight DIP switches, with different interpretations depending on whether a kernel is present on the system. &lt;br /&gt;
If a kernel is present on the system, as the unit is shipped with, these switches are:&lt;br /&gt;
* [8] - On: Enable GAMMA correction&lt;br /&gt;
* [7] - Graphics resolution controls&lt;br /&gt;
* [6] - Not used&lt;br /&gt;
* [5] - Not used&lt;br /&gt;
* [4] - On: Feather Board installed (ESP8266)&lt;br /&gt;
* [3] - On: Enable SLIP Base Networking&lt;br /&gt;
* [2] - Reserved&lt;br /&gt;
* [1] - On: Enable Boot from RAM, off means it will boot from a pre-installed kernel in the first 48K of memory.&lt;br /&gt;
&lt;br /&gt;
If a kernel is not present on the system, these switches can be used as desired:&lt;br /&gt;
* [8] - On: Enable GAMMA correction&lt;br /&gt;
* [7] - USER2&lt;br /&gt;
* [6] - USER1&lt;br /&gt;
* [5] - USER0&lt;br /&gt;
* [4] - BOOT Mode3&lt;br /&gt;
* [3] - BOOT Mode2&lt;br /&gt;
* [2] - BOOT Mode1&lt;br /&gt;
* [1] - BOOT Mode0&lt;br /&gt;
&lt;br /&gt;
= Boot =&lt;br /&gt;
To start the machine, ensure A/C power is plugged in and flip the power switch. The exact boot behavior depends on the &amp;quot;Boot from RAM&amp;quot; DIP switch on the bottom.&lt;br /&gt;
&lt;br /&gt;
* If the DIP1 &amp;quot;Boot from RAM&amp;quot; switch is '''off''' and a kernel is used, the kernel will search the 48K of memory for a pre-loaded kernel binary. &lt;br /&gt;
&lt;br /&gt;
* If the DIP1 &amp;quot;Boot from RAM&amp;quot; switch is '''on''', then control is transferred to the reset vector entrypoint located at offset $FFFC.&lt;br /&gt;
&lt;br /&gt;
Switching DIP1 to 'on' is useful for developer convenience and testing code. For those using the machine outside of a development-style environment, it's more likely the switch will be 'off'.&lt;br /&gt;
&lt;br /&gt;
The ''Boot from RAM'' and ''Boot from flash'' options in uploader tools such as [https://github.com/pweingar/FoenixMgr FoenixMgr] or [https://github.com/clandrew/F256Uploader F256 Uploader] are unrelated to the &amp;quot;Boot from RAM&amp;quot; DIP switch:&lt;br /&gt;
* The DIP switch alters boot behavior by telling the kernel to search the first 48K of RAM for a pre-loaded kernel binary. &lt;br /&gt;
* Those tools, on the other hand, initiate a new boot using a soft reset signal, and the choice of ''Boot from RAM'' versus ''Boot from flash'' affects the initial memory look-up tables upon boot. &lt;br /&gt;
&lt;br /&gt;
So those tools' options are also useful for developer convenience, they just affect a different part of the boot process, and are tightly integrated with the act of pushing data over the debug port onto F256K memory.&lt;br /&gt;
&lt;br /&gt;
= Memory =&lt;br /&gt;
The F256K has a 16-bit address space, $0000 through $FFFF, visible to its CPU. In other words, the CPU address space is 64KB in size. While other units such as the TinyVicky graphics unit can access memory beyond that, the CPU itself has a 16-bit address space. &lt;br /&gt;
&lt;br /&gt;
The address space is divided up into eight equal-sized ''banks''. The CPU-visible address space is divided into banks as follows:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Bank&lt;br /&gt;
! scope=&amp;quot;col&amp;quot;| Address Range&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 0&lt;br /&gt;
| $0000-$1FFF&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 1&lt;br /&gt;
| $2000-$3FFF&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 2&lt;br /&gt;
| $4000-$5FFF&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 3&lt;br /&gt;
| $6000-$7FFF&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 4&lt;br /&gt;
| $8000-$9FFF&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 5&lt;br /&gt;
| $A000-$BFFF&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 6&lt;br /&gt;
| $C000-$DFFF&lt;br /&gt;
|-&lt;br /&gt;
| scope=&amp;quot;row&amp;quot;| 7&lt;br /&gt;
| $E000-$FFFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Note that each bank is $2000 in size; on other (e.g., non-Foenix) platforms, the term ''bank'' may be used differently. Here, each bank is 8KB, or $2000. &lt;br /&gt;
&lt;br /&gt;
Since the F256K has a larger amount of total memory (up to 768KB) than this address space exposes, programs use and adjust the address space as a &amp;quot;window&amp;quot; to underlying memory needed by the CPU at any given time. &lt;br /&gt;
&lt;br /&gt;
In other words, programs control what device memory this address space maps to. They do this through ''memory lookup tables'', or ''MLUT''s for short. Up to four MLUTs can be set up at a time, and programs choose which one is active at any given time.&lt;br /&gt;
&lt;br /&gt;
To ensure that control of MLUTs is always possible, CPU address $0000 is special, and is a memory-mapped register to manipulate MLUTs:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
MMU_MEM_CTRL = $0000&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For example, to enable editing of MLUT 0, set the MMU_EDIT_EN (the leftmost) bit:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
LDA MMU_MEM_CTRL&lt;br /&gt;
ORA #MMU_EDIT_EN&lt;br /&gt;
STA MMU_MEM_CTRL&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for where a bank of CPU address space can map to: programs can map a bank to any of RAM, flash or expansion memory.&lt;br /&gt;
&lt;br /&gt;
An example of a straightforward mapping is to simply map the CPU address space linearly to the first 64KB of RAM.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
LDA #$00&lt;br /&gt;
STA MMU_MEM_BANK_0 ; map $000000 to bank 0&lt;br /&gt;
INA&lt;br /&gt;
STA MMU_MEM_BANK_1 ; map $002000 to bank 1&lt;br /&gt;
INA&lt;br /&gt;
STA MMU_MEM_BANK_2 ; map $004000 to bank 2&lt;br /&gt;
INA&lt;br /&gt;
STA MMU_MEM_BANK_3 ; map $006000 to bank 3&lt;br /&gt;
INA&lt;br /&gt;
STA MMU_MEM_BANK_4 ; map $008000 to bank 4&lt;br /&gt;
INA&lt;br /&gt;
STA MMU_MEM_BANK_5 ; map $00a000 to bank 5&lt;br /&gt;
INA&lt;br /&gt;
STA MMU_MEM_BANK_6 ; map $00c000 to bank 6&lt;br /&gt;
INA&lt;br /&gt;
STA MMU_MEM_BANK_7 ; map $00e000 to bank 7&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
where MMU_MEM_BANK_0, 1, 2, are specially mapped at addresses $0008, $0009, and so on. In this example code, the accumulator stores the bank number of device memory, and that value is written to the corresponding register. Write higher values to map later regions of device memory.&lt;br /&gt;
&lt;br /&gt;
Finally, use&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
LDA MMU_MEM_CTRL&lt;br /&gt;
AND #~(MMU_EDIT_EN)&lt;br /&gt;
STA MMU_MEM_CTRL  ; disable mmu edit, use mmu lut 0&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
to commit the changes and enable use of the updated MLUT 0.&lt;br /&gt;
&lt;br /&gt;
= Sound =&lt;br /&gt;
The F256K has a few different components capable of processing sound:&lt;br /&gt;
* Two PSG(SN76489) chips&lt;br /&gt;
* Two SID chips; SID, or Sound Interface Device, was used on C64 and others&lt;br /&gt;
* Yamaha OPL3 chip&lt;br /&gt;
&lt;br /&gt;
The PSG chips are memory-mapped as follows:&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
PSG_INT_L_PORT = $D600          ; Control register for the SN76489&lt;br /&gt;
PSG_INT_B_PORT = $D608          ; Control register for the SN76489, writes to both L and R ports&lt;br /&gt;
PSG_INT_R_PORT = $D610          ; Control register for the SN76489&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Keyboard =&lt;br /&gt;
The built-in keyboard does not operate by PS/2 controller, it's a matrix keyboard controlled by two WDC VIA (Versatile Interface Adapter) controllers and the CPU's NMI signal. &lt;br /&gt;
&lt;br /&gt;
There are two ways for programs to interact with the keyboard:&lt;br /&gt;
* '''Using the kernel''', where the exact mechanism depends on the kernel involved; this can be through an environment like SuperBASIC that talks to the kernel&lt;br /&gt;
* '''Directly with the device''', using memory mappings.&lt;br /&gt;
&lt;br /&gt;
For more information on interacting directly with the keyboard device, see [[F256K Keyboard]].&lt;br /&gt;
&lt;br /&gt;
The F256K also supports plugging in an external keyboard. If this is done, it is through PS/2 interface.&lt;br /&gt;
&lt;br /&gt;
= Manual =&lt;br /&gt;
For a technical reference, use this manual:&lt;br /&gt;
https://github.com/pweingar/F256Manual&lt;br /&gt;
&lt;br /&gt;
Although the manual is F256Jr-centric, it's suitable for F256K development owing to the similarity of the two units. It describes common aspects between F256Jr and F256K, with some sections highlighting F256K functionality that differs.&lt;br /&gt;
&lt;br /&gt;
= Kernels =&lt;br /&gt;
There are three kernels for the F256K.&lt;br /&gt;
* [[The TinyCore MicroKernel]] (ships with the unit)&lt;br /&gt;
* [[OpenKERNAL]] (for those wishing to run software written for the CBM KERNAL)&lt;br /&gt;
* [https://github.com/ghackwrench/FoenixKERNAL FoenixKERNAL], an open source, CBM-style layer also compatible with software written for Commodore 64 KERNAL&lt;br /&gt;
&lt;br /&gt;
= Tools =&lt;br /&gt;
* [https://github.com/clandrew/F256Uploader F256 Uploader]&lt;br /&gt;
* https://github.com/pweingar/FoenixMgr&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256JR&amp;diff=962</id>
		<title>F256JR</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256JR&amp;diff=962"/>
		<updated>2023-07-05T02:42:09Z</updated>

		<summary type="html">&lt;p&gt;PJW: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The F256 Jr is a 65C02 based system which includes the following features:&lt;br /&gt;
&lt;br /&gt;
* 512K of Shared System &amp;amp; Video RAM (256k on the Rev A)&lt;br /&gt;
* 256k of flash&lt;br /&gt;
* 256k of cartridge ram/rom &lt;br /&gt;
* TinyVICKY Graphic Chip (CFP9599)&lt;br /&gt;
* 1x Simple 3-wire UART (RS-232 Port, [[F256_WiFi|Feather ESP8266 wifi]], or Feather MIDI)&lt;br /&gt;
* 2x Atari Style Joystick Ports, 1x DB9 to interface to NES/SNES Adapter (For Rev B Only)&lt;br /&gt;
* 1x IEC Port to interface to Commodore Drives&lt;br /&gt;
* 2x Internal PSG Sound Chip&lt;br /&gt;
* 2x External SID Sockets&lt;br /&gt;
&lt;br /&gt;
Aside from its sound chip, it's very similar to the [[F256K]].&lt;br /&gt;
&lt;br /&gt;
= Hardware Setup =&lt;br /&gt;
[[File:Pinout_Jr_December_7th_Trans.png|200px]]&lt;br /&gt;
&lt;br /&gt;
The PS2 mouse port may be wired to the keyboard port and then split out using a laptop PS2 splitter.&lt;br /&gt;
* [[Dual PS2 Port]]&lt;br /&gt;
&lt;br /&gt;
If your Jr. is booting to a blank screen with a dark purple border, be sure that the RAM/FLASH jumper is set to FLASH.&lt;br /&gt;
&lt;br /&gt;
= Kernels =&lt;br /&gt;
There are three kernels for the Jr.&lt;br /&gt;
* [[The TinyCore MicroKernel]] (ships with the unit)&lt;br /&gt;
* [[OpenKERNAL]] (for those wishing to run software written for the CBM KERNAL)&lt;br /&gt;
* [https://github.com/ghackwrench/FoenixKERNAL FoenixKERNAL], an open source, CBM-style layer also compatible with Commodore 64 KERNAL&lt;br /&gt;
&lt;br /&gt;
= BASIC =&lt;br /&gt;
The F256 Jr. ships with SuperBASIC: https://github.com/paulscottrobson/superbasic&lt;br /&gt;
&lt;br /&gt;
= DOS =&lt;br /&gt;
* There is a simple example DOS shell for the MicroKernel in the kernel/dos project: https://github.com/ghackwrench/F256_Jr_Kernel_DOS&lt;br /&gt;
* It may also be found in the SuperBASIC project under source/releases: https://github.com/paulscottrobson/superbasic&lt;br /&gt;
* SuperBASIC's install scripts install it by default.  To access it, type &amp;quot;DOS&amp;quot; from BASIC.&lt;br /&gt;
* To return to SuperBASIC, type &amp;quot;basic &amp;lt;enter&amp;gt;&amp;quot; from DOS.&lt;br /&gt;
* To auto-boot into DOS instead of BASIC, install DOS in flash slot 1, and BASIC in slots 2,3,4. &lt;br /&gt;
&lt;br /&gt;
= Assemblers =&lt;br /&gt;
* 64tass: https://sourceforge.net/projects/tass64/&lt;br /&gt;
&lt;br /&gt;
= C compiler =&lt;br /&gt;
* [[cc65]]&lt;br /&gt;
&lt;br /&gt;
= Tools =&lt;br /&gt;
* [https://github.com/clandrew/F256Uploader F256 Uploader]&lt;br /&gt;
* https://github.com/pweingar/FoenixMgr&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=961</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=961"/>
		<updated>2023-07-05T02:41:24Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The F256 computers (both the [[F256JR]] and [[F256K]]) optionally support connecting to your home wireless network.&lt;br /&gt;
Setting up your F256 to use wi-fi requires the installation and setup of a micro-controller board as a wi-fi router. The process is detailed in the [[F256_WiFi_Setup|F256 Wi-Fi Setup document]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=960</id>
		<title>F256 WiFi Setup</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=960"/>
		<updated>2023-07-05T02:40:48Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Configuring the ESP8266 Router Using the F256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional Wi-Fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the [[F256K]] and [[F256JR]], both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP Wi-Fi router. This document will cover the process of configuring and installing such a Wi-Fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs.&lt;br /&gt;
&lt;br /&gt;
= Supplies Needed =&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be Wi-Fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable --- A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
= Software Needed =&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/Wi-Fi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : [Optional] Once installed, the Wi-Fi router firmware must be configured. This process requires connecting to the ESP8266's SLIP interface on a particular port and sending some commands. This can be done either through Linux or using the &amp;lt;code&amp;gt;Wi-Fi&amp;lt;/code&amp;gt; command in the TinyCore DOS.&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the Wi-Fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
= Preparing the Feather ESP8266 =&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can be done on the F256 itself using the TinyCore DOS, or it can be done through Linux and using &amp;lt;code&amp;gt;telnet&amp;lt;/code&amp;gt; to connect to the SLIP interface. Currently, Windows and MacOS X do not support SLIP networking, so they cannot be used to configure the router.&lt;br /&gt;
&lt;br /&gt;
== Installation Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools (Linux-only: If Needed)&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
== Installing the ESP_SLIP_ROUTER Firmware ==&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router Using the F256 ==&lt;br /&gt;
&lt;br /&gt;
Once you have installed the ESP router software on the Wi-Fi module and socketed it into the F256 (see below),&lt;br /&gt;
you can use the TinyCore DOS &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
To use this command, you must have a recent version of TinyCore MicroKernel installed in flash (since 4 July, 2023).&lt;br /&gt;
&lt;br /&gt;
# Turn on the machine and wait for the SuperBASIC start screen&lt;br /&gt;
# Enter the command &amp;quot;&amp;lt;code&amp;gt;/dos&amp;lt;/code&amp;gt;&amp;quot; to switch to the TinyCore DOS command line&lt;br /&gt;
# Enter the command &amp;quot;&amp;lt;code&amp;gt;wifi {ssid} {password}&amp;lt;/code&amp;gt;&amp;quot;, where &amp;lt;code&amp;gt;{ssid}&amp;lt;/code&amp;gt; is your network's name, and &amp;lt;code&amp;gt;{password}&amp;lt;/code&amp;gt; is the password.&lt;br /&gt;
# Wait the command to send the configuration data to your Wi-Fi module and reset it.&lt;br /&gt;
# The status light on your Wi-Fi module should turn on briefly but go out after the module has connected to your Wi-Fi. If it remains on, it is not able to connect to your wireless network for some reason.&lt;br /&gt;
&lt;br /&gt;
It is possible that something might go wrong with your configuration, locking up the &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
The key combination CTRL-C will quit the command.&lt;br /&gt;
If a second attempt still does not work, you may need to completely turn off your system and leave it off for a few minutes to let the memory completely clear out to a random state before you try again.&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router for Your Network in Linux ==&lt;br /&gt;
&lt;br /&gt;
To configure the router using Linux, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the Wi-Fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the Wi-Fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
= Installing the Wi-Fi Module in Your F256 =&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the Wi-Fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the Wi-Fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 Wi-Fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with Wi-Fi module position highlighted|Figure 1: F256jr motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with Wi-Fi module position highlighted|Figure 2: F256k motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 Wi-Fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the Wi-Fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the Wi-Fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a Wi-Fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=959</id>
		<title>F256 WiFi Setup</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=959"/>
		<updated>2023-07-05T02:40:09Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional Wi-Fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the [[F256K]] and [[F256JR]], both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP Wi-Fi router. This document will cover the process of configuring and installing such a Wi-Fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs.&lt;br /&gt;
&lt;br /&gt;
= Supplies Needed =&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be Wi-Fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable --- A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
= Software Needed =&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/Wi-Fi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : [Optional] Once installed, the Wi-Fi router firmware must be configured. This process requires connecting to the ESP8266's SLIP interface on a particular port and sending some commands. This can be done either through Linux or using the &amp;lt;code&amp;gt;Wi-Fi&amp;lt;/code&amp;gt; command in the TinyCore DOS.&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the Wi-Fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
= Preparing the Feather ESP8266 =&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can be done on the F256 itself using the TinyCore DOS, or it can be done through Linux and using &amp;lt;code&amp;gt;telnet&amp;lt;/code&amp;gt; to connect to the SLIP interface. Currently, Windows and MacOS X do not support SLIP networking, so they cannot be used to configure the router.&lt;br /&gt;
&lt;br /&gt;
== Installation Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools (Linux-only: If Needed)&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
== Installing the ESP_SLIP_ROUTER Firmware ==&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router Using the F256 ==&lt;br /&gt;
&lt;br /&gt;
Once you have installed the ESP router software on the Wi-Fi module and socketed it into the F256 (see below),&lt;br /&gt;
you can use the TinyCore DOS &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
To use this command, you must have a recent version of TinyCore MicroKernel installed in flash (since 4 July, 2023).&lt;br /&gt;
&lt;br /&gt;
# Turn on the machine and wait for the SuperBASIC start screen&lt;br /&gt;
# Enter the command &amp;lt;code&amp;gt;/dos&amp;lt;/code&amp;gt; to switch to the TinyCore DOS command line&lt;br /&gt;
# Enter the command &amp;lt;code&amp;gt;wifi {ssid} {password}&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;{ssid}&amp;lt;/code&amp;gt; is your network's name, and &amp;lt;code&amp;gt;{password}&amp;lt;/code&amp;gt; is the password.&lt;br /&gt;
# Wait the command to send the configuration data to your Wi-Fi module and reset it.&lt;br /&gt;
# The status light on your Wi-Fi module should turn on briefly but go out after the module has connected to your Wi-Fi. If it remains on, it is not able to connect to your wireless network for some reason.&lt;br /&gt;
&lt;br /&gt;
It is possible that something might go wrong with your configuration, locking up the &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
The key combination CTRL-C will quit the command.&lt;br /&gt;
If a second attempt still does not work, you may need to completely turn off your system and leave it off for a few minutes to let the memory completely clear out to a random state before you try again.&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router for Your Network in Linux ==&lt;br /&gt;
&lt;br /&gt;
To configure the router using Linux, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the Wi-Fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the Wi-Fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
= Installing the Wi-Fi Module in Your F256 =&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the Wi-Fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the Wi-Fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 Wi-Fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with Wi-Fi module position highlighted|Figure 1: F256jr motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with Wi-Fi module position highlighted|Figure 2: F256k motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 Wi-Fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the Wi-Fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the Wi-Fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a Wi-Fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=958</id>
		<title>F256 WiFi Setup</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=958"/>
		<updated>2023-07-05T02:38:37Z</updated>

		<summary type="html">&lt;p&gt;PJW: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional Wi-Fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the [[F256k]] and [[F256jr]], both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP Wi-Fi router. This document will cover the process of configuring and installing such a Wi-Fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs.&lt;br /&gt;
&lt;br /&gt;
= Supplies Needed =&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be Wi-Fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable --- A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
= Software Needed =&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/Wi-Fi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : [Optional] Once installed, the Wi-Fi router firmware must be configured. This process requires connecting to the ESP8266's SLIP interface on a particular port and sending some commands. This can be done either through Linux or using the &amp;lt;code&amp;gt;Wi-Fi&amp;lt;/code&amp;gt; command in the TinyCore DOS.&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the Wi-Fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
= Preparing the Feather ESP8266 =&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can be done on the F256 itself using the TinyCore DOS, or it can be done through Linux and using &amp;lt;code&amp;gt;telnet&amp;lt;/code&amp;gt; to connect to the SLIP interface. Currently, Windows and MacOS X do not support SLIP networking, so they cannot be used to configure the router.&lt;br /&gt;
&lt;br /&gt;
== Installation Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools (Linux-only: If Needed)&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
== Installing the ESP_SLIP_ROUTER Firmware ==&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router Using the F256 ==&lt;br /&gt;
&lt;br /&gt;
Once you have installed the ESP router software on the Wi-Fi module and socketed it into the F256 (see below),&lt;br /&gt;
you can use the TinyCore DOS &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
To use this command, you must have a recent version of TinyCore MicroKernel installed in flash (since 4 July, 2023).&lt;br /&gt;
&lt;br /&gt;
# Turn on the machine and wait for the SuperBASIC start screen&lt;br /&gt;
# Enter the command &amp;lt;code&amp;gt;/dos&amp;lt;/code&amp;gt; to switch to the TinyCore DOS command line&lt;br /&gt;
# Enter the command &amp;lt;code&amp;gt;wifi {ssid} {password}&amp;lt;/code&amp;gt;, where &amp;lt;code&amp;gt;{ssid}&amp;lt;/code&amp;gt; is your network's name, and &amp;lt;code&amp;gt;{password}&amp;lt;/code&amp;gt; is the password.&lt;br /&gt;
# Wait the command to send the configuration data to your Wi-Fi module and reset it.&lt;br /&gt;
# The status light on your Wi-Fi module should turn on briefly but go out after the module has connected to your Wi-Fi. If it remains on, it is not able to connect to your wireless network for some reason.&lt;br /&gt;
&lt;br /&gt;
It is possible that something might go wrong with your configuration, locking up the &amp;lt;code&amp;gt;wifi&amp;lt;/code&amp;gt; command.&lt;br /&gt;
The key combination CTRL-C will quit the command.&lt;br /&gt;
If a second attempt still does not work, you may need to completely turn off your system and leave it off for a few minutes to let the memory completely clear out to a random state before you try again.&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router for Your Network in Linux ==&lt;br /&gt;
&lt;br /&gt;
To configure the router using Linux, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the Wi-Fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the Wi-Fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
= Installing the Wi-Fi Module in Your F256 =&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the Wi-Fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the Wi-Fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 Wi-Fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with Wi-Fi module position highlighted|Figure 1: F256jr motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with Wi-Fi module position highlighted|Figure 2: F256k motherboard with Wi-Fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 Wi-Fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the Wi-Fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the Wi-Fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a Wi-Fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=957</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=957"/>
		<updated>2023-07-05T02:21:38Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Introduction */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The F256 computers (both the [[F256jr]] and [[F256k]]) optionally support connecting to your home wireless network.&lt;br /&gt;
Setting up your F256 to use wi-fi requires the installation and setup of a micro-controller board as a wi-fi router. The process is detailed in the [[F256_WiFi_Setup|F256 Wi-Fi Setup document]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=956</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=956"/>
		<updated>2023-07-05T02:20:53Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Foenix F256 Wi-fi HOWTO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The F256 computers (both the [[F256jr]] and [[F256k]]) optionally support connecting to your home wireless network.&lt;br /&gt;
Setting up your F256 to use wi-fi requires the installation and setup of a micro-controller board as a wi-fi router. The process is detailed in the setup document: [[F256_WiFi_Setup]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=955</id>
		<title>F256 WiFi Setup</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=955"/>
		<updated>2023-07-05T02:17:34Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Foenix F256 Wi-fi Setup */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Introduction =&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
= Supplies Needed =&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable --- A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
= Software Needed =&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
= Preparing the Feather ESP8266 =&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
== Installation Prerequisites ==&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
== Installing the ESP_SLIP_ROUTER Firmware ==&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuring the ESP8266 Router for Your Network ==&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
= Installing the Wi-Fi Module in Your F256 =&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=954</id>
		<title>F256 WiFi Setup</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi_Setup&amp;diff=954"/>
		<updated>2023-07-05T02:15:28Z</updated>

		<summary type="html">&lt;p&gt;PJW: Created page with &amp;quot;= Foenix F256 Wi-fi Setup =  == Introduction ==  The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi mo...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi Setup =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=953</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=953"/>
		<updated>2023-07-05T02:15:07Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Foenix F256 Wi-fi HOWTO */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
[[F256_WiFi_Setup]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=952</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=952"/>
		<updated>2023-07-05T02:14:16Z</updated>

		<summary type="html">&lt;p&gt;PJW: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
[[f256_wifi_howto]]&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=944</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=944"/>
		<updated>2023-06-29T00:34:10Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Installing the Wi-Fi Module in Your F256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
# If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
# Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
# [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
# Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
# There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
# Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=943</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=943"/>
		<updated>2023-06-29T00:32:42Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Preparing the Feather ESP8266 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
&lt;br /&gt;
2. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
1. If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
&lt;br /&gt;
2. Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
&lt;br /&gt;
3. [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
&lt;br /&gt;
4. Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
&lt;br /&gt;
5. There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
&lt;br /&gt;
6. Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=942</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=942"/>
		<updated>2023-06-28T23:48:31Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Supplies Needed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards are designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
1. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
1. If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
&lt;br /&gt;
2. Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
&lt;br /&gt;
3. [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
&lt;br /&gt;
4. Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
&lt;br /&gt;
5. There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
&lt;br /&gt;
6. Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=941</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=941"/>
		<updated>2023-06-28T23:48:01Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Supplies Needed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather Huzzah with ESP8266 : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards is designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
1. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
1. If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
&lt;br /&gt;
2. Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
&lt;br /&gt;
3. [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
&lt;br /&gt;
4. Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
&lt;br /&gt;
5. There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
&lt;br /&gt;
6. Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=940</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=940"/>
		<updated>2023-06-28T23:46:48Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Installing the Wi-Fi Module in Your F256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather ESP8266 Huzzah : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards is designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
1. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_unpop_highlight.jpg|thumb|alt=F256k motherboard with wi-fi module position highlighted|Figure 2: F256k motherboard with wi-fi module position highlighted]]&lt;br /&gt;
&lt;br /&gt;
1. If you did not buy the Feather with the pre-soldered pins, first solder the pins to the Feather board. The pins should be soldered so that the short side of the metal goes through the board of the Feather, and the long end (and the plastic separator) are on the underside of the board. The solder joint should be made on the top side of the board (see figure 3 but ignore some of the less than perfect solder joints).&lt;br /&gt;
&lt;br /&gt;
2. Then it will be time to solder the socket header to the F256 motherboard. The socket header is inserted through the top side of the motherboard and soldered on the bottom side (see figure 4).&lt;br /&gt;
&lt;br /&gt;
3. [Optional but recommended] Use a little isopropyl alcohol to clean any flux residue off the two boards.&lt;br /&gt;
&lt;br /&gt;
4. Insert the Feather ESP 8266 wi-fi module into the socket header on the F256 (see figure 5).&lt;br /&gt;
&lt;br /&gt;
5. There are two jumpers next to the wi-fi module. These route the transmit (Tx) and receive (Rx) pins to either the serial port or the wi-fi module. Make sure the jumpers are moved to the &amp;quot;SLIP&amp;quot; positions. You can see this in figure 5&lt;br /&gt;
&lt;br /&gt;
6. Turn on DIP switches #3 and #4. These tell the kernel that SLIP support should be enabled and that a wi-fi module is installed.&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_soldered.jpg|thumb|alt=Feather ESP8266 with pins soldered|Figure 3: Feather ESP8266 with pins soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:F256k_header.jpg|thumb|alt=F256k with headers soldered|Figure 4: F256k with headers soldered]]&lt;br /&gt;
&lt;br /&gt;
[[File:Feather_installed.jpg|thumb|alt=F256k with Feather ESP8266 installed|Figure 5: F256k with Feather ESP8266 installed]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=File:Feather_installed.jpg&amp;diff=939</id>
		<title>File:Feather installed.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=File:Feather_installed.jpg&amp;diff=939"/>
		<updated>2023-06-28T23:46:02Z</updated>

		<summary type="html">&lt;p&gt;PJW: F256k with Feather ESP8266 installed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
F256k with Feather ESP8266 installed&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=File:F256k_header.jpg&amp;diff=938</id>
		<title>File:F256k header.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=File:F256k_header.jpg&amp;diff=938"/>
		<updated>2023-06-28T23:45:08Z</updated>

		<summary type="html">&lt;p&gt;PJW: F256k with headers soldered&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
F256k with headers soldered&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=File:Feather_soldered.jpg&amp;diff=937</id>
		<title>File:Feather soldered.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=File:Feather_soldered.jpg&amp;diff=937"/>
		<updated>2023-06-28T23:44:08Z</updated>

		<summary type="html">&lt;p&gt;PJW: Feather ESP8266 with pins soldered&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
Feather ESP8266 with pins soldered&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=File:F256k_unpop_highlight.jpg&amp;diff=936</id>
		<title>File:F256k unpop highlight.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=File:F256k_unpop_highlight.jpg&amp;diff=936"/>
		<updated>2023-06-28T23:42:28Z</updated>

		<summary type="html">&lt;p&gt;PJW: F256k motherboard with wi-fi module position highlighted&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
F256k motherboard with wi-fi module position highlighted&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=935</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=935"/>
		<updated>2023-06-28T23:41:58Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Installing the Wi-Fi Module in Your F256 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather ESP8266 Huzzah : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards is designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
1. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;br /&gt;
&lt;br /&gt;
The next step is to actually install the wi-fi module onto the F256 motherboard, and this step will require some soldering. If you look at the motherboard, you will see two rows of unpopulated pads. These pads are for the wi-fi module. You will need to solder socket headers to those pads, and then insert the Feather ESP8266 wi-fi module board into the headers.&lt;br /&gt;
&lt;br /&gt;
[[File:F256jr_unpop_highlight.jpg|thumb|alt=F256jr motherboard with wi-fi module position highlighted|Figure 1: F256jr motherboard with wi-fi module position highlighted]]&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=File:F256jr_unpop_highlight.jpg&amp;diff=934</id>
		<title>File:F256jr unpop highlight.jpg</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=File:F256jr_unpop_highlight.jpg&amp;diff=934"/>
		<updated>2023-06-28T23:34:23Z</updated>

		<summary type="html">&lt;p&gt;PJW: F256jr motherboard with wi-fi module position highlighted&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Summary ==&lt;br /&gt;
F256jr motherboard with wi-fi module position highlighted&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=933</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=933"/>
		<updated>2023-06-28T23:30:20Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Software Needed */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather ESP8266 Huzzah : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards is designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the &amp;lt;code&amp;gt;slattach&amp;lt;/code&amp;gt; command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
1. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=932</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=932"/>
		<updated>2023-06-28T23:29:50Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Preparing the Feather ESP8266 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather ESP8266 Huzzah : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards is designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the `slattach` command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
This process is a bit involved on the software side. There are really just two main tasks that need to happen:&lt;br /&gt;
&lt;br /&gt;
1. Installing the ESP_SLIP_FIRMWARE&lt;br /&gt;
1. Configure the ESP8266 for Your Network&lt;br /&gt;
&lt;br /&gt;
However, both of these tasks require that the correct software and libraries are installed on your system. The first task can be done using Windows, Linux, or MacOS X. The second task can only be done using a Linux install at this time. The example commands below are shown for Linux, and in particular the Ubuntu distribution.&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
If you are currently using the FoenixMgr Python script to work with your F256's debug port, then you already have the prerequisites installed and can skip this section. Otherwise, you will need to make sure you have Python 3 installed, set as your default version of Python, PIP installed, PySerial installed, and the Net Tools package installed:&lt;br /&gt;
&lt;br /&gt;
1. Install Python 3&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install python3&lt;br /&gt;
sudo apt install python-is-python3&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
     &lt;br /&gt;
2. Install PIP&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo apt install pip&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
3. Install PySerial&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
python pip install pyserial  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
      &lt;br /&gt;
4. Install Net Tools&lt;br /&gt;
&lt;br /&gt;
This will vary with each Linux distribution. Sometimes this package is installed by default.&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
Use the USB cable to connect the Feather ESP8266 to your computer and make a note of the device or COM port the Feather will used. Now, the esptool.py script may be used to install the ESP_SLIP_ROUTER firmware. The ESP_SLIP_ROUTER repository includes two binary files in the firmware directory that need to be installed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
esptool.py --port {device} write_flash -fs 8MB 0x00000 {path}/0x00000.bin 0x10000 {path}/0x10000.bin&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Substitute the path to the USB serial device for your ESP8266 (likely &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt; or something similar on Linux, or some COM device on Windows) for &amp;lt;code&amp;gt;{device}&amp;lt;/code&amp;gt; and the path to the ESP_SLIP_ROUTER's firmware directory for &amp;lt;code&amp;gt;{path}&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
The activity light on the Feather should flash for a bit. Once that is complete, the firmware should be installed.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' you may get an error message about access to your device on Linux. It is common for Linux distributions to lock USB device access to a special group. You can either add your account to that group, or for a quick and dirty solution add read and write access to all users—for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo chmod a+rw /dev/ttyUSB0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
To configure the router, you will need to make a SLIP connection over the USB cable and use the router's console to set the SSID and password of the wi-fi network it is to use. Unfortunately, there does not seem to be any SLIP support in Windows or MacOS X anymore. This is why a Linux install is needed.&lt;br /&gt;
&lt;br /&gt;
To make this connection, you must first issue some commands in Linux to create a SLIP tunnel over the USB cable to the router and to assign it a local IP address so you can connect (assuming the Feather is on &amp;lt;code&amp;gt;/dev/ttyUSB0&amp;lt;/code&amp;gt;. Substitute the correct device path, if it is different.):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
sudo slattach -L -p slip -s 115200 /dev/ttyUSB0 &amp;amp;&lt;br /&gt;
sudo ifconfig sl0 192.168.240.2 pointopoint 192.168.240.1 up mtu 1500  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
Once that has been done, you can use telnet to connect to the router's console:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
telnet 192.168.240.1 7777  &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, you should see a prompt from the router's console. Enter the commends to set the SSID, set the password, and set the router to use an access point:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
CMD&amp;gt;set ssid {your_ssid}&lt;br /&gt;
CMD&amp;gt;set password {your_pw}&lt;br /&gt;
CMD&amp;gt;set use_ap 0&lt;br /&gt;
CMD&amp;gt;save&lt;br /&gt;
CMD&amp;gt;reset    &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
        &lt;br /&gt;
At this point, the wi-fi module should be ready to install in your F256.&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=931</id>
		<title>F256 WiFi</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=F256_WiFi&amp;diff=931"/>
		<updated>2023-06-28T23:18:10Z</updated>

		<summary type="html">&lt;p&gt;PJW: A description of how to set up a Wi-Fi module on the F256 computers.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix F256 Wi-fi HOWTO =&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
The Foenix F256 computers were designed to allow for networking either through the serial port or through an optional wi-fi module. The TinyCore MicroKernel installed by default includes support for networking using SLIP (Serial Line Internet Protocol). While it is possible to use SLIP through the RS-232 serial port on the F256k and F256jr, both computers include solder pads that can be used to install an ESP8266 board to serve as a SLIP wi-fi router. This document will cover the process of configuring and installing such a wi-fi module on your Foenix F256.&lt;br /&gt;
&lt;br /&gt;
WARNING: The process described here requires some technical skills. It will be necessary to solder sockets to the F256 motherboard, which, if not done properly, could damage the board. Therefore, this process should only be attempted by someone comfortable soldering electronics onto PCBs. Similarly, some steps in setting up the wi-fi router can currently only be done on a Linux installation, so some experience with Linux and setting up software packages on Linux will be needed.&lt;br /&gt;
&lt;br /&gt;
== Supplies Needed ==&lt;br /&gt;
&lt;br /&gt;
; F256 Motherboard : Either the F256jr mini-itx motherboard or the F256k motherboard will work.&lt;br /&gt;
&lt;br /&gt;
; Feather ESP8266 Huzzah : This board will be wi-fi module when the correct firmware is installed. It is available from Adafruit ([https://www.adafruit.com/product/2821 product link]), either with or without the pins pre-soldered. While the firmware will run on other ESP8266 boards, the solder pads on the F256 motherboards is designed for the Feather board from Adafruit. Be sure to order the Feather with the header pins (not with the &amp;quot;stacking headers&amp;quot;), although the correct header pins are readily available from several suppliers, as they are commonly used with Arduino projects (single row, 0.1 inch (2.5mm) spacing).&lt;br /&gt;
&lt;br /&gt;
; Header Sockets : Single row, 0.1 inch (2.5 mm) spacing. These are commonly available from many suppliers, but Adafruit have a kit including the correct sized headers ([https://www.adafruit.com/product/2886 product link]).&lt;br /&gt;
&lt;br /&gt;
; Soldering Supplies : Soldering iron suitable for through-hole soldering, decent solder, flux, and cleaning supplies to remove flux residue.&lt;br /&gt;
&lt;br /&gt;
; USB Cable: A to B Micro : This cable will be used to connect your Feather ESP8266 to the computer you will use to install and configure the firmware.&lt;br /&gt;
&lt;br /&gt;
== Software Needed ==&lt;br /&gt;
&lt;br /&gt;
; ESP_SLIP_ROUTER : The firmware to install on the ESP8266 to turn it into a SLIP/WiFi router. [https://github.com/martin-ger/esp_slip_router GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Linux : While installation of the firmware on the ESP8266 can be done in Linux, Windows, or MacOS X, the configuration step seems to be possible only using a Linux install. Currently, configuration of the wi-fi router once the firmware is installed can only be done through a SLIP connection, but Windows and MacOS X do not support SLIP networking. An installation on a Raspberry Pi should be fine.&lt;br /&gt;
&lt;br /&gt;
; Python 3 : Needed by the esptool.py for installing firmware on the ESP8266.&lt;br /&gt;
&lt;br /&gt;
; PySerial : The Python package that provides serial port access for esptool.py.&lt;br /&gt;
&lt;br /&gt;
; esptool.py : Tool used to install firmware on the ESP8266. [https://github.com/espressif/esptool GitHub Repository]&lt;br /&gt;
&lt;br /&gt;
; Net Tools : A package for Linux that includes the `slattach` command, used to configure the wi-fi router. The correct link will depend on your Linux distribution, but it may already be installed.&lt;br /&gt;
&lt;br /&gt;
== Preparing the Feather ESP8266 ==&lt;br /&gt;
&lt;br /&gt;
=== Installation Prerequisites ===&lt;br /&gt;
&lt;br /&gt;
=== Installing the ESP_SLIP_ROUTER Firmware ===&lt;br /&gt;
&lt;br /&gt;
=== Configuring the ESP8266 Router for Your Network ===&lt;br /&gt;
&lt;br /&gt;
== Installing the Wi-Fi Module in Your F256 ==&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=845</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=845"/>
		<updated>2023-04-09T22:16:52Z</updated>

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

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

		<summary type="html">&lt;p&gt;PJW: /* Uploading with the Foenix IDE */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Using the Debug interface =&lt;br /&gt;
&lt;br /&gt;
Data and programs may be sent to the C256 Foenix over the USB debug port (right side of the FMX, left side of the U/U+).&lt;br /&gt;
&lt;br /&gt;
== Installing Drivers ==&lt;br /&gt;
&lt;br /&gt;
The debug interface is a USB serial port which requires a driver to be installed on the host system. The drivers for the serial USB device (XR21B1411) can be found at: https://www.maxlinear.com/support/design-tools/software-drivers.&lt;br /&gt;
&lt;br /&gt;
== Uploading with the Foenix IDE ==&lt;br /&gt;
&lt;br /&gt;
To setup the Foenix IDE, download and run the MSI installer from the repository from GitHub (https://github.com/Trinity-11/FoenixIDE/releases).&lt;br /&gt;
&lt;br /&gt;
To upload a BIN or HEX file with the Foenix IDE's user interface:&lt;br /&gt;
&lt;br /&gt;
# Select the Tools &amp;gt; Uploader menu option. An &amp;quot;Uploader Window&amp;quot; will open.&lt;br /&gt;
# Select the COM port associated with the C256 debug interface in the drop down selector.&lt;br /&gt;
# Click the &amp;quot;Connect&amp;quot; button to establish a connection to the C256.&lt;br /&gt;
# Click the button labeled with ellipsis (...) to select the file to upload. By default, the uploader will show BIN files, but you can choose to search for HEX files instead.&lt;br /&gt;
# If you are uploading a BIN file, enter the starting destination address in the field &amp;quot;C256 Dest Address&amp;quot;. This step is not needed with HEX files, since they have the destination addresses for their data included.&lt;br /&gt;
# Click the &amp;quot;Send Binary&amp;quot; button to start the upload process.&lt;br /&gt;
&lt;br /&gt;
[[File:Foenix IDE Uploader.png]]&lt;br /&gt;
&lt;br /&gt;
== Uploading with C256Mgr ==&lt;br /&gt;
&lt;br /&gt;
C256Mgr is a set of Python scripts allowing access to the C256's USB debug interface. The scripts allow you to use the command line to upload BIN and HEX files to the C256, reprogram the flash memory, or examine memory on the C256. If your code includes a 64Tass compatible LBL file, the C256Mgr scripts can use that LBL file to allow you to examine memory based on the labels in your code. C256Mgr was originally intended to provide a cross-platform option for those who cannot run .Net applications. The C256Mgr can be found at: https://github.com/pweingar/C256Mgr.&lt;br /&gt;
&lt;br /&gt;
To install the C256Mgr, you will need to make sure you have Python 3.7 installed as well as the PySerial library. You will need to edit the c256.ini file to set the default COM port and LBL file for your project, although both settings can be overridden by the command line options.&lt;br /&gt;
&lt;br /&gt;
Once the manager is installed and configured correctly, there are two batch files that can be used to upload a file to the C256:&lt;br /&gt;
&lt;br /&gt;
; Binary&lt;br /&gt;
: To upload a binary file, you use the UPLOAD.BAT file, which takes a BIN file and destination address (in hex) as arguments:&lt;br /&gt;
&amp;lt;code&amp;gt;upload kernel.bin 380000&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
; HEX File&lt;br /&gt;
: To upload an Intel HEX file, you use the RUN256.BAT file, which takes just the HEX file as an argument:&lt;br /&gt;
&amp;lt;code&amp;gt;run256 hello.hex&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=680</id>
		<title>Executable binary file</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=680"/>
		<updated>2021-08-09T15:52:06Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* PGZ */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''F_RUN''' and '''F_LOAD''' kernel calls supports multiple binary formats. If you try to load a file in one of these formats without specifying a starting address, it will be loaded into the locations specified in the file. If you try to run a file in one of these formats, the file will be loaded into memory and executed.&lt;br /&gt;
&lt;br /&gt;
== PGX ==&lt;br /&gt;
&lt;br /&gt;
PGX is a simple, single segment format akin to Commodore's PRG format. The file starts with an eight byte header, followed by the contents to be loaded into memory. The header consists of three parts:&lt;br /&gt;
&lt;br /&gt;
* The first three bytes are the ASCII codes for &amp;quot;PGX&amp;quot;, serving as a file type signature.&lt;br /&gt;
* The fourth byte is the CPU code, indicating the target CPU. Currently, only the value $01 is supported and designates that the 65816 is the target CPU.&lt;br /&gt;
* The final four bytes of the header are the starting destination address in little-endian format. This address will be the location to store the first byte of the data (which is the ninth byte of the file).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Count !! Example !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 3 || &amp;quot;PGZ&amp;quot; || Signature&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || $01 || CPU&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 4 || $010000 || Destination Address&lt;br /&gt;
|-&lt;br /&gt;
| 8 || - || $00 $01 $02 ... || The data to load&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== PGZ ==&lt;br /&gt;
&lt;br /&gt;
PGZ is a multi-segment file format that can load data into multiple areas in memory. The format is derived from binary format used by Western Design Center's C compiler.&lt;br /&gt;
&lt;br /&gt;
* The first byte of the PGZ format is the ASCII code for &amp;quot;Z&amp;quot;. This serves as the file type signature.&lt;br /&gt;
* Next comes any number of segments, each following right after the previous segment with no separator. Each segment has the following format:&lt;br /&gt;
** Three bytes of address, in little endian format. This is the starting address for writing the data of the segment.&lt;br /&gt;
** Three bytes indicating the size of the segment, in little endian format.&lt;br /&gt;
** The bytes of data in the segment (same number of bytes as specified in the size).&lt;br /&gt;
* If final segment has a size of $000000 and no data bytes, then address specifies the starting address of the executable.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Segment !! Offset !! Count !! Example !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| N/A || 0 || 1 || &amp;quot;Z&amp;quot; || Signature&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| 1 || 1 || 3 || $010000 || Address of segment #1&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 3 || $000009 || Size of segment #1&lt;br /&gt;
|-&lt;br /&gt;
| 7 || ... || ... || Data of Segment #1&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;3&amp;quot;| 2 || 16 || 3 || $020000 || Address of segment #2&lt;br /&gt;
|-&lt;br /&gt;
| 19 || 3 || $000008 || Size of segment #2&lt;br /&gt;
|-&lt;br /&gt;
| 22 || ... || ... || Data of Segment #2&lt;br /&gt;
|-&lt;br /&gt;
|rowspan=&amp;quot;2&amp;quot;| START || 30 || 3 || $010000 || Starting address&lt;br /&gt;
|-&lt;br /&gt;
| 33 || 3 || $000000 || 0 to indicate start address&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=679</id>
		<title>Executable binary file</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=679"/>
		<updated>2021-08-09T15:43:39Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* PGX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''F_RUN''' and '''F_LOAD''' kernel calls supports multiple binary formats. If you try to load a file in one of these formats without specifying a starting address, it will be loaded into the locations specified in the file. If you try to run a file in one of these formats, the file will be loaded into memory and executed.&lt;br /&gt;
&lt;br /&gt;
== PGX ==&lt;br /&gt;
&lt;br /&gt;
PGX is a simple, single segment format akin to Commodore's PRG format. The file starts with an eight byte header, followed by the contents to be loaded into memory. The header consists of three parts:&lt;br /&gt;
&lt;br /&gt;
* The first three bytes are the ASCII codes for &amp;quot;PGX&amp;quot;, serving as a file type signature.&lt;br /&gt;
* The fourth byte is the CPU code, indicating the target CPU. Currently, only the value $01 is supported and designates that the 65816 is the target CPU.&lt;br /&gt;
* The final four bytes of the header are the starting destination address in little-endian format. This address will be the location to store the first byte of the data (which is the ninth byte of the file).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Count !! Example !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 3 || &amp;quot;PGZ&amp;quot; || Signature&lt;br /&gt;
|-&lt;br /&gt;
| 3 || 1 || $01 || CPU&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 4 || $010000 || Destination Address&lt;br /&gt;
|-&lt;br /&gt;
| 8 || - || $00 $01 $02 ... || The data to load&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== PGZ ==&lt;br /&gt;
&lt;br /&gt;
PGZ is a multi-segment file format that can load data into multiple areas in memory. The format is derived from binary format used by Western Design Center's C compiler.&lt;br /&gt;
&lt;br /&gt;
* The first byte of the PGZ format is the ASCII code for &amp;quot;Z&amp;quot;. This serves as the file type signature.&lt;br /&gt;
* Next comes any number of segments, each following right after the previous segment with no separator. Each segment has the following format:&lt;br /&gt;
** Three bytes of address, in little endian format. This is the starting address for writing the data of the segment.&lt;br /&gt;
** Three bytes indicating the size of the segment, in little endian format.&lt;br /&gt;
** The bytes of data in the segment (same number of bytes as specified in the size).&lt;br /&gt;
* If final segment has a size of $000000 and no data bytes, then address specifies the starting address of the executable.&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=678</id>
		<title>Executable binary file</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=678"/>
		<updated>2021-08-09T15:43:14Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* PGX */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''F_RUN''' and '''F_LOAD''' kernel calls supports multiple binary formats. If you try to load a file in one of these formats without specifying a starting address, it will be loaded into the locations specified in the file. If you try to run a file in one of these formats, the file will be loaded into memory and executed.&lt;br /&gt;
&lt;br /&gt;
== PGX ==&lt;br /&gt;
&lt;br /&gt;
PGX is a simple, single segment format akin to Commodore's PRG format. The file starts with an eight byte header, followed by the contents to be loaded into memory. The header consists of three parts:&lt;br /&gt;
&lt;br /&gt;
* The first three bytes are the ASCII codes for &amp;quot;PGX&amp;quot;, serving as a file type signature.&lt;br /&gt;
* The fourth byte is the CPU code, indicating the target CPU. Currently, only the value $01 is supported and designates that the 65816 is the target CPU.&lt;br /&gt;
* The final four bytes of the header are the starting destination address in little-endian format. This address will be the location to store the first byte of the data (which is the ninth byte of the file).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Offset !! Count !! Example !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 3 || &amp;quot;PGZ&amp;quot; || Signature&lt;br /&gt;
|-&lt;br /&gt;
| 4 || 1 || $01 || CPU&lt;br /&gt;
|-&lt;br /&gt;
| 5 || 3 || $010000 || Destination Address&lt;br /&gt;
|-&lt;br /&gt;
| 8 || - || $00 $01 $02 ... || The data to load&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== PGZ ==&lt;br /&gt;
&lt;br /&gt;
PGZ is a multi-segment file format that can load data into multiple areas in memory. The format is derived from binary format used by Western Design Center's C compiler.&lt;br /&gt;
&lt;br /&gt;
* The first byte of the PGZ format is the ASCII code for &amp;quot;Z&amp;quot;. This serves as the file type signature.&lt;br /&gt;
* Next comes any number of segments, each following right after the previous segment with no separator. Each segment has the following format:&lt;br /&gt;
** Three bytes of address, in little endian format. This is the starting address for writing the data of the segment.&lt;br /&gt;
** Three bytes indicating the size of the segment, in little endian format.&lt;br /&gt;
** The bytes of data in the segment (same number of bytes as specified in the size).&lt;br /&gt;
* If final segment has a size of $000000 and no data bytes, then address specifies the starting address of the executable.&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=677</id>
		<title>Executable binary file</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Executable_binary_file&amp;diff=677"/>
		<updated>2021-08-09T15:40:02Z</updated>

		<summary type="html">&lt;p&gt;PJW: Created page with &amp;quot;The '''F_RUN''' and '''F_LOAD''' kernel calls supports multiple binary formats. If you try to load a file in one of these formats without specifying a starting address, it wil...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The '''F_RUN''' and '''F_LOAD''' kernel calls supports multiple binary formats. If you try to load a file in one of these formats without specifying a starting address, it will be loaded into the locations specified in the file. If you try to run a file in one of these formats, the file will be loaded into memory and executed.&lt;br /&gt;
&lt;br /&gt;
== PGX ==&lt;br /&gt;
&lt;br /&gt;
PGX is a simple, single segment format akin to Commodore's PRG format. The file starts with an eight byte header, followed by the contents to be loaded into memory. The header consists of three parts:&lt;br /&gt;
&lt;br /&gt;
* The first three bytes are the ASCII codes for &amp;quot;PGX&amp;quot;, serving as a file type signature.&lt;br /&gt;
* The fourth byte is the CPU code, indicating the target CPU. Currently, only the value $01 is supported and designates that the 65816 is the target CPU.&lt;br /&gt;
* The final four bytes of the header are the starting destination address in little-endian format. This address will be the location to store the first byte of the data (which is the ninth byte of the file).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== PGZ ==&lt;br /&gt;
&lt;br /&gt;
PGZ is a multi-segment file format that can load data into multiple areas in memory. The format is derived from binary format used by Western Design Center's C compiler.&lt;br /&gt;
&lt;br /&gt;
* The first byte of the PGZ format is the ASCII code for &amp;quot;Z&amp;quot;. This serves as the file type signature.&lt;br /&gt;
* Next comes any number of segments, each following right after the previous segment with no separator. Each segment has the following format:&lt;br /&gt;
** Three bytes of address, in little endian format. This is the starting address for writing the data of the segment.&lt;br /&gt;
** Three bytes indicating the size of the segment, in little endian format.&lt;br /&gt;
** The bytes of data in the segment (same number of bytes as specified in the size).&lt;br /&gt;
* If final segment has a size of $000000 and no data bytes, then address specifies the starting address of the executable.&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=676</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=676"/>
		<updated>2021-08-09T15:26:04Z</updated>

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

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

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

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

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

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

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

		<summary type="html">&lt;p&gt;PJW: /* GABE Random Number Generator Status and Control ($AF:E886) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GABE -- The System Control, I/O, and Sound Chip ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;GABE&amp;quot; is the name of the system controller chip of the C256 Foenix RevC board, and performs several functions including system bus management, math coprocessing, I/O, and sound.&lt;br /&gt;
The RevB version of the C256 had two chips &amp;quot;Gavin&amp;quot; and &amp;quot;Beatrix&amp;quot; that were combined into a single master chip called &amp;quot;GABE&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
GABE has several key functions:&lt;br /&gt;
* System start up&lt;br /&gt;
* Debug interface control and bus mastering&lt;br /&gt;
* I/O interfacing&lt;br /&gt;
* Math coprocessor&lt;br /&gt;
* Sound chip interfacing and emulation&lt;br /&gt;
&lt;br /&gt;
=== GABE System Startup Process ===&lt;br /&gt;
&lt;br /&gt;
When the C256 Foenix powers up, GABE takes control and coordinates the startup process.&lt;br /&gt;
It first copies the flash data out of flash and into system RAM, starting at bank $38 on the FMX ($18 on the RevB).&lt;br /&gt;
GABE also copies the first bank of flash data down to bank $00 of system RAM&lt;br /&gt;
before control is given to the CPU and the CPU's RESET is triggered.&lt;br /&gt;
This process ensures that the kernel, hardware vectors, and interrupt handlers are all in place prior to the CPU&lt;br /&gt;
taking control and resetting the first time on power up.&lt;br /&gt;
&lt;br /&gt;
The mapping of flash memory locations to system RAM is thus:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Flash Range !! RAM Range&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$FF:FFFF || $38:0000...$3F:FFFF&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$F8:FFFF || $00:0000...$00:FFFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Integer Math Coprocessor ($00:0100 &amp;amp;ndash; $00:012B) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an easy to use integer math coprocessor in the form of two 16-multipliers (one signed, one unsigned),&lt;br /&gt;
two 16-bit dividers (one signed, one unsigned), and a single 32-bit adder. Using the coprocessor is straight-forward:&lt;br /&gt;
the operands are written to the correct registers, and the result is read from the output registers. The operations&lt;br /&gt;
are all performed within a single CPU clock cycle, so no waiting is required.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0100 || $00:0101 || UNSIGNED_MULT_A || A operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0102 || $00:0103 || UNSIGNED_MULT_B || B operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0104 || $00:0107 || UNSIGNED_MULT_RESULT || Result for unsigned multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0108 || $00:0109 || SIGNED_MULT_A || A operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010A || $00:010B || SIGNED_MULT_B || B operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010C || $00:010F || SIGNED_MULT_RESULT || Result for signed multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0110 || $00:0111 || UNSIGNED_DIV_DEM || Denominator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0112 || $00:0113 || UNSIGNED_DIV_NUM || Numerator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0114 || $00:0115 || UNSIGNED_DIV_QUO || Quotient for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0116 || $00:0117 || UNSIGNED_DIV_REM || Remainder for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0118 || $00:0119 || SIGNED_DIV_DEM || Denominator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011A || $00:011B || SIGNED_DIV_NUM || Numerator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011C || $00:011D || SIGNED_DIV_QUO || Quotient for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011E || $00:011F || SIGNED_DIV_REM || Remainder for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0120 || $00:0123 || ADDER32_A || A operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0124 || $00:0127 || ADDER32_B || B operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0128 || $00:012B || ADDER32_R || Result of 32-bit addition (32-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Keyboard Ports ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1060 || X || KBD_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || Keyboard data port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1061 || X || PORTB || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || R || KBD_STATUS || PAR_E || RX_TO || TX_TO || KBD_INH || CMD || SYS || IN_F || OUT_F || Keyboard Status&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || W || KBD_CMD || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Keyboard Command&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Keyboard Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;PAR_E&lt;br /&gt;
:Parity error&lt;br /&gt;
&lt;br /&gt;
;RX_TO&lt;br /&gt;
:Time out reading data&lt;br /&gt;
&lt;br /&gt;
;TX_TO&lt;br /&gt;
:Time out transmitting data&lt;br /&gt;
&lt;br /&gt;
;CMD&lt;br /&gt;
:If 0, then data written to input buffer is data for PS/2 device. If 1, then data written to input buffer is data for PS/2 controller command&lt;br /&gt;
&lt;br /&gt;
;SYS&lt;br /&gt;
:Flag to the firmware that the keyboard has past POST&lt;br /&gt;
&lt;br /&gt;
;IN_F&lt;br /&gt;
:Input buffer is full&lt;br /&gt;
&lt;br /&gt;
;OUT_F&lt;br /&gt;
:Output buffer is full&lt;br /&gt;
&lt;br /&gt;
=== GABE Floating Point Math Coprocessor ($AF:E200 &amp;amp;ndash; AFE20F) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides a floating point math coprocessor, providing addition, subtraction, multiplication, and division for 32-bit floating point numbers.&lt;br /&gt;
Additionally, the coprocessor allows for conversion between a fixed point format and 32-bit IEEE 754 floating point format.&lt;br /&gt;
The floating point coprocessor is a little more complex than the integer coprocessor, with each math unit having input multiplexers that control&lt;br /&gt;
where the inputs come from, and with the output registers having their own multiplexer. Finally, the output of the multiplier and divider units&lt;br /&gt;
can be used directly as inputs to the adder/subtracter.&lt;br /&gt;
&lt;br /&gt;
[[File:FMX Floating Point.jpg|800px|FMX Floating Point Math Coprocessor]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E200 || || FP_MATH_CTRL0 || Controls input multiplexers, Adder function, and Adder multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E201 || || FP_MATH_CTRL1 || Controls output multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E202 || || FP_MATH_CTRL2 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E203 || || FP_MATH_CTRL3 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E204 || || FP_MATH_MULT_STAT || Status of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E205 || || FP_MATH_DIV_STAT || Status of the divider&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E206 || || FP_MATH_ADD_STAT || Status of the adder/subtracter&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E207 || || FP_MATH_CONV_STAT || Status of the converters&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_INPUT0 || Input 0 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_INPUT1 || Input 1 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_OUTPUT_FP || Result in IEEE 754 format (read only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_OUTPUT_FIXED || Result in 20.12 fixed point format (read only)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL0 ($AF:E200) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN1_MUX ||colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN0_MUX || FP_MATH_CTRL0_ADD_SUB || || FP_MATH_CTRL0_INPUT1_MUX || FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
: If 0, Input0 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT1_MUX&lt;br /&gt;
: If 0, Input1 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_SUB &lt;br /&gt;
: If 0, the adder will perform a subtract operation. If 1, it will perform an addition.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN0_MUX &lt;br /&gt;
: Selects the source for input 0 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN1_MUX &lt;br /&gt;
: Selects the source for input 1 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Adder Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Input&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Input 0&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Input 1&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Output of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Output of the divider&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL1 ($AF:E201) ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot;| ||colspan=&amp;quot;2&amp;quot;| FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
: Selects which functional block provides the output result:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Result Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Output Source&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Result of multiplier is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Result of divider is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Result of adder is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 11 || 1.0 is routed to the output registers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Registers: FP Status Registers ($AF:E204 &amp;amp;ndash; $AF:E207) ====&lt;br /&gt;
&lt;br /&gt;
These registers contain the status flags for the various functional units. The status flags are all roughly similar across the four units:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Status Codes&lt;br /&gt;
|-&lt;br /&gt;
! Code !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| $01 || Result was not a number (NAN)&lt;br /&gt;
|-&lt;br /&gt;
| $02 || Overflow&lt;br /&gt;
|-&lt;br /&gt;
| $04 || Underflow&lt;br /&gt;
|-&lt;br /&gt;
| $08 || Result was 0.0&lt;br /&gt;
|-&lt;br /&gt;
| $10 || Division by 0.0 was attempted&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Timer Registers ($00:0160 – $00:017F) ===&lt;br /&gt;
&lt;br /&gt;
* Timer0 and Timer1 count system clock transitions (14318180Hz)&lt;br /&gt;
* Timer2 is clocked from VICKY's Start-of-Frame output (50hz).&lt;br /&gt;
* To create interrupts at a set interval for timer 0 and 1 divide the clock frequency by the desired interval. So if one wishes 4 interrupts every second use 14318180 divided by 4.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0160 || || TIMER0_CTRL_REG || Timer 0 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0161 || || TIMER0_CHARGE_L || Timer 0 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0162 || || TIMER0_CHARGE_M || Timer 0 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0163 || || TIMER0_CHARGE_H || Timer 0 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0164 || || TIMER0_CMP_REG || Timer 0 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0165 || || TIMER0_CMP_L || Timer 0 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0166 || || TIMER0_CMP_M || Timer 0 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0167 || || TIMER0_CMP_H || Timer 0 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0168 || || TIMER1_CTRL_REG || Timer 1 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0169 || || TIMER1_CHARGE_L || Timer 1 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016A || || TIMER1_CHARGE_M || Timer 1 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016B || || TIMER1_CHARGE_H || Timer 1 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016C || || TIMER1_CMP_REG || Timer 1 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:016D || || TIMER1_CMP_L || Timer 1 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016E || || TIMER1_CMP_M || Timer 1 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016F || || TIMER1_CMP_H || Timer 1 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0170 || || TIMER2_CTRL_REG || Timer 2 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0171 || || TIMER2_CHARGE_L || Timer 2 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0172 || || TIMER2_CHARGE_M || Timer 2 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0173 || || TIMER2_CHARGE_H || Timer 2 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0174 || || TIMER2_CMP_REG || Timer 2 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0175 || || TIMER2_CMP_L || Timer 2 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0176 || || TIMER2_CMP_M || Timer 2 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0177 || || TIMER2_CMP_H || Timer 2 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Register&lt;br /&gt;
!Value&lt;br /&gt;
!Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x01 || TMR_EN || Enabled the timer&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x02 || TMR_SCLR || Set when counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x04 || TMR_SLOAD|| Set when counting down&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x08 || TMR_UPDWN|| Set when counting up (1 = Up, 0 = Down)&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x01 || TMR_CMP_RECLR|| Set to one for it to cycle when Counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x02 || TMR_CMP_RELOAD|| Set to one for it to reload when Counting Down&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting up ====&lt;br /&gt;
TIMER1_CHARGE_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = clockValue &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RECLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_UPDWN | TMR_SCLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting down ====&lt;br /&gt;
TIMER1_CHARGE_L = (clockValue &amp;gt;&amp;gt; 0) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RELOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_SLOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GABE Interrupt Control Registers ($00:0140 &amp;amp;ndash; $00:014B) ===&lt;br /&gt;
&lt;br /&gt;
There are four types of interrupt control register that GABE provides: pending, polarity, edge detection, and mask.&lt;br /&gt;
Each interrupt that is supported has a bit position in each of the 24 or 32 bits provided by the register types.&lt;br /&gt;
&lt;br /&gt;
; Pending&lt;br /&gt;
: The pending registers indicate if an interrupt of a particular type has been triggered and needs processing. An interrupt handler should also write to this register to clear the pending flag, once the interrupt has been processed.&lt;br /&gt;
&lt;br /&gt;
; Polarity&lt;br /&gt;
: This register indicates if the interrupt is triggered by a high or low signal on the input to GABE.&lt;br /&gt;
&lt;br /&gt;
; Edge&lt;br /&gt;
: This register indicates if the interrupt is triggered by an transition (edge) or by a high or low value.&lt;br /&gt;
&lt;br /&gt;
; Mask&lt;br /&gt;
: This register indicates if the associated interrupt will trigger an IRQ to the processor. Interrupt signals with a mask bit of 0 will be ignored, while those with a mask bit of 1 will trigger an interrupt to the CPU.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0140 || INT_PENDING_REG0 || Interrupt pending #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0141 || INT_PENDING_REG1 || Interrupt pending #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0142 || INT_PENDING_REG2 || Interrupt pending #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0143 || INT_PENDING_REG3 || Interrupt pending #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0144 || INT_POL_REG0     || Interrupt polarity #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0145 || INT_POL_REG1     || Interrupt polarity #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0146 || INT_POL_REG2     || Interrupt polarity #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0147 || INT_POL_REG3     || Interrupt polarity #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_EDGE_REG0    || Enable Edge Detection #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_EDGE_REG1    || Enable Edge Detection #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_EDGE_REG2    || Enable Edge Detection #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_EDGE_REG3    || Enable Edge Detection #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_MASK_REG0    || Enable Interrupt #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_MASK_REG1    || Enable Interrupt #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_MASK_REG2    || Enable Interrupt #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_MASK_REG3    || Enable Interrupt #3---FMX Model only &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are several interrupts the GABE can handle, distributed over four blocks:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Block !! Bit !! Name !! Function&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $01 || FNX0_INT00_SOF || Start of Frame @60Hz&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $02 || FNX0_INT01_SOL || Start of Line (programmable)&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $04 || FNX0_INT02_TMR0 || Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $08 || FNX0_INT03_TMR1 || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $10 || FNX0_INT04_TMR2 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $20 || FNX0_INT05_RTC || Real Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $40 || FNX0_INT06_FCC || Floppy Drive Controller&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $80 || FNX0_INT07_MOUSE || Mouse Interrupt (INT12 in SuperIO IOspace)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $01 || FNX1_INT00_KBD || Keyboard Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $02 || FNX1_INT01_SC0 || VICKY_II (INT2) Sprite 2 Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $04 || FNX1_INT02_SC1 || VICKY_II (INT3) Sprite 2 Tiles Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $08 || FNX1_INT03_COM2 || Serial Port 2 (Internal)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $10 || FNX1_INT04_COM1 || Serial Port 1 (External)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $20 || FNX1_INT05_MPU401 || Midi Controller Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $40 || FNX1_INT06_LPT || Parallel Port&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $80 || FNX1_INT07_SDCARD || SD Card Controller Interrupt (CH376S, if present)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $01 || FNX2_INT00_OPL3 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $02 || FNX2_INT01_GABE_INT0 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $04 || FNX2_INT02_GABE_INT1 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $08 || FNX2_INT03_SDMA || VICKY_II (INT4)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $10 || FNX2_INT04_VDMA || VICKY_II (INT5) -- Vicky DMA completion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $20 || FNX2_INT05_GABE_INT2 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $40 || FNX2_INT06_EXT || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $80 || FNX2_INT07_SDCARD_INS || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $01 || FNX3_INT00_OPN2 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $02 || FNX3_INT01_OPM || OPM&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $04 || FNX3_INT02_IDE || HDD IDE Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $08 || FNX3_INT03_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $10 || FNX3_INT04_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $20 || FNX3_INT05_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $40 || FNX3_INT06_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $80 || FNX3_INT07_TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SID Emulation ($AF:E400 &amp;amp;ndash; $AF:E41F) ===&lt;br /&gt;
&lt;br /&gt;
GABE emulates the SID sound chip. Currently, the FMX provides one SID unit.&lt;br /&gt;
Although the real SID chip provides analog to digital conversion for two&lt;br /&gt;
potentiometer inputs for paddles, the C256's paddle inputs are provided through&lt;br /&gt;
a different chip, so the POT registers listed below are not useful.&lt;br /&gt;
&lt;br /&gt;
For complete information on how to use these registers, please consult documentation&lt;br /&gt;
on the SID chips.&lt;br /&gt;
&lt;br /&gt;
All registers are write-only, except where noted otherwise.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E400 || $AF:E401 || SID0_V1_FREQ || SID0 V1 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E402 || $AF:E403 || SID0_V1_PW || SID0 V1 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E404 || || SID0_V1_CTRL || SID0 V1 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E405 || || SID0_V1_ATCK_DECY || SID0 V1 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E406 || || SID0_V1_SSTN_RLSE || SID0 V1 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E407 || $AF:E408 || SID0_V2_FREQ || SID0 V2 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E409 || $AF:E40A || SID0_V2_PW || SID0 V2 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40B || || SID0_V2_CTRL || SID0 V2 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40C || || SID0_V2_ATCK_DECY || SID0 V2 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40D || || SID0_V2_SSTN_RLSE || SID0 V2 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40E || $AF:E40F || SID0_V3_FREQ || SID0 V3 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E410 || $AF:E411 || SID0_V3_PW || SID0 V3 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E412 || || SID0_V3_CTRL || SID0 V3 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E413 || || SID0_V3_ATCK_DECY || SID0 V3 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E414 || || SID0_V3_SSTN_RLSE || SID0 V3 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E415 || || SID0_FC_LO || SID0 Filter Frequency LOW (3 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E416 || || SID0_FC_HI || SID0 Filter Frequency HIGH (8 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E417 || || SID0_RES_FILT || SID0 Resonance / Filter (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E418 || || SID0_MODE_VOL || SID0 Mode / Volume (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E419 || || SID0_POT_X || SID0 POT X (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41A || || SID0_POT_Y || SID0 POT Y (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41B || || SID0_OSC3_RND || SID0 OSC3 / RANDOM (Read only, 8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41C || || SID0_ENV3 || SID0 ENV3 (Read only, 8-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Trinity Joystick/Gamepad and DIP Switch Registers ($AF:E800 &amp;amp;ndash; $AF:E80E) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides access to the Trinity chip, which provides access to the joystick ports and the DIP switches.&lt;br /&gt;
The joystick ports can be used in two modes: default mode, where they work like Atari style joysticks, and NES mode&lt;br /&gt;
where they can interface with either NES or SNES game pads.&lt;br /&gt;
&lt;br /&gt;
[[File:Joystick Ports.jpg|800px|FMX Joystick Ports Configuration]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E800 || JOYSTICK0 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Left-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E801 || JOYSTICK1 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E802 || JOYSTICK2 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E803 || JOYSTICK3 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Right-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E804 || JOYSTICK_MODE || NES_TRIG || 0 || 0 || 0 || NES_DONE || NES_JOY || NES_EN1 || NES_EN0 || Control SNES compatibility&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E805 || REVOFPCB_C ||colspan=&amp;quot;8&amp;quot;| &amp;quot;C&amp;quot; || Board identification code byte (expect &amp;quot;C&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E806 || REVOFPCB_4 ||colspan=&amp;quot;8&amp;quot;| &amp;quot;4&amp;quot; || Board identification code byte (expect &amp;quot;4&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E807 || REVOFPCB_A ||colspan=&amp;quot;8&amp;quot;| &amp;quot;A&amp;quot; || Board identification code byte (expect &amp;quot;A&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 0: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below|| Port 0: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80C || CFP9301_REV ||colspan=&amp;quot;8&amp;quot;| revision || Trinity revision code&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80D || DIP_USER ||colspan=&amp;quot;8&amp;quot;| user || Switches 3 through 5. User defined meaning.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80E || DIP_BOOTMODE || HD_INSTALLED || 0 || 0 || 0 || 0 || 0 || BM1 || BM0 || Boot control switches.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ SNES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN0 = 1)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ NES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused if NES_EN0 = 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused in NES mode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== NES Control Bits ====&lt;br /&gt;
&lt;br /&gt;
;NES_TRIG&lt;br /&gt;
:Set to one to trigger the serializer to read the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_DONE&lt;br /&gt;
:Poll to see if the serializer has finished reading the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_JOY&lt;br /&gt;
:If 1, sets SNES compatibility. If 0, sets NES compatibility.&lt;br /&gt;
&lt;br /&gt;
;NES_EN1&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 1. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
;NES_EN0&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 0. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
==== Boot Mode ====&lt;br /&gt;
&lt;br /&gt;
Switches 0 and 1 allow you to select the boot mode for the FMX. Note that the switches are active low:&lt;br /&gt;
a switch in the &amp;quot;On&amp;quot; position registers as a 0.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! BM1 || BM0 !! Boot Mode&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || Boots from the IDE drive DIP switch 8 must be set (HD_INSTALLED).&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Boots from the SD card&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || Boots from the floppy drive&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Boots to BASIC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE IDE Registers ($AF:E830 &amp;amp;ndash; $AF:E839) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an IDE interface to a hard drive (if installed). This is done through the Unity chip and uses standard IDE interface command, error, and status codes.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E830 || x || IDE_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 8-bit data read/write&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E831 || R || IDE_ERROR || BBK  || UNC || MC || IDNF || MCR || ABRT || TK0NF || AMNF || Error code for the transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E832 || W || IDE_SECT_CNT || SC7 || SC6 || SC5 || SC4 || SC3 || SC2 || SC1 || SC0 || Sector count&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E833 || W || IDE_SECT_SRT || SS7 || SS6 || SS5 || SS4 || SS3 || SS2 || SS1 || SS0  || Sector start (0 = 256), start at 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E834 || W || IDE_CLDR_LO || C7 || C6 || C5 || C4 || C3 || C2 || C1 || C0 || Cylinder Number (low)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E835 || W || IDE_CLDR_HI || C15 || C14 || C13 || C12 || C11 || C10 || C9 || C8 || Cylinder Number (high)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E836 || W || IDE_HEAD || 1 || 0 || 1 || M/S || H3 || H2 || H1 || H0 || Head number and Master (0) / Slave(1) device&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || W || IDE_CMD_STAT || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Send a command to the drive&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || R || IDE_CMD_STAT || BSY || DRDY || DF || DSC || DRQ || CORR || IDX || ERR || Get the status of device. Reading this will clear the Interrupt Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E838 || X || IDE_DATA_LO || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 16-bit data transfer registers (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E839 || X || IDE_DATA_HI || D15 || D14 || D13 || D12 || D11 || D10 || D9 || D8 || 16-bit data transfer registers (high byte)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;BSY&lt;br /&gt;
:Device is busy if set&lt;br /&gt;
&lt;br /&gt;
;DRDY&lt;br /&gt;
:Device is ready for a command if set&lt;br /&gt;
&lt;br /&gt;
;DF&lt;br /&gt;
:Device fault&lt;br /&gt;
&lt;br /&gt;
;DSC&lt;br /&gt;
:Device seek complete. If set, the head has stopped moving and is over a track.&lt;br /&gt;
&lt;br /&gt;
;DRQ&lt;br /&gt;
:Device is ready to transfer a data byte (either read or write) if set.&lt;br /&gt;
&lt;br /&gt;
;CORR&lt;br /&gt;
:If set, indicates that data was corrected automatically.&lt;br /&gt;
&lt;br /&gt;
;IDX&lt;br /&gt;
:A vendor specific status&lt;br /&gt;
&lt;br /&gt;
;ERR&lt;br /&gt;
:If set, an error occurred with additional data in the error register.&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Error Flags ====&lt;br /&gt;
&lt;br /&gt;
;BBK&lt;br /&gt;
:Bad block&lt;br /&gt;
&lt;br /&gt;
;UNC&lt;br /&gt;
:Uncorrectable data error&lt;br /&gt;
&lt;br /&gt;
;MC&lt;br /&gt;
:Media changed&lt;br /&gt;
&lt;br /&gt;
;IDNF&lt;br /&gt;
:ID mark not found&lt;br /&gt;
&lt;br /&gt;
;MCR&lt;br /&gt;
:Media change requested&lt;br /&gt;
&lt;br /&gt;
;ABRT&lt;br /&gt;
:Command aborted&lt;br /&gt;
&lt;br /&gt;
;TK0NF&lt;br /&gt;
:Track 0 not found&lt;br /&gt;
&lt;br /&gt;
;AMNF&lt;br /&gt;
:Address mark not found&lt;br /&gt;
&lt;br /&gt;
=== GABE Control Registers ($AF:E880 &amp;amp;ndash; $AF:E887) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!Ending Address&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E880 || || GABE_MSTR_CTRL&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E881 || || Reserved&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E882 || || GABE_RST_AUTH0 || Must Contain the BYTE $AD for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E883 || || GABE_RST_AUTH1 || Must Contain the BYTE $DE for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E884 || $AF:E885 || GABE_RNG_DATASEED || On read: 16-bit random data. On write, set 16-bit RNG seed.&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E886 || || GABE_RNG_STATCTRL || On read: 8-bit status. On write: 8-bit control&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E887 || || GABE_SYS_STAT || 8-bit system status&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Master Control Register ($AF:E880) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|GABE_CTRL_WRM_RST || || || GABE_CTRL_BUZZER || || || GABE_CTRL_SDC_LED || GABE_CTRL_PWR_LED&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_PWR_LED&lt;br /&gt;
: Turns the power LED (next to the reset button) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_SDC_LED&lt;br /&gt;
: Turns the SDC activity LED (next to the SDC slot) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_BUZZER &lt;br /&gt;
: Turns the built-in piezo buzzer on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_WRM_RST &lt;br /&gt;
: Triggers a warm reset of the board (GABE_RST_AUTH0 must be set to $AD and GABE_RST_AUTH1 to $DE in order to trigger the reset).&lt;br /&gt;
&lt;br /&gt;
==== GABE Random Number Generator Status and Control ($AF:E886) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! R/W !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| R || GABE_RNG_LFSR_DONE || || || || || || ||&lt;br /&gt;
|-&lt;br /&gt;
| W || || || || || || || GABE_RNG_CTRL_DV || GABE_RNG_CTRL_EN&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_RNG_LFSR_DONE &lt;br /&gt;
: Indicates that output = seed database.&lt;br /&gt;
&lt;br /&gt;
; GABE_RNG_CTRL_DV &lt;br /&gt;
: After setting the seed value, toggle this bit for the seed be registered.&lt;br /&gt;
&lt;br /&gt;
; GABE_RNG_CTRL_EN&lt;br /&gt;
: Enable the LFSR block.&lt;br /&gt;
&lt;br /&gt;
==== GABE System Status Register ($AF:E887) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| GABE_SYS_STAT_CPUX || GABE_SYS_STAT_CPUA || || || GABE_SYS_STAT_EXP || || GABE_SYS_STAT_MID1 || GABE_SYS_STAT_MID0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_SYS_STAT_CPUX &lt;br /&gt;
: Indicates if the CPU's index registers are 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_CPUA &lt;br /&gt;
: Indicates if the CPU's accumulator is 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_EXP &lt;br /&gt;
: Indicates if the and expansion card is present (0).&lt;br /&gt;
; GABE_SYS_STAT_MID1 and GABE_SYS_STAT_MID0&lt;br /&gt;
: These two bits show the machine ID:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!GABE_SYS_STAT_MID1 !! GABE_SYS_STAT_MID0 !! Machine &lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || FMX - Development Platform&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || C256 Foenix - Dev Platform&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || C256 Foenix - User Version (65C816)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Reserved&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SDC Interface ($AF:EA00) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides block-level access to the SPI interface of the SD card. Currently, there are other registers in that provide access to the SD card through a CH376S chip, but that interface should be considered deprecated in favor of this interface. Most FMX boards do not have the CH376S chip, leaving its position unpopulated on the board.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA00 || R || SDC_VERSION_REG || colspan=&amp;quot;8&amp;quot;|version || Should read 12&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA01 || W || SDC_CONTROL_REG || x || x || x || x || x || x || x || RESET || Control register: RESET = 1 resets the core logic. Self clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA02 || W || SDC_TRANS_TYPE_REG ||x || x || x || x || x || x || colspan=&amp;quot;2&amp;quot;|TRANS || Sets the type of transaction: 0 = Direct, 1 = INIT SD, 2 = Read Block, 3 = Write block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA03 || W || SDC_TRANS_CONTROL_REG || x || x || x || x || x || x || x || START || Start transaction bit.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA04 || R || SDC_TRANS_STATUS_REG || x || x || x || x || x || x || x || BUSY || Status of the transaction. BUSY = 1 indicates a transaction is in progress.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA05 || R || SDC_TRANS_ERROR_REG || x || x || colspan=&amp;quot;2&amp;quot;|WR_ERR || colspan=&amp;quot;2&amp;quot;|RD_ERR || colspan=&amp;quot;2&amp;quot;|TRANS_ERR || Error conditions for read, write, and transaction.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA06 || RW || SDC_DIRECT_ACCESS_REG || colspan=&amp;quot;8&amp;quot;|data || SPI Direct Read and Write - Set DATA before initiating direct Access Transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA07 || W || SDC_SD_ADDR_7_0_REG || A7 || A6 || A5 || A4 || A3 || A2 || A1 || A0 || Set the ADDR before a block read or block write.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA08 || W || SDC_SD_ADDR_15_8_REG || A15 || A14 || A13 || A12 || A11 || A10 || A9 || A8 || ADDR[8:0] always should be 0, since each block is 512 bytes&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA09 || W || SDC_SD_ADDR_23_16_REG || A23 || A22 || A21 || A20 || A19 || A18 || A7 || A6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0A || W || SDC_SD_ADDR_31_24_REG || A32 || A31 || A30 || A29 || A28 || A26 || A25 || A24&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0B || W || SDC_SPI_CLK_DEL_REG || colspan=&amp;quot;8&amp;quot;|clock delay&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA10 || R || SDC_RX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Data from block read&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA12 || R || SDC_RX_FIFO_DATA_CNT_HI || CNT15 || CNT14 || CNT13 || CNT12 || CNT11 || CNT10 || CNT9 || CNT8 || How many bytes in the read FIFO (HI)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA13 || R || SDC_RX_FIFO_DATA_CNT_LO || CNT7 || CNT6 || CNT5 || CNT4 || CNT3 || CNT2 || CNT1 || CNT0 || How many bytes in the read FIFO (LOW)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA14 || W || SDC_RX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the read FIFO. Bit is self-clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA20 || W || SDC_TX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Write data block here.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA21 || W || SDC_TX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the write FIFO. Bit is self-clearing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE: SDC_TRANS_ERROR_REG ($AF:EA05) ====&lt;br /&gt;
&lt;br /&gt;
Lists any error conditions on reads, writes, or general transactions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ TRANS_ERR codes [1:0]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No INIT error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || INIT CMD0 error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || INIT CMD1 error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RD_ERR codes [3:2]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No read error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Token error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ WR_ERR codes [5:4]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No write error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Data error&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Busy error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SN76489 Interface ($AF:F100) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides the interface to the SN76489 sound chip on the Foenix FMX. This chip uses only a single write-only address: $AF:F100. The SN76489 has four voices: three tone generators, and one noise generator. Each voice has a frequency and an attenuation setting. For full details on how to use the SN76489 chip, please consult the official documentation, but here is a brief summary.&lt;br /&gt;
&lt;br /&gt;
==== Playing a Tone ====&lt;br /&gt;
&lt;br /&gt;
To change the frequency of a tone generator, two bytes are sent to the chip in order:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| First || 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 0 || F3 || F2 || F1 || F0&lt;br /&gt;
|-&lt;br /&gt;
| Second || 0 || x || F9 || F8 || F7 || F6 || F5 || F4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual frequency played depends on the clock driving the chip: freq = N / (32 * F), where N = 3575800 (for the FMX), and F is the 10-bit number sent to the chip. The &amp;quot;Channel&amp;quot; number above must be 0, 1, or 3.&lt;br /&gt;
&lt;br /&gt;
==== Play a Noise ====&lt;br /&gt;
&lt;br /&gt;
To play a noise, only a single byte is written to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 1 || 0 || x || NF|| NF1 || NF0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The NF bit controls the type of noise generated, and the NF bits control the base frequency of the noise.&lt;br /&gt;
&lt;br /&gt;
==== Setting the Volume ====&lt;br /&gt;
&lt;br /&gt;
The volumes of each of the four voices can be set independently. To set the volume of a single voice, a single byte is sent to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 1 || A3 || A2 || A1 || A0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Channel&amp;quot; bits are the number of the voice to change: 0, 1, 2, or 3. The four bit value A is the level of attenuation, where 0 is fully on, and 15 is fully off.&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=GABE&amp;diff=666</id>
		<title>GABE</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=GABE&amp;diff=666"/>
		<updated>2021-08-02T15:12:51Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* GABE Control Registers ($AF:E880 &amp;amp;ndash; $AF:E887) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== GABE -- The System Control, I/O, and Sound Chip ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;GABE&amp;quot; is the name of the system controller chip of the C256 Foenix RevC board, and performs several functions including system bus management, math coprocessing, I/O, and sound.&lt;br /&gt;
The RevB version of the C256 had two chips &amp;quot;Gavin&amp;quot; and &amp;quot;Beatrix&amp;quot; that were combined into a single master chip called &amp;quot;GABE&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
GABE has several key functions:&lt;br /&gt;
* System start up&lt;br /&gt;
* Debug interface control and bus mastering&lt;br /&gt;
* I/O interfacing&lt;br /&gt;
* Math coprocessor&lt;br /&gt;
* Sound chip interfacing and emulation&lt;br /&gt;
&lt;br /&gt;
=== GABE System Startup Process ===&lt;br /&gt;
&lt;br /&gt;
When the C256 Foenix powers up, GABE takes control and coordinates the startup process.&lt;br /&gt;
It first copies the flash data out of flash and into system RAM, starting at bank $38 on the FMX ($18 on the RevB).&lt;br /&gt;
GABE also copies the first bank of flash data down to bank $00 of system RAM&lt;br /&gt;
before control is given to the CPU and the CPU's RESET is triggered.&lt;br /&gt;
This process ensures that the kernel, hardware vectors, and interrupt handlers are all in place prior to the CPU&lt;br /&gt;
taking control and resetting the first time on power up.&lt;br /&gt;
&lt;br /&gt;
The mapping of flash memory locations to system RAM is thus:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Flash Range !! RAM Range&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$FF:FFFF || $38:0000...$3F:FFFF&lt;br /&gt;
|-&lt;br /&gt;
|$F8:0000...$F8:FFFF || $00:0000...$00:FFFF&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Integer Math Coprocessor ($00:0100 &amp;amp;ndash; $00:012B) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an easy to use integer math coprocessor in the form of two 16-multipliers (one signed, one unsigned),&lt;br /&gt;
two 16-bit dividers (one signed, one unsigned), and a single 32-bit adder. Using the coprocessor is straight-forward:&lt;br /&gt;
the operands are written to the correct registers, and the result is read from the output registers. The operations&lt;br /&gt;
are all performed within a single CPU clock cycle, so no waiting is required.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0100 || $00:0101 || UNSIGNED_MULT_A || A operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0102 || $00:0103 || UNSIGNED_MULT_B || B operand for unsigned multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0104 || $00:0107 || UNSIGNED_MULT_RESULT || Result for unsigned multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0108 || $00:0109 || SIGNED_MULT_A || A operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010A || $00:010B || SIGNED_MULT_B || B operand for signed multiplication (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:010C || $00:010F || SIGNED_MULT_RESULT || Result for signed multiplication (32-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0110 || $00:0111 || UNSIGNED_DIV_DEM || Denominator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0112 || $00:0113 || UNSIGNED_DIV_NUM || Numerator for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0114 || $00:0115 || UNSIGNED_DIV_QUO || Quotient for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0116 || $00:0117 || UNSIGNED_DIV_REM || Remainder for unsigned division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0118 || $00:0119 || SIGNED_DIV_DEM || Denominator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011A || $00:011B || SIGNED_DIV_NUM || Numerator for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011C || $00:011D || SIGNED_DIV_QUO || Quotient for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:011E || $00:011F || SIGNED_DIV_REM || Remainder for signed division (16-bit)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0120 || $00:0123 || ADDER32_A || A operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0124 || $00:0127 || ADDER32_B || B operand for 32-bit addition (32-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $00:0128 || $00:012B || ADDER32_R || Result of 32-bit addition (32-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Keyboard Ports ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1060 || X || KBD_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || Keyboard data port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1061 || X || PORTB || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || R || KBD_STATUS || PAR_E || RX_TO || TX_TO || KBD_INH || CMD || SYS || IN_F || OUT_F || Keyboard Status&lt;br /&gt;
|-&lt;br /&gt;
| $AF:1064 || W || KBD_CMD || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Keyboard Command&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Keyboard Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;PAR_E&lt;br /&gt;
:Parity error&lt;br /&gt;
&lt;br /&gt;
;RX_TO&lt;br /&gt;
:Time out reading data&lt;br /&gt;
&lt;br /&gt;
;TX_TO&lt;br /&gt;
:Time out transmitting data&lt;br /&gt;
&lt;br /&gt;
;CMD&lt;br /&gt;
:If 0, then data written to input buffer is data for PS/2 device. If 1, then data written to input buffer is data for PS/2 controller command&lt;br /&gt;
&lt;br /&gt;
;SYS&lt;br /&gt;
:Flag to the firmware that the keyboard has past POST&lt;br /&gt;
&lt;br /&gt;
;IN_F&lt;br /&gt;
:Input buffer is full&lt;br /&gt;
&lt;br /&gt;
;OUT_F&lt;br /&gt;
:Output buffer is full&lt;br /&gt;
&lt;br /&gt;
=== GABE Floating Point Math Coprocessor ($AF:E200 &amp;amp;ndash; AFE20F) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides a floating point math coprocessor, providing addition, subtraction, multiplication, and division for 32-bit floating point numbers.&lt;br /&gt;
Additionally, the coprocessor allows for conversion between a fixed point format and 32-bit IEEE 754 floating point format.&lt;br /&gt;
The floating point coprocessor is a little more complex than the integer coprocessor, with each math unit having input multiplexers that control&lt;br /&gt;
where the inputs come from, and with the output registers having their own multiplexer. Finally, the output of the multiplier and divider units&lt;br /&gt;
can be used directly as inputs to the adder/subtracter.&lt;br /&gt;
&lt;br /&gt;
[[File:FMX Floating Point.jpg|800px|FMX Floating Point Math Coprocessor]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E200 || || FP_MATH_CTRL0 || Controls input multiplexers, Adder function, and Adder multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E201 || || FP_MATH_CTRL1 || Controls output multiplexers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E202 || || FP_MATH_CTRL2 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E203 || || FP_MATH_CTRL3 || Unused: reserved&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E204 || || FP_MATH_MULT_STAT || Status of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E205 || || FP_MATH_DIV_STAT || Status of the divider&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E206 || || FP_MATH_ADD_STAT || Status of the adder/subtracter&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E207 || || FP_MATH_CONV_STAT || Status of the converters&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_INPUT0 || Input 0 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_INPUT1 || Input 1 (write only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E208 || $AF:E20B || FP_MATH_OUTPUT_FP || Result in IEEE 754 format (read only)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E20C || $AF:E20F || FP_MATH_OUTPUT_FIXED || Result in 20.12 fixed point format (read only)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL0 ($AF:E200) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN1_MUX ||colspan=&amp;quot;2&amp;quot;|FP_MATH_CTRL0_ADD_IN0_MUX || FP_MATH_CTRL0_ADD_SUB || || FP_MATH_CTRL0_INPUT1_MUX || FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT0_MUX&lt;br /&gt;
: If 0, Input0 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_INPUT1_MUX&lt;br /&gt;
: If 0, Input1 is assumed to be in IEEE format. If 1, it is assumed to be in 20.12 fixed point format and will be converted to IEEE.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_SUB &lt;br /&gt;
: If 0, the adder will perform a subtract operation. If 1, it will perform an addition.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN0_MUX &lt;br /&gt;
: Selects the source for input 0 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL0_ADD_IN1_MUX &lt;br /&gt;
: Selects the source for input 1 of the adder unit.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Adder Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Input&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Input 0&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Input 1&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Output of the multiplier&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Output of the divider&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Register FP_MATH_CTRL1 ($AF:E201) ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|colspan=&amp;quot;6&amp;quot;| ||colspan=&amp;quot;2&amp;quot;| FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; FP_MATH_CTRL1_OUTPUT_MUX0&lt;br /&gt;
: Selects which functional block provides the output result:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Result Source Selector Codes&lt;br /&gt;
|-&lt;br /&gt;
! Control Bits !! Output Source&lt;br /&gt;
|-&lt;br /&gt;
| 00 || Result of multiplier is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Result of divider is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Result of adder is the routed to the output registers&lt;br /&gt;
|-&lt;br /&gt;
| 11 || 1.0 is routed to the output registers&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Registers: FP Status Registers ($AF:E204 &amp;amp;ndash; $AF:E207) ====&lt;br /&gt;
&lt;br /&gt;
These registers contain the status flags for the various functional units. The status flags are all roughly similar across the four units:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ Status Codes&lt;br /&gt;
|-&lt;br /&gt;
! Code !! Meaning&lt;br /&gt;
|-&lt;br /&gt;
| $01 || Result was not a number (NAN)&lt;br /&gt;
|-&lt;br /&gt;
| $02 || Overflow&lt;br /&gt;
|-&lt;br /&gt;
| $04 || Underflow&lt;br /&gt;
|-&lt;br /&gt;
| $08 || Result was 0.0&lt;br /&gt;
|-&lt;br /&gt;
| $10 || Division by 0.0 was attempted&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Timer Registers ($00:0160 – $00:017F) ===&lt;br /&gt;
&lt;br /&gt;
* Timer0 and Timer1 count system clock transitions (14318180Hz)&lt;br /&gt;
* Timer2 is clocked from VICKY's Start-of-Frame output (50hz).&lt;br /&gt;
* To create interrupts at a set interval for timer 0 and 1 divide the clock frequency by the desired interval. So if one wishes 4 interrupts every second use 14318180 divided by 4.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!End Address&lt;br /&gt;
!Register Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0160 || || TIMER0_CTRL_REG || Timer 0 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0161 || || TIMER0_CHARGE_L || Timer 0 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0162 || || TIMER0_CHARGE_M || Timer 0 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0163 || || TIMER0_CHARGE_H || Timer 0 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0164 || || TIMER0_CMP_REG || Timer 0 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0165 || || TIMER0_CMP_L || Timer 0 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0166 || || TIMER0_CMP_M || Timer 0 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0167 || || TIMER0_CMP_H || Timer 0 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0168 || || TIMER1_CTRL_REG || Timer 1 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0169 || || TIMER1_CHARGE_L || Timer 1 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016A || || TIMER1_CHARGE_M || Timer 1 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016B || || TIMER1_CHARGE_H || Timer 1 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:016C || || TIMER1_CMP_REG || Timer 1 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:016D || || TIMER1_CMP_L || Timer 1 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016E || || TIMER1_CMP_M || Timer 1 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:016F || || TIMER1_CMP_H || Timer 1 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
!colspan=&amp;quot;4&amp;quot; style=&amp;quot;text-align:left;&amp;quot; | Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0170 || || TIMER2_CTRL_REG || Timer 2 control register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0171 || || TIMER2_CHARGE_L || Timer 2 precharge register lower byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0172 || || TIMER2_CHARGE_M || Timer 2 precharge register middle byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0173 || || TIMER2_CHARGE_H || Timer 2 precharge register high byte, loaded when counting down&lt;br /&gt;
|-&lt;br /&gt;
| $00:0174 || || TIMER2_CMP_REG || Timer 2 compare register&lt;br /&gt;
|-&lt;br /&gt;
| $00:0175 || || TIMER2_CMP_L || Timer 2 compare register lower byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0176 || || TIMER2_CMP_M || Timer 2 compare register middle byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
| $00:0177 || || TIMER2_CMP_H || Timer 2 compare register high byte, loaded when counting up&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Register&lt;br /&gt;
!Value&lt;br /&gt;
!Name&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x01 || TMR_EN || Enabled the timer&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x02 || TMR_SCLR || Set when counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x04 || TMR_SLOAD|| Set when counting down&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CTRL_REG || 0x08 || TMR_UPDWN|| Set when counting up (1 = Up, 0 = Down)&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x01 || TMR_CMP_RECLR|| Set to one for it to cycle when Counting up&lt;br /&gt;
|-&lt;br /&gt;
| TIMER&amp;lt;X&amp;gt;_CMP_REG || 0x02 || TMR_CMP_RELOAD|| Set to one for it to reload when Counting Down&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting up ====&lt;br /&gt;
TIMER1_CHARGE_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = clockValue &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RECLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_UPDWN | TMR_SCLR;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== C pseudo code for counting down ====&lt;br /&gt;
TIMER1_CHARGE_L = (clockValue &amp;gt;&amp;gt; 0) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_M = (clockValue &amp;gt;&amp;gt; 8) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CHARGE_H = (clockValue &amp;gt;&amp;gt; 16) &amp;amp; 0xFF;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_L = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_M = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_H = 0x00;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CMP_REG = TMR_CMP_RELOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
TIMER1_CTRL_REG = TMR_EN | TMR_SLOAD;&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== GABE Interrupt Control Registers ($00:0140 &amp;amp;ndash; $00:014B) ===&lt;br /&gt;
&lt;br /&gt;
There are four types of interrupt control register that GABE provides: pending, polarity, edge detection, and mask.&lt;br /&gt;
Each interrupt that is supported has a bit position in each of the 24 or 32 bits provided by the register types.&lt;br /&gt;
&lt;br /&gt;
; Pending&lt;br /&gt;
: The pending registers indicate if an interrupt of a particular type has been triggered and needs processing. An interrupt handler should also write to this register to clear the pending flag, once the interrupt has been processed.&lt;br /&gt;
&lt;br /&gt;
; Polarity&lt;br /&gt;
: This register indicates if the interrupt is triggered by a high or low signal on the input to GABE.&lt;br /&gt;
&lt;br /&gt;
; Edge&lt;br /&gt;
: This register indicates if the interrupt is triggered by an transition (edge) or by a high or low value.&lt;br /&gt;
&lt;br /&gt;
; Mask&lt;br /&gt;
: This register indicates if the associated interrupt will trigger an IRQ to the processor. Interrupt signals with a mask bit of 0 will be ignored, while those with a mask bit of 1 will trigger an interrupt to the CPU.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
| $00:0140 || INT_PENDING_REG0 || Interrupt pending #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0141 || INT_PENDING_REG1 || Interrupt pending #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0142 || INT_PENDING_REG2 || Interrupt pending #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0143 || INT_PENDING_REG3 || Interrupt pending #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0144 || INT_POL_REG0     || Interrupt polarity #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0145 || INT_POL_REG1     || Interrupt polarity #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:0146 || INT_POL_REG2     || Interrupt polarity #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:0147 || INT_POL_REG3     || Interrupt polarity #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_EDGE_REG0    || Enable Edge Detection #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_EDGE_REG1    || Enable Edge Detection #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_EDGE_REG2    || Enable Edge Detection #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_EDGE_REG3    || Enable Edge Detection #3---FMX Model only &lt;br /&gt;
|-&lt;br /&gt;
| $00:0148 || INT_MASK_REG0    || Enable Interrupt #0&lt;br /&gt;
|-&lt;br /&gt;
| $00:0149 || INT_MASK_REG1    || Enable Interrupt #1&lt;br /&gt;
|-&lt;br /&gt;
| $00:014A || INT_MASK_REG2    || Enable Interrupt #2&lt;br /&gt;
|-&lt;br /&gt;
| $00:014B || INT_MASK_REG3    || Enable Interrupt #3---FMX Model only &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
There are several interrupts the GABE can handle, distributed over four blocks:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Block !! Bit !! Name !! Function&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $01 || FNX0_INT00_SOF || Start of Frame @60Hz&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $02 || FNX0_INT01_SOL || Start of Line (programmable)&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $04 || FNX0_INT02_TMR0 || Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $08 || FNX0_INT03_TMR1 || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $10 || FNX0_INT04_TMR2 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $20 || FNX0_INT05_RTC || Real Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $40 || FNX0_INT06_FCC || Floppy Drive Controller&lt;br /&gt;
|-&lt;br /&gt;
| 0 || $80 || FNX0_INT07_MOUSE || Mouse Interrupt (INT12 in SuperIO IOspace)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $01 || FNX1_INT00_KBD || Keyboard Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $02 || FNX1_INT01_SC0 || VICKY_II (INT2) Sprite 2 Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $04 || FNX1_INT02_SC1 || VICKY_II (INT3) Sprite 2 Tiles Collision&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $08 || FNX1_INT03_COM2 || Serial Port 2 (Internal)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $10 || FNX1_INT04_COM1 || Serial Port 1 (External)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $20 || FNX1_INT05_MPU401 || Midi Controller Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $40 || FNX1_INT06_LPT || Parallel Port&lt;br /&gt;
|-&lt;br /&gt;
| 1 || $80 || FNX1_INT07_SDCARD || SD Card Controller Interrupt (CH376S, if present)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $01 || FNX2_INT00_OPL3 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $02 || FNX2_INT01_GABE_INT0 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $04 || FNX2_INT02_GABE_INT1 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $08 || FNX2_INT03_SDMA || VICKY_II (INT4)&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $10 || FNX2_INT04_VDMA || VICKY_II (INT5) -- Vicky DMA completion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $20 || FNX2_INT05_GABE_INT2 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $40 || FNX2_INT06_EXT || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| 2 || $80 || FNX2_INT07_SDCARD_INS || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $01 || FNX3_INT00_OPN2 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $02 || FNX3_INT01_OPM || OPM&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $04 || FNX3_INT02_IDE || HDD IDE Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $08 || FNX3_INT03_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $10 || FNX3_INT04_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $20 || FNX3_INT05_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $40 || FNX3_INT06_TBD || TBD&lt;br /&gt;
|-&lt;br /&gt;
| 3 || $80 || FNX3_INT07_TBD || TBD&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SID Emulation ($AF:E400 &amp;amp;ndash; $AF:E41F) ===&lt;br /&gt;
&lt;br /&gt;
GABE emulates the SID sound chip. Currently, the FMX provides one SID unit.&lt;br /&gt;
Although the real SID chip provides analog to digital conversion for two&lt;br /&gt;
potentiometer inputs for paddles, the C256's paddle inputs are provided through&lt;br /&gt;
a different chip, so the POT registers listed below are not useful.&lt;br /&gt;
&lt;br /&gt;
For complete information on how to use these registers, please consult documentation&lt;br /&gt;
on the SID chips.&lt;br /&gt;
&lt;br /&gt;
All registers are write-only, except where noted otherwise.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Register Name !! Additional Information&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E400 || $AF:E401 || SID0_V1_FREQ || SID0 V1 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E402 || $AF:E403 || SID0_V1_PW || SID0 V1 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E404 || || SID0_V1_CTRL || SID0 V1 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E405 || || SID0_V1_ATCK_DECY || SID0 V1 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E406 || || SID0_V1_SSTN_RLSE || SID0 V1 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E407 || $AF:E408 || SID0_V2_FREQ || SID0 V2 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E409 || $AF:E40A || SID0_V2_PW || SID0 V2 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40B || || SID0_V2_CTRL || SID0 V2 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40C || || SID0_V2_ATCK_DECY || SID0 V2 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40D || || SID0_V2_SSTN_RLSE || SID0 V2 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E40E || $AF:E40F || SID0_V3_FREQ || SID0 V3 Frequency (16-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E410 || $AF:E411 || SID0_V3_PW || SID0 V3 Pulse Width (12-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E412 || || SID0_V3_CTRL || SID0 V3 Control (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E413 || || SID0_V3_ATCK_DECY || SID0 V3 Attack/Decay (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E414 || || SID0_V3_SSTN_RLSE || SID0 V3 Sustain/Release (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E415 || || SID0_FC_LO || SID0 Filter Frequency LOW (3 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E416 || || SID0_FC_HI || SID0 Filter Frequency HIGH (8 bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E417 || || SID0_RES_FILT || SID0 Resonance / Filter (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E418 || || SID0_MODE_VOL || SID0 Mode / Volume (8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E419 || || SID0_POT_X || SID0 POT X (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41A || || SID0_POT_Y || SID0 POT Y (Read only, C256 - NOT USED)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41B || || SID0_OSC3_RND || SID0 OSC3 / RANDOM (Read only, 8-bits)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E41C || || SID0_ENV3 || SID0 ENV3 (Read only, 8-bits)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE Trinity Joystick/Gamepad and DIP Switch Registers ($AF:E800 &amp;amp;ndash; $AF:E80E) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides access to the Trinity chip, which provides access to the joystick ports and the DIP switches.&lt;br /&gt;
The joystick ports can be used in two modes: default mode, where they work like Atari style joysticks, and NES mode&lt;br /&gt;
where they can interface with either NES or SNES game pads.&lt;br /&gt;
&lt;br /&gt;
[[File:Joystick Ports.jpg|800px|FMX Joystick Ports Configuration]]&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E800 || JOYSTICK0 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Left-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E801 || JOYSTICK1 || BUTTON2 || BUTTON1 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E802 || JOYSTICK2 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Next to joystick port 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E803 || JOYSTICK3 || 0 || 0 || 0 || BUTTON0 || RIGHT || LEFT || DOWN || UP || Right-most joystick port&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E804 || JOYSTICK_MODE || NES_TRIG || 0 || 0 || 0 || NES_DONE || NES_JOY || NES_EN1 || NES_EN0 || Control SNES compatibility&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E805 || REVOFPCB_C ||colspan=&amp;quot;8&amp;quot;| &amp;quot;C&amp;quot; || Board identification code byte (expect &amp;quot;C&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E806 || REVOFPCB_4 ||colspan=&amp;quot;8&amp;quot;| &amp;quot;4&amp;quot; || Board identification code byte (expect &amp;quot;4&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E807 || REVOFPCB_A ||colspan=&amp;quot;8&amp;quot;| &amp;quot;A&amp;quot; || Board identification code byte (expect &amp;quot;A&amp;quot;)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 0: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below|| Port 0: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;8&amp;quot;| see below || Port 1: NES or SNES gamepad data (highbyte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80C || CFP9301_REV ||colspan=&amp;quot;8&amp;quot;| revision || Trinity revision code&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80D || DIP_USER ||colspan=&amp;quot;8&amp;quot;| user || Switches 3 through 5. User defined meaning.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80E || DIP_BOOTMODE || HD_INSTALLED || 0 || 0 || 0 || 0 || 0 || BM1 || BM0 || Boot control switches.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ SNES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN0 = 1)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || B || Y || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI || 0 || 0 || 0 || 0 || A || X || L || R || NES data if NES_JOY = 1 and NES_EN1 = 1&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ NES mode&lt;br /&gt;
|-&lt;br /&gt;
! Address !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E808 || NES_SNES0_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN0 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E809 || SNES0_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused if NES_EN0 = 0&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80A || NES_SNES1_DAT_LO || A || B || SELECT || START || UP || DOWN || LEFT || RIGHT || NES data if NES_JOY = 0 and NES_EN1 = 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E80B || SNES1_DAT_HI ||colspan=&amp;quot;2&amp;quot;| N/A || Unused in NES mode&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== NES Control Bits ====&lt;br /&gt;
&lt;br /&gt;
;NES_TRIG&lt;br /&gt;
:Set to one to trigger the serializer to read the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_DONE&lt;br /&gt;
:Poll to see if the serializer has finished reading the gamepad.&lt;br /&gt;
&lt;br /&gt;
;NES_JOY&lt;br /&gt;
:If 1, sets SNES compatibility. If 0, sets NES compatibility.&lt;br /&gt;
&lt;br /&gt;
;NES_EN1&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 1. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
;NES_EN0&lt;br /&gt;
:If 1, enables NES/SNES compatibility on port 0. If 0, joysticks work like Atari joysticks&lt;br /&gt;
&lt;br /&gt;
==== Boot Mode ====&lt;br /&gt;
&lt;br /&gt;
Switches 0 and 1 allow you to select the boot mode for the FMX. Note that the switches are active low:&lt;br /&gt;
a switch in the &amp;quot;On&amp;quot; position registers as a 0.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! BM1 || BM0 !! Boot Mode&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || Boots from the IDE drive DIP switch 8 must be set (HD_INSTALLED).&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || Boots from the SD card&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || Boots from the floppy drive&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Boots to BASIC&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE IDE Registers ($AF:E830 &amp;amp;ndash; $AF:E839) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides an IDE interface to a hard drive (if installed). This is done through the Unity chip and uses standard IDE interface command, error, and status codes.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E830 || x || IDE_DATA || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 8-bit data read/write&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E831 || R || IDE_ERROR || BBK  || UNC || MC || IDNF || MCR || ABRT || TK0NF || AMNF || Error code for the transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E832 || W || IDE_SECT_CNT || SC7 || SC6 || SC5 || SC4 || SC3 || SC2 || SC1 || SC0 || Sector count&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E833 || W || IDE_SECT_SRT || SS7 || SS6 || SS5 || SS4 || SS3 || SS2 || SS1 || SS0  || Sector start (0 = 256), start at 1&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E834 || W || IDE_CLDR_LO || C7 || C6 || C5 || C4 || C3 || C2 || C1 || C0 || Cylinder Number (low)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E835 || W || IDE_CLDR_HI || C15 || C14 || C13 || C12 || C11 || C10 || C9 || C8 || Cylinder Number (high)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E836 || W || IDE_HEAD || 1 || 0 || 1 || M/S || H3 || H2 || H1 || H0 || Head number and Master (0) / Slave(1) device&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || W || IDE_CMD_STAT || CMD7 || CMD6 || CMD5 || CMD4 || CMD3 || CMD2 || CMD1 || CMD0 || Send a command to the drive&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E837 || R || IDE_CMD_STAT || BSY || DRDY || DF || DSC || DRQ || CORR || IDX || ERR || Get the status of device. Reading this will clear the Interrupt Registers&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E838 || X || IDE_DATA_LO || D7 || D6 || D5 || D4 || D3 || D2 || D1 || D0 || 16-bit data transfer registers (low byte)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:E839 || X || IDE_DATA_HI || D15 || D14 || D13 || D12 || D11 || D10 || D9 || D8 || 16-bit data transfer registers (high byte)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Status Flags ====&lt;br /&gt;
&lt;br /&gt;
;BSY&lt;br /&gt;
:Device is busy if set&lt;br /&gt;
&lt;br /&gt;
;DRDY&lt;br /&gt;
:Device is ready for a command if set&lt;br /&gt;
&lt;br /&gt;
;DF&lt;br /&gt;
:Device fault&lt;br /&gt;
&lt;br /&gt;
;DSC&lt;br /&gt;
:Device seek complete. If set, the head has stopped moving and is over a track.&lt;br /&gt;
&lt;br /&gt;
;DRQ&lt;br /&gt;
:Device is ready to transfer a data byte (either read or write) if set.&lt;br /&gt;
&lt;br /&gt;
;CORR&lt;br /&gt;
:If set, indicates that data was corrected automatically.&lt;br /&gt;
&lt;br /&gt;
;IDX&lt;br /&gt;
:A vendor specific status&lt;br /&gt;
&lt;br /&gt;
;ERR&lt;br /&gt;
:If set, an error occurred with additional data in the error register.&lt;br /&gt;
&lt;br /&gt;
==== GABE IDE Error Flags ====&lt;br /&gt;
&lt;br /&gt;
;BBK&lt;br /&gt;
:Bad block&lt;br /&gt;
&lt;br /&gt;
;UNC&lt;br /&gt;
:Uncorrectable data error&lt;br /&gt;
&lt;br /&gt;
;MC&lt;br /&gt;
:Media changed&lt;br /&gt;
&lt;br /&gt;
;IDNF&lt;br /&gt;
:ID mark not found&lt;br /&gt;
&lt;br /&gt;
;MCR&lt;br /&gt;
:Media change requested&lt;br /&gt;
&lt;br /&gt;
;ABRT&lt;br /&gt;
:Command aborted&lt;br /&gt;
&lt;br /&gt;
;TK0NF&lt;br /&gt;
:Track 0 not found&lt;br /&gt;
&lt;br /&gt;
;AMNF&lt;br /&gt;
:Address mark not found&lt;br /&gt;
&lt;br /&gt;
=== GABE Control Registers ($AF:E880 &amp;amp;ndash; $AF:E887) ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Start Address&lt;br /&gt;
!Ending Address&lt;br /&gt;
!Register Description&lt;br /&gt;
!Additional Info&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E880 || || GABE_MSTR_CTRL&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E881 || || Reserved&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E882 || || GABE_RST_AUTH0 || Must Contain the BYTE $AD for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E883 || || GABE_RST_AUTH1 || Must Contain the BYTE $DE for Reset to Activate&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E884 || $AF:E885 || GABE_RNG_DATASEED || On read: 16-bit random data. On write, set 16-bit RNG seed.&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E886 || || GABE_RNG_STATCTRL || On read: 8-bit status. On write: 8-bit control&lt;br /&gt;
|-&lt;br /&gt;
|$AF:E887 || || GABE_SYS_STAT || 8-bit system status&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE Master Control Register ($AF:E880) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
|GABE_CTRL_WRM_RST || || || GABE_CTRL_BUZZER || || || GABE_CTRL_SDC_LED || GABE_CTRL_PWR_LED&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_PWR_LED&lt;br /&gt;
: Turns the power LED (next to the reset button) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_SDC_LED&lt;br /&gt;
: Turns the SDC activity LED (next to the SDC slot) on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_BUZZER &lt;br /&gt;
: Turns the built-in piezo buzzer on or off.&lt;br /&gt;
&lt;br /&gt;
; GABE_CTRL_WRM_RST &lt;br /&gt;
: Triggers a warm reset of the board (GABE_RST_AUTH0 must be set to $AD and GABE_RST_AUTH1 to $DE in order to trigger the reset).&lt;br /&gt;
&lt;br /&gt;
==== GABE Random Number Generator Status and Control ($AF:E886) ====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== GABE System Status Register ($AF:E887) ====&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| GABE_SYS_STAT_CPUX || GABE_SYS_STAT_CPUA || || || GABE_SYS_STAT_EXP || || GABE_SYS_STAT_MID1 || GABE_SYS_STAT_MID0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
; GABE_SYS_STAT_CPUX &lt;br /&gt;
: Indicates if the CPU's index registers are 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_CPUA &lt;br /&gt;
: Indicates if the CPU's accumulator is 8-bits or 16-bits wide.&lt;br /&gt;
; GABE_SYS_STAT_EXP &lt;br /&gt;
: Indicates if the and expansion card is present (0).&lt;br /&gt;
; GABE_SYS_STAT_MID1 and GABE_SYS_STAT_MID0&lt;br /&gt;
: These two bits show the machine ID:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!GABE_SYS_STAT_MID1 !! GABE_SYS_STAT_MID0 !! Machine &lt;br /&gt;
|-&lt;br /&gt;
| 0 || 0 || FMX - Development Platform&lt;br /&gt;
|-&lt;br /&gt;
| 0 || 1 || C256 Foenix - Dev Platform&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 0 || C256 Foenix - User Version (65C816)&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || Reserved&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SDC Interface ($AF:EA00) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides block-level access to the SPI interface of the SD card. Currently, there are other registers in that provide access to the SD card through a CH376S chip, but that interface should be considered deprecated in favor of this interface. Most FMX boards do not have the CH376S chip, leaving its position unpopulated on the board.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Address !! R/W !! Name !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0 !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA00 || R || SDC_VERSION_REG || colspan=&amp;quot;8&amp;quot;|version || Should read 12&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA01 || W || SDC_CONTROL_REG || x || x || x || x || x || x || x || RESET || Control register: RESET = 1 resets the core logic. Self clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA02 || W || SDC_TRANS_TYPE_REG ||x || x || x || x || x || x || colspan=&amp;quot;2&amp;quot;|TRANS || Sets the type of transaction: 0 = Direct, 1 = INIT SD, 2 = Read Block, 3 = Write block&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA03 || W || SDC_TRANS_CONTROL_REG || x || x || x || x || x || x || x || START || Start transaction bit.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA04 || R || SDC_TRANS_STATUS_REG || x || x || x || x || x || x || x || BUSY || Status of the transaction. BUSY = 1 indicates a transaction is in progress.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA05 || R || SDC_TRANS_ERROR_REG || x || x || colspan=&amp;quot;2&amp;quot;|WR_ERR || colspan=&amp;quot;2&amp;quot;|RD_ERR || colspan=&amp;quot;2&amp;quot;|TRANS_ERR || Error conditions for read, write, and transaction.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA06 || RW || SDC_DIRECT_ACCESS_REG || colspan=&amp;quot;8&amp;quot;|data || SPI Direct Read and Write - Set DATA before initiating direct Access Transaction&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA07 || W || SDC_SD_ADDR_7_0_REG || A7 || A6 || A5 || A4 || A3 || A2 || A1 || A0 || Set the ADDR before a block read or block write.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA08 || W || SDC_SD_ADDR_15_8_REG || A15 || A14 || A13 || A12 || A11 || A10 || A9 || A8 || ADDR[8:0] always should be 0, since each block is 512 bytes&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA09 || W || SDC_SD_ADDR_23_16_REG || A23 || A22 || A21 || A20 || A19 || A18 || A7 || A6&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0A || W || SDC_SD_ADDR_31_24_REG || A32 || A31 || A30 || A29 || A28 || A26 || A25 || A24&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA0B || W || SDC_SPI_CLK_DEL_REG || colspan=&amp;quot;8&amp;quot;|clock delay&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA10 || R || SDC_RX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Data from block read&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA12 || R || SDC_RX_FIFO_DATA_CNT_HI || CNT15 || CNT14 || CNT13 || CNT12 || CNT11 || CNT10 || CNT9 || CNT8 || How many bytes in the read FIFO (HI)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA13 || R || SDC_RX_FIFO_DATA_CNT_LO || CNT7 || CNT6 || CNT5 || CNT4 || CNT3 || CNT2 || CNT1 || CNT0 || How many bytes in the read FIFO (LOW)&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA14 || W || SDC_RX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the read FIFO. Bit is self-clearing.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA20 || W || SDC_TX_FIFO_DATA_REG || colspan=&amp;quot;8&amp;quot;|data || Write data block here.&lt;br /&gt;
|-&lt;br /&gt;
| $AF:EA21 || W || SDC_TX_FIFO_CTRL_REG || x || x || x || x || x || x || x || CLEAR || CLEAR = 1, clear the write FIFO. Bit is self-clearing.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== GABE: SDC_TRANS_ERROR_REG ($AF:EA05) ====&lt;br /&gt;
&lt;br /&gt;
Lists any error conditions on reads, writes, or general transactions:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ TRANS_ERR codes [1:0]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No INIT error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || INIT CMD0 error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || INIT CMD1 error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ RD_ERR codes [3:2]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No read error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Token error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ WR_ERR codes [5:4]&lt;br /&gt;
! Code !! Condition&lt;br /&gt;
|-&lt;br /&gt;
| 00 || No write error&lt;br /&gt;
|-&lt;br /&gt;
| 01 || CMD error&lt;br /&gt;
|-&lt;br /&gt;
| 10 || Data error&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Busy error&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== GABE SN76489 Interface ($AF:F100) ===&lt;br /&gt;
&lt;br /&gt;
GABE provides the interface to the SN76489 sound chip on the Foenix FMX. This chip uses only a single write-only address: $AF:F100. The SN76489 has four voices: three tone generators, and one noise generator. Each voice has a frequency and an attenuation setting. For full details on how to use the SN76489 chip, please consult the official documentation, but here is a brief summary.&lt;br /&gt;
&lt;br /&gt;
==== Playing a Tone ====&lt;br /&gt;
&lt;br /&gt;
To change the frequency of a tone generator, two bytes are sent to the chip in order:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! !! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| First || 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 0 || F3 || F2 || F1 || F0&lt;br /&gt;
|-&lt;br /&gt;
| Second || 0 || x || F9 || F8 || F7 || F6 || F5 || F4&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The actual frequency played depends on the clock driving the chip: freq = N / (32 * F), where N = 3575800 (for the FMX), and F is the 10-bit number sent to the chip. The &amp;quot;Channel&amp;quot; number above must be 0, 1, or 3.&lt;br /&gt;
&lt;br /&gt;
==== Play a Noise ====&lt;br /&gt;
&lt;br /&gt;
To play a noise, only a single byte is written to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 || 1 || 1 || 0 || x || NF|| NF1 || NF0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The NF bit controls the type of noise generated, and the NF bits control the base frequency of the noise.&lt;br /&gt;
&lt;br /&gt;
==== Setting the Volume ====&lt;br /&gt;
&lt;br /&gt;
The volumes of each of the four voices can be set independently. To set the volume of a single voice, a single byte is sent to the chip:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! 7 !! 6 !! 5 !! 4 !! 3 !! 2 !! 1 !! 0&lt;br /&gt;
|-&lt;br /&gt;
| 1 ||colspan=&amp;quot;2&amp;quot;| Channel || 1 || A3 || A2 || A1 || A0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;Channel&amp;quot; bits are the number of the voice to change: 0, 1, 2, or 3. The four bit value A is the level of attenuation, where 0 is fully on, and 15 is fully off.&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=586</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=586"/>
		<updated>2021-06-01T17:46:27Z</updated>

		<summary type="html">&lt;p&gt;PJW: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix Kernel Documentation =&lt;br /&gt;
&lt;br /&gt;
== Kernel Essentials ==&lt;br /&gt;
Source Code: https://github.com/Trinity-11/Kernel_FMX&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Kernel routines are called through a kernel jump table that starts at $00:1000.&lt;br /&gt;
All kernel routines must be called using the JSL instruction (long, or 24-bit subroutine call), since they all terminate with an RTL.&lt;br /&gt;
This allows the kernel routines to be called from anywhere in system memory.&lt;br /&gt;
&lt;br /&gt;
== Kernel Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Address !! Description&lt;br /&gt;
|-&lt;br /&gt;
| BOOT || $00:1000 || Cold boot routine&lt;br /&gt;
|-&lt;br /&gt;
| PUTC || $00:1018 || Print a character to the currently selected channel. [See [[ANSI Support]] for more details.]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || ASCII code of the character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PUTS || $00:101C || Print a null-terminated ASCII string to the currently selected channel&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the first character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETSCANCODE || $00:1028 || [v0.4] Get the next scancode from the keyboard (A = scancode, 0 if none available). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SETIN || $00:1038 || Set the current input channel used by the GET subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Keyboard&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| SETOUT || $00:103C || Set the current output channel used by the PUT subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Screen&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
* 4 = EVID video expansion card (if present)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETCH || $00:1048 | Get a character from the input channel. A=0 and Carry=1 if no data is waiting.&lt;br /&gt;
|-&lt;br /&gt;
| GETCHW || $00:104C || Get a character from the input channel. Waits until data received. A=0 and Carry=1 if no data is waiting&lt;br /&gt;
|-&lt;br /&gt;
| GETCHE || $00:1050 || Get a character from the input channel and echo to the screen. Wait if data is not ready.&lt;br /&gt;
|-&lt;br /&gt;
| PRINTCR || $00:106C || Print Carriage Return&lt;br /&gt;
|-&lt;br /&gt;
| PRINTH || $00:1078 || Print hex value in memory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the last byte to print&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || Number of bytes to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PRINTAH || $00:1080 || Prints hex value in A. Printed value is 2 wide if M flag is 1, 4 wide if M&lt;br /&gt;
|-&lt;br /&gt;
| LOCATE || $00:1084 || Move the cursor to a new position on the screen.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || The column for the cursor&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || The row for the cursor&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| CSRRIGHT || $00:1090 || Move the cursor one position to the right&lt;br /&gt;
|-&lt;br /&gt;
| CSRLEFT || $00:1094 || Move the cursor one position to the left&lt;br /&gt;
|-&lt;br /&gt;
| CSRUP || $00:1098 || Move the cursor up one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRDOWN || $00:109C || Move the cursor down one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRHOME || $00:10A0 || Move the cursor to the upper-left corner&lt;br /&gt;
|-&lt;br /&gt;
| SCROLLUP || $00:10A4 || Scroll the screen up one line. Creates an empty line at the bottom.&lt;br /&gt;
|-&lt;br /&gt;
| CLRSCREEN || $00:10B0 || Clear the screen&lt;br /&gt;
|-&lt;br /&gt;
| INITCHLUT || $00:10B4 || Init character look-up table&lt;br /&gt;
|-&lt;br /&gt;
| INITSUPERIO || $00:10B8 || Init Super-IO chip&lt;br /&gt;
|-&lt;br /&gt;
| INITKEYBOARD || $00:10BC || Init keyboard&lt;br /&gt;
|-&lt;br /&gt;
| INITRTC || $00:10C0 || Init Real-Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| INITCURSOR || $00:10C4 || Init the Cursors registers&lt;br /&gt;
|-&lt;br /&gt;
| INITFONTSET || $00:10C8 || Init the Internal FONT Memory&lt;br /&gt;
|-&lt;br /&gt;
| INITGAMMATABLE || $00:10CC || Init the RGB GAMMA Look Up Table&lt;br /&gt;
|-&lt;br /&gt;
| INITALLLUT || $00:10D0 || Init the Graphic Engine (Bitmap/Tile/Sprites) LUT&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYTXTMODE || $00:10D4 || Init the Text Mode @ Reset Time&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYGRPMODE || $00:10D8 || Init the Basic Registers for the Graphic Mode&lt;br /&gt;
|-&lt;br /&gt;
| F_OPEN     || $00:10F0 || Open a file for reading/writing. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CREATE   || $00:10F4 || Create a new file and write its first cluster. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CLOSE    || $00:10F8 || Close a file (make sure last cluster is written). DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_WRITE   || $00:10FC || Write the current cluster to the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_READ     || $00:1100 || Read the next cluster from the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_DELETE   || $00:1104 || Delete a file / directory. DOS_PATH_BUFF = a buffer containing the full path to the file (NULL terminated).&lt;br /&gt;
|-&lt;br /&gt;
| F_DIROPEN  || $00:1108 || Open a directory and seek the first directory entry. NOTE: currently only works with the root directory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || IN || Points to a file descriptor for the path to lookup. NOTE: currently unused.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the first FAT directory entry in that directory.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRNEXT  || $00:110C || seek to the next directory of an open directory&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || IN || Pointer to the current FAT directory entry.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the next FAT directory entry.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRREAD  || $00:1110 || Read the directory entry for the specified file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || IN || The buffer containing the path to the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the FAT directory entry for that file.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRWRITE || $00:1114 || Write any changes in the current directory cluster back to the drive&lt;br /&gt;
|-&lt;br /&gt;
| F_LOAD     || $00:1118 || load a binary file into memory, supports multiple file formats&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || Pointer to the location to load the file (any value &amp;gt; $3F:FFFF to load the file where the file specifies).&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_SAVE     || $00:111C || Save memory to a binary file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to create.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || Address of the first byte to save.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || Address of the last byte to save.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| CMDBLOCK ||  $00:1120 || Send a command to a block device.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_DEV || The target device&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 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.  &lt;br /&gt;
|-&lt;br /&gt;
| F_MOUNT || $00:1128 || Mount the designated block device. BIOS_DEV is the device number to mount.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
is a limit of 8 file descriptors that can be allocated at any one time.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
allocated previously through F_ALLOCFD.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| TESTBREAK || $00:113C || [v0.4] Check if BREAK was pressed recently by the user (C is set if true, clear if false)&lt;br /&gt;
|-&lt;br /&gt;
| SETTABLE || $00:1140 || [v0.4] Set the keyboard scan code -&amp;gt; character translation tables (B:X points to the new tables). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
|-&lt;br /&gt;
| DELAY || $00:114C || [v0.4] Wait at least Y:X ticks of the system clock.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DOS Calling Conventions ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
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&lt;br /&gt;
variables may contain non-zero status codes describing the nature of the failure.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Address !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || $00:0340 || 4 || A pointer to a file descriptor structure (defined below).&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || $00:0400 || 256 || A buffer space for storing a path to a file or directory.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || $00:0354 || 4 || A pointer to a block of memory to be filled from the disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || $00:0350 || 4 || A pointer to a block of memory to write to disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || $00:0358 || 4 || A pointer to the last byte of a block of memory.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_STATUS || $00:032E || 1 || A status code for DOS operations. $00 = success&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_STATUS || $00:0320 || 1 || A status code for sector level operations. $00 = success&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== File Descriptor ====&lt;br /&gt;
&lt;br /&gt;
Most DOS subroutines take a pointer to a file descriptor as an argument. This file descriptor contains several elements needed to manage a file,&lt;br /&gt;
including the buffer containing the current cluster of the file:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Offset !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| STATUS || 0 || 1 || A special status byte containing information about the file's state&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Value !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_READ || $01 || The file is open for reading&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_WRITE || $02 || The file is open for writing&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_OPEN || $40 || The file is open.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_ERROR || $60 || There is an error with the file.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_EOF || $80 || The file is being read and has reach the end of the file.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| DEV || 1 || 1 || A byte containing the device number for the file (should not be modified by the user program).&lt;br /&gt;
|-&lt;br /&gt;
| PATH || 2 || 4 || A pointer to a null-terminated string containing the path to the file. Set by the user program.&lt;br /&gt;
|-&lt;br /&gt;
| CLUSTER || 6 || 4 || The ID of the current cluster being read or written. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| FIRST_CLUSTER || 10 || 4 || The ID of the first cluster of the file. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SIZE || 18 || 4 || The size of the file in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_DATE || 22 || 2 || The creation date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_TIME || 24 || 2 || The creation time in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_DATE || 26 || 2 || The modification date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_TIME || 28 || 2 || The modification time in the same format as used by FAT.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Interrupt Jump Table ==&lt;br /&gt;
&lt;br /&gt;
The kernel provides a jump table for interrupt handler support. When an interrupt is triggered of any particular type, the kernel interrupt handler will&lt;br /&gt;
jump to the vector for that interrupt. The vector should point to a subroutine that returns to the caller through an RTL instruction.&lt;br /&gt;
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.&lt;br /&gt;
Currently, the kernel only supports a few interrupts in this manner. All system interrupts will eventually have an entry in this table.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
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&lt;br /&gt;
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&lt;br /&gt;
number of the interrupt is provided in A, with A[7..4] containing the block number, and A[3..0] containing the interrupt number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Interrupt !! Block !! Number !!  Address !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT00_SOF || 0 || 0 || $00:1700 || Start Of Frame (vertical blank, used by floppy drive code)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT01_SOL || 0 || 1 || $00:1704 || Start Of Line (horizontal blank)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT02_TMR0 || 0 || 2 || $00:1708 || Timer 0 (used by floppy drive code and DELAY call)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT03_TMR1 || 0 || 3 || $00:170C || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT04_TMR2 || 0 || 4 || $00:1710 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT05_RTC       || 0 || 5 || $00:1714 || Real Time Clock interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT06_FDC       || 0 || 6 || $00:1718 || Floppy Drive Controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT07_MOUSE     || 0 || 7 || $00:171C || Mouse interrupt (used by kernel to handle mouse)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT10_KBD       || 1 || 0 || $00:1720 || Keyboard interrupt (used by kernel to handle keyboard input)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT11_COL0      || 1 || 1 || $00:1724 || VICKY_II (INT2) Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT12_COL1      || 1 || 2 || $00:1728 || VICKY_II (INT3) Bitmap Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT13_COM2      || 1 || 3 || $00:172C || Serial port #2 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT14_COM1      || 1 || 4 || $00:1730 || Serial port #1 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT15_MIDI      || 1 || 5 || $00:1734 || MIDI controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT16_LPT       || 1 || 6 || $00:1738 || Parallel port interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDC       || 1 || 7 || $00:173C || SD Card Controller interrupt (no longer used)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT20_OPL       || 2 || 0 || $00:1740 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT21_GABE0     || 2 || 1 || $00:1744 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT22_GABE1     || 2 || 2 || $00:1748 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT23_VDMA      || 2 || 3 || $00:174C || VICKY_II (INT4) - VDMA Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT24_COL2      || 2 || 4 || $00:1750 || VICKY_II (INT5) Tile Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT25_GABE2     || 2 || 5 || $00:1754 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT26_EXT       || 2 || 6 || $00:1758 || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDINS     || 2 || 7 || $00:175C || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT30_OPN2      || 3 || 0 || $00:1760 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT31_OPM       || 3 || 1 || $00:1764 || OPM&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT32_IDE       || 3 || 2 || $00:1768 || HDD IDE Interrupt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special Kernel Variables ==&lt;br /&gt;
&lt;br /&gt;
The kernel keeps track of several variables.&lt;br /&gt;
Most kernel variables should be left alone by applications, but there are some which an application might want to set or read.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Name !! R/W || Description&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000F || $00:0010 || COLS_VISIBLE || RW || The number of columns currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0013 || $00:0014 || LINES_VISIBLE || RW || The number of rows currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0017 || $00:0018 || CURSORPOS || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001A || $00:001B || CURSORX || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001C || $00:001D || CURSORY || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001E || || CURCOLOR || RW || The foreground and background colors to be used when printing via PUTC and PUTS&lt;br /&gt;
|-&lt;br /&gt;
| $00:001F || $00:0020 || COLORPOS || RO || The address of the text color cell under the cursor&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=585</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=585"/>
		<updated>2021-06-01T17:41:49Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Interrupt Jump Table */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix Kernel Documentation =&lt;br /&gt;
&lt;br /&gt;
== Kernel Essentials ==&lt;br /&gt;
Source Code: https://github.com/Trinity-11/Kernel_FMX&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Kernel routines are called through a kernel jump table that starts at $00:1000.&lt;br /&gt;
All kernel routines must be called using the JSL instruction (long, or 24-bit subroutine call), since they all terminate with an RTL.&lt;br /&gt;
This allows the kernel routines to be called from anywhere in system memory.&lt;br /&gt;
&lt;br /&gt;
== Kernel Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Address !! Description&lt;br /&gt;
|-&lt;br /&gt;
| BOOT || $00:1000 || Cold boot routine&lt;br /&gt;
|-&lt;br /&gt;
| PUTC || $00:1018 || Print a character to the currently selected channel. [See [[ANSI Support]] for more details.]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || ASCII code of the character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PUTS || $00:101C || Print a null-terminated ASCII string to the currently selected channel&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the first character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETSCANCODE || $00:1028 || [v0.4] Get the next scancode from the keyboard (A = scancode, 0 if none available). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SETIN || $00:1038 || Set the current input channel used by the GET subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Keyboard&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| SETOUT || $00:103C || Set the current output channel used by the PUT subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Screen&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
* 4 = EVID video expansion card (if present)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETCH || $00:1048 | Get a character from the input channel. A=0 and Carry=1 if no data is waiting.&lt;br /&gt;
|-&lt;br /&gt;
| GETCHW || $00:104C || Get a character from the input channel. Waits until data received. A=0 and Carry=1 if no data is waiting&lt;br /&gt;
|-&lt;br /&gt;
| GETCHE || $00:1050 || Get a character from the input channel and echo to the screen. Wait if data is not ready.&lt;br /&gt;
|-&lt;br /&gt;
| PRINTCR || $00:106C || Print Carriage Return&lt;br /&gt;
|-&lt;br /&gt;
| PRINTH || $00:1078 || Print hex value in memory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the last byte to print&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || Number of bytes to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PRINTAH || $00:1080 || Prints hex value in A. Printed value is 2 wide if M flag is 1, 4 wide if M&lt;br /&gt;
|-&lt;br /&gt;
| LOCATE || $00:1084 || Move the cursor to a new position on the screen.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || The column for the cursor&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || The row for the cursor&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| CSRRIGHT || $00:1090 || Move the cursor one position to the right&lt;br /&gt;
|-&lt;br /&gt;
| CSRLEFT || $00:1094 || Move the cursor one position to the left&lt;br /&gt;
|-&lt;br /&gt;
| CSRUP || $00:1098 || Move the cursor up one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRDOWN || $00:109C || Move the cursor down one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRHOME || $00:10A0 || Move the cursor to the upper-left corner&lt;br /&gt;
|-&lt;br /&gt;
| SCROLLUP || $00:10A4 || Scroll the screen up one line. Creates an empty line at the bottom.&lt;br /&gt;
|-&lt;br /&gt;
| CLRSCREEN || $00:10B0 || Clear the screen&lt;br /&gt;
|-&lt;br /&gt;
| INITCHLUT || $00:10B4 || Init character look-up table&lt;br /&gt;
|-&lt;br /&gt;
| INITSUPERIO || $00:10B8 || Init Super-IO chip&lt;br /&gt;
|-&lt;br /&gt;
| INITKEYBOARD || $00:10BC || Init keyboard&lt;br /&gt;
|-&lt;br /&gt;
| INITRTC || $00:10C0 || Init Real-Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| INITCURSOR || $00:10C4 || Init the Cursors registers&lt;br /&gt;
|-&lt;br /&gt;
| INITFONTSET || $00:10C8 || Init the Internal FONT Memory&lt;br /&gt;
|-&lt;br /&gt;
| INITGAMMATABLE || $00:10CC || Init the RGB GAMMA Look Up Table&lt;br /&gt;
|-&lt;br /&gt;
| INITALLLUT || $00:10D0 || Init the Graphic Engine (Bitmap/Tile/Sprites) LUT&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYTXTMODE || $00:10D4 || Init the Text Mode @ Reset Time&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYGRPMODE || $00:10D8 || Init the Basic Registers for the Graphic Mode&lt;br /&gt;
|-&lt;br /&gt;
| F_OPEN     || $00:10F0 || Open a file for reading/writing. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CREATE   || $00:10F4 || Create a new file and write its first cluster. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CLOSE    || $00:10F8 || Close a file (make sure last cluster is written). DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_WRITE   || $00:10FC || Write the current cluster to the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_READ     || $00:1100 || Read the next cluster from the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_DELETE   || $00:1104 || Delete a file / directory. DOS_PATH_BUFF = a buffer containing the full path to the file (NULL terminated).&lt;br /&gt;
|-&lt;br /&gt;
| F_DIROPEN  || $00:1108 || Open a directory and seek the first directory entry. NOTE: currently only works with the root directory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || IN || Points to a file descriptor for the path to lookup. NOTE: currently unused.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the first FAT directory entry in that directory.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRNEXT  || $00:110C || seek to the next directory of an open directory&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || IN || Pointer to the current FAT directory entry.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the next FAT directory entry.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRREAD  || $00:1110 || Read the directory entry for the specified file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || IN || The buffer containing the path to the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the FAT directory entry for that file.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRWRITE || $00:1114 || Write any changes in the current directory cluster back to the drive&lt;br /&gt;
|-&lt;br /&gt;
| F_LOAD     || $00:1118 || load a binary file into memory, supports multiple file formats&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || Pointer to the location to load the file (any value &amp;gt; $3F:FFFF to load the file where the file specifies).&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_SAVE     || $00:111C || Save memory to a binary file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to create.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || Address of the first byte to save.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || Address of the last byte to save.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| CMDBLOCK ||  $00:1120 || Send a command to a block device.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_DEV || The target device&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 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.  &lt;br /&gt;
|-&lt;br /&gt;
| F_MOUNT || $00:1128 || Mount the designated block device. BIOS_DEV is the device number to mount.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
is a limit of 8 file descriptors that can be allocated at any one time.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
allocated previously through F_ALLOCFD.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| TESTBREAK || $00:113C || [v0.4] Check if BREAK was pressed recently by the user (C is set if true, clear if false)&lt;br /&gt;
|-&lt;br /&gt;
| SETTABLE || $00:1140 || [v0.4] Set the keyboard scan code -&amp;gt; character translation tables (B:X points to the new tables). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
|-&lt;br /&gt;
| DELAY || $00:114C || [v0.4] Wait at least Y:X ticks of the system clock.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DOS Calling Conventions ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
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&lt;br /&gt;
variables may contain non-zero status codes describing the nature of the failure.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Address !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || $00:0340 || 4 || A pointer to a file descriptor structure (defined below).&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || $00:0400 || 256 || A buffer space for storing a path to a file or directory.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || $00:0354 || 4 || A pointer to a block of memory to be filled from the disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || $00:0350 || 4 || A pointer to a block of memory to write to disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || $00:0358 || 4 || A pointer to the last byte of a block of memory.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_STATUS || $00:032E || 1 || A status code for DOS operations. $00 = success&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_STATUS || $00:0320 || 1 || A status code for sector level operations. $00 = success&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== File Descriptor ====&lt;br /&gt;
&lt;br /&gt;
Most DOS subroutines take a pointer to a file descriptor as an argument. This file descriptor contains several elements needed to manage a file,&lt;br /&gt;
including the buffer containing the current cluster of the file:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Offset !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| STATUS || 0 || 1 || A special status byte containing information about the file's state&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Value !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_READ || $01 || The file is open for reading&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_WRITE || $02 || The file is open for writing&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_OPEN || $40 || The file is open.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_ERROR || $60 || There is an error with the file.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_EOF || $80 || The file is being read and has reach the end of the file.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| DEV || 1 || 1 || A byte containing the device number for the file (should not be modified by the user program).&lt;br /&gt;
|-&lt;br /&gt;
| PATH || 2 || 4 || A pointer to a null-terminated string containing the path to the file. Set by the user program.&lt;br /&gt;
|-&lt;br /&gt;
| CLUSTER || 6 || 4 || The ID of the current cluster being read or written. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| FIRST_CLUSTER || 10 || 4 || The ID of the first cluster of the file. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SIZE || 18 || 4 || The size of the file in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_DATE || 22 || 2 || The creation date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_TIME || 24 || 2 || The creation time in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_DATE || 26 || 2 || The modification date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_TIME || 28 || 2 || The modification time in the same format as used by FAT.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Interrupt Jump Table ==&lt;br /&gt;
&lt;br /&gt;
The kernel provides a jump table for interrupt handler support. When an interrupt is triggered of any particular type, the kernel interrupt handler will&lt;br /&gt;
jump to the vector for that interrupt. The vector should point to a subroutine that returns to the caller through an RTL instruction.&lt;br /&gt;
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.&lt;br /&gt;
Currently, the kernel only supports a few interrupts in this manner. All system interrupts will eventually have an entry in this table.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
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&lt;br /&gt;
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&lt;br /&gt;
number of the interrupt is provided in A, with A[7..4] containing the block number, and A[3..0] containing the interrupt number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Interrupt !! Block !! Number !!  Address !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT00_SOF || 0 || 0 || $00:1700 || Start Of Frame (vertical blank, used by floppy drive code)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT01_SOL || 0 || 1 || $00:1704 || Start Of Line (horizontal blank)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT02_TMR0 || 0 || 2 || $00:1708 || Timer 0 (used by floppy drive code and DELAY call)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT03_TMR1 || 0 || 3 || $00:170C || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT04_TMR2 || 0 || 4 || $00:1710 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT05_RTC       || 0 || 5 || $00:1714 || Real Time Clock interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT06_FDC       || 0 || 6 || $00:1718 || Floppy Drive Controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT07_MOUSE     || 0 || 7 || $00:171C || Mouse interrupt (used by kernel to handle mouse)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT10_KBD       || 1 || 0 || $00:1720 || Keyboard interrupt (used by kernel to handle keyboard input)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT11_COL0      || 1 || 1 || $00:1724 || VICKY_II (INT2) Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT12_COL1      || 1 || 2 || $00:1728 || VICKY_II (INT3) Bitmap Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT13_COM2      || 1 || 3 || $00:172C || Serial port #2 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT14_COM1      || 1 || 4 || $00:1730 || Serial port #1 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT15_MIDI      || 1 || 5 || $00:1734 || MIDI controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT16_LPT       || 1 || 6 || $00:1738 || Parallel port interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDC       || 1 || 7 || $00:173C || SD Card Controller interrupt (no longer used)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT20_OPL       || 2 || 0 || $00:1740 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT21_GABE0     || 2 || 1 || $00:1744 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT22_GABE1     || 2 || 2 || $00:1748 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT23_VDMA      || 2 || 3 || $00:174C || VICKY_II (INT4) - VDMA Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT24_COL2      || 2 || 4 || $00:1750 || VICKY_II (INT5) Tile Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT25_GABE2     || 2 || 5 || $00:1754 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT26_EXT       || 2 || 6 || $00:1758 || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDINS     || 2 || 7 || $00:175C || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT30_OPN2      || 3 || 0 || $00:1760 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT31_OPM       || 3 || 1 || $00:1764 || OPM&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT32_IDE       || 3 || 2 || $00:1768 || HDD IDE Interrupt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Console Special Characters ==&lt;br /&gt;
&lt;br /&gt;
The console routines support several special control codes for both input and output.&lt;br /&gt;
When the key on the keyboard is pressed, the associated code is returned by the GET routines.&lt;br /&gt;
If the code is printed through the PUTC or PUTS, the associated operation will be performed on the screen.&lt;br /&gt;
Note that this means that any graphics characters associated with those code points will not be displayed by PUTC or PUTS.&lt;br /&gt;
If those characters must be displayed, they would have to be written to the text memory directly.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code !! Name !! Keyboard !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $08 || BS || Backspace || Deletes the character to the left of the cursor, pulling characters in from the right.&lt;br /&gt;
|-&lt;br /&gt;
| $09 || TAB || TAB || Moves the cursor right to the next tabulated column (every eight columns).&lt;br /&gt;
|-&lt;br /&gt;
| $0A || LF || N/A || Puts the cursor at column 0 on the next line on the same column.&lt;br /&gt;
|-&lt;br /&gt;
| $0D || CR || RETURN || Creates a newline on the screen. Puts the cursor at column 0 on the next line.&lt;br /&gt;
|-&lt;br /&gt;
| $0F || INS || Insert || Inserts a blank space under the cursor (pushing characters to the right).&lt;br /&gt;
|-&lt;br /&gt;
| $11 || UP || Up Arrow || Moves the cursor up one row.&lt;br /&gt;
|-&lt;br /&gt;
| $1D || RIGHT || Right Arrow || Moves the cursor right one column. May wrap to the next line.&lt;br /&gt;
|-&lt;br /&gt;
| $7F || DEL || Delete || Deletes the character under the cursor, pulling characters in from the right.&lt;br /&gt;
|-&lt;br /&gt;
| $91 || DOWN || Down Arrow || Moves the cursor down one row. May scroll the screen.&lt;br /&gt;
|-&lt;br /&gt;
| $9D || LEFT || Left Arrow || Moves the cursor left one column.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special Kernel Variables ==&lt;br /&gt;
&lt;br /&gt;
The kernel keeps track of several variables.&lt;br /&gt;
Most kernel variables should be left alone by applications, but there are some which an application might want to set or read.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Name !! R/W || Description&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000F || $00:0010 || COLS_VISIBLE || RW || The number of columns currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0013 || $00:0014 || LINES_VISIBLE || RW || The number of rows currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0017 || $00:0018 || CURSORPOS || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001A || $00:001B || CURSORX || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001C || $00:001D || CURSORY || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001E || || CURCOLOR || RW || The foreground and background colors to be used when printing via PUTC and PUTS&lt;br /&gt;
|-&lt;br /&gt;
| $00:001F || $00:0020 || COLORPOS || RO || The address of the text color cell under the cursor&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=584</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=584"/>
		<updated>2021-06-01T17:41:05Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Interrupt Jump Table */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix Kernel Documentation =&lt;br /&gt;
&lt;br /&gt;
== Kernel Essentials ==&lt;br /&gt;
Source Code: https://github.com/Trinity-11/Kernel_FMX&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Kernel routines are called through a kernel jump table that starts at $00:1000.&lt;br /&gt;
All kernel routines must be called using the JSL instruction (long, or 24-bit subroutine call), since they all terminate with an RTL.&lt;br /&gt;
This allows the kernel routines to be called from anywhere in system memory.&lt;br /&gt;
&lt;br /&gt;
== Kernel Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Address !! Description&lt;br /&gt;
|-&lt;br /&gt;
| BOOT || $00:1000 || Cold boot routine&lt;br /&gt;
|-&lt;br /&gt;
| PUTC || $00:1018 || Print a character to the currently selected channel. [See [[ANSI Support]] for more details.]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || ASCII code of the character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PUTS || $00:101C || Print a null-terminated ASCII string to the currently selected channel&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the first character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETSCANCODE || $00:1028 || [v0.4] Get the next scancode from the keyboard (A = scancode, 0 if none available). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SETIN || $00:1038 || Set the current input channel used by the GET subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Keyboard&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| SETOUT || $00:103C || Set the current output channel used by the PUT subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Screen&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
* 4 = EVID video expansion card (if present)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETCH || $00:1048 | Get a character from the input channel. A=0 and Carry=1 if no data is waiting.&lt;br /&gt;
|-&lt;br /&gt;
| GETCHW || $00:104C || Get a character from the input channel. Waits until data received. A=0 and Carry=1 if no data is waiting&lt;br /&gt;
|-&lt;br /&gt;
| GETCHE || $00:1050 || Get a character from the input channel and echo to the screen. Wait if data is not ready.&lt;br /&gt;
|-&lt;br /&gt;
| PRINTCR || $00:106C || Print Carriage Return&lt;br /&gt;
|-&lt;br /&gt;
| PRINTH || $00:1078 || Print hex value in memory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the last byte to print&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || Number of bytes to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PRINTAH || $00:1080 || Prints hex value in A. Printed value is 2 wide if M flag is 1, 4 wide if M&lt;br /&gt;
|-&lt;br /&gt;
| LOCATE || $00:1084 || Move the cursor to a new position on the screen.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || The column for the cursor&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || The row for the cursor&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| CSRRIGHT || $00:1090 || Move the cursor one position to the right&lt;br /&gt;
|-&lt;br /&gt;
| CSRLEFT || $00:1094 || Move the cursor one position to the left&lt;br /&gt;
|-&lt;br /&gt;
| CSRUP || $00:1098 || Move the cursor up one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRDOWN || $00:109C || Move the cursor down one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRHOME || $00:10A0 || Move the cursor to the upper-left corner&lt;br /&gt;
|-&lt;br /&gt;
| SCROLLUP || $00:10A4 || Scroll the screen up one line. Creates an empty line at the bottom.&lt;br /&gt;
|-&lt;br /&gt;
| CLRSCREEN || $00:10B0 || Clear the screen&lt;br /&gt;
|-&lt;br /&gt;
| INITCHLUT || $00:10B4 || Init character look-up table&lt;br /&gt;
|-&lt;br /&gt;
| INITSUPERIO || $00:10B8 || Init Super-IO chip&lt;br /&gt;
|-&lt;br /&gt;
| INITKEYBOARD || $00:10BC || Init keyboard&lt;br /&gt;
|-&lt;br /&gt;
| INITRTC || $00:10C0 || Init Real-Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| INITCURSOR || $00:10C4 || Init the Cursors registers&lt;br /&gt;
|-&lt;br /&gt;
| INITFONTSET || $00:10C8 || Init the Internal FONT Memory&lt;br /&gt;
|-&lt;br /&gt;
| INITGAMMATABLE || $00:10CC || Init the RGB GAMMA Look Up Table&lt;br /&gt;
|-&lt;br /&gt;
| INITALLLUT || $00:10D0 || Init the Graphic Engine (Bitmap/Tile/Sprites) LUT&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYTXTMODE || $00:10D4 || Init the Text Mode @ Reset Time&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYGRPMODE || $00:10D8 || Init the Basic Registers for the Graphic Mode&lt;br /&gt;
|-&lt;br /&gt;
| F_OPEN     || $00:10F0 || Open a file for reading/writing. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CREATE   || $00:10F4 || Create a new file and write its first cluster. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CLOSE    || $00:10F8 || Close a file (make sure last cluster is written). DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_WRITE   || $00:10FC || Write the current cluster to the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_READ     || $00:1100 || Read the next cluster from the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_DELETE   || $00:1104 || Delete a file / directory. DOS_PATH_BUFF = a buffer containing the full path to the file (NULL terminated).&lt;br /&gt;
|-&lt;br /&gt;
| F_DIROPEN  || $00:1108 || Open a directory and seek the first directory entry. NOTE: currently only works with the root directory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || IN || Points to a file descriptor for the path to lookup. NOTE: currently unused.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the first FAT directory entry in that directory.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRNEXT  || $00:110C || seek to the next directory of an open directory&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || IN || Pointer to the current FAT directory entry.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the next FAT directory entry.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRREAD  || $00:1110 || Read the directory entry for the specified file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || IN || The buffer containing the path to the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the FAT directory entry for that file.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRWRITE || $00:1114 || Write any changes in the current directory cluster back to the drive&lt;br /&gt;
|-&lt;br /&gt;
| F_LOAD     || $00:1118 || load a binary file into memory, supports multiple file formats&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || Pointer to the location to load the file (any value &amp;gt; $3F:FFFF to load the file where the file specifies).&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_SAVE     || $00:111C || Save memory to a binary file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to create.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || Address of the first byte to save.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || Address of the last byte to save.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| CMDBLOCK ||  $00:1120 || Send a command to a block device.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_DEV || The target device&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 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.  &lt;br /&gt;
|-&lt;br /&gt;
| F_MOUNT || $00:1128 || Mount the designated block device. BIOS_DEV is the device number to mount.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
is a limit of 8 file descriptors that can be allocated at any one time.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
allocated previously through F_ALLOCFD.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| TESTBREAK || $00:113C || [v0.4] Check if BREAK was pressed recently by the user (C is set if true, clear if false)&lt;br /&gt;
|-&lt;br /&gt;
| SETTABLE || $00:1140 || [v0.4] Set the keyboard scan code -&amp;gt; character translation tables (B:X points to the new tables). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
|-&lt;br /&gt;
| DELAY || $00:114C || [v0.4] Wait at least Y:X ticks of the system clock.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DOS Calling Conventions ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
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&lt;br /&gt;
variables may contain non-zero status codes describing the nature of the failure.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Address !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || $00:0340 || 4 || A pointer to a file descriptor structure (defined below).&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || $00:0400 || 256 || A buffer space for storing a path to a file or directory.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || $00:0354 || 4 || A pointer to a block of memory to be filled from the disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || $00:0350 || 4 || A pointer to a block of memory to write to disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || $00:0358 || 4 || A pointer to the last byte of a block of memory.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_STATUS || $00:032E || 1 || A status code for DOS operations. $00 = success&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_STATUS || $00:0320 || 1 || A status code for sector level operations. $00 = success&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== File Descriptor ====&lt;br /&gt;
&lt;br /&gt;
Most DOS subroutines take a pointer to a file descriptor as an argument. This file descriptor contains several elements needed to manage a file,&lt;br /&gt;
including the buffer containing the current cluster of the file:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Offset !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| STATUS || 0 || 1 || A special status byte containing information about the file's state&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Value !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_READ || $01 || The file is open for reading&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_WRITE || $02 || The file is open for writing&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_OPEN || $40 || The file is open.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_ERROR || $60 || There is an error with the file.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_EOF || $80 || The file is being read and has reach the end of the file.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| DEV || 1 || 1 || A byte containing the device number for the file (should not be modified by the user program).&lt;br /&gt;
|-&lt;br /&gt;
| PATH || 2 || 4 || A pointer to a null-terminated string containing the path to the file. Set by the user program.&lt;br /&gt;
|-&lt;br /&gt;
| CLUSTER || 6 || 4 || The ID of the current cluster being read or written. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| FIRST_CLUSTER || 10 || 4 || The ID of the first cluster of the file. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SIZE || 18 || 4 || The size of the file in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_DATE || 22 || 2 || The creation date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_TIME || 24 || 2 || The creation time in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_DATE || 26 || 2 || The modification date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_TIME || 28 || 2 || The modification time in the same format as used by FAT.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Interrupt Jump Table ==&lt;br /&gt;
&lt;br /&gt;
The kernel provides a jump table for interrupt handler support. When an interrupt is triggered of any particular type, the kernel interrupt handler will&lt;br /&gt;
jump to the vector for that interrupt. The vector should point to a subroutine that returns to the caller through an RTL instruction.&lt;br /&gt;
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.&lt;br /&gt;
Currently, the kernel only supports a few interrupts in this manner. All system interrupts will eventually have an entry in this table.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
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&lt;br /&gt;
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&lt;br /&gt;
number of the interrupt is provided in A, with A[7..4] containing the block number, and A[3..0] containing the interrupt number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Interrupt !! Block !! Number !!  Address !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT00_SOF || 0 || 0 || $00:1700 || Start Of Frame (vertical blank, used by floppy drive code)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT01_SOL || 0 || 1 || $00:1704 || Start Of Line (horizontal blank)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT02_TMR0 || 0 || 2 || $00:1708 || Timer 0 (used by floppy drive code and DELAY call)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT03_TMR1 || 0 || 3 || $00:170C || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT04_TMR2 || 0 || 4 || $00:1710 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT05_RTC       || 0 || 5 || $00:1714 || Real Time Clock interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT06_FDC       || 0 || 6 || $00:1718 || Floppy Drive Controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT07_MOUSE     || 0 || 7 || $00:171C || Mouse interrupt (used by kernel to handle mouse)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT10_KBD       || 1 || 0 || $00:1720 || Keyboard interrupt (used by kernel to handle keyboard input)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT11_COL0      || 1 || 1 || $00:1724 || VICKY_II (INT2) Sprite Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT12_COL1      || 1 || 2 || $00:1728 || VICKY_II (INT3) Bitmap Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT13_COM2      || 1 || 3 || $00:172C || Serial port #2 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT14_COM1      || 1 || 4 || $00:1730 || Serial port #1 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT15_MIDI      || 1 || 5 || $00:1734 || MIDI controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT16_LPT       || 1 || 6 || $00:1738 || Parallel port interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDC       || 1 || 7 || $00:173C || SD Card Controller interrupt (CH376S???)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT20_OPL       || 2 || 0 || $00:1740 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT21_GABE0     || 2 || 1 || $00:1744 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT22_GABE1     || 2 || 2 || $00:1748 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT23_VDMA      || 2 || 3 || $00:174C || VICKY_II (INT4) - VDMA Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT24_COL2      || 2 || 4 || $00:1750 || VICKY_II (INT5) Tile Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT25_GABE2     || 2 || 5 || $00:1754 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT26_EXT       || 2 || 6 || $00:1758 || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDINS     || 2 || 7 || $00:175C || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT30_OPN2      || 3 || 0 || $00:1760 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT31_OPM       || 3 || 1 || $00:1764 || OPM&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT32_IDE       || 3 || 2 || $00:1768 || HDD IDE Interrupt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Console Special Characters ==&lt;br /&gt;
&lt;br /&gt;
The console routines support several special control codes for both input and output.&lt;br /&gt;
When the key on the keyboard is pressed, the associated code is returned by the GET routines.&lt;br /&gt;
If the code is printed through the PUTC or PUTS, the associated operation will be performed on the screen.&lt;br /&gt;
Note that this means that any graphics characters associated with those code points will not be displayed by PUTC or PUTS.&lt;br /&gt;
If those characters must be displayed, they would have to be written to the text memory directly.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code !! Name !! Keyboard !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $08 || BS || Backspace || Deletes the character to the left of the cursor, pulling characters in from the right.&lt;br /&gt;
|-&lt;br /&gt;
| $09 || TAB || TAB || Moves the cursor right to the next tabulated column (every eight columns).&lt;br /&gt;
|-&lt;br /&gt;
| $0A || LF || N/A || Puts the cursor at column 0 on the next line on the same column.&lt;br /&gt;
|-&lt;br /&gt;
| $0D || CR || RETURN || Creates a newline on the screen. Puts the cursor at column 0 on the next line.&lt;br /&gt;
|-&lt;br /&gt;
| $0F || INS || Insert || Inserts a blank space under the cursor (pushing characters to the right).&lt;br /&gt;
|-&lt;br /&gt;
| $11 || UP || Up Arrow || Moves the cursor up one row.&lt;br /&gt;
|-&lt;br /&gt;
| $1D || RIGHT || Right Arrow || Moves the cursor right one column. May wrap to the next line.&lt;br /&gt;
|-&lt;br /&gt;
| $7F || DEL || Delete || Deletes the character under the cursor, pulling characters in from the right.&lt;br /&gt;
|-&lt;br /&gt;
| $91 || DOWN || Down Arrow || Moves the cursor down one row. May scroll the screen.&lt;br /&gt;
|-&lt;br /&gt;
| $9D || LEFT || Left Arrow || Moves the cursor left one column.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special Kernel Variables ==&lt;br /&gt;
&lt;br /&gt;
The kernel keeps track of several variables.&lt;br /&gt;
Most kernel variables should be left alone by applications, but there are some which an application might want to set or read.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Name !! R/W || Description&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000F || $00:0010 || COLS_VISIBLE || RW || The number of columns currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0013 || $00:0014 || LINES_VISIBLE || RW || The number of rows currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0017 || $00:0018 || CURSORPOS || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001A || $00:001B || CURSORX || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001C || $00:001D || CURSORY || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001E || || CURCOLOR || RW || The foreground and background colors to be used when printing via PUTC and PUTS&lt;br /&gt;
|-&lt;br /&gt;
| $00:001F || $00:0020 || COLORPOS || RO || The address of the text color cell under the cursor&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
	<entry>
		<id>https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=583</id>
		<title>Foenix Kernel Documentation</title>
		<link rel="alternate" type="text/html" href="https://wiki.c256foenix.com/index.php?title=Foenix_Kernel_Documentation&amp;diff=583"/>
		<updated>2021-06-01T17:39:59Z</updated>

		<summary type="html">&lt;p&gt;PJW: /* Interrupt Jump Table */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Foenix Kernel Documentation =&lt;br /&gt;
&lt;br /&gt;
== Kernel Essentials ==&lt;br /&gt;
Source Code: https://github.com/Trinity-11/Kernel_FMX&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
Kernel routines are called through a kernel jump table that starts at $00:1000.&lt;br /&gt;
All kernel routines must be called using the JSL instruction (long, or 24-bit subroutine call), since they all terminate with an RTL.&lt;br /&gt;
This allows the kernel routines to be called from anywhere in system memory.&lt;br /&gt;
&lt;br /&gt;
== Kernel Calls ==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Address !! Description&lt;br /&gt;
|-&lt;br /&gt;
| BOOT || $00:1000 || Cold boot routine&lt;br /&gt;
|-&lt;br /&gt;
| PUTC || $00:1018 || Print a character to the currently selected channel. [See [[ANSI Support]] for more details.]&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || ASCII code of the character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PUTS || $00:101C || Print a null-terminated ASCII string to the currently selected channel&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the first character to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETSCANCODE || $00:1028 || [v0.4] Get the next scancode from the keyboard (A = scancode, 0 if none available). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SETIN || $00:1038 || Set the current input channel used by the GET subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Keyboard&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| SETOUT || $00:103C || Set the current output channel used by the PUT subroutines&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| A || 8 || Input channel to use&lt;br /&gt;
* 0 = Screen&lt;br /&gt;
* 1 = COM1 (external serial)&lt;br /&gt;
* 2 = COM2 (internal serial)&lt;br /&gt;
* 4 = EVID video expansion card (if present)&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| GETCH || $00:1048 | Get a character from the input channel. A=0 and Carry=1 if no data is waiting.&lt;br /&gt;
|-&lt;br /&gt;
| GETCHW || $00:104C || Get a character from the input channel. Waits until data received. A=0 and Carry=1 if no data is waiting&lt;br /&gt;
|-&lt;br /&gt;
| GETCHE || $00:1050 || Get a character from the input channel and echo to the screen. Wait if data is not ready.&lt;br /&gt;
|-&lt;br /&gt;
| PRINTCR || $00:106C || Print Carriage Return&lt;br /&gt;
|-&lt;br /&gt;
| PRINTH || $00:1078 || Print hex value in memory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| B || 8 || Bank containing the data to print&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || Address within that bank of the last byte to print&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || Number of bytes to print&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| PRINTAH || $00:1080 || Prints hex value in A. Printed value is 2 wide if M flag is 1, 4 wide if M&lt;br /&gt;
|-&lt;br /&gt;
| LOCATE || $00:1084 || Move the cursor to a new position on the screen.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Register !! Width !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| X || 16 || The column for the cursor&lt;br /&gt;
|-&lt;br /&gt;
| Y || 16 || The row for the cursor&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| CSRRIGHT || $00:1090 || Move the cursor one position to the right&lt;br /&gt;
|-&lt;br /&gt;
| CSRLEFT || $00:1094 || Move the cursor one position to the left&lt;br /&gt;
|-&lt;br /&gt;
| CSRUP || $00:1098 || Move the cursor up one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRDOWN || $00:109C || Move the cursor down one row&lt;br /&gt;
|-&lt;br /&gt;
| CSRHOME || $00:10A0 || Move the cursor to the upper-left corner&lt;br /&gt;
|-&lt;br /&gt;
| SCROLLUP || $00:10A4 || Scroll the screen up one line. Creates an empty line at the bottom.&lt;br /&gt;
|-&lt;br /&gt;
| CLRSCREEN || $00:10B0 || Clear the screen&lt;br /&gt;
|-&lt;br /&gt;
| INITCHLUT || $00:10B4 || Init character look-up table&lt;br /&gt;
|-&lt;br /&gt;
| INITSUPERIO || $00:10B8 || Init Super-IO chip&lt;br /&gt;
|-&lt;br /&gt;
| INITKEYBOARD || $00:10BC || Init keyboard&lt;br /&gt;
|-&lt;br /&gt;
| INITRTC || $00:10C0 || Init Real-Time Clock&lt;br /&gt;
|-&lt;br /&gt;
| INITCURSOR || $00:10C4 || Init the Cursors registers&lt;br /&gt;
|-&lt;br /&gt;
| INITFONTSET || $00:10C8 || Init the Internal FONT Memory&lt;br /&gt;
|-&lt;br /&gt;
| INITGAMMATABLE || $00:10CC || Init the RGB GAMMA Look Up Table&lt;br /&gt;
|-&lt;br /&gt;
| INITALLLUT || $00:10D0 || Init the Graphic Engine (Bitmap/Tile/Sprites) LUT&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYTXTMODE || $00:10D4 || Init the Text Mode @ Reset Time&lt;br /&gt;
|-&lt;br /&gt;
| INITVKYGRPMODE || $00:10D8 || Init the Basic Registers for the Graphic Mode&lt;br /&gt;
|-&lt;br /&gt;
| F_OPEN     || $00:10F0 || Open a file for reading/writing. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CREATE   || $00:10F4 || Create a new file and write its first cluster. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_CLOSE    || $00:10F8 || Close a file (make sure last cluster is written). DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_WRITE   || $00:10FC || Write the current cluster to the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_READ     || $00:1100 || Read the next cluster from the file. DOS_FD_PTR points to a file descriptor for the file.&lt;br /&gt;
|-&lt;br /&gt;
| F_DELETE   || $00:1104 || Delete a file / directory. DOS_PATH_BUFF = a buffer containing the full path to the file (NULL terminated).&lt;br /&gt;
|-&lt;br /&gt;
| F_DIROPEN  || $00:1108 || Open a directory and seek the first directory entry. NOTE: currently only works with the root directory.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || IN || Points to a file descriptor for the path to lookup. NOTE: currently unused.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the first FAT directory entry in that directory.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRNEXT  || $00:110C || seek to the next directory of an open directory&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || IN || Pointer to the current FAT directory entry.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the next FAT directory entry.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRREAD  || $00:1110 || Read the directory entry for the specified file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Direction !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || IN || The buffer containing the path to the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DIR_PTR || OUT || Pointer to the FAT directory entry for that file.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_DIRWRITE || $00:1114 || Write any changes in the current directory cluster back to the drive&lt;br /&gt;
|-&lt;br /&gt;
| F_LOAD     || $00:1118 || load a binary file into memory, supports multiple file formats&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to lookup.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || Pointer to the location to load the file (any value &amp;gt; $3F:FFFF to load the file where the file specifies).&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| F_SAVE     || $00:111C || Save memory to a binary file&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || Points to a file descriptor for the file to create.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || Address of the first byte to save.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || Address of the last byte to save.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| CMDBLOCK ||  $00:1120 || Send a command to a block device.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Contents&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_DEV || The target device&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
|-&lt;br /&gt;
| 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.  &lt;br /&gt;
|-&lt;br /&gt;
| F_MOUNT || $00:1128 || Mount the designated block device. BIOS_DEV is the device number to mount.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
is a limit of 8 file descriptors that can be allocated at any one time.&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
allocated previously through F_ALLOCFD.&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| TESTBREAK || $00:113C || [v0.4] Check if BREAK was pressed recently by the user (C is set if true, clear if false)&lt;br /&gt;
|-&lt;br /&gt;
| SETTABLE || $00:1140 || [v0.4] Set the keyboard scan code -&amp;gt; character translation tables (B:X points to the new tables). See [[C256 Keyboard]] for details.&lt;br /&gt;
|-&lt;br /&gt;
| 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).&lt;br /&gt;
|-&lt;br /&gt;
| 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&lt;br /&gt;
|-&lt;br /&gt;
| DELAY || $00:114C || [v0.4] Wait at least Y:X ticks of the system clock.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== DOS Calling Conventions ===&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
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&lt;br /&gt;
variables may contain non-zero status codes describing the nature of the failure.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Variable !! Address !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| DOS_FD_PTR || $00:0340 || 4 || A pointer to a file descriptor structure (defined below).&lt;br /&gt;
|-&lt;br /&gt;
| DOS_PATH_BUFF || $00:0400 || 256 || A buffer space for storing a path to a file or directory.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_DST_PTR || $00:0354 || 4 || A pointer to a block of memory to be filled from the disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_SRC_PTR || $00:0350 || 4 || A pointer to a block of memory to write to disk.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_END_PTR || $00:0358 || 4 || A pointer to the last byte of a block of memory.&lt;br /&gt;
|-&lt;br /&gt;
| DOS_STATUS || $00:032E || 1 || A status code for DOS operations. $00 = success&lt;br /&gt;
|-&lt;br /&gt;
| BIOS_STATUS || $00:0320 || 1 || A status code for sector level operations. $00 = success&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== File Descriptor ====&lt;br /&gt;
&lt;br /&gt;
Most DOS subroutines take a pointer to a file descriptor as an argument. This file descriptor contains several elements needed to manage a file,&lt;br /&gt;
including the buffer containing the current cluster of the file:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Name !! Offset !! Width (bytes) !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| STATUS || 0 || 1 || A special status byte containing information about the file's state&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Name !! Value !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_READ || $01 || The file is open for reading&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_WRITE || $02 || The file is open for writing&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_OPEN || $40 || The file is open.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_ERROR || $60 || There is an error with the file.&lt;br /&gt;
|-&lt;br /&gt;
| FD_STAT_EOF || $80 || The file is being read and has reach the end of the file.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| DEV || 1 || 1 || A byte containing the device number for the file (should not be modified by the user program).&lt;br /&gt;
|-&lt;br /&gt;
| PATH || 2 || 4 || A pointer to a null-terminated string containing the path to the file. Set by the user program.&lt;br /&gt;
|-&lt;br /&gt;
| CLUSTER || 6 || 4 || The ID of the current cluster being read or written. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| FIRST_CLUSTER || 10 || 4 || The ID of the first cluster of the file. Usually set by DOS.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| SIZE || 18 || 4 || The size of the file in bytes.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_DATE || 22 || 2 || The creation date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| CREATE_TIME || 24 || 2 || The creation time in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_DATE || 26 || 2 || The modification date in the same format as used by FAT.&lt;br /&gt;
|-&lt;br /&gt;
| MODIFIED_TIME || 28 || 2 || The modification time in the same format as used by FAT.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Interrupt Jump Table ==&lt;br /&gt;
&lt;br /&gt;
The kernel provides a jump table for interrupt handler support. When an interrupt is triggered of any particular type, the kernel interrupt handler will&lt;br /&gt;
jump to the vector for that interrupt. The vector should point to a subroutine that returns to the caller through an RTL instruction.&lt;br /&gt;
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.&lt;br /&gt;
Currently, the kernel only supports a few interrupts in this manner. All system interrupts will eventually have an entry in this table.&lt;br /&gt;
&lt;br /&gt;
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).&lt;br /&gt;
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&lt;br /&gt;
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&lt;br /&gt;
number of the interrupt is provided in A, with A[7..4] containing the block number, and A[3..0] containing the interrupt number.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Interrupt !! Block !! Number !!  Address !! Purpose&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT00_SOF || 0 || 0 || $00:1700 || Start Of Frame (vertical blank)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT01_SOL || 0 || 1 || $00:1704 || Start Of Line (horizontal blank)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT02_TMR0 || 0 || 2 || $00:1708 || Timer 0&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT03_TMR1 || 0 || 3 || $00:170C || Timer 1&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT04_TMR2 || 0 || 4 || $00:1710 || Timer 2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT05_RTC       || 0 || 5 || $00:1714 || Real Time Clock interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT06_FDC       || 0 || 6 || $00:1718 || Floppy Drive Controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT07_MOUSE     || 0 || 7 || $00:171C || Mouse interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT10_KBD       || 1 || 0 || $00:1720 || Keyboard interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT11_COL0      || 1 || 1 || $00:1724 || VICKY_II (INT2) Sprite Collisio &lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT12_COL1      || 1 || 2 || $00:1728 || VICKY_II (INT3) Bitmap Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT13_COM2      || 1 || 3 || $00:172C || Serial port #2 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT14_COM1      || 1 || 4 || $00:1730 || Serial port #1 interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT15_MIDI      || 1 || 5 || $00:1734 || MIDI controller interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT16_LPT       || 1 || 6 || $00:1738 || Parallel port interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDC       || 1 || 7 || $00:173C || SD Card Controller interrupt (CH376S???)&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT20_OPL       || 2 || 0 || $00:1740 || OPL3&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT21_GABE0     || 2 || 1 || $00:1744 || GABE (INT0) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT22_GABE1     || 2 || 2 || $00:1748 || GABE (INT1) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT23_VDMA      || 2 || 3 || $00:174C || VICKY_II (INT4) - VDMA Interrupt&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT24_COL2      || 2 || 4 || $00:1750 || VICKY_II (INT5) Tile Collision&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT25_GABE2     || 2 || 5 || $00:1754 || GABE (INT2) - TBD&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT26_EXT       || 2 || 6 || $00:1758 || External Expansion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT17_SDINS     || 2 || 7 || $00:175C || SDCARD Insertion&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT30_OPN2      || 3 || 0 || $00:1760 || OPN2&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT31_OPM       || 3 || 1 || $00:1764 || OPM&lt;br /&gt;
|-&lt;br /&gt;
| VEC_INT32_IDE       || 3 || 2 || $00:1768 || HDD IDE Interrupt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Console Special Characters ==&lt;br /&gt;
&lt;br /&gt;
The console routines support several special control codes for both input and output.&lt;br /&gt;
When the key on the keyboard is pressed, the associated code is returned by the GET routines.&lt;br /&gt;
If the code is printed through the PUTC or PUTS, the associated operation will be performed on the screen.&lt;br /&gt;
Note that this means that any graphics characters associated with those code points will not be displayed by PUTC or PUTS.&lt;br /&gt;
If those characters must be displayed, they would have to be written to the text memory directly.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Code !! Name !! Keyboard !! Description&lt;br /&gt;
|-&lt;br /&gt;
| $08 || BS || Backspace || Deletes the character to the left of the cursor, pulling characters in from the right.&lt;br /&gt;
|-&lt;br /&gt;
| $09 || TAB || TAB || Moves the cursor right to the next tabulated column (every eight columns).&lt;br /&gt;
|-&lt;br /&gt;
| $0A || LF || N/A || Puts the cursor at column 0 on the next line on the same column.&lt;br /&gt;
|-&lt;br /&gt;
| $0D || CR || RETURN || Creates a newline on the screen. Puts the cursor at column 0 on the next line.&lt;br /&gt;
|-&lt;br /&gt;
| $0F || INS || Insert || Inserts a blank space under the cursor (pushing characters to the right).&lt;br /&gt;
|-&lt;br /&gt;
| $11 || UP || Up Arrow || Moves the cursor up one row.&lt;br /&gt;
|-&lt;br /&gt;
| $1D || RIGHT || Right Arrow || Moves the cursor right one column. May wrap to the next line.&lt;br /&gt;
|-&lt;br /&gt;
| $7F || DEL || Delete || Deletes the character under the cursor, pulling characters in from the right.&lt;br /&gt;
|-&lt;br /&gt;
| $91 || DOWN || Down Arrow || Moves the cursor down one row. May scroll the screen.&lt;br /&gt;
|-&lt;br /&gt;
| $9D || LEFT || Left Arrow || Moves the cursor left one column.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Special Kernel Variables ==&lt;br /&gt;
&lt;br /&gt;
The kernel keeps track of several variables.&lt;br /&gt;
Most kernel variables should be left alone by applications, but there are some which an application might want to set or read.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Start Address !! End Address !! Name !! R/W || Description&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000C || $00:000E || SCREENBEGIN || RO || Address of the first character of the text display&lt;br /&gt;
|-&lt;br /&gt;
| $00:000F || $00:0010 || COLS_VISIBLE || RW || The number of columns currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0013 || $00:0014 || LINES_VISIBLE || RW || The number of rows currently displayed&lt;br /&gt;
|-&lt;br /&gt;
| $00:0017 || $00:0018 || CURSORPOS || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001A || $00:001B || CURSORX || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001C || $00:001D || CURSORY || RO || The address of the text character under the cursor&lt;br /&gt;
|-&lt;br /&gt;
| $00:001E || || CURCOLOR || RW || The foreground and background colors to be used when printing via PUTC and PUTS&lt;br /&gt;
|-&lt;br /&gt;
| $00:001F || $00:0020 || COLORPOS || RO || The address of the text color cell under the cursor&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>PJW</name></author>
		
	</entry>
</feed>