Win32Forth


Using the Block Wordset


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.

Glossary

        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 $