Part Five:
ROM Calls and Condition Bits

    A call does not necessarily call a routine that you made.  The TI-86 has a large ROM that includes many predefined routines; it is often advantageous to call these routines rather than writing the calls yourself.  ROM calls (any call for that matter) has both input and output.  You may, for instance, load a register with a certain value before the call (input) and have the call perform an action on that register, returning a value, manipulating variables or writing text to the screen (output).
    TI has released the equates for only some ROM calls, and other have been discovered by hacking the ROM.  Most of the known equates have been collected into include files (extension .inc), it is a good idea to look through the include files to see what calls you have to work with; if a needed ROM call equate is defined in a certain include file, then you must include that file by typing: <#include “filename.inc”>.  #include copies all the text from the included file into your asm program.  Both #includes and equates occupy no memory once compiled, so don’t hesitate to use them.  All current include files can be found on my web page: http://www.eden.rutgers.edu/~assets/ti86.htm

    One of the most common ROM calls is _puts, which takes the input of a string pointer in HL and gives the output of text to the LCD (Liquid Crystal Display, or the calculator’s screen) at the current cursor row and column.  _curRow is a RAM address permanently situated at $c00f; load this with any value between 0 and 7.  _curCol is similar; load it with a value between 0 and 20.  <ld a,5 / ld (_curRow),a / ld (_curCol),a / ld hl,string / call _puts> will put the text labeled by “string”: to row 5, column 5 of the LCD.  A special kind of string is needed by call _puts, however, because the calculator needs to know where the string ends.  There are two methods used by the calculator to find the string end; the two types of strings are: 1) zero-terminated, strings where the end is marked by zero (also called null-terminated) 2) length-byte, strings that are lead by either a byte or a word whose value is the string length.  _puts inputs a zero-terminated string.
    A second useful call is _clrLCD, which clears the screen, taking void input and giving the output of a cleared screen.  <call _homeup> loads the cursor locations with 0,0; <call _putc> puts a character addressed by HL to the LCD at cursor row / col; <call _runidicoff> will remove the run indicator from the upper left of the screen; <call _getkey> will pause until a key is pressed, also returning the keycode in A.

    A flag is a bit that indicates a certain system state depending on whether that bit is set or reset.  Set usually means that a certain kind of function is enabled.  TI-86 has a block of bytes from $c3e5 to $c409 used for system flags.  IY always points to $c3e5, meaning that you can access this block using IY offsets from (IY) to (IY+$24).  There are three main instructions you can use to manipulate the bits of system flags. Set will set the bit at the given bit number: set bit #,operandOperand must be a register or an memory location indirectly addressed by a register.  Reset has the same format: res bit #,operand.  <set 7,a> sets bit 7 of a.  <res 0,(iy+18)> is another way of turning off the run indicator; bit 0 of $c3e5+18 is the system flag that controls the run indicator.  Not many system flags are known to asm programmers, TI only released knowledge of a very few, and very, very few system flags have been discovered independently.  Look at ti86asm.inc for the flags TI released.

    It’s often useful to employ calls, returns and jumps only if a certain condition is met.  The F register is called the flag register because it contains the bits indicating Z80 system states.  Because a programmer can test these bits to look for a set condition, they’re also called condition bits.  Most instructions affect the condition bits in some way or another; the instructions you have seen so far, however, do not.  There are four condition bits that can be checked (more that can’t) by the control flow instructions: call, ret, jp and jr.  From this point forward, as an instruction is introduced, the affected condition bits will be explained as well.
    The zero flag is the most common flag, which can be tested with the condition codes Z and NZ.  If you have within your code <call z,is_zero>, then is_zero will be called iff the zero flag is set, otherwise it will execute the following instruction.  <ret nz> will return iff the zero flag is reset.  Z is set, in most cases, when the operand becomes zero.
    Condition codes C and NC indicate a carry, a set bit displaced to a position outside the operate byte or borrowed from an inoperate byte (a better definition will come with experience).  <jr c,has_carried> will make a relative jump  to has_carried iff the carry flag is set.
 The other two condition codes can only be used with call, ret and jp (not jr).  The sign flag is usually set if the operand is negative and reset if the operand is positive.  P tests for positivity and M tests for negativity of the sign flag.  <jp m,is_negative> will make an absolute jump to is_negative iff the sign flag is set.  PO and PE test for parity in most cases, but also has more varied uses.  Use PO to test if the parity is odd (reset) and PE to test if the parity is even (set).  This flag is called P/V (the parity / overflow flag).