%include "inc:util.imp"
%begin
%option "-nons-low"
%recordformat f(%halfarray w(0:2*8-1) %or %byte dma %or-
  (%readonlyhalf current data %orwriteonlyhalf output data,*),
           %half initiator command,*,
                 mode,*,
                 target command,*,
  (%readonlyhalf current status %orwriteonlyhalf select enable,*),
  (%readonlyhalf bus and status %orwriteonlyhalf start dma send,*),
  (%readonlyhalf input data     %orwriteonlyhalf start target receive,*),
  (%readonlyhalf reset          %orwriteonlyhalf start initiator receive))

%constinteger-
ic rst  = 128,
ic test = 64,
ic aip  = 64,
ic lost = 32,
ic ack  = 16,
ic bsy  = 8,
ic sel  = 4,
ic atn  = 2,
ic data = 1

%constinteger-
mo block  = 128,
mo target = 64,
mo parchk = 32,
mo parint = 16,
mo eopint = 8,
mo monbsy = 4,
mo dma    = 2,
mo arb    = 1

%constinteger-
tc req = 8,
tc msg = 4,
tc cd  = 2,
tc io  = 1,
ph out = 0,
ph in  = 1,
ph cmd = 2,
ph sta = 3,
ph mso = 6,
ph msi = 7

%constinteger-
cs rst = 128,
cs bsy = 64,
cs req = 32,
cs msg = 16,
cs cd  = 8,
cs io  = 4,
cs sel = 2,
cs dbp = 1

%constinteger-
bs end = 128,
bs drq = 64,
bs par = 32,
bs irq = 16,
bs pha = 8,
bs bsy = 4,
bs atn = 2,
bs ack = 1

%routine show(%integer u,%record(f)%name c)
%half b

  %routine p(%string(7)s,%integer v)
  %integer i,k
    space
    %for i = 1,1,length(s) %cycle
      k = charno(s,i); k = k-32 %if k>='a' %and v#0
      printsymbol(k)
    %repeat
  %end

  %routine phase(%integer n)
  %ownstring(11)%array name(0:7) = "data out","data in",
    "command", "status", "illegal out","illegal in",
    "message out","message in"
    printstring(name(n&7))
  %end

  newline
  printstring("Unit "); printsymbol(u&1+'0')
  printstring(      " data:    "); phex2(c_current data>>8)
  %if c_current status>>8&csbsy#0 %start
    printstring(" expected phase: "); phase(c_target command>>8)
    printstring(", actual phase: "); phase(c_current status>>8>>2)
  %finish
  newline
  printstring("Init command:   "); b = c_initiator command>>8; phex2(b)
    p("rst",b&icrst)
    p("aip",b&icaip)
    p("lost",b&iclost)
    p("ack",b&icack)
    p("bsy",b&icbsy)
    p("sel",b&icsel)
    p("atn",b&icatn)
    p("data",b&icdata)
    newline
  printstring("Mode:           "); b = c_mode>>8; phex2(b)
    p("block",b&moblock)
    p("target",b&motarget)
    p("parchk",b&moparchk)
    p("parint",b&moparint)
    p("eopint",b&moeopint)
    p("monbsy",b&momonbsy)
    p("dma",b&modma)
    p("arb",b&moarb)
    newline
  printstring("Target command: "); b = c_target command>>8; phex2(b)
    p("req",b&tcreq)
    p("msg",b&tcmsg)
    p("cd",b&tccd)
    p("io",b&tcio)
    newline
  printstring("Current status: "); b = c_current status>>8; phex2(b)
    p("rst",b&csrst)
    p("bsy",b&csbsy)
    p("req",b&csreq)
    p("msg",b&csmsg)
    p("cd",b&cscd)
    p("io",b&csio)
    p("sel",b&cssel)
    p("dbp",b&csdbp)
    newline
  printstring("Bus and status: "); b = c_bus and status>>8; phex2(b)
    p("end",b&bsend)
    p("drq",b&bsdrq)
    p("par",b&bspar)
    p("irq",b&bsirq)
    p("pha",b&bspha)
    p("bsy",b&bsbsy)
    p("atn",b&bsatn)
    p("ack",b&bsack)
    newline
%end

%routine p(%string(255) s)
  printstring(s); newline
%end

@16_fd0000 %record(f)chip0
@16_fd0002 %record(f)chip1
%ownhalfarray last(0:11)=0(*)

%predicate changed
%integer d=0,i
%half b
  %for i = 0,1,5 %cycle
    b = chip0_w(i*2)
    d = d!(b!!last(i*2)); last(i*2) = b
  %repeat
  %for i = 0,1,5 %cycle
    b = chip1_w(i*2)
    d = d!(b!!last(i*2+1)); last(i*2+1) = b
  %repeat
  %trueif d>>8#0; %false
%end

%integer k
%record(f)%name chip
%halfname w

  %on 0 %start
    printstring("**"); phex(event_extra); newline
  %finish
  set terminalmode(nopage)
  p("e - exit")
  p("r - reset")
  p("s - show")
  p("an / bn / an=v / bn=v")
  p("c / d / c=v / d=v")
  %cycle
    k = testsymbol
    %exitif k='e'
    k = 's' %if k=nl %and changed
    %if k='r' %start
      byte(16_fc0001) = 0
    %elseif k='s'
      show(0,chip0); show(1,chip1)
    %elseif k='a' %or k='b'
      chip == chip0; chip == chip1 %if k='b'
      w == chip_w(rhex*2)
      k = nextsymbol
      %if k='=' %start
        readsymbol(k)
        w = rhex<<8
      %else
        phex2(w>>8)
      %finish
    %elseif k='c' %or k='d'
      chip == chip0; chip == chip1 %if k='d'
      k = nextsymbol
      %if k='=' %start
        readsymbol(k)
        chip_dma = rhex
      %else
        phex2(chip_dma)
      %finish
    %finish
  %repeat
%end
