home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
dirs
/
resident_396.lzh
/
Resident
/
Resident.asm
< prev
next >
Wrap
Assembly Source File
|
1990-10-29
|
9KB
|
319 lines
*--------------------------------------------------------------------*
* Startup code to create reentrant program files using the
* Manx Aztec 'C' compiler (any version).
*
* Created by: Olaf Barthel, MXM
* Brabeckstrasse 35
* D-3000 Hannover 71
*
* Federal Republic of Germany
*
*
* Z-Net: O.BARTHEL@A-Link-H
* Fido: Olaf Barthel@2:247/200
* Sub: olsen@veeble.uucp
* UUCP: olsen%veeble@horga.as.sub.org
*
* Copyright (C) 1990 by MXM, all rights reserved.
*
*--------------------------------------------------------------------*
*
* This startup code permits to create 100% reentrant programs.
* Neither is arp.library required, nor is the program to be
* terminated via exit() (such as with Lattice/SAS 'C').
*
* The following conditions must be met for the program to
* work properly:
*
* 1) The program MUST not use the large code/large data model.
*
* 2) The program MUST not use scatter loading or overlays.
*
* Since the entire data segment, containing initialized
* and uninitialized data (bss), is cloned both data types
* will reside in the same type of memory (chip/public).
* This may not be a problem since it already is the default
* with the small memory/small data model.
*
* Important! Your program MUST not perform a segment split
* using the detach.o?? module or its segment list
* will be deallocated. Should this happen the next
* call to your resident program will crash your
* Amiga!
*
* Should you discover any 'undocumented features' or errors
* in this program, please DO inform me ASAP!
*
*--------------------------------------------------------------------*
*
* To create a resident program, use the following sequence:
*
* AS Resident.asm
* CC <Programm.c>
*
* LN <Programm.o> Resident.o -Lc
*
*--------------------------------------------------------------------*
include "exec/types.i"
include "exec/tasks.i"
include "exec/alerts.i"
include "exec/memory.i"
include "exec/execbase.i"
include "libraries/dosextens.i"
*--------------------------------------------------------------------*
*
* Global macro definitions (doesn't use asmsupp.i).
*
*--------------------------------------------------------------------*
CALL macro
xref _LVO\1
jsr _LVO\1(a6)
endm
AbsExecBase equ (4).w
*--------------------------------------------------------------------*
*
* Global static and shared data.
*
*--------------------------------------------------------------------*
dseg
DosName:
dc.b 'dos.library',0 ; Name of dos.library.
MemName:
dc.b 'MXM',0 ; Identification of the
; cloned data segment.
public __H1_org,__H1_end,__H2_org,__H2_end
public __savsp,_SysBase,_DOSBase
*--------------------------------------------------------------------*
cseg
entry .begin
public .begin,_geta4,__main
mc68881
*--------------------------------------------------------------------*
*
* Global entry point of the program to follow.
*
*--------------------------------------------------------------------*
.begin
move.l sp,a3 ; Remember stackpointer.
far data
lea __H1_org+32766,a4 ; Get the data base register.
near data
lea __H1_end,a1
lea __H2_org,a2
cmp.l a1,a2 ; Small code/small data?
bne Error1 ; Obviously not!
movem.l d0/a0,-(sp) ; Remember command line.
lea __H1_org,a1 ; Where's the data segment?
move.l AbsExecBase,a6 ; SysBase.
CALL TypeOfMem ; Check memory type
bset #MEMB_CLEAR,d0 ; We want clear memory.
bclr #MEMB_FAST,d0 ; Not necessarily fast mem!
*--------------------------------------------------------------------*
*
* We will create a MemEntry structure right on the stack and
* will copy the contents of the data segment to the allocated
* block of memory.
*
*--------------------------------------------------------------------*
pea (__H2_end-__H1_org).w ; Length of data segment.
move.l d0,-(sp) ; Type of memory.
pea (1).w ; Number of entries (1).
clr.l -(sp) ; Node...
clr.l -(sp) ; Still node...
clr.l -(sp) ; Ever still node...
lea (sp),a0 ; Start of MemEntry.
CALL AllocEntry ; Allocate!
add.w #24,sp ; Fix the stack.
move.l d0,a1 ; Did we get an entry?
beq Error2 ; Fix the stack and quit!
pea (a1) ; Put it on the stack.
*--------------------------------------------------------------------*
*
* To help geta4() to identify the MemEntry we will give it
* a unique name.
*
*--------------------------------------------------------------------*
lea MemName,a0 ; Get the node name.
move.l a0,LN_NAME(a1) ; Put it in the MemEntry.
move.l ThisTask(a6),a0 ; Get current task.
lea TC_MEMENTRY(a0),a0 ; Look for MemList.
CALL AddTail ; Add the MemEntry.
move.l (sp)+,a1 ; Get the MemEntry.
move.l ML_SIZE+ME_ADDR(a1),a1 ; Remember memory block.
lea __H1_org,a0 ; Get start of data segment.
move.l #((__H1_end-__H1_org)/4)-1,d0 ; Remember its length.
*--------------------------------------------------------------------*
*
* This loop will copy the contents of the data segment to
* our 'fake' segment.
*
*--------------------------------------------------------------------*
1$ move.l (a0)+,(a1)+ ; Copy data.
dbra d0,1$
*--------------------------------------------------------------------*
*
* Do the last setups for the main program.
*
*--------------------------------------------------------------------*
start bsr _geta4 ; Load the base register.
move.l a3,__savsp ; Set the original stack
; pointer.
lea DosName,a1 ; Name of dos.library.
moveq #0,d0 ; No special version.
CALL OpenLibrary ; Open the tin...
move.l d0,_DOSBase ; Successful?
bne 2$ ; Start the main program.
move.l #AG_OpenLib!AO_DOSLib,d7 ; Blast!
lea ThisTask(a6),a5 ; Current task.
CALL Alert ; Call Mr.Guru.
bra Error2 ; Finish it.
2$ move.l a6,_SysBase ; Set SysBase.
andi.w #AFF_68881,AttnFlags(a6) ; FPU present?
beq 3$
lea Restore,a5
CALL Supervisor ; Reset FPU.
3$ jsr __main ; Call main routine.
addq.l #8,sp ; Fix the stack.
*--------------------------------------------------------------------*
*
* If __main simply 'drops through' dos.library won't have been
* closed. To keep the counts even, we will test if DOS is still
* open and close it if necessary.
*
*--------------------------------------------------------------------*
move.l _DOSBase,a1
move.l a1,d0 ; dos.library still open?
beq 4$ ; Don't think so.
move.l AbsExecBase,a6 ; SysBase.
CALL CloseLibrary ; Close the library.
4$ rts ; Back to shell.
*--------------------------------------------------------------------*
Error2: addq.l #8,sp ; Fix the stack.
move.l AbsExecBase,a6 ; SysBase.
*--------------------------------------------------------------------*
*
* This part handles early startup failure. If this program was
* started from Workbench the startup message will probably
* be roaming around. We will intercept it and send it back
* to the caller.
*
*--------------------------------------------------------------------*
move.l ThisTask(a6),a0 ; Get current task.
tst.l pr_CLI(a0) ; Started from Workbench?
bne Error1
lea pr_MsgPort(a0),a0 ; Remember our MsgPort.
move.l a0,a3
CALL WaitPort ; Wait for WBenchStartup.
move.l a3,a0 ; Return MsgPort.
CALL GetMsg ; Pick up WBenchMsg.
move.l d0,a3 ; Remember Message.
CALL Forbid ; Turn off multitasking.
move.l a3,a1 ; Return the message.
CALL ReplyMsg ; And reply it.
Error1: moveq #-1,d0 ; Failed!
rts
*--------------------------------------------------------------------*
*
* This subroutine will reset the FPU (if any)!
*
*--------------------------------------------------------------------*
Restore:
clr.l -(sp)
frestore (sp)+ ; Reset the FPU.
rte
*--------------------------------------------------------------------*
*
* One of the most important routines of this file. Sets
* the global data segment pointer to a defined value.
*
*--------------------------------------------------------------------*
_geta4:
movem.l d0-d1/a0-a1/a6,-(sp) ; Save some registers.
move.l AbsExecBase,a6 ; SysBase.
move.l ThisTask(a6),a0 ; Get current task.
lea TC_MEMENTRY(a0),a0 ; Remember MemList.
lea MemName,a1 ; Get name of MemEntry.
CALL FindName ; Scan the list...
move.l d0,a1
move.l ML_SIZE+ME_ADDR(a1),a4 ; Start of data segment.
lea 32766(a4),a4 ; Add the offset.
movem.l (sp)+,d0-d1/a0-a1/a6 ; Restore all registers.
rts
*--------------------------------------------------------------------*
end