How do interrupts work on the Intel 8080? I have searched Google and in Intel's official documentation (197X), and I've found only a little description about this. I need a detailed explanation about it, to emulate this CPU.
The 8080 has an Interrupt line (pin 14). All peripherals are wired to this pin, usually in a "wire-OR" configuration (meaning interrupt request outputs are open-collector and the interrupt pin is pulled high with a resistor). Internally, the processor has an Interrupt Enable bit. Two instructions, EI and DI, set and clear this bit. The entire interrupt system is thus turned on or off, individual interrupts cannot be masked on the "bare" 8080. When a device issues an interrupt, the processor responds with an "Interrupt Acknowledge" (~INTA) signal. This signal has the same timing as the "Memory Read" (~MEMR) signal and it is intended to trigger the peripheral device to place a "Restart" instruction on the data bus. The Interrupt Acknowledge signal is basically an instruction fetch cycle, it occurs only in response to an interrupt.
There are eight Restart instructions, RST 0 - RST 7. RST 7 is opcode "0xFF". The Restart instructions cause the processor to push the program counter on the stack and commence execution at a restart vector location. RST 0 vectors to 0x0000, RST 1 vectors to 0x0008, RST 2 vectors to 0x0010 and so on. Restart 7 vectors to 0x0038. These vector addresses are intended to contain executable code, generally a jump instruction to an interrupt service routine. The Interrupt Service Routine will stack all of the registers it uses, perform the necessary I/O functions, unstack all the registers and return to the main program via the same return instruction that ends subroutines (RET, opcode 0xC9).
Restart instructions are actual opcodes, meaning they will do the same thing if they are fetched from memory during program execution. It was convenient to use Restart 7 as "warm restart" for a keyboard monitor / debugger program because early EPROMs generally contained 0xFF in each blank location. If you were executing blank EPROM, that meant something had gone awry and you probably wanted to go back to the monitor anyway.
Note that RST 0 vectors to the same memory location as RESET, both start executing at 0x0000. But RST 0 leaves a return address on the stack. In a way, RESET can be thought of as the only non-maskable interrupt the 8080 had.
An interrupt signal will also clear the Interrupt bit so an Interrupt Service Routine will need to execute an EI instruction, generally immediately before the RET. Otherwise, the system will respond to one and only one interrupt event.
CP/M reserved the first 256 bytes of memory for system use -- and that interrupt vector map used the first 64 bytes (8 bytes per Restart instruction). On CP/M systems, RAM started at 0x0000 and any ROM lived at the top end of memory. These systems used some form of clever bank switching to switch in an EPROM or something immediately after a RESET to provide a JUMP instruction to the system ROM so it could begin the boot sequence. Systems that had ROM at the low end of the memory map programmed JUMP instructions to vectors located in RAM into the first 64 bytes. These systems had to initialize those RAM vectors at startup.
The 8080 was dependent on external hardware to control its handling of interrupts, so it is impossible to generalize. Look for information on the Intel 8214 or 8259 interrupt controllers.
I finally find it!
I create a variable called bus where interruption opcode goes.
Then, I called a function to handle the interruption:
void i8080::interruption()
{
// only for RST
cycles -= cycles_table[bus];
instruction[bus]();
INT = false;
}
INT is true when needs an interruption.
EI and DI instructions handle INTE.
When INT and INTE is true interruption is executed.
Function pointers to the interrupt handlers are stored in the low memory.
Some 32 or so of the first addresses are hardware interrupts: hardware triggered.
The next 32 or so address are user-triggerable, these are called software interrupts. They are triggered by an INT instruction.
The parameter to INT is the software interrupt vector number, which will be the interrupt called.
You will need to use the IRET instruction to return from interrupts.
It's likely you should also disable interrupts as the first thing you do when entering an interrupt.
For further detail, you should refer to the documentation for your specific processor model, it tends to vary widely.
An interrupt is a way of interrupting the cpu with a notification to handle something else, I am not certain of the Intel 8080 chip, but from my experience, the best way to describe an interrupt is this:
The CS:IP (Code Segment:Instruction Pointer) is on this instruction at memory address 0x0000:0020, as an example for the sake of explaining it using the Intel 8086 instructions, the assembler is gibberish and has no real meaning...the instructions are imaginative
0x0000:001C MOV AH, 07
0x0000:001D CMP AH, 0
0x0000:001E JNZ 0x0020
0x0000:001F MOV BX, 20
0x0000:0020 MOV CH, 10 ; CS:IP is pointing here
0x0000:0021 INT 0x15
When the CS:IP points to the next line and an INTerrupt 15 hexadecimal is issued, this is what happens, the CPU pushes the registers and flags onto the stack and then execute code at 0x1000:0100, which services the INT 15 as an example
0x1000:0100 PUSH AX
0x1000:0101 PUSH BX
0x1000:0102 PUSH CX
0x1000:0103 PUSH DX
0x1000:0104 PUSHF
0x1000:0105 MOV ES, CS
0x1000:0106 INC AX
0x1000:0107 ....
0x1000:014B IRET
Then when the CS:IP hits on the instruction 0x1000:014B, an IRET (Interrupt RETurn), which pops off ALL registers and restore the state, is issued and when it gets executed the CPU's CS:IP points back to here, after the instruction at 0x0000:0021.
0x0000:0022 CMP AX, 0
0x0000:0023 ....
How the CPU knows where to jump to a particular offset is based on the Interrupt Vector table, this interrupt vector table is set by the BIOS at a particular location in the BIOS, it would look like this:
INT BIOS's LOCATION OF INSTRUCTION POINTER
--- --------------------------------------
0 0x3000
1 0x2000
.. ....
15 0x1000 <--- THIS IS HOW THE CPU KNOWS WHERE TO JUMP TO
That table is stored in the BIOS and when the INT 15 is executed, the BIOS, will reroute the CS:IP to the location in the BIOS to execute the service code that handles the interrupt.
Back in the old days, under Turbo C, there was a means to override the interrupt vector table routines with your own interrupt handling functions using the functions setvect and getvect in which the actual interrupt handlers were re-routed to your own code.
I hope I have explained it well enough, ok, it is not Intel 8080, but that is my understanding, and would be sure the concept is the same for that chip as the Intel x86 family of chips came from that.
Related
If I have a set of peripherals in an AVR microcontroller with equal priority, does the microcontroller use round-robin as a suitable arbitration mechanism for interrupting the sub system?
Or else, how can it manage interrupts with the same priority that happen at same time?
It depends.
For example "classical" AVR microcontrollers have simple one-level interrupt controller. That means, when interrupt is running, interrupt flag in SREG is cleared, thus blocking any other interrupt from running. IRET instruction enables this flag back again, and
after one instruction from the main code is executed, next interrupt is ready to be executed.
When several interrupt requests are asserted simultaneously, then only the one with the lowest interrupt vector address is chosen.
For example, refer to the ATMega328P datasheet (section 6.7 Reset and Interrupt Handling, page 15):
The lower the address the higher is the priority level.
Thus, if interrupt request flag is not cleared, or reasserted before return of the interrupt handler, the same interrupt will run again, and interrupt handlers with higher interrupt vector addresses might be never executed.
But in the newest versions of the architecture there is a more advanced interrupt controller, which allows to enable Round Robin scheduling, and assign to one of the interrupts a higher level (allowing it to be executed even if another interrupt handler is running).
For example in ATmega3208 (refer to the datasheet, section 12. CPU Interrupt Controller):
All interrupt vectors other than NMI are assigned to priority level 0 (normal) by default. The user may override this by assigning one of these vectors as a high priority vector. The device will have many normal priority vectors, and some of these may be pending at the same time. Two different scheduling schemes are available to choose which of the pending normal priority interrupts to service first: Static and round robin
So, the answer is: carefully read the datasheet on the part you're working with.
Section 9 of the ATmega328PB datasheet is entitled "AVR CPU Core" and it says:
All interrupts have a separate interrupt vector in the interrupt vector table.
The interrupts have priority in accordance with their interrupt vector position. The lower the interrupt vector address, the higher the priority.
I want to understand what exactly an interrupt is for my 6502 work-alike processor project in Logisim.
I know that an interrupt does the following steps:
Stops the current program from processing
Saves all unfinished data into the stack
Does "SOMETHING"
Loads back the unfinished data and let's the program keep running normally.
My question is: what happens during that "SOMETHING" step? Does the program counter get redirected to a special program to be executed? Something like reading the pressed button's ASCII code and saving that into a register or some memory location? If so, where is that special program usually stored in the memory? And can you make such a CPU that will handle different kinds of interrupts? Maybe if you press the button "a" then it's ASCII will be stored in A register, but if you press the button "b" then it will be stored in X register?
Any help is greatly appreciated.
Edit: Thanks to everybody for answers. I learned a lot and now can proceed with my project.
My question is: what happens during that "SOMETHING" step? Does the program counter get redirected to a special program to be executed?
What happens with a 6502 maskable interrupt is this:
the interrupt is raised (by this I mean the interrupt pin on the chip is forced low.
when it's time to execute a new instruction, the 6502 checks if the interrupt pin is low and the interrupt mask in the status register is not set. If either is not thew case i.e. if the interrupt pin is high or the interrupt mask is high, the CPU just carries on.
Assuming an interrupt is required, the CPU saves the PC on the stack
The CPU then saves the status register on the stack but with the B bit set to 0. The B bit is the "break" bit. It would be set to 1 for a BRK instruction and that is the only way to tell the difference between a hardware interrupt and a BRK instruction.
The CPU then fetches the address at locations $FFFE and $FFFF and stuffs it into the PC, so execution begins again at that address.
That's all it does. Everything else is up to the programmer until the programmer executes an RTI, then the status word and the return address are pulled off the stack and restored into their respective registers. It is the programmer's responsibility to save any registers and other data.
Does the program counter get redirected to a special program to be executed? Something like reading the pressed button's ASCII code and saving that into a register or some memory location?
That is correct. In 6502 based computer systems, there are three vectors at the top of memory:
$FFFA - $FFFB : Non maskable interrupt (as above except the I bit in the status register is ignored).
$FFFC - $FFFD : Reset vector used when the CPU detects a reset
$FFFE - $FFFF : Normal interrupt vector.
The above are usually in ROM because the reset vector (at least) has to be there when the CPU powers up. Each address will point to a routine in the machine's operating system for handling interrupts.
Typically, the interrupt routine will first do an indirect jump through a vector stored in RAM. This allows the interrupt routine to be changed when the machine is running.
Then the interrupt routine has to determine the source of the interrupt. For example, on the Commodore PET thew interrupt might originate from the VIA chip or either of the PIA chips and each of those may raise an interrupt for various reasons e.g. one of the PIA chips raises an interrupt when the monitor does a vertical blank i.e. when it finishes scanning the screen and goes back to the top line. During this interrupt, the PET executes a routine to scan the keyboard and another routine to invert the cursor. Another interrupt might occur when the VIA timer hits zero and the programmer can insert an interrupt routine to, for example toggle an output line to generate a square wave for sound.
Some answers to questions in the comments.
program counter goes to address $FFFE to get relocate to the address
No, the program counter is set to whatever is at that address. If you have:
FFFE: 00
FFFF: 10
the program counter will be set to $1000 (6502 is little endian) and that's where the interrupt routine must start. Also, the vector for NMI is at $FFFA. The normal interrupt shares $FFFE with the BRK instruction, not the NMI.
What exactly the reset vector does? Does it reset the cpu?
The reset vector contains the location of the code that runs after the processor has been powered on or when a reset occurs.
What's the difference between NMI and IRQ? Then I also would like to know what's up with masking? Is it the way to set the "I" flag in Processor Status Register high or low?
The 6502 status register contains seven flags. Mostly they are to do with the results of arithmetic instructions e.g. Z is set if the result of an operation is zero, C is set when an operation overflows eight bits and for shifts. The I flag enables and disables the normal interrupt (IRQ). If it's zero, interrupts on IRQ will be respected. If it's 1, interrupts are disabled. You can set it and disable it manually with the SEI and CLI instructions and it is set automatically when an interrupt occurs (this is to prevent an interrupt from interrupting an interrupt).
NMI is a non maskable interrupt. The difference is that it ignores the state of the I flag and uses a different vector.
And finally, what are vectors? Are they synonymous for indirect addresses?
Yes.
Oh, and if you do know, how are interrupt addresses starting from $FFFA stored in ROM instead of RAM in real 6502?
You have to arrange for the address decoding logic to point those address at ROM instead of RAM. In fact, in Commodore systems the whole block from $F000 is ROM containing part of the operating system. The same probably applies to most other 6502 based systems.
There are four types of interrupt on the 6502: RESET, NMI, IRQ and BRK. The first three are hardware interrupts and the last is a software interrupt. The hardware interrupts have physical input voltages on pins on the microprocessor itself. The software interrupt is caused by a BRK instruction.
All interrupts are 'vectored'. That means when they occur the program counter (PC) is immediately loaded from an address stored in memory, and instruction execution continues from that address.
The addresses are stored as two bytes little endian format at the end of the 64k memory space. They are (in hex):
NMI $FFFA/$FFFB
RESET $FFFC/$FFFD
IRQ $FFFE/$FFFF
BRK $FFFE/$FFFF
In the case of NMI, IRQ and BRK, the current PC address is pushed on to the stack, before loading the interrupt address. The processor status register is also pushed on to the stack.
Pushing the registers on to the stack, is enough information to resume execution after the interrupt has been serviced (processed). The A, X and Y registers however, are not pushed automatically on to the stack. Instead the interrupt service routine should do this if necessary - and pull them back off the stack at the end of the service.
Notice that the IRQ and BRK vectors have the same address. In order to distinguish what happened in your service code, you need to examine the Break Bit of the pushed processor status register. The Break Bit is set if the interrupt came from a BRK instruction.
The currently executing instruction will always be completed before servicing the interrupt.
There are many subtleties to interrupt processing. One of which is which type of interrupt wins in the case that they happen (asserted) at the same time. Another is the point at which an interrupt occurs during the instruction cycle. If the interrupt occurs before the penultimate cycle of the instruction, then it will be serviced on the next instruction. If on or after the penultimate cycle, then it will be delayed until one instruction after.
IRQ interrupts can be 'switched off' or ignored by setting a bit in the processor status register, using the SEI instruction.
Typically the interrupt service routine needs to determine the cause of the interrupt (disc drive, keyboard etc.) and to make sure the interrupt condition is cleared and perform any processing (e.g. putting key presses into a buffer). It can normally do this by reading/writing specific memory locations which are mapped to hardware.
There is more information at this link: https://www.pagetable.com/?p=410
Some more information on how interrupts work in a real 8 bit machine (pages 59, 86, 295): BBC Microcomputer Advanced User Guide
And more information on the physical chip package where you can see the NMI, RES(ET) and IRQ pins on the chip package itself (pages 2,3): 6502 Datasheet
I guess you ask for hardware interrupt (IRQ or NMI). At your step 2 in stack (not in stack register) are stored program counter and flags register. Later you call RTI to resume program execution. The program counter is loaded with start address of "something" which is interrupt subroutine or program to process the interrupt. It has to store A, X, Y registers if need to modify their values and restore them before RTI. The IRQ interrupt can be masked (delayed) with I flag and NMI is non-maskable i.e. it is always processed. They have different addresses for subroutine.
An interrupt is the signal to the running processor by means of hardware or software so that the processor will give attention to that action and does the action according to the interrupt message.
There are three kinds of interrupt:
Internal interrupt :- which include the clock cycle interrupt ,in which cpu has to perform the certain action until the particular time and has to go to perform for the another operation.
Software interrupt:- This interrupt is occurred when the problem or errors occurs in the software itself. For example user tries to divide something by zero and error occurs. And there is interrupt.
External interrupt:- External interrupt is caused by IO devices for example mouse and keyboards.
Cpu is designed to handle such type of interrupt and resumes the process before the interrupt occurred.
I'm trying just for the fun to design a more complex Z80 CP/M system with a lot of peripheral devices. When reading the documentation I stumbled over an (undocumented?) behaviour of the Z80 CPU, when accepting an interrupt in IM0.
When an interrupt occurs, the Z80 activates M1 and IORQ to signal the external device: "Hey, give me an opcode". All is well if the opcode is rst 00 or something like this. Now the documentation tells, ANY opcode of any command can be given to the cpu, for instance a CALL.
But now comes the undocumented part: "The first byte of a multi-byte instruction is read during the interrupt acknowledge cycle. Subsequent bytes are read in by a normal memory read sequence."
A "normal memory read sequence". How can I determine, if the CPU wants to get a byte from memory or instead the next byte from the device?
EDIT: I think, I found a (good?) solution: I can dectect the start of the interrupt acknowlegde cycle by analyzing IORQ and M1. Also I can detect the next "normal" opcode fetch by analyzing MREQ and M1. This way I can install a flip-flop triggered by these two ANDed signals, i.e. the flip-flop is 1 as long as the CPU reads data from the io-device. This 1 I can use to inhibit the bus drivers to and from the memory.
My intentions? I'm designing an interrupt controller with 8 prioritized inputs in a CPLD. It's registers hold a 16 bit address for each interrupt pin. Just for the fun :-)
My understanding is that the peripheral device is required:
to know how many bytes it needs to feed;
to respond to normal read cycles following the IORQ cycle; and
to arrange that whatever would normally respond to memory read cycles does not do so for the duration.
Also the behaviour was documented by Zilog in an application note, from which your quote originates (presumably uncredited).
In practice I guess 99.99% of IM0 users just use an RST and 99.99% of the rest use a known-size instruction like CALL xxxx.
(also I'm aware of a few micros that effectively guaranteed not to put anything onto the bus during an interrupt cycle, thereby turning IM0 into a synonym of IM1 owing to open collector output).
The interrupt behavior is reasonably documented in the Z80 manual:
Interupt modes, IM2 allows you to supply an 8-bit address to a 16-bit pointer. At least halfway to the desired 16-bit direct address.
How to set the interrupt modes
My understanding is that the M1 + IORQ combination is used since there was no pin left for a dedicated interrupt response. A fun detail is also that the Zilog I/O chips like PIO, SIO, CTC reads the RETI instruction (as the CPU fetches it) to learn that the CPU is ready to accept another interrupt.
I should first share all what I know - and that is complete chaos. There are several different questions on the topic, so please don't get irritated :).
1) To find an ISR, CPU is provided with a interrupt number. In x86 machines (286/386 and above) there is a IVT with ISRs in it; each entry of 4 bytes in size. So we need to multiply interrupt number by 4 to find the ISR. So first bunch of questions is - I am completely confused in mechanism of CPU receiving the interrupt. To raise an interrupt, firstly device shall probe for IRQ - then what ? The interrupt number travels "on IRQ" towards CPU? I also read something like device putting ISR address on data bus ; whats that then ? What is the concept of devices overriding the ISR. Can somebody tell me few example devices where CPU polls for interrupts? And where does it finds ISR for them ?
2) If two devices share an IRQ (which is very much possible), how does CPU differs amongst them ? What if both devices raise an interrupt of same priority simultaneously. I got to know there will be masking of same type and low priority interrupts - but how this communication happens between CPU and device controller? I studied the role of PIC and APIC for this problem, but could not understand.
Thanks for reading.
Thank you very much for answering.
CPUs don't poll for interrupts, at least not in a software sense. With respect to software, interrupts are asynchronous events.
What happens is that hardware within the CPU recognizes the interrupt request, which is an electrical input on an interrupt line, and in response, sets aside the normal execution of events to respond to the interrupt. In most modern CPUs, what happens next is determined by a hardware handshake particular to the type of CPU, but most of them receive a number of some kind from the interrupting device. That number can be 8 bits or 32 or whatever, depending on the design of the CPU. The CPU then uses this interrupt number to index into the interrupt vector table, to find an address to begin execution of the interrupt service routine. Once that address is determined, (and the current execution context is safely saved to the stack) the CPU begins executing the ISR.
When two devices share an interrupt request line, they can cause different ISRs to run by returning a different interrupt number during that handshaking process. If you have enough vector numbers available, each interrupting device can use its own interrupt vector.
But two devices can even share an interrupt request line and an interrupt vector, provided that the shared ISR is clever enough to go back to all the possible sources of the given interrupt, and check status registers to see which device requested service.
A little more detail
Suppose you have a system composed of a CPU, and interrupt controller, and an interrupting device. In the old days, these would have been separate physical devices but now all three might even reside in the same chip, but all the signals are still there inside the ceramic case. I'm going to use a powerPC (PPC) CPU with an integrated interrupt controller, connected to a device on a PCI bus, as an example that should serve nicely.
Let's say the device is a serial port that's transmitting some data. A typical serial port driver will load bunch of data into the device's FIFO, and the CPU can do regular work while the device does its thing. Typically these devices can be configured to generate an interrupt request when the device is running low on data to transmit, so that the device driver can come back and feed more into it.
The hardware logic in the device will expect a PCI bus interrupt acknowledge, at which point, a couple of things can happen. Some devices use 'autovectoring', which means that they rely on the interrupt controller to see to it that the correct service routine gets selected. Others will have a register, which the device driver will pre-program, that contains an interrupt vector that the device will place on the data bus in response to the interrupt acknowledge, for the interrupt controller to pick up.
A PCI bus has only four interrupt request lines, so our serial device will have to assert one of those. (It doesn't matter which at the moment, it's usually somewhat slot dependent..) Next in line is the interrupt controller (e.g. PIC/APIC), that will decide whether to acknowledge the interrupt based on mask bits that have been set in its own registers. Assuming it acknowledges the interrupt, it either then obtains the vector from the interrupting device (via the data bus lines), or may if so programmed use a 'canned' value provided by the APIC's own device driver. So far, the CPU has been blissfully unaware of all these goings-on, but that's about to change.
Now it's time for the interrupt controller to get the attention of the CPU core. The CPU will have its own interrupt mask bit(s) that may cause it to just ignore the request from the PIC. Assuming that the CPU is ready to take interrupts, it's now time for the real action to start. The current instruction usually has to be retired before the ISR can begin, so with pipelined processors this is a little complicated, but suffice it to say that at some point in the instruction stream, the processor context is saved off to the stack and the hardware-determined ISR takes over.
Some CPU cores have multiple request lines, and can start the process of narrowing down which ISR runs via hardware logic that jumps the CPU instruction pointer to one of a handful of top level handlers. The old 68K, and possibly others did it that way. The powerPC (and I believe, the x86) have a single interrupt request input. The x86 itself behaves a bit like a PIC, and can obtain a vector from the external PIC(s), but the powerPC just jumps to a fixed address, 0x00000500.
In the PPC, the code at 0x0500 is probably just going to immediately jump out to somewhere in memory where there's room enough for some serious decision making code, but it's still the interrupt service routine. That routine will first go to the PIC and obtain the vector, and also ask the PIC to stop asserting the interrupt request into the CPU core. Once the vector is known, the top level ISR can case out to a more specific handler that will service all the devices known to be using that vector. The vector specific handler then walks down the list of devices assigned to that vector, checking interrupt status bits in those devices, to see which ones need service.
When a device, like the hypothetical serial port, is found wanting service, the ISR for that device takes appropriate actions, for example, loading the next FIFO's worth of data out of an operating system buffer into the port's transmit FIFO. Some devices will automatically drop their interrupt request in response to being accessed, for example, writing a byte into the transmit FIFO might cause the serial port device to de-assert the request line. Other devices will require a special control register bit to be toggled, set, cleared, what-have-you, in order to drop the request. There are zillions of different I/O devices and no two of them ever seem to do it the same way, so it's hard to generalize, but that's usually the way of it.
Now, obviously there's more to say - what about interrupt priorities? what happens in a multi-core processor? What about nested interrupt controllers? But I've burned enough space on the server. Hope any of this helps.
I Came over this Question like after 3 years.. Hope I Can help ;)
The Intel 8259A or simply the "PIC" has 8 pins ,IRQ0-IRQ7, every pin connects to a single device..
Lets suppose that u pressed a button on the keyboard.. the voltage of the IRQ1 pin, which is connected to the KBD, is High.. so after the CPU gets interrupted, acknowledge the Interrupt bla bla bla... the PIC does simply add 8 to the number of the IRQ line so IRQ1 means 1+8 which means 9
SO the CPU sets its CS and IP on the 9th entry in the vector table.. and because the IVT is an array of longs it just multiply the number of cells by 4 ;)
CPU.CS=IVT[9].CS
CPU.IP=IVT[9].IP
the ESR deals with the device through the I/O ports ;)
Sorry for my bad english .. am an Arab though :)
Maybe the question should be, are external interrupts even vectored on the PowerPC at all? I've been looking at http://www.ibm.com/developerworks/eserver/library/es-archguide-v2.html, 'book 3', trying to figure out how the processor locates the appropriate interrupt service routine in response to an external interrupt. It seems to suggest that when the PPC recognizes an external interrupt, it just jumps execution to 0x0000_0500.
I may be laboring under a misconception about how the PPC works. With x86, the processor responds to interrupt requests with an interrupt acknowledge cycle, and obtains a 'vector' directly from the device. The vector (really an index) then allows the cpu to pick an appropriate handler routine from its interrupt vector table. Most importantly, this acknowledge/vector fetch is a hardware, bus-protocol thing, nobody has to write any code to make it happen. The only code that needs writing (read, software) is the ISRs themselves.
Does the PPC do something similar? Would there be a table of vectors at 0x500? Or does it do something radically different, and offload the functionality of getting the device's vector to an external interrupt controller? I suppose it could just jump to code at 0x500, where actual software would then interrogate the (hypothetical?) interrupt controller to get the vector .. and then use it in a jump-table/what-have-you, but I can't find documentation to verify this is the case, one way or another.
The PowerPC CPU has no concept of an interrupt vector table, and only provides a single interrupt pin and interrupt vector.