# Drive Stream

A drive stream is, drum roll, a stream [io/stream] interface to a drive
[io/drive] .

It maintains a byte based position within it and that position advances at each
read or write.

It maintains a single sector buffer which contains the sector that is the target
of the previous read or write operation.

Writing to the stream will set the a "dirty" flag, which will trigger a write
of the buffer to the sector either when the buffer's target sector changes or
when "flush" is called.

## API

Fields:
tgtdrv  Target drive [io/drive]
pos     Current byte-based position
bufsec  Sector currently in buffer
dirty   Whether the buffer is dirty
buf(    Pointer to buffer

Words:

newdrivestream ( tgtdrv -- drvstr )
  Create a new drivestream targeting "tgtdrv".

load ( sec drvstr -- )
  Load sector "sec" in the buffer. Aborts if outside the window.

flush ( drvstr -- )
  If buffer is dirty, save it.

invalidate ( drvstr -- )
  Flush and then set "bufsec" to -1 to indicate that buf( has nothing. This can
  be useful when the underlying drive is a dynamic view (for example
  [io/secwin] ) that is being reframed.

window ( pos drvstr -- a? n-or-0 )
  Load, if needed, the correct sector so that the position "pos" is available in
  the buffer. Returns its address in "a" as well as the number of bytes that can
  be read before the end of the buffer is reaches, as "n". If "pos" is outside
  the window, "n" is 0 and "a" is absent.

dirty! ( drvstr -- )
  Make the buffer dirty.
