Authors
Publication
Publication Details
Volume: 3 Issue: 4
Date
Pages
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.