;; Interface.ASM ;; Copyright 1986, James M Synge ;; ;; This file contains the assembly language interfaces which ;; allow the C routines to be called from any language which ;; can push arguments on to the stack. far code far data ;; Imported Functions: public _Library_Open public _Library_Close public _Library_Expunge public _CreateTask public _DeleteTask ;; Exported Functions: public __Library_Open public __Library_Close public __Library_Expunge public __CreateTask public __DeleteTask ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Due to the fact that the Aztec C68K compiler does not use ;; the same register allocation as the rest of the system, ;; it tromps on some of the registers which it is supposed ;; to preserve. It is designed to be the top level, making ;; calls to the rest of the system and NOT being called by ;; the OS. ;; ;; Using version 3.4a of the compiler, I find it necessary ;; to save A6. Version 3.2a also stepped on D2 and D3. I ;; have not yet seen any use of register A4, even though I'm ;; using the +R option on the CC command line. Nonetheless, ;; I'll be cautious, and save A4. ;; ;; So? So I've written an interlude for each of the ;; routines which the OS will be calling. These interludes ;; know where the arguments are in the registers, and push ;; them onto the stack where they are useful. ;; ;; And after these interludes are the library specific ;; interlude routines. These are designed to have their ;; arguments on the stack, as if called by a C routine. AztecBugList: reg a4/a6 AztecBugSize: equ 2 ; 2 registers ; AztecBugList_3_2a: reg d2/d3/a4/a6 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; These are the interlude routines for Library_Open, ;; Library_Close and Library_Expunge. They enable these C ;; routines to receive the arguments which are in registers. __Library_Open: movem.l AztecBugList,-(sp) move.l d0,-(sp) ; Push the version move.l a6,-(sp) ; and the lib base jsr _Library_Open addq.l #8,sp ; Pop them movem.l (sp)+,AztecBugList rts __Library_Close: movem.l AztecBugList,-(sp) move.l a6,-(sp) ; Push lib base jsr _Library_Close addq.l #4,sp ; Pop it movem.l (sp)+,AztecBugList rts __Library_Expunge: movem.l AztecBugList,-(sp) move.l a6,-(sp) ; Push lib base jsr _Library_Expunge addq.l #4,sp ; Pop it movem.l (sp)+,AztecBugList rts ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; ;; Library specific interface routines. These first push ;; certain registers to the stack to protect them, then push ;; the arguments from earlier on the stack. The only reason ;; this is done is so that we can protect two of the ;; registers. Otherwise the need for these silly routines ;; would totally disappear. ;; ;; In order to make it easy for those not familiar with ;; 68000 assembly language to add their own routines to a ;; library, and the corresponding interface routines, I've ;; written a macro which can be invoked to generate all the ;; code to protect the registers and move the arguments. ;; The macro, protect, is defined in the file Protect.i, but ;; I don't recommend reading it until after you get a good ;; feeling for the way macro's and assembly work. ;; ;; It is very easy to use protect. The syntax should be: ;; ;; label PROTECT.L address,n ;; ;; where label is the name of the routine you are creating, ;; for example __CreateTask below; address is the name of a ;; C routine (with the underscore prepended), just like ;; _CreateTask below; and finally n is the number of ;; longword arguments the routine takes. No support is ;; supplied for variable numbers of arguments. Nor support ;; for arguments which are not longwords. include protect.i ; CreateTask(Task_Name, Startup_Routine, Cleanup_Routine, ; Priority, Stack_Size) __CreateTask protect.l _CreateTask,5 ; DeleteTask( Child ) __DeleteTask: protect.l _DeleteTask,1 ; Now that was pretty painless, wasn't it. Macros are great ds.w 0 END