Unless it is packed, a Pascal char is a C int. Using C types, hilo.p passed an int *buf to uread(), which expected a char *buf. Then uread() wrote the char on the end of the int. This worked on little-endian platforms. This failed on big-endian platforms, as writing the value to the big end of an int multiplied it by 16777216. The fix is to use a packed array [0..0] of char in Pascal. I also change 'string' to a packed array, though this is not a necessary part of the fix.
		
			
				
	
	
		
			170 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
			
		
		
	
	
			170 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			OpenEdge ABL
		
	
	
	
	
	
(* $Source$
 | 
						|
 * $State$
 | 
						|
 * $Revision$
 | 
						|
 *)
 | 
						|
 | 
						|
(*$U+ --- enables underscores in identifiers *)
 | 
						|
 | 
						|
program hilo(input, output);
 | 
						|
 | 
						|
type
 | 
						|
	string = packed array [0..255] of char;
 | 
						|
	charstar = packed array [0..0] of char;
 | 
						|
	
 | 
						|
var
 | 
						|
	playing : Boolean;
 | 
						|
	seed : integer;
 | 
						|
	
 | 
						|
{ This version of Pascal seems to have no random number generator I can find,
 | 
						|
  so we have to implement our own here. This is a hacked up and probably
 | 
						|
  broken version of the C library generator. }
 | 
						|
 | 
						|
procedure randomise(s : integer);
 | 
						|
	begin
 | 
						|
		seed := s;
 | 
						|
	end;
 | 
						|
	
 | 
						|
function random(range : integer) : integer;
 | 
						|
	begin
 | 
						|
		seed := (20077 * seed + 12345);
 | 
						|
		random := seed mod range;
 | 
						|
	end;
 | 
						|
 | 
						|
{ Pascal doesn't provide string input, so we interface to the read() syscall
 | 
						|
  and do it manually. But... we can't interface to read() directly because
 | 
						|
  that conflicts with a Pascal keyword. Luckily there's a private function
 | 
						|
  uread() in the ACK Pascal library that we can use instead. }
 | 
						|
  
 | 
						|
function uread(fd : integer; var buffer : charstar; count : integer) : integer;
 | 
						|
	extern;
 | 
						|
 | 
						|
function readchar : char;
 | 
						|
	var
 | 
						|
		c : charstar;
 | 
						|
		dummy : integer;
 | 
						|
		
 | 
						|
	begin
 | 
						|
		c[0] := chr(0);
 | 
						|
		dummy := uread(0, c, 1);
 | 
						|
		readchar := c[0];
 | 
						|
	end;
 | 
						|
	
 | 
						|
procedure readstring(var buffer : string; var length : integer);
 | 
						|
	var
 | 
						|
		finished : Boolean;
 | 
						|
		c : char;
 | 
						|
		
 | 
						|
	begin
 | 
						|
		write('> ');
 | 
						|
		
 | 
						|
		length := 0;
 | 
						|
		finished := FALSE;
 | 
						|
		seed := 0;
 | 
						|
		while not finished do
 | 
						|
			begin
 | 
						|
				c := readchar;
 | 
						|
				if (ord(c) = 10) then
 | 
						|
					finished := true
 | 
						|
				else
 | 
						|
					begin
 | 
						|
						buffer[length] := c;
 | 
						|
						length := length + 1;
 | 
						|
					end
 | 
						|
			end;
 | 
						|
	end;
 | 
						|
 | 
						|
procedure getname;
 | 
						|
	var
 | 
						|
		name : string;
 | 
						|
		namelen : integer;
 | 
						|
		i : integer;
 | 
						|
		seed : integer;
 | 
						|
		
 | 
						|
	begin
 | 
						|
		writeln;
 | 
						|
		writeln('Hi there! I''m written in Pascal. Before we start, what is your name?');
 | 
						|
		writeln;
 | 
						|
		readstring(name, namelen);
 | 
						|
		writeln;
 | 
						|
		write('Hello, ');
 | 
						|
		
 | 
						|
		seed := 0;
 | 
						|
		for i := 0 to (namelen-1) do
 | 
						|
			begin
 | 
						|
				write(name[i]);
 | 
						|
				seed := seed + ord(name[i]);
 | 
						|
			end;
 | 
						|
			
 | 
						|
		randomise(seed);
 | 
						|
		write('! ');
 | 
						|
	end;
 | 
						|
	
 | 
						|
procedure game;
 | 
						|
	var
 | 
						|
		Number : integer;
 | 
						|
		Attempts : integer;
 | 
						|
		guess : integer;
 | 
						|
		
 | 
						|
	begin
 | 
						|
		writeln('See if you can guess my number.');
 | 
						|
		Number := random(100);
 | 
						|
		Attempts := 0;
 | 
						|
		
 | 
						|
		guess := -1;
 | 
						|
		while guess <> Number do
 | 
						|
			begin
 | 
						|
				Attempts := Attempts + 1;
 | 
						|
				write('> ');
 | 
						|
				readln(guess);
 | 
						|
			
 | 
						|
				if guess < Number then
 | 
						|
					begin
 | 
						|
						writeln;
 | 
						|
						writeln('Try a bit higher.');
 | 
						|
					end;
 | 
						|
			
 | 
						|
				if guess > Number then
 | 
						|
					begin
 | 
						|
						writeln;
 | 
						|
						writeln('Try a bit lower.');
 | 
						|
					end;
 | 
						|
			end;
 | 
						|
			
 | 
						|
		writeln;
 | 
						|
		write('You got it right in only ', Attempts:0, ' ');
 | 
						|
		if Attempts = 1 then
 | 
						|
			write('go')
 | 
						|
		else
 | 
						|
			write('goes');
 | 
						|
		writeln('!');
 | 
						|
	end;
 | 
						|
	
 | 
						|
function question: Boolean;
 | 
						|
	var
 | 
						|
		response: char;
 | 
						|
		
 | 
						|
	begin
 | 
						|
		write('> ');
 | 
						|
		readln(response);
 | 
						|
		
 | 
						|
		question := not ((response = 'n') or (response = 'N')); 
 | 
						|
	end;
 | 
						|
 
 | 
						|
begin
 | 
						|
	getname;
 | 
						|
 | 
						|
	playing := TRUE;
 | 
						|
	while playing do
 | 
						|
		begin
 | 
						|
			game;
 | 
						|
			writeln;
 | 
						|
			writeln('Would you like another go?');
 | 
						|
			playing := question;
 | 
						|
			
 | 
						|
			writeln;
 | 
						|
			if playing then
 | 
						|
				write('Excellent! ')
 | 
						|
			else
 | 
						|
				writeln('Thanks for playing --- goodbye!');
 | 
						|
		end;
 | 
						|
end.
 |