Kempston Plus Interface
As promised, I hereby present an extended Kempston Joystick Interface capable of reading 8 input lines or powering a mouse. The circuit is very popular and reliable; the original comes from the Happy Computer Spectrum Sonderheft (unfortunately a one-off!) and was only slightly modified by me, more on that in a moment. Only the A line is decoded, which keeps the component cost comfortably low, and the user suffers no disadvantages, as this is standard practice. The inverting bus driver 74LS240 converts the incoming signals so that they are accepted by the computer.
Regarding construction: The chips should be socketed, and whoever feels confident enough can solder the board (I used a stripboard/perfboard experimenter's PCB) directly to the Spectrum PCB to save the cost of an edge connector, which is many times more expensive than the components.
The switch S should be installed in such a way that its position is unmistakable. A mistake could send your Spectrum straight to Hades. What I mean is that if the switch is set to +5V power supply and you happen to have a modified Megadrive control pad connected, pressing the fourth fire button will cause a short circuit; the current will flow with zero resistance from +5V to 0 Volts (ground). The current will then take the easier path instead of flowing through the chips, leaving them suddenly forced to cope without (one of) the supply voltages. Anyone familiar with TTL knows how narrow the tolerance margin for voltage fluctuations is. In the best case, the Spectrum will be its old self the next time you turn it on; in the worst, it's just scrap. (Now would be the right moment to insert an ad for Spectrum repairs!)
But don't worry, the fourth fire button is hardly ever used anyway—three of them are usually more than enough! My modification (the switch), however, allows reading full 8-bit data, or, when left in the position shown on the diagram, operation with an Amiga/Atari/Geos mouse. The fire buttons can be read independently, even on 3-button mice as introduced on the Amiga. In some programs, this can trigger secret functions.
Trackballs can be used just the same; with extravagant models, e.g. with an illuminated plexiglass ball, the power consumption might exceed permissible limits. That is rather unlikely, but it should still be considered, especially if your Spectrum is a hyper-duper edition with all the bells and whistles like a disk interface, coprocessor, windshield wipers, carousel, and water fountain. In such cases, I recommend either a beefier main power supply or an external supply for the interface or trackball.
Reading the interface should pose no problem to anyone; it is done via IN 31. If you want to visualize this on the screen, you can use this Basic one-liner:
1 POKE 16384, IN 31: GO TO 1
or:
1 PRINT AT 0,0; IN 31;" ": GO TO 1
The black dots on the screen are produced by joystick movements, or displayed as numbers in the second program.
What will appear in the next Hardware Corner is not yet clear, because there are so few submissions that, as mentioned, I had to fall back on the HC Sonderheft. So folks, seriously this time: send me some articles at last! I mean, there is so much to write about, but nobody does it!
Yours, L. C. D. (Tiger's Claw)
Cracking Workshop pt 3
This month I dedicate myself to beautifying programs cracked with LERM Conversion Utility and programs that load as an entire memory dump.
LERM CU is actually quite a useful program because it automatically cracks several very tricky systems like Speedlock I, II, Firebird, and Alcatraz. Unfortunately, the screen looks quite broken while loading Alcatraz programs. The solution to make it more presentable is very simple:
Whenever I load the original program, I take a snap of the screen and use it during loading. The LERM crack will restore it after loading the program, but during loading it looks pretty stupid. Therefore, I always compress the main part and append the corrupted screen after the code part—there should be enough space, though I could also use Screencompressor Plus to pack the screen as well. Even if the result isn't always fully satisfying, no further tools are needed.
After loading the main part, I decompress the screen, which overwrites the nice title picture. On the disk, there is also a program called LDIR, with which you can very easily design memory shifts in machine code, allowing you to bring an image out of memory as well. Once the screen is as it should be, I decompress the main code part and start the program with USR 16384. The end result is that after loading the program, the title picture is disrupted for only a second and then reassembled. The program can then be started with a single keypress. In this way, I cracked MAZEMANIA from the YS Covertape, and many others.
Another advantage is that only three files remain instead of the usual four. On +D, where only 80 files fit per disk, that is already a good result, and because the files are packed, loading them from tape takes a little less time and more programs fit on a cassette.
I invested considerably more work to crack programs like 3DSTARSTRIKE or DEFENDER OF THE CROWN. Without the excellent Polish copying program COPY COPY, I probably would never have managed it. The problem was that the files are too long to fit another routine into memory. The programs usually occupy 49152 bytes, and that is simply the entire memory space of the Spectrum 48K; even a 128K Spectrum doesn't help here.
COPY COPY offers the function LOAD (x TO y); more details on that can be found in the manual located in the ASC freeware library. This function allows long programs to be sliced up, thereby making cracking such large programs much easier.
Using Screencompressor+, I first load the title picture; the program stops automatically once 6912 bytes have been read (for CAULDRON II it is useless for that reason, but at least SNAPOUT worked there, see SCENE 12/95). Next, using COPY COPY, a 1704-byte part is isolated after the first 6912 bytes, which in the end must be located back at address 23296. It is easy to calculate that the next part must be split after 8616 bytes, this time all the way to the end—that is, 40536 bytes long. This part will then reside in memory starting from address 25000, which leaves room for a "Cracked By..." message.
The other cracking utility that I have saved on the disk is called LDHDLS (Load Headerless); with it, it is possible to load the parts obtained in this way from tape in order to save them to disk.
The main part (CODE 25000, 40536) must be compressed, either with TURBO IMPLODER—which is a bit unreliable, but brings no other disadvantages—or PK LITE, whose decompression address must lie in the screen area, which slightly disfigures the title picture. The calculated start address is entered as the execution address; therefore, the possibility to verify the code part only exists if you compress it as a test without the execute address, decompress it, and verify it against the original code (+D users have the option to use VERIFY pn).
Now let's assume the code part was compressed from 40536 to 32411 bytes. In this case, the second code part with a length of 1704 bytes is to be loaded to address 57411. We then have free memory from address 59115 onwards—but not so fast, because somehow this code part must be brought back to the correct address, namely 23296. For that, we can use the program LDIR again (Source=57411, Length=1704, Destination=23296, Start=25000, Jump type=195, Startadr.=59115). The MC generated in this way must be saved together with the main code part. The SP value determined by the loader varies from case to case, but it must also be entered, otherwise the program will crash.
After RAND USR 59115 (theoretically speaking, in this case), the STACK POINTER is first set to the correct value, then the program copies the 1704 bytes from 57411 to 23296 and calls the decompression routine, which in turn launches the program automatically.
It is a bit of an ordeal, but the result rewards the effort, and the crack is much cleaner than many others. In this way, I have cracked STARSTRIKE II, WANDERER 3D, and many other programs, while elsewhere MF "cracks" are still circulating.
Well, that's pretty much it for now. The series will be continued if further questions on the topic come in, or whenever I find something new to report, because so far I have published almost my entire wealth of cracking experience.
L. C. D. / Tiger's Claw
USCHI
USCHI is one of the best Basic compilers available for the Spectrum, and it is PD, which is why I am bringing the manual for this program and the compiler itself straight to your home.
If you own a Spectrum and program in Basic, USCHI is just the thing for you: it compiles your programs into super-fast machine code, speeding them up many times over. To be sure, there are many Basic compilers available for the Spectrum these days, but "USCHI", the "Ultraschneller Spectrum-Compiler für hundertprozentige Integerarithmetik" (Ultra-fast Spectrum Compiler for 100% Integer Arithmetic), outshines almost all of them. USCHI is written 100% in MC and is characterized by almost unbelievable speed both during compilation and during execution of the generated machine code. The compiler occupies the memory range 60000 to 65367, so that you can continue to use all UDGs without restriction.
Operating USCHI is very simple. After loading the compiler, you can program in Basic as usual or load a program from a storage medium. Once your program is finished and runs smoothly, start USCHI with:
RANDOMIZE USR 60000
The compiler now translates your Basic program into machine code. During this process, meaningless patterns appear on the screen because the screen memory is used for variables and tables.
If USCHI finds an error, the erroneous line is displayed with a question mark at the position where the error occurred (depending on the type of error, also at the end of a line); otherwise, USCHI reports "Keine Fehler" (No Errors) and displays three addresses.
The first address indicates the start of the generated machine code (compiled code). This
The value is always equal to RAMTOP. RAMTOP is initialized to 40000 and can be changed with the CLEAR command (for those interested: unusual addresses like 24000 or similar can be poked directly into the double system variable 23730/31). The second address indicates the end of the machine code. It points to the last byte of the compiled code, which is immediately followed by the memory for variables. The third and last address points to the end of the variable memory area, which is followed by the memory for array variables.
The machine code generated by USCHI is started with:
RANDOMIZE USR start
where the value of "start" is the first of the three addresses output by the compiler. With the command:
SAVE "Name" CODE start,end-start+1
the new machine code can be saved. For the variable "end", you must enter the second address displayed by USCHI (any other existing programs and data must not overlap with the variable memory, which is why I recommend using the third address instead and avoiding array variables).
If you want to load and use the machine code, first enter CLEAR start-1 to protect the memory area for the machine code. Then load the program with LOAD "" CODE (or using disk syntax) and start it as mentioned with RANDOMIZE USR start.
To run a compiled program, the USCHI compiler does not need to be in the Spectrum's memory, because the compiled code runs entirely standalone from the compiler.
As a BASIC programmer, you must observe the following points when working with USCHI:
- You may only use integer arithmetic (whole-number values from -32768 to +32767). Exception: POKE, PEEK, USR, and wherever memory addresses are concerned; these are also accepted by USCHI in ranges up to 65535; negative numbers are then not permitted and meaningless.
- Mathematical expressions can fundamentally be used anywhere (including with the commands GO TO, GO SUB, RESTORE, and STEP).
- Functions and parentheses may be nested to any depth.
- String handling (alphanumeric strings) is not permitted.
- The commands CLEAR, DEF FN, LIST, LLIST, and RUN, as well as all cassette and Microdrive commands, are not translated.
- The functions INKEY$ and SCREEN$ must be written as CODE INKEY$ and CODE SCREEN$. They then produce the character code. For example,
IF INKEY$="a"becomesIF CODE INKEY$=CODE "a". - The RND function yields a number between 0 and 32768; for example,
LET a=INT (RND*6)+1becomesLET a=RND/5462+1(this was precisely the problem with "Godzilla", where I couldn't calculate the strength loss values correctly). - With the commands BEEP and DRAW, division is not rounded down. You can write, for example,
BEEP 1/100orDRAW 50,50,3/2. - If a STOP command appears in your BASIC program, the program is only translated up to this command; the rest is ignored.
Normally, compiled code can always be interrupted with the BREAK key. However, you can disable the effect of this key with the command sequence REM !ROFF, and re-enable it with REM !RON. When the BREAK key is disabled, the compiled code runs slightly faster and is shorter!
The command sequence REM !GNORE causes the following program line not to be translated. That is, it will only be executed when the program runs normally under BASIC, but the commands of this line are not included in the compiled code. The !GNORE command is useful when a program is supposed to function both under BASIC and in the compiled version.
Tip: The address of the BASIC program is taken from the system variable 23635/36. You can load your program to another address and then poke it in, for example if compiled code needs to run from a very low address.
I also discovered that some functions do not work properly; for example:
LET c=POINT (0,175)*128 + POINT (0,174)*64 + POINT (0,173)*32
must be formulated differently in order to work:
LET c=0: IF POINT (0,175)=1 THEN LET c=c+128
IF POINT (0,174)=1 THEN LET c=c+64
IF POINT (0,173)=1 THEN LET c=c+32
One can therefore say that IF NOT POINT (0,174) THEN ... works just as little as IF POINT (0,174) THEN ....
How to work with USCHI
Here is a concrete example of working with USCHI:
Clear the Spectrum's memory with NEW or PRINT USR 0 and load the compiler. Once USCHI has reported in, type in the following test program:
10 FOR n=0 TO 100: FOR m=1 TO 100
20 PLOT n,m
30 NEXT m: NEXT n
Then start the compiler with RANDOMIZE USR 60000 (or 6e4). The following message will appear on the screen:
Start of compiled code: 40000
End of compiled code: 40123
End of variables: 40134
You can start the compiled code with RANDOMIZE USR 40000 (or 4e4). If you then enter RUN to test the BASIC program, you will have a very good opportunity to compare the speed between machine code and the BASIC program.
USCHI supports the following commands:
ABS, AND, AT, ATTR, BEEP, BIN, BORDER, BRIGHT, CHR$, CIRCLE, CLS, CODE, CODE INKEY$, CODE SCREEN$, COPY, DATA, DIM, DRAW, FLASH, FOR.. TO .. STEP, GO TO, GO SUB, IF.. THEN, IN, INK, INPUT, INT, INVERSE, LET, LPRINT, NEXT, OVER, OUT, PAPER, PAUSE, PEEK, PLOT, POINT, POKE, PRINT, RANDOMIZE, READ, REM, RESTORE, RETURN, RND, SGN, SQR, STOP, TAB, USR.
Author: Martin Würthner / Happy Computer 9/87
Subsequent remarks and improvements: L.
Share your thoughts about the article