Well, this file concludes the majority of the tutorial on Devpac
version 2. for more information, see the accompanying quick
reference files also on this Sewer Doc Disk Number 8, the Devpac
Disk. As usual, this file was typed by the Animal House and
edited by Sewer Rat
CHAPTER 5
LINKER
Introduction
A linker's job is to accept one or more input files generated
with GenST or a high-level language compiler and create a single
executable file from it. One of the most powerful features is
library searching, which means that the linker will only use the
parts of a library of modules that are required by other sections
of the program, resulting in much smaller output files.
There are unfortunately tow different linker file formats on the
Atari ST, known as DRI- and GST-formats. While GenST can
generate both formats, only the GST-format is supported in the
LinkST linker. To link DRI code you need either the Atari ALN
program or the Digital Research LINK68 and RELMOD programs.
Note: LinkST will only link GST format files.
Invoking the Linker
The simplest way to run the linker from the Desktop is to
double-click on the LINKST.TTP icon, and enter a suitable command
line. There is another way to invoke the linker, using a control
file which contains the required options.
The command line contains the necessary information for the
linker to read all the relevant files, and generate an output
file.
Command Line
The command line should be of the form:
<filename> <-options> [filename] [options]
Options are denoted by a - sign then an alphabetic character,
allowed options being:
B generate a true BSS section for any such named sections
D debug - include all symbols in the binary file using DR
standard 8 character format (for MonST or other debuggers)
F force pass 2 of the linker, useful if you want to see all
errors (as any pass 1 errors will by default stop the link
before the second pass)
L specify that all following filenames are library filenames
M dump a map file showing the order of the sections and labels,
will be the main filename with an extension of .MAP
O specify object code filename, may be followed by white space
before filename
Q 'quiet' mode, which disables the pause after the link
S dump a symbol table listing, will be the main filename with an
extension of .SYM
X extended debug, using the HiSoft Extended Debug format
W specify control file filename, defaults to .LINK extension
Normally any filenames given are taken to be input files,
defaulting to the extension of .BIN, though if a .LNK extension
is specified it will be taken to be a control file, or after a -L
option filenames are all assumed to be libraries.
The output filename can be specified with the -o option on the
command line, or using the OUTPUT directive in the control file.
If there is more than one of these, the last one is used. If
there is none, then the first input filename specified in the
command line or control file is used with an extension of .PRG.
Example Command Lines
PART1 PART2 -d
Reads PART1.BIN and PART2.BIN as input files, and generates
PART1.PRG as an output file complete with debugging information.
PART1 PART2 -o TEST.PRG
Reads PART1.BIN and PART2.BIN as input files, and generates
TEST.PRG as an output file.
-o TEST.TOS START -1 MYLIB -s
Reads START.BIN as an input file, selectively reads MYLIB.BIN as
a library, and generates the output file TEST.TOS and the symbol
listing file TEST.SYM.
LiokST Running
LinkST has tow passes - during pass 1 it builds up a symbol table
of all sections and modules, and during pass 2 it actually
creates the output file. When it starts a logon message, then
reports on which files it is reading or scanning during both
passes. This gives you some idea of what takes time to do, as
well as exactly where errors have occurred.
If there is enough free memory at the end of pass 1 LinkST will
use a cache to store the output file, which greatly speeds up the
process. If it uses the cache it will write to the disk at the
end of pass 2, and report the number of errors.
When the link finishes you will be prompted to press a key before
quitting. This is to give you an opportunity to read any warning
or error messages before returning to the Desktop. You can
disable this pause by using the -q option, useful if you are
using a CLI or batch file program.
LinkST was especially optimised for speed, though the speed of
the ST floppies is still a restricting factor. If you can't
afford a hard disk we recommend the use of a RAM disk which can
make great improvements, but leave enough memory free for the
linker to cache your output file. If you are limited in what you
can fit on your RAM disk we recommend you put many small library
or input files on there.
Error and warning messages are directed to the screen - if you
want to pause output you can press Ctrl-S, and Ctrl-Q will resume
it. Pressing Ctrl-C will abort the linker immediately. You can
re-direct screen output to a disk file by starting the command
line with
>FILENMAE.TXT
or you can re-direct it to a printer by starting the command line
with
>PRN: (parallel port) or >AUX: (serial port)
Control Files
The alternate way to run the linker is to have a control file for
the programs which you are linking together.
If you require a lot of options which won't fit on the command
line or you get bored of typing them you can use a control file,
which is a text file containing commands and filenames for the
linker. The default extension is .LNK, and the text file can be
generated with GenST (though don't try and assemble it!). The
control filename is specified on the command line with the -w
(for With) option, and each line can be one of the following:
INPUT <filename>
This specifies a filename to be read as an input file. The
default extension is .BIN if none is given.
OUTPUT <filename>
This specifies the filename to be used for the output file. There
is no default extension - you should specify it explicitly.
LIBRARY <filename>
This specifies a filename to be scanned as a library. The default
extension is .BIN if none is given.
SECTION <sectionname>
This allows specific section ordering to be forced.
DEBUG
All symbol names included in the link are put in the output file
so that debugging programs such as MonST can use them when the
program is running.
XDEBUG
Similar to debug option us uses HiSoft Extended Debug format for
up to 22 character significance.
DATA size(K)
The BSS segment size is set accordingly. The size can be given
either as a number of bytes of as a number of K-bytes (units of
1024). This option is particularly useful for compilers like
Prospero Pascal which store their variables in the BSS segment.
Blank lines in the control file are ignored, and comments can be
included by making the first character in the line a (small zero
in superscript), a semicolon or an exclamation mark.
BSS <sectionname>
Specifies that the named sections should lie in the GEMDOS BSS
section area. This can save valuable disk space, but will
generate errors if the section contains any non-zero data. This
should not be used at the same time as the DATA statement.
With the INPUT or OUTPUT directive if the filename is specified
as (small zero in superscript) it is substituted for the first
filename on the command line. This can be useful for having
a generic control file for linking C programs, for example.
An example control file is:
(small zer in superscript) control file for linking C program
INPUT STARTUP
INPUT (small zero in superscript)
XDEBUG
LIBRARY BLIB
Assuming this control file is called CPROG.LNK, the LinkST
command line
TEST -w CPROG
will read as input files STARTUP.BIN and TEST.BIN, and scan the
library CLIB.BIN. The object code, including extended debug
information, will be written to TEST.PRG, as none was explicitly
specified.
If you do not specify a drive name in the control file or on the
command line, the default drive will be assumed. If you run
LinkST from the Desktop, the default drive will always be the
same as the file on which you double-clicked; though if you run
it from a CLI or from the GenST editor this will not necessarily
be so.
Automatic Double-Clicking
It is possible to install LinkST so that you can double-click on
a .LNK file from the Desktop to invoke the linker, by using the
Install Application option from the Desktop. This is a similar
process to that described for GenST, except the type should be
left as TOS Take Parameters and the extension should be .LNK.
LinkST Warnings
Warnings are messages indicating that something might be wrong,
but it's nothing too serious.
duplicate definition of value for symbol "x"
The symbol was defined twice. This can happen if you replace a
subroutine in a module with one of your own, for example. The
linker will use the first definition it comes across, and give
this warning on the second.
module name is too long
Module names can only be 80 characters long.
comment is too long
Comment directives are only allowed to 80 characters long (don't
ask us why, we don't know!)
absolute sections overlap
Two absolute sections clash with each other.
SECTION "x" is neither COMMON nor SECTION
A section name was specified without defining its type.
LinkST Errors
LinkST errors divide into four areas; general errors, I/O errors,
binary file errors, and linker bugs. In some error messages a
string is included, denoted by "x" below. In others a number may
be output, denoted by 99 below.
General Errors
unresolved symbol "x" in file "x"
The symbol was referred to but not defined in the file. There may
also be other files which refer to the symbol, but this gives you
a start in your search!
XREF value truncated
A value was too large to fit into the space allocated for it, for
example a BSR to an external may be out of range.
bad control line "x"
An illegal line was found in a control file.
non-zero data in BSS section
A section wanted as a true BSS section contained non-zero data.
file "x" not found
Can't open output file "x"
Can't open map file "x"
Can't open symbol file "x"
Can't open input file "x"
i/o error on input file
disk write failed
filename "x" was too long
Binary File Errors
These are errors in the internal syntax of the input file, and
should not occur. If they do it probably means the compiler or
assembler produced incorrect code.
missing SOURCE directive
Can occur if a file is not in GST format, for example a DRI file.
runtime relocation is only available for LONGs
attempt to redefine id of symbol "x"
attempt to DEFINE "x" with <id> of zero
bad operator code 0x99 in XREF directive
bad truncation rule in XREF
wrongly placed SOURCE directive
bad directive 99
<id> 99 not DEFINEd as a SECTION but used as one
attempted re-use of <id> 99 as SECTION id
attempted re-use of "x" as SECTION name
Section is COMMON but being used as though it's not
SECTION is being misused as COMMON
unexpected end of input file
'Linker Bug' Messages
These can be produced as a result of internal checks by the
linker. If you get one please send us copies of the files you are
trying to link!
APPENDIX A
GEMDOS error codes
This appendix details the numeric GEMDOS errors and their
meanings. The error numbers shown are those displayed by MonST
and GenST; when calling GEMDOS from your own programs these
values will be negative.
0 OK (no error) 32 Invalid function number
1 Fundamental error 33 File not found
2 Drive not ready 34 Path not found
3 Unknown command 35 Too many files open
4 CRC error 36 Access denied
5 Bad request 37 Invalid Handle
6 Seek error 39 Insufficient memory
7 Unknown medium 40 Invalid memory block address
8 sector not found 46 Invalid drive
9 No paper 49 No more files
10 Write fault 50 Disk full (not a GEMDOS error;
11 Read fault produced by GenST)
12 General error 64 Range error
13 Write protect 65 Internal error
14 Medium change 66 Invalid program load format
15 Unknown device 67 Setblock failure due to growth
16 Bad sectors on format restrictions
17 Insert other disk
APPENDIX B
GenST error messages
GenST can produce a large number of error messages, most of which
are pretty self explanatory. This appendix lists them all in
alphabetic order, with clarifications for those which require
them.
Please note that GenST is continually being improved and list may
not agree exactly with the version you have, there may be
additional messages not documented here.
Errors
If you get a message beginning with INTERNAL please tell us - you
should never see these.
.W or .L expected as index size
absolute expression MUST evaluate
absolute not allowed
additional symbol on pass 2
somehow a symbol has appeared during pass 2 that did
not appear during pass 1
address register expected
addressing mode not allowed
addressing mode not recognised
BSS or OFFSET cannot contain data
OFFSET sections and non-GST BSS sections can only
contain DS directives
cannot create a binary file
could be a bad filename, or a write-protected disk,
etc.
cannot export symbol
cannot import symbol
cannot reset MACRO definitions or define in REPTs
macro definitions may not be nested or defined within
repeat loops
cannot nest repeat loops
comma expected
data register expected
data too large
division by zero
duplicate MODULE name
module names must be unique
error during listing output
listing will be stopped at this point
error during writing binary file
normally disk full
executable code only
only executable code may be assembled to memory
expression mismatch
normally a syntax error within an expression
fatally bad conditional
there were more ENDCs in a macro than IFs
file not found
forward reference
garbage following instruction
illegal BSR.S
a BSR.S to the following instruction is not allowed -
change it to BSR
illegal type combination
immediate data expected
imported label not allowed
include file read error
instruction not recognised
invalid FORMAT parameter
invalid IF expression, ignored
invalid MOVEF addressing mode
invalid number
invalid numeric expression
the symbol is not defined or relative or a syntax
error
invalid option
invalid printer parameter
invalid register list
invalid section name, TEXT assumed
invalid size
line malformed
linked format restriction
the DRI format is destructive about where it allows
imports
local not allowed
missing close bracket
missing ENDC
there were more IFs than ENDCs
missing quote
misuse of label
not yet implemented
number too large
odd address
option must be at start
ORG not allowed
out of memory
phasing error
should never happen, look investigate immediately
before first such error
program buffer full
change the program buffer size when assembling to
memory
register expected
relative not allowed
relocation not allowed
repeated include file
each include file may only be included once on each pass
source expired prematurely
with an IF, MACRO or REPT and the source ran out
spurious ENDC
spurious ENDM or MEXIT
spurious ENDR
symbol defined twice
symbol expected
undefined symbol
user error
caused by FAIL directive
wrong processor
XREFs not allowed within brackets
Warnings
68010 instruction, converted to MOVE SR
MOVE CCR, is not a 68000 instruction
branch made short
by optimising
directive ignored
invalid LINK displacement
if negative or odd
offset removed
xx(An) form reduce to (An) by optimising
relative cannot be relocated
short branch converted to NOP
sign extended operand
data in MOVEQ needed sign extension to fit
size should be .W
APPENDIX C
ST Memory Map
This Appendix details certain information about the ST memory
map:
1. Processor Dump area
2. Base Page layout
3. Hardware memory map
Processor Dump Area
When the ST crashes with an exception (i.e. mushrooms or bombs)
it stores a copy of the processor's state in an area of memory
which is not destroyed by a RESET. Thus after such a crash you
can load MonST and investigate the relevant area of memory to try
to ascertain what exactly went wrong. If this happens a lot you
should use the auto-resident version of MonST so you will have a
much better idea of the cause of the problem.
$380 long contains $12345678 if valid
$384 8 longs saved values of D0-D7
$3A4 8 longs saved values of A0-A7
$3C4 byte exception number
$3C8 long saved USP
$3CC 16 words copied from the SSP
Base Page Layout
Every program that runs under GEMDOS has a base page area which
contains certain information. It is $100 bytes long.
Offset Name Contents
$00 p_lowtpa base address of the TPA (i.e. here)
$04 p_hitpa pointer to end of TPA+1
$08 p_tbase pointer to start of TEXT area
$0C p_tien length of TEXT area
$10 p_dbase pointer to start of DATA area
$14 p_dlen length of DATA area
$18 p_bbase pointer to start of BSS area
$1C p_blen length of BSS area
$20 p_data pointer to DTA address
$24 p_parent pointer to parents's base page (0 if
desk acc.)
$28 (reserved)
$2C p_env pointer to environment string
$80 p_cmdlin command line: length byte then string,
which is not guaranteed to be null-
terminated
$100 your program starts here
Hardware Memory Map
Address Usage MonST Access
Read Write
FFFFFF ÿ ÿ
Hardware Registers
FF8000
FFEFFF ÿ
System ROM |
FC0000 |
Expansion ROM |
FA0000 -
1040ST 100000 _ _
520ST 080000 | |
RAM | |
020000 | |
Protected RAM | |
000000 | ÿ
ÿ ÿ
Not to scale
APPENDIX D
Calling the Operating System
The operating system of the ST is large and complex and consists
of various levels. To help in your own program development, this
appendix describes the calling mechanisms and routines available,
but it is not intended to be definitive. It also details the
various example programs and include files supplied with
DevpacST. The various levels of the operating system are:
GEM AES window and event manager
GEM VDI device-independent graphics routine
GEMDOS disk and screen I/O, similar to MS-DOS
BIOS low level I/O
XBIOS extended low level I/O
Each of these will now be described in varying degrees of detail.
GEMDOS - Disk and Screen I/O
GEMDOS was converted from CP/M 68k and is similar in many ways to
generic CP/M but with extra facilities (e.g. sub-directories)
taken from MS-DOS. It is responsible for disk I/O and character
I/O via the screen, keyboard, serial and parallel ports. It is
also responsible for memory management.
GEMDOS was designed to be called directly from C, so all
parameters are put onto the stack and have to be removed
afterwards. The calling sequence from assembler is of this
general form:
move ??,-(a7) put parameters on stack
move.w #??,-(a7) the function number
trap #1 call GEMDOS\
add.l #??,a7 restore the stack
After the call the stack has to be corrected; while an ADD.L can
be used as above, it is slow and takes six bytes. If the stack
needs correction by 8 bytes or less, the best way is to use
add.l #??,a7
which takes two bytes. If it has to be corrected by more than 8
bytes, the best way is
lea ??(a7),a7
which takes four bytes. Both methods are smaller and faster than
the first method. Incidentally, a major source of bugs when
starting programming with GEMDOS is forgetting to correct the
stack, or correcting it by the wrong value.
Program Startup and Termination
When a GEMDOS program starts up it owns all free memory - that is
the memory from the end of the program through to the end of
usable RAM (normally just before the screen) is owned by the
program, which is just as well as the stack is at the very end of
the area.
If any memory management calls (such as m_alloc) are required,
you wish to execute other programs within yours, or if you are
writing a GEM program, it is important to give back some of this
memory. If you don't there will be no free memory for these uses.
this is normally done during at the beginning of programs using
the m_shrink call, utilising the fact that a pointer to the
programs basepage is 4 bytes down on the stack, like this:
move.l 4(a7),a3 basepage
move.l $C(a3),d0 text length
add.l $14(a3),d0 data length
add.l $1C(a3),d0 BSS length
add.l #extra,d0 any additional memory
add.l #$100,d0 basepage length
move.l #mystack,a7 before shrinking
move.l d0,-(a7)
move.l a3,-(a7)
clr.w -(a7)
move.w _(a7)
trap #1 do the shrink
lea 12(sp),sp
The extra bytes may be required for your programs storage. Note
that you should move the stack to a safe before the shrink,
otherwise the stack will be in memory that is not owned by your
program and liable to corruption.
A GEMDOS program can terminate in one of three ways: p_term0,
which is not recommended, p_term, the normal way to finish a
program, and p_termres, for system patches and the like. For
normal termination use this code:
clr.w -(a7) no return code
move.w #S4c,-(a7) p_term
trap #1
When a program terminates all memory it owns is freed and any
open files are closed.
GEMDOS Summary
The calls will now be described in numeric order by giving the
size of the parameters, in the order they should be placed on the
stack, and the stack correction number. For example, using
function call 2, c_conout, to print the character x, the code
would be
move.w #'X',-(a7) the character
move.w #2,-(a7) the function number
trap #1 call it
addq.l #4,sp then correct
At present GEMDOS calls corrupt registers d0 and a0 only, but
this is not documented. We therefore recommended programmers to
assume that registers d0-d2/a0-a2 are corrupted, in a similar way
to the other operating system calls.
0 - Terminate Process (old form), p_term0
Parameters: None
Result: None
Stack: 2
This terminates the current program, with a return code of 0. It
is recommended that p_term (function $4c) should be used in
preference to this call. As control never returns after the call,
no stack correction is actually required.
1 - Read character from keyboard, c_conin
Parameters: None
Result: D0.L=key code
Stack: 2
This waits for a key to be struck, echoes it to the screen, and
returns its value. The long result has the ASCII value in the
lowest 8 bits, and a physical key number is returned in bits 16-
23. All other bits are set to 0.
2 - Write character to screen, c_conout
Parameters: word: character
Result: None
Stack: 4
This writes the given character to the screen. A 16-bit parameter
is supported for future expansion, so bytes should always be
ANDed with $FF before the call, though currently the upper 8 bits
are ignored.
3 - Read Character from serial port, c_auxin
Parameters: None
Result: D0.B=character read
Stack: 2
This waits for a byte to be received from the auxiliary device,
which is the serial port.
4 - Write characters to serial port, c_auxout
Parameters: word: character
Result: None
Stack: 4
This sends the character out via the serial port. As with
function 2, the upper 8 bits of the word should be 0 for upward
compatibility.
5 - Write character to printer, c_prnout
Parameters: word: character
Result: D0.W=0 if failed, -1 if OK
Stack: 4
This sends the character out via the parallel printer port. As
with functions 2 and 4 above, bits 8-15 of the word should be 0.
6 - Raw I/O to standard I/O, c_rawio
Parameters: word: character for output, or $00FF to read
Result: D0.W if $00FF passed
Stack: 4
If the character is passed as $00FF then the keyboard is scanned
and a result returned in D0.W (or 0 if no key available). If the
character is not $00FF, then it is printed on the screen.
7 - Raw input from keyboard, c_rawcin
Parameters: None
Result: D0.L=character read
Stack: 2
This waits for a key to be pressed and returns its value. It does
not echo it to the screen.
8 - Read character from keyboard, no echo, c_necin
Parameters: None
Result: D0.L=character read
Stack: 2
This waits for a key to be pressed and returns its value. It does
not echo, but the control keys Ctrl-C, Ctrl-S and Ctrl-Q are
interpreted in their usual way - Ctrl-C will abort the program.
Ctrl-S will pause output and Ctrl-Q will resume it.
9 - Write string to screen, c_conws
Parameters: long: address of string
Result: Non
Stack: 6
This writes the given null-terminated string to the screen.
$A - Read edited string from keyboard, c_conrs
Parameters: long: address of input buffer
Result: None
Stack: 6
Before calling this, the first byte of the buffer should be set
to the size of the data portion of the buffer. On return, the
second byte in the buffer will be set to the length of the
string, and the string itself starts at the third byte. No CR or
null is stored in the returned string and pressing Ctrl-C will
terminate the entire program.
$B - Check status of keyboard, c_conis
Parameters: None
Result: D0.L=-1 if character available, 0 if none
Stack: 2
This returns the status of the keyboard. The key itself should be
read with another call.
$E - Set default drive, d_setdrv
Parameters: word: drive number
Result: D0.L=bit map of drives in the system
Stack: 4
This sets the default drive; a word of 0 denotes A:, 1 denotes
B;, etc. The returned value has a bit set for each installed
drive, bit 0=A:, bit 1=B:, etc.
$10 _ Check status of standard output, c_conos
Parameters: None
Result: D0.L=-1 if ready, 0 if not
Stack: 2
This tests to see if the console device is ready for output.
$11 - Check status of printer, c_prnos
Parameters: None
Result: D0.L=-1 if ready, 0 if not
Stack: 2
This tests the status of the printer port. If the printer is
ready to receive a character it returns -1, else it returns 0.
$12 - Check status of serial port input, c_auxis
Parameters: None
Result: D0.L=-1 if character waiting. 0 if not
Stack: 2
This tests the serial port and returns -1 if there is a character
waiting to be read.
$13 - Check status of serial port output, c_auxos
Parameters: None
Result: D0.L=-1 if ready, 0 if not
Stack: 2
This tests the serial port and returns -1 if it is ready to
receive a character.
$19 - Get default drive, d_getdrv
Parameters: None
Result: D0.W=drive number
Stack: 2
This returns the number of the current drive, with A:=0, B:=1,
etc.
$1A - Set disk transfer address, f_setdta
Parameters: long: pointer to disk transfer address
Result: None
Stack: 6
This sets the address of a 44-byte buffer used for searching for
filenames. It must be word-aligned.
$20 - Get into Supervisor/User Mode, s_super
Parameters: long: value for stack, or 0 or 1
Result: D0.L=(depends on parameter)
Stack: 6
This has two functions - it can tell you if the program is in
User or Supervisor mode and it can switch from one mode to
another. To find which mode the processor is in, call this
routine with a parameter of 1. The return value will be 0 for
user mode, and -1 for supervisor. To switch modes you have to
supply a new stack pointer, or pass 0 if you want the stack to
remain unchanged. For example, if you are in user mode and want
to switch to supervisor mode using a SPP at address myssp, the
code would be:
move.l #myssp,-(a7)
move.w #$20,-(a7)
trap #1
addq.l #6,a7
When switching to supervisor mode the old value of the SSP is
returned in d0.l. If you only want to go temporarily into
Supervisor mode to hack protected memory, for example, XBIOS call
supexec is a lot easier.
$2A - Get date, t_getdate
Parameters: None
Result: D0.W
Stack: 2
This reads the date, with the result in this format:
Day: bits 0-4
Month: bits 5-8
Year: bits 9-15 (since 1980).
$2B - Set date, t_setdate
Parameters: word: date
Result: None
Stack: 4
This sets the date, using the same word format as the previous
function.
$2C - Get time, t_gettime
Parameters: None
Result: D0.W
Stack: 2
This returns the time of day, with the result in this format:
Seconds/2: bits 0-4
Minutes: bits 5-10
Hours: bits 11-15
$2D - Set time, t_settime
Parameters: word: time
Result: None
Stack: 4
This sets the current time of day, in the same word format as the
previous function.
$2F - Get disk transfer address, f_getdta
Parameters: None
Result: D0.L=pointer to disk transfer address
Stack: 2
This returns the current disk transfer address, and should always
be even.
$30 - Get version number, s_version
Parameters: None
Result: D0.W=version number
Stack: 2
This returns the GEMDOS version number, with the major number in
the low byte, and the minor number in the high byte. Known
releases at this time are:
$0D00 version 0.13 (obsolete disk-based)
$1300 version 0.19 (ROM-based)
$31 - Terminate and stay resident, p_termres
Parameters: word: exit code, long: bytes to keep
Result: None
Stack: 8
This allows a program to terminate while keeping part or all of
it in memory. It is useful for programs which extend the system,
such as RAM disk drivers; if they terminated normally the memory
the lie in would get destroyed when the next program loaded. The
memory that can be retained is that starting at the base page,
and the length parameter should include the $100 of the base
page, the required program length, data and stack space if
relevant.
$36 - Get drive free space, d_free
Parameters: word: drive code, long: pointer to buffer
Result: None
Stack: 8
This returns various bits of information about a particular disk
drive. The drive code should be 0 for the default drive, 1 for
A:, 2 for B:, etc. The buffer should be 16 bytes long, and word
aligned. On return, it will contain 4 longs of information; free
space, number of available clusters, sector size (in bytes), and
cluster size (in sectors).
$39 - Create a sub-directory, d_create
Parameters: long: address of pathname
Result: D0.W=0 if OK, else error code
Stack: 6
This creates a new directory, according to the null-terminated
string.
$3A - Delete a sub-directory, d_delete
Parameters: long: address of pathname
Result: D0.W=0 if OK, else error code
Stack: 6
This deletes a directory, so long as it has no files or other
directories in it.
$3B - Set current directory, d_setpath
Parameters: long: address of pathname
Result: D0.W=0 if OK, else error code
Stack: 6
This sets the current directory, according to the null-terminated
string. Note that drive specifiers are not allowed - you should
set the current drive then its directory.
$3C - Create a file, f_create
Parameters: word: attributes, long: pointer to string
Result: D0.W=file handle if successful, else error (and
longword negative)
Stack: 8
This will attempt to create the given file and if successful will
return a file handle that can be used in other file GEMDOS calls.
The attribute word can be these values:
01 read only
02 hidden file
04 hidden system file
08 filename contains volume name in first 11 bytes
File handle numbers returned by this call and the following one
start are words normally starting at 6 and go upwards. Handles 0
to 5 are standard handles which are already open when a program
starts. They correspond to the following devices:
0 - console input
1 - console output
2 - serial port
3 - parallel port
There are three system device names, called CON:, AUX: and PRN:
which can be used with this and the following call. They return
negative works, so to distinguish these from error returns always
TST.L/BMI for the error case.
$3D - Open a file, f_open
Parameters: word: mode, long: pointer to filename
Result: D0,W=file handle if successful, else error (and
longword negative)
Stack: 8
This will open an existing file for reading, writing, or both.
The mode word must be one of the following:
0 open to read
1 open to write
2 open for both reading and writing
If successful this will return a handle which can be used
subsequently, else an error number.
$3E - Close file, f_close
Parameters: word: handle
Result: D0.W=0 if OK, else an error number
Stack: 4
Given a file handle this will close the file. Do not close a
standard handle.
Note: This call, along with all the others that require handles,
do not do very extensive checks on the validity of the handle. If
you pass an invalid one you may get an error return, or the
machine may crash!
$3F - Read file, f_read
Parameters: long: load address, long: number of bytes to
read, word: handle
Result: D0.L=number of bytes read, or an error code
Stack: 12
This will attempt to read bytes from the given file. If an error
occurs D0.L will be negative. If the end of file is reached
during the read operation an error code is not returned - if you
wish to check for this you have to compare the number of bytes
you asked for with the result - if they are different then you
tried to read past the end of file.
$40 - Write file, f_write
Parameters: long: start address, long: number of bytes to
write, word: handle
Result: D0.L=number of bytes written, or an error code
Stack: 12
This will attempt to write bytes to the given file. If an error
occurs D0.L will be negative. If the disk becomes full an error
code will not be issued, but the value returned will not be the
same as the value passed to it as the number of bytes to write.
Note: If you pass a negative length parameter GEMDOS will crash
very badly.
$41 - Delete File, f_delete
Parameters: long: pointer to filename
Result: D0.W=0 if successful, else error code
Stack: 6
This will attempt to delete the given file.
$42 - Seek file pointer, f_seek
Parameters: word: mode, word: file handling, long position
Result: D0.L=absolute position in file after seek
Stack: 10
This will move the file pointer to a given position in the file.
The mode word should be one of the following.
0 move to N bytes from the start of the file
1 move to N bytes from the current location
2 move to N bytes from the end of the file
If you try and move past either end of the file you will get a
result of 0 (for the start) or the actual length of the file.
$43 - Get/Set file attributes, f_attrib
Parameters: word: attributes, word: get/set, long: pointer to
filename
Result: D0.W=new attributes, or an error code
Stack: 10
This can be used to get or set the attributes for a given file.
The attribute's word can be:
01 read only
02 hidden file
04 hidden system file
08 filename is actually the volume label in first 11
bytes
$10 sub-directory
$20 file is written and closed
The other word should be 0 to Get the attribute, or 1 to Set it.
$45 - Duplicate File Handle, f_dup
Parameters: word: standard handle
Result: D0.W=new handle, or error code
Stack: 4
Given a handle to a standard device (0-5), this function returns
another handle that can be used to address the same device. It
can also be closed without affecting the standard device handle.
$46 - Force file handle, f_force
Parameters: word: non-standard handle, word: standard handle
Result: D0.W=0 if OK, else error code
Stack: 6
This forces the standard handle to point to the same device or
file as the non-standard one, and can be used, for example, to
re-direct screen output to a disk file.
$47 - Get Current Directory, d_getpath
Parameters: word: drive number, long: pointer to buffer
Result: D0.W=0 if OK, else error code
Stack: 8
Given a drive number (default drive=0, A:=1, B:=2 etc.) this will
return the current directory in the given buffer, in null-
terminated form. The buffer should be 64 bytes long.
$48 - Allocate Memory, m_alloc
Parameters: long: number of bytes required
Result: D0.L=address of memory allocated, or 0 if failed
Stack: 6
This allocates the given amount of memory from the system pool,
if available. When a program terminates all its memory
allocations are cleaned up. This call can also be used to find
the amount of free memory, if -1 is passed.
Note: When GEMDOS itself uses this call it always ensures the
number of bytes required is even, so we recommend this out of
paranoia. This call can occasionally return an odd value for the
start of the allocated memory under TOS 13.
$49 - Free Allocated Memory, m_free
Parameters: long: address of area to free
Result: D0.W=0 if OK, else an error code
Stack: 6
This frees a block of memory allocated with m_alloc above.
$4A - Shrink Allocated Memory, m_shrink
Parameters: long: length to keep, long: start address to
keep, word: 0
Result: D0.W=0 if OK, else an error code
Stack: 12
This is normally used when a program starts up and releases part
of the allocated memory back to GEMDOS.
$4B - Load or Execute a Program, p_exec
Parameters: long: pointer to environment string, long:
pointer to command line, long: pointer to
filename, word: mode
Result: D0.L=(depends on mode)
Stack: 16
This call can be used for loading and chaining programs. The mode
word can be one of:
0 load and execute
3 load but do not execute
4 execute base page
5 create base page
For load and execute, the return value is either an error code,
or the value returned when the child program exited.
For load but don't execute the return value is either an error
code, or a pointer to the base page of the loaded program.
A discussion of using modes 4 and 5 is beyond the scope of this
document.
The command line should be of the form of a length byte followed
by the line itself.
The environment string may be passed as 0 to inherit the programs
parents basepage, or as a pointer to a list of null-terminated
environment strings, ending in a double-null. The normal
environment looks like this:
dc.b 'PATH=',0,'A:\',0,0
$4C - Terminate Program, p_term
Parameters: word: return value
Result: N/A as doesn't return
Stack: N/A
$4E - Search for First, f_sfirst
Parameters: word: attributes, long: pointer to filespec
Result: D0.W=0 if found, else -33 not found
Stack: 8
This trap can be used to scan a directory using wild-cards to
find all the files. This should be called to find the first one,
then f_snext should be called for the rest. When a file is found
the parameters of the file are returned in the DTA buffer area.
The attribute word determines which file types are to be included
in the search, and may be one of:
00 normal files
01 read only files
02 hidden files
04 system files
08 return volume name only
$10 sub-directories
$20 files that have been written to and closed
The returned values in the DTA buffer are:
0-20 reserved for internal use
21 file attributes
22-23 file time stamp
24-25 file date stamp
26-29 file size (long)
30-43 name and extension of file, null terminated
The address of the DTA buffer can be set with function $1A, and
read with function $2F.
$4F - Search for Next Occurrence, f_snext
Parameters: None
Result: D0.W=0 if found, else -33 not found
Stack: 2
After calling f_first to find the first occurrence of a filespec,
this call is used to find subsequent files. When a file is found
the DTA buffer is filled as described previously. For it to work
the first 20 bytes of the DTA must remain untouched between
calls.
$57 - Rename a file, f_rename
Parameters: long: pointer to new name, long: pointer to old
name, word: 0
Result: D0.W=0 if OK, else error code
Stack: 12
This will attempt to rename the file to the new name. A file with
the new name must not already exist.
$57 - Get/Set File Date & Time Stamp
Parameters: word: 0 for Get/1 for Set, word: file handle,
long: pointer to buffer
Result: None
Stack: 10
This can be used to get or set the time and date stamp on an open
file. The buffer should contain two words, the first being the
time, and the second the date, in the format already described.
BIOS - Basic I/O System
The ST BIOS is intended for low-level access to the screen,
keyboard and disk drives. It is accessed using the stack for
parameters as described previously, but using TRAP #13 to invoke
it. Programmers who require access to the BIOS are likely to need
much more details then we could provide, so only one BIOS call is
described here. For greater BIOS detail see the books in the
bibliography. The BIOS handler preserves registers D3-D7/A3-A7 -
all others may be corrupted by a call.
BIOS 5 - Set Exception Vector, setexc
This is a very useful trap and sets certain system vectors to
point to your own routines. It can set both exception vectors and
system vectors. The calling sequence is:
move.l #myroutine,-(a7) address of new handler
move.w #vectornum,-(a7) vector number
move.w #5,-(a7) BIOS function number
trap #8,a7 restore stack
move.l d0,oldroutine store old one
The vector number should be the exception number (2 for bus
error, 3 for address error etc.) or one of the following system
vectors:
$45 200Hz list
$100 system timer interrupt
$101 critical error handler
$102 process terminate hook
On return from the trap D0.L contains the previous value. If a
program modifies any vectors it should always restore them to
their original values before terminating.
If you pass an address of -1 it will not be changed, but the
current value will be returned in D0.L.
XBIOS - Extended BIOS
The XBIOS consists of 40 functions for a wide variety of
functions including hardware access, screen control, and
keyboard mapping. Again we leave most of the description to the
books in the bibliography, with the exception of five XBIOS
calls. The XBIOS handler preserves registers D3-D7/A3-A7 - all
others can be corrupted by a call. The calling sequence is the
usual one: put parameters on the stack, put a function word on
the stack, do a TRAP #14, then restore the stack. The XBIOS
functions are:
XBIOS 2 - Get Physical Screen Address, _physbase
Parameters: None
Result: D0.L=start of screen
Stack: 2
This will return the physical address of the screen, which always
occupies 32000 bytes and is aligned on a 256-byte boundary.
XBIOS 3 - Get Logical Screen Address, _logbase
Parameters: None
Result: D0.L=start of screen
Stack: 2
This will return the logical address of the screen.
XBIOS 4 - Get Screen Resolution, _getRez
Parameters: None
Result: D0.W=0 low, 1 medium, 2 high
Stack: 2
This will return the current screen resolution.
XBIOS 5 - Set Screen Address & Mode, _setScreen
Parameters: word: mode, long: physical address, long: logical
address
Result: None
Stack: 12
This lets you change the screen resolution and addresses. If any
parameter is specified as -1 then it is left alone. Changing the
screen mode will clear the screen.
XBIOS $26 - Call Supervisor Routine, supexec
Parameters: long: address of routine
Result: None
Stack: 6
This will call the given routine in supervisor mode. The routine
should not make any BIOS, XBIOS or GEMDOS calls.
GEM Libraries
GEM itself consists of two components; the VDI and the AES.
The GEM VDI (for virtual Device Interface) is the main part of
the operating system that draws graphics and text on the screen.
The GEM AES (for Application Environment Services) is the part of
the operating system that provides the user-interface facilities
of GEM such as windows, menus and dialogue boxes.
This section is intended to give details of the supplied library
files and calling conventions used. It does not attempt to
describe either the VDI or the AES in great detail - the books in
the Bibliography should be referred to for this. However, details
are given of information that we feel is badly documented or not
documented at all.
GEM AES Library
The calling sequence to the AES is based on various arrays of
words and longwords. These arrays are defined using DS directives
and are:
control words
int_in words
addr_in longwords
int_out words
addr_out words
aes_params longwords
global words
For example the C program segement
val=int_out (2)+int_out (3)
could be converted into this assembly language:
move.w int_out+4,d0
add.w int_out+6,d0
Note the way that the array index is doubled before adding to the
start of the array, as it is an array of words. For an array of
longs the index should be quadrupled.
A macro file, called GEMMACRO.S should be used which defines
various macros and, if generating executable code, the file
AESLIB.S should be included at the end of assembly.
The macros take a varying number of parameters and place them in
the required places in the AES arrays, before making a call to
the general AES routine. If passing a constant to a macro be sure
to precede it with a # sign, for example passing the parameters
3,myptr to a macro could generate the code
move.w 3,int_in
move.1 myptr,addr_in
The first line will cause a run-time error, the parameter should
have been #3. There are a few AES macros which do not take all
the required parameters - additional information may have to be
placed in other arrays. On return from and AES macro D0.W (and
the flags) reflect the contents of the array int_out(0), normally
useful. Various return values can often be found in the int_out
array.
The following descriptions assume all parameters to be word
sized, unless shown with a .L suffix, denoting a longword
parameter.
Application Library
appl_init
Should be called at the start of any AES program.
appl_read id,length,buffer.L
apppl_write id,length,buffer.L
appl_find name.L
Find a named program, normally a desk accessory
appl_tplay memory.L,number scale
appl_trecord memory.L,count
appl_exit
Should be just before an AES program terminates. It sends
AC_CLOSE type messages to all desk accessories.
Event Library
evnt_keybd
evnt_button clicks,mask,state
The return value is the number of times the button entered the
desired state. Array elements 1-4 of int_out contain the X co-
ordinate, the Y co-ordinate, the button state and the keyboard
state at the time of the event in that order.
evnt_mouse flags,x,y,w,h
The return values are as described for the previous call.
evnt_mesag buffer.L
evnt_timer count.L
evnt_multi flags,clicks,mask,m1flags,m1x,m1y,m1w,m1h,
& m2flags,m2x,m2y,m2w,m2h,count.L
All parameters except the first are optional, specifying a null
parameter means nothing is placed in the relevant element of
int_in. It shown above with the syntax of a multi-line macro
call but this is not obligatory. The int_out array contains
which event, mouse X, mouse Y, button, keyboard state, keyboard
code and button value, respectively.
evnt_dclick new,getset
Menu Library
menu_bar free.L,show
menu_icheck tree.L,item,check
menu_ienable tree.L,item,enable
menu_tnormal tree.L,title,normal
menu_text tree.L,item,text.L
menu_register id,string
Note: Normally a menu tree is generated by a resource editor
though they can be constructed, with a great deal of care, by
hand. Another alternative is to use the MENU2ASM
compiler,detailed later in this section.
Object Library
Object trees are normally constructed with a resouce editor,
though they can be constructed by hand if required. Dialog boxes
are the easiest type of object tree to construct by hand and
menus the most difficult.
objc_add tree.L,parent,child
objc_delete tree.L,object
objc_draw tree.L,startob,depth,x,y,w,h
objc_find tree.L,startob,depth,x,y
objc_offset tree.L,object
Elements 1 and 2 of int_out contain the returned X and Y co-
ordinates.
objc_order tree.L,object,newpos
objc_edit tree.L, object,char,idx,kind
int_out(1) contains the new idx
objc_change tree.L,object,x,y,w,h,new,redraw
Form Library
form_do tree.L,startob
Never pass startob as -1 as often documented, use 0 instead
form_dial flag,x1,y1,w1,h1,x2,y2,w2,h2
form_alert button,string.L
form_error errnum
Error numbers should be positive and less than 64
form_center tree.L
Graphics Library
graf_rubberbox x,y,w,h
int_out(1) contains the finish width, int_out(2) the height
graf_dragbox w,h,x,y,bx,by,bw,bh
int_out(1) contains the finish X co-ordinate, int_out(2) the Y
graf_movebox w,h,x,y,dx,dy
graf_growbox w,y,w,h,fx,fy,fw,fh
graf_shrinkbox x,y,w,h,sx,sy,sw,sh
graf_watchbox tree.L,object,instate,outstate
graf_slidebox tree.L,parent,obj,vh
graf_handle
The int_out array will contain the VDI handle, character cell
width, then height, system font width, then height
graf_mouse number,address.L
The address parameter is optional, only required if defining
your own shape
graf_mkstate
The int_out array will contain a reserved value, mouse X and Y
position, mouse button state and keyboard state.
Scrap Library
scrp_read buffer.L
scrp_write buffer.L
File Selector Library
fsel_input path.L,filename.L
The path parameter should point to a buffer containing the
null-terminated path, such as A:\ø.S, and the new path will be
returned in it, so be sure it is large enough. The filename
buffer should be 13 bytes, with a maximum of 12 used for
filename, for example TEST.S. If D0.W is non-zero on return
then it means there was not enough free memory to invoke the
selector, else int_out(1) will contain 0 if Cancelled.
Window Library
wind_create kind,x,y,w,h
wind_open handle,x,y,w,h
wind_close handle
wind_delete handle
wind_get handle,field
wind_set handle,field
wind_find x,y
wind_update begend
wind_calc type,kind,inx,iny,inw,inh
Resource Library
rsrc_load filename.L
rsrc_free
rsrc_gaddr type,index
The result address may be found in addr_out
rsrc_saddr type,index,saddr.L
rsrc_obfex tree.L,object
Shell Library
shel_read command.L,shell.L
shel_write doex,sgr,scr,cmd.L,shell.L
We have never managed to get this call to work reliably
shel_find buffer.L
The buffer should be a minimum of 80 bytes
shel_envrn value.L,string.L
Debugging AES Calls
Unlike the calls to the VDI, calls to the AES are not immediately
obvious when viewed from MonSt as they are of the form:
moveq #??,d0 AES function number
bsr CALL_AES
As an aid to decoding these, here is a table listing all the AES
calls and their hex function numbers:
A appl_init B appl_read C appl_write
D appl_find E appl_tplay F appl_trecord
13 appl_exit 14 evnt_keybd 15 evnt_button
16 evnt_mouse 17 evnt_mesag 18 evnt_timer
19 evnt_multi 1A evnt_dclick 1E menu_bar
1F menu_icheck 20 menu_ienable 21 menu_tnormal
22 menu_text 23 menu_register 28 objc_add
29 objc_delete 2A objc_draw 2B objc_find
2C objc_offset 2D objc_order 2E objc_edit
2F objc_change 32 form_do 33 form_dial
34 form_alert 35 form_error 36 form_center
46 graf_rubberbox 47 graf_dragbox 48 graf_movebox
49 graf_growbox 4A graf_shrinkbox 4B graf_watchbox
4C graf_slidebox 4D graf_handle 4E graf_mouse
4F graf_mkstate 50 scrp_read 51 scrp_write
5A fsel_input 64 wind_create 65 wind_open
66 wind_close 67 wind_delete 68 wind_get
69 wind_set 6A wind_find 6B wind_update
6C wind_calc 6E rsrc_load 6F rsrc_free
70 rsrc_gaddr 71 rsrc_saddr 72 rsrc_obfix
78 shel_read 79 shel_write 7A shel_find
7B shel_envrn
GEM VDI Library
The calling sequence itself to the VDI is, like the AES, based on
various arrays of words and longwords. These arrays are defined
using DS directives and are:
contrl words
intin words
ptsin words
intout words
ptsout words
vdi_params longwords
All (but one) VDI calls require a VDI handle, which by tradition
is a parameter to every call. However, the majority of programs
only use one handle, to a virtual workstation (the screen), so
the supplied VDI libraries use a word called current_handle as
the handle to pass on to the VDI itself. This saves an
appreciable amount of code and is the same way the HiSoft BASIC
libraries work. As the source to the library is supplied you
could change this, if required.
The macro file GEMMACRO.S should be used which defines various
macros and, if generating executable code, the file VDILIB.S
should be included at the end of assembly.
The macros take a varying number of parameters and place them in
the required places in the VDI arrays, before making a call to a
VDI library routine. The warning about # signs in parameters
described previously applies to the VDI too. There are a number
of VDI macros which do not take all the required parameters -
additional information may have to be placed in other macros. On
return, various return values can often be found in the intout
ptsout arrays.
The following descriptions assume all parameters to be word
sized, unless shown with a .L suffix, denoting a longword
parameter.
Control Functions
v_opnwk Open Workstation
This should not be used unless GDOS is installed. The intin array
should be suitably initialised, current_handle will be set to the
result of this call.
v_clswk Close Workstation
v_opnvwk Open Virtual workstation
This uses current_handle to open another workstation and sets
current_handle to the result. intin is normally filled with 10
words of 1 and one word of 2 (denoting RC co-ordinates).
v_clsvwk Close Virtual Workstation
V_clrwrk Clear Workstation
v_updwk Update Workstation
vst_load_fonts Load Fonts
Do not attempt this unless GDOS is loaded.
vst_unload_fonts Unload Fonts
Fonts must be unloaded before a workstation is closed.
vs_clip flag,x1,y1,x2,y2 Set Clipping Rectangle
Output Functions
v_pline count Polyline
The input co-ordinates should be copied to intin before the call.
v_pmarket count Polymarker
The input co-ordinates should be copied to intin before the call.
v_gtext x,y,string.L Text
The string should be in the form of null-terminated bytes.
v_fillarea Filled Area
The input co-ordinates should be copies to itin before the call.
v_contourfill x,y,index Contour Fill
vr_recfl x1,y1,x2,y2 Bar
v_arc x,y,radius,start,end Arc
v_pieslice x,y,radius,start,end Pie
v_circle x,y,radius Circle
v_ellarc x,y,xradius,yradius,start,end Elliptical Arc
v_ellpie x,y,xradius,yradius,start,end Elliptical Pie
v_ellipse x,y,xradius,yradius Ellipse
v_rbox x1,y1,x2,y2 Rounded Rectangle
v_rfbox x1,y1,x2,y2 Filled Rounded Rectangle
v_justified x,y,string.L,length,ws,cs Justified Graphics Text
The string should be null-terminated
Attribute Functions
vswr_mode mode Set Writing Mode
vs_colour index,red,green,blue Set Colour Representation
vsl_type style Set Polyline Line Type
vsl_udsty pattern Set User Defined Line Style Pattern
vsl_width width Set Polyline Line Width
vsl_color index Set Polyline Colour Index
vsl_ends begin,end Set Polyline End Styles
vsm_type symbol Set Polymarker Type
vsm_height height Set Polymarker Height
vsm_color index Set Polymarker Colour Index
vst_height height Set Character Height, Absolute Mode
The ptsout array will contain the selected size
vst_point point Set Character Height, Points Mode
The ptsout array will contain the selected size.
vst_rotation angle Set Character Baseline Vector
vst_font font Set Text Face
vst_colour index Set Graphic Text Colour Index
vst_effects effect Set Graphic Text Special Effects
vst_alignment horizontal,vertical Set Graphic Text Alignment
vst_interior style Set Fill Interior Style
vst_style index Set Fill Style Index
vsf_color index Set Fill Colour Index
vsf_perimeter vis Set Fill Perimeter Visibility
vsf_updat Set User Defined Fill Pattern
The intin array should be filled with the pattern and contrl(3)
set suitably.
Raster Operations
vro_cpyfm mode,source.L,dest.L Copy Raster, Opaque
This is the general blit call, most often used for scrolling the
screen. The source and destination parameters should point to a
memory form definition block (MFDB) which describes the format of
the memory to blit. An MFDB consists of ten words:
0 high word of address
2 low word of address
4 width in pixels
6 height in pixels
8 width in words
10 form flag, normally 1
12 number of planes
14-18 reserved, set to 0
The address in the first two words is normally either the screen
address of the address of a buffer being used for the blit. The
width and height fields should be those suitable for the screen
size and the number of planes can be found from a vq_extend 1
call in intout(4). When scrolling the screen the source and
destination parameters may point to the same MFDB.
The source and destination rectangles should be placed in the
ptsin array, each in the form x1,y1,x2,y2. A mode of 3 means
replace.
vrt_cpyfm mode,source.L,dest.L,i1,i2 Copy Raster, Transparent
vr_trnfm source.L,destination.L Transform Form
vr_get_pixel x,y Get Pixel
Input Functions
vex_timv newtimer Exchange Timer Interrupt Vector
v_show_c reset Show Cursor
v_hide_c Hide Cursor
vq_mouse Sample Mouse Button State
vex_butv newxbut Exchange Button Change Vector
vex_motv newmotv Exchange Mouse Movement Vector
vex_curv newcursor Exchange Cursor Change Vector
vq_key_s Sample Keyboard State Information
Inquire Functions
vq_extnd flag Extended Inquire
vq_color index,flag Inquire Colour Representation
vql_attributes Inquire Polyline Attributes
vqm_attributes Inquire Polymarker Attributes
vqf_attributes Inquire Fill Area Attributes
vqf_attributes Inquire Graphic Text Attributes
vqt_extent string.L Inquire Text Extent
The string should be null-terminated, the results will be found
in ptsout.
vqt_width char Inquire Character Cell Width
vqt_name number Inquire Face Name & Index
vqt_fontinfo Inquire Current Face Information
AES & VDI Program Skeleton
The general structure of a GEM-type program is as follows:
shrink memory call
call appl_init
set current_handle to the result from graf_handle
open a virtual workstation using this handle
open a window, perhaps
main wait for events & act on them as required
quit close any window
call appl_exit
finally p_term
Desk Accessories
A desk accessory is an executable file with the extension .ACC
loaded during AES initialisation. We have never seen any official
documentation on desk accessories, and the following information
has been learnt the hard way, mainly when writing our Saved!
program.
The first thing to be wary of is that it is not a normal GEMDOS
program. When it starts up all registers including A7 are 0, with
the exception of A0 which points to the basepage. An accessory
must include all the memory it requires within itself, the BSS
segment being a good place. An accessory must not do a GEMDOS
shrink call or attempt to terminate.
The main loop of an accessory is like any other AES program,
consisting of an event loop, but note that most documentation
details incorrect message numbers - AC_OPEN is really 40 and
AC_CLOSE is 41.
Other programmers have reported problems using the VDI from
within an accessory. The recommended method is to open a virtual
workstation only when you have to (i.e. before creating a window)
and always close it (when you close your window or, failing that,
when receiving an AC_CLOSE message. The example accessory
supplied, like our Saved! program, does not use the VDI at all -
paranoia rules!
If your accessory responds to timer events ensure that no GEMDOS
calls (Trap #1s) are made unless your window is the front one,
otherwise time bombs will be set and a crash is highly likely.
The file DESKACC.S contains the source to an example accessory,
which simply displays the system free memory in an alert box. It
has a label called RUNNER which can be set to 1 to produce a
stand-alone application instead of an accessory. This can be
invaluable during program development as you can symbolically
debug a stand-alone program, while an accessory has to be
debugged using AMONST without the benefit of symbols.
Linking with AES & VDI Libraries
The supplied macro file GEMMACRO.S is designed to be used in
executable or linkable programs. The files AESLIB.S and VDILIB.S
contain the actual code and should be included at the end of
programs when generating executable code, but if generating
linkable code they should not. If you look at GEMTEST.S you can
see how a conditional is used to make this automatic.
When developing a program using these libraries we recommend
executable code as it greatly reduces development time. However
the file size can be reduced by using the selective library
feature of the linker and using the GEMLIB.BIN file. For example,
if GEMTEST is linked to GST-linkable code, producing
GEMTEST.BIN, it can be linked with this library by passing LinkST
the command line
gemtest -wgemlib
The GEMLIB.LNK control file will do the rest. If you want to
reduce your program to the absolute minimum then you can change
the libraries as you require, which is why we supply the source
code.
Menu Compiler
For those who wish to use menus without using a resource editor
we supply the program MENU2ASM.TTP which converts a menu
definition file into assembly language source statement for
inclusion in your program. We use this method ourselves in the
GenST editor.
The menu specification should be created in a text file with the
extension .MDF and an example follows:
[ Desk | About Program ]
[ File | New \ Load \ (-------\ Quit ]
[ Search | Find ]
and so on. Line breaks are ignored. Each menu title and its items
are enclosed in square brackets [ and ]. There is a vertical bar
(|) after each title and the individual items separated by back-
slashes (\). For grey items precede the text with an open
parentheses (. The first menu is always the desk title (normally
Desk); the currently loaded desk accessories will be added by the
AES. (It is no coincidence that this is the same syntax as that
accepted by our BASIC compilers).
We recommend that you precede each menu item with two spaces and
have at least one space after the item. Menu titles should have
one space before and after them.
To compile a file double-click on MENU2ASM.TTP and enter the
filename, without an extension. It will produce a file with an
extension of .MNU which may be included in your program.
The file MENUTEST.MDF contains an example definition of a menu
and MENUTEST.S the source code to a program illustrating its use,
as well as showing other AES features.
Old GenST AES & VDI Libraries
The folder OLDGEM contains updated versions of the source files
supplied with version 1 of DevpacST. These use different calling
conventions and are supplied for users who have upgraded.
VT52 Screen Codes
When writing to the screen via the BDOS or BIOS calls, the screen
driver emulates VT52 protocols. The control codes are sent via
escape sequences, which means an escape character is sent (27
decimal, or $1B) followed by one or more other characters.
ESC A cursor up; no effect if at the top line
ESC B cursor down; no effect if at the bottom line
ESC C cursor right; no effect if on the right hand side
ESC D cursor left; no effect if on left hand side
ESC E clear screen and home cursor
ESC H home cursor
ESC I move cursor up one line; if at top scrolls the screen
down a line
ESC J erase to end of screen, from the cursor position onwards
ESC K clear to end of line
ESC L insert a line by moving all following lines down. Cursor
is positioned at start of the new line
ESC M delete a line by moving all following lines up
ESC Y position cursor; should be followed by two characters the
first being the Y position, the second the X. Row and
column numbering starts at (32,32) which is the top left
ESC b foreground colour; should be followed by a character to
determine the colour, of which the four lowest bits are
used
ESC c background colour; similar to above
ESC d erase from beginning of display to the current position
ESC e enable cursor
ESC f disable cursor
ESC j save the current cursor position
ESC k restore a current position saved using ESC j
ESC l erase a line and put cursor at start of line
ESC o erase from start of line to cursor position
ESC p inverse video on
ESC q inverse video off
ESC v wrap around at end of line on
ESC w wrap around at end of line off
APPENDIX E
Converting from other Assemblers
Most 68000 assemblers for the ST follow, to one degree or another
the Motorola standard. While the instructions themselves are
thankfully standard, the syntax rules for labels, comments and
directives can, and do, vary. This Appendix covers the changes
most likely to be made when converting programs from another
assembler, whether they are your old source files or a program
listed in a magazine. It does not attempt to detail the
differences in user interfaces or options between the different
assemblers.
Atari MADMAC
GenST does not require colons after labels or comments to be
delimited with semi-colons, but it does not allow instructions or
directives to start in the label field.
The syntax and rules for local labels are the same, though $ and
? are not valid in GenST symbols. The use of \ in quoted strings
may have to be changed, and some arithmetic operators and
priorities are different.
MADMAC allows directives to start with dot, if these are removed
most directives are the same as GenST. Those that differ, and
their GenST equivalents are:
BSS=SECTION BSS, DATA=SECTION DATA, TEXT=SECTION TEXT,
ABS=OFFSET, ELSE=ELSEIF, ENDIF=ENDC, EXITM=MEXIT, GLOBL and
EXTERN=XREF or XDEF, EJECT=PAGE, TITLE=TTL, NLIST=NOLIST.
INIT can be converted to DC or DCB statements and CARGS can be
replaced with suitable RS directives.
MADMACs macro syntax is unique and its named parameters will need
conversion, equivalents for its parameters are \~=\@ and
\#=NARG.\? can be emulated using IFC or IFNC. The 6502 options of
MADMAC are not supported.
GST-ASM
GST labels are significant only to the first 8 characters and are
case insensitive so OPT C8- may be required. Its rules for
expression evaluation are very similar though $ is not allowed
within a GenST symbol.
Most directives are the same, those requiring name changes are
PAGEWID=LEN and PAGELEN=PLEN. Macro definitions will require
conversion as will GSTs unique form of local symbols.
Built-in functions and structure statements are not supported.
MCC Assembler
Very few changes are required, only the syntax for local labels
and add.L to XREF directives of absolutes.
K-SEKA
Colons are not required after labels in GenST though instructions
or directives that start in the label field will need a tab added
before them. Several Seka directives default to Byte instead of
Word sizes for some reason. Equivalent directives names are:
D=DC, BLK=DS, CODE=SECTION CODE, DATA=SECTION DATA, IF=IFNE,
ELSE=ELSEIF, ENDIF=ENDC.
Macro syntax requires ?s to be changed to \s, except ?0 which
should be replaced with \@.
Fast ASM
The syntax of Fast ASM was designed around GenST 1.2 so few
changes are required. Tokenised source files will need conversion
to ASCII (using the Clipboard) before attempting to load them
into the GenST editor. The main change involves comment
delimiters - Fast ASM lines starting with \ should be changed to
start with ø or ;-\s used after instructions will not require any
changes.
The floating point facilities in Fast ASM, left over from its
BASIC interpreter origins, are not supported in GenST.
APPENDIX F
BIBLIOGRAPHY
This bibliography contains our suggestions for further reading on
the subject of the 68000, the ST, and GEM. The views expressed
are our own and as with all reference books there is no
substitute for looking at the books in a good bookshop before
making a decision.
68000 Programming
M68000 Programmer's Reference Manual
Published by Prentice-Hall
The definitive guide to the instruction set produced by Motorola.
the supplied Pocket Guide is a subset of this book. Be sure to
get the latest version - at the time of writing the Fifth Edition
is the latest.
68000 Assembly Language Programming by Kane, Hawkins & Leventhal
Published by Osborne/McGraw-Hill
This is large (and expensive) but good, containing lots of
examples. Be sure to get the second edition. Not for complete
beginners to microprocessors.
68000 Tricks and Traps by Mike Morton
BYTE magazine, September 1986 issue
By far the best article on 68000 programming we have ever seen.
We wish there was a book like this.
ST Technical Manuals
GEM Programmer's Guide Volumes 1 & 2 - VDI and AES
By Digital Research
The definitive guide to the VDI and the AES, but marred by
mistakes and lack of 68000 details. Only available to registered
developers.
GEMDOS Specification by Digital Research
The definition of the GEMDOS calls. Only available to registered
developers.
A Hitchhikers Guide to the BIOS by Atari Corp
The definition of the BIOS and XBIOS calls, and corrections to
the GEMDOS manual. This is accurate, a good read and updated
regularly. Normally only available to developers.
The Anatomy of the Atari ST by Data Becker/Abacus
This book is the best documentation available for the user who is
not a registered developer. It describes the hardware and non-GEM
aspects of the operating system, including an (out-of-date) BIOS
listing. Thoroughly recommended, despite its inaccuracies.
GEM on the Atari ST by Data Becker/Abacus
This describes programming under GEM, though is not as complete
as the DR manual, but has similar errors. It describes calls
mainly from C, although there is more reference to the 68000 than
in the DR manual. Better than no book at all on GEM.
Concise Atari 68000 Programmer's Reference by Katherine Peel
Published by Glentop
An alternative to Atari ST internals. It contains information on
the ST's hardware, the operating system and GEM. Its coverage of
the various levels of the machine is comprehensive, though a
couple of sections are very inaccurate and some features are
described that simply don't exist. It is rather difficult to find
one's way around as the layout is based on large numbers of
tables and it lacks an index.
Tricks and Tips on the Atari St by Data Becker/Abacus
This contains a wide variety of material, including an accurate
description of the more esoteric ST BASIC commands, and good
sample listings including a RAM-disk driver and desk accessory.
M68000 Cross Macro Assembler Reference Manual
Published by Motorola (M68KXASM)
The official definition of 68000 assembly-language syntax on
which GenST is based.
M68000 Resident Structured Assembler Reference Manual
Published by Motorola (M68KMASM)
This details the more advanced aspects of the Motorola standard
including extended macros and 68010/20/881 processors.
APPENDIX G
TECHNICAL SUPPORT & UPGRADES
So that we can maintain the quality of our technical support
service we are detailing how to take best advantage of it. These
guidelines will make it easier for us to help you, fix bugs as
they get reported and save other users from having the same
problem. Technical support is available in three ways.
Phone our technical support hour is normally between 3 p.m. and
4 p.m. though non-European customers' calls will be
accepted at other times.
Post if sending a disk, please put your name & address on it.
BIXTM our username is (not surprisingly) hisoft. Would UK
customers please use more old fashioned methods; it's
cheaper for everyone.
Whichever method you use please always quote your serial number
(from your master disk) and the version number of the program. We
reserve the right to refuse technical support if you do not
supply this information.
For bug reports, please run the CHECKST.PRG program supplied and
quote the information given by it, as well as details of any desk
accessories and auto-folder programs in use. If you think you
have found a bug, try and create a small program that reproduces
the problem. It is always easier for us to answer your questions
if you send us a letter and, if the problem is with a particular
source file, enclose a copy on disk (which we will return).
Upgrades
As with all our products, DevpacST is undergoing continual
development and, periodically, new versions become available. We
make a small charge for upgrades, though if extensive additional
documentation is supplied the charge may be higher. All users who
return their registration cards will be notified of major
upgrades.
Suggestions
We welcome any comments or suggestions about out programs and, to
ensure we remember them, they should be made in writing.
DevpacST Developer Version
For those that require maximum power from their 68000 assembler
we have available the Developer version of Devpac ST. Features
over and above this version include:
GDOS is supplied together with documentation, sample program and
calling sequences; Motorola S record hex output and multiple-ORG
statements for users cross-developing; Amiga executable &
linkable file formats; 68010/20/30/881/882 instructions; Dual
machine debugging; Detailed notes on GST & DRI file formats
including special dump programs for both formats, source (in
HiSoft BASIC) included; Free upgrades for a year, despatched
automatically).
DevpacST Developer is available as an upgrade.
APPENDIX H
REVISION HISTORY
Product History
DevpacST 0.50 was first released in late 1985, but with various
restrictions to do with the editor and lack of linkable code. The
next major version was 0.91 which was much improved in many
respects, followed by 0.99f, the last version which didn't
produce linkable code. Version 1.0 was released in April 1986,
and underwent a few minor changes before the release of version
1.22 in June 1986, the first version supplied in a ring-bound
manual. After various small revisions the greatly improved
version 2.0 was released in April 1988.
Development Technique
DevpacST was originally based on DevpacQL, our Assembler
Development suite for the Sinclair QL. Both GenST and MonST were
written in assembler on the QL then uploaded via the serial port
into the ST, and LinkST was written using Lattice C on the ST.
Development moved across to the ST around version 1.24 which had
minor changes made, reaching version 1.26. Special internal
versions were written to experiment with things like linkable
code and extended debug and reached version 1.57 before both
GenST and MonST were completely re-written for version 2. The
editor was extensively altered, originally for HiSoft BASIC, then
Power BASIC, then GenST. The editor is written entirely in
assembly language.
Summary of Version 2 Improvements
This section is intended as a quick guide to the main additional
features for users who have upgraded from version 1.2 or
DevpacST. It gives an overview of the new features, for further
details you should consult the relevant sections of the new
manual.
The Editor
This has been greatly enhanced, with an overall improvement in
display speed being the most obvious. The editor supports lines
up to 240 characters in length, sideways scrolling as required.
It also works in low-resolution. There is now a horizontal scroll
bar and the workings of the vertical scroll bar is now more
"standard". By default the numeric pad is configured as an IBM-
style cursor cluster and the text editor. This, combined with the
saving of preferences, means the installation program in version
1 is redundant. Other programs can be run from within the editor
using the Run Other facility.
Block Deleter has changed to Shift-F5 from Shift-F3 (as fast
left-handed typists can generate the Shift-F3 scan-code in
ordinary typing) and now remembers the block, if possible,
allowing it to be pasted. A deleted line may be recalled as many
times as required. A block may be copied to the block buffer, and
marked blocks are now shown on screen. Our Saved! desk accessory
may be invoked at the press of a key, there is a keyboard
shortcut for Save, and the editor will now run in low-resolution.
The Assembler
Symbols are now significant to the first 127 characters and local
labels are supported. The INCBIN directive takes a straight
binary file and copies it into the output file, particularly
useful for screen data. Speed - include files are read only once,
memory permitting, and the binary file is buffered for as long as
possible. The absolute maximum speed has over doubled to 75,000
lines per minute though for real programs 35,000 lines is the
norm. The output file is also extensively buffered if possible
producing spectacular improvements during floppy-to-floppy
assemblies in particular.
General improvements in symbol table searching and hashing have
also increased overall speed. Extended Debug - a HiSoft extended
version of the DR symbol table, allowing debugging with up to 22
character significance. Macro calls and Includes may be nested as
deeply as memory allows. IFs can be 64K levels deep. TEXT, DATA &
BSS segments are properly supported when generating executable
code.
There is much greater control over output filenames. Multiple
Modules & Sections - the GST linker format is more fully
supported allowing multiple modules and multiple sections.
Externals may be used in expressions, with each other if
required. DRI linkable code can now be generated.
Optimising can now be performed by the assembler on things such
as short branches. Macros now support up to 36 parameters multi-
line calls and numeric substitution. The macro buffer is now
dynamic, the free space in the editor workspace is no longer used
for this. REPEAT loops are now allowed and the exprerssion
evaluator now includes comparisons. The REG directive allows
symbolic register lists. There are a considerable number of
extensions to the OPT directive. Octal numbers are supported.
Registers may also be called R0 through R15. A stand-alone
assembler is supplied for those who use alternate editors, CLIs
or batch files.
Compatibility Issues
Most source files should assemble with little or no changes. The
differences to be careful of are: BSS sections - neither RSBSS or
DSBSS are supported, the code should be converted to switch to
SECTION BSS then use DS statements. Symbols now default to case-
dependent and are significant to the first 127 characters. OPT N
for narrow listings has been superseded with the FORMAT directive
allowing much greater flexibility and general listing control has
been improved. The ORG statement has changed which will effect
any programs that use it.
HiSoft BASIC users - if creating libraries please note that GenST
2 output is not accepted by BUILDLIBs prior to version 1.4.
BRA.W wasn't accepted by version 1, forcing the use of BRA.L -
this is, strictly speaking, a 68020 instruction so now generates
a warning, BRA.W (and BRA.B) are now accepted. Various minor
changes have been made to the parsing of instructions allowing a
greater degree of flexibility. If you used (expressions)\W
(denoting short-word addressing) within a macro this will be
ignored as \W and \L refer to macro parameters and will probably
be replaced with nulls. Use instead (expression).W. which is the
Motorola standard.
The use of \W or \L after register equates used as index
registers is no longer required, for example if buf is a register
equate then move,b d0,0(a6,buf.l) is now allowed. Register
equates are now allowed in MOVEMs. The priority of the equality
operator (=) has been changed.
The GEM example program has been changed to use a true BSS
section and to fix a bug preventing correct operation under GDOS
- this and its include file can be found in the OLDGEM folder.
Many new example files are supplied including a desk accessory
and completely new AES and VDI libraries.
The assembler now reports syntactic errors on pass 1 and will not
start pass 2 if errors have been found. It now uses GEMDOS
character output routines so can be paused with Ctrl-S, resumed
with Ctrl-Q and aborted with Ctrl-C.
There are several new directives which could potentially clash
with macro names in GenST 1 source files. These are: COMMENT,
DCB, ELSEIF, ENDR, FORMAT, IIF, INCBIN, OFFSET, OUTPUT, REG,
REPT, RSSET, SUBTTL.
There are three reserved symbols which could theoretically clash
with your own, all starting with two underlines: __LK, __RS and
__G2.
Debugger
MonST supports a great number of new features including multiple
windows and, as a result, has a changed user interface. It is
strongly recommended that you read the Reference section of the
Chapter 4 before trying any serious work with the new version.
The main new features are: Multi-window display; Timed screen
switching removing flicker; Full expression evaluator including
indirection; Supports up to 22 significant characters in symbols;
Multi-resolution allows you to debug a low-res program in medium
res (or vice versa); Allows the viewing of source files within
the debugger; Disassemble to printer with automatic label
generation or to a disk file in GenST format; Conditional
breakpoints; History Buffer; Interrupt running programs.
Both GEM and TOS versions of the debugger are now the same except
for the file extension and one one auto-resident version needs to
be supplied.
Integration
Probably the greatest improvement to the package as a whole is
the integration between its various parts. The assembler is
available at the press of a key from the editor, as it was, but
so is the debugger. The assembler can assemble directly into
memory, then the code can be run from the editor without any disk
accesses. If required debugging information can also be included
in assembled-to-memory programs so they can be debugged at the
press of a key, directly from the editor. A program assembled to
memory is a true GEMDOS task so no code changes are required.
Assembly warnings and errors are remembered by the editor and can
be stepped through by pressing Alt-J. Errors are no longer lost
when the number of lines is changed, though they are not re-
calculated. After an assembly which had an error the editor will
automatically place the cursor on the line of the first error.
Linker
This now supports the HiSoft Extended Debug format and is faster
than its predecessors. It also allows explicit section ordering
and true BSS sections. Note that LinkST only supports the GST
format - if you wish to link DRI format code you need to use the
Atari ALN or the Digital Research LINK68 linkers.