--------------- FIDO MESSAGE AREA==> TOPIC: 214 POWER BASIC Ref: DE400010 Date: 10/01/96 From: THOMAS GOHEL Time: 12:00am \/To: ALLE (Read 4 times) Subj: 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