! ###################################################################
! ###################################################################
! ###                                                             ###
! ###  IOMD system level block models                             ###
! ###                                                             ###
! ###   DAG - DMA address generator                               ###
! ###                                                             ###
! ###################################################################
! ###################################################################
! ###  Revision History:                                          ###
! ###   14/9/92: WHO : Started                                    ###
! ###   16/9/92: WHO : restructured                               ###
! ###   18/9/92: WHO : sort of working                            ###
! ###   21/9/92: WHO : added sndir                                ###
! ###   21/9/92: WHO : added vidlast to dagblks and removed in2c  ###
! ###   22/9/92  WHO   reset control regs, dmastart to ramctl     ###
! ###   29/9/92  WHO   mask off 2 lsbs of dsize during vid or cur ###
! ###   05/10/92 WHO   changed flybks to flybi                    ###
! ###   06/10/92 WHO   added dag_tc bus (io last bits)            ###
! ###   06/10/92 WHO   changed mux on vidlast                     ###
! ###   21/10/92 WHO   masked enables off when overrun            ###
! ###   30/10/92 WHO   tc only set if stop set and extra en masks ###
! ###   19/11/92 WHO   prog gated into async clear of state machine##
! ###   24/11/92 WHO   prog removed, needed /dmagoing in sel_*    ###
! ###   25/11/92 WHO   mask write-back of low vid bits for non-1 inc#
! ###   25/11/92 WHO   mask write-back of fixed 8-bits in vidcur  ###
! ###   21/12/92 WHO   add dmastart to DAGCONC and DAGNOEC        ###
! ###                  change rclk to dmastart in DAGSBC          ###
! ###   23/12/92 WHO   made dwrite=0 when not active              ###
! ###    1/2/93  WHO   removed rclk                               ###
! ###   16/2/93  WHO   made changes for IOMDplus                  ###
! ###   17/2/93  WHO   rotated vram video registers down to 0     ###
! ###                  made dram screen size to 16Mbyte           ###
! ###   26/2/93  WHO   added 0's in bits 7 and 6 of irq regs      ###
! ###    8/3/93  WHO   changed psition of video write back masking###
! ###                  to fix bug when last but one from end of   ###
! ###                  screen.                                    ###
! ###   17/3/93  WHO   added dout bus so that bus repeating in    ###
! ###                  vectors matches netlist                    ###
! ###################################################################

FROM StdParts.Misc         IMPORT  $SLatch,$BLatch,$Sink,$SDTFF,$BCompare,$SMux,$BMux
FROM StdParts.Gates        IMPORT  $SGate1,$SGate2,$SGate3,$SGate4,$SGate8,$BGate1,$BGate2
FROM StdParts.TriDrive     IMPORT  $BBuff,$SBuff

FROM iomd.dagblks      IMPORT $DAGBSMC,$DAGCONC,$DAGSELC,$DAGNOEC,$DAGSTC,$DAGINCC,$DAGSBC

BLOCK TBDLO({OUT} s)
  tbdlo = $SGate1(Vss) => s WITH (delay=1, OP=BUFF)
END {TBDLO}

BLOCK SNK({IN} s)
  sink = $Sink(z(s, s))
END {SNK}

BLOCK BCLAT(g,clr,Noe,d)=>qz   { clearable transparent latch }
  in2 = $SGate1(clr) => Nclr WITH (delay=ns_1,OP=INV)
  ff  = $SDTFF(g,d,Vdd,Nclr) => (q,Nq) WITH (delay=ns_2)
  buf = $SBuff(q,Noe) => qz  WITH (delay=ns_1)
  sn  = SNK(Nq)
END {BCLAT}

BLOCK BCLAT5(g,clr,Noe,in[4:0])=>qz[4:0]   { clearable transparent latch (5-wide) }
  in2 = $SGate1(clr) => Nclr WITH (delay=ns_1,OP=INV)
  ff1 = $SDTFF(g,in[0],Vdd,Nclr) => (q[0],Nq[0]) WITH (delay=ns_2)
  ff2 = $SDTFF(g,in[1],Vdd,Nclr) => (q[1],Nq[1]) WITH (delay=ns_2)
  ff3 = $SDTFF(g,in[2],Vdd,Nclr) => (q[2],Nq[2]) WITH (delay=ns_2)
  ff4 = $SDTFF(g,in[3],Vdd,Nclr) => (q[3],Nq[3]) WITH (delay=ns_2)
  ff5 = $SDTFF(g,in[4],Vdd,Nclr) => (q[4],Nq[4]) WITH (delay=ns_2)
  sn  = $Sink(z(Nq[0],Nq[1],Nq[2],Nq[3],Nq[4]))
  buf = $BBuff(q[4:0],Noe) => qz[4:0] WITH (delay=ns_5)
END {BCLAT5}

BLOCK BCLAT6(g,clr,Noe,in[5:0])=>qz[5:0]   { clearable transparent latch (6-wide) }
  in2 = $SGate1(clr) => Nclr WITH (delay=ns_1,OP=INV)
  ff1 = $SDTFF(g,in[0],Vdd,Nclr) => (q[0],Nq[0]) WITH (delay=ns_2)
  ff2 = $SDTFF(g,in[1],Vdd,Nclr) => (q[1],Nq[1]) WITH (delay=ns_2)
  ff3 = $SDTFF(g,in[2],Vdd,Nclr) => (q[2],Nq[2]) WITH (delay=ns_2)
  ff4 = $SDTFF(g,in[3],Vdd,Nclr) => (q[3],Nq[3]) WITH (delay=ns_2)
  ff5 = $SDTFF(g,in[4],Vdd,Nclr) => (q[4],Nq[4]) WITH (delay=ns_2)
  ff6 = $SDTFF(g,in[5],Vdd,Nclr) => (q[5],Nq[5]) WITH (delay=ns_2)
  sn  = $Sink(z(Nq[0],Nq[1],Nq[2],Nq[3],Nq[4],Nq[5]))
  buf = $BBuff(q[5:0],Noe) => qz[5:0] WITH (delay=ns_5)
END {BCLAT6}

! ###############################################################
! IOMD DAG - DMA address generator
! ###############################################################

BLOCK DAG(
  {IN}  dmastart,    ! this is nor made in ramctl to save clk32 coming here
  {IN}  la[7:2],     ! from ADEC
  {IN}  reset,       ! from IOINT
  {IN}  lwrite,      ! from PROGCTL
  {IN}  prog,        ! from ADEC
  {IN}  dagreg,      ! from VCTL
  {IN}  flybi,       ! from VCTL
  {IN}  vncs,        ! from VCTL
  {IN}  dmagoing,    ! from BUSCTL
  {IN}  dmach[2:0],  ! from BUSCTL
  {IN}  ioch[1:0],   ! from IOCTL
  {IN}  ramdmaend,   ! from RAMCTL
  {OUT} da[28:0],    ! to AMUX and RAMCTL
  {OUT} dsize[1:0],  ! to RAMCTL
  {OUT} dwrite,      ! to RAMCTL
  {OUT} dagint,      ! to IOINT
  {OUT} xsnden[1:0], ! to SOUND
  {OUT} sndir[1:0],  ! to SOUND
  {OUT} vsnden,      ! to BUSCTL
  {OUT} viden,       ! to VCTL
  {OUT} xioden[3:0], ! to IOCTL
  {OUT} iodir[3:0],  ! to IOCTL
  {OUT} dag_tc[3:0], ! to IOCTL
  {OUT} vrm,         ! to VCTL
  {BID} data[31:0]   ! system bus
)

vrm = $SGate1(dmode) => vrm WITH (delay=ns_1,OP=INV)

! mask the exported enable bus with the individual overrun bits

in0  = $SGate1(ov_i0)                     => Nov_i0    WITH (delay=ns_1,OP=INV)
enm0 = $SGate3(ioden[0],Nov_i0,Nlastd_i0) => xioden[0] WITH (delay=ns_1,OP=AND)
in1  = $SGate1(ov_i1)                     => Nov_i1    WITH (delay=ns_1,OP=INV)
enm1 = $SGate3(ioden[1],Nov_i1,Nlastd_i1) => xioden[1] WITH (delay=ns_1,OP=AND)
in2  = $SGate1(ov_i2)                     => Nov_i2    WITH (delay=ns_1,OP=INV)
enm2 = $SGate3(ioden[2],Nov_i2,Nlastd_i2) => xioden[2] WITH (delay=ns_1,OP=AND)
in3  = $SGate1(ov_i3)                     => Nov_i3    WITH (delay=ns_1,OP=INV)
enm3 = $SGate3(ioden[3],Nov_i3,Nlastd_i3) => xioden[3] WITH (delay=ns_1,OP=AND)

! generate a vidc sound enable signal for BUSCTL

in4  = $SGate1(ov_s0)            => Nov_s0  WITH (delay=ns_1,OP=INV)
in15 = $SGate1(sndir[0])         => Nsndir0 WITH (delay=ns_1,OP=INV)
an15 = $SGate3(snden[0],Nsndir0  ,Nov_s0) => vsnden  WITH (delay=ns_2,OP=AND)
enm4 = $SGate3(snden[0], sndir[0],Nov_s0) => xsnden[0] WITH (delay=ns_1,OP=AND)

in5  = $SGate1(ov_s1)            => Nov_s1    WITH (delay=ns_1,OP=INV)
enm5 = $SGate2(snden[1],Nov_s1)  => xsnden[1] WITH (delay=ns_1,OP=AND)

! must mask the bottom two bits of dsize during video dma so as not to cause byte writes
! - only in vram dma now

an10 = $SGate2(contr[0],Nvdma) => dsize[0] WITH (delay=ns_2,OP=AND)
an11 = $SGate2(contr[1],Nvdma) => dsize[1] WITH (delay=ns_2,OP=AND)

! There are six state machines for the four io and two sound channels. They are clocked at the end of every
! dma cycle or when a register is programmed. The state machines control which buffer from the a/b pair are
! to be used.

or1 = $SGate2(prog,ramdmaend) => sm_clk WITH (delay=ns_2,OP=NOR)  ! clk is backedge of prog or ramdmaend

st_i0 = $DAGBSMC(sm_clk,reset,sel_c_i0,data[7],sel_e_i0a,sel_e_i0b,dma_go_i0,
         last_i0a,last_i0b,stop_i0a,stop_i0b,ioden[0]) => (state_i0(ov_i0,
         int_i0,bna_i0))
         WITH (delay=(rd_del=ns_1,wr_del=ns_2,dr_del=ns_2,st_del=ns_2,oe_del=ns_3))

st_i1 = $DAGBSMC(sm_clk,reset,sel_c_i1,data[7],sel_e_i1a,sel_e_i1b,dma_go_i1,
         last_i1a,last_i1b,stop_i1a,stop_i1b,ioden[1]) => (state_i1(ov_i1,
         int_i1,bna_i1))
         WITH (delay=(rd_del=ns_1,wr_del=ns_2,dr_del=ns_2,st_del=ns_2,oe_del=ns_3))

st_i2 = $DAGBSMC(sm_clk,reset,sel_c_i2,data[7],sel_e_i2a,sel_e_i2b,dma_go_i2,
         last_i2a,last_i2b,stop_i2a,stop_i2b,ioden[2]) => (state_i2(ov_i2,
         int_i2,bna_i2))
         WITH (delay=(rd_del=ns_1,wr_del=ns_2,dr_del=ns_2,st_del=ns_2,oe_del=ns_3))

st_i3 = $DAGBSMC(sm_clk,reset,sel_c_i3,data[7],sel_e_i3a,sel_e_i3b,dma_go_i3,
         last_i3a,last_i3b,stop_i3a,stop_i3b,ioden[3]) => (state_i3(ov_i3,
         int_i3,bna_i3))
         WITH (delay=(rd_del=ns_1,wr_del=ns_2,dr_del=ns_2,st_del=ns_2,oe_del=ns_3))

st_s0 = $DAGBSMC(sm_clk,reset,sel_c_s0,data[7],sel_e_s0a,sel_e_s0b,dma_go_s0,
         last_s0a,last_s0b,stop_s0a,stop_s0b,snden[0]) => (state_s0(ov_s0,
         int_s0,bna_s0))
         WITH (delay=(rd_del=ns_1,wr_del=ns_2,dr_del=ns_2,st_del=ns_2,oe_del=ns_3))

st_s1 = $DAGBSMC(sm_clk,reset,sel_c_s1,data[7],sel_e_s1a,sel_e_s1b,dma_go_s1,
         last_s1a,last_s1b,stop_s1a,stop_s1b,snden[1]) => (state_s1(ov_s1,
         int_s1,bna_s1))
         WITH (delay=(rd_del=ns_1,wr_del=ns_2,dr_del=ns_2,st_del=ns_2,oe_del=ns_3))

! each state machine has a 3 bit status register

r05  = $BBuff(sta_i0(ov_i0,int_i0,bna_i0),Noe_i0s) => dout[2:0] WITH (delay=ns_3)  ! status read buffer
r0D  = $BBuff(sta_i1(ov_i1,int_i1,bna_i1),Noe_i1s) => dout[2:0] WITH (delay=ns_3)  ! status read buffer
r15  = $BBuff(sta_i2(ov_i2,int_i2,bna_i2),Noe_i2s) => dout[2:0] WITH (delay=ns_3)  ! status read buffer
r1D  = $BBuff(sta_i3(ov_i3,int_i3,bna_i3),Noe_i3s) => dout[2:0] WITH (delay=ns_3)  ! status read buffer
r25  = $BBuff(sta_s0(ov_s0,int_s0,bna_s0),Noe_s0s) => dout[2:0] WITH (delay=ns_3)  ! status read buffer
r2D  = $BBuff(sta_s1(ov_s1,int_s1,bna_s1),Noe_s1s) => dout[2:0] WITH (delay=ns_3)  ! status read buffer

! modify the cursor channel to video if in new mode. (dmach==6 => newch=4)

new3 = $SGate1(dmach[0])                    => Ndmach0  WITH (delay=ns_1,OP=INV)
new4 = $SGate4(vncs,dmode,Ndmach0,dmach[2]) => Nc2v     WITH (delay=ns_1,OP=NAND)
new5 = $SGate1(dmach[2])                    => newch[2] WITH (delay=ns_2,OP=BUFF)
newB = $SGate1(dmach[1])                    => dmach1   WITH (delay=ns_1,OP=BUFF)
new6 = $SGate2(dmach1,Nc2v)                 => newch[1] WITH (delay=ns_1,OP=AND)
new7 = $SGate1(dmach[0])                    => newch[0] WITH (delay=ns_2,OP=BUFF)

! the following blocks generate the control signals for all the registers * see "Static logic" section
! for generation of the DAGCONC, DAGSELC, DAGNOEC, DAGSTC and DAGSBC output signals.

control = $DAGCONC(prog,dmagoing,lwrite,flybi,vidlast,dagreg,bna_i0,
           bna_i1,bna_i2,bna_i3,bna_s0,bna_s1,la[7:2],newch[2:0],lioch[1:0],dmastart)=>
          (Nwr_c,Nrd_c,Ndr_w2c,Nrd_in,Nrd_co,Nrd_e,
           dma_go_i0,dma_go_i1,dma_go_i2,dma_go_i3,dma_go_s0,dma_go_s1,dma_go_vid)
           WITH (delay=(rd_del=ns_5,oe_del=ns_5,wr_del=ns_5,dr_del=ns_5))

select = $DAGSELC(dmagoing,lwrite,dagreg,la[7:2]) => (sel_c_i0,sel_e_i0a,sel_e_i0b,
          sel_c_i1,sel_e_i1a,sel_e_i1b,sel_c_i2,sel_e_i2a,sel_e_i2b,
          sel_c_i3,sel_e_i3a,sel_e_i3b,sel_c_s0,sel_e_s0a,sel_e_s0b,
          sel_c_s1,sel_e_s1a,sel_e_s1b)
          WITH (delay=(oe_del=ns_5))

outenab = $DAGNOEC(prog,dmagoing,lwrite,flybi,vidlast,dagreg,bna_i0,
          bna_i1,bna_i2,bna_i3,bna_s0,bna_s1,vncs,la[7:2],newch[2:0],lioch[1:0],dmastart) =>
         (Noe_i0ca,Noe_i0ea,Noe_i0cb,Noe_i0eb,Noe_i0co,Noe_i0s,Noe_i1ca,
          Noe_i1ea,Noe_i1cb,Noe_i1eb,Noe_i1co,Noe_i1s,Noe_i2ca,Noe_i2ea,
          Noe_i2cb,Noe_i2eb,Noe_i2co,Noe_i2s,Noe_i3ca,Noe_i3ea,Noe_i3cb,
          Noe_i3eb,Noe_i3co,Noe_i3s,Noe_s0ca,Noe_s0ea,Noe_s0cb,Noe_s0eb,
          Noe_s0co,Noe_s0s,Noe_s1ca,Noe_s1ea,Noe_s1cb,Noe_s1eb,Noe_s1co,
          Noe_s1s,Noe_cc,Noe_cin,Noe_vc,Noe_ve,oe_ve,Noe_vst,Noe_vin,
          Noe_vco,Noe_cco,Noe_msk,Noe_sta,Noe_req,Nnone)
          WITH (delay=(oe_del=ns_5))

strobes = $DAGSTC(prog,dmagoing,ramdmaend,lwrite,flybi,vidlast,dagreg,
           bna_i0,bna_i1,bna_i2,bna_i3,bna_s0,bna_s1,vncs,dmastart,la[7:2],newch[2:0],
           lioch[1:0]) => (st_i0ea,st_i0eb,st_i0co,
           st_i1ea,st_i1eb,st_i1co,st_i2ea,st_i2eb,
           st_i2co,st_i3ea,st_i3eb,st_i3co,st_s0ea,
           st_s0eb,st_s0co,st_s1ea,st_s1eb,st_s1co,
           st_cin,st_ve,st_vst,st_vin,st_vco,st_msk)
           WITH (delay=(st_del=ns_5))

wb_stobes = $DAGSBC(prog,dmagoing,ramdmaend,lwrite,flybi,vidlast,dagreg,bna_i0,
             bna_i1,bna_i2,bna_i3,bna_s0,bna_s1,vncs,dmastart,la[7:2],newch[2:0],
             lioch[1:0])=>(sb_i0ca,sb_i0cb,sb_i1ca,
             sb_i1cb,sb_i2ca,sb_i2cb,sb_i3ca,sb_i3cb,sb_s0ca,sb_s0cb,sb_s1ca,
             sb_s1cb,sb_cc,sb_vc,sd_vc,ck_i0a,ck_i0b,ck_i1a,ck_i1b,ck_i2a,
             ck_i2b,ck_i3a,ck_i3b,ck_s0a,ck_s0b,ck_s1a,ck_s1b) WITH (delay=(st_del=ns_5))

! current registers

r00 = $BLatch(sb_i0ca,Noe_i0ca,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 0 A
r02 = $BLatch(sb_i0cb,Noe_i0cb,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 0 B
r08 = $BLatch(sb_i1ca,Noe_i1ca,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 1 A
r0A = $BLatch(sb_i1cb,Noe_i1cb,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 1 B
r10 = $BLatch(sb_i2ca,Noe_i2ca,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 2 A
r12 = $BLatch(sb_i2cb,Noe_i2cb,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 2 B
r18 = $BLatch(sb_i3ca,Noe_i3ca,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 3 A
r1A = $BLatch(sb_i3cb,Noe_i3cb,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! io 3 B
r20 = $BLatch(sb_s0ca,Noe_s0ca,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! snd 0 A
r22 = $BLatch(sb_s0cb,Noe_s0cb,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! snd 0 B
r28 = $BLatch(sb_s1ca,Noe_s1ca,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! snd 1 A
r2A = $BLatch(sb_s1cb,Noe_s1cb,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! snd 1 B
r30 = $BLatch(sb_cc  ,  Noe_cc,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! cursor
r34 = $BLatch(sb_vc  ,  Noe_vc,curin[28:0])  =>     dac[28:0] WITH (delay=ns_5) ! video

! init/start registers

r31  = $BLatch(st_cin,Noe_cin,data[28:0]) =>  curin[28:0] WITH (delay=ns_5)  ! cursor init reg
r36  = $BLatch(st_vst,Noe_vst,data[28:0]) =>  curin[28:0] WITH (delay=ns_5)  ! video start reg
r37a = $BLatch(st_vin,Noe_vin,data[28:0]) =>  curin[28:0] WITH (delay=ns_5)  ! video init reg
r37b = $SLatch(st_vin,        data[30]  ) =>  last_v      WITH (delay=ns_5)

! end registers

r01a = $BLatch(st_i0ea,Noe_i0ea, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 0 A
r01d = $SBuff(last_i0a,Noe_i0ea            ) => lastbus      WITH (delay=ns_5)
r01e = $SBuff(stop_i0a,Noe_i0ea            ) => stopbus      WITH (delay=ns_5)
r03a = $BLatch(st_i0eb,Noe_i0eb, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 0 B
r03d = $SBuff(last_i0b,Noe_i0eb            ) => lastbus      WITH (delay=ns_5)
r03e = $SBuff(stop_i0b,Noe_i0eb            ) => stopbus      WITH (delay=ns_5)
r09a = $BLatch(st_i1ea,Noe_i1ea, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 1 A
r09d = $SBuff(last_i1a,Noe_i1ea            ) => lastbus      WITH (delay=ns_5)
r09e = $SBuff(stop_i1a,Noe_i1ea            ) => stopbus      WITH (delay=ns_5)
r0Ba = $BLatch(st_i1eb,Noe_i1eb, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 1 B
r0Bd = $SBuff(last_i1b,Noe_i1eb            ) => lastbus      WITH (delay=ns_5)
r0Be = $SBuff(stop_i1b,Noe_i1eb            ) => stopbus      WITH (delay=ns_5)
r11a = $BLatch(st_i2ea,Noe_i2ea, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 2 A
r11d = $SBuff(last_i2a,Noe_i2ea            ) => lastbus      WITH (delay=ns_5)
r11e = $SBuff(stop_i2a,Noe_i2ea            ) => stopbus      WITH (delay=ns_5)
r13a = $BLatch(st_i2eb,Noe_i2eb, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 2 B
r13d = $SBuff(last_i2b,Noe_i2eb            ) => lastbus      WITH (delay=ns_5)
r13e = $SBuff(stop_i2b,Noe_i2eb            ) => stopbus      WITH (delay=ns_5)
r19a = $BLatch(st_i3ea,Noe_i3ea, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 3 A
r19d = $SBuff(last_i3a,Noe_i3ea            ) => lastbus      WITH (delay=ns_5)
r19e = $SBuff(stop_i3a,Noe_i3ea            ) => stopbus      WITH (delay=ns_5)
r1Ba = $BLatch(st_i3eb,Noe_i3eb, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! io 3 B
r1Bd = $SBuff(last_i3b,Noe_i3eb            ) => lastbus      WITH (delay=ns_5)
r1Be = $SBuff(stop_i3b,Noe_i3eb            ) => stopbus      WITH (delay=ns_5)
r21a = $BLatch(st_s0ea,Noe_s0ea, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! snd 0 A
r21d = $SBuff(last_s0a,Noe_s0ea            ) => lastbus      WITH (delay=ns_5)
r21e = $SBuff(stop_s0a,Noe_s0ea            ) => stopbus      WITH (delay=ns_5)
r23a = $BLatch(st_s0eb,Noe_s0eb, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! snd 0 B
r23d = $SBuff(last_s0b,Noe_s0eb            ) => lastbus      WITH (delay=ns_5)
r23e = $SBuff(stop_s0b,Noe_s0eb            ) => stopbus      WITH (delay=ns_5)
r29a = $BLatch(st_s1ea,Noe_s1ea, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! snd 1 A
r29d = $SBuff(last_s1a,Noe_s1ea            ) => lastbus      WITH (delay=ns_5)
r29e = $SBuff(stop_s1a,Noe_s1ea            ) => stopbus      WITH (delay=ns_5)
r2Ba = $BLatch(st_s1eb,Noe_s1eb, data[11:0]) => endbus[11:0] WITH (delay=ns_5)   ! snd 1 B
r2Bd = $SBuff(last_s1b,Noe_s1eb            ) => lastbus      WITH (delay=ns_5)
r2Be = $SBuff(stop_s1b,Noe_s1eb            ) => stopbus      WITH (delay=ns_5)
r35a = $SBuff(Vss     ,Noe_ve              ) => lastbus      WITH (delay=ns_5)
r35b = $SBuff(Vss     ,Noe_ve              ) => stopbus      WITH (delay=ns_5)
r35c = $BLatch(st_ve  ,Noe_ve ,  data[23:0]) => endbus[23:0] WITH (delay=ns_5)   ! video

ueq  = $BBuff(mwbus[23:12],oe_ve) => endbus[23:12] WITH (delay=ns_5)    ! essential for 11-bit compares

! the control bits (dsize, dir and enable)

r04a = BCLAT5(st_i0co,reset,Noe_i0co,data[4:0])    => contr[4:0]
r04e = $BBuff(costi0(iodir[0],ioden[0]),Noe_i0co)  => contr[6:5] WITH (delay=ns_3)
r04f = $SBuff(Vss,Noe_i0co)                        => contr[7]   WITH (delay=ns_3)
r0Ca = BCLAT5(st_i1co,reset,Noe_i1co,data[4:0])    => contr[4:0]
r0Ce = $BBuff(costi1(iodir[1],ioden[1]),Noe_i1co)  => contr[6:5] WITH (delay=ns_3)
r0Cf = $SBuff(Vss,Noe_i1co)                        => contr[7]   WITH (delay=ns_3)
r14a = BCLAT5(st_i2co,reset,Noe_i2co,data[4:0])    => contr[4:0]
r14e = $BBuff(costi2(iodir[2],ioden[2]),Noe_i2co)  => contr[6:5] WITH (delay=ns_3)
r14f = $SBuff(Vss,Noe_i2co)                        => contr[7]   WITH (delay=ns_3)
r1Ca = BCLAT5(st_i3co,reset,Noe_i3co,data[4:0])    => contr[4:0]
r1Ce = $BBuff(costi3(iodir[3],ioden[3]),Noe_i3co)  => contr[6:5] WITH (delay=ns_3)
r1Cf = $SBuff(Vss,Noe_i3co)                        => contr[7]   WITH (delay=ns_3)
r24a = BCLAT5(st_s0co,reset,Noe_s0co,data[4:0])    => contr[4:0]
r24e = $BBuff(costs0(sndir[0],snden[0]),Noe_s0co)  => contr[6:5] WITH (delay=ns_3)
r24f = $SBuff(Vss,Noe_s0co)                        => contr[7]   WITH (delay=ns_3)
r2Ca = BCLAT5(st_s1co,reset,Noe_s1co,data[4:0])    => contr[4:0]
r2Ce = $BBuff(costs1(sndir[1],snden[1]),Noe_s1co)  => contr[6:5] WITH (delay=ns_3)
r2Cf = $SBuff(Vss,Noe_s1co)                        => contr[7]   WITH (delay=ns_3)
r32a = $BBuff(curinc(Vdd,Vss,Vss,Vss,Vss),Noe_cco) => contr[4:0] WITH (delay=ns_5)
r32b = $BBuff(curcon(Vss,Vss,Vss),Noe_cco)         => contr[7:5] WITH (delay=ns_3)
r38a = BCLAT5(st_vco,reset,Noe_vco,data[4:0])      => contr[4:0]
r38b = BCLAT(st_vco ,reset,Vss,data[5])            => viden
r38c = $SBuff(viden, Noe_vco)                      => contr[5] WITH (delay=ns_3)
r38d = BCLAT(st_vco ,reset,Vss,data[6])            => dmode
r38e = $SBuff(dmode, Noe_vco)                      => contr[6] WITH (delay=ns_3)
r38f = $SBuff(Vss  , Noe_vco)                      => contr[7] WITH (delay=ns_3)

r04b = BCLAT(st_i0co,reset,Vss,data[5])      => ioden[0]   ! Note that these bits are always on
r0Cb = BCLAT(st_i1co,reset,Vss,data[5])      => ioden[1]
r14b = BCLAT(st_i2co,reset,Vss,data[5])      => ioden[2]
r1Cb = BCLAT(st_i3co,reset,Vss,data[5])      => ioden[3]
r24b = BCLAT(st_s0co,reset,Vss,data[5])      => snden[0]
r2Cb = BCLAT(st_s1co,reset,Vss,data[5])      => snden[1]
r04c = BCLAT(st_i0co,reset,Vss,data[6])      => iodir[0]
r0Cc = BCLAT(st_i1co,reset,Vss,data[6])      => iodir[1]
r14c = BCLAT(st_i2co,reset,Vss,data[6])      => iodir[2]
r1Cc = BCLAT(st_i3co,reset,Vss,data[6])      => iodir[3]
r24c = BCLAT(st_s0co,reset,Vss,data[6])      => sndir[0]
r2Cc = BCLAT(st_s1co,reset,Vss,data[6])      => sndir[1]

! muxed direction bit for ramctl

r04d = $SBuff(iodir[0],Noe_i0co            ) => dwrite      WITH (delay=ns_5)
r0Cd = $SBuff(iodir[1],Noe_i1co            ) => dwrite      WITH (delay=ns_5)
r14d = $SBuff(iodir[2],Noe_i2co            ) => dwrite      WITH (delay=ns_5)
r1Cd = $SBuff(iodir[3],Noe_i3co            ) => dwrite      WITH (delay=ns_5)
r24d = $SBuff(sndir[0],Noe_s0co            ) => dwrite      WITH (delay=ns_5)
r2Cd = $SBuff(sndir[1],Noe_s1co            ) => dwrite      WITH (delay=ns_5)
r38g = $SBuff(  Vss  ,Nnone                ) => dwrite      WITH (delay=ns_5)

!-------------------------- make the terminal count bus ------------------------

sa0 = $SGate2(last_i0a,stop_i0a) => tc_i0a WITH (delay=ns_2,OP=AND)
sb0 = $SGate2(last_i0b,stop_i0b) => tc_i0b WITH (delay=ns_2,OP=AND)
sa1 = $SGate2(last_i1a,stop_i1a) => tc_i1a WITH (delay=ns_2,OP=AND)
sb1 = $SGate2(last_i1b,stop_i1b) => tc_i1b WITH (delay=ns_2,OP=AND)
sa2 = $SGate2(last_i2a,stop_i2a) => tc_i2a WITH (delay=ns_2,OP=AND)
sb2 = $SGate2(last_i2b,stop_i2b) => tc_i2b WITH (delay=ns_2,OP=AND)
sa3 = $SGate2(last_i3a,stop_i3a) => tc_i3a WITH (delay=ns_2,OP=AND)
sb3 = $SGate2(last_i3b,stop_i3b) => tc_i3b WITH (delay=ns_2,OP=AND)

mxi3 = $SMux(bna_i3,tc_i3a,tc_i3b) => dag_tc[3] WITH (delay=ns_4)
mxi2 = $SMux(bna_i2,tc_i2a,tc_i2b) => dag_tc[2] WITH (delay=ns_4)
mxi1 = $SMux(bna_i1,tc_i1a,tc_i1b) => dag_tc[1] WITH (delay=ns_4)
mxi0 = $SMux(bna_i0,tc_i0a,tc_i0b) => dag_tc[0] WITH (delay=ns_4)

!--------------------------- make the extra enable masks -----------------------

mex3 = $SMux(bna_i3,last_i3a,last_i3b) => last_i3 WITH (delay=ns_4)
mex2 = $SMux(bna_i2,last_i2a,last_i2b) => last_i2 WITH (delay=ns_4)
mex1 = $SMux(bna_i1,last_i1a,last_i1b) => last_i1 WITH (delay=ns_4)
mex0 = $SMux(bna_i0,last_i0a,last_i0b) => last_i0 WITH (delay=ns_4)

ld3  = $SGate2(last_i3,dma_go_i3) => Nlastd_i3 WITH (delay=ns_2,OP=NAND)
ld2  = $SGate2(last_i2,dma_go_i2) => Nlastd_i2 WITH (delay=ns_2,OP=NAND)
ld1  = $SGate2(last_i1,dma_go_i1) => Nlastd_i1 WITH (delay=ns_2,OP=NAND)
ld0  = $SGate2(last_i0,dma_go_i0) => Nlastd_i0 WITH (delay=ns_2,OP=NAND)

!---------------------------- io channel 0 -------------------------------------

r01b = $SDTFF(ck_i0a,mux_de ,Vdd,Vdd)  => (last_i0a,Nli0a) WITH (delay=ns_5) ! last A reg bit
r01c = $SLatch(st_i0ea,   data[31]  )  => stop_i0a    WITH (delay=ns_5)      ! stop A reg bit
r03b = $SDTFF(ck_i0b,mux_de ,Vdd,Vdd)  => (last_i0b,Nli0b) WITH (delay=ns_5) ! last B reg bit
r03c = $SLatch(st_i0eb,   data[31]  )  => stop_i0b    WITH (delay=ns_5)      ! stop B reg bit

!---------------------------- io channel 1 -------------------------------------

r09b = $SDTFF(ck_i1a,mux_de ,Vdd,Vdd)  => (last_i1a,Nli1a) WITH (delay=ns_5) ! last A reg bit
r09c = $SLatch(st_i1ea,   data[31]  )  => stop_i1a    WITH (delay=ns_5)      ! stop A reg bit
r0Bb = $SDTFF(ck_i1b,mux_de ,Vdd,Vdd)  => (last_i1b,Nli1b) WITH (delay=ns_5) ! last B reg bit
r0Bc = $SLatch(st_i1eb,   data[31]  )  => stop_i1b    WITH (delay=ns_5)      ! stop B reg bit

!---------------------------- io channel 2 -------------------------------------

r11b = $SDTFF(ck_i2a,mux_de ,Vdd,Vdd)  => (last_i2a,Nli2a) WITH (delay=ns_5) ! last A reg bit
r11c = $SLatch(st_i2ea,   data[31]  )  => stop_i2a    WITH (delay=ns_5)      ! stop A reg bit
r13b = $SDTFF(ck_i2b,mux_de ,Vdd,Vdd)  => (last_i2b,Nli2b) WITH (delay=ns_5) ! last B reg bit
r13c = $SLatch(st_i2eb,   data[31]  )  => stop_i2b    WITH (delay=ns_5)      ! stop B reg bit

!---------------------------- io channel 3 -------------------------------------

r19b = $SDTFF(ck_i3a,mux_de ,Vdd,Vdd)  => (last_i3a,Nli3a) WITH (delay=ns_5) ! last A reg bit
r19c = $SLatch(st_i3ea,   data[31]  )  => stop_i3a    WITH (delay=ns_5)      ! stop A reg bit
r1Bb = $SDTFF(ck_i3b,mux_de ,Vdd,Vdd)  => (last_i3b,Nli3b) WITH (delay=ns_5) ! last B reg bit
r1Bc = $SLatch(st_i3eb,   data[31]  )  => stop_i3b    WITH (delay=ns_5)      ! stop B reg bit

!---------------------------- sound channel 0 ----------------------------------

r21b = $SDTFF(ck_s0a,mux_de ,Vdd,Vdd)  => (last_s0a,Nls0a) WITH (delay=ns_5) ! last A reg bit
r21c = $SLatch(st_s0ea,   data[31]  )  => stop_s0a    WITH (delay=ns_5)      ! stop A reg bit
r23b = $SDTFF(ck_s0b,mux_de ,Vdd,Vdd)  => (last_s0b,Nls0b) WITH (delay=ns_5) ! last B reg bit
r23c = $SLatch(st_s0eb,   data[31]  )  => stop_s0b    WITH (delay=ns_5)      ! stop B reg bit

!---------------------------- sound channel 1 ----------------------------------

r29b = $SDTFF(ck_s1a,mux_de ,Vdd,Vdd)  => (last_s1a,Nls1a) WITH (delay=ns_5) ! last A reg bit
r29c = $SLatch(st_s1ea,   data[31]  )  => stop_s1a    WITH (delay=ns_5)      ! stop A reg bit
r2Bb = $SDTFF(ck_s1b,mux_de ,Vdd,Vdd)  => (last_s1b,Nls1b) WITH (delay=ns_5) ! last B reg bit
r2Bc = $SLatch(st_s1eb,   data[31]  )  => stop_s1b    WITH (delay=ns_5)      ! stop B reg bit

!---------------------------- video channel ------------------------------------

r35d = $SDTFF(sd_vc,mux_ve ,Vdd,Vdd)   => (vidlast,Nvidlast) WITH (delay=ns_5) ! vidlast reg bit
m02  = $SMux(dmagoing,last_v,equal)    => mux_ve WITH (delay=ns_2)

!-------------------- common to all io and sound channels ---------------------

m01 = $SMux(dmagoing,data[30],equal)   => mux_de WITH (delay=ns_2)  ! 2 sources for last. Note 3

! Note 3: The signal mux_de must hold over ck_xxx, and is a bit close at present.

!----------------------- the final output buffer ------------------------------

doutbuf = $BBuff(dout[31:0],Nrd_dag)       => data[31:0] WITH (delay=ns_4)
Nlwrite = $SGate1(lwrite)                  => Nlwrite    WITH (delay=ns_1,OP=INV)
Nrd_dag = $SGate4(dagreg,Nlwrite,prog,Vdd) => Nrd_dag    WITH (delay=ns_2,OP=NAND)

!---------------------------- routing buffers ---------------------------------

rdc = $BBuff(dac[28:0]   ,Nrd_c) =>  dout[28:0]  WITH (delay=ns_4) ! read current
rde1= $SBuff(stopbus     ,Nrd_e) =>  dout[31]    WITH (delay=ns_4)   ! read end
rde2= $SBuff(lastbus     ,Nrd_e) =>  dout[30]    WITH (delay=ns_4)   ! read end
rde = $BBuff(endbus[23:0],Nrd_e) =>  dout[23:0]  WITH (delay=ns_4)   ! read end
rdi1= $SBuff(Vss        ,Nrd_in) =>  dout[31]    WITH (delay=ns_4)   ! read init
rdi2= $SBuff(last_v     ,Nrd_in) =>  dout[30]    WITH (delay=ns_4)   ! read init
rdi3= $SBuff(equal      ,Nrd_in) =>  dout[29]    WITH (delay=ns_4)   ! read init (vid status)
rdi = $BBuff(curin[28:0],Nrd_in) =>  dout[28:0]  WITH (delay=ns_4)   ! read init (or vid status)
rdco= $BBuff(contr[7:0],Nrd_co)  =>  dout[7:0]   WITH (delay=ns_4)   ! read control

wrc = $BBuff(data[28:0],Nwr_c)    => curin[28:0]  WITH (delay=ns_5)   ! write current
w2ca= $BBuff(mwbus[23:0],Ndr_w2c) => curin[23:0]  WITH (delay=ns_5)   ! write back current
w2cb= $BBuff(dac[28:24],Ndr_w2c)  => curin[28:24] WITH (delay=ns_5)   ! write back current

!---------------------------- the incrementer ---------------------------------
! 5 bits of adder, then 3 bits of increment, then 5 more bits of add and finally
! 9 more bits of increment. The final carry can be optimised away.

new10= $SGate1(dmode)             => Ndmode WITH (delay=ns_1,OP=INV)
new8 = $SGate2(dma_go_vid,Ndmode) => Nvdma  WITH (delay=ns_2,OP=NAND)
new9 = $SGate2(dma_go_vid,Ndmode) =>  vdma  WITH (delay=ns_2,OP=AND)

admh = $BGate2(contr[4:0],b1(vdma,vdma,vdma,vdma,vdma)) => addh[4:0] WITH (delay=ns_2,OP=AND)
adml = $BGate2(contr[4:0],b2(Nvdma,Nvdma,Nvdma,Nvdma,Nvdma)) => addl[4:0] WITH (delay=ns_2,OP=AND)

inc = $DAGINCC(da[23:0],addh[4:0],addl[4:0]) => wbus[23:0] WITH (delay=ns_40)

!------------- latch la[15:0] at front of dmagoing ----------------------------

lat2  = $BLatch(dmastart,Vss,ioch[1:0])  => lioch[1:0]  WITH (delay=ns_5)
lat16 = $BLatch(dmastart,Vss,dac[28:0])  => da[28:0]  WITH (delay=ns_5)

!-------- the masking of the video pointer to half-sam port -------------------

msk23 = $SGate1(wbus[23])       => mwbus[23] WITH (delay=1,OP=BUFF)  ! do not implement
msk22 = $SGate1(wbus[22])       => mwbus[22] WITH (delay=1,OP=BUFF)  ! do not implement
msk21 = $SGate1(wbus[21])       => mwbus[21] WITH (delay=1,OP=BUFF)  ! do not implement
msk20 = $SGate1(wbus[20])       => mwbus[20] WITH (delay=1,OP=BUFF)  ! do not implement
msk19 = $SGate1(wbus[19])       => mwbus[19] WITH (delay=1,OP=BUFF)  ! do not implement
msk18 = $SGate1(wbus[18])       => mwbus[18] WITH (delay=1,OP=BUFF)  ! do not implement
msk17 = $SGate1(wbus[17])       => mwbus[17] WITH (delay=1,OP=BUFF)  ! do not implement
msk16 = $SGate1(wbus[16])       => mwbus[16] WITH (delay=1,OP=BUFF)  ! do not implement
msk15 = $SGate1(wbus[15])       => mwbus[15] WITH (delay=1,OP=BUFF)  ! do not implement
msk14 = $SGate1(wbus[14])       => mwbus[14] WITH (delay=1,OP=BUFF)  ! do not implement
msk13 = $SGate1(wbus[13])       => mwbus[13] WITH (delay=1,OP=BUFF)  ! do not implement
msk12 = $SGate2(wbus[12],mask4) => mwbus[12] WITH (delay=ns_1,OP=AND)
msk11 = $SGate2(wbus[11],mask3) => mwbus[11] WITH (delay=ns_1,OP=AND)
msk10 = $SGate2(wbus[10],mask2) => mwbus[10] WITH (delay=ns_1,OP=AND)
msk09 = $SGate2( wbus[9],mask1) =>  mwbus[9] WITH (delay=ns_1,OP=AND)
msk08 = $SGate2( wbus[8],mask0) =>  mwbus[8] WITH (delay=ns_1,OP=AND)
msk07 = $SGate2( wbus[7],Nvdma) =>  mwbus[7] WITH (delay=ns_1,OP=AND)
msk06 = $SGate2( wbus[6],Nvdma) =>  mwbus[6] WITH (delay=ns_1,OP=AND)
msk05 = $SGate2( wbus[5],Nvdma) =>  mwbus[5] WITH (delay=ns_1,OP=AND)
msk04 = $SGate2( wbus[4],Nvdma) =>  mwbus[4] WITH (delay=ns_1,OP=AND)
msk03 = $SGate2( wbus[3],Nvdma) =>  mwbus[3] WITH (delay=ns_1,OP=AND)
msk02 = $SGate2( wbus[2],Nvdma) =>  mwbus[2] WITH (delay=ns_1,OP=AND)
msk01 = $SGate2( wbus[1],Nvdma) =>  mwbus[1] WITH (delay=ns_1,OP=AND)
msk00 = $SGate2( wbus[0],Nvdma) =>  mwbus[0] WITH (delay=ns_1,OP=AND)

mor04 = $SGate2(contr[4],mask3) => mask4 WITH (delay=ns_1,OP=OR)
mor03 = $SGate2(contr[3],mask2) => mask3 WITH (delay=ns_1,OP=OR)
mor02 = $SGate2(contr[2],mask1) => mask2 WITH (delay=ns_1,OP=OR)
mor01 = $SGate2(contr[1],mask0) => mask1 WITH (delay=ns_1,OP=OR)
mor00 = $SGate2(contr[0],Nvdma) => mask0 WITH (delay=ns_1,OP=OR)

!---------------------------- the end test ------------------------------------
! if (endbus[23:0]==mwbus[23:0]) equal = 1 else equal =0

comp = $BCompare(endbus[23:0],mwbus[23:0]) => equal WITH (delay=ns_15,type=EQ)

s00 = $Sink(s0(Nli0a, Nli0b, Nli1a, Nli1b, Nli2a, Nli2b, Nli3a, Nli3b, Nls0a, Nls0b, Nls1a, Nls1b,
               Nvidlast))

!---------------------------- the interrupt stuff ------------------------------

imreg = BCLAT6(st_msk,reset,Vss,data[5:0])      => mask[5:0]             ! mask register
imbuf = $BBuff(irqm(Vss,Vss,mask[5],mask[4],mask[3],mask[2],mask[1],mask[0]),Noe_msk)
        =>  dout[7:0] WITH (delay=ns_5)     ! read mask reg

isbuf = $BBuff(irqs(Vss,Vss,int_s1,int_s0,int_i3,int_i2,int_i1,int_i0),Noe_sta)
        =>  dout[7:0] WITH (delay=ns_5)                                   ! read status bits

an0 = $SGate2(int_i0,mask[0]) => req[0] WITH (delay=ns_2,OP=AND)             ! mask the interrupt sources
an1 = $SGate2(int_i1,mask[1]) => req[1] WITH (delay=ns_2,OP=AND)
an2 = $SGate2(int_i2,mask[2]) => req[2] WITH (delay=ns_2,OP=AND)
an3 = $SGate2(int_i3,mask[3]) => req[3] WITH (delay=ns_2,OP=AND)
an4 = $SGate2(int_s0,mask[4]) => req[4] WITH (delay=ns_2,OP=AND)
an5 = $SGate2(int_s1,mask[5]) => req[5] WITH (delay=ns_2,OP=AND)

or2 = $SGate8(req[5],req[4],req[3],req[2],req[1],req[0],Vss,Vss) => dagint WITH (delay=ns_5,OP=OR)

irbuf = $BBuff(irqr(Vss,Vss,req[5],req[4],req[3],req[2],req[1],req[0]),Noe_req)
       =>  dout[7:0] WITH (delay=ns_5)     ! active req status reg

END {DAG}

