Missed Interrupts with DI+IM2 in assembly
Re: Missed Interrupts with DI+IM2 in assembly
as soon as you enable interupts on other computers the interupt fires?
dont think its possible on spectrum
dont think its possible on spectrum
Re: Missed Interrupts with DI+IM2 in assembly
There are several techniques without disabling interrupts to work with data on the stack. Their application depends on the specific situation, if you give an example of how the stack can be used more precisely.
Re: Missed Interrupts with DI+IM2 in assembly
The Gate Array in the CPC holds the interrupt line until the Z80 acknowledges it, which is why you won't miss an interrupt there (well unless you DI for long enough that multiple interrupts fire). IIRC the Speccy, in contrast, just pulses the interrupt line at the start of the frame. That has the advantage that interrupt positioning is more reliable but does create the possibility of missing out if you happen to have interrupts disabled. There's also not really much control over them either, it's basically an on/off switch.
Re: Missed Interrupts with DI+IM2 in assembly
If your drawing code takes more time than one frame maybe split it into 2 parts and play music between them?
Re: Missed Interrupts with DI+IM2 in assembly
That's my understanding, if you miss the interrupt you miss it.keith56 wrote: ↑Sun Nov 26, 2017 3:04 am Hello there! I'm currently working on porting my Chibi Akumas game from the CPC to the ZX spectrum (and msx), things are going well, but one thing on the speccy has caught me out, so I thought I'd ask some advise on here!
Just to point out I'm using a custom interrupt handler using IM2, and do not use the firmware one in any way during gameplay
My game code 'Misuses' the stack pointer to fast fill areas of memory for sprites and screen clears, so obviously I need to disable interrupts during these times to avoid a horrible crash! On the CPC and MSX a missed interrupt occurs immediately after EI, but on the spectrum it seems that the missed interrupt never fires - which means the music is playing slowly!
I've had a look at the documentation, and I've not seen anything about changing how the 50hz interrupt fires,and I can think of some changes I can make to reduce the problem. But I thought I'd just ask on the offchance if there was some way of altering the way the Speccy fires it interrupts or detect when an interrupt was missed, of if I was totally misunderstanding things!
Game coding is going well, by the way, I should have some screenshots to show in the next few weeks!
Most people fit their stack routines around the interrupt by syncing to a HALT or similar, so they know it will never come during. Is that an option here?
You can't alter the way the int fires, or directly check if it was missed. If your int routine increased a counter you'd be able to tell if one hadn't happened yet, but I don't think that would help your problem.
Keen to see krt17's suggestions, I didn't realise it was possible.
Some of the suggestions how to play music in the Edge Grinder thread may help.
Re: Missed Interrupts with DI+IM2 in assembly
method 1
Code: Select all
;sprite out routine
ld c,(hl)
inc hl
ld b,(hl)
inc hl
ld sp,hl
....
pop bc
....
;------
int
ld (.memhl), hl
pop hl
ld (.memret), hl
ld (.memsp), sp
push bc
ld sp, intSp
.... ;player timer etc
.memhl equ $+1
ld hl, 0
.memsp equ $+1
ld sp, 0
ei
.memret equ $+1
jp 0
Re: Missed Interrupts with DI+IM2 in assembly
Two cases isn't a problem:
1. Screen clears. As a general rule, you're just writing to the screen, so a triggered interrupt isn't going to corrupt anything. Just make sure not to get too close to #4000 (read: the ROM) or perhaps some sort of upper status panel/s that aren't updated constantly.
2. Sprite/tile graphics based on reading graphics data using the stack like: POP DE: LD (HL),E: INC L: LD (HL),D: INC L ...
Designate a single register pair to use for the POP-reading across all your sprite routines, for instance DE. Make sure DE = (SP-2) all the while SP is being pointed to sprite graphics. In that case, when an interrupt comes, you know that (SP) will contain the return address, and DE will hold two bytes of the sprite data that are the previous contents of (SP). So it's just a matter of putting those two bytes back into (SP) and getting the return address (EX (SP),HL might be is useful here). As a general rule, this operation will do no damage if an interrupt occurs outside of sprite routines.
Anything else I'd probably attempt to tackle it from another angle, like separating the amounts of work differently across the frames and so on.
1. Screen clears. As a general rule, you're just writing to the screen, so a triggered interrupt isn't going to corrupt anything. Just make sure not to get too close to #4000 (read: the ROM) or perhaps some sort of upper status panel/s that aren't updated constantly.
2. Sprite/tile graphics based on reading graphics data using the stack like: POP DE: LD (HL),E: INC L: LD (HL),D: INC L ...
Designate a single register pair to use for the POP-reading across all your sprite routines, for instance DE. Make sure DE = (SP-2) all the while SP is being pointed to sprite graphics. In that case, when an interrupt comes, you know that (SP) will contain the return address, and DE will hold two bytes of the sprite data that are the previous contents of (SP). So it's just a matter of putting those two bytes back into (SP) and getting the return address (EX (SP),HL might be is useful here). As a general rule, this operation will do no damage if an interrupt occurs outside of sprite routines.
Anything else I'd probably attempt to tackle it from another angle, like separating the amounts of work differently across the frames and so on.
Inactive account
- 1024MAK
- Bugaboo
- Posts: 3123
- Joined: Wed Nov 15, 2017 2:52 pm
- Location: Sunny Somerset in the U.K. in Europe
Re: Missed Interrupts with DI+IM2 in assembly
The ULA in a ZX Spectrum generates a 64us (32 T-states) pulse at the being of the (non-visible section of the) TV/video field. Hence the frequency being 50Hz. The ULA does not hold the interrupt line active if the CPU ignores it and it does not provide any other interrupt facilities.
This interrupt from the ULA always occurs. It's operation is hard wired and so there are no configuration settings.
The Z80 CPU will only detect a maskable (normal) interrupt when it samples the /INT pin at the end of an instruction (assuming that /RESET, /BUSRQ and /NMI are all inactive and maskable interrupts are enabled and the instruction is not DI, EI or a instruction prefix). So if the interrupt pulse from the ULA ends before maskable interrupts are enabled, yes, your program will miss that interrupt.
Mark
This interrupt from the ULA always occurs. It's operation is hard wired and so there are no configuration settings.
The Z80 CPU will only detect a maskable (normal) interrupt when it samples the /INT pin at the end of an instruction (assuming that /RESET, /BUSRQ and /NMI are all inactive and maskable interrupts are enabled and the instruction is not DI, EI or a instruction prefix). So if the interrupt pulse from the ULA ends before maskable interrupts are enabled, yes, your program will miss that interrupt.
Mark
Standby alert
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Missed Interrupts with DI+IM2 in assembly
Tut-tut. Use the Force (of BBCode), Mark. It’s INT, RESET, BUSRQ, and NMI.
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Re: Missed Interrupts with DI+IM2 in assembly
Method 2
The basic idea is to store the checksums for all the blocks in which the reading through the stack is used. The interrupt routine considers the block checksum (add as a rule) and restores the value on the stack. Requires a little more memory (for checksums) and spends more tacts (~1400) in each interrupt. Usually blocks of 128 bytes are used. If it's not clear I can write a sample code.
The basic idea is to store the checksums for all the blocks in which the reading through the stack is used. The interrupt routine considers the block checksum (add as a rule) and restores the value on the stack. Requires a little more memory (for checksums) and spends more tacts (~1400) in each interrupt. Usually blocks of 128 bytes are used. If it's not clear I can write a sample code.
Re: Missed Interrupts with DI+IM2 in assembly
And I'd like to add one more, maybe obvious thing - you don't have to play music in interrupt routine
You can do it anywhere in your code, just do it during each frame. Some purists may say that if you call music player sometimes at frame beginning and sometimes at frame end then there would be loss of music quality. But I did it in my games before and nobody noticed and complained
You can do it anywhere in your code, just do it during each frame. Some purists may say that if you call music player sometimes at frame beginning and sometimes at frame end then there would be loss of music quality. But I did it in my games before and nobody noticed and complained
- 1024MAK
- Bugaboo
- Posts: 3123
- Joined: Wed Nov 15, 2017 2:52 pm
- Location: Sunny Somerset in the U.K. in Europe
Re: Missed Interrupts with DI+IM2 in assembly
Yeah, I knowAst A. Moore wrote: ↑Sun Nov 26, 2017 12:46 pmTut-tut. Use the Force (of BBCode), Mark. It’s INT, RESET, BUSRQ, and NMI.
But I composed this post off-line in a text editer. Then had to post in a rush, as channel 4's formula 1 coverage was about to start and I had a few other things to do before sitting down to watch it and eat lunch...
Mark
Standby alert
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
“There are four lights!”
Step up to red alert. Sir, are you absolutely sure? It does mean changing the bulb
Looking forward to summer later in the year.
- Ast A. Moore
- Rick Dangerous
- Posts: 2641
- Joined: Mon Nov 13, 2017 3:16 pm
Re: Missed Interrupts with DI+IM2 in assembly
You humans are so weird. You watch TV and each lunch. So bizarre.1024MAK wrote: ↑Sun Nov 26, 2017 7:12 pmYeah, I knowAst A. Moore wrote: ↑Sun Nov 26, 2017 12:46 pm Tut-tut. Use the Force (of BBCode), Mark. It’s INT, RESET, BUSRQ, and NMI.
But I composed this post off-line in a text editer. Then had to post in a rush, as channel 4's formula 1 coverage was about to start and I had a few other things to do before sitting down to watch it and eat lunch...
Mark
Every man should plant a tree, build a house, and write a ZX Spectrum game.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.
Author of A Yankee in Iraq, a 50 fps shoot-’em-up—the first game to utilize the floating bus on the +2A/+3,
and zasm Z80 Assembler syntax highlighter.