Anonymous
User login
Please support the defense of Ukraine.
Direct or via Unclutter App
Active forum topics
Recent content
Navigation
No Ads.
No Trackers.
No Social Media.
All Content Locally Hosted.
Built on Free Software.
We have complied with zero government requests for information.
Yes, the speed looks perfect. Does your STM work with Locksmith's Fast Backup (NOT the ordinary slow Backup) especially when acting as a writing drive? Along with V option for writing with verification?
I will do the test,
it passes the certify process without any problem
No, not Certify. Fast Backup is the fastest diskette copy. Once loaded enter [V] RETURN to switch on verification after writing process. "12" means copying is to be done from drive one to drive 2. "21" means the source is drive 2 and destination is drive 1. "12V" means that along with copying a verification of written tracks is also done on the fly.
I did the test, and it seems to pass the test
IMG_6695.jpeg
Moving forward trying to get Bouncing Kamungas - Disk 1, Side A working.
Given the approach to play with the track size, the DMA has to be stopped, resized and restarted. This is one of the limitation of the STM32 circular buffer. when restarted it is not possible to resume the position of the last read index.
This is an issue when playing with the cross track read or the so called spiral track. But I guess this is not implemented in Bouncing Kamungas - Disk 1, Side A.
I am considering the following options to address this issue:
- Having a larger DMA track size and playing with the remaining bytes index to be sent according to the real track size
- Doing memcopy in 2 parts to shift the start of the next track according to the last read index.
I need to do some testing of the 2 solutions...
Regarding Bouncing Kamungas - Disk 1, Side A, I will try to play with a bit slip at the beginning to see if I have an alignement issue.
Any other hint would be really help me, because except from this I do not understand the blocking point.
V
Excellent for Fast backup. I can assure you Apple2's accept much lower drive rpm than the defined 2%. My advice is to assume the largest buffer you've seen in any woz and play it at the convenient rate about 4uS per bit, you can try that for every disk image, it must work. If the buffer is less than your defined size, just fill it with noise/gap, and don't bother with buffer resizing. One comment on the WOZ files, they are usually "artificially" reviewed/modified by humans or software and unlike A2R do not necessarily represent the physical diskette recording. The WOZ purpose is to use the software with (drive) emulators.
Rereading the WOZ spec and focusing on what is called weak bits,
In the Bouncing Kamungas, in the info chunk WeakBits is set to 1, meaning that fake bits are replaced by 0;
This part is not yet implemented in my firmware, and I search for a 0b000 pattern in track 0 -> 3, and I found many of this pattern, like the one in the red box.
Screenshot 2024-07-18 at 17.49.44.png
It can be pure garbage or this could be as well the explaination of my issue ? What do you think ?
Vincent
EDIT 1 the suggested approach by applesauce is to do :
I need to see how I would implement this in the circular buffer to make bit random each round of the circular DMA...
The best approach would be to identify fake bits position during the adjacent track load, and to change them using the DMA half track interrupt.... well not an easy piece of work....
Is everything else apart from weak bits working? Does your STM now work with 99.9% of the disk images available on the net?
I think for the weak/random bits you have to give up the DMA and start bit banging bits.
In post #159, 'retro_devices' wrote:
" I think for the weak/random bits you have to give up the DMA and start bit banging bits. "
Uncle Bernie comments:
I think it's too soon to address the 'weak bit' problem right now. I've recommended in a post above to first try and catalog ALL recommended WOZ file images if they load and run fine with this emulator. I think 'weak bits' are less important until everything else works.
"bit banging" to the port is not necessary for emulation of 'weak bits'. Knowing where they are, an interrupt can be timed to fire sufficiently long before the DMA reads them, and then the interrupt routine would put certain plausible 'weak bit' patterns onto the track buffer at the known place. These must change once every revolution. Note that the extreme case are unformatted tracks where everything being read is a total random mess. All these thing are not difficult to program, but time consuming, to implement and test all cases, and I would not do that before everything else related to reading tracks is stable and works. The rationale behind this is that if the track buffer machinery changes, for any reason, most likely you can throw all your 'weak bit' code into the trash, and all the work on it is wasted.
- Uncle Bernie
Well, one more time you are right !
I have installed apple2js from https://github.com/whscullin/apple2js#readme
This emulator is js based and able to read all woz file... (not like mine ;) ) including Bouncing Kamunga !
I have modified the woz_driver of the apple2js to disable the weak_bits feature and it can still read and launch BK, so the issue on my side is somewhere else !
On my emulator the head move is the following (after the reset init move to head track 0)
ph:02 newTrak:00, prevTrak:01, prev_woz_trk:00-01-02 woz_trk:00-01-02 0 M1:2 P1:1 op:1--1-1 DMA_SIZE:6374 d1:786092 d2:53ph:04 newTrak:01, prevTrak:00, prev_woz_trk:00-01-02 woz_trk:00-01-02 1 M1:0 P1:2 op:1--1-1 DMA_SIZE:6372 d1:783463 d2:55ph:08 newTrak:02, prevTrak:01, prev_woz_trk:00-01-02 woz_trk:01-02-03 1 M1:0 P1:2 op:1--1-0 DMA_SIZE:6372 d1:819233 d2:629840ph:12 newTrak:03, prevTrak:02, prev_woz_trk:01-02-03 woz_trk:02-03-04 1 M1:0 P1:2 op:1--1-0 DMA_SIZE:6372 d1:821849 d2:625754
On the apple2js :
it goes from track 0 to (very briefly to track 2) and then to track 4 ! not stopping in track 3
It seems something is wrong on track 0 on my end...
V
After copying a diskette with Locksmith is the copy working?
yes...
& the bad news is that doing test, changing things nothing works... :(
I suspect that I might have an issue with the LS123...
V
The disk copied with LockSmith works, I use Donkey Kong.woz,
I came back to using the DMA in Master mode and to avoid the external timer to check if I do not have an delay issue and I was using an inverted polarity on the Clock which was causing the LS123 to do some noise on the output.
Now I have back something working (if one can say)
I have done check & recheck, it seems that the image Bouncing Kamunga is weakBit sensible...
I was keeping all the zero and it was working, but when I increase the number of 1 it is not working anymore.
I have nothing else todo than testing this piece....
V
This is my poor score card :
//sprintf(filename,"/WOZ 2.0/Blazing Paddles (Baudville).woz"); // NOT WORKING playing with 255 track 0 & 1 and BLAZING PADDLES TXT 04431 on screen
//sprintf(filename,"/WOZ 2.0/Border Zone - Disk 1, Side A.woz"); // NOT WORKING
sprintf(filename,"/WOZ 2.0/Bouncing Kamungas - Disk 1, Side A.woz"); // NOT WORKING
//sprintf(filename,"/WOZ 2.0/Commando - Disk 1, Side A.woz"); // NOT WORKING
//sprintf(filename,"/WOZ 2.0/DOS 3.2 System Master.woz"); // NOT WORKING
//sprintf(filename,"/WOZ 2.0/DOS 3.3 System Master.woz"); // 15/07 WORKING
//sprintf(filename,"/WOZ 2.0/Dino Eggs - Disk 1, Side A.woz"); // NOT WORKING playing with 255
//sprintf(filename,"/WOZ 2.0/First Math Adventures - Understanding Word Problems.woz"); // WORKING 20.07
//sprintf(filename,"/WOZ 2.0/Hard Hat Mack - Disk 1, Side A.woz"); // NOT WORKING stay at track 0;
//sprintf(filename,"/WOZ 2.0/Miner 2049er II - Disk 1, Side A.woz"); // NOT WORKING playing with 255
//sprintf(filename,"/WOZ 2.0/Planetfall - Disk 1, Side A.woz"); // NOT WORKING plkaying with 255
//sprintf(filename,"/WOZ 2.0/Rescue Raiders - Disk 1, Side B.woz"); // NOT WORKING playing with 255
//sprintf(filename,"/WOZ 2.0/Sammy Lightfoot - Disk 1, Side A.woz"); // NOT WORKING Stop at track 0
//sprintf(filename,"/WOZ 2.0/Stargate - Disk 1, Side A.woz"); // NOT WORKING playing with 255
//sprintf(filename,"/WOZ 2.0/Stickybear Town Builder - Disk 1, Side A.woz"); // NOT WORKING Can see the splashscreen (with missing line) then stop
//sprintf(filename,"/WOZ 2.0/Take 1 (Baudville).woz"); // NOT WORKING Playing with 255
//sprintf(filename,"/WOZ 2.0/The Apple at Play.woz"); // 15/07 WORKING
//sprintf(filename,"/WOZ 2.0/The Bilestoad - Disk 1, Side A.woz"); // NOT WORKING Scramble flashing screen moving from track 0 to 1
//sprintf(filename,"/WOZ 2.0/The Print Shop Companion - Disk 1, Side A.woz"); // NOT Working playing with track 255
//sprintf(filename,"/WOZ 2.0/Wings of Fury - Disk 1, Side A.woz"); // NOT Working playing with track 255
In post #166, 'VIBR' wrote:
'" This is my poor score card "
Uncle Bernie comments:
Don't give up, the fact that you can parse WOZ files and boot DOS 3.3. means that great work already has been done !
Ignore DOS 3.2. because this came before the upgrade of the DISK II card with different PROMs. DOS 3.3 came with a new set of PROMs which changed the state machine on the DISK II card and the GCR encoding. This increased the number of sectors per track from 13 to 16. A conversion program was provided to read the old floppy disks and turn them into the new format. I don't know if DOS 3.2.1. itself would ever boot on the modified DISK II card with the new PROMs, maybe somebody in the know can chime in here.
This is what I would do:
Look for WOZ files of older titles with less sophisticated copy protecttion schemes. Use the 'Tome" book as a guidance. Find some titles which work (this will boost your confidence) and research which copy protections they use. Make a spreadsheet, line items are software titles, colums are copy protection methods. Put in a 'F' for 'fail' or a 'P' for 'pass' in the intersections. A pattern will emerge which will guide you through the debugging process. Note that a lot of the later titles are protected by one (or more) of a group of commercially sold protection methods, and maybe two of them dominated the marketplace for Apple II copy protections. So if you solve this riddle for one of the titles using a given protection, a LOT of other titles you struggled with will change from 'F' to 'P'. Look into the '4AM' cracks ... they come with a disk image file and most have an additional bonus file which contains a discussion which protection was used and how it was cracked. These '4AM' files are a treasure trove for researchers of Apple II copy protections, despite the crack of course removed it. But you can check the '4AM' repository for the same titles your floppy emulator has trouble with the WOZ files, and in most cases, '4AM' will tell you which copy protection was used. This will get your work up to speed !
As a general advice, try to find a simple protection which relies on 'synchronized tracks' first, but no 'spiral tracks' yet. Develop your firmware until this works, which essentially means you got the loading of the track buffers and the timing of the stepping action between the tracks right. This is very, very important. Once tracks are switched, you cannot allow your emulator to lose the perfect synchronization with the (virtual) rotating 'floppy disk'. If you slip the timing by more than a few bytes (6400 * 0.01 = 64 bytes ??? ... 1% RPM error) then all bets are off (it won't work, and your platform is wonky ... don't build any other copy protection method emulation on this sand ;-)
Once this works, proceed to 'fat tracks' and once that works, to 'spiral tracks'. Always do regression tests.
Once your emulator can do that, you may proceed with the 'weak bits'. I think you NEVER would need to indulge into the details of ANY of the 'modified GCR encoding' or 'weird format' copy protection techniques because the bit cell stream technique should provide all of that automatically, without any extra coding effort.
Still, a lot of work to be done. All I can do is to give you guidance in which direction to proceed, based on my experience with my own floppy emulator development for the Atari 8-bit (which was never commercialized, I did that because I saw my floppy disks deteriorating). On the Atari, exact timing of everything is essential. I used a 8-bit timer running forever which emulated the rotation of the floppy disk with 0.5% accuracy. This turned out to be good enough even for the most aggressive 'synchronized track' protections. If your floppy emu has deficiencies there, fix these first.
- Uncle Bernie
Thanks Uncle Bernie for the advice.
I will not let go until I finish the work and I think I need to step back before further testing. Somehow, retro_device is right, one of the issue is the lack of time accuracy and one of the reason is the STM32 High Abstraction Level driver.
In fact, after doing some testing, it appears that HAL Driver brings jitter in DMA Stop & Start as well as for the TIMER.
Before moving forward I have to fix this by writing Low level driver (that does not exist), it is not a big deal it is playing with core registers but it takes time to make it right.
I need to be able :
- to start the DMA,
- to transfer the predefined number of Bytes
- to stop it with time accuracy & interrupt based,
Everything monitored by an internal timer (as suggested) and by the logic Analyzer.
Vincent
Me Again,
to be able to debug investigate I need also to be able to have the logic analyzer time synced with the DMA SPI and the RDDATA and this is not the case because of the LS123...
I also had a look at the write bloc that would be simplified and maybe with more accuracy.
On the READ SIDE, the LS123 is gone and replace by a LS74 where :
- TIM3 is a PWM timer used to clock the SPI at 250 MHz (2 uS duty cycle for 4 uS period)
- TIM1 is a PWM timer with a 1 uS duty cycle with 4 uS period.
TIM3 trigger TIM1 and thus both are synced, no need anymore to have LS123
Polarity of TIM1 & TIM3 is HIGH, the clear pin on LS74 is active low, it should work.
I also changed LS125 RDATA pull-up to pull-down.
Below is the 2 TIMER on the Logic Analyzer, Data will be set on the rising edge
Screenshot 2024-07-22 at 17.12.55.png
On the WRITE SIDE:
I remove as well the LS123 and the Counter the LS393, I changed TIM4 to TIM2 (due to pin occupation issue),
ETR_TIM2 is connected to /WRDATA and triggers TIM2 that is a 2Mhz timer (2 uS pulse, 4 uS period) auto reload timer, (trigger and reset),
without ETR_TIM2 pulse (TIM2 continues and get resync every pulse).
This is the new schema:
Screenshot 2024-07-22 at 17.19.20.png
NB: I also changed the Blackpill from STM32F401 to STM32F411 (100 Mhz, 128 KBytes SRAM), this is why the period of the timer and duty cycles have changed.
Uncle Bernie, WDYT?
Vincent
it is working for the read side, I will do some testing for the write side
I am focusing on the read part of the emulator,
I change the circuitery of the read side to be able to fully debug with the logic analyzer.
I add as well a 74LS08 to be able to stop or not the RDDATA stream, it appears that when the SPI is stop on a FF the RDDATA line stay high... with is not great from a nibbe counting perspective.
I found also something a bit weired,
The image "The Apple at play.woz" was working and it is not anymore...
I have done some investigation and it appears that when the emulator is switching the data track to fast it does not work but when I add between 5 to 8 ms delay (like the normal coil switching) it start working again...
Is this normal ?
Vincent
In post #179, 'VIBR' wrote:
" I have done some investigation and it appears that when the emulator is switching the data track to fast it does not work but when I add between 5 to 8 ms delay (like the normal coil switching) it start working again... "
" Is this normal ? "
Uncle Bernie comments:
Well, it is not "normal" for a floppy disk image to behave like that UNLESS it has a copy protection which looks for the timing between tracks to be right. The so-called 'synchronized track' protections take this to the max, as ALL tracks are synchronized and are being checked for proper radial alignment, but actually, TWO synchronized tracks are enough. The chance to accidentially "hit" the right alignment by a copy program NOT instructed to do the alignment is very low. If I'd design a 'synchronized track' copy protection it would only use two tracks, spread apart, and all the other tracks would not look aligned. This would slow down software pirates by a few hours, or maybe days ;-) . . . if you wanted to really sabotage their efforts then relax the check such that they have a maybe 30% chance to get a functional pirated copy despite using no alignment copy mode. So they would think the copy is OK and send it to their peers. Who would try to make a 2nd generation copy for their peers and fail. And then complain. Which costs time, effort, and postage. A similar rationale applies to other copy protections: use a weak one and a strong one. The weak one, if not copied properly, would crash the program upon booting. But if the weak one was copied correctly (i.e. by LOCKSMITH), and the strong one would not be copied perfectly, the game would work, but have a dead counter which self-destructs the floppy disk contents after X loads. As this would happen downstream along the software pirate's distribution chain, it will cause a lot of complaints and a lot of effort to remedy. I'm mentioning this not as a recipe to build floppy disk copy protections (as they are a thing of the past, and floppy disks went the way of the dinosaur), but there are lessons to be learned here on how to test floppy disk emulators dealing with images of copy protected floppy disks. Add a indicator flag which tells you if the game tries to write to the floppy disk. This may be harmless (such as keeping a scoreboard or allowing to save the game state) but it also could mean the game tries to self-destruct.
I already did explain here on an earlier post how to treat the change of tracks properly. Your ST32 can do interrupt-on-change for the PH0 ... PH3 stepper motor phases to detect when the software initiated a track change, but there will be some mechanical inertia before the head starts moving and even more delay until the RDDATA pattern gets disturbed (as the head moved away from that track). Until that point in time after a stepper motor phase change you MUST provide the correct RDDATA pattern of the old track. You can use the time to load the next track into a new track buffer, though. But you can't overwrite the old track buffer as the RDDATA stream must continue to flow for a small amount of time. The next thing is that you need to start the DMA out of your new track buffer at the right place which is the rotational angle you can calculate from the 'forever running' timer that rolls over all 200ms, or once per revolution.
If you did not implement this track change mechanism in the right way, it's no wonder that many copy protected floppy disk images won't load.
- Uncle Bernie
In my effort to build my lib of protection type, I have search for info on the Internet and I found 2 very intersting articles :
- E7 protection with slip bit explain in details pferrie E7 protection
- GFTO Issue 10 with a special list of Apple II copy protection POC GFTO Issue 10
This is for me gold mine :)
I am on vaccations, so my prototpye is waiting at home, and I am reading stuff on copy protection as 4am txt file that are very useful
Hello All,
Quick update on my side, I do not have my Apple on vaccation but I continue my journey to fix the STM32 emulator and understand why it is not passing basic copy protection.
Reading 4am text file on the proposed woz images from AppleSauce, I decided to focus my efforts on Commando as a starting
Commando protection is using 2 protection:
- Epilogue change for both Address and Data field: instead of using DE.AA.EB, it is using FF.FF.EB (should not be an issue)
- Timing bit on sector 0x0D with between the Address Field and the Data field a bytes sequence with double timing bit on Byte 15, (ff e7 f9 fe 7f 9f e7 f9 fe)
It seems that the appleSauce version of Commando is not the same as the one from 4am,
Using a python script to convert Nibble to machine code (gcr 6 and 2), I found the protection on T00,S03 instead of S06. even the byte sequence is not exactly the same.
I used a 6502 disassembler to be able to check the asm code (https://www.masswerk.at/6502/disassembler.html)
the protection is here: (the sector in Apple II memory is at D8XX)
0041 BD 8C C0 L0041 LDA $C08C,X ;(4/5)
0044 10 FB BPL L0041 ;(2/3)
0046 88 DEY ;(2)
0047 F0 43 BEQ L008C ;(2/3)
0049 C9 E7 CMP #$E7 ;(2)
004B D0 F4 BNE L0041 ;(2/3)
004D BD 8C C0 L004D LDA $C08C,X ;(4/5)
0050 10 FB BPL L004D ;(2/3)
0052 C9 E7 CMP #$E7 ;(2)
0054 D0 36 BNE L008C ;(2/3)
0056 BD 8C C0 L0056 LDA $C08C,X ;(4/5)
0059 10 FB BPL L0056 ;(2/3)
005B C9 E7 CMP #$E7 ;(2)
005D D0 2D BNE L008C ;(2/3)
005F BD 8D C0 LDA $C08D,X ;(4/5)
0062 A0 10 LDY #$10 ;(2)
0064 24 06 BIT $06 ;(3)
0066 BD 8C C0 L0066 LDA $C08C,X ;(4/5)
0069 10 FB BPL L0066 ;(2/3)
006B 88 DEY ;(2)
006C F0 1E BEQ L008C ;(2/3)
the typical LDA $C08D is doing a reset of the latch to desync the stream and be able to see the timing bit
when the protection failed (copy is detected a branch is done to 0x008c
so my next step is to replace the BNE branch to 0x8C (+D8), by a branch at the end of the sector to display on screen a debug message based on the Accumulator content
I am not done yet but I am progressing ;)
at least I learnt a bit of 6502 asm and copy protection.
to be continued
In post #174, 'VIBR' wrote:
" It seems that the appleSauce version of Commando is not the same as the one from 4am ..."
Uncle Bernie comments:
Of course ! It has to be like that because:
- AppleSauce makes WOZ files which contain the original copyprotection as faithfully as possible. The rules are:
Do do not make any changes to the contents of the floppy disk image.
No code patches, no manipulations.
- 4AM is a very sophisticated "cracker" who makes "cracks" and produces disk images which do not contain the original copy protection anymore. These disk images are supposed to be fit to be copied with some very primitive utility which otherwise is unable to make a functional copy of the original disk. Making the "cracked" version involves code changes to the contents of the floppy disk, so these "4AM cracks" are NOT a faithful reproduction of the original floppy disk. But "4AM" tries to keep everything in the program intact, including the title screens, and does NOT put his "tag" in like many teenage crackers back in the 1980s did (and ruining the experience. You do not want a mutilated title screen spelling out "Cracked by the Green Mental Midget. For more cracks, call the safehouse, phone number ...", wherein the phone number may have been a BBS, no way to find out almost half a century later.)
Now here is a dirty little secret about "cracking": in some cases the copy protection was so tough to crack that the "cracker" could not remove it completely by manipulating the code alone. It may have been necessary to put some alternate "weird format" on the floppy disk which is easier to copy but fools the copyprotection checks into thinking it's an original. So standard Apple DOS3.3 copy utilities could not copy these "cracked" disks and some "defeated" version of LOCKSMITH - or the like - was needed. With "defeated" I mean that that version could not copy the original floppy disk with the original, tough copy protection anymore. But you can see the manipulations done by the "cracker" in this case as a "downgrade" of the original copy protection to make it copyable by the "defeated" tools.
Whether this conundrum applies to 4AM cracks, I can't say, as I did not look into them too much. I was more interested in the "extras" where 4AM describes the copy protection and how he cracked it, and not in the cracked version of the program itself. This of course was driven by trying to study which Apple II copy protections where there, back in the 1980s and early 1990s. Then I found the "Tome" book and my thirst for information was satisfied. At least for the moment.
You should not confuse or compare WOZ images coming from AppleSauce and 4AM images. I recommended the latter for you such that you can look at the "extras" explaining how the copy protection on the WOZ file works. This was thought to help you with debugging your floppy emu firmware. If your floppy emu can't support loading 4AM crack disk images, and the crack won't run, something more serious is wrong in your code. But don't give up ... all the "secrets" about Apple II copy protections from half a Century ago ain't no secrets anymore, they are public knowledge that can be found on the internet. So you have all the know-how right there. The trick is to a) find these docs (I gave you the hint with 4AM) and b) apply the knowledge gained.
Good luck !
- Uncle Bernie
Hello Uncle,
I thought you were as well on pause for the summer, good to have you responding.
You are right 4am text file are a gold of mine, that I look after them very carefully to understand copy protection.
I spend quite some time on Commando, and getting deeper to the asm code (reversing the original game) I do not fully agree with 4am. I think he has done it on purpose or maybe was too quick when writing his review, or we simply do not have the same version of the game (which i doubt because the sector chksum are the same...)
4am is providing the unprotected woz file and the one with the crack.
for my case study I use the version from Applesauce.
4am find the protection on T00,S06 where I find it on Sector 03
4am states:
Well after deNibble, paddingBits, removingTimingBits, 6&2 GCR Decoding and dissaembly, I can tell this is not true: it is not in the dead zone (the zone between the address field and the data field), it is in the data zone on Track17 sector 0D
After reading the D5.AA.AD: it is looking for a serie of E7 (3 to be precised) after an endless 96 : see below the dump of the sector 0D
Screenshot 2024-08-06 at 15.31.50.png
Y Register starts at 255 and a check is made to reach 0 if E7 is not found (then the protection failed)
after the 3xE7 are found, it creates a desync of the latch (with LDA $C08D, it is like reseting the latch in the middle of a nibble): add D48 to the address below (it is clearly not a slow reading just a desync like the typical E7 protection)
005F BD 8D C0 LDA $C08D,X ;(4/5)
0062 A0 10 LDY #$10 ;(2)
0064 24 06 BIT $06 ;(3)
and then it starts reading the content of the indirect addressing at zero page $48 & $49 that contain D89F (D8 in $49 and 9F in 48, one have to read it in reverse order)
and compare with the dsync reading, desync reading is working because of the timingBits at the right place
this is below the dump of the sector 0D with the timingBits in place :
Screenshot 2024-08-06 at 15.49.23.png
The TimingsBits are in position:
timingBits pos:112
timingBits pos:113
timingBits pos:138
timingBits pos:139
timingBits pos:148
timingBits pos:149
timingBits pos:158
timingBits pos:159
timingBits pos:168
timingBits pos:169
timingBits pos:178
timingBits pos:179
timingBits pos:188
timingBits pos:189
timingBits pos:198
timingBits pos:199
timingBits pos:208
timingBits pos:209
timingBits pos:218
timingBits pos:219
so if my Emulator is not going to track 17, I might have another issue indeed
My quest continue, one possible answer is that my emulator is eating timings bits... will do some checks when I will be back home.
Understanding how games where protected 40 years ago is really fun ;)
When I will have time, I will do a quick how-to with my github scripts for people wanting to learn how to go in the deep of ASM (if I can do it, trust me everybody can do it ;) ).
Vincent
This is all above my pay grade. But if you are reading up on 4am's write up on the E7 protection, make sure you read the revised one (which maybe you are, again, above my pay grade). At least I'm assuming he revised it.
In a nutshell, about 3 years ago it was discovered that his E7 cracking method wasn't 100% right. As I understand it, his original thoughts on how it worked were wrong, but by a fluke worked only on standard disk II controllers, and would fail on IWMs. It took a while before it was caught that it was failing on IWM machines and caused him to go back and reinvestigate the whole thing.
Hello Nick3092,
Yes I have seen the last post on the E7. My goal is not to have an emulator working with a crack but pass the copy protection like any original game and it is not the case, and for the moment I am building tools to understand what is happening.
I am working on 3 types of protection that use quite easy stuf :
- Timingbits (like the E7)
- Nibble counting
- Deceptive track gap
Once I pass the above I will start working on fat & spiral track
Btw , I am looking for a write up regarding the sierra protection and I can not find one (the one use by Sammy lightfoot and many others)
I am digging in the code self decryption and I would like to understand 4am approach. On Sammy the write up is not write the protection is on T5,S02 instead of S0E
I am back a few days home,
and I run some preliminarty testing to check that the SPI is correctly issuing the timingbits (and of course this is the case).
Reflecting on the Commando protection code and the log of the analyzer, I might have found the issue and it is not easy to explain and I need some help to find the right approach.
I will try to explain.
The protection on Commando is a E7 protection (I would say classic ;)).
What Commanndo is doing and expecting.
1 - BOOT Stage 0 in the ROM with 80 Phasing instruction reinit the drive (Head is on Track 0)
- Boot Stage 1 with the reading of the Track 0, Sector 0 and the Quick DOS is loading in memory.
- Then It continues to load a few sector including the famous protection code in memory at address D8XX
- It move the head to track 17 and it jmp to the start of the protection at memory address D8XX.
the protection code is waiting for Sector 0D to be decoded and have the value in the zero page $2E ($002E). zero page is simple what is called the first 256 Bytes of memory.
When the head is reading 0x0D in the adress field it put 0x0D in $002E and the protection start checking for the 0x96 sequence after D5 and wait for E7E7E7.
Then It desync the latch of the Controller card and It expect to read someting different from the upcoming E7 because of the timing bits.
My Emulator is doing that, and I can see a correct track 17 on the logic Analyzer (it means that if the Logic Analyzer is seeing it the Apple II as well). the problem might be somewhere else.
The way the emulator is currently working:
Phase 0, Phase 1, Phase 2, Phase 3 are connected to GPIO with Rising and Falling Edge interrupt.
As soon as a change is detected on the Phase 0/3 line (either 0->1 or 1->0) it starts calculating the new physical track
At the end of the interrupt function if the logical track is changed (using TMAP conversion in Woz), the new logicial track is set and the firmware continue the execution.
In the main thread there is an endless loop and inside a condition with logical track change.
When the condition is executed :
- It execute the data track change on the DMA ( it can be very fast less than 30K cycle if the track is already loaded in one of the 3 adjacent tracks) or 700 K cycles if not present in memory.
- and then it re starts the DMA and load the adjacent track.
The full process can take 200 ms if the new logical track is not adjacent to the current track.
I hope that I have not lost people ;).
If you remember the protection of Commando :
It move the head to track 17 straight and wait for sector 0x0D => but does not check the track, the CMP is only on $2E and not $2D.
My Emulator on the log file is moving from head based on the interrupt and reload data at each loop in the main thread like :
ph:03 newTrak:01, prevTrak:00,pos2:6394 htim5:1151, Abs:3558, prev_woz_trk:00-01-02 woz_trk:00-01-02 1 M1:0 P1:2 op:1-1-1 DMA_SIZE:6394 d1:282447 d2:54
ph:12 newTrak:02, prevTrak:01,pos2:6395 htim5:0398, Abs:4144, prev_woz_trk:00-01-02 woz_trk:03-01-02 2 M1:1 P1:0 op:1-1-0 DMA_SIZE:6395 d1:282644 d2:760820
ph:25 newTrak:04, prevTrak:02,pos2:6394 htim5:0772, Abs:5358, prev_woz_trk:03-01-02 woz_trk:03-04-05 1 M1:0 P1:2 op:1-0-0 DMA_SIZE:6394 d1:783733 d2:623530
ph:41 newTrak:07, prevTrak:04,pos2:6395 htim5:0701, Abs:0109, prev_woz_trk:03-04-05 woz_trk:06-07-08 1 M1:0 P1:2 op:0-0-0 DMA_SIZE:6395 d1:781253 d2:1245379
ph:58 newTrak:12, prevTrak:07,pos2:6395 htim5:1055, Abs:1563, prev_woz_trk:06-07-08 woz_trk:11-12-13 1 M1:0 P1:2 op:0-0-0 DMA_SIZE:6395 d1:783515 d2:1246011
ph:68 newTrak:15, prevTrak:12,pos2:6394 htim5:0988, Abs:3017, prev_woz_trk:11-12-13 woz_trk:14-15-16 1 M1:0 P1:2 op:0-0-0 DMA_SIZE:6394 d1:783568 d2:1243377
ph:68 newTrak:17, prevTrak:15,pos2:6394 htim5:0168, Abs:4469, prev_woz_trk:14-15-16 woz_trk:16-17-18 1 M1:0 P1:2 op:0-0-0 DMA_SIZE:6394 d1:783029 d2:1241875
Each line is a data load process going to the end with D2 = number of CPU cycle after DMA starts.
so it means that the Apple II is seeing data from track other than 17 while the main thread is getting to track 17.
My assumtpion is that the protection is seing data for sector 0x0D from other track and failed the test, and the data track 17 is loaded after.
One of the way to manage it would be to load a new track only when all the Phase (0,1,2,3) are low (because there is an overlap between phase) ? The point is whith spiral track it will not work...
Given the above, I need to do some testing to validate my assumption,
What is the right way to trigger new track load ? (I can do it withing the interrupt function, interrupt has to be lean and simple).
Vincent
Looking at the Phase timings,
If I wait all phase to be low with some delay, I might have some issue with Spiral track...
the other way would be to, wait to have only 1 phase ON and have a delay of 12ms, which is the max timing of phase without overlaps (the last phase has a duration of 36ms). doing so I have 24 (36 -12) ms to load the track which is by far enough.
But I am sure Uncle Bernie will have an opinion :)
Vincent
In post #177, 'nick3092' wrote:
" ... but by a fluke worked only on standard disk II controllers, and would fail on IWMs. It took a while before it was caught that it was failing on IWM machines and caused him to go back and reinvestigate the whole thing."
Uncle Bernie comments:
Since a few weeks I have a 100% "in lockstep" RTL for the IWM Rev B., and I can confirm that the IWM is a quite different animal than the original DISK II controller, even in the 'legacy mode' (my name for it) where it was supposed to be DISK II controller compatible. This is very bad news.
The 'read state diagram' of the IWM is a closed loop over 14 or 16 states and it never looks at the state of the shift register MSB, and never has a "wait for RDDATA pulse" wait state (a state looping onto itself). This is very bad news for copyprotection compatibility.
The message here for 'VIBR' is: do not work with a IWM based Apple. Use an original DISK II card only.
I intend to modify my IWM such that it is 100% compatible with the DISK II und all conditions (but only as long as it is in 'legacy mode'). This extra logic does not fit in the current PLD I'm working with as an intermediate step (Altera EP900). So my whole IWM substitution project gets more and more time consuming ... this (and a few other problems which need immediate attention / time to remedy) is the primary reason why I can't pay too much attention this thread at the moment. I'm just overloaded.
The worst crisis at the moment is with my Italian Parsley which gets more and more little white spots. At least I have now identified the culprits, two types of very tiny insects. They seem to suck the "blood" of the plant. The trick is to find some chemical compound which will kill them but is harmless for me when I then later eat the Parsley. Caffeine comes to mind - the shrubs who have it in their leaves are absolutely deady for many sucking insects. But how do I get Caffeine into the Parsley "bloodstream" (well, the plant equivalent of blood). These science projects can quickly get out of hand and suck you in !
- Uncle Bernie
In post #180, 'VIBR' wrote:
" Looking at the Phase timings, if I wait all phase to be low with some delay, I might have some issue with Spiral track...
the other way would be to, wait to have only 1 phase ON and have a delay of 12ms, which is the max timing of phase without overlaps (the last phase has a duration of 36ms). doing so I have 24 (36 -12) ms to load the track which is by far enough.
But I am sure Uncle Bernie will have an opinion :)"
Uncle Bernie's opinion:
I posted some comments already how to tackle the head movement problem. The point is: you need to model the inertia of the head properly. If a stepper motor phase is changed when the head is at standstill, the RDDATA stream of the current track will continue for a while, until the head finally starts moving and the signal coming from the old track faints and gets lost. Likewise, when arriving on the new track, it will take a short while before the RDDATA stream of that new track stabilizes. This is true for all "normal" floppy disks (no copy protection).
I'm not sure what really happens with 'spiral tracks' or 'fat tracks' because I never had the time to look at their RDDATA streams. Is there a gap in the RDDATA stream filled with trash / instable bits or not, if the head moves ? We can't easily tell anything because we don't know what the software does in terms of reading the DISK II controller while the head is moving. Will it allow for some random trash and look for a SYNC sequence (or any sequence which does the same, synchronizing to 'disk nibble frames'. Or will it expect a continous stream of nicely stable RDDATA bits ? I think the latter is possible if the head is only being moved by a very tiny amount. You can actually gently and carefully "wiggle" the head assembly a little bit with your fingers while reading, and reading is not disrupted (if you are ham fisted / fat fingered, don't try that, it might damage the head assembly). This experiment gives a clue that indeed, very small head movements may allow a continous, non-disturbed RDDATA stream.
This requires more investigation with a real floppy disk having such a copy protection. Just hook your logic analyzer up to RDDATA and the stepper motor phases and investigate what happens.
Also be aware that head movement algorithms (stepper motor phase sequences) vary. You need to be able to detect all cases and have an algorithm which calculates on which quarter track the head actually is at any given point in time. The algorithms I've seen in some Apple II emulators dealing with head movement based on stepper motor phases are quite sophisticated. And they are best copied, not re-invented ;-)
The weird pdf from GFTO you have found and mentioned in the above post #173 has a lot of info about which titles use tricky stepping.
(Oh and I'm still curious about what that Gazette really is ... they use the English language but have ads from small German one-man businesses catering to hackers (i.e. selling annotated ROM listings) in the German language ! Who would pay for that ad ? Makes no sense to me. The whole weird pdf looks bogus for that reason. But the article on Apple II protections was a great read !
- Uncle Bernie
Important but subtle detail: if you're using a Disk II controller (state machine) then make sure the emulated drive is signalling that the disk is WRITE PROTECTED for most reliable results
In order to "desync the latch" the E7 copy-proteciton routine puts the controller in WP-SENSE mode. The original game disk was permanently write-protected (no notch), the WP-SENSE mode causes the data register to immediately fill with 1-bits (ie: "full"). If the drive does not return a WRITE PROTECTED signal, the data register will be filled with 0-bits. (ie: "empty") Apparently that's sufficient to upset the signature check.
Some years ago I adapted the copy-protcetion code from Prince of Persia into a stand-alone E7 signature-check program. In my tests on an Apple //e with Disk II controller it was 100% reliable with WRITE PROTECTED disks, but only about 50% with WRITE ENABLED disks.
I have no idea whether write-protect affects IWM the same way, since it uses separate registers for status vs data.
Hello Elliott,
Yes indeed, I have set the W_PROTECT to High but it does not help (it helps but not solve the issue)
I am struggling this.
I have disassemble the full protection of Commando, and I start to master this piece.
But for now, i am blind...
Next step is :
-With Merlin or Merlin 32, write a piece of software that is the copy of Commando protection code using DOS33 instead of quick Dos (changing track 17 to track 14 because track 17 is DOS3.3 the File Alloc Table).
- put trace on screen to understand the blocking point...
At this point this is the only way...
For Uncle Bernie: thanks for your support, do not worry i am blocked at this stage and I need to solve the issue before moving forward. It has to be with something around the latch desync ...
I have put champagne in my fridge when I will pass this step ;)
In post #183, "S.Elliott" wrote:
" In order to "desync the latch" the E7 copy-proteciton routine puts the controller in WP-SENSE mode. The original game disk was permanently write-protected (no notch), the WP-SENSE mode causes the data register to immediately fill with 1-bits (ie: "full"). If the drive does not return a WRITE PROTECTED signal, the data register will be filled with 0-bits. (ie: "empty") Apparently that's sufficient to upset the signature check."
Uncle Bernie comments:
True that. In general, it is VERY important that the floppy emu will produce the right WRITE PROTECT flag for any given software title. Original, professionally mastered floppy disks mostly were write protected (no notch on the edge of the floppy disk) and many copy protections check for that - pirates using LOCKSMITH and the like had to have a notch (no write protect) to make the copy, and if they did not put a write protect sticker back before test booting the copy, all sorts of more or less evil things could happen. The more stupid copy protection routines make the boot crash when the write protect was missing, which, alas, is obvious, but the more "evil" ones ("evil" from the standpoint of the pirate ;-) would allow the game to run perfectly for that boot, after overwriting a sector with critical code, which would make the game unplayable at the second boot event. The bottom line here is: always emulate the write protection properly. This involves not allowing any writes to a write protected disk.
Just to add a little detail S.Elliott did not mention: the manipulation of the DISK II controller state machine during E7 checks does not only check the write protect status line but also brings the state machine (aka "Woz Machine") into a specific state that does not change. When the mode is switched back to "READ MODE" (L7 = L6 = 0) then there is NO reset or restart of the read state machine. It just continues with that state it was in the write protect sense mode. And continues from there. The actual trajectory through the read state diagram will depend on whether the write protect check did set or clear the MSB of the shift register. So reactivating the read mode at just the right point in time, combined with a RDDATA pulse or not, can lead to several different outcomes as seen in the shift register.
The IWM does not work like that. As I mentioned in my post #181 above, its read state machine (meaning the bit cell centering part, which substitutes the WOZ machine seen in the DISK II controller) does not look at the MSB of the shift register at any time, and worse, it continues reading while the write protect status is checked. The IWM does not use the read data shift register running backwards (right shift) to capture the write protect sense status line. Instead, it just implements another I/O port where the write protect sense line can be read. In some Apple products the SENSE input of the IWM serves other duties than sensing the write protect. I did not look into that, but it may be used as a sort of handshake signal for some more sophisticated I/O protocol. Can't prove it but this may have been the motivation why the IWM designers did move the write protect sense away from the read data shift register, into another functional block.
Which of course is yet another difference to the original DISK II controller, and will inevitable make certain copy protections fail on the Apple IIc (which uses the IWM), despite of an original and intact disk that loads fine on an Apple II, II+ or IIe using the DISK II controller.
So we can state that the IWM is ***NOT*** 100% compatible with the DISK II controller. Their "IWM specifications" which we can find on the web nowadays say otherwise. They seem to believe the IWM is fully compatible with the DISK II controller. Which is wishful thinking.
- Uncle Bernie
So far it is not "we", it is mainly you who is stating that and as a human yourself you could be wrong too. Is there any practical proof to that? Which protections fail on //c and/or //GS?
In post #186, 'retro-devices' wrote:
" So far it is not "we", it is mainly you who is stating that and as a human yourself you could be wrong too. Is there any practical proof to that? Which protections fail on //c and/or //GS ? "
Uncle Bernie answers:
Look into the Apple II "Prince of Persia" story as written up by Jordan Mechner himself (alas, I can't find it anymore, so it's up to you to find it in the vast wastelands of the internet). According to Mechner (and this is from my memory, so take it with a grain of salt), he had developed a very tough copy protection for "Prince of Persia" which worked robustly on Apple IIe but turned out to fail on the Apple IIc. He wrote that this problem forced him to weaken the copy protection check, so it would work on both machines. IMHO, this weaking may have enabled "4AM" to do his cracking work, but it is know known that 4AM's theory about the inner workings of this copy protection was a little bit off from what really happens. "S.Elliott" has looked into that and developed an alternate bit cell sequence which also fools the "Prince of Persia" copy protection. Here is the link to that exploit:
https://www.applefritter.com/content/two-disk-replica-prince-persia
This story by Jordan Mechner caused me to suspect (since I started to look into the IWM) that the IWM may behave different in legacy read mode where it should be 100% DISK II compatible. So I was aware of the possibility of a difference in the various state machines and paid attention to every detail while I was reverse-engineering the IWM. It turned out that the designers of the IWM have split the functions of the "Woz Machine" of the DISK II into two independent state machines: a bit cell alignment state machine (which centers the sampling point of the RDDATA input in the mid of the bit cell, and initiates the shift command to the shift register), and a read port control state machine which controls the read data latch (not present in the DISK II), the "freeze" of the data seen by the CPU, the clear of the shift register, and the MSB behaviour in all configurations of the IWM. The key difference to the "Woz Machine" is that the first of the two state machines runs always and never stops / freezes. The "freeze" effect for the completed disk nibble byte with MSB set is done by the second state machine. So unlike the "Woz Machine", the IWM continues the bit cell centering and shifting process even during the "freeze" period without any stoppage. The write protect sense of the IWM also does not affect this process. And this inevitably makes a difference for the E7 protection checks which manipulate the "Woz Machine" state by briefly changing the mode to write protect sense. The IWM ignores that as far as the ongoing read process is concerned.
There also is a mathematical / algorithmic proof of "state machine equivalence" which failed, so there is a difference. This manifests as a test vector fail of test vectors which were generated from the IWM substitute netlist when the same vectors are applied to the "Woz Machine". The vectors pass when applied to the real IWM in the test rig. What this proves is that the RTL I have for the read process of the IWM is 100% identical to the read process in the real IWM, with the caveat that the real IWM might have more (hidden) functions the algorithm is not looking for, as it only looks to cover all functions of the RTL. But if this test vector set which passes on the real IWM fails on the "Woz Machine", which it did, then it is proven that the two state machines have a difference (and are not state machine equivalent).
This does not imply that specific copy protections which work on the Apple IIe must fail on the Apple IIc. Programmers can work around the subtle differences between the IWM and the DISK II controller. Like Jordan Mechner did, according to his own story as written up by himself.
Furthermore, it was not a "human" (me) who found the difference. It was a machine / algorithm which found a difference. And this CAD suite never failed in more than 30 years when it comes to such proofs. Of course, as explained above, it can only check for equivalence of the set of functions it extracts from the netlist which was synthesized from known RTL. For the comparision of two known RTLs it is 100% exact. But when the RTL was based on reverse engineering and the "equivalence test" is done against real hardware, then there may be false positives in the sense that it claims "state machine equivalence" when there is none (but the subset of functions described in the RTL is equivalent). However, the theory behind these equivalence checks also says that there never, ever will be false negatives (test vectors fail despite state machines being equivalent). Since I got a "negative" = "non equivalent" judgement from this automated process, I am 100% certain that IWM is not state machine equivalent to the DISK II "Woz Machine", even if limited to legacy read modes, and hence, they are different and can't be 100% compatible.
Hope this clarifies the subject. I will publish more details when my IWM reverse engineering / substitute work has progressed more, but in its own thread, and not here ... this thread here deals with a floppy emu project, and my well meant advice was to avoid the IWM during this development work.
- Uncle Bernie
You can't find it because the protection was written not by Jordan Mechner but by Roland Gustafsson for Brøderbund, and the //c or IWM was never mentioned as a problem:
https://fabiensanglard.net/prince_of_persia/pop_boot.php
Hello All,
I have been working on this E7 protection, I made some progresses
My goal was to replicate the only protection of the game Commando (except the strange address & data epilog FF.FF.EB instead of DE.AA.EB)
Step 1: Using virtual II with Merlin 2.48, I have written a small software in asm that replicate exactly the E7 protection on Commando.
I create a blank woz file, I put diversiDos on it (much faster than DOS33)
With a python script I have copy the track 17 (where is E7 bitstream is) from to commando to new woz on track 14 (and I recreate a valid CRC of the WOZ)
The little software is diplaying to number on the screen based on where it failed or sucess
10 -> moving to track 14
20 -> Finding sector 0x0D
30 -> finding the 3xE7
50 -> Dsync of the latch and reading the EE.EE.FC.E7.EE.FC.E7
It is working on virtual II, and I have tested all the status to validate it.
My next step was to test it on a real Apple II//e. I was expecting a status below 50 because this is the only protection of Commando...
I tested it several time and each time I received a status 50 !!!!! so it means that my emulator is providing the right protection bitstream to the DISK II Card.
I deceided to test the same woz file on an Apple II+. And ....
I received everytime a status 30, meaning that the latch is not desync the right way.
2 Apple, 2 different behaviour, and on virtual II it is working...
This is a bit crazy to be honest, I lost my latin.
EDIT1: on a 2nd apple II+ it is working (I might have then a RAM issue)
My Next Step is to crack the WOZ file by replace the ASM SEC (Set the carry) and ASM CLC Carry to see if I can load it or not ? and I will test the am crack one
EDIT2: 4AM dsk file is working but freezing on the home page. Can someone test the dsk file to confirm the same behaviour please ?
keep you posted
Vincent
I need to boot trace on a real Apple II to understand the blocking point
Commando is using quickDos and when I hit RESET button, it seams that the game is resetting the memory to avoid me to see the protection code.
How do I avoid this and be able to interrupt at the beginning and trace step by step ?
Is there somewhere a document that describe this ?
Thanks
Vincent
I finally know where is the problem...
All this time spent to actually understand why it was failling the protection check. But it was not, ...
Discussing on Discord with some Guys from Applecause team (Disk Blitz, Keyfrazer,...), they put back on the right track.
and in the end Retro_Devices was right, SPI can not be the solution... bit bang must be used...
Here is why :
- In the woz specification (starting from the first release), the is per track the block count and the bit count.
- Bit count represents the number (exact) number of bit to be sent to the Apple II. And this number is not 8 bits aligned (not a multiple of 8).
Sometime when you are lucky 1 track can be 8 bits aligned (1 chance over 8) and this for every track.
using the SPI, you can only send chunk 8 bits. so it mean that the last bits are padded with 0.
One can ask the question why is it a problem ? Answer:
a track is made by 16 sectors (normally) from 0x00 to 0x0F
A sector is made by :
GAP 1
Addr prolog : D5.AA.96
Sector Addr DATA
Addr epilog: DE.AA.EB
GAP 2
Data prolog: D5.AA.AD
Sector data (342+chksum)
Data epilog : DE.AA.AD
GAP 3 (samller than GAP1)
Woz track might split a data sector from the end of the woz track and the begining of non 8 bits aligned data.
I have tested dozen of woz file and it is the case almost everytime.
so using SPI, best you are courrupting the chksum of the sector at the end of the woz track (1 byte chksum), or providing corrupted nibble to the Apple II.
In a nutshell, the last sector of a woz file (and this is not necessary the 0x0F), might never be read correctly... and this is the case for Commando.
using ASM code with delay simulated with multiple NOP does not work
So what is the solution :
- move away for SPI,
- Use instead 2 sync timers with interrupt and bit bang a GPIO port,
- Timer 1 set the GPIO according the current bit, prepare next bits and so on, til the end of the number of bit and start over.
- Timer 2 after 1,3 Us set the GPIO down.
- disable all the Interrupts to avoid timer slippage.
I need to do some tests but this is the approach, the good news is, I do not need additionnal 74LSXX, retro_device was right one more time ;) everything can be done with the STM32. I think same for the write part.
Vincent
In post #191, 'VIBR' wrote:
" Discussing on Discord with some Guys from Applecause team (Disk Blitz, Keyfrazer,...), they put back on the right track.
and in the end Retro_Devices was right, SPI can not be the solution... bit bang must be used... "
Uncle Bernie comments:
Ouch !
To me this looks like a severe flaw in the whole WOZ file concept, which brings complications for floppy disk emulators (other than software only Apple II emulators, these are not so much affected, as in there, the "bit banging" is cheap to implement).
Frankly, I did not expect that the very competent Applesauce team would be satisfied with cutting off the track at non-byte boundaries. I don't think this is necessary, as every track, even if made with a professional mastering machine, would have a "write splice area" which which the writing was stopped and the write current was turned off. This write splice area should be easy to detect for original, professionally mastered floppy disks. As the data there is undefined, it is highly unlikely that any copy protection would rely on reading data from that write splice area --- the reaction of different floppy disk drives in the field would be different. But of course, I could be wrong with this conjecture ... never underestimate the wickedness or stupidity of copy protection developers. In this context, with "stupidity" I mean clever concepts which rely on unstable phenomena, and then generate a flood of complaints from customers who have bought an original game floppy disk which would not work on their computer. Things like this can bankrupt a software company ...
The point I want to make here is that once the write splice area is detected, it could be trimmed in length to the nearest byte boundary, and this would allow a clean WOZ file track image which has full byte boundaries only.
This would have two benefits:
First, floppy disk emulators could use DMA which is much more powerful than bit banging ... the problem with bit banging is that it sucks up all the CPU activity and then, how do you handle stepper motor phase change events and reloading of the next track(s) from the flash memory card ? Keep in mind that the RDDATA stream must flow, all the time, without interruptions, even under track changes (at least for those copy protections which use this kind of tricks).
Second, re-creating of the physical floppy disk from a WOZ file would be easier, if the location and size of the write splice area is known.
Unfortunately I can't use Discord to reach out to the Applesauce team. I signed up for it with a bogus email address but found out it would swamp me with garbage and lose track when I go offline (I have no internet at home, and must go to a public WiFi place, this has nothing to do with money, because the gas to get there costs me more than internet at home would, it's just for self-protection). I think that Discord is only good for people who have smartphones which are online all the time, and not worried about the epigones of the Gestapo tracking and monitoring them 24/7. THIS is the fundamental issue with all social media on the internet. They are honeypots to suck you in and to spy on you 24/7, to sell your 'digital self image' to third parties, including foreign and domestic crime organizations. No good, at least for me !
This said, I'm sorry I can't reach out to the Applesauce team for discussion of this issue and possible improvements to their WOZ file format.
But I think that if you can identify where the write splice area is in the current WOZ file format, you could do the manipulation of the track to yield clean byte boundary cutoffs with a purpose written tool running under Linux. Use this tool to convert the original WOZ file to a VIB file which then is fed into your floppy emu. This would allow you to keep your DMA.
The point is that I don't see a way to make a bit-banged floppy emu work. The ST32 is no multithreading / multicore CPU, no ?
(Oh, and now I think I have a hunch why the BMOW Floppy Emu has a quite sophistcated CPLD/FPGA on it).
- Uncle Bernie
Hello Uncle Bernie,
If I look at Commando the Bit / track:
51155
51148
51153
51146
51151
51151
51152
51153
51152
51152
51151
51151
51153
51153
51153
51148
51152
51150
51152
51149
51149
51144
51143
51148
51146
51157
51159
51163
51156
51159
51155
51155
51138
51141
51139
As you can see not 8 bits aligned.
And the Data Sector section, is every time splitted at the end of the woz track...
It seems that discussing with the Applesauce team, they are also using an ARM device for their recording hardware.
Oe way to keep the DMA would be to use timings bits at the begining of one the sector GAP (FF.00.FF.00) but it means also to shift the full buffer to realign to 8 bits.
But if we start injecting timing bits, then some protections (counting and checking bit with precise timing) will failed.
The STM32 is not multithreading, and it is a single CORE SoC.
However the way I implemented the Bit Bang still enable to do what is needed :
- We need to issue 1 bits every 4 us, Having a STM32 running at 100 Mhz, it means 1 bit every 400 CPU Cycles
- I setup a TIMER that is running in background like the DMA, and triggers an interrupt every 400 CPU cycles, during that interrupt the requested bit is served from the track buffer.
- Another TIMER is synced, started with single shot each rising edge of the first timer, it will set LOW the GPIO after 133 cycles and will take 2/3 cycles.
After the TIMER interrupt is exectued, the STM32 continues the flow of the main thread where it was interrupted.
It can queue as well other interrupt and continues the flow of instructions.
From my point of view (but I do not have a full Apple II to validate), but this way Drive Phasing can be manage, SDCARD track can be loaded while bit banging.
Vincent
Hi Vincent -
I've read your post #193 and understand your reasoning. However, I think if you go with bit banging, your work will be harder and forever locked to the ST32 version you are using (not portable without starting from scratch). It's your decision what you do, as it's your project and your time, but you have to weigh all factors before you make a decision.
I am sure that if we could detect the write splice area of each track, it would be easy to remove or add 1...3 bit cells in this splice area to have only whole byte bounday aligned tracks in the track buffer. With proper wrap around on byte boundaries you could use your DMA / SPI based concept, which is more elegant and easier to port than any bit banging concept would be.
I don't think that this small manipulation of the write splice area by no more than 3 bit cells (or 12 microseconds) could have any effect on any copy protection. Unless that copy protection would look at the write splice and have some magical algorithm to detect if it is the original write splice. I think that would be a hopeless attempt, but I may be mistaken. I do have reasons to believe nobody ever did that, however. Because some 40 years ago I tried to generate unstable bits in floppy disk data sectors by using write splices. Which never yielded any reproducible or useful results the copy protection check would swallow as "good". We ended up to solve the problem by putting a second incarnation of the unstable sector in the track, which was read from the original disk, and only a few bits in it were flipping and flopping. Since we read the various incarnations from the original disk, the copy protection had to accept them, naturally. This exploit had the added benefit that we did not need to upgrade the copy chip we were selling at the time ;-)
For the Apple II, the situation is a little bit different as there are those copy protections which involve synchronized tracks and all sorts of stepper motor phasing tricks. But here is my rationale why we still could dare to add or delete a few bits in the write splice area:
If we make the hypothesis that these "synchronized" tracks were written as "fat tracks" - if such a thing really exists physically, I did not check my specimen disks with magnasee fluid yet - then this implies a wider write head, and the consequence would be that the contents of the quarter tracks covering that fat track would be perfectly aligned. In this case, you would use ONE track image for all these quarter tracks. The WOZ file format supports this method.
But if we make the the hypothesis that two (or more) "synchronized" tracks have been written using a normal write head, or were written by a 80 track drive, then any pair of these tracks cannot be perfectly synchronized (do the math: 12 microseconds for 3 bit cells vs. 200 000 microseconds per revolution at nominal RPMs). It is impossible to have perfectly synchronized tracks if they are written track by track, just due to wow and flutter which is inevitable with the spindle motor speed control and the non-constant friction effects etc. So in these cases, the copy protection check must allow a certain skew between these synchronized tracks. Which allows us to do the +/- 3 bit cell manipulation again.
The only copy protection which could puke on the proposed manipulation (other than the attempt to check the write splice area itself, which I dicussed above and don't fear) is one where a real 'spiral track' would produce a continous RDDATA stream over several revolutions of the media, and every revolution providing new and valid data. Theoretically, such a spiral could cover the whole area of the floppy disk, with no interruptions. Much like a vinyl record for music (remember these ?). But I can't say if such a copy protection really existed for the Apple II. The AppleSauce team should know more. Ask them. Note the fine point I am making ... spiral track with no interruptions of the RDDATA stream, ever, and no slips / resync action necessary while reading for more than one revolution. Spiral tracks could also be done with interruptions of the data stream, all they would need to do is to throw in a few SYNC bytes to recover. I can't say what they really did back in the day. What I know is that industry standard mastering machines could NOT generate a spiral track continously because they used a hardware track buffer that had a limited length and needed reloading when exhausted. The upside of this was that they were able to control the write process in a very fine grained way ... including "density frequency modulation". There were tricks which were played on PLLs of floppy disk controllers which timing wise look like fishbones. The target was i.e. the Western Digital FDC in the Atari ST computers, which had a digital PLL that could be made to do weird things with these tricks. Absolutely impossible for a copy program running on the Atari ST and using the same FDC to duplicate such a copy protection. Happy Computers solved this with their HART custom chip. But I don't think they sold enough of them to be a threat to the software industry. But back to the Apple spiral disk protections. Such a uninterrupted RDDATA flow spiral track of several revolutions of length could be produced on an Apple II itself, using the unmodified DISK II system. The great difficulty for a copy program would be to properly analyze the spiral to later reproduce it. So that mythical thing could exist. And if it exists, any WOZ file and any floppy emu would struggle to replicate it. The WOZ format probably could do it ... but analyzing such a continuous spiral would be hell. The copy protection read algorithm could use encrypted clues in the data stream coming from the DISK II controller to 'servo' the read head in the proper way, hereby guaranteeing successful read even under RPM variations. And the spiral as such could wiggle around in unpredictable ways. Again, note this is my conjecture / hypothesis / fantasy (you name it) based on the toxic thoughts I have in my mind. This is how I would design a spiral track protection. It would be incredibly difficult to reproduce this even with our current technology. The open question is if any real world Apple II software title ever used such a tough copy protection. Ask the AppleSauce team.
Once you have collected the information about the above topics, you can make a decision on which method to use for your floppy emu based on facts. Before you have all facts together, I would not recommend you to throw away all your work and start from scratch (using bit banging). I still hope my proposed bit cell manipulation method could make the DMA approach viable.
- Uncle Bernie
Summary of the previous episodes,
Over the summer, I continued to work on the STM32 emulator and try to find my way with the copy protection.
For this purpose, I wrote a small piece of code that is strictly replicating the protection mechanism of the game Commando :
It turned out that the STM32 was passing the test each time. In other words, the problem was not the copy protection. During my investigation of 6502 ASM code, I used the nice book where Antoine Vigneau (another French Guy ;)) has been contributing and he is holding a website. To move forward, I sent an email to Antoine and he reply by suggesting to ask for help with the AppleSauce folks on discords.
This is what I did, and the AS (AppleSauce) was not surprised by my issues… they pointed out very quickly that I have to check for the exact bit and not byte at the end of a woz track otherwise it will be corrupted data. They also quickly confirmed that SPI was not making sens given the WOZ Format.
It seems that AS is using Teensy 3.x and they plan to move to Teensy 4.1 using GPIO Bitbanging.
I did some investigations to understand why it is so important to strictly respect the number of bits and not to pad with 0 in case it is not aligned with size of Byte (8 bits). The main reason is that the last sector may be splitted at the end of the woz track and the data segment may be starting before the end of the woz track end finish at the beginning before the next sector. The consequence is that for a given track one may have a chance over 8 to successfully read the last sector, and 7 chances over 8 to have a corrupted checksum and the Apple II not being able to execute the software.
It took me quite a while to figure out this pretty easy postulat.
It means moving away from SPI and start thinking about bitBanging a GPIO port.
At the very beginning of the project, I wrote a small assembly piece that was reading memory and set/resetting GPIO with the right number of NOP instruction to artificially create the good timing. It turned out that due to the internal ARM cooking, it was quite impossible to have an accuracy bitstream out of it. This is the main reason why I move to SPI.
Now it is time to find a new way. And the winner is …. TIMER as always.
I started implementing a first version using very simple timers. 1 timer was triggering an interrupt to set the GPIO for 4us and another was resetting after 1us. This way I can still play with the frequency of the bitstream in case I have to increase the speed for specific game (Optimal Timing Bit in Woz file).
What is tricky is the SDCard part. When using SPI everything was done behind the scene with DMA and no interrupt were disturbing the SDCard. Now with Timer interrupt every 1us this is not the same story. The good news is : the STM32F411 has a SDIO port with native DMA support.
The SDIO port allows DMA write and read operation. One get an interrupt when the operation (read / write) is finished. SDIO with 4 wire bus is 4x faster than SPI and the CPU is free to do other stuff because of the DMA. In the end, loading a track takes 290 K cycles instead of 1.2 M (less than 3ms). Thus the loading of adjacent track might not be needed.
Regarding timers, using 2 timers is not needed as you can use multi channel compare with different pulse. Thus I have simplify the architecture with 1 READ TIMER and plan to have 1 WRITE TIMER.
With the new approach, for the moment there is no need to extra 74LS, only a simple BlackPill STM32 would be sufficient.
After hours of testing and fixing small stuff, using a single track this is my news score card …
//sprintf(filename,"/WOZ 2.0/Blazing Paddles (Baudville).woz"); // 21/08 WORKING
//sprintf(filename,"/WOZ 2.0/Border Zone - Disk 1, Side A.woz"); // NOT WORKING
//sprintf(filename,"/WOZ 2.0/Bouncing Kamungas - Disk 1, Side A.woz"); // NOT WORKING
//sprintf(filename,"/WOZ 2.0/Commando - Disk 1, Side A.woz"); // WORKING
//sprintf(filename,"/WOZ 2.0/Crisis Mountain - Disk 1, Side A.woz"); // WORKING
//sprintf(filename,"/WOZ 2.0/DOS 3.2 System Master.woz"); // NOT WORKING
//sprintf(filename,"/WOZ 2.0/DOS 3.3 System Master.woz"); // 15/07 WORKING
//sprintf(filename,"/WOZ 2.0/Dino Eggs - Disk 1, Side A.woz"); // 21/08 NOT WORKING SHOWING A B on screen
//sprintf(filename,"/WOZ 2.0/First Math Adventures - Understanding Word Problems.woz"); // WORKING 20.07
//sprintf(filename,"/WOZ 2.0/Hard Hat Mack - Disk 1, Side A.woz"); // 21/08 NOT WORKING stay at track 0;
//sprintf(filename,"/WOZ 2.0/Miner 2049er II - Disk 1, Side A.woz"); // 21/08 NOT WORKING crash to monitor
//sprintf(filename,"/WOZ 2.0/Planetfall - Disk 1, Side A.woz"); // 21/08 WORKING
//sprintf(filename,"/WOZ 2.0/Rescue Raiders - Disk 1, Side B.woz"); // 21/08 WORKING
//sprintf(filename,"/WOZ 2.0/Sammy Lightfoot - Disk 1, Side A.woz"); // 21/08 WORKING
//sprintf(filename,"/WOZ 2.0/Stargate - Disk 1, Side A.woz"); // 21/08 NOT WORKING playing with 255
//sprintf(filename,"/WOZ 2.0/Stickybear Town Builder - Disk 1, Side A.woz"); // 21/08 NOT WORKING
//sprintf(filename,"/WOZ 2.0/Take 1 (Baudville).woz"); // 21/08 WORKING
//sprintf(filename,"/WOZ 2.0/The Apple at Play.woz"); // 15/07 WORKING 5ms, 21/08 Working
//sprintf(filename,"/WOZ 2.0/The Bilestoad - Disk 1, Side A.woz"); // 20/08 WORKING
//sprintf(filename,"/WOZ 2.0/The Print Shop Companion - Disk 1, Side A.woz"); // FAILED AFTER SHOWING SPLASH WeakBit to be reviewed
//sprintf(filename,"/WOZ 2.0/Wings of Fury - Disk 1, Side A.woz"); // NOT Working missing 128K of RAM
Not too bad ;)
I have to fix :
- Glitches with the Device Enable Signal (issue with PA4 pin on STM32),
- Weakbit algo
- AS proposed bitposition does not work (make BlazingPaddle not to work), need to better approach,
- Spiral track
To be continued.
New score Card
And now PrintShop is working ;) weakBit is now working (AppleSauce approach is not working in every case)
So what is left :
Bouncing Kamunga
Stargate
BorderZone
I think I still have a big issue with ghost interrupt... when an interrupt is triggered on the STM32 then it create delay on the bitbang... I think I solved a lot of issue disabling SDIO interrupt and other stuff but still I need to continue to investigate.
A confirm even with spiradisc, there is no need for adjacent track management with the SDIO and the DMA ;)
BorderZone use the high density bits (not 4 Us but 3.5 Us), so let's see tomorow if playing with the timer frequency the game can start.
Hello All,
Quick update on the investigations done over the last days.
I wanted to test, dig, and try all the possible solutions to keep the existing work around SPI & DMA.
The issue with SPI DMA is that woz file are not 8 bits aligned, and if you pad with 0 or 1 the missing then you corrupted the track.
The first approach was to keep the DMA but not using the circular buffer interrupt, so at the end of a DMA SPI sending process, a manual trigger of the GPIO for the remaining bits.
This is not giving any good results because you get jitter when starting and stopping a timer to trigger GPIO, it is the same with DMA Start and Stop. It is almost impossible to play with the interrupt.
Secondly, it is also impossible to manage simply the writing process.
The second approach was to realign the track before reading by adding timing bit in the GAP 1 or GAP 2 area, it works (sometimes) but when there is a Nibble counting protection it failed,
And it failed also for the perfect track protection. and sometime GAP1 and GAP2 are inversed as a copy protection. And processing a track to realign is passing the spiradisc protection (time consuming)
The last approach was to use DMA SDIO and not SPI for the SDCard and use GPIO bit banging.
It turned out that this is the best approach and very simple, no extra 74LS, use of very simple timer and interrupts, weak bit implementation is also very very simple with no hassle to analyze the buffer.
SDIO is ultra fast less than 1 ms to read and copy a track (4x faster than SPI).
So Uncle Bernie,, I tried to keep the hard work, but it is not the right way (IMHO).
On a side note, I am still fighting with the Bouncing Kamungas, Stargate and Borderzone is not working on any Software emulator...
This is where I am so far.
Vincent
Stargate is finally working, 2 min to load... playing with soft switch /Enable like hell.
What was missing is the fake track of 51200 random bits for 0xFF woz track...
BINGO !!!!
IMG_7083 Large.jpeg
I finally make it working !!! but to be honest I did nothing, I have just changed the controller card and by magic it start to work... old retro stuff are sometimes crazy.
So in a nutshell, my emulator is working, I will make the track writing also stable and it will be ready to be tested by the community
Vincent
Pages