Missed Interrupts with DI+IM2 in assembly

The place for codemasters or beginners to talk about programming any language for the Spectrum.
User avatar
keith56
Berk
Posts: 7
Joined: Mon Nov 13, 2017 9:23 pm

Missed Interrupts with DI+IM2 in assembly

Post by keith56 » 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!
0 x
Chibi Akuma(s) Comedy-Horror 8-bit Bullet Hell shooter for CPC - http://www.chibiakumas.com
「チビ悪魔」可笑しいゴシックSTG: http://www.chibiakuma.com
Chibi Akumas Episode 2:Confrontation for CPC ...Out Now!

Wall_Axe
Dizzy
Posts: 58
Joined: Mon Nov 13, 2017 11:13 pm

Re: Missed Interrupts with DI+IM2 in assembly

Post by Wall_Axe » Sun Nov 26, 2017 5:43 am

as soon as you enable interupts on other computers the interupt fires?
dont think its possible on spectrum
0 x

krt17
Berk
Posts: 7
Joined: Wed Nov 22, 2017 6:54 pm

Re: Missed Interrupts with DI+IM2 in assembly

Post by krt17 » Sun Nov 26, 2017 7:47 am

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.
0 x

AndyC
Berk
Posts: 15
Joined: Mon Nov 13, 2017 5:12 am

Re: Missed Interrupts with DI+IM2 in assembly

Post by AndyC » Sun Nov 26, 2017 8:26 am

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.
0 x

Ralf
Microbot
Posts: 148
Joined: Mon Nov 13, 2017 11:59 am
Location: Poland

Re: Missed Interrupts with DI+IM2 in assembly

Post by Ralf » Sun Nov 26, 2017 9:14 am

If your drawing code takes more time than one frame maybe split it into 2 parts and play music between them?
0 x

User avatar
R-Tape
Site Admin
Posts: 287
Joined: Thu Nov 09, 2017 11:46 am

Re: Missed Interrupts with DI+IM2 in assembly

Post by R-Tape » Sun Nov 26, 2017 9:17 am

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!
That's my understanding, if you miss the interrupt you miss it.

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.
0 x

krt17
Berk
Posts: 7
Joined: Wed Nov 22, 2017 6:54 pm

Re: Missed Interrupts with DI+IM2 in assembly

Post by krt17 » Sun Nov 26, 2017 9:38 am

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			
0 x

Hikaru
Dizzy
Posts: 56
Joined: Mon Nov 13, 2017 1:42 pm
Location: Russia
Contact:

Re: Missed Interrupts with DI+IM2 in assembly

Post by Hikaru » Sun Nov 26, 2017 9:53 am

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.
0 x

User avatar
1024MAK
Dizzy
Posts: 52
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

Post by 1024MAK » Sun Nov 26, 2017 12:27 pm

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
0 x

User avatar
Ast A. Moore
Dizzy
Posts: 79
Joined: Mon Nov 13, 2017 3:16 pm

Re: Missed Interrupts with DI+IM2 in assembly

Post by Ast A. Moore » Sun Nov 26, 2017 12:46 pm

1024MAK wrote:
Sun Nov 26, 2017 12:27 pm
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
Tut-tut. Use the Force (of BBCode), Mark. It’s INT, RESET, BUSRQ, and NMI. :D
2 x
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.

Post Reply