Moving a .PRG for saving?

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
Radical Brad
Vic 20 Devotee
Posts: 256
Joined: Sat Jun 24, 2017 8:18 pm
Website: http://www.AtomicZombie.com
Location: Kakabeka Falls, ONT
Occupation: hACKER

Moving a .PRG for saving?

Post by Radical Brad »

This is going to be a strange question, but something I need to do.

I have hardware that can take a .PRG file (saved from internet), and write it to memory location A000-BFFF in a real VIC-20.
This is normally the expansion ROM location where a cartridge image would live.

What I want to do is with few lines of directly typed basic code, peek & poke it back to it's normal location.
From there, I can just SAVE "Program",8,1 to put it on disk.

Is it just a matter of peeking at the first two bytes here to get the original location of the file?...

Code: Select all

NEWADR = PEEK(40960) + PEEK(40961) * 256
If that assumption is correct, would this then move the file back to its proper location?...

Code: Select all

OLDADR = 40962
FOR X = NEWADR TO NEWADR + 8191 : POKE X , PEEK(OLDADR) : OLDADR = ALDADR + 1 : NEXT
Not sure if I also have to POKE some other address to tell basic where the code lives now?
I also don't care that each program will be 8K in length.

Thanks,
Brad
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Moving a .PRG for saving?

Post by Mike »

For *.prg files, the load address is part of the file (a two-byte header).

This is an adopted convention from the KERNAL LOAD and SAVE calls.

The load address does not appear in memory - at least not at a position 'near' the memory dump. A KERNAL SAVE call puts the load address in front of the memory dump, so there's an easy way to find out where to put back that memory dump, for KERNAL LOAD. You can instruct KERNAL LOAD to re-instate the file data (sans load address) at either the original address (that's called an 'absolute' load) or force it to load the data to another address (again, sans load address) - that's then called 'relative' or 'relocating' load. The latter, relative load, is used by BASIC to load a BASIC programm to the current BASIC start, rather than to the original address it was saved from.

Please refer to my post in the pinned thread 'ROM call & other tricks' here in the Programming section.

...

Now what you have is - some data from an essentially unspecified source, that you've managed to be mapped into the range $A000..$BFFF. If this was from a *.bin file (without load address), the information where the file really should be located is lost.

If your hardware actually maps in the complete *.prg file, including load address, then of course the addresses $A000 and $A001 contain this load address. The information still missing is the length of file, and that's not as unimportant as you might think: if you save an over-length BASIC program away, a memory range behind the BASIC program will not be available for the storage of variables. This can easily lead to an ?OUT OF MEMORY error, even if the program as such fits into memory, because it hasn't anymore enough memory for its variables! Also, you won't ever be able to store away a complete 8K block as *.prg file.

Neither is 'just' moving away the program to another range, and then doing a SAVE"...",8,1 going to help you. The SAVE command has no information, that there has been new data re-instated by some POKE loop somewhere in memory. It will just save away an empty BASIC program or the current program in memory, provided it wasn't overwritten by that copy action.

Suppose you want to use BLK5 as scratch board, filled by PC and stored away by VIC-20: to write *.prg files to disk, you'll need to add an extra step to the protocol, providing the file length and load address independently and then construct a correct *.prg on the CBM disk drive roughly as follows:

Code: Select all

10 <instruct your hardware to map in the file length in $A000/$A001 *excluding* this 2-byte-header>
11 L=PEEK(40960)+256*PEEK(40961)
12 <instruct your hardware to map in the first two bytes of the file in $A000/$A001>
13 A=PEEK(40960):B=PEEK(40961)
14 OPEN2,8,2,"FILE.PRG,P,W":PRINT#2,CHR$(A)CHR$(B);
15 FOR T=0 TO L-1 STEP 8192:S=0
16 <instruct your hardware to map in the next 8K block of the file>
17 IF S+T<L AND S<8192 THEN PRINT#2,CHR$(PEEK(40960+S));:S=S+1:GOTO17
18 NEXT
19 CLOSE2
... or something like this. :)
User avatar
Radical Brad
Vic 20 Devotee
Posts: 256
Joined: Sat Jun 24, 2017 8:18 pm
Website: http://www.AtomicZombie.com
Location: Kakabeka Falls, ONT
Occupation: hACKER

Re: Moving a .PRG for saving?

Post by Radical Brad »

Thanks Mike, this is great info.
The files I will be uploading (.PRG) will most likely have both the location and size bytes intact.
I am just choosing these randomly. Here is an example...

ftp://www.zimmers.net/pub/cbm/vic20/dem ... l%20II.zip

When I have a chance, I will try to make this work based on the great response you offered.

I think the only issue would be a basic program, as it would poke right over the wedge code.
Most of that code should be ok being entered right at the console.

Brad
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Moving a .PRG for saving?

Post by Mike »

Radical Brad wrote:The files I will be uploading (.PRG) will most likely have both the location and size bytes intact.
The load address, yes. The file length can only be inferred from the file system you stored the file in. Notwithstanding of course, that the original source indeed stored the complete file and did not crop it or extend it with padding.
Radical Brad wrote:I think the only issue would be a basic program, as it would poke right over the wedge code.
The pseudo-code I posted above would not be in any danger. It is supposed to write the data from BLK5 directly to a file without any further copy action. You'd then use LOAD"FILE.PRG",8,1 (or any other file name) to load the data back to its correct address.

What you need to fill in are those sections I put into ankle braces <...> - I wouldn't know what registers of your external hardware you'd have to access how, to make exactly those actions supposed to do by the description in the braces. Providing the essential data (length and load address as byte pairs, and raw file data) is entirely up to you.

If you actually do not want to use a disk drive as (temporary) storage, you'd indeed need a small copy loop in machine language. Especially for BASIC programs, you'd also have to relink the link-pointers and set the pointers to the start of variables in 45/46 (a.k.a. 'start of variables'). This then more or less amount to a 'inject-to-RAM' technique.

It would then actually be preferable not to use the huge address range of BLK5 for this purpose, rather you should think about to reserve a small patch in the I/O 2 or I/O 3 area for this. Maybe one 256 byte page. Again, the hardware should first present file length and load address, and then the raw file data in 256 byte chunks. The ML program then simulates the LOAD command, just it doesn't LOAD the program from disk, rather from your external hardware.
User avatar
Radical Brad
Vic 20 Devotee
Posts: 256
Joined: Sat Jun 24, 2017 8:18 pm
Website: http://www.AtomicZombie.com
Location: Kakabeka Falls, ONT
Occupation: hACKER

Re: Moving a .PRG for saving?

Post by Radical Brad »

Ok thanks, I get it now.
This does not move the program to the VIC, but directly to disk.

To explain my test hardware, the actual binary data gets shoved into BLOCK-5 like this...

1) I download a PRG file from some internet archive like Zimmers.
2) The PRG file is converted to AVR assembly by a PC program I wrote.
3) I program the AVR with that file, and the AVR pretends to be ROM to the VIC.

When the VIC powers up, it now has an exact binary image of that .PRG at location 40960.
I can easily rework the binary in my PC program, adding or removing whatever bytes are needed.
I currently rip the first 2 bytes to make games boot like cartridges.

Brad
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Moving a .PRG for saving?

Post by Mike »

Yes, that's what I meant with the "essentially unspecified source". ;)

For cartridge images with load address $A000, you actually don't want the 2 bytes of the load address at $A000/$A001, the cartridge data is wrongly shifted by 2 bytes, and 2 bytes at the end are missing. You clearly want to write the *.bin data - without load address - into the AVR in this case.

Any other use, namely for *.prg files with unspecified length and load address, is better handled by a small transfer program in machine language, which uses a small buffer in I/O 2 or I/O 3 to first "do protocol" (transferring length and load address - the first of which you have to infer from the originating file system, and subtract 2) and then transferring the raw data.

I suppose using a SD2IEC is not your cup of tea? Then you could go the other way and fill the external hardware entirely from the VIC-20 (with data that were put on the SD Card by a PC, of course).
User avatar
Radical Brad
Vic 20 Devotee
Posts: 256
Joined: Sat Jun 24, 2017 8:18 pm
Website: http://www.AtomicZombie.com
Location: Kakabeka Falls, ONT
Occupation: hACKER

Re: Moving a .PRG for saving?

Post by Radical Brad »

At this point, it was just a fun way to see some of the old programs and demos up on the VIC.
When my project is completed, it will have its own ability to reach out to external sources and convert.

The SD2IEC is a great product for sure, but my VIC-20 is banned from touching anything modern.
It would seem wrong to spoil it after 36 years of great service!

Thanks,
Brad
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Moving a .PRG for saving?

Post by Mike »

Radical Brad wrote:At this point, it was just a fun way to see some of the old programs and demos up on the VIC.
When my project is completed, it will have its own ability to reach out to external sources and convert.
Your OS still has a long way to go, though.

If you insist that the VIC-20 shall only operate with standard TTL/NMOS devices, you could still go the way of presenting the data to load as proper cartridge image. A small program in the cartridge image is automatically executed and copies the payload into the internal memory of the VIC-20. I did this some years ago with a game of TRON Light Cycles. There, the extra information of load address and file length was contained within the machine code program, and this method could also be applied to the file of the demo you linked to. It will take me maybe one hour to transfer this file into a cartridge image. Interested?

Edit: I see this is a multi-part demo... which makes this a little more complicated, since the parts insist on loading the next part from disk. You could always try my TRON game, though. :)
User avatar
Radical Brad
Vic 20 Devotee
Posts: 256
Joined: Sat Jun 24, 2017 8:18 pm
Website: http://www.AtomicZombie.com
Location: Kakabeka Falls, ONT
Occupation: hACKER

Re: Moving a .PRG for saving?

Post by Radical Brad »

Yes, that would be cool.

I could feed your image through my PC, across my breadboard, and then into the VIC to see it run.
A binary image is all I need, and will try it tonight.
You can email it to... (mod: removed e-mail)

In the project I am working on, the VIC will have to fill over 10MB os SRAM, which is why I decided to go with a clocked 8 bit IO system. I can't imagine waiting 3.5 hours for my latest graphics demo to load!

Thanks,
Brad
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Moving a .PRG for saving?

Post by Mike »

@Brad: PM sent. :)
User avatar
Radical Brad
Vic 20 Devotee
Posts: 256
Joined: Sat Jun 24, 2017 8:18 pm
Website: http://www.AtomicZombie.com
Location: Kakabeka Falls, ONT
Occupation: hACKER

Re: Moving a .PRG for saving?

Post by Radical Brad »

Looks like fun...

Image

But I cannot get anything to work except F1, which just starts a game that I cannot control.
Joystick has no response, and I tried all the keys.

I was always better at making games than playing them, so it's probably something simple I missed.

Image

Thanks,
Brad
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Moving a .PRG for saving?

Post by Mike »

Radical Brad wrote:Joystick has no response,
Indeed. The game is entirely keyboard controlled.
and I tried all the keys.
In the game, try out Z, C, f1 and f7 as per instructions. You'll need both hands. ;)

The intro melody has to play completely, before the game responds to any key to start.
User avatar
Radical Brad
Vic 20 Devotee
Posts: 256
Joined: Sat Jun 24, 2017 8:18 pm
Website: http://www.AtomicZombie.com
Location: Kakabeka Falls, ONT
Occupation: hACKER

Re: Moving a .PRG for saving?

Post by Radical Brad »

Ah, that would explain it.
I do not have the sound connected.
Will give it a go tonight.

Thanks,
Brad
Post Reply