{Memory test for Intel-82586-based APM local bus 10MHz Ethernet board}

%begin
%include "inc:util.imp"
%option "-low-nocheck-nodiag-nons-nowarn"
%integer address=0,mode='l',data=0,k,e,f
%integer oldpattern,newpattern,pattern,picks,drops,ahi,alo,cumupicks,cumudrops
%constinteger kbytes=128  {or 64}
%constinteger bytes=kbytes*1024,words=kbytes*512,longwords=kbytes*256
%constinteger base=16_60000-bytes
@base %bytearray b(0:bytes-1)
@base %halfarray w(0:words-1)
@base %integerarray l(0:longwords-1)
%integerarray errors(0:16)
%integer p1,p2,p3,bits,oldbits

%integerfn arbpattern
%owninteger seed = -1
%integer old
! %cycle
    old = seed
    seed = seed<<1
    seed = seed!!16_04c11db7 %if old<0
    old = seed&65535; bits = 0
    %while old#0 %cycle
      old = old&(old-1); bits = bits+1
    %repeat
! %repeatuntil bits<=limit
  %result = seed&65535
%end

%cycle
  k = testsymbol %until k>=0
  %exitif k='.'
  %if k!32='a' %start
    printstring("Address"); address = rhex; skipsymbol
  %elseif k!32='d'
    printstring("Data"); data = rhex; skipsymbol
  %elseif k!32='b'
    printstring("Byte mode"); newline; mode = 'b'
  %elseif k!32='h'
    printstring("Halfword mode"); newline; mode = 'h'
  %elseif k!32='l'
    printstring("Longword mode"); newline; mode = 'l'
  %elseif k='r'
    printstring("M("); phex(address); printstring(") = ")
    %if mode='b' %then phex2(b(address)) %else -
    %if mode='h' %then phex4(w(address)) %else phex(l(address))
    address = address+1
    newline
  %elseif k='R'
    %cycle
      %for k = 1,1,1000 %cycle
        %if mode='b' %then data = b(address) %else -
        %if mode='h' %then data = w(address) %else data = l(address)
      %repeat
    %repeatuntil testsymbol>=0
  %elseif k='w'
    %if mode='b' %then b(address) = data %else -
    %if mode='h' %then w(address) = data %else l(address) = data
    address = address+1
    newline
  %elseif k='W'
    %cycle
      %for k = 1,1,1000 %cycle
        %if mode='b' %then b(address) = data %else -
        %if mode='h' %then w(address) = data %else l(address) = data
      %repeat
    %repeatuntil testsymbol>=0
  %elseif k='/'
    %cycle
      %if mode='b' %start
        b(address) = data; k = b(address)
      %elseif mode='h'
        w(address) = data; k = w(address)
      %else
        l(address) = data; k = l(address)
      %finish
      data = \data
    %repeatuntil testsymbol>=0
  %elseif k='-'
    address = address-1
  %elseif k='='
    address = address-2
  %elseif k='*' %or k='&'
    e = 0; f = 0
    %if mode='b' %start
      %unless k='&' %start
        b(k) = data %for k = 0,1,bytes-1
      %finish
      %for k = 0,1,bytes-1-16 %cycle
        p1 = b(k)
        %unless p1=data&255 %start
          e = e+1; phex(k); space; phex2(p1); newline
        %finish
      %repeat
    %elseif mode='h'
      data = data&65535
      %unless k='&' %start
        w(k) = data %for k = 0,1,words-1
      %finish
      %for k = 0,1,words-1-8 %cycle
        p2 = w(k); p3 = -1
        %cycle
          p3 = p3+1
          p1 = p2
          p2 = w(k)
%if p1#p2 %start
  phex(k)
  space %and phex4(p1) %unless p1=data
  space %and phex4(p2) %unless p2=data
  printstring(" sb "); phex4(data); newline
%finish
        %repeatuntil p1=p2
        f = f+p3
        %unless p1=data %start
          e = e+1; phex(k); space; phex4(p1); newline
        %finish
      %repeat
    %else
      %unless k='&' %start
        l(k) = data %for k = 0,1,longwords-1
      %finish
      %for k = 0,1,longwords-1-4 %cycle
        p1 = l(k)
        %unless p1=data %start
          e = e+1; phex(k); space; phex(p1); newline
        %finish
      %repeat
    %finish
    printstring("Not ") %unless e=0; printstring("OK")
    write(e,1) %unless e=0
    %unless f=0 %start
      printstring(" ("); write(f,0); printsymbol(')')
    %finish
    newline
  %elseif k='\'
    %cycle
      %if mode='b' %start
        b(k) = data %for k = 0,1,bytes-1
        e = b(k) %for k = 0,1,bytes-1
      %elseif mode='h'
        w(k) = data %for k = 0,1,words-1
        e = w(k) %for k = 0,1,words-1
      %else
        l(k) = data %for k = 0,1,longwords-1
        e = l(k) %for k = 0,1,longwords-1
      %finish
      data = \data
    %repeatuntil testsymbol>=0
  %elseif k='!'
    ahi = 0; alo = 0; cumupicks = 0; cumudrops = 0
    oldpattern = 0; oldbits = 0
    errors(bits) = 0 %for bits = 0,1,16
    w(k) = oldpattern %for k = 0,1,words-1
    %cycle
      newpattern = arbpattern
      picks = 0; drops = 0; ahi = 0; alo = 0; e = 0
      %for k = 0,1,words-1-8 %cycle
        pattern = w(k)!!oldpattern
        %unless pattern=0 %start
phex(k); space; phex4(pattern!!oldpattern); space; phex4(oldpattern)
space; phex4(w(k)); skipsymbol
          e = e+1
          picks = picks!(pattern&\oldpattern)
          drops = drops!(pattern&oldpattern)
          ahi = ahi!k
          alo = alo!\k
        %finish
        w(k) = newpattern
      %repeat
      errors(oldbits) = errors(oldbits)+e
      cumupicks = cumupicks!picks
      cumudrops = cumudrops!drops
      printstring("Data="); phex4(oldpattern)
      printstring(", picks="); phex4(picks); printsymbol('/'); phex4(cumupicks)
      printstring(", drops="); phex4(drops); printsymbol('/'); phex4(cumudrops)
      printstring(", addr: ")
      k = words>>1
      %cycle
        space %if k&16_888#0
        %if k&ahi=0 %and k&alo=0 %start
          printsymbol('-')
        %elseif k&ahi=0 %and k&alo#0
          printsymbol('0')
        %elseif k&ahi#0 %and k&alo=0
          printsymbol('1')
        %else
          printsymbol('*')
        %finish
        k = k>>1
      %repeatuntil k=0
      newline
      oldbits = bits
      oldpattern = newpattern
      %for bits = 0,1,16 %cycle
        %if errors(bits)#0 %start
          write(bits,1); printsymbol(':'); write(errors(bits),0)
        %finish
      %repeat
      newline
    %repeatuntil testsymbol>=0
  %elseif k='@'
    ahi = 0; alo = 0; cumupicks = 0; cumudrops = 0
    oldpattern = 0; oldbits = 0
    l(k) = oldpattern %for k = 0,1,longwords-1
    %cycle
      %if oldpattern<0 -
      %then newpattern = oldpattern<<1 -
      %else newpattern = oldpattern<<1+1
      picks = 0; drops = 0; ahi = 0; alo = 0; e = 0
      %for k = 0,1,longwords-1-4 %cycle
        pattern = l(k)!!oldpattern
        %unless pattern=0 %start
phex(k); space; phex(pattern!!oldpattern); space; phex(oldpattern)
space; phex(l(k)); skipsymbol
          e = e+1
          picks = picks!(pattern&\oldpattern)
          drops = drops!(pattern&oldpattern)
          ahi = ahi!k
          alo = alo!\k
        %finish
        l(k) = newpattern
      %repeat
      cumupicks = cumupicks!picks
      cumudrops = cumudrops!drops
      printstring("Data="); phex(oldpattern)
      printstring(", picks="); phex(picks); printsymbol('/'); phex(cumupicks)
      printstring(", drops="); phex(drops); printsymbol('/'); phex(cumudrops)
      printstring(", addr: ")
      k = longwords>>1
      %cycle
        space %if k&16_888#0
        %if k&ahi=0 %and k&alo=0 %start
          printsymbol('-')
        %elseif k&ahi=0 %and k&alo#0
          printsymbol('0')
        %elseif k&ahi#0 %and k&alo=0
          printsymbol('1')
        %else
          printsymbol('*')
        %finish
        k = k>>1
      %repeatuntil k=0
      newline
      oldpattern = newpattern
    %repeatuntil testsymbol>=0
  %elseif k='#'
    ahi = 0; alo = 0; cumupicks = 0; cumudrops = 0
    oldpattern = 0; oldbits = 0
    b(k) = oldpattern %for k = 0,1,bytes-1
    %cycle
      newpattern = oldpattern<<1
      newpattern = newpattern+1 %if newpattern&256=0
      newpattern = newpattern&255
      picks = 0; drops = 0; ahi = 0; alo = 0; e = 0
      %for k = 0,1,bytes-1-16 %cycle
        pattern = b(k)!!oldpattern
        %unless pattern=0 %start
phex(k); space; phex2(pattern!!oldpattern); space; phex2(oldpattern)
space; phex2(b(k)); skipsymbol
          e = e+1
          picks = picks!(pattern&\oldpattern)
          drops = drops!(pattern&oldpattern)
          ahi = ahi!k
          alo = alo!\k
        %finish
        b(k) = newpattern
      %repeat
      cumupicks = cumupicks!picks
      cumudrops = cumudrops!drops
      printstring("Data="); phex2(oldpattern)
      printstring(", picks="); phex2(picks); printsymbol('/'); phex2(cumupicks)
      printstring(", drops="); phex2(drops); printsymbol('/'); phex2(cumudrops)
      printstring(", addr: ")
      k = bytes>>1
      %cycle
        space %if k&16_8888#0
        %if k&ahi=0 %and k&alo=0 %start
          printsymbol('-')
        %elseif k&ahi=0 %and k&alo#0
          printsymbol('0')
        %elseif k&ahi#0 %and k&alo=0
          printsymbol('1')
        %else
          printsymbol('*')
        %finish
        k = k>>1
      %repeatuntil k=0
      newline
      oldpattern = newpattern
    %repeatuntil testsymbol>=0
  %else
    printstring(". stop,   b/h/l  byte/half/long mode,   a/d set addr/data,")
    newline
    printstring("r/R  w/W  read/write one/loop, - dec addr,  * rw test,")
    newline
    printstring("! pattern test"); newline
  %finish
%repeat

%end
