MaxZ80 - Chapter 7

We can happily report success! The new lines are:

{
5/10,30/06 - lrb - added Z-System logic to tune delay
based on PC's speed. changed player characters - added
Program line, last changed date and a bit more detail
on usage etc.
}

The above is an overall comment describing what changed.

Program Chicken;
{$I nz-tool.def}
{$I nz-tool.box}

The $I lines mean "include these files." These files were written by
Joe Wright and contain Z-System type, variable and function
declarations and definitions. He comments

"The Record structure and Turbo Pascal Pointers will allow the veteran
Pascal programmer complete access to the Z-System Environment and by
implication a description of its entire structure."

We only use a few of the declarations here, namely the ENVREC
structure and the variable Z3EADR Absolute $0109, which is a pointer
to this structure. The field in this structure that we care about here
is the SPEED field. From NZ-TOOL.DEF:

{
 The following Record Structures define the Z3 Environment of any
 NZ-System.
}

  ENVPTR = ^ENVREC;
  ENVREC =
    Record
      ENV     : Byte;
      CBIOS   : Integer;
      Z3ID    : Array[1..5] of Char;
      ENVTYP  : Byte;
      EXPATH  : patptr;
      EXPATHS : Byte;
      RCP     : Integer;
      RCPS    : Byte;
      IOP     : Integer;
      IOPS    : Byte;
      FCP     : Integer;
      FCPS    : Byte;
      Z3NDIR  : ndrptr;
      Z3NDIRS : Byte;
      Z3CL    : mclptr;
      Z3CLS   : Byte;
      Z3ENV   : Integer;
      Z3ENVS  : Byte;
      SHSTK   : Integer;
      SHSTKS  : Byte;
      SHSIZE  : Byte;
      Z3MSG   : msgptr;
      EXTFCB  : fcbptr;
      EXTSTK  : Integer;
      QUIET   : Byte;
      Z3WHL   : ^Byte;
      SPEED   : Byte;
      MAXDSK  : Byte;
      MAXUSR  : Byte;
      DUOK    : Byte;
      CRT     : Byte;
      PRT     : Byte;
      COLS    : Byte;
      ROWS    : Byte;
      LINS    : Byte;
      DRVEC   : Integer;
      SPAR1   : Byte;
      PCOL    : Byte;
      PROW    : Byte;
      PLIN    : Byte;
      FORM    : Byte;
      SPAR2   : Byte;
      SPAR3   : Byte;
      SPAR4   : Byte;
      SPAR5   : Byte;
      CCP     : Integer;
      CCPS    : Byte;
      DOS     : Integer;
      DOSS    : Byte;
      BIO     : Integer;
      SHVAR   : Array[1..11] of Char;
      FILE1   : Array[1..11] of Char;
      FILE2   : Array[1..11] of Char;
      FILE3   : Array[1..11] of Char;
      FILE4   : Array[1..11] of Char;
      PUBLIC  : Integer;
    End;

From NZ-TOOL.BOX:

Function Z3EXIST:Boolean;   { z3 existence test } {lrb}<
Begin<
  z3exist := z3eadr^.z3env = mem[addr(z3eadr)] + 256 * mem[addr(z3eadr)+1];<
End;<

The above line uses pointer syntax.

Under Z-System, you can count on address hex 109 to be filled with the
integer memory address of the environment record.

The assignment statement in the definition of z3exist is saying "set
the boolean variable z3exist to true if the integer at address 109 is
equal to the integer in the field named z3env of the environment
record in memory." This field was put in the environment record so it
could be used for this very purpose.

var
 mhz: integer; rdelay: real;
 s1,s2:char;

begin {ning of CHICKEN.PAS}

s1:=Chr(131);
s2:=Chr(132);
mhz:=80;
if z3exist then mhz:=z3eadr^.speed;

If Z-System is present, the above sets the variable mhz to the value
of the speed field in the environment record.

rdelay:=delay*1000;
rdelay:=rdelay*Sqrt(mhz div 80);

{
We make this last adjustment because the nested loop below (find the
comment which says delay logic) goes a number of times which is
proportional to delay*delay. The above adjustment will therefore change
this number by a factor of Sqr(Sqrt(mhz div 80)) or mhz div 80.  This
would make the loop have twice as many cycles on a 160 MHz machine as
it has on an 80. If we describe the delay time for a "slow" (80 MHz)
machine by

cycles * time-per-cycle

we can describe the delay time for a "fast" (160 MHz) machine in terms
of the slow machine's cycles and time-per-cycle by

(2 * cycles) * (.5 * time-per-cycle)

Since 2 * .5 = 1, the delay time is the same.
}

{ delay logic }
delay:=Round(rdelay);
gotoxy(1,1); for i:=1 to delay do begin
 j:=delay div 100; repeat j:=j-1; until j=0;
 end;

We use the Real variable rdelay because the builtin function Sqrt
returns a Real. We convert it back to an Integer, by using the builtin
function Round, so we can use it in the loops.