(*$ Implementation- *)
DEFINITION MODULE Hardware;

(* (C) Copyright 1994 Marcel Timmermans. All rights reserved. *)

FROM SYSTEM IMPORT ADDRESS,BITSET,SHORTSET;

IMPORT ExecD;

TYPE
 AdkFlags=(
  use0v1,    (* standard set/clear bit *) 
  use1v2,    (* two bits of precompensation *) 
  use2v3,     
  use3vn,    (* use mfm style precompensation *) 
  use0p1,    (* force uart output to zero *)   
  use1p2,    (* enable DSKSYNC register matching *)   
  use2p3,    (* (Apple GCR Only) sync on MSB for reading *)   
  use3pn,    (* 1 -> 2 us/bit (mfm), 2 -> 4 us/bit (gcr) *)   
  fast,      (* use aud chan 3 to modulate period of ?? *) 
  msbSync,   (* use aud chan 2 to modulate period of 3 *)   
  wordSync,  (* use aud chan 1 to modulate period of 2 *)   
  uartBrk,   (* use aud chan 0 to modulate period of 1 *)   
  mfmPrec,   (* use aud chan 3 to modulate volume of ?? *)   
  preComp0,  (* use aud chan 2 to modulate volume of 3 *)   
  preComp1,  (* use aud chan 1 to modulate volume of 2 *)   
  adkSet     (* use aud chan 0 to modulate volume of 1 *)       
 );
 AdkFlagSet=SET OF AdkFlags;

CONST
 pre000ns=AdkFlagSet{};                   (* 000 ns of precomp *)
 pre140ns=AdkFlagSet{preComp0};           (* 140 ns of precomp *)
 pre280ns=AdkFlagSet{preComp1};           (* 280 ns of precomp *)
 pre560ns=AdkFlagSet{preComp0,preComp1};  (* 560 ns of precomp *)

 hSizeBits=6;
 vSizeBits=16-hSizeBits;
 hSizeMask=03FH;      (* 2^6  - 1 *)
 vSizeMask=03FFH;     (* 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 *)

  minBytesPerRow=128;
  maxBytesPerRow=4096;

  maxBytesPerRowNoBigBlits=128;

TYPE
(* definitions for blitter control register 0 *)

 BC0Flags=(
  nanbnc,nanbc,nabnc,nabc,anbnc,anbc,abnc,abc,
  dest,srcC,srcB,srcA,ash1,ash2,ash4,ash8
 );
 BC0FlagSet=SET OF BC0Flags;

CONST
 aORb=BC0FlagSet{abc,anbc,nabc,abnc,anbnc,nabnc};
 aORc=BC0FlagSet{abc,nabc,abnc,anbc,nanbc,anbnc};
 aXORc=BC0FlagSet{nabc,abnc,nanbc,anbnc};
 aTOd=BC0FlagSet{abc,anbc,abnc,anbnc};

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

TYPE
 BC1Flags=(
  lineMode,desc,fillCarryIn,fillOr,fillXor,ovFlag,signFlag,
  bf7,bf8,bf9,bf10,bf11,bsh1,bsh2,bsh4,bsh8
 );
 BC1FlagSet=SET OF BC1Flags;
CONST
 oneDot=desc;
 blitReverse=desc;
 aul=BC1FlagSet{fillCarryIn};
 sul=BC1FlagSet{fillOr};
 sud=BC1FlagSet{fillXor};
 octant1=sud;
 octant2=BC1FlagSet{};
 octant3=sul;
 octant4=aul+sud;
 octant5=aul+sul+sud;
 octant6=aul+sul;
 octant7=aul;
 octant8=sul+sud;


TYPE
 BltnodePtr=POINTER TO Bltnode;
 Bltnode=RECORD
  n:BltnodePtr;
  function:ADDRESS;
  stat:CHAR;
  blitsize:INTEGER;
  beamsync:INTEGER;
  cleanup:ADDRESS;
 END;

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


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

TYPE
(* interrupt control register bit numbers *)
 CiaIcrFlags=(ta,tb,alrm,sp,flg,if5,if6,setclr);
 CiaIcrFlagSet=SET OF CiaIcrFlags;
CONST
 ir=setclr; (* On read setclr has the meaning of ir *)
TYPE
(* control register A bit numbers *)
 CiaCraFlags=(
  craStart,craPbon,craOutmode,craRunmode,craLoad,craInmode,
  craSpmode,craTodin
 );
 CiaCraFlagSet=SET OF CiaCraFlags;

(* control register B bit numbers *)
 CiaCrbFlags=(
  crbStart,crbPbon,crbOutmode,crbRunmode,crbLoad,crbInmode0,
  crbInmode1,crbAlarm
 );
 CiaCrbFlagSet=SET OF CiaCrbFlags;

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

(* ciaa port A (0xbfe001) *)
 CiaaPraFlags=(
  overlay,    (* memory overlay bit *)
  led,        (* led light control (0==>bright) *)
  dskChange,  (* disk change *)
  dskProt,    (* disk write protect *)
  dskTrack0,  (* disk on track 00 *)
  dskRdy,     (* disk ready *)
  gamePort0,  (* gameport 0, pin 6 (fire button) *)
  gamePort1   (* gameport 1, pin 6 (fire button) *)
 );
 CiaaPraFlagSet=SET OF CiaaPraFlags;

(* ciaa port B (0xbfe101) -- parallel port *)
 CiaaPrbFlags=[0..7];

(* ciab port A (0xbfd000) -- serial and printer control *)
 CiaaPrbFlagSet=SET OF CiaaPrbFlags;
 CiabPraFlags=(
  prtrBusy,   (* printer busy *)
  prtrPOut,   (* printer paper out *)
  prtrSel,    (* printer SELECT *)
  comDSR,     (* serial Data Set Ready *)
  comCTS,     (* serial Clear to Send *)
  comCD,      (* serial Carrier Detect *)
  comRTS,     (* serial Request to Send *)
  comDTR      (* serial Data Terminal Ready *)
 );
 CiabPraFlagSet=SET OF CiabPraFlags;

(* ciab port B (0xbfd100) -- disk control *)
 CiabPrbFlags=(
  dskStep,    (* disk step heads *)
  dskDirec,   (* disk direction of seek *)
  dskSide,    (* disk side select *)
  dskSel0,    (* disk select unit 0 *)
  dskSel1,    (* disk select unit 1 *)
  dskSel2,    (* disk select unit 2 *)
  dskSel3,    (* disk select unit 3 *)
  dskMotor    (* disk motor *)
 );
 CiabPrbFlagSet=SET OF CiabPrbFlags;

TYPE
 Pad=ARRAY [0..253] OF SHORTSET;
 CIA=RECORD
  pra:CiaaPraFlagSet; pad0:Pad;
  prb:CiaaPrbFlagSet; pad1:Pad;
  ddra:CiaaPraFlagSet; pad2:Pad;
  ddrb:CiaaPrbFlagSet; pad3:Pad;
  talo:SHORTCARD; pad4:Pad;
  tahi:SHORTCARD; pad5:Pad;
  tblo:SHORTCARD; pad6:Pad;
  tbhi:SHORTCARD; pad7:Pad;
  todlow:SHORTCARD; pad8:Pad;
  todmid:SHORTCARD; pad9:Pad;
  todhi:SHORTCARD; pad10:Pad;
  unusedreg:SHORTSET; pad11:Pad;
  sdr:SHORTSET; pad12:Pad;
  icr:CiaIcrFlagSet; pad13:Pad;
  cra:CiaCraFlagSet; pad14:Pad;
  crb:CiaCrbFlagSet;
 END;

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

 Coord=RECORD
  v,h:SHORTINT;
 END;

 SerialFlags=(d8,stop,sf2,rxd,tsre,tbe,rbf,ovrun);
 SerialFlagSet=SET OF SerialFlags;

 SerialInfo=RECORD
  flags:SerialFlagSet;
  data:CHAR;
 END;

 DiskFlags=(df0,df1,df2,df3,wordEqual,diskWrite,dmaOn,dskByte);
 DiskFlagSet=SET OF DiskFlags;

 DiskInfo=RECORD
  flags:DiskFlagSet;
  data:SHORTCARD;
 END;

 AudioChannel=RECORD
  ptr:ADDRESS;    (* ptr to start of waveform data *)
  len:CARDINAL;   (* length of waveform in words *)
  per:CARDINAL;   (* sample period *)
  vol:CARDINAL;   (* volume *)
  dat:CARDINAL;   (* sample pair *)                  
  pad:ARRAY [0..1] OF CARDINAL; (* unused *)
 END;
 AudioChannels=ARRAY [0..3] OF AudioChannel;

(* defines for beamcon register *)
 BeamConFlags=(
  hSyncTrue,    (* horizontal sync true *)
  vSyncTrue,    (* vertical sync true *)
  cSyncTrue,    (* composite sync true signal *)
  cSBlank,      (* Composite blank out to CSY* pin *)
  varCSync,     (* Variable composite sync enable *)
  displayPal,   (* set decodes to generate PAL display *)
  displayDual,  (* use UHRES pointer and standard pointers *)
  varBeam,      (* variable beam counter enable *)
  varHSync,     (* Variable horizontal sync enable *)
  varVSync,     (* Variable vertical sync enable *)
  cSBlankEn,    (* redirect composite sync *)
  lolDis,       (* long line disable *)
  varVBlank,    (* Variable vertical blank enable *)
  bcf13,        
  bcf14,        
  bcf15         
 );
 BeamConFlagSet=SET OF BeamConFlags;

 BPLC0Flags=(
  bp0,
  ersy,
  lace,
  lpen,
  bp4,
  bp5,
  bp6,
  bp7,
  gaud,
  color,
  dblpf,
  homod,
  bpu0,
  bpu1,
  bpu2,
  hires
 );
 BPLC0FlagSet=SET OF BPLC0Flags;

 CollisionControlFlags=(
  plane1,plane2,plane3,plane4,plane5,plane6,
  enablePlane1,enablePlane2,enablePlane3,
  enablePlane4,enablePlane5,enablePlane6,
  enableSprite01,enableSprite23,
  enableSprite45,enableSprite67
 );
 CollisionControlFlagSet=SET OF CollisionControlFlags;
 CollisionFlags=(
  play1toPlay2,
  play1toSprite01,play1toSprite23,play1toSprite45,play1toSprite67,
  play2toSprite01,play2toSprite23,play2toSprite45,play2toSprite67,
  sprite01toSprite23,sprite01toSprite45,sprite01toSprite67,
  sprite23toSprite45,sprite23toSprite67,
  sprite45toSprite67
 );
 CollisionFlagSet=SET OF CollisionFlags;
 DmaFlags=(
  aud0,aud1,aud2,aud3,disk,sprite,blitter,copper,
  raster,master,blithog,df11,df12,bltnzero,bltdone,dmaSet
 );
 DmaFlagSet=SET OF DmaFlags;

CONST
 dmaAll=DmaFlagSet{aud0..raster};

TYPE
 IntFlags=ExecD.IntFlags;
 IntFlagSet=SET OF IntFlags;

TYPE
 PotFlags=(
  start,pf1,pf2,pf3,pf4,pf5,pf6,pf7,
  datalx,outlx,dataly,outly,datarx,outrx,datary,outry
 );
 PotFlagSet=SET OF PotFlags;
 SpriteControlFlags=(sho,ev8,sv8,sct3,sct4,sct5,sct6,att);
 SpriteControlFlagSet=SET OF SpriteControlFlags;
 SpriteControlInfo=RECORD
  ev:SHORTCARD;
  flags:SpriteControlFlagSet;
 END;
 SpriteInfo=RECORD
  pos:CARDINAL;
  ctl:SpriteControlInfo;
  data:LONGCARD;
 END;
 Sprites=ARRAY [0..7] OF SpriteInfo;

 Custom=RECORD
  bltddat:CARDINAL;
  dmaconr:DmaFlagSet;
  vposr:LONGCARD;
  dskdatr:CARDINAL;
  joy0dat:Coord;
  joy1dat:Coord;
  clxdat:CollisionFlagSet;
  adkconr:AdkFlagSet;
  pot0dat:Coord;
  pot1dat:Coord;
  potinp:PotFlagSet;
  serdatr:SerialInfo;
  dskbytr:DiskInfo;
  intenar:IntFlagSet;
  intreqr:IntFlagSet;
  dskpt:ADDRESS;
  dsklen:CARDINAL;
  dskdat:CARDINAL;
  refptr:CARDINAL;
  vposw:LONGCARD;
  copcon:BITSET;
  serdat:SerialInfo;
  serper:CARDINAL;
  potgo:PotFlagSet;
  joytest:Coord;
  strequ:CARDINAL;
  strvbl:CARDINAL;
  strhor:CARDINAL;
  strlong:CARDINAL;
  bltcon0:BC0FlagSet;
  bltcon1:BC1FlagSet;
  bltafwm:BITSET;
  bltalwm:BITSET;
  bltcpt:ADDRESS;
  bltbpt:ADDRESS;
  bltapt:ADDRESS;
  bltdpt:ADDRESS;
  bltsize:CARDINAL;
  pad2d:ARRAY [0..2] OF CARDINAL;
  bltcmod:CARDINAL;
  bltbmod:CARDINAL;
  bltamod:CARDINAL;
  bltdmod:CARDINAL;
  pad34:ARRAY [0..3] OF CARDINAL;
  bltcdat:CARDINAL;
  bltbdat:CARDINAL;
  bltadat:CARDINAL;
  pad3b:ARRAY [0..3] OF CARDINAL;
  dsksync:CARDINAL;
  cop1lc:ADDRESS;
  cop2lc:ADDRESS;
  copjmp1:CARDINAL;
  copjmp2:CARDINAL;
  copins:CARDINAL;
  diwstrt:Coord;
  diwstop:Coord;
  ddfstrt:Coord;
  ddfstop:Coord;
  dmacon:DmaFlagSet;
  clxcon:CollisionControlFlagSet;
  intena:IntFlagSet;
  intreq:IntFlagSet;
  adkcon:AdkFlagSet;
  aud:AudioChannels;
  bplpt:ARRAY [0..5] OF ADDRESS;
  pad7c:ARRAY [0..3] OF CARDINAL;
  bplcon0:BPLC0FlagSet;
  bplcon1:CARDINAL;
  bplcon2:CARDINAL;
  bplcon3:CARDINAL;
  bpl1mod:CARDINAL;
  bpl2mod:CARDINAL;
  bplcon4:CARDINAL;
  clxcon2:CARDINAL;
  bpldat:ARRAY [0..7] OF CARDINAL;
  sprpt:ARRAY [0..7] OF ADDRESS;
  spr:Sprites;
  color:ARRAY [0..31] OF CARDINAL;
  htotal:CARDINAL;
  hsstop:CARDINAL;
  hbstrt:CARDINAL;
  hbstop:CARDINAL;
  vtotal:CARDINAL;
  vsstop:CARDINAL;
  vbstrt:CARDINAL;
  vbstop:CARDINAL;
  sprhstrt:CARDINAL;
  sprhstop:CARDINAL;
  bplhstrt:CARDINAL;
  bplhstop:CARDINAL;
  hhposw:CARDINAL;
  hhposr:CARDINAL;
  beamcon0:BeamConFlagSet;
  hsstrt:CARDINAL;
  vsstrt:CARDINAL;
  hcenter:CARDINAL;
  diwhigh:CARDINAL;    (* 1e4 *)
  padf3:ARRAY[0..10] OF CARDINAL;
  fmode:CARDINAL;
 END;

VAR
 custom[0DFF000H]:Custom;
 ciaa[0BFE001H]:CIA;
 ciab[0BFD000H]:CIA;

END Hardware.
