-- BandBLT.mesa  - Last edit by
-- Olmstead January 15, 1981  10:49 AM
-- Forrest January 21, 1981  12:48 PM
-- Karlton 19-Mar-81 13:32:50

DIRECTORY
  BitBlt USING [DstFunc, SrcFunc],
  Environment USING [PageNumber],
  MiscAlpha USING [aBANDBLT],
  Mopcodes USING [zMISC];

BandBLT: DEFINITIONS =
  BEGIN

  BandBLTTablePtr: TYPE = POINTER TO BandBLTTable;
  BandBLTTable: TYPE = MACHINE DEPENDENT RECORD [
    readLO(0):      Environment.PageNumber,  -- input leftover-list virtual page #
    bandlist(1):    LONG POINTER,            -- input bandlist
    writeLO(3):     Environment.PageNumber,  -- output leftover-list virtual page #
    bandbuf(4):     LONG POINTER,            -- band buffer virtual address
    fontPtrTbl(6):  Environment.PageNumber,  -- Font Pointer Table virtual page #
    fontRasters(7): Environment.PageNumber,  -- Font raster memory virtual page #
    inkwells(8):    Environment.PageNumber]; -- inkwell(s) virtual page #

  BandBLT: PROC [POINTER TO BandBLTTable] RETURNS [LONG POINTER] =
    MACHINE CODE {Mopcodes.zMISC, MiscAlpha.aBANDBLT};

  BandBLTTableAlignment: CARDINAL = 16;
  BBTableSpace: TYPE =
    ARRAY [1..SIZE[BandBLTTable]+BandBLTTableAlignment) OF WORD;

  AlignedBandBLTTable: PROC [
    ip: POINTER TO BBTableSpace] RETURNS [b: BandBLTTablePtr] =
    INLINE BEGIN
    align: TYPE = MACHINE DEPENDENT RECORD [
      s: [0..LAST[WORD]/BandBLTTableAlignment),
      z: [0..BandBLTTableAlignment)];
    b ← LOOPHOLE[ip+BandBLTTableAlignment-1];
    LOOPHOLE[b, align].z ← 0;
    END;

  Font: TYPE = CARDINAL[0..177B];
  Command:  TYPE = CARDINAL[0..17B];

  -- Clients are encouraged to use bound varient constructors
  -- when making these guys.
  -- fields named mustBeZero are required by the the BandBLT microcode to be 0.

  BlItem: TYPE = MACHINE DEPENDENT RECORD[
   tag(0): SELECT OVERLAID * FROM 
    char => [
      type(0:0..0): [0..1] ← charCmd,
      font(0:1..7): Font,
      cc(0:8..15): [0..377B],
      xloc(1:0..3): [0..17B],
      yloc(1:4..15): [0..7777B]],
    leftOverChar => [
      type(0:0..0): [0..1] ← charCmd,
      font(0:1..7): Font,
      cc(0:8..15): [0..377B],
      mustBeZero(1:0..3): [0..17B] ← 0,
      yloc(1:4..15): [0..7777B],
      alsoMustBeZero(2:0..3): [0..17B] ← 0,
      scansToSkip(2:4..15): [0..7777B]],
    rectangle => [
      type(0:0..3): Command ← rectangleCmd,
      yloc(0:4..15): [0..7777B],
      mustBeZero(1:0..3): [0..17B] ← 0,
      bitsPerScan(1:4..15): [0..7777B],
      nScans(2:0..11): [0..7777B],
      xloc(2:12..15): [0..17B]],
    setLevel => [
      type(0:0..3): Command ← setLevelCmd,
      mustBeZero(0:4..4): [0..1] ← 0,
      pad(0:5..7): [0..7B] ← 0,
      levelnum(0:8..15): [0..377B]],
    setInk => [
      type(0:0..3): Command ← setInkCmd,
      srcFunc(0:4..4): BitBlt.SrcFunc ← null,
      dstFunc(0:5..6): BitBlt.DstFunc ← null,
      unused(0:7..7):  BOOLEAN ← NULL,
      inknum(0:8..15): [0..377B]],
    endOfBand => [
      type(0:0..3): Command ← endOfBandCmd,
      pad(0:4..15): [0..7777B] ← 0],
    endOfPage => [
      type(0:0..3): Command ← endOfPageCmd,
      pad(0:4..15): [0..7777B] ← 0],
    rulette => [
      type(0:0..3): Command ← ruletteCmd,
      yloc(0:4..15): [0..7777B],
      length(1:0..11): [0..7777B],
      xloc(1:12..15): [0..17B]],
    nop1 => [
      type(0:0..3): Command ← nopCmd1,
      pad(0:4..15): [0..7777B] ← 0],
    nop2 => [
      type(0:0..3): Command ← nopCmd2,
      pad(0:4..15): [0..7777B] ← 0],
    ENDCASE];

  BandListItemLongPointer: TYPE = MACHINE DEPENDENT RECORD [
    SELECT OVERLAID * FROM
      ptr =>           [ptr:           LONG POINTER],
      char =>          [char:          LONG POINTER TO char BlItem],
      leftOverChar =>  [leftOverChar:  LONG POINTER TO leftOverChar BlItem],
      rectangle =>     [rectangle:     LONG POINTER TO rectangle BlItem],
      setLevel =>      [setLevel:      LONG POINTER TO setLevel BlItem],
      setInk =>        [setInk:        LONG POINTER TO setInk BlItem],
      endOfBand =>     [endOfBand:     LONG POINTER TO endOfBand BlItem],
      endOfPage =>     [endOfPage:     LONG POINTER TO endOfPage BlItem],
      rulette =>       [rulette:       LONG POINTER TO rulette BlItem],
      nop1 =>          [nop1:          LONG POINTER TO nop1 BlItem],
      nop2 =>          [nop2:          LONG POINTER TO nop2 BlItem],
      ENDCASE];


  charCmd:      CARDINAL = 0;
  endOfBandCmd: CARDINAL = 8;
  endOfPageCmd: CARDINAL = 9;
  rectangleCmd: CARDINAL = 10;
  setLevelCmd:  CARDINAL = 11;
  setInkCmd:    CARDINAL = 12;
  ruletteCmd:   CARDINAL = 13;
  nopCmd1:      CARDINAL = 14;
  nopCmd2:      CARDINAL = 15;

  END...