[BUGS] Drive Emulation HLS protection

Caution: Non registered users only see threads and messages in the currently selected language, which is determined by their browser. Please create an account and log in to see all content by default. This is a limitation of the forum software.


Also users that are not logged in can not create new threads. This is a, unfortunately needed, counter measure against spam. Please create an account and log in to start new threads.

Don't Panic. Please wash hands.
  • There is a protection (which I believe is written by Herndon Labs?) that does not work in the emulated drive. It is described in a Vice bug report a few years back and was determined to be due to timing of the SO line with regards to sync detection, as well as these tracks being written at a higher-than-standard density.


    https://sourceforge.net/p/vice-emu/bugs/203/


    This protection is used on many commercial games, and is the reason for a number of the entries in the "not-working" G64 list. I tried a handful on both beta-9l and beta-9h, and they did not work on either firmware. Here are some titles that I had encountered in the past which used this:


  • Interesting.... unfortunately this type of thing is really hard to test or debug (and Games are really terrible testcases) - We'll have to wait and see if any VIA detail fixes that will come in the future will fix it

  • If it would help, I could create a g64 image that contains just a single prg file that does nothing but the protection check and reports back to the user what the resulting values of the check returned (it measures block length and byte before/after sync for a number of sectors on the track).

  • I'd like to add that this is the king's class of test cases and is therefore not just "of help", but the highest goal to achieve for a test case. The only icing on top would be to have the source code, so we can add the test to our automated test suite that automatically records results and spits them out for inclusion in the Wiki.

  • well yes, we do need the source and must be able to rebuild the test (ideally, including the disk image). crazy cool would be a way to master the same disk on a c64/1541, so i can also crosscheck on the real thing (but i realise this isnt exactly trivial).

  • Here is the test program. It fails on the TC in a way I did not anticipate nor understand. It works perfectly on real hardware (tested with 1541-II), although if the TC emulated drive is on the bus (I had TC as dev #9, in cartridge mode, internal IEC bus) it randomly introduces errors and the kernal IEC commands will sometimes hang. I noticed this as well when using emulated WarpSpeed cartridge to read 1541-II drive memory. This is a separate issue though, so as not to get distracted from the topic.


    When the test program is reading a track on the emulated TC drive, it takes a very long time, on the order of 30 seconds or so. On real hardware (and on Vice emu) this takes a fraction of a second. The results that come back are completely nonsensical as well. I don't know where it is consuming all of it's time. I would have to add some additional debugging options in the drive code, perhaps with the LED.


    When you run the program, it shows what bytes it expects for each block and what it actually got from the drive code. There are four bytes, which are:


    length of block (low byte), length of block (high byte), byte before sync, byte after sync


    There are only 2 different tables of results which correspond with the two most-dense speed zones. The check becomes unreliable once you hit track 25, and no titles I have run into will check past track 24, so the test program stops you at 24 as well. Vice (as of version 3.5) is not completely reliable in the track 18-24 speed zone either.


    Press + to increase track

    Press - to decrease track

    Run/stop to exit

    any other key to run the check again on the same track


    You can run the test on the g64 image it's provided on (which, incidentally, was originally the Batman disk image), or you can put in any of the game disks that use this protection, as it's exactly the same disk layout on all of them.


    If you want to change the disk being tested, run/stop to exit the program first, then RUN again after swapping. Otherwise the disk ID bytes will not be updated and further results are invalid.


    You could master a blank disk with this layout just using a special format routine. Such a disk should pass the protection check. However, I believe the timing of the check might be altered subtlety by the higher-than-normal density of the tracks, in which case you would have to slow your drive motor down when creating the disk. If these disks are remasterable with ZoomFloppy without changing drive speed, then no-speed change should be needed for this either.

  • The above results were with beta-9l. When trying with beta-9h, it worked much better and failed in the way I expected it to fail. It reads the track very quickly, but some of the results are wrong. The sync mark arrives just a little bit too late and causes the read to pass through the mark and include the next block in its total, so instead of a block length of $163 on T1-18, you frequently get $2c8, but sometimes other results occur as well.


    On tracks 18+, the results are even further off the mark.

  • There was an error in the previous test. I had not noticed that the timing of the test was modified in games that checked T18+, where it uses a 6 cycle delay instead of 4. After accounting for this, Vice now passes the checks on those tracks reliably.


    Interestingly, this disk layout is found on many disks, even those that don't use this protection check. It must be common to one or more mastering facilities of the time. For example, my original of Ultima III passes the test, as does Garry Kitchen's Gamemaker, which uses a different protection (Xemag 2.0).

  • Sounds good.


    Tested a bit more with the beta9-h drive code and it looks like it's running about 2 cycles too fast (or the rotational speed of the virtual disk is 2 cycles too slow, however you want to look at it). By increasing the delay instruction in the protection routine an extra 2 cycles, the protection check passes every time. At +1 cycle it usually works, but a failure will occur now and then.


    Also modified the test program to cover up to track 35. Assumed +2 cycle delay for each further density zone and included the T31-35 results that original disks return for comparison. While these are never checked from what I've seen, it might be useful in testing timing at each density level.

  • Tested a bit more with the beta9-h drive code and it looks like it's running about 2 cycles too fast (or the rotational speed of the virtual disk is 2 cycles too slow, however you want to look at it).

    Did I read this right, and you're assuming that the disk rotation (300RPM = 0.2s per rotation) to be accurate to 2 CPU cycles? Or are you using the word "cycles" for something else here? Just saying - it's a mechanical device and therefore will spin un-evenly on the real thing and one should in no way rely on the rotational speed, especially with millions of drives out there that are all ageing differently.


    I sure hope you're using the word "cycles" for something else - if so, please explain.

  • Yeah, rotational speed isnt that accurate ever, you can make it +/- a couple cycles on a real drive with a lot of fiddling - but such code then wouldnt ever work reliable on random Drives "in the wild", so its really unlikely for any protection to require this. Its more likely the problem is related to SYNC detection, or some kind of VIA bug.


    Is this protection using a different density than normal DOS would use on some track? that may be another problem

  • The timing is per-GCR byte. The loop counts bytes and exits to update the table when sync is detected, looping primarily on byte-ready condition. The modification was to increase the 4 cycle delay in the ldx command to a 6 cycle delay (and 8 cycles in speed zone for tracks 18-24)

    Code
    1. loop ldx $eaea
    2. loop2 clv
    3. ldx $1c00
    4. bpl sync_detected
    5. bvc *
    6. lda $1c01
    7. iny
    8. bne loop
    9.         inc $0d
    10. bne loop2

    The condition that occurs on tracks 1-17 happens when SO is asserted after the ldx $1c00 command but before a new byte is ready, so the loop sits through the entire sync mark instead of exiting and recording the block length. Instead of having separate entries in the table, one for header block and one for data block, each entry is actually the combination of both.


    Since a GCR byte is received approx every 26 cycles at this speed zone, 2 cycles difference in this case is nearly 8%, and equivalent to a neighbouring speed zone or a drive speed difference of over 20RPM.


    The issue might not be rotational speed. I don't know the inner workings of this implementation and I can only see symptoms, so it could be something else, such as a delays on sync detection, assertion of SO line, setting of the overflow bit, or any other number of conditions.

  • That's an area where I'm totally with you about being cycle-exact (or "nearly", as the PLL and read-pulses are still analogue things). To my knowledge, there has not been any test program before that goes down this rabbit hole, but it's good to have one. It should be possible to adjust the core to do the right thing here.

  • Tobias

    Changed the title of the thread from “Drive Emulation HLS protection” to “[BUGS] Drive Emulation HLS protection”.
  • The last reply was more than 365 days ago, this thread is most likely obsolete. It is recommended to create a new thread instead.