*
* C initial startup procedure under AmigaDOS for usage with Lattice 5.04
* Special stripped version !!
*

*               INCLUDE "exec/types.i"
                INCLUDE "libraries/dosextens.i"
                INCLUDE "call.i"
                INCLUDE "globdefs.i"

AbsExecBase     EQU     4


*-------------------------------------------------------*
*
*  StartUp
*
*  Highest level routine of a CLI-based program, a limited interface between system and application.
*
*  Input:       4(a7)   Stacksize (if called from CLI)
*               a0      Commandline parameter string
*               d0      Commandline parameter length
*
*  Output:      d0      Return value (as can be used in script files)
*               (pr_result2  to pass DOS errors for usage with "Why")
*
*  Usage:       a3      Pointer to our Process structure
*               a4      Pointer to our global data area
*               a5      Stack marker
*               a6      Library pointers
*


                xdef    _XCEXIT                         Exit() is standard way to leave C. (Not here)

                xref    _LinkerDB                       Linker defined base value
                xref    __BSSBAS                        Linker defined base of BSS
                xref    __BSSLEN                        Linker defined length of BSS

                CSECT   text,0,0,1,2                    Any xref's after this are 16-bit reloc

                Func    _StartUp
                movem.l d1-d7/a0-a6,-(a7)
REGSIZE         EQU     (7+7)*4
                lea     REGSIZE(a7),A5                  Determine old stack pointer, it has some parameters
                move.l  a0,a2                           Save commandline parameter pointer
                move.l  d0,d2                           And commandline parameter length

*--     Set BSS to zero

                lea     __BSSBAS,a0                     Get base of BSS
                move.l  #__BSSLEN,d0                    Get length of BSS in longwords
                moveq.l #0,d1
                bra.s   ClearLoop                       And clear for length given
ClearBSS        move.l  d1,(a0)+
ClearLoop       dbf     d0,ClearBSS                     Loop..


*--     Load baseregister and init some importand globals

                lea     _LinkerDB,a4                    Load base register
                move.l  a7,__StackPtr(a4)               Save stack ptr
                move.l  AbsExecBase.w,a6                Exec pointer
                move.l  a6,_SysBase(A4)
                lea     DOSName(pc),A1                  "dos.library"
                moveq.l #0,D0                           Version number
                LibCall OpenLibrary                     Open DOS-library
                move.l  D0,_DOSBase(A4)                 Library base pointer, success?
                bne.s   DOSok                           Yes..
                moveq.l #100,d0                         No, how did we get here anyway?
                bra     Exit2                           Leave..
DOSok

*--     Get the address of our task

                suba.l  a1,a1                           0-> a1 for own task
                LibCall FindTask                        Findtask() used as FindProcess()
                move.l  d0,a3                           Pointer to struct Process
                move.l  d0,_OurTask(a4)                 Save for later and other users

*--     Are we running as a child of Workbench?  Leave if so..

                move.l  pr_CurrentDir(A3),_curdir(A4)   Lock associated with current directory
                tst.l   pr_CLI(A3)                      Pointer to ConsoleLineInterpreter
                bne.s   FromCLI                         We are from the CLI, process CLI startup..
                lea.l   pr_MsgPort(a3),a0               Port Workbench will send us it's startupmessage
                LibCall WaitPort                        Wait for it
                lea.l   pr_MsgPort(a3),a0               Port Workbench has send us it's startupmessage
                LibCall GetMsg                          Remove message from port
                move.l  d0,d3                           Keep message
                LibCall Forbid                          No task-switching to prevent Workbench to UnLoadSeg() us
                move.l  d3,a1                           Workbench startup message
                LibCall ReplyMsg                        Reply message to tell Workbench we have terminated
                bra     Exit4                           Leave..

FromCLI

*--     Calculate available stackspace

                move.l  a5,D0                           Get top of stack
                sub.l   4(a5),D0                        Compute bottom
                add.l   #128,D0                         Allow for parms overflow
                move.l  D0,__base(A4)                   Save for dynamic stack checking

*--     Find command name

                move.l  pr_CLI(a3),a0                   BCPL-pointer to ConsoleLineInterpreter
                add.l   a0,a0                           Pointer conversion
                add.l   a0,a0
                move.l  cli_CommandName(a0),a1          BCPL-pointer to name of current command
                add.l   a1,a1                           Pointer conversion
                add.l   a1,a1

*--     Collect parameters

                move.l  d2,d0                           Command line parameters length
                moveq.l #0,d1
                move.b  (a1)+,d1                        First byte BCPL string is length
                move.l  a1,__ProgramName(A4)            Updated string pointer
                add.l   d1,d0                           Add length of command name
                addq.l  #1,d0                           Allow for space after command

                clr.w   -(A7)                           Set null terminator for command line
                addq.l  #1,D0                           Force to even number of bytes
                andi.w  #$fffe,D0                       Round up
                sub.l   D0,A7                           Make room on stack for command line
                subq.l  #2,D0
                clr.w   0(A7,D0)

*--     Copy command line onto stack

                move.l  d2,d0                           Command line parameters length
                subq.l  #1,d0
                add.l   d1,d2                           Add length of command name

CopyLine        move.b  0(A2,D0.W),0(A7,D2.W)           Copy command line parameters to stack
                subq.l  #1,d2                           Post decrement
                dbf     d0,CopyLine                     Loop..
                move.b  #' ',0(a7,d2.w)                 Add space between command and parms
                subq.l  #1,d2                           Post decrement
CopyCommand     move.b  0(a1,d2.w),0(a7,d2.w)           Copy command name to stack
                dbf     d2,CopyCommand                  Loop..
                move.l  A7,A1                           Commandline address
                move.l  A1,-(A7)                        Push command line address

*--     Open low level standard error in the current window

                lea.l   Asterix(pc),a0                  "*" Current window name
                move.l  a0,d1                           Name parameter
                move.l  #MODE_OLDFILE,d2                AccessMode parameter
                DosCall Open                            Open output
                move.l  d0,_ConOut(a4)                  Make public
                beq.s   Exit4                           No stderr, leave..

*--     Call application or next stage of interface

Main            Call    __main                          Call C entrypoint
                ;moveq.l #0,d0                          Set successful status (we donot: int _main(), main();)
                bra.s   Exit2                           Skip exit() stack argument..

*--     exit() entry-point.  All our registers are unreliable.

_XCEXIT         move.l  4(a7),d0                        Extract return code from stack
Exit2           move.l  d0,d7                           Keep return code
                lea     _LinkerDB,a4                    Base register. Could have been trashed when called Exit()... Yes?
                move.l  __StackPtr(a4),a7
Exit3           ;Call   _MemCleanup                     Let's not

*--     Close stderr

                move.l  _ConOut(a4),d1                  File handle to stderr
                DosCall Close                           Close stderr

Exit4           move.l  _OurTask(a4),a3                 Restore a3 as Processpointer
                move.l  _R2(a4),pr_Result2(a3)          Pass some extra error info
                move.l  d7,d0                           Return code
                movem.l (a7)+,d1-d7/a0-a6
                rts


DOSName         dc.b    'dos.library',0
Asterix         dc.b    '*',0



*-------------------------------------------------------*


                csect   __MERGED,1,,2,2

                gs_l    __StackPtr,1
                gs_l    _OurTask,1
                gs_l    _SysBase,1
*               gs_l    _DOSBase,1
                gs_l    _ConOut,1
                gs_l    _R2,1                   Secondary result (DOS-Why program)
                gs_l    __base,1                Base of stack
                gs_l    __ProgramName,1
                gs_l    _curdir,1

                END

