HOW TO HACK on the ZX Spectrum

A complete guide to creating POKEs on the Spectrum, featuring 
full examples. Devised and written by Richard P Swann

NB : This document was originally intended to be printed in
Your Sinclair magazine. It is split into "pages" of 58 lines.


CONTENTS

WHAT YOU WILL NEED...........................Page 1

THE BASIC IDEA...............................Page 2
    Getting started with hacking

CONVENTIONAL HACKING TECHNIQUES..............Page 8
    Forwards trace and backwards trace

EASY LOADING SYSTEMS.........................Page 11
    Headerless loaders, turboloads and compression

DECRYPTERS...................................Page 18
    Single decrypter loading systems    

ADVANCED HACKING METHODS.....................Page 24
    Stack trace and interrupt trace

COMMERCIAL PROTECTION SYSTEMS................Page 26
    Bleepload, Ultimate loader, Mikro Gen Loader,
    Powerload, Search Loader, Paul Owens Protection
    System, Speedlocks

EPILOGUE.....................................Page 59
    Scrolling credits etc. etc.

GLOSSARY AND INDEX...........................Page 60

WHAT YOU WILL NEED

If you want to use this book successfully, you will need the 
following:

* An understanding of Spectrum BASIC. If you are total beginner, 
you will almost certainly find this book too complicated, and 
hence useless to you. If you can understand most of the Spectrum 
manual, then you should be all right. If you don't understand a 
word of the section on using +3 DOS in machine code in the +3 
manual, don't worry, 'cause I don't either!

* A disassembler or a monitor program. You can, in theory, hack 
anything without one of these, but in practice, it would be 
impossible for a beginner, and next to impossible for someone 
experienced. My personal choice is Hisoft's DEVPAC, but if you 
have the programs STK and 007 Disassembler (which were on the 
covertapes of YS #75 and #77), that'll do fine for this book.

* Some games to hack. Obviously business software is out of the 
window because it's illegal to hack it, and you don't need to 
anyway. Strategy and adventure games are pretty unlikely to 
demand a POKE (although it's possible, and I'll show you how I 
hacked an adventure later on), so you're left with arcade and 
arcade adventure games. Most of the time you'll want to find 
infinite lives and/or energy, but there are always exceptions. 
This book concentrates on games that you're likely to have, which 
are games which have been on magazine covertapes, or bestsellers.

* Patience and determination. This is the most important thing of 
all. Finding POKEs is challenging without any knowledge of how 
the program works, or even a knowledge of the language it's 
written in! So be prepared to do some serious THINKING!

* A Multiface or other "magic box" device. This is not essential, 
but it is extremely useful, and a few sections in this book 
require you to have one (but as few as possible, I might point 
out!)

PART ONE - The Basic Idea

 Before we get down to some serious hacking, it will be a good 
idea to know what we are looking for. Okay, I know that some of 
you may think that this is pointless, but if you don't know what 
you're aiming at, you'll never get anywhere.
 Basically, we are going to examine a program, and change it so 
that certain instructions are altered so that the game becomes 
more easier to the user. This may be in the form of infinite 
lives, infinite energy, immunity, infinite bullets etc.
 The only way we can hope to do this is to understand what is 
going on in the game. And because most games are written in 
machine code, we're going to have to understand that as well. 
Please don't be put off by the thought of learning a new 
language; in fact you need know very little machine code 
knowledge to hack most games.

 To start with, we'll just look at infinite lives. Lives are 
normally a small number, between 3 and 9 (although some games may 
have more), and the common thing with all games that have lives 
is that somewhere in the game, the amount of lives are set as a 
definite number, and somewhere else, the amount of lives goes 
down by one. In order to get infinite lives, we would have to 
remove the command in the program which decreased a player's 
lives.
 You probably have and idea about how a lives system would work 
in BASIC. Say if, for argument's sake, a BASIC game had three 
lives, you would expect to see something like...

100 LET LIVES=3

...contained in the program. Then, a bit further on, you'd expect 
to see...

500 LET LIVES=LIVES-1

 In order to get infinite lives, we would simply remove line 500 
altogether and RUN the program.

 A similar idea appears in machine code, but the way it's done is 
slightly different.
 For starters, machine code doesn't have any variables! You might 
therefore wonder how on earth the computer can store anything. In 
actual fact, the computer can store information anywhere in RAM, 
as you may well know, and this is exactly what happens in machine 
code.
 In Chapter 24 ("The Memory") of the Spectrum manual, there's a 
detailed description of the Spectrum's memory. The best way to 
visualise the memory, I think, is to imagine 65,536 boxes, each 
one containing a piece of paper with a number from 0 to 255 
written on it.
 Therefore, it is no problem for a computer to store the number 
of lives in machine code, since it can just put it as a byte in a 
memory location, leave it there, and come back to it later.
 You should be aware that in machine code, commands are also 
stored in memory locations as bytes; so if you get commands and 
data mixed up in memory, the computer could easily try and 
execute the data, thinking it's a command, and trying to execute 
it. Unlike BASIC, there are no errors in machine code, and the 
computer can execute anything it finds, so in this case you will 
get a crash. So most programs keep program data and program 
commands separately.
 Anyway, in order to store three lives in machine code, we'd put 
the number 3 in a memory location. Unfortunately, we can't do 
this straight away in machine code, and we can only do it by 
using what are called registers.
 Registers store information in the same way as memory locations. 
They are bit more versatile though, as you can perform 
calculations with them. All the same, they are not the same as 
variables in BASIC, and are more like a pair of hands used for 
counting.
 The main register we'll look at for now is the A register 
(sometimes called the accumulator), which can store a single 
byte and have sums done to it.
 What we would do to store the number three in a memory location 
is to put the number 3 into the A register, then put the contents 
of the A register (which are of course, 3) into a memory 
location.
 The actual way of writing this in machine code is:

LD A,3
LD (#8000),A

 Actually, strictly speaking, the above isn't machine code at all! 
Machine code as the computer sees it is, as I explained earlier, 
consists of many bytes in memory, which are pretty meaningless to 
humans. So some people invented assembly language (which is what 
the above is), where each instruction carried out by the computer 
is given a name (called a mnemonic).
 The above program features one command used in two different 
ways. The command is LD, which is pronounced "load". This has 
nothing at all to do with loading a program from tape. It 
basically is a transfer of information from one place to another. 
The comma in the instructions is read as "with", so the whole 
instruction is read as "Load A with 3". It now seems obvious that 
this instruction is putting the number 3 into the A register.
 The second command is also LD, but the way its used is slightly 
different. The brackets mean "the contents of", so the whole 
instruction is read as "load the contents of #8000 with A". 
(Think of a bracket as a byte in memory, where everything in the 
bracket is part of that byte) Therefore, this instruction would 
make the computer take whatever value is in the A register, and 
store it in memory location #8000 (of course, it could be any 
other memory location as long as it is unused).
 So the overall result of the two commands (normally called 
operations) would be to put the number 3 in memory location 
#8000.

 Congratulations! You've just learned the first way to hack. 
Clearly, if in a real program, we found these operations, we 
could change the LD A,3 to something like LD A,100 to get 100 
lives!
 Before we can do any "real" hacking, I'd better discuss how 
"real" machine code is written.
 Every machine code instruction contains and opcode, and some 
instructions need an operand. An opcode is simply the instruction 
the computer is going to do. Every number from 0 to #FF corresponds
with a specific opcode. You can find a complete list of opcodes 
in Appendix A of your Spectrum manual.
 The operand is used whenever there is ambiguity over something. 
If you look in Appendix A of the Spectrum manual, you will see 
that the opcode #3E is "LD A,n". "n" in this case can mean any 
single byte number ie: a number from 0 to 255. But it's possible 
to put any number within this range eg: LD A,3 or LD A,#40 or LD 
A,#80 etc. The computer has to somehow know what data it is 
dealing with, and this is where the operand comes in. In machine 
code, whenever the computer comes across the opcode #3E, it 
looks at the byte after the opcode, and assumes it's the data 
needed. So, if the computer came across the bytes #3E and #40 in 
succession, it would put the value #40 in the A register. In this 
example, #3E is the opcode, while #40 is the operand. After 
executing the instruction, the computer goes to the byte after 
the operand, and starts running code from there.
 In the second instruction of our example, the opcode is #32, ie: 
"LD (NN),A". The ambiguity is in the address where we are going 
to store the value of the A register. In this case, the operand 
takes up two bytes, hence the "NN", which again comes after the 
opcode. You should note that this is an address in memory, and is 
always referred to as two bytes. So you might expect the machine 
code equivalent of LD (#8000),A to be #32 #80 #00. Except it 
isn't! For some odd reason, in machine code, all two byte 
operands are written the wrong way round, so the actual machine 
code equivalent of LD (#8000),A is #32 #00 #80. There is no hard 
and fast reason why, it's just vitally important that you 
remember this.

 In short, the program of the previous page is written as...

#3E #03 #32 #00 #80

...which takes up five bytes.
 Not all instructions require operands. For example, DEC A (short 
for "decrease A", which subtracts one from the A register) has no 
ambiguity at all. There is only one way to decrease the value in 
the A register, so the instruction only takes up one byte, in 
this case #3D. No operands are needed.

 Right, time for your first bit of hacking! From what we've 
discussed above, we want to find, somewhere in the game's code, a 
set of instructions which put the number of lives into a byte in 
memory. So if the game had three lives, we could expect to see 
the bytes...

#3E #03 #32

...unfortunately, we don't know where in memory the number of 
lives is going to go, so we can't work out the operands for the 
second instruction (#32). But in fact, we don't need to, for if 
we find the above sequence of bytes in a program, we can simply 
examine the two bytes after this sequence to find out where in 
memory the number is being put.

 So let's put this into practice and hack an actual game. For 
convenience I've chosen Sweevo's World, which featured on a YS 
Covertape Issue 60 December 1990. I would have chosen a more 
recent game, but they all have some form of protection on them. 
Besides, obtaining infinite lives is relatively easy.
 Getting the game in memory without it running is easy. If you've 
typed out a fair few POKEs in your time, this will be no problem. 
Just MERGE the BASIC loader and put a STOP statement before the 
RANDOMIZE USR statement. Then RUN the program and wait for it to 
load, until the OK message appears.
 Now we have the game in memory, we can load STK and examine it. 
You have to be a bit careful here, because STK occupies 6K of the 
Spectrum's memory. Although it can be anywhere in memory, it 
possible to overwrite the all-important lives code in the game 
with STK, so we have to be careful. The best places to put STK are 
in the graphics, map or sound data. There's no easy way to tell 
where this is, so you'll have to try pot luck. But it helps if 
you know where the game loads to, so load up STK at any address, 
and press J and then Caps+9 to read in a header a couple of 
times. Then read the headers of the three blocks of code after 
the BASIC. They are:

Bytes: S 4000,1B00
Bytes: M FB90,043D
Bytes: P 60E0,82B0

The first block is the loading screen. The second block is in 
actual fact the game's music (but you wouldn't be expected to 
know this), and the third block is the actual game itself. 
Therefore, we can put STK anywhere above (60E0+82B0)=E390. For 
argument's sake, let's put it at EA60, which is 60000 decimal. 
When we've finished hacking, we can reload "Bytes: M" and run the 
program. Load up STK (after having stopped the BASIC and returned 
with a STOP statement) at address 60000.

 Now at last, some hacking. Bearing in mind that you start the 
game with five lives. Press Q to search for a byte. Enter the 
address we want to start searching at as 60E0, because that's the 
start of the game. Now type in the following:
#3E #05 #32
These are the search bytes we described on the previous page. 
Keep pressing N for "next" until all of the memory has been 
searched. You will get the following addresses: 905C and EEDC. 
You can ignore the one at EEDC, because it's in the middle of STK 
and outside the main game code, so that leaves just the one at 
905C. Press E for edit and type #905C. You'll see the following 
bytes:

3E 05 32 1A 61

 So this tells us that the computer puts the number five in box 
number 611A (remember that 2 byte numbers are reversed!) Now to 
hack the game, we simply change the number 5 at 905D to any 
number of lives we want (the maximum is #FF).
Now, get out of STK, reload the "Bytes: M" file and RANDOMIZE USR 
24800 (the original command in the BASIC), and hey presto - you 
will have whatever amount of lives you wanted!

 All that remains to do is to write a proper hack for it. 905D is 
36957 in decimal, so your hack would be something like "MERGE the 
BASIC loader, and insert POKE 36957,n before the RANDOMIZE USR 
statement, where 'n' is the number of lives."
 And it's as simple as that. If you can understand what we've 
done so far, you're doing well, so stick at it.
 Any unprotected game like Sweevo's World is hacked in the same 
way, except you will probably have to reload STK to a different 
address, and you may find that in your search for #3e <lives> 
#32, you may come across several locations in memory outside STK 
that have this pattern. In this case, you'll have to use trial 
and error to work out which one holds the number of lives.

 It is, of course, perfectly possible for you now to find 'number 
of lives' POKEs for any unprotected game under the sun, and in 
the early days of Spectrums ('82-'84), this would have been 
perfectly adequate. Of course, what your really need is the real 
nitty gritty - INFINITE lives. This is done by taking things just 
a step further.
 What you basically need to do is find out which memory location 
the number of lives are being put in. Then you need to search for 
parts of the program which put the value of that memory location 
in a register, subtract one from it, and put the new value in the 
register back. Then you have to rewrite the code slightly so that 
the computer "forgets" to decrease the value in the register, and 
simply puts the old value back in again.

 Coming back to Sweevo's World, we already know that the number 
of lives are stored at memory location 611A. I normally refer to 
this memory location as the "lives store" for obvious reasons. 
All we have to do is search for all the occurrences of the 
address of the lives store. So, search for #1A,#61, and you will 
find it referred to at the following addresses:

779B   8160   81A9   905F   EEDC

 You can ignore the one at EEDC because it's in STK, but you can 
also ignore the one at 905F, since that's part of the lives 
setting routine we discussed earlier. So the routine to decrease 
the number of lives must lie at one of the other locations.
 You should note, that any instruction that involves the lives 
store will begin at the byte before, because 1A and 61 are two 
byte operands (see page 3 for more about operands).

 So for starters, press E to edit an address and type in #779A. 
You'll see the following:

779A - 3A 1A 61 C3 61 99

 If you look up 3A in Appendix A of your Spectrum manual, you'll 
see it corresponds to the instruction LD A,(NN). This is simply a 
reverse of the LD (NN),A instruction, in that the value of a 
memory location is put into the A register. This is important, 
because subtraction of any sort can only be done in a register, 
and usually in the A register.
 After the computer has executed the three byte instruction 3A 1A 
61 (which is LD A,(611A in mnemonics), it executes the 
instruction C3. If you look up C3 in Appendix A of your Spectrum 
manual, you'll see it corresponds to the instruction JP. JP is 
short for "jump", and is in a sense like GOTO in BASIC. What the 
computer does is to jump to a location in memory. As you can see, 
there is ambiguity as to where it is going to jump, so we need a 
two byte operand. Like the ones me have met before, the bytes are 
written the wrong way round. So C3 61 99 means JP 9961. In this 
case, the computer would go to address 9961, and start executing 
code from there.
 It is possible that the code to decrease the number of lives is 
at 9961, but is unlikely, because it pointless to have to jump to 
a completely different area of memory. So we'll leave this part 
of memory, and go onto the next instruction, at 8160. Press EDIT 
to leave the editing procedure, and edit address 815F. You'll see 
the following:

815F - 21 1A 61 35

 21 is the instruction LD HL,NN. HL is another register like A, 
but its main difference is that it can store two bytes at once. 
So LD HL,NN requires a two byte operand, whereas LD A,N only 
requires one. So here the instruction 21 1A 61 means LD HL,611A. 
The next instruction, 35 doesn't need any operands, and is the 
instruction we've been looking for. 35 means DEC (HL). You've 
already come across brackets meaning "the contents of", so as you 
might have guessed, DEC (HL) decreases whatever is at the memory 
location with the same number as HL by one. In this case, we know 
that HL is 611A, because we've just set it in the last 
instruction. So DEC (HL) will decrease the value of whatever is 
in memory location 611A by one in this case.
 But we already know that the number of lives is stored at memory 
location 611A. So clearly DEC (HL) is going to decrease the 
number of lives by one!
 What we need to do to make an infinite lives POKE is to somehow 
overwrite the DEC (HL) so that the computer doesn't decrease the 
number of lives. There are two things that can be done. Firstly 
the address containing DEC (HL) can be replaced by 0. The number 
0 relates to an instruction called NOP. NOP is short for "No 
operand", and in short means absolutely nothing! When the 
computer encounters the instruction NOP, it will do nothing and 
execute the next instruction. So if we overwrite DEC (HL) with 
NOP, the computer won't decrease the number of lives, but do 
nothing instead. The vast majority of POKEs have the format POKE 
address,0 for the reasons described above.
 If you run Sweevo's World changing the DEC (HL) to NOP, you'll 
find you only get one life instead of five! In this case, you 
should overwrite the DEC (HL) with OR (HL). OR (HL) is a single 
byte instruction, B6. Don't worry about what it does, because it 
isn't important. What is important is to remember to do this if 
you only get one life.
 Rerun Sweevo's World, replacing the DEC (HL) with OR (HL), and 
you'll have your infinite lives! The DEC (HL) is at address 8162, 
which is 33122 decimal, while B6 is 182 decimal, so the POKE 
would go something like "MERGE the loader, and put POKE 33122,182 
before the RANDOMIZE USR statement, RUN the program and restart 
the tape."
 Now we've covered the rudiments of machine code involved in 
hacking, we can look at more detailed ways of finding POKEs.

PART 2 - Conventional Hacking Techniques

 By now, you should have an idea of how simple machine code 
works. Now we're going to look at the usual techniques of 
hacking. There are five techniques, which are called Forwards 
Trace, Backwards Trace, Stack Trace and Interrupt Trace, in that 
order of difficulty. Of these, Forwards Trace and Backwards trace 
are the only techniques you can use without a Multiface, and are 
the most reliable methods. You should only really have to use the 
others in exceptional circumstances, which are, on the whole, 
games which don't have a lives system or a GAME OVER message. 
Very few games use unusual routines, since it's just a hindrance 
to the programmer.

 We'll start with Forwards Trace. You've already had a go at this 
from the last part, so hopefully it won't be too hard to 
understand. Then we'll look at the backwards trace, followed by 
some practical examples.

FORWARDS TRACE:

 For the forwards trace, you start with the lives initialisation
routine, and then work forwards from there.
 The first thing you need to do is to find where the number of
lives are defined. We've already seen how numbers are put into
memory locations, and this is exactly what happens in most games.
 (From now on, all the machine code programs discussed here will
be written as hexadecimal bytes, and as mnemonics.)

3E XX         LD A,XX (where XX is the number of lives)
32 XX XX      LD (XXXX),A (where XXXX is a memory location,
                           which we will refer to as the
                           "lives store".)

 You have already come across these instructions, but just to
resume, the number of lives is put in the A register, which in
turn is put in the lives store, the overall result being the
number of lives being put in the lives store.

 To find this, use the search function on your disassembler
(QUEST 16384 on STK), and search for 3E <number of lives>. So
if you had five lives, you'd search for 3E 05. You may find that
this instruction occurs a few times, but you will probably find
that only one actually puts the value of A in a memory location
straight away. If there appear to be two occurrences where the
number of lives is put into a memory location, then you may have
to test all of them. You can, in general, rule out memory locations
in which the number of lives is put in twice.
 If you want to confirm you've found the lives store, you need
a Multiface. Load the game up, and while playing the game, alter
the value in what you think is the lives store. If the number
of lives varies, you've found the lives store. If not, try
another possible location. If you can't find any memory location
which looks like a lives store, you won't be able to forwards
trace, I'm afraid, in which case you should try the backwards 
trace instead.
 Once you've found the lives store, you'll have to search for
occurrences of it. You are basically looking for code which takes
the value out of the lives store and puts it in a register
(normally the A register), decreases the number by one, and puts
the new result back in the lives store. To get infinite lives, you
 have to overwrite the decrement instruction with a blank
instruction so that the number of lives is left intact.
 The code you want normally takes one of two formats:

1st type:
3A XX XX     LD A,(XXXX) where XXXX is the lives store
3D           DEC A (we want to remove this)
32 XX XX     LD (XXXX),A (putting the new value in the lives store)

2nd type:
21 XX XX     LD HL,XXXX where XXXX is the lives store
35           DEC (HL)   We want to remove this

 You may find that there are other instructions between these.
Don't worry about what they mean, just ignore them.

 In order to remove the decrement instruction, we have to do
one of two things. The most common is to replace the DEC A or
DEC (HL) with a NOP (code 00). If this gives you only one life,
replace the DEC A with OR A (code B7), or replace the DEC (HL)
with OR (HL) (code B6). Don't worry why!

BACKWARDS TRACE:

 Also known as "backtracking", a backwards trace starts from the
GAME OVER message, and goes back from there to the lives routine.
It is normally used when a forwards trace does not work or is
unsuitable (eg: when finding infinite energy), the easiest
alternative is to use a backwards trace.

 The first thing you need to do is to find out what message is
printed on the screen when you die. Nine times out of ten it's
"GAME OVER", but there are exceptions.
 For GAME OVER you have to search for the following bytes :
47 41 4D 45 32 4F 56 45 52. This is GAME OVER in ASCII (look up
the codes in Appendix A of the Spectrum manual if you like).
Sometimes, you may not find it, in which case just search for
47 41 4D 45 (GAME in ASCII). If that search fails, then the
GAME OVER text is not in an ASCII format (this is rare, because
printing routines are considerably smaller when ASCII is used),
and you can't do a backwards trace.

 Once you've found the GAME OVER message, you need to find out
which part of the program refers to it. Normally, a print
routine will load a register with the address of the GAME OVER
routine, then print it. One possible register is HL (as we have
met before), but also two other registers called BC and DE. Normally, 
all of these three registers are referred to as "register pairs",
because they are two registers, each the same size as the A
register, working together, so they can address all of the memory.
You want to look for the following:

01 XX XX     LD BC,XXXX (where XXXX is the address of the GAME        
                                                 OVER MESSAGE)

11 XX XX     LD DE,XXXX (as above)

21 XX XX     LD HL,XXXX (as above)

(Remember that XXXX will be written "backwards" in the game's
machine code!)

 You should only find one occurrence of any of the above
instructions. If you can't find any, repeat the search but take
one away from the address the GAME OVER text is. (This is because
sometimes there are Spectrum ASCII control codes such as 16 XX
for PAPER XX before the actual text, and these are referred
to as the start of the message). If that doesn't work, repeat the
search taking one away again. Keep doing this and you'll soon
find one of the above instructions.

 When you've found the instruction, note down where it occurs.
The part of the code you are now in is part of the GAME OVER
printing routine. What you now need to do is go back through
the code until you find either the code C3 XX XX (which is JP
XXXX), or C9 (which is RET, which behaves exactly the same way
as RETURN in BASIC.) Alternatively, you may find a blank area
of memory (00 00 00 00 00 00 etc.) The address after one of
these instructions is the START of the GAME OVER routine.

 When you've found the start of the GAME OVER routine, you
can find out which part of the code calls it. Then, to get a
cheat, you can remove all parts of the code which branch to
the GAME OVER routine. Search for the address of the start of
the routine. You will probably find some of the following:

CD XX XX   CALL XXXX
CC XX XX   CALL Z, XXXX
C4 XX XX   CALL NZ, XXXX
C3 XX XX   JP XXXX
CA XX XX   JP Z,XXXX
C2 XX XX   JP NZ,XXXX

...where XXXX is the start of the game over routine. JP is 
similar to GOTO in BASIC, while CALL is similar to GOSUB (so that 
a RET instruction will return to the instruction after the call - 
except in some protection systems, but more about that later).To 
cheat, simply poke all three bytes of the instruction you find 
with 00 (so as to disable the CALL or JP). And there you have it!

 Using the techniques of forwards trace and backwards trace, you 
should be able to hack most old, unprotected games!

PART 3 - EASY LOADING SYSTEMS

 So far, you've worked out the all important basics of hacking. 
However, there is another, equally important facet of hacking 
games that you should know about.

 Few games these days are unprotected. They feature "protection 
systems" which prevent you from breaking into a program and 
fiddling about with it. The difficulty level varies, but in 
general they use two concepts - headerless loading and 
decryption. 

 Before we do anything, I should point out that you're going to 
need a disassembler from now on. The machine code listings in 
this book use Devpac's notation, but 007 Disassembler's notation 
is almost identical, except it uses decimal instead of hex. 
Hopefully, you shouldn't get lost if you use

 Anyway, for now, we'll forget about decryption and 
concentrate of headerless loaders, since they're common to all 
protection systems.

 A headerless loader will look something like this:

DD 21 XX XX    LD IX,XXXX
11 XX XX       LD DE,XXXX
3E FF          LD A,#FF
37             SCF
CD 56 05       CALL #0556

 ...where XX can be any number from #00 to #FF. IX is another 
register similar to HL, but has slightly different properties, 
which you don't need to worry about right now. The value put into 
IX is always the start address of the block to be loaded, and the 
value put into DE is always the length of the block to be loaded. 
So the routine works exactly like loading and saving bytes in 
BASIC.
 The only differences you should ever find are that the CALL is 
to a different address (#0556 is the ROM loading routine, so 
other CALLS are to turboloaders in RAM), the LD A,#FF has some 
other value loaded into A instead, or is missing, or the SCF is 
missing. Basically, if you see DD 21 XX XX 11 XX XX in a 
protection system, you can be pretty sure it will be used to load 
something.

 Now we know how a headerless loader works, let's try and hack a 
real one. As an example, I've chosen Ethnipod, which was on the 
May 1991 YS Covertape.

 First of all, load up STK at any address (I'd suggest 32768, but 
you don't have to) and press Z to BLOAD in the BASIC. Then use 
STK to list the basic, and you'll get the following:

10 BORDER 0: PAPER 0: INK 7: CLEAR 24999: LOAD "" CODE
65000: RANDOMIZE USR 65000

Therefore, we should type in CLEAR 24999:LOAD "" CODE 65000 and 
restart the tape. When the OK message appears, stop the tape, 
load up your disassembler, and have a look at address 65000 
(#FDE8). Here's a complete disassembly of the code you'll find 
there.

FDE8 21 00 40    LD HL,#4000
FDEB 11 01 40    LD DE,#4001
FDEE 01 FF 1A    LD BC,#1AFF
FDF1 36 00       LD (HL),#00
FDF3 ED B0       LDIR

 LDIR is a command we haven't met before, but it's easy to 
understand. It's a copying routine. The start address of the 
block you want to copy is put in HL, the length of the block you 
want to copy is put in BC, and the start address of the area of 
memory you want to copy it to is put in DE. So, in the example 
above, the area of memory from #4000 is copied to #4001 for #1AFF 
bytes. In short, this routine is overlaying each address in this 
area of memory with the byte of the previous address.
 The LD (HL),00 means that byte #00 is put into address #4000. 
Therefore, the whole of the memory from #4000 to #5AFF is filled 
with 0. In case you didn't know, the whole of this memory is the 
screen memory, so this bit of code is what makes the screen black 
when loading the game normally. If you want, you can change the 
byte at #FDED to #00 to give LD DE,#0001, so the contents of the 
screen memory are copied into the ROM (except that they aren't 
because the ROM is a read-only memory and you can't write 
anything into it.) This will stop the screen going black. You 
don't actually need to do it at all, but there we go.
 Continuting the disassembly:

FDF5 11 00 1B    LD DE,#1B00
FDF8 DD 21 00 80 LD IX,#8000
FDFC 3E FF       LD A,#FF
FDFE 37          SCF
FDFF CD 56 05    CALL #0556

 This portion of code loads in a block of code, with the start 
#8000 and the length #1B00.

FE02 3E 00       LD A,#00
FE04 D3 FE       OUT (#FE),A

 This part of the code includes an OUT instruction, but OUT in 
machine code is exactly indentical to that in BASIC. So, this 
routine is basically the equivalent of OUT 254,0 in BASIC. If you 
don't know what that does, it sets the border to black.

FE06 11 00 40    LD DE,#4000
FE09 21 00 80    LD HL,#8000
FE0C 01 00 1B    LD BC,#1B00
FE0F ED B0       LDIR

 This is another LDIR, and it moves the code from #8000 to #4000 
for #1B00 bytes. In other words, it copies the screen picture 
into the screen memory so you can see it.

FE11 11 60 9D    LD DE,#9D60
FE14 DD 21 B4 5F LD IX,#5FB4
FE18 37          SCF
FE19 3E FF       LD A,#FF
FE1B CD 56 05    CALL #0556

 This part of code loads another block, with start 5FB4 and 
length 9D60.

FE1E C3 C7 61    JP 61C7

 This part of the routine jumps to the game itself once it is 
loaded.

 To hack the game, replace the C3 at FE1E with C9. This will put 
a RET at the end of all the code, so the loader will return to 
BASIC when all loading has finished.

 When the OK message comes up, you can hack the game as you've 
done with unprotected games. If you load STK into address #6000 
(24576 decimal), and hack the game using a forwards trace, you'll 
eventually find that changing #EF09 to 0 gives you infinite lives 
for player one. Then to start the game, type RANDOMIZE USR 25031 
(61C7 in decimal), and bingo!

 To write a hack, we need to rewrite the BASIC loader, but make 
the modifications so we can put POKEs in:

10 CLEAR 24999
20 LOAD "" CODE 65000

This comes directly from the BASIC loader and loads the small 
headerless loader code.

30 POKE 65054,201

This means that control will return to BASIC when all the 
headerless code has been loaded

40 RANDOMIZE USR 65000

This starts off the headerless loader.

50 POKE 61193,0

This is the infinite lives POKE


60 RANDOMIZE USR 25031

This starts the game itself. Easy when you know how!

 Now we know how a simple headerless loader works, let's crack a 
turboloader. There are loads of YS covertape games which have a 
suitable loader, but I'm going to choose Pixy the Microdot 2, 
although you'll find that any YS game which uses blue, black and 
magenta stripes when loading is almost identical.

 First of all, load up STK at address 58550 (you'll find out why 
later on), to find out what the BASIC loader has to say, using 
the same method as with Ethnipod. It starts running at line 0.

1 BORDER 0:PAPER 0:CLEAR 64999:LOAD "" CODE
2 RANDOMIZE USR 65146
20 CLEAR 64999:LOAD "mc" CODE:LOAD "pixldsy"
CODE:SAVE "t:":SAVE "PIXY" LINE 1:SAVE "x"
CODE 65146,200:LOAD "screen" SCREEN$:RANDOMIZE
USR 65000

 The BASIC starts at line 1. The commands should be obvious to 
you. Type CLEAR 64999:LOAD "" CODE, start the tape, and load in 
the first block of code. Stop the tape when the OK message comes 
up.

 Now load your disassembler and examine the code at 65146, which is 
FE7A hex.

FE7A F3           DI

 DI is short for "disable interrupts". What are interrupts, I 
hear you ask? Well, imagine you're watching TV when suddenly, 
someone says "We interrupt this program to give you an important 
newsflash!" Then, after the newsflash, the program you were 
watching resumes. Well, computer interrupts work in exactly the 
same way. In fact, every fiftieth of a second, a program is 
"interrupted" by the computer, which then checks to see if you're 
pressing any keys, and resumes the original program. The command 
DI simply stops this happening, and your program continues 
without any interruption! This makes the program run faster. 
However, you CANNOT get back to BASIC by a RET command, because 
the computer won't be checking the keyboard, and so it has 
effectively locked up. To get round this, you must execute the 
command EI (enable interrupts) first, so control can be resumed. 
Don't worry about doing this now, though.

FE7B 31 60 61    LD SP,6160

 This is a new instruction. SP (short for "stack pointer") is a 
16-bit register, like BC, DE and HL. However, it's far more 
important as far as BASIC is concerned. In machine code, there 
are two ways of storing numbers. The first, using memory 
locations, we've already come across. However, there is another 
method by storing numbers on what is called a stack. Think of a 
stack as a big spike on which you can push pieces of paper with 
information on. Then, later on, you can take them off the stack 
and use them. If you think about it, if you put the numbers 1, 2 
and 3 on the stack, in that order, you'll have to take 3 off 
first, then 2, then 1 (think about it). And it's the same in 
machine code. There are instructions which enable values of 
registers to be put on the stack, and which enable the value on 
the top of the stack to be taken off and put in a register.
 The stack, like everything else, has to go somewhere in memory. 
The SP (stack pointer) register gives the address of the top of 
the stack. So LD SP,6160 will mean that the stack is to start at 
address 6160.
 This is bad news if you want to return to BASIC, because the 
Spectrum's ROM program puts lots of information on the stack, so 
if you change the stack pointer, it's going to receive garbage 
when it takes all the values off what it thinks is the stack. And 
that, of course, will mean a crash. So the general rule is LEAVE 
THE STACK POINTER ALONE!
 You can change the value of the stack pointer using CLEAR from 
BASIC. If a machine code instruction has LD SP,XXXX, you can type 
CLEAR (XXXX)-1. So here, we should CLEAR (#6160)-1 = #615F. Bear 
in mind that the value will have to be in decimal, which is 
24927. So exit from STK, CLEAR 24927, and go back into it again. 
This will mean that later on we can do the EI / RET as described 
above. Then you have to remove the LD SP instruction, which is 
most easily done by changing FE7B to 21, so it reads LD HL,6160. 
This is harmless in this case.
 Carrying on through the code....

FE7E DD 21 00 40 LD IX,4000
FE82 11 00 1B    LD DE,1B00
FE85 CD 97 FE    CALL FE97

 As you can probably see, this loads a headerless block, the 
loading screen, in fact. However, you'll notice, as I said 
eariler, that some of the other commands (LD A,#FF and SCF) are 
missing, and the CALL goes to a different address. This is 
because it's a turboloader.

FE88 DD 21 60 61 LD IX,6160
FE8C 11 4B 83    LD DE,834B
FE8F CD 97 FE    CALL FE97

 This loads another block, start 6160 and length 834B. This 
means, that all the memory from 6160 to E4AB will be overwritten. 
Fortunately, you loaded STK into address 58550, which is E4B6 
hex, so it won't be overwritten. Clever, eh? Meanwhile....

FE92 30 F4       JR NC,FE88

 Something I haven't told you yet is that after a headerless 
load, a JR NC will result in that JR if there is a tape loading 
error. So, if there was a tape loading error in loading this 
game, the JR NC,FE88 would be executed (so that computer would 
try and reload the block).

FE94 C3 60 61    JP 6160

This starts the main program running.

 To crack the loader, therefore, POKE FE94 with FB (for EI) and 
FE95 with C9 (for RET), along with the modifications I've already 
told you about. Then RANDOMIZE USR 65146, and restart the tape 
(it is possible that you didn't stop the tape quickly enough the 
previous time, so you'll miss the turboload header, in which case 
wind back just before  it). When the game has finished loading, 
an OK message will appear.

 And that's it! Well, actually it's not, because the game is 
actually compressed, and needs to be unpacked first. Don't worry, 
because it's easy to hack. Go into STK again, and look at address 
6160. You're looking for a JP instruction to the game, which is 
what is executed when the game is unpacked. You'll find it at 
61A3. So POKE 61A3,FB and 61A4,C9 (for an EI / RET), and 
RANDOMIZE USR 24928. Wait a few seconds until BASIC returns. And 
there we are - you've cracked the loader!

 You might be wondering how you can tell that the game is 
compressed. Well, there are two things. Firstly, the JP from the 
loader (6160) is to a very low address in the usuable RAM (which 
only starts at 5B00). But more noticeable, you won't be able to 
do a forwards trace or a backwards trace until you run the 
decompressor. In fact, in general, if you think you should be 
able to forwards trace or backwards trace a game for infinite 
lives, and haven't overloaded any important code with a 
disassembler, but nothing happens, its worth looking at the start 
of the code executed and seeing if there's a JP a bit later on to 
a completely different address.

 So now, perhaps, we should write a complete hack for the game.

10 CLEAR 24927:LOAD "" CODE

This is from the BASIC loader and loads in the first block of 
code. We've changed the CLEAR though, so the stack is in the 
right place.

20 POKE 65147,33

This changes the LD SP,6160 into LD HL,6160 so the SP isn't 
tampered with.

30 POKE 65172,251:POKE 65173,201

This changes the JP 6160 to an EI / RET so control will return to 
our hack once the game has loaded.


40 RANDOMIZE USR 65146

This starts the game loading

50 POKE 24995,251:POKE 24996,201

This changes the JP 86CE to an EI / RET so control will return to 
our hack once the game has decompressed

60 RANDOMIZE USR 24928

This starts the game decompressor.

70 POKE 28402,0

This is the infinite lives POKE, which you'll find out when you 
do a forwards trace on the uncompressed game.

80 RANDOMIZE USR 34510

This is the start of the game.

 Now that you've done that, why not crack another game which uses 
the same loader? They're nearly all the same, except some of the 
JP addresses will be different. And then when you've done that, 
why not have a look at some other headerless loaders - most games 
by Codemasters use them.

 You will find, however, that you will sometimes have to 
overwrite some of the memory with your disassembler. There's no 
easy way to tell where it should be, I'm afraid, so you'll have 
to take pot luck. If your forwards trace and backwards trace are 
both unsuccessful, try loading the disassembler elsewhere in 
memory, or look to see if the game is compressed.

PART 4 - DECRYPTERS

 By this point, you should be familiar with headerless loaders, 
which take up the bulk of most protection systems these days. 
However, there is one other important aspect of protection that 
you need to know about if you are to crack the more complex 
protection systems. It's encryption.

 Encryption works like a secret code. You start off with somthing 
unintelligable, then you use the "secret rules" to change it into 
something that makes sense. So, IBDLFST doesn't make much sense, 
but if you take the previous letter in the alphabet each time, 
you get HACKERS, which makes perfect sense. Encryption works in 
roughly the same way. We've already seen that a loading system 
occupies a small area of memory. An encrypted loading system will 
appear as a block of code which makes absolutely no sense 
whatsoever. There will also be a short program which changes all 
this nonsense into workable code so the loading system can be 
run. Some really tough loading systems, have more than one 
decrypter, such as the Alkatrazz loading system which has 250 of 
the damn things; in practice I've got through about 25 before 
going mad and hacking something else (don't worry, there's 
another way of hacking them which I'll tell you about later.)

 To make it easier for you to understand decryption, its best to 
have a look at a real loading system. As an example, I've chosen 
Impossaball, which was on the YS#75 covertape. Load up STK at 
address 50000 (it's a safe address), and see what the BASIC has 
to say for itself by BLOADing it......

10 CLEAR 64530: LOAD "" CODE:RANDOMIZE USR 64531
20 LOAD "" CODE 16384
21 FOR i=1 TO 40 STEP - RANDOMIZE USR 50000

 Fair enough - so enter CLEAR 64530:LOAD "" CODE and start the 
tape. The first code block loads in, and then - it crashes! 
What's going on? Don't worry, you have just fallen victim to the 
first type of encryption - BASIC encryption.

 In BASIC, any numerical constant (technotwaddle for "number") 
between 0 and 65,535 is stored in the memory as follows. First, 
there is the number in it's ASCII form, which takes between 1 and 
5 bytes. So, the number 1234 will appear as #30,#31#,#32,#33 
here. Then, come the numbers #0D,#00 and 00 (this is always the 
case). Then, there is the number stored in it's two byte form (as 
in machine code). What happens it that the computer prints the 
ASCII form (which is what you get when you LIST a program), but 
uses the two-byte form in calculations and expressions. The 
upshot of all this is that what you see isn't always what you 
get! As an example, type in this:

1 PRINT 1

 Now type POKE 23760,50 (which changes the ASCII value of the 
number 1 from "1" to "2"). Now if you LIST the program, you will 
see 1 PRINT 2, but if you RUN the program, the computer will 
print the number 1 instead!
 Needless to say, protection systems use the same idea. 
Sometimes, the numbers listed are obviously fake (if you list a 
program and you get something like 0 CLEAR 0:RANDOMIZE USR 0 it's 
obviously got encrypted BASIC), but some programs, like the 
Impossaball are not obvious at all until you try executing what 
you see.

 There was a program called *List printed ages ago in YS, but if 
you haven't got that, I've reprinted it here. So type it in, SAVE 
it to tape, RUN it and reload the Impossaball BASIC loader.

loading LINE 10 LEN 81

10 CLEAR 25599: LOAD "" CODE: RANDOMIZE USR 64512
20 LOAD "" CODE 16384
21 FOR i=1 TO 40 STEP ????....

 Now that's what you really get! Type CLEAR 25599:LOAD "" CODE 
and load in the first block of code. When that's done, load up 
your disassembler, and disassemble address 64512 (FC00 hex) to 
have a look at the decrypter.

FC00 01 99 02   LD BC,#0299
FC03 21 13 FC   LD HL,#FC13
FC06 11 14 FC   LD DE,#FC14

 This part of the program sets up all the initial values for the 
decrypters in some of the registers.

FC09 1A         LD A,(DE)

 We've come across brackets before, but briefly what happens here 
is that the contents of the address with the value of the DE 
register (which starts of as #FC14) are put into the A register. 
So now the A register could contain any byte.

FC0A AE         XOR (HL)

 We haven't seen XOR before, so I'll explain what it does. It is 
in technical terms a Boolean Operation. You may have seen XOR 
gates if you studied (or are studying!) Physics, Electronics or 
Computer Science at school. An XOR gate has two inputs, which can 
each either be 0 or 1, and one output, which can be either 0 or 1 
as well. If the two inputs are the same (0 and 0, or 1 and 1), 
the output is 0, otherwise it is 1. In machine code, you XOR the 
A register with a number or contents of a register, and what 
happens is that each bit in the A register is XORed with the same 
bit in the number or register contents, and the result is stored 
in the A register. If you're confused, look at the example below.

Contents of the A register   00100101
Number to be XORed with      01010011
Result                       01110110

(Notice that all the numbers are in binary - see your Spectrum 
manual for more information about this).

 If you still don't understand, just remember that an XOR will 
change the contents of the A register. That's all you need to 
remember for now.

 Continuing the disassembly...

FC0B 77       LD (HL),A

 This puts the value of A (which has just been changed) into the 
bytes at the address with the value of the HL register (which 
starts off as #FC13).
 So, the routine has basically taken a byte out of a memory 
location, changed it a bit, and put the altered value back again. 
This is decryption in its most obvious form - the changed values 
make up a working machine code program.

FC0C 23       INC HL
FC0D 13       INC DE
FC0E 0B       DEC BC

 I don't think I've mentioned INC before, but it's basically the 
opposite of DEC in that it increases the value in whatever 
register. So the values in the HL and DE registers are 
incremented, and the value in the BC register is decremented.

FC0F 78       LD A,B
FC10 B1       OR C
FC11 20 F6    JR NZ,#FC09

 This is a standard piece of code, and it essentially means "If 
BC isn't 0, then jump to #FC09". In other words, another byte 
will be decrypted until the value of BC is 0 (which happens when 
everything has been decrypted), and the decrypter ends.

 Continuing the disassembly...

FC13 5C       LD E,H
FC14 9F       SBC A,A
FC15 A5       AND L
FC16 5B       LD E,E
FC17 13       INC DE
FC18 5B       LD E,E
.... 

 Hang on - this code doesn't make sense! It has no relation to 
the code above, and the instruction LD E,E is pointless anyway. 
Well, you'll remember that the initial value of decryption is 
#FC13, which means that all the code from there onwards has to be 
decrypted. So we'll have to crack the decrypter to go any 
further.
 Sometimes, it is possible to put an EI/RET instruction directly 
after the decrypter, but this is not possible here, as you will 
see. So instead, we'll have to move the decrypter somewhere else 
in memory, and put the EI/RET on the end (in actual fact we don't 
need the EI because there is no DI command in the decrypter). 
This is easily done by using the LDIR command. Type in the 
following program:

1 FOR N=23296 TO 23310:INPUT A:POKE N,A:NEXT N

 Now RUN it and enter the following numbers:

33,0,252,17,128,91,1,1,18,0,237,176,54,201,201

 The program you have just typed in is this:

LD HL,FC00
LD DE,5B80
LD BC,0012
LDIR
LD (HL),C9
RET

 Now RANDOMIZE USR 23296 and the decrypter will be copied to 5B80 
and a RET will be stuck on the end. Just RANDOMIZE USR 23424 
(5B80 in decimal) to run the decrypter. When the OK message comes 
up, restart the disassembler and look at FC13 again:

FC13 C3 3A FE   JP #FE3A

 This jumps to #FE3A, to start the loading.

FE3A F3         DI
FE3B 21 00 58   LD HL,#5800
FE3E 11 01 58   LD DE,#5801
FE41 01 FF 02   LD BC,#02FF
FE44 36 00      LDIR

As you already know, this makes the screen black.

FE48 CD 81 FE   CALL #FE81
FE4B CD 00 80   CALL #8000

 If you look at the code at #FE81, you'll see it's a headerless 
loader. The routine at #8000 prints the loading screen.

FE4E CD 81 FE   CALL #FE81
FE51 CD 00 64   CALL #6400 

 This loads another block (the main game), and prints another 
screen (the border for the game).

FE54 F3         DI
FE55 31 FF FF   LD SP,#FFFF

 This disables interrupts and changes the stack pointer, so we'll 
have to change that in the final hack.

FE58 21 00 6D   LD HL,#6000
FE5B 11 00 5B   LD DE,#5B00
FE5E 01 00 8F   LD BC,#8F00
FE61 ED BO      LDIR

 This is another LDIR command, but if you know how the Spectrum's 
memory is organised, you will see that the BASIC system variables 
are overwritten, which means we can't return to BASIC when the 
game has loaded. Fortunately, there's a short routine to get 
round this, which I'll explain in a mo.

FE63 21 71 FE   LD HL,#FE71
FE66 11 00 F0   LD DE,#F000
FE69 01 10 00   LD BC,#0010
FE6C ED B0      LDIR
FE6E C3 00 F0   JP F000

 This moves the code from FE71 to F000, and jumps to F000. 
Obviously, then, the code at FE71 is important.

FE71 21 00 FC   LD HL,#FC00
FE74 11 01 FC   LD DE,#FC01
FE77 01 FF 01   LD BC,#01FF
FE7A 36 00      LD (HL),0
FE7C ED B0      LDIR
FE7E C3 00 80   JP #8000

 This routine wipes out all the memory from #FC00 to #FC01, but 
in actual fact you don't need to do this. Then it jumps to #8000, 
which is the start of the game. So, we can put a machine code 
routine to put a POKE in, and then jump to #8000.
 However, we've got to find the POKE first, and there's the 
problem that we can't use BASIC because it is overwritten. 
Luckily, there is a short routine you can use which will cause a 
NEW to a certain address. Put it into the above program by typing 
in the following:

1 FOR N=65137 TO 65144:INPUT A:POKE N,A:NEXT N

Then RUN it, and enter these numbers in turn:

243,175,17,0,95,195,203,17

 The program you've just typed in is the following:

DI
XOR A
LD DE,#5F00
JP #11CB

 DI disables interrupts, XOR A loads A with 0 (think about what 
would happen if you XORed the value of the A register with 
itself, LD DE,#5F00 means we want to NEW up to #5F00 (this value 
can be changed from about #5D00 to #FFFF), and JP #11CB starts 
the NEW.

 Now RANDOMIZE USR 65082 (#FE3A in decimal), and restart the game 
tape. When the computer resets, you can load STK into address 
24320 to find POKEs.

 Phew! And that's about all of that protection system cleared up. 
If you can get your way through that lot, I think you're probably 
ready to have a go at a "commercial" protection system. First, 
though, we'll write a complete hack for the game.

10 CLEAR 25599:LOAD "" CODE

 This is from the BASIC loader, and it loads in the first machine 
code block

20 FOR N=23296 TO 23310:READ A:POKE N,A:NEXT N

 This line POKEs in the machine code program to move the 
decrypter.

30 DATA 33,0,252,17,128,91,1,19,0,237,176,54,201,201

And here's the actual machine code itself

40 RANDOMIZE USR 23296

This line calls the decrypter and returns to BASIC

40 FOR N=65137 TO 65143: READ A:POKE N,A:NEXT N

This line POKEs in our hacking program

50 DATA 175,50,??,??,195,0,128

 And here's the hacking program, which loads ???? with 0 (which is 
the infinite lives POKE), and jumps to #8000.

60 RANDOMIZE USR 65082

 This starts the whole loading system off, with the POKE firmly in 
place.

 And that's about it. A bit of a long piece of work, but it was 
worth it!


PART 5 - Advanced Hacking Methods

 Remember in Part 2, when I said there were other ways of 
hacking, apart from forwards and backwards tracing? Well, you can 
find them here. But you need a Multiface to be able to use them. 
The two we're interested with here are what I call a stack trace 
and an interrupt trace.

STACK TRACE:

 We've already come across the stack as a means of storing 
numbers. What you haven't come across yet is how the stack is 
used. Well, in a CALL to a subroutine, what actually happens is 
that the return address from the subroutine (which is the address 
after the CALL instruction) is stored on the stack, and with a 
RET, the top value of thhe stack is taken off and jumped to.
 With a Multiface, the value on the top of the stack is the 
return address to the program. and subsequent values refer to 
return addresses in subroutines.
 To do a stack trace, load and play the game, and wait until the 
"death effect" occurs - this may be a beep, a flashing border or 
something else recognisable. Now quickly press the Multiface 
button during this effect - if you're too slow, you won't get 
the values you're looking for (so return to the game and die 
again). Now, look at the value of the stack pointer (your 
Multiface manual will tell you how to do this), and write down 
all the values on top of the stack for the first ten bytes. All 
numbers are stored in the normal reversed two-byte form, so if 
the bytes on the top of the stack were #00,#80,#80,#70,#90,#60, 
the values would be #8000,#7080 and #6090. Have a look at all of 
these addresses - you should find that some of them are addresses 
right after CALL instructions.
 Now for the hacking bit - go to one of these address and write 
down the two bytes there. Then change them to the magic codes #18 
and #FE (this is the machine code version of JR -2, which is an 
endless loop, a bit like 1 GOTO 1 in BASIC). Restart the game, 
and hopefully, you'll find that the game pauses as soon as you do 
something which would normally result in you losing a life! (If 
not, replace the #18FE with the original two bytes, look at 
another address on the "hit list" and repeat the whole 
procedure).
 Once you've found a target address, try putting a RET (#C9) at 
the start of the subroutine. If this just cancels the death 
effect, but you still "die", activate the Genie Disassembler if 
you have it (or use the NEW routine in Part 4 at any address, 
then load in STK or Devpac somewhere far away from the area of 
memory you're looking at), and search for CALLs to this routine. 
Then go back from this CALL until you find a RET or a JP, and 
search for the address of the instruction after this (if nothing 
comes up, search for one more than this, then two more etc.). You 
will hopefully either see one of these:

JP Z
JP NZ
JP C
JP NC

(The JP may be a JR or a CALL instead)

 Simply overwrite this instruction with NOPs to get immunity or 
something similar.
 On the other hand, when searching from the CALL address, you may 
find a JP Z or JP NZ, etc. Change this to an unconditional JP to 
get immunity.

INTERRUPT TRACE:

 This involves looking at the interrupt routine in the game. 
Since the whole routine must be executed in 1/50th of a second, 
the routines are usually quite short, especially if there is a 
LDIR or something similar. Most of the time you'll find infinite 
time in this routine (because interrupts work in real time, so 
its an ideal place to put a time routine), and you need a 
Multiface to find it.
 Load the game and start playing as normal. Then activate the 
Multiface, and have a look at the I register. If the value is 
#3F, there are no special interrupts, so forget about an 
interrupt trace altogether (but you can use a stack trace which 
will make the clock loop round to 99 or whatever when it reaches 
0). If it is between #80 and #FF (and if it's not in that range 
and not #3F you've probably crashed the computer!), go to the 
address #100 time that of the value in the I register (so if the 
value of I is #F0, look at #F000). You will see an area of memory 
filled with the same number. Go to this address (if this area of 
memory is filled with #FE, go to #FEFE etc.) There will either be 
a jump to the interrupts routine, or the interrupts routine 
itself. Have a look at the routine, and somewhere you will see 
the commands to decrease the timer - just remove the DEC 
instruction to get infinite time.

PART 6 - Commercial Protection Systems

 If you can understand everything we've done so far, you can now 
probably crack just about any budget game or YS covergame that's 
thrown at you. And indeed, you can probably get featured in 
"Practical POKEs" month in month out (like a load of anonymous 
hackers, I might add!) by using the knowledge you've got. 
However, if you want to become a hacking legend, you should have 
a go at some of the numerous commercial protection systems, which 
have been written by freelancers for software houses.
 I think we're getting seriously into Multiface territory now, 
but I'll try and do as much as possible with only STK and 007 
Disassembler.
 I think I should also say that cracking commercial protection 
systems is NOT easy. The code is deliberately badly structured 
and obscurely coded to put you off, so you'll have to perservere. 
You really do need something like a Multiface or Devpac to crack 
some of these systems, because they can overwrite the system 
variabes in BASIC, and you sometimes need to know the values of 
certain registers, which is impossible to determine using BASIC.
You'll also need some games other than YS stuff to hack, but 
fortunately, protection systems such as Speedlock or Alkatrazz 
are so common, you're bound to have a game with one of them on. 
I'll be doing examples specific to one game, but you'll find that 
onther game with the same protection is pretty much the same, 
except you're likely to find that some of the addresses will be 
different.
 Before we start, I'd just like to point out that I'll be 
referring to the term "breakpoint" a lot. This is simply a small 
bit of code which will stop the program dead in its tracks. Using 
DEVPAC, you just press the W key. On a Multiface, you do the same 
as a stack trace, by writing down the two bytes at the place you 
want to put a breakpoint, then replacing them with #18 and #FE. 
If you are using 007 disassembler and/or STK, you'll need to put 
a jump to the start of the program (#C3 #00 #40 for 007 
disassembler; STK varies depending on where you put it).

 So let's start with something relatively simple....

BLEEPLOAD

 "Bleepload" first appeared on Firebird games around March 1987, 
and was used by them on every release by them from then on until 
their demise in 1989. It emulates a BBC loading system in that 
each file loads in a series of blocks, which are numbered in 
hexadecimal. The hardness is not because it uses non standard 
cde, it's just that it jumps around so much in memory you need to 
put in an awful lot of software patches.
 I'll be hacking Bubble Bobble as an example.

First of all, load in *Hack, and load in the BASIC loader.

Bubble LINE 10 LEN 179

10 REM
20 CLEAR 50000
30 BORDER 0:PAPER 0:INK 0:CLS
40 PRINT AT 1,7;PAPER 1;INK 7;"BUBBLE BOBBLE"
50 LOAD "Bobble" CODE 52480
60 RANDOMIZE USR 52480

 There is absolutely nothing difficult about this BASIC loader, 
so just type CLEAR 50000:LOAD "" CODE and start the tape to load 
the first block of code. Stop the tape when it's loaded, and load 
in your disassembler into address 32768 (it's a safe one), and 
have a look at the code at CD00.

CD00 3A 5C 5B    LD A,(#5B5C)
CD03 32 00 60    LD (#6000),A

 This takes the byte at #5B5C and puts it in #6000. #5B5C is the 
system variable for the 128K page number, in case you're 
interested.

CD06 3E 02       LD A,#02
CD08 CD 01 16    CALL #1601

 This is a standard ROM routine, and all it does it to tell the 
computer we want to print something on the screen.

CD0B AF          XOR A
CD0C 32 6B 5C    LD (#5C6B),A

 As you may be aware, poking #5C6B (23659 decimal) with 0 will 
cause the computer to crash if you press BREAK or return to 
BASIC. So POKE CD0E,0 which changes it to LD (#006B),A; this is 
harmless.

CD0F CD CE CE    CALL #CECE

 The routine at #CECE prints the message "Searching" on screen.

CD12 10 09       DJNZ #CD1D

 We haven't come across the command DJNZ before. It basically 
means "decrease the value in the B register, and jump if B is not 
zero."

CD14 11 08 FF    LD DE,#FF08
CD17 16 00       LD D,0
CD19 CD 1A CE    CALL #CEA1

This routine prints the number 00 on screen.

CD1C 3E 08       LD A,#08
CD1E 32 15 FF    LD (#FF15),A
CD21 CD 74 CD    CALL #CD74

 This routine loads in a block of code from tape (in actual fact 
the start address is #FE00 and its length is #100 bytes).

CD24 3E 00 FA    LD A,(#FE00)
CD27 FE 64       CP #64
CD29 20 F6       JR NZ,#CD21

 This routine loads A with the value at #FE00. The CP instruction 
compares the value in the A register with something, in this case 
the number #64. If there is no match, the routine jumps back to 
#CD21, otherwise it continues. This routine actually checks to 
see if the block is found.

CD2B 3A 01 FF    LD A,(#FF01)
CD2E BA          CP D
CD2F 28 05       JR Z,#CD36

 This routine checks to see if the block has been loaded 
successfully. If so, it jumps to #CD36, otherwise it continues.

CD31 CD 84 CE    CALL #CE84
CD34 18 EB       JP #CD21

 This routine prints up the "loading error" message, and attemps 
to load the block again.

CD36 CD 30 CE    CALL #CE30

 The routine at #CE30 is a decrypter (have a look - do you see 
why?), which decrypts the block loaded in ie: from #FE00 to FEFF. 
You don't need to crack it yourself.

CD39 BE          CP (HL)
CD3A 28 05       JR Z,#CD41

 This routine reloads the block if the value of A equals the 
value at (HL). Don't ask me why.

CD41 CD 5F CD    CALL #CD5F

 This routine moves the code at #FE00 to where it should really 
be in memory.

CD44 CD 5D CE    CALL #CE5D

 This routine prints the "loading" message on the screen, but 
this should in actual fact be "loaded", because the block has 
just been read in at this point of the code.

CD47 21 04 FF    LD HL,#FF04
CD4A 7E          LD A,(HL)
CD4B 23          INC HL
CD4C 3D          DEC A
CD4D 20 FC       JR NZ,#CD4B
CD4F 23          INC HL
CD50 23          INC HL
CD51 23          INC HL
CD52 23          INC HL
CD53 7E          LD A,(HL)
CD54 2B          DEC HL
CD55 2B          DEC HL
CD56 2B          DEC HL
CD57 E6 07       AND #07
CD59 3C          INC A
CD5A 32 15 FF    LD (#FF15),A
CD5D 14          INC D
CD5E E9          JP (HL)

 This routine starts off with HL as FF04, then does a lot of 
sums, and comes out with a value in the HL register, which it 
jumps to after its loaded the block. This is what we need to 
hack. So POKE CD5E with C9 and RANDOMIZE USR 52480 - you'll find 
out it loads in one block and then stops. However, this isn't 
much use as you can't find out the value of the HL register. So 
put this routine somewhere, such as #5B00.

5B00 CD 00 CD     CALL #CD00
5B03 22 10 5B     LD (#5B10),HL
5B06 C9           RET

 This routine simply loads the first block, and puts the value of 
HL in #5B10 so we can find out what it is from BASIC.
 Now rewind the tape before the first Bleepload block again, and 
RANDOMIZE USR 23296. When that's finished, type PRINT PEEK 
23312+256*PEEK 23313. You should get the answer 65293, which is 
#FF0D. Disassemble this address.

FF0D C3 21 CD    JP #CD21

 This will go back and load the next block from tape. We can 
crack it in the same way as the first be changing our routine at 
5B00.

5B00 CD 00 CD    CALL #CD00
5B03 CD 21 CD    CALL #CD21
5B06 22 10 5B    LD (#5B10),HL
5B09 C9          RET

 Now wind the tape back to the first Bleepload block again, 
RANDOMIZE USR 23296 and start the tape. When the OK message comes 
up, type PRINT PEEK 23312+256*PEEK 23313, and you should get 
65286 which is FF06 hex. Disassemble this address.

FF06 C3 21 CD    JP #CD21

 This goes back and loads another block. By now, you might have 
guessed that the value of HL will always contain the address of a 
JP #CD21 instruction - except for the last block which will jump 
elsewhere. Now we can write a routine which will load any block 
as long as it jumps to #CD21 at the end. I'm putting the routine 
at #CCEC, because it's right next to the loading system, and 
hence is unlikely to be overloaded (although it could be, in 
which case we'd just put the routine elsewhere). The routine goes 
like this.

CCEC CD 00 CD    CALL #CD00

This is just loading the first block

CCEF CD 21 CD    CALL #CD21

This loads in a block from tape.

CCF0 23          INC HL
CCF1 7E          LD A,(HL)
CCF2 2B          DEC HL

 This routine loads the A register with the value of (HL+1). This 
will be #21 if another block is to be loaded.

CCF3 FE 21       CP #21
CCF5 20 02       JR NZ,#CCF8
CCF6 18 F7       JR #CCEF

 This compares the value in the A register to 21. If there is no 
match, then the routine jumps to the end to preserve the value of 
HL, and to return to BASIC. Otherwise, it goes back to load 
another block.

CCF8 22 FE CC    LD (#CCFE),HL
CCFB <breakpoint>
 
 This puts the value of HL in address #CCFE, then returns to 
control of the disassembler.

 Now, run this routine (RANDOMIZE USR 52463), rewind to the first 
Bleepload block, and start loading. The program will now load 
blocks 00-2D, and return to control of the disassembler. The 
value at #CCFE is #FF06, so disassemble this address.


FF06 C3 00 5B    JP #5B00
                 
 Now disassemble #5B00, which is the real meat of the loading 
system!

5B00 DD E5       PUSH IX
5B02 CD 74 CD    CALL #CD74
5B05 CD 30 CE    CALL #CE30
5B08 28 07       JR Z,#5B12
5B0B 06 00       LD B,#00
5B0D CD 84 CE    CALL #CE84
5B10 18 F0       JR #5B02

 This routine loads in another block of code, and will jump to 
5B12 when it has been successfully loaded.

5B12 F3          DI
5B13 E1          POP HL
5B14 2E 00       LD L,#00
5B16 ED 5B E7 FE LD DE,(#FEE7)
5B1A 1A          LD A,(#DE)
5B1B AE          XOR (HL)
5B1C 24          INC H
5B1D AE          XOR (HL)
5B1E 25          DEC H
5B1F 12          LD (#DE),A
5B20 2C          INC L
5B21 IC          INC E
5B22 20 F6       JR NZ,#5B1A

 This routine is a decrypter, which decrypts some of the code we 
just loaded in from tape.

5B24 ED 5B E7 FE LD DE,(#FEE7)
5B26 21 40 5B    LD HL,#5B40
5B2B 1A          LD A,(DE)
5B2C AE          XOR (HL)
5B2D 77          LD (HL),A
5B2E 1C          INC E
5B2F 2C          INC L
5B30 20 F9       JR NZ,#5B2B

 This code decrypts some more code loaded in from tape, but it 
puts it at #5B40, which is right in the middle of the code we are 
working on at the moment. So put a breakpoint at #5B32 (the first 
instruction after the decrypter), and jump to #5B00 (because we 
haven't executed any of the code from #5B00 onwards yet!)

5B32 21 00 00    LD HL,#0000
5B35 22 B0 5C    LD (#5CB0),HL
5B38 2E 02       LD A,#02
5B3A 32 6B 5C    LD (#5C6B),A

 This puts the value #0000 into #5CB0, but I'm not sure why, 
because #5CB0 is an unused system variable. It then changes the 
value of #5C6B to #02, which is what it was originally before it 
was changed to protect the loader.
 
5B3D ED 5B E7 FE LD DE,(#FEE7)
5B41 2A E9 FE    LD HL,(#FEE9)
5B44 1A          LD A,(DE)
5B45 AE          XOR (HL)
5B46 77          LD (HL),A
5B47 23          INC HL
5B48 IC          INC E
5B49 20 F9       JR NZ,#5B44
5B4B 3A EC FE    LA A,(#FEEC)
5B4E BC          CP H
5B4F 20 F3       JR NZ,#5B44

 This is another decrypter, which works in exactly the same way 
as the others.

5B51 31 FF 60    LD SP,#60FF
5B54 21 00 CF    LD HL,#CF00
5B57 11 00 40    LD DE,#4000
5B5A 01 00 1B    LD BC,#1B00
5B5D ED B0       LDIR
5B5F 21 00 EA    LD HL,#EA00
5B62 11 00 61    LD DE,#6100
5B65 01 00 10    LD BC,#1000
5B68 ED B0       LDIR

 This code moves all the decrypted code to where it should be. 
This includes the loading screen (as you can see by the reference 
to #4000.)

5B6A 3E 65       LD A,#65
5B6C 32 00 5B    LD (#5B00),A
5B6F 21 0F 14    LD HL,#140F
5B72 22 01 5B    LD (#5B01),HL
5B75 21 0F 00    LD HL,#004F
5N78 22 03 5B    LD (#5B03),HL
5B7B CD 00 FA    CALL #FA00

 This code loads the next Bleepload block, from 00 to 87, but 
will return to 5B7E when it's finished.

5B7E 21 00 40    LD HL,#4000
5B81 11 01 40    LD DE,#4001
5B84 36 00       LD (HL),0
5B86 01 FF 1A    LD BC,#1AFF
5B89 ED B0       LDIR
5B8B 3E 66       LD A,#66
5B8D 32 00 5B    LD (#5B00),A
5B90 21 0A 0A    LD HL,#0A0A
5B92 22 01 5B    LD (#5B01),HL
5B96 21 0D 0A    LD HL,#0A0D
5B99 22 03 5B    LD (#5B03),HL
5B9C CD 00 FA    CALL #FA00

 This code blanks out the screen and loads some code into it. 
Some Bleepload games do not have this code, and it is only used 
on games whos game code overwrites the loading system at #FA00.

5B9F 21 00 40    LD HL,#4000
5BA2 11 00 FA    LD DE,#FA00
5BA5 01 00 06    LD BC,#0600
5BA8 ED B0       LDIR

 This moves the code loaded from the screen to #FA00 (where it 
should be).

5BAA 3A 00 60    LD A,(#6000)
5BAD 32 5C 5B    LD (#5B5C),A
5BB0 31 A7 61    LD SP,#61A7
5BB3 CD 8E 02    CALL #28E
5BB6 28 1D       JR Z,#5BD5

 This routine restores the value of #5B5C that was stored in 
#6000 right at the very start. It then sets the stack to #61A7, 
and calls the ROM keycheck routine. If no key is pressed (and 
there shouldn't be), the routine jumps to 5BD5. In fact, it must 
jump there, otherwise it would attempt to load a normal 
headerless block, and there are none!

5BD5 C3 BC F5    JP #F5BC

 This is what we've all been waiting for - the JP to the game 
itself. You can simply put POKEs on the end of #5BD5, and follow 
them with a JP #F5BC to load the game. For now, though, it might 
be a good idea to put the NEW routine up to #61A7 there, instead, 
and JP to #5B32 (where we left off). Then load the rest of the 
game, which will reset at the end, enabling you to load in STK, 
Devpac or whatever.

 Now we've gone all the way through Bleepload, perhaps we should 
write a hack for the complete game. However, I'm going to put 
most of the hack in machine code, rather than have long lines of 
decimal DATA statements. You should be able to convert the 
machine code into DATA statements and get a short program which 
reads them in and POKEs them into memory.
 The only thing that has to be done from BASIC is the CLEAR 
50000:LOAD "" CODE 52480 from the BASIC loader. The machine code 
hack will consist of the first routine we wrote, followed by a 
few patches to the main loading system, so that the JP to the 
game is overwritten with our POKEs. I'll be putting it at #CC80, 
because it's a safe place in memory.


CC80 3E C9        LD A,#C9
CC82 32 5E CD     LD (#CD5E),A

 This puts a RET in place of the JP (HL) at #CD5E so we can CALL 
the loading system.

CC85 CD 00 CD     CALL #CD00

This loads in the first Bleepload block.

CC88 CD 21 CD     CALL #CD21

This loads in another Bleepload block.

CC8B 23           INC HL
CC8C 7E           LD A,(HL)
CC8D 2B           DEC HL
CC8E FE 21        CP #21
CC90 20 02        JR NZ,#CC94
CC92 18 F4        JR #CC88

 This checks to see if all the Bleepload blocks have been loaded, 
and jumps ahead if they have, otherwise it jumps back to load the 
next block.

CC94 3E C3       LD A,#C3
CC96 32 32 5B    LD (#5B32),A
CC99 21 A1 CC    LD HL,CCA1
CC9B 22 33 5B    LD (#5B33),HL
CC9E C3 00 5B    JP #5B00

 This puts the instruction JP #CCA1 at #5B32 so the loader 
decrypter will return to our hack at #CCA1 when finished.

CCA1 21 B2 CC    LD HL,#CCB2
CCA4 11 D5 5B    LD DE,#5BD5
CCA7 01 08 00    LD BC,#0008
CCAA ED B0       LDIR

 This copies the final part of our hacking routine to #5BD5, 
where it will be executed once the whole game has been loaded.

CCAC 21 00 00    LD HL,#0000
CCAF C3 35 5B    JP #5B35

 The LD HL,#0000 instruction is important, because it's the 
instruction we overwrote with out JP back to the hack. Therefore, 
we've got to execute it, otherwise the loading system may crash. 
Then it resumes loading at #5B35 with the POKEs firmly in place.

CCB2 3E B6       LD A,#B6
CCB4 32 5F AB    LD (#AB5F),A
CCB7 C3 BC F5    JP #F5BC

 This is the hacking routine which will be copied into the 
loading system. AB5F,B6 is the POKE for infinite lives (which can 
be worked out by a forwards or a backwards trace), and JP #F5BC 
jumps to the game.

 And that's about it for Bleepload! Hopefully, if you were 
hacking a different game, you still managed to do it (they're all 
virtually identical anyway).

ULTIMATE LOADER

 Remember Ultimate? They were one of the finest software houses 
of all time. Most of their games from 1983 to 1987 had the same 
type of loader (but a few were Speedlocked - more about them 
later). On the face of it, it just looks like a totally 
unprotected BASIC loader, but the appearance is deceptive. The 
five blocks it loads are the loading screen, the game itself, a 
decrypter at #5B80, and two very short blocks of system 
variables. The system variables are, in actual fact the BASIC 
clock, and determine how many 50ths of a second the computer has 
been switched on for. The decrypter works using this system 
variable. The upshot of all this is that if you stop the program 
for even 1/50th of a second, you'll mess up the decrypter. You 
can get round this with a Multiface by loading in the first three 
blocks of code, then replacing the code at #5B80 with #F3,#18 and 
#FE. This disables interrupts, so the system variable doesn't get 
updated, and causes an endless loop. Load in the last two blocks, 
activate the Multiface, and find out what the system variable 
should be. Then you can put this into the decrypter 
automatically.

MIKRO-GEN LOADER

 This loading system appeared on just about every game released 
by the software house Mikro-Gen (oddly enough!) from about mid-84 
to their demise in 1987. They come in two varieties, and you'll 
need a Multiface to hack some of the later ones, unfortunately.
 The first type are recognised by black and white loading 
stripes, which loads in a screen block, and then the main game 
block separately. I'll be doing Pyjamarama as an example, but any 
Mikro Gen game which fits the above description will do.

So the first thing to do is to *Hack the BASIC loader.

PYJAMARAMA LINE 0 LEN 504

0 BORDER 7:PAPER 7:INK 0:BRIGHT 0:FLASH 0:CLS:PRINT AT 
12,12;"LOADING":RANDOMIZE USR (PEEK 23627+256*PEEK 23628+6)
20 POKE 23756,0:POKE 23757,0:SAVE "PYJAMARAMA" LINE 0:RANDOMIZE 
USR 33040

 The BASIC loader actually features much more than what we can 
list. If you're old enough to remember the ZX81, you'll recall 
that the best place to put a machine code program is in a REM 
statement. And that's almost the case here, except the machine 
code comes after the ASCII code #0D (newline), so you can't list 
it. But it's there. It's activated by the RANDOMIZE USR command. 
Type PRINT (PEEK 23627+256*PEEK 23628+6) and you'll find out the 
start address of the code. I made it 23984, which is 5DB0 hex 
(but you might find it to be something different), so disassemble 
this address.


5DB0 F3           DI
5DB1 31 00 00     LD SP,#0000
5DB4 2A 4B 5C     LD HL,(#5C4B)
5DB7 11 1C 00     LD DE,#001C
5DBA 19           ADD HL,DE
5DBB 11 16 80     LD DE,8016
5DBE 01 E7 00     LD BC,00E7
5DC1 ED B0        LDIR
5DC3 C3 16 80     JP 8016

 Hopefully the DI and the LD SP,#0000 should be familiar. The 
next line loads HL with the two byte value starting at 5C4B. I 
made it 5DAA. This then has 1C added onto it, making it 5DC6. The 
rest of the code is a simple LDIR command, which puts the loading 
system to where it should be.
 In our hack, we can simply use a headerless loader to load the 
code into place. We know that 5DC6 goes to 8016. BASIC always 
starts at the value in #5C53, which is #5CCB in this case. We 
know that the length is 504, or #1F8 hex bytes long, and the 
start address is (#5CCB-#5DC6)+8016 = #7F1B. So, run the 
following routine.

5B00 DD 21 1B 7F LD IX,#7F1B
5B04 11 F8 01    LD DE,#01F8
5B07 3E FF       LD A,#FF
5B09 37          SCF
5B0A CD 56 05    CALL #0556
5B0D 30 F1       JR NC,#5B00
5B0F C9          RET

 I've put a JR NC,#5B00 in, so that the computer ignores the 
BASIC header, and will only return on loading the main BASIC 
block. You should also note, that in the final hack, we'll have 
to add a DI and a LD SP,#0000 sometime. For now, disassemble 
#8016

8016 DD 21 00 40 LD IX,#4000
801A 11 01 1B    LD DE,#1B01
801D CD 4F 80    CALL #804F

 This code activates the turboloader, which loads in the title 
screen.

8020 21 00 40    LD HL,#4000
8023 01 00 1B    LD BC,#1B00
8026 CD 3F 80    CALL #803F

 This code verifies that the screen has loaded in properly 
(the routine at #803F adds up all the memory with start HL and 
length BC, and compares it with the byte after this block), and 
resets the computer if it hasn't.

8029 DD 21 00 82 LD IX,#8200
802D 11 A0 7A    LD DE,#7AA0
8030 CD 4F 80    CALL #804F
8033 21 00 82    LD HL,#8200
8036 01 9F 7A    LD BC,#7A9F
8039 CD 3F 80    CALL #803F

 This is exactly the same as with the previous code, except it 
loads and checks the main game instead of the loading screen.

803C C3 89 FC    JP #FC89

 Put a breakpoint over this instruction. Now POKE #8012 with F3, 
#8013 with #31, #8014 with #00 and #8015 with #00 (because we 
didn't execute the DI:LD SP,#0000 from the BASIC loader, and the 
game will not load otherwise), JP #8012 and start the tape. When 
the main game's loaded, disassemble #FC89.

FC89 21 EF B4    LD HL,#B4EF
FC8C 11 00 40    LD DE,#4000
FC8F 01 00 1B    LD BC,#1B00
FC92 1A          LD A,(DE)
FC93 AE          XOR (HL)
FC94 77          LD (HL),A
FC95 23          INC HL
FC96 13          INC DE
FC97 0B          DEC BC
FC98 78          LD A,B
FC99 B1          OR C
FC9A 20 F6       JR NZ,#FC92
FC9C C3 EA BE    JP #BEEA

 This decrypter uses values in the screen memory, so you'll have 
to put a breakpoint at FC9C, put a JP #FC89 at #8029, JP to #8012 
and reload the loading screen before you can run it. Then 
disassemble #BEEA.

BEEA 31 00 00    LD SP,#0000
BEED CD CC BE    CALL #BECC
BEF0 C3 00 82    JP #8200

 This code puts the stack pointer back at #0000, CALLs another 
decrypter, and JPs to #8200, which is the start of the game. 
Change the #8200 to a suitable place to put POKEs; finish them 
with a JP #8200 to start the game.

 Here's the final hack, and I've put it at #5B00, because it 
doesn't get overloaded, apart from the byte at #5B00 itself, 
which is no longer needed by that time. Also, I've executed the 
DI:LD SP,#0000 directly, as well as the code from BEEA to BEF2.

5B00 DD 21 1B 7F LD IX,#7F1B
5B04 11 F8 01    LD DE,#01F8
5B07 3E FF       LD A,#FF
5B09 37          SCF
5B0A CD 56 05    CALL #0556
5B0D 30 F1       JR NC,#5B00
5B0F 21 1C 5B    LD HL,#5B1C
5B12 22 3D 80    LD (#803D),HL
5B15 F3          DI
5B16 31 00 00    LD SP,#0000
5B19 C3 16 80    JP #8016
5B1C 21 25 5B    LD HL,#5B25
5B1F 22 9D FC    LD (#FC9D),HL
5B22 C3 89 FC    JP #FC89
5B25 31 00 00    LD SP,#0000
5B28 CD CC BE    CALL #BECC
5B2B AF          XOR A
5B2C 32 ?? ??    LD (????),A
5B2F C3 00 82    JP #8200

 The other type of Mikro Gen loader is almost identical, except 
the whole game loads in one long block. Then end of the BASIC 
loading system is missing to start with, and is only loaded right 
at the end of the main headerless block. You can find out the 
missing code by loading the game as normal, then stopping it with 
a Multiface in the pause between the game loading, and the game 
starting (approx. 3 seconds), and hack it in the same way as 
Pyjamarama.

POWERLOAD

 This protection system appeared first around the start of 1984, 
and was written by "Tag" (Phil Taglione) for Incentive Software. 
However, it's been used by quite a lot of other software 
companies as well, including Beyond, Mirrorsoft, Prism and 
Ariolasoft. It can be recognised by the screen turning black, 
accompnied by a few ascending beeps. It then loads one short 
headerless block, and then a longer headerless block, which 
includes the attribute file for the game coming up "backwards" 
ie: right to left, starting from the bottom. The game also stops 
loading just before the end of the long headerless block.
 The only thing I know of that YS have put on the covertape that 
has Powerload is the Graphic Adventure Creator, but that's 
pointless hacking, so instead I'll be hacking Dynamite Dan. Of 
course, most other Powerload games are identical apart from some 
addresses, and, in fact, the BASIC loaders are all identical. 

 Before we start, I need to explain a little more about the 
stack, because Powerload uses it a lot. There are four commands 
which use the stack, and they are:

PUSH X (where X is any register) - this takes the value in a 
register, and puts it onto the stack. The stack pointer then 
decreases by two (to be in the right place to store another 
value).

POP X - this takes the two byte value at the stack pointer (ie: 
the top of the stack), and puts them in a register. This also 
increases the stack pointer by two.

CALL XXXX - when you CALL a subroutine, the return address (ie: 
the address after the call) is PUSHed onto the stack, and the 
subroutine is JPed to. The stack pointer also decreases by two.

RET - when a RET instruction occurs, the computer takes the value 
on the top of the stack, and JPs to it. The stack pointer 
increases by two.

 Now we've cleared that up, let's start hacking. *Hack the BASIC 
as usual.

D.D. LINE 0 LEN 496

0 REM
10 CLEAR 59999:POKE 23693,0:POKE 23624,0:POKE 23697,0:CLS:POKE 
23659,0:FOR N=30 TO 36:BEEP .075,N:NEXT N:RANDOMIZE USR 
24146:RANDOMIZE USR 0
100 REM

 The POKEs in line 10 just make the screen black and prevent you 
from pressing break. 24146 is #5E52 hex; but a breakpoint at 
#5E52 and GOTO 0. This is because the stack is set up in a 
specific way by the BASIC commands.

5E52 F3          DI
5E53 21 00 00    LD HL,#0000
5E56 39          ADD HL,SP
5E57 22 F2 5D    LD (#5DF2),HL

 This code simply puts the value of the stack pointer into 
address #5DF2, so it can be retreived later. 

5E5A 31 95 5E    LD SP,#5E95
5E5D 26 5E       LD H,#5E
5E5F E5          PUSH HL
5E60 21 68 5E    LD HL,#5E68
5E63 E9          JP (HL)

5E68 3E 12       LD A,#12
5E6A 32 93 53    LD (#5E93),A
5E6D E1          POP HL
5E6E E5          PUSH HL
5E6F D1          POP DE
5E70 C9          RET

 Put a breakpoint at 5E70 and JP to 5E52. At 5E70, the value on 
the top of the stack is #5E76, so a RET will JP to there.

5E76 C1          POP BC
5E77 7E          LD A,(HL)
5E78 ED 44       NEG
5E7A 77          LD (HL),A
5E7B 23          INC HL
5E7C 10 F9       DJNZ #5E77

 This code is, as you might realise, a decrypter. The start value 
of HL is #5E12, and the initial value of B is #3A. In case you're 
interested, the NEG instruction turns the value in the A register 
into its negative form; in other words, the value in A is 
subtracted from #100 hex. Put a breakpoint at #5E7E and JP #5E70 
(which is where we left off).

5E7E E1          POP HL
5E7F 22 78 5E    LD (#5E78),HL
5E82 C1          POP BC
5E83 3E C9       LD A,#C9
5E85 32 7E 5E    LD (#5E7E),A
5E88 3E 00       LD A,#00
5E8A 32 7A 5E    LD (#5E7A),A
5E8D 5D          PUSH DE
5E8E E1          POP HL
5E8F C9          RET

 This code changes the previous decrypter slightly, and RETs to 
5E77. Put a breakpoint at 5E8F and JP #5E7E.

5E77 7E          LD A,(HL)
5E78 ED 67       RRD
5E7A 00          NOP
5E7B 23          INC HL
5E7C 10 F9       DJNZ,#5E77
5E7E C9          RET

 This code works with the same values as the previous one; 
HL=5E12 and B=3A. It then RETs to 5E12. Put a breakpoint at 
#5E7E, and JP #5E8F (where we left off last time).

5E12 21 B4 5F    LD HL,#5FB4
5E15 11 B5 5F    LD DE,#5FB5
5E18 01 B8 88    LD BC,#88B8
5E1B ED B0       LDIR
5E1D E1          POP HL
5E1E 54          LD D,H
5E1F 5D          LD E,L
5E20 1C          INC E
5E21 C1          POP BC
5E22 ED B0       LDIR

 These two LDIR commands wipe all the memory that isn't being 
used by the loading system. To get round this, you should change 
#5E1B, #5E1C, #5E22 and #5E23 to #00, to stop them being 
executed. Put a breakpoint at #5E24 and JP #5E7E (where we left 
off).

5E24 06 1E       LD B,#1E
5E26 E1          POP HL
5E27 7E          LD A,(HL)
5E28 EE A3       XOR #A3
5E2A 77          LD (HL),A
5E2B 23          INC HL
5E2C 10 F9       DJNZ,5E27

 The value in HL for this decrypter is #5E2E, which is right 
after the decrypter. To crack it, therefore, move the code from 
#5E24 to #5E2D somewhere safe (such as #5B00), put a breakpoint 
on the end, and run the code from there. When that's done, put a 
breakpoint at #5E2E and JP to #5E2E (so that you're back in the 
right place in the loading system).
 Carrying on with the loader....

5E2E E1          POP HL
5E2F 22 02 5E    LD (#5E02),HL
5E32 E1          POP HL
5E33 22 05 5E    LD (#5E05),HL
5E36 37          SCF
5E37 3E 07       LD A,#07
5E39 CD 00 5E    CALL #5E00

 This code takes some values off the stack, and puts them into 
the subroutine at #5E00, which is then CALLed. Put a breakpoint 
at #5E39 and JP to #5E2E.

5E00 DD 21 40 9C LD IX,#9C40
5E04 11 90 1     LD DE,#190
5E07 14          INC D
5E08 08          EX AF,AF'
5E09 15          DEC D
5E0A 3E 0F       LD A,#0F
5E0C DB FE       OUT (#FE),A
5E0E CD 62 05    CALL #0562
5E11 C9          RET

 This routine is a headerless loader. The start is #9C40 and the 
length is #190. Also the value of A is 7, and the carry flag has 
been set. In effect, we could have used a standard CALL #0556 
headerless loader. Put a breakpoint at #5E3C and JP to #5E39. 
Start the tape and load in the first short headerless block. Then 
continue disassembling.

5E3C D2 01 00    JP NC,#0001

 This code resets the computer if there was a loading error from 
the first headerless block.

5E3F 21 40 9C    LD HL,#9C40
5E42 06 FF       LD B,#FF
5E44 CD 77 5E    CALL #5E77
5E47 06 FF       LD B,#FF
5E49 CD 77 5E    CALL #5E77
5E4C F3          DI
5E4D C9          RET

 This code decrypts the headerless file we have just loaded in. 
The decrypter is CALLed to, and it's the same one we had before 
(with the RRD). So, in actual fact, we can forget about the BASIC 
loader; just load in the headerless file normally and run our own 
decrypter. For now, just put a breakpoint at #5E4D and JP to 
#5E3F. The RET is to #9C40

9C40 21 52 9C    LD HL,#9C52
9C43 01 90 01    LD BC,#0190
9C46 16 A5       LD D,#A5
9C48 7E          LD A,(HL)
9C49 AA          XOR D
9C4A 77          LD (HL),A
9C4B 23          INC HL
9C4C 0B          DEC BC
9C4D 78          LD A,B
9C4E B1          OR C
9C4F C2 48 9C    JP NZ,9C48

 This is a decrypter, and you can crack it in one of two ways. 
Firstly, you can copy if to somewhere else, put a breakpoint on 
the end, and run it from there, or you can replace the JP NZ,9C48 
with JR NZ,9C48. Both do the same thing, but the JR NZ only uses 
two bytes. This means we can put a RET at #9C51 and CALL the 
decrypter. So change #9C4F to #20, #9C50 to #F7 and #9C51 to #C9, 
then put a CALL #9C40 and a breakpoint somewhere convenient (such 
as #5B00) and run the decrypter from there. When decrypted, the 
code continues at #9C52.

9C52 21 63 9C    LD HL,#9C63
9C55 11 45 FE    LD DE,#FE45
9C58 01 90 01    LD BC,#0190
9C5B ED B0       LDIR
9C5D 31 84 FD    LD SP,#FD84
9C60 C3 45 FE    JP #FE45

 This moves the code we've just decrypted to #FE45, sets the 
stack pointer to #FD84, and JPs to #FE45. Put a breakpoint at 
#9C60 and JP to #9C52.

Now at #FE45, we come to the actual loading system itself.

FE45 3E 84       LD A,#84
FE47 11 00 18    LD DE,#1800
FE4A DD 21 00 40 LD IX,#4000
FE4E CD AB FE    CALL #FEAB

 This code loads in a headerless file with start #4000 and length 
#1800 (which is the display file for the screen). Nothing too 
unusual about that.....

FE51 11 00 04    LD DE,#0400
FE54 DD 21 FF 5B LD IX,#5BFF
FE58 CD 2A FF    CALL #FF2A

....except that as soon as it's done that,it loads in a block 
with start #5BFF and length #0400 straight away. This block is 
"sandwiched" right next to the other block on the tape. This 
particular block loads "backwards".

FE5B 11 E1 01    LD DE,#01E1
FE5E DD 21 1F FE LD IX,#FE1F
FE62 CD FA FA    CALL #FEFA

 And here's another block of the same kind, except it's loaded 
forwards this time. What's worse is that it's going to overwrite 
the code we're looking at now, so it must be a "modification" to 
the loading system (similar to the Mikro-Gen loader). To get 
round this, we would have to copy the code somewhere else, stick 
a breakpoint on the end, and run it from there. But remember that 
the loading system was copied from address #9C63, so there is, in 
actual fact, a copy of the code anyway. You want to put a 
breakpoint at #9C83 (the instruction after loading these three 
blocks), and JP to #9C63. Then start the tape and load in the 
next headerless block. The loading screen will appear, and the 
game will load for about four seconds, then control will return 
to the disassembler. Now look at the code at #FE65.

FE65 11 1D 9F    LD DE,#9F1D
FE68 DD 21 1C FA LD IX,#FA1C
FE6C CD 2A FF    CALL #FF2A

 This code loads the main game backwards. This will overwrite 
your disassembler, so you will have to put the NEW routine at 
#FE6F (but write down all the bytes you are replacing, because 
you'll need to restore all the original code later). Then you 
will have to go back and load the first block, because there 
isn't a header for the main game block. Change #FE4D to #01, 
#FE57 to #10 and #FE61 to #01 - this will make the computer try 
to load the three blocks into the ROM. Then rewind the tape back 
to the start of this headerless block, JP #FE45, and start the 
tape. Upond loading the whole block, the computer will reset. 
Load in your disassembler, and replace the code from the NEW 
routine to the values they should be. Now you can tackle the 
final part of the loading system.

FE6F 11 E4 12    LD DE,#12E4
FE72 DD 21 FF FF LD IX,#FFFF
FE76 C3 70 FF    JP #FF70

FF70 3E 00       LD A,0
FF72 D3 FE       OUT (#FE),A
FF74 CD 1F FE    CALL #FE1F
FF77 21 43 FE    LD HL,#FE43
FF7A BE          CP (HL)
FF7B CA 89 FF    JP Z,#FF89
FF7E 21 48 EE    LD HL,#EE48
FF81 01 FF FF    LD BC,#FFFF
FF84 11 49 EE    LD DE,#EE49
FF87 ED B0       LDIR

 The routine at #FE1F adds up all the memory in the screen to get 
a value in the D register. This is then compared with the value 
of the byte at #FE43. If there is no match, all the memory is 
blanked out, so the value in the D register must be the same as 
the byte at #FE43. You should find that the byte is #E6. You need 
to know this for later on.

FF89 21 A3 FF    LD HL,#FFA3
FF8C 01 45 00    LD BC,#0045
FF8F 7A          LD A,D
FF90 AE          XOR (HL)
FF92 23          INC HL
FF93 0B          DEC BC
FF94 78          LD A,B
FF95 B1          OR C
FF96 C2 8F FF    JP NZ,#FF8F

 This is all we can disassemble for the moment, because the code 
from #FF89 to #FF98 decrypts the final part of the loader. Change 
the byte at #FF87 to #16, and the byte at #FF88 to #E6 (this is 
LD D,#E6, which is used in the decrypter), put a breakpoint at 
#FF99, and JP to #FF87. Then continue the disassembly.

FF99 CD 31 FE    CALL #FE31
FF9C 21 44 FE    LD HL,#FE44
FF9F BE          CP (HL)
FFA0 C2 7E FF    JP NZ,#FF7E

 This code checks the main game, coming out with a result in the 
E register. However, this value is never used, so you can ignore 
this whole routine.
 Following on.....

FFA3 21 C0 5D    LD HL,#5DC0
FFA6 01 30 75    LD BC,#7530
FFA9 CD D4 FF    CALL #FFD4
FFAC 21 C0 5D    LD HL,#5DC0
FFAF 01 30 75    LD BC,#7530
FFB2 CD DE FF    CALL #FFDE
FFB5 21 1C FA    LD HL,#FA1C
FFB8 11 1C FF    LD DE,#FF1C
FFBB 01 1D 9F    LD BC,#9F1D
FFBE ED B8       LDIR
FFC0 21 10 A7    LD HL,#A710
FFC3 22 36 5C    LD (#5C36),HL
FFC6 01 10 DF    LD BC,#DF10
FFC9 AF          XOR A
FFCA ED 42       SBC HL,BC
FFCC 31 FF FF    LD SP,FFFF
FFCF ED 56       IM1
FFD1 C3 6F 00    JP #006F

006F E9          JP (HL)

 This routine runs the game decrypters, moves the game into the 
right place, sets the stack and the interrupts, and puts the 
start address for the game in the HL register. Change the #006F 
at #FFD2 to somewhere where you can put a NEW routine (such as 
#5B00), because the disassembler will be overwritten. Then, 
change the value at #FFA1 to 16, and the value at #FFA2 to #E6 
(because one decrypter uses the value in the D register), and JP 
to #FFA2. When that's done, you can reload your disassembler, and 
hack the game using a forwards and backwards trace (but you won't 
be able to run the code because some of it's missing!)

 Now we'll write a complete hack for the game. You have to be a 
bit careful about where you put your hack in memory, because a 
lot of memory is overloaded. The first free address we can put 
the code at is #FA1D.

FA1D DD 21 40 9C LD IX,#9C40
FA21 11 90 01    LD DE,#0190
FA24 3E 07       LD A,#07
FA26 37          SCF
FA27 CD 56 05    CALL #0556
FA2A 30 F1       JR NC,#FA1D

 This loads in the first headerless block using the values set up 
in the BASIC loader.

FA2C 06 FF       LD B,#FF
FA2E 21 40 9C    LD HL,#9C40
FA31 7E          LD A,(HL)
FA32 ED 67       RRD
FA34 23          INC HL
FA35 10 FA       DJNZ #FA31
FA37 06 FF       LD B,#FF
FA39 7E          LD A,(HL)
FA3A ED 67       RRD
FA3C 23          INC HL
FA3D 10 FA       DJNZ, #FA39

This decrypts the headerless block.

FA3F 21 20 F7    LD HL,#F720
FA42 22 4F 9C    LD (#9C4F),HL
FA45 3E C9       LD A,#C9
FA46 32 51 9C    LD (#9C51),A
FA49 CD 40 9C    CALL #9C40

 This changes the JP NZ at #9C4F to a JR NZ and a RET, then calls 
the decrypter.

FA4C 3E C3       LD A,#C3
FA4E 32 83 9C    LD (#9C83),A
FA51 21 5A FA    LD HL,#FA5A
FA54 22 84 9C    LD (#9C84),HL
FA57 C3 63 9C    JP #9C63

 This puts a JP back to our hack at #9C83, and jumps to #9C63 to 
load the first part of the headerless block.

FA5A 3E C9       LD A,#C9
FA5C 32 6F FE    LD (#FE6F),A
FA5F CD 65 FE    CALL #FE65

 This puts a RET after the code to load the rest of the game, 
then CALLs that loading procedure.


FA62 21 E6 16    LD HL,#16E6
FA65 22 87 FF    LD (#FF87),HL
FA68 3E C9       LD A,#C9
FA6A 32 99 FF    LD (#FF99),A
FA6D CD 87 FF    CALL #FF87

 This patches in the LD D,#E6, puts a RET at the end of the 
decrypter, and CALLs it.

FA70 21 7E FA    LD HL,#FA7E
FA73 11 00 40    LD DE,#4000
FA76 01 20 00    LD BC,#0020
FA79 ED B0       LDIR
FA7B C3 00 40    JP #4000

 This code moves our hack into the screen memory (so it isn't 
affected by the LDIR which overwrites it in the next bit of 
code), and jumps to it there.

FA7E 21 0B 40    LD HL,#400B
FA81 22 D2 FF    LD (#FFD2),HL
FA84 16 E6       LD D,#E6
FA86 C3 A3 FF    JP #FFA3

 This code replaces the JP #006F with a JP back to our hack 
(which is in the screen memory by this time), and JPs to #FFA3. 
We have to include the LD D,#E6 again, because the value of DE 
was corrupted by the LDIR.

FA89 AF          XOR A
FA8A 32 C6 CD    LD (#CDC6),A
FA8D E9          JP (HL)

 This sets the infinite lives POKE, and does a JP (HL) to start 
the game.

 Phew! I hope you managed to get all that, because it's really 
hard to do without a Multiface. If you can do it, then you've 
definitely got the hang of things, so keep it up!

SEARCH LOADER

 This loading system appears on every game ever written by Steve 
Marsden (who wrote the original loading system), as well as a few 
others. You can recognise them by their fancy front end, which 
consists of a countdown timer, accompnied by animated graphics 
and/or instructions, which appear as the game loads. The only 
game I've actually got at the moment that's got a Search Loader 
on it is Technician Ted, so I'm going to have to hack that.

 So, *Hack the BASIC loader, and let's see what it's got to 
offer....

Chip Fact LINE 0 LEN 736

0 RANDOMIZE USR 24341

 The rest of the BASIC is a load of garbage which consists of the 
machine code for the game. It is stored in a similar way to that 
in the Mikro Gen loader. 24341 is 5F15 hex, so disassemble this 
address.

5F15 F3          DI
5F16 21 00 40    LD HL,#4000
5F19 11 01 40    LD DE,#4001
5F1C 01 FF 17    LD BC,#17FF
5F1F 36 00       LD (HL),0
5F21 ED B0       LDIR

This code blanks out the screen.

5F23 CD 32 5E    CALL #5E32

 The routine at #5E32 sets up the attributes for the screen ie: 
red banners at the top and bottom, black background with varying 
ink colours in the middle.

5F26 C3 38 5F    JP #5F38

5F38 21 AB 5F    LD HL,#5FAB
5F3B 01 59 A0    LD BC,#A059
5F3E 31 00 5C    LD SP,#5C00
5F41 3A A8 5F    LD A,(#5FA8)
5F44 57          LD D,A
5F45 1E 0B       LD E,#0B
5F47 7A          LD A,D
5F48 87          ADD A,A
5F49 87          ADD A,A
5F4A 87          ADD A,A
5F4B 87          ADD A,A
5F4C 82          ADD A,D
5F4D 83          ADD A,E
5F4E 57          LD D,A
5F4F 77          LD (HL),A
5F50 23          INC HL
5F51 0B          DEC BC
5F52 78          LD A,B
5F53 B1          OR C
5F54 20 F1       JR NZ,#5F47

 This routine fills all of the memory above #5FAB with 
unexecutable code. It is, however, extremely important code, as 
we shall see later on.

5F56 CD 93 5F    CALL #5F93

 This routine at #5F93 just messes around with the garbage a bit 
more.

5F59 CD 80 5D    CALL #5D80

 The routine at #5D80 scrolls in the title messages for the game, 
accompnied by annoying clicks.

5F5C 3A 66 80    LD A,(#8066)
5F5F 6F          LD L,A
5F60 3A E6 60    LD A,(#60E6)
5F63 67          LD H,A
5F64 E5          PUSH HL
5F65 3A 4F FC    LD A,(#FC4F)
5F68 5F          LE E,A
5F69 3A 0F 60    LD A,(#600F)
5F6C 57          LD D,A
5F6D DD E1       POP IX
5F6F 37          SCF
5F70 3E FF       LD A,#FF
5F72 14          INC D
5F73 08          EX AF,AF'
5F74 15          DEC D
5F75 3A 66 63    LD A,(#6366)
5F78 6F          LD L,A
5F79 3A E6 63    LD A,(#63E6)
5F7C 67          LD H,A
5F7D E5          PUSH HL
5F7E DB FE       OUT (#FE),A
5F80 1F          RRA
5F81 E6 20       AND #20
5F83 F6 01       OR #01
5F85 4F          LD C,A
5F86 BF          CP A
5F87 F5          PUSH AF
5F88 3A 87 65    LD A,(#6587)
5F8B 6F          LD L,A
5F8C 3A 85 64    LD A,(#6485)
5F8F 67          LD H,A
5F90 F1          POP AF
5F91 E5          PUSH HL
5F92 C9          RET

 This code takes values out of the garbage and puts them in 
certain registers. It then imitates the start of the ROM loading 
routine, and puts some values on the stack. At #5F92, the values 
of the registers are: Hl= #056B, DE=#03C3, IX=#8000, and the 
values on the stack are first #056B, then #8000. So, this code 
will load a headerless file with start #8000 and length #0363, 
then will JP straight to #8000. We can do away with the BASIC 
loader altogether in the final hack by mimicing the headerless 
loader. This is done using the following program.

5B00 F3          DI
5B01 31 00 5C    LD SP,#5C00
5B04 DD 21 00 80 LD IX,#8000
5B08 11 C3 03    LD DE,#03C3
5B0B 3E FF       LD A,#FF
5B0D 37          SCF
5B0E 14          INC D
5B0F 08          EX AF,AF'
5B10 15          DEC D
5B11 AF          XOR A
5B12 DB FE       OUT (#FE),A
5B14 1F          RRA
5B15 E6 20       AND #20
5B17 F6 01       OR #01
5B19 4F          LD C,A
5B1A CD 6B 05    CALL #056B
5B1D <breakpoint>

 This routine is slightly different than the one in the loader 
for two reasons. Firstly, I've put values into the registers 
directly, rather than have their values taken from bytes in 
memory. Secondly, you aren't allowed by law to rip off someone 
else's code; if you directly copied a loading system into a hack, 
you could be sued. In fact, someone was, once! You're probably 
alright copying a five byte decrypter from Powerload across, 
because there really isn't any other code which can do the job in 
the same way. In general, I would say don't copy code into your 
hack unless you have to. If you do, change it if you can so it 
does the same job in a different way. Copying 40 bytes of code 
directly out of a loading system is definitely out, and most 
magazines wouldn't print the routine anyway.
 There are a few commands we haven't met in the routine. EX AF', 
AF' concerns the swapping of registers. In the Z80, in actual 
fact, there are two different sets of each register, although 
only one set can ever be used at once. Think of it like a TV set, 
although both registers (A and A' in this case) are there, you 
can only see one at a time. EX AF,AF' exchanges both the A 
register and the contents of the flags. Don't worry any more 
about swapping registers for now.
 RRA rotates all the bits in the A register to the right. 
Actually, it doesn't quite do this, but we don't need to know 
about it.
 If you're not using a Multiface, the garbage routine will have 
overwritten the disassembler, so reload it in anywhere below 
#8000. Then run the routine and restart the tape from where you 
left off. A small part of the headerless block will load in, and 
control will return to the disassembler. Have a look at address 
#8000.

8000 D2 00 00    JP NC,#0000

 This resets the computer if the previous headerless block didn't 
load properly.

8003 3E 08       LD A,#08
8005 D3 FE       OUT (#FE),A

 This makes the border black, and sends a signal to the cassette 
recorder.

8007 D9          EXX

 EXX is a "general exchange" instruction, and changes the 
registers B,C,D,E,H and L for their alternate sets.

800E 0E 00       LD C,#00
800A D9          EXX
800B 26 00       LD H,#00
800D 06 80       LD B,#80
800F DD 21 1C 8C LD IX,#8C1C
8013 16 05       LD D,#05
8015 CD 41 83    CALL #8341
8018 D2 00 00    JP NC,#0000
801B 06 B1       LD B,#B1
801D 15          DEC D
801E 20 F5       JR NZ,#8015

 This code loads in five bytes of tape (the routine at #8341 
loads in information off tape into the address pointed to by the 
IX register), starting at #8C1C. Therefore, this tape routine 
will start loading code at #8C1C.

8020 11 D8 72    LD DE,#72D8
8023 D9          EXX
8024 0C          INC C
8025 D9          EXX
8026 C3 7D 83    JP #837D

837D 2E 01       LD L,#01
837F CD 41 83    CALL #8341
8382 D2 00 00    JP NC,#0000
8385 3E CB       LD A,#CB
8387 B8          CP B
8388 17          RLA
8389 D9          EXX
838A 47          LD B,A
838B E6 01       AND #01
838D 3D          INC A
838F 11 6B 80    LD DE,#806B
8392 1A          LD A,(DE)
8393 A7          AND A
8394 C4 77 82    CALL NZ,#8277

 This loads in a set number of bytes from tape, and then prints 
some sprites on screen (the routine at #8277). This produces all 
the men walking forwards and backwards while the game loads.

8397 CB 18       RRB
8399 D9          EXX
839A CB 15       RL L
839C 06 B1       LD B,#B1
839E 30 DF       JR NC,#837F
83A0 7C          LD A,H
83A1 AD          XOR L
83A2 67          LD H,A
83A3 7A          LD A,D
83A4 B3          OR E
83A5 20 CE       JR NZ,#8375

 This updates the computer ready to do the next loading and 
animation sequence.

83A7 7C          LD A,H
83A8 A7          AND A
83A9 C2 00 00    JP NZ,#0000
83AC 11 2F EC    LD DE,#EC2F
83AF 06 EB       LD B,#EB
83B1 CD 41 83    CALL #8431
83B4 D2 00 00    JP NC,#0000
83B7 3E EA       LD A,#EA
83B9 B8          CO #0B
83BA D2 00 00    JP NC,#0000
83BD 42          LD B,D
83BE 15          DEC D
83BF 1D          DEC E
83C0 C2 B1 83    JP NZ,#83B1

 This loads in some more bytes from tape. When these have 
finished, the computer will continue execution at address #83C3. 
The code beyond this address does nothing except fiddle about 
with registers, so there might as well be nothing there. The 
first bit of useful code will appear at #8C1C, but this hasn't 
been loaded yet. Instead, put a breakpoint at #83C3, move the 
headerless loading routine so the CALL #056B is at #7FFD, and run 
the code from there. Rewind the tape a bit and reload in all of 
the main headerless block. When finished, you'll find the 
following code at #8C1C.

8C1C 3E 5C       LD A,#5C
8C1E 21 00 40    LD HL,#4000
8C21 54          LD D,H
8C22 5D          LD E,L
8C23 EB          EX DE,HL
8C24 4E          LD C,(HL)
8C25 23          INC HL
8C26 46          LD B,(HL)
8C27 23          INC HL
8C28 EB          EX DE,HL
8C29 09          ADD HL,BC
8C2A BA          CP D
8C2B 20 F6       JR NZ,8C23
8C2D 11 92 5C    LD DE,#5C92
8C30 EE 5C       XOR 5C
8C32 28 EF       JR Z,#8C23
8C34 E5          PUSH HL

 This routine adds up every single byte in memory to get a value 
in HL, which is pushed onto the stack. This value is important, 
because it is used in decrypting. This is what the garbage was 
all used for - to get the right value. It's impossible to 
calculate it yourself, because any programs you right will mean 
you get the wrong answer. The only way I can think of to get this 
value is to load the game as normal, and stop the game with a 
Multiface as soon as the timer hits 000. Then put a breakpoint at 
#8C35 and return. Wait a few seconds, then reactivate the 
Multiface and have a look at the stack. The first value will be 
#8C35, the second will be the value of HL you want. You should 
find it's #4DBD.
 Carrying on the disassembly....

8C35 21 00 58    LD HL,#5800
8C38 11 01 58    LD DE,#5801
8C3B 01 FF 02    LD BC,#02FF
8C3E 36 00       LD (HL),#00
8C40 ED B0       LDIR
8C42 E1          POP HL

 This clears the screen and restores the value of HL, which is 
used for the following decrypter.

8C43 11 60 8C    LD DE,#8C60
8C46 0E 29       LD C,#29
8C48 7C          LD A,H
8C49 65          LD H,L
8C4A 47          LD B,A
8C4B 09          ADD HL,BC
8C4C 1A          LD A,(DE)
8C4D AD          XOR L
8C4E 12          LD (DE),A
8C4F 6F          LD L,A
8C50 13          INC DE
8C51 1A          LD A,(DE)
8C52 AC          XOR H
8C53 12          LD (DE),A
8C54 13          INC DE
8C55 CB 7A       BIT 7,D
8C57 20 F0       JR NZ,#8C49
8C59 FB          EI
8C5A 67          LD H,A
8C5B 11 70 71    LD DE,#7170
8C5E 19          ADD HL,DE
8C5F E9          JP (HL)

 First of all, POKE #8C40, #8C41 and #8C42 with #21, #BD and #4D 
respectively (so you get the right value of HL), put a breakpoint 
at #8C5B (nearest place possible to the JP (HL) that we can place 
a breakpoint), and JP #8C40. On return, the value of HL is #38F5. 
Add this to #7170 (which is what happens in the next two 
commands) to get #AA65. This is the start address of the game. So 
put a JP to your POKEing routine (anywhere from #5B00 to #5BA0 is 
fine) at #8C5B, and finish your POKEs with a JP #AA65.
 You will have to do a stack trace to find infinite lives in the 
actual game itself. There is a complete hack for this game by 
myself in YS #78, so why not disassemble it and have a look. It's 
slightly different to what we've done in that it intercepts the 
RET at the end of the loading system rather than mimic the first 
headerless loader, and puts a JP back to the hack at #83C3, but 
apart from that, it's more or less everything we'e discussed 
above put together.

PAUL OWEN'S PROTECTION SYSTEM

 This has been used on a few Ocean games, but is in fact a 
standard headerless loader in disguise. The value of A to use is 
always #98. Load in the BASIC loader and the first block of code, 
then stop it with a Multiface, and use a stack trace to find out 
the values of IX and DE for each block, and the JP to the game.

SPEEDLOCK

 Concluding the look at protection systems, I think it's only 
fitting that we end in quite possible the most famous protection 
system of all time.
 Speedlock was first written by two guys called David Looker and 
David Aubery Jones around late 1983, although it wasn't 
commercially used until October 1984, on Daley Thompson's 
Decathlon, by which time it had reached it's third version. Since 
then, it has been used by many major sofware companies, 
especially Ocean. Its also gone many modifications, and can be 
split into three distinct generations.
 I should state at this point that you need to have a Multiface 
to crack most of these Speedlocks, because they completely 
disrupt the operating system which will lock up any disassembler 
which relies on ROM routines. The Multiface relies on its own 
ROM, which isn't affected by the Speedlock code.

Type 1 - have one or two BASIC loaders, and load the main code 
with the infamous "clicking" leader tones (you know, instead of a 
steady "bleep", they go "blip, blip, blip, blip" a few times).

Type 2 - have one short BASIC loader, a long CODE block, lots of 
annoying beeps, then a similar loader to Type 1, minus the 
clicking leader tones, plus a countdown timer.

Type 3 - as for Type 2, except there is just one very long BASIC 
loader. The protection system crashes if a Multiface is left 
switched on. Mazemania on YS #77 covertape used a Type 3.

 So, let's start at the very beginning (a very good place to 
start) with Type 1. In fact, there are about four different 
difficulty levels of Type 1 Speedlocks; the difficulty goes in 
chronological order (as you might expect).

 The very first Type Ones were completely different to later 
ones, having the same initialisation routine, but a completely 
standard decrypter. The only differences between this Speedlock 
and an ordinary decrypting loader were its initialisation routine 
and its use of the IY register.

 We came across index registers when we first met headerless 
loaders. There are, in fact, two index registers, IX and IY. In 
BASIC, the IX register is free for use in a machine code program 
run from a USR command, but the IY register must always contain 
the value #5C3A, which is the base address of the BASIC system 
variables which are wiped with a NEW command. If you return to 
BASIC with the value of IY anything other than #5C3A, the 
computer will crash, even if you use the "exit to BASIC" feature 
on a Multiface. The value of IY must also be #5C3A whenever a 
BASIC interrupt occurs. Both Devpac and 007 Disassembler run 
under the BASIC interrupts. They also use built in ROM routines, 
such as those to check the keyboard and print text; this is 
preferable, otherwise they'd have to waste memory rewriting their 
own versions of the routines. Hence the value of IY must always 
equal #5C3A.
 The only safe way of using the IY register is to disable 
interrupts and write the whole program in RAM without using any 
built in ROM routines. And Speedlock fits this bill exactly, so 
it uses the IY register for most of its decrypter calculations.
 Speedlock code also uses a lot of undocumented instructions. In 
theory, you cannot split the sixteen bit IY register into two 
eight bit registers. But the processor doesn't understand this, 
and you can split the IY register into two if you want. You 
simply put the code #FD on the front of any instructions using H 
or L. There are no standard names for the two halves of the IY 
register, but I will refer to them as IYH (Hi part of IY) and IYL 
(Lo part of IY).

 Now let's hack a Speedlock game. To start with, I'm hacking 
Knight Lore, but the following games are also suitable: Beach 
Head, Daley Thompson's Decathlon, Gilligan's Gold and 
Underwurlde. Anything released after these will be explained 
later.

 So first *Hack the BASIC loader.

KNIGHT LINE 0 LEN 1037

0 BEEP 0.1,1:BEEP 0.1,2:BEEP 0.1,3:BEEP 0.1,4:BEEP 0.1,5:PAPER 
0:BORDER 0:INK 0:BRIGHT 1:CLS:PRINT BRIGHT 1;INK 0;AT 9,5;
"LOADING: KNIGHT LORE";AT 12,10;"PLEASE WAIT"
0 POKE (PEEK 23641+256*PEEK 23642),PEEK 23649:POKE (PEEK 23641+ 
256*PEEK 23642)+1,PEEK 23650
0 POKE (PEEK 23613+256*PEEK 23614),PEEK 23627:POKE (PEEK 23613+
256*PEEK 23614)+1,PEEK 23628
0 POKE 23662,PEEK 23618:POKE 23663,PEEK 23619:POKE 23664,PEEK 
23621
23676 "REM CLOSE #ATTR....

 Wait a minute, there's absolutely no sign of a RANDOMIZE USR 
command anywhere! There's just some BASIC which beeps a bit, sets 
the colours, and prints a message, a whole load of POKEs, and 
then a load of garbage. Surely the computer will do everything, 
then report with an error message as soon as it reaches 23676?
 Well, that's not actually the case. Look at the third line 0 
(the one which starts POKE [PEEK 23613+256* etc.). This system 
variable is known as ERR SP. What happens is that when an error 
occurs (and it will do here), the computer jumps to the value in 
this register. This value is PEEK 23627+256*PEEK 23628. PRINT 
this value, and there's the start of the machine code. You might 
get a different result to me, but I made the start address #60A8. 
Disassemble this address.

60A8 F3          DI
60A9 FD 25       DEC IYH
60AB FD 7C       LD A,IYH
60AD FD AD       XOR IYL

 The DI is very important, because otherwise the I register can't 
be used. Given that IY starts off as being #5C3A, the value in A 
will end up being #5B XORed with #3A, which is #61.

60AF FD 26 F3    LD IYH,#F3
60B2 FD 2E A6    LD IYL,#A6
60B5 3B          DEC SP
60B6 3B          DEC SP
60B7 01 54 FE    LD BC,#FE54
60BA FD E3       EX (SP),IY

 First of all, this loads IY with the value #F3A6. It then 
decreases the stack pointer by two. By doing this, the stack 
pointer is now pointing to the start address of the machine code, 
which is #60A8. EX (SP),IY is a variation to the register 
exchange commands we've already come across. It basically swaps 
the value in the address pointed by the stack pointer with the 
value in the IY register. So, after this instruction, IY will 
contain #60A8, and the value on the top of the stack will be 
#F3A6.

60BC 21 30 F2    LD HL,#F230
60BF FD 09       ADD IY,BC
60C1 01 AC 01    LD BC,#01AC
60C4 FD 5D       LD E,IYL
60C6 FD 54       LD D,IYH
60C8 EB          EX DE,HL

 Here, HL is being loaded with #F230. The value in BC (#FE54) is 
added to the value in IY (#60A8), making the value in IY #5EFC. 
Then BC is loaded with #01AC, and the value in IY is transferred 
into DE. Then the values of DE and HL are swapped. So, by the end 
of the code we've looked at so far, HL will equal #5EFC, DE will 
equal #F230, BC will equal #01AC, and A will equal #61. These 
values are all used in the decrypter which follows.

60C9 AE          XOR (HL)
60CA 12          LD (DE),A
60CB 7E          LD (HL),A
60CC 23          INC HL
60CD 13          INC DE
60CE 0B          DEC BC
60CF FD 6F       LD IYL,A
60D1 78          LD A,B
60D2 B1          OR C
60D3 FD 7D       LD A,IYL
60D5 20 F2       JR NZ,#60C9
60D7 C9          RET

 This is a straightforward decrypter, except the value for A 
(which is needed throughout the decrypter) is temporarily stored 
in part of the IY register. The RET is to #F3A6 (the top value on 
the stack).
 To crack this, we can set up the register values manually, CALL 
the decrypter, and then hack the main loader ourselves. Type out 
this program:

5B00 F3          DI
5B01 21 FC 5E    LD HL,#5EFC
5B04 11 30 F2    LD DE,#F230
5B07 01 AC 01    LD BC,#01AC
5B0A 3E 61       LD A,#61
5B0C CD C9 60    CALL #60C9
5B0F FD 21 3A 5C LD IY,#5C3A
5B13 <breakpoint>

 Notice that we've disabled interrupts to avoid crashing, and we 
need to restore the value of IY to #5C3A afterwards, so your 
disassembler won't crash. RUN the program, and have a look at the 
code at #F3A6. You'll find it's just a straightforward headerless 
loader with absoultely no frills, and you should be able to hack 
it no problem.
 As for the final hack, load the BASIC into address #5CCB, run 
the decryption routine above, patch the JP in the main 
turboloader to your POKEs, and start running.

 All other Speedlock Type 1s have the same sort of decrypter. The 
code for the decrypter is very complicated, with the result that 
I have been unable to reproduce it here. Luckily, you don't have 
to touch the code; you can write your own decrypter as long as 
you have a Multiface.

 I'll be doing Tapper as an example, but any other Speedlock 
follows this procedure almost exactly. *Hack your game and note 
down the length of the code (you'll need it later). I made it 
1453, which is #05AD hex. Now look at address #5EFD. The byte at 
#5EFD is always decrypted to give the byte #42, and the byte at 
#5EFD is always decrypted to give the byte #55. The decrypter 
works by XORing the encrypted byte with a number taken from the R 
register. By inspecting the code before and after running, you'll 
see the XORing number starts off as #CB, and increases by #0A 
each time. If the result is more than #FF, the result has #80 
subtracted from it. We can incorporate this into our decrypter. 
The start of the code is #5EFD, and the length is (PEEK 23627+
256*PEEK 23628)-#5EFD, which is #01ED in the case of Tapper.
The following code will simulate the decrypter.

    LD HL,<start> 
    LD BC,<length>
    LD D,<initial decrypter value>
*** LD A,(HL)
    XOR D
    LD (HL),A
    LD A,D
    ADD #0A
    SET 7,A
    LD D,A
    INC HL
    DEC BC
    JR NZ, ***

 Once you've done that decrypter, you've got to do the whole lot 
again, starting at #5EFD. The byte there will be decrypted to 
either #3E or #ED - you'll have to guess which decrypting value 
to use. For Tapper, the start is #5F2B, the length is #1BF, and 
the second decrypter value is #AB.
 When you've done that, you'll either get the complete loading 
system or another decrypter. If you've got the loading system, 
then reload the BASIC loader, and do a stack trace to find out 
where it should go. You should have no problems with the loader.
 If you've got another decrpyter, go along five bytes and find a 
LD DE,(XXXX). Add #2E to this value, and that's where you move it 
to. The length is the same as that for the second decrypter. The 
decrypter itself can be cracked by changing a JP Z in the code 
about forty bytes later (the value of this is the start of the 
turboloader), but the decrypter itself uses a byte which is 
worked out by adding all the memory together in the loading 
system. Since we've got an exact copy of this system elsewhere in 
memory, just change the value of XXXX in the aforementioned LD 
DE,(XXXX), and then JP to the start of the decrypter.
 If the first decrypting value you used was #CB, then you can 
just change the JP in the turboloader to your POKEs.

 If the value was #CD, then you'll need to know about the 
Standard Speedlock patch. Somewhere in the loading system there 
will be the two bytes ED 53 [LD DE,(XXXX)]. Change the XXXX to 
the address of your POKEs (#5BA0 is normally safe), and end your 
POKEs with a JP to the value you overwrote. You'll have to use 
this patch for the later Speedlocks as well.

 There was a Speedlock Type 1 MultiPOKE in YS#79. RUN the 
program, press BREAK and disassemble address #5B00 to find out 
what to do in your own hacks.

 Type 2 Speedlocks feature a very easy BASIC loader, and one big 
block of code, which has six short decrypters and a complex 
moving routine. The decrypters are all easy peasy, just move them 
to somewhere else in memory (such as #5B00), bung a RET on the 
end, and CALL the decrypter from there (but watch out for the 
third decrypter, which checks for a Multiface and crashes if it 
finds it. The moving routine fiddles about with the loader. 
Search for 31, which means LD SP,XXXX. Hopefully, you'll find a 
LD SP,#0000, with perhaps a DI right before it. Write down the 
address and run the moving routine (you may have to restart the 
tape, because some of the moving routines insist on a signal 
coming into the tape recorder). Use a stack trace to find out 
where the code has gone to. Now you can move all the code from 
the moving routine to the end of the machine code block to where 
it should be, given that you know where the LD SP,#0000 goes to. 
Once moved, patch the loader in the same way as the first 
Speedlock.

 Type 3s have just one long BASIC loader, with about 144 
decrypters, but that's nothing to worry about. *Hack the BASIC 
loader, and have a look at the first bit of code which moves the 
rest of the code into the right place (you can then use a 
headerless loader to load this into the right place in memory). 
The tricky bit is changing a byte in memory so a CALL to the 
loading system at the very top of the code is changed to a CALL 
somewhere else once all the decrypters have been run. The only 
way you can do this is to change the address of the hi byte of 
this CALL to something else, and RUN the huge load of the 
decrypters. The computer will crash if you have a Multiface 
attached, but only after everything's been decrypted, so then 
look and see what the CALL's been changed to. If it's suitable, 
remember the patch, position your hack around this, change the 
CALL to what it should be,and put in the usual Speedlock patch. 
Look at the start address in the turboloader. This address will 
be overwritten by a decrypter once loading finishes. This 
decrypter is nothing special, so just crack it as usual, and 
watch out for the game moving around.
 Jon North's Pokerama Tapes usually have a Speedlock Type 3 crack 
on it - load up the Pokerama, choose your POKE, then do a stack 
trace to find it and have a look at it.

Part 7 - Epilogue

 Well folks, I'm sorry to have to break this to you, but I've 
just about told everything you should ever need to know to crack 
every protection system under the sun. So I'll just say some 
final words and credits, and then sign off, okay?

 The idea of this book, its production and its writing were done 
entirely by Richard Swann, from February to June 1992.

 Some suggestions and tips came from two people to whom this book 
is dedicated, Matt Corby from "down-the-road", and Niall "Mr 
Incredibly Technical" Daley. Thanks, guys!

 Thanks to YS for putting disassemblers and the like on recent 
covertapes; it saved me the trouble of writing one!

 Thanks to Jon North for some of the info on hacking he gave to 
me on disk recently - much appreciated, mate.

 Thanks for YOU for buying this. There aren't many Speccy hackers 
around right now, so we need to make the numbers up. Good luck!

 What's that? "I don't understand this bit at all!" I hear you 
say. Well, send me any queries that you may have about this book, 
stating exactly what the problem is, along with an SAE (very 
important that), and I'll do my best to reply to them. DON'T 
write to me asking me to hack a whole list of games for you - I 
just haven't got the time. However, I've got a big book of 
Multiface POKEs which you can obtain for 1.50 and an A4 SAE if 
you want it, so that might come in handy.

 Thought for the year: Seven years ago, Spectrum and Commodore 
owners were at each other's throats. Spectrum owners would vow 
never to have anything to do with Commodore. Then why do I hear 
of so many Spectrum owners that have upgraded to a Commodore 
Amiga? Personally, I can't stand the Amiga's operating system - 
it's terrible!

 Well, that seems to be about it, so I'll just leave you know in 
the hands of a glossary of terms. Happy hacking!

RICHARD SWANN - June 1992

GLOSSARY

Breakpoint - an instruction put in by a disassembler which will 
return control to it when it is executed. Also something to do 
with tennis.

Crack/cracking - writing a routine or executing some code which 
will get round some element of a protection system, enabling the 
user to put a POKE into the game.

Crash - an undesired effect which the programmer or user did not 
intend to happen. Classic example is the computer resetting 
itself to give the old "(C) 1982 Sinclair etc.etc.", or a whole 
load of flashing squares. Also a now defunct computer magazine.

Decrypter - a short program contained in a protection system 
which, when run will change garbage into runnable code. You need 
to crack a decrypter to write a hack for it.

Endless loop - the Multiface equivalent of a breakpoint, put in 
hacking a protection system or doing a stack trace. The computer 
will keep executing the same code over and over again, 
indefinitely, unless the Multiface button is pressed. See also 
endless loop (ho ho ho!)

Garbage - A block of machine code which does not make sense to a 
human. The computer will attempt to process it, but will almost 
certainly crash. Also what the dustmen collect in America.

Hack - a self-standing program which when run will load a game        
and activate certain cheats. Also the act of getting round a 
protection system. (See also crack). Also a lot of anonymous 
people from Scotland.

Headerless loader - a loader which does not contain the first 
"header part" of a file specifying it's name, length etc, but 
has it ready built into memory. This makes the program harder to 
hack.

Interrupt - small program which occurs every 150 of a second, 
regardless of what the computer is doing.

Loader - any program which reads a file off tape into memory, and 
executes it. This may consist of simple BASIC commands, a 
headerless loader, a turboloader or even a protection system.

Operating system - this the built in program into the computer to 
deal with all the basic things like reading the keyboard and 
loading software. This is BASIC in the case of the Spectrum. Most 
protection systems deliberately confuse the operating system or 
lock you out of it.

Patch - replacing a bit of code whith something designed to hack 
it. This patch may consist of a jump elsewhere in memory, or a 
breakpoint. Also something that pirates wear on one eye.

POKE - the process in which a single byte of memory is changed. 
Originally, games were hacked by one or two POKEs.

Protection system - A block of code which tags on the front of a 
game's loader and prevents anyone from accessing the code it is 
protecting. At least, that's what it's supposed to do!

Trace - looking through a block of code with the aim of finding 
something specific (such as an infinite lives POKE). This may be 
forwards, backwards, interrupt or stack trace.

Turboloader - a loader which loads in a file off tape at a faster 
speed than usual. This speeds up loading. The turboloader may be 
hidden by a protection system.

THE END

[C] 1992 NSA Publications. No part of this book may be copied, 
otherwise I'll send the Mafia round. Okay?
