home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / varie / tsm / source / tsm_v1.2.asm < prev   
Encoding:
Assembly Source File  |  1999-11-12  |  23.9 KB  |  1,048 lines

  1. *:ts=8
  2. *:fo=excel,11
  3.  
  4.  
  5. * :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
  6. * ::::::::::::::::###::::######::::::::::#:::::::::##::::::::
  7. * :####::::::::####:::::########:::::::::##::::::::##::::::::
  8. * :###############:::::##::::::::::::::::###::::::###::::::::
  9. * :::::#######:::::::::##:::::::::::::::::##::::::###::::::::
  10. * ::::::::##:::::::::::#::::::::::::::::::###:::::#:#::::::::
  11. * ::::::::#::::::::::::##:::::::::::::::::####:::##:#::::::::
  12. * :::::::##::::::::::::##::::::::::::::::::###:::#::#::::::::
  13. * :::::::##:::::::::::::##:::::::::::::::::#:##::#::#::::::::
  14. * :::::::#:::::::::::::::##::::::::::::::::#::####::##:::::::
  15. * ::::::##::::::::::::::::###::::::::::::::#:::##:::##:::::::
  16. * ::::::##:::::::::::::::::###:::::::::::::#:::::::::#:::::::
  17. * ::::::##::::::::::::::::::###::::::::::::#:::::::::##::::::
  18. * ::::::##:::::::::::::::::::##:::::::::::##:::::::::##::::::
  19. * ::::::##::::::::::::::::::::##::::::::::##::::::::::#::::::
  20. * ::::::##:::::::::::::::::::::#::::::::::##::::::::::##:::::
  21. * ::::::##:::::::::::::::::::::##:::::::::#::::::::::::#:::::
  22. * ::::::##:::::::::::::::::::::##::::::::##::::::::::::##::::
  23. * ::::::##:::::::::::::::::::::##::::::::##:::::::::::::##:::
  24. * ::::::##::::::::::::::::::::##::::::::##:::::::::::::::##::
  25. * :::::::#::::::::::::#########::::::::##::::::::::::::::###:
  26. * :::::::#:::::::::::::#######::::::::###::::::::::::::::::#:
  27. * :::::::#:::::::::::::::::::::::::::::#:::::::::::::::::::::
  28. * ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: version 1.2
  29.  
  30.  
  31. *
  32. ** This source-code for MCC and compatible assemblers.
  33. ** This stuff is Amiga-ROM® specific and re-entrant.
  34. ** It was written through the use of HiSoft's Devpac Amiga 3 assembler.
  35. *
  36. ** One of the few programs ever written for the Amiga that when resident
  37. ** will detach from CLI/Shell.
  38. *
  39. ** Please note: Cannot run multiple times on the same console-task
  40. ** otherwise strange things happen - because of an installed hook
  41. ** for process entry »PktWait« !
  42. *
  43.  
  44. *
  45. ** © Copyright 10 & 12/1998, 11/1999    Joerg van de Loo
  46. **                    Hoevel 15
  47. **                    47559 Kranenburg
  48. **                    Germany
  49. *
  50.  
  51. *
  52. ** 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  !
  53. *
  54.  
  55. *
  56. ** The problem: How to get informed when the console window is closed by user.
  57. ** For what:    To remove a console window from list of Workbench AppWindows.
  58. ** Remedy:    This file ... (TSM)
  59. *
  60.  
  61.     IFD    __G2    ; Devpac 2 (__G2 (BYTE) >= 43 == Devpac 3)
  62.         MACHINE    MC68000
  63.         OUTPUT        RAM:TSM
  64.         IDNT 'Tame Shell Master'
  65.         OPT    OW-
  66.     ENDC
  67.  
  68.     include    exec/exec_lib.i
  69.     include    exec/memory.i
  70.  
  71.     include    dos/dos_lib.i
  72.     include    dos/dos.i
  73.     include    dos/dosextens.i
  74.  
  75.     include    intuition/intuition_lib.i
  76.  
  77.     include    workbench/wb_lib.i
  78.     include    workbench/startup.i
  79.     include    workbench/workbench.i
  80.  
  81.     include    libraries/commodities_lib.i
  82.     include    libraries/commodities.i
  83.  
  84.     include    devices/input.i
  85.     include    devices/inputevent.i
  86.  
  87.  
  88.     STRUCTURE    BaseTable,0
  89.     APTR        nada            ; In german (nix da bzw. nichts)
  90.     APTR        _SysBase
  91.     APTR        _ThisTask
  92.     ULONG        _errno
  93.     APTR        _DOSBase
  94.     APTR        __ResSegment
  95.     APTR        __PgmName
  96.     ULONG        __PgmNameSize
  97. * ------------------------------------
  98.     APTR        _IntuitionBase
  99.     APTR        _WBenchBase
  100.     APTR        _CxBase
  101.     BPTR        _ConHandle
  102.     APTR        _WinPtr
  103.     APTR        _ConTask
  104.     APTR        _ConPort
  105.     APTR        _MsgPort
  106.     APTR        _OldPort
  107.     STRUCT        _DummyMessage,16    ; 14 required
  108.     APTR        _AppPort
  109.     APTR        _AppWin
  110.     APTR        _ReplyPort
  111.     STRUCT        _InputIOReq,IOSTD_SIZE
  112.     STRUCT        _InputEvent,ie_SIZEOF
  113.     STRUCT        _StrStorage,254
  114.     LABEL        BT_SIZEOF
  115.  
  116.  
  117. BREL    EQU    $8000
  118.  
  119. get    MACRO
  120.     move.\0    \1-BREL(A4),\2
  121.     ENDM
  122.  
  123. geta    MACRO
  124.     movea.\0 \1-BREL(A4),\2
  125.     ENDM
  126.  
  127. put    MACRO
  128.     move.\0    \1,\2-BREL(A4)
  129.     ENDM
  130.  
  131. adr    MACRO
  132.     lea    \1-BREL(A4),\2
  133.     ENDM
  134.  
  135. taz    MACRO            Test against zero
  136.     tst.\0    \1-BREL(A4)
  137.     ENDM
  138.  
  139. qmove    MACRO
  140.     ifgt    \1-255
  141.     move.\0    #\1,\2
  142.     mexit
  143.     endc
  144.  
  145.     ifle    \1-127
  146.     moveq    #\1,\2
  147.     mexit
  148.     endc
  149.  
  150.     moveq    #255-\1,\2
  151.     not.b    \2
  152.     ENDM
  153.  
  154.  
  155.  
  156. ;DEBUG    SET    1
  157.  
  158.     IFD    DEBUG
  159.         IFD    __G2
  160.         OPT    D+
  161.         ENDC
  162.  
  163.     XDEF    __start_me_up
  164.     XDEF    _FindSegment
  165.     XDEF    __exitNoProc
  166.     XDEF    __exitNoPgmNameMem
  167.     XDEF    __exitNoOutput
  168.     XDEF    __exitDOSOpen
  169.     XDEF    __exitNoDOS
  170.     XDEF    __exitReal
  171.     XDEF    _DOSName
  172.     XDEF    _IntName
  173.     XDEF    _WBenchName
  174.     XDEF    _CxName
  175.     XDEF    _Con
  176.  
  177.     XDEF    __createStartup
  178.     XDEF    _AwaitCloseDown
  179.     XDEF    _ReactToMsg
  180.     XDEF    _WriteIE
  181.     XDEF    _NewPktWait
  182.     XDEF    _RemPort
  183.     XDEF    _CreatePort
  184.     XDEF    _ConToWin
  185.     XDEF    _IntputName
  186.     XDEF    _ID
  187.  
  188.     ENDC
  189.  
  190.  
  191.     SECTION TEXT0,CODE
  192.  
  193. __start_me_up    ; int = _start_me_up( void)
  194.     moveq    #ERROR_INVALID_RESIDENT_LIBRARY,D2    ; Set up possible error
  195.  
  196.     movea.l    (4).w,A6            ; Zero-Page addressing mode!
  197.     cmpi.w    #32,LIB_VERSION(A6)        ; At least OS 1.2; it contains
  198.     bls.w    __exitReal            ;  the OpenLibrary( name, version) call
  199.  
  200.     moveq    #ERROR_NO_FREE_STORE,D2        ; Set up possible error
  201.  
  202.     qmove.l    BT_SIZEOF,D0            ; Var-table size
  203.     move.l    #MEMF_CLEAR|MEMF_PUBLIC,D1    ; Prevent from being used by GIGAMEM etc.
  204.     jsr    _LVOAllocMem(A6)
  205.     tst.l    D0
  206.     beq.w    __exitReal            ; No BSS section
  207.  
  208.     movea.l    D0,A4                ; Set up base register
  209.     adda.l    #BREL,A4
  210.  
  211.     put.l    A6,_SysBase            ; Remember it (if possible in fast-ram)
  212.  
  213.     suba.l    A1,A1
  214.     jsr    _LVOFindTask(A6)
  215.     put.l    D0,_ThisTask
  216.  
  217.     moveq    #ERROR_INVALID_RESIDENT_LIBRARY,D2    ; Set up possible error
  218.  
  219.     lea    _DOSName(pc),A1
  220.     moveq    #36,D0                ; beta Kick 2.0 and up
  221.     jsr    _LVOOpenLibrary(A6)
  222.     put.l    D0,_DOSBase
  223.     beq.w    __exitNoDOS
  224.  
  225.     lea    _IntName(pc),A1
  226.     moveq    #36,D0
  227.     jsr    _LVOOpenLibrary(A6)
  228.     put.l    D0,_IntuitionBase
  229.     beq.w    __exitDOSOpen
  230.  
  231.     lea    _WBenchName(pc),A1
  232.     moveq    #36,D0
  233.     jsr    _LVOOpenLibrary(A6)
  234.     put.l    D0,_WBenchBase
  235.     beq.w    __exitDOSOpen
  236.  
  237.     lea    _CxName(pc),A1
  238.     moveq    #36,D0
  239.     jsr    _LVOOpenLibrary(A6)
  240.     put.l    D0,_CxBase
  241.     beq.w    __exitDOSOpen
  242.  
  243. * ##############################
  244.  
  245.     lea    _ConName(pc),A0            ; Get current console handle (from where we have been started)
  246.     move.l    A0,D1
  247.     move.l    #MODE_OLDFILE,D2        ; It really exists...
  248.     geta.l    _DOSBase,A6
  249.     jsr    _LVOOpen(A6)            ; Tell DOS we'll use console window
  250.     put.l    D0,_ConHandle            ; so it cannot be closed
  251.  
  252. * ##############################
  253.  
  254. *
  255. ** Copy from Shell given name into private buffer
  256. *
  257.     geta.l    _ThisTask,A0
  258.     movea.l    pr_CLI(A0),A0            ; Pointer CommandLineInterface
  259.     add.l    A0,A0                ; BPTR to APTR
  260.     add.l    A0,A0
  261.     movea.l    cli_CommandName(A0),A2        ; Pointer to BSTR
  262.     adda.l    A2,A2                ; BSTR to STRPTR
  263.     adda.l    A2,A2
  264.     moveq    #0,D2                ; Erase D2
  265.     move.b    (A2)+,D2            ; Get length-byte of name
  266.     move.l    D2,D0                ; Length of name also in D0
  267.     addq.w    #8,D0                ; Plus 1 because of zero-byte
  268.     andi.l    #-8,D0    
  269.     put.l    D0,__PgmNameSize        ; Store in basetable
  270.     move.l    #MEMF_PUBLIC|MEMF_CLEAR,D1    ; Requirements
  271.     geta.l    _SysBase,A6
  272.     jsr    _LVOAllocMem(A6)        ; Get memory
  273.     put.l    D0,__PgmName            ; Store in basetable
  274.     beq.w    __exitNoPgmNameMem        ; If no memory
  275.     movea.l    D0,A0                ; Buffer for name
  276.     bra.s    2$                ; 'Cause of DBF (-alias)
  277. 1$
  278.     move.b    (A2)+,(A0)+            ; Copy name
  279. 2$
  280.     subq.w    #1,D2
  281.     bcc.s    1$                ; If some chars left
  282.     clr.b    (A0)                ; Zero-byte
  283.  
  284.  
  285. *
  286. ** Here we check now whether the pgm is in the ResidentList; if it is we'll
  287. ** increment the UseCount (seg_UC) but the first code hunk is not erased in
  288. ** this case to break the hunk-list of the AmigaDOS load-file.
  289. *
  290.     lea    __start_me_up(pc),A0
  291.     subq.l    #4,A0                ; APTR segment
  292.     bsr.w    _FindSegment            ; Find own Resident-Segment
  293.     put.l    D0,__ResSegment            ; Resident-Segment or zero
  294.     beq.s    .normalStart
  295.  
  296.     movea.l    D0,A0
  297.     addq.l    #1,seg_UC(A0)            ; We are resident, so the second code fragment is,
  298. *                          but the first code segment quits thus we increment
  299. *                          usecount by 1 indicating TSM (2nd code fragment)
  300. *                          is still used!
  301.  
  302. .normalStart
  303.     
  304. *
  305. ** Now we start the following code-segment(s) (goes into D3) as real background process
  306. *
  307.     lea    __start_me_up(pc),A0        ; Pointer to code start
  308.     subq.l    #4,A0                ; Pointer to BPTR next-segment
  309.     move.l    (A0),D3                ; BPTR-segment
  310.  
  311.     taz.l    __ResSegment            ; Flag set (segment in ResList)?
  312.     bne.s    .hunkStuffDone            ; Yes...
  313.  
  314.     clr.l    (A0)                ; Erase linked hunk-pointer to next segment (important!) (only if not resident!)
  315.  
  316. .hunkStuffDone
  317.     get.l    __PgmName,D1            ; Address name task
  318.     moveq    #0,D2
  319.     get.l    _ThisTask,A0            ; Current TSM process
  320.     move.b    LN_PRI(A0),D2            ; Get current TSM's priority
  321.     subq.b    #1,D2                ; One less than normal priority (pri is non-important while running, but at startup!)
  322. *    move.l    D3,D3                ; Segment(s)
  323.     move.l    #2560,D4            ; Stack size (2.5 KByte)
  324.     geta.l    _DOSBase,A6            ; DOS takes control
  325.     jsr    _LVOCreateProc(A6)        ; Create a DOS process
  326.     tst.l    D0                ; D0 ~0 = msg-port of created task
  327.     beq.w    __exitNoProc            ; If zero, error!
  328.  
  329.     movea.l    D0,A0
  330.     lea    -TC_SIZE(A0),A0            ; From port to process
  331.     move.l    A4,TC_Userdata(A0)        ; Overgive new task the base-table
  332.  
  333.     move.l    #$10000,D0            ; Bit 16
  334.     geta.l    _SysBase,A6
  335.     jsr    _LVOWait(A6)            ; Wait for 2nd program to say we can quit
  336.  
  337. *
  338. * The allocated/opened things will not freed nor closed !!!
  339. *
  340.     suba.l    A1,A1
  341.     geta.l    _SysBase,A6
  342.     jsr    _LVOFindTask(A6)
  343.     movea.l    D0,A0                ; ThisTask
  344.     clr.l    pr_Result2(A0)            ; No error!
  345.     moveq    #0,D0                ; For the CLI
  346.     rts                    ; Program (#1) ends
  347.  
  348. *
  349. ** This routine will test if in the ResidentList of DOS the overgiven segment
  350. ** resides.
  351. *
  352. _FindSegment    ; struct Segment *FindSegment( struct *Segment)
  353. *            D0                 A0
  354.     move.l    A2,-(sp)
  355.  
  356.     geta.l    _DOSBase,A1
  357.     movea.l    dl_Root(A1),A1            ; RootNode
  358.     movea.l    rn_Info(A1),A1            ; BPTR DosInfo
  359.     adda.l    A1,A1
  360.     adda.l    A1,A1                ; DosInfo
  361.     tst.l    di_NetHand(A1)
  362.     beq.s    .SegNotFound
  363.     movea.l    di_NetHand(A1),A1        ; BPTR NetHand
  364.     adda.l    A1,A1
  365.     adda.l    A1,A1                ; NetHand (pointer to ResList)
  366.     bra.s    .CmpSeg
  367. .NextSeg
  368.     tst.l    seg_Next(A1)
  369.     beq.s    .SegNotFound
  370.     movea.l    seg_Next(A1),A1            ; BPTR segment
  371.     adda.l    A1,A1
  372.     adda.l    A1,A1                ; APTR segment
  373. .CmpSeg
  374.     movea.l    seg_Seg(A1),A2            ; BPTR segment
  375.     adda.l    A2,A2
  376.     adda.l    A2,A2                ; APTR segment
  377.  
  378.     cmpa.l    A0,A2                ; Segments the same?
  379.     bne.s    .NextSeg
  380.  
  381.     move.l    A1,D0                ; ResList
  382. .EndSeg
  383.     movea.l    (sp)+,A2
  384.     rts
  385.  
  386. .SegNotFound
  387.     moveq    #0,D0
  388.     bra.s    .EndSeg
  389.  
  390. * ################################
  391.  
  392. __exitNoProc
  393.     moveq    #ERROR_TASK_TABLE_FULL,D2
  394.  
  395.     geta.l    __PgmName,A1
  396.     get.l    __PgmNameSize,D0
  397.     geta.l    _SysBase,A6
  398.     jsr    _LVOFreeMem(A6)
  399.  
  400. __exitNoPgmNameMem
  401.     get.l    _ConHandle,D1
  402.     geta.l    _DOSBase,A6
  403.     jsr    _LVOClose(A6)            ; Allow to shut down console
  404.  
  405. __exitDOSOpen
  406.     geta.l    _SysBase,A6
  407.  
  408.     taz.l    _WBenchBase
  409.     beq.s    1$
  410.     geta.l    _WBenchBase,A1
  411.     jsr    _LVOCloseLibrary(A6)
  412. 1$
  413.     taz.l    _CxBase
  414.     beq.s    1$
  415.     geta.l    _CxBase,A1
  416.     jsr    _LVOCloseLibrary(A6)
  417.  
  418.     taz.l    _IntuitionBase
  419.     beq.s    2$
  420.     geta.l    _IntuitionBase,A1
  421.     jsr    _LVOCloseLibrary(A6)
  422. 2$
  423.     geta.l    _DOSBase,A1
  424.     jsr    _LVOCloseLibrary(A6)
  425.  
  426. __exitNoDOS
  427.     geta.l    _ThisTask,A0
  428.     move.l    D2,pr_Result2(A0)
  429.  
  430.     movea.l    A4,A1
  431.     suba.l    #BREL,A1
  432.     qmove.l    BT_SIZEOF,D0
  433.     jsr    _LVOFreeMem(A6)
  434.  
  435. __exitReal
  436.     move.l    D2,D0
  437.     rts
  438.  
  439. _DOSName
  440.     dc.b    'dos.library',0
  441. _IntName
  442.     dc.b    'intuition.library',0
  443. _WBenchName
  444.     dc.b    'workbench.library',0
  445. _CxName
  446.     dc.b    'commodities.library',0
  447. _ConName
  448.     dc.b    'CONSOLE:',0                ; <- means current input stream
  449.  
  450.  
  451. * ################################################################
  452.  
  453.     SECTION    TEXT1,CODE
  454.  
  455. __createStartup
  456.     movea.l    (4).w,A6            ; SysBase alias
  457.     suba.l    A1,A1
  458.     jsr    _LVOFindTask(A6)
  459.     movea.l    D0,A0                ; Own task
  460. .getBaseReg
  461.     tst.l    TC_Userdata(A0)
  462.     beq.s    .getBaseReg
  463.     movea.l    TC_Userdata(A0),A4        ; Set up base register
  464.     get.l    _ThisTask,-(sp)            ; Master task
  465.     put.l    A0,_ThisTask            ; And setup new own task !!!
  466.  
  467.     get.l    _ConHandle,D0            ; Console's handle
  468.     adr    _WinPtr,A0
  469.     adr    _ConTask,A1
  470.     adr    _ConPort,A2
  471.     bsr.w    _ConToWin            ; Get console's window, task and port address
  472.  
  473.     movea.l    (sp)+,A1
  474.     move.l    #$10000,D0            ; Signal bit 16
  475.     geta.l    _SysBase,A6
  476.     jsr    _LVOSignal(A6)            ; Tell master task to quit
  477.  
  478.     moveq    #10,D1
  479.     put.l    D1,_errno            ; Set up possible error
  480.  
  481.     tst.l    D0                ; Do we got the needed things from ConToWin()?
  482.     beq.w    3$
  483.  
  484.     bsr.w    _CreatePort
  485.     put.l    D0,_AppPort
  486.     beq.s    3$
  487.  
  488.     bsr.w    _CreatePort
  489.     put.l    D0,_ReplyPort
  490.     beq.s    2$
  491.  
  492.     adr    _InputIOReq,A1
  493.     moveq    #IOF_QUICK,D0
  494.     move.b    D0,IO_FLAGS(A1)
  495.     lea    _InputName(pc),A0        ; We'll use
  496.     moveq    #0,D0                ;  the
  497. *    adr    _InputIOReq,A1            ;  console
  498.     moveq    #0,D1                ;  device
  499.     jsr    _LVOOpenDevice(A6)        ;  to send RAW-KEY
  500.     tst.l    D0                ;  codes
  501.     bne.s    1$
  502.  
  503.     adr    _InputIOReq,A0            ; Set reply-port
  504.     get.l    _ReplyPort,MN_REPLYPORT(A0)    ; so that the console-device knows who gets the msgs
  505.  
  506.     moveq    #0,D0
  507.     moveq    #0,D1
  508.     geta.l    _WinPtr,A0
  509.     geta.l    _AppPort,A1
  510.     suba.l    A2,A2
  511.     geta.l    _WBenchBase,A6
  512.     jsr    _LVOAddAppWindowA(A6)        ; Make out of the console window (Shell) an app-windoww
  513.     put.l    D0,_AppWin
  514.     beq.s    0$                ; No App-Window thus do nada
  515.  
  516.     moveq    #0,D0
  517.     put.l    D0,_errno            ; No error occurred
  518.  
  519.     bsr.w    _AwaitCloseDown            ; Fetch datas from console's window
  520.  
  521.     geta.l    _AppWin,A0
  522.     geta.l    _WBenchBase,A6
  523.     jsr    _LVORemoveAppWindow(A6)
  524.  
  525. 0$
  526.     adr    _InputIOReq,A1
  527.     geta.l    _SysBase,A6
  528.     jsr    _LVOCloseDevice(A6)    
  529.  
  530. 1$
  531.     geta.l    _ReplyPort,A0
  532.     bsr.w    _RemPort
  533.  
  534. 2$
  535.     geta.l    _AppPort,A0
  536.     bsr.w    _RemPort
  537.  
  538. 3$
  539.     get.l    _ConHandle,D1
  540.     geta.l    _DOSBase,A6
  541.     jsr    _LVOClose(A6)            ; Allow to shut down console
  542.  
  543.     get.l    _errno,D2
  544.     geta.l    _ThisTask,A0
  545.     move.l    D2,pr_Result2(A0)
  546.  
  547.     geta.l    _SysBase,A6
  548.     jsr    _LVOForbid(A6)
  549.  
  550.     taz.l    __ResSegment            ; ResList?
  551.     beq.s    4$
  552.     geta.l    __ResSegment,A0
  553.     subq.l    #1,seg_UC(A0)            ; Usecount -1!
  554.     bra.s    5$
  555. 4$
  556.     lea    __createStartup(pc),A0        ; Pointer to pgm code
  557.     subq.l    #4,A0                ; -4 = segment pointer
  558.     move.l    A0,D1                ; to D1
  559.     lsr.l    #2,D1                ; to BPTR
  560.     geta.l    _DOSBase,A6            ; Base DOS
  561.     jsr    _LVOUnLoadSeg(A6)        ; Remove by pgm used mem
  562. 5$
  563.     geta.l    _SysBase,A6
  564.  
  565.     geta.l    _CxBase,A1
  566.     jsr    _LVOCloseLibrary(A6)
  567.  
  568.     geta.l    _WBenchBase,A1
  569.     jsr    _LVOCloseLibrary(A6)
  570.  
  571.     geta.l    _IntuitionBase,A1
  572.     jsr    _LVOCloseLibrary(A6)
  573.  
  574.     geta.l    _DOSBase,A1
  575.     jsr    _LVOCloseLibrary(A6)
  576.  
  577.     geta.l    __PgmName,A1
  578.     get.l    __PgmNameSize,D0
  579.     jsr    _LVOFreeMem(A6)
  580.  
  581.     movea.l    A4,A1
  582.     suba.l    #BREL,A1
  583.     qmove.l    BT_SIZEOF,D0
  584.     jsr    _LVOFreeMem(A6)
  585.  
  586.     jsr    _LVOPermit(A6)
  587.  
  588.     move.l    D2,D0
  589.     rts
  590.  
  591. * ################### MAIN ###################
  592.  
  593. _AwaitCloseDown
  594.     move.l    A5,-(sp)
  595.  
  596.     geta.l    _ConTask,A5            ; Let us talk with the console task
  597.  
  598.     tst.l    TC_Userdata(A5)            ; Assumption: if TC_Userdata is used, another TSM obtains
  599.     bne.s    .done                ; the handle to this console task so we should terminate immediately
  600.  
  601.     bsr.w    _CreatePort
  602.     put.l    D0,_MsgPort            ; We need a message port...
  603.     beq.s    .done
  604.  
  605.     move.l    A4,TC_Userdata(A5)        ; Remember A4 in global for new WaitPkt() function
  606.     put.l    pr_MsgPort(A5),_OldPort        ; Remember for restoring the old msg-port of console task
  607.     move.l    D0,pr_MsgPort(A5)        ; Drop our message port where old of console task has been hooked up
  608.  
  609.     lea    _NewPktWait(pc),A0        ; The additional function for the original WaitPkt()
  610.     move.l    A0,pr_PktWait(A5)
  611.  
  612.     geta.l    _SysBase,A6
  613.  
  614. .event
  615.     geta.l    _AppPort,A0
  616.     moveq    #1,D0
  617.     moveq    #0,D1
  618.     move.b    MP_SIGBIT(A0),D1
  619.     lsl.l    D1,D0
  620.     ori.w    #$1000,D0            ; And also CTRL-C (bit 12)
  621.     jsr    _LVOWait(A6)            ; Wait...
  622.  
  623.     moveq    #12,D1                ; Does our task (not the console's one) got a break signal?
  624.     btst.l    D1,D0
  625.     bne.s    .remove
  626.  
  627.     geta.l    _AppPort,A0            ; Check if we got a workbench message
  628.     moveq    #0,D1
  629.     move.b    MP_SIGBIT(A0),D1        ; Signal bit of port
  630.     btst.l    D1,D0
  631.     bne.s    .receivedAppMsg            ; Message received...
  632.  
  633.     bra.s    .event                ; If not...
  634.  
  635. .remove
  636.     clr.l    pr_PktWait(A5)            ; Remove additional function for WaitPkt()
  637.     get.l    _OldPort,pr_MsgPort(A5)        ; Restore original (by DOS set up) msg-port
  638.     clr.l    TC_Userdata(A5)            ; Restore
  639.     geta.l    _MsgPort,A0            ; Our allocated msg-port
  640.     bsr.w    _RemPort            ; Remove it
  641. .done
  642.     movea.l    (sp)+,A5
  643.     rts
  644.  
  645. .receivedAppMsg
  646.     geta.l    _AppPort,A0
  647.     jsr    _LVOGetMsg(A6)
  648.     tst.l    D0
  649.     beq.s    .msgLoopDone
  650.  
  651.     move.l    D0,-(sp)
  652.  
  653.     movea.l    D0,A0
  654.     bsr.s    _ReactToMsg
  655.  
  656.     movea.l    (sp)+,A1
  657.     jsr    _LVOReplyMsg(A6)
  658.  
  659. .msgLoopDone
  660.     bra.s    .event
  661.  
  662.     IFND    MTYPE_APPWINDOW            ; Define of include file V39 to V40 differ...
  663. MTYPE_APPWINDOW    EQU    7
  664.     ENDC
  665.  
  666. _ReactToMsg
  667.     movem.l    D2-D4/A2/A6,-(sp)
  668.  
  669.     cmpi.w    #MTYPE_APPWINDOW,am_Type(A0)
  670.     bne.s    5$
  671.  
  672.     movea.l    A0,A2
  673.     moveq    #1,D4
  674.  
  675.     geta.l    _WinPtr,A0
  676.     geta.l    _IntuitionBase,A6
  677.     jsr    _LVOActivateWindow(A6)        ; Which window gets the input stream?
  678.  
  679.     geta.l    _DOSBase,A6
  680. 1$
  681.     move.l    D4,D0                ; Parse argument x
  682.     subq.w    #1,D0                ; as index
  683.     lsl.w    #3,D0                ; * 8
  684.     movea.l    am_ArgList(A2),A0        ; Arguments
  685.     lea    0(A0,D0.w),A0            ; Current argument
  686.     move.l    A0,D0
  687.     beq.s    5$                ; E.g.: Disk is mounted (e.g. CD-ROM) but not in drive!
  688.  
  689.     move.l    A0,-(sp)            ; Current arg-pointer onto stack
  690.  
  691.     move.l    wa_Lock(A0),D1            ; Get lock of drawer
  692.     adr    _StrStorage,A0            ; Buffer to store characters
  693.     move.w    #$2022,(A0)+            ; Write blank and double quote
  694.     move.l    A0,D2
  695.     qmove.l    251,D3                ; Max. room for 251 characters
  696.     jsr    _LVONameFromLock(A6)        ; Get name from lock
  697.  
  698.     adr    _StrStorage,A0            ; Address string buffer
  699. 2$
  700.     tst.b    (A0)+                ; Find end of drawer name
  701.     bne.s    2$
  702.  
  703.     subq.l    #1,A0                ; One too far; pointed to zero byte (terminator)
  704.     cmpi.b    #':',-1(A0)            ; Volume name or drawer name?
  705.     beq.s    3$
  706.  
  707.     move.b    #'/',(A0)+            ; Was drawer...
  708. 3$
  709.     move.l    (sp)+,A1            ; Get back pointer to arg-pointer
  710.     movea.l    wa_Name(A1),A1            ; Name of file
  711. 4$
  712.     move.b    (A1)+,(A0)+            ; Copy name at end of drawer name
  713.     bne.s    4$
  714.  
  715.     move.b    #'"',-1(A0)
  716.     clr.b    (A0)
  717.  
  718.     adr    _StrStorage,A0            ; Address complete filename
  719.     bsr.s    _WriteIE            ; Write RAW-KEY-codes
  720.  
  721.     addq.l    #1,D4                ; One more argument
  722.     cmp.l    am_NumArgs(A2),D4
  723.     bls.s    1$                ; If some left to work out
  724.  
  725. 5$
  726.     movem.l    (sp)+,D2-D4/A2/A6
  727.     rts
  728.  
  729. _WriteIE    ; STRPTR A0
  730.     move.l    A2,-(sp)
  731.     move.l    A6,-(sp)
  732.  
  733.     movea.l    A0,A2                ; The string
  734.  
  735. .writeIE
  736.     tst.b    (A2)
  737.     beq.s    .ieDone
  738.  
  739.     adr    _InputIOReq,A1
  740.     moveq    #IOF_QUICK,D0
  741.     move.b    D0,IO_FLAGS(A1)
  742.     moveq    #IND_WRITEEVENT,D0
  743.     move.w    D0,IO_COMMAND(A1)
  744.     moveq    #ie_SIZEOF,D0
  745.     move.l    D0,IO_LENGTH(A1)
  746.     adr    _InputEvent,A0
  747.     move.l    A0,IO_DATA(A1)
  748.  
  749.     moveq    #IECLASS_RAWKEY,D0
  750.     move.b    D0,ie_Class(A0)
  751.     moveq    #0,D0
  752.     move.w    D0,ie_Code(A0)
  753.     move.b    D0,ie_SubClass(A0)
  754.     lea    ie_TimeStamp(A0),A1
  755.     move.l    D0,TV_SECS(A1)
  756.     move.l    D0,TV_MICRO(A1)
  757.  
  758.     movea.l    D0,A1                ; Zero !!!
  759.     move.b    (A2)+,D0            ; Character
  760.     geta.l    _CxBase,A6
  761.     jsr    _LVOInvertKeyMap(A6)        ; Convert ASCII to RAW-KEY code
  762.     tst.l    D0
  763.     beq.s    .writeIE
  764.     
  765.     adr    _InputIOReq,A1
  766.     geta.l    _SysBase,A6
  767.     jsr    _LVODoIO(A6)            ; Send RAW-KEY-codes to input stream
  768.     bra.s    .writeIE
  769.     
  770. .ieDone
  771.     movea.l    (sp)+,A6
  772.     movea.l    (sp)+,A2
  773.     rts
  774.  
  775. * ############### ADDITIONAL TO PktWait() ##################
  776.  
  777. _NewPktWait
  778.     movem.l    D2/A0-A1/A4/A6,-(sp)
  779.  
  780.     movea.l    (4).w,A6            ; Already set but...
  781.     suba.l    A1,A1
  782.     jsr    _LVOFindTask(A6)        ; We're running from the CON-task
  783.     movea.l    D0,A0                ; Con-task
  784.     movea.l    TC_Userdata(A0),A4        ; Get base-register (stored in user-data)
  785. *
  786. ** We want to talk to the process of the console window
  787. *
  788.     lea    pr_MsgPort(A0),A0        ; Console process msg-port
  789.     move.l    A0,D2
  790.     beq.s    .exitFalse            ; If no msg-port...
  791.  
  792. .getPkt
  793.     movea.l    D2,A0                ; Messasge port
  794.     jsr    _LVOGetMsg(A6)            ; Get message
  795.     tst.l    D0
  796.     beq.s    .waitPkt            ; If none
  797.  
  798.     move.l    D0,D2                ; Remember in D2 (message for console process)
  799.  
  800. *
  801. ** We do not only check for ACTION_END, we care also about any REXX-server and IXEMUL-application
  802. ** who are using DOS-packets on their own; thus we need an identification for CONSOLE's termination,
  803. ** which infact is indicated through a Result1 of #-1 (TRUE) !!!
  804. ** NOTE: Earlier systems than v39 may use #1 for TRUE which is also o.k. .
  805. *
  806.     movea.l    D0,A0
  807.     movea.l    LN_NAME(A0),A0            ; WaitPkt() modifies a message so that it is stored in LN_NAME
  808.     cmpi.l    #ACTION_END,dp_Type(A0)        ; User/application want to close something?
  809.     bne.s    .return
  810.  
  811.     cmpi.l    #1,dp_Res1(A0)            ; Old synonym fro TRUE?
  812.     beq.s    .sayQuit
  813.  
  814.     cmpi.l    #-1,dp_Res1(A0)            ; Really quit?
  815.     bne.s    .return
  816.  
  817. .sayQuit
  818.     geta.l    _ThisTask,A1            ; Main (TSM) process (not console)!
  819.     move.l    #$1000,D0            ; Break signal (bit 12)
  820.     jsr    _LVOSignal(A6)            ; Awake main process (tell it to terminate)
  821.  
  822. .return
  823.     move.l    D2,D0                ; Message
  824.  
  825.     movem.l    (sp)+,D2/A0-A1/A4/A6
  826.     rts
  827.  
  828. .waitPkt
  829.     moveq    #1,D0
  830.     movea.l    D2,A0                ; Msg-port
  831.     moveq    #0,D1
  832.     move.b    MP_SIGBIT(A0),D1        ; Get signal bit of message port
  833.     lsl.l    D1,D0                ; 1 << 31?    (normally bit 31 is the first free signal)
  834.     ori.w    #$100,D0            ; Wait also for packet arrival (bit 8)
  835.     jsr    _LVOWait(A6)
  836.     bra.s    .getPkt
  837.  
  838. .exitFalse
  839.     adr    _DummyMessage,A0        ; Because the function NewPktWait() is a sub of PktWait()
  840.     move.l    A0,D0                ; and PktWait() doesn't deals with empty messages we have
  841. *                          to create a dummy dos-packet where PktWait() can modify
  842. *                          it
  843.  
  844. *    ROM-listing of PktWait(): [OS 1.1 through OS 3.1]
  845. *
  846. *    d_PktWait    equ    pr_PktWait-pr_MsgPort
  847. *
  848. *    _PktWait    ; struct StandardPacket *PktWait( void);
  849. *        movem.l    D7/A0-A1/A6,-(sp)
  850. *        movea.l    (4).w,A6
  851. *        movea.l    ThisTask(A6),A0        Own Task/process structure
  852. *        cmpi.b    #NT_PROCESS,LN_TYPE(A0)
  853. *        bne.s    .NotAProcess
  854. *        adda.w    #pr_MsgPort,A0        From Process to msg-port
  855. *        move.l    d_PktWait(A0),D1    Get installed PktWait() function of process structure
  856. *        beq.s    .NoPacketWait
  857. *        movea.l    D1,A0
  858. *        jsr    (A0)            Calls installed PktWait() function
  859. *        bra.s    .ModifyMsg
  860. *    .NotAProcess
  861. *        movea.l    A1,A0            If we're are an exec-task, call: struct StandardPacket *PktWait( struct MsgPort *p);
  862. *    .NoPacketWait
  863. *        move.l    A0,D7
  864. *    .GetMsg
  865. *        movea.l    D7,A0
  866. *        jsr    _LVOGetMsg(A6)
  867. *        tst.l    D0
  868. *        beq.s    .WaitForMsg
  869. *    .ModifyMsg                This is it, no empty messages allowed!!!
  870. *        movea.l    D0,A0
  871. *        move.l    LN_NAME(A0),D0        Packet
  872. *        move.l    D0,D1
  873. *        asr.l    #2,D1            BPTR Packet
  874. *        movem.l    (sp)+,D7/A0-A1/A6
  875. *        rts
  876. *    .WaitForMsg
  877. *        moveq    #1,D0
  878. *        rol.l    #8,D0
  879. *        jsr    _LVOWait(A6)
  880. *        bra.s    .GetMsg
  881.  
  882.  
  883.     movem.l    (sp)+,D2/A0-A1/A4/A6
  884.     rts
  885.  
  886. * ##################################
  887.  
  888. _RemPort    ; A0 - Port
  889.     move.l    A6,-(sp)
  890.  
  891.     geta.l    _SysBase,A6
  892.  
  893.     move.b    MP_SIGBIT(A0),D0
  894.     move.l    A0,-(sp)
  895.     jsr    _LVOFreeSignal(A6)
  896.  
  897.     movea.l    (sp)+,A1
  898.     moveq    #MP_SIZE,D0
  899.     jsr    _LVOFreeMem(A6)
  900.  
  901.     movea.l    (sp)+,A6
  902.     rts
  903.  
  904. _CreatePort    ; void
  905.     move.l    A6,-(sp)
  906.     move.l    A2,-(sp)
  907.  
  908.     geta.l    _SysBase,A6
  909.  
  910.     moveq    #MP_SIZE,D0
  911.     move.l    #MEMF_CLEAR|MEMF_PUBLIC,D1    ; Prevent from being used by virtual memory
  912.     jsr    _LVOAllocMem(A6)
  913.     tst.l    D0
  914.     beq.s    1$
  915.     movea.l    D0,A2
  916.  
  917.     moveq    #-1,D0                ; Alloc _ANY_ signal
  918.     jsr    _LVOAllocSignal(A6)
  919.     cmpi.l    #-1,D0
  920.     beq.s    2$
  921.     move.b    D0,MP_SIGBIT(A2)
  922.  
  923.     suba.l    A1,A1
  924.     jsr    _LVOFindTask(A6)
  925.     move.l    D0,MP_SIGTASK(A2)
  926.     move.b    #NT_MSGPORT,LN_TYPE(A2)
  927.     lea    MP_MSGLIST(A2),A0
  928.     NEWLIST A0                ; Exec include file MACRO
  929.  
  930.     move.l    A2,D0
  931.  
  932.     movea.l    (sp)+,A2
  933.     movea.l    (sp)+,A6
  934.     rts
  935.  
  936. 2$
  937.     movea.l    A2,A1
  938.     moveq    #MP_SIZE,D0
  939.     jsr    _LVOFreeMem(A6)
  940. 1$
  941.     movea.l    (sp)+,A2
  942.     movea.l    (sp)+,A6
  943.  
  944.     moveq    #0,D0
  945.     rts
  946.  
  947. * ##################################
  948.  
  949. *
  950. ** This material was released by Commodore Amiga (with stuff dropped in amiga.lib).
  951. ** Jan Kautz published a shortened version in a disk-mag (written in C).
  952. ** I translated it to asssembler without using any stuff of the amiga.lib.
  953. *
  954. _ConToWin    ; (BPTR consoleHandle, struct Window **win, struct Process **proc, struct MsgPort **msgPort)
  955. *            D0            A0            A1            A2
  956.  
  957.     movem.l    D2-D5/A2-A6,-(sp)
  958.  
  959.     move.l    A0,D3                ; Variable window
  960.     move.l    A1,D4                ; Variable contask
  961.     move.l    A2,D5                ; Variable conport
  962.  
  963.     move.l    D0,D2                ; Console Handle
  964.  
  965.     bsr.s    _CreatePort            ; We need a port to comminicate with DOS
  966.     movea.l    D0,A5                ; IOReplyPort
  967.     tst.l    D0
  968.     beq.w    1$
  969.  
  970.     moveq    #id_SIZEOF,D0
  971.     move.l    #MEMF_CLEAR|MEMF_PUBLIC,D1
  972.     geta.l    _SysBase,A6
  973.     jsr    _LVOAllocMem(A6)        ; The InfoData-structure holds the result after
  974.     movea.l    D0,A3                ; the DOS-packet has been invoked (InfoData)
  975.     tst.l    D0
  976.     beq.w    2$
  977.  
  978.     moveq    #sp_SIZEOF,D0
  979.     move.l    #MEMF_CLEAR|MEMF_PUBLIC,D1
  980.     jsr    _LVOAllocMem(A6)        ; Let's talk to DOS via a packet
  981.     movea.l    D0,A2                ; StandardPacket
  982.     tst.l    D0
  983.     beq.s    3$
  984.  
  985. *    movea.l    A2,A2                ; Packet
  986.     lea    sp_Pkt(A2),A0            ; Pointer to sp_Pkt
  987.     move.l    A0,LN_NAME(A2)            ; sp_Msg ^ node ^ name (valid DOS-packet)
  988.     move.l    A0,dp_Link(A0)            ; sp_Pkt ^ dp_Link
  989.     move.l    A5,dp_Port(A0)            ; sp_Pkt ^ dp_Port (IOReplyPort)
  990.     moveq    #ACTION_DISK_INFO,D0
  991.     move.l    D0,dp_Type(A0)            ; sp_Pkt ^ dp_Type
  992.     move.l    A3,D0                ; APTR InfoData
  993.     lsr.l    #2,D0                ; to BPTR
  994.     move.l    D0,dp_Arg1(A0)            ; sp_Pkt ^ dp_Arg1
  995.  
  996.     movea.l    D2,A0                ; File handle (BPTR)
  997.     adda.l    A0,A0
  998.     adda.l    A0,A0                ; APTR file handle
  999.     movea.l    fh_Type(A0),A0            ; Console port to put msg
  1000.     movea.l    MP_SIGTASK(A0),A0        ; Console's task
  1001.     movea.l    D4,A1
  1002.     move.l    A0,(A1)                ; Save pointer to ConTask
  1003.     lea    pr_MsgPort(A0),A0        ; Task's port
  1004.     movea.l    D5,A1
  1005.     move.l    A0,(A1)                ; Save pointer to ConPort
  1006.     movea.l    A2,A1                ; Packet
  1007.     jsr    _LVOPutMsg(A6)
  1008.  
  1009.     movea.l    A5,A0                ; IOReplyPort
  1010.     jsr    _LVOWaitPort(A6)
  1011.  
  1012.     movea.l    D3,A0
  1013.     move.l    id_VolumeNode(A3),(A0)        ; InfoData ^ VolumeNode = window's address
  1014.  
  1015.     movea.l    A2,A1                ; StandardPacket
  1016.     moveq    #sp_SIZEOF,D0
  1017.     jsr    _LVOFreeMem(A6)
  1018.  
  1019.     movea.l    A3,A1                ; InfoData
  1020.     moveq    #id_SIZEOF,D0
  1021.     jsr    _LVOFreeMem(A6)
  1022.  
  1023.     movea.l    A5,A0                ; IOReplyPort
  1024.     bsr.w    _RemPort
  1025.  
  1026.     moveq    #-1,D0                ; TRUE
  1027.     movem.l    (sp)+,D2-D5/A2-A6
  1028.     rts
  1029.  
  1030. 3$
  1031.     movea.l    A3,A1                ; InfoData
  1032.     moveq    #id_SIZEOF,D0
  1033.     jsr    _LVOFreeMem(A6)
  1034. 2$
  1035.     movea.l    A5,A0                ; IOReplyPort
  1036.     bsr.w    _RemPort
  1037. 1$
  1038.     moveq    #0,D0                ; FALSE
  1039.     movem.l    (sp)+,D2-D5/A2-A6
  1040.     rts
  1041.  
  1042. _InputName
  1043.     dc.b    'input.device',0
  1044. _ID
  1045.     dc.b    '$VER: Tame Shell Master 1.2 (13.11.99) © 1999 »ONIX« - all rights reserved',13,10,0
  1046.  
  1047.     END
  1048.