Version 0.2
October 2010
Mimas is an integrated development environment for writing Z80 assembly programs on the Texas Instruments TI-83 Plus, TI-84 Plus, and TI-Nspire graphing calculators. Using Mimas, you can write, compile, and run programs in assembly language, entirely on the calculator; no PC or other tools are required.
The latest version of Mimas can be found at ticalc.org. Mimas is free software; you are permitted (and encouraged) to distribute it to others, and/or modify it to suit your needs, under the terms of the GNU General Public License.
When you first start Mimas, the main menu is displayed. Select “1: New Program” to create a new program file, or “2: Open Program” to open an existing file.
The New Program dialog is used to create a new assembly program. The name of the program must be a legal variable name (i.e., it must begin with a letter), and must be unique. (If a file with that name already exists, the existing file is opened instead.) You can also select a program type (“Asm(”, “Ion”, “MirageOS”, “DoorsCS7”, or “Library / Other”.) Based on the program type you select, Mimas will insert an appropriate program header. (You can, of course, change this header later if you wish.) Press [ENTER] or [GRAPH] (“OK”) to create the program.
The Open Program dialog shows a list of existing assembly programs. As in normal OS menus, a star is displayed to indicate that a program is archived. Press [ENTER] or [GRAPH] to open the selected program.
After you create or open a program, the program section editor is displayed. Sections serve two purposes: they can be used to divide a large program into more manageable pieces, and they allow you to define the order that parts of the program will be assembled. (“Header” sections will be placed first, followed by “code” sections, then “data” sections, and finally “footer” sections. Separating code from data is important for large programs due to the calculator’s execution restrictions.) By default, a single code section will be created for you, called MAIN.
To create a new section, select “New Section” and press [ENTER]. You can also add a new section in the middle of the program, by moving the cursor to the place where you want to insert a section, and pressing [WINDOW] (“Ins”).
To delete a section, press [ZOOM] (“Del”). You cannot delete a section that has code in it; delete the code first.
Press [Y=] (“Edit”) to edit the selected section (see Editing Assembly Code.)
Press [GRAPH] (“Menu”) for more options:
1: Libraries | Edit the list of libraries used by this program (see Using Libraries.) |
2: Compile Program | Compile the program (see Compiling Programs.) |
3: Archive Program | Archive the program (see Archiving Programs.) |
4: Close Program | Close the program and return to the main menu. |
5: Quit | Quit Mimas and return to the calculator OS. |
The program code editor is similar to an ordinary text editor, with an important difference: the text must be valid assembly code (see Assembly Language Syntax.)
Within the code editor, lowercase alpha mode is enabled (press [ALPHA] twice to type lowercase letters.) In addition, a number of keys have special functions within the code editor:
[ALPHA] [.] (normally :) | Types either a colon (:) or a semicolon (;) depending on context. |
[ALPHA] [(–)] (normally ?) | Types an underscore (_). |
[ENTER] | Inserts a new line after this line. |
[2nd] [DEL] | Inserts a new line before this line. |
[CLEAR] | Deletes all text on this line after the cursor. If the cursor is already at the end of the line, deletes all text before the cursor. If the line is already empty, deletes it and moves to the next line. The deleted text is saved to the clipboard. |
[2nd] [STO ▸] | Inserts text from the clipboard (i.e., whatever was most recently deleted using [CLEAR].) |
[2nd] [ENTER] | Undoes changes to the current line, restoring its previous contents. |
[MATH] | Displays a menu containing the mathematical operators that can be used in expressions. |
[PRGM] | Displays a menu containing all of the supported Z80 instructions. |
[X,T,θ,n] | Displays a menu containing useful special characters. |
[Y=] (“Lbl”) | Displays the Lbl menu. |
[WINDOW] (“Sys”) | Displays the Sys menu. |
[ZOOM] (“Char”) | Displays a menu containing all of the characters in the calculator’s font (including all of the characters found in the [MATH] and [X,T,θ,n] menus, and then some.) |
[GRAPH] (“Done”) | Exits the code editor and returns to the program section editor. |
[2nd] [MATH] | Shortcut for the Test/Logic menu. |
[APPS] | Shortcut for the System Routines menu. |
[VARS] | Shortcut for the System Addresses menu. |
In addition, there are shortcut keys for the most commonly used Z80 instruction mnemonics. The following can be used only when the cursor is on an empty line (otherwise, the keys perform their usual functions):
[+] | ADD |
[×] | AND |
[APPS] | BCALL |
[TAN] | BIT |
[(] | CALL |
[(–)] | CP |
[x-1] | DEC |
[x2] | INC |
[,] | JQ |
[STO ▸] | LD |
[/] | OR |
[LOG] | POP |
[LN] | PUSH |
[COS] | RES |
[)] | RET |
[SIN] | SET |
[–] | SUB |
[^] | XOR |
The Lbl menu displays all of the labels that have been used or defined within the current program. As in the system CATALOG menu, pressing a letter key will jump to the appopriate location in the list.
To open the Lbl menu, press [Y=]. If you have already typed the first few characters of a label, the menu will show labels beginning with those characters.
Mimas includes a large collection of built-in constants that are useful in writing TI-83 Plus programs. The Sys menu displays these constants, and is divided into four sub-menus:
BCALL
and
BJUMP
instructions and cannot be
used in ordinary expressions (e.g., PutS
is just a
normal symbol in all other contexts.) (If you really
want to refer to the B_CALL table address, write
_PutS
instead.)
OP1
,
curRow
, and saveSScreen
.) Many of these
RAM areas are used for inputs and outputs to various system
routines; a few are more or less free for assembly programs to
store variables in.
CALL
and RST
instructions: rMOV9TOOP1
,
rOP1TOOP2
, rPUSHREALO1
,
rFINDSYM
, rFPADD
,
LCD_BUSY_QUICK
, APP_PUSH_ERRORH
, and
APP_POP_ERRORH
.
GetCSC
and GetKey
routines), variable data types (used in
the calculator Symbol Table and by the FindSym
and
ChkFindSym
routines), and system flag offsets.
SET
,
RES
, and BIT
instructions, you can omit
the IY offset: SET textInverse
will be automatically
expanded to SET textInverse, (IY + textFlags)
.
(For more information about TI-83 Plus system routines, RAM areas, constants, and flags, see the official documentation from the TI-83 Plus SDK, as well as the third-party documentation provided by WikiTI.)
To open the Sys menu, press [WINDOW]. As with the Lbl menu, if you have already typed the first few characters of a built-in symbol, the menu will show possible completions (within the category you select.)
When creating a large program, you may find it helpful to break it up into several smaller source files. (If you are creating a very large program, breaking it up may be necessary, since the entire source code won’t fit in RAM all at once.) You may also find it useful to place commonly-used subroutines in separate files, so that they can be used by multiple programs.
Each program source file contains a list of other source files that it uses as libraries. When you compile your program, all of its libraries, and all of its libraries’ libraries, and so forth, will also be compiled into the output file. (If a particular file is listed more than once, only one copy of it will be included in the final program.)
To edit the list of libraries, go to the program section editor, press [GRAPH] (“Menu”), and select “1: Libraries”. Initially the list will be empty. Press [Y=] (“Add”) to add a file to the list; press [WINDOW] (“Del”) to remove the selected file from the list.
Mimas program files may be stored either in RAM or archive (Flash) memory, but they must be stored in RAM while you are editing them. (If you try to modify a program that is archived, Mimas will try to unarchive it; if you don’t have enough free RAM, an error message will be displayed and you will not be able to change the program.) It is generally a good idea to keep your programs archived whenever possible, to protect them from being lost or corrupted when the calculator crashes.
Also keep in mind that compiling a program requires a fair amount of free RAM; if you are editing a large program, you may need to archive it before compiling.
To archive a program, go to the program section editor, press [GRAPH] (“Menu”), and select “3: Archive Program”.
To compile your program into executable Z80 machine code, go to the program section editor, press [GRAPH] (“Menu”), and select “2: Compile Program”.
By default, the name of the output file is the same as the main source file; you can change this if you want.
By default, Mimas will report an error if code is stored above address BFFFh. (Although shells such as Ion and MirageOS allow you to run programs larger than that, the calculator will crash if you try to execute any code stored in the upper 16k of RAM.) You can set “Allow PC > BFFF” to “Yes” to disable this behavior, if you really know what you’re doing.
Any of the following errors may occur while compiling. When an error occurs, Mimas will, whenever possible, jump directly to the location of the error.
LD
and arithmetic
instructions must be in the range –128 to 255. Values used
as offsets to IX and IY must be in the range –128 to 127.
Addresses used as the destination of a JR
instruction
must be between –126 and 129 bytes away from the current PC
(you can, if you prefer, use JQ
instead, which will switch to using a JP
instruction
if the destination is too far away.)
ASSERT
condition is not true.
ramCode
before executing them. (In this
case, use RORG
to adjust code
labels appropriately, and to notify the assembler that the code is
meant to be copied elsewhere rather than being executed in place.)
EQU
and/or IF
directives. To avoid this, use backward
references whenever possible (e.g., if label2
is
defined in terms of label1
, place the definition
of label1
first.)
IF
(or IFDEF
or IFNDEF
) directive does not have a
corresponding ENDIF
.
EQU
directive is attempting to assign a
value to a symbol that is already defined. (Global symbols may
only be defined once in the entire program, including libraries;
local symbols may only be defined once in each file.)
IF
(or IFDEF
or IFNDEF
) directives is nested too deeply (the limit
is currently 255.)
ELSE
or ENDIF
directive does not have
a corresponding IF
.
Due to the small screen size, the syntax of Mimas is somewhat restricted compared to that of other assemblers: each line may contain either a label, a comment, an instruction, or a directive, but not more than one at once.
All instructions, directives, register names, and operators are
case-insensitive (e.g., ld a,42
is the same as LD
A,42
.) Case is significant only in comments and user-defined
symbols.
All argument expressions are evaluated as 16-bit integer values. (This may, unfortunately, cause some confusion if you are trying to port code that has been written on a PC; for instance, 8000h is considered a negative number, equivalent to –32768.)
Expressions may contain any of the following:
123
)
is a decimal constant. Adding a %
before the
number, or a b
after it, marks the number as binary
(base 2): %01111011
or 01111011b
is
the same as 123 decimal. Likewise, an @
prefix, or
an o
suffix, marks the number as octal (base 8),
and a $
prefix, or an h
suffix, marks
the number as hexadecimal (base 16). (Note that if you use the
h
notation, the number must begin with a digit
0–9; A0h
would be interpreted as a symbol, so
you must write 0A0h
instead.)
'A'
, "A"
) represents the (TI-variant)
ASCII value of the character.
EQU
directive. Note that normal
(user-defined) symbols are case-sensitive: my_loop
is
not the same as MY_LOOP
.
appbackupscreen
is the same
as APPBACKUPSCREEN
.)
θB
(theta-B) refers to the
address of the previous anonymous label.
The symbol θF
(theta-F) refers to the next
anonymous label.
PC
or $
refers to the
current value of the program counter (as defined by the
ORG
or
RORG
directive.)
LPC
or $$
refers to
the current address within the program (as defined by the
ORG
directive, and ignoring the
effect of RORG
, if any.)
lsb(x) |
Least significant byte of x; i.e., (x & $FF) |
msb(x) |
Most significant byte of x; i.e., (x >> 8) |
–x (minus) |
Negative x |
~x |
Bitwise complement of x; i.e., (x ^ $FFFF) |
!x |
Logical negation of x; i.e., 1 if x = 0, or
0 otherwise, as with the TI-BASIC not(
function |
x × y |
Multiplication | (highest precedence) |
---|---|---|
x / y |
Signed division (rounds down) | |
x % y |
Signed remainder | |
x + y |
Addition | |
x – y |
Subtraction | |
x << y |
Logical left shift | |
x >> y |
Logical right shift | |
x < y |
x is less than y (signed) | |
x > y |
x is greater than y | |
x ≤ y |
x is less than or equal to y | |
x ≥ y |
x is greater than or equal to y | |
x = y |
x equals y | |
x ≠ y |
x does not equal y | |
x & y |
Bitwise AND of x and y | |
x ^ y |
Bitwise XOR of x and y | |
x | y |
Bitwise OR of x and y | (lowest precedence) |
(
, )
) or square
brackets ([
, ]
) can be used to group
sub-expressions; the two are equivalent. Note that parentheses or
brackets around an entire expression indicate indirection
(LD A,123
stores the value 123 in register A,
while LD A,(123)
reads a value from memory address
123.)
A label defines a name for a particular location in the program. A label consists of a valid symbol followed by a colon (:). (Unlike many other assemblers, the colon is not optional.) The symbol must begin with a letter (A–Z, a–z, and θ), an underscore (_), or a period (.), followed by a string of letters, digits, and/or underscores.
A label that begins with a period (.) is considered “local” to the source file where it is defined (i.e., other source files cannot refer to that label, but may contain their own labels with the same name.) Local labels can be useful in large programs and libraries, since they let you use short, descriptive names without worrying about conflicts between files. Local labels can also make compilation slightly faster.
A label consisting of the single letter θ (theta) is an
“anonymous” label. (These are similar to
$$
labels in ZMASM, or {@}
labels in
Brass.) Any number of anonymous labels can be defined within the
program. The symbol θB
can then be used in any
expression to refer to the last anonymous label before that
expression; the symbol θF
refers to the next
anonymous label after that expression.
Labels are stored in a slightly compressed form; using lowercase letters in your labels will result in a smaller source file.
All labels are limited to a maximum length of 32 characters.
A line beginning with a semicolon (;) is considered a comment. Comments are ignored by the assembler; they’re just there for the programmer’s benefit.
Comments, like labels, are compressed, and as a result, not all characters can be used in a comment. Letters, numbers, and most ASCII punctuation characters are allowed; other characters will be replaced with ‘#’.
Mimas supports all of the Z80 instructions, both documented and undocumented. For details of the documented instructions, see the official Z80 documentation.
For convenience, when setting, resetting, or testing a system flag,
you can simply type the name of the flag (or select it from
the System Flags menu), omitting the IY
offset. For instance, SET textInverse
will be
automatically replaced with SET textInverse, (IY +
textFlags)
.
The undocumented instructions are described below. Note, however, that undocumented instructions will not work on the TI-Nspire, so you should avoid using them in programs that are intended to be portable.
ADD
, SUB
, ADC
,
SBC
, AND
, OR
,
XOR
, CP
, INC
,
DEC
), can have constant values loaded into them, and
can be loaded to and from the A, B, C, D, and E registers.
SLIA
is similar to the documented SLA
,
except that the low bit of the result is set to 1 instead of 0.
(SLIA arg
has the same effect as
SCF
followed by RL arg
.)
SLIA
can be used with any of the same arguments that
can be used with SLA
.
SLA
, SRA
,
SLIA
, SRL
, RL
,
RLC
, RR
, and RRC
can be used
with two arguments, where the first is one of the registers B, C, D,
E, H, L, and A, and the second is an indexed address (either
(IX+n) or (IY+n).) The instructions
SET
and RES
can be used with three
arguments, where the first is a bit number, the second is a
register, and the third is an indexed address. This means that a
value is read from that indexed address, the appropriate operation
is performed on that value, and the result is both written back to
memory and also copied into the given register. For
instance, SLA H,(IX+2)
has the same effect
as LD H,(IX+2) / SLA H / LD (IX+2),H
. SET
3,H,(IX+2)
has the same effect as LD H,(IX+2) / SET
3,H / LD (IX+2),H
.
IN (C)
reads a byte from I/O port C, without storing
it anywhere, but sets or clears the sign, zero, and parity flags
according to the input value, just as the documented IN
r,(C)
instructions do. (IN (C)
has
essentially the same effect as PUSH BC / IN B,(C) / POP
BC
.)
OUT (C),0
writes a zero byte to I/O port C.
(OUT (C),0
has essentially the same effect
as PUSH BC / LD B,0 / OUT (C),B / POP BC
.)
Mimas also supports the following special instructions. These, of course, are really just Z80 instructions with a more convenient syntax.
BCALL addr
BCALL GrBufCpy
) or an expression giving
an exact address (BCALL 486Ah
).
BJUMP addr
JQ addr
JQ C, addr
JQ NC, addr
JQ Z, addr
JQ NZ, addr
JP
or a JR
instruction, depending on
how far away the given address is.
Assembly directives are commands to the assembler, which will be performed at the time the program is compiled (as opposed to instructions, which become part of the compiled program.) Mimas supports the following assembly directives:
ALIGN expr
ALIGN 8
would move the program counter
forward to the next address equal to zero mod 8.
ASSERT expr
ASSERT (abc ≤
def)
would display an error message if abc
were greater than def
.
DB expr,expr,...
DB "string"
DB "string",0
DB
statement. A single
zero, however, may be added to the end of the string, as a
terminator.
DS expr
DW expr,expr,...
name EQU expr
name = expr
EQU
) it is fixed; it cannot be
redefined later in the program.
IF expr
...
ELSE
...
ENDIF
IFDEF name
...
ELSE
...
ENDIF
IFNDEF name
...
ELSE
...
ENDIF
IF
evaluates
the given expression; lines following the IF
, up to
the next ELSE
or ENDIF
, are assembled
only if that expression’s value is not zero.
IFDEF
or IFNDEF
must be
a symbol. Lines following IFDEF
are assembled only
if that symbol has been defined prior to the IFDEF
.
Lines following IFNDEF
are assembled only if that
symbol has not yet been defined.
ELSE
statement is optional; lines following the
ELSE
, if any, are assembled if
the IF
/IFDEF
/IFNDEF
condition is not satisfied.
INCBIN "ABCD"
INCBIN "prgmABCD"
INCBIN "Pic0"
INCBIN
will
include that header as well.)
ORG expr
PC
and LPC
. Note that this is the
behavior of ORG
in most assemblers, but not SPASM.
SPASM’s .ORG
behaves as
RORG
, described below.)
ORG
directive
giving the address where the program will be loaded
(normally userMem – 2
.)
RORG expr
RORG
will be
stored in the output file as usual, but will be assembled as if
they were located at the given address. Labels following
RORG
will also be adjusted accordingly. (Sets
PC
without affecting
LPC
.)
appBackUpScreen
area before running it, you could
use RORG appBackUpScreen
at the beginning of the
routine. (This won’t actually copy your code into
appBackUpScreen
, of course; you have to do that
yourself.) At the end of the routine, use
RORG LPC
to return to normal.
.ORG
directive behaves
in SPASM, although SPASM does not have an equivalent
to LPC
.)
Copyright © 2010 Benjamin Moody
Permission is granted to copy and distribute this manual, with or without modification, under any terms, provided that the above copyright notice and this permission notice are included in all copies.