The QBNews Page 8 Volume 1, Number 2 February 2, 1990 ---------------------------------------------------------------------- W h o y a g o n n a c a l l ? C A L L I N T E R R U P T ---------------------------------------------------------------------- Using the PSP by Hector Plasmic COMMAND$ lets you see what was entered on the command line (the command tail) by the user when your program was started. For instance, if the user typed: C:\> PROGRAM -a -b PRINT COMMAND$ would display "-A -B". Notice that the command tail was uppercased by COMMAND$, though. What if you need to receive case sensitive information from the command line? Well, it just happens that DOS can provide you with the answer. DOS keeps an area called the PSP (program segment prefix) which contains a lot of potentially useful information in the following format: 0000h Interrupt 20h 0002h Segment, end of allocation block 0004h Reserved 0005h Long call to MS-DOS function handler 000Ah Previous contents of termination handler interrupt vector (Int 22h) 000Eh Previous contents of CTRL-C interrupt vector (Int 23h) 0012h Previous contents of critical-error interrupt vector (Int 24h) 0016h Reserved 002Ch Segment address of environment block 002Eh Reserved 005Ch Default file control block #1 006Ch Default file control block #2 (overlaid if FCB #1 opened) 0080h Command tail and default DTA (buffer) So, to get the command tail in its pre-uppercased format, all we have to do is PEEK into the PSP. But how do we find out where the PSP is? Interrupt 21h function 62h will get it for you, returning the PSP's segment in register .bx. If DEF SEG is set to the returned .bx value, PEEK will be looking at the PSP. What follows is a simple program to get the command tail from the PSP, list the environment, and return the name of the program that's currently running. DEFINT A-Z TYPE RegType AX AS INTEGER BX AS INTEGER CX AS INTEGER DX AS INTEGER The QBNews Page 9 Volume 1, Number 2 February 2, 1990 BP AS INTEGER SI AS INTEGER DI AS INTEGER Flags AS INTEGER END TYPE TYPE RegType2 AX AS INTEGER BX AS INTEGER CX AS INTEGER DX AS INTEGER BP AS INTEGER SI AS INTEGER DI AS INTEGER Flags AS INTEGER DS AS INTEGER ES AS INTEGER END TYPE 'You must link in QB.LIB (QB.QLB) for Interrupt DECLARE SUB Interrupt (Intnum%, InReg AS RegType, OutReg AS RegType) DECLARE SUB InterruptX (Intnum%, InReg2 AS RegType2, OutReg2 AS RegType2) DIM SHARED InReg AS RegType DIM SHARED OutReg AS RegType InReg.AX = 25088 'Find PSP Interrupt &H21, InReg, OutReg DEF SEG = OutReg.BX 'Segment of PSP EnvLo = PEEK(&H2C) 'The pointers from the PSP to our copy of the EnvHi = PEEK(&H2D) 'environment ComlineLength = PEEK(&H80) 'Length of command tail in PSP CLS PRINT " Command tail:": PRINT 'Print command tail FOR X = &H81 TO &H81 + ComlineLength - 1 PRINT CHR$(PEEK(X)); NEXT PRINT : PRINT DEF SEG = EnvLo + (EnvHi * 256) 'Segment of environment X = 0 'Print environment The QBNews Page 10 Volume 1, Number 2 February 2, 1990 PRINT " Environment:": PRINT DO UNTIL PEEK(X) = 0 DO UNTIL PEEK(X) = 0 PRINT CHR$(PEEK(X)); X = X + 1 LOOP PRINT X = X + 1 LOOP PRINT X = X + 3 PRINT " Program drive:\path\name:": PRINT 'Print program filespec DO UNTIL PEEK(X) = 0 PRINT CHR$(PEEK(X)); X = X + 1 LOOP PRINT END Knowing where the PSP is gives you yet another advantage. When a QuickBASIC program RUNs another program outside the environment, the RUN program inherits the old PSP, _including_ the old command tail. If we change that command tail before RUNning the new program, we can pass arguments to it as if they were typed on the command line! Here's the Sub to do it: ' SUB RunIt (Tail$, Prog$) 'Changes command tail and RUN program InReg.AX = 25088 'Find PSP Interrupt &H21, InReg, OutReg DEF SEG = OutReg.BX 'Point PEEK and POKE at it Text$ = Text$ + " " + CHR$(13) 'Prep the new command tail POKE &H80, LEN(Text$) - 1 'Poke the length FOR X = &H81 TO &H81 + LEN(Text$) 'Poke the string POKE X, ASC(MID$(Text$, X - &H80, 1) + " ") NEXT RUN Prog$ 'Run the program (.EXE or .COM) END SUB The QBNews Page 11 Volume 1, Number 2 February 2, 1990 To test this Sub, use it to RUN a program that just PRINTs COMMAND$, and see if it picks up your new command tail.