%begin

%option "-nons-low-nocheck-nodiag"
%include "inc:util.imp"
%string(255)output=""
%constinteger -
  portflag=1<<31,buffflag=1<<30,procflag=1<<29,
  varsflag=1<<28,zeroflag=1<<27,countflag=1<<26,
  deltaflag=1<<25,loopflag=1<<24
%integer bools=0

%ownintegerarray c(1:20)=-1(*)

@16_7fffc %byte status,data,*,control
%constinteger tbe=8,rd=4,rc=2,rbf=1
%integer sym

%routine twait
  %cycle
    %returnif status&tbe#0
  %repeat
%end

%routine putc(%integer x)
  control = x; twait
%end

%routine putd(%integer x)
  data = x; twait
%end

%integerfn getd
%integer x
  %cycle
  %repeatuntil status&rbf#0
  %if status&rd#0 %then x = data %else x = control
  %result = x
%end

%routine getc(%integer x)
%integer y
  %cycle
    %cycle
    %repeatuntil status&rbf#0
    %if status&rd#0 %start
      y = data
      %unless x=16_0b %start
        printsymbol('['); phex2(y); printsymbol(']')
      %finish
    %finishelsestart
      y = control
      %returnif x=y
      %unless x!!y=16_f0 %start; !?????
        printstring("[^"); phex2(y); printsymbol(']')
      %finish
    %finish
  %repeat
%end

%constinteger ptr=8,peek=13,poke=14
%owninteger pos=0

%routine at(%integer x)
  putc(ptr); putd(x&255); putd(x>>8&255)
  pos = x
%end

%integerfn byte
%integer x=0
  status = x; putc(peek); getc(poke); x = getd; status = 6
  pos = pos+1; %result = x
%end

%integerfn word
%integer x
  x = byte; %result=byte<<8+x
%end

%integerfn long
%integer x
  x = word; %result = word<<16+x
%end

%routine count(%integername was,%string(255)s)
%integer x = long
  %returnif x=was %and bools&deltaflag#0
  was = x
  %returnif x=0 %and bools&zeroflag=0
  write(x,6); space; printstring(s); newline
%end

%routine do long(%string(255)s)
%integer x
  x = long
  %returnif x=0 %and bools&zeroflag=0
  printstring(s); space; phex(x); newline
%end

%routine do word(%string(255)s)
%integer x = word
  %returnif x=0 %and bools&zeroflag=0
  printstring(s); spaces(5); phex4(x); newline
%end

%routine do byte(%string(255)s)
%integer x = byte
  %returnif x=0 %and bools&zeroflag=0
  printstring(s); spaces(7); phex2(x); newline
%end

%routine spy
%integer ad,sym,i
%constinteger portstart=16_1e00
%constinteger portsize=32
%constinteger procstart=portstart+32*portsize
%constinteger procsize=40
%constinteger buffstart=procstart+32*procsize
%constinteger buffsize=14+512+20+6

  %routine do port(%integer p)
  %integer i,j
  %bytearray b(1:32)
    %returnif bools&portflag=0
    ad = portstart+p*portsize; at(ad)
    j = 0
    %for i = 1,1,32 %cycle
      b(i) = byte; j = j!b(i) %unless i=7 %or i=8
    %repeat
    %returnif j=0
    at(ad)
    printstring("port"); phex2(p)
    printstring(" ("); phex4(ad); printsymbol(')')
    %for i=0,1,11 %cycle
      space %if i=0 %or i=6; phex2(byte)
    %repeat
    printstring(" t"); phex2(byte)
    printstring(" i"); phex2(byte)
    space; phex4(word)
    printstring(" o"); phex2(byte)
    space; printsymbol('l'); phex2(byte); space; phex4(word)
    newline; spaces(13)
    printsymbol('r'); phex4(word); space
    printsymbol('s'); phex4(word); space
    printsymbol('L'); phex4(word); printsymbol('/'); phex4(word); space
    printsymbol('E'); phex4(word); printsymbol('/'); phex4(word); newline
  %end

  %routine do proc(%integer i)
  %integer lim,sp
    %returnif bools&procflag=0
    ad = procstart+i*procsize
    at(ad); lim = ad+procsize
    printstring("proc"); phex2(i)
    printstring(" ("); phex4(ad); printsymbol(')')
    space; phex4(word)
    sp = word
    newline %andreturnif sp=0
    printstring(" sp"); phex4(sp);
    printstring(" bu"); phex4(word)
    printstring(" sz"); phex4(word)
    %unless ad>sp %start
      at(sp)
      %while sp<lim %cycle
        printsymbol('|'); sp = sp+2; phex4(word)
      %repeat
      printsymbol('|')
    %finish
    newline
  %end

  %routine do buff(%integer i)
    %returnif bools&buffflag=0
    ad = buffstart+i*buffsize
    printstring("buff"); phex2(i)
    printstring(" ("); phex4(ad); printstring(") ")
    at(ad)
    phex4(word); space
    at(ad)
    phex2(byte) %for i = 1,1,6; space
    phex2(byte) %for i = 1,1,6; space
    phex2(byte) %for i = 1,1,2; space
    phex2(byte) %for i = 1,1,5; newline
  %end

  %if bools&varsflag#0 %start
    at(3)
    printstring("Station "); phex2(byte)
    printstring(" firmware of "); phex2(byte); printsymbol('/')
    phex2(byte); printsymbol('/'); phex2(byte); newline
    at(16_3d00)
    do word("prolist")
    do word("buflist")
    do word("bufque ")
    do word("erbuf1 ")
    do word("erbuf2 ")
    do word("lrpro  ")
    do word("ltpro  ")
    do word("ltque  ")
    do word("etpro  ")
    do word("etque  ")
    do word("temp   ")
    do word("intstak")
    do byte("dmaon  ")
    do byte("dmaoff ")
    do byte("inton  ")
    do byte("station")
    do long("net    ")
    do word("ptr    ")
    at(16_3d72)
    do byte("mode   ")
  %finish
  %if bools&countflag#0 %start
    at(16_3d22)
    count(c(01),"packets received with inconsistent size")
    count(c(02),"CRC errors")
    count(c(03),"RX detected collisions")
    count(c(04),"packets discarded due to size/CRC/collision/filter error")
    count(c(05),"data packets heard")
    count(c(06),"ACKs heard")
    count(c(07),"packets ignored (wrong type or disabled broadcast channel)")
    count(c(08),"packets ignored (duplicate sequence number)")
    count(c(09),"packets ignored (port closed)")
    count(c(10),"packets ignored (wrong destination address)")
    count(c(11),"packets ignored (wrong source address)")
    count(c(12),"spurious ACKs received")
    count(c(13),"ACKs received with wrong sequence number")
    count(c(14),"retransmissions (collision)")
    count(c(15),"retransmissions (ACK timeout)")
    count(c(16),"packets sent (data and ACK)")
    count(c(17),"ACKs sent")
    count(c(18),"RX FIFO overflows")
    count(c(19),"RX DMA overruns")
    count(c(20),"address filter failures")
  %finish
  do port(i) %for i=0,1,31
  do proc(i) %for i=0,1,31
  do buff(i) %for i=0,1,9
%end

%on 0,9 %start
  %stop
%finish

%cycle
  defineparam("Output",output,pamnewgroup)
  definebooleanparams("POrts,Buffs,PRocs,Vars,Zeroes,Counts,Delta,Loop",bools,0)
  bools = countflag
  processparameters(cliparam)
  openoutput(1,output) %unless output=""
  spy %until bools&loopflag=0
  %exitunless output=""
  readline(cliparam)
%repeat

%endofprogram
