CPCWiki forum

General Category => Programming => Topic started by: Arnaud on 21:38, 05 May 20

Title: Should disable interrupt when using ex (sp), hl
Post by: Arnaud on 21:38, 05 May 20
Hi,
i think i have found rare and totally random bug in my code, i solved it by disable interrupt when using ex (sp), hl

Is mandatory to disable interrupt with a "classic" use of the stack with using pop / push / ex (sp), hl simply to store data ?

Arnaud
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: andycadley on 21:52, 05 May 20
As long as your interrupt routine correctly manages the stack (i.e. POPs the same number of things it PUSHes), no it shouldn't be. But if you're doing something funky like abusing the stack pointer as a fast way of clearing memory then you probably don't want an interrupt routine cutting in and messing up memory you weren't expecting.
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: Arnaud on 21:55, 05 May 20
And for ex (sp), hl the code exchange hl with sp value which was potentialy modified in interrupt ?
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: andycadley on 22:01, 05 May 20
Like I say, it shouldn't matter because the effect of the ISR (aside from trashing stack memory) should be entirely transitory. Once it returns, assuming every register it uses was preserved and all PUSH/POPs match, the registers should all be in the same state as they were before it started. It's more likely that either the ISR is using registers it doesn't preserve, trashing memory that is important or some other kind of race condition that disabling interrupts is hiding.
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: Arnaud on 22:04, 05 May 20
Ok thanks.
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: GUNHED on 23:27, 05 May 20
ex (sp),hl can be a killer as soon as the next POP or RET will follow.
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: andycadley on 00:25, 06 May 20
ex (sp),hl can be a killer as soon as the next POP or RET will follow.
But the ISR will always PUSH a return address first and the PUSH//POP the same amount of data. The status of the stack should be unchanged once an ISR completes, regardless of whether an EX (SP), HL was done beforehand or not as the Z80 can't interrupt mid-instruction.
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: GUNHED on 12:59, 06 May 20
But the ISR will always PUSH a return address first and the PUSH//POP the same amount of data. The status of the stack should be unchanged once an ISR completes, regardless of whether an EX (SP), HL was done beforehand or not as the Z80 can't interrupt mid-instruction.

That's not the point. Imagine the following two situations f.e.:

LD DE,API_Entry
PUSH DE ;store return address
EX (SP),HL ;store
RET


or....


CALL XXX
...

XXX EX (SP),HL
...
RET


Some games have that kind of constructions.
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: andycadley on 17:42, 06 May 20
Still doesn't matter.


No matter which of the instructions in that sequence is proceeded by an interrupt, the end result will be exactly the same as long as the ISR properly manages the stack.
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: GUNHED on 18:23, 06 May 20
Well, the RET does POP an element from the stack into SP. If this element was exchanged before, the CPU will not RETurn, instead it will jump somewhere else. Just give it a try with you assembler or choice.  :)
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: andycadley on 18:52, 06 May 20
I know. it doesn't change anything though.


Imagine the following code:


PUSH HL
RET


Which, effectively, jumps to HL via the stack.


Now imagine the same code, but that an interrupt occurs right between the two commands:

Before the interrupt, HL is on the top of the stack.
*interrupt occurs*
The Z80 PUSHes the return address so that becomes the top of the stack. A well behaved ISR can PUSH/POP whatever it likes and as long as the sequence is balanced it will end with the return address at the top of the stack.


Finally the ISR does a RET, popping it's return address off the stack. At this point the value of HL will once again be the value on the stack
*interrupt handling complete*


The previous code continues at the RET, which fetches HL from the stack and jumps to it.




The sequence for the interrupted code is logically the same regardless of if/when an interrupt occurs. This will always be the case as long as the following are true:


* The stack hasn't been moved to point at memory that mustn't (or can't) be written too.
* The ISR doesn't trash any registers (unless the overall system design allows it to - f.e. reserving the alternate register set for ISRs)
* There is sufficient stack space so the it doesn't clobber something else (or worse some other called code clobbers the stack) 
 
Title: Re: Should disable interrupt when using ex (sp), hl
Post by: GUNHED on 23:51, 06 May 20
Seems we're talking slightly different topics.