Announcement

Collapse
No announcement yet.

Popup Multiplex

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Popup Multiplex

    Hi,
    I would like to create "Installable Commands" for 4DOS using PowerBASIC 3.5 for DOS. This involves creating a TSR using the POPUP MULTIPLEX command. I'm running MS-DOS 6.22.

    The 4DOSTECH.TXT file has this to say;

    Writing Installable Commands

    An "installable command" is created with a memory-resident program (TSR) which can receive signals from 4DOS and process commands. 4DOS makes every command available to such TSRs before it is executed; if any TSR chooses to execute the command, 4DOS will do no further processing. Otherwise, 4DOS processes the command normally.

    The 4DOS "Installable Command" interface is compatible with an undocumented interface present in COMMAND.COM for MS-DOS and PC-DOS 3.3 and above. This interface is documented more thoroughly in the excellent reference text Undocumented DOS by Schulman et. al., published by Addison Wesley.

    4DOS looks for an installable command after alias and variable expansion and redirection, and after checking to see if the command is a drive change, but before checking for an internal or external command.

    4DOS first makes an INT 2Fh call to determine whether any TSR loaded will respond to the command, with:

    AX AE00h
    BX offset of command line buffer:
    first byte = maximum length of command line
    second byte = actual length of command line, not including
    trailing CR
    remainder = command line, with a trailing CR
    CH FFh
    CL length of command line, not including the command name
    DX FFFFh
    SI offset of command name buffer:
    first byte = length of command name
    remainder = command name, shifted to upper case
    and padded with blanks to 11 characters
    DS segment for command line and command name buffers

    If the TSR does not recognize the command as its own, it must pass the INT 2Fh along with registers unchanged. If it does recognize the command, it must return 0FFh in AL. The command should not be executed at this point.

    4DOS will then make another call (buffer formats are the same as above):

    AX AE01h
    BX offset of command line buffer
    CH 0
    CL length of command name
    DX FFFFh
    SI offset of command name buffer
    DS segment for command line and command name buffers

    If the TSR executes the command line, it must set the command name length at DS:[SI] to 0. If the command name length is not set to 0, 4DOS will attempt to execute the command as an internal or external command. This allows the TSR to return a modified command line to 4DOS by modifying the command line buffer at DS:BX, and leaving the command name length byte at DS:[SI] set to a non-zero value. If the command is executed,the TSR should return the result of the command (zero for normal return or non-zero for an error) in AL.

    End of 4DOSTECH.TXT

    Here's my 4DOSTSR.BAS program so far;

    $COMPILE EXE
    $OPTION cntlbreak OFF
    $ERROR ALL ON

    $INCLUDE "REGNAMES.INC"

    Dummy& = SETMEM(-700000)

    POPUP MULTIPLEX &HAE00, &HFFFF

    PRINT "Before Interrupt call"
    PRINT
    PRINT "AX = ";
    PRINT REG(%AX)
    PRINT "BX = ";
    PRINT REG(%BX)
    PRINT "CX = ";
    PRINT REG(%CX)
    PRINT "DX = ";
    PRINT REG(%DX)

    REM If the TSR does not recognize the command as its own, it must pass
    REM the INT 2Fh along with registers unchanged.

    CALL INTERRUPT &H2F

    PRINT "After Interrupt call"
    PRINT
    PRINT "AX = ";
    PRINT REG(%AX)
    PRINT "BX = ";
    PRINT REG(%BX)
    PRINT "CX = ";
    PRINT REG(%CX)
    PRINT "DX = ";
    PRINT REG(%DX)

    POPUP SLEEP USING ems, "C:\TEMP\4DOSTSR.SWP"

    End of 4DOSTSR.BAS

    Now, I'm not sure where to loop this code to check for the call from 4DOS, or if I'm on the right track or not so far.

    I've looked at the "Popping up on the multiplex interrupt" section in the PB user's guide, but it is using POPUP KEY as the TSR activator.

    Any constructive suggestions would be appreciated.

    Thanks,

    Joe

  • #2
    From the archives...
    Code:
    '                       TSRKEL.BAS - skeleton for PB TSR'S
    ' FILE :
    ' PURPOSE : 
    ' USAGE:   
    ' HISTORY ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    ' 06.06.98 Ported this skeleton to PB/DOS 3.5
    ' ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    $COMPILE EXE            ' TSR's must be exe
     ' this statement must come first.
    $STACK 2048
    ' Valid values for $STACK are 2048 thru 32766 (decimal)
    $DIM ARRAY
    ' options: ALL, ARRAY, NONE. If an option is enabled, the Arrays or Variables
    ' must be DIM'ed prior to appearing in a statement. Like AUTODIM
    $LIB COM-, IPRINT+, GRAPH-, CGA-, LPT-, FULLFLOAT-
    '$LIB options include:
    ' COM - Serial communications support
    ' LPT - line printer support
    ' GRAPH - all graphics            If a certain graphics is enabled,
    '  CGA                            all subordinate graphics are also
    '  EGA                            enabled. Priority is CGA,EGA,VGA;
    '  VGA                            HERC is independent. GRAPH- and CGA- do
    '  HERC                           permit the use of COLOR statements
    ' FULLFLOAT - full floating point emulation
    ' ALL  - all the above
    ' $FLOAT PROCEDURE
    ' $FLOAT options are:
    '  PROCEDURE - larger but faster than EMULATE; runs on any CPU
    '  EMULATE   - smaller but slower than EMULATE
    '  NPX       - runs only on 80x87, 80386 and 80486 processors
    $OPTION CNTLBREAK+
    $ERROR ALL ON
    ' if not on, program will continue to run with wierd results.
    ' options: BOUNDS, NUMERIC, OVERFLOW, STACK or ALL. Best to debug with
    ' ALL ON. (my choice for finished, thoroughly debugged program: ALL OFF)
    $STRING 4
    ' values 1,2,4,8,16,32. Default = 32. Maximum size of any one string in Kb.
    ' actual size = Kb - 18 bytes overhead. Use minimum in each program.
    ' $string 4 minimum needed to save entire screen in one shot.
    CommBuffer:
    $COM 0                  ' default 256 bytes. Generally, 1024 good @2400 baud
    $SOUND 0
    ' maximum size of background music buffer for PLAY statment in notes: 1-4096 notes.
    ' Each note requires 8 bytes. Default = 32 notes (256 bytes)
    $OPTIMIZE SPEED
    ' options: SPEED, SIZE.
    
    
    StandardMaterial:
    '========= Standard Materials ===========================================
    DEFINT A - Z                    ' Variables are Integer unless overridden
    '======= End Standard Materials ==========================================
    
    LinkerOptions:
    ' ===== Linker Options ================
    ' $LINK filename ( extension .PBU or .OBJ required) - multiple statements OK
    ' Also include DECLARE SUB|FUNCTION and PUBLIC statements here.
    ' ==== End Linker Options =============
    
    ProgramPlanning:
    ' ======== Program Planning Section =================
    ' BASIC FLOW :
    ' ========= End Program Planning Section ============
    
    ProgramConstants:
    '======== Named Program Constants ============
    %TRUE      =  -1
    %FALSE     =   0
    DebugControl:
    %Debugging =   0                ' debugger
    '====== End Named Program Constants ==========
    
    SharedDataNames:
    ' ========= SHARED Data Names ====================
    ' SHARED ......
    ' ======== End SHARED Data Names =================
    StandardStartup:
    '======== Standard Program Startup =================================
    
    
    VideoSegment = &hB800           ' make this soft in the future
    				' this is for color monitor
    ReservedMem& =                  ' amount of memory to save for dynamic data
    HotKeyLit$   =                  ' could make hot-key a command-line option
    HotKeyShift  =                  ' SHIFT=&h03 CTRL=&h04 ALT=&h08
    HotKeyScan   =                  ' ScrollLock=&h10 NumLock=&h20 CapsLock=&h40
    HotKeyAny    =                  ' Add them for multiple combinations.
    MpxInstallAX =                  ' to check if previously installed
    MpxInstallDX =                  ' maybe offer command-line option???
    MpxSleepAX   =                  ' anything different from MpxInstallAX
    MpxSleepDX   =                  '  "          "        "      "     DX
    ProgramName$ =                  ' used at startup to announce installation
    
    CommandLine$ = UCASE$(COMMAND$) ' Get the parameters
    
     IF INSTR (CommandLine$, "/U") THEN
      UnInstallit = %TRUE
     END IF
    
     ' check other command line parameters here!!!!
    
    
    POPUP KEY CHR$(HotKeyShift, HotKeyScan, HotKeyAny)
     ' set popup method. Other Options: MULTIPLEX, INTERRUPT, TIMER,QUIET
    ' Check For Previous installation
    
    POPUP MULTIPLEX MpxInstallAX, MpxInstallDX   ' adds Mpx popup
    REG 1, MpxInstallAX
    REG 4, MpxInstallDX
    IF UnInstallit THEN
     REG 2, 1		' send "deinstall" command to resident copy
     CALL INTERRUPT &h2F
     END                    ' and terminate this one.
    ELSE
     REG 2, 0
    END IF
    
    CALL INTERRUPT &h2F
    
    IF REG(1) <> MpxInstallAX AND REG(4) <> MpxInstallDX THEN END
    ' already installed; could add error message, but why bother?
    
    Dummy& = SETMEM (-700000)          ' free as much memory as possible
    DUMMY& = SETMEM (ReservedMem&)     ' save some screen save & work
    
    DIM SaveVideo AS STRING * 4000   ' this eliminated the error 7 on the
                                     ' second save of the screen...
    PRINT ProgramName$;" installed. Use ";HotKeyLit$;" to invoke."
    
    ' ****** MAIN LOOP HERE *********
    DO
    
      REG 1, MpxSleepAX            '  so we can check on popup
      REG 4, MpxSleepDX
      POPUP SLEEP                   ' add swapfile and/or EMS here!
    
      ' program pops up here!
    
      ' check if this an attempt to deinstall or load a second time...
      IF REG(1) = MpxInstallAX AND REG(4) = MpxInstallDX THEN
       ' Since this happens only when starting the program from the DOS command
       ' line, not necessary to worry about locating cursor; but looks neater
       ' if it's in a colored VIEW TEXT box.
    
          IF REG(2) = 1 THEN
              CALL UnInstall     ' which will end the program
          ELSE
              PRINT ProgramName$ + " is already Installed."
              PRINT " Use "; HotKeyLit$;" to invoke or ";ProgramName$;" /U" to de-install."
          END IF
    
      ELSE                           ' it's a real call...
    
          ' save the screen ....    USUALLY NEED TO DO THIS
          DEF SEG = VideoSegment
          SaveVideo = PEEK$ (0,4000)
          ' and the cursor
          SaveY = CSRLIN: SaveX = POS(0)
                                      ' if using VIEW TEXT for TSR OUTPUT
                                      ' PUT HERE with COLOR and CLS statments
    
          ' ********************************************************************
          '   HERE IS WHERE TO GOSUB "whatever the TSR is supposed to do"
          ' ********************************************************************
    
          ' restore the screen  USUALLY!
           DEF SEG = VideoSegment
           POKE$ 0, SaveVideo
           DEF SEG
           CALL BiosLocate (SaveY,SaveX) ' this deals with "hidden" cursors
    
      END IF                         ' if real hotkey call
    
    
    LOOP
    
    SUB BiosLocate (R,C)
    ' Locates cursor without telling PB. No Error if R or C out of range,
    ' which is how some programs "hide" the cursor.
     REG 1, &h0200                          ' AH = 02 set position
     REG 4, ((R -1) * 256) + C - 1          ' DH = row DL = Col (0-based)
     CALL INTERRUPT &h10
    END SUB
    
    '*****************New sub ******************
    SUB Uninstall  'Try to uninstall
       'Purpose:  Uninstalls the current tsr program if possible.
       'if not possible, at least it inactivates the program
       'Problem: Can't uninstall while another program is running, so
       'we have to wait for other program to end, then popup
       'and try to uninstall!
       'By Al Musella  2/2/94
       ' MCM's note: if swapping to disk this SUB needs a much longer delay on
       ' my system (2 sec). Probably not true on a fast machine (I have a
       ' 6 Mhx 286 w/30ms hard disk.) 6/28/94.
    
       '**** WHAT WE COULD DO Here is POPUP KEY STOP/OFF, POPUP MULTIPLEX STOP/OFF
       ' and go into a sleep loop here where the program continues to try
       ' to de-install itself by popping up on timer and seeing if it
       ' can now de-install itself. Not tested 8/4/97.
    
        PRINT" Attempting to uninstall - please wait 5 seconds..";
        I=0
        POPUP Timer 9  'try every .5 seconds
        WHILE I<10  'try for 5 seconds - then give up
           popup sleep
           INCR I
           IF POPUP(1) then
              PRINT ProgramName$ + " Uninstalled"
              END
           ELSE
             PRINT ".";
           END IF
        WEND
    
        ' IF no END/Deactivate desired, cancel the "END" Statement below.
        ' once ended like this, program cannot be un-installed even if it would
        ' be OK; need to reboot to reclaim memory.
    
        PRINT"UNABLE TO UNINSTALL ";ProgramName$"; " - DEACTIVATING"
        END
    
    END SUB
    
    ' ** END OF FILE **    Michael C. Mattias CIS:72030,3563 6/28/94 revised 6/6/98
    Description when this was available in the "PCVENB" forum on Compuserve:

    Code:
    [72030,3563] Michael Mattias
    TSRSKL.ZIP
      Bin,  Bytes:     7562, Count:   239, 21-Feb-94
    
      Title   : Skeleton source code aid for coding PB3 TSR's.
      Keywords: PB3 TSR HELP SKELETON FRAMEWORK SOURCE FREE
    
      Updated PB source code to serve as a "skeleton" for TSR coding.
      Includes screen save/restore, de-install from command line, expanded
      documentation. Previous version had 90+ d/ls. Free, Public Domain. From
      Michael Mattias.
    I seem to have lost the documentation. Let me look in "OLD" section of my hard drives. It should be there somewhere.
    Michael Mattias
    Tal Systems (retired)
    Port Washington WI USA
    [email protected]
    http://www.talsystems.com

    Comment


    • #3
      Hi,
      Thankyou for the code, but your code shows how to pop up on a key selection, and then go to SLEEP.

      I'm not sure if or how I should be using SLEEP.

      I have the hardcopy PowerBASIC Manuals, and all of the example code, which includes TSR example code.

      The code you provide shows how to POPUP on the MULTIPLEX, check to see if the TSR is already resident, and then un-install. I will not need to un-install my TSR, as it will become part of the OS.

      The PB TSR will be activated by the 4DOS.COM program, via Interrupt 2Fh, as indicated in the tech doc from my previous message.

      Again, any example of "installable command" code for 4DOS would be appreciated. I have asked in the 4DOS groups, but so far, we have not come up with any.

      Thanks,

      Joe

      Comment


      • #4
        Hi,
        I'm starting to get things working. Here's the code that I came up with so far,

        $COMPILE EXE
        $OPTION cntlbreak OFF
        $ERROR ALL ON

        $INCLUDE "REGNAMES.INC"

        Dummy& = SETMEM(-700000)

        POPUP MULTIPLEX &HAE00, &HFFFF

        DO
        POPUP SLEEP USING ems, "C:\TEMP\4DOSTSR.SWP"

        PRINT "Before Interrupt call"
        PRINT
        PRINT "AX = ";
        PRINT HEX$(REG(%AX))
        PRINT "BX = ";
        PRINT HEX$(REG(%BX))
        PRINT "CX = ";
        PRINT HEX$(REG(%CX))
        PRINT "DX = ";
        PRINT HEX$(REG(%DX))

        REM If the TSR does not recognize the command as its own, it must pass
        REM the INT 2Fh along with registers unchanged.

        CALL INTERRUPT &H2F

        PRINT "After Interrupt call"
        PRINT
        PRINT "AX = ";
        PRINT HEX$(REG(%AX))
        PRINT "BX = ";
        PRINT HEX$(REG(%BX))
        PRINT "CX = ";
        PRINT HEX$(REG(%CX))
        PRINT "DX = ";
        PRINT HEX$(REG(%DX))
        LOOP

        End of 4DOSTSR.BAS

        When I have this in memory, it provides me with the info returned from 4DOS. For example, if I type DIR /W at the prompt, and then press enter, CL returns 03, showing the command line length, not including the command name, which is correct (space/W). If I type log.exe 42 it returns 3, while log.exe 4 returns 2.

        Now I have to figure out the other items, such as command name, command tail, etc. I'm not that good with the segmentffset stuff, so please feel free to jump in and provide input in regards to the tech info from my previous messages.

        Thanks,

        Joe

        Comment


        • #5
          I must be in a good mood today to go thru this effort for you.


          Let me get my PB/DOS help file up (ain't none of this stuff still fresh)....

          Ok, here we go.

          Code:
          [ ALT-F1 ]─[ SHIFT-F1 ]── PowerBASIC Help System ──────────────BACK...PgU
           POPUP MULTIPLEX axmask%, dxmask%
          
           Use this function to check for your TSR already installed.  It
           uses the DOS multiplex interrupt (2Fh).  dxmask may have any value
           but axmask values from &H0000-&HBFFF are reserved by DOS.
           If id mask is matched, popup is attempted immediately: if popup is
           not successful due to the status of DOS (busy), register dx is
           returned unchanged, and register ax is returned with a value of zero.
           Upon popup, callers registers are stored in the REG array
           Upon popdown, callers registers are loaded from the REG array.
           REG array allows two-way communication between foreground/background
          Well, your own doc says...
          AX AE00h
          ...
          DX FFFFh
          So there's your mask for your popop:
          Code:
            POPUP MULTIPLEX  &hAE00, &hFFFF
          So, you've popped up. Now what? Well, the doc says you have to read the command line, which is stored as

          BX offset of command line buffer:
          first byte = maximum length of command line
          second byte = actual length of command line, not including trailing CR
          remainder = command line, with a trailing CR
          CH FFh
          CL length of command line, not including the command name
          DX FFFFh
          DS segment for command line and command name buffers
          If I read this correctly, DS:BX points to a buffer where the first two bytes are control info and the information(the command itself) follows

          So let's read the two bytes at offset BX, and then read that command, shall we?

          Code:
          LOCAL pB AS BYTE PTR 
          
          DO 
              POPUP SLEEP  .....
              ' --------------------------------------
              ' begin execution here when you wake up 
              ' --------------------------------------- 
           
          
              SaveDefSeg  = pbvDefSeg   ' save current data segment 
          
              DEF SEG  = REG(%DS)       ' set segment in synch with caller 
              pb       = REG(%BX)       ' set pointer to where data begin within segment
          
              maxLen   = @pb            ' read the max length 
              INCR        pb            ' advance one byte
              actLen   = @pb            ' read actual length 
              Cmd      = SPACE$(actLen) '  build buffer to hold the command string
          
              INCR       pb          ' advance to first character of command 
              FOR Z  = 1 TO actLen   ' for each valid character of command 
                  MID$(Cmd, Z, 1) =  CHR$(@pb)   ' store the character
                 INCR  pb           ' and advance to next character
               NEXT Z
          
              IF Cmd = "something I can handle" then.....
          
                  just follow the above model to do the rest of the stuff. 
                  ....
              END IF
          
             'Restore the default data segment 
             DEF SEG =  SaveDefSeg 
          
          LOOP
          To arrange to popup on a second (different) set of AX/DX values, I'm pretty sure you can just add another POPUP MULTPLEX statement with that ax/dx mask. To decide what to do when you wake up, just query the AX and DX registers

          It's a start for you anyway.

          MCM
          Michael Mattias
          Tal Systems (retired)
          Port Washington WI USA
          [email protected]
          http://www.talsystems.com

          Comment


          • #6
            I have been thinking about this. I might have those pointers wrong.
            Code:
            pb       = REG(%BX)       ' set pointer to where data begin within segment
            That might need to be a full 32-bit MS-DOS ptr, in which case it would be...
            Code:
            pb =  REG(%DS) * 256 * 256 + %REG(%BX)
            ... and you would not have to save, set and reset DS with DEF SEG.

            MCM
            Michael Mattias
            Tal Systems (retired)
            Port Washington WI USA
            [email protected]
            http://www.talsystems.com

            Comment


            • #7
              Hi,
              I'm at a point where my program is doing 50% of what I want, but does not complete the task properly.

              When I run the program, and enter my installable command, it produces the following output;

              Code:
              c:\data\pb\4dos>mylog 4
              Cannot Un-Install      
               1.38629436111989      
              Cannot Un-Install      
              Cannot Un-Install      
              Cannot Un-Install      
              Cannot Un-Install      
              Cannot Un-Install      
              Unknown command mylog  
              Cannot Un-Install      
              Cannot Un-Install      
              Cannot Un-Install      
              Cannot Un-Install      
              Cannot Un-Install
              Two things are not working here. First, I keep getting the "Unknown command mylog", when I should not be getting it. I'm doing as the 4DOSTECH.TXT document says;

              Code:
                  ! mov al,&HFF           
                  ! mov word ptr DS:[SI],0
                                          
                  CALL INTERRUPT &H2F
              but I feel that some address or segment is not set the way it should be.

              I also think this has something to do with the fact that I cannot un-install the TSR. As the Multiplex Interrupt is not that well documented, and I cannot find any examples in any language of how to create an installable command (such as the MS-DOS APPEND or PRINT installable commands), I'm not really sure how to proceed.

              I've stepped through the code using Turbo Debugger, and I see where the code is looping, but I'm not sure why. (I'm using Turbo Debugger in Resident mode to debug the TSR).

              Any constructive assistance would be appreciated.

              Thanks,

              Joe

              Code:
              $COMPILE EXE
              $DEBUG MAP ON
              $OPTION cntlbreak OFF
              $ERROR ALL ON
              
              $INCLUDE "REGNAMES.INC"
              
              DIM pb AS WORD
              
              Dummy& = SETMEM(-700000)
              
              POPUP MULTIPLEX &HAE00, &HFFFF
              
              POPUP SLEEP USING ems, "C:\TEMP\4DOSTSR.SWP"
              
              DO
                SaveDefSeg = pbvDefSeg       'save current data segment
              
                DEF SEG = REG(%DS)           'set segment in synch with caller
              
                pb = H2D(HEX$(REG(%BX)))
              
                maxLen = PEEK(pb)                   'read the max length
              
                INCR pb
                actLen = PEEK(pb)                   'read actual length
              
                CmdLnBuf$ = SPACE$(actLen)       'build buffer to hold the command string
              
                INCR pb
                FOR Z = 1 TO actLen          'for each valid character of command
                  MID$(CmdLnBuf$, Z, 1) = CHR$(PEEK(pb))  'store the character
                    INCR pb                    'and advance to next character
                NEXT Z
              
                ValidCmd$ = "N"
                ExitTSR$ = "Y"
              
                IF LEFT$(UCASE$(CmdLnBuf$),5) = "MYLOG" THEN
                  ValidCmd$ = "Y"
                END IF
              
                IF LEFT$(CmdLnBuf$,3) = "JjJ" THEN
                  ExitTSR$ = "Y"
                END IF
              
              REM If the TSR does not recognize the command as its own, it must pass
              REM  the INT 2Fh along with registers unchanged.
              
                IF ValidCmd$ = "Y" THEN
                  ! mov al,&HFF
                  ! mov word ptr DS:[SI],0
              
                  CALL INTERRUPT &H2F
              
                  IF LEN(CmdLnBuf$) > 5 THEN
                    TheParam$ = RIGHT$(CmdLnBuf$,LEN(CmdLnBuf$)-6)
                    IF VAL(TheParam$) = 0 THEN
                      PRINT "Invalid Parameter For MYLOG"
                    ELSE
                      PRINT LOG(VAL(TheParam$))
                    END IF
                  ELSE
                    PRINT "USAGE: MYLOG #"
                  END IF
                ELSE
                  DEF SEG = SaveDefSeg
              
                  CALL INTERRUPT &H2F
                END IF
              
                DEF SEG = SaveDefSeg
              
                POPUP SLEEP
              
                IF ExitTSR$ = "Y" THEN
                  IF POPUP(1) THEN
                    PRINT "Safe To Un-Install"
                    END
                  ELSE
                    PRINT "Cannot Un-Install"
                  END IF
                END IF
              LOOP
              
              END
              
              FUNCTION H2D (TheHex$) AS WORD
                TheString$ = "ABCDEF"
              
                IF LEN(TheHex$) = 4 THEN
                  sNumb1$ = RIGHT$(TheHex$,1)
                  sNumb2$ = MID$(TheHex$,3,1)
                  sNumb3$ = MID$(TheHex$,2,1)
                  sNumb4$ = LEFT$(TheHex$,1)
              
                  ThePos = INSTR(TheString$,sNumb1$)
              
                  IF ThePos > 0 THEN
                    bNumb1? = ThePos + 9
                  ELSE
                    bNumb1? = VAL(sNumb1$)
                  END IF
              
                  ThePos = INSTR(TheString$,sNumb2$)
              
                  IF ThePos > 0 THEN
                    bNumb2? = ThePos + 9
                  ELSE
                    bNumb2? = VAL(sNumb2$)
                  END IF
              
                  ThePos = INSTR(TheString$,sNumb3$)
              
                  IF ThePos > 0 THEN
                    bNumb3? = ThePos + 9
                  ELSE
                    bNumb3? = VAL(sNumb3$)
                  END IF
              
                  ThePos = INSTR(TheString$,sNumb4$)
              
                  IF ThePos > 0 THEN
                    bNumb4? = ThePos + 9
                  ELSE
                    bNumb4? = VAL(sNumb4$)
                  END IF
              
                  Result?? = bNumb1? * 1
                  Result?? = Result?? + bNumb2? * 16
                  Result?? = Result?? + bNumb3? * 256
                  Result?? = Result?? + bNumb4? * 4096
              
                  H2D = Result??
              
                END IF
              END FUNCTION

              Comment


              • #8
                I'm certainly no assembly guy, but don't you have to save and restore some registers in your procedure before you start using ASM statements?
                Michael Mattias
                Tal Systems (retired)
                Port Washington WI USA
                [email protected]
                http://www.talsystems.com

                Comment


                • #9
                  Hi,
                  The reason I am getting the "Unknown command" is because I have to perform a "chain interrupt", that is, I have to pass the INT 2F along with AX=&HAEFF to tell the command processor that I am going to handle the command typed at the prompt.

                  According to the Microsoft C help file;

                  "The _chain_intr routine joins one interrupt handler to another. It is
                  generally used when a user-defined interrupt handler begins processing,
                  then chains to the original interrupt handler to finish processing. The
                  stack and the registers of the first routine are passed to the second,
                  allowing the second routine to return as if it had been called directly."

                  Is it possible to chain an interrupt in PowerBASIC 3.5? I believe I would have to do a "chain interrupt" just before POPUP SLEEP.

                  Thanks,

                  Joe

                  Comment


                  • #10
                    I don't know squat about interrupts but it sure looks like the help file explains interrupt chaining...

                    Code:
                     POPUP INTERRUPT int%, ticks%, ON|OFF, ON|OFF                              │
                                                                                               │
                     The interrupt number may be defined only once, before the first           │
                     POPUP SLEEP.  int sets interrupt number to "hook". ticks sets timeout     │
                     limit in ticks (18.2 per second). [i]The first ON|OFF controls execution     │
                     or "chain" of the prior interrupt handler upon entry - typically on - if  │
                     on, whenever the interrupt is executed, the prior handler is called       │
                     immediately (even if the POPUP is active, therefore "busy"); when         │
                     complete, POPUP is attempted per the usual rules. The second ON|OFF       │
                     controls execution or "chain" of the prior interrupt handler upon exit    │
                     from the POPUP, typically off[/i].  One-way communication is possible:        │
                     upon POPUP, callers registers are stored in the REG array.                │
                                                                                               │
                    Not being helped by this a lot due to unfamiliarity, I'd still have four things to try:
                    Both on, Both Off, First Only On, Second Only On.
                    Michael Mattias
                    Tal Systems (retired)
                    Port Washington WI USA
                    [email protected]
                    http://www.talsystems.com

                    Comment


                    • #11
                      Hi,
                      While POPUP INTERRUPT has these options, POPUP MULTIPLEX does not, and I am using POPUP MULTIPLEX since POPUP INTERRUPT will not allow me to use &H2F, at least according to page 214 of the PB3.5 Reference Guide.

                      Joe

                      Comment


                      • #12
                        That caveat re POPUP INTERRUPT is not in the help file.

                        Hmmmm......Maybe...

                        ...You just 'CALL INTERRUPT &h2F' yourself to do the 'chain?' (restoring original registers if you modified them first?)

                        (I know I have have never been in this territory before).

                        WHOA... that can't be right. That would start an endless loop, wouldn't it?

                        I'm pretty sure there is some kind of system service you can call to find the 'chain' for any interrupt. That might be useful. Or maybe not.
                        Last edited by Michael Mattias; 6 Sep 2008, 02:52 PM.
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment

                        Working...
                        X