Speedlock 2


This is the one with the flashing border and loads of annoying bleeps. I'm doing Athena as an example, because it was the first one I found.


The Basic Bit
*Load and *list as usual

. "athen 48" LINE 0 LEN 65
0 BORDER 0: PAPER 0: INK 0: CLEAR 32000: LOAD ""CODE: PRINT USR 58616
So CLEAR 32e3: LOAD ""CODE and load in that huge chunk of code that follows, and start diassembling it. 58616 is E4F8 hex.


Siz of One....
There are six decryptors in Speedlock 2, but they are all very easy to crack.
E4F8 LD   B,21
E4FA LD   HL,E508
E4FD LD   A,(HL)
E4FE XOR  B
E4FF LD   B,A
E500 LD   (HL),A
E501 INC  HL
E502 LD   A,H
E503 OR   L
E504 JR   Z,E508
E506 JR   E4FD
To crack this simply put it somewhere convenient and stick a breakpoint on the end. Note that it terminates (as do the other five) when HL=0 (ie there is no counter to check how many bytes are left). HL=0 when you INC HL if HL=FFFF, so this decryptor (and the others) decrypt from the initial value of HL (E508 in this case) through to FFFF, so don't put it there!
E508 JR   E50F
E50A LD   DE, E520
E50D JR   E512
E50F DI
E510 JR   E517
E512 LD   A,(DE)
E513 RLCA
E514 LD   (DE),A
E515 JR   E519
E517 JR   E50A
E519 INC  DE
E51A LD   A,E
E51B OR   D
E51C JR   Z,E520
E51E JR   E512
As you can see, this one is full of JR's going all over the place. If you look at where it's going and make a note of what it does along the way, you can see what happens a bit easier.
E50F DI
E50A LD   DE,E520
E512 LD   A,(DE)
E513 RLCA
E514 LD   (DE),A
E519 INC  DE
E51A LD   A,D
E51B OR   D
E51C JR   Z,E520
E51E JR   E512
Again, this is an easy decryptor (they all are). Simply move E508-E51F to somewhere convenient, slap a breakpoint on the end and run it from there.
E520 LD   E,85
E522 DI
E523 XOR  A
E524 OUT  (9F),A
E526 IN   A,(9F)
E528 LD   A,(300E)
E52B CP   C9
E52D JR   Z,E530
E52F RST  0
E530 LD   A,43
E532 OUT  (7F),A
E534 LD   HL,0000
E537 LD   (0000),HL
E53A LD   HL,(0000)
E53D LD   A,L
E53E OR   H
E53F JR   NZ,E546
E541 LD   A,40
E543 OUT  (7F),A
E545 RST  0
E546 LD   BC,E552
E549 LD   A,(BC)
E54A XOR  E
E54B LD   E,A
E54C LD   (BC),A
E54D INC  BC
E54E LD   A,B
E54F OR   C
E550 JR   NZ,E549
The actual decryptor in this chunk of code is at E546-E551, but it uses the value of E, set right at the start. For those interested, the code at E522-E52F checks for a Multiface, and from E530-E545 for a SoftRom (this is pointless as they can both be made "invisible"). To crack, do whatever you've been doing so far - move E520-E551 somewhere, slap a breakpoint on the end and run it from there. Make sure, before you run it, that if a Multiface or SoftRom are connected, that you disable them, or the checking routines will cause a crash.
E552 LD   DE,E560
E555 LD   A,(DE)
E556 XOR  D
E557 SUB  E
E558 XOR  E
E559 ADD  A,D
E55A LD   (DE),A
E55B INC  DE
E55C LD   A,D
E55D OR   E
E55E JR   NZ,E555
This is very straighforward, and you crack it as you've been cracking the others.
E560 JR   E567
E562 LD   HL,E579
E565 JR   E56A
E567 DI
E568 JR   E570
E56A LD   A,(HL)
E56B XOR  F3
E56D LD   (HL),A
E56E JR   E572
E570 JR   E562
E572 INC  HL
E573 LD   A,H
E574 OR   L
E575 JR   Z,E579
E577 JR   E56A
This one is similar to the one at E508, with JR's all over the place. The order on which the instructions are executed is...
E567 DI
E562 LD   HL,E579
E56A LD   A,(HL)
E56B XOR  F3
E56D LD   (HL),A
E572 INC  HL
E573 LD   A,H
E574 OR   L
E575 JR   Z,E579
E577 JR   E56A
Move E560-E578 to somewhere convenient and slap a breakpoint at the end.
E579 LD   HL,5BFF
E57C LD   (HL),0
E57E DEC  HL
E57F LD   A,H
E580 CP   3F
E582 JR   NZ,E57C
E584 LD   HL,E58F
E587 LD   A,(HL)
E588 RRCA
E589 LD   (HL),A
E58A INC  HL
E58B LD   A,H
E58C OR   L
E58D JR   NZ,E587
Cracking this final one (in the usual way) will reveal the Speedlock loader. Now all we need to do is find it.


Where'd the loader go?
From the experience with the first Speedlock, you know that LD IY,address points to the address of the table. With Speedlock 2, it's the second LD IY, not the third, that gives the address of the table, so search for FD 21 (LD IY,nn). The first one, at EE67, is LD IY,0000. Again from Speedlock 1, you know that this is the first byte of the loader, so make a note of the address. Now search for FD 21 again, and you see a LD IY,8B5E, so you know that this is where the table should be. Now look for ED 53, which is the code for LD (nn),DE and is the standard Speedlock patch. For Athena, this is at F0AD, with the LD DE,nn at F0AA. Change the LD DE,nn above it to point to a convenient address where you have put your pokes. Now search for F3 31, which is the code for DI: LD SP,nn. These are the first two instructions executed by Speedlock, and JPing here will start is loading (don't do it yet). Following the code from F15B (where the DI is), you will see the table of addresses to load, at F1C5 (you identify it by the 00 80 00 03 10, which loads the attribute file for the screen).


Moving around
So far you know where the table is (F1C5) and where it should be (8B5E). You also know that EE67 is the first byte. Now you are in a position to put Speedlock into its correct address and start loading.
If F1C5 goes to 8B5E, EE67 goes to 8B5E-(F1C5-EE67), which is 8800. The address it executes from was originally F15B, which is now at F15B-EE67+8800, ie 8AF4. To be on the safe side, make the length of the code FFFF-EE67, to make sure you've got it all. Now that you know the address of the patch, where the loader's going to and the address to get it going, you can move it with
LD   HL,#EE67
LD   DE,#8800
LD   BC,#FFFF-#EE67
LDIR
JP   #8AF4
This is the code in my hack, once the six decryptors have been cracked.


The Athena hack
The way the decryptor loop in this works is to have the lengths of the siz decryptors stored as a little line of data at the end. The length is taken out, and a pointer used to point to the length of the next decryptor. It is similar to having a line of basic DATA, then doing a FOR-NEXT loop, and READing a length in the loop. Before using this program, make sure you CLEAR 32e3: LOAD ""CODE (from the basic loader).
      ORG  30000
      LD   IX,DATA       ;IX POINTS TO THE LINE OF DATA
      LD   HL,#E4F8      ;E4F8 IS THE ADDRESS OF THE
                         ; FIRST DECRYPTOR
      LD   B,6           ;SIX DECRYPTORS
DCRLP PUSH BC            ;STORE B TEMPORARILY
      LD   C,(IX+0)      ;GET LENGTH OF THE DECRYPTOR
                         ; FROM THE DATA LINE
      LD   B,0           ;CAN NEVER BE OVER 255 BYTES
                         ; LONG
      INC  IX            ;POINT TO THE LENGTH OF THE
                         ; NEXT DECRYPTOR
      LD   DE,25000      ;A SAFE PLACE
      LDIR               ;MOVE THE DECRYPTOR
      PUSH HL            ;HL NOW POINTS TO THE ADDRESS
                         ; OF THE NEXT ONE. STORE IT
                         ; TEMPORARILY
      LD   A,#C9         ;C9 IS CODE FOR RET
      LD   (DE),A        ;STICK A RET ON THE END OF THE
                         ; DECRYPTOR (IN PLACE OF A
                         ; BREAKPOINT)
      CALL 25000         ;DO THE DECRYPTOR
      POP  HL            ;TAKE THE ADDRESS OF THE NEXT
                         ; DECRYPTOR OFF THE STACK
      POP  BC            ;BC HOLDS THE AMOUNT LEFT
      DJNZ DCRLP         ;LOOP BACK IF MORE DECRYPTORS
                         ; TO DO
      LD   HL,POKES
      LD   DE,#5BA0      ;A SAFE PLACE
      LD   BC,DATA-POKES ;BC=LENGTH OF POKES
      LD   (#F0AB),DE    ;THE STANDARD SPEEDLOCK PATCH,
                         ; F0AB IS THE ADDRESS OF THE
                         ; NUMBER IN LD DE,NN
      LDIR               ;MOVE THE POKES
      LD   HL,#EE67      ;EE67 HOLDS THE LD IY,0
      LD   DE,#8800      ;THIS IS WHERE IT SHOULD BE
      LD   BC,#FFFF-#EE67 ;MAKE SURE YOU'VE GOT ALL THE
                         ; CODE
      LDIR
      JP   #8AF4         ;LOAD THE GAME
POKES EQU  $             ;MAKE SURE YOU PRESERVE HL IN
                         ; YOUR POKES IF YOU'RE USING IT
      JP   #8B45         ;THE ORIGIB\NAL NUMBER IN THE
                         ; LD DE,NN
DATA  DEFB 16,24,50,14,25,22 ; LENGTHS OF THE DECRYPTORS