Join GitHub today
GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.Sign up
INT0 IM1 & RET - Hangs - Help Wanted #117
I'm trying to write an interrupt service routine (ISR) which is driven by INT0 in IM1 mode.
In initialising (all) the RST and IM1 jump locations I've put RET (C9) instructions as standard practice. for the APU, I insert the RET at the jump location 0x3800.
My issue is that as soon as I try to remove or replace the INT0 RET instruction, the machine hangs.
I've confirmed that the ISR is not broken. It works as expected when called from another program.
I've tried to establish the ISR with interrupts generally disabled (DI), and with them enabled but turned off for INT0. No difference.
OK. Definitely its a hardware problem, you'd think. Something holding the INT0 line low, causing infinite interrupts.
I've found no reference on the Internet for anyone having this kind of issue, and I'm at a loss.
It seems that the sentient machine is waiting patently for a window to escape out of (the INT0 RET), and as soon as it is removed, it is gone!
Any help or suggestion welcome, please.
You may not be able to get away with a RET to terminate ISRs on the z180. Try using the proper RETI instead.
A RET is not going to work for im2-aware devices. It was never 'right' on the z80 either but the z80 does not have im2 hardware built in, unlike the z180 which is im2 aware all the way through.
Good catch. Thanks.
Even though INT0 is disabled in ITC register, and there is no external trigger being applied. The location for the INT0 IM1 jump at
As soon as I remove the RET (C9) at
Might need to work on a simple replication... too many pieces of code at play here.
Experimenting with code fragments. It is not so simple.
The mystery for me is why is the ISR being run at all, without an INT0 signal.
I guess I'll just work on fixing the ISR, and perhaps it will become obvious what's happening.
This really is the bug that keeps on giving.
I was still getting lots of interrupts to the APU, which was not good, so I decided that I needed to be a bit more robust with the Z80 interrupt jump table. So I implemented one. Pretty standard. Just builds a prototype at 0x0040 in ROM, and then copies it during INIT to 0x2000. I've moved some buffers around and it all works good on the RC2014, and on YAZ180.
The connection to this issue became apparent when I improved the code by correctly inserting an EI before the RETI in the jump location for a null interrupt INT0. Somehow the EI wasn't working for the Z180 based machine, but it was for the Z80 machine. Hmm. Curious, and connected.
Here's the trap which I fell into.
What these things mean is that if the Program Counter gets to any unusual locations, then a RST 38 jump to the INT0 code is executed. Which would just RET if the INT0 code said to.
So it was not spurious INT0 calls that are the problem, but rather executing RST 38 instructions.
That explains so much. Two days to get to this point... But, doesn't fix the problem.
First step to fixing the problem is to fill free ROM space with 76 bytes, which is the Op Code for HALT. Then I could see which address was being jumped to, because the TIL311 address display on the YAZ180 just shows me.
The problematic destination is 0x00C3.
And, this bad jump happens after three bytes of printing. Knowing that the TX0 routine does immediate printing for the first two bytes, and then uses the buffer for the following bytes, it should be simple to find the issue, right?
Well not... I'm still looking for a loose RET or similar that could pop the PC at the wrong time. And it is not easy to find where the code starts executing out of the normal bounds.
I've spent the last 8 days looking at this code. And, I still can't see what is causing the bad jump. There's nothing that I can see is affecting the
Something is pushing
Any sanity preserving input, gratefully accepted.
In fact, it is failing after the third character is transmitted. The first two characters slip straight into the TX0 immediate transmit case (as the ASCI is double buffered)., The third character is the first run through the TX0 buffer code where the TEI flag sets the Tx interrupt, and then the ASCI interrupt,
Therefore it must be something in the interrupt code or the TX0 code that causes a jump to 0x00C3.
My issue is that I can't find anything that would cause that jump, and no reference to 0xC3 anywhere which could get it incorrectly loaded into
Finally, I've resolved my issue.
Somewhat embarrassed to leave this here for Internet eternity.
That cost so much time. But at least on the up side, I've written robust Z80 and Z180 vector tables, improved the ASCI code, and cleaned up initialisation code, in trying to track this down.