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.