Computus Interruptus, Part 2

Authors

Wes Brzozowski

Publication

Publication Details

Volume: 3 Issue: 4

Date

February 1985

Pages

5-6
See all articles from SINCUS v3 n4

How Does The Demonstrator Work? 

Pretty well! Seriously, let’s first look at what the demonstrator sets up in memory, and then we’ll see how it all works together. Understanding this description will require a bit of knowledge of machine code, but only a bit. The demonstrator has been written to be understood by as wide an audience as possible. (That audience will also need a little persistence, though) 

Line 30 CLEARs the necessary space for the interrupt software. Line 40 fills memory locations FE00h to FF00h with FDh. Line 50 places a JP FF0h8 instruction at location FDFDh. Lines 40 and 70 load the following machine code, starting at location FF01h: 

Addr	Hexcode	Label	Mnemonic
FF01	3EFE	BLOCK1	LD A,FE
FF03	ED47		LD I, A
FF05	ED5E		IM 2
FF07	C9		RET
FF08	F5	BLOCK2	PUSH AF
FF09	C5		PUSH BC
FF0A	D5		PUSH DE
FF0B	E5		PUSH HL
FF0C	3E7E	BLOCK3	LD A, 7E
FF0E	DBFE		IN A, (FE)
FF10	F6E0		OR E0
FF12	FEFC		OR FC
FF14	2006	BLOCK4	JR NZ, FF1C
FF16	F3		DI
FF17	06C0		LD B, C0
FF19	CD050A		CALL 0A05
FF1C	E1	BLOCK5	POP HL
FF1D	D1		POP DE
FF1E	C1		POP BC
FF1F	F1		POP AF
FF20	C33800		JP 0038

I’ve divided the code into five blocks, whose meaning will be explained shortly.

Line 80 executes machine code at location 65281, which, not so coincidentally, is equal to location FF01 in the machine code listing. Only block #1 is executed, since it ends with a RET instruction. Block #1 loads FE into the I-register, and sets the machine into interrupt mode 2. 

From here on, the T/S 2068 is doing something new that it does not ordinarily do. Every time an interrupt occurs, the machine has to find out where it is to execute the interrupt code. It gets the upper byte of an address from the I-register and the lower byte from the data bus. This combination is the ADDRESS OF THE ADDRESS of the interrupt handler. It will become clearer (hopefully) as we “walk through” what happens. 

When the T/S 2068 gets an interrupt, it looks to the I-register and the data bus to generate the address FExxh, where xx is a number that is not known because the T/S 2068 mysteriously puts different values on the data bus at different times. The T/S 2068 will then look to memory location FExxh for the address of the interrupt handler, and then run the code wherever that happens to be. 

However, the BASIC program filled all memory locations from FE00h to FF00h with the number FD, so no matter what value FExxh pens to be, the T/S 2068 will find FDFDh when it looks there!This is where it will start to execute the interrupt handler. 

Unfortunately, FDFDh is just 3 bytes less than FE00h, where the “kluge block” of FD’s are located. There’s not room for much code, but there’s just enough space for the JP FF08 instruction that the BASIC program put there. This means that the interrupt handler will continue at location FF08h, or, block #2 in the machine code listing.

If the explanation seems murky so far, it’s O.K. to forget it for a while. Just take my word for it that the aforementioned code makes it appear that an interrupt will cause code to be executed at location FF08h. This is where our true interrupt handler is to be found. 

The handler begins with block #2, which saves all of the registers. We do this so that we can leave them as we found them when we’re done. This will ensure that we don’t disrupt the program that was running when the interrupt occurred. 

Block #3 reads-a small portion of the keyboard. We won’t cover keyboard scanning here (see SYNTAX Feb. 1984 for a tutorial on the subject) but block #3 causes block #4 to be skipped if the BREAK and SYMBOL SHIFT keys are not being pressed simultaneously. 

Block #4 causes the screen to be copied. Before CALLing the screen copy routine in ROM, we load B with the number of pixel lines to be copied. Changing this would allow us to COPY part of the screen. 

Block #5 prepares the computer to leave our interrupt handler. All registers are restored to their original values. Note that the first item that POPs off the stack is the last item that was PUSHed on. This means the registers must be restored in reverse order. 

Ordinarily an interrupt handler ends with RETI (similar to RET) instruction. In this case, we’ll end it with a JP 0038, which jumps to the normal interrupt handler. This allows the normal interrupt functions of keyboard scanning and updating the system variable FRAMES to be performed, 

You Mentioned Copying Only Part Of The Screen. How Is This Done? 

By loading a different number into the B register before CALLing the COPY routine. You can change the number of lines printed in the following way. Suppose that LINES=the number of lines of characters (from the top of the screen) that you want to COPY. Just POKE 65304, (8*LINES). The handler is now setup to COPY only part of the screen.

What Other Things Can An Interrupt Handler Do? 

By reading the system variable FRAMES, which is incremented every 1/60th of a second a nice real time clock can be made, that flashes the time up on some unused part of the screen, even when you’re running other programs. FRAMES isn’t updated when the interrupts are disabled, so the clock “stops” whenever you use cassette I/0, the T/S 2040 printer, or the BEEP command, and resumes when you are done. Still, it’s a free, “software only” clock. 

If the interrupt handler were linked to a hardware real tine clock, it wouldn’t stop at all. 

Among other uses is an item called a print spooler. Printers are very slow compared to the computers running them, and the computers spend most of their tine waiting while the printer is running. It’s possible to send LPRINT commands to a transfer area in memory, and have the interrupt handler “pick up” this data and print it one character per interrupt. 

This would allow the printer to run at up to 60 characters per second while you’re doing other things with your computer. In other words, you could be running or entering a program at the sase time as the computer is printing something else. Those who’ve used such a feature on an IBM PC or other computer will agree that it is a great time saver. 

Another use is a program that reads and “stacks up” keyboard entries before the computer requires them. When an INPUT is needed, it gets it from this stacked up data. This is called a keyboard buffer, and it’s also very convenient.

Since the interrupt is synchronized to the video display, it’s possible to change the BORDER color some fixed time after the interrupt, and obtain a “full screen horizon” that extends into the border area. The Spectrum game “Aquaplane” does this, but the required timing amay be different to make the effect work on the T/S 2068’s 60 Hertz interrupt. (The Spectrum uses a 50 Hertz interrupt.)

These are others that come immediately to wind. Other less obvious uses are out there. One that I’m considering involved ay software that makes BASIC work in the 64 column mode. Certain keyboard inputs cause the computer to change a system address table in an undesirable manner. I expect to use the interrupt to “change the table back” before any harm is done. 

Scroll to Top