anchor.diff:  
   \ clk! ( r -- ) updates the clock for the corresponding
   \ cache line.
  -t: clk!		bclk @ DUP 1+ bclk ! SWAP CELLS clocks @ + ! ;
  +t: clk!		bclk @ DUP 1+ bclk ! SWAP >clk ! ;
   
   \ assign ( b r -- a ) assigns a specified cache row to the
   \ provided block.  It answers with the corresponding block
   \ buffer for the cache row specified.
   t: assign ( b r -- a )
  -  >R R@ clk!
  -  R@ CELLS blocks @ + !
  -  0 R@ laundry @ + C!
  -  R> 1024 * buffers @ + ;
  +  >R R@ clk!  R@ >blk !  R@ clean R> >buf ;
   
   \ ?wrb ( r -- ) cleans the specified cache row.  If it's
   \ dirty, it'll flush the cache contents to backing store.
  
positive.code: \ block cache row and returns it.
  t: lru ( b -- b r )
    -1 0 BEGIN DUP 64 < WHILE
      DUP CELLS clocks @ + @ 0 = IF NIP EXIT THEN
      SWAP OVER CELLS clocks @ + @ UMIN SWAP
      1+
    REPEAT DROP
    0 BEGIN DUP 64 < WHILE
      2DUP CELLS clocks @ + @ = IF NIP EXIT THEN
      1+
    REPEAT
    .S ABORT" LRU fault" ;
  
negative.code: \ provided cache row index.
  t: >buf		1024 * buffers @ + ;
  
  \ >blk ( r -- a ) calculates the block cache address for the
  \ provided cache row index.
  t: >blk		CELLS blocks @ + ;
  
  \ >clk ( r -- a ) calculates the clock cache address for the
  \ provided cache row index.
  t: >clk		CELLS clocks @ + ;
  
  \ wrb ( r -- ) writes back the indicated block buffer.
  t: wrb ( r -- )	DUP >R R@ >buf R@ CELLS
  		blocks @ + @ 1 LSHIFT 2 PUTS THROW R> clean ;
  