/Check Out New Ether Boards
/ (1) Non-Interrupt-Driven Comms Test (Echo)
/ (2) Memory Test                     ('M')
/ (3) Loader                          ('S')
/ (4) Simple non-int IO package for link

/Frig
withiy=16_fd

/Memory
low=16_1000
high=16_4000

/Device addresses
dma=16_00
clrtc=16_10 /read-only
inten=16_10 /write-only (ltbe.lrdr.lrcr.dmatc)
linkc=16_20
linkd=16_30
ethrx=16_40 /read: data/control, write: filter/reset
links=16_50 /read-only (rbf.rdr.rcr.0.0.0.0.tbe)
ethtxd=16_50 /write-only: data into fifo
eths=16_60  /read-only: (tcol.ta.tdone.rctrl.crce.ra.over)
ethtxc=16_60 /write-only: hold-off counter, reset

/NB: Interrupt vectors
/2 ltbe
/4 lrdr
/6 lrcr
/8 dmatc
/a etdone
/c erdone
/e overflow

/IO-package entry points
pdata=8
pctrl=16
rdata=16_18
rctrl=16_20
rsym=16_28

loc 16_00; ld sp,high
           jp begin
loc 16_08; jp xpdata
loc 16_10; jp xpctrl
loc 16_18; jp xrdata
loc 16_20; jp xrctrl
loc 16_28; jp xrsym
loc 16_30; jp *+16_1000
loc 16_38; jp *+16_1000
loc 16_66; jp *+16_1000

/  I N I T I A L   E N T R Y

begin: ld a,halt
   ld (16_1030),a
   ld (16_1038),a
   ld (16_1066),a
   jp rwait

/  E C H O   T E S T

twait:
   in a,links       /Wait for LTBE
   rra
   jp nc,twait
rwait:
   in a,links       /Wait for LRBF
   add a,a
   jp nc,rwait
   jp n,data        /LRDR=0: ->
   in a,linkc
   out linkc,a
   jp twait
data:
   in a,linkd
   cp 'S'
   jp z,loader
   cp 'M'
   jp z,memtest
   out linkd,a
   jp twait

/  M E M O R Y   T E S T

/   B Old pattern
/   C New pattern
/   D Long-term error count
/   E Short-term e c
/ IYH Picks                *NAUGHTY*
/ IYL Drops                *NAUGHTY*
/  IX Pointer
/  HL Counter

message:
  text "Memory test"
memtest:
  ld hl,message
hello:
  in a,links
  rra; jr nc,hello
  ld a,(hl); inc hl
  or a; jr z,startm
  out (linkd),a
  jr hello
startm:
  ld ix,low        /Clear store
  ld hl,high-low
clearloop:
  ld (ix),0
  inc ix; dec hl
  ld a,h; or l
  jp nz,clearloop
  ld c,0           /Set Oldpat=0 (later)
  ld de,0          /Clear error counts
  ld iy,0          /Clear pick/drop
mainloop:
  ld b,c
  ld a,b; rlca     /Work out new pattern
  xor 1; ld c,a
  ld ix,low
  ld hl,high-low
testloop:
  ld a,b
  xor (ix)       /Check old pattern
  jp z,longok    /OK ->
  and b
  withiy; or l   /Record picks
  withiy; ld l,a
  ld a,b; cpl; ld b,a
  cpl; xor (ix)  /Re-read (!)
  and b
  withiy; or h   /Record drops
  withiy; ld h,a
  ld a,b; cpl; ld b,a
  inc d          /Bump error count
  jp nz,longok   /But not past 255
  ld d,255
longok:
  ld a,c
  ld (ix),a      /Write and
  xor (ix)       /check new pattern
  jp z,shortok   /OK ->
  and c
  withiy; or l
  withiy; ld l,a
  ld a,c; cpl; ld c,a
  cpl; xor (ix)
  and c
  withiy; or h
  withiy; ld h,a
  ld a,c; cpl; ld c,a
  inc e
  jp nz,longok
  ld e,255
shortok:
  inc ix          /Bump pointer
  dec hl          /Count down
  ld a,h; or l    /Done?
  jp nz,testloop  /No ->
wtre: in a,links /write results to link
  rra; jr nc,wtre
  ld a,b         /First Oldpat
  out linkc,a
wtb: in a,links
  rra; jr nc,wtb
  ld a,c         /Then Newpat
  out linkd,a
wtc: in a,links
  rra; jr nc,wtc
  ld a,d         /Then Long errcount
  out linkd,a
wtd: in a,links
  rra; jr nc,wtd
  ld a,e         /Then Short errcount
  out linkd,a
wte: in a,links
  rra; jr nc,wte
  withiy; ld a,h /Then Picks
  out linkd,a
wth: in a,links
  rra; jr nc,wth
  withiy; ld a,l /Then Drops
  out linkd,a
wtl: in a,links
  rra; jr nc,wtl
  jp mainloop

/ L O A D E R

/ Motorola format loader

skip: call rdata
  cp 'S'
  jr nz,skip
loader:
  call rdata
  cp '9'
  jp z,endfile
  cp '1'
  jp nz,skip
  ld b,2             /Prevent leap-out
  call rhex; ld b,a  /Bytecount
  ld c,a             /Initialise checksum (??)
  call rhex; ld h,a  /Pointer(ms)
  call rhex; ld l,a  /Pointer(ls)
loadloop:
  call rhex
  ld (hl),a; inc hl
  jp loadloop
endfile: call rdata   /Skip to nl
  cp 10
  jr nz,endfile
  jp low

/Send one data character from A
xpdata: out linkd,a
  push af
xpwait: in a,links
  rra; jp nc,xpwait
  pop af
  ret

/Send one control character from A
xpctrl: out linkc,a
  push af
  jp xpwait

/Read one data or control char into A
xrsym: in a,links
  add a,a; jp nc,xrsym
  jp n,gotd
  jp gotc

/Read one control character into A
xrc0: in a,linkd
xrctrl: in a,links
  add a,a; jp nc,xrctrl
  jp n,xrc0          /Skip data ->
gotc: in a,linkc
  ret

/Read one data character into A
xrd0: in a,linkc
xrdata: in a,links
  add a,a; jp nc,xrdata
  jp p,xrd0          /Skip control ->
gotd: in a,linkd
  ret

/Read one hex digit into A
rdig: call rdata
  sub '0'
  cp 10
  ret n
  sub 7
  and 15
  ret

/Read hex one byte into A, using D as temp
/Adjust checksum, count the byte,
/On end of record, leap out, ignoring checksum.
rhex: call rdig
  rlca; rlca; rlca; rlca
  ld d,a
  call rdig
  add a,d; ld d,a
  add a,c; ld c,a
  ld a,d
  dec b
  ret nz
  pop hl
  jp skip

  end
