I've described the differences between the 6800 and the 6801 instruction architectures at length in several other posts. This is a high-level overview.
(This same rant with notes on 68HC11 and 6809 can be found here: https://defining-computers.blogspot.com/2021/08/differences-between-6800-and-6801-with-notes-68hc11-6809.html .)
(But I still ignore the built-in ROM, RAM, and peripheral devices in the 6801. Those are important, but require separate treatment.)
First, where the 6800 had two independent 8-bit accumulators, A and B, the 6801 has, in addition, the ability to combine them as a single 16-bit accumulator (A:B, or D) for several key instructions, load, store, add, and subtract:
LDD
STD
ADDD
SUBD
HIgh byte is in A, low byte in B.
These are available in the full complement of binary addressing modes that the 6800 provides:
- immediate (16-bit immediate value)
- direct/zero page (addresses 0 to 255)
- indexed (with 8-bit constant offset)
- extended/absolute (addresses 0 to 65536)
Note that there is no separate CMPD. If you really need to compare two 16-bit values, you'll need to go ahead do a destructive compare -- save D in a temporary, if necessary, and use the subtract instruction. (The way the flags work, it's only rarely necessary to do so.)
Be aware that the D register is not an actual additional register. It is simply the concatenation and A and B. If you LDD #$ABCD, A will have $AB in it and B will have $CD in it.
Second, the 6801 has an 8-bit by 8-bit integer multiply,
MUL
which multiplies the A and B accumulators yielding a 16-bit result in the double accumulator D. 16-bit multiplies can be done the traditional bit-by-bit way to save a few bytes, or with four 8-bit MULs and appropriate adding of columns for a much faster result.
There is no hardware divide in the 6801. You'll have to move up to 68HC11, 68HC12, 68HC16, 68000, or Coldfire, for that.
Third, the 6801 adds two 16-bit shifts, logical shift left and right, accumulator-only:
LSLD (ASLD)
LSRD
These were considered key instructions. If you need 16-bit versions of the rest of the accumulator shifts and rotates, they are easy, and not expensive, to synthesize with shift-rotate or shift-shift pairs.
(Note that the 6800/6801 does not provide an arithmetic shift left distinct from the logical shift left. As an exercise for the reader, see if you can make an argument for doing so, and describe the separate behavior the arithmetic shift left should have. Heh. Not sure if I'm kidding or not. Saturation?)
Fourth, the 6801 adds a bit of index math, and push and pop for the index register:
ABX (add B to X, unsigned only)
PSHX
PULX
There is one 6801 instruction (four op-codes for each of the binary addressing modes), and one only, with different semantics from the 6800:
CPX (full results in flags)
On the 6800, you could only depend on the Zero flag after a CPX. (Actually, Negative was also set, and oVerflow, too, but not by rules that were useful.) On the 6801, the Negative, oVerflow, and Carry flags are also set appropriately, so that you can use any conditional branch, not just BEQ/BNE, after a CPX and get meaningful results.
These improve index handling, help support stack frames, etc.
(I am not a fan of stack frames on the return address stack, but the frame pointer pushed on S could as easily be a pointer into a synthesized parameter stack. I think maintaining a synthetic parameter stack is no more expensive than maintaining stack frames in a combined stack on the 6800 or 6801.)
The 6801 provides an additional op-code for the call instruction, adding the direct/zero page addressing mode:
JSR (direct page)
This allows the programmer to put short, critical subroutines in the direct page for more efficient calls.
(JMP does not get the additional op-code, which means that inner-interpreter loops for virtual machines do not benefit from allocation in the direct page, same as the 6800.)
Finally, the 6801 adds a branch never instruction:
BRN
This can be useful as a marker no-op in object code, helpful in debugging, linking, and compiler code generation.
At this point, you should suspect that the 6801 is fully object-code level upwards compatible with the 6800. It is.
If you want more information than this and my writing seems understandable --
You can see something of how these additions improve code in a post I put up describing 64-bit math on several of the Motorola CPUs:
https://joels-programming-fun.blogspot.com/2020/12/64-bit-addition-on-four-retro-cpus-6800.htmlAlso, I discussed microcontroller (plus 6809) differences in this post:
https://defining-computers.blogspot.com/2021/08/guessing-which-motorola-microcontroller-6801-6805-6811-6809.htmlI have a long rant discussing the differences between the 68HC11 and the 6809, which picks up the 6801 and 68000 along the way:
https://defining-computers.blogspot.com/2018/12/68hc11-is-not-modified-6809-and-what-if.html
And I have this chapter of a novel in process (or suspended animation, not sure which), which gives a bit more of a detailed discussion of the 6800 instruction set architecture, touching on the 6801:
https://joelrees-novels.blogspot.com/2020/02/33209-little-about-6800-and-others.html
Also, with Joe H. Allen's permission, I forked his Exorsim project and added instruction set architecture support for the 6801 to it. You can find source code for a fig-Forth implementation for the 6800 and an implementation (somewhat) optimized to the 6801 in the test source code I include there:
My assembler for 6800/6801 may be useful for assembling the fig-Forth source:
No comments:
Post a Comment