home *** CD-ROM | disk | FTP | other *** search
- *
- ** Startup.Easy v1.1
- *
- ** Author: Jörg van de Loo
- ** Hövel 15
- ** 47559 Kranenburg
- ** Germany
- ** ...this material was written using HiSoft's "Devpac Assembler 3".
- *
- ** This file is FreeWare (I would say public domain but this gives criminal
- ** people the right to add "their" copyright remark, so to protect myself from
- ** excluding of the use of this startup-code, it's FreeWare and I'm the
- ** copyright holder).
- ** HiSoft (UK) is it allowed to use/spread/include this file if they like to,
- ** also in modified form, for free.
- *
- ** Date: 5.21.1993
- *
- ** I cannot be held for any failures may happen using this startup-code.
- ** Unnecessary to tell that you use it at your own risk.
- *
-
- *
- ** This startup-code is reentrant, so if your code is it too, you may use
- ** Shell command "Resident".
- *
-
- *
- ** The BaseTable is only readable! Don't go messing with 'em or weird things
- ** may happen.
- *
-
- *
- ** The BaseTable used by this startup-code is 68 bytes large. If you define a
- ** label called "_TableSize" before you include the startup-code (it's
- ** important!) then you can specify the bytesize of the table on your own,
- ** e.g. 1024 bytes. Up from offset 68 you can now store your own datas,
- ** e.g. _GfxBase.
- *
- ** Note: This startup-code offers only 32KB of datas that can be reached -
- ** BSS relative to A5.
- *
-
- *
- ** Example:
- **
- * STRUCTURE mytable,68 ; begin at offset 68
- * APTR _GfxBase ; offset 68
- * APTR _IntuitionBase ; offset 72
- * UBYTE _myFlag ; offset 76
- * LABEL _TableSize
- * ; size for "BaseTable" and! "mytable" (here 77 bytes) -
- * ; automatically allocated when startup-code is executed.
- *
- * include include/startup.easy ; insert startup-code
- *
- * _main ; this label is the entry point for your code!
- * ....
- * ....
- *
- **
- ** The label "_main" will be called out of the startup-code. There your own
- ** code has to start.
- ** When your code returns to the exit-routine, all things allocated/opened by
- ** the startup-code are freed/closed.
- *
- ** The address register where the BaseTable is stored, is the processor
- ** register A5. Now you can store/read constants out of it, e.g.
- *
- * movea.l _DOSBase(A5),A6 ; get base of dos-lib
- *
-
- *
- ** To exit your code there are different ways.
- *
- ** 1. By "RTS" stack must be ok!
- ** 2. By calling "bsr _exit" no need for corrected stack
- ** 3. By calling "bra _exit" ditto
- ** 4. By calling "jsr _exit" ditto
- ** 5. By calling "jmp _exit" ditto
- *
- ** It's not necessary to restore the stack nor to restore the A5 register when
- ** using exits 2,3,4,5.
- *
-
- *
- ** This startup-code is a thined version of a startup-code which I use
- ** normally. Because I wrote a few programs for the PD and I don't want to
- ** spread my hard worked made startup-code (it's a lot time better than the
- ** original of Commodore), I wrote this one.
- *
-
-
- IFND STARTUP_EASY
- STARTUP_EASY SET 1
-
- * incdir :include/
- IFND EXEC_TYPES_I
- include exec/types.i
- ENDC
-
- IFND EXEC_MEMORY_I
- include exec/memory.i
- ENDC
-
- IFND EXEC_TASKS_I
- include exec/tasks.i
- ENDC
-
- IFND EXEC_LIBRARIES_I
- include exec/libraries.i
- ENDC
-
- IFND CALLEXEC
- include exec/exec_lib.i
- ENDC
-
- * include exec/execbase.i
-
- IFND CALLDOS
- include dos/dos_lib.i
- ENDC
-
- IFND DOS_DOSEXTENS_I
- include dos/dosextens.i
- ENDC
-
- IFND WORKBENCH_STARTUP_I
- include workbench/startup.i
- ENDC
-
- * include workbench/icon_lib.i
-
- IFND WORKBENCH_WORKBENCH_I
- include workbench/workbench.i
- ENDC
-
-
- IFND AbsExecBase
- AbsExecBase EQU 4
- ENDC
-
- IFND ThisTask
- ThisTask EQU 276
- ENDC
-
- IFND _LVOGetDiskObject
- _LVOGetDiskObject EQU -78
- ENDC
-
- IFND _LVOFreeDiskObject
- _LVOFreeDiskObject EQU -90
- ENDC
-
-
-
- StoreTableSize MACRO
- IFND _TableSize
- move.l #256,D0 ; Default, if nothing is specified
-
- ELSE
-
- IFLE _TableSize-127 ; If _TableSize < 128 use moveq
- moveq #_TableSize,D0
-
- ELSE
-
- IFLE _TableSize-32767 ; _TableSize not larger than 32KB
- move.l #_TableSize,D0
-
- ELSE
- FAIL <BSS-table exeeds 32KB!> ; else tell user
- ENDC
-
- ENDC
- ENDC
-
- addq.l #7,D0 ; ...make size divisible
- andi.l #-8,D0 ; through eight -> for exec's AllocMem()...
- ENDM
-
-
-
- *
- ** This is the BaseTable....
- *
- STRUCTURE BaseTable,0 ; begin at offset NULL
- APTR bt_Reserved0 ; currently unused - do not use!
- APTR _SysBase ; pointer to exec-base (readable)
- ; NOTE: « movea.l _SysBase.w,A6 » still work
- APTR bt_Reserved1 ; currently unused - do not use!
- APTR bt_Reserved2 ; currently unused - do not use!
- APTR _DOSBase ; pointer to dos-base (opened/readable)
- APTR _IconBase ; pointer to icon-base (readable, may not opened)
- APTR _argv ; pointer to dos/WB-arguments (readable, may NULL)
- ULONG _argc ; numbers of dos/WB-arguments (readable, may NULL)
- APTR _OwnTask ; pointer to own-process-structure (readable)
- APTR _OwnName ; pointer to own-program-name
- ; (readable, Shell: with path, WB: name only)
- ULONG _CmdNameSize ; PRIVATE!!!
- APTR _WBenchMsg ; pointer to Workbench-message (readable, may NULL)
- APTR _ToolTypesArray ; pointer to tooltypes (readable, may NULL)
- APTR _OwnDiskObject ; pointer to own-program-icon-structure (readable,
- * may NULL)
- APTR _stdin ; pointer to standard output-handle (readable,
- * may NULL)
- APTR _stdout ; pointer to standard input-handle (readable,
- * may NULL)
- ULONG _errno ; place into this constant the returncode of
- * your program
- LABEL bt_SIZEOF ; size of this table: 68 bytes - next free offset: 68!
-
- *
- ** Where "may NULL" stands it's possible that this values are not initialized
- ** if running from Workbench or when running from Shell.
- *
- * Examples: The WBenchMsg will be NULL if running under Shell.
- * The stdin or stdout will be NULL when running from Workbench.
- * So watch out!
-
-
- _startup
- movem.l D0/A0,-(sp)
-
- move.l AbsExecBase.w,A6
- StoreTableSize ; MACRO - bytesize of "_TableSize"
- move.l #MEMF_PUBLIC|MEMF_CLEAR,D1
- jsr _LVOAllocMem(A6) ; Allocate BaseTable and user's BSS
- tst.l D0
- beq.w __noTable
- movea.l D0,A5 ; Pointer to BaseTable into A5
- move.l A6,_SysBase(A5)
-
- move.l (sp)+,_argc(A5) ; Number of chars in commandline
- move.l (sp)+,_argv(A5) ; Address commandline (if Shell)
-
- move.l A5,-(sp) ; Save BaseTable right in front
- * of ReturnAddr of task
-
- cmpi.w #32,LIB_VERSION(A6) ; Say: I need at least kickstart 1.2
- bls.w __fastout
-
- lea _DOSName(pc),A1
- moveq #0,D0 ; Say: any version up from Kickstart 1.2
- jsr _LVOOpenLibrary(A6)
- move.l D0,_DOSBase(A5)
- beq.w __fastout ; ...only for savety...
-
- sub.l A1,A1
- jsr _LVOFindTask(A6)
- move.l D0,_OwnTask(A5) ; Pointer to process-structure
-
- movea.l D0,A2
- tst.l pr_CLI(A2) ; Are we called from CLI or WBench?
- bne.s .fromDOS
-
- * ...it was Workbench
- lea pr_MsgPort(A2),A0
- jsr _LVOWaitPort(A6) ; Wait for WB-message
-
- lea pr_MsgPort(A2),A0
- jsr _LVOGetMsg(A6) ; Get message
- move.l D0,_WBenchMsg(A5) ; and save message for later
-
- movea.l D0,A0 ; Message
- move.l sm_NumArgs(A0),_argc(A5) ; Number of files
- move.l sm_ArgList(A0),_argv(A5) ; Array of locks and files
-
- lea _IconName(pc),A1
- moveq #33,D0
- jsr _LVOOpenLibrary(A6) ; Open Icon-library
- move.l D0,_IconBase(A5)
- beq.s .skipToolTypes
-
- tst.l _argv(A5) ; Array empty?
- beq.s .skipToolTypes
- movea.l _argv(A5),A0 ; Array of:
- * lock[0],file[0], lock[1],file[1], lock[2],file[2] and so on
- move.l (A0),D1 ; wa_Lock(A0),D1 (home-lock)
- beq.s .skipLock
- movea.l _DOSBase(A5),A6
- jsr _LVOCurrentDir(A6) ; Change directory to PROGDIR
- tst.l D0
- bmi.s .skipToolTypes
- .skipLock
- movea.l _IconBase(A5),A6
- movea.l _argv(A5),A0
- movea.l wa_Name(A0),A0 ; Our name...
- move.l A0,_OwnName(A5) ; Remember name of prg
- jsr _LVOGetDiskObject(A6) ; Read program-icon
- tst.l D0
- beq.s .skipToolTypes
- move.l D0,_OwnDiskObject(A5) ; Remember icon-structure of our prg
- movea.l D0,A0
- move.l do_ToolTypes(A0),_ToolTypesArray(A5)
- .skipToolTypes
- bra.s __main
-
- * ...Shell start...
- .fromDOS
- movea.l _DOSBase(A5),A6
- jsr _LVOInput(A6)
- move.l D0,_stdin(A5)
- jsr _LVOOutput(A6)
- move.l D0,_stdout(A5)
-
- movea.l _OwnTask(A5),A0
- movea.l pr_CLI(A0),A0
- adda.l A0,A0
- adda.l A0,A0
- movea.l cli_CommandName(A0),A2 ; BSTR to our prg-name
- adda.l A2,A2
- adda.l A2,A2 ; APTR
- moveq #0,D2
- move.b (A2)+,D2 ; Get length of our name
-
- move.l #103,_errno(A5) ; Setup possible error
-
- move.l D2,D0 ; Length
- addq.w #8,D0 ; plus 1 byte (NULL-byte) plus 7 &
- andi.w #-8,D0 ; "and" with -8 = make length divisible through 8
- move.l D0,_CmdNameSize(A5) ; Remember size for later
- move.l #MEMF_PUBLIC|MEMF_CLEAR,D1
- movea.l _SysBase(A5),A6
- jsr _LVOAllocMem(A6) ; Allocate name-buffer
- move.l D0,_OwnName(A5) ; Save pointer to name-buffer
- beq.s __closeAndFree
-
- clr.l _errno(A5) ; Tell: no error occurred
-
- movea.l D0,A0 ; Name-buffer
- bra.s .doIt ; Because of DBF
- .StoreName
- move.b (A2)+,(A0)+ ; Copy CMD-name into own buffer
- .doIt
- dbf D2,.StoreName
- clr.b (A0) ; Not needed....
- __main
- move.l _SysBase(A5),A6
- bsr.w _main ; Call user's code with:
- * ·A5 BaseTable, A6 SysBase·
-
- _exit
- movea.l AbsExecBase.w,A6 ; Execbase
- suba.l A1,A1 ; 0 = own task (process)
- jsr _LVOFindTask(A6) ; Find our process
- movea.l D0,A0 ; Pointer to A0
- movea.l pr_ReturnAddr(A0),A0 ; Program's exit address
- subq.l #8,A0
- move.l A0,sp ; Correct Stackpointer
- move.l (sp)+,A5 ; Place basetable pointer in A5
- * and make a "RTS" using right address
-
- tst.l _WBenchMsg(A5)
- beq.s .fromDOS
-
- tst.l _IconBase(A5)
- beq.s .ReplyMsg
-
- tst.l _OwnDiskObject(A5)
- beq.s .ReplyMsg
- movea.l _OwnDiskObject(A5),A0
- movea.l _IconBase(A5),A6
- jsr _LVOFreeDiskObject(A6)
-
- .ReplyMsg
- movea.l _SysBase(A5),A6
- tst.l _IconBase(A5)
- beq.s .skipIt
- movea.l _IconBase(A5),A1
- jsr _LVOCloseLibrary(A6)
- .skipIt
- jsr _LVOForbid(A6)
-
- movea.l _WBenchMsg(A5),A1
- jsr _LVOReplyMsg(A6)
-
- bra.s __closeAndFree
-
- .fromDOS
- movea.l _SysBase(A5),A6
- move.l _CmdNameSize(A5),D0
- movea.l _OwnName(A5),A1
- jsr _LVOFreeMem(A6)
-
- __closeAndFree
- move.l _errno(A5),D2
- movea.l _DOSBase(A5),A1
- movea.l _SysBase(A5),A6
- jsr _LVOCloseLibrary(A6)
- movea.l _OwnTask(A5),A2
- movea.l A5,A1
- StoreTableSize
- jsr _LVOFreeMem(A6)
- move.l D2,D0
- move.l D0,pr_Result2(A2) ; Back to Shell/WB with returncode in D0
- rts ; and a valid Result2 constant...
-
- * ------------------------------------- *
- __noTable
- addq.w #8,sp
- moveq #103,D0
- move.l ThisTask(A6),A0
- move.l D0,pr_Result2(A0)
- rts
- __fastout
- movea.l A5,A1
- StoreTableSize
- jsr _LVOFreeMem(A6)
- moveq #121,D0
- move.l ThisTask(A6),A0
- move.l D0,pr_Result2(A0)
- rts
- _DOSName
- dc.b 'dos.library',0
- _IconName
- dc.b 'icon.library',0
-
- CNOP 0,4
-
- ENDC
- * ------------------------------------- *
-