1

I have looked this video - Altair 8800 - Interrupt Acknowledge Cycle and have few questions (I have read wikipedia Intel 8080 article, Altair 8800 Operator's manual, Charles Petzold "Code" and few article on the internet, like this and didn't found answer yet):

  1. Altair 8800 (and Intel 8080) have 8 RST, the first, RST 0 used by hard reset button, so only 7 RST we can use for peripherals (I think). Does it mean, that it couldn't be connected more than 7 peripherals to this computer? Because, how it will be work, if the CPU doesn't notice it?

The excerpt from the "Charles Petzold. Code: The Hidden Language of Computer Hardware and Software":

The S-100 bus also includes 8 interrupt signals. These are signals generated by other devices when they need immediate attention from the CPU. For example (as we'll see later in this chapter), a keyboard might generate an interrupt signal when a key is pressed. A short program run by the 8080 can then determine what that key was and take some action. The board containing the 8080 also generally includes a chip called the Intel 8214 Priority Interrupt Control Unit to handle these interrupts. When an interrupt occurs, this chip generates an interrupt signal to the 8080. When the 8080 acknowledges the interrupt, the chip provides a RST (Restart) instruction that causes the microprocessor to save the current program counter and branch to address 0000h, 0008h, 0010h, 0018h, 0020h, 0028h, 0030h, or 0038h depending on the interrupt.

  1. Why Intel 8080 have 256 I/O port addresses, while it has only 8 RST instructions to handle 8 devices? How is it supposed to work with the other 248 devices?

  2. Does each RST "hardwired" to specific socket on the S-100 bus? In other words, if I plug the keyboard controller to the second socket, do I need write my keyboard handler only to the specific memory address, for example 0008h? And if I change the keyboard controller place to the another bus socket, does the subroutine needs to be moved to another RST address? Or may be the mapping table can exists somewhere in the memory, but I don't see it in the Altair 8800's video.

  3. How the device port number are determined? That is, why the keyboard in the video has the 20Q port, why not 1Q for example? Is it caused by the socket number, the device type, something else?

  • 3
    I'm sure someone else will come up with an authoritative answer. But off the top of my head, I think the S-100 was totally passive - essentially all control data and power uniform across the backplane. My S-100 experience is relatively limited (a few years with a few CompuPro machines) and I don't recall any "this board goes in this slot" the way things often were the case with Apple ][ or other buses. – manassehkatz Jun 25 '18 at 16:35
  • 2
    I don't know much about the S-100 bus either, but the basic problem here though is that your assumption that every device uses one I/O port address and one interrupt line is incorrect. A device could use multiple I/O ports or none, and may or may not use interrupts. I believe normally S-100 cards only use the one unvectored interrupt on the bus, and not the 8 vectored ones, so multiple cards could share the same interrupt line. – Ross Ridge Jun 25 '18 at 17:56
  • 1
    @RossRidge the 8080 has neither vectored nor non-vectored interrupts. You could say it has weird interrupts, though ;) – tofro Jun 25 '18 at 19:00
  • 1
    @tofro I didn't say otherwise. – Ross Ridge Jun 25 '18 at 22:19
7

I have looked this video - Altair 8800 - Interrupt Acknowledge Cycle and have few questions (I have read wikipedia Intel 8080 article, Altair 8800 Operator's manual, Charles Petzold "Code" and few article on the internet, like this and didn't found answer yet):

Maybe to start with the obvious: Not every device needs to be interrupt driven.

  1. Altair 8800 (and Intel 8080) have 8 RST, the first, RST 0 used by hard reset button, so only 7 RST we can use for peripherals (I think). Does it mean, that it couldn't be connected more than 7 peripherals to this computer? Because, how it will be work, if the CPU doesn't notice it?

No, all it means that there are only 8 distinctive routines that can be called directly by issuing one of the RST instructions. It doesn't imply any relation to the number if interrupt serviceable devices or devices at all.

(And it's 8, not 7, as RST0 can ofc be used for an interrupt handler)

An interrupt controller (like 8259 *1) can issue one RST for all interrupts, having them all initiate the same routine and then be polled by the routine to check which is the one to be served. Or they can have separate. Or a mixture of both. It's up to the systems requirements (and what style the designer preferred).

Or, instead of an RST, a CALL can be delivered (*2). When the 8080 (or Z80 in Mode 0) senses a CALL opcode during an interrupt cycle it will issue two additional cycles to fetch the address to be used. Thus there can be as many different entrypoints as one wishes (*3)

  1. Why Intel 8080 have 256 I/O port addresses, while it has only 8 RST instructions to handle 8 devices? How is it supposed to work with the other 248 devices?

As said above, number of RST instructions, number of interrupt sources and number of I/O ports are not in any predefined relation to each other and to the number of 'devices'.

To start with, there is no assumption if a device is represented by a single I/O address, or if it occupies several. A 8251 serial interface would occupy 4 I/O addresses, while a 16550 needs 8, and a 8250 can get alone with just two.

In fact, one I/O address could as well be shared by multiple devices due to whatever (hardware or software) protocol. Like accessing different devices when writing or reading.

Next, a 'device' does not need to have an interrupt associated. It may or may not, depending on its purpose, structure and workings. This may even differ for the same type of device. For example a keyboard interface can be implemented interrupt driven - with issuing an interrupt for each keypress, or polled, where it' up to the CPU to look if a new keypress has occurred or not.

And last, an interrupt can be shared by two devices - like having a board with several 16550 sharing a single interrupt line, programmed to use the same RST. Resulting in one interrupt, one RST, two devices and 16 addresses.

  1. Does each RST "hardwired" to specific socket on the S-100 bus?

(I assume you mean Slot when speaking about 'Socket')

No. The S100 bus (in actual use, not as with the original Altair) supports three interrupt lines: /RESET, /NMI and /INT which connect all slots in parallel. Ignoring /RESET and /NMI, there is only one line, thus there can not be a slot specific assignment (*4). It all depends on the CPU used, the interrupt mode used and programming of the interrupt controller used.

But as there is only one interrupt, it is the same for all devices. The routine is selected by what instruction is placed on the bus during an interrupt cycle by the interrupt controller. In case of an 8080/85, it will be one of 8 possible RST instructions inserted by the 8259 interrupt controller as well an arbitary CALL instruction. In case of a Z80 (Interrupt Mode 3) it might also be one of 128 vector numbers.

Now, if your question is about the 8 seperate interrupt lines usually called VI0..VI7, then again, they are shared between all boards and it's up to the system configuration if they get assigned to seperate boards (usually by jumpers) or get used by multiple - in both cases again, they can be used by one or more devices on these boards. Wellcome to the wonderful world of S100 bus configuration :))

Remember there is only one interrupt line on the CPU, so handling 8 lines from the bus means, that there must be an interrupt controller (8259) on the CPU board to encode and prioritize them. Otherwise they might be a bit hard to handle.

  1. How the device port number are determined? That is, why the keyboard in the video has the 20Q port, why not 1Q for example? Is it caused by the socket number, the device type, something else?

(Not sure what 20Q or 1Q should mean here)

As said, the assignment of I/O addresses to 'devices' is arbitrary and decoded at each I/O board. (hopefully) The right board will respond to an address (if not we got a configuration error). The assignment is usually hard coded or can be selected from a predefined range by jumpers. On the software side it depends as usual on the software used. It may be hardcoded in the drivers (BIOS) or due some kind of configuration file.

After all, that's why a system abstraction like CP/M is so handy as all these codings are hidden below and user programs only interact with symbolic devices.


Confused? Well, interrupt handling isn't the easyest lesson to learn when about a CPU, especially not with rather sophisticated mechanics like on the 8080/Z80 family. Just take your time an gnaw thru all the paper :)


*1 - Usually the 8259 is associated with vectored interrupts (RST or CALL). There are other chips, like the 8214, but they lack the ability to issue different vectors (or vectors at all).

*2 - IIRC, any instruction can be issued, but only RST and CALL do make sense under normal circumstances as they both do a proper subroutine invocation. Then again, with a careful design other instructions could be useful in the right situation.

*3 - Within the reasoning of a system with only 64 KiB address space of course :))

*4 - Keep in mind, S100 is a simple parallel bus utilizing an undefined number of slots. None is prioritized or special in any way. Any card can be placed in any slot. Much like the PC bus system. In contrast the Apple II bus uses geographical addressing, meaning while each slot is electrical the same (lets ignore #0 and #7 for this), they will be seen on different address ranges by the CPU. That would be geographical addressing - which S100 is not.

  • 1
    "Not sure what 20Q or 1Q should mean here" - it is from this assembly demo code this - the out port number in the octal format (Q - octal suffix). I were thinking, that it is the keyboard port number. This link from the video description. – MiniMax Jun 25 '18 at 18:57
  • 1
    As far as I know, 8259 is able to insert CALLs for i8080 as well for Z80. For both RST insertion is also OK, that might be done with the abovementioned 8214. Z80 has two more interrupt modes over i8080-compatible one, and they are numbered mode 0 (i8080 compatible), mode 1 (simply automatic RST #38 insertion by CPU itself) and mode 2 (vectored mode), numbered as per Z80 manual. The funny thing is that Z80 doesn't care which vector out of 256 ones is given him during mode 2 interrupt acknowledgement: it is only a convention for Z80 chipset to use just 128 even numbers for vectors. – lvd Jun 25 '18 at 21:21
  • @lvd yes, you're right, when the 8080 sees a CALL during the first interrupt cycle it does two more fetches. Just, AFAIR it must be an even address supplied by the interrupting device - at least that's what the Z80 manual states. I have to admit, I never tried an odd one. Also, some devices are only able to deliver even more granualated vectors - like the CTC can only deliver in seps of 8, as the 3 lower bits of the vector command are used otherwise. – Raffzahn Jun 25 '18 at 22:24
  • 1
    "And it's 8, not 7, as RST0 can ofc be used for an interrupt handler" ... I wouldn't say that's so obvious, unless you understand the boot process of the Altair 8800, which is somewhat different to most more recent machines, so it's understandable to assume that RST 0 would be reserved for the reset vector. But because the Altair has RAM at address 0 and that RAM is (usually) overwritten by a bootloader on every reset, it is available for the running software to use for whatever purpose it wants. – Jules Jun 25 '18 at 23:32
  • 1
    @Raffzahn Because of data bus pullups, interrupt vector in rubber ZX Spectrum is #FF, and therefore in IM 2 mode, Z80 fetches the interrupt address from (I*256+255, I*256+256) address pair. So it's ok to supply an odd interrupt vector to Z80 – lvd Jun 26 '18 at 10:53
5

1 I/O port <> 1 hardware device

1 RST vector <> 1 interrupt from one device

You have read the datasheet under false assumptions.

There is no such thing as a 1:1 correlation between these concepts.

Actually, I/O devices that hold only one single I/O port are pretty rare. A typical floppy controller, for example, the WD1772, has four registers (status/command, track, sector, data), thus occupies four I/O ports. A simple UART of the time, the 8250, occupies 7 I/O addresses.

A Restart Vector is actually a software interrupt and has nothing (at least not directly) to do with devices. The RST is rather something close to a CALL operation, or an interrupt triggered by software. The RST operation is only specific with regards to interrupts that it is the only opcode that generates a jump to a handler routine and occupies only one byte - Thus, external devices can push it onto the data bus during the interrupt acknowledge cycle of the CPU to cause a jump into an interrupt service routine. (The 8080 is pretty unique (simple?) in expecting interrupting devices to push an instruction onto the bus during the interrupt acknowledge cycle that will then be executed by the device)

In case you have more interrupting devices than interrupt lines (easy on the 8080, it has only one such line), there are a number of strategies you can take

  • wired-or of all interrupt lines from peripherals to the CPU, use a single RST vector and query (poll) all connected devices "was it you?" in the interrupt service routine. This has been done in simpler, cheaper computers. It adds a bit of latency but works well.
  • Employ an interrupt controller (e.g. 8214). A separate chip that handles the various devices triggering interrupts and can push different RST instructions onto the data bus during the interrupt acknowledge cycle of the CPU and can prioritize them. Note these different RST commands can be used as "one per device" in case you have no more than 8, or the RST vectors are used to handle more than one device per RST, thus a mixed approach between the previous method and this one is used: lower priority interrupts serve many, slow devices, while higher priority interrupts are dedicated to a single, fast device prioritized by the interrupt controller. After all, a terminal port running at 300 Baud doesn't need to be served with the same priority and latency as a high-speed interface to a hard disk, for example.

The eight available RST vectors are thus used to prioritize and group various interrupting devices, rather than each of them handling only one device.

3

Manassehkatz is correct about the bus. All components can see all bus activity. So each picks for itself which bus cycles to respond to; ordinarily IO accesses to a particular address or range of addresses.

The 8080 has a very direct interrupt system — it'll read an instruction off the bus and execute it. In practice it's easier to make these single byte instructions because that doesn't require any state to be maintained by the peripheral, though — as per Raffzahn's correction in the comments — the processor is smart enough to continue signalling that it's performing an interrupt response even if it needs to read multiple bytes.

That being said, the RSTs are then a natural choice, and I'd even be surprised if this isn't exactly why they exist. But if Intel had wanted to provide more RSTs then they'd have needed to remove other instructions to free up encodings and, in any case, encoding would have been tricky. 8080 instructions generally break down into two three-bit fields plus a two-bit part, and there are eight RSTs because one of those three-bit parts directly maps to the destination address.

This is one of the things that was extended on the Z80; one of its modes of operations allows external devices to supply an index into a vector lookup table rather than an instruction. So you're not alone in seeing a difficulty.

However there is no reason why two devices can't supply the same RST as long as the code it points to can perform some additional test to figure out which need attention. It's also possibly to use other instructions if the CPU knows to wait — e.g. it can spin in a tight loop on the carry flag and the instruction posted at interrupt could be set carry flag.

A lot of hardware has multiple IO ports rather than just one so a direct mapping between IO address and interrupt vector wouldn't necessarily make sense anyway, and even if it did then you'd eat a lot of address space if you reserved room for 256 unique interrupt routines.

I don't think the S-100 bus makes any attempt to communicate location to things you install. It's just a hub. So cards should respond to the same IO addresses and produce the same interrupts no matter where physically installed.

  • 1
    and I'd even be surprised if this isn't exactly why they exist -- other evidence for this being the reason they were added: all the non address bits in their opcodes are 1, which is the natural default value in a bus driven by open collector peripherals. This is clearly intended to simplify circuits that signal interrupts. – Jules Jun 25 '18 at 21:01
  • 1
    @Tommy Easy is something like the .5 RST pins of the 8085 or the interrupts of a 6502. Having special interrupt cycles with data transmissions from interrupt controllers is anything but simple. For the CALL handling check the Z80 Technical Manual from 1976 p56 or for the 8085 the MCS80/85 Family Manual section 2.3.4 on page 2-13 (sorry, got no 8080 manual at hand) – Raffzahn Jun 26 '18 at 0:03
  • 1
    @Tommy I'd say the Z80 UM is rather clear about this when Mode 0 is described on p24/25: " Thus, the interrupting device provides the next instruction to be executed. Often this is a restart instruction because the interrupting device only need supply a single byte instruction. Alternatively, any other instruction such as a 3-byte call to any location in memory could be executed." (The wording is still the same as in the 1976 manual) | Concurent interrupts are managed in 8080 systems by the PIC, while Z80 devices supports priority via chaining. – Raffzahn Jun 26 '18 at 10:33
  • 1
    'Priority via chaining' is the feature of Z80 support chips (Z80 pio, Z80 ctc, Z80 sio etc.) and Z80 supports them only by its RETI instruction that those chips have to recognize. RETI is totally equivalent to simple RET for Z80 itself. Apart from that, Z80 doesn't know whether there are sophisticated priority chaining involved or just some kind of priority encoder as found in 8259. – lvd Jun 26 '18 at 11:01
  • 1
    @Raffzahn my concern, as stated several times, was whether an 8080 continues to signal that it is responding to an interrupt while fetching the tail end of multibyte instructions. Let me know how you think the Z80 manual answers that. What about that text guarantees that a bus observer will know that the operand fetches are part of the interrupt response and not just any other fetch? – Tommy Jun 26 '18 at 14:18
2

The chip has 256 I/O ports, rather than some smaller number, because it was just as easy to provide 256 ports as it would be to provide eight. The part supports eight restart vectors because the hardware to support eight was simpler than hardware to support more.

Note that many I/O devices use a single interrupt but use multiple I/O register addresses (often between 2 and 16) to perform various functions. If a system has seven I/O devices each of which use 16 addresses, that would require a total of 112. Allowing for 256 would be more than sufficient, and is just as easy as providing for anything less, so why not?

  • 1
    Also, ease of address decoding is relevant: a device may use, say, 5 addresses, or even only one, but the logic to fully decode the addresses it uses and then allocate adjacent addresses to another device is quite tricky. In most designs, a few high bits were decoded and everything else ignored, so every device got a reasonably large allocation (say 32 ports) and there was a large unused space between each device. That made designing the devices much easier than if they had to be precise in their allocations ... – Jules Jun 25 '18 at 23:45
  • 1
    ... and why geographic addressing was more useful on the Apple II (because the 6502 doesn't support a separate IO address space, so every port allocated to a device was a byte that couldn't be filled with memory) than on machines based on Intel processors (which had a large IO address space that could be more easily sliced up, so it wasn't as critical to do it properly). – Jules Jun 25 '18 at 23:47
  • @Jules: The Apple II gave each expansion card a 256-byte chunk of address space and a 16-byte one. In addition, there was a 2048-byte chunk of address space that cards were expected to share (if they used it at all). I don't think there was a perceived need to fill up every byte of address space at the time the I/O layout was being designed; in fact, one thing I wish 6502 hardware designers would have realized is that a good bank-switching design can allow more efficient code than a jam-packed address space. – supercat Jun 26 '18 at 14:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.