Interrupt-intercept



Simon Liston,

Walthamstow,

London.



The ZX Spectrum produces an interrupt every 0.2 seconds.

The  Spectrum ROM uses this interrupt to increment the

FRAMES system variable and also to see if any keys are

being pressed. This short machine-code program causes the

micro to CALL address 63479 on each of these interrupts.

I have written a real-time clock to illustrate one possible

use of this facility.

  First, reserve some memory: type CLEAR 63400. Next, poke

the 23 bytes of the interrupt-intercept into locations

65040-65062. Now, poke the machine code for the real-time

clock into locations 63479-63665. Check what you have poked

with the listing, then save the the code you have entered.

Next, enter RANDOMIZE USR 65040.

  You should now have a random time displayed in the top

right-hand corner of the screen. Hours, minutes and seconds

are stored in packed-bed [sic] format. Their respective

addresses are 63667, 63668 and 63669.

  Setting the time, for example 11:44:13, is done as

follows:

        POKE 63667,1*16+1

        POKE 63668,4*16+4

        POKE 63669,1*16+3

Note that you must have a self-contained machine-code

program at locations 63479-64760, that is, unless you know

exactly what you are doing, you should save all the regis-

ters and do not alter any system variables.

  It is a good idea to end your routine not with ei; ret,

but with JP 56(dec); this causes control to be passed to

the usual interrupt routine.

  The clock program given will keep good time so long as

LOAD, SAVE, BEEP, COPY or the printer are not used. [Or

MERGE, VERIFY or the Microdrive; in other words, anything

which drives a peripheral.] Some other ideas: on every

interrupt, print the value of the system variable PPC to

show you the line number being interpreted. This provides

a simple trace mechanism. Or set SCR CT to 255 on every

interrupt; this will stop the Scroll? function being

erased [sic!]. Why not have a delay loop on every inter-

rupt? This will slow down program execution - if it is not

slow enough already. [But beware - don't slow it down so

much that a new interrupt is called while you're still

executing your old one!]

  [The TZX which goes with this text contains three code

files. The first one, "All Code", is exactly that: both

parts of the code, with a lot of blank space in between.

  The second, "Driver", is just the small part which loads

the interrupt vector and activates it. Do not call this

code without an actual interrupt routine in memory as well,

or you'll crash the machine. Note also that it will clobber

over memory from 64760 to 65031, although it would have

sufficed to poke only the two bytes at 65023. These two

bytes must not be overwritten while the interrupt routine

is used, but the others (and the code of Driver itself)

can safely be re-used once it is up and running.

  The third code file is the demonstration Clock interrupt

routine. You can safely call this yourself if you wish, but

unless you do so 50 times a second it's rather pointless.]