5

After reading about the Signetics 2650, and being a bit familiar with the HP2100's, I'm curious how common the style of "indirect addressing via the address value" instruction was at the time?

CPUs like the 6502 offered indirect addressing but did so via separate opcodes in the 8-bit instruction. In contrast, machines like the HP triggered indirection by setting the bit in the address itself.

I see references to this style here and there, but I'm curious in a general fashion: was this sort of bit-stealing in the address common in machines of the mini era, or was the 6502 separate-opcode more common for indicating addressing modes?

3 Answers 3

8

As another-dave points out, your "indirect bit in the instruction" versus "indirect bit in the address" distinction can be ambiguous. When the instruction and the address operand are always contained within a single machine word at the same address, is the indirect bit part of the address or part of the instruction?

I think we can clearly say that for multi-level memory indirect addressing where, due to indirection, an address loaded separately after an instruction has been executed can cause yet another level of indirection, the indirect bit would be considered part of the address. An example of this would be on the UNIVAC 1100 series, where there was an "i bit" in each word. If this is set in a word read as an instruction and operand, the lower 22 bits of that word (which include the i bit) are replaced by the contents of the referenced address; the i bit is then checked again and, if set, the replacement done again. This continues until the i bit is clear in the data loaded from the referenced address.

This multi-level indirect was reasonably popular in the 1950s and 1960s, implemented in the IBM 1620 (1959), UNIVAC 1100 series (1962), HP 2100 series (1964), PDP-10 (1966), SDS 940[] (1966), Data General Nova (1969), and various others.

That said, there were plenty of other word-oriented machines, from the IBM 700 and 7000 series (late 1950s onward) through the PDP-8 (1965) and beyond that had a single word containing an instruction, indirect bit and address operand yet gave only one level of indirect addressing: if the target location from which the next address was loaded had the indirect bit set, that was ignored.

7
  • I think the key statement is the first one - minis might have a 16-bit word whereas the early micros generally had 8 so you were doing optional fetches anyway. In that case putting the bit in the instruction makes more sense. Jan 21, 2020 at 15:54
  • 1
    Good answer and just wanted to give a shout-out to the entirely strange PDP-8 concept of "auto incrementing addresses" - if you went indirect through a pointer stored in addresses 010 through 017 then after you went indirect the value stored in that address would be automagically incremented! Very convenient for looping on a machine with only one register - the accumulator - and no index registers! (The IMLAC PDS-1, which ripped off and "stretched" the PDP-8 instruction set turned it up to 11: that plus addresses 020 through 027 would auto decrement when you went indirect through them!)
    – davidbak
    Jan 21, 2020 at 17:45
  • While the Univac 1108 has its indirect flag (bit 17) adjacent to the 16-bit address field in an instruction word and in an indirect word, it is not described as being "a bit in the address". And since indexing occurs before indirection, the address is actually 18 bits wide at the point we consider indirection; i.e., it's strange to consider the indirect flag as any part of an address. Lastly, indexing is chained as well as indirection. Jan 24, 2020 at 3:23
  • @another-dave Well, as I said, it kinda depends on how you want to define "what's in the address" in such "address is a sub-part of the word" architectures. Personally, I would go with, "if you load an adress and you follow an indirect bit from the word you loaded, that indirect bit was part of the address you loaded." But without carefully defining terms, there's plenty of room for argument there, I'm sure.
    – cjs
    Jan 24, 2020 at 21:59
  • I'd also like to point out that the PDP-10 XCT instruction - which would compute an effective address and execute the (single) instruction at the pointed-to location also respected the indirect bit - which meant you could play remarkable tricks with the XCT - combine that with the index computation as part of an effective address and you got really powerful jump tables, tight interpreter loops, etc. - and now add in the capability to XCT a subroutine call instruction!! PDP-10 was too early for O-O languages with vtables but those would have rocked!
    – davidbak
    Jan 25, 2020 at 0:37
6

I'm curious how common the style of "indirect addressing via the address value" instruction was at the time?

To avoid a list answer and as an absolute answer isn't possible anyway, let's say "quite". Notable examples in addition to the mentioned HP2100 are IBM's 1620 of 1959 or DG's NOVA of 1969. All of them are based on the idea that word size is larger than usable address size.

After all, up until the mid 1970s, were all these CPUs were designed, Memory sizes of 64 KiB were more of a theoretical limit. When the DSI-1000 (HP2100) was designed in the early 60s, even the biggest computers of it's time like the CDC 6600 had only 128 KiWords of Memory. Minis way less.

Similar for monolithic CPUs and semiconductor Memory in 1972 when the 2650 project started. Heck, 64 KiB was still close to unobtainium, in the second half of the 1970s, when CPU's like 8080 or 6502 were ready. It wasn't until DRAM in form of Mostek's MK4116 DRAM came about in 1976 that 64 KiB became a common sight for (upper end) micro computers.

As a result CPU designs of that time, like Datapoint 2200 or its follow up the i8008, did not use the full 16 Bit address, even without setting bits apart for indirect handling.

So even if CPUs used a flat 64 Ki addressing, system designers than used single bits for function. Commodore being a great example by using 2^15 to distinguish between RAM and everything else. Easy for the PET in 1976, but making use of any RAM beyond 32 KiB a true pain for all that followed.

Such decisions are usually rather based in what data structures the designers imagined, like linked lists and how the CPU is constructed, especially if it's microprogrammed in a way that allows to iterate over several levels of indirektion.

It is mostly a decision about support to high level structures. For example following a linked list on a 6502 is clumsy at least - and more important, programmers had not only to embedded this in their code, but also use a different way of keeping track how many levels are to be used and/or special values for start or end. With an indirect feature embedded in the address word, programs didn't have to be adjusted to used indirection or not or how many levels, but let this to the hardware.

In fact, to some degree programmers 'reinvented' the idea of address tagging as different times. On /370 machines with 32 Bit words but 24 bit address, it was common to use the top byte of an address word as marker of various kind. oten to mark the end of a linked list as well. Similar did MacOS on the 68k use the top byte of its addresses (here called Handle) to store information about locking, or if it was to be loaded first (much like being paged out). This is what added issues with less than clean programs when switching to 32 bit addressing. Newest incarnation might be the use on iOS where all pointers are always aligned to word boundries, 'freeing' two bits to be used for memory management.

Of course, all of this makes only sense if the CPU is indended for tasks with highly dynamic data - like minis are. Embedded applications don't call for such a luxury. Tables are on fixed spots (thus the 6502 has an ABS,X/Y mode, but no (ABS),X/Y) and linked lists are rather uncommon.

was this sort of bit-stealing in the address common [...], or was the 6502 separate-opcode more common [...]?

On what measurements? Number of CPU's sold or designs? And if designs, which to include? Only those sold in a certain number? Even more important at what time? The question setretches from early 60s until mit 1970s, eventually the most dynamic time for CPU design. A time were borders were stretched a lot changing the base allowing to spend bits or not a lot.

Bottom Line: It is always a good use when word size is larger than address size. Which was for the mentioned architectures the case - at a time when 64 Ki was way more than anyone could resonably afford.

5
  • by using 2^15 to distinguish between RAM and everything else. - that is an interesting point. Several other micros did the same now that I think of it, like the Astrovision. Jan 21, 2020 at 15:52
  • @Maury What it sounds like Raffzahn is talking about there is just a particular implementation of address decoding; it doesn't "distinguish RAM" in any real sense and is nothing like an indirect bit. In the PET, for example, you could replace a ROM chip with a static RAM (jumpering the write signal out to it) and have RAM with A15 set, and of course in a <32K PET you had plenty of "non-RAM" with A15 clear. It's just about where you send device (chip) select signals.
    – cjs
    Jan 21, 2020 at 16:07
  • @CurtJ.Sampson It's exactly that point, about giving up maximum address size to gain some other feature. 64 Ki was, at that point a lot, giving away half of it to non RAM. Like you mention, even 32 KiB was more than what would have been filled up early on. That this can be tweaked later on, doesn't invalidate the rational behind.
    – Raffzahn
    Jan 21, 2020 at 16:52
  • You haven't given up any address space at all by decoding A15⇒RAM/CS; you still have full 16-bit addresses. That's a very different thing from having a smaller address space. The reason you don't do ¬(A15&A14)⇒RAM/CS is because on a board with sockets for only 32K of RAM you gain nothing from doing so, while using extra gates. They did decode it differently on the VIC-20 with no problems at all. But I think, as usual, this argument will go nowhere. TLDR: address decoding has nothing to do with indirect bits.
    – cjs
    Jan 21, 2020 at 17:04
  • @CurtJ.Sampson Of course it will go nowhere, as you're arguing about something that hasn't been said. It's not about indirect bits, but the underlaying idea of spending possible address space to gain a feature. Something that can be done on various levels (System, Software, etc), not just CPU. Also, it helps to keep arguments in line with cause and effect. A board design (adding sockets) is due the way the system was layed out, not the other way around, isn't it?
    – Raffzahn
    Jan 21, 2020 at 17:16
5

tl;dr - I see the world divided into 'indirection indicated by dedicated field in instruction and (sometimes) in indirect words as well' versus 'indirection is a property of certain opcodes'. No 'indirection indicated by bit in address'. I think dedicated-field is more common.

Introductory remarks

I don't think there were many computers where indirection was indicated by a bit in the actual address. Some of the confusion may be more due to words used in the description rather than in the actual computer operation.

Most of my assembly-level experience has been with computers where indirection is a field in the instruction (and to a lesser extent, where chained indirection is supported, by a field in the indirect word).

Perhaps I have a big-machine (anything that can host a timesharing system) bias; perhaps early micros tended to specific instructions. I can't comment on that.

The case where there are distinct opcodes for indirection is obvious enough; I merely think it's not particularly common in the sort of machines I am used to. I don't discuss it further.

Machines with a separate field indicating indirection

Indirection is indicated by a separate field (not part of the opcode, not part of the address field). That is, it's the same MOVE or LOAD opcode regardless of whether there is indirection; in contrast to having a specific LOAD-INDIRECT opcode.

It may be useful to consider two subcases: single-level indirection and multi-level indirection, the latter being where the indirect word itself can call for another indirection.

Single level of indirection

If the indirection is not considered to be part of the opcode then it is a separate field in the instruction.

For the PDP-11, there are "mode" fields (potentially two, for operations with source and destination addresses), some values of which indicate "indirect" modes.

The VAX follows the PDP-11 model, except that some operations have more than two operands, but there's still a mode value as part of each operand specifier.

It seems unlikely that anyone would call this model "indirect flag in address".

Multiple levels of indirection

The initial indirection is again indicated by a field in the instruction word. The processor then fetches an indirect word which in the machines I am familiar with tends to have a similar format to the original instruction -- for example if the computer supports indirection and indexing, then the indirect word will also have an indirection indicator and an indexing indication (flag or register number).

For the PDP-10, there is an "indirect bit" in the instruction word and an "indirect bit" in the indirect word. The instruction and indirect words also indicate indexing by having a non-zero value in the "index register" field.

The SDS940 (which I have not programmed) is similar to the PDP-10. The instruction word contains an indirect flag and an index flag, considered as distinct from the address. Any indirect word also contains these flags. Indirection proceeds to arbitrary depth.

It may be considered a matter of opinion whether the indirect and index-reg fields are "part of" or "separate from" the address field. Since it is natural to consider them as separate in the actual instruction word, and since the indirect word follows the same overall format as the instruction word, the indirect/index fields are also best considered as separate in the indirect word.

Opinion on the above

In general, and even for computers I haven't programmed (but don't have them in mind's cache right now) this seems "standard" to me - to have a field or fields in the instruction that says how to form the effective address, but separate from the opcode and the address (displacement, whatever it is locally called).

I view this as clean design. It seems similar to having "use a modifier register (index register) in address calculation" not be implicit in the opcode but explicitly appearing in a separate field in the instruction word. Or even which register to use as source/destination, in a machine with register/memory instructions.

Machines quoted in the question

HP 2100

I have now read the Wikipedia page on the HP 2100. Based on that, I would describe the HP 2100 operation as follows:

An initial indirection is indicated by a field in the instruction (bit 15), which is not described (by the wiki page) as part of the address in bits 0-9; it is a distinct flag.

Optionally, a second indirection can be requested by setting bit 15 in the indirect word. And so on to any degree.

This is analogous in some way to the way the PDP-10 handles chained indirect. If bit 13 is set in the instruction, then it's indirect mode. If bit 13 is set in the indirect word (the one fetched from the effective address in the instruction) then it's another indirection.

For the HP 2100 case (a machine I am not familiar with), I would prefer to regard the indirect bit, bit 15, as a separate flag rather than part of the address. I have two reasons for this: (1) it's a separate flag in the instruction, not even contiguous with the address, so symmetry says it's a separate flag in the indirect word, (2) if bit 15 is set in the indirect word, then bits 0-14 are used as the address from which the next indirect word is fetched - i.e., bit 15 is not part of the address.

Even if it turns out I'm only quibbling about terminology, note that "bit in the address" as used in the HP 2100 is only a consideration for CPUs that have a multi-level indirect capability. Anecdotally, I think that's falling out of favour in mainstream processors.

(But the alternative is still not only "separate instructions for direct/indirect cases")

Signetics 2650

This user manual (which I assume to be authoritative) describes the instruction format as having an 'indirect' bit.

Example:

The format of relative addressing instruction is:

oooooorr    iaaaaaaa
76543210    76543210
 Byte 0      Byte 1

o: operation code
r: register
i: indirect addressing flag
a: relative displacement

and further, under the heading 'Indirect Addressing':

Indirect addresses are 15-bit addresses stored right justified in two contiguous bytes of memory. As such, an indirect address may specify any location in addressable memory (0-32767). The high order bit of the two-byte indirect address is not used by the processor.

So I see nothing that would cause me to describe this as an indirection flag in an address. The flag is a separate field in the instruction, not part of the address and not implicit in the opcode.

10
  • Isn't that a overspecific DECish view of 'fields' when the question calls for a generic comparsion? Also, as far as I understand the question, it is about indirection being part of the address - which is not restricted to the instruction formats.
    – Raffzahn
    Jan 21, 2020 at 14:18
  • My reading of the question is that it's whether the indirection indicator is part of the address or part of the instruction (the latter meaning that ADD and ADD INDIRECT are different opcodes). I wish to point out a third possibility. Jan 22, 2020 at 0:53
  • Hmm. It may of course be that my interpretation of English fails me here, as I would read the mentioned condition of "indirect addressing via the address value" means that the decision/marking for indirection must be part of the address word, not some additional fields or any parts of the instruction. This also makes sense in the context of the two mentioned CPUs (2650/HP2100), were indirection is marked with the top bit of an index register or a word in memory, not anywere in the instruction word. What part do I miss?
    – Raffzahn
    Jan 22, 2020 at 1:03
  • 2nd paragraph of the question - contrasts separate opcodes (example 6502) and a bit in the address (example HP2100). My answer is that there's a third way. Jan 22, 2020 at 1:16
  • So it isn't about what was asked? Ok. Works for me. For a better clarity it might be useful to add this as first paragraph - maybe including the reasoning why you think it isn't part of the instruction, but something else. (On a side note, the 6502 encodes indirect as '00' in bit position 3/4 for all instruction supporting indirection via a ZP pointer)
    – Raffzahn
    Jan 22, 2020 at 1:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .