--- title: "Interrupts" type: "article" slug: "interrupts-2" url: "http://localhost/article/interrupts-2/" markdown_url: "http://localhost/article/interrupts-2.md" published_at: "2024-02-14T03:48:34+00:00" modified_at: "2026-07-23T12:33:10+00:00" featured_image: url: "http://localhost/wp-content/uploads/2022/04/20230809-041332.jpg" excerpt: "А discussion of interrupts was a bit too advanced a subject to cover in detail in my book \"Introduction to 2068 Machine Code,\" since the beginning student has enough other things to learn, so here is a short discussion of them. There are two kinds of interrupts available for the Z80 CPU, the maskable (MI)…" category: - name: "The Data Expansion" slug: "the-data-expansion" taxonomy: "category" url: "http://localhost/category/periodicals/the-data-expansion/" post_tag: - name: "Best of Timex/Sinclair 2068 Articles and Documents" slug: "ts2068best" taxonomy: "post_tag" url: "http://localhost/tag/ts2068best/" - name: "TS 1000" slug: "ts1000" taxonomy: "post_tag" url: "http://localhost/tag/ts1000/" - name: "TS 2068" slug: "ts2068" taxonomy: "post_tag" url: "http://localhost/tag/ts2068/" - name: "Tutorial" slug: "tutorial" taxonomy: "post_tag" url: "http://localhost/tag/tutorial/" model: - name: "Timex/Sinclair 1000" slug: "ts-1000" taxonomy: "model" url: "http://localhost/model/ts-1000/" - name: "Timex/Sinclair 2068" slug: "ts-2068" taxonomy: "model" url: "http://localhost/model/ts-2068/" indiv: - name: "Lloyd Dreger" slug: "lloyd-dreger" taxonomy: "indiv" url: "http://localhost/indiv/lloyd-dreger/" publication_r: id: 50143 title: "The Data Expansion" type: "periodical" url: "http://localhost/periodical/the-data-expansion/" authors: "Lloyd Dreger" authors_r: - name: "Lloyd Dreger" slug: "lloyd-dreger" taxonomy: "indiv" url: "http://localhost/indiv/lloyd-dreger/" volume: "3" issue: "10" issues_articles: - id: 50236 title: "The Data Expansion v3 n10" type: "issue" url: "http://localhost/issue/the-data-expansion-v3-n10/" pages: "19-21" pubdate: "October 1986" archive_link: false --- # Interrupts А discussion of interrupts was a bit too advanced a subject to cover in detail in my book “[Introduction to 2068 Machine Code](http://localhost/book/introduction-to-ts-2068-machine-code-programming/),” since the beginning student has enough other things to learn, so here is a short discussion of them. There are two kinds of interrupts available for the Z80 CPU, the maskable (MI) and nonmaskable (NMI) interrupts. As the name implies, the maskable interrupt can be masked, which is another word for defeated. Machine code students will remember the disable interrupt (DI) and its opposite, the enable interrupt (EI). These commands only work on the maskable interrupt. Since а maskable interrupt comes along every 1/60th of a second, the Sinclair computers use this signal to refresh the screen. In addition, the 2068 also uses this signal to check the keyboard for an input. The ZX81/1000 computers have а SLOW (refresh the screen) mode and a FAST (don’t bother with the screen) mode, which obviously are but little more than enabling or disabling the maskable interrupt. Certain machine code routines, such as data or code transfers; must be done without an interrupt until finished. Forgetting to do an EI before coming out of code back to BASIC results in a dead keyboard, which is equivalent to a crash. HALT is another instruction which requires an interrupt to start the computer again. It works with either type of interrupt. However, since the MI can be disabled with the DI statement, the 1/60th second delay may not work on many programs. The NMI, on the other hand, always gets through. However, a word of caution is in order so read on. What really happens with a MI is that all the registers are saved and the machine jumps to address 56 (38H) and follows the instructions given there. When a return іs encountered, the registers are all restored as the machine goes back to working on whatever it was doing before the interrupt occurred. The NMI is a hardware or peripheral interrupt. A line inside the computer called NMI normally has 5 volts on it. If for any reason it temporarily goes low, like being grounded, a NMI has occurred. The registers are again all saved along with the status of the MI as the machine jumps to address 102 (66H). On the ZX81/1000 machine it checks for SLOW and continues without any provision for adding another NМІ routine. Оп the 2068, we have a problem as it checks for an address іп the system variable located at address 23728-23729. If you check your 2068 Users Manual, you will find that these addresses are not used. This is due to a bug in the next instruction іп the ROM (whether this bug is deliberate or not is open to some debate). The instruction in effect reads “jump to the address only if it is 0000,” effectively doing a wipeout or restart. If, for some reason, you poked something into this address, the NMI is ignored and a return to the program is made. This is NOT the way an NMI should work. The errant instruction at address 109 should be JR Z, not JR NZ. This change would cause the computer to return immediately if the NMI interrupt address at 23728/9 was 0000 or jump to the address contained there and handle the interrupt with a routine you could write, finally returning to the program when finished. Unfortunately, the error is in ROM and nothing short of burning a new ROM on an EPROM will permanently correct it. Unless… Unless you are NOT in the home bank. If you are in the dock bank with an LROS program, your technical manual states that you MUST write both a MI and NMI routine to handle interrupts at the addresses given above. If you are lucky enough to have an AERCO disk drive, you have 64K of the RAM in the dock bank at all times. Every time you use the disk drives you run the routines put there by the AERCO interface ROM. It, thus, would be possible to correct the NMI handling routine since the AERCO program first starts at address 256 with only the LROS identification, the MI, and NMI routines below address 256. There is only one problem with this and that is that the computer does not run BASIC programs from the dock bank, but from the home bank, so it spends most of its time іп the home bank and would use the home bank ROM NMI interrupt, with its error, most of the time. You are really, lucky with the RP/M version of the AERCO disk drive, as it is loaded and run exclusively from the dock bank. Of course, the present AERCO NMI routine would have to be rewritten to handle an automatic jump to an NMI handler routine. Why use the NMI? Certain peripheral devices, notably the keyboard, can give an NMI to the CPU indicating that they are in need of attention. Most computers use the NMI to indicate input coming from the keyboard. As you saw above, Sinclair computers use the MI to scan the keyboard. not the NMI, but that іs no reason to disable the NMI. Other devices such as a printer or a modem could be made to give an NMI when they need attention as well. For example, most printers have a 2K to 8K buffer which is loaded and then printed out. When empty, it is reloaded with the next batch, etc. All the time that the printer is emptying the buffer it is sending a signal saying “I’m busy, don’t send more yet.” The way it stands at present, the driver program monitors this signal in а wait loop and is really wasting time. Instead the ‘busy’ signal could be put on the NMI line thus freeing the CPU to do something else and return for another buffer reload only when needed. Or for another example. Your modem is monitoring the phone for calls. Nothing might happen for hours, but when it does the modem needs attention immediately. Or yet another, your computer is set up to play watchdog for your house, yet you would like to do an iterative program that takes hours to run overnight and have the answer in the morning. You could do both with а working NMI. Sinclair had the right idea with the NMI routine address at 23728. This routine with the same error is also in Spectrum ROM. Why did they chicken out? Reprinted from SMUG Bytes, August 1986.