TIP: Click on subject to list as thread! ANSI
echo: power_bas
to: ALLE
from: THOMAS GOHEL
date: 1996-09-01 00:00:00
subject: FAQ: PowerBASIC 07/16 (Problems 1)

    ===================
    4. Standardproblems
    ===================
    4.1.  Compatability between the PBUs and LIBs of the 3.x Versions
    4.2.  Not enough memory in the PowerBASIC-IDE
    4.3.  Finding out the filename and path to the filename
    4.4.  No free memory with ENVIRON$
    4.5.  No Returnerrorlevel with SHELL
    4.6.  Cutting files
    4.7.  Error 502/514 when using C-OBJ-Files
    4.8.  Preventing a Warmboot with CTRL-ALT-DEL
    4.9.  Opening more than 15 Files with PowerBASIC and/or DOS
    4.10. HEX$-DWORD Routine for PowerBASIC 3.1/3.2
    
    4.1. Compatability between the PBUs and LIBs of the 3.x Versions
    ----------------------------------------------------------------
    Other than the PowerBASIC-Update from V2.10 to 3.00, the PBU/LIBs of
    the 3.x Versions are downwards compatible. That means that you can
    continue to use an under PowerBASIC 3.0 developed PBU/LIB under the
    two higher PowerBASIC Versions. But you can't use a PowerBASIC 3.1 PBU/
    LIB with any of the older Versions. There are probably some
    differences between the Versions 3.0-3,1 because of the new Number-
    System when exchanging sourcecode. In that case please read the
    Chapter 'Errors ...'.
    4.2. Not enough memory in the PowerBASIC-IDE
    --------------------------------------------
    There is a Tool by Bob Zale himself which activates parts of the VGA-
    Graphic-RAM and the parts of the monochrome Herculescard for
    PowerBASIC. The Tool 'PBPLUS96' (96kByte more RAM) was written for
    PowerBASIC Version 2.00, but still works with Version 3.10.
    4.3. Finding out the filename and the path to the filename
    ----------------------------------------------------------
    We often stand in front of the problem that we can start our program
    over a path command, but that it can't find its own data and INI-Files
    anymore after that. The solution is quite simple: DOS saves this
    information in the PSP or in its Environmentblock.
    --- Cut --------------------------------------------------------------
    '*********************************************************************
    '
    '   Finding the path and filename of the current program in
    '   PowerBASIC 3.0/3.2
    '
    '   von Thomas Gohel
    '
    '*********************************************************************
    $COMPILE EXE
        ! mov ax, &h6200
        ! int &h21
        ! mov es, bx
        ! mov ax, word ptr es:[&h2C]
        ! mov pbvDefSeg, ax           ; undocumented in PowerBASIC 3.0
        FOR i% = 0 TO 1024
            IF PEEK$(i%, 4) = CHR$(0,0,1,0) THEN EXIT FOR
        NEXT i%
        WHILE PEEK(i% + 4)  0
            Temp$ = Temp$ + CHR$(PEEK(i% + 4))
            i% = i% + 1
        WEND
        DEF SEG
        FOR i%=LEN(Temp$) TO 1 STEP -1
            IF RIGHT$(MID$(Temp$,1,i%),1) = "\" THEN EXIT FOR
        NEXT i%
        ExeDir$ = MID$(Temp$,1,i%)
        ExeName$ = MID$(Temp$,i%+1)
        PRINT ExeDir$; "  "; ExeName$
    --- Cut End ----------------------------------------------------------
    4.4. No free memory with ENVIRON$
    ---------------------------------
    This chapter is partly documented in the manuals, but I want to give
    some advanced tips, because this subject often causes misunderstandig.
    The structure of the environmentblock in connection with the Program
    Segment Prefix (PSP) is not documented further, but it is of enourmous
    meaning gor the better understanding of this error.
    Shortly said, you can only modify the existing environent, and not add
    any new entries!! You can use three ways if you want to add entries
    anyways:
    a) Delete part of the environment and then add the new entry or first
    create a Dummy-Environmententry and the delete or modify it using the
    ENVIRON-Command.
    b) When you want to start a DOS-SHELL with an information:
           OldEnv$ = ENVIRON$("PROMPT")
           SHELL "COMMAND.COM /K SET PROMPT=PowerBASIC " + OldEnv$
    The trick with this is that when you call a SHELL a new PSP will be
    created and the memory will be allocated correctly.
    c) Get the address of the PSP, get the pointer to the current
    Environmentblock and then read the environment into a string, where it
    can be modified. The allocate a DOS-Memoryblock using INT21, save the
    modified environment therem abd the set the pointer to the
    Environmentblock within the PSP to the new one.
    (Also see: Already available PD-Solutions)
    4.5. No Returnerrorlevel with SHELL
    -----------------------------------
    You often need to check the Errorcode of an ended program in a SHELL-
    Command. This is not possible directly under PowerBASIC, because
    PowerBASIC runs a program using COMMAND.COM and because of that the
    Errorcode can't be returned (This is a problem of MS-DOS!!).
    Example:
            SHELL "C:\DOS\COMMAND.COM /C MEINDEMO.EXE"
    To solve this problem there is for instance an alternative SHELL-
    Command in form of a FUNCTION (as Sourcecode):
    --- Cut ---------------------------------------------------------------
    '**********************************************************************
    '
    '   Errorlevel in PowerBASIC 3.0/3.2
    '
    '   by Thomas Gohel (after a pattern from PDS, by Bernd Hohmann)
    '
    '***********************************************************************
    $COMPILE EXE
    DECLARE FUNCTION PBShell% (FileName$)
    CLS
    PRINT
    PRINT "Fehlercode ist: "; PBShell%("c:\dos\command.com")
    END
    FUNCTION PBShell% (FileName$)
        LOCAL Dummy%
        Datei$ = FileName$                  ' Copy filename.
        Datei$ = LTRIM$(Datei$)             ' Trim filename.
        i% = INSTR(Datei$, " ")             ' Pass Command ?
        IF i% > 0 THEN                      '
           Cmd$ = MID$(Datei$, i%)          ' Cut Command
           Datei$ = LEFT$(Datei$, i% - 1)   ' Cut filename
        END IF                              '
        Datei$ = UCASE$(Datei$)
        i% = INSTR(Datei$, ".")             ' Is a dot in it ?
        IF i% > 0 THEN                      '
           Ext$ = MID$(Datei$, i%)          ' Get extension
        ELSE                                '
           Ext$ = ""                        ' Extension is empty
        END IF                              '
        SELECT CASE Ext$                    ' Test extension.
            CASE ".BAT"                     ' Batch over COMMAND.COM
                Cmd$ = "/C " + Datei$ + " " + Cmd$
                Datei$ = ENVIRON$("COMSPEC")
            CASE ".COM"                     ' Free
            CASE ".EXE"                     ' Free
            CASE ELSE                       ' No Extension,
                Datei$ = Datei$ + ".EXE"    ' Add .EXE.
        END SELECT                          '
        Datei$ = Datei$ + CHR$(0)           ' Create ASCII-String.
        dNul$ = CHR$(0) + CHR$(0)           ' Doublezero for Parameterblock
        nul$ = SPACE$(127)                  ' Save 127 bytes for Strings
        MemFree& = SETMEM(0)                ' Get free space
        x& = SETMEM(-MemFree&)              ' Free all memory
                                            '
        nul$ = ""                           ' restore 127 Bytes.
        IF Cmd$ > "" THEN                    ' Commandline ?
            CmdLen$ = CHR$(LEN(Cmd$))        ' Length of Cmd$ as String
            Cmd$ = CmdLen$ + Cmd$ + CHR$(13) ' Length + Cmd$ + '13'
            segm$ = MKI$(STRSEG(Cmd$))       ' Single parts of the
                                             ' Parameter-Block
            Offs$ = MKI$(STRPTR(Cmd$))       ' Add ( MID$(....)
                                             ' = segm$ doesn't work)
            Param$ = dNul$ + Offs$ + segm$   ' Create Parameterblock.
        ELSE                                 '
            Cmd$ = CHR$(13)                  ' Start of Bug-Fixed
            segm$ = MKI$(STRSEG(Cmd$))       ' Segment of Terminator
            Offs$ = MKI$(STRPTR(Cmd$))       ' Offset         -"-
            Param$ = dNul$ + Offs$ + segm$   ' Create Parameterblock.
        END IF                               ' End of Bugfixed
        DateiSeg% = STRSEG(Datei$)           ' Get addresses
        DateiOff% = STRPTR(Datei$)
        ParamSeg% = STRSEG(Param$)
        ParamOff% = STRPTR(Param$)
        ! push ds                            ; Save DS
        ! mov  ax, &h4B00                    ; EXEC-Funktion 4Bh / INT 21h
        ! mov  es, ParamSeg%                 ; Segment of Parameterblock
        ! mov  bx, ParamOff%                 ; Offset of Parameterblock
        ! mov  dx, DateiOff%                 ; Offset of Filename
        ! mov  ds, DateiSeg%                 ; Segment of Filename
        ! int  &h21                          ; Interrupt &h21
        ! pop  ds
        ! jc   ExecError
        ! jmp  ExecOk
        ExecError:
        ! mov Dummy%, ax
        SELECT CASE Dummy%                   ' Evaluate Error.
            CASE 1   : PRINT "illegal Function call!"
            CASE 2,3 : PRINT "File not found: " + FileName$
            CASE 4   : PRINT "to many files opened"
            CASE 5   : PRINT "Access denied " + Filename$
            CASE 8   : PRINT "Not enough free memory for " + FileName$
            CASE 10  : PRINT "wrong Environmentblock"
            CASE 11  : PRINT "wrong Format"
            CASE ELSE: PRINT "Problem while executing " + FileName$
        END SELECT
        ExecOk:
        Mem2& = SETMEM(MemFree&)             ' Completely free memory.
        IF MemFree&  Mem2& THEN            ' Free memory changed
           PRINT "Warning: possibly a TSR was installed!!"
        END IF
        ! mov  ah, &h4d                      ; Get Exit-Code
        ! int &h21                           ; Interrupt &h21
        ! mov Dummy%, al
        PBShell% = Dummy%
        ! mov  ah, &h03                      ; Pass current cursor
        ! mov  bh, &h00                      ; position
        ! int &h10                           ; Interrupt &h10
        ! inc dh                             ; Recalc to basis of 1
        ! inc dl
        ! mov NewZeile?, dh
        ! mov NewSpalte?, dl
        LOCATE NewZeile?, NewSpalte?         ' Set cursor
    END FUNCTION
    - Cut End -------------------------------------------------------------
    Further on your can modify the COMSPEC-Variable in your environment
    and directly run your program with COMMAND.COM.
    Example:
            Comspec$ = ENVIRON$("COMSPEC")  'Save COMSPEC
            ENVIRON "COMSPEC=MEINDEMO.EXE"
            SHELL                           'Execution of MEINDEMO.EXE
            ENVIRON "COMSPEC="+Comspec$     'Restore COMSPEC
    Always remember, that the SHELL-Function always transfers the
    Parameter '/C' to the executing program, if you want to transfer
    Commandlineparamters yourself.
    4.6. Cutting files
    ------------------
    You often stand in front of the problem that you have cleaned your
    datafile, but it is still too big. In this case this small but
    effective trick helps:
    Example:
            OPEN "DEMO.DAT" FOR BINARY AS #1
            SEEK #1, 20
            PUT$ #1, ""
            CLOSE #1
    Shortens the file 'DEMO.DAT' to a length of 20 Bytes.
--- CrossPoint v3.11 R
---------------
* Origin: -= http://www.snafu.de/~pbsound/ =- (2:2410/301.12)

SOURCE: echomail via exec-pc

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.