<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>
TurboForth uses the following memory:
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
Note: the locations of these vectors MUST NOT change between releases | ||||
A000 |
0000 |
intvec | 2 |
vector for INTERPRET >a000 |
A002 |
0000 |
blkvec | 2 |
vector for BLOCK |
A004 |
0000 |
numvec | 2 |
vector for NUMBER |
A006 |
0000 |
fndvec | 2 |
vector for FIND |
A008 |
0000 |
usrisr | 2 |
vector for user isr |
A00A |
0000 |
kdel | 2 |
Keyboard auto-repeat initial delay/2 (high-byte) and repeat delay (low byte) |
A00C |
0000 |
dsrvec | 2 |
pointer to DSRLNK vector in bank 1 |
A00E |
0000 |
gplvec | 2 |
pointer to GPLLNK vector in bank 1 |
A010 |
0000 |
padvec | 2 |
pointer to scratchpad restore code in bank 1 |
A012 |
8300 |
wp | 2 |
Assembly language vector for returning to TF from external assembly code that runs in a different workspace. External assembly code (for example, code written with the TF assembler) that changes workspace can simply perform a BLWP @>A012 to restore TF's workspace and jump to NEXT in the inner interpreter, which will restore normal Forth execution perfectly. Software can actually change TF's workspace while running. A copy of the desired workspace address MUST be written here so that KEY can restore the correct workspace address after its call into the TI ROM. |
A014 |
0000 |
pnext | 2 |
pointer to NEXT's executable code |
A016 |
0000 |
pdocon | 2 |
pointer to DOCON's executable code |
A018 |
0000 |
pcreate | 2 |
pointer to CREATE's executable code |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A01A |
0000 |
ffailm | 2 |
first free address in low memory pointer |
A01C |
0000 |
ffaihm | 2 |
first free address in hi memory pointer |
Address |
Value (hex) |
Label/Name |
Size (bytes) |
Description |
A01E |
0000 |
s0 |
2 |
reserved for FORTH variable S0 - holds the address of the start of the data stack (r4) |
A020 |
0000 |
rs0 |
2 |
address of start of return stack (r5) |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A022 |
0000 |
keydev | 2 |
keyboard device to use for KSCAN routine in console ROM |
A024 |
0000 |
cursrd | 2 |
cursor delay used in KEY and the editor |
A026 |
0000 |
noscrl | 2 |
data to determine if screen scrolling should be suppressed. >0=suppress |
A028 |
0000 |
scrX | 2 |
x (column) co-ordinate of next character to be displayed on screen |
A02A |
0000 |
scrY | 2 |
y (row) co-ordinate of next character to be displayed on screen |
A02C |
0000 |
xmax | 2 |
screen width - 32, 40 or 80 |
A02E |
0000 |
ymax | 2 |
screen height - always 24 |
A030 |
0000 |
wrap | 2 |
used to determine if wrap-around is used by SCROLL |
A032 |
0000 |
panxy | 2 |
starting screen address (top left) of panel |
A034 |
0000 |
panr | 2 |
number of rows in panel |
A036 |
0000 |
panc | 2 |
number of columns in panel |
A038 |
0000 |
errnum | 2 |
holds io error number of last error |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A03A |
0000 |
spcnt | 2 |
number of bytes remaining in speech buffer |
A03C |
0000 |
spadr | 2 |
address of next byte in speech buffer |
A03E |
0000 |
spcsvc | 2 |
speech service: address of the speech service which should be called |
A040 |
0000 |
synyes | 2 |
0=speech synth not fitted. >FFFF=speech synth detected |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A042 |
0000 |
in | 2 |
holds the current index into the terminal input buffer (TIB) - used by variable >IN |
A044 |
0000 |
latest | 2 |
reserved for FORTH variable LATEST, which points to the most recently defined word in the dictionary |
A046 |
0000 |
here | 2 |
points to the next free byte of memory. When compiling, compiled words go HERE |
A048 |
0000 |
_state | 2 |
is the interpreter interpreting (0) or compiling a word (!=0) |
A04A |
0000 |
tibsiz | 2 |
characters per line: 80 on command line, 64 in blocks |
A04C |
0000 |
_span | 2 |
the number of characters received by EXPECT. See variable #TIB |
A04E |
0000 |
doboot | 2 |
"we're booting" flag (>0=booting) |
A050 |
0000 |
sdelim | 2 |
stores the end of string marker (normally ") for S". the word .( sets it temporarily to a ) character |
A052 |
0000 |
isdbl | 2 |
flag to indicate if NUMBER pushed a double (>0=yes) |
A054 |
0000 |
dpl | 2 |
decimal point location. set by NUMBER (doubles only) |
A056 |
0000 |
cassen | 2 |
if 0 dictionary searches are case sensitive |
A058 |
0000 |
source | 2 |
source-id. -1=string (via evaluate). 0=user input (keyboard/block) |
A05A |
0000 |
dotsin | 2 |
flag for .S to use signed or unsigned numbers |
A05C |
0000 |
base | 2 |
the current base for printing and reading numbers (would normally be 10 or 16) |
A05E |
0000 |
lbase | 2 |
last number base, used by Number to String routine |
A060 |
0000 |
expcnt | 2 |
exponent count, used by Number to String routine |
A062 |
0000 |
lzi | 2 |
leading zero indicator, used by N>S routine to determine if leading 0's are ignored |
A064 |
0000 |
dosign | 2 |
flag for NTS routine. If >0, then NTS will treat numbers as unsigned, set by U. and . |
A066 |
0000 |
_warn | 2 |
redefinition warnings are suppressed if _warn=0 |
A068 |
0000 |
coding | 2 |
!0 if CODE: compiling is active |
A06A |
0000 |
patch | 2 |
holds the CFA of latest word created with CREATE in case DOES> needs to patch it |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A06C |
0000 |
vdpr1 | 2 |
copy of vdp register 1 (stored at 83d4) |
A06E |
0000 |
retbnk | 2 |
holds bank number to return to as a memory address (>6000 or >6002) |
A070 |
0000 |
temp | 2 |
for temporary storage |
A072 |
0000 |
temp2 | 2 |
for temporary storage |
A074 |
0000 |
temp3/seed | 2 |
for temporary storage |
A076 |
0000 |
seedc | 2 |
seed for random number generation |
A078 |
0000 |
sumode | 2 |
graphics mode selected from cartridge menu screen |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
note: These variables use the same addresses as the compiler reference counters (below). This is safe to do, as the compiler is never in use when the editor is in use, and vice versa. Hence it makes sense to use the same addresses and save some valuable user RAM in low-memory. I'm nice like that. |
||||
A07A |
0000 |
epage | 2 |
holds block editor page |
A07C |
0000 |
csrx | 2 |
cursor x for editor |
A07E |
0000 |
csry | 2 |
cursor y for editor |
A080 |
0000 |
csrflg | 2 |
cursor blink flag for editor |
A082 |
0000 |
autorp | 2 |
keyboard auto repeat counter |
A084 |
0000 |
autorl | 2 |
keyboard auto repeat re-load value |
A086 |
0000 |
edblk | 2 |
block number of the block currently being edited |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A07C |
0000 |
ifcnt | 2 |
incremented by IF, decremented by THEN |
A07E |
0000 |
docnt | 2 |
incremented by DO, decremented by LOOP & +LOOP |
A080 |
0000 |
forcnt | 2 |
incremented by FOR, decremented by NEXT |
A082 |
0000 |
cascnt | 2 |
incremented by CASE, decremented by ENDCASE |
A084 |
0000 |
ofcnt | 2 |
incremented by OF, decremented by ENDOF |
A086 |
0000 |
begcnt | 2 |
incremented by BEGIN, decremented by UNTIL, REPEAT & AGAIN |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A088 |
0000 |
sal | 128 |
sprite attribute list |
A108 |
0000 |
smlist | 64 |
sprite movement list |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A148 |
0000 |
sav8a | 2 |
save data following blwp @dsrlnk (8 or >a) |
A14A |
0000 |
savcru | 2 |
cru address of the peripheral |
A14C |
0000 |
savent | 2 |
entry address of dsr or subprogram |
A14E |
0000 |
savlen | 2 |
device or subprogram name length |
A150 |
0000 |
savpab | 2 |
pointer to device or subprogram in the pab |
A152 |
0000 |
savver | 2 |
version # of dsr |
A154 |
0000 |
flgptr | 2 |
pointer to flag in pab (byte 1 in pab) |
A156 |
0000 |
dsrlws | 10 |
dsrlnk workspace |
A160 |
0000 |
dstype | 22 |
|
A176 |
0000 |
haa | 2 |
used to store AA pattern for DSR ROM detection |
A178 |
0000 |
namsto | 8 |
dsrlnk 8 bytes device name buffer |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A180 | 00 | pabopc | 1 | opcode: open, read, etc |
A181 | 00 | pabflg | 1 | error code & file type |
A182 | 0000 | pabbuf | 2 | vdp address of data |
A184 | 00 | pablrl | 1 | logical record length |
A185 | 00 | pabcc | 1 | output character count |
A186 | 0000 | pabrec | 2 | record number |
A188 | 00 | pabsco | 1 | screen offset for char |
A189 | 00 | pabnln | 1 | name length |
A18A | 0000 | pabfil | 32 | file name starts here |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A1AA |
0000 |
falloc | 6 |
Allocation table for file IO. At run time, these 3 cells are filled with addresses f1pab, f2pab & f3pab (see VDP RAM table). The MSB is set when a file is in use (i.e. when opened with #OPEN). The MSB is reset when #CLOSE is executed, and thus the file 'slot' can be re-used. |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A1B0 |
0000 |
totblk | 2 |
number of block buffers available |
A1B2 |
0000 |
blknum | 2 |
holds the block currently being compiled by INTERPRET |
A1B4 |
0000 |
lstblk | 2 |
holds the block currently being worked on |
A1B6 |
0000 |
blk0 | 2 |
block number of the block stored in buf0 (0=unassigned) |
A1B8 |
0000 |
2 |
VDP address of block0 MSB=1=dirty block | |
A1BA |
0000 |
blk1 | 2 |
block number of the block stored in buf1 (0=unassigned) |
A1BC |
0000 |
2 |
VDP address of block1 MSB=1=dirty block | |
A1BE |
0000 |
blk2 | 2 |
block number of the block stored in buf2 (0=unassigned) |
A1C0 |
0000 |
2 |
VDP address of block2 MSB=1=dirty block | |
A1C2 |
0000 |
blk3 | 2 |
block number of the block stored in buf3 (0=unassigned) |
A1C4 |
0000 |
2 |
VDP address of block3 MSB=1=dirty block | |
A1C6 |
0000 |
blk4 | 2 |
block number of the block stored in buf4 (0=unassigned) |
A1C8 |
0000 |
2 |
VDP address of block4 MSB=1=dirty block | |
A1CA |
0000 |
blk5 | 2 |
block number of the block stored in buf5 (0=unassigned) |
A1CC |
0000 |
2 |
VDP address of block5 MSB=1=dirty block | |
note: the vdp addresses of the block buffers are defined in 1-15-Initialise.a99 |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A1CE |
3420 |
tibadr | 2 |
address of the terminal input buffer in VDP memory |
A1D0 |
0000 |
wrdbuf | 80 |
buffer for holding a word string. WORD copies a word string here from the terminal input buffer in VDP RAM. |
A222 |
0000 |
wrkbuf | 32 |
work buffer for Number to String routine (holds exponents) |
A242 |
0000 |
strbuf | 18 |
string buffer for Number to String routine to construct a string in |
Address |
Value (hex) |
Label/Name | Size (bytes) |
Description |
A254 | 0000 | retstk | 52 | return stack |
A2C6 | 0000 | dstack | 62 | data stack |
note: both stacks grow towards lower memory addresses |
User programs start immediately after the stacks, and grow (towards higher memory addresses) towards >FFFF. Note: The 8K section of the 32K RAM is also available for user programs, by changing the variable H to a memory address in low RAM. H tracks the current compilation address (HERE simply reads H). By changing it, you can change the address that the compiler will compile to. Dictionary linkage works normally. Take care when using MARKER when programs are split across high/low memory addresses, as invoking MARKER may leave the current compilation in the wrong memory bank!
Note: TurboForth output is shown below in green.
FFAILM @ H ! \ set H to first free addes in low memory
: FOO CR ." FOO! " ;
FFAIHM @ H ! \ set H to first free address in high memory
: BAR ." BAR!" CR ;
FOO BAR
FOO! BAR!
ok:0
' FOO $.
2008 ok:0
' BAR $.
A2C8 ok:0
<< Home | About Forth | About TurboForth | Download | Language Reference | Resources | Tutorials | YouTube >>