Access:
Using All The 130XE's Memory
Mark Slagell
This compact machine language program opens up an extra 64K of programming space for BASIC programmers who own an Atari 130XE. No machine language knowledge is needed to use it.The Atari 130XE is ostensibly a 128K machine, but half of that memory is useless to many BASIC programmers. BASIC doesn't know about the added 64K of memory, nor does the operating system. The reason for this concerns how the computer's microprocessor "sees" memory. The processor in the 130XE uses 16-bit numbers to select memory locations, which limits it to locations with addresses in the range 0-65535. Thus, the computer can access only one 64K (65536-byte) segment of memory at any given time.
Atari circumvented this limitation for the 130XE by creating an access windowat locations 16384-32767. The 130XE can see any one of five different 16K banks of memory in that space: the normal RAM for those addresses or one of four 16K chunks of the extra 64K. The only catch is that when you bring a new segment of memory into the access window, it replaces whatever was there. All of the 130XE's memory is usable—just not at the same time.
At first, this scheme seems most inconvenient. Except in very short programs, BASIC uses the memory in the access window for variable storage. In fact, many programs will themselves reside partly in the access window, since it occupies over half of BASIC'S free space. If you don't understand this system, it's easy to lock up the computer when trying to use extra memory from BASIC.
Fast Bank Switching
"Access" is a short machine language program that allows you to access the extra memory from BASIC with safety and convenience. It switches one of the blocks of extra memory into the access window, performs the necessary read or write operation, then restores the true memory before it returns control to BASIC. All transfers between banks occur at the rate of about 9000 bytes per second.
BASIC still won't know that the extra memory is there, so you won't be able to use it to add more program lines. But you can PEEK and POKE freely in this space; store strings, arrays, and display screens in it; and even use it to pass data from one program to another.
You won't have to worry about the configuration of the four banks of extra memory. Given an address in the extra memory area from 0-65535, the correct bank will be selected and brought into the access window. This gives you the virtual equivalent of an additional 64K of memory to work with.
Starting Out
Type in and save "Access Loader." It's a BASIC loader that POKEs the machine language Access program into memory. Be sure to press RESET to disable the Proofreader before you run the program. The machine language fills most of page six. That's a popular area for machine language programs; if you already use that zone for something, see "Machine Language Notes" at the end of this article.
Once Access has been installed, you have access to 64K of auxiliary memory. The Access package consists of three machine language routines. Lines 1-2 of the loader program assign the addresses of these routines to the variables AUXBYTE, AUXDUMP, and AUXLOAD. Each routine can then be called with the USR function, the appropriate address variable, and one or more additional parameters. Here's how to use them.
The AUXBYTE operation lets you do the equivalent of a PEEK or POKE in auxiliary memory. The following statement works like a PEEK. The value in location address in extra memory will be assigned to the variable X (address can be any number in the range 0-65535):
X=USR(AUXBYTE, address)
This statement works like a POKE, storing the value of the variable X in the specified address in extra memory:
X = USR(AUXBYTE, address, value)
The AUXDUMP operation works like a multibyte version of POKE, moving an entire block of values from normal memory into the specified block in extra memory:
X=USR(AUXDUMP, source, destination, size)
The source and destination parameters indicate the starting addresses of the source block in normal memory and destination block in extra memory, respectively. The size parameter indicates how many bytes to move.
The AUXLOAD operation is like AUXDUMP in reverse—it transfers the contents of a block of values from extra memory into normal memory:
X - USR(AUXLOAD, source, destination, size)
In this case, source is the starting address of the block in extra memory and destination is the starting address of the block in normal memory.
To take a simple example, the statement X=USR(AUXBYTE, 1790, 200) stores the value 200 in location 1790 in extra memory. The statement PRINT USR (AUXBYTE, 1790) does the equivalent of a PEEK of that location, and should produce 200 if you stored as previously mentioned. Note that location 1790 in normal memory is unaltered. Now try saving an entire screen. Type the following commands, ending each line with RETURN:
LIST
SCREEN = PEEK(88) + 256 * PEEK(89)
X = USR(AUXDUMP,SCREEN,0,960)
PRINT CHR$(125)
POSITION 2,23
After you execute those statements, the screen is stored in locations 0-959 of auxiliary memory. To retrieve the screen, type this statement and press RETURN:
X = USR( AUXLOAD,0,SCREEN,960)
A little arithmetic shows that you have enough room in auxiliary memory to store 68 text screens.
Using Access In Your Programs
When you type NEW after having loaded and run the Access Loader program, the machine language in page six of memory remains intact for your use. However, the variables AUXBYTE, AUXDUMP, and AUXLOAD are no longer defined. For this reason, any program using Access should begin with those assignments (simply copy the first two lines from the loader program). Alternatively, you can substitute the actual addresses for the variables: 1624 for AUXBYTE, 1655 for AUXDUMP, and 1718 for AUXLOAD.
If you have a disk drive and an Atari version of DOS, Access can be configured as an AUTORUN.SYS file to make it present whenever you boot the system. To do this, change the following lines in the loader program and run it with a disk in the drive.
PK 90 OPEN #3,8,0,"D: AUTORUN.SYS"
LJ 100 FOR I=1 TO 251:READ A :PUT #3,A:NEXT I
FO 110 CLOSE #3
PH 120 DATA 255,255,0,6,244,6
These routines should not be used if you're using the extra memory of the 130XE as a ramdisk. Since RAMDISK.COM will run automatically from DOS 2.5 when you turn the machine on, make sure that file is not on the disk you boot up with.
Machine Language Notes
You may wish to add other machine language routines to this program, such as an AUXSEARCH, or an AUXMOVE that transfers blocks of data from one auxiliary memory area to another. Here are some instructions for addressing single bytes in auxiliary memory.
To load a byte, place the target address in locations 214-215 (low byte at 214, high byte at 216) and perform JSR 1560. Upon return from the subroutine, the contents of the specified auxiliary memory location can be stored at location 212. To store a byte, place the target auxiliary memory address in locations 214-215 as described above, and place in location 212 the value to be stored in auxiliary memory; then perform JSR 1536. In either case, locations 215 and 217 are changed, along with the A register. The Y register is cleared.
Access can be moved out of page six if desired. However, it cannot be moved into the access window itself. Be sure to change all the JSR commands in the program (they appear as the sequences 32,0,6 and 32,44,6 in the loader program). For instance, if you move the program to page 29 (locations 7424-7670), those instructions would become 32,0,29 and 32,44, 29, respectively. Finally, don't forget to change the values of the BASIC variables AUXBYTE, AUXDUMP, and AUXLOAD accordingly.
Access Loader
For Instructions on entering this program, please refer to "COMPUTE!'s Guide to Typing In Programs" in this issue of COMPUTE!
FN 1 AUXBYTE=1624
LK 2 AUXDUMP=1655 : AUXLOAD=1718
LI 100 FOR I=1536 TO 1780 : READ A : POKE I, A : NEXT I
BE 1000 DATA 160,0,173,1,211,41,195,133,217,165,216,41,192,74
CE 1010 DATA 74,74,74,9,32,5,217,141,1,211,165,216,41,63
OP 1020 DATA 9,64,133,215,165,212,145,214,165,217,9,48,141,1
BD 1030 DATA 211,96,160,0,173,1,211,41,195,133,217,165,216,41
GA 1040 DATA 192,74,74,74,74,9,32,5,217,141,1,211,165,216
PH 1050 DATA 41,63,9,64,133,215,177,214,133,212,165,217
FF 1060 DATA 9,48,141,1,211,96,104, 133,245,198,245,104,133,216
BL 1070 DATA 104,133,214,165,245,208,6,32,44,6,132,213,96,104
DC 1080 DATA 104,133,212,32,0,6,24,144,243,104,104,133,225,104
BE 1090 DATA 133,224,104,133,216,104,133,214,104,133,227,104,133,226
AH 1100 DATA 160,0,132,229,132,228,177,224,133,212,32,0,6,230
JH 1110 DATA 224,208,2,230,225,230,214,208,2,230,216,230,228,208
DD 1120 DATA 2,230,229,165,228,197,226,208,225,165,229,197,227,208
DE 1130 DATA 219,96,104,104,133,216,104,133,214,104,133,225,104,133
NC 1140 DATA 224,104,133,227,104,133,226,160,0,132,229,132,228,32
HB 1150 DATA 44,6,165,212,145,224,230,224,208,2,230,225,230,214
LK 1160 DATA 208,2,230,216,230,228,208,2,230,229,165,228,197,226
JA 1170 DATA 208,225,165,229,197,227,208,219,96