OS9 Assembly Language
The OS9 Level I Assembler
The actual machine instructions executed by a computer are sequences of binary numbers that are difficult and inconvenient for people to deal with directly. Creating a machine language program of any length ny hand is tedious, error prone, and time consuming, making it an almost impossible task. Assembly language bridges the gap between computers and people who must write machine-language programs. In assembly language, descriptive mnemonics (abbreviations) for each machine instruction are used which are much easier to learn, read, and remember, are used instead of numerical codes. The assembler also lets the programmer assign sybolic names to memory addresses and constant values. The assembler also has many other features to make assembly language programming easier
This assembler was designed expressly for the modular, multi-tasking enviroment of the OS-9 Operating System, and incorporates built-in functions for calling OS-9, generating memory modules, encouraging the creation of position-independant code, and maintaining seperate program and data sections. It has also been optimized for the use by OS-9 high-level language compilers such as Pascal and C, and can be used on either OS-9 Level 1 or OS-9 Level 2 systems.
Another noteworthy characteristic of this assembler is it's extremely fast assembly speed which is attributable to it's tree-structured symbol table organization. The tree structure dramatically reduces symbol table searching, which is the most time consuming operation performed bay an assembler
The OS-9 Level Two Relocatable Macro Assembler
RMA is a full-featured relocatable macro assembler and linkage editor designed to be used by advanced programmers or with compiler systems.
RMA lets you assemble sections of assembly-language programs independently to create relocatable object files. The linkage editor, RLINK, takes any number of program sections and/or library sections, and combines them into a single OS-9 memory module RMA's features include:
- OS-9 modular, multi-tasking environment support
- Built-in functions for calling OS-9 system routines
- Position-independent, re-entrant code support
- Creating of standard subroutine libraries by allowing programs to be written and assembled separately and then linked together.
- Macro capabilities
- OS-9 Level Two compatibility
- Automatic resolution of global data and program references
- Conditional assembly and library source file support
About 0S-9 PASCAL
From the OS-9 Pascal Manual
The internal operation of a language as powerful as Pascal must be relatively complex, and running Pascal programs can be quite demanding of the computer. Therefore, microcomputer versions of Pascal traditionally have been quite limited and much slower than their big computer cousins. The gap has been narrowed considerably in 0S-9 Pascal because of two factors. The first factor is the 6809 microprocessor, which was specifically designed to efficiently execute high-level languages such as Pascal. The second factor is the part of 0S-9 Pascal called "PascalS", which allows the Pascal system to utilize disk space as "virtual memory". Being able to utilize disk space as "virtual memory" means that you can run Pascal programs that are much larger than the actual memory size. Indeed, a Pascal compiler as complete as the 0S-9 Pascal compiler would otherwise be too big to fit in your computer's memory.
One other unusual characteristic of 0S-9 Pascal is its ability to compile and run programs in either "P-code" or "native code" forms. "P-codes" are instructions particularly created for an ideal , imaginary "Pascal Computer". The 6809 can't directly execute P-code instructions, so a program called a "P-code interpreter" is used to simulate the ideal "Pascal Computer". Most microcomputer versions of Pascal use the P-code concept because it simplifies the design of the compiler and makes most effic1ient use of a limited amount of memory. Another plus for P-code is that while programs are running, the P-code interpreter can perform thorough error checks and can give excellent diagnostic messages.
Using P-code, the execution speed of programs is relatively slow compared to true machine language. Each P-code instruction causes actual machine language instructions to be run in the interpreter program (which are "overhead" and not actually needed to carry out the original Pascal program). 0S-9 Pascal provides a unique solution to this problem by means of a program called a "native code translator". The native code translator takes a P-code program and translates it to 6809 assembly language (machine language) source code. Both the P-code and the native code forms of the program work exactly the same way - except that the native code version will run from four to ten times faster! And because the output of the translator is a text file that is processed by the standard 0S-9 assembler, you can examine or manually edit it if you wish.
Why even bother with P-code? One reason is that very big programs will only fit in your computer in P-code form. While Pcode is not as fast as native code, in many cases speed is not an important enough factor to bother with the optional translation step. Perhaps the main value of P-code is its use in program debugging because the P-code interpreter has more comprehensive error checking and diagnostics. Typically, 0S-9 Pascal users debug programs in p-code form and translate to native code as a final step.
OS-9 "C" Programming Language
From The C Compiler's User Manual
C was originally developed at the Bel Telephone Laboratories as an implementation language for the UNIX operating system by Brian Kernighan and Dennis Ritchie. They also wrote a book titled The C Programming Language which is universally accepted as the standard for the language. It is an interesting reflection on the language that although no formal industry-wide "standard" was ever developed for C, programs written in C tend to be far more portable between radically different computer systems as compared to so-called "standardized" languages such as BASIC, COBOL, and PASCAL. The reason C is so portable is that the language is so inherently expandable that if some special function is required, the user can create a portable extension to the language, as opposed to the common practice of adding additional statements to the language. For example, the number of special-purpose BASIC dialects defies all reason. A lesser factor is the underlying UNIX operating system, which is also sufficiently versatile to discourage nonstandardization of the language. Indeed, standard C compilers and UNIX are intimately related. Fortunately, the 6809 microprocessor, the OS-9 operating system, and the C language form an outstanding combination. The 6809 was specifically designed to efficiently run high-level languages, and its stack-oriented instruction set and versatile repertoire of addressing modes handle the C language very well. As mentioned previously, UNIX and C are closely related, and because OS-9 is derived from UNIX, it also supports C to the degree that almost any application written in C can be transported from a UNIX system to an OS-9 system, recompiled, and corrected executed.
The Language Implementation
OS-9 C is implemented almost exactly as described in The C Programming Language by Kernighan and Ritchie (hereafter referred to as K&R). A copy of this book, which serves as the language reference manual, is included with each software package. Although this version of C follows the specification faithfully, there are some differences. The differences mostly reflect parts of C that are obsolete or the constraints imposed by memory size limitations.
Differences From the K&R Specification
- Bit fields are not supported.
- Constant expressions for initializers may include arithmetic operators only if all the operands are of type int or char.
- The older forms of assignment operators, =+ or =*, which are recognized by some C compilers, are not supported. You must use the newer forms, +=, *=, etc.
- "#ifdef (#ifndef) ... [#else...] #endif" is supported but "#if <constant expression>" is not.
- It is not possible to extend macro definitions or strings over more than one line of source code.
- The escape sequence for newline '\n' refers to the ASCII carriage return character (used by OS-9 for end-of-line), not linefeed (hex 0A). Programs which use '\n' for end-of-line (which includes all programs in K&R) will still work properly.
Enhancements and Extensions
The "Direct" Storage Class
The 6809 microprocessor instruction for accessing memory via an index register or the stack pointer can be relatively short and fast when they are used in C programs to access "auto" (function local) variables or function arguments. The instructions for accessing global variables are normally not so nice and must be four-bytes long and correspondingly slow. However, the 6809 has a nice feature which helps considerably. Memory, anywhere in a single page (256 byte block), may be accessed with fast, two byte instructions. This is called the "direct page", and at any time its location is specified by the contents of the "direct page register" within the processor. The linkage editor sorts out where this should be, and it need not concern the program, who only needs to specify for the compiler which variables should be in the direct page to give the maximum benefit in code size and execution speed. To this end, a new storage class specifier is recognized by the compiler. In the manner of K&R page 192, the sc-specifier list is extended as follows:
- direct (extension)
- extern direct (extension)
- static direct (extension)
The new keyword may be used in place of one of the other sc-specifiers, and its effect is that the variable will be placed in the direct page. direct creates a global direct page variable. extern direct references an external-type direct page variable and static direct creates a local direct page variable. These new classes may not be used to declare function arguments. "Direct" variables can be initialized but will, as with other variables not explicitly initialized, have the value zero at the start of program execution. 255 bytes are available in the direct page (the linker requires one byte). If all the direct variables occupy less than the full 255 bytes, the remaining global variables will occupy the balance and memory above if necessary. If too many bytes of storage are requested in the direct page, the linkage editor will report an error, and the programmer will have to reduce the use of direct variables to fit the 256 bytes addressable by the 6809.
It should be kept in mind that direct is unique to this compiler, and it may not be possible to transport programs written using direct to other environments without modification.
Embedded Assembly Language
As versatile as C is, occasionally there are some things that can only be done (or done at maximum speed) in assembly language. The OS-9 C compiler permits user-supplied assembly-language statements to be directly embedded in C source programs.
From the Basic09 manual: Basic09 is an enhanced structured BASIC language programming system specially created for the 6809 Advanced Microprocessor. In addition to the standard BASIC language statements and functions, Basic09 includes many of the most useful elements of the Pascal programming language so that programs can be modular, well-structured, and use sophisticated data structures. It also permits full access to almost all of the OS-9 Operating System commands and functions so it can be used as a systems programming language. These features make Basic09 an ideal language for many applications: scientific, business, industrial control, education and more.
Basic09 is unusual in that it is an Interactive Compiler that has the best of both kinds of language system: it gives the fast execution speed typical of compiler languages plus the ease of use and memory space efficiency typical of interpreter languages. Basic09 is truly a complete programming system that includes a powerful text editor, multi-pass compiler, run-time interpreter, high-level interactive debugger, and a system executive. Each of these components was carefully integrated so the user "sees" a friendly, highly interactive programming resource that provides all the tools and helpful "extra" facilities needed for fast, accurate creation and testing of structured programs.
Basic09 RunB GFX GFX2 Inkey SysCall ============ ============ ========= ========== ======= ======= OS-9 Dragon Level 1 5AB5 (23221) <do not have any of these from the Dragon version> OS-9 Level 1 5ACC (23244) 2F99 (12185) 1F5 (501) <N/A> 5E (94) <N/A> OS-9 Level 2 5ACC (23244) 2F99 (12185) 1F5 (501) 8CA (2250) 5F (95) 63 (99) NitrOS-9 Level 1 5A29 (23081) 2FA7 (12199) 1F5 (501) <N/A> 5F (95) 63 (99) NitrOS-9 Level 2 6809 5A29 (23081) 2FA7 (12199) 1F5 (501) 8CA (2250) 5F (95) 63 (99) NitrOS-9 Level 2 6309 5955 (22869) 2FA7 (12199) 1F5 (501) 8CA (2250) 5F (95) 63 (99) ============ ============ ========= ========== ======= =======
(Dragon) (6809) (6309) OS9 Level 1 OS9 Level 1 NOS9 Level 1 OS9 Level 2 NOS9 Level 2 NOS9 Level 2 ============ ============ ============ ============ ============ ============ Basic09 5AB5 (23221) 5ACC (23244) 5A29 (23081) 5ACC (23244) 5A29 (23081) 5955 (22869) RunB ??? 2F99 (12185) 2FA7 (12199) 2F99 (12185) 2FA7 (12199) 2FA7 (12199) GFX ??? 1F5 (501) 1F5 (501) 1F5 (501) 1F5 (501) 1F5 (501) GFX2 ??? <N/A> <N/A> 8CA (2250) 8CA (2250) 8CA (2250) Inkey ??? 5E (94) 5F (95) 5F (95) 5F (95) 5F (95) SysCall ??? <N/A> 63 (99) 63 (99) 63 (99) 63 (99) ============ ============ ============ ============ ============ ============
Comparisons are between OS-9 Level 1 and OS-9 Level 2 versions. All values in hex in case I have it backwards: MSB LSB 10 00 20 00
BASIC09: ======= The difference between Level 1 and Level 2 Basic09 is a 4K data buffer. Level 1 Basic09 has a default workspace size of 4K, and Level 2 has a default workspace size of 8K. Module differences include the MSB of the module header Runtime Variable Storage Size field, the revision number bump to 1, and the module CRC.
RUNB: ==== The Level 1 and Level 2 RunB has the same differences as Basic09.
SYSCALL: ======= Level 1 did not include SysCall, and if it had, it would have been named with all caps (SYSCALL), as all of the modules on the disk are in all caps, including Basic09.
INKEY: ===== The Level 1 Inkey subroutine has 4 bytes that are different from, plus the CRC, and is 1 byte smaller than the Level 2 version (name reference includes the hi- bit set last character): Header differences: Module Size changed from 005E to 005F Module Attributes/Revision changed from 81 to 80 1st field after Header Parity changed from 0012 to 0013 The Edition byte (the first byte after the module name) is a value of 01, and it is the reason the Level 2 version is 1 byte longer than the Level 1 version. It was inserted here in the level 2 version of Inkey. The CRC values differ: 1A6916 as compared to FE0637
GFX: === According to the module header definition, the 8th and 9th bytes are the Attributes/Revision byte and the Header Parity byte. They are changed from 81 and EC in the Level 1 version to 80 and ED in the Level 2 version. The CRC values differ: DDC98B as compared to C29373 This concludes the immediate comparisons of the Level 1 and Level 2 versions of Basic09. Other than the differences stated above, both versions are identical. SysCall was not included on the Level 1 Basic09 diskette as sold by Radio Shack/Tandy. It is my understanding that a assembly source listing for SysCall exists somewhere in the OS-9 manuals. I will modify this document when I have that listing.
CoCo OS-9 Level 1 Basic09 comparison to Dragon OS-9 Level 1 Basic09: (CoCo value is listed first) header differences: Module Size is changed from 5ACC to 5AB5 Module Header Parity changed from A8 to D1 1st int after Header Parity changed from 07C1 to 07AA 3rd int after Header Parity changed from 00DC to 00C5 4th int after Header Parity changed from 1CA5 to 1C8E 5th int after Header Parity changed from 255A to 2543 6th int after Header Parity changed from 31E8 to 31D1 7th int after Header Parity changed from 3C09 to 3BF2 8th int after Header Parity changed from 5084 to 506D 0039-52 RS VERSION 01.00.00. removed from Dragon version 00B7-C1 TANDY CORP changed at 009B-A9 to DRAGON DATA LTD 0822 DD changed at 080B to F4 082D DF changed at 0816 to F6 08A9 7A changed at 0892 to 91 08AF 6B changed at 0898 to 82 CRC value at 5AC9 C5054F changed at 5AB2 to E3C48D This concludes the CoCo and Dragon version comparisons. I do not understand the differences in the code as yet.
SysCall comparisons between OS-9 Level 2 and NOS-9 Level 1 and Level 2 =================== The NitrOS-9 Level 1 and Level 2 versions of SysCall are identical. The OS-9 Level 2 version has differences from the NitrOS-9 versions, as follows: Attributes/Revision byte 81 changed to 80 Header Parity byte 7B changed to 7A CRC F37B74 changed to 8583E2
Source listings for use with asm/rma.
Inkey Level 1
Inkey listing from Basic09 Level 1 Programming manual Revision F February 1983 Appendix A: Sample Programs: pp.107-108 (spacing between fields added by me) *************** * INKEY - a subroutine for BASIC09 by Robert Doggett * Called by: RUN INKEY(StrVar) * RUN INKEY(Path, StrVar) * Inkey determines if a key has been typed on the given path * (Standard Input if not specified), and if so, returns the next * character in the String Variable. If no key has been type, the * null string is returned. If a path is specified, it must be * either type BYTE or INTEGER. 0021 TYPE set SBRTN+OBJCT 0081 REVS set REENT+1 * The Level 2 listing uses SIZE instead of 0 0000 87CD005E mod InKeyEnd,InKeyNam,TYPE,REVS,InKeyEnt,0 000D 496E6B65 InKeyNam fcs "Inkey" D 0000 org 0 Parameters D 0000 Return rmb 2 Return addr of caller D 0002 PCount rmb 2 Num of params following D 0004 Param1 rmb 2 1st param addr D 0006 Length1 rmb 2 size D 0008 Param2 rmb 2 2nd param addr D 000A Length2 rmb 2 size 0012 3064 InKeyEnt leax Param1,S 0014 EC62 ldd PCount,S Get parameter count 0016 10830001 cmpd #1 just one parameter? * this line in the Level 2 listing shows 2727 001A 2717 beq InKey20 ..Yes; default path A=0 001C 10830002 cmpd #2 Are there two params? 0020 2635 bne ParamErr No, abort 0022 ECF804 ldd [Param1,S] Get path number 0025 AE66 ldx Length1,S 0027 301F leax -1,X byte available? 0029 2706 beq InKey10 ..Yes; (A)=Path number 002B 301F leax -1,X Integer? 002D 2628 bne ParamErr ..No; abort 002F 1F98 tfr B,A 0031 3068 InKey10 leax Param2,S 0033 EE02 InKey20 ldu 2,X length of string 0035 AE84 ldx 0,X addr of string 0037 C6FF ldb #$FF 0039 E784 stb 0,X Initialize to null str 003B 11830002 cmpu #2 at least two-byte str? 003F 2502 blo InKey30 ..No 0041 E701 stb 1,X put str terminator 0043 C601 InKey30 ldb #SS.Ready 0045 103F8D OS9 I$GetStt is there an data ready? 0048 2508 bcs InKey90 ..No; exit 004A 108E0001 ldy #1 004E 103F89 OS9 I$Read Read one byte 0051 39 rts 0052 C1F6 InKey90 cmpb #E$NotRdy 0054 2603 bne InKeyErr 0056 39 rts (carry clear) 0057 C638 ParamErr ldb #E$Param Parameter Error 0059 43 InKeyErr coma 005A 39 rts 005B 1A6926 emod 005E InKeyEnd equ *
Inkey Level 2
Inkey listing from Level 2 Basic09 Reference Appendix B: The Inkey Program: pp.B-1,B-2 This listing has differences from the listing in the Level 1 manual. *************** * INKEY - a subroutine for BASIC09 by Robert Doggett * Called by: RUN INKEY(StrVar) * RUN INKEY(Path, StrVar) * Inkey determines if a key has been typed on the given path * (Standard Input if not specified), and if so, returns the next * character in the String Variable. If no key has been type, the * null string is returned. If a path is specified, it must be * either type BYTE or INTEGER. *********************************** * These lines do not exist in the Level 1 listing NAM INKEY IFP1 USE /D0/DEFS/OS9DEFS ENDC *********************************** 0021 TYPE set SBRTN+OBJCT 0081 REVS set REENT+1 * The Level 1 listing uses 0 instead of SIZE 0000 87CD005E mod InKeyEnd,InKeyNam,TYPE,REVS,InKeyEnt,SIZE 000D 496E6B65 InKeyNam fcs "Inkey" D 0000 org 0 Parameters D 0000 Return rmb 2 Return addr of caller D 0002 PCount rmb 2 Num of params following D 0004 Param1 rmb 2 1st param addr D 0006 Length1 rmb 2 size D 0008 Param2 rmb 2 2nd param addr D 000A Length2 rmb 2 size *********************************** * These lines do not exist in the Level 1 listing 000C E$Param equ $38 000E SIZE equ * *********************************** 0012 3064 InKeyEnt leax Param1,S 0014 EC62 ldd PCount,S Get parameter count 0016 10830001 cmpd #1 just one parameter? * this line in the Level 1 listing shows 2717 001A 2727 beq InKey20 ..Yes; default path A=0 001C 10830002 cmpd #2 Are there two params? 0020 2635 bne ParamErr No, abort 0022 ECF804 ldd [Param1,S] Get path number 0025 AE66 ldx Length1,S 0027 301F leax -1,X byte available? 0029 2706 beq InKey10 ..Yes; (A)=Path number 002B 301F leax -1,X Integer? 002D 2628 bne ParamErr ..No; abort 002F 1F98 tfr B,A 0031 3068 InKey10 leax Param2,S 0033 EE02 InKey20 ldu 2,X length of string 0035 AE84 ldx 0,X addr of string 0037 C6FF ldb #$FF 0039 E784 stb 0,X Initialize to null str 003B 11830002 cmpu #2 at least two-byte str? 003F 2502 blo InKey30 ..No 0041 E701 stb 1,X put str terminator 0043 C601 InKey30 ldb #SS.Ready 0045 103F8D OS9 I$GetStt is there an data ready? 0048 2508 bcs InKey90 ..No; exit 004A 108E0001 ldy #1 004E 103F89 OS9 I$Read Read one byte 0051 39 rts 0052 C1F6 InKey90 cmpb #E$NotRdy 0054 2603 bne InKeyErr 0056 39 rts (carry clear) 0057 C638 ParamErr ldb #E$Param Parameter Error 0059 43 InKeyErr coma 005A 39 rts 005B 1A6926 emod 005E InKeyEnd equ *
SysCall Level 1
SysCall Listing November 1984, Volume 4, Number 4 of The Rainbow Magazine Page 281, under the segment title "Microware's Third Annual OS-9 Users Seminar" Mid-page, center column, there is a call-out that says: "SysCall ... lets you program OS-9 system calls directly in your BASIC09 program." Lower-right corner of the page, the last part of the 3rd column: Two Useful Routines We're printing two useful routines this month. SysCall is an assembly language subroutine designed to work with BASIC09. It lets you program OS-9 system calls directly in your BASIC09 program. One of the handiest tools you'll ever find, it was written by Robert Doggett at Microware. Also, we are presenting three BASIC09 procedures that show you how to create and use pipes. The procedure "POpen" creates a pipe by DUPEing one of the standard paths and using it as the path for the pipe that will go to or from the FORKed pipeline process. It uses SysCall. The procedure "OutPipe" calls POpen to create a pipe to a spooler. The pipe lets the output of OutPipe be read and printed by the spooler. If you do not have a spooler program, you can open a path to any other program by changing the parameters in the RUN statement. The procedure "InPipe" calls POpen to create a pipe from the OS-9 MDIR utility command to itself. InPipe can then read the standard output path from MDIR and display its output. Special thanks to Bill Pierce for finding this jewel and bringing it to this collection. The listing below appears exactly as it appears in the Rainbow's article on page 284. The extra comments between lines 00007 and 00008 are mine. I made a correction to the procedure listing for filesize.
THE PROCEDURE SYSCALL Microware OS-9 Assembler 2.1 09/05/84 22:32:33 Page 001 - OS·9 System Symbol Definitions --------------- cut here --------------- 00001 *************************************** 00002 * SYSCALL - a powerful subroutine for use with Basic09 00003 * A special thanks to Robert Doggett for writing this routine. 00004 00005 * Basic09 calling suquence: 00006 * TYPE Registers=CC,A,B,DP:BYTE; X,Y,U:INTEGER 00007 * DIM regs:Registers * * There is no DIM statement for code, which must be a BYTE or INTEGER value, * and a non-DIM'd variable in Basic09 is either a type REAL or, with a $ as the * last character of the name, a 32-character STRING. * DIM code:BYTE * 00008 * RUN SysCall(code,registers) 00009 00010 * SysCall will allow you to execute ANY OS-9 System call from 00011 * your Basic09 programs. BE WARNED!!! SysCall can be VERY 00012 * dangerous, since it permits you to do things you may not want 00013 * done during program execution (like format disks, write 00014 * thousands of bytea all at once, and so on). However, it can 00015 * also be very useful, IF you know what you are doing. 00016 00017 * NOTE: This version of SysCall will cause a Basic09 runtime 00018 * error to occur if your system call returns an error. This can 00019 * be easily overcome, as noted below. If you do this, you 00020 * must check "regs.CC" to see if a system error has occurred. 00021 00022 * Here is an example of one possible use you may have for SysCall 00023 * 00024 * PROCEDURE filesize 00025 * TYPE Registers=CC,A,B,DP:BYTE; X,Y,U:INTEGER 00026 * DIM regs:Registers 00027 * DIM path,callcode:BYTE \(* or INTEGER *) 00028 * OPEN #path,"test":READ 00029 * regs.A:=path 00030 * regs.B:=2 \(* I$GetStt code *) 00031 * RUN SysCall(callcode,regs) 00032 * CLOSE #path 00033 * PRINT USING "filesize = 0',2(h4)",regs.X; regs.U 00034 00035 USE /d0/defs/os9defs 00421 opt 1 00422 00423 00424 0021 TYPE set SBRTN+ONJCT 00425 0081 REVS set REENT+1 00426 0000 87CD005E mod SyCalEnd,SyCalNam,TYPE,REVS,SyCalEnt,0 00427 000D 53797343 SyCalNam fcs "SysCall" 00428 0014 02 fcb 2 edition number 00429 00430 0038 E$Paras equ 56 Basic09's parameter error code 00431 103F M.OS9 equ $103F OS-9 system call machine code 00432 0039 M.RTS equ $39 rts machine code 00433 00434 D 0000 org 0 stacked variable 00435 D 0000 Return rmb 2 Return address 00436 D 0002 PCount rmb 2 number of params passed 00437 D 0004 Function rmb 4 OS-9 function code 00438 D 0008 Regs rmb 4 Register image 00439 00440 0015 EC62 SyCalEnt ldd PCount,s Get parameter count 00441 0017 10830002 cmpd #2 exactly 2 parameters? 00442 001B 263A bne ParamErr abort if not 00443 001D EC6A ldd Regs+2,s check size of register image 00444 001F 1083000A cmpd #10 exactly 10 bytes? 00445 0023 2632 bne ParamErr abort if not --------------- cut here --------------- Microware OS-9 Assembler 2.1 09/05/84 22:32:33 Page 002 - OS·9 System Symbol Definitions --------------- cut here --------------- 00446 0025 ECF804 ldd [Function,S] get os-9 function code 00447 0028 AE66 ldx Function+2,S get size of function param 00448 002A 301F leax -1,X INTEGER? 00449 002C 2629 bne ParamErr abort if not 00450 002E 1F98 tfr B,A 00451 00452 * Now you build your OS9 call and return from subroutine on 00453 * stack (A)=OS9 function call 00454 00455 0030 C639 SysCall ldb #M.RTS get "rts" machine code 00456 0032 3406 pshs D 00457 0034 CC103F ldd #M.OS9 get OS-9 machine code 00458 0037 3406 pshs D 00459 0039 EE6C ldu Regs+4,S get register image ptr 00460 003B EC41 ldd R$D,U initialize regs for system call 00461 003D AE44 ldx R$X,U 00462 003F 10AE46 ldy R$Y,U 00463 0042 EE48 ldu R$U,U 00464 0044 ADE4 jsr 0,S execute system call 00465 0046 3441 pshs CC,U save CC,U 00466 0048 EE6F ldu Regs+7,S 00467 004A 3348 leau R$U,U 00468 004C 363E pshu A,B,DP,X,Y return unpdatd regs to caller 00469 004E 3512 puls A,X get CC,U 00470 0050 A7C2 sta ,-U 00471 0052 AF48 stx R$U,U 00472 0054 3264 leas 4,S discard OS-9 call subroutine 00473 00474 * If you want to eliminate the possibility of a runtime error 00475 * remove the comment designator (*) from the next line 00476 00477 * clrb 00478 0056 39 rts 00479 0057 53 ParamErr comb return carry set 00480 0058 C638 ldb #E$Param Parameter error 00481 005A 39 rts 00482 00483 005B B931F4 emod 00484 005E SyCalEnd equ * 00000 error(s) 00000 warning(s) $005E 00094 program bytes generated $00E5 00229 data bytes allocated $1006 04102 bytes used for symbols