TURBO Pascal handling addresses
Type Range Bytes in
memory
------- ------------- --------
Byte 0..255 1
Integer -32768..32767 2
Real 1E-38..1E38 6
Programmers using the 16 address bits of the Z80 CPU may run into a problem.
The address $FFFF is definitely larger than address $0001.
Nevertheless comparing these addresses with a standard routine (e.g. X<Y) will go wrong
because TURBO interpretes $FFFF as -1, which is in fact <1.
To compare unsigned 16 bit integers the right way the following functions may be used:
function cmpwrd(x,y:integer):integer;
Begin
if x=y then cmpwrd:=1
else if ((x<y) xor ((x<0) xor (y<0))) then cmpwrd:=0
else cmpwrd:=2;
End;
This function delivers:
function wEQ(x,y:integer):boolean; function wNE(x,y:integer):boolean; Begin Begin wEQ:=(cmpwrd(x,y)=1); wNE:=(cmpwrd(x,y)<>1); End; End;But both routines may be programmed using standard routines:
ires:=wEQ(x,y); is equivalent to bres:=x=y;
ires:=wNE(x,y); is equivalent to bres:=x<>y;
(Where ires is as an integer, bres a boolean variable)
But using the other compare routines require the new functions:
function wLT(x,y:integer):boolean; function wGT(x,y:integer):boolean; Begin Begin wLT:=(cmpwrd(x,y)=0); wGT:=(cmpwrd(x,y)=2); End; End;and function wLTE(x,y:integer):boolean; function wGTE(x,y:integer):boolean; Begin Begin wLTE:=((cmpwrd(x,y)=0) OR (x=y)); wGTE:=((cmpwrd(x,y)=2) OR (x=y)); End; End;Using these functions you may program unsigned integer compare routines without problems. Another point is the output of integers in the range $8000..$FFFF because they will be displayed as negative numbers. Find here two functions displaying the integers either as hex numbers or as positive numbers in that range as usual. HEX
type
HexStr = string[4];
function Hex(val:integer):HexStr;
const
HexTab : array[0..15] of char='0123456789ABCDEF';
var
str : HexStr;
i : integer;
Begin
str:='0000';
for i:=4 downto 1 do
begin
str[i]:=HexTab[val AND $0F];
val:=val SHR 4;
end;
Hex:=str;
End;
The function returns a string holding four characters in hex format.
INTEGERTo display an integer in range $8000..$FFFF as a positive number the range of the integer number must be expanded using a real number. The following function can do it:
function wrd(x:integer):real;
Begin
if x<0 then wrd:=65536.0+x
else wrd:=x;
end;
Use the following statement displaying the number:
write('Adresse=',wrd(x):0:0);
By the way also TURBO Pascal 3.0 did not pass the "elk test".
To everybody who does not believe feel free to test the function wrd as follows
program Elk(input,output);
var
i : integer;
adr : integer;
function wrd(x:integer):real;
Begin
if x<0 then wrd:=65536.0+x
else wrd:=x;
end;
BEGIN
adr:=$7fff;
for i:=1 to 3 do
begin
writeln(adr:6,' is ',wrd(adr):0:0);
adr:=succ(adr);
end;
END.
The transition $7FFF -> $8000 -> $8001 will be tested here.
We expect the following display:
32767 is 32767
-32768 is 32768
-32767 is 32769
And this happens:
32767 is 32767
-32768 is
Yes, indeed that is all we see.
In fact there does exist an error within the TURBO run time library but only for exactly one value - if the integer $8000 is converted to real.
(See here for a detailed description)
Published in Klubzeitung No. 53. Author: Werner Cirsovius |