I mentioned another way to define THRU . Here are the block loading words in Fleet Forth.
These are in the kernel.
Code: Select all
2VARIABLE HISTORY
: LINELOAD ( LINE# BLK# -- )
DUP 0=
ABORT" CAN'T LOAD 0"
RB DECIMAL
BLK 2@ 2>R
BLK ! C/L * >IN !
INTERPRET 2R>
BRANCH [ BLK.2! , ] -;
: LOAD ( U -- )
0 SWAP BRANCH
[ ' LINELOAD >BODY , ] -;
: RAM ( BLK#1 -- BLK#2 )
RAM.OFFSET + ;
: FH ( N1 -- N2 )
BLK @ DUP UNDER+ ?EXIT
SCR @ + ;
: DR+ ( BLK#1 #DR -- BLK#2 )
7 AND DR.OFS.PWR LSHIFT + ;
HISTORY is set by WORD . HISTORY was originally added to Fleet Forth so WHERE could accurately display where an error originated.
LINELOAD takes a line number and a block number. It will load a screen starting at the specified line number.
LOAD loads the entire block. It branches to the beginning of LINELOAD .
Fleet Forth sets aside a range of block numbers for each disk as well as a range for the Ram Expansion Unit.
In the current version of Fleet Forth, RAM adds an offset of 16384 ($4000) to the number on the stack. Fleet Forth's BLOCK and BUFFER will access blocks higher than 16383 ($3FFF) from the Ram Expansion Unit
DR+ masks off the higher bits of a number and treats drive numbers 0 and 8 as the same device, 1 and 9 as the same device on up to treating 7 and 15 as the same device. DR+ adds the offset for the desired drive.
Code: Select all
0 DR+ \
8 DR+ \ adds 0 to the number on the stack
1 DR+ \
9 DR+ \ adds 2048 to the number on the stack
2 DR+ \
10 DR+ \ adds 4096 to the number on the stack
...
7 DR+ \
15 DR+ \ adds 14336 to the number on the stack
RAM \ adds 16384 to the number on the stack
Each drive, and the Ram Expansion Unit, sees its block range starting at 0.
Assume there is a disk with Forth blocks in drive 8 and drive 9 and both drives are open for block access.
Code: Select all
1 LOAD \ loads block 1 from drive 8
1 8 DR+ LOAD \ also loads block 1 from drive 8
1 9 DR+ LOAD \ loads block 1 from drive 9
1 RAM LOAD \ loads block 1 from the Ram Expansion Unit
FH , from here, is a nice utility word from Leo Brodie's "Thinking Forth". When loading a screen, it adds the current block number to the number on the stack. This allows loading blocks (with LOAD or THRU ) relative from the currently loading block. When not loading a block, FH adds the current screen number to the number on the stack to assist editing.
THRU is defined in the system loader. This is its source in Fleet Forth.
Code: Select all
: THRU ( U1 U2 -- )
>R
BEGIN
5 ?CR
DUP U. LOAD
R@ HISTORY @ 1+ DUP>R U<
DONE? OR
?LEAVE
R>
AGAIN -;
Yes, that is ?LEAVE used without a DO LOOP . Fleet Forth's ?LEAVE will, if the flag on the data stack is TRUE , drop two items from the return stack and pull a third item from the return stack and store it in IP .?LEAVE is used in Fleet Forth's definition of THRU to make it 2 bytes smaller than this:
Code: Select all
: THRU ( U1 U2 -- )
>R
BEGIN
5 ?CR
DUP U. LOAD
R@ HISTORY @ 1+ TUCK U<
DONE? OR
UNTIL
R> 2DROP ;
Fleet Forth's source for THRU is not portable to other Forth systems with ?LEAVE in there and it doesn't matter. THRU is in the Controlled Reference Words of the Forth-83 Standard and it is in the ANSI Forth Standard. Any Forth system which uses blocks will likely have THRU .
I have not yet added --> except as a temporary definition. Should I choose to define it in the system, it will be defined in the system loader along with THRU .