Alarm Clock (Clock This) - Ian Turtle (Your Spectrum-Issue 2-Page 93)


Have you ever got so engrossed in your programming that the
hours just ticked by and you missed that important appointment?
Well, type in this program and one worry at least will
be over.
	The Basic program which performs this amazing feat
includes two machine code routines as well as a self-
performing checksum, which should ensure that you type the
program in correctly . However,just to take all precautions,
it would be wise to SAVE the program once typed in, before
running it.
	This done, now let's try it out. One of two things will
happen. At worst, it'll respond with an 'Error in data' message,
and list the DATA lines where the error occurs. You should
now check these lines, restore the program to good health,
SAVE the listing to tape and start over.
	Should the program run correctly first time, you will be
greeted with an 'OK' message and prompted to input the time
(in hours and minutes) that you'd like the alarm to be set off.
That done, the computer NEWs itself. Don't panic at this
stage - the program has not crashed; it's merely waiting for
you to start the countdown.
	To initiate the timer, simply type RANDOMIZE USR
65120, to which the response should be 'OK', indicating that
all is going according to plan. This instruction executes a
small machine code routine to set up the interrupt. When
your time is up, the program blanks the screen, turning it a
glorious shade of red. Again, nothing to panic about - just
press the Enter key and you'll find all the work you've been
doing is still in memory waiting to be SAVEd so it can be
continued at a later date.
	Once the timer has been set, you are free to start your
programming - up until whenever the alarm is due to go off.
Basic programs will not affect the alarm, and most machine
code programs should also work (as long as they don't use
interrupts nor occupy addresses 65120 upwards).
	Don't worry if at any time during your programming you
NEW the computer - you won't clear the Spectrum Alarm.
However, you will need to reset the interrupt by typing in
RANDOMIZE USR 65120 again. The timer will thus
begin where it left off. Also, PAUSEs, BEEPs, and all
LOADing and SAVEing operations, will cause the alarm to
stop. But once finished, the alarm automatically resets itself,
so you shouldn't lose too much time.
	If you'd like a continuous on-screen printout of the time
remaining before the alarm goes off, type in this Basic one-
liner:

10 PRINT AT 0,0; PEEK 65532;":"; PEEK 65533;":"; PEEK 65534;"   ": GO TO 10


Line 10         Lowers RAMTOP and restores data.
Lines 15-20     Print the on-screen message, and set the checksum and
		data counters.
Lines 30-60     Read the machine code for the interrupt routine and POKE it
		into memory. When all the interrupt machine code is
		installed, check to see whether an error has occurred.
Lines 70-90     This area of the program carries out the same task as lines
		30-60 for the alarm call machine code.
Lines 100-210   Set the alarm time, POKE it into memory and then NEWs 
		the computer.
Line 300        The machine code for the interrupt routine.
Lines 310-350   The machine code for the alarm call routine.


Here is a disassembled listing of the main service routine, which is
included in lines 310-350 of the Basic program.

The Alarm Call routine
Machine Code            Assembler       Comments
10              CLOCK   RST 56          Performs the keyboard scan which
					had been diverted.
20                      DI              Disable the interrupts, ie. ensure
					this routine cannot be interrupted,
30                      PUSH AF         and save the only register used onto
					the stack.
					The addresses used are:
					65532 - count of hours remaining.
					65533 - count of minutes remaining
					in the present hour.
					65534 - count of seconds remaining
					in the present minute.
					65535 - count of 1/50 second remaining
					in the present minute.
40                      LD A,(65535)    Check if the 1/50 of a second counter
50                      CP 0            has gone down to zero.
60                      JR Z,BMPSEC     If so, jumps to line 100 onwards which
					causes a decrement in seconds.
70                      DEC A           If not, simply decrements the 1/50 of
80                      LD (65535),A    a second counter and jumps to the
90                      JR END          returning part of the routine
					(lines 430-450).
--------------------------------------------------------------------------------
100             BMPSEC  LD A,49         Decrement the seconds counter and jump
110                     LD (65535),A    to the minutes decrementer (if required).
120                     LD A,(65534)
130                     CP 0
140                     JR Z,BMPMIN
150                     DEC A
160                     LD (65534),A
170                     JR END
--------------------------------------------------------------------------------
180             BMPMIN  LD A,59         Decrement the minutes counter and jump
190                     LD (65534),A    to the hours decrementer (if required).
200                     LD A,(65533)
210                     CP 0
220                     JR Z,BMPHOU
230                     DEC A
240                     LD (65533),A
250                     JR END
--------------------------------------------------------------------------------
260             BMPHOU  LD A,59         Decrement the hours counter. If this
270                     LD (65533),A    has already reached zero, it causes a
280                     LD A,(65532)    call to the alarm routine.
290                     CP 0
300                     JR Z,ALARM
310                     DEC A
320                     LD (65532),A
330                     JR END
--------------------------------------------------------------------------------
340             ALARM   LD A,2          Set the BORDER colour red.
350                     CALL #229B
360                     LD A,23         Set the attribute colours to PAPER 2:
370                     LD (23693),A    INK 7: FLASH 0: BRIGHT 0.
380                     CALL #0D4D
390                     CALL #0D6B      A ROM call to effect a cleared screen.
400                     LD A,62         Reset the interrupts to the previous
410                     LD I,A          mode.
420                     IM 1
--------------------------------------------------------------------------------
430             END     POP AF          Restore the A register, re-enable the
440                     EI              interrupts and return.
450                     RET


For those in the know, the data in line 300 of the Basic program generates a
short routine to set up the interrupts, its task being to make the computer
service the routine at address 65129. Here is the disassembled listing.

The Interrupt routine
10  LD A,9
20  LD I,A
30  IM 2
40 RET

------------------------------------------------------------------------------


letter from Your Spectrum #3 (May'84)

CLOCK THAT

Further to the Clock This program (issue 2), I have re-written the alarm
routine as, after much thought, I consider the whole screen turning red
to be unsatisfactory. Instead, the border still turns red and a two-toned
BEEP sounds for 20 seconds - a bit more like an alarm. (The new listing
is shown alongside.)

Ian Turtle, Loughborough

[This alternative version is included in ALARMCLK.TAP. JimG]

