--------Fantasy Land (Red Level)------- A 4am crack 2014-06-05 --------------------------------------- "Professor Davensteev's Fantasy Land (Red Level)" is a 1983 educational game. The title pages gives copyright to two companies: Learning Well of Roslyn Heights, NY, and Methods & Solutions of Woburn, MA. According to online sources, there was also a "Blue Level" distributed separately, but I only have this one. COPYA fails miserably and immediately with a disk read error. EDD 4 bit copy gives no errors, and the copy works, which suggests that this disk may not use any secondary protection beyond the non-standard disk structure. (I have seen some weaker nibble checks that can be defeated with a strong bit copier, so you never know until you try.) Turning to my trusty Copy ][+ sector editor, I press "P" to get to the Sector Editor Patcher, and select "DOS 3.3 PATCHED". This option ignores checksum bytes and epilogue sequences. As long as the address and data prologue are standard ("D5 AA 96" and "D5 AA AD", respectively), this will allow me to read each sector. And lo and behold, it works! I can read the data from every sector on every track. Track $11 appears to be a standard DOS 3.3 disk catalog. T01,S09 lists HELLO as the autorun program. Given the (relatively) weak structural protection, I used to turn to the DOS 3.3 master disk, patch the RWTS to ignore checksums and epilogue bytes (changing $B942 from "SEC" to "CLC"), and run COPYA. Then, one fine day, and completely by accident, I came across an original disk with a bad sector. I suppose this shouldn't surprise me. These floppies are decades old by now; it's amazing any of them work at all. The point is, I shouldn't be using tools that ignore potentially serious read errors. There are other tools, like Super Demuffin, that can convert a disk like this (with non-standard epilogue bytes) into a standard format. It requires figuring out what the actual epilogue bytes are, but it has the advantage of surfacing a read error if the original disk actually has a read error. So... no more COPYA+B942:18 patch. From now on, it's Super Demuffin or Advanced Demuffin to convert disks to a standard format. Based on my initial inspection with a sector editor, this disk loads DOS and runs a HELLO program. So it shouldn't be difficult to capture the RWTS and load it into Advanced Demuffin. [S6,D1=original disk] [S5,D1=my work disk] ]PR#5 ... CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 CAPTURING BOOT1 ...reboots slot 6... ...reboots slot 5... SAVING BOOT1 SAVING RWTS Well, that worked flawlessly. My work disk first runs AUTOTRACE0, which sets up a minimal boot trace to capture the first sector of track 0 and saves it to the file "BOOT0" (on my work disk, not the original disk). If the first sector looks reasonably normal, it runs AUTOTRACE1, which sets up a more involved boot trace to capture the rest of track 0 and save it to the file "BOOT1". If *that* looks reasonably normal, it saves the RWTS to a file, unimaginatively named "RWTS", which can be loaded with Advanced Demuffin to copy each track of the original disk to a duplicate with standard address/data prologue/epilogue sequences. Advanced Demuffin will only load RWTS files from a drive in slot 6, which is annoying since mine is in slot 5. Note to self: patch that someday. In the meantime, I'm swapping floppies like some kind of 20th century teenager. [S6,D1=my work disk] ]PR#6 ]BRUN ADVANCED DEMUFFIN 1.1 --> LOAD NEW RWTS MODULE At $B8, load "RWTS" from drive 1 [S6,D1=original disk] [S6,D2=blank disk] --> FORMAT TARGET DISK ...grind grind grind... --> CONVERT DISK --> CHANGE DEFAULT VALUES? N Press RETURN to start the copy process, and... it crashes. Wait, what? Let's back up. *C500G ... ]BLOAD RWTS,A$2800 ]CALL -151 *2800L 2800- A2 00 LDX #$00 2802- A0 02 LDY #$02 2804- 88 DEY 2805- B1 3E LDA ($3E),Y 2807- 4A LSR 2808- 3E 00 3C ROL $3C00,X 280B- 4A LSR 280C- 3E 00 3C ROL $3C00,X 280F- 99 00 3B STA $3B00,Y Bloody hell, I think I see the problem. *BLOAD BOOT1,A$2600 2700- 8E E9 37 STX $37E9 2703- 8E F7 37 STX $37F7 2706- A9 01 LDA #$01 2708- 8D F8 37 STA $37F8 This disk uses a DOS 3.3 "master" RWTS that is loaded into low memory ($1B00.. $3FFF), then relocated into a "normal" location ($9B00..$BFFF) later. This was a hack that dates back to the time when developers couldn't rely on an Apple II having 48K of memory. Talk about backward compatibility! It also explains why Advanced Demuffin crashed. I loaded the "RWTS" file at $B800, but the RWTS wants to be loaded at $3800. This calls for an IOB module. What's an IOB module? Quoting from the Advanced Demuffin documentation (which I've included on my work disk): --v-- An IOB module is an interface for the source RWTS. Advanced Demuffin uses the IOB module to set up the IOB table and jump to RWTS. The IOB module is stored from $1400-$14FB. When Advanced Demuffin loads in a IOB module, it reads the first sector of the file off the track-sector list and stores it at $13FC-$14FB. When Advanced Demuffin wants to read a sector it JSRs to the IOB module with the phase number, sector number, and the page number stored in the A, Y and X registers respectively. Since the source drive always has to be drive one, Advanced Demuffin can make the IOB module very compact. After it gets the page,track and sector Advanced Demuffin sets up the IOB for RWTS using this infor- mation, and JMPs to RWTS. (It jumps instead of JSRing, because it lets the RWTS do the RTS.) Here is a list of the IOB module that is built in to Advanced Demuffin: ; Convert phase # to track # 1400- 4A LSR ; Store track number 1401- 8D 22 0F STA $0F22 ; Store sector number 1404- 8C 23 0F STY $0F23 ; Store page number ; [note: original docs have incorrect ; hex opcode on this line] 1407- 8E 27 0F STX $0F27 140A- A9 01 LDA #$01 ; Store the drive number 140C- 8D 20 0F STA $0F20 ; Store the read code 140F- 8D 2A 0F STA $0F2A ; With high byte of IOB 1412- A9 0F LDA #$0F ; With low byte of IOB 1414- A0 1E LDY #$1E ; Goto RWTS 1416- 4C 00 BD JMP $BD00 --^-- Basically, Advanced Demuffin only knows how to call a custom RWTS if it - is loaded at $B800..$BFFF, - uses a standard RWTS parameter table, - and has an entry point at $BD00 that takes the address of the parameter tables in A and Y As it turns out, that covers a *lot* of copy protected disks, but it doesn't cover this one because the RWTS on disk is loaded at $3800..$3FFF and has its entry point at $3D00. So, let's make an IOB module. ]CALL -151 ; Most of this is identical to the ; standard IOB module that comes with ; Advanced Demuffin (explained above). 1400- 4A LSR 1401- 8D 22 0F STA $0F22 1404- 8C 23 0F STY $0F23 1407- 8E 27 0F STX $0F27 140A- A9 01 LDA #$01 140C- 8D 20 0F STA $0F20 140F- 8D 2A 0F STA $0F2A ; One problem with having an RWTS at ; $3800..$3FFF is that that range is ; normally used to store track data ; during the copy process. If we just ; let Advanced Demuffin run, it will ; overwrite the custom RWTS almost ; immediately and crash (again). In the ; ADVANCED DEMUFFIN TECH NOTES (also ; included on my work disk), the author ; mentions that you can control how ; many sectors Advanced Demuffin reads ; at a time, and where it puts it in ; memory. Normally $1CF0 is $20 and ; $1CF1 is $90, meaning that it will ; copy 7 tracks worth of data at a time ; into $2000..$8FFF. Changing the end ; parameter to $30 will only copy one ; track at a time, but has the distinct ; advantage of not overwriting the RWTS ; and crashing. 1412- A9 30 LDA #$30 1414- 8D F1 1C STA $1CF1 ; get the address of the RWTS parameter ; table at $0F1E and call the RWTS ; entry point at $3D00 (instead of the ; usual $BD00) 1417- A9 0F LDA #$0F 1419- A0 1E LDY #$1E 141B- 4C 00 3D JMP $3D00 *BSAVE IOB,A$1400,L$1E Now let's tell Advanced Demuffin to use this custom IOB as well as the RWTS we captured from the original disk. [S6,D1=my work disk] ]BRUN ADVANCED DEMUFFIN 1.1 --> LOAD NEW RWTS MODULE At $38, load "RWTS" from D1 --> LOAD NEW IOB MODULE load "IOB" from D1 [S6,D1=original disk] [S6,D2=blank disk] --> CONVERT DISK --> CHANGE DEFAULT VALUES? N This disk is 16 sectors, and the default options (copy the entire disk, all tracks, all sectors) don't need to be changed unless something goes horribly wrong (again). ADVANCED DEMUFFIN 1.1 - COPYRIGHT 1983 WRITTEN BY THE STACK -CORRUPT COMPUTING =======PRESS ANY KEY TO CONTINUE======= TRK:................................... +.5: 0123456789ABCDEF0123456789ABCDEF012 SC0:................................... SC1:................................... SC2:................................... SC3:................................... SC4:................................... SC5:................................... SC6:................................... SC7:................................... SC8:................................... SC9:................................... SCA:................................... SCB:................................... SCC:................................... SCD:................................... SCE:................................... SCF:................................... ======================================= 16 SC $00,$00 TO $22,$0F BY $01 TO DRV2 Rebooting my work disk, I can now see the catalog on the demuffin'd copy. [S6,D1=demuffin'd copy] [S5,D1=my work disk] ]PR#5 ... ]CATALOG,S6,D1 C1983 DSR^C#254 005 FREE A 002 HELLO T 223 Q1 B 010 TITLE.OBJ B 039 TEACHER.OBJ B 007 INSTRUCT.OBJ B 016 INIT.OBJ B 041 P2C.OBJ B 023 PART1.OBJ B 010 CG B 014 PICDRAWH B 002 PIC.UNPACKER.6000 B 008 PROFG4D.PK B 008 PROFG4U.PK B 004 I1 *B 017 RUNTIME B 007 I2 B 003 I3 B 005 I4 B 002 I5 B 007 I6 B 005 ST B 005 S1 B 006 S2 B 008 A1 B 004 A2 B 002 C1 B 002 C2 B 003 C3 B 004 W1 B 008 STRING B 002 SHAPE B 002 UNPACKER B 008 MAP.PACK B 003 MG T 002 PARMS ]RUN HELLO The game loads and runs without complaint. All further disk access is done through standard DOS functions. There doesn't appear to be any kind of nibble check or other copy protection, beyond the custom RWTS. Now to make the disk be able to read itself (remember, it still has the original RWTS on it)... For future reference (mostly mine), here's a nice chart of the memory locations for all the prologues and epilogues for an RWTS loaded into low memory. The disk loads T00,S02 at $3800, T00,S03 in $3900, and so on. 0x | read | write ---------------+-------+------- D5 | $3955 | $3C7A prologue AA | $395F | $3C7F / 96 | $396A | $3C84 ADDRESS -------+-------+------- \ DE | $3991 | $3CAE epilogue AA | $399B | $3CB3 EB | | $3CB8 ---------------+-------+------- D5 | $38E7 | $3853 prologue AA | $38F1 | $3858 / AD | $38FC | $385D DATA ----------+-------+------- \ DE | $3935 | $389E epilogue AA | $393F | $38A3 EB | | $38A8 ---------------+-------+------- I spent way too much time making that. Based on manual inspection with a sector editor, it appears I need to change the first byte of both the address and data epilogues. Everything else is standard. T00,S02,$9E change "BF" to "DE" T00,S03,$35 change "BF" to "DE" T00,S03,$91 change "BF" to "DE" T00,S06,$AE change "BF" to "DE" Success! The disk boots and loads with no complaint. There doesn't appear to be any secondary protection. Quod erat liberandum. ~ POSTSCRIPT: AUTOMATING IOB MODULES This is the second time I've had Advanced Demuffin crash on me because my AUTOTRACE program didn't alert me that the RWTS was in a non-standard location. That calls for some auto- mation. I've added these lines to my work disk's HELLO program. At line 270, I check whether the RWTS is loaded at $B800. If it's not, I create an IOB module that reads one track at a time and calls the proper RWTS entry point. Lines 280-285 create the IOB module in memory; lines 290-295 save it to disk; line 300 contains the assembly language instructions as an array. 268 REM $BDBB HOLDS HIGH BYTE OF START OF RWTS 269 REM (USUALLY $B8) 270 IF PEEK (10171) = 184 THEN GOTO 1000 279 REM NON-STANDARD RWTS STAR T LOCATION 280 FOR I = 5120 TO 5148: READ X: POKE I,X: NEXT I 285 POKE 5149, PEEK (10171) + 5 290 PRINT "SAVING IOB" 295 PRINT CHR$ (4)"BSAVE IOB,A $1400,L$1E" 300 DATA 74,141,34,15,140,35,1 5,142,39,15,169,1,141,32,15, 141,42,15,169,48,141,241,28, 169,15,160,30,76,0 --------------------------------------- A 4am crack No. 63 ------------------EOF------------------