Re: Help Z180 Interrupt Vector INT0 Mode 2
- From: Jack Klein <jackklein@xxxxxxxxxxx>
- Date: Thu, 24 Nov 2005 23:22:07 -0600
On Thu, 24 Nov 2005 02:21:13 -0500, Tosca Berisha <tberisha@xxxxxxxx>
wrote in comp.arch.embedded:
> Jack, thank you.
>
> I see that a lot of things are not the way I understood from zilog docs.
OK, let's start from the beginning. I'm going to reply here to this
response, and to some of your other responses in the thread.
Let me repeat the summary of Mode 2, which the Z180 inherits
completely unchanged from the original Z80, and I used on the Z80 for
years.
Interrupt mode 2 allows you to have up to 128 different interrupt
service routines. The addresses of these routines must be stored in
an interrupt address table. The table more or less needs to start on
a 256 byte boundary. For this example, we'll use address 0xF000. The
high 8 bits of this address, 0xF0, is loaded into the processors I
register.
When the INT0 pin is triggered in mode 2, the processor generates an
interrupt acknowledge bus cycle. This cycle is recognized by
peripheral devices outside the chip because both MI and IORQ signals
go active (low) at the same time, something that never happens at any
other time. The processor automatically adds two wait states to this
cycle, and more wait states can be added by external devices.
During this interrupt acknowledge cycle, the highest priority
peripheral with an active enabled interrupt drives an 8-bit byte onto
the data bus. This should normally be an even value, 0x00, 0x02,
0x04, ... 0xFA, 0xFC, 0xFE. The Z180 documentation does not specify
that it must be even, but I think the original Z80 did.
The processor reads the value on the data bus at the end of the
interrupt acknowledge cycle and uses it and the contents of the I
register to make a full 16-bit address. It does this by putting the 8
bits in the I register into the top 8 bits of the address, and the
byte it just read on the data bus into the low 8 bits of the address.
Then it generates two memory accesses, to the address it just made and
to that address plus one, to fetch the 16-bit address of the interrupt
service routine. It pushes the program counter and clears the
interrupt enable flags and jumps to the address it just fetched.
As to why the table must start on a page boundary, just suppose it
started at the end of a page, for example at 0xE0FE. You will put the
address of your interrupt 0 handler at 0xE0FE, the address of your
interrupt 1 handler at 0xE100, interrupt 2 at 0xE102, and so on. You
can only put the 0xE0 into I register. So when the device that is
supposed to generate interrupt 2 responds to an interrupt acknowledge
cycle by putting 0x04 on the bus, the processor will concatenate this
with the I register and try to fetch an interrupt service routine
address from 0xE004, not 0xE102 where you have put it.
But all of this depends on having external devices that understand how
to operate with the Z80/Z180 bus and interrupt mode 2.
In the old days of the Z80, there were dedicated peripherals designed
for this, the PIO, the SIO, the DART, and the CTC. They were
connected to the M1 and IORQ signals of the processor, and recognized
the interrupt acknowledge cycle when both of these signals were active
at the same time. They even recognized when the processor fetched the
RETI instruction at the end of the interrupt service routine and reset
their internal interrupt logic.
Zilog also made some general purpose peripherals in the Z85xx family,
such as the Z8536 CIO and the Z8530 SCC, which could be used with the
processors with a little bit of external logic.
And with some logic chips or a PLD of some kind, you could use other,
non-Zilog devices with mode 2.
But to use mode 2, you must have one or more devices that recognize
the interrupt acknowledge cycle and put an even number, between 0x00
and 0xFE, on the bus.
Do you have such devices on your board? If you don't, you can't use
mode 2.
But the only reason to use mode 2 is if you have multiple devices
capable to generating their own unique vectors during the interrupt
acknowledge cycle.
If you only have one device that can generate the interrupt, or if you
have multiple devices but they don't support the interrupt acknowledge
vector sequence, the only sensible thing to do is use interrupt mode
1.
In mode 1, the processor does not perform an acknowledge cycle at all.
If just saves the program counter and sets the interrupt flags and
jumps to address 0x0038 to run the routing starting there.
If you have only a single device, your ISR does what is necessary to
service the device, clear the device's interrupt logic, and reset it
so it can generate another interrupt when it needs to.
If you have multiple devices that don't support the interrupt
acknowledge cycle, your mode 1 routine starting at 0x0038 will have to
check all the devices that can generate the interrupt and take care of
the device or devices that need service.
You asked:
> It is a key that triggers INT0. But I don't understand how to specify
> which element of the vector will be executed.
> The z180 pdf says that 8bits are read from the data bus. That value will
> determine the position the element in the Interrupt Vector. But how do
> we pecify that value? Is that a random value? O is it programmed into
> some register first? Which one?
I don't know what this key is connected to. If it is connected to
some Zilog compatible peripheral (PIO, SIO, DART, CTC) or
semi-compatible (CIO, SCC) device with additional logic, there is a
register in the device where you put the low byte of the address, and
it will output it during the interrupt acknowledge cycle. So yes, if
you have a device compatible with the Z80/Z180 mode 2 vectored
interrupts, you do program the value into a register, but in the
peripheral device, not the processor.
> Well, it is a key connected to a 3-state buffer and to the INT0 pin. How
> do you program it?
As I said before, since this is not part of a device that supports
mode 2 vectored interrupts, I would use mode 1. But the thing that
you need to remember is that INT0 is level sensitive. At the end of
every instruction cycle, the processor samples the INT0 pin. If it is
active (low), and interrupts are enabled, then it will respond to the
interrupt.
That means that something in your interrupt service routine must cause
the hardware to deactivate the INT0 pin, let it go high again, until
the key is released and pressed a second time. If not, as soon as
your interrupt service routine ends with the instructions EI and RET
or RETI, if the INT0 pin is still low, the processor will immediately
execute the interrupt service routine again.
I'd suggest you read the section on interrupts in the Z180 manual
again. The document I am looking at, the one currently available on
Zilog's web site, is "UM0050 Z8018x MPU Family User Manual".
The bit about starting the vector table on a 256 byte boundary is
mentioned in "Interrupt Vector Register (I)" on page 66.
Hope this helps.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
.
- References:
- Help Z180 Interrupt Vector INT0 Mode 2
- From: Tosca Berisha
- Re: Help Z180 Interrupt Vector INT0 Mode 2
- From: Jack Klein
- Re: Help Z180 Interrupt Vector INT0 Mode 2
- From: Tosca Berisha
- Help Z180 Interrupt Vector INT0 Mode 2
- Prev by Date: Re: Debugging assembly
- Next by Date: Re: VB6.0
- Previous by thread: Re: Help Z180 Interrupt Vector INT0 Mode 2
- Next by thread: Re: Help Z180 Interrupt Vector INT0 Mode 2
- Index(es):
Relevant Pages
|
|