Your Spectrum
Issue 1, January 1984 - Machine Code Breakout!
Home Contents KwikPik


See also these letters about the article:
Issue 2"Breaking-In to 16K"
Issue 19"Grid Bug"


Once upon a time machine code gave rise to infinite loops. If such a loop was encountered then there was absolutely nothing you could do about it except pull the plug out and start again. Now, however, those sorry days are gone as, exclusively for readers of this magazine, Toni Baker presents one of the most important Spectrum discoveries ever made. Learn from her the secrets of Spectrum RESET. MACHINE

C O D E

BREAKOUT!


 

Consider the machine code program:

18FE LOOP JR LOOP

Not a very sensible program is it? Still, it makes a good demonstration. You probably won't need to actually try out the above program to prove that it causes a crash. The screen will freeze and the keyboard won't work. Infinite loops in Basic are usually easier to handle. For instance, the program:

10 GO TO 10

is also an infinite loop, but now note that if you press BREAK (ie. CAPS SHIFT together with SPACE) you are no longer stuck there. It is, however,
possible to create loops which are quite difficult to break out of, for instance the program:

10 INPUT LINE A$: GO TO 10

In this example the only way out is to keep one finger on the CAPS SHIFT key and then press ENTER followed by SPACE in very, very quick succession. Try it if you like, but be warned - it's extremely tricky.
Now, however, those days are in the past, for there's been an important breakthrough. This is a software controlled system which adds a RESET function to the ZX Spectrum. The system is activated by the single instruction RANDOMIZE USR 33001, and will remain active until you
deactivate it by typing RANDOMIZE USR 32994. When the system is active, both Basic and machine code will work as normal; however, you will notice that a new function has been added to the Spectrum vocabulary. The function is called RESET and is operated by pressing CAPS SHIFT simultaneous with ENTER. The RESET function will immediately break out from any operation being carried out by the Spectrum and will return the computer to command mode, waiting for a new Basic keyword command.
Note, by the way, the useful feature that if you press RESET whilst typing in a command line in Basic then the
Machine codeAssemblerComments
 
            ORG 80E2
 
3E3F
ED47
ED56
C9
DEACTIVATE  LD A,3F
            LD I,A
            IM 1
            RET
  
I: = 3F (Normal Spectrum value). 
Spectrum now in normal mode. 
Deactivation complete.
3E80
ED47
ED5E
 
C9
ACTIVATE    LD A,80
            LD I,A
            IM 2
            
            RET
  
I: = 80 
Interrupts now vectored through 
the label I_ADDR.
 
524553
45542065
78656375
746564A1
RES_MESSAGE 
            
            
            DEFM RESET executed!
Message to be printed on 
completion of task. Note that the 
code for '!' has 80h added.
 
0181
 
I_ADDR      DEFW TEST_RESET
 
Direct interrupt control to address 
labelled TEST_RESET.
F5
3EFE
DBFE
1F
3807
3EBF
DBFE
1F
3004
TEST_RESET  PUSH AF
            LD A,FE
            IN A,(FE)
            RRA
            JR C,NO_RESET
            LD A,BF
            IN A,(FE)
            RRA
            JR NC,RESET
Stack A and the flags. 
 
Scan segment zero of the keyboard. 
Test for CAPS SHIFT key. 
Jump unless CAPS SHIFT is pressed. 
 
Scan segment six of the keyboard. 
Test for ENTER key. 
Jump if ENTER is also depressed.
F1
FF
 
ED4D
NO_RESET    POP AF
            RST 38
            
            RETI
Restore A and the flags. 
Update the system variables 
KSTATE, LAST_K and FRAMES. 
Return from interrupt routine.
2AB25C
2B
F9
2B
2B
223D5C
 
AF
32715C
CD0116
CD6E0D
213B5C
CB9E
23
CBEE
 
AF
11EF80
CD0A0C
FB
C3A912
RESET       LD HL,(RAMTOP)
            DEC HL
            LD SP,HL
            DEC HL
            DEC HL
            LD (ERR_SP),HL
            
            XOR A
            LD (FLAGX),A
            CALL CHAN_OPEN
            CALL CLS_LOWER
            LD HL,FLAGS
            RES 3,(HL)
            INC HL
            SET 5,(HL)
            
            XOR A
            LD DE,RES_MESSAGE-1
            CALL PO_MSG
            EI
            JP MAIN_1
  
  
Empty the machine stack. 
 
 
Reset the system variable 
ERR_SP. 
 
Cancel INPUT mode if needed. 
Use channel zero. 
Empty lower part of screen. 
 
Specify 'K' cursor required. 
HL now points to TVFLAG. 
Signal that the lower part of 
screen will require clearing. 
 
 
Print "RESET executed!". 
Re-enable the interrupts. 
Jump into command routine.

entire line will be deleted. This serves much the same purpose as pressing EDIT when trying to input something.
The machine code begins at address 80E2. It is not relocatable (although you may like to try rewriting it so that it is designed to sit at some other address). It's activated by calling it from the label ACTIVATE, and deactivated by calling it from the label DEACTIVATE.
If you load in the code in the table to address 80E2 (equal to decimal 32994) using any machine code loader program, and then run the machine code from address 33001 (80E9 in hex - this is the address of the label ACTIVATE) you will find that the power of your Spectrum has been vastly improved, for you now have a RESET button! RESET, remember, is CAPS SHIFT and ENTER.
Type in and run the following machine code program, and then use RESET to break out. just to convince yourself that it works:

18FE LOOP JR LOOP

Now try the Basic infinite loop:

10 INPUT LINE A$: GO TO 10

and break out of that using RESET. Type in any Basic program, and then press ENTER on its own to get an automatic listing. Now quickly before the listing fills the screen, press RESET and interrupt it halfway through. Even that works!

Some things to know about RESET

* To activate the RESET facility type RANDOMIZE USR 33001.
* To deactivate the RESET facility type RANDOMIZE USR 32994. You are warned not to rely on using RESET to break out of a program since the facility may not always be in use.
* The existence or otherwise of the RESET facility is not SAVEd. This means that if you SAVE a program which contains an infinite loop, and then LOAD it back at some future stage when RESET is not present then you may find some problems. You can of course SAVE the RESET program itself using SAVE "RESET" CODE 32994,89 and then initiating it as in point (1) above.
* RESET will not work whilst LOADing or SAVEing a program, nor will it work during BEEP.
* RESET will not work if interrupts are disabled. This explains the point above. It is therefore possible to write a machine code program which may not be broken into simply by making the first instruction DI and remembering that you must execute EI before returning to Basic.
* The Basic command NEW will deactivate the RESET function, even if the code is stored above RAMTOP. It may of course be reactivated as in the first observation unless NEW has erased the code itself.
* Sadly, the RESET function cannot (as far as I know) be implemented on a 16K machine. This is because the I register cannot hold values in the range 40 to 7F without corrupting the TV screen.
See the issue 2 letters page for a 16K version of this routine.
Home Contents KwikPik