Relocating VIC Loads
Tony Valeri
When you need to relocate a program in the VIC's memory, you can use this simple technique.
As most VIC users know, the VIC relocates all programs to the start of BASIC memory unless told otherwise. For example, LOAD 1, 1 tells the computer to load the program into the area of memory specified by the tape.
So we have two choices; we can either load a program into the start of BASIC memory (usually $1000 hex) or load a program back into its original location in memory (using a monitor like TINY-MON). But what if we want to place a previously prepared subroutine at the end of a program, or relocate a machine language program to some novel place in memory? There's not much we could do short of retyping it.
Basically, what happens during a LOAD is that, after a few pointers are stored (buffer location, program name, etc.), a routine is called that searches the tape for the next program header, and then reads it into the cassette buffer. The load routine next checks the buffer to find out whether the program being loaded is to be placed into the locations specified in the buffer or is to be relocated to the start of BASIC. Now, if we could by-pass the routine that does this, things would be much simpler.
In the figure, you'll see the locations necessary to relocate a program anywhere in the VIC's memory.
Use a SYS 63407. The computer will prompt with the usual PRESS PLAY ON TAPE. The difference is that the computer now prints READY as soon as the program is found. What has happened is that the SYS 63407 tells the computer to load the next program header and store the information in the cassette buffer.
To find out the original start and end locations of your program, type in PRINT PEEK(829) + PEEK(830)*256, PEEK(831) + 256*PEEK(832).
Increasing the value in locations 829 and 831 by one will place the program one byte higher in memory. Increasing the value in locations 830 and 832 by one will place the program 256 bytes higher in memory. Decreasing the values in these locations will have the opposite effect.
After the buffer has been changed, a SYS 62980 will return control of the computer to the load routine. Now load the main body of the program into memory, but load it into the new locations just specified.
See It Work
To demonstrate this technique, we'll fill the screen with data from tape. The demonstration is for the unexpanded VIC, so you'll need to remove or disable any memory expansion. To prepare, type in the following line in direct mode:
POKE46, PEEK(46) + 2
This reserves two pages (512 bytes) at the end of your BASIC program for data.
Type in the following one-line program exactly as it appears. Any additional spaces will cause errors. The program will fill the space between the end of the program and the start of variables with the screen POKE value for the ball character.
10 FORA = 4124 TO 4629 : POKEA, 81 : NEXT
After checking your typing, RUN the program then SAVE it to cassette.
Next, rewind the tape and reset the VIC with a SYS 64802. Start the relocatable load by typing:
SYS 63407
After the VIC reads the tape header into its buffer you can check the original start and end addresses by PEEKing addresses 829 – 832 as indicated above. The starting and ending addresses should be 4097
HEX | DEC | |
Routine To Load Header | $F7AF | 63407 |
Buffer Start Of Prog. | $033D & $033E | 829 & 830 |
Buffer End Of Prog. | $033F & $0340 | 831 & 832 |
Continue Load | $F607 | 62980 |
Locations necessary to place a program anywhere in the VIC's memory.
and 4636. Instead we want to put the block of 506 ball characters into screen memory, which starts at location 7680. To accomplish this, type in the following series of POKEs:
POKE 829,229 : POKE 830,29 : POKE 831,0 : POKE 832,32
You'll need to prepare the screen by changing the colors to make the balls visible. Try POKE 36879,76. Finally, complete the tape LOAD by typing:
SYS 62980
The data coming in from tape will be directed to the screen memory area and will fill the display with ball characters.