home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
ftp.vapor.com
/
microdot-1
/
md1_src_02.lzx
/
mdc.a
< prev
next >
Wrap
Text File
|
1989-08-24
|
13KB
|
471 lines
*
* C initial startup procedure under AmigaDOS
*
* Use the following command line to make c.o
* asm -u -isc:Assembler_Include/ c.a
*
INCLUDE "exec/types.i"
INCLUDE "exec/alerts.i"
INCLUDE "exec/nodes.i"
INCLUDE "exec/lists.i"
INCLUDE "exec/ports.i"
INCLUDE "exec/libraries.i"
INCLUDE "exec/tasks.i"
INCLUDE "exec/memory.i"
INCLUDE "exec/execbase.i"
INCLUDE "libraries/dos.i"
INCLUDE "libraries/dosextens.i"
INCLUDE "workbench/startup.i"
INCLUDE "exec/funcdef.i"
INCLUDE "exec/exec_lib.i"
INCLUDE "libraries/dos_lib.i"
MEMFLAGS EQU MEMF_CLEAR+MEMF_PUBLIC
AbsExecBase EQU 4
xref __ctors
xref __dtors
;;;
;;; Stack map.
;;;
OFFSET 0
ds.b 4
savereg ds.b 13*4
stackbtm ds.b 4
; some usefull macros:
callsys macro
CALLLIB _LVO\1
endm
xdef _XCEXIT * exit(code) is standard way to leave C.
xdef @_XCEXIT
xref LinkerDB * linker defined base value
xref _BSSBAS * linker defined base of BSS
xref _BSSLEN * linker defined length of BSS
xref __stack
* library references
section text,code
xref __main * Name of C program to start with.
xref _MemCleanup * Free all allocated memory
start0:
lea restartflag(pc),a1
movem.l d0/a0,6(a1)
start1:
clr.w (a1)
movem.l 6(a1),d0/a0
bsr.s start
lea restartflag(pc),a1
tst.w (a1)
bne.s start1
rts
restartflag:
dc.w 0 ; 0
wbmsgback:
dc.l 0 ; 2
argps:
dc.l 0,0 ; 6
cdtsave:
dc.l 0,0 ; 14
xdef __dorestart
__dorestart:
lea restartflag(pc),a0
move.w #'MD',(a0)+
move.l _WBenchMsg(a4),(a0)
rts
start:
movem.l d1-d6/a0-a6,-(a7) * save registers
move.l a0,a2 * save command pointer
move.l d0,d2 * and command length
lea LinkerDB,a4 * load base register
move.l AbsExecBase.W,a6
IFND RESIDENT
lea _BSSBAS,a3 * get base of BSS
moveq #0,d1
move.l #_BSSLEN,d0 * get length of BSS in longwords
bra.s clr_lp * and clear for length given
clr_bss move.l d1,(a3)+
clr_lp dbf d0,clr_bss
move.l a7,_StackPtr(A4) * Save stack ptr
move.l a6,SysBase(A4)
*------ get the size of the stack, if CLI use cli_DefaultStack
*------ if WB use a7 - TC_SPLOWER
move.l ThisTask(a6),A3
move.l pr_CLI(A3),d0
beq.s fromwb
lsl.l #2,d0
move.l d0,a0
move.l cli_DefaultStack(a0),d0
lsl.l #2,d0 * # longwords -> # bytes
bra.s dostack
fromwb:
move.l a7,d0
sub.l TC_SPLOWER(a3),d0
dostack:
*------ Set __base for stack checking
move.l a7,d1
sub.l d0,d1 * get top of stack
add.l #128,D1 * allow for parms overflow
move.l D1,__base(A4) * save for stack checking
cmp.l __stack(a4),d0
bcc.s nochange
*-- current stack is not as big as __stack says it needs
*-- to be. Allocate a new one.
move.l __stack(a4),d0
add.l #128,d0 * extra room
move.l d0,newstacksize(a4)
move.l #MEMFLAGS,d1
callsys AllocMem
tst.l d0
beq.w return
move.l d0,newstack(a4)
add.l #128,d0 * extramain room
move.l d0,__base(a4)
add.l __stack(a4),d0
move.l d0,d1
*-- If we're running under 2.0, call StackSwap to set up
*-- the new stack. Otherwise, just jam the new value into
*-- A7.
cmpi.w #36,$14(a6)
blt.s no20
move.l d0,mystk_Pointer(a4)
move.l d1,mystk_Upper(a4)
sub.l newstacksize(a4),d1
lea mystk_Lower(a4),a0
move.l d1,(a0)
callsys StackSwap
bra.s nochange
no20: move.l d0,a7
nochange:
ENDC
clrwb:
clr.l _WBenchMsg(A4)
*----- clear any pending signals
moveq #0,d0
move.l #$00003000,d1
callsys SetSignal
move.l ThisTask(a6),A3
*------ attempt to open DOS library:
lea DOSName(PC),A1
moveq.l #33,D0
callsys OpenLibrary
move.l D0,DOSBase(A4)
bne.s ok2
moveq.l #100,d0
bra.w exit2
ok2:
*------ are we running as a son of Workbench?
move.l pr_CurrentDir(A3),__curdir(A4)
tst.l pr_CLI(A3)
beq.w fromWorkbench
*=======================================================================
*====== CLI Startup Code ===============================================
*=======================================================================
*
* Entry: D2 = command length
* A2 = Command pointer
fromCLI:
*------ find command name:
move.l pr_CLI(a3),a0
add.l a0,a0 * bcpl pointer conversion
add.l a0,a0
move.l cli_CommandName(a0),a1
add.l a1,a1 * bcpl pointer conversion
add.l a1,a1
*------ collect parameters:
move.l d2,d0 * get command line length
moveq.l #0,d1
move.b (a1)+,d1
move.l a1,_ProgramName(A4)
add.l d1,d0 * add length of command name
addq.l #7,d0 * allow for space after command, quotes
* and null terminator, as well as
andi.w #$fffc,D0 * force to long word boundary
move.l d0,Commandlen(a4)
movem.l d1/a1,-(a7)
move.l #MEMFLAGS,d1
callsys AllocMem
movem.l (a7)+,d1/a1
tst.l d0
bne.s ok_copy
moveq.l #30,d0 * what should the return code be for out of mem?
move.l d0,-(a7) * put a return code on the stack
beq.w nodofree * Was exitToDOS
ok_copy:
move.l d0,a0
move.l d0,Commandbuf(a4)
*------ copy command line into memory
move.l d2,d0 * get command line length
subq.l #1,d0
add.l d1,d2
copy_line:
move.b 0(A2,D0.W),2(A0,D2.W) * copy command line to stack
subq.l #1,d2
dbf d0,copy_line
move.b #' ',2(a0,d2.w) * add space between command and parms
subq.l #1,d2
move.b #'"',2(a0,d2.w) * add end quote
copy_cmd:
move.b 0(a1,d2.w),1(a0,d2.w) * copy command name to stack
dbf d2,copy_cmd
move.b #'"',(a0)
move.l A0,-(A7) * push command line address
bra.s main * call C entrypoint
*=======================================================================
*====== Workbench Startup Code =========================================
*=======================================================================
fromWorkbench:
*------ we are now set up. wait for a message from our starter
lea wbmsgback(pc),a0
move.l (a0),d0
beq.s wbwaitmsg
clr.l (a0)
bra.s wbrestart
wbwaitmsg:
lea pr_MsgPort(A3),a0 * our process base
callsys WaitPort
lea pr_MsgPort(A3),a0 * our process base
callsys GetMsg
wbrestart:
move.l d0,_WBenchMsg(a4)
move.l d0,-(SP)
move.l d0,a2 * get first argument
move.l sm_ArgList(a2),d0
beq.s do_main
move.l DOSBase(a4),a6
move.l d0,a0
move.l wa_Lock(a0),d1
callsys DupLock
move.l d0,__curdir(A4)
move.l d0,d1
callsys CurrentDir
do_main:
move.l _WBenchMsg(A4),a0 * get address of workbench message
move.l a0,-(a7) * push argv
pea NULL(a4) * push argc
move.l sm_ArgList(a0),a0 * get address of arguments
move.l wa_Name(a0),_ProgramName(A4) * get name of program
*=============================================
*------ common code --------
*=============================================
main
jsr __fpinit(PC) * Initialize floating point
jsr __main(PC) * call C entrypoint
moveq.l #0,d0 * set successful status
bra.s exit2
*
XCEXIT:
_XCEXIT:
move.l 4(SP),d0 * extract return code
@XCEXIT:
@_XCEXIT:
exit2:
*-- Save Return Code
move.l _StackPtr(a4),a2
move.l d0,-(a2)
*-- Swap back to original stack
*-- If we're running under 2.0, call StackSwap
*-- Otherwise, just jam the new value into a7
move.l AbsExecBase.W,A6
cmpi.w #36,$14(a6)
blt.s noswap
tst.l mystk_Lower(a4)
beq.s noswap
lea mystk_Lower(a4),a0
subq.l #4,mystk_Pointer(a4) * make room for the ret code
callsys StackSwap
noswap:
movea.l a2,a7 * restore stack ptr
move.l _ONEXIT(A4),d0 * exit trap function?
beq.s exit3
move.l d0,a0
jsr (a0)
exit3:
jsr __fpterm(PC) * clean up any floating point
jsr _MemCleanup(PC) * cleanup leftover memory alloc.
ifnd RESIDENT
*------ free the stack if we allocated one
move.l newstacksize(a4),d0
beq.s exit4
move.l newstack(a4),a1
move.l AbsExecBase.W,A6
callsys FreeMem
endc
exit4:
*------ if we ran from CLI, skip workbench cleanup:
tst.l _WBenchMsg(A4)
beq.s exitToDOS
move.l DOSBase(A4),a6
move.l __curdir(a4),d1
beq.s done_5
callsys UnLock
done_5:
*------ return the startup message to our parent
* we forbid so workbench can't UnLoadSeg() us
* before we are done:
move.l AbsExecBase.W,A6
tst.w restartflag
bne.s nodofree
callsys Forbid
move.l _WBenchMsg(a4),a1
callsys ReplyMsg
bra.s nodofree
exitToDOS:
move.l AbsExecBase.W,a6
*------ free the command line buffer
move.l Commandlen(a4),d0
beq.s nodofree
move.l Commandbuf(a4),a1
callsys FreeMem
*------ this rts sends us back to DOS:
nodofree:
move.l DOSBase(A4),a1
callsys CloseLibrary * close Dos library
IFD RESIDENT
move.l realdatasize(a4),d0
move.l a4,a1
sub.l #RESBASE,a1
callsys FreeMem
ENDC
move.l (a7)+,d0
return:
movem.l (a7)+,d1-d6/a0-a6
rts
__fpterm: ; call dtors
move.l a2,-(sp)
lea __dtors(a4),a2
bra.s fpil
__fpinit: ; call ctors
move.l a2,-(sp)
lea __ctors(a4),a2
fpil:
move.l (a2)+,d0
beq.s fpil2
move.l d0,a0
jsr (a0)
bra.s fpil
fpil2:
move.l (sp)+,a2
rts
DOSName dc.b 'dos.library',0
section __MERGED,BSS
xref DOSBase
xdef NULL,SysBase,_WBenchMsg
xdef __curdir
xdef _OSERR,_FPERR,_SIGFPE,_ONERR,_ONEXIT,_ONBREAK
xdef _SIGINT
xdef _ProgramName,_StackPtr,__base
ifd CATCH
xdef _ONGURU,_FMEM,_STAKOffset
endc
NULL ds.b 4
__base ds.b 4 * base of stack
_OSERR ds.b 4
_FPERR ds.b 4
_SIGFPE ds.b 4
_SIGINT ds.b 4
_ONERR ds.b 4
_ONEXIT ds.b 4
_ONBREAK ds.b 4
__curdir ds.b 4
SysBase ds.b 4
_WBenchMsg ds.b 4
_StackPtr ds.b 4
_ProgramName ds.b 4
Commandbuf ds.b 4
Commandlen ds.b 4
mystk_Lower ds.b 4
mystk_Upper ds.b 4
mystk_Pointer ds.b 4
ifnd RESIDENT
newstack ds.b 4 * pointer to new stack (if needed)
newstacksize ds.b 4 * size of new stack
endc
END