April 4, 1986
TABLE OF CONTENTS
Introduction
Calling GEMDOS
File Naming
File Operations
Processes
Extended Vectors
Error Handling
> GEMDOS calls - by number
> GEMDOS calls - by name
> GEMDOS calls description
Executable File Format
Volume Structure
Introduction_______________________________ | THIS IS A PRELIMINARY DOCUMENT| | AND IT DOES NOT CLAIM TO | | PERFECTLY DESCRIBE REALITY | | (or even GEMDOS). PLEASE | | REPORT BUGS AND TYPOS TO | |_______________________________| This is the Atari GEMDOS User's Manual. It describes the internals and use of GEMDOS on the Atari ST. This manual is divided into three parts; a tutorial and introduc- tion for beginning users, a reference manual for application writers, and appendices for GEMDOS wizards. The GEMDOS Tutorial is a gentle introduction to the basics of GEMDOS. Its intention is to get beginning users started as quickly as possible. It gives example programs, designed to exercise most of GEMDOS, which combine into a simple commandline interface, or "shell". The tutorial also covers common pitfalls and useful shortcuts. The GEMDOS Reference Manual is the application-writer's bible. It covers GEMDOS' calling conventions, file and han- dle manipulation, process execution, and every GEMDOS call. The Appendices contain nitty-gritty details and hints for those who have to push GEMDOS to the limit. They are for application writers (and the merely curious) who have "need to know" about obscurities in the system. To use this manual effectively readers should be fami- liar with C and 68000 assembly language. Familiarity with MSDOS, Unix, and the standard C runtime library will also help. |
Calling GEMDOSGEMDOS uses the Alcyon (or Digital Research) C calling conventions. Note that these conventions may differ from other 68000 C compilers. If you are using another C com- piler it might not be possible to call GEMDOS directly; please check your compiler's documentation for compatibil- ity. Arguments are pushed on the stack, in reverse order of their declaration. The GEMDOS function number is pushed last, as a WORD. To do the call to GEMDOS, a 68000 "TRAP #1" instruction is executed. The trap can be made with the 68000 in user or supervisor mode. NOTE Applications running in supervisor mode may be forced back into user mode after making a GEM AES call. Stack Snapshot (Just Before a GEMDOS Trap) _____________________________ |_____________________________| | (sp)| WORD function number| | 2(sp)| argument 1 | | X(sp)| argument 2 | | Y(sp)| argument 3 | | .| . | | .| ... and so on ... | | .| . | |_____________________________| Results are returned in D0. Registers D0-D2 and A0-A2 can be modified; registers D3-D7 and A3-A7 will always be preserved. The caller is responsible for popping the argu- ments (including the function number) off of the stack after the call. The Alcyon C compiler does not generate TRAP instruc- tions, so most applications use a small assembly-language binding. It typically looks like: ________________________________________________________ | text | | *+ | | * GEMDOS binding for Alcyon C | | * | | * NOTE: | | * This binding is NOT re-entrant, and cannot | | * be shared by foreground and interrupt code. | | * | | *- | | .globl _gemdos | | _gemdos: | | move.l (sp)+,t1sav ; save ret addr | | trap #1 ; call GEMDOS | | move.l t1sav,-(sp) ; restore ret addr | | rts ; do "real" return | | | | bss | | t1sav: ds.l 1 ; saved ret addr | |________________________________________________________| |
File NamesA filename consists of a drive specification followed by a pathname and a simple filename. A drive specification consists of a single letter, A through P, followed by a colon; if the specification is missing, the default drive is used. A pathname consists of a list of simple filenames separated with backslashes. If the pathname starts with a backslash it is anchored in the root directory, otherwise it is anchored in the current directory. If the pathname is missing, the current directory is used. A simple filename consists of one to eight characters, optionally followed by a period and zero to three more characters. Legal characters in filenames and pathnames include the alphabet (A-Z), digits (0-9), and most punctuation. Periods, colons, backslashes, slashes, question-marks, asterisks, control characters (including NULs), and charac- ters greater than 0x7f may never appear in filenames. Lowercase letters are converted to uppercase. A full file specification may not exceed 125 charac- ters. ______________________________ |______________________________| | letters A-Z, a-z | | numbers 0-9 | | _ (underscore) | | ! @ # $ % ^ & ( ) | | + - = ~ ` ; ' " , | | < > | [ ] { } | |______________________________| In a pathname, "." refers to the current directory and ".." refers to the current directory's parent directory. Thus, the paths: "..\..\foo" and ".\.\.\.\.\.\..\.\.\..\.\foo" refer to the same file two directories up from the current one. (There is no parent directory at the root.) There are three character devices. Only the calls Fread(), Fwrite() Fopen(), Fcreate(), and Fclose(), and the standard I/O functions work on them: ___________________________________________ |___________________________________________| | CON:, con:| 0x0ffff (-1)| system console| | AUX:, aux:| 0x0fffe (-2)| RS232 port | | PRN:, prn:| 0x0fffd (-3)| printer port | |___________________________________________| An Fopen() or Fcreate() call on one of the character devices will return a character device handle. The handle is WORD negative, but not LONG negative. |
File OperationsGEMDOS places no restrictions on what a file may con- tain. Most applications assume that text files contain lines separated with carriage-return linefeeds, with a control-Z indicating the end of file. The format of execut- able files is documented in the Appendix. The GEMDOS calls Fcreate() and Fopen() return small, positive 16-bit integers, called handles, that refer to open files. A file may be opened for reading only, for writing only, or for reading and writing. Closing the file relinqu- ishes the handle, allowing the handle to be re-used. There are three kinds of handles. Standard handles range from 0 to 5, and may refer to character devices or files. Non-standard handles start at 6, and refer only to files. Character handles refer only to character devices; the handle numbers range from 0xfffd to 0xffff, which are WORD negative, but not LONG negative. When a process does a Pexec() call the child process inherits the parent's standard handles. Handle 0 is often referred to as "standard input" or "standard output"; nor- mally it is connected to the console, CON:. With Fdup() and Fforce() calls it is possible to redirect a process's stan- dard I/O to or from a file or another character device. When a media change occurs, all files open on the disk that was removed are forced closed by GEMDOS. There is no concept of "standard error" output. |
ProcessesAlthough GEMDOS does not support multitasking, it is possible to execute processes in a subroutine-like manner. A process may "call" another with Pexec(); the child process will terminate with a WORD return code. A process owns any files it opens and any memory it allocates. Open files are closed and memory is deallocated when the process terminates. Before a process is actually terminated GEMDOS will call extended vector 0x102. This allows applications to make a "last ditch" effort to recover from error conditions, or to deinstall themselves. The memory model used by GEMDOS is similar to MSDOS's. A process runs in the TPA (Transient Program Area). The first 0x100 bytes of the TPA is the process's basepage, which contains process-specific information. Basepage Structure __________________________________________________ |__________________________________________________| | 0x00 p_lowtpa -> base of TPA | | 0x04 p_hitpa -> end of TPA | | 0x08 p_tbase base of text segment | | 0x0c p_tlen size of text segment | | 0x10 p_dbase base of data segment | | 0x14 p_dlen size of data segment | | 0x18 p_bbase size of BSS segment | | 0x1c p_blen base of BSS segment | | 0x20 p_dta Disk Transfer Address (DTA)| | 0x24 p_parent -> parent's basepage | | 0x28 (reserved) | | 0x2c p_env -> enviroment string | | 0x80 p_cmdlin commandline image | |__________________________________________________| `p_lowtpa' points to the basepage (to itself). `p_hitpa' points to the TPA's limit, to the first unusable location. `p_tbase', `p_tlen' and so on contain the start- ing addresses and sizes of the text, data and BSS segments. `p_parent' points to the process's parent process's basepage. `p_env' points to the enviroment string [see Pexec()]. The first byte of the commandline image contains the number of characters in the commandline. The second through Nth bytes contain the image. The image is ___ guaranteed to be null-terminated. An application receives control at the starting address of its text segment. The second longword on the stack, 4(sp), will contain a pointer to the process's basepage. Normally all free memory is allocated to a new process; if the process is going to use Malloc() or Pexec() then it must relocate its stack and call Mshrink() to release memory back to the system. The stack segment starts near the highest TPA location and grows toward the BSS. |
Extended VectorsThe 68000 uses vectors 0x02 through 0xff, corresponding to absolute locations 0x0000 through 0x03fc. GEMDOS adds eight _______ vectors, numbered 0x100 through 0x107. The absolute locations of the logical vectors is undefined; it is up to the BIOS to allocate storage for them. Logical Vector Assignments ________________________________________ |________________________________________| | 0x100 | timer tick | | 0x101 | critical error handler | | 0x102 | terminate (^C) handler | | 0x103 - 0x107| reserved for future use| |________________________________________| 0x100 Timer Tick This vector is called periodically (at 50hz) by the BIOS to maintain the system's date/time-of-day clock and do housekeeping. The first word on the stack, 4(sp), contains the number of milliseconds from the last timer tick interrupt. To intercept the timer vector, use the BIOS call to get and set the vector. Each handler should execute its own code first, and then follow the old vector. Interrupt handlers should be short and sweet; dawdling here will affect system performance. All registers (except SP and USP) are modified by GEMDOS. The BIOS takes responsibility for saving registers D0-D7/A0-A6; therefore handlers chained to this interrupt do not have to save and restore regis- ters. 0x101 Critical Error Handler The Critical Error Handler is called by the BIOS to handle certain errors (rwabs() disk errors and media change requests.) It allows the application to handle the errors as it sees fit. The first word on the stack, 4(sp), is an error number. Depending on the error, other arguments may also be on the stack. The critical error handler should preserve registers D3-D7/A3-A6. When the handler returns, D0 contains a result code: _______________________________________________________ |_______________________________________________________| | 0x00010000 | retry | | 0x00000000 | pretend there wasn't an error (ignore)| | 0xffffffXX | abort with an error | |_______________________________________________________| The default critical error handler simply returns -1. 0x102 Terminate (^C) Handler Before a process is actually terminated, GEMDOS calls the terminate vector. If the terminate vector points to an RTS (the default case), the process will be terminated. If the application does not wish to be terminated it should do a longjump (or its equivalent) to an appropriate handler. |
Error HandlingAll error numbers are negative. Two ranges of errors are defined; BIOS errors range from -1 to -31 and GEMDOS errors range from -32 to -127. BIOS Error Codes _________________________________________________ |_________________________________________________| | E_OK 0 OK (no error) | | ERROR -1 Error | | EDRVNR -2 Drive not ready | | EUNCMD -3 Unknown command | | E_CRC -4 CRC error | | EBADRQ -5 Bad request | | E_SEEK -6 Seek error | | EMEDIA -7 Unknown media | | ESECNF -8 Sector not found | | EPAPER -9 Out of paper | | EWRITF -10 Write fault | | EREADF -11 Read fault | | -12 (unused) | | EWRPRO -13 Write on write-protected media| | E_CHNG -14 Media change detected | | EUNDEV -15 Unknown device | | EBADSF -16 Bad sectors on format | | EOTHER -17 Insert other disk (request) | |_________________________________________________| `EOTHER' is really a request from the BIOS to insert another disk in drive A:. The "virtual" disk number (0 or 1) is at 6(sp). This feature is used to fake GEMDOS into thinking that a single drive system really has two drives. GEMDOS Error Codes (numbers in parenthesis are MSDOS-equivalent error#s) ___________________________________________________ |___________________________________________________| | EINVFN -32 (1) Invalid function number | | EFILNF -33 (2) File not found | | EPTHNF -34 (3) Path not found | | ENHNDL -35 (4) Handle pool exhausted | | EACCDN -36 (5) Access denied | | EIHNDL -37 (6) Invalid handle | | ENSMEM -39 (8) Insufficient memory | | EIMBA -40 (9) Invalid memory block address | | EDRIVE -46 (15) Invalid drive specification | | ENMFIL -47 (18) No more files | | ERANGE -64 Range error | | EINTRN -65 GEMDOS internal error | | EPLFMT -66 Invalid executable file format| | EGSBF -67 Memory block growth failure | |___________________________________________________| |
GEMDOS calls - sorted by numberdecimal hexa name description ---------------------------------------------------------------- 00 0x00 Pterm0 Terminate Process 01 0x01 Cconin Read character from Standard Input 02 0x02 Cconout Write Character to Standard Output 03 0x03 Cauxin Read Character from Standard AUX: 04 0x04 Cauxout Write Character to Standard AUX: 05 0x05 Cprnout Write Character to Standard PRN: 06 0x06 Crawio Raw I/O to Standard Input/Output 07 0x07 Crawcin Raw Input from Standard Input 08 0x08 Cnecin Read Character from Standard Input, No Echo 09 0x09 Cconws Write String to Standard Output 10 0x0A Cconrs Read Edited String from Standard Input 11 0x0B Cconis Check Status of Standard Input 14 0x0E Dsetdrv Set Default Drive 16 0x10 Cconos Check Status of Standard Output 17 0x11 Cprnos Check Status of Standard PRN: 18 0x12 Cauxis Check Status of Standard AUX: Input 19 0x13 Cauxos Check Status of Standard AUX: Output 25 0x19 Dgetdrv Get Default Drive 26 0x1A Fsetdta Set DTA (Disk Transfer Address) 32 0x20 Super Get/Set/Inquire Supervisor Mode 42 0x2A Tgetdate Get Date 43 0x2B Tsetdate Set Date 44 0x2C Tgettime Get Time 45 0x2D Tsettime Set Time 47 0x2F Fgetdta Get DTA (Disk Transfer Address) 48 0x30 Sversion Get Version Number 49 0x31 Ptermres Terminate and Stay Resident 54 0x36 Dfree Get Drive Free Space 57 0x39 Dcreate Create Directory 58 0x3A Ddelete Delete Directory 59 0x3B Dsetpath Set Current Directory 60 0x3C Fcreate Create File 61 0x3D Fopen Open File 62 0x3E Fclose Close File 63 0x3F Fread Read From File 64 0x40 Fwrite Write To File 65 0x41 Fdelete Delete File 66 0x42 Fseek Seek File Pointer 67 0x43 Fattrib Get/Set File Attributes 69 0x45 Fdup Duplicate File Handle 70 0x46 Fforce Force File Handle 71 0x47 Dgetpath Get Current Directory 72 0x48 Malloc Allocate Memory 73 0x49 Mfree Release Memory 74 0x4A Mshrink Shrink Size of Allocated Block 75 0x4B Pexec Load/Execute Process 76 0x4C Pterm Terminate Process 78 0x4E Fsfirst Search First 79 0x4F Fsnext Search Next 86 0x56 Frename Rename File 87 0x57 Fdatime Get/Set File Timestamp |
GEMDOS calls - sorted by namedecimal hexa name description ---------------------------------------------------------------- 03 0x03 Cauxin Read Character from Standard AUX: 18 0x12 Cauxis Check Status of Standard AUX: Input 19 0x13 Cauxos Check Status of Standard AUX: Output 04 0x04 Cauxout Write Character to Standard AUX: 01 0x01 Cconin Read character from Standard Input 11 0x0B Cconis Check Status of Standard Input 16 0x10 Cconos Check Status of Standard Output 02 0x02 Cconout Write Character to Standard Output 10 0x0A Cconrs Read Edited String from Standard Input 09 0x09 Cconws Write String to Standard Output 08 0x08 Cnecin Read Character from Standard Input, No Echo 17 0x11 Cprnos Check Status of Standard PRN: 05 0x05 Cprnout Write Character to Standard PRN: 07 0x07 Crawcin Raw Input from Standard Input 06 0x06 Crawio Raw I/O to Standard Input/Output 57 0x39 Dcreate Create Directory 58 0x3A Ddelete Delete Directory 54 0x36 Dfree Get Drive Free Space 25 0x19 Dgetdrv Get Default Drive 71 0x47 Dgetpath Get Current Directory 14 0x0E Dsetdrv Set Default Drive 59 0x3B Dsetpath Set Current Directory 67 0x43 Fattrib Get/Set File Attributes 62 0x3E Fclose Close File 60 0x3C Fcreate Create File 87 0x57 Fdatime Get/Set File Timestamp 65 0x41 Fdelete Delete File 69 0x45 Fdup Duplicate File Handle 70 0x46 Fforce Force File Handle 47 0x2F Fgetdta Get DTA (Disk Transfer Address) 61 0x3D Fopen Open File 63 0x3F Fread Read From File 86 0x56 Frename Rename File 66 0x42 Fseek Seek File Pointer 26 0x1A Fsetdta Set DTA (Disk Transfer Address) 78 0x4E Fsfirst Search First 79 0x4F Fsnext Search Next 64 0x40 Fwrite Write To File 72 0x48 Malloc Allocate Memory 73 0x49 Mfree Release Memory 74 0x4A Mshrink Shrink Size of Allocated Block 75 0x4B Pexec Load/Execute Process 76 0x4C Pterm Terminate Process 00 0x00 Pterm0 Terminate Process 49 0x31 Ptermres Terminate and Stay Resident 32 0x20 Super Get/Set/Inquire Supervisor Mode 48 0x30 Sversion Get Version Number 42 0x2A Tgetdate Get Date 44 0x2C Tgettime Get Time 43 0x2B Tsetdate Set Date 45 0x2D Tsettime Set Time |
Executable FilesAn executable file consists of a header followed by images for the text and data segments, zero or more symbol table entries, a fixup offset, and zero or more fixup records: Executable File Parts __________________ | file header | |__________________| | | | text segment | | | |__________________| | data segment | |__________________| | symbols | | | |__________________| | fixup information| |__________________| The file header contains a "magic" number (a signature to indicate that it is an executable file) and several long- words containing size information: Executable File Header ________________________________________ |________________________________________| | 0x00 | word| 0x601A (magic number) | | 0x02 | long| Size of text segment | | 0x06 | long| Size of data segment | | 0x0A | long| Size of BSS segment | | 0x0E | long| Size of symbol table | | 0x12 | long| (reserved) | | 0x16 | long| (reserved) | | 0x1A | long| (reserved) | | 0x1E | | (start of text segment)| |________________________________________| The text and data segment images immediately follow the header. The symbol table, if there is one, follows the data segment. GEMDOS will "fix up" a longword in the text or data segments by adding the base of the text segment to the value already in the longword. The fixup list specifies which longwords need to be relocated. The first item in the fixup list is a longword specifying the offset of the first fixup; the longword is NULL (0L) if there are no fixups. Single bytes following the longword specify offsets to more fixups. The longwords ____ start on word boundaries, or the system will crash. Relocation Bytes ______________________________________________________ |______________________________________________________| | 0 | end of relocation information | | 1 | advance 254 bytes, get next byte | | 2, 4, .. 254| fixup longword at location pointer | | 3, 5, .. 255| (odd numbers, reserved for future use)| |______________________________________________________| The symbol table consists of symbol-table entries, for- matted as: Symbol Table Entry __________________ | | | | | 8 bytes | | symbol name | |__________________| | WORD symbol type | |__________________| | LONG symbol value| | | |__________________| << |
Volume StructureGEMDOS uses the first few sectors of a disk to indicate where files are stored. A volume usually contains five parts; an optional boot sector, two identical FAT tables, a root directory, and a cluster area. When GEMDOS first accesses a drive (or accesses one after a media change), it makes a `GETBPB' (Get BIOS Parame- ter Block) BIOS call to determine how big these areas are, and where they are stored on the disk. GETBPB returns a pointer to a nine-word structure. From this structure, GEM- DOS can puzzle out where the various parts of the file sys- tem are. BIOS Parameter Block (BPB) __________________________________________________ |__________________________________________________| | recsiz| 512 | physical sector size in bytes | | clsiz| 2 | cluster size in sectors | | clsizb| 1024 | cluster size in bytes | | rdlen| | root directory length in sectors| | fsiz| | FAT size, in sectors | | fatrec| | sector# of 1st sector of 2nd FAT| | datrec| | sector# of 1st data sector | | numcl| | number of data clusters on disk | | bflags| | flags | |__________________________________________________| RECSIZ indicates the number of bytes per physi- cal sector; this must be 512 with the current GEM- DOS. CLSIZ indicates the number of sectors in a cluster; this must be 2 in the current GEMDOS. CLSIZB is the number of bytes in a cluster, which must be 1024. RDLEN is the size of the root directory, in sectors. A directory entry uses 32 bytes, so the number of root files available is RDLEN * 512 / 32. FSIZ is the size of each FAT in sectors. FA- TREC is the starting sector number of the first sec- tor of the /second/ FAT. DATREC is the starting sector# of the first cluster. NUMCL is the number of clusters on the device. BFLAGS was supposed to be a bit-vector of flags. Currently only bit 0 is being used; when set it indicates that 16-bit FAT entries (instead of 12-bit ones) are to be used. If there are boot sectors, they occupy logical sectors 0 through FATREC - FSIZ - 1. The second FAT starts at FATREC, and the first FAT starts at FATREC - FSIZ. The root directory starts at FATREC + FSIZ, and the first cluster starts at DATREC. The cluster region is where the data for all files on the volume is kept. A directory entry contains a filename, some flags, the file's creation time and date, the file's size, and the file's starting cluster number. The entry itself is a 32- byte structure that looks like: Directory Entry _______________________ | | | 8-character | | primary name | | | |_______________________| | 3-character | | extension | | | |_______________________| |_______________________| | | | (10 bytes unused) | | | |_______________________| | WORD creation time | |_______________________| | WORD creation date | |_______________________| | WORD starting cluster#| |_______________________| | LONG file length | | | | | |_______________________- All WORDS and LONGS in the directory entry are in 8086 "byte reversed" format. When a file is deleted, the first byte of the name field is set to 0xe5. A subdirectory is a file that contains directory entries. The first two entries in a subdirectory are always the special directories "." and "..". The File Allocation Table (FAT) is used to allocate clusters and to link clusters together into files. FAT entries may be 12 or 16 bits. A file's directory entry con- tains the number of the first cluster in the file. Each cluster's associated FAT entry contains the number of the next cluster in the file, or a number that indicates end- of-file. 12-bit FAT Entries ____________________________________ | value meaning | |____________________________________| | 0x000| free cluster | | 0x001| (impossible) | | 0x002 - 0xfef| next cluster number| | 0xff0 - 0xff7| bad sector | | 0xff8 - 0xfff| end of file | |____________________________________| 16-bit FAT Entries ______________________________________ | value meaning | |______________________________________| | 0x0000| free cluster | | 0x0001| (impossible) | | 0x0002 - 0x7fff| next cluster number| | 0x8000 - 0xffef| (impossible) | | 0xfff0 - 0xfff7| bad sector | |________________|_____________________| For a 12-bit FAT, obtain the next cluster in the file, NCL, given the current cluster number, CL, by: [1] (Multiply by 1.5) NCL = CL + CL / 2 [2] Set NCL to the 16-bit word in the FAT indexed by NCL (it must be byte-swapped to 68000 format as well.) The word might not be on a 68000 word boundary. [3] (Extract the correct 12 bits.) If CL is odd, set NCL = NCL >> 4. [4] (Mask off incorrect bits.) Set NCL = NCL & 0x0FFF. [5] (Interpret the result.) If NCL is 0x0FF8 or higher, then CL was the last cluster in the file. If NCL is zero or in the range 0x0FF0 to 0x0FF7 then there is a file system problem. Otherwise, NCL is the number of the next cluster in the file. For a 16-bit FAT, obtain the next cluster in the file, NCL, given the current cluster number, CL, by: [1] Set NCL to the 16-bit word in the FAT indexed by CL. The word must be byte-swapped into 68000 format. [2] If NCL is 0xfff8 or higher, then CL was the last cluster in the file. If NCL is 0 or in the range 0x8000 to 0xfff7 then there is a file system problem. Otherwise, NCL is the number of the next cluster in the file. To convert from a cluster number, CL, to a logical sec- tor number, LSN: [1] (Adjust for reserved FAT entries.) LSN = CL - 2 [2] Multiply LSN by the number of sectors per cluster (CLSIZ). [3] Add the logical sector# of the first cluster to LSN (DATREC). |