;
; MatrixLib.a - shared library assembly header
;
; Contains the Resident and Library structures, jump vector table,
; user data, and function stub routines
;
; This code is FREELY DISTRIBUTABLE but NOT PUBLIC DOMAIN
; (Written by Randy Finch)
;

VERSION     equ     1
REVISION    equ     0

	    CSECT text

	    XDEF  _LibName,_LibID,_SysBase,_MathIeeeDoubBasBase

; Library C functions to be accessed from assembly

	    XREF  _CInit
	    XREF  _LibOpen
	    XREF  _LibClose
	    XREF  _LibExpunge

; User C functions to be accessed from assembly

	    XREF  _AllocLVector
	    XREF  _AllocLMatrix
	    XREF  _FreeLVector
	    XREF  _FreeLMatrix
	    XREF  _AddLVectors
	    XREF  _SubLVectors
	    XREF  _AddLMatrices
	    XREF  _SubLMatrices
	    XREF  _MultLMatrices
	    XREF  _MultLVectorMatrix
	    XREF  _MultLMatrixVector
	    XREF  _TransposeLMatrix

	    XREF  _AllocDVector
	    XREF  _AllocDMatrix
	    XREF  _FreeDVector
	    XREF  _FreeDMatrix
	    XREF  _AddDVectors
	    XREF  _SubDVectors
	    XREF  _AddDMatrices
	    XREF  _SubDMatrices
	    XREF  _MultDMatrices
	    XREF  _MultDVectorMatrix
	    XREF  _MultDMatrixVector
	    XREF  _TransposeDMatrix

	    XREF  _InvertDMatrix    ;no equivalent for LONG
				    ;for obvious reasons


; In case we are executed as a program

Start:	    clr.l   D0
	    rts

; romtag (or Resident) structure -
;     Exec looks for $4AFC followed by a pointer to it near the
;	  beginning of load point.
;     Lets Exec know how to set up library.

InitDesc:   dc.w    $4AFC	;RTC_MATCHWORD
	    dc.l    InitDesc	;Pointer to beginning
	    dc.l    EndCode	;Not sure it matters
	    dc.b    0		;flags (NO RTF_AUTOINIT)
	    dc.b    VERSION	;version
	    dc.b    9		;NT_LIBRARY
	    dc.b    0		;priority (doesn't matter)
	    dc.l    _LibName	;Name of library (given below)
	    dc.l    _LibID	;ID string (note CR-LF at end below)
	    dc.l    Init	;Pointer to init routine

_LibName:   dc.b    "Matrix.library",0
_LibID:     dc.b    "Matrix.library 1.00 (21 Jan 1990)",13,10,0

; Force word alignment

	    ds.w    0

; Here is the function list or jump vectors.
; If you use MakeLibrary() this is not needed, but a table of vectors
;  must be passed to MakeLibrary() which allocates space for the jump
;  vectors.

Funcs:

; First the user functions - reverse order from .fd file

	    jmp  AInvertDMatrix     ;no equivalent for LONG

	    jmp  ATransposeDMatrix
	    jmp  AMultDMatrixVector
	    jmp  AMultDVectorMatrix
	    jmp  AMultDMatrices
	    jmp  ASubDMatrices
	    jmp  AAddDMatrices
	    jmp  ASubDVectors
	    jmp  AAddDVectors
	    jmp  AFreeDMatrix
	    jmp  AFreeDVector
	    jmp  AAllocDMatrix
	    jmp  AAllocDVector

	    jmp  ATransposeLMatrix
	    jmp  AMultLMatrixVector
	    jmp  AMultLVectorMatrix
	    jmp  AMultLMatrices
	    jmp  ASubLMatrices
	    jmp  AAddLMatrices
	    jmp  ASubLVectors
	    jmp  AAddLVectors
	    jmp  AFreeLMatrix
	    jmp  AFreeLVector
	    jmp  AAllocLMatrix
	    jmp  AAllocLVector

; System functions are always here in this order

	    jmp      ALibReserved   ;Not used at this time
	    jmp      ALibExpunge    ;For removing library
	    jmp      ALibClose	    ;Guess what? Close the library
	    jmp      ALibOpen	    ;Right again! Open the library

; Here is the Library structure.  Must be at this location, just
;   after the jump vectors.  This must be initialized if not using
;   MakeLibrary().

Lib:

; First five items make up the Node structure which is the first
;  data item in the Library structure.

	    dc.l     0		    ;ln_Succ  (next node)
	    dc.l     0		    ;ln_Pred  (previous node)
	    dc.b     9		    ;ln_Type  (NT_LIBRARY)
	    dc.b     0		    ;ln_Pri   (priority)
	    dc.l     _LibName	    ;ln_Name  (Library name)

; The next nine items make up the remainder of the Library structure

	    dc.b     6		    ;lib_Flags (LIBF_CHANGED | LIBF_SUMUSED)
	    dc.b     0		    ;lib_pad

; The next value will change when the number of user functions change.

	    dc.w     Lib-Funcs	    ;lib_NegSize (size of jump vectors)
				    ; (6 bytes per vector)

; The next value will change when the number of user data items change.
;  The value is (Library structure size)+(User data size) = 34+User.

	    dc.w     EndData-Lib    ;lib_PosSize (size of data)

	    dc.w     VERSION	    ;lib_Version
	    dc.w     REVISION	    ;lib_Revision
	    dc.l     _LibID	    ;lib_IdString
	    dc.l     0		    ;lib_Sum  (the checksum)
	    dc.w     0		    ;lib_OpenCnt (number of opens on lib)

; User data can be placed here.  If you are using C, only the data needed
;  in assembly code needed here.  Make sure all user data appears before
;  the EndData label so lib_PosSize will be correct.

_seglist:		dc.l	 0
_SysBase:		dc.l	 0
_MathIeeeDoubBasBase:	dc.l	 0

; EndData label only used for data size in lib_PosSize above

EndData:

; Initialization routine -
;  This is only called once - when the library is first loaded.
;  Exec passes the load point or seglist of the library in A0.
;  Since we are not auto init, the Library structure pointer, Lib, must
;   be passed to the C routine so AddLibrary() can be called.

Init:	    move.l   A6,_SysBase ;Save A6 (SysBase)
	    move.l   A0,_seglist ;Save segment list
	    lea      Lib,A1	 ;Bring in Library base
	    move.l   A1,-(sp)    ;Put Library base on stack
	    jsr      _CInit	 ;Call our C init routine
	    addq.l   #4,sp	 ;Reset the stack pointer
	    rts

; Open routine -
;  This is called each time an application opens the library.
;  Just set up stack here and call the C routine.

ALibOpen:   move.l  D0,-(sp)     ;Put version number on the stack
	    move.l  A6,-(sp)     ;Put Library base on stack
	    jsr     _LibOpen	 ;Call our C routine
	    addq.l  #8,sp	 ;Adjust the stack
	    rts

; Close routine -
;  This is called each time an application closes the library.
;  Again, just set up stack and call the C routine.

ALibClose:  move.l  A6,-(sp)     ;Put Library base on stack
	    jsr     _LibClose	 ;Call our C routine
	    addq.l  #4,sp	 ;Adjust the stack
	    rts

; Expunge routine -
;  When all applications that opened the library have also closed the
;   library, this routine is called to clean up and unload the library.
;  Again, set up stack and call the C routine.

ALibExpunge:
	    move.l  A6,-(sp)     ;Put Library base on stack
	    jsr     _LibExpunge  ;Call our C routine
	    addq.l  #4,sp	 ;Adjust the stack
	    rts

; This is a reserved routine and not used at this time.

ALibReserved:
	    clr.l   0
	    rts

; User routines -
;  Again these are used to set up the stack to call our C functions.
;  When the routines are called, the arguments will be in registers.
;  These arguments must be put on the stack before executing the C function.
;  The stack will be adjusted by 4 for each argument after returning from
;   the C function.
;  Arguments are placed on the stack from right to left.

; Here are the setup routines for the LONG functions

AAllocLVector:
	    move.l   D0,-(sp)
	    jsr      _AllocLVector
	    addq.l   #4,sp
	    rts

AAllocLMatrix:
	    movem.l  D0-D1,-(sp)
	    jsr      _AllocLMatrix
	    addq.l   #8,sp
	    rts

AFreeLVector:
	    move.l   D0,-(sp)
	    move.l   A0,-(sp)
	    jsr      _FreeLVector
	    addq.l   #8,sp
	    rts

AFreeLMatrix:
	    movem.l  D0-D1,-(sp)
	    move.l   A0,-(sp)
	    jsr      _FreeLMatrix
	    add.l    #12,sp
	    rts

AAddLVectors:
	    move.l   D0,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _AddLVectors
	    add.l    #16,sp
	    rts

ASubLVectors:
	    move.l   D0,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _SubLVectors
	    add.l    #16,sp
	    rts

AAddLMatrices:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _AddLMatrices
	    add.l    #20,sp
	    rts

ASubLMatrices:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _SubLMatrices
	    add.l    #20,sp
	    rts

AMultLMatrices:
	    movem.l  D0-D2,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _MultLMatrices
	    add.l    #24,sp
	    rts

AMultLVectorMatrix:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _MultLVectorMatrix
	    add.l    #20,sp
	    rts

AMultLMatrixVector:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _MultLMatrixVector
	    add.l    #20,sp
	    rts

ATransposeLMatrix:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A1,-(sp)
	    jsr      _TransposeLMatrix
	    add.l    #16,sp
	    rts

; Here are the setup routines for the DOUBLE functions

AAllocDVector:
	    movem.l  D0,-(sp)
	    jsr      _AllocDVector
	    addq.l   #4,sp
	    rts

AAllocDMatrix:
	    movem.l  D0-D1,-(sp)
	    jsr      _AllocDMatrix
	    addq.l   #8,sp
	    rts

AFreeDVector:
	    move.l   D0,-(sp)
	    move.l   A0,-(sp)
	    jsr      _FreeDVector
	    addq.l   #8,sp
	    rts

AFreeDMatrix:
	    movem.l  D0-D1,-(sp)
	    move.l   A0,-(sp)
	    jsr      _FreeDMatrix
	    add.l    #12,sp
	    rts

AAddDVectors:
	    move.l   D0,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _AddDVectors
	    add.l    #16,sp
	    rts

ASubDVectors:
	    move.l   D0,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _SubDVectors
	    add.l    #16,sp
	    rts

AAddDMatrices:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _AddDMatrices
	    add.l    #20,sp
	    rts

ASubDMatrices:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _SubDMatrices
	    add.l    #20,sp
	    rts

AMultDMatrices:
	    movem.l  D0-D2,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _MultDMatrices
	    add.l    #24,sp
	    rts

AMultDVectorMatrix:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _MultDVectorMatrix
	    add.l    #20,sp
	    rts

AMultDMatrixVector:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _MultDMatrixVector
	    add.l    #20,sp
	    rts

ATransposeDMatrix:
	    movem.l  D0-D1,-(sp)
	    movem.l  A0-A1,-(sp)
	    jsr      _TransposeDMatrix
	    add.l    #16,sp
	    rts

AInvertDMatrix:
	    move.l   D0,-(sp)
	    movem.l  A0-A2,-(sp)
	    jsr      _InvertDMatrix
	    add.l    #16,sp
	    rts

EndCode:
	    END

