The Novels

Economics 101, a Novel (Rough Draft) -- My first sustained attempt at a novel, two-thirds finished in rough draft, and heading a little too far south.
What would you do if you and your study partner, with whom you had been seriously discussing marriage, suddenly found yourselves all alone together on a desert island? Study economics?
Sociology 500, a Romance (Second Draft) -- The first book in the Economics 101 Trilogy.(On hold.)
Karel and Dan, former American football teammates and now graduate students, meet fellow graduate students Kristie and Bobbie, and the four form a steady study group.

Featured Post

Sociology 500, a Romance, ch 1 pt 1 -- Introducing Bobbie

TOC Well, let's meet Roberta Whitmer. Bobbie entered the anthropology department office and looked around. Near the receptionis...

Tuesday, February 11, 2020

Backup: 33209: A little about the 6800 (and Others)

Backup of https://joelrees-novels.blogspot.com/2020/02/33209-little-about-6800-and-others.html.

Chapter 7: Wandering Eyes

Chapter 7.5: A Little about the 6800 (and Others)


This chapter is for the geek in you. It's also important background information, to motivate the directions taken by various people in the story.

The 6800 had the primary binary operators that could be implemented for its two accumulators (A and B) in integrated circuits of the early 1970s:
  • Addition (ADD) and subtraction (SUB)
  • ADD and SUB taking previous carries into account (ADC and SBC)
  • Compare (CMP -- subtract without storing the result.)
  • Data movement (LDA and STA -- load and store accumulator)
  • Bit logic: AND, OR, and XOR (exclusive-or)
  • Bit test (BIT -- bit AND without storing the result.) 
  • Compare index register (CPX -- index as one operand instead of accumulator)
  • Load and store index and stack register (LDX, STX, LDS, STS -- also index and stack pointers instead of accumulators)
They also had several unary operators. Well, unary operators are binary operators with one of the operands implicit:
  • Increment and decrement (INC, DEC -- add and subtract 1)
  • shift and rotate left and right 1:
    • "Arithmetic" Shift Left (ASL -- equivalent to adding operand to itself. Ignores sign, or, in other words, the previous sign disappears.)
    • "Arithmetic" and "Logical" Shift Right (ASR  and LSR -- equivalent to dividing by 2. ASR preserves the high bit as a sign bit, LSR clears the high bit.)
    • Bit rotate left and right (ROL, ROR --  shifts, but the previous carry bit gets shifted in to replace the vacated bit.)
    All shifts and rotates save the bit shifted out in the carry bit, so the rotates are nine-bit rotations.
    Note that shifting n times is multiplying or dividing by 2n.
  • Clear (CLR -- load or store 0)
  • Bit Complement (COM: invert the bits, equivalent to subtracting the operand from 255 or bit XOR-ing with $FF. $FF == 255, or eight bits set to 1s.)
  • Negate (NEG: subtract the operand from 256. 256 == $100, one more than fits in eight bits.)
  • Value test (TST -- subtract zero from operand. Tells the program whether the operand is zero or negative, without altering the operand.)
Of the unary operators, the right shifts and the bit rotates are the only operators that can't be synthesized from one or more binary operators. And the rotates can be synthesized from the shifts, so the only truly necessary unary operators ar the two right shifts.

However, the unary operators can operate directly on memory, which can save a lot of code that would otherwise have to save the accumulator, do the math, and then restore the accumulator.

Hopefully, you are wondering how the operands are specified. This is the strength of the 6800, what sets it apart from the 8080. But it is also one of the places the engineers missed a bet.

Each of the binary operators (or instructions) has a version for each accumulator.  The other operand is specified as
  • the value of a byte of memory at an absolute sixteen-bit address (extended mode)
  • the value of the byte of memory immediately  following the instruction (immediate mode)
  • or the value pointed at by the index register offset by value of the byte following the instruction (indexed mode)
  • ... or the value at one of the first 256 locations in memory (direct mode).
The direct mode saves a byte, and the time of a memory cycle, somewhat softening the cost of saving registers to memory and then restoring them.

(Unfortunately, while the unary operators/instructions have both indexed and extended mode versions -- operating directly on memory. They also have a version for each accumulator. But there is not a direct mode version, apparently because the designers ran out of space in the 8-bit op-code map.

Kibitzing is free and you can always say it shouldabeen, but I think if I had been on the design team I'd have agitated for moving the inherent operators out of one of the ranks, to clear space for a direct mode version.

This is not a serious problem in any of the real implementations of the 6800, because direct is exactly the same as extended, with the high byte of the address equal to zero, except for the code size and time savings.

But if there were a direct mode version of the unary operators, the intent that the direct page be used to overcome the scarcity of registers would have been more clear, and much of the false information that circulated about the limits of the 6800 instruction set could have been avoided.

Also, if you wanted to put the direct page in its own address space, it would be a problem, which is something to keep that in mind.)

In addition, there are several instructions that are called "inherent" mode, where the operands are all implicit in the instruction. These include
  • manipulating result flag bits (TPA, TAP -- transfer Processor flags to/from A accumulator)
  • incrementing and decrementing the index and stack pointers (INX, DEX, INS, DES)
  • moving and adding/subtracting between accumulators (ABA, SBA, TBA TAB)
  • pushing and popping the accumulators to/from the stack (PSH, PUL. Note that the "pop from stack" operator in Motorola dialect is "PUL".)
  • moving the stack pointer to/from the index register to get at parameters (TSX, TXS)
  • returning from subroutines and interrupts (RTS, RTI)
  • waiting for interrupts (WAI)
  • Software interrupt (SWI -- useful for debugging and/or system calls)
Then there are the flow of control instructions which operate on the program counter (PC -- called instruction pointer in many other CPUs):
  • Jump and call/jump to subroutine (JMP and JSR -- only indexed and extended modes.)
  • Near branch and call (BRA, BSR -- one byte of signed offset is added to program counter.)
  • Conditional branches (Bcc -- condition encoded in the instruction.):
    • BEQ, BNE (zero bit -- equal or not equal after subtract or compare.)
    • BPL, BMI (negative bit -- plus or minus.)
    • BCC, BCS (carry bit -- clear or set, complemented in unsigned compare in BHI and BLS.)
    • BHI, BLS (combination carry and zero for unsigned comparison, high and low-or-same.)
    • BVC, BVS (overflow bit -- used in signed comparisons.)
    • BGT, BGE, BLE, BLT (combination overflow, zero, and negative bits for signed compares -- greater than, greater than or equal, less than or equal, less than)
I think that covers the instruction set of the 6800.

All of this is done with relatively few transistors, about 4000 to 5000 gates, less than ten thousand individual transistors, making it possible to manufacture the part using the technology available in the mid-1970s.

In the process of building these, however, they developed new technology that enabled more complex CPUs that could multiply and divide and such without having to add and subtract repeatedly.

When you design a computer's central processing unit, you may not realize it, but you use a mathematical technique of reducing the abstract general computing machine to real hardware.

Each CPU design reflects the what the engineers were focusing on when they performed the reduction.

RISC, "Reduced Instruction Set Computer", is therefore something of a pun, overloading the word "reduced" in a somewhat confusing way. The mathematical reduction in RISC architecture is performed with a focus on simplifying the instruction set -- reducing the number of instructions. (Didn't I say engineers love puns?)

When the 4004 was designed, the focus was on the functionality of a single accumulator in an absolute, incomplete reduction of the general computing model. It had to be that way, to fit a functional calculator controller into the available space on an integrated circuit using the technologies available and techniques understood in the very early seventies. The 8080 inherited that focus, through the 8008, adding separate index functionality in the form of index registers.

Intel's engineers were aware of the importance of indexing, so they designed it in a way that a base index address could be saved in one pair of eight bit registers, to be copied to the index register pair where offsets could be added as necessary. Each register had a purpose, and you moved data to the necessary register to operate on it.

Motorola's engineers started with an eight-bit implementation (reduction) of a minicomputer that they had built for their internal use, internally called the 680, according to one story I've heard. According to another, the 6800 was a reduction of the PDP-11 architecture. Either way, they focused on a pair of general-purpose accumulators., adding an index register that implicitly performed offsets.

Lack of generalization in the 8080 was a bottleneck, and the Z-80 was developed as an extension to the 8080, to get around that lack. The Z-80 was the source of the "80" in Tandy Radio Shack TRS-80's name.

The 6800's generalizations also had some lacks. Having only one index register can be clumsy. Constant offsets are not the only math you want to do on index addresses.

The 6502 was developed in no small part as a response to those lacks. It allows variables in page zero (6502 equivalent of the 6800 direct page) to be used directly as pointers, which helps it keep in the same ballpark, performance-wise, as the Z-80.

Motorola developed the 6801 to address the worst of the lacks in the 6800 while keeping the transistor count low, to save room for other functions in systems-on-a-chip (SOC) applications.
  • The 6801 adds instructions which pair the A and B accumulators, A as the high byte, to load, store, add, subtract, and shift sixteen bit values. This significantly simplifies manipulating pointers.
  • It also adds an instruction to directly add the B accumulator to the index register, directly supporting small variable offsets.
  • CPX, the comparison for the index register, is generalized in effect on the flags. Again, this improves index handling.
  • It adds a hardware multiply instruction, 8 bit by 8 bit, yielding sixteen bits useful for many things, including speeding array index math.
  • Adding a JSR call into the direct page might seem odd, but it makes it less costly to implement a small number of short convenience subroutines.
  • Pushing and PUL-ing (popping) the index register seems like an odd omission in the 6800, the omission is corrected in the 6801.)
  • BRN is not really new with the 6801, but the 6801 makes it official, allowing its use as a marker No-op separate from the one-byte NOP. 
*****

In overall performance, an engineered skilled in programming the 6502, Z-80, and 6801 could get similar performance from each in many general applications. The companies that produced them also produced a variety of special purpose microcontrollers based on or similar to them, for specific classes of applications, as the market moved forward in the 1980s.

*****


That's too much tech for one chapter, but I'll add a little more arithmetic, for background.

The smallest bit of information in a binary computer is called a "bit". You may think this is a pun, and it is, but it is also an acronym: "Binary digIT".
A bit can take two values, but the values can be interpreted in many ways, for example:

Values of a Bit
Values:OnOff
Numeric:10
Logic:TrueFalse
Sign:PlusMinus
Gender:Non-traditionalTraditional

are some possible ways of interpreting the values of a bit. Note, in particular, that the actual assignments are arbitrary. "On" could also be interpreted as "minus", for instance.

Two bits together can take four values. Some example interpretations might be

Values of Two Bits Strung Together
Values:On-OnOn-OffOff-OnOff-Off
Unsigned Numeric:3210
Signed Numeric:-1-210
Logic:TrueTheoreticalFantasyFalse
Sign:Plus-RealPlus-ImaginaryMinus-RealMinus-Imaginary
Vegetable:PotatoOnionCabbageCarrot

The fundamental size of a piece of information for a computer has been traditionally called a "byte".  Yes, this is a pun, pure and simple.

Most modern computers use an eight bit byte, which allows 28, or 256 possible values. Numeric interpretations quickly spring to mind, such as 0 to 255, or -128 to 127. Other interpretations are not just possible, but are quite often used. For example, one might imagine an encoding in which male, female, and 254 other genders are encoded in an eight-bit byte.

More typical is the US ASCII encoding, which actually only uses seven bits. Uppercase 'A', for instance, is encoded as decimal 65, and lowercase 'z' as decimal 122. '0' through '9' are decimal 48 through 57, which may seem confusing until you consider carefully the difference between numerals and numbers, or between the names of numbers and the value of numbers. The period, '.', is decimal 46.


So we can use numbers as codes for letters and words and all sorts of ideas, which means we can also store and work on text.

And we can use numbers to specify the color of a dot on a screen or a piece of paper, so we can also store pictures.

This provides us with ways to store and manipulate pretty much any information we could want. Sort of.

Interpretations are arbitrary. The binary number
01101101011000010110100101101100
could easily be read as binary equivalent of the decimal number
1,835,100,524
But If you put the most significant byte last, as Intel has been influencing the world more and more to do, it would be  
swap order: 01101100 01101001 01101101 01100001
compress:  01101100011010010110110101100001
decimal: 1,818,848,609
Or it could be the text string
mail
Of if the Intel byte order played tricks on you, it could be
liam
Or it could be interpreted as a floating point number under several different standards. Depending on the standard, it could be very large or very small.


Even as integers unsullied by byte order issues, the numbers have limits.

A byte in a 6800 or 6502 or about any microprocessor you'll see is eight bits. (In some other computer CPUs, especially older mainframes, a byte will be a different size -- nine, six, seven, twelve, etc.)

An 8-bit register or memory cell can store a number between 0 and 255, inclusive. That's not a lot, but you can string several together. Two 8-bit registers treated together can store a number between 0 and 65,535, inclusive.

Unsigned Integers
SizebitsMinimumMaximumas Power of 2
1 bit1 bit0121-1
2 bits2 bits0322-1
1 nibble4 bits01524-1
1 byte8 bits025528-1
2 bytes16 bits065,535216-1
4 bytes32 bits04,294,967,295232-1
8 bytes64 bits018,446,744,073,709,551,615264-1

(Nibble is also sometimes spelled "nybble".)

The same numbers can be read as signed numbers, in various ways. Two's complement is currently the most common method:

Signed Integers (Two's Complement)
SizebitsMinimumMaximumas Power of 2
1 bit1 bitplusminus--
2 bits2 bits-21-21 ~ 21-1
1 nibble4 bits-87-23 ~ 23-1
1 byte8 bits-128127-27 ~ 27-1
2 bytes16 bits-3276832767-215 ~ 215-1
4 bytes32 bits-2,147,483,6482,147,483,647-231 ~ 231-1
8 bytes64 bits-9,223,372,036,854,775,8089,223,372,036,854,775,807-263 ~ 263-1


It's tempting to show some limits for the current most common standard floating point numbers, but this really is probably enough tech for this chapter.

[JMR202002111425, added after posting:]

*****

Well, wait. I need to mention the 6809.

Some people think the 68000 was Motorola's answer to Intel's 8086.

That isn't really a good comparison.

The 68000 was Motorola's answer to the ARM, almost ten years too early. Or it was Motorola's answer to AMD's x86-64, about twenty years too early and 32 bits short. More to the point, it was Motorola's answer to Intel's iAPX 432, which was another architecture that was a little too much, too far ahead of its time.

That the 68000 was successful so far ahead of its time is something to think about, but I want to point to what was actually Motorola's answer to the 8086, the 6809. (Perhaps it would be more clear if I said it was the answer to the 8088.)

The 6809 is often mistaken for a stepping stone between the 6800 and the 68000. But they were developed simultaneously, with different but similar design goals.

The 6801, by the way, is thought to have been influenced by the design work on the 6809.

The 6809 was targeted more towards extending the 6800's reach into the sixteen-bit controller market, which it did quite well.

For various reasons (including the ever-mistaken "Must not compete with ourselves!" mantra), Motorola's SOC offerings split between the true-8-bit 6805 series and the half-16-bit 6801 series for half a decade, then moved ahead building on the 6801 instead of the 6809.

Although some see the 68HC11 as a stripped-down 6809, the indexed modes tells the tale. The 68HC11 is simply a 6801 with an additional index register and hardware divide, and appropriate instruction extensions. The 68HC12 and 68HC16 continued building on the 6801, neither offering the advanced programming model that the 6809 offered, although the 68HC16 offered a twenty bit address space.

This programming model could almost be achieved in the 8086, but Intel designed that for the mis-engineered stack frame approach to nested local context. BP and SP are in the same segment unless overridden. (We won't mention the half-baked nature of the segments up until the 80386, since everyone knows about that.)

The 68000 could be used to implement the model, but no one did because Intel was busy pushing stack frames. And IBM, ...

But that gets ahead of my story.

[JMR202002111425 end]

Chapter 8: Bootstrapping

[Backed up at https://joel-rees-economics.blogspot.com/2020/02/bk-33209-little-about-6800-and-others.html.]

No comments:

Post a Comment

Keep it on topic, and be patient with the moderator. I have other things to do, too, you know.