;; 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
