---------The Ancient Art of War-------- A 4am crack 2014-07-22 --------------------------------------- "The Ancient Art of War" is a 1989 strategy game developed by Dave and Barry Murry and distributed by Broderbund. It is distributed on one double-sided disk. COPYA copies both sides of the disk with no errors, but the copy does not work. Booting side A loads several tracks from disk, displays the title title screen, then reboots. (EDD 4 bit copy fares no better.) There is no sign of a disk catalog on track $11 or any other track, and no sign of a standard DOS on tracks 0-2. Time for boot tracing with AUTOTRACE. [S6,D1=original disk, side A] [S5,D1=my work disk] ]PR#5 CAPTURING BOOT0 ...reboots slot 6... ...reboots slot 5... SAVING BOOT0 For those of you just tuning in, my work disk uses a custom program that I affectionately call "AUTOTRACE" to automate the process of boot tracing as far as possible. For some disks (like this one, apparently), it just captures track 0, sector 0 (saved in a file called "BOOT0") and stops. Now I need to look at that sector and figure out how this disk boots, and why my copy reboots while the original does not. ]CALL -151 *800<2800.28FFM *801L 0801- A5 27 LDA $27 0803- C9 09 CMP #$09 0805- D0 2F BNE $0836 ; munging reset vector right away 0807- A9 00 LDA #$00 0809- 8D F2 03 STA $03F2 080C- 8D F3 03 STA $03F3 080F- 8D F4 03 STA $03F4 ; read/write main memory and ROM 0812- 8D 02 C0 STA $C002 0815- 8D 04 C0 STA $C004 0818- AD 82 C0 LDA $C082 081B- 8D 08 C0 STA $C008 ; set up vector for re-using the disk ; controller ROM routine to read ; more sectors from track 0 081E- A5 2B LDA $2B 0820- 4A LSR 0821- 4A LSR 0822- 4A LSR 0823- 4A LSR 0824- 09 C0 ORA #$C0 0826- 85 3F STA $3F 0828- A9 5C LDA #$5C 082A- 85 3E STA $3E ; sector read loop 082C- 18 CLC 082D- AD FE 08 LDA $08FE 0830- 6D FF 08 ADC $08FF 0833- 8D FE 08 STA $08FE 0836- AE FF 08 LDX $08FF 0839- 30 15 BMI $0850 083B- BD 58 08 LDA $0858,X 083E- 85 3D STA $3D 0840- CE FF 08 DEC $08FF 0843- AD FE 08 LDA $08FE 0846- 85 27 STA $27 0848- CE FE 08 DEC $08FE 084B- A6 2B LDX $2B 084D- 6C 3E 00 JMP ($003E) 0850- EE FE 08 INC $08FE 0853- A6 2B LDX $2B ; execution continues at $8000 0855- 4C 00 80 JMP $8000 *8FE.8FF 08FE- 7F 0F OK, so this loop reads all of track 0 into $7F00..$8EFF then jumps to $8000. Let's capture that. *9600 again 802A- 20 B5 81 JSR $81B5 ; track 3 into $4000..$4FFF 802D- A9 02 LDA #$02 802F- A0 40 LDY #$40 8031- 20 00 8B JSR $8B00 ; track 4 into $5000..$5FFF 8034- A9 03 LDA #$03 8036- A0 50 LDY #$50 8038- 20 00 8B JSR $8B00 ; check for again 803B- 20 B5 81 JSR $81B5 803E- AE FF 8A LDX $8AFF 8041- 86 43 STX $43 8043- A9 00 LDA #$00 8045- 8D 0A 25 STA $250A 8048- 8D 0B 25 STA $250B 804B- 8D 0C 25 STA $250C ; don't know what this does 804E- 20 00 20 JSR $2000 Some hasty sector editing (this code is on T00,S01) to break into the monitor right after this instruction convinces me that this subroutine is harmless. 8051- AD 82 C0 LDA $C082 8054- AD 98 BF LDA $BF98 8057- 29 B2 AND #$B2 8059- C9 B2 CMP #$B2 805B- F0 03 BEQ $8060 805D- 4C CA 25 JMP $25CA 8060- AD 26 BF LDA $BF26 8063- CD 16 BF CMP $BF16 8066- D0 08 BNE $8070 8068- AD 27 BF LDA $BF27 806B- CD 17 BF CMP $BF17 806E- F0 1C BEQ $808C 8070- AE 31 BF LDX $BF31 8073- BD 32 BF LDA $BF32,X 8076- 29 70 AND #$70 8078- C9 30 CMP #$30 807A- F0 05 BEQ $8081 807C- CA DEX 807D- 10 F4 BPL $8073 807F- 30 0B BMI $808C 8081- BD 33 BF LDA $BF33,X 8084- 9D 32 BF STA $BF32,X 8087- F0 03 BEQ $808C 8089- E8 INX 808A- D0 F5 BNE $8081 ; track 5 into $4000..$4FFF 808C- A9 04 LDA #$04 808E- A0 40 LDY #$40 8090- 20 00 8B JSR $8B00 ; check for again 8093- 20 B5 81 JSR $81B5 ; track 6 into $5000..$5FFF 8096- A9 05 LDA #$05 8098- A0 50 LDY #$50 809A- 20 00 8B JSR $8B00 ; don't know what this does 809D- 20 00 40 JSR $4000 Some more hasty sector editing to break into the monitor right after this instruction shows that this subroutine is what displays the graphical title screen. Moving on... ; don't know what this does, but the ; branch-on-carry-clear right after it ; is mildly suspicious 80A0- 20 08 82 JSR $8208 80A3- 90 03 BCC $80A8 80A5- 4C 91 81 JMP $8191 Just a hunch, but I'm guessing that $8191 is The Badlands (the point of no return). *8191L ; reset memory flags 8191- 8D 0C C0 STA $C00C 8194- 8D 08 C0 STA $C008 8197- AD 82 C0 LDA $C082 ; switch to text and clear the screen 819A- 20 2F FB JSR $FB2F 819D- 20 58 FC JSR $FC58 ; put "R" in the upper-left of the ; screen 81A0- A9 D2 LDA #$D2 81A2- 8D 00 04 STA $0400 ; reboot 81A5- AE FF 8A LDX $8AFF 81A8- 8A TXA 81A9- 4A LSR 81AA- 4A LSR 81AB- 4A LSR 81AC- 4A LSR 81AD- 09 C0 ORA #$C0 81AF- 8D B4 81 STA $81B4 81B2- 4C 00 00 JMP $0000 OK, so we definitely don't want to end up at $8191. $8191 is bad. That means that the routine at $8208 reaaaally needs to clear the carry bit. *8208L ; Looks like a ProDOS call ($BF00 is ; the entry point to all ProDOS MLI ; routines). That would explain why ; the code listing goes off into the ; weeds at $8215 -- that's not code, ; it's the parameters to the MLI call. 8208- AD FF 8A LDA $8AFF 820B- 29 7F AND #$7F 820D- 8D 21 82 STA $8221 8210- 85 2B STA $2B 8212- 20 00 BF JSR $BF00 8215- 80 ??? 8216- 20 82 90 JSR $9082 8219- 03 ??? 821A- 4C 91 81 JMP $8191 821D- 4C 26 82 JMP $8226 Real code continues at $8218. *8218L 8218- 90 03 BCC $821D 821A- 4C 91 81 JMP $8191 821D- 4C 26 82 JMP $8226 ProDOS MLI calls set the carry flag on error, so if this call fails, we're going to end up in The Badlands again. Otherwise execution continues at $8226. *8226L 8226- A9 0A LDA #$0A 8228- 85 50 STA $50 822A- A6 2B LDX $2B ; turn on the disk motor manually: ; always a sign of impending evil bits ; (a.k.a. a nibble check) 822C- BD 89 C0 LDA $C089,X 822F- BD 8E C0 LDA $C08E,X 8232- A9 A7 LDA #$A7 8234- 85 48 STA $48 8236- A9 82 LDA #$82 8238- 85 49 STA $49 823A- A9 80 LDA #$80 823C- 85 51 STA $51 ; looks like the failure path goes ; to $82A1 823E- C6 51 DEC $51 8240- F0 5F BEQ $82A1 ;fail ; this subroutine looks for, and skips ; past, the next address field 8242- 20 AF 82 JSR $82AF 8245- B0 5A BCS $82A1 8247- A5 2D LDA $2D 8249- C9 07 CMP #$07 824B- D0 F1 BNE $823E 824D- A0 00 LDY #$00 824F- BD 8C C0 LDA $C08C,X 8252- 10 FB BPL $824F 8254- 88 DEY 8255- F0 4A BEQ $82A1 ;fail 8257- C9 D5 CMP #$D5 8259- D0 F4 BNE $824F ; Search for a specific sequence of ; nibbles in the "dead zone" between ; the address field and data field. ; This area is normally not important, ; so COPYA didn't copy it precisely ; because normal disks don't care. ; (Actually, it's even more evil than ; that, because the original disk is ; written with timing bits in specific ; non-standard places between the ; nibbles in the dead zone. This code ; not only requires the right nibbles ; in the right order, it reads them ; just slightly faster than normal. So ; the timing bits need to be in the ; right places too, or the disk will ; get out of sync and read the wrong ; nibble values. This will trip up even ; the best bit copiers. And you can ; forget about making a disk image for ; emulators -- those don't store timing ; bits at all.) 825B- A0 00 LDY #$00 825D- BD 8C C0 LDA $C08C,X 8260- 10 FB BPL $825D 8262- 88 DEY 8263- F0 3C BEQ $82A1 ;fail 8265- C9 E7 CMP #$E7 8267- D0 F4 BNE $825D 8269- BD 8C C0 LDA $C08C,X 826C- 10 FB BPL $8269 826E- C9 E7 CMP #$E7 8270- D0 2F BNE $82A1 ;fail 8272- BD 8C C0 LDA $C08C,X 8275- 10 FB BPL $8272 8277- C9 E7 CMP #$E7 8279- D0 26 BNE $82A1 ;fail 827B- BD 8D C0 LDA $C08D,X 827E- A0 10 LDY #$10 8280- 24 06 BIT $06 8282- BD 8C C0 LDA $C08C,X 8285- 10 FB BPL $8282 8287- 88 DEY 8288- F0 17 BEQ $82A1 ;fail 828A- C9 EE CMP #$EE 828C- D0 F4 BNE $8282 828E- A0 07 LDY #$07 8290- BD 8C C0 LDA $C08C,X 8293- 10 FB BPL $8290 8295- 99 40 BF STA $BF40,Y 8298- D1 48 CMP ($48),Y 829A- D0 05 BNE $82A1 ;fail 829C- 88 DEY 829D- 10 F1 BPL $8290 ; success path is here -- clear carry ; bit and exit gracefully 829F- 18 CLC 82A0- 60 RTS ; failure path is here -- after enough ; tries, give up and set the carry bit 82A1- C6 50 DEC $50 82A3- D0 95 BNE $823A 82A5- 38 SEC 82A6- 60 RTS It looks like I can bypass this copy protection by clearing the carry flag and exiting gracefully. T00,S03,$08 change "AD FF" to "18 60" Quod erat liberandum. --------------------------------------- A 4am crack No. 93 ------------------EOF------------------