{ This program, written in Turbo Pascal [Tm], will display and
  allow you to easily change the arrow keys on your Osborne 01
  computer without re-booting the disk.

  This program is the sole property of Howard Gerber, WB5YWS, and
  may not be sold for commercial gain in any way shape or form.
  Permission is hereby granted for personal use of this program.

  Anyone having questions about this program may contact Howard
  by leaving a message on the OZZ-HAM RCP/M at (713) 893-0424
  or the Weekender BBS at (713) 492-8700. }

program ArrowKeys (input, output);
const
   first_cursor = 11;
   last_cursor = 14;
var
   adr, lng : array [1 .. last_cursor] of integer;
   cpm, ws : array[1 .. 4] of integer;
   wordstar, cp_m : boolean;
   response : char;

function contents( location : integer ) : integer;
begin
   contents := mem[location]  +  $100 * mem[location+1]
end;

procedure initialize;
const
   bios_entry = 2;
var
   i, address, last_address : integer;
begin
cpm[1] := $0B; cpm[2] := $0C; cpm[3] := $0A; cpm[4] := $08;
ws[1]  := $05; ws[2]  := $04; ws[3]  := $18; ws[4]  := $13;
address := $100 * mem[bios_entry] + $6B;
last_address := contents(address);
for i := 1 to last_cursor do
   begin
   adr[i] := last_address;
   address := address + 2;
   last_address := contents(address);
   lng[i] := last_address - adr[i];
   end;
end;

procedure display_keys;
var
   i, j, ad : integer;
   aks : array [1 .. 4] of integer;
begin
wordstar := false;
cp_m := false;
for i := 1 to 4 do
  if lng[i] = 1 then
   begin
   for j := 1 to 4 do
      begin
      ad := adr[11] + j - 1;
      aks[j] := mem[ad]
      end;
   cp_m := (aks[1]=cpm[1]) and (aks[2]=cpm[2]) and (aks[3]=cpm[3]) and
      (aks[4]=cpm[4]);
   wordstar := (aks[1]=ws[1]) and (aks[2]=ws[2]) and (aks[3]=ws[3]) and
      (aks[4]=ws[4]);
   end;
if cp_m then write('CP/M')
else if wordstar then write('WordStar')
else write('Non-Standard');
writeln(' Arrow Keys.    ');
end;

procedure make_ws_keys;
var
   i, ad : integer;
begin
for i := 1 to 4 do
   begin
   ad := adr[11] + i - 1;
   mem[ad] := ws[i];
   end;
end;

procedure make_cpm_keys;
var
   i, ad : integer;
begin
for i := 1 to 4 do
   begin
   ad := adr[11] + i - 1;
   mem[ad] := cpm[i];
   end;
end;

begin
writeln(^Z,'   ArrowKeys [C] 1984 Howard Gerber, WB5YWS');
writeln('Permission granted for non-commercial use only');
writeln;
write('Your keyboard is now set to ');
initialize;
display_keys;
write('Change? ');
readln( response );
if response in ['y', 'Y'] then
   begin
   write('Changed to ');
   if wordstar then make_cpm_keys
   else make_ws_keys;
   display_keys;
   writeln;
   end;
end.