===================
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
2:2410/330.1)
---------------
* Origin: PBSOUND, PBFILES (40MB), PBFAQ, PBRULES, PBHIVGA at:
|