-- AltoHardware.Mesa  Edited by Sandman on June 30, 1980  9:21 AM
-- Copyright  Xerox Corporation 1979, 1980

AltoHardware: DEFINITIONS =
  BEGIN

  WordLength: CARDINAL = 16;
  CharLength: CARDINAL = 8;
  PageSize: CARDINAL = 256;

  -- Extended Memory

  BankRegister: TYPE = MACHINE DEPENDENT RECORD [
    undefined: [0..7777B], normal, alternate: BankNumber];

  BankNumber: TYPE = CARDINAL [0..3];

  BankRegisters: POINTER TO ARRAY Task OF BankRegister = LOOPHOLE[177740B];

  Task: TYPE = {
    Emulator, OrbitSlot, unused2, Trident3, KSEC, Tape5, Tape6, ETHER, MRT, DWT,
    CURT, DHT, DVT, PART, KWD, Trident17};

  Maxc2MemoryInterface: Task = Task[Trident17];

  -- Display Controller

  DCBchainHead: POINTER TO DCBHandle = LOOPHOLE[420B];
  DIW: POINTER TO WORD = LOOPHOLE[421B];

  DCB: TYPE = MACHINE DEPENDENT RECORD [
    next: DCBHandle,
    resolution: Resolution,
    background: Background,
    indenting: [0..77B], -- in units of 16 bits
    width: [0..377B], -- likewise;  must be even
    bitmap: POINTER, -- must be even
    height: CARDINAL]; -- in double scan lines

  DCBHandle: TYPE = POINTER TO DCB;
  Resolution: TYPE = {high, low};
  Background: TYPE = {white, black};

  CursorBits: TYPE = ARRAY [0..16) OF WORD;
  CursorHandle: TYPE = POINTER TO CursorBits;
  Cursor: CursorHandle = LOOPHOLE[431B];

  Coordinate: TYPE = MACHINE DEPENDENT RECORD [x, y: INTEGER];
  CursorXY: POINTER TO Coordinate = LOOPHOLE[426B];

  -- Keyboard

  KBDAD: POINTER TO KeyboardBits = LOOPHOLE[177034B];

  KeyboardBits: TYPE = MACHINE DEPENDENT RECORD [
    Five, Four, Six, E, Seven, D, U, V, Zero, K, Dash, P, Slash, BackSlash, LF,
      BS: UpDown,
    Three, Two, W, Q, S, A, Nine, I, X, O, L, Comma, Quote, RightBracket, Spare2,
      Spare1: UpDown,
    One, ESC, TAB, F, Ctrl, C, J, B, Z, LeftShift, Period, SemiColon, Return,
      Arrow, DEL, FL3: UpDown,
    R, T, G, Y, H, Eight, N, M, Lock, Space, LeftBracket, Equal, RightShift,
      Spare3, FL4, FR5: UpDown];

  UpDown: TYPE = {down, up};

  -- Mouse, Keyset, UtilIn and UtilOut

  UtilInBits: TYPE = MACHINE DEPENDENT RECORD [
    util: [0..377B], -- Diablo, Versatec, etc.
    key0: UpDown, -- left-most
    key1: UpDown,
    key2: UpDown,
    key3: UpDown,
    key4: UpDown, -- right-most
    redMouse: UpDown,
    blueMouse: UpDown,
    yellowMouse: UpDown];

  UtilIn: POINTER TO UtilInBits = LOOPHOLE[177030B];

  UtilOut: POINTER TO WORD = LOOPHOLE[177016B];

  -- Parity Error Stuff

  ParityErrorData: TYPE = MACHINE DEPENDENT RECORD [
    DCBR: POINTER, -- Disk control block fetch pointer
    KNMAR: POINTER, -- Disk word fetch/store pointer
    DWA: POINTER, -- Display word fetch address
    CBA: POINTER, -- Display control block fetch address
    PC: POINTER, -- Current program counter in Alto emulator
    SAD: POINTER]; -- Temporary register for indirection in Alto emulator

  ParityErrorDataLoc: POINTER TO ParityErrorData = LOOPHOLE[614B];

  MemoryErrorAddressRegister: POINTER TO POINTER = LOOPHOLE[177024B];

  MemoryErrorStatus: TYPE = MACHINE DEPENDENT RECORD [
    hammingCode: [0..77B],
    parityError: [0..1],
    memoryParity: [0..1],
    syndrome: [0..77B],
    bankNumber: BankNumber];

  MemoryErrorStatusRegister: POINTER TO POINTER = LOOPHOLE[177025B];

  MemoryErrorControl: TYPE = MACHINE DEPENDENT RECORD [
    spare1: [0..17B],
    testHammingCode: [0..177B],
    testMode: [0..1],
    interruptSingleBitErrors: [0..1],
    interruptDoubleBitErrors: [0..1],
    noErrorCorrection: [0..1],
    spare2: [0..1]];

  MemoryErrorControlRegister: POINTER TO POINTER = LOOPHOLE[177026B];

  -- Disk Controller

  NextDiskCommand: POINTER TO KCBHandle = LOOPHOLE[521B];
  DiskStatus: POINTER TO DS = LOOPHOLE[522B];
  LastDiskAddress: POINTER TO DA = LOOPHOLE[523B];
  SectorInterrupts: POINTER TO WORD = LOOPHOLE[524B];

  -- physical disk address

  DA: TYPE = MACHINE DEPENDENT RECORD [
    sector: [0..17B], track: [0..777B], head, disk: [0..1], restore: [0..1]];

  -- DAs with special meaning

  InvalidDA: DA = DA[17B, 777B, 1, 1, 1];

  -- disk header

  DH: TYPE = MACHINE DEPENDENT RECORD [packID: CARDINAL, diskAddress: DA];

  -- file identifier

  FID: TYPE = MACHINE DEPENDENT RECORD [
    version: CARDINAL, serial: LONG UNSPECIFIED];

  -- disk label

  DL: TYPE = MACHINE DEPENDENT RECORD [
    next, prev: DA,
    blank: UNSPECIFIED,
    bytes: CARDINAL,
    page: CARDINAL,
    fileID: FID];

  -- disk final status

  DFS: TYPE = {CommandComplete, HardwareError, CheckError, IllegalSector};

  -- disk status word

  DS: TYPE = MACHINE DEPENDENT RECORD [
    sector: [0..17B],
    done: [0..17B],
    seekFailed: [0..1],
    seekInProgress: [0..1],
    notReady: [0..1],
    dataLate: [0..1],
    noTransfer: [0..1],
    checksumError: [0..1],
    finalStatus: DFS];

  -- disk subcommands

  DSC: TYPE = {DiskRead, DiskCheck, DiskWrite, DiskWriteAlso};

  -- hardware disk command

  DC: TYPE = MACHINE DEPENDENT RECORD [
    seal: [0..377B], header, label, data: DSC, seek, exchange: [0..1]];

  KCBHandle: TYPE = POINTER TO KCB;

  -- disk command block (label, page, and zone added)

  KCB: TYPE = MACHINE DEPENDENT RECORD [
    nextCB: KCBHandle,
    status: DS,
    command: DC,
    headerAddress: POINTER,
    labelAddress: POINTER,
    dataAddress: POINTER,
    normalWakeups: WORD,
    errorWakeups: WORD,
    unused: UNSPECIFIED,
    diskAddress: DA];

  -- Ethernet Controller

  EPLoc: POINTER TO EthernetDeviceBlock = LOOPHOLE[600B];

  EthernetDeviceBlock: TYPE = MACHINE DEPENDENT RECORD [
    postData: EthernetPost,
    interruptBit: WORD,
    wordsLeft: CARDINAL,
    retransmissionMask: WORD,
    inputBuffer: WordBlockDescriptor,
    outputBuffer: WordBlockDescriptor,
    hostNumber: WORD];

  WordBlockDescriptor: TYPE = MACHINE DEPENDENT RECORD [
    count: CARDINAL, pointer: POINTER];

  EthernetPost: TYPE = MACHINE DEPENDENT RECORD [
    microcodeStatus: EthernetMicrocodeStatus,
    hardwareStatus: EthernetHardwareStatus];

  EthernetMicrocodeStatus: TYPE = RECORD [[0..377B]];
  inputDone: EthernetMicrocodeStatus = [0];
  outputDone: EthernetMicrocodeStatus = [1];
  inputBufferOverflow: EthernetMicrocodeStatus = [2];
  outputLoadOverflow: EthernetMicrocodeStatus = [3];
  zeroLengthBuffer: EthernetMicrocodeStatus = [4];
  hardwareReset: EthernetMicrocodeStatus = [5];
  interfaceBroken: EthernetMicrocodeStatus = [6];

  EthernetHardwareStatus: TYPE = MACHINE DEPENDENT RECORD [
    unused: [0..2],
    inputDataLate: [0..1],
    collision: [0..1],
    badInputCRC: [0..1],
    inputCommandIssued: [0..1],
    outputCommandIssued: [0..1],
    incompleteTransmission: [0..1]];

  -- Other

  RealTimeClock: POINTER TO CARDINAL = LOOPHOLE[430B];

  END.