home *** CD-ROM | disk | FTP | other *** search
- *
- * System0.asm - invoke system's command processor
- *
- * Copyright (C) by Ralph Babel, Guru Meditation Network,
- * Falkenweg 3, D-6204 Taunusstein, West-Germany
- *
- * This piece of code may be used as part of any product as
- * long as the source code for the complete program can be
- * obtained free of charge (except for a small copying fee)
- * and this copyright notice is left unchanged.
- *
- * Bug reports and improved versions appreciated.
- *
- * 20-Jul-1987 created original version
- * 11-Jan-1988 now based on "official" information only
- *
-
- nolist
-
- include "exec/types.i"
- include "libraries/dos.i"
- include "libraries/dosextens.i"
- include "extern/exec.i"
- include "extras/asm.i"
-
- list
-
- *
- * LONG System0(name, seglist, args)
- * char *name;
- * BPTR seglist;
- * char *args;
- *
-
- xdef _System0
- xref _DOSBase
-
- * parameter offsets & stack
-
- SAVED_REGS reg a2-a6/d2-d3
-
- DELTA equ 7*4
-
- ARG_NAME equ 4+DELTA
- ARG_SEGLIST equ 8+DELTA
- ARG_ARGS equ 12+DELTA
-
- * additional return codes
-
- NO_CLI equ -1
- NO_MEM equ -2
-
- * local constants
-
- MAXBSTR equ 255
- LF equ 10
-
- * register usage
-
- REG_Result equr d3
- REG_Process equr a2 ;may not be A4, see below!
- REG_CLI equr a3
- REG_CIS equr a4 ;may not be A3, see below!
- REG_PrevStack equr a5
-
- * local stack frame
-
- STRUCTURE StackFrame,0
- STRUCT sf_CommandName,MAXBSTR+1 ;BSTR, length byte!
- STRUCT sf_CommandArgs,MAXBSTR+1 ;not a BSTR, LF-terminated!
-
- APTR sf_PrevStack
-
- APTR sf_SaveReturnAddr
- BPTR sf_SaveModule
- BPTR sf_SaveCommandName
-
- APTR sf_StackBase
- LONG sf_StackSize
- LONG sf_PushSize
-
- APTR sf_Process
- APTR sf_CLI
- APTR sf_CIS
-
- BPTR sf_SCB_Buf
- LONG sf_SCB_Pos
- LONG sf_SCB_End
-
- LABEL sf_SIZEOF
-
- * entry point
-
- _System0:
- movem.l SAVED_REGS,-(sp)
-
- moveq #NO_CLI,REG_Result ;ERROR - not a CLI task
-
- movea.l AbsExecBase,REG_SysBase
- suba.l a1,a1
- callsys FindTask ;find own task
- movea.l d0,REG_Process
- move.l pr_CLI(REG_Process),d0
- beq quit0
-
- * build local stack frame & save some values
-
- lsl.l #2,d0 ;BPTR to machine pointer
- movea.l d0,REG_CLI
-
- movea.l sp,REG_PrevStack ;save old stack pointer
- move.l sp,d0
- andi.b #$fc,d0 ;make SP longword-aligned for BPTRs
- movea.l d0,sp
- suba.w #sf_SIZEOF,sp
-
- move.l REG_PrevStack,sf_PrevStack(sp)
- move.l REG_Process,sf_Process(sp)
- move.l REG_CLI,sf_CLI(sp)
-
- move.l pr_ReturnAddr(REG_Process),sf_SaveReturnAddr(sp)
-
- * allocate space for stack
-
- moveq #NO_MEM,REG_Result ;ERROR - no memory for STACK
-
- move.l cli_DefaultStack(REG_CLI),d0 ;in longwords for "VEC"
- lsl.l #2,d0
- move.l d0,sf_PushSize(sp)
- addq.l #4,d0 ;one additional longword
- move.l d0,sf_StackSize(sp)
- moveq #0,d1 ;intentionally NOT "MEMF_PUBLIC"!
- callsys AllocMem
- tst.l d0
- beq quit1
-
- move.l d0,sf_StackBase(sp) ;save result
-
- * save old command pointer, build new BCPL command name
-
- move.l cli_CommandName(REG_CLI),sf_SaveCommandName(sp)
-
- movea.l ARG_NAME(REG_PrevStack),a0 ;first parameter to "System0()"
- lea sf_CommandName+1(sp),a1 ;first char location for BSTR
- move.l a1,d0
- lsr.l #2,d0 ;will ignore (+1), BPTR as result
- move.l d0,cli_CommandName(REG_CLI)
-
- move.w #MAXBSTR,d0
- bra.s 2$
-
- 1$ move.b d1,(a1)+
- 2$ move.b (a0)+,d1
- dbeq d0,1$
-
- suba.l ARG_NAME(REG_PrevStack),a0 ;subtract original source
- move.l a0,d0
- subq.l #1,d0 ;terminating null-byte
- move.b d0,sf_CommandName(sp) ;to first location in BSTR
-
- * save contents of Current Input Stream
-
- move.l pr_CIS(REG_Process),d0
- lsl.l #2,d0
- movea.l d0,REG_CIS ;contains APTR to CIS
- move.l REG_CIS,sf_CIS(sp)
-
- move.l fh_Buf(REG_CIS),sf_SCB_Buf(sp)
- move.l fh_Pos(REG_CIS),sf_SCB_Pos(sp)
- move.l fh_End(REG_CIS),sf_SCB_End(sp)
-
- * convert argument to LF-terminated string
-
- movea.l ARG_ARGS(REG_PrevStack),a0 ;third argument to "System0()"
- lea sf_CommandArgs(sp),a1 ;first buffer location
- move.l a1,d0
- lsr.l #2,d0 ;make buffer pointer a BPTR
- move.l d0,fh_Buf(REG_CIS)
-
- move.w #MAXBSTR,d0 ;leave some room for terminating LF
- bra.s 4$
-
- 3$ move.b d1,(a1)+
- 4$ move.b (a0)+,d1
- dbeq d0,3$
-
- move.b #LF,(a1)
- suba.l ARG_ARGS(REG_PrevStack),a0 ;subtract first position
- move.l a0,d0 ;do NOT subtract, LF need this byte
-
- * setup start/end indices in Stream Control Block
-
- clr.l fh_Pos(REG_CIS)
- move.l d0,fh_End(REG_CIS)
-
- * misc setup
-
- clr.l pr_Result2(REG_Process) ;clear secondary result
-
- moveq #0,d0
- move.l #SIGBREAKF_CTRL_C,d1
- callsys SetSignal ;clear CTRL-C flag
-
- * handle seglist and start address
-
- move.l cli_Module(REG_CLI),sf_SaveModule(sp)
-
- move.l ARG_SEGLIST(REG_PrevStack),d0 ;second argument to "System0()"
- move.l d0,cli_Module(REG_CLI)
- lsl.l #2,d0
- movea.l d0,a3 ;make it a machine pointer in A3
-
- * setup processor registers & C-interface
-
- lea sf_CommandArgs(sp),a0
- move.l fh_End(REG_CIS),d0
-
- * setup processor registers, BCPL-interface, stack & return address for "Exit()"
-
- movea.l sf_StackBase(sp),a1 ;BCPL stack, low end
- move.l sf_PushSize(sp),d2
- lea 4(a1,d2.l),a4 ;must not destroy REG_Process!
- move.l sp,-(a4) ;previous stack frame
- move.l d2,-(a4) ;stack size in bytes
- move.l a4,pr_ReturnAddr(REG_Process)
- movea.l a4,sp
-
- movea.l _DOSBase,a4 ;large data memory model!
- movem.l dl_A2(a4),a2/a5/a6
-
- * now call the command at its entry point
-
- jsr 4(a3) ;code starts one longword behind segment pointer
-
- move.l d0,REG_Result ;save return code
-
- * get old stackframe & reload old register contents
-
- movea.l 4(sp),sp ;old stack frame
-
- movea.l sf_Process(sp),a0
- move.l sf_SaveReturnAddr(sp),pr_ReturnAddr(a0)
-
- movea.l sf_CLI(sp),a0
- move.l sf_SaveCommandName(sp),cli_CommandName(a0)
- move.l sf_SaveModule(sp),cli_Module(a0)
-
- * restore original contents of Current Input Stream
-
- movea.l sf_CIS(sp),a0
- lea sf_CommandArgs(sp),a1
- move.l a1,d0
- lsr.l #2,d0
- cmp.l fh_Buf(a0),d0 ;still the same?
- bne.s 5$ ;no: don't restore
- move.l sf_SCB_Buf(sp),fh_Buf(a0)
- 5$ move.l sf_SCB_Pos(sp),fh_Pos(a0)
- tst.l fh_End(a0) ;end index set?
- beq.s 6$ ;no: don't restore
- move.l sf_SCB_End(sp),fh_End(a0)
-
- * free temporary stack
-
- 6$ movea.l AbsExecBase,REG_SysBase
- movea.l sf_StackBase(sp),a1
- move.l sf_StackSize(sp),d0
- callsys FreeMem
-
- quit1 movea.l sf_PrevStack(sp),sp ;UNLINK local variables
-
- quit0 move.l REG_Result,d0
-
- movem.l (sp)+,SAVED_REGS
- rts
-
- end
-