I'm getting some time to work on my long-neglected '816 Forth, and started considering the words for accessing the non-bank-0 locations. Because of Forth's code compactness, and in order to keep performance good, I've kept to a 16-bit Forth with all the actual Forth code running in bank 0, reserving the other banks primarily for data (large arrays, tables, etc.). So ! for example only stores a normal 16-bit cell at the address pointed to by the top 16-bit stack cell; but now I need another one where the address at the top will be a double number, and I need another name. Below, I propose just adding an X in front (for eXtended memory) but I would rather not come up with new non-standards if other such things already exist in common (or not-so-common) practice. Does anyone know?
The last two variations on CMOVE are for moving blocks of less than 64K from bank-0 memory to extended memory and vice-versa. Since these blocks will never overlap, there's no need for the "up" version. For simplicity, I suppose XCMOVE could just be used, but it will need a double-number address for even the bank-0 source or destination. XCMOVE and XCMOVE> will be able to move more than one bank at a time-- ie, in effect, there really will be no bank boundaries above bank 0.
The DO...LOOP and related words will also need to be able to handle a limit and index that are double numbers. Here I've just added a 2 in front of the name. Again, does anyone know if other more-standard names exist in Forth practice?
Code:
normal extended-memory (X)
words: version and stack effect:
! X! ( n Xaddr -- )
C! XC! ( c Xaddr -- )
@ X@ ( Xaddr -- n )
C@ XC@ ( Xaddr -- c )
2@ X2@ ( Xaddr -- d )
2! X2! ( d Xaddr -- )
CMOVE XCMOVE ( from_Xaddr to_Xaddr count -- )
CMOVE> XCMOVE> ( from_Xaddr to_addr count -- )
CMOVE>X ( from_addr to_Xaddr count -- )
X>CMOVE ( from_Xaddr to_Xaddr count -- )
VARIABLE XVARIABLE
ALLOT XALLOT ( d-count -- )
FILL XFILL
DO 2DO ( to_d from_d -- )
?DO 2?DO ( to_d from_d -- )
I 2I ( -- d )
J 2J ( -- d )
LOOP 2LOOP
+LOOP 2+LOOP (maybe only take 16-bit input?)
LEAVE 2LEAVE
UNLOOP 2UNLOOP
BOUNDS 2BOUNDS ( Xaddr d_count -- Xend_addr+1 Xbegin_addr )