****************************
*   modified STARTUP.ASM   *
* to allow pure (resident) *
* code to be produced and  *
* req.library to utilized  *
*                          *
****************************

RLibLng  EQU  30


TaskPTR         EQU  VS+0           ; this task struct storage
DOSBase         EQU  VS+4           ;       DOS
GFXBase         EQU  VS+8           ;       Graphics
INTBase         EQU  VS+12          ;       Intuition
MATHBase        EQU  VS+16          ;       MathFFP
TRANSBase       EQU  VS+20          ;       MathTrans
REQBase         EQU  VS+24          ;       Requester lib
WBMsg           EQU  VS+28          ; address of WB Message (if any)
StdIn           EQU  VS+32          ; address of INPUT file
StdOut          EQU  VS+36          ; address of OUTPUT file
StdErr          EQU  VS+40          ; address of ERROR file
EndFromWB       EQU  VS+44          ; set to 1 if from WB
EndFromCLI      EQU  VS+48          ; set to 1 if from CLI
Command         EQU  VS+52          ; command line from DOS
CmdLen          EQU  VS+56          ; length of command line
TotalVarSp      EQU  VS+60          ; total to alloc

   EvenPC


Start:
   PushReg    d0/a0
   AllocPubMem #TotalVarSp          ; get mem for variables
   tst.l      d0                    ; if not got
   beq        _DontStart            ; get OUT
   move.l     d0,a5                 ; keep PTR to var memory in a5
   PullReg    d0/a0
   move.l     d0,CmdLen(a5)         ; store command params
   move.l     a0,Command(a5)
   clr.b      -1(a0,d0.w)           ; and set null at end of command
   suba.l     a1,a1                 ; Clear a1
   SysCall    FindTask              ; Find address of task's task struct
   move.l     d0,TaskPTR(a5)

NowStartup
   move.l     #1,EndFromWB(a5)      ; Assume its from WB
   move.l     d0,a2                 ; a2 contains the Task Struct address
   tst.l      pr_CLI(a2)            ; IS this a CLI process?
   beq.s      From_WB               ; No, its from WB

From_CLI                            ; Do this if from CLI
   move.l     #0,EndFromWB(a5)
   move.l     #1,EndFromCLI(a5)
   bsr        _OpenReq
   tst.l      d0
   beq.s      NoReq
   bsr        _SetUpStd
   bra.s      NowDoMain

NoReq
   lea        DOSName(pc),a1
   SysCall    OpenLibrary
   move.l     d0,a6
   Call       Output
   move.l     d0,d1
   lea        ReqLibMsg(pc),a0
   move.l     a0,d2                 ; Tell user he needs to find library.
   move.l     #RLibLng,d3
   Call       Write
   bra        _StartError

From_WB                             ; do this if from WB
   lea        pr_MsgPort(a2),a0     ; wait for WB message
   SysCall    WaitPort
   lea        pr_MsgPort(a2),a0
   SysCall    GetMsg
   move.l     d0,WBMsg(a5)          ; save pointer to this message
   bsr        _OpenReq          
   tst.l      d0
   beq.s      _StartError           ; no req.library!


   IFD WBC                          ; did we want a console?

DefaultConsole
   lea        NewConsole(pc),a0
   move.l     a0,d1
   move.l     #MODE_NEWFILE,d2
   DosCall    Open
   move.l     d0,StdIn(a5)
   move.l     d0,StdOut(a5)
   move.l     d0,StdErr(a5)
   beq.s      _StartError           ; give up if console didn't make it!

SetConTask                          ; we have a BCPL PTR (sigh)
   lsl.l      #2,d0                 ; convert to an address
   move.l     d0,a0                 ; and stuff it in a0 as File Handle
   move.l     TaskPTR(a5),a2        ; and fill in task struct with
   move.l     fh_Type(a0),pr_ConsoleTask(a2)
   ENDC                             ; info about the console


*******   Now open libs and start _Main  *******

NowDoMain
   bsr        _Main
   tst.l      EndFromWB(a5)         ; if from WB, must close Console!
   beq.s      _Error
   move.l     StdOut(a5),d1         ; if it wasn't opened...
   beq.s      _Error                ; SKIP IT!
   DosCall    Close

;*** Now clean up and exit to system ***

_Error                              ; here is where we clean up and exit
   PushReg    d0                    ; hide d0 on the stack
   tst.l      WBMsg(a5)             ; was there a WBmsg?
   beq.s      MorFinish             ; if not....
   SysCall    Forbid                ; ensure WB doesn't dump us till we're done
   move.l     WBMsg(a5),a1          ; get orig mesg from WB
   Call       ReplyMsg              ; reply it, we're leaving!
MorFinish
   move.l     a5,a1                 ; PTR to memory for vars
   move.l     #TotalVarSp,d0        ; and size it was
   SysCall    FreeMem               ; and give it back
   PullReg    d0                    ; get d0 back off the stack
   rts                              ; and get outta here

_DontStart
   addq      #8,sp                  ; return the stack (!)
   move.l    #20,d0
   rts

_StartError
   moveq      #20,d0
   bra        _Error

_OpenReq
   lea        REQName(pc),a1
   moveq      #ReqVersion,d0
   SysCall    OpenLibrary
   tst.l      d0
   bne.s      ItsOkay
   rts
ItsOkay
   move.l     d0,a6
   move.l     d0,REQBase(a5)        ; store it, use to find other libs
   move.l     rl_DosLib(a6),DOSBase(a5)
   move.l     rl_GfxLib(a6),GFXBase(a5)
   move.l     rl_IntuiLib(a6),INTBase(a5)
   rts

_SetUpStd
   DosCall    Input
   move.l     d0,StdIn(a5)
   DosCall    Output
   move.l     d0,StdOut(a5)
   move.l     d0,StdErr(a5)
   rts

_DosTextLen                         ; Calculates length of ASCIIZ string into d3
   move.l    d2,a0
1$
   tst.b     (a0)+
   bne.s     1$
   move.l    a0,d3
   sub.l     d2,d3
   subq      #1,d3
   rts

; ****  Data Storage ***


DOSName
   dc.b       'dos.library',0       ; all these names for OpenLibrary
ReqLibMsg
   dc.b       'You need V1+ of '
REQName
   dc.b       'req.library',0
   dc.b       10,10,0
NewConsole
   dc.b       'CON:0/0/1/1/ ',0
   EvenPC
