Commodore‎ > ‎BASIC‎ > ‎Keywords‎ > ‎


Keyword Abbreviation Token (hex) Version(s) Classification
FETCH F{Shift+E} FE 21 7.0 Command and Statement

FETCH byteCount , systemAddress , externalAddress , externalBank
Parameters Type Legal Value(s) Default Value Note(s)
byteCount Unsigned Integer 0 ~ 65535 0 acts like 65536
systemAddress Unsigned Integer 0 ~ 65535    
externalAddress Unsigned Integer 0 ~ 65535    
externalBank Unsigned Byte  0 ~ 15     
Memory initialization.  Load system RAM from an external "RAM Expansion Unit".

FETCH is used to load data into the system from a special cartridge with a DMA controller.  This was desgined for Commodore's 1700, 1750, and 1764 devices; each known as an REU (RAM Expansion Unit).  Some other devices, like the 1541 Ultimate, also have a compatible DMA controller.  Other RAM expansions devices (without a DMA controller), like GeoRAM, will not work with command.
The C128 must have the CPU running at SLOW speed for this to work correctly.
The byteCount specifies the number of bytes to get.  A value of 0 specifies 65536 bytes for most devices, but should never be used.
The systemAddress is a 16-bit address inside the host computer.  The "system bank" is not given in this command; use the BANK command to set the desired bank inside the computer.  Note the original ROMs of the C128 (start-up says copyright 1985) do not set the correct RAM bank, although it does set the correct I/O and ROM configurations.  However, loading data into I/O registers is not reliable.
The externalAddress is a 16-bit address in the R.E.U., and forms the "low word" of the starting address in the R.E.U. where that data will data will come from.  The externalBank is a 4-bit "bank" in the R.E.U. and forms the "high word" of the starting address in the R.E.U.  The FETCH command limits externalBank to a maximum of 15, so the largest REU this supports is 1 MiByte.
The CPU is disabled while R.E.U. performs the transfer.  This means interrupts (for video events and RS-232 communication) will be delayed.  The R.E.U. is so fast, however, that unless you transfer a large number of bytes the loading will seem instant.  Of course what seems instant for a human may be a long time for a computer, so it may cause problems in some cases.
While transferring data, the REU's address can wrap from one bank to the next; however the wrap from the last bank back to the first bank is not reliable.
While transferring data, the REU updates the address where data goes inside the computer, however it can not wrap the computer's BANK.
If no REU is connected, the command will usually silently succeed.  However, it is possible that some other cartridge device that uses the same registers as an R.E.U. would see the command and result in other behavior.
If any of the parameters are omitted, or if they are an invalid expression, SYNTAX ERROR occurs.  If any parameter is a string expression, TYPE MISMATCH ERROR occurs.  Floating-point values are converted with INT.  If the result is not a Legal Value (see table above) then an ILLEGAL QUANTITY ERROR occurs.
You need to consult a good memory map to know which systemAddresses are safe to load with data.  Loading the wrong addresses with data will cause strange results or crash the system.
The externalAddress and externalBank are not critical.  Usually if you specify an address that doesn't exist in the R.E.U., the address will wrap-around to a valid value.  Of course you need to know where data is stored in the R.E.U. in order to successfully load it into the computer's RAM.  This is totally up to the programmer/user.
Unfortunately loading a BASIC program is not simple.  Although you can FETCH the data from the REU, you need to POKE the secret variable "End of Text" if you plan to edit the program or save it to disk; but the REU can't tell you where the end of the loaded program is.  It should be okay if you load more than enough bytes that include the full program and you only RUN or LIST it (i.e., don't try to change it or save to cassette/disk).  Also remember the systemAddress for the start of the BASIC program will vary depending on whether a VIC/TED bitmap has been allocated or not. 
Assuming you don't have buggy ROMs, loading variables is also possible.  This is only practical with non-string variables.  You don't need to PEEK secret variables however (you can if you like) because there is the POINTER function.  It will tell you the address (in BANK 1) where a variable is currently located.  You can use that to load one or more variables (even an array) into RAM.  However there should already be enough variables exisiting in BANK 1 because FETCH won't update any secret variables (like "Start of Arrays" or "End of Arrays").
Example (for C128):
BANK 0 : REM load into bank 0

FETCH 512,3584, 0,0 : REM load sprites from REU address 0, bank 0

FETCH 32768,7169, 512,0 REM load 32K BASIC program from REU address 512, bank 0

BANK 1 : DIM A(9,9) : REM load into bank 1, create floating array 10x10

FETCH 500,POINTER(A(0,0)), 0,1 : REM load array from REU address 0, bank 1

  Compare With  
  Contrast With  
  See Also  

© H2Obsession, 2014