!Lance receive test
%begin
%option "-nons-low"
%include "inc:util.imp"
%include "ether:ethutil.inc-list"

@16_106c %integer ipl3 vector
%integer oldvector
%integer pr=0,pt=0

%conststring(17)our dte = "12-34-56-78-9A-BC"
%conststring(17)vax dte = "AA-00-03-01-0C-D7"
%bytearray dte(1:6)
%bytearray vdte(1:6)

%record(ibf)ib
%record(drf)%name rring,tring

@16_fe0000 %half lance address register, lance data register

%routine wcsr(%half r,v)
  lance address register = r
  lance data register = v
%end

%integerfn rcsr(%half r)
  lance address register = r
  %result = lance data register
%end

%predicate samedte(%bytename a,b)
%integer i
  %for i = 1,1,6 %cycle
    %falseunless a=b
    a == a[1]; b == b[1]
  %repeat
  %true
%end

%integerfn swab(%integer x)
  *rol.w #8,d0
%end

%integerfn swap(%integer x)
  *swap d0
%end

%routine setup data structure
%integer i
%record(df)%name d
  ib = 0
  set dte(dte(1), our dte)
  convert dte to halfwords(dte(1), ib_pa0)
  rring == new ring
  tring == new ring
  point(ib_highrad,ib_lowrad,rring)
  point(ib_hightad,ib_lowtad,tring)
  ib_rcount = 16_e0
  ib_tcount = 0
  %for i = 0,1,127 %cycle
    d == rring_desc(i)
    d = 0; d_minus = -900
    point(d_highad,d_lowad,new buffer)
    d_control = r own
  %repeat
  d == tring_desc(0)
  d = 0; d_minus = -20
  point(d_highad,d_lowad,new buffer)
%end

%routine setup device
%half l
%byte h
  point(h,l,ib)
  wcsr(0, c stop)
  wcsr(1,l)
  wcsr(2,h)
  wcsr(3, bswp)
  wcsr(0, c init ! c strt ! c inea)
%end

%ownhalf intcsr=0,idon=0,rint=0,tint=0

%routine intwait
!%cycle
  *move.w #16_2000,d0; *trap#0; *stop #16_2000; *mtsr #0
!  %exitif intcsr & c intr#0
!  intcsr = lance data register
!  idon = intcsr
!  rint = intcsr
!  tint = intcsr
!%repeatuntil intcsr & c intr # 0
%end

%routine scan rring
%ownintegerarray logged(0:3)=0(*)
%ownintegerarray lost(0:3)=0(*)
%owninteger lastin=-1
%integer seqno,nomsize,n=0,j
%record(df)%name d
%record(bf)%name b
%owninteger pos=0
  %predicate from vax
    %trueif same dte(vdte(1),b_sdte(1))
    %false
  %end
  %predicate to us
    %trueif same dte(dte(1),b_ddte(1))
    %false
  %end
  %routine pp(%integer a,b)
    b = b+a; b = 1 %if b=0
    a = 99 %and b = 100 %if a=b
    write((a*100)//b,2)
  %end
  %cycle
    d == rring_desc(pos)
    %if d_control & r own = 0 %start
      n = n+1
      b == buffer of(d)
      nomsize = b_isolength
      %if b_decpty=16_6006 %and from vax %and to us %start
        seqno = b_data(1)<<8 + b_data(2)
        j = nomsize+18-d_plus
        %if j#0 %start
          %if (j-1)&\3#0 %start
            printstring("Nominal size "); phex4(nomsize)
            printstring(" inconsistent with physical size "); phex4(d_plus)
            printstring(" lost "); write(j,0); newline
            %unless d_control= r stp + r enp %start
              printstring("Bad status "); phex2(d_control)
              printstring(" size "); phex4(d_plus); newline
            %finish
!         %else
!           write(j,0); printstring(" bytes lost"); newline
          %finish
        %finish
        %unless nomsize=(seqno>>4&3)<<8+64 %start
          printstring("Sequence number "); phex4(seqno)
          printstring(" inconsistent with nominal size "); phex4(nomsize); newline
        %finish
        logged(seqno>>4&3) = logged(seqno>>4&3)+1
        lastin = seqno-1 %if lastin=-1
        %cycle
          lastin = (lastin+1)&65535
          %exitif lastin=seqno
          lost(lastin>>4&3) = lost(lastin>>4&3)+1
        %repeat
      %else
!       newline
!       %unless d_control= r stp + r enp %start
!         printstring("Wrong status "); phex2(d_control)
!         printstring(" size "); phex4(d_plus); newline
!       %finish
!       printstring("Foreign packet ")
!       printstring(getdte(b_ddte(1))); space
!       printstring(getdte(b_sdte(1))); space
!       phex4(b_decpty); space; phex4(nomsize)
!       spaces(3); newline
!       nomsize = b_decpty-2
!       nomsize = 64 %if nomsize<0 %or nomsize>64
!       %for j = 1,1,nomsize %cycle
!         space; phex2(b_data(j))
!         newline %if j&15=0
!       %repeat
!       newline %unless j&15=0
      %finish
      d_control = r own
      pos = (pos+1)&127
    %finishelseexit
  %repeat
  %returnif n=0
  printstring("Got")
  %for j = 0,1,3 %cycle
    space; phex4(logged(j))
  %repeat
! printstring(" lost")
! %for j = 0,1,3 %cycle
!   space; phex4(lost(j))
! %repeat
  pp(logged(j),lost(j)) %for j = 0,1,3
  pp(logged(0)+logged(1)+logged(2)+logged(3),
     lost(0)+lost(1)+lost(2)+lost(3))
  printsymbol(13)
  pr = pr+n
! %returnif n=128
! write(n,0); printstring(" received"); newline
%end

%owninteger lives=9

%onevent 0 %start
  lives = lives-1
  %if lives>=0 %start
    %if event_sub=2 %start
      printstring("Bus error at "); phex(event_extra); newline
    %elseunless event_sub=1
      printstring("Event 0 "); write(event_sub,1); newline
    %finish
    write(pr,0); write(pt,1); printstring(" R T"); newline
    phex4(intcsr); space; phex4(lance data register)
    printstring("Int Csr"); newline
    wcsr(0,c stop)
  %finish
  ipl3 vector = oldvector
  %stop
%finish

->begin

handler:
  *move.w d0,-(sp)
  *move.w lance data register, d0
  *move.w d0,intcsr
  *and.w #(cbabl!ccerr!cmiss!cmerr!crint!ctint!cidon!cinea),d0
  *move.w d0,lance data register
  *move.w (sp)+,d0
  *rte

begin:

  printstring("Starting")
    oldvector = ipl3 vector
    ipl3 vector = addr(handler)
    setup data structure
    ib_mode = m prom ! m dtx
    setup device
    setdte(vdte(1),vaxdte)
  newline

  %cycle
    intwait
    %stop %if testsymbol>=0
    %if intcsr& c err # 0 %or intcsr&(c rxon ! c txon) # c rxon %start
      printstring("Int: "); phex4(intcsr); newline
    %finish
    %if idon & c idon # 0 %start
      idon = 0
      lance data register = (intcsr & c inea) ! c idon
    %finish
    %if rint & c rint # 0 %start
      rint = 0
      lance data register = (intcsr & c inea) ! c rint
    %finish
    scan rring
    %if tint & c tint # 0 %start
      tint = 0
      lance data register = (intcsr & c inea) ! c tint
      printstring("T INT ?"); newline
    %finish
  %repeat
  
%endofprogram
