'===========================================================================
' Subject: EXECUTING ANOTHER PROGRAM          Date: 09/95 (00:00)          
'  Author: Unknown Author(s)                  Code: QB, PDS                
'  Origin: FidoNet QUIK_BAS Echo            Packet: INTERRPT.ABC
'===========================================================================
' > I don't really know how to use interrupts, but I could really use
' > that. Could you give me some commented code and an explanation of how
' > to do it?


'Load QB /LQB. This includes the routines needed for calling interrupts.
'Second, this will _*NOT*_ work in the IDE! You have to compile it...

'$INCLUDE: 'QB.BI'

DIM Regs AS RegType              ' Whatever it is (Look in that BI
DIM RegsX AS RegTypeX            ' file)

CLS

'               INT 21,4B - EXEC/Load and Execute Program
'        AH = 4B
'        AL = 00  to load and execute program
'           = 01  (Undocumented)  create program segment prefix and load
'                 program, but don't execute.  The CS:IP and SS:SP of the
'                 program is placed in parameter block. Used by debuggers
'           = 03  load program only
'           = 04  called by MSC spawn() when P_NOWAIT is specified
'        DS:DX = pointer to an ASCIIZ filename
'        ES:BX = pointer to a parameter block

'Okay. First, we have to load AX with the appropriate values. AX is the
'accumulator register, and is 16 bits wide. The two 8 bit portions are
'commonly referred to as AH and AL. (High and Low) Each can obviously
'hold one byte. AX=AH*256+AL

CLS
A$ = "C:\COMMAND.COM" + CHR$(0)        'ASCIIZ = STRING$+&H00
'B$ = "My parameters!! WOW! Command.com will barf on these ones.. <G>"
B$ = ""
RegsX.AX = &H4B00      ' 4b - Select EXEC function from Int 21
                       ' 00 - Just load & run. Don't mess with the other
                       '      stuff... Life is too short!
RegsX.DS = VARSEG(A$)  ' DS: Holds Segment of String
RegsX.DX = SADD(A$)    ' DX: Holds Offset of String
                       ' For reference, 32-bit pointers to ram can be
                       ' calculated using SEGMENT * 65536 + OFFSET
                       ' However, since QB, unlike PB, doesn't support
                       ' pointers in any form, this is only useful for
                       ' passing to assembly routines or interrupts
RegsX.ES = VARSEG(B$)  ' Parameters in a string... Segment
RegsX.BX = SADD(B$)    ' Offset. You should be getting the drill <G>

PRINT "Calling Int 21h EXEC on "; A$

CALL INTERRUPTX(&H21, RegsX, RegsX)

'        on return:
'        AX = error code if CF set  (see DOS ERROR CODES)


ProgramErrorCode = RegsX.AX
PRINT "Program exited with "; ProgramErrorCode
END
