MASK does not load at all, not matter what options and manual starting/stopping of the tape I try. This applies to both the TZX available on World of Spectrum (sha256 9ae1017e5999d9b773d106a0bb623ee0057833475bfc567236d5a9a46c90e8b8) and the "v1.20" TZX available from the TZX Vault (sha256 e522f544f2d5330c42ebb9557d51b1aa0b29254570f0279883c0b77725bc43b4 - perhaps significantly, this turns out not to be a v1.20 TZX file at all!)
See also bug 23 - not sure if we ever saw a working version of MASK then.
Okay, I did some tests with my loader. A table with
Mine is a turbo loader, but—as virtually any other loader out there—follows closely in the footsteps of the standard ROM loader. Bits 3 and 4 were changed right before the OUT ($FE),A instruction which changes the border color as well.
A few extra considerations:
1. Some of the crackling on the 128K could be attributed to EMI (noise).
2. It's a little odd that at a particular configuration the 128K does detect the pilot tone.
3. I used the Sound jack on the +2A for the loading. (It's a mod; assume a non-modified +3).
If there's sufficient interest, I can provide all eight versions of my loader (including the unmodified "proper" original) that I used to produced the results above.
Last edit: Nicholas Naime 2019-01-18
I can't be very helpful with loaders stuff, but I've found that zx1 stated at WOS that some loaders are polarity sensitive:
Thanks Sergio, I actually think it's very useful to have a list of potentially problematic loaders.
Interestingly enough I gave a quick try to the other games on that list, and apart from Basil I can load all of the other ones with Fuse without problems, even Forbidden Planet (although this one seems to need the --no-issue2 option).
Basil I can load if I rewind and try again the failing blocks.
Just tried Basil on my +2A today using the audio generated by Tapir. No go. I then opened the wave file in a wave editor and inverted the phase of the first custom block. It started loading (the border stripes changed color from green/black to green/cyan/black), but the black didn't load. The loader did, however, manage to fetch the flag byte and reject the wrong blocks.
Really odd.
Not sure if this analysis can provide any tip:
http://www.alessandrogrussu.it/loading/schemes/docs/gremlin2.html
So the TZX specification states that if there's a pause after a data block then it should produce an edge and keep the same level for at least 1 milisecond. After that the pulse level should be low for the rest of the duration of the pause, and the following block should also start low (i.e. without starting immediately with an edge).
Here's a patch for libspectrum to do just that.
With it I can load successfully the unmodified TZX files of all the games mentioned by Sergio in an earlier comment, including the ones that were not working at all before: Basil, Lone Wolf III and MASK.
I confirm that this is the behaviour followed by tools like PlayTZX or emulators like ZEsarUX, which can also load those games.
Also, with the patched libspectrum, Fuse's tape2wav produces WAV files that can be loaded without problems by an unpatched version of the emulator (I don't have real hardware to try those on though). Note also that some WAVs don't load because of [bugs:#369].
There are some quirks however: Forbidden Planet stops loading unless I enable the "Issue 2 Keyboard" setting (you can load it already in Fuse but with that setting disabled). There may be other games with similar issues.
So perhaps if we want to add this patch we can make it configurable and add a setting to Fuse and libspectrum.
Opinions and comments are welcome.
Related
Bugs:
#369Last edit: Alberto Garcia 2019-01-16
More things: the TZX spec says that trailing pauses at the end of a data block and pause blocks should behave the same (with the exception that a 0ms pause block should stop the tape).
We are currently not doing this: we force all pause blocks (in TZX tapes) to have FLAGS_LEVEL_LOW, which has two consequences:
1) if the previous data block did not have a trailing pause and it ended with a low pulse then the pause block will not produce an edge, causing a loading error (see attached trailing-pause.tzx for a test case).
2) the following data block will start by flipping the level to high in order to produce an edge, causing the same problem with level-sensitive loaders that we have been discussing.
In short: replacing a >0ms trailing pause with a pause block of the same length should produce the same result, but it currently doesn't. The attached patch fixes that (it should go after the previous one).
P.S: For the PZX case, the spec says that the pause level should be the one specified in the block header. libspectrum is doing that already, this patch keeps that behaviour.
I've tested both patches with check_loaders (fuse-automation) and there are more tapes that can load succesfully: ActionForce II, 1942, Gryzor, Gauntlet II, Leader Board Par 3, MatchDay II, Outrun and SplATTR. They have bug entries at SF, so seems you have made a good progress here.
There are also some tapes that fail: AlterEgo, DanDare, IkariWarriors, KokotoniWilf, Macadam Bumper, Kentilla, LotusEspritTurboChallenge, Marauder, Pinball, Saboteur, Switchblade, TurboEsprit, TurboTheTortoise and World Cup Football. But these are false failures as the timeout in check_loaders needs to be bigger.
Dan Dare has a significally longer loading time (x5) with these patches when traps are enabled. When traps are disabled, these patches doesn't have an impact on the loading time. Probably is not a big issue.
Oh, but those were cases of tapes that could be loaded without acceleration but failed with some options enabled (detect loaders, traps, etc.). That's an unexpected side effect because I didn't debug that problem at all :)
Interesting, I'll have a look (I hadn't checked the tape traps code either).
I see, the loader detection code gets confused after the changes I made to the pauses. I think I have a simpler idea to solve this whole problem, I'll try to write a new patch.
PROPOSED PATCH v2
I had this half-written several months ago already, but it hasn't been until now that I found the time to finish it.
My previous attempt confused the loader detection code so I decided to try a simpler approach this time.
The idea is that if you play a tape you should always get the same signal with the same polarity, no matter if you start from the beginning or from a different point. This is necessary especially for games like MASK, that are polarity sensitive but are also multi-load.
The TZX spec says that:
and also
So this is what this patch does. This fixes Basil, Lone Wolf 3 and Mask.
In addition to that, it seems that if a polarity sensitive loader works on a 48 issue 2 model then it fails on the 48K issue 3 and 128K models (and vice versa). Of the games that I tested, Forbidden Planet is the only one that does not work on a 48K issue 3 model after patching libspectrum.
So I wrote a second patch (for Fuse this time) that adds a new option called "Reverse tape polarity". It simply reverses the polarity of the tape signal in case the default polarity is not the one that the loader expects.
Feedback is very welcome!
The patch for libspectrum looks good though running the fuse automation test suite shows unexpected failures for Chuckie Egg 2 and Lords Of Chaos - Side 1, could you have a look at those?
I personally prefer to minimise the number of options to keep things as simple as possible for the user and I guess that the polarity option may be complex to understand when to use and the issue type is already enough to allow the tapes to be used? I will defer if there are strong opinions about this.
I will have a look at those two and come back with my findings. Thanks!
Ok I can reproduce the problem with Chuckie Egg 2 (I haven't debugged it yet), but Lords os Chaos seems to work fine. Can you tell me the exact version that you used and the settings? I tried the only TZX available in WoS.
No, sorry, Chuckie Egg 2 loads fine too. I was testing it with
--detect-loader
, and it fails with that option, but it works fine without it.Checking the TZX files I see that both Chuckie Egg 2 and Lords of Chaos contain only standard ROM blocks so I'm not even sure how this patch would have an effect.
The sha1sums of the images I am using are the following - do they match yours?:
6354cdef91c18508a9bce87d96f532e14eb8954d Chuckie Egg 2.tzx
ed84d7e8035e380de3d951cd92930b556c0d3e6e Lords Of Chaos - Side 1.tzx
At least with these files I can reproduce a problem with Chuckie Egg 2 - it resets after loading with the patch installed rather than completing loading.
With Lords of Chaos, it still successfully loads but the fuse tape traps or similar seem to be affected as it loads with border stripes etc rather than being short circuted. It is probably exeeding the expected timeout in the test case.
Ok, those are the two files that I was also testing.
I tried with different command-line options and the problem that you describe with Chuckie Egg 2 (resets after loading) happens when I use
--detect-loader
regardless of whether I use the patch or not. I don't see that the patch is having any effect.With Lords of Chaos I also don't see any difference. If I enable tape traps then the loading screen appears immediately, but the data block after that loads at normal speed (or faster if I enable
--fastload
).Hmm, actually with Lords of Chaos I do see a difference with these options (after removing the
.fuserc
config file):--accelerate-loader --fastload --traps
Here the game loads very fast with and without the patch, but with the patch I can see the loading stripes for a brief moment. It doesn't really affect the loading process that much (it takes maybe half a second more) but there is definitely a difference. I'll try to debug it.
Just focussing on Chuckie Egg 2 for a second - I have no .fuserc and so this is the out of the box config. I am running
./fuse Chuckie\ Egg\ 2.tzx
. The attached movie files show the different results I am seeing with and without the patch. Can you get the same results?Last edit: Fredrick Meunier 2021-03-09
Ok, I must have been testing it incorrectly because you're right, I can reproduce the problem now. I'll investigate, sorry for the noise !
Ok so my earlier analysis was not so wrong after all. It seems that the problem can be reproduced without the patch if you use
--detect-loader
, unless you also add--accelerate-loader
.Both options are enabled by default, so you need to unset the latter.
In other words, with an empty .fuserc you can reproduce the problem like this:
$ fuse --no-accelerate-loader Chuckie\ Egg\ 2.tzx
My guess is that with the new patch the "accelerate loader" feature gets confused with this tape, so the option is not used and the bug is triggered.
So there are two problems here:
1) The patch messes with the code that decides whether to use loader acceleration, i.e.
acceleration_detector()
returns a different result with and without the patch. This is almost certainly what makes Lord of Chaos behave differently, and I bet it affects many other games.2) Chuckie Egg 2 fails to load when "Detect loaders" is enabled and "Accelerate loaders" is disabled. This is a pre-existing problem, it's just that it's triggered because of (1).
So, about (2): the Chuckie Egg 2 tape contains one single data block with the screen and game data combined, the BASIC loader simply does
LOAD "" CODE
.Now, according to the header that data block is 49152 bytes long, but the actual data block is shorter: 48896 bytes.
So under normal circumstances the ROM data loader fails at the end of the tape, the stack pointer is set to the contents of ERR-SP (0xA488 in this case), and then the ROM loader returns to the new address taken from the new stack: 0x60C2, which is where the actual game code starts.
However if "Detect loaders" is enabled then Fuse sees that the game is still trying to load data, the tape starts playing again from the beginning and the loader (incorrectly) continues.
This can be worked around by adding a pause block at the end of the tape, e.g.
echo -en '\x20\xe8\x03' >> Chuckie\ Egg\ 2.tzx
. This will force the ROM loader to fail, as expected.How to fix this? Perhaps libspectrum could generate a silence at the end of the tape to make sure that no loader ever tries to load the last and the first block as if they were consecutive.
I think that the Chuckie Egg 2 problem is a bug in Fuse after all. I opened bug #480 to keep track of it: https://sourceforge.net/p/fuse-emulator/bugs/480/