A0CBM wrote:
I am working up a VIC 20 with a 65C816. My prototype works, I think, and it has 128K of memory. My question involves saving data/programs that extend into bank 1 and above with Commodore drives...is it possible?
Of course it's possible, but be sure to read White Flame's response again before going further.
The on-disk format of a CBM program file consists of a little-endian load address, followed by the program text. It must be understood that the disk itself knows nothing about this, only that a bunch of bytes have been stored in a file that the CBM DOS considers to be a program (type PRG). When the kernel LOAD function is called the kernel sets up the disk to be a TALKer (refer to the operation of IEEE-488 if you aren't sure what that means) and the computer to be a LISTENer. The kernel then repeatedly executes a low-level function called ACPTR ($FFA5), which grabs a byte from the TALKer and puts it into RAM.
In a non-relocating load, the load address in bytes 0 and 1 of the file is used as the start address. Otherwise, the load is to an address specified as part of the LOAD kernel call. In both cases, after a byte has been written to RAM a pointer is incremented to point at the next location in which to write. This process continues until the disk signals that the end-of-data (EOD) has been reached. EOD is determined by examining the ST kernel flag in zero page after each call to ACPTR. I seem to recall that in the VIC-20, C-64 and C-128 kernels it was possible to hang the serial bus by calling ACPTR after EOD had been signaled.
Since the kernel only recognizes 16-bit load addresses, you would have to write a new version of the kernel's SAVE function to generate more load information in the program file. If I were doing it, I'd arrange the following:
Code:
File
Offset Function
——————————————————————————
00 Load address LSB
01 Load address MSB
02 Load bank
03 Unused, set to $00
04 Start of data
——————————————————————————
In the unmodified kernel, when a SAVE is executed, the kernel commands the disk to be a LISTENer and the computer becomes the TALKer. The save itself iteratively calls the low level CIOUT function ($FFA8) to write to the disk. The first and second bytes are the starting address of the block of RAM to be saved, after which bytes grabbed from RAM are written. In your new SAVE function, you'd write the load address, then the bank, both of which would be expressed as 16-bit values. Once the load information has been written you can write your data.
Similarly, a new LOAD function would have to be written to understand your file format. Again, you'd read bytes $00-$03 to get the load address, and then iteratively call the ACPTR function to load the actual text/data. As part of loading and saving, you will need to allocate a 24-bit pointer on zero (direct) page for long indirect access, that is,
[<dp>],Y addressing. As the kenel ROM is effectively in bank $00, using long indirect saves you the trouble of fiddling with banks as you load or save. You would set the 65C816's DB register to $00.