%include "inc:util.imp"
%begin
%option "-nons-low"
%recordformat f(%bytearray b(0:4*8-1) %or-
  (%readonlybyte current data %orwriteonlybyte output data,*,*,*),
           %byte initiator command,*,*,*,
                 mode,*,*,*,
                 target command,*,*,*,
  (%readonlybyte current status %orwriteonlybyte select enable,*,*,*),
  (%readonlybyte bus and status %orwriteonlybyte start dma send,*,*,*),
  (%readonlybyte input data     %orwriteonlybyte start target receive,*,*,*),
  (%readonlybyte reset          %orwriteonlybyte 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)
%byte 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)
  %if c_current status&csbsy#0 %start
    printstring(" expected phase: "); phase(c_target command)
    printstring(", actual phase: "); phase(c_current status>>2)
  %finish
  newline
  printstring("Init command:   "); b = c_initiator command; 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; 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; 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; 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; 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
%ownbytearray last(0:11)=0(10),8,8

%predicate changed
%integer d=0,i
%byte b
  %for i = 0,1,5 %cycle
    b = chip0_b(i*4)
    d = d!(b!!last(i*2)); last(i*2) = b
  %repeat
  %for i = 0,1,5 %cycle
    b = chip1_b(i*4)
    d = d!(b!!last(i*2+1)); last(i*2+1) = b
  %repeat
  %trueif d#0; %false
%end

%integer k
%record(f)%name chip
%bytename b

  %on 0 %start
    printstring("**"); phex(event_extra); newline
  %finish
  set terminalmode(nopage)
  p("e - exit")
  p("r - reset")
  p("s - show")
  p("an")
  p("bn")
  p("an=v")
  p("bn=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'
      b == chip_b(rhex*4)
      k = nextsymbol
      %if k='=' %start
        readsymbol(k)
        rhex(b)
      %else
        phex2(b)
      %finish
    %finish
  %repeat
%end
