'===========================================================================
' Subject: CHANGING DOS COMMAND$              Date: 01-13-00 (00:31)       
'  Author: Mike Anderson                      Code: QB, PDS                
'  Origin: MikeAinIA@aol.com                Packet: DOS.ABC
'===========================================================================
'I found a request on the ABC page for a snippet to change the
'COMMAND$ from within QB.  I figured that should be pretty
'easy to do.  I was right  :-)    So here it is --

'===========================================================================
'  Subject: Changing DOS Command$           Date: 1/14/00
'  Author: Mike Anderson                    Code: QB
'  NOTE: This doesn't work correctly from the IDE.  Compiled, it does.
'===========================================================================

DEFINT A-Z

DECLARE FUNCTION DosCmd$ (dtaseg%, dtaoff%)
DECLARE SUB findDTA (dtaseg%, dtaoff%)

'$INCLUDE: 'QB.BI'

'-----  A couple constants that our procedures use -----

CONST DOS = &H21, GetDTA = &H2F00

CLS
PRINT "QB's Command$ returns "; COMMAND$; : IF COMMAND$ = "" THEN PRINT 
"<nothing>"
PRINT


'--------------------------------------------------------------------
' Using the findDTA sub to get the seg:offset of the DOS command tail
'--------------------------------------------------------------------

findDTA dtaseg%, dtaoff%
y% = dtaoff% + 2

'--------------------------------------------------------------------
' Using the DosCmd$ function to get the contents of DOS command tail
'--------------------------------------------------------------------

Cmd$ = DosCmd$(dtaseg%, y%)

PRINT
PRINT "DOS stored the command tail at ";
PRINT dtaseg%; ":"; y%

PRINT
PRINT "It is an ASCIIZ string containing:"
PRINT Cmd$

PRINT : PRINT
PRINT "Now let's change it - type something and hit enter"
INPUT r$
PRINT "Adding a CHR$(0) to make it an ASCIIZ string"
r$ = r$ + CHR$(0)

y% = dtaoff%
FOR x% = 1 TO LEN(r$)
    POKE (y% + x%), ASC(MID$(r$, x%, 1))
NEXT x%

PRINT
PRINT "here is the new DTA contents"

y% = dtaoff% + 1
FOR x% = y% TO y% + 128
    IF PEEK(x%) = 0 THEN EXIT FOR
    IF PEEK(x%) > 20 THEN
        PRINT CHR$(PEEK(x%));
    END IF
NEXT x%

PRINT : PRINT
PRINT "Here is what the built in Command$ function returns"
PRINT COMMAND$

DEF SEG
END

FUNCTION DosCmd$ (dtaseg%, dtaoff%)
DIM temp$

DEF SEG = dtaseg%
y% = dtaoff%

DO
    IF PEEK(y%) = 0 THEN EXIT DO
    temp$ = temp$ + CHR$(PEEK(y%))
    y% = y% + 1
LOOP
DosCmd$ = temp$

END FUNCTION

SUB findDTA (dtaseg%, dtaoff%)

DIM Regs AS RegTypeX
Regs.ax = GetDTA
INTERRUPTX &H21, Regs, Regs

'-----------------------------------
' Interrupt &H21, Service &H2F00 gets
' the current DTA segment and offset
' and returns it in ES:BX
'-----------------------------------

dtaseg% = Regs.es
dtaoff% = Regs.bx

END SUB
