(**************************************************************************

     $RCSfile: Hardware.mod $
  Description: Definitions for Amiga hardware and custom chips

   Created by: fjc (Frank Copeland)
    $Revision: 3.2 $
      $Author: fjc $
        $Date: 1994/08/08 00:47:05 $

  Includes Release 40.15

  (C) Copyright 1985-1993 Commodore-Amiga, Inc.
      All Rights Reserved

  Oberon-A interface Copyright © 1994, Frank Copeland.
  This file is part of the Oberon-A Interface.
  See Oberon-A.doc for conditions of use and distribution.

***************************************************************************)

MODULE Hardware;

(*
** $C- CaseChk       $I- IndexChk  $L+ LongAdr   $N- NilChk
** $P- PortableCode  $R- RangeChk  $S- StackChk  $T- TypeChk
** $V- OvflChk       $Z- ZeroVars
*)

IMPORT E := Exec, SYS := SYSTEM;

(*
**      $VER: adkbits.h 39.1 (18.9.92)
**
**      bit definitions for adkcon register
*)

CONST

  adkSetClr   * = 15; (* standard set/clear bit *)
  adkPreComp1 * = 14; (* two bits of precompensation *)
  adkPreComp0 * = 13;
  adkMfmPrec  * = 12; (* use mfm style precompensation *)
  adkUartBrk  * = 11; (* force uart output to zero *)
  adkWordSync * = 10; (* enable DSKSYNC register matching *)
  adkMsbSync  * =  9; (* (Apple GCR Only) sync on MSB for reading *)
  adkFast     * =  8; (* 1 -> 2 us/bit (mfm), 2 -> 4 us/bit (gcr) *)
  adkUse3pn   * =  7; (* use aud chan 3 to modulate period of ?? *)
  adkUse2p3   * =  6; (* use aud chan 2 to modulate period of 3 *)
  adkUse1p2   * =  5; (* use aud chan 1 to modulate period of 2 *)
  adkUse0p1   * =  4; (* use aud chan 0 to modulate period of 1 *)
  adkUse3vn   * =  3; (* use aud chan 3 to modulate volume of ?? *)
  adkUse2v3   * =  2; (* use aud chan 2 to modulate volume of 3 *)
  adkUse1v2   * =  1; (* use aud chan 1 to modulate volume of 2 *)
  adkUse0v1   * =  0; (* use aud chan 0 to modulate volume of 1 *)

  pre000ns  * = {};                           (* 000 ns of precomp *)
  pre140ns  * = { adkPreComp0 };              (* 140 ns of precomp *)
  pre280ns  * = { adkPreComp1 };              (* 280 ns of precomp *)
  pre560ns  * = { adkPreComp0, adkPreComp1 }; (* 560 ns of precomp *)

(*
**      $VER: blit.h 39.1 (18.9.92)
**
**      Defines for direct hardware use of the blitter.
*)

CONST

  hSizeBits* = 6;
  vSizeBits* = 16-hSizeBits;
  hSizeMask* = 3FH;        (* 2^6 -- 1 *)
  vSizeMask* = 3FFH;       (* 2^10 - 1 *)

(* all agnii support horizontal blit of at least 1024 bits (128 bytes) wide *)
(* some agnii support horizontal blit of up to 32768 bits (4096 bytes) wide *)

(* #ifndef  NO_BIG_BLITS *)

  minBytesPerRow * = 128;
  maxBytesPerRow * = 4096;

(* #else *)

(* maxBytesPerRow * = 128; *)

(* #endif *)

(* definitions for blitter control register 0 *)

  abc   * = 7;
  abnc  * = 6;
  anbc  * = 5;
  anbnc * = 4;
  nabc  * = 3;
  nabnc * = 2;
  nanbc * = 1;
  nanbnc* = 0;

(* some commonly used operations *)
  aORb   * = { abc, anbc, nabc, abnc, anbnc, nabnc };
  aORc   * = { abc, nabc, abnc, anbc, nanbc, anbnc };
  aXORc  * = { nabc, abnc, nanbc, anbnc };
  aTOd   * = { abc, anbc, abnc, anbnc };

  bc0Dest * = 8;
  bc0SrcC * = 9;
  bc0SrcB * = 10;
  bc0SrcA * = 11;

  bc1Desc * = 1;         (* blitter descend direction *)

  dest * = {bc0Dest};
  srcC * = {bc0SrcC};
  srcB * = {bc0SrcB};
  srcA * = {bc0SrcA};

  aShiftShift * = 12;       (* bits to right align ashift value *)
  bShiftShift * = 12;       (* bits to right align bshift value *)

(* definations for blitter control register 1 *)
  lineMode    * = 0;
  fillOr      * = 3;
  fillXor     * = 4;
  fillCarryIn * = 2;
  oneDot      * = 1;      (* one dot per horizontal line *)
  ovFlag      * = 5;
  signFlag    * = 6;
  blitReverse * = 1;

  sud         * = {fillXor};
  sul         * = {fillOr};
  aul         * = {fillCarryIn};

  octant8  * = sul+sud;
  octant7  * = aul;
  octant6  * = aul+sul;
  octant5  * = aul+sul+sud;
  octant4  * = aul+sud;
  octant3  * = sul;
  octant2  * = {};
  octant1  * = sud;

(* stuff for blit qeuer *)

TYPE

  BltnodePtr* = CPOINTER TO Bltnode;
  Bltnode* = RECORD
    n       * : BltnodePtr;
    function* : E.PROC;
    stat    * : SHORTINT;
    blitsize* : INTEGER;
    beamsync* : INTEGER;
    cleanup * : E.PROC;
  END; (* Bltnode *)

CONST

(* defined bits for bltstat *)
  cleanup* = 40H;
  cleanme* = cleanup;


(*
**      $VER: cia.h 39.1 (18.9.92)
**
**      registers and bits in the Complex Interface Adapter (CIA) chip
*)


(*
 * ciaa is on an ODD address (e.g. the low byte) -- $bfe001
 * ciab is on an EVEN address (e.g. the high byte) -- $bfd000
 *
 * do this to get the definitions:
 *    extern struct CIA ciaa, ciab;
 *)


TYPE

  Pad = ARRAY 254 OF SHORTINT;

  CIAPtr* = CPOINTER TO CIA;
  CIA* = RECORD
    pra   * : E.BSET;    pad0 * : Pad;
    prb   * : E.BSET;    pad1 * : Pad;
    ddra  * : E.BSET;    pad2 * : Pad;
    ddrb  * : E.BSET;    pad3 * : Pad;
    talo  * : E.BSET;    pad4 * : Pad;
    tahi  * : E.BSET;    pad5 * : Pad;
    tblo  * : E.BSET;    pad6 * : Pad;
    tbhi  * : E.BSET;    pad7 * : Pad;
    todlow* : E.BSET;    pad8 * : Pad;
    todmid* : E.BSET;    pad9 * : Pad;
    todhi * : E.BSET;    pad10* : Pad;
    unusedreg* : E.BSET; pad11* : Pad;
    sdr   * : E.BSET;    pad12* : Pad;
    icr   * : E.BSET;    pad13* : Pad;
    cra   * : E.BSET;    pad14* : Pad;
    crb   * : E.BSET;
  END; (* CIA *)


CONST

(* interrupt control register bit numbers *)
  icrTa     * = 0;
  icrTb     * = 1;
  icrAlrm   * = 2;
  icrSp     * = 3;
  icrFlg    * = 4;
  icrIr     * = 7;
  icrSetClr * = 7;

(* control register A bit numbers *)
  craStart  * = 0;
  craPbon   * = 1;
  craOutmode* = 2;
  craRunmode* = 3;
  craLoad   * = 4;
  craInmode * = 5;
  craSpmode * = 6;
  craTodin  * = 7;

(* control register B bit numbers *)
  crbStart  * = 0;
  crbPbon   * = 1;
  crbOutmode* = 2;
  crbRunmode* = 3;
  crbLoad   * = 4;
  crbInmode0* = 5;
  crbInmode1* = 6;
  crbAlarm  * = 7;

(*
 * Port definitions -- what each bit in a cia peripheral register is tied to
 *)

(* ciaa port A (0BFE001H) *)
  gamePort1 * = 7;   (* gameport 1, pin 6 (fire button) *)
  gamePort0 * = 6;   (* gameport 0, pin 6 (fire button) *)
  dskRdy    * = 5;   (* disk ready *)
  dskTrack0 * = 4;   (* disk on track 00 *)
  dskProt   * = 3;   (* disk write protect *)
  dskChange * = 2;   (* disk change *)
  led       * = 1;   (* led light control (0==>bright) *)
  overlay   * = 0;   (* memory overlay bit *)

(* ciaa port B (0BFE101H) -- parallel port *)

(* ciab port A (0BFD000H) -- serial and printer control *)
  comDTR    * = 7;   (* serial Data Terminal Ready *)
  comRTS    * = 6;   (* serial Request to Send *)
  comCD     * = 5;   (* serial Carrier Detect *)
  comCTS    * = 4;   (* serial Clear to Send *)
  comDSR    * = 3;   (* serial Data Set Ready *)
  prtrSel   * = 2;   (* printer SELECT *)
  prtrPOut  * = 1;   (* printer paper out *)
  prtrBusy  * = 0;   (* printer busy *)

(* ciab port B (0BFD100H) -- disk control *)
  dskMotor  * = 7;   (* disk motorr *)
  dskSel3   * = 6;   (* disk select unit 3 *)
  dskSel2   * = 5;   (* disk select unit 2 *)
  dskSel1   * = 4;   (* disk select unit 1 *)
  dskSel0   * = 3;   (* disk select unit 0 *)
  dskSide   * = 2;   (* disk side select *)
  dskDirec  * = 1;   (* disk direction of seek *)
  dskStep   * = 0;   (* disk step heads *)


(* cia addresses, initialised to point to correct addresses *)

VAR
  ciaa* : CIAPtr;
  ciab* : CIAPtr;


(*
**      $VER: custom.h 39.1 (18.9.92)
**
**      Offsets of Amiga custom chip registers
*)


(*
 * do this to get base of custom registers:
 * extern struct Custom custom;
 *)


TYPE

  AudChannelPtr* = CPOINTER TO AudChannel;
  AudChannel* = RECORD
    ptr* : E.APTR;      (* ptr to start of waveform data *)
    len* : E.UWORD;     (* length of waveform in words *)
    per* : E.UWORD;     (* sample period *)
    vol* : E.UWORD;     (* volume *)
    dat* : E.UWORD;     (* sample pair *)
    pad* : ARRAY 2 OF E.UWORD;  (* unused *)
  END; (* AudChannel *)

  SpriteDefPtr* = CPOINTER TO SpriteDef;
  SpriteDef* = RECORD
    pos  * : E.UWORD;
    ctl  * : E.UWORD;
    dataa* : E.UWORD;
    datab* : E.UWORD;
  END; (* SpriteDef *)

  CustomPtr* = CPOINTER TO Custom;
  Custom* = RECORD
    bltddat * : E.UWORD;
    dmaconr * : E.WSET;
    vposr   * : E.UWORD;
    vhposr  * : E.UWORD;
    dskdatr * : E.UWORD;
    joy0dat * : E.UWORD;
    joy1dat * : E.UWORD;
    clxdat  * : E.WSET;
    adkconr * : E.WSET;
    pot0dat * : E.UWORD;
    pot1dat * : E.UWORD;
    potinp  * : E.WSET;
    serdatr * : E.UWORD;
    dskbytr * : E.UWORD;
    intenar * : E.WSET;
    intreqr * : E.WSET;
    dskpt   * : E.APTR;
    dsklen  * : E.UWORD;
    dskdat  * : E.UWORD;
    refptr  * : E.UWORD;
    vposw   * : E.UWORD;
    vhposw  * : E.UWORD;
    copcon  * : E.WSET;
    serdat  * : E.UWORD;
    serper  * : E.UWORD;
    potgo   * : E.WSET;
    joytest * : E.UWORD;
    strequ  * : E.UWORD;
    strvbl  * : E.UWORD;
    strhor  * : E.UWORD;
    strlong * : E.UWORD;
    bltcon0 * : E.WSET;
    bltcon1 * : E.WSET;
    bltafwm * : E.WSET;
    bltalwm * : E.WSET;
    bltcpt  * : E.APTR;
    bltbpt  * : E.APTR;
    bltapt  * : E.APTR;
    bltdpt  * : E.APTR;
    bltsize * : E.UWORD;
    pad2d   * : SHORTINT;
    bltcon0l* : E.BSET; (* low 8 bits of bltcon0, write only *)
    bltsizv * : E.UWORD;
    bltsizh * : E.UWORD;     (* 5e *)
    bltcmod * : E.UWORD;
    bltbmod * : E.UWORD;
    bltamod * : E.UWORD;
    bltdmod * : E.UWORD;
    pad34   * : ARRAY 4 OF E.UWORD;
    bltcdat * : E.UWORD;
    bltbdat * : E.UWORD;
    bltadat * : E.UWORD;
    pad3b   * : ARRAY 3 OF E.UWORD;
    deniseid* : E.UWORD;   (* 7c *)
    dsksync * : E.UWORD;
    cop1lc  * : E.ULONG;
    cop2lc  * : E.ULONG;
    copjmp1 * : E.UWORD;
    copjmp2 * : E.UWORD;
    copins  * : E.UWORD;
    diwstrt * : E.UWORD;
    diwstop * : E.UWORD;
    ddfstrt * : E.UWORD;
    ddfstop * : E.UWORD;
    dmacon  * : E.WSET;
    clxcon  * : E.WSET;
    intena  * : E.WSET;
    intreq  * : E.WSET;
    adkcon  * : E.WSET;
    aud     * : ARRAY 4 OF AudChannel;
    bplpt   * : ARRAY 8 OF E.APTR;
    bplcon0 * : E.WSET;
    bplcon1 * : E.WSET;
    bplcon2 * : E.WSET;
    bplcon3 * : E.WSET;
    bpl1mod * : E.UWORD;
    bpl2mod * : E.UWORD;
    bplhmod * : E.UWORD;
    pad86   * : E.UWORD;
    bpldat  * : ARRAY 8 OF E.UWORD;
    sprpt   * : ARRAY 8 OF E.APTR;
    spr     * : ARRAY 8 OF SpriteDef;
    color   * : ARRAY 32 OF E.UWORD;
    htotal  * : E.UWORD;
    hsstop  * : E.UWORD;
    hbstrt  * : E.UWORD;
    hbstop  * : E.UWORD;
    vtotal  * : E.UWORD;
    vsstop  * : E.UWORD;
    vbstrt  * : E.UWORD;
    vbstop  * : E.UWORD;
    sprhstrt* : E.UWORD;
    sprhstop* : E.UWORD;
    bplhstrt* : E.UWORD;
    bplhstop* : E.UWORD;
    hhposw  * : E.UWORD;
    hhposr  * : E.UWORD;
    beamcon0* : E.WSET;
    hsstrt  * : E.UWORD;
    vsstrt  * : E.UWORD;
    hcenter * : E.UWORD;
    diwhigh * : E.UWORD;    (* 1e4 *)
    padf3   * : ARRAY 11 OF E.UWORD;
    fmode   * : E.UWORD;
  END; (* Custom *)

CONST

(* defines for beamcon register *)
  varVBlank      * = 13;  (* Variable vertical blank enable *)
  loLDis         * = 12;  (* long line disable *)
  cscBlankEn     * = 11;  (* redirect composite sync *)
  varVSync       * = 10;  (* Variable vertical sync enable *)
  varHSync       * =  9;  (* Variable horizontal sync enable *)
  varBeam        * =  8;  (* variable beam counter enable *)
  displayDual    * =  7;  (* use UHRES pointer and standard pointers *)
  displayPAL     * =  6;  (* set decodes to generate PAL display *)
  varCSync       * =  5;  (* Variable composite sync enable *)
  csBlank        * =  4;  (* Composite blank out to CSY* pin *)
  cSyncTrue      * =  3;  (* composite sync true signal *)
  vSyncTrue      * =  1;  (* vertical sync true *)
  hSyncTrue      * =  0;  (* horizontal sync true *)

(* new defines for bplcon0 *)
  useBplCon3    * = 1;

(* new defines for bplcon2 *)
  bplcon2ZdCTen         * = 10; (* colormapped genlock bit *)
  bplcon2ZdBPen         * = 11; (* use bitplane as genlock bits *)
  bplcon2ZdBPSel0       * = 12; (* three bits to select one *)
  bplcon2ZdBPSel1       * = 13; (* of 8 bitplanes in *)
  bplcon2ZdBPSel2       * = 14; (* zdBPen genlock mode *)

(* defines for bplcon3 register *)
  bplcon3ExtBlnkEn      * = 0;  (* external blank enable *)
  bplcon3ExtBlkZD       * = 1;  (* external blank ored into trnsprncy *)
  bplcon3ZdClkEn        * = 2;  (* zd pin outputs a 14mhz clock*)
  bplcon3BrdnTran       * = 4;  (* border is opaque *)
  bplcon3BrdnBlnk       * = 5;  (* border is opaque *)

(* Pointer to custom hardware *)

VAR

  custom* : CustomPtr;

(*
**      $VER: dmabits.h 39.1 (18.9.92)
**
**      include file for defining dma control stuff
*)

CONST

(* write definitions for dmaconw *)
  dmaSetClr * = 15;
  dmaAud0   * = 0;
  dmaAud1   * = 1;
  dmaAud2   * = 2;
  dmaAud3   * = 3;
  dmaAudio  * = {dmaAud0, dmaAud1, dmaAud2, dmaAud3}; (* 4 bit mask *)
  dmaDisk   * = 4;
  dmaSprite * = 5;
  dmaBlitter* = 6;
  dmaCopper * = 7;
  dmaRaster * = 8;
  dmaMaster * = 9;
  dmaBlithog* = 10;
  dmaAll* = {dmaAud0 .. dmaRaster}; (* all dma channels *)

(* read definitions for dmaconr *)
(* bits 0-8 correspnd to dmaconw definitions *)
  dmaBltDone   * = 14;
  dmaBltNZero  * = 13;


(*
**      $VER: intbits.h 39.1 (18.9.92)
**
**      bits in the interrupt enable (and interrupt request) register
*)

CONST

  intSetClr  * =  15;  (* Set/Clear control bit. Determines if bits *)
                       (* written with a 1 get set or cleared. Bits *)
                       (* written with a zero are allways unchanged *)
  intIntEn   * =  14;  (* Master interrupt (enable only ) *)
  intExter   * =  13;  (* External interrupt *)
  intDskSync * =  12;  (* Disk re-SYNChronized *)
  intRBF     * =  11;  (* serial port Receive Buffer Full *)
  intAud3i   * =  10;  (* Audio channel 3 block finished *)
  intAud2i   * =   9;  (* Audio channel 2 block finished *)
  intAud1i   * =   8;  (* Audio channel 1 block finished *)
  intAud0i   * =   7;  (* Audio channel 0 block finished *)
  intBlit    * =   6;  (* Blitter finished *)
  intVertB   * =   5;  (* start of Vertical Blank *)
  intCoper   * =   4;  (* Coprocessor *)
  intPorts   * =   3;  (* I/O Ports and timers *)
  intSoftint * =   2;  (* software interrupt request *)
  intDskblk  * =   1;  (* Disk Block done *)
  intTBE     * =   0;  (* serial port Transmit Buffer Empty *)

(* $L- *)

BEGIN
  ciaa := SYS.VAL (CIAPtr, 00BFE001H);
  ciab := SYS.VAL (CIAPtr, 00BFD000H);
  custom := SYS.VAL (CustomPtr, 00DFF000H);
END Hardware.
