Block save / load

Discussion about ZX80 / ZX81 Software
roganjosh
Posts: 100
Joined: Thu Jun 14, 2018 12:59 pm

Block save / load

Post by roganjosh »

Before I dig into the ROM, has anyone written any ZX81 assembler routines (with source code) that can save/load a specified contiguous block of memory to/from a cassette (preferably prefixed with a program name)?

Alan
User avatar
mrtinb
Posts: 1906
Joined: Fri Nov 06, 2015 5:44 pm
Location: Denmark
Contact:

Re: Block save / load

Post by mrtinb »

There is no ROM routine to load/save a specified block of memory to tape.

The routine in ROM will only load/save from location $4009 and X bytes forward, where X = (address stored @ $4014+$4015) - $4009.

Special hardware e.g. ZXpand might implement routines to save any location to storage.

This is why there is not data files on ZX81. When programs are saved, they are saved along with the data.
Martin
https://zx.rtin.be
ZX81, Lambda 8300, Commodore 64, Mac G4 Cube
Moggy
Posts: 3231
Joined: Wed Jun 18, 2008 2:00 pm

Re: Block save / load

Post by Moggy »

Whilst it cannot be done directly from the ROM it can be be done by making an altered copy of the ROMs save/load routines. This way you could save,say for example, the variables area only then reload same.

In his book "Advanced programming for the ZX81" author Mike Costello shows one such method.
The PDF can be found here...
https://datassette.nyc3.cdn.digitalocea ... zx81.pdfen

Pages 105 to 107 then page 120 are the pages of relevance here.


Also this taken from Sinclair User July 1983 answers a question asked by Richard Mellor (sounds familiar?)

QUOTE.
"Richard Mellor poses a question which does not concern the display file but the solution involves saving information above RAMTOP in a similar manner to storing the display. He asks: Is it possible, on the ZX-81, to load and save variables only from within a program so that they can be loaded in at a later date and reused?

The ZX-81 LOAD and SAVE routines transfer to and from cassette all the information between address 16384 and the address held in the system variable called STKEND. Inspection of the memory map on page 171 of ZX-81 Basic Programming shows that most of the active contents of memory - the system variables, the program, the display and the variables and the like - lie between 16384 and STKEND. Hence those items are transferred automatically by the LOAD and SAVE commands.

It is unfortunate that the starting address is fixed at 16384. If it was determined by the contents of an extra system variable it would be possible, by POKEing suitable values into the system variable, to LOAD or SAVE portions of memory as can be done on the Spectrum. An alternative would be to copy the SAVE and LOAD routines into RAM, alter them and then use the new routines instead of the originals.

A simpler solution is to copy the contents of the memory area which is required separately - in this case the variables area - above RAMTOP, SAVE the program, copy the variables back again and then SAVE them separately. The reverse procedure is used when LOADing the program and the variables.
Sinclair printout

Supposing a two-dimensional array P(5,2 3) is to be SAVEd separately from the program. The first task is to determine how much memory is required in the variables area, and therefore also above RAMTOP, to store the array. It is possible to calculate the space requirements using the information in chapter 27 of ZX-81 Basic Programming but it is probably easier to let the machine do the work for you. First clear the ZX-81 by entering NEW and define the array by entering:

DIM P(5,23)

Then calculate the length of the variables area by checking the value of the two systems variables VARS - which points to the beginning of the area - and E-LINE - which points to one more than the end of the variables area. The difference between E-LINE and VARS less one, i.e. PEEK 16404 + 256*PEEK 16405-1-PEEK 16400-256*PEEK 16401 is the length of the variables area and, as the array P is the only variable, it is also the length of P. In this case P proves to be 583 bytes long - five bytes for each of the 5*23 = 115 elements of the array plus another eight bytes to hold various ancillary information as shown on page 173 of the manual.

Thus at least 583 bytes of memory are required above RAMTOP to provide temporary storage for the array. Reducing the contents of 16389 from 128 to 125 reserves 3*256 = 768 bytes, hence enter POKE 16389,125 followed by NEW.

The program can then be LOADed from cassette and the two routines listed in table three can be added to it. The two routines transfer the first 583 bytes of the variables area to and from the space above RAMTOP in much the same way as the display was transferred previously. There is one more requirement of the program. That is that the array must be the first variable declared by the program. That ensures that the array lies at the bottom of the variables area.

100 REM STORE P(5,23) ABOVE RAMTOP
110 LET I=PEEK 16400+256*PEEK 16401
120 LET J=PEEK 16388+256*PEEK 16389
130 FOR K=0 TO 582
140 POKE J+K, PEEK(I+K)
150 NEXT K
200 REM RECALL P(5,23) FROM ABOVE RAMTOP
210 LET I=PEEK 16400+256*PEEK 16401
220 LET J=PEEK 16388+256*PEEK 16389
230 FOR K=0 TO 582
240 POKE I+K, PEEK(J+K)
250 NEXT K

Table 3. Two ZX-81 routines to store an array p(5,23)
above RAMTOP and to retrieve it.

That final requirement makes it difficult to use the technique with ordinary string variables because they can move up the variables area when they are redefined by the program. It is therefore best to use the technique only with numeric variables, arrays and string arrays.

Two simple machine code loops could be used to transfer the data in a similar manner to the loops in table two. That is left as an exercise for the reader."

END QUOTE.
roganjosh
Posts: 100
Joined: Thu Jun 14, 2018 12:59 pm

Re: Block save / load

Post by roganjosh »

Thanks. Yes indeed, my intention was/is to lift/modify existing ROM code (it looks like my post wasn't clear enough on that point) but I was hoping to save myself a bit of work. I have a ZXPAND+ and use its block save/load regularly. However I do have the need for a standalone ZX81 tape method.

Thanks for the book link suggestion Moggy. On the face of it it's not a substantial improvement on the comments provided in the ROM disassembly. Much appreciated though. I'll see if I can find a hidden gem within.

I just find it a little odd that in the 40 years the ZX81 has been with us that no one has released any code to do it - it's such an obvious thing to want to do. I'll add it to my 'mysterious' folder.

Alan
roganjosh
Posts: 100
Joined: Thu Jun 14, 2018 12:59 pm

Re: Block save / load

Post by roganjosh »

OK. Here are a couple of routines to do block saves/loads to/from cassette tape. They are modifications of the ROM routines. They've been tested within EO. Note that files created using the block save routine will likely hang your machine if you try loading it with the BASIC LOAD command. I may add more functionality at a later date but they satisfy my current requirements. The routines are documented at the top of (and within) the ASM file.
block.zip
(1.91 KiB) Downloaded 216 times

Alan
User avatar
siggi
Posts: 988
Joined: Thu May 08, 2008 9:30 am
Location: Wetterau, Germany
Contact:

Re: Block save / load

Post by siggi »

If the block size is max. 8kByte (e. g. a rom image): I once wrote a block save/restore program (in C), which stores a memory block up to 8192 bytes in its own variable region inside the program. You then can SAVE that as P-File or on tape, using any usual program storage method (also standard LOAD/SAVE).
Later you can reload that program and restore the stored 8K image to its original or any other memory location.

Would that help?

Siggi
My ZX81 web-server: online since 2007, running since dec. 2020 using ZeddyNet hardware
http://zx81.ddns.net/ZxTeaM
roganjosh
Posts: 100
Joined: Thu Jun 14, 2018 12:59 pm

Re: Block save / load

Post by roganjosh »

siggi wrote: Sun Mar 21, 2021 6:01 pm
Would that help?

Siggi
Thanks for the thoughtful offer but extracting and modifying the relevant routines from ROM, as I posted above, provided just the functionality I needed.

Alan
procount
Posts: 3
Joined: Mon Sep 13, 2021 12:57 am

Re: Block save / load

Post by procount »

This issue seems to be resolved now, but as I've just come across this forum, I thought I would share an alternative.

Back in August 1983, I wrote an article for Your Computer magazine (Vol 3 No. 8) called "Cassette Files" where I presented my assembler program to save and load data files by name from any contiguous memory block region. It uses the standard load/save ROM routines, but prefixes each file on the tape with a small header containing just the name of the following data file. In that way you can quickly find where you are on the cassette tape without having to load the whole of a program or data file into the computer.

At the time I didn't realise there were 2 versions of the ROM, until someone pointed it out in the October Letters section and provided the few changes that needed to be made to the program for it to work with the newer ROMs. That's quite some dedication considering YC didn't print any assembly listing of the program.

Someone has kindly archived a copy of this issue of the magazine https://ia800704.us.archive.org/34/item ... 983_08.pdf, so if you feel like going back in time and typing in the HEX code (oh those were the days!) you're very welcome to. Unfortunately I can't remember what bytes needed to be changed for the newer ROMS. I think it was just 2 function calls that moved, but I'm sure someone can work them out if necessary.

EDIT: I found the changes necessary for the newer ROMS from after the end of 1981:
Poke:
31700 - 43 (decimal)
31898 - 43
32048 - 43
32060 - 35
32351 - 70
These are apparently the calls to the Slow, Fast and Test for Break routines.
Last edited by procount on Mon Sep 13, 2021 4:34 pm, edited 1 time in total.
User avatar
1024MAK
Posts: 5101
Joined: Mon Sep 26, 2011 10:56 am
Location: Looking forward to summer in Somerset, UK...

Re: Block save / load

Post by 1024MAK »

Thanks :D

Oh, by the way, we now know that there were three ROM versions!

Mark
ZX81 Variations
ZX81 Chip Pin-outs
ZX81 Video Transistor Buffer Amp

:!: Standby alert :!:
There are four lights!
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb :!:
Looking forward to summer later in the year.
procount
Posts: 3
Joined: Mon Sep 13, 2021 12:57 am

Re: Block save / load

Post by procount »

Three? :o
I am out of touch!

At the time, I added some extra RAM for a programmable character generator, 3x 2K eproms for my assembly routines, a serial port, digital and analog joysticks and put it all in a DKTronics keyboard. Having blown the dust off it, I'm finding the modulator doesn't work so I'm following the threads on composite mods etc to see if I can get it working with a modern TV again.
Post Reply