home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
disks
/
disk459.lzh
/
XprZmodem
/
latticelib.a
< prev
next >
Wrap
Text File
|
1991-02-18
|
8KB
|
256 lines
; 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 XProtocolCleanup
XDEF XProtocolSetup
XDEF XProtocolSend
XDEF XProtocolReceive
XDEF XProtocolHostMon
XDEF XProtocolUserMon
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 10
LibName:
dc.b "xprzmodem.library",0
LibIDString:
dc.b "xprzmodem 2.10 (12 Feb 1991)",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
dc.l XProtocolSend
dc.l XProtocolReceive
dc.l XProtocolHostMon
dc.l XProtocolUserMon
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
; Added glue to protect the comm program from having us munge its registers
; when it calls our code, due to bug which caused us to munge the A6
; register in an earlier version. Since the XPR spec requires the arguments
; to be passed in the same registers that Lattice uses for function call
; register arguments, all we have to do is save the non-changeable registers
; on entry and restore them on exit.
XProtocolCleanup:
movem.l d2-d7/a2-a6,-(sp)
jsr @XProtocolCleanup
movem.l (sp)+,d2-d7/a2-a6
rts
XProtocolSetup:
movem.l d2-d7/a2-a6,-(sp)
jsr @XProtocolSetup
movem.l (sp)+,d2-d7/a2-a6
rts
XProtocolSend:
movem.l d2-d7/a2-a6,-(sp)
jsr @XProtocolSend
movem.l (sp)+,d2-d7/a2-a6
rts
XProtocolReceive:
movem.l d2-d7/a2-a6,-(sp)
jsr @XProtocolReceive
movem.l (sp)+,d2-d7/a2-a6
rts
XProtocolHostMon:
movem.l d2-d7/a2-a6,-(sp)
jsr @XProtocolHostMon
movem.l (sp)+,d2-d7/a2-a6
rts
XProtocolUserMon:
movem.l d2-d7/a2-a6,-(sp)
jsr @XProtocolUserMon
movem.l (sp)+,d2-d7/a2-a6
rts
LibEnd:
END