!oslan bug
begin 
option  "-nons-low"
include  "inc:util.imp"
!include "ether:lance.inc"
include  "ether:ethutil.inc"

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

conststring (17)our dte = "12-34-56-78-9A-BC"
conststring (17)oslan dte = "02-60-8C-02-23-29"
bytearray  dte(1:6)
bytearray  odte(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 

owninteger  pos=0,n=0
routine  scan rring
ownintegerarray  logged(0:3)=0(*)
ownintegerarray  lost(0:3)=0(*)
owninteger  lastin=-1
integer  seqno,nomsize,j
record (df)name  d
record (bf)name  b
  predicate  from oslan
    trueif  same dte(odte(1),b_sdte(1))
    false 
  end 
  predicate  to oslan
    trueif  same dte(odte(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; selectoutput(0); write(n,0); selectoutput(1); newline
      b == buffer of(d)
      unless  d_control= r stp + r enp start 
        printstring("Status "); phex2(d_control)
        printstring(" size "); phex4(d_plus); newline
      finish 
      nomsize = b_decpty{isolength
      if  from oslan or  to oslan start 
        printstring("Got ")
        printstring(getdte(b_ddte(1))); space
        printstring(getdte(b_sdte(1))); space
        phex4(b_decpty); space; phex4(b_isolength); newline
        unless  d_plus=nomsize+18 start 
        unless  d_plus=64 and  nomsize+18<64 start 
          printstring("Nominal size "); phex4(nomsize)
          printstring(" inconsistent with physical size "); phex4(d_plus)
          printstring(" lost "); write(nomsize+18-d_plus,0); newline
        finish 
        finish 
        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
        for  j = 1,1,nomsize cycle 
          space
          if  ' '<=b_data(j)<=126 then  printsymbol(b_data(j)) elsec 
            printsymbol('_')
          space
          newline if  j&15=0
        repeat 
        newline unless  j&15=0
      else 
        n = n-1
        printstring("Foreign ")
        printstring(getdte(b_ddte(1))); space
        printstring(getdte(b_sdte(1))); space
        phex4(b_decpty); space; phex4(b_isolength); newline
      finish 
      d_control = r own
      pos = (pos+1)&127
      selectoutput(0); newline
      selectoutput(1)
    finishelseexit 
  repeat 
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(odte(1),oslandte)
  newline

  openoutput(1,"$bug.dat"); selectoutput(1)
  cycle 
    intwait
    stop  if  testsymbol>=0 or  n>100
    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