Win32Forth implements a virtual block system, based on the ANSI standard Block
and Block extension wordsets.
The block words are not loaded by default and have to be included. The file
BLOCK.F is in the lib folder (some older versions of W32F placed it in the extras
folder).
The constants B/BUF, and #BUFFERS control the block size, and the number of
buffers the system uses. These are defaulted to 1024 byte blocks, and
8 buffers. A true LRU (least recently used) buffer allocation mechanism
is used, implemented as a bubble up buffer stack. The least recently used
buffer is always on the bottom of the stack. As buffers are used or
re-used, they are bubbled immediately up to the top of the stack, destined
to settle to the bottom of the stack if the same record is not accessed
again.
Blocks are stored in a blockfile (normally with the .blk extension,
although some forths use .fb) which is set by the words set-blockfile,
open-blockfile or create-blockfile and closed by close-blockfile. Only one
blockfile is active at any one time, open-blockfile and create-blockfile
automatically close the current one prior to setting themselves as the current
blockfile.
NOTE set-blockfile does not close the current blockfile.
A sample block file BANNER.BLK has been included for your examination.
type the following commands after loading BLOCK.F
OPEN-BLOCKFILE DEMOS\BANNER.BLK
1 7 THRU
This will load and run a simple demo.
Type DEMO again to run it again after it has been loaded.
1024 constant b/buf \ W32F Block extra
Length of each block.
64 constant c/l \ W32F Block extra
Number of characters per line.
8 constant #buffers \ W32F Block extra
Number of block buffers.
-1 value blockhandle \ W32F Block extra
The handle of the current block file, or -1 if no current block file.
variable blk ( -- a-addr ) \ ANSI Block
a-addr is the address of a cell containing zero or the number of the mass-storage block being interpreted. If BLK contains zero, the input source is not a block and can be identified by SOURCE-ID, if SOURCE-ID is available. An ambiguous condition exists if a program directly alters the contents of BLK.
variable scr ( -- a-addr ) \ ANSI Block ext
a-addr is the address of a cell containing the block number of the block most recently listed.
: save-buffers ( -- ) \ ANSI Block
Transfer the contents of each updated block buffer to mass storage. Mark all buffers as unmodified.
: buffer ( u -- a-addr ) \ ANSI Block
a-addr is the address of the first character of the block buffer assigned to block u.
The contents of the block are unspecified. An ambiguous condition exists if u is not
an available block number.
If block u is already in a block buffer, a-addr is the address of that block buffer.
If block u is not already in memory and there is an unassigned buffer, a-addr is the
address of that block buffer.
If block u is not already in memory and there are no unassigned block buffers,
unassign a block buffer. If the block in that buffer has been UPDATEd, transfer
the block to mass storage. a-addr is the address of that block buffer.
At the conclusion of the operation, the block buffer pointed to by a-addr is
the current block buffer and is assigned to u.
: empty-buffers ( -- ) \ ANSI Block ext
Unassign all block buffers. Do not transfer the contents of any updated block buffer to mass storage.
: flush ( -- ) \ ANSI Block
Perform the function of SAVE-BUFFERS, then unassign all block buffers.
: update ( -- ) \ ANSI Block
Mark the current block buffer as modified. An ambiguous condition exists if there
is no current block buffer.
Update does not write the block to the disc.
: block ( u -- a-addr ) \ ANSI Block
a-addr is the address of the first character of the block buffer assigned to
mass-storage block u. An ambiguous condition exists if u is not an available
block number.
If block u is already in a block buffer, a-addr is the address of that block buffer.
If block u is not already in memory and there is an unassigned block buffer,
transfer block u from mass storage to an unassigned block buffer. a-addr is
the address of that block buffer.
If block u is not already in memory and there are no unassigned block buffers, unassign
a block buffer. If the block in that buffer has been UPDATEd, transfer the block to
mass storage and transfer block u from mass storage into that buffer. a-addr is the
address of that block buffer.
At the conclusion of the operation, the block buffer pointed to by a-addr is the
current block buffer and is assigned to u.
: list ( u -- ) \ ANSI Block ext
Display block u in the console in a 16 line format. Store u in SCR.
An error occurs if u is greater than the number of blocks in the current blockfile.
: wipe ( u -- ) \ W32F Block extra
Erase the specified block to blanks.
: set-blockfile ( fileid -- ) \ W32F Block extra
Make fileid the current blockfile.
: load ( i*x u -- j*x ) \ ANSI Block
Save the current input-source specification. Store u in BLK (thus making block u the input source and setting the input buffer to encompass its contents), set >IN to zero, and interpret. When the parse area is exhausted, restore the prior input source specification. Other stack effects are due to the words LOADed. An ambiguous condition exists if u is zero or is not a valid block number.
: thru ( i*x u1 u2 -- j*x ) \ ANSI Block ext
LOAD the mass storage blocks numbered u1 through u2 in sequence. Other stack effects are due to the words LOADed.
: close-blockfile ( -- ) \ W32F Block extra
Close the current blockfile, flushing any updated buffers. Set the current blockfile to no file.
: open-blockfile ( "<spaces>'filename'" ) \ W32F Block extra
Close the current blockfile. Open the file and make it the current block file.
: create-blockfile ( u "<spaces>'filename'" ) \ W32F Block extra
Close the current blockfile. Create a file of u blocks long, initialise the blocks to blanks and make it the current blockfile.
: #blocks ( -- u ) \ W32F Block extra
u is the number of blocks in the current blockfile.
Document $Id: p-block.htm,v 1.2 2006/10/28 11:01:13 georgeahubert Exp $