home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
back2roots/padua
/
padua.7z
/
padua
/
ftp.vapor.com
/
microdot-1
/
md1_src_02.lzx
/
c.a
< prev
next >
Wrap
Text File
|
1989-08-24
|
12KB
|
417 lines
*
IFD CATCH
IFND NOREQ
AUTOREQ set 1
ENDC
ENDC
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"
IFD CATCH
INCLUDE "intuition/intuition.i"
VERSION equ 1
REVISION equ 0
ENDC
MEMFLAGS EQU MEMF_CLEAR+MEMF_PUBLIC
AbsExecBase EQU 4
;;;
;;; 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
IFD RESIDENT
xref RESLEN
xref RESBASE
xref NEWDATAL
ENDC
* library references
section text,code
xref __main * Name of C program to start with.
xref __fpinit * initialize floating point
xref __fpterm * terminate floating point
xdef firstseg
firstseg:
*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
cmpi.w #36,$14(a6)
bge.s noneedtoclr
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
noneedtoclr:
move.l a7,_StackPtr(A4) * Save stack ptr
move.l a6,SysBase(A4)
movem.l d2/a2,_CLICmdLen(a4) * store CLI args
*------ 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 * extra 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
callsys OldOpenLibrary
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 #20,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 pr_MsgPort(A3),a0 * our process base
callsys WaitPort
lea pr_MsgPort(A3),a0 * our process base
callsys GetMsg
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
move.l d0,wblock(a4)
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 and constructors
tst.l d0
bne.s exit2
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
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 wblock(a4),d1
callsys CurrentDir
move.l d0,d1
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
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
move.l (a7)+,d0
return:
movem.l (a7)+,d1-d6/a0-a6
rts
DOSName dc.b 'dos.library',0
section __MERGED,BSS
xdef NULL,SysBase,DOSBase
xref _FPERR
xref _WBenchMsg
xref _OSERR,_SIGFPE,_ONERR,_ONEXIT,_ONBREAK
xref _SIGINT
xref _ProgramName,_StackPtr,__base
ifd CATCH
xdef _ONGURU,_FMEM,_STAKOffset
endc
wblock ds.b 4
NULL ds.b 4
DOSBase ds.b 4
SysBase 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
newstack ds.b 4 * pointer to new stack (if needed)
newstacksize ds.b 4 * size of new stack
xdef _CLICmdLen
xdef _CLICmd
_CLICmdLen: ds.b 4
_CLICmd: ds.b 4
END