Z80 interrupt mode 2

Page 1/4
| 2 | 3 | 4

By abiliojr

Supporter (8)

abiliojr's picture

01-08-2018, 06:09

I've been reading about the Z80 for my current project of implementing a cartridge for the MSX (see my previous post), specially about interrupts. I've read that the MSX is able to support mode 2 interrupts, but I wonder how this happens in the MSX:

Imagine the following situation: two cartridges can at the same time trigger an interrupt request. When the time comes to put in the Data bus the 8-bit vector, how can each cartridge tell it is it's turn (in my nms8245 schematic seems to me all lines are tied together in an open collector fashion). Data lines are not open collector in the chips normally used in the cartridge, and two peripherals, one driving the line high and the other driving the line low can mean nothing but trouble. In other Z80 designs, I see the use of daisy chained interrupt lines.

What am I missing?

Login or register to post comments

By Grauw

Ascended (10146)

Grauw's picture

01-08-2018, 08:51

Nothing, the MSX architecture doesn't support IM2, for the reason you described. The data bus isn't even guaranteed to have pullups so interrupts from non-IM2 devices can end up all over the place (even at odd addresses). The only device that I know of which can service an interrupt vector to the Z80 is the Yamaha SFG FM sound module, and I guess as long as it is the only one such device in an MSX with pullups then it sorta works, but yeah it really doesn't (and afaik nobody uses that function).

However software does sometimes use IM2 on the MSX, in order to pre-empt the BIOS interrupt handler when it is desirable to have faster interrupt response than the H.KEYI hook can offer, e.g. for line splits or MIDI data receiving. It's a bit cumbersome, you gotta fill the entire table +1 with an entry address where the hi and lo byte are the same, but it works. In DOS it's much easier, you can just hook 38H directly.

By DarkSchneider

Paladin (942)

DarkSchneider's picture

01-08-2018, 09:07

@Grauw sure it does not support to send a value? It would be interesting to check creating a jump table with different values and look the address called at different interrupts (VPD, cartridges, etc.).

If not, is a total waste IMO. IM2 is perfect for dispatching the devices interrupts in a clear and fast way, with each one sending its own value. If not, you have to check on the common one the origin with flags registers from any device, a waste.

By Grauw

Ascended (10146)

Grauw's picture

01-08-2018, 09:42

You mean the SFG? It does, you can set it at addresses 3FF3H and 3FF4H. It’s a function of the YM2148 (although I haven’t tried it myself). It’s just that on the MSX architecture it’s hardly reliable.

IM2 itself is nice, but it requires more logic to implement in hardware so makes it more expensive to create interrupt generating cartridges, and it’s not compatible with the MSX cartridge slot design, so it’s not used by the MSX. I believe PC does use a IM2-like interrupt mode, but I don’t think we’re so terribly off, there’s typically not so many interrupt-capable devices active anyway, and if you put the handler for the one that delivers the most frequent interrupts in front, that gives a pretty decent response time.

By DarkSchneider

Paladin (942)

DarkSchneider's picture

01-08-2018, 09:43

I meant the MSX itself. Then external devices cannot generate value, a big mistake. What about internal devices, like VDP? Maybe it sends a fixed value other than 0.

By Grauw

Ascended (10146)

Grauw's picture

01-08-2018, 09:48

Devices can put stuff on the data bus, the problem is that if there's two interrupts active at a time, there is no way to prevent a bus conflict. The logic and system architecture to deal with that case is not present. So that's why it's inherently not usable.

No interrupt generating devices other than the SFG put anything on the data bus on interrupt acknowledge.

By DarkSchneider

Paladin (942)

DarkSchneider's picture

01-08-2018, 09:53

According to this guy, Z80 disables interrupts when one is triggered, so there should not be confilct, simply the 2nd one would not be attended.

http://codersbucket.blogspot.com/2015/04/interrupts-on-zx-spectrum-what-are.html

Quote:

EI but not DI?

There is another oddity in the interrupt routine, we have an EI at the end but we never do a DI. This is due to the fact the Z80 will do an internal DI when it starts processing the interrupts. The reason for this is to stop multiple interrupts triggering on top of each other and overrunning the system stack. You can do an EI before the end of your interrupt routine if you wish but general practice is to wait until you have finished then enable them, that way there is no chance of you starting a new interrupt routine before the old one has finished.

Not sure if that is true. And what could happen in this case. I suppose the problem is not having a daisy chained system.

By abiliojr

Supporter (8)

abiliojr's picture

01-08-2018, 10:13

My question was more from the electrical point of view, as I remember reading in a few places that the MSX supports interrupt mode 2, which seems inconceivable to me from the electrical point of view if the devices have no way to identify that the ACK belongs to themselves, risking to drive the data lines both to 1 and to 0 at the same time, and I was wondering if I was missing something.

By Grauw

Ascended (10146)

Grauw's picture

01-08-2018, 10:15

DarkSchneider wrote:

According to this guy, Z80 disables interrupts when one is triggered, so there should not be confilct, simply the 2nd one would not be attended.

That’s fine, that’s why IM0 works with simultaneous interrupts. But for IM2, the CPU needs to ask the interrupting device to put an interrupt vector on the bus, and in the MSX architecture the CPU can not ask specific devices, it can only broadcast such a request. Which it does, so all interrupting devices that implement an IM2 vector would put their interrupt vector on the bus at once, and you would get a bus conflict. So on MSX devices don’t do this, except for the SFG (I guess just because it was already present in the YM2148 and they thought it would be nice to hook it up despite it being useless).

By abiliojr

Supporter (8)

abiliojr's picture

01-08-2018, 10:23

Ok, then, my second question is: How does the interrupt handler identify which device caused the interrupt?

I'm still starting to get around the available documentation, but so far I believe most of it must be available in languages other than English. Any good suggestions on technical documentation for things like the BIOS, video, and sound chips? I found something that seems to be "The Book" for the MSX but sadly it was in Japanese.

By DarkSchneider

Paladin (942)

DarkSchneider's picture

01-08-2018, 11:01

The only way seems to be setting some kind of flag to be read by the CPU at the common ISR.

So, your cartridge triggers and interrupt by any reason, it set internally a flag somewhere, then in the ISR the program must check all the interrupts it handles, i.e. the VDP S#1 register if handles VDP line interrupts, and your device flag if it handles it.

Then, you have to put on documentation if the flag is auto-reset or not, so the software could reset it by its own writing on it. I.e. the VDP S#0 register is reset when readed.

IMO is wasting the Z80 capabilities, but is what we have.

Page 1/4
| 2 | 3 | 4