MODULE @INITIALIZE;

(* CP/M-86 VERSION *)

(*$I FIBDEF.LIB*)
TYPE
  PTR = ^BYTE;
  paob = packed array [0..0] of byte;
  paobptr = ^paob;

  flp = ^fle;
  fle = record
          nxt : flp;
          prv : flp;
          siz : long_int
        end;

  ptrix = record
            case boolean of
              true : (p:paobptr);
              false: (loword : word;
                      hiword : word)
            end;



VAR

  @FRL :        flp;                    (* pointer to free memory list *)

  INPUT,
  OUTPUT:       text;                   (* DEFAULT CONSOLE FILES *)
                  
  @TFN:         STRING[2];              (* FOR TEMP. FILE NAMES  *)

  @SYSIN:       PTR;                    (* ADDR OF "INPUT"  ROUTINE *)
  @SYSOU:       PTR;                    (* ADDR OF "OUTPUT" ROUTINE *) 

  SYSMEM:       EXTERNAL INTEGER;

(*$E-*)

  extrabase:    ptrix;          (* points to segment base of extra seg *)
  extralen :    ptrix;          (* points to len of extra seg *)

  frlfirst :    fle;            (* for building free list *)
  frllast  :    fle;
  junk     :    ptrix;
(*$E+*)


external procedure @ini3;
external PROCEDURE GET;         (* NOT FOR CALLING JUST FOR ADDR *)
external procedure PUT;         (* NOT FOR CALLING JUST FOR ADDR *)
external function @ds:word;     (* returns value of hardware ds reg *)

PROCEDURE @INI;
BEGIN
  (* LEAVE THIS CALL TO @INI3 ALONE AND DON'T MOVE IT *)
  (* IT ZEROS THE ENTIRE DATA AREA (ABOVE 100H) AND WILL ZAP ANYTHING *)
  (* THAT WAS PREVIOUSLY INITIALIZED *)
  @ini3;                (* zero data area and overlay area bytes *)


  @SYSIN := ADDR(SYSMEM);       (* TO FORCE SYSMEM TO BE LOADED *)


  (* now initialize the heap *)
  extrabase.hiword := @ds;
  extralen.hiword := @ds;
  extrabase.loword := $000f;
  extralen.loword := $000c;

  frlfirst.prv := NIL;
  frlfirst.siz := #0;

  move(extrabase.p^,junk.hiword,2);
  junk.loword := 0;
  frlfirst.nxt := junk.p;

  frlfirst.nxt^.prv := addr(frlfirst);
  frlfirst.nxt^.nxt := addr(frllast);
  frlfirst.nxt^.siz := #0;
  move(extralen.p^,frlfirst.nxt^.siz,3);    (* fill in the length *)

  frllast.nxt := NIL;
  frllast.siz := #0;
  frllast.prv := junk.p;


  @frl := addr(frlfirst);

  @TFN := '00';

  @SYSIN := ADDR(GET);
  @SYSOU := ADDR(PUT);



  ASSIGN(INPUT,'CON:');
  RESET(INPUT);

  ASSIGN(OUTPUT,'CON:');
  REWRITE(OUTPUT);
END;

MODEND.

