home *** CD-ROM | disk | FTP | other *** search
- *:ts=8
- *:fo=excel,11
-
-
- * :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- * ::::::::::::::::###::::######::::::::::#:::::::::##::::::::
- * :####::::::::####:::::########:::::::::##::::::::##::::::::
- * :###############:::::##::::::::::::::::###::::::###::::::::
- * :::::#######:::::::::##:::::::::::::::::##::::::###::::::::
- * ::::::::##:::::::::::#::::::::::::::::::###:::::#:#::::::::
- * ::::::::#::::::::::::##:::::::::::::::::####:::##:#::::::::
- * :::::::##::::::::::::##::::::::::::::::::###:::#::#::::::::
- * :::::::##:::::::::::::##:::::::::::::::::#:##::#::#::::::::
- * :::::::#:::::::::::::::##::::::::::::::::#::####::##:::::::
- * ::::::##::::::::::::::::###::::::::::::::#:::##:::##:::::::
- * ::::::##:::::::::::::::::###:::::::::::::#:::::::::#:::::::
- * ::::::##::::::::::::::::::###::::::::::::#:::::::::##::::::
- * ::::::##:::::::::::::::::::##:::::::::::##:::::::::##::::::
- * ::::::##::::::::::::::::::::##::::::::::##::::::::::#::::::
- * ::::::##:::::::::::::::::::::#::::::::::##::::::::::##:::::
- * ::::::##:::::::::::::::::::::##:::::::::#::::::::::::#:::::
- * ::::::##:::::::::::::::::::::##::::::::##::::::::::::##::::
- * ::::::##:::::::::::::::::::::##::::::::##:::::::::::::##:::
- * ::::::##::::::::::::::::::::##::::::::##:::::::::::::::##::
- * :::::::#::::::::::::#########::::::::##::::::::::::::::###:
- * :::::::#:::::::::::::#######::::::::###::::::::::::::::::#:
- * :::::::#:::::::::::::::::::::::::::::#:::::::::::::::::::::
- * ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: version 1.2
-
-
- *
- ** This source-code for MCC and compatible assemblers.
- ** This stuff is Amiga-ROM® specific and re-entrant.
- ** It was written through the use of HiSoft's Devpac Amiga 3 assembler.
- *
- ** One of the few programs ever written for the Amiga that when resident
- ** will detach from CLI/Shell.
- *
- ** Please note: Cannot run multiple times on the same console-task
- ** otherwise strange things happen - because of an installed hook
- ** for process entry »PktWait« !
- *
-
- *
- ** © Copyright 10 & 12/1998, 11/1999 Joerg van de Loo
- ** Hoevel 15
- ** 47559 Kranenburg
- ** Germany
- *
-
- *
- ** This is N O T P U B L I C D O M A I N S O F T W A R E !
- *
-
- *
- ** The problem: How to get informed when the console window is closed by user.
- ** For what: To remove a console window from list of Workbench AppWindows.
- ** Remedy: This file ... (TSM)
- *
-
- IFD __G2 ; Devpac 2 (__G2 (BYTE) >= 43 == Devpac 3)
- MACHINE MC68000
- OUTPUT RAM:TSM
- IDNT 'Tame Shell Master'
- OPT OW-
- ENDC
-
- include exec/exec_lib.i
- include exec/memory.i
-
- include dos/dos_lib.i
- include dos/dos.i
- include dos/dosextens.i
-
- include intuition/intuition_lib.i
-
- include workbench/wb_lib.i
- include workbench/startup.i
- include workbench/workbench.i
-
- include libraries/commodities_lib.i
- include libraries/commodities.i
-
- include devices/input.i
- include devices/inputevent.i
-
-
- STRUCTURE BaseTable,0
- APTR nada ; In german (nix da bzw. nichts)
- APTR _SysBase
- APTR _ThisTask
- ULONG _errno
- APTR _DOSBase
- APTR __ResSegment
- APTR __PgmName
- ULONG __PgmNameSize
- * ------------------------------------
- APTR _IntuitionBase
- APTR _WBenchBase
- APTR _CxBase
- BPTR _ConHandle
- APTR _WinPtr
- APTR _ConTask
- APTR _ConPort
- APTR _MsgPort
- APTR _OldPort
- STRUCT _DummyMessage,16 ; 14 required
- APTR _AppPort
- APTR _AppWin
- APTR _ReplyPort
- STRUCT _InputIOReq,IOSTD_SIZE
- STRUCT _InputEvent,ie_SIZEOF
- STRUCT _StrStorage,254
- LABEL BT_SIZEOF
-
-
- BREL EQU $8000
-
- get MACRO
- move.\0 \1-BREL(A4),\2
- ENDM
-
- geta MACRO
- movea.\0 \1-BREL(A4),\2
- ENDM
-
- put MACRO
- move.\0 \1,\2-BREL(A4)
- ENDM
-
- adr MACRO
- lea \1-BREL(A4),\2
- ENDM
-
- taz MACRO Test against zero
- tst.\0 \1-BREL(A4)
- ENDM
-
- qmove MACRO
- ifgt \1-255
- move.\0 #\1,\2
- mexit
- endc
-
- ifle \1-127
- moveq #\1,\2
- mexit
- endc
-
- moveq #255-\1,\2
- not.b \2
- ENDM
-
-
-
- ;DEBUG SET 1
-
- IFD DEBUG
- IFD __G2
- OPT D+
- ENDC
-
- XDEF __start_me_up
- XDEF _FindSegment
- XDEF __exitNoProc
- XDEF __exitNoPgmNameMem
- XDEF __exitNoOutput
- XDEF __exitDOSOpen
- XDEF __exitNoDOS
- XDEF __exitReal
- XDEF _DOSName
- XDEF _IntName
- XDEF _WBenchName
- XDEF _CxName
- XDEF _Con
-
- XDEF __createStartup
- XDEF _AwaitCloseDown
- XDEF _ReactToMsg
- XDEF _WriteIE
- XDEF _NewPktWait
- XDEF _RemPort
- XDEF _CreatePort
- XDEF _ConToWin
- XDEF _IntputName
- XDEF _ID
-
- ENDC
-
-
- SECTION TEXT0,CODE
-
- __start_me_up ; int = _start_me_up( void)
- moveq #ERROR_INVALID_RESIDENT_LIBRARY,D2 ; Set up possible error
-
- movea.l (4).w,A6 ; Zero-Page addressing mode!
- cmpi.w #32,LIB_VERSION(A6) ; At least OS 1.2; it contains
- bls.w __exitReal ; the OpenLibrary( name, version) call
-
- moveq #ERROR_NO_FREE_STORE,D2 ; Set up possible error
-
- qmove.l BT_SIZEOF,D0 ; Var-table size
- move.l #MEMF_CLEAR|MEMF_PUBLIC,D1 ; Prevent from being used by GIGAMEM etc.
- jsr _LVOAllocMem(A6)
- tst.l D0
- beq.w __exitReal ; No BSS section
-
- movea.l D0,A4 ; Set up base register
- adda.l #BREL,A4
-
- put.l A6,_SysBase ; Remember it (if possible in fast-ram)
-
- suba.l A1,A1
- jsr _LVOFindTask(A6)
- put.l D0,_ThisTask
-
- moveq #ERROR_INVALID_RESIDENT_LIBRARY,D2 ; Set up possible error
-
- lea _DOSName(pc),A1
- moveq #36,D0 ; beta Kick 2.0 and up
- jsr _LVOOpenLibrary(A6)
- put.l D0,_DOSBase
- beq.w __exitNoDOS
-
- lea _IntName(pc),A1
- moveq #36,D0
- jsr _LVOOpenLibrary(A6)
- put.l D0,_IntuitionBase
- beq.w __exitDOSOpen
-
- lea _WBenchName(pc),A1
- moveq #36,D0
- jsr _LVOOpenLibrary(A6)
- put.l D0,_WBenchBase
- beq.w __exitDOSOpen
-
- lea _CxName(pc),A1
- moveq #36,D0
- jsr _LVOOpenLibrary(A6)
- put.l D0,_CxBase
- beq.w __exitDOSOpen
-
- * ##############################
-
- lea _ConName(pc),A0 ; Get current console handle (from where we have been started)
- move.l A0,D1
- move.l #MODE_OLDFILE,D2 ; It really exists...
- geta.l _DOSBase,A6
- jsr _LVOOpen(A6) ; Tell DOS we'll use console window
- put.l D0,_ConHandle ; so it cannot be closed
-
- * ##############################
-
- *
- ** Copy from Shell given name into private buffer
- *
- geta.l _ThisTask,A0
- movea.l pr_CLI(A0),A0 ; Pointer CommandLineInterface
- add.l A0,A0 ; BPTR to APTR
- add.l A0,A0
- movea.l cli_CommandName(A0),A2 ; Pointer to BSTR
- adda.l A2,A2 ; BSTR to STRPTR
- adda.l A2,A2
- moveq #0,D2 ; Erase D2
- move.b (A2)+,D2 ; Get length-byte of name
- move.l D2,D0 ; Length of name also in D0
- addq.w #8,D0 ; Plus 1 because of zero-byte
- andi.l #-8,D0
- put.l D0,__PgmNameSize ; Store in basetable
- move.l #MEMF_PUBLIC|MEMF_CLEAR,D1 ; Requirements
- geta.l _SysBase,A6
- jsr _LVOAllocMem(A6) ; Get memory
- put.l D0,__PgmName ; Store in basetable
- beq.w __exitNoPgmNameMem ; If no memory
- movea.l D0,A0 ; Buffer for name
- bra.s 2$ ; 'Cause of DBF (-alias)
- 1$
- move.b (A2)+,(A0)+ ; Copy name
- 2$
- subq.w #1,D2
- bcc.s 1$ ; If some chars left
- clr.b (A0) ; Zero-byte
-
-
- *
- ** Here we check now whether the pgm is in the ResidentList; if it is we'll
- ** increment the UseCount (seg_UC) but the first code hunk is not erased in
- ** this case to break the hunk-list of the AmigaDOS load-file.
- *
- lea __start_me_up(pc),A0
- subq.l #4,A0 ; APTR segment
- bsr.w _FindSegment ; Find own Resident-Segment
- put.l D0,__ResSegment ; Resident-Segment or zero
- beq.s .normalStart
-
- movea.l D0,A0
- addq.l #1,seg_UC(A0) ; We are resident, so the second code fragment is,
- * but the first code segment quits thus we increment
- * usecount by 1 indicating TSM (2nd code fragment)
- * is still used!
-
- .normalStart
-
- *
- ** Now we start the following code-segment(s) (goes into D3) as real background process
- *
- lea __start_me_up(pc),A0 ; Pointer to code start
- subq.l #4,A0 ; Pointer to BPTR next-segment
- move.l (A0),D3 ; BPTR-segment
-
- taz.l __ResSegment ; Flag set (segment in ResList)?
- bne.s .hunkStuffDone ; Yes...
-
- clr.l (A0) ; Erase linked hunk-pointer to next segment (important!) (only if not resident!)
-
- .hunkStuffDone
- get.l __PgmName,D1 ; Address name task
- moveq #0,D2
- get.l _ThisTask,A0 ; Current TSM process
- move.b LN_PRI(A0),D2 ; Get current TSM's priority
- subq.b #1,D2 ; One less than normal priority (pri is non-important while running, but at startup!)
- * move.l D3,D3 ; Segment(s)
- move.l #2560,D4 ; Stack size (2.5 KByte)
- geta.l _DOSBase,A6 ; DOS takes control
- jsr _LVOCreateProc(A6) ; Create a DOS process
- tst.l D0 ; D0 ~0 = msg-port of created task
- beq.w __exitNoProc ; If zero, error!
-
- movea.l D0,A0
- lea -TC_SIZE(A0),A0 ; From port to process
- move.l A4,TC_Userdata(A0) ; Overgive new task the base-table
-
- move.l #$10000,D0 ; Bit 16
- geta.l _SysBase,A6
- jsr _LVOWait(A6) ; Wait for 2nd program to say we can quit
-
- *
- * The allocated/opened things will not freed nor closed !!!
- *
- suba.l A1,A1
- geta.l _SysBase,A6
- jsr _LVOFindTask(A6)
- movea.l D0,A0 ; ThisTask
- clr.l pr_Result2(A0) ; No error!
- moveq #0,D0 ; For the CLI
- rts ; Program (#1) ends
-
- *
- ** This routine will test if in the ResidentList of DOS the overgiven segment
- ** resides.
- *
- _FindSegment ; struct Segment *FindSegment( struct *Segment)
- * D0 A0
- move.l A2,-(sp)
-
- geta.l _DOSBase,A1
- movea.l dl_Root(A1),A1 ; RootNode
- movea.l rn_Info(A1),A1 ; BPTR DosInfo
- adda.l A1,A1
- adda.l A1,A1 ; DosInfo
- tst.l di_NetHand(A1)
- beq.s .SegNotFound
- movea.l di_NetHand(A1),A1 ; BPTR NetHand
- adda.l A1,A1
- adda.l A1,A1 ; NetHand (pointer to ResList)
- bra.s .CmpSeg
- .NextSeg
- tst.l seg_Next(A1)
- beq.s .SegNotFound
- movea.l seg_Next(A1),A1 ; BPTR segment
- adda.l A1,A1
- adda.l A1,A1 ; APTR segment
- .CmpSeg
- movea.l seg_Seg(A1),A2 ; BPTR segment
- adda.l A2,A2
- adda.l A2,A2 ; APTR segment
-
- cmpa.l A0,A2 ; Segments the same?
- bne.s .NextSeg
-
- move.l A1,D0 ; ResList
- .EndSeg
- movea.l (sp)+,A2
- rts
-
- .SegNotFound
- moveq #0,D0
- bra.s .EndSeg
-
- * ################################
-
- __exitNoProc
- moveq #ERROR_TASK_TABLE_FULL,D2
-
- geta.l __PgmName,A1
- get.l __PgmNameSize,D0
- geta.l _SysBase,A6
- jsr _LVOFreeMem(A6)
-
- __exitNoPgmNameMem
- get.l _ConHandle,D1
- geta.l _DOSBase,A6
- jsr _LVOClose(A6) ; Allow to shut down console
-
- __exitDOSOpen
- geta.l _SysBase,A6
-
- taz.l _WBenchBase
- beq.s 1$
- geta.l _WBenchBase,A1
- jsr _LVOCloseLibrary(A6)
- 1$
- taz.l _CxBase
- beq.s 1$
- geta.l _CxBase,A1
- jsr _LVOCloseLibrary(A6)
-
- taz.l _IntuitionBase
- beq.s 2$
- geta.l _IntuitionBase,A1
- jsr _LVOCloseLibrary(A6)
- 2$
- geta.l _DOSBase,A1
- jsr _LVOCloseLibrary(A6)
-
- __exitNoDOS
- geta.l _ThisTask,A0
- move.l D2,pr_Result2(A0)
-
- movea.l A4,A1
- suba.l #BREL,A1
- qmove.l BT_SIZEOF,D0
- jsr _LVOFreeMem(A6)
-
- __exitReal
- move.l D2,D0
- rts
-
- _DOSName
- dc.b 'dos.library',0
- _IntName
- dc.b 'intuition.library',0
- _WBenchName
- dc.b 'workbench.library',0
- _CxName
- dc.b 'commodities.library',0
- _ConName
- dc.b 'CONSOLE:',0 ; <- means current input stream
-
-
- * ################################################################
-
- SECTION TEXT1,CODE
-
- __createStartup
- movea.l (4).w,A6 ; SysBase alias
- suba.l A1,A1
- jsr _LVOFindTask(A6)
- movea.l D0,A0 ; Own task
- .getBaseReg
- tst.l TC_Userdata(A0)
- beq.s .getBaseReg
- movea.l TC_Userdata(A0),A4 ; Set up base register
- get.l _ThisTask,-(sp) ; Master task
- put.l A0,_ThisTask ; And setup new own task !!!
-
- get.l _ConHandle,D0 ; Console's handle
- adr _WinPtr,A0
- adr _ConTask,A1
- adr _ConPort,A2
- bsr.w _ConToWin ; Get console's window, task and port address
-
- movea.l (sp)+,A1
- move.l #$10000,D0 ; Signal bit 16
- geta.l _SysBase,A6
- jsr _LVOSignal(A6) ; Tell master task to quit
-
- moveq #10,D1
- put.l D1,_errno ; Set up possible error
-
- tst.l D0 ; Do we got the needed things from ConToWin()?
- beq.w 3$
-
- bsr.w _CreatePort
- put.l D0,_AppPort
- beq.s 3$
-
- bsr.w _CreatePort
- put.l D0,_ReplyPort
- beq.s 2$
-
- adr _InputIOReq,A1
- moveq #IOF_QUICK,D0
- move.b D0,IO_FLAGS(A1)
- lea _InputName(pc),A0 ; We'll use
- moveq #0,D0 ; the
- * adr _InputIOReq,A1 ; console
- moveq #0,D1 ; device
- jsr _LVOOpenDevice(A6) ; to send RAW-KEY
- tst.l D0 ; codes
- bne.s 1$
-
- adr _InputIOReq,A0 ; Set reply-port
- get.l _ReplyPort,MN_REPLYPORT(A0) ; so that the console-device knows who gets the msgs
-
- moveq #0,D0
- moveq #0,D1
- geta.l _WinPtr,A0
- geta.l _AppPort,A1
- suba.l A2,A2
- geta.l _WBenchBase,A6
- jsr _LVOAddAppWindowA(A6) ; Make out of the console window (Shell) an app-windoww
- put.l D0,_AppWin
- beq.s 0$ ; No App-Window thus do nada
-
- moveq #0,D0
- put.l D0,_errno ; No error occurred
-
- bsr.w _AwaitCloseDown ; Fetch datas from console's window
-
- geta.l _AppWin,A0
- geta.l _WBenchBase,A6
- jsr _LVORemoveAppWindow(A6)
-
- 0$
- adr _InputIOReq,A1
- geta.l _SysBase,A6
- jsr _LVOCloseDevice(A6)
-
- 1$
- geta.l _ReplyPort,A0
- bsr.w _RemPort
-
- 2$
- geta.l _AppPort,A0
- bsr.w _RemPort
-
- 3$
- get.l _ConHandle,D1
- geta.l _DOSBase,A6
- jsr _LVOClose(A6) ; Allow to shut down console
-
- get.l _errno,D2
- geta.l _ThisTask,A0
- move.l D2,pr_Result2(A0)
-
- geta.l _SysBase,A6
- jsr _LVOForbid(A6)
-
- taz.l __ResSegment ; ResList?
- beq.s 4$
- geta.l __ResSegment,A0
- subq.l #1,seg_UC(A0) ; Usecount -1!
- bra.s 5$
- 4$
- lea __createStartup(pc),A0 ; Pointer to pgm code
- subq.l #4,A0 ; -4 = segment pointer
- move.l A0,D1 ; to D1
- lsr.l #2,D1 ; to BPTR
- geta.l _DOSBase,A6 ; Base DOS
- jsr _LVOUnLoadSeg(A6) ; Remove by pgm used mem
- 5$
- geta.l _SysBase,A6
-
- geta.l _CxBase,A1
- jsr _LVOCloseLibrary(A6)
-
- geta.l _WBenchBase,A1
- jsr _LVOCloseLibrary(A6)
-
- geta.l _IntuitionBase,A1
- jsr _LVOCloseLibrary(A6)
-
- geta.l _DOSBase,A1
- jsr _LVOCloseLibrary(A6)
-
- geta.l __PgmName,A1
- get.l __PgmNameSize,D0
- jsr _LVOFreeMem(A6)
-
- movea.l A4,A1
- suba.l #BREL,A1
- qmove.l BT_SIZEOF,D0
- jsr _LVOFreeMem(A6)
-
- jsr _LVOPermit(A6)
-
- move.l D2,D0
- rts
-
- * ################### MAIN ###################
-
- _AwaitCloseDown
- move.l A5,-(sp)
-
- geta.l _ConTask,A5 ; Let us talk with the console task
-
- tst.l TC_Userdata(A5) ; Assumption: if TC_Userdata is used, another TSM obtains
- bne.s .done ; the handle to this console task so we should terminate immediately
-
- bsr.w _CreatePort
- put.l D0,_MsgPort ; We need a message port...
- beq.s .done
-
- move.l A4,TC_Userdata(A5) ; Remember A4 in global for new WaitPkt() function
- put.l pr_MsgPort(A5),_OldPort ; Remember for restoring the old msg-port of console task
- move.l D0,pr_MsgPort(A5) ; Drop our message port where old of console task has been hooked up
-
- lea _NewPktWait(pc),A0 ; The additional function for the original WaitPkt()
- move.l A0,pr_PktWait(A5)
-
- geta.l _SysBase,A6
-
- .event
- geta.l _AppPort,A0
- moveq #1,D0
- moveq #0,D1
- move.b MP_SIGBIT(A0),D1
- lsl.l D1,D0
- ori.w #$1000,D0 ; And also CTRL-C (bit 12)
- jsr _LVOWait(A6) ; Wait...
-
- moveq #12,D1 ; Does our task (not the console's one) got a break signal?
- btst.l D1,D0
- bne.s .remove
-
- geta.l _AppPort,A0 ; Check if we got a workbench message
- moveq #0,D1
- move.b MP_SIGBIT(A0),D1 ; Signal bit of port
- btst.l D1,D0
- bne.s .receivedAppMsg ; Message received...
-
- bra.s .event ; If not...
-
- .remove
- clr.l pr_PktWait(A5) ; Remove additional function for WaitPkt()
- get.l _OldPort,pr_MsgPort(A5) ; Restore original (by DOS set up) msg-port
- clr.l TC_Userdata(A5) ; Restore
- geta.l _MsgPort,A0 ; Our allocated msg-port
- bsr.w _RemPort ; Remove it
- .done
- movea.l (sp)+,A5
- rts
-
- .receivedAppMsg
- geta.l _AppPort,A0
- jsr _LVOGetMsg(A6)
- tst.l D0
- beq.s .msgLoopDone
-
- move.l D0,-(sp)
-
- movea.l D0,A0
- bsr.s _ReactToMsg
-
- movea.l (sp)+,A1
- jsr _LVOReplyMsg(A6)
-
- .msgLoopDone
- bra.s .event
-
- IFND MTYPE_APPWINDOW ; Define of include file V39 to V40 differ...
- MTYPE_APPWINDOW EQU 7
- ENDC
-
- _ReactToMsg
- movem.l D2-D4/A2/A6,-(sp)
-
- cmpi.w #MTYPE_APPWINDOW,am_Type(A0)
- bne.s 5$
-
- movea.l A0,A2
- moveq #1,D4
-
- geta.l _WinPtr,A0
- geta.l _IntuitionBase,A6
- jsr _LVOActivateWindow(A6) ; Which window gets the input stream?
-
- geta.l _DOSBase,A6
- 1$
- move.l D4,D0 ; Parse argument x
- subq.w #1,D0 ; as index
- lsl.w #3,D0 ; * 8
- movea.l am_ArgList(A2),A0 ; Arguments
- lea 0(A0,D0.w),A0 ; Current argument
- move.l A0,D0
- beq.s 5$ ; E.g.: Disk is mounted (e.g. CD-ROM) but not in drive!
-
- move.l A0,-(sp) ; Current arg-pointer onto stack
-
- move.l wa_Lock(A0),D1 ; Get lock of drawer
- adr _StrStorage,A0 ; Buffer to store characters
- move.w #$2022,(A0)+ ; Write blank and double quote
- move.l A0,D2
- qmove.l 251,D3 ; Max. room for 251 characters
- jsr _LVONameFromLock(A6) ; Get name from lock
-
- adr _StrStorage,A0 ; Address string buffer
- 2$
- tst.b (A0)+ ; Find end of drawer name
- bne.s 2$
-
- subq.l #1,A0 ; One too far; pointed to zero byte (terminator)
- cmpi.b #':',-1(A0) ; Volume name or drawer name?
- beq.s 3$
-
- move.b #'/',(A0)+ ; Was drawer...
- 3$
- move.l (sp)+,A1 ; Get back pointer to arg-pointer
- movea.l wa_Name(A1),A1 ; Name of file
- 4$
- move.b (A1)+,(A0)+ ; Copy name at end of drawer name
- bne.s 4$
-
- move.b #'"',-1(A0)
- clr.b (A0)
-
- adr _StrStorage,A0 ; Address complete filename
- bsr.s _WriteIE ; Write RAW-KEY-codes
-
- addq.l #1,D4 ; One more argument
- cmp.l am_NumArgs(A2),D4
- bls.s 1$ ; If some left to work out
-
- 5$
- movem.l (sp)+,D2-D4/A2/A6
- rts
-
- _WriteIE ; STRPTR A0
- move.l A2,-(sp)
- move.l A6,-(sp)
-
- movea.l A0,A2 ; The string
-
- .writeIE
- tst.b (A2)
- beq.s .ieDone
-
- adr _InputIOReq,A1
- moveq #IOF_QUICK,D0
- move.b D0,IO_FLAGS(A1)
- moveq #IND_WRITEEVENT,D0
- move.w D0,IO_COMMAND(A1)
- moveq #ie_SIZEOF,D0
- move.l D0,IO_LENGTH(A1)
- adr _InputEvent,A0
- move.l A0,IO_DATA(A1)
-
- moveq #IECLASS_RAWKEY,D0
- move.b D0,ie_Class(A0)
- moveq #0,D0
- move.w D0,ie_Code(A0)
- move.b D0,ie_SubClass(A0)
- lea ie_TimeStamp(A0),A1
- move.l D0,TV_SECS(A1)
- move.l D0,TV_MICRO(A1)
-
- movea.l D0,A1 ; Zero !!!
- move.b (A2)+,D0 ; Character
- geta.l _CxBase,A6
- jsr _LVOInvertKeyMap(A6) ; Convert ASCII to RAW-KEY code
- tst.l D0
- beq.s .writeIE
-
- adr _InputIOReq,A1
- geta.l _SysBase,A6
- jsr _LVODoIO(A6) ; Send RAW-KEY-codes to input stream
- bra.s .writeIE
-
- .ieDone
- movea.l (sp)+,A6
- movea.l (sp)+,A2
- rts
-
- * ############### ADDITIONAL TO PktWait() ##################
-
- _NewPktWait
- movem.l D2/A0-A1/A4/A6,-(sp)
-
- movea.l (4).w,A6 ; Already set but...
- suba.l A1,A1
- jsr _LVOFindTask(A6) ; We're running from the CON-task
- movea.l D0,A0 ; Con-task
- movea.l TC_Userdata(A0),A4 ; Get base-register (stored in user-data)
- *
- ** We want to talk to the process of the console window
- *
- lea pr_MsgPort(A0),A0 ; Console process msg-port
- move.l A0,D2
- beq.s .exitFalse ; If no msg-port...
-
- .getPkt
- movea.l D2,A0 ; Messasge port
- jsr _LVOGetMsg(A6) ; Get message
- tst.l D0
- beq.s .waitPkt ; If none
-
- move.l D0,D2 ; Remember in D2 (message for console process)
-
- *
- ** We do not only check for ACTION_END, we care also about any REXX-server and IXEMUL-application
- ** who are using DOS-packets on their own; thus we need an identification for CONSOLE's termination,
- ** which infact is indicated through a Result1 of #-1 (TRUE) !!!
- ** NOTE: Earlier systems than v39 may use #1 for TRUE which is also o.k. .
- *
- movea.l D0,A0
- movea.l LN_NAME(A0),A0 ; WaitPkt() modifies a message so that it is stored in LN_NAME
- cmpi.l #ACTION_END,dp_Type(A0) ; User/application want to close something?
- bne.s .return
-
- cmpi.l #1,dp_Res1(A0) ; Old synonym fro TRUE?
- beq.s .sayQuit
-
- cmpi.l #-1,dp_Res1(A0) ; Really quit?
- bne.s .return
-
- .sayQuit
- geta.l _ThisTask,A1 ; Main (TSM) process (not console)!
- move.l #$1000,D0 ; Break signal (bit 12)
- jsr _LVOSignal(A6) ; Awake main process (tell it to terminate)
-
- .return
- move.l D2,D0 ; Message
-
- movem.l (sp)+,D2/A0-A1/A4/A6
- rts
-
- .waitPkt
- moveq #1,D0
- movea.l D2,A0 ; Msg-port
- moveq #0,D1
- move.b MP_SIGBIT(A0),D1 ; Get signal bit of message port
- lsl.l D1,D0 ; 1 << 31? (normally bit 31 is the first free signal)
- ori.w #$100,D0 ; Wait also for packet arrival (bit 8)
- jsr _LVOWait(A6)
- bra.s .getPkt
-
- .exitFalse
- adr _DummyMessage,A0 ; Because the function NewPktWait() is a sub of PktWait()
- move.l A0,D0 ; and PktWait() doesn't deals with empty messages we have
- * to create a dummy dos-packet where PktWait() can modify
- * it
-
- * ROM-listing of PktWait(): [OS 1.1 through OS 3.1]
- *
- * d_PktWait equ pr_PktWait-pr_MsgPort
- *
- * _PktWait ; struct StandardPacket *PktWait( void);
- * movem.l D7/A0-A1/A6,-(sp)
- * movea.l (4).w,A6
- * movea.l ThisTask(A6),A0 Own Task/process structure
- * cmpi.b #NT_PROCESS,LN_TYPE(A0)
- * bne.s .NotAProcess
- * adda.w #pr_MsgPort,A0 From Process to msg-port
- * move.l d_PktWait(A0),D1 Get installed PktWait() function of process structure
- * beq.s .NoPacketWait
- * movea.l D1,A0
- * jsr (A0) Calls installed PktWait() function
- * bra.s .ModifyMsg
- * .NotAProcess
- * movea.l A1,A0 If we're are an exec-task, call: struct StandardPacket *PktWait( struct MsgPort *p);
- * .NoPacketWait
- * move.l A0,D7
- * .GetMsg
- * movea.l D7,A0
- * jsr _LVOGetMsg(A6)
- * tst.l D0
- * beq.s .WaitForMsg
- * .ModifyMsg This is it, no empty messages allowed!!!
- * movea.l D0,A0
- * move.l LN_NAME(A0),D0 Packet
- * move.l D0,D1
- * asr.l #2,D1 BPTR Packet
- * movem.l (sp)+,D7/A0-A1/A6
- * rts
- * .WaitForMsg
- * moveq #1,D0
- * rol.l #8,D0
- * jsr _LVOWait(A6)
- * bra.s .GetMsg
-
-
- movem.l (sp)+,D2/A0-A1/A4/A6
- rts
-
- * ##################################
-
- _RemPort ; A0 - Port
- move.l A6,-(sp)
-
- geta.l _SysBase,A6
-
- move.b MP_SIGBIT(A0),D0
- move.l A0,-(sp)
- jsr _LVOFreeSignal(A6)
-
- movea.l (sp)+,A1
- moveq #MP_SIZE,D0
- jsr _LVOFreeMem(A6)
-
- movea.l (sp)+,A6
- rts
-
- _CreatePort ; void
- move.l A6,-(sp)
- move.l A2,-(sp)
-
- geta.l _SysBase,A6
-
- moveq #MP_SIZE,D0
- move.l #MEMF_CLEAR|MEMF_PUBLIC,D1 ; Prevent from being used by virtual memory
- jsr _LVOAllocMem(A6)
- tst.l D0
- beq.s 1$
- movea.l D0,A2
-
- moveq #-1,D0 ; Alloc _ANY_ signal
- jsr _LVOAllocSignal(A6)
- cmpi.l #-1,D0
- beq.s 2$
- move.b D0,MP_SIGBIT(A2)
-
- suba.l A1,A1
- jsr _LVOFindTask(A6)
- move.l D0,MP_SIGTASK(A2)
- move.b #NT_MSGPORT,LN_TYPE(A2)
- lea MP_MSGLIST(A2),A0
- NEWLIST A0 ; Exec include file MACRO
-
- move.l A2,D0
-
- movea.l (sp)+,A2
- movea.l (sp)+,A6
- rts
-
- 2$
- movea.l A2,A1
- moveq #MP_SIZE,D0
- jsr _LVOFreeMem(A6)
- 1$
- movea.l (sp)+,A2
- movea.l (sp)+,A6
-
- moveq #0,D0
- rts
-
- * ##################################
-
- *
- ** This material was released by Commodore Amiga (with stuff dropped in amiga.lib).
- ** Jan Kautz published a shortened version in a disk-mag (written in C).
- ** I translated it to asssembler without using any stuff of the amiga.lib.
- *
- _ConToWin ; (BPTR consoleHandle, struct Window **win, struct Process **proc, struct MsgPort **msgPort)
- * D0 A0 A1 A2
-
- movem.l D2-D5/A2-A6,-(sp)
-
- move.l A0,D3 ; Variable window
- move.l A1,D4 ; Variable contask
- move.l A2,D5 ; Variable conport
-
- move.l D0,D2 ; Console Handle
-
- bsr.s _CreatePort ; We need a port to comminicate with DOS
- movea.l D0,A5 ; IOReplyPort
- tst.l D0
- beq.w 1$
-
- moveq #id_SIZEOF,D0
- move.l #MEMF_CLEAR|MEMF_PUBLIC,D1
- geta.l _SysBase,A6
- jsr _LVOAllocMem(A6) ; The InfoData-structure holds the result after
- movea.l D0,A3 ; the DOS-packet has been invoked (InfoData)
- tst.l D0
- beq.w 2$
-
- moveq #sp_SIZEOF,D0
- move.l #MEMF_CLEAR|MEMF_PUBLIC,D1
- jsr _LVOAllocMem(A6) ; Let's talk to DOS via a packet
- movea.l D0,A2 ; StandardPacket
- tst.l D0
- beq.s 3$
-
- * movea.l A2,A2 ; Packet
- lea sp_Pkt(A2),A0 ; Pointer to sp_Pkt
- move.l A0,LN_NAME(A2) ; sp_Msg ^ node ^ name (valid DOS-packet)
- move.l A0,dp_Link(A0) ; sp_Pkt ^ dp_Link
- move.l A5,dp_Port(A0) ; sp_Pkt ^ dp_Port (IOReplyPort)
- moveq #ACTION_DISK_INFO,D0
- move.l D0,dp_Type(A0) ; sp_Pkt ^ dp_Type
- move.l A3,D0 ; APTR InfoData
- lsr.l #2,D0 ; to BPTR
- move.l D0,dp_Arg1(A0) ; sp_Pkt ^ dp_Arg1
-
- movea.l D2,A0 ; File handle (BPTR)
- adda.l A0,A0
- adda.l A0,A0 ; APTR file handle
- movea.l fh_Type(A0),A0 ; Console port to put msg
- movea.l MP_SIGTASK(A0),A0 ; Console's task
- movea.l D4,A1
- move.l A0,(A1) ; Save pointer to ConTask
- lea pr_MsgPort(A0),A0 ; Task's port
- movea.l D5,A1
- move.l A0,(A1) ; Save pointer to ConPort
- movea.l A2,A1 ; Packet
- jsr _LVOPutMsg(A6)
-
- movea.l A5,A0 ; IOReplyPort
- jsr _LVOWaitPort(A6)
-
- movea.l D3,A0
- move.l id_VolumeNode(A3),(A0) ; InfoData ^ VolumeNode = window's address
-
- movea.l A2,A1 ; StandardPacket
- moveq #sp_SIZEOF,D0
- jsr _LVOFreeMem(A6)
-
- movea.l A3,A1 ; InfoData
- moveq #id_SIZEOF,D0
- jsr _LVOFreeMem(A6)
-
- movea.l A5,A0 ; IOReplyPort
- bsr.w _RemPort
-
- moveq #-1,D0 ; TRUE
- movem.l (sp)+,D2-D5/A2-A6
- rts
-
- 3$
- movea.l A3,A1 ; InfoData
- moveq #id_SIZEOF,D0
- jsr _LVOFreeMem(A6)
- 2$
- movea.l A5,A0 ; IOReplyPort
- bsr.w _RemPort
- 1$
- moveq #0,D0 ; FALSE
- movem.l (sp)+,D2-D5/A2-A6
- rts
-
- _InputName
- dc.b 'input.device',0
- _ID
- dc.b '$VER: Tame Shell Master 1.2 (13.11.99) © 1999 »ONIX« - all rights reserved',13,10,0
-
- END
-