Jump to content
IGNORED

Reverse engineering the PRO disk format


Farb

Recommended Posts

I've spent some time reverse engineering APE's PRO format to allow SIO2Arduino to support PRO images. I realize there isn't much information around since it's a closed format. I was going to publish the work I've done in hopes that it would be useful to (or potentially be improved) by others.

 

Does anyone see a problem with releasing what information I've gathered?

Link to comment
Share on other sites

You could ask Steve Tucker (Atarimax), he might just give you the .pro info you need.

 

I don't know whether you're better off supporting .pro or the Vapi stuff - personally when I run a game I just want the thing to function, and don't really care about the nostalgia value of having every single sector read occur just as it did originally.

Link to comment
Share on other sites

I have most of the PRO images that come with APE working properly (Bandits, Jumpman, Karateka, Archon 2, Ballblazer)... although Archon 1 is still giving me trouble for some reason even though it only has one phantom sector and uses phantom mode 2 the same as the others.

 

I'll contact Steve and see if he's willing to help fill in some of the gaps.

Link to comment
Share on other sites

The main problem I have with the .PRO format is that it is not a proper protected disk image format. Instead, as far as I can tell, it encodes the sector load pattern of the loader. This creates the following problems:

  • You cannot recreate a viable physical disk from a .PRO image.
  • The .PRO format either stores or cannot be interpreted without data that could not be inferred from the disk layout itself. This either means that you cannot create a .PRO image without either instrumenting an actual load of the disk -- thus requiring enough of it to be run to hit all of the protected areas of the disk -- or having pre-knowledge of the loader's protection strategy in either the imaging software or the disk emulator. The latter is especially troublesome as it involves direct attacks on specific protections and calling that imaging is questionable. In the general case, blind imaging of a protected disk with an unknown protection into .PRO could be impossible because it could require information that simply is not on the disk (i.e. manual-based protection or randomized sector check pattern).
  • Disk emulation accuracy actually has to be degraded in order to run a .PRO disk, because the phantom sector order has to be obeyed regardless of load timing.

In contrast, the VAPI (ATX) format is a more appropriate imaging format because it is simply a representation of the physical disk and it contains enough information to correctly emulate both the timing and order of disk loads. The main problem with it is that the direct way of creating one requires a drive interface that can do a raw track read, which you can't do with a standard 810 disk drive and apparently normally requires an expanded 1050. I believe it would still be possible to create a VAPI image purely with standard SIO disk read commands, but it would involve carefully timing all of the sector reads to determine timing for each sector and to pick up any phantom sectors.

 

Now, regarding the Archon I .PRO image, it turns out that not only can Altirra boot the Archon I .pro image, it can do so with SIO patch enabled. The loader uses SIOV! Here's the disk activity output from the Archon I load:

DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=8.73 >> 0.00.
DISK: Reading vsec=  2 (1/1) (trk=0), psec=  1, chk=63, rot=8.38 >> 0.50.
DISK: Reading vsec=  3 (1/1) (trk=0), psec=  2, chk=fd, rot=8.88 >> 0.06.
DISK: Reading vsec=  4 (1/1) (trk=0), psec=  3, chk=f7, rot=8.44 >> 0.56.
DISK: Reading vsec=  5 (1/1) (trk=0), psec=  4, chk=3c, rot=8.94 >> 0.11.
DISK: Reading vsec=  6 (1/1) (trk=0), psec=  5, chk=ac, rot=8.49 >> 0.61.
DISK: Reading vsec= 49 (1/1) (trk=2), psec= 49, chk=6b, rot=9.08 >> 0.33.
DISK: Reading vsec= 50 (1/1) (trk=2), psec= 50, chk=fe, rot=9.71 >> 0.83.
DISK: Reading vsec= 51 (1/1) (trk=2), psec= 51, chk=b2, rot=10.21 >> 0.39.
DISK: Reading vsec= 52 (1/1) (trk=2), psec= 52, chk=7c, rot=10.76 >> 0.89.
DISK: Reading vsec=  9 (1/1) (trk=0), psec=  8, chk=23, rot=11.34 >> 0.22.
DISK: Reading vsec=  9 (1/1) (trk=0), psec=  8, chk=23, rot=11.60 >> 0.22.
DISK: Reading vsec= 10 (1/1) (trk=0), psec=  9, chk=f2, rot=11.60 >> 0.72.
DISK: Reading vsec= 11 (1/1) (trk=0), psec= 10, chk=94, rot=12.09 >> 0.28.
DISK: Reading vsec= 12 (1/1) (trk=0), psec= 11, chk=0a, rot=12.65 >> 0.78.
DISK: Reading vsec= 13 (1/1) (trk=0), psec= 12, chk=f2, rot=13.15 >> 0.33.
DISK: Reading vsec= 14 (1/1) (trk=0), psec= 13, chk=f4, rot=13.71 >> 0.83.
DISK: Reading vsec= 15 (1/1) (trk=0), psec= 14, chk=be, rot=14.21 >> 0.39.
DISK: Reading vsec= 16 (1/1) (trk=0), psec= 15, chk=40, rot=14.76 >> 0.89.
DISK: Reading vsec= 17 (1/1) (trk=0), psec= 16, chk=f3, rot=15.26 >> 0.44.
DISK: Reading vsec= 18 (1/1) (trk=0), psec= 17, chk=d7, rot=15.82 >> 0.94.
DISK: Reading vsec= 19 (1/1) (trk=1), psec= 18, chk=4a, rot=16.32 >> 0.00.
DISK: Reading vsec= 20 (1/1) (trk=1), psec= 19, chk=6a, rot=16.37 >> 0.50.
DISK: Reading vsec= 21 (1/1) (trk=1), psec= 20, chk=b9, rot=16.87 >> 0.06.
DISK: Reading vsec= 22 (1/1) (trk=1), psec= 21, chk=65, rot=16.43 >> 0.56.
DISK: Reading vsec= 23 (1/1) (trk=1), psec= 22, chk=65, rot=16.93 >> 0.11.
DISK: Reading vsec= 24 (1/1) (trk=1), psec= 23, chk=0a, rot=16.48 >> 0.61.
DISK: Reading vsec= 25 (1/1) (trk=1), psec= 24, chk=7b, rot=16.98 >> 0.17.
DISK: Reading vsec= 26 (1/1) (trk=1), psec= 25, chk=76, rot=16.54 >> 0.67.
DISK: Reading vsec= 27 (1/1) (trk=1), psec= 26, chk=50, rot=17.04 >> 0.22.
DISK: Reading vsec= 28 (1/1) (trk=1), psec= 27, chk=d9, rot=17.59 >> 0.72.
DISK: Reading vsec= 29 (1/1) (trk=1), psec= 28, chk=98, rot=18.09 >> 0.28.
DISK: Reading vsec= 30 (1/1) (trk=1), psec= 29, chk=3f, rot=18.65 >> 0.78.
DISK: Reading vsec= 31 (1/1) (trk=1), psec= 30, chk=80, rot=19.15 >> 0.33.
DISK: Reading vsec= 32 (1/1) (trk=1), psec= 31, chk=6f, rot=19.71 >> 0.83.
DISK: Reading vsec= 33 (1/1) (trk=1), psec= 32, chk=e0, rot=20.21 >> 0.39.
DISK: Reading vsec= 34 (1/1) (trk=1), psec= 33, chk=24, rot=20.76 >> 0.89.
DISK: Reading vsec= 35 (1/1) (trk=1), psec= 34, chk=94, rot=21.26 >> 0.44.
DISK: Reading vsec= 36 (1/1) (trk=1), psec= 35, chk=dd, rot=21.82 >> 0.94.
DISK: Reading vsec= 37 (1/1) (trk=2), psec= 36, chk=02, rot=22.32 >> 0.00.
DISK: Reading vsec= 38 (1/1) (trk=2), psec= 37, chk=90, rot=22.37 >> 0.50.
DISK: Reading vsec= 39 (1/1) (trk=2), psec= 38, chk=f9, rot=22.87 >> 0.06.
DISK: Reading vsec= 40 (1/1) (trk=2), psec= 39, chk=6e, rot=22.43 >> 0.56.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=25.30 >> 0.00.
DISK: Reading vsec=  9 (1/1) (trk=0), psec=  8, chk=23, rot=25.49 >> 0.22.
DISK: Reading vsec= 50 (1/1) (trk=2), psec= 50, chk=fe, rot=25.71 >> 0.83.
DISK: Reading vsec= 41 (1/2) (trk=2), psec= 40, chk=ff, rot=30.57 >> 0.11.
DISK: Reading vsec= 41 (2/2) (trk=2), psec= 41, chk=df, rot=30.49 >> 1.11.
DISK: Reading vsec= 54 (1/1) (trk=2), psec= 54, chk=ab, rot=32.15 >> 0.94.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.36 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.51 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.51 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.50 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.51 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.51 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.52 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.52 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.52 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.49 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.37 >> 0.00.
DISK: Reading vsec=  1 (1/1) (trk=0), psec=  0, chk=5d, rot=33.54 >> 0.00.
DISK: Reading vsec= 19 (1/1) (trk=1), psec= 18, chk=4a, rot=33.37 >> 0.00.
DISK: Reading vsec= 19 (1/1) (trk=1), psec= 18, chk=4a, rot=33.53 >> 0.00.
DISK: Reading vsec=145 (1/1) (trk=, psec=145, chk=f0, rot=33.37 >> 0.00.
DISK: Reading vsec= 37 (1/1) (trk=2), psec= 36, chk=02, rot=33.53 >> 0.00.
DISK: Reading vsec=181 (1/1) (trk=10), psec=181, chk=72, rot=33.37 >> 0.00.
DISK: Reading vsec= 55 (1/1) (trk=3), psec= 55, chk=4f, rot=33.52 >> 0.00.
DISK: Reading vsec= 37 (1/1) (trk=2), psec= 36, chk=02, rot=33.37 >> 0.00.
DISK: Reading vsec= 73 (1/1) (trk=4), psec= 73, chk=87, rot=33.54 >> 0.00.
DISK: Reading vsec= 55 (1/1) (trk=3), psec= 55, chk=4f, rot=33.37 >> 0.00.
DISK: Reading vsec= 91 (1/1) (trk=5), psec= 91, chk=d3, rot=33.53 >> 0.00.
DISK: Reading vsec=145 (1/1) (trk=, psec=145, chk=f0, rot=33.37 >> 0.00.
DISK: Reading vsec=109 (1/1) (trk=6), psec=109, chk=2b, rot=33.53 >> 0.00.
DISK: Reading vsec= 55 (1/1) (trk=3), psec= 55, chk=4f, rot=33.37 >> 0.00.
DISK: Reading vsec= 54 (1/1) (trk=2), psec= 54, chk=ab, rot=33.52 >> 0.94.
DISK: Reading vsec= 55 (1/1) (trk=3), psec= 55, chk=4f, rot=34.32 >> 0.00.
DISK: Reading vsec= 56 (1/1) (trk=3), psec= 56, chk=27, rot=34.38 >> 0.50.
DISK: Reading vsec= 57 (1/1) (trk=3), psec= 57, chk=1a, rot=34.88 >> 0.06.
DISK: Reading vsec= 58 (1/1) (trk=3), psec= 58, chk=a8, rot=34.43 >> 0.56.
DISK: Reading vsec= 59 (1/1) (trk=3), psec= 59, chk=fd, rot=34.93 >> 0.11.
DISK: Reading vsec= 60 (1/1) (trk=3), psec= 60, chk=46, rot=34.49 >> 0.61.
DISK: Reading vsec= 61 (1/1) (trk=3), psec= 61, chk=7c, rot=34.99 >> 0.17.
DISK: Reading vsec= 62 (1/1) (trk=3), psec= 62, chk=d5, rot=34.54 >> 0.67.
DISK: Reading vsec= 63 (1/1) (trk=3), psec= 63, chk=55, rot=35.04 >> 0.22.
DISK: Reading vsec= 64 (1/1) (trk=3), psec= 64, chk=6c, rot=35.60 >> 0.72.
DISK: Reading vsec= 65 (1/1) (trk=3), psec= 65, chk=1d, rot=36.10 >> 0.28.
DISK: Reading vsec= 66 (1/1) (trk=3), psec= 66, chk=a0, rot=36.65 >> 0.78.
DISK: Reading vsec= 67 (1/1) (trk=3), psec= 67, chk=d1, rot=37.15 >> 0.33.
DISK: Reading vsec= 68 (1/1) (trk=3), psec= 68, chk=ff, rot=37.71 >> 0.83.
DISK: Reading vsec= 69 (1/1) (trk=3), psec= 69, chk=98, rot=38.21 >> 0.39.
DISK: Reading vsec= 70 (1/1) (trk=3), psec= 70, chk=6e, rot=38.76 >> 0.89.
DISK: Reading vsec= 71 (1/1) (trk=3), psec= 71, chk=6e, rot=39.26 >> 0.44.
DISK: Reading vsec= 72 (1/1) (trk=3), psec= 72, chk=0d, rot=39.82 >> 0.94.
DISK: Reading vsec= 73 (1/1) (trk=4), psec= 73, chk=87, rot=40.32 >> 0.00.
DISK: Reading vsec= 74 (1/1) (trk=4), psec= 74, chk=be, rot=40.38 >> 0.50.
DISK: Reading vsec= 75 (1/1) (trk=4), psec= 75, chk=ee, rot=40.88 >> 0.06.
DISK: Reading vsec= 76 (1/1) (trk=4), psec= 76, chk=fe, rot=40.43 >> 0.56.
DISK: Reading vsec= 77 (1/1) (trk=4), psec= 77, chk=f9, rot=40.93 >> 0.11.
DISK: Reading vsec= 78 (1/1) (trk=4), psec= 78, chk=72, rot=40.49 >> 0.61.
DISK: Reading vsec= 79 (1/1) (trk=4), psec= 79, chk=88, rot=40.99 >> 0.17.
DISK: Reading vsec= 80 (1/1) (trk=4), psec= 80, chk=0d, rot=40.54 >> 0.67.
DISK: Reading vsec= 81 (1/1) (trk=4), psec= 81, chk=dc, rot=41.04 >> 0.22.
DISK: Reading vsec= 82 (1/1) (trk=4), psec= 82, chk=fb, rot=41.60 >> 0.72.
DISK: Reading vsec= 83 (1/1) (trk=4), psec= 83, chk=09, rot=42.10 >> 0.28.
DISK: Reading vsec= 84 (1/1) (trk=4), psec= 84, chk=4f, rot=42.66 >> 0.78.
DISK: Reading vsec= 85 (1/1) (trk=4), psec= 85, chk=e8, rot=43.15 >> 0.33.
DISK: Reading vsec= 86 (1/1) (trk=4), psec= 86, chk=aa, rot=43.71 >> 0.83.
DISK: Reading vsec= 87 (1/1) (trk=4), psec= 87, chk=1c, rot=44.21 >> 0.39.
DISK: Reading vsec= 88 (1/1) (trk=4), psec= 88, chk=60, rot=44.76 >> 0.89.
DISK: Reading vsec= 89 (1/1) (trk=4), psec= 89, chk=42, rot=45.26 >> 0.44.
DISK: Reading vsec= 90 (1/1) (trk=4), psec= 90, chk=12, rot=45.82 >> 0.94.
DISK: Reading vsec= 91 (1/1) (trk=5), psec= 91, chk=d3, rot=46.32 >> 0.00.
DISK: Reading vsec= 92 (1/1) (trk=5), psec= 92, chk=4f, rot=46.38 >> 0.50.
DISK: Reading vsec= 93 (1/1) (trk=5), psec= 93, chk=52, rot=46.88 >> 0.06.
DISK: Reading vsec= 94 (1/1) (trk=5), psec= 94, chk=a7, rot=46.43 >> 0.56.
DISK: Reading vsec= 95 (1/1) (trk=5), psec= 95, chk=b5, rot=46.93 >> 0.11.
DISK: Reading vsec= 96 (1/1) (trk=5), psec= 96, chk=59, rot=46.49 >> 0.61.
DISK: Reading vsec= 97 (1/1) (trk=5), psec= 97, chk=7c, rot=46.99 >> 0.17.
DISK: Reading vsec= 98 (1/1) (trk=5), psec= 98, chk=6f, rot=46.54 >> 0.67.
DISK: Reading vsec= 99 (1/1) (trk=5), psec= 99, chk=8b, rot=47.04 >> 0.22.
DISK: Reading vsec=100 (1/1) (trk=5), psec=100, chk=5e, rot=47.60 >> 0.72.
DISK: Reading vsec=101 (1/1) (trk=5), psec=101, chk=ff, rot=48.10 >> 0.28.
DISK: Reading vsec=102 (1/1) (trk=5), psec=102, chk=b4, rot=48.65 >> 0.78.
DISK: Reading vsec=103 (1/1) (trk=5), psec=103, chk=33, rot=49.15 >> 0.33.
DISK: Reading vsec=104 (1/1) (trk=5), psec=104, chk=d6, rot=49.71 >> 0.83.
DISK: Reading vsec=105 (1/1) (trk=5), psec=105, chk=88, rot=50.21 >> 0.39.
DISK: Reading vsec=106 (1/1) (trk=5), psec=106, chk=51, rot=50.76 >> 0.89.
DISK: Reading vsec=107 (1/1) (trk=5), psec=107, chk=83, rot=51.27 >> 0.44.
DISK: Reading vsec=108 (1/1) (trk=5), psec=108, chk=fe, rot=51.82 >> 0.94.
DISK: Reading vsec=109 (1/1) (trk=6), psec=109, chk=2b, rot=52.32 >> 0.00.
DISK: Reading vsec=110 (1/1) (trk=6), psec=110, chk=08, rot=52.38 >> 0.50.
DISK: Reading vsec=111 (1/1) (trk=6), psec=111, chk=a2, rot=52.88 >> 0.06.
DISK: Reading vsec=112 (1/1) (trk=6), psec=112, chk=04, rot=52.43 >> 0.56.
DISK: Reading vsec=113 (1/1) (trk=6), psec=113, chk=5d, rot=52.93 >> 0.11.
DISK: Reading vsec=114 (1/1) (trk=6), psec=114, chk=c8, rot=52.49 >> 0.61.
DISK: Reading vsec=115 (1/1) (trk=6), psec=115, chk=19, rot=52.99 >> 0.17.
DISK: Reading vsec=116 (1/1) (trk=6), psec=116, chk=77, rot=52.54 >> 0.67.
DISK: Reading vsec=117 (1/1) (trk=6), psec=117, chk=87, rot=53.04 >> 0.22.
DISK: Reading vsec=118 (1/1) (trk=6), psec=118, chk=cf, rot=53.60 >> 0.72.
DISK: Reading vsec=119 (1/1) (trk=6), psec=119, chk=35, rot=54.10 >> 0.28.
DISK: Reading vsec=120 (1/1) (trk=6), psec=120, chk=3c, rot=54.65 >> 0.78.
DISK: Reading vsec=121 (1/1) (trk=6), psec=121, chk=97, rot=55.15 >> 0.33.
DISK: Reading vsec=122 (1/1) (trk=6), psec=122, chk=e3, rot=55.71 >> 0.83.
DISK: Reading vsec=123 (1/1) (trk=6), psec=123, chk=bb, rot=56.21 >> 0.39.
DISK: Reading vsec=124 (1/1) (trk=6), psec=124, chk=52, rot=56.76 >> 0.89.
DISK: Reading vsec=125 (1/1) (trk=6), psec=125, chk=87, rot=57.26 >> 0.44.
DISK: Reading vsec=126 (1/1) (trk=6), psec=126, chk=70, rot=57.82 >> 0.94.
DISK: Reading vsec=127 (1/1) (trk=7), psec=127, chk=ee, rot=58.32 >> 0.00.
DISK: Reading vsec=128 (1/1) (trk=7), psec=128, chk=c0, rot=58.38 >> 0.50.
DISK: Reading vsec=129 (1/1) (trk=7), psec=129, chk=10, rot=58.88 >> 0.06.
DISK: Reading vsec=130 (1/1) (trk=7), psec=130, chk=c1, rot=58.43 >> 0.56.
DISK: Reading vsec=131 (1/1) (trk=7), psec=131, chk=02, rot=58.93 >> 0.11.
DISK: Reading vsec=132 (1/1) (trk=7), psec=132, chk=f8, rot=58.49 >> 0.61.
DISK: Reading vsec=133 (1/1) (trk=7), psec=133, chk=9b, rot=58.99 >> 0.17.
DISK: Reading vsec=134 (1/1) (trk=7), psec=134, chk=99, rot=58.54 >> 0.67.
DISK: Reading vsec=135 (1/1) (trk=7), psec=135, chk=e3, rot=59.04 >> 0.22.
DISK: Reading vsec=136 (1/1) (trk=7), psec=136, chk=bd, rot=59.60 >> 0.72.
DISK: Reading vsec=137 (1/1) (trk=7), psec=137, chk=50, rot=60.10 >> 0.28.
DISK: Reading vsec=138 (1/1) (trk=7), psec=138, chk=1c, rot=60.65 >> 0.78.
DISK: Reading vsec=139 (1/1) (trk=7), psec=139, chk=f7, rot=61.15 >> 0.33.
DISK: Reading vsec=140 (1/1) (trk=7), psec=140, chk=65, rot=61.71 >> 0.83.
DISK: Reading vsec=141 (1/1) (trk=7), psec=141, chk=9d, rot=62.21 >> 0.39.
DISK: Reading vsec=142 (1/1) (trk=7), psec=142, chk=2d, rot=62.76 >> 0.89.
DISK: Reading vsec=143 (1/1) (trk=7), psec=143, chk=ae, rot=63.26 >> 0.44.
DISK: Reading vsec=144 (1/1) (trk=7), psec=144, chk=30, rot=63.82 >> 0.94.
DISK: Reading vsec=145 (1/1) (trk=, psec=145, chk=f0, rot=64.32 >> 0.00.
DISK: Reading vsec=146 (1/1) (trk=, psec=146, chk=0a, rot=64.38 >> 0.50.
DISK: Reading vsec=147 (1/1) (trk=, psec=147, chk=f9, rot=64.88 >> 0.06.
DISK: Reading vsec=148 (1/1) (trk=, psec=148, chk=58, rot=64.43 >> 0.56.
DISK: Reading vsec=149 (1/1) (trk=, psec=149, chk=de, rot=64.93 >> 0.11.
DISK: Reading vsec=150 (1/1) (trk=, psec=150, chk=76, rot=64.49 >> 0.61.
DISK: Reading vsec=151 (1/1) (trk=, psec=151, chk=f6, rot=64.99 >> 0.17.
DISK: Reading vsec=152 (1/1) (trk=, psec=152, chk=94, rot=64.54 >> 0.67.
DISK: Reading vsec=153 (1/1) (trk=, psec=153, chk=1e, rot=65.04 >> 0.22.
DISK: Reading vsec=154 (1/1) (trk=, psec=154, chk=24, rot=65.60 >> 0.72.
DISK: Reading vsec=155 (1/1) (trk=, psec=155, chk=bc, rot=66.10 >> 0.28.
DISK: Reading vsec=156 (1/1) (trk=, psec=156, chk=34, rot=66.65 >> 0.78.
DISK: Reading vsec=157 (1/1) (trk=, psec=157, chk=f1, rot=67.15 >> 0.33.
DISK: Reading vsec=158 (1/1) (trk=, psec=158, chk=3f, rot=67.71 >> 0.83.
DISK: Reading vsec=159 (1/1) (trk=, psec=159, chk=54, rot=68.21 >> 0.39.
DISK: Reading vsec=160 (1/1) (trk=, psec=160, chk=78, rot=68.76 >> 0.89.
DISK: Reading vsec=161 (1/1) (trk=, psec=161, chk=0e, rot=69.26 >> 0.44.
DISK: Reading vsec=162 (1/1) (trk=, psec=162, chk=3b, rot=69.82 >> 0.94.
DISK: Reading vsec=163 (1/1) (trk=9), psec=163, chk=e8, rot=70.32 >> 0.00.
DISK: Reading vsec=164 (1/1) (trk=9), psec=164, chk=20, rot=70.38 >> 0.50.
DISK: Reading vsec=165 (1/1) (trk=9), psec=165, chk=1c, rot=70.88 >> 0.06.
DISK: Reading vsec=166 (1/1) (trk=9), psec=166, chk=b3, rot=70.43 >> 0.56.
DISK: Reading vsec=167 (1/1) (trk=9), psec=167, chk=87, rot=70.93 >> 0.11.
DISK: Reading vsec=168 (1/1) (trk=9), psec=168, chk=6d, rot=70.49 >> 0.61.
DISK: Reading vsec=169 (1/1) (trk=9), psec=169, chk=d9, rot=70.99 >> 0.17.
DISK: Reading vsec=170 (1/1) (trk=9), psec=170, chk=3d, rot=70.54 >> 0.67.
DISK: Reading vsec=171 (1/1) (trk=9), psec=171, chk=cf, rot=71.04 >> 0.22.
DISK: Reading vsec=172 (1/1) (trk=9), psec=172, chk=bf, rot=71.60 >> 0.72.
DISK: Reading vsec=173 (1/1) (trk=9), psec=173, chk=1b, rot=72.10 >> 0.28.
DISK: Reading vsec=174 (1/1) (trk=9), psec=174, chk=1e, rot=72.65 >> 0.78.
DISK: Reading vsec=175 (1/1) (trk=9), psec=175, chk=33, rot=73.16 >> 0.33.
DISK: Reading vsec=176 (1/1) (trk=9), psec=176, chk=df, rot=73.71 >> 0.83.
DISK: Reading vsec=177 (1/1) (trk=9), psec=177, chk=b0, rot=74.21 >> 0.39.
DISK: Reading vsec=178 (1/1) (trk=9), psec=178, chk=6a, rot=74.76 >> 0.89.
DISK: Reading vsec=179 (1/1) (trk=9), psec=179, chk=2e, rot=75.26 >> 0.44.
DISK: Reading vsec=180 (1/1) (trk=9), psec=180, chk=90, rot=75.82 >> 0.94.
DISK: Reading vsec=181 (1/1) (trk=10), psec=181, chk=72, rot=76.32 >> 0.00.
DISK: Reading vsec=182 (1/1) (trk=10), psec=182, chk=a6, rot=76.38 >> 0.50.
DISK: Reading vsec=183 (1/1) (trk=10), psec=183, chk=06, rot=76.88 >> 0.06.
DISK: Reading vsec=184 (1/1) (trk=10), psec=184, chk=0b, rot=76.43 >> 0.56.
DISK: Reading vsec=185 (1/1) (trk=10), psec=185, chk=4f, rot=76.93 >> 0.11.
DISK: Reading vsec=186 (1/1) (trk=10), psec=186, chk=06, rot=76.49 >> 0.61.
DISK: Reading vsec=187 (1/1) (trk=10), psec=187, chk=5a, rot=76.99 >> 0.17.
DISK: Reading vsec=188 (1/1) (trk=10), psec=188, chk=0c, rot=76.54 >> 0.67.
DISK: Reading vsec=189 (1/1) (trk=10), psec=189, chk=80, rot=77.04 >> 0.22.
DISK: Reading vsec=190 (1/1) (trk=10), psec=190, chk=21, rot=77.60 >> 0.72.
DISK: Reading vsec=191 (1/1) (trk=10), psec=191, chk=a1, rot=78.10 >> 0.28.
DISK: Reading vsec=192 (1/1) (trk=10), psec=192, chk=1a, rot=78.65 >> 0.78.
DISK: Reading vsec=193 (1/1) (trk=10), psec=193, chk=dc, rot=79.15 >> 0.33.
DISK: Reading vsec=194 (1/1) (trk=10), psec=194, chk=98, rot=79.71 >> 0.83.
DISK: Reading vsec=195 (1/1) (trk=10), psec=195, chk=f9, rot=80.21 >> 0.39.
DISK: Reading vsec=196 (1/1) (trk=10), psec=196, chk=8e, rot=80.76 >> 0.89.
DISK: Reading vsec=197 (1/1) (trk=10), psec=197, chk=7b, rot=81.27 >> 0.44.
DISK: Reading vsec=198 (1/1) (trk=10), psec=198, chk=e4, rot=81.82 >> 0.94.
DISK: Reading vsec=199 (1/1) (trk=11), psec=199, chk=68, rot=82.32 >> 0.00.
DISK: Reading vsec=200 (1/1) (trk=11), psec=200, chk=fd, rot=82.38 >> 0.50.
DISK: Reading vsec=201 (1/1) (trk=11), psec=201, chk=0e, rot=82.88 >> 0.06.
DISK: Reading vsec=202 (1/1) (trk=11), psec=202, chk=f9, rot=82.43 >> 0.56.
DISK: Reading vsec=203 (1/1) (trk=11), psec=203, chk=91, rot=82.93 >> 0.11.
DISK: Reading vsec=204 (1/1) (trk=11), psec=204, chk=8e, rot=82.49 >> 0.61.
DISK: Reading vsec=205 (1/1) (trk=11), psec=205, chk=11, rot=82.99 >> 0.17.
DISK: Reading vsec=206 (1/1) (trk=11), psec=206, chk=02, rot=82.54 >> 0.67.
DISK: Reading vsec=207 (1/1) (trk=11), psec=207, chk=69, rot=83.04 >> 0.22.
DISK: Reading vsec=208 (1/1) (trk=11), psec=208, chk=8f, rot=83.60 >> 0.72.
DISK: Reading vsec=209 (1/1) (trk=11), psec=209, chk=b5, rot=84.10 >> 0.28.
DISK: Reading vsec=210 (1/1) (trk=11), psec=210, chk=73, rot=84.65 >> 0.78.
DISK: Reading vsec=211 (1/1) (trk=11), psec=211, chk=db, rot=85.15 >> 0.33.
DISK: Reading vsec=212 (1/1) (trk=11), psec=212, chk=75, rot=85.71 >> 0.83.
DISK: Reading vsec=213 (1/1) (trk=11), psec=213, chk=74, rot=86.21 >> 0.39.
DISK: Reading vsec=214 (1/1) (trk=11), psec=214, chk=c0, rot=86.76 >> 0.89.
DISK: Reading vsec=215 (1/1) (trk=11), psec=215, chk=51, rot=87.26 >> 0.44.
DISK: Reading vsec=216 (1/1) (trk=11), psec=216, chk=ff, rot=87.82 >> 0.94.
DISK: Reading vsec=217 (1/1) (trk=12), psec=217, chk=4b, rot=88.32 >> 0.00.
DISK: Reading vsec=218 (1/1) (trk=12), psec=218, chk=0b, rot=88.38 >> 0.50.
DISK: Reading vsec=219 (1/1) (trk=12), psec=219, chk=2d, rot=88.88 >> 0.06.
DISK: Reading vsec=220 (1/1) (trk=12), psec=220, chk=ce, rot=88.43 >> 0.56.
DISK: Reading vsec=221 (1/1) (trk=12), psec=221, chk=f5, rot=88.93 >> 0.11.
DISK: Reading vsec=222 (1/1) (trk=12), psec=222, chk=ff, rot=88.49 >> 0.61.
DISK: Reading vsec=223 (1/1) (trk=12), psec=223, chk=7b, rot=88.99 >> 0.17.
DISK: Reading vsec=224 (1/1) (trk=12), psec=224, chk=6c, rot=88.54 >> 0.67.
DISK: Reading vsec=225 (1/1) (trk=12), psec=225, chk=39, rot=89.04 >> 0.22.
DISK: Reading vsec=226 (1/1) (trk=12), psec=226, chk=35, rot=89.60 >> 0.72.
DISK: Reading vsec=227 (1/1) (trk=12), psec=227, chk=27, rot=90.10 >> 0.28.
DISK: Reading vsec=228 (1/1) (trk=12), psec=228, chk=81, rot=90.65 >> 0.78.
DISK: Reading vsec=229 (1/1) (trk=12), psec=229, chk=3b, rot=91.15 >> 0.33.
DISK: Reading vsec=230 (1/1) (trk=12), psec=230, chk=b9, rot=91.71 >> 0.83.
DISK: Reading vsec=231 (1/1) (trk=12), psec=231, chk=d5, rot=92.21 >> 0.39.
DISK: Reading vsec=232 (1/1) (trk=12), psec=232, chk=11, rot=92.76 >> 0.89.
DISK: Reading vsec=233 (1/1) (trk=12), psec=233, chk=66, rot=93.26 >> 0.44.
DISK: Reading vsec=234 (1/1) (trk=12), psec=234, chk=44, rot=93.82 >> 0.94.
DISK: Reading vsec=235 (1/1) (trk=13), psec=235, chk=ac, rot=94.32 >> 0.00.
DISK: Reading vsec=236 (1/1) (trk=13), psec=236, chk=08, rot=94.38 >> 0.50.
DISK: Reading vsec=237 (1/1) (trk=13), psec=237, chk=d0, rot=94.88 >> 0.06.
DISK: Reading vsec=238 (1/1) (trk=13), psec=238, chk=01, rot=94.43 >> 0.56.
DISK: Reading vsec=239 (1/1) (trk=13), psec=239, chk=52, rot=94.93 >> 0.11.
DISK: Reading vsec=240 (1/1) (trk=13), psec=240, chk=60, rot=94.49 >> 0.61.
DISK: Reading vsec=241 (1/1) (trk=13), psec=241, chk=35, rot=94.99 >> 0.17.
DISK: Reading vsec=242 (1/1) (trk=13), psec=242, chk=11, rot=94.54 >> 0.67.
DISK: Reading vsec=243 (1/1) (trk=13), psec=243, chk=29, rot=95.04 >> 0.22.
DISK: Reading vsec=244 (1/1) (trk=13), psec=244, chk=2c, rot=95.60 >> 0.72.
DISK: Reading vsec=245 (1/1) (trk=13), psec=245, chk=d9, rot=96.10 >> 0.28.
DISK: Reading vsec=246 (1/1) (trk=13), psec=246, chk=a6, rot=96.65 >> 0.78.
DISK: Reading vsec=247 (1/1) (trk=13), psec=247, chk=32, rot=97.15 >> 0.33.
DISK: Reading vsec=248 (1/1) (trk=13), psec=248, chk=31, rot=97.71 >> 0.83.
DISK: Reading vsec=249 (1/1) (trk=13), psec=249, chk=f7, rot=98.21 >> 0.39.
DISK: Reading vsec=250 (1/1) (trk=13), psec=250, chk=f0, rot=98.76 >> 0.89.
DISK: Reading vsec=251 (1/1) (trk=13), psec=251, chk=0e, rot=99.26 >> 0.44.
DISK: Reading vsec=252 (1/1) (trk=13), psec=252, chk=94, rot=99.82 >> 0.94.
DISK: Reading vsec=253 (1/1) (trk=14), psec=253, chk=56, rot=100.32 >> 0.00.

Link to comment
Share on other sites

Thanks for SIO dump of the Archon load, phaeron. I didn't know that Altirra could do that!

 

I don't disagree that VAPI/ATX is a better format for imaging copy-protected disks. My problem with it is the same problem I have with the SPS's IPF format -- there's no way for an end-user to create disk images (someone please correct me if I'm mistaken here). I realize that both ATX and IPF are WAY better for creating preservation quality images. When I can personally create an ATX file from a physical disk, it will become more interesting to me. Right now, PRO is the only format that allows me to do that and hence why I want to support it in SIO2Arduino. I personally have a lot of working PRO images I've made from my disk collection and I haven't seen any other hardware-based Atari drive emulators that can load them. Plus, the past few evenings have been a fun lesson in Atari disk copy protection which has always been a fascinating mystery to me.

 

Anyway, my intent with the thread wasn't to be an advocate for the PRO format. It exists for better or for worse and very few people know how it works. I definitely feel it deserves credit for what it is and it would be great for it to be properly documented. I was questioning whether I should help get the ball rolling on that front or whether it would ruffle any feathers.

Link to comment
Share on other sites

I have most of the PRO images that come with APE working properly (Bandits, Jumpman, Karateka, Archon 2, Ballblazer)... although Archon 1 is still giving me trouble for some reason even though it only has one phantom sector and uses phantom mode 2 the same as the others.

 

If by "phantom" you mean a sector with weak (or fuzzy, or flakey) bits, then Archon doesn't have any. Archon has the older EA protection, the same one in MULE. It has one duplicated sector (possibly Steve used the term phantom for a duplicated sector), and it has skew aligned tracks. Skew align requires rather strict (or at least constant, in this particular case) timing.

 

Now, regarding the Archon I .PRO image, it turns out that not only can Altirra boot the Archon I .pro image, it can do so with SIO patch enabled. The loader uses SIOV!

 

It doesn't surprise me. The way the "skew align" check is implemented, is by checking a more or less constant timing when reading sectors across tracks. It is not uncommon for emulators (and SIO2PC type setups) to "fool" the protection check. As long as every sector read would take the same time (since the previous one), that would make the protection check to pass.

Link to comment
Share on other sites

If by "phantom" you mean a sector with weak (or fuzzy, or flakey) bits, then Archon doesn't have any. Archon has the older EA protection, the same one in MULE. It has one duplicated sector (possibly Steve used the term phantom for a duplicated sector), and it has skew aligned tracks. Skew align requires rather strict (or at least constant, in this particular case) timing.

 

I'm using the same terminology that the PRO format uses. I believe what PRO calls a phantom sector is indeed a duplicated sector -- multiple reads of the same sector return different data. In the case of PRO, it can alternate between 5 sets of additional sector data.

 

It doesn't surprise me. The way the "skew align" check is implemented, is by checking a more or less constant timing when reading sectors across tracks. It is not uncommon for emulators (and SIO2PC type setups) to "fool" the protection check. As long as every sector read would take the same time (since the previous one), that would make the protection check to pass.

 

Interesting, I wasn't familiar with skew alignment... your nice writeup on the VAPI site clarified that for me. I will have to check if the problem lies in my emulation of the duplicate sector or the the timing of sector reads.

Link to comment
Share on other sites

Now, regarding the Archon I .PRO image, it turns out that not only can Altirra boot the Archon I .pro image, it can do so with SIO patch enabled. The loader uses SIOV! Here's the disk activity output from the Archon I load:

 

Puzzling, when I try booting the Archon I PRO image with Alitirra 2.00 (on a Mac under Parallels), the emulator just crashes around sector 50.

 

It appears that each time I boot, the first sector read after the batch of 21 sector 1 reads is different. I think that jibes with your comment that the loader is using SIOV. I wonder if it's vectoring based on timing or something strange like that?

Edited by Farb
Link to comment
Share on other sites

It appears that each time I boot, the first sector read after the batch of 21 sector 1 reads is different.

 

This is intentional. The protection selects random tracks, and checks that each track is (skew) aligned correctly.

 

I will have to check if the problem lies in my emulation of the duplicate sector or the the timing of sector reads.

 

That's pretty easy if you have some log of the sectors read. If the duplicate sector fails, it would lock immediately at that point. The duplicated sector is sector #41 (see Phaeron dump, it is read twice in a row). Skew align checking is performed later.

Edited by ijor
Link to comment
Share on other sites

That's pretty easy if you have some log of the sectors read. If the duplicate sector fails, it would lock immediately at that point. The duplicated sector is sector #41 (see Phaeron dump, it is read twice in a row). Skew align checking is performed later.

 

That makes sense. Here's what I see:

 

31 52 1 0 84 : READ 1
31 52 2 0 85 : READ 2
31 52 3 0 86 : READ 3
31 52 4 0 87 : READ 4
31 52 5 0 88 : READ 5
31 52 6 0 89 : READ 6
31 52 31 0 B4 : READ 49
31 52 32 0 B5 : READ 50
31 52 33 0 B6 : READ 51
31 52 34 0 B7 : READ 52
31 52 9 0 8C : READ 9
31 52 9 0 8C : READ 9
31 52 A 0 8D : READ 10
31 52 B 0 8E : READ 11
31 52 C 0 8F : READ 12
31 52 D 0 90 : READ 13
31 52 E 0 91 : READ 14
31 52 F 0 92 : READ 15
31 52 10 0 93 : READ 16
31 52 11 0 94 : READ 17
31 52 12 0 95 : READ 18
31 52 13 0 96 : READ 19
31 52 14 0 97 : READ 20
31 52 15 0 98 : READ 21
31 52 16 0 99 : READ 22
31 52 17 0 9A : READ 23
31 52 18 0 9B : READ 24
31 52 19 0 9C : READ 25
31 52 1A 0 9D : READ 26
31 52 1B 0 9E : READ 27
31 52 1C 0 9F : READ 28
31 52 1D 0 A0 : READ 29
31 52 1E 0 A1 : READ 30
31 52 1F 0 A2 : READ 31
31 52 20 0 A3 : READ 32
31 52 21 0 A4 : READ 33
31 52 22 0 A5 : READ 34
31 52 23 0 A6 : READ 35
31 52 24 0 A7 : READ 36
31 52 25 0 A8 : READ 37
31 52 26 0 A9 : READ 38
31 52 27 0 AA : READ 39
31 52 28 0 AB : READ 40
31 52 1 0 84 : READ 1
31 52 9 0 8C : READ 9
31 52 32 0 B5 : READ 50
31 52 29 0 AC : READ 41
31 52 29 0 AC : READ 41
31 52 36 0 B9 : READ 54
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 7F 0 3 : READ 127
31 52 13 0 96 : READ 19
31 52 D9 0 5D : READ 217
31 52 25 0 A8 : READ 37
31 52 1 0 84 : READ 1
31 52 37 0 BA : READ 55
31 52 FD 0 81 : READ 253
31 52 49 0 CC : READ 73
31 52 D9 0 5D : READ 217
31 52 5B 0 DE : READ 91
31 52 7F 0 3 : READ 127
31 52 6D 0 F0 : READ 109
31 52 FD 0 81 : READ 253
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 1 0 84 : READ 1
31 52 A3 0 27 : READ 163
31 52 13 0 96 : READ 19
31 52 A3 0 27 : READ 163
31 52 25 0 A8 : READ 37
31 52 6D 0 F0 : READ 109
31 52 37 0 BA : READ 55
31 52 13 0 96 : READ 19
31 52 49 0 CC : READ 73
31 52 D9 0 5D : READ 217
31 52 5B 0 DE : READ 91
31 52 EB 0 6F : READ 235
31 52 6D 0 F0 : READ 109
31 52 49 0 CC : READ 73

Edited by Farb
Link to comment
Share on other sites

You should be able to boot it in Altirra 2.00 with default settings (/resetall), followed by setting up and switching to the XL kernel. It will not boot with the built-in kernel due to a custom OS check, and it will not boot with the accurate disk timing option because that overrides .PRO sector ordering.

 

Looking at the dump, you passed the phantom sector check, and I'd say skew is the problem. I don't suppose you have an optimization to avoid hitting the backing store when the sector is already resident on the device? The emulator is running the program in virtualized time and can therefore do or not do I/O effectively instantly, but your device would have to spend real time doing that and you might be getting screwed by the variance.

Link to comment
Share on other sites

Looking at the dump, you passed the phantom sector check, and I'd say skew is the problem. I don't suppose you have an optimization to avoid hitting the backing store when the sector is already resident on the device? The emulator is running the program in virtualized time and can therefore do or not do I/O effectively instantly, but your device would have to spend real time doing that and you might be getting screwed by the variance.

 

Unfortunately, the device only has 8K of RAM so I can't load much data into memory from the backing store. I tried changing my algorithm to load and retain a track's worth of sector data at a time. My hope was that each time a skew check read a sector on a different track, the overall time to read a track and return a sector within it would be fairly consistent. It seems that there is a variance of around 1-2 milliseconds between each skew check read and that doesn't appear to cut it as the image still won't load.

Link to comment
Share on other sites

You might need to resort to a time delay to fix this, like padding out the ACK-to-Complete whenever the same sector is re-read or a sector on another track is requested. It'll slow down directory operations in DOS, but you could enable it only with .PRO images and a 5ms delay wouldn't be too bad.

Link to comment
Share on other sites

That's a good pointer in the right direction, phaeron. As a test, I tried making EVERY sector read consistently take 111ms and that worked. However, trying to make all sector reads take a consistent amount of time (6ms) and all track changes a consistent amount of time (105ms) doesn't work. So there's still something I'm not understanding. For example, here's a log of a failed load:

 

31 52 1 0 84 : READ 1
Changing tracks
Read sector and sent complete in 111576 us
31 52 2 0 85 : READ 2
Read sector and sent complete in 6160 us
31 52 3 0 86 : READ 3
Read sector and sent complete in 6156 us
31 52 4 0 87 : READ 4
Read sector and sent complete in 6152 us
31 52 5 0 88 : READ 5
Read sector and sent complete in 6152 us
31 52 6 0 89 : READ 6
Read sector and sent complete in 6160 us
31 52 31 0 B4 : READ 49
Changing tracks
Read sector and sent complete in 111548 us
31 52 32 0 B5 : READ 50
Read sector and sent complete in 6156 us
31 52 33 0 B6 : READ 51
Read sector and sent complete in 6160 us
31 52 34 0 B7 : READ 52
Read sector and sent complete in 6164 us
31 52 9 0 8C : READ 9
Changing tracks
Read sector and sent complete in 111568 us
31 52 9 0 8C : READ 9
Read sector and sent complete in 6156 us
31 52 A 0 8D : READ 10
Read sector and sent complete in 6156 us
31 52 B 0 8E : READ 11
Read sector and sent complete in 6160 us
31 52 C 0 8F : READ 12
Read sector and sent complete in 6164 us
31 52 D 0 90 : READ 13
Read sector and sent complete in 6156 us
31 52 E 0 91 : READ 14
Read sector and sent complete in 6180 us
31 52 F 0 92 : READ 15
Read sector and sent complete in 6156 us
31 52 10 0 93 : READ 16
Read sector and sent complete in 6160 us
31 52 11 0 94 : READ 17
Read sector and sent complete in 6160 us
31 52 12 0 95 : READ 18
Read sector and sent complete in 6156 us
31 52 13 0 96 : READ 19
Changing tracks
Read sector and sent complete in 111568 us
31 52 14 0 97 : READ 20
Read sector and sent complete in 6160 us
31 52 15 0 98 : READ 21
Read sector and sent complete in 6152 us
31 52 16 0 99 : READ 22
Read sector and sent complete in 6160 us
31 52 17 0 9A : READ 23
Read sector and sent complete in 6160 us
31 52 18 0 9B : READ 24
Read sector and sent complete in 6160 us
31 52 19 0 9C : READ 25
Read sector and sent complete in 6156 us
31 52 1A 0 9D : READ 26
Read sector and sent complete in 6156 us
31 52 1B 0 9E : READ 27
Read sector and sent complete in 6160 us
31 52 1C 0 9F : READ 28
Read sector and sent complete in 6152 us
31 52 1D 0 A0 : READ 29
Read sector and sent complete in 6164 us
31 52 1E 0 A1 : READ 30
Read sector and sent complete in 6156 us
31 52 1F 0 A2 : READ 31
Read sector and sent complete in 6152 us
31 52 20 0 A3 : READ 32
Read sector and sent complete in 6152 us
31 52 21 0 A4 : READ 33
Read sector and sent complete in 6160 us
31 52 22 0 A5 : READ 34
Read sector and sent complete in 6152 us
31 52 23 0 A6 : READ 35
Read sector and sent complete in 6156 us
31 52 24 0 A7 : READ 36
Read sector and sent complete in 6156 us
31 52 25 0 A8 : READ 37
Changing tracks
Read sector and sent complete in 111568 us
31 52 26 0 A9 : READ 38
Read sector and sent complete in 6156 us
31 52 27 0 AA : READ 39
Read sector and sent complete in 6152 us
31 52 28 0 AB : READ 40
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Changing tracks
Read sector and sent complete in 111564 us
31 52 9 0 8C : READ 9
Read sector and sent complete in 6164 us
31 52 32 0 B5 : READ 50
Changing tracks
Read sector and sent complete in 111552 us
31 52 29 0 AC : READ 41
Read sector and sent complete in 6160 us
31 52 29 0 AC : READ 41
Using phantom sector
Read sector and sent complete in 13952 us
31 52 36 0 B9 : READ 54
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Changing tracks
Read sector and sent complete in 111564 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6152 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6164 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6164 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6152 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6152 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6148 us
31 52 A3 0 27 : READ 163
Changing tracks
Read sector and sent complete in 111560 us
31 52 13 0 96 : READ 19
Changing tracks
Read sector and sent complete in 111552 us
31 52 37 0 BA : READ 55
Changing tracks
Read sector and sent complete in 111560 us
31 52 25 0 A8 : READ 37
Changing tracks
Read sector and sent complete in 111552 us
31 52 6D 0 F0 : READ 109
Changing tracks
Read sector and sent complete in 111552 us
31 52 37 0 BA : READ 55
Changing tracks
Read sector and sent complete in 111548 us
31 52 1 0 84 : READ 1
Changing tracks
Read sector and sent complete in 111568 us
31 52 49 0 CC : READ 73
Changing tracks
Read sector and sent complete in 111552 us
31 52 FD 0 81 : READ 253
Changing tracks
Read sector and sent complete in 111540 us
31 52 5B 0 DE : READ 91
Changing tracks
Read sector and sent complete in 111552 us
31 52 6D 0 F0 : READ 109
Changing tracks
Read sector and sent complete in 111572 us
31 52 6D 0 F0 : READ 109
Read sector and sent complete in 6160 us
31 52 D9 0 5D : READ 217
Changing tracks
Read sector and sent complete in 111540 us
31 52 1 0 84 : READ 1
Changing tracks
Read sector and sent complete in 111564 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6148 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6164 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6152 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6164 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6164 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6156 us
31 52 1 0 84 : READ 1
Read sector and sent complete in 6160 us
31 52 D9 0 5D : READ 217
Changing tracks
Read sector and sent complete in 111544 us
31 52 13 0 96 : READ 19
Changing tracks
Read sector and sent complete in 111556 us
31 52 A3 0 27 : READ 163
Changing tracks
Read sector and sent complete in 111560 us
31 52 25 0 A8 : READ 37
Changing tracks
Read sector and sent complete in 111552 us
31 52 1 0 84 : READ 1
Changing tracks
Read sector and sent complete in 111560 us
31 52 37 0 BA : READ 55
Changing tracks
Read sector and sent complete in 111552 us
31 52 6D 0 F0 : READ 109
Changing tracks
Read sector and sent complete in 111552 us
31 52 49 0 CC : READ 73
Changing tracks
Read sector and sent complete in 111552 us
31 52 6D 0 F0 : READ 109
Changing tracks
Read sector and sent complete in 111548 us
31 52 5B 0 DE : READ 91
Changing tracks
Read sector and sent complete in 111556 us
31 52 7F 0 3 : READ 127
Changing tracks
Read sector and sent complete in 111580 us
31 52 6D 0 F0 : READ 109
Changing tracks
Read sector and sent complete in 111552 us
31 52 49 0 CC : READ 73
Changing tracks
Read sector and sent complete in 111548 us

Edited by Farb
Link to comment
Share on other sites

The time for a read frame without delays is around 75ms, so you've got about 81 ms vs. 180ms... that looks way off. What you really need is for the time between the ends of data frames of adjacent requests to be multiples of a common value (the simulated disk rotation speed). If you can equalize the delays for all requests, then it works out for a particular loader, but if you've got a longer delay for one case then that needs to be a multiple of the total time. What you may need to do instead is stall until it's been a multiple of 80ms since the end of the last request, or 208ms if you want to be faithful to 288 RPM.

Link to comment
Share on other sites

Also note - although the games probably don't/can't check unless using custom SIO -

 

The delay for a read should also be for the "Complete" reply from peripheral, not just the transmission of the data frame.

 

So you have: Read Command ... peripheral "Ack" ... peripheral (extra) delay ... peripheral "Complete" ... peripheral data frame.

Link to comment
Share on other sites

Well, the actual read times for sector data when read from the SD backing store individually (no track buffering) is under 10ms. So, as phaeron mentioned earlier, I if I just make all sector reads take a consistent 75ms, the skew check seems to pass. That seems to be the easiest route to the goal and I'll only enable it if a PRO image is mounted.

Edited by Farb
Link to comment
Share on other sites

As a test, I tried making EVERY sector read consistently take 111ms and that worked. However, trying to make all sector reads take a consistent amount of time (6ms) and all track changes a consistent amount of time (105ms) doesn't work. So there's still something I'm not understanding.

 

Do you see in the logs that the protection is reading sector 1 more than a dozen times? Why you do think it does so ? :)

 

Well, what it does is to compute the average timing to read two sectors that are perfectly aligned in the same angular position. In effect, it is computing the average RPM. Later, it reads aligned sectors, but now in two different tracks. And it expects that the timing will match close enough to the timing computed when it read sector 1, or a multiple of it. Otherwise, the skew align check fails (as it happens to you in your second test).

 

So, as phaeron mentioned earlier, I if I just make all sector reads take a consistent 75ms, the skew check seems to pass. That seems to be the easiest route to the goal and I'll only enable it if a PRO image is mounted.

 

That depends on which exactly is the goal. If all you want is to run this protection, in this specific EA implementation, then that's ok. But as phaeron is saying, that strategy would break with different protections, or even possibly with a different implementation of this protection. If your goal is to emulate copy protected disks as many as possible, then there is no option other than trying to emulate the real timing as accurately as possibly.

 

Btw, most original loaders use SIOV or DSKINV ($E453). Very few go directly to the hardware (Lucasfilm games is a notable case).

 

**** Note to the Admin and mods ****

There is something in this thread that some browsers don't like. Some versions of Firefox hang and some versions of the Android browser crash. I assume I am not the only one seeing this behaviour, am i?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...