home *** CD-ROM | disk | FTP | other *** search
- ; Latticelib.a: Amiga shared runtime library shell for Lattice 'C' 5.02+
- ; By Rick Huebner, 28 October 1989. Released to the Public Domain.
- ; Derived from sample.library.asm in ROM Kernal Reference Manual and other
- ; sources.
-
- ; Provides RomTag and other magic thingies needed to make a set of
- ; C routines into a library. Should work with most any set of routines;
- ; just substitute in the proper external labels. This file should be the
- ; first one given in the link list, so that the RomTag struct can be quickly
- ; & easily found by the system when the library is opened.
-
- ; 5.04 note: I just got done trying to use the new libent and libinit modules
- ; provided with Lattice C 5.04, and ran into a few problems. I'm probably
- ; not using them quite right (the update docs are pretty sketchy), but I'm
- ; not going to waste any more time on them. I'd already written and tested
- ; this stuff before 5.04 came, and it works well. If it ain't broke...
-
- INCLUDE "exec/types.i"
- INCLUDE "exec/libraries.i"
- INCLUDE "exec/lists.i"
- INCLUDE "exec/initializers.i"
- INCLUDE "exec/resident.i"
-
- ; Things we define for external reference (for easier debuggging)
- XDEF LibStart
- XDEF RomTag
- XDEF LibName
- XDEF LibIDString
- XDEF LibInit
- XDEF LibOpen
- XDEF LibClose
- XDEF LibExpunge
- XDEF LibExtFunc
- XDEF LibEnd
-
- ; Our library base structure description
- STRUCTURE XPRBase,LIB_SIZE
- ULONG xb_SegList
- LABEL XPRBase_SIZEOF
-
-
- SECTION text,code
-
- ; Things we need others to define
- XREF @XProtocolCleanup
- XREF @XProtocolSetup
- XREF @XProtocolSend
- XREF @XProtocolReceive
- XREF @XProtocolHostMon
- XREF @XProtocolUserMon
- XREF __BSSBAS
- XREF __BSSLEN
- XREF _AbsExecBase
- XREF _LVOOpenLibrary
- XREF _LVOCloseLibrary
- XREF _LVORemove
- XREF _LVOFreeMem
-
-
- ; Supposed start of executable code. This is where execution
- ; will start if anybody's silly enough to try and run the library
- ; from the command line. Just return the highest error code we
- ; conveniently can to tell them they screwed up.
- LibStart:
- moveq #$7F,d0
- rts
-
- ; Where the magic begins. OpenLibrary actually looks through the
- ; library file contents trying to find this table by locating the
- ; magic RTC_MATCHWORD value followed by its own address. This
- ; table then tells OpenLibrary where to find other things it needs.
- ; This needs to be close to the front of your library file to cut
- ; down on the amount of searching OpenLibrary does; that's why
- ; this object file should be first in the link list.
- RomTag: dc.w RTC_MATCHWORD ; Magic value to search for to find table
- dc.l RomTag ; Address of matchword; the two together prevent accidental matches
- dc.l LibEnd ; Address of end of library handler code
- dc.b RTF_AUTOINIT ; Request system to automatically initialize our library
- dc.b VERSION ; Version number of our library (defined below)
- dc.b NT_LIBRARY ; Node type = Library
- dc.b 0 ; Node priority = 0 (normal)
- dc.l LibName ; Name of this library file, for debugging info
- dc.l LibIDString ; More debugging info
- dc.l inittable ; Initialization table used by RTF_AUTOINIT
-
- VERSION EQU 2
- REVISION EQU 0
- LibName:
- dc.b "xprzmodem.library",0
- LibIDString:
- dc.b "xprzmodem 2.0 (28 Oct 1989)",13,10,0
-
- ds.w 0
-
- inittable:
- dc.l XPRBase_SIZEOF ; Size of our library base struct
- dc.l functable ; Where our function addresses are
- dc.l datatable ; Initialization info for our library base struct
- dc.l LibInit ; Library initialization routine address
-
- functable:
- dc.l LibOpen ; Addresses of all library functions
- dc.l LibClose ; First 4 MUST be provided, in this order
- dc.l LibExpunge
- dc.l LibExtFunc
- dc.l @XProtocolCleanup ; The meat of the library.
- dc.l @XProtocolSetup ; Since the XPR spec requires the args
- dc.l @XProtocolSend ; to be passed in the same registers that
- dc.l @XProtocolReceive ; Lattice uses for -rr, we can just let the
- dc.l @XProtocolHostMon ; calling program jump straight into the
- dc.l @XProtocolUserMon ; C routines, with no glue code required.
- dc.l -1
-
- ; Things for the system to automatically initialize for us via RTF_AUTOINIT request
- datatable:
- INITBYTE LN_TYPE,NT_LIBRARY
- INITLONG LN_NAME,LibName
- INITBYTE LIB_FLAGS,LIBF_SUMUSED | LIBF_CHANGED
- INITWORD LIB_VERSION,VERSION
- INITWORD LIB_REVISION,REVISION
- INITLONG LIB_IDSTRING,LibIDString
- dc.l 0
-
-
- ; System interface routines. Exec has performed Forbid() before
- ; getting here, so do this stuff quick and get the hell out.
-
-
- ; Routine which is executed by the system as part of first OpenLibrary
- ; call, when the library is first loaded into RAM from disk.
- ; D0 = library base pointer, A0 = segment list pointer. Must return
- ; nonzero in D0 if initialization worked, or zero if it failed.
- LibInit:
- move.l d0,-(sp) ; Save D0 for return code
- move.l d0,a1 ; A1 = library base
- move.l a0,xb_SegList(a1) ; Save seglist addr for future expunge
- lea __BSSBAS,a0 ; Initialize BSS memory to 0s
- move.l #__BSSLEN,d0
- moveq #0,d1
- bra.s clr_lp
- clr_bss move.l d1,(a0)+
- clr_lp dbf d0,clr_bss
- move.l (sp)+,d0 ; Return nonzero = success
- rts
-
- ; Open the library. Executed by system as part of OpenLibrary call,
- ; after loading the library into RAM and calling LibInit if necessary.
- ; D0 = version, A6 = library base. Return nonzero if open worked,
- ; or zero if open failed for some reason.
- LibOpen:
- addq.w #1,LIB_OPENCNT(a6) ; Increment open count
- bclr #LIBB_DELEXP,LIB_FLAGS(a6) ; Clear delayed expunge flag
- move.l a6,d0 ; Return nonzero = success
- rts
-
- ; Close the library. Executed by system as part of CloseLibrary call.
- ; A6 = library base. Return seglist address if a delayed expunge
- ; was performed, else return 0 if library is still loaded.
- LibClose:
- moveq #0,d0 ; Init return value = 0
- subq.w #1,LIB_OPENCNT(a6) ; Decrement open count
- bne.s dontexpunge ; If still open by others, can't expunge
- btst #LIBB_DELEXP,LIB_FLAGS(a6) ; Was an expunge requested while we were open?
- beq.s dontexpunge
- bsr.s LibExpunge ; If so, do it now
- dontexpunge:
- rts
-
- ; Expunge the library (remove it from RAM). Executed by system
- ; memory allocation routine when memory gets tight. A6 = library
- ; base. Return seglist address if library was closed and we were
- ; able to expunge, else return 0 if library is still loaded.
- LibExpunge:
- movem.l d2/a5/a6,-(sp)
- move.l a6,a5
- move.l _AbsExecBase,a6 ; Get ExecBase for future use
- tst.w LIB_OPENCNT(a5) ; Is library open?
- beq.s doexpunge
- bset #LIBB_DELEXP,LIB_FLAGS(a5) ; If so, set delayed expunge flag
- moveq #0,d0 ; and return 0
- bra.s expungedone
- doexpunge:
- move.l xb_SegList(a5),d2 ; Save seglist address in D2
- move.l a5,a1 ; A1 = library base address
- jsr _LVORemove(a6) ; Unlink library node from system library list
- moveq #0,d0 ; Compute total size of library node
- move.w LIB_NEGSIZE(a5),d0 ; D0 = bytes used before base
- move.l a5,a1
- sub.l d0,a1 ; A1 = base - negsize
- add.w LIB_POSSIZE(a5),d0 ; D0 = possize + negsize
- jsr _LVOFreeMem(a6) ; Free library node memory
- move.l d2,d0 ; Return segment list address
- expungedone:
- movem.l (sp)+,d2/a5/a6
- rts
-
- ; "Extra" function (room for future growth?). We don't need it,
- ; so dummy it out.
- LibExtFunc:
- moveq #0,d0
- rts
-
- LibEnd:
- END
-