APIGuide - jedimatt42/fcmd GitHub Wiki

Force Command API Guide

Force Command exposes many useful ROM routines to extension programs, so that they may act something like a BIOS. Programs using these routines can participate in the current 80 or 40 column screen setup, and cooperate with the force command system.

There are example programs and build systems in the repository jedimatt42/fcmd.

The GCC cross-complier toolchain targetting the tms9900 is a pre-requisite:

API Functions

There are more than 90 function in the ForceCommand ROM that can be called from executables. They provide information about the current system and environment, utilities for file access, string manipulation, Real Time Clock, TIPI Sockets, mouse, and messaging, and other conveniences.

A Complete list and description of each function is provided:

  • API function reference

Calling API Functions

The API uses the tms9900-gcc calling convention. In this convention, parameters are passed in the current workspace as R1 through R5, and return values are found in R1.

R10 is the common gcc stack pointer. It can be shared or your function can save and restore it before returning.

R11 is the return address back into Force Command.

The entry point and bank switching addresses are stored in a table in bank 0 of the cartridge ROM.

Starting at bank 0, address 0x6080.

The first entry is a trampoline function name FC_SYS. This is passed the table entry API_ID of the desired API call as R0. Then called with the parameters in subsequent registers. This function handles the cartridge rom bank switching requirement and indirection to get to the requested API function, calls it, and then restores back to bank 0 and returns to the calling program.

A wrapper macro has been created for tms9900-gcc, along with symbol names for each of the API function index values, so calling an API function is just like calling any other function in gcc. For instance, the following accesses the TPUTS function passing "Hello World" and a newline to print to the terminal:

  fc_tputs("Hello World\n");

From C the functions are all defined in the fc_api.h header file. There are additional header files with conveniences included:

  • fc_api.h - the main API header file with all the built-in functions and structures defined.
  • kscan.h - keyboard modes and mode 5 keycode constants for use with the fc_kscan routine.
  • ioports.h - macros, constants and inline functions for direct efficient writing to the VDP and it's memory.
  • vocab.h - constants for the speech synthesizer vocabulary.

In assembly, this would be

FC_SYS      EQU >6080
FC_TPUTS    EQU >0001

HELWOR      TEXT 'Hello World\n'
            BYTE 0
            EVEN

;... call the tputs function
            LI R0, FC_TPUTS    ; load target API function
            LI R1, HELWOR      ; param1 points to Hello World data
            LI R9, FC_SYS      ; load api trampoline
            BL *R9             ; call api trampoline

Assembly Note: all registers are used and consumed by the gcc calling convention. If your caller requires preserving specific register values, then you need to store them yourself. You can push them onto the gcc stack held in R10 such as:

           DECT R10            ; allocate one word on the stack
           MOV  R11, R10       ; store R11 to 'top' of stack
           ... 
           MOV  R10, R11       ; restore R11 from stack
           INCT R10            ; pop the stack

ANSI Terminal

Enhanced screen output capabilities exist by utilizing standard ANSI display sequences to manipulate color (if using supported F18A display hardware), display location, and special characters from IBM terminal graphics or formally codepage-437 character set.

Common ANSI commands include but are not limited to:

  • change color: 0x27 '[' '3' '0' ';' '1' '0' '6' 'm'
  • move cursor to top left corner: 0x27 '[' '1' ; '1' 'H'
  • clear screen: 0x27 '[' '2' 'J'

Functions fc_putc and fc_puts interpret the ANSI terminal emulation sequences.

Direct Display access

An additional header file is included ioports.h that provides definition and macros to ease direct interaction with the VDP. With the fc_display_info function, you can fetch the different VDP table addresses used for the current screen mode.