Newsgroups: comp.sys.sinclair Path: vanilla!asbach!noris.net!blackbush.xlink.net!tank.news.pipex.net!pipex!oleane!jussieu.fr!math.ohio-state.edu!usc!howland.reston.ans.net!vixen.cso.uiuc.edu!newsfeed.internetmci.com!btnet!btnet-feed1!news.compulink.co.uk!cix.compulink.co.uk!usenet From: jritman@cix.compulink.co.uk ("Jon Ritman") Subject: Re: Interrupts: How do they work? Message-ID: Organization: Cranberry Source Limited References: <4rh83s$nqb@yama.mcc.ac.uk> Date: Tue, 9 Jul 1996 10:47:15 GMT X-News-Software: Ameol Lines: 46 > > So if you want to have ISR you must do the following steps: > > >- create ISR which must either DISABLE INTERRUPTS on its start or > > take less than about 60000 processor tacts (to prevent endless loop) > > Actually, you don't need the DI at all -- namely because interrupts > are automatically disabled at the start of an interrupt service. Check > the manual - I assure you it does it. I repeat - the 50hz display interrupt is non-maskable, it can't be stopped short of un soldering the Z80 pin (I don't recommend this ;-) If your routine does last more than 1/50th of a second then a 2nd interrupt will occur - what does happen is that lower level interrupts (maskable ones) are disabled automatically but since you can't use these in a speccy that wont effect you. The standard way to use the interrupt is to use interrupt mode 2 (instruction IM 2) and build a vector table (If I remember rightly you have to point the I register at the page with the table) to jump into your routine - bear in mind that on a real speccy many joysticks have been badly designed so that they issue joystick reads when the Z80 asks for a vector offset (they ignore the state of one of the control lines, I believe I was the first person to ever work this out:-) - this means that you can't rely on FFh being returned and have to build a 257 byte vector table full of the same value - this in turn mean that the final location of your routine (or another jump instruction) must be something like 9898h or FEFEh. So to use mode 2 -------------------------------------------------------- ld a,high table ;load the A reg with the high 8 bits of 'table' ld i,a im 2 ;or im2 for some assemblers ----- ;and in memory at ??00h - it's very important this is on a page boundary table: db 257 Dup (FEh) ;creates 257 byte table full of FEh ;and in memory at FEFEh jp service_routine ;or the service routine itself -------------------------------------------------------- Cheers Jon Ritman ---- Path: vanilla!asbach!noris.net!blackbush.xlink.net!tank.news.pipex.net!pipex!usenet.eel.ufl.edu!warwick!lyra.csx.cam.ac.uk!mgr11 From: mgr11@cus.cam.ac.uk (M.G. Rison) Newsgroups: comp.sys.sinclair Subject: Re: Interrupts: How do they work? Date: 9 Jul 1996 14:41:40 GMT Organization: University of Cambridge, England Lines: 37 Sender: rison@hep.phy.cam.ac.uk Message-ID: <4rtr34$isu@lyra.csx.cam.ac.uk> References: <4rh83s$nqb@yama.mcc.ac.uk> Reply-To: rison@hep.phy.cam.ac.uk NNTP-Posting-Host: ursa.cus.cam.ac.uk En la artikolo , Jon Ritman skribis: > > > So if you want to have ISR you must do the following steps: > > >- create ISR which must either DISABLE INTERRUPTS on its start or > > > take less than about 60000 processor tacts (to prevent endless loop) > > Actually, you don't need the DI at all -- namely because interrupts > > are automatically disabled at the start of an interrupt service. Check > > the manual - I assure you it does it. > I repeat - the 50hz display interrupt is non-maskable, it can't be > stopped short of un soldering the Z80 pin (I don't recommend this ;-) > If your routine does last more than 1/50th of a second then a 2nd > interrupt will occur - what does happen is that lower level interrupts > (maskable ones) are disabled automatically but since you can't use these > in a speccy that wont effect you. > The standard way to use the interrupt is to use interrupt mode 2 > (instruction IM 2) and build a vector table (If I remember rightly you > have to point the I register at the page with the table) to jump into > your routine > [...] OK, I'm now totally confused! If the 50 Hz interrupts are NMIs, then they'll cause a CALL to &66, irrespective of the IM and/or the value of I, no? Or is there some wacky code at &66 which makes it do the IM2 MI behaviour (don't see how it could grab the databus byte, though)? Mark, who wonders how bad it is on a ZX81... P.S.: Why &66? Why not &80, or &40, or &65, or &67, or ... ? ====================================================================== | rison@hep.phy.cam.ac.uk | Esperanto - lingvo inter-nacia | | rison@vxcern.cern.ch | * Mi estas riisto * | ====================================================================== ---- Path: vanilla!asbach!noris.net!blackbush.xlink.net!tank.news.pipex.net!pipex!news.mathworks.com!news-res.gsl.net!news.gsl.net!usenet.eel.ufl.edu!warwick!yama.mcc.ac.uk!usenet From: simon.cooke@umist.ac.uk (Simon Cooke) Newsgroups: comp.sys.sinclair Subject: Re: Interrupts: How do they work? Date: Tue, 09 Jul 1996 23:01:14 GMT Organization: Entropy Technology Lines: 26 Message-ID: <4rts73$e03@yama.mcc.ac.uk> References: <4rh83s$nqb@yama.mcc.ac.uk> NNTP-Posting-Host: annex1-2.mcc.ac.uk X-Newsreader: Forte Free Agent 1.0.82 jritman@cix.compulink.co.uk ("Jon Ritman") wrote: >> > So if you want to have ISR you must do the following steps: >> >> >- create ISR which must either DISABLE INTERRUPTS on its start or >> > take less than about 60000 processor tacts (to prevent endless loop) >> >> Actually, you don't need the DI at all -- namely because interrupts >> are automatically disabled at the start of an interrupt service. Check >> the manual - I assure you it does it. >I repeat - the 50hz display interrupt is non-maskable, it can't be >stopped short of un soldering the Z80 pin (I don't recommend this ;-) >If your routine does last more than 1/50th of a second then a 2nd >interrupt will occur - what does happen is that lower level interrupts >(maskable ones) are disabled automatically but since you can't use these >in a speccy that wont effect you. Jon... what *exactly* do you mean by non-maskable? Because on the Speccy, the 50Hz interrupt doesn't go into the NMI line - it goes into the INT line of the Z80. Therefore doing a DI will disable the 50hz display interrupt. Si ---- Newsgroups: comp.sys.sinclair Subject: Re: Interrupts: How do they work? Followup-To: comp.sys.sinclair Reply-To: kio@vanilla.nbg.sub.org References: Distribution: world Organization: private Keywords: Summary: (1) Jon Ritman's INT/NMI mixup (2) thoughts about RET/RETI (3) Q: timing of the INT generated by the ULA (1) In article , "Jon Ritman" writes: > >I repeat - the 50hz display interrupt is non-maskable, it can't be >stopped short of un soldering the Z80 pin (I don't recommend this ;-) > >If your routine does last more than 1/50th of a second then a 2nd >interrupt will occur - what does happen is that lower level interrupts >(maskable ones) are disabled automatically but since you can't use these >in a speccy that wont effect you. > I have just polled news and the last follow-up to this thread is 5 days old :-( so Jon will most probably be already corrected again. But i cannot resist to respond for myself: Jon is definitely wrong in this point: The NMI is not used in a non-expanded ZX Spectrum, though the NMI line is connected to the rear connector, and it's service routine at address $0066 (which the Z80 CPU always calls when the NMI line is activated) contains the 'famous' and probably intended bug which will only branch to a custom service routine if you decide it to be at address $0000. The 50 Hz interrupt generated by the ULA with every screen fly-back is connected to the maskable INT line. When the Z80 CPU services the interrupt, further interrupt requests are automatically masked off. As long as you do not re-enable them with an EI instruction, further interrupts will not interrupt your interrupt handling routine itself. This is even true if you put the highly recommended EI plus RET instruction combination at the end of your interrupt handler, because interrupts are still disabled between EI and the following instruction. This prevents potential stack overflow at this point. If you call the original ROM routine from your own routine, you must be aware that it executes the EI instrction at it's end. If you call it first in your interrupt handler and then go into longish own routines, you have a high risk of getting your interrupt handler re-interrupted if you don't DI interrupts again. You may even get a stack overflow if you end your private interrupt handler with RST 56 plus RET, because after the RET of the original interrupt handler and _before_ the RET of your private interrupt handler the next interrupt will be processed. Therefore you should do a JP $0056 instead - which is faster too. (2) The original interrupt service routine in the ZX Spectrum ROM ends with a normal RET instruction and not with RETI. Therefore you cannot use the daisy chain feature of Z80 peripheral chips at all - except if you supply a patched ROM too. Therefore interrupt service routines for games et al never need to end with RETI. The faster and shorter RET will always be fine. (3) Question: How long does the ZX Spectrum ULA activate the INT line? Is there a timing limit or is the INT line kept active until the Z80 processes the interrupt? ... KIO ! -- My computers work fine with NAND and NOR but refuse work with BILL Gates. Any help appreciated... email: kio@vanilla.nbg.sub.org ftp://lst.informatik.uni-erlangen.de//incoming/kio/readme