Block save / load
Re: Block save / load
Three official ROMs and a plethora of unofficial ones, the latest being the "Big Bang" double speed BASIC ROM.
The thread and ROM image can be found here..
https://sinclairzxworld.com/viewtopic.php?f=5&t=2986
The thread and ROM image can be found here..
https://sinclairzxworld.com/viewtopic.php?f=5&t=2986
Re: Block save / load
I had typed up this program a few years ago for submission to the Type Fantastic website but found the program didn't work when I tested it. The hex byte listing on the second page wasn't very clear and so it was hard to tell if I'd typed in all bytes correctly (especially Bs and 8s). It's been on my list to delve into the program and debug it to find all the typos. Now seemed like a very appropriate time to do this!
So here is the working copy of the program, along with typed up instructions and a modified version for the Edition 2/3 ROMs (updated the zip due to a typo found in the edition 2/3 ROM version):
It's a very nice program, providing a comprehensive set of tape facilities!
Last edited by Fruitcake on Sun Sep 19, 2021 3:06 am, edited 2 times in total.
Re: Block save / load
Brilliant!
Thanks for doing that and for your comments.
I was a young wippersnapper back then, just learning Z80 assembly and hand converting it to the hex code as I didn't have an assembler!
Thanks for doing that and for your comments.
I was a young wippersnapper back then, just learning Z80 assembly and hand converting it to the hex code as I didn't have an assembler!
Re: Block save / load
Here's an uncommented disassembly of the program, which would be a start should you wish to revisit the code and create a fully commented listing:
Re: Block save / load
I found a typo had crept into the edition 2/3 ROM version of 'Cassette Files' so I've updated the zip above. If you have downloaded the original zip then please replace it with the new zip.
-
- Posts: 19
- Joined: Tue May 30, 2017 1:26 am
Re: Block save / load
Great program and great job Mr Fruitcake in typing that up and the Assembler file.. It's also good to see another ZX81 programmer reunited with his code and back on the machine!!
Regards
Steve.
Regards
Steve.
Re: Block save / load
My choice for z88dk was digging into the MUSAMY tool.
The audio encoding (close to the Spectrum one) is less prone to failures caused by distortion and the SAVE speed can be adjusted (LOAD is auto adaptive).
https://github.com/z88dk/z88dk/tree/mas ... /zx81/tape
The audio encoding (close to the Spectrum one) is less prone to failures caused by distortion and the SAVE speed can be adjusted (LOAD is auto adaptive).
https://github.com/z88dk/z88dk/tree/mas ... /zx81/tape
Re: Block save / load - TZX Manager
Hello,
having the idea such a function could be useful in own programs I reviewed the code (Kevin Hill 1983) in more detail to learn how this could be done.
In principle the program seems to work.
I am saying "in principle" as for one I am working with an emulator not knowing how representative this might be for real hardware.
The second reason is that instead of the expected 2 parts the TZX Manager is coming up with four parts (with content as expected):
- Name
- Start, length
- Name
- data block
I assume on a real tape the data would be simply sequential but the TZX is identifying them as being separate blocks?
So the first question I am having is: For the TZX would one have to use a single memory block, i.e. copy first name and any metadata next to the data and write all in a single go? Or can this somehow get controlled?
The second issue I am having is related on getting the TZX starting up.
This code is starting the TZX while it using a call into ROM to OUT_BYTE $031E. I copied this code as well with this idea to eventually play around on bit level. But using a plain copy where I think I have not changed anything:
is not starting the TZX. Although the wave loader seem to indicate that some output is happening. What might I be missing to get the TZX-Manager to react?
Here is the version from procount/fruitcake with same additional comments and descriptive labels as well as a sample in Basic (FASM-ZX or ZX-IDE):
having the idea such a function could be useful in own programs I reviewed the code (Kevin Hill 1983) in more detail to learn how this could be done.
In principle the program seems to work.
I am saying "in principle" as for one I am working with an emulator not knowing how representative this might be for real hardware.
The second reason is that instead of the expected 2 parts the TZX Manager is coming up with four parts (with content as expected):
- Name
- Start, length
- Name
- data block
I assume on a real tape the data would be simply sequential but the TZX is identifying them as being separate blocks?
So the first question I am having is: For the TZX would one have to use a single memory block, i.e. copy first name and any metadata next to the data and write all in a single go? Or can this somehow get controlled?
The second issue I am having is related on getting the TZX starting up.
This code is starting the TZX while it using a call into ROM to OUT_BYTE $031E. I copied this code as well with this idea to eventually play around on bit level. But using a plain copy where I think I have not changed anything:
Code: Select all
0108: [4111] 5E OUTBYTE:LD E,(HL)
0109: [4112] 37 SCF
010A: [4113] CB 13 EACHBIT:RL E
010C: [4115] C8 RET Z ; return after 8 bits
010D: [4116] 9F SBC A,A
010E: [4117] E6 05 AND $05
0110: [4119] C6 04 ADD A,$04
0112: [411B] 4F LD C,A ; if bit c=9, else c=4
0113: [411C] D3 FF PULSES: OUT ($FF),A
0115: [411E] 06 23 LD B,$23
0117: [4120] 10 FE DELAY2: DJNZ DELAY2 ; 35*8+13 T-states / 3.25 MHz = 0.09 msec
0119: [4122] CD 46 0F CALL break1 ; BREAK-1 A=+7F, IN A,(+FE)
011C: [4125] 30 0C jr nc,REPORTD
011E: [4127] 06 1E LD B,$1E
0120: [4129] 10 FE DELAY3: DJNZ DELAY3 ; 30*8+13 T-states = 0.08 msec
0122: [412B] 0D DEC C
0123: [412C] 20 EE JR NZ,PULSES
0125: [412E] A7 DELAY4: AND A ; reset carry for bit counter
0126: [412F] 10 FD DJNZ DELAY4 ; trailing silence 256*8+13 = 0.6 msec
0128: [4131] 18 E0 JR EACHBIT
012A: [4133] C3 A6 03 REPORTD:jp $03A6 ; allow relative jump inside SAVE
Here is the version from procount/fruitcake with same additional comments and descriptive labels as well as a sample in Basic (FASM-ZX or ZX-IDE):
-
- Posts: 5
- Joined: Thu Oct 24, 2019 9:39 pm
Re: Block save / load
The Brazilian ZX81 clone, TK85 came with an extra 2K ROM at 8192-10239 with hi speed (4200 bps) save, load and verify, and what they called DSAVE, DLOAD and DVERIFY, which would save the contents of a string to tape. Strings on the ZX81 are more like byte arrays, and can contain binary data. This string could be saved and loaded at 300 bps, so you could read a tape into a variable, and re-save it to another tape, allowing the copying of programs up to around 14K.
To save the contents of A$, you'd use something like this:
Z is the length of bytes to write
Z$ points to the name of the variable you want to save (A$ in this example)
Here's a list of entry points:
HISAVE = 8405
HILOAD = 8630
HIVERIFY = 8539
DSAVE = 8288
DLOAD = 8305
DVERIFY = 9816
DHLOAD (4200bps) = 9008
DHSAVE (4200bps) = 9189
There's a whole list of return codes if an error occurs.
The high-speed routines appear to be based on QSave by PSS Software, and use frequency shift keying. The base frequencies are approximately 5710Hz and 3057Hz, but varied slightly (the pulses at the end of a byte are slightly longer due to the extra code to fetch a new byte.
To save the contents of A$, you'd use something like this:
Code: Select all
10 DIM A$(12000)
...
(manipulate A$)
...
100 LET Z=LEN(A$)
110 LET Z$="A"
115 LET STATUS = USR 8288
Z$ points to the name of the variable you want to save (A$ in this example)
Here's a list of entry points:
HISAVE = 8405
HILOAD = 8630
HIVERIFY = 8539
DSAVE = 8288
DLOAD = 8305
DVERIFY = 9816
DHLOAD (4200bps) = 9008
DHSAVE (4200bps) = 9189
There's a whole list of return codes if an error occurs.
The high-speed routines appear to be based on QSave by PSS Software, and use frequency shift keying. The base frequencies are approximately 5710Hz and 3057Hz, but varied slightly (the pulses at the end of a byte are slightly longer due to the extra code to fetch a new byte.
Re: Block save / load
The listing 8.3 is the routine to read 1 byte from cassette (c is the byte read)