TURBO PASCAL Run Time ErrorAccording to the principle that "no software is error free" also CP/M-80 TURBO Pascal 3.0 has some bugs which cannot be treated as features. Beneath some publications referring this subject I found a strange error myself.The error happened when I tried to display free memory always as a positive integer. If there is much free memory the function memavail returns a negative integer.
This may be performed by the following instructions:
if memavail<0 then mfree:=65536.0+memavail else mfree:=memavail;The variable mfree must be of type real .
The correction with the constant 65536.0 does take place in case of a negative integer in range $8000..$FFFF accordingly.
The value $FFFF presents -1, therefore mfree holds 65535 being correct.
Now to the error: On a unique value of memavail only the machine is hanging up! This value is $8000. I took a look into the code and found the compiler routine for converting an integer to a real number at address $1008. This piece of code is responsible for the hang-up. This function is as follows: ; ; Address $1008 ; int2real: ld a,h ; Test if integer=0 or l jp z,int.0 ; If so, set result of real to zero bit 7,h ; Test if integer<0 ex af,af' ; Remember sign call absNEG ; Make integer absolute (positive only) ld a,90h ; Init exponent to start with i2r.loop: add hl,hl ; Shift left integer dec a bit 7,h ; Until MSB is set jr z,i2r.loop ld b,h ; Load resultat ld c,l ld de,0 ld h,d ld l,a ex af,af' ; Get original sign ret nZ ; Was negative res 7,b ; Make real positive retThe routine I called " int.0 " will ne found at address $07b2 of the compiler:
; ; Address $0b72 ; int.0: xor a ld l,a ; Init real to zero ld b,a ld c,a ld d,a ld e,a ld h,a retThis routine looks problem-free. But what about the routine I called " absNEG " ?
; ; Address $0780 ; absNEG: bit 7,h ; Test sign ret z ; End if $0000..$7FFF ld a,h ; Negate number cpl ; Returns $8000..$FFFF -> $8000..$0001 ld h,a ld a,l cpl ld l,a inc hl retIt is eye-catching that just the number hanging up the machine is identical as well as negative and positive number. And exactly that is the trouble. The routine " int2real " shifts register pair HL left and checks if bit 7 of register H is set or not.
If not, the left shift proceeds.
But sfifting $8000 left results into a value of $0000 ! This leads to an endless loop waiting for bit 7 to be set - no more bits are available ! That explains the machine hang-up. The only way to correct that is a patch which first checks the bit and then performs the shift. Unfortunately there is no room in the converter routine doing that - we need another place in memory. The fixed routine could look like this one: ; ; Address $1008 ; int2real: ld a,h or l jp z,int.0 bit 7,h ex af,af' ; ; #### PATCH #### ; call i2r.patch i2r.loop: bit 7,h ; Test bit jr nz,i2r.ex ; End if set add hl,hl ; Else shift dec a jr i2r.loop i2r.ex: ; ; #### PATCH ENDE #### ; ld b,h ld c,l ld de,0 ld h,d ld l,a ex af,af' ret nz res 7,b retThe patch requires one byte more than available !! Therefore I moved it to address $0106 of the compiler (here only the copyright message will be found): ; ; Address $0106 ; i2r.patch: call absNEG ld a,90h retFor everybody who wants to install this patch type the following sequences using SID: x>SID TURBO.COM # Call SID, loading TURBO.COM CP/M 3 SID - Version 3.0 NEXT MSZE PC END 7980 7980 0100 D1FF #S106 # Indicate bytes to be modified 0106 6F CD # Modify values 0107 70 80 0108 79 07 0109 72 3E 010A 69 90 010B 67 C9 0108 68 . # Ready #S1011 # Part two 1011 80 06 1012 07 01 1013 3E CB 1014 90 7C 1015 29 20 1016 3D 04 1017 CB 29 1018 7C 3D 1019 28 18 101A FA F8 101B 44 . # End #WTURBOP.COM # Write new file TURBOP.COM 00F1h record(s) written. #^C # End x> Use this batch file (for SUBMIT) which performs the modification without keyboard typing. Published in Klubzeitung No. 55 - März 1999. Author: Werner Cirsovius |