home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug120.arc / PASCAL.LBR / TURBOPCG.PZS / TURBOPCG.PAS
Pascal/Delphi Source File  |  1979-12-31  |  5KB  |  158 lines

  1. {
  2.  _________________________________________________________
  3. | MicroBee Turbo Pascal Pcg Handler for 80 x 24 screen    |
  4. | Written by Phil Parton.                                 |
  5.  ---------------------------------------------------------
  6. }
  7. Const
  8.      PCGHeight = 11; PCGWidth = 8;
  9.      ScrChrWidth = 80; ScrChrHeight = 24;
  10.      Xmax = 639; Ymax = 263;
  11.      MinPCG = 128; MaxPCG = 255;
  12. Type
  13.     PCGdef = array [1..11] of byte;
  14.     PCGrecord = record
  15.                       Pattern: PCGdef;
  16.                       CheckSum: Integer;
  17.                       Count: Integer;
  18.                       Spare: Byte;
  19.                 end;
  20. var
  21.    PCGmem: array [MinPCG..MaxPCG] of PCGrecord absolute $F800;
  22.    ScreenMem: array [1..ScrChrHeight,1..ScrChrWidth] of byte absolute $F000;
  23.    WorkX,WorkY,WorkCode,UsedPCG: integer;
  24.    GrafOk: Boolean;
  25.    WorkType: (Text,PCG);
  26.    Work: PCGrecord;
  27.  
  28. Procedure InitBee;
  29. var
  30.    Row,RowSize: integer;
  31. begin
  32.      GrafOk := True;
  33.      FillChar(PCGmem[MinPCG].Pattern,PCGHeight,0);
  34.      PCGmem[MinPCG].CheckSum := 0;
  35.      PCGmem[MinPCG].Count := SizeOf(ScreenMem);
  36.      FillChar(ScreenMem[1,1],SizeOf(ScreenMem),MinPCG);
  37.      UsedPCG := MinPCG;
  38. end;
  39.  
  40. Procedure SetWorkCell(x,y: Integer);
  41. begin
  42.      {calculate cell coordinates}
  43.      WorkX := (x div PCGWidth) + 1;
  44.      WorkY := (y div PCGHeight) + 1;
  45.      WorkCode := ScreenMem[WorkY,WorkX];
  46.      if WorkCode < MinPCG then
  47.          WorkType := Text
  48.      else begin
  49.          Worktype := PCG;
  50.          Work := PCGmem[WorkCode];
  51.          PCGmem[WorkCode].Count := Pred(PCGmem[WorkCode].Count);
  52.      end;
  53. end;
  54.  
  55. Function AssignCode: integer;
  56. var
  57.    Row,Code: Integer;
  58.    Match: Boolean;
  59. begin
  60.      Code := MinPCG; Match := False;
  61.      While (Code <= UsedPCG) and not Match do
  62.      begin
  63.           if Work.CheckSum = PCGmem[Code].CheckSum then
  64.           begin
  65.                Row := 1; Match := True;
  66.                While (Row <= PCGHeight) and Match do
  67.                begin
  68.                     Match := (PCGmem[Code].Pattern[Row] = Work.Pattern[Row]);
  69.                     Row := Succ(Row);
  70.                end;
  71.           end;
  72.           Code := Succ(Code);
  73.      end;
  74.      if Match then AssignCode := Pred(Code)
  75.         else AssignCode := Code;
  76. end;
  77.  
  78. Function Sum(var Patt: PCGdef): Integer;
  79. var
  80.    RowSum,Row: Integer;
  81. begin
  82.      RowSum := 0;
  83.      for Row := 1 to PCGHeight do
  84.      begin
  85.           RowSum := RowSum + Patt[Row]
  86.      end;
  87.      Sum := RowSum;
  88. end;
  89.  
  90. Procedure DeletePCG(Code: Integer);
  91. var
  92.    ScreenAddress,ScreenSize: Integer;
  93.    DelCode: Byte;
  94. begin
  95.      DelCode := UsedPCG;
  96.      PCGmem[WorkCode] := PCGmem[UsedPCG];
  97.      if WorkCode <> UsedPCG then
  98.      begin {Change screen ram pointers}
  99.           ScreenAddress := Addr(ScreenMem[1,1]);
  100.           ScreenSize := SizeOf(ScreenMem);
  101.           Inline ($2A/ScreenAddress/       { LD   HL,(ScreenAddress)  }
  102.                   $3A/DelCode/             { LD   A,(DelCode)         }
  103.                   $ED/$4B/ScreenSize/      { LD   BC,(ScreenSize)     }
  104.                   $ED/$B1/                 { CPIR                     }
  105.                   $2B/                     { DEC  HL                  }
  106.                   $22/ScreenAddress);      { LD   (ScreenAddress),HL  }
  107.           mem[ScreenAddress] := Code;
  108.      end;
  109. end;
  110.  
  111. Procedure DisplayWorkCell;
  112. var
  113.    Code: Integer;
  114. begin
  115.      {see if new pattern already exists}
  116.      Work.CheckSum := Sum(Work.Pattern);
  117.      Code := AssignCode;
  118.      if Code > MaxPCG then
  119.           GrafOk := False
  120.      else begin
  121.           If Code > UsedPCG then
  122.           begin {Not found, store it.}
  123.                UsedPCG := UsedPCG + 1;
  124.                Work.Count := 1;
  125.                PCGmem[Code] := Work;
  126.                end
  127.           else begin {Pattern already exists}
  128.                PCGmem[Code].Count := Succ(PCGmem[Code].Count);
  129.           end;
  130.           {now display it}
  131.           ScreenMem[WorkY,WorkX] := Code;
  132.           {Now check if the old pattern is redundant, if so, delete it.}
  133.           if PCGmem[WorkCode].Count = 0 then
  134.           begin {delete work cell PCG}
  135.                DeletePCG(WorkCode);
  136.                UsedPCG := UsedPCG - 1;
  137.           end;
  138.      end;
  139. end;
  140.  
  141. Procedure SetPixel(x,y: Integer);
  142. var
  143.    Row,BitShift: Integer;
  144. begin
  145.      if ((Trunc(x) div PCGWidth) <> WorkX - 1) or
  146.         ((Trunc(y) div PCGHeight) <> WorkY - 1) then
  147.      begin
  148.           if (WorkType = PCG) and GrafOk then DisplayWorkCell;
  149.           SetWorkCell(x,y);
  150.      end;
  151.      if (WorkType = PCG) and GrafOk then
  152.      begin
  153.           BitShift := x mod PCGWidth;
  154.           Row := (y mod PCGHeight) + 1;
  155.           Work.Pattern[Row] := Work.Pattern[Row] or (128 shr BitShift);
  156.      end;
  157. end;
  158.