|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
Consider the machine code program:
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:
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
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
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.
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:
Now try the Basic infinite loop:
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.|