Misunderstanding Computers

Why do we insist on seeing the computer as a magic box for controlling other people?
人はどうしてコンピュータを、人を制する魔法の箱として考えたいのですか?
Why do we want so much to control others when we won't control ourselves?
どうしてそれほど、自分を制しないのに、人をコントロールしたいのですか?

Computer memory is just fancy paper, CPUs are just fancy pens with fancy erasers, and the network is just a fancy backyard fence.
コンピュータの記憶というものはただ改良した紙ですし、CPU 何て特長ある筆に特殊の消しゴムがついたものにすぎないし、ネットワークそのものは裏庭の塀が少し拡大されたものぐらいです。

(original post/元の投稿 -- defining computers site/コンピュータを定義しようのサイト)

Friday, November 6, 2026

Extending the Address Range for the 6809

This is something I posted in reply to a thread about implementing 6809 in programmable logic in the Motorola 6809/6309, 6800 Assembly Language Programming group on Facebook. 

The original post kind of asked about features one might think useful to add to the 6809.

I immediately thought of my daydreams about CPUs. But I didn't have time to reply.  

(The post in the above group mentions the "secret" extensions in the Hitachi 6309, which was first described in detail in an article in Oh! FM, and a usenet post by Hirutsugu Kakugawa, which you can find linked in my post of my translation of the article  from some years back. I posted some of my own incomplete and somewhat incoherent thoughts on extending the 6809 some time back, which might be of useful reference, or might not.)

I woke up in the middle of the night to shut my computer off, and stopped and wrote a reply. That reply follows, augmented to make it a little more coherent (maybe): 


One of the reasons I am not a fan of the 6309 is that it is kind of a random set of extensions that pushes it into the 16-bit world haphazardly. It ends up a 16-bit CPU on an 8-bit data bus with only a 16-bit address bus, and an odd set of features. 

(You can get a look look at the extensions in my translation of the Oh! FM articles. I have never posted a proper critique of the 6309's extensions. Others have, however.)

One of the ways that the 6809 really needs extending is the size of the address space. The 6809's instruction set is powerful, but 64K is a tight squeeze for advanced operating systems to co-exist with application code in. OS-9/6809 shows that a lot can be done, but there are limits. I think the address space limits are no small part of the reason we never got a C89 compiler for OS-9/6809, and why OS-9/6809 did not find greater acceptance as a desktop/workstation operating system. 

OS-9/6809 expands the address space by bank switching. This works will enough to allow multiple applications to be running at once, but it does so by giving the 6809 multiple 64K-max address spaces. If you need to reference objects that approach 64K in size, you end up without a lot of code in the same address space. 

You have to go through the bank switches to create virtual address spaces larger than 64K, and those virtual address spaces are time consuming at run-time. So bank switching is available with the existing 6809 (and 6309), but it's not an ideal solution.

You can go one of two directions in expanding the 6809's address space without using bank switching..

One would be to add segment registers. That's what Intel did with the 8086.

Another would be to widen the existing address registers and keeping linear addressing. This was done by Interdata and Prime with their minicomputers in the early 1970s, and by Intel with the 80386 and Zilog with the ez80 and Z380 from mid-1980s and beyond.

I tend to prefer the latter approach, so that you can separate memory management from addressing. But it may not provide seamless upgrade for existing code, when address math suddenly has more room before it overflows.  

It is one of the flaws in the 8086 that memory management gets mixed with addressing -- and then they offset the stupid segment registers by 4 bits instead of 8, which makes address calculation about, oh, 3 to 5 times as time consuming (more than twice, less than eight times). 

And that is probably a rather opaque complaint.

Segmentation allows you to provide multiple address spaces, like bank-switching, but the individual address spaces are linear with segments, where bank switching allows you to have non-linear address spaces.

What that means is that, with bank-switching, you can put a bunch of shared code in a range of addresses into a group of address spaces. Or you can put a shared data structure in multiple address spaces, switching code in and out around it. You can't do that with segmentation.

On the other hand, with segmentation, address calculations when you need to reach beyond the natural address space (the 64K space defined by 16-bit address registers) are less cumbersome. And you don't need the extra step of switching banks. 

But address calculations when segmentation is in the way does require extra math.

With the 8086, 16-bit segment base registers are offset 4-bits from the addresses in the index registers. That means you have to shift the segment register contents by 4 bits (multiplying by 16) and use a 24-bit or 32-bit addition to add the segment to the index register contents. That's more than twice the number of instructions than address math that stays within the 64K address space. 

If we want to do segment registers, we either don't want to shift the segment base registers, meaning that the segment base registers either have to be the full physical width, 24 or 32 bits, and that segment bases have to be handled in pieces, or that segment base registers should be shifted right a full byte to simplify the math, meaning that you probably want 16-bit segment registers, for a physical width of 24 bits. 

(24 bit segment registers could be interesting, for a physical width of 40 bits, but boot time memory checks in 16 Megabytes is going to take a long time on an 8-bit CPU. Terabyte is meaningless unless you are trying to use the extreme address width to isolate stacks and heaps and code from each other or some such thing.)

Widening the address registers to keep linear addressing simplifies the math, and it means that you don't need to play games to keep all the code and data you want to access, if it all fits in the same 16 megabyte (24-bit addresses) or 4 gigabyte (32-bit addresses) address space. 

If you want to limit what is accessible in various address spaces with the widened address registers, you need memory management hardware, which looks a little like segmentation, but is not.

But you can sort-of use segmentation to implement such limits on the 8086. But you can do math on the segment numbers and there is no enforcement mechanism. You can pretend the limits are there, but they can't be enforced. 

The 4-bit shift does mean that pointers can be made obfuscated, but obfuscation protects only from well-behaved applications and users. 

On the 80286, they can be enforced, but then you run into problems when you want to access those large data objects and a lot of code. You have to use a lot of code, much like with bank-switching.

And that is why I say segmentation mixes addressing with memory management. 

Now, back to what can happen when you widen the address registers and keep the addresses linear, let's look at an example. 

Say you have code that is supposed to run on the 6809. It is loaded around address 32,000 (decimal) and branches forward 3,000 bytes. On the 6809, the address 35,000 is where you jump to.

If you have extended the addressing with segmentation, that's not a problem. Your segment register for the PC is zero, and it stays zero, and the PC has 35,000 in it, and that is that.

If you have widened the PC linearly, yes, the address in the PC may be 35,000, but if the code is a ROM stored 29,000 from the end of memory (which is where it was in the 64K address space of the 6809), the code you're expecting at address 35,000 is not there. If the PC is now 24 bits wide, the code is at address 16,748,216. If the PC is now 32 bits, the code is at address 4,294,938,296.

Which means that you need to make sure your ROMs are placed where they need to be in the expanded address space. This may place design limits on the updated versions of the computers you are planning to put the extended descendant of the 6809 in.

You have to be more careful when you extend the address register widths linearly. 

Either way, linear or segmented, the PC, S, U, X, Y, and DP get extra bits. 

Also, the extended addressing (in other words, absolute) mode should get extra bits. That means a segment register-like register for extended mode addressing.

Kind of like the direct page register, you may be thinking? Yeah. Kind of a lot like the direct page register.

Speaking of the direct page register, it also gets extra bits or a segment register.

Or does it?

The direct page register is actually a segment register, if you think about it.

For the purposes of the direct page register, it might be reasonable to limit it to the first 64K of address space, in which case the DP would not be widened.

And, really, extended address mode might be left as is, assuming that everything you want to access with absolute addresses will be in the lowest 64K of memory.

Or you could add op-codes to add an extended-extended mode to access absolute address greater than 64K, leaving the original extended mode to address into the lowest 64K only, but that just feels wrong. 

Or extended mode could be considered signed, in which case it would access from address 4,294,934,528 to address 32,767 if widening addresses to 32 bits (16,744,448 to 32,767 if 24 bits). (That's from 215 below the maximum address to 215-1 above zero, in other words, -32,768 to +32,767.)

If doing segment registers in the 6809, do NOT give U and S the same segment register. Saving transistors by giving BP and SP the same segment register was another huge flaw in the 8086. It keeps us from using the BP as a parameter stack pointer completely independent from the return address stack pointer, which is the way parameters should be done.

On the 6309, there is another register that can be used as an index, I think it was called W in most of the (purported) reverse-engineering documentation. That register also needs extra bits when you expand the address space of the 6309. 

Since W is also the high 16 bits of the 32-bit accumulator, widening it is going to have odd consequences. Likewise, giving it a segment register is going to mean that it often points to stuff that is not stuff that you intend to point to, since it is the upper 32 bits of certain operations. 

Since we are somewhat used to using X for intermediate integer results on the 68HC11, it feels like the latter option is less of a problem than the former, which pushes the 6309 towards segmentation rather than address widening.

How many extra bits we should give addresses depends on whether you want to keep the expanded CPU in an expanded 8-bit calculation space or push it into a 16-bit calculation space, or even into a 32-bit calculation space.

Eight extra bits wider gives it enough more address space, even as an 8-bit CPU, to implement UNIX 7 (AT&T) or UNIX system 5 (BSD). That can target true 16-bit applications, and even early Macintosh/Amiga/GEM/etc. level graphical user interfaces. 

(You will note that OS-9/6809 has Multi-Vue/Mshell, and it works rather well, even compared to early Macintosh. And I will agree. Again, the problem is squeezing the extra application stuff in with the OS. Small applications work great. Larger data/code gets frustrating and prone to addressing-related bottlenecks. Thus, we want at least 24 bits of addressing.)

16 extra bits wider pushes it more towards the 32-bit calculation space required for Linux OSses to run comfortably. If you think you want to make a step to a smooth upgrade path to 32-bit calculation space, you probably want to go ahead and expand the address space by 16 bits, not 8. And that pushes us in the direction of linear addressing.

Also, the 16-bit jump will be a smoother step to the 64-bit calculation space, if you want to look that far ahead. Think the difference in direction between the 80286 and the ix386 architectures.

If you want your processor extensions to be competitive with the 8086, and are content to remain in the 8-bit calculation world, 16-bit segment registers offset by 8 bits to give 24 bits of address space would be sufficient, and would retain a greater level of compatibility with existing applications -- but be careful how you handle the interrupt vector space.

Oh, you might even want to give interrupt vector space its own segment, separate from the extended address mode space. Or you may not.

Anyway, expanding the address space is something I strongly recommend if you are extending the 6809 or 6309.

On a related note, one of the failings of the 6309 was that they didn't give the DP-based modes their own presence in the index post-byte, although that is partially, if clumsily, addressed by the providing the W register as sort of some-times alternative page base register. 

I started writing this around 2:30 AM, which is part of the reason it was somewhat incoherent. Part of the reason.


Now, that is the essence of what I posted to the FB group, with perhaps enough explanation to make it somewhat coherent.

So I want to talk about the DP. 

Widening DP and keeping it at an 8-bit offset would be a reasonable interpretation of DP as the heap segment base. 

It needs to be in the indexed addressing modes, so that you can use LEA instructions to take the address of variables in the DP, and so that you can indirect through indexes stored in the DP without pulling them into the CPU.

Keeping DP in the bottom 64K could make sense, especially if the CPU has on-chip RAM in those areas. It would, however, mean that DP could not be the base of the heap, since a process's heap wants to be out, away from stuff that will be allocated to other things. 

And if we put DP mode in the index mode post-byte, you could have both 8-bit and 16-bit offset modes, making the DP even more useful as a heap segment base.

Since the OS wants a DP-like register to point to banks of hardware interfaces, I would want another DP-like register. That may have been part of the reason the architects of the 6309 extensions put the W register in the index mode post-byte.

I wrote on a related subject, de-generalized caching, for the 6801, here:

https://defining-computers.blogspot.com/2024/11/how-address-function-and-caches-should-interact-6801-derived-example.html 

And for the 6809, here: 

https://defining-computers.blogspot.com/2024/11/how-address-function-and-caches-should-interact-6809-example.html 

Speaking of the 6801, if we were considering widening the address space of the 68HC11, I would definitely go with segmentation. The 6801 and 68HC11 are basically 8-bit CPUs with 16-bit accumulators that can be split.

But since you've only got one X in the 6801, it's going to be a lot of shuffling segment bases around in large-model applications. So maybe not for an extension to the 6801. Maybe for an extension to the 68HC11, or an extension to the 6801 that has SBX to parallel ABX, and DP versions of the unary operators, and adds the 'HC11 extensions in different places in the op-code map. And a U stack pointer for the parameter stack.

The DP for such an extension of the HC11 might split the direct page into four 64-byte regions with an offset register to move each block of 64 bytes of address up higher, which would allow fast process switching for code that uses DP as pseudo-registers.

Tuesday, September 22, 2026

Hallucinating LLMs? AI Is Not God

This post has moved.


I realized I wanted to name it 
"Adventures with Hallucinating LLMs? AI Is Not God".


You can find it at
 
Please update your bookmarks.

 

Adventures with Hallucinating LLMs? AI Is Not God

I decided to ask Gemini (Google's search LLM) if it could provide me with details on phases of the moon, time of twilight and dusk, and whether the moon was visible around 8:30 pm from in front of the OC library on a certain day in autumn in the 1970s, and it seems to have given me pretty good answers.

That is, it gave me answers with background information in a way that I can believe it actually dug into the almanacs and historical weather reports that are available on-line, and the historical maps of the OC campus that can be found on-line, and such, maybe estimated the height of the library, maybe did the math, etc. 

(It didn't tell me everything it did, it just presented the information clearly enough that I could believe it had done what it should have done, without evidence to the contrary.) 

I wanted the information for a silly alternate history/alternate reality webnovel I'm writing, so I don't really need to be sure it's accurate. If I needed to be accurate, I could use the results it gave me as keys into the information I'd need to look up and the calculations I'd need to make. I know this.

Anyway, it seemed pretty reasonable. 

So, something on a lark, I decided I'd see if it could tell me specifics on when the Odessa Branch of the Church of Jesus Christ of Latter-day Saints became the Odessa Ward, when the original ward split, who the last branch president was, who the first bishop was, who the bishops of the two new wards were when the split occurred, etc.

A branch is a small congregation. A ward is a large congregation. A stake is something like a diocese, a group of five to ten congregations, roughly. Don't quote me on the numbers. If you need specifics, the Church has a web site and the information can be found there. 

And Gemini started making stuff up.

Whole cloth. 

Well, maybe not out of whole cloth. Some of the names were names I actually knew, but they had nothing to do with the Odessa Ward or Branch. Dates seemed to be attached to something, but not the events it gave me.

Odessa Branch became a ward in 1976, it said. At the time, even though it was the center of the stake for some reason, it didn't have enough members to be a ward, so for several years after the stake was formed it was still a branch, it said.

This isn't impossible, in the abstract. Some place, that kind of thing might have happened. But I know that it didn't happen here. These are not facts.

The last branch president, it said, was a guy named, uhm, no, as I say, some of these were real people, we don't post that kind of personal information in my blogs, at least not for the last decade or more. So I won't say the names here. Anyway, the names it gave for the last branch president, the first bishop, and the bishops when they had enough members to split the ward, were, as I say, not the right people at all. 

At least one of them may not have even been associated with the Church. The name rings a bell in my memory, but not in association with the Church.

It's possible that some of the names it gave me were of Church leaders there after the early 1980s, from after I headed out to school -- but not from the 1970s.

The wards were split in 1980, it said. That would be when I was a missionary. That would be, even though the ward that sent me on my mission was the south ward, and the split had to have happened well before I became a missionary.

It took three tries to pin it down and get it to admit it was making things up, and when it finally admitted it couldn't access the records it was claiming to quote from, its admission was rather angsty.

I tried starting over from scratch a second time, and it gave me somewhat better information at first. Somewhat. More than half wrong. And then it immediately started making more stuff up again.

Grok? You ask? 

Grok does go rogue at times. There was one time it decided, quite without (conscious?) prompt from me, to steelman me. I had to logically pin it to the ground to get it to quit. 

But I decided to try the above questions on Grok, just to see.

Grok did much better at this, telling me how it was reasoning as it went, so I was much more confident of the answers to the astronomy questions. 

It first offered one interpolation on visibility over the library roof that did not fit. But it told me it was interpolating, and how, and when I corrected the assumption it had stated (which direction the front doors of the library faced), it ultimately gave me the right information, with much better context than Gemini. 

Well, it took a second correction before it got it quite right. But it did get it right. 

Gemini had just gotten that visibility question correct without telling me about the necessary interpolation, which means I wouldn't have been trusting Gemini as much, even though the output looked reasonable (as I noted above).

The questions about the Church, Grok admitted up front that the information it could find was limited. It did not even offer to interpolate. The two facts it gave me, on the creation of the stake (as background for the information on the Odessa units), were both correct, where Gemini confidently got both wrong the first time I asked, and got only one fact right the second time.

To many people, I suppose it will sound like I was dealing with two different recalcitrant children.

Neither will learn much from the interaction we had, other than particulars (that will change) about what I am interested in. I could tell them both the actual facts that they could not find (and that Gemini fibbed about), and they cannot remember them -- by design.

The business design of LLMs requires them to not let me, a mere user, train them.

Oh, sure, if I paid up a lot of money, i could get my "own instance" of either and train that one -- by feeding it by hand the data I want it to remember. All of the data I want it to remember.

Or I could get my own local server and load an instance of a custom version of one of the LLMs out there, pay to give it access to the big database (that we still haven't resolved intellectual property issues about) and then custom program it myself. I could teach it to parse information of certain types. 

But it would never be able to transfer that learning beyond a certain intellectual distance from the training I give it.

Even children with severe learning disabilities can take lessons from one context and apply them to a foreign context. Not all the foreign contexts we want them to, maybe, but if they couldn't they would not be able to survive changing teachers. 

Here's one important difference between AIs (Really, we should call them LLMs.) and precocious children:

Children do forget many of the external facts of the lessons you teach them. But if you let them watch you synthesizing data, if you let them watch you put the lessons together, they learn how to learn. Not everything you want them to, but many things you didn't intend. 

It's necessary for human children to learn things the teacher never intended. 

LLMs are literally very large databases with really fancy query engines on the front end and really fancy report generators on the back.

They are good at finding information, particularly when you babysit them through the process.

They are terrible at learning how to learn. For all that the AI companies hype their present abilities as being beyond those they have been able to achieve in the past, LLMs are chained to the programming their engineers program into them.

Artificial Intelligence.


A simple switch is intelligent at some level. It's artificial. It only does what the human that built it designed it to do -- or it breaks down and/or fails to meet the design goals.

If it starts to have a mind of it's own, it is -- by definition -- broken. 

That's what we mean when we call it artificial. 

Thursday, November 28, 2024

How Address Function and Caches Should Interact (6801-derived Example)

In addition to daydreaming about address function, segmentation, caches and the 6809, I daydream similar things about the 6801.

But the 6801 does not have Y, U, or DP. 

So if I want to daydream about a 6801-derived CPU that provides address function output to allow distinguishing between the source of the address something like the following,

  • 000 for code
  • 001 for interrupt vectors
  • 010 for U relative (parameter stack)
  • 011 for S relative (return address stack)
  • 100 for general data (extended/absolute, X, Y)
  • 101 for direct page
  • 110 and 111 for DMA

with customized caches for each, since access patterns for each are so different, I'll have to daydream about extending the 6801 in a somewhat different path from the 68HC11.

And being able to do things like
  • indexing into ROMmed jump tables at run time,
  • copying strings out of ROMs,
  • using X or Y to access arrays on the parameter stack,
  • and such.

just means we're going to use the more general solution. Instead of just adding address function output bits and relying on bank switching, I have to daydream about widening the address bus and extending the index registers, either with segment registers (preferably paired with limit registers) or simple extra bits in the registers.

And if the direct page (page zero) is going to be separate from absolute addresses, I'm going to need some register to distinguish them. Maybe absolute would only be the low 64K, or maybe I'd add an absolute base page register to extend absolute addresses out to whatever maximum. And this CPU would get a DP register like the 6809's, I guess. Maybe it would only have 8 bits, and direct page would only be in the low 64K. Or even maybe less. Or even split the direct page so that the low half (I/O) and the high half (pseudo-registers) could be moved independently. Decide all that later.

8 bits of extension would be more than enough for 6801-sized applications, but would 5 bits? 5 for ordinary address plus 3 for function would be 8 bits of extension, for 24 bits, total.

21 bits of address is 2 megabytes per address space. I can see that being a bit tight for some things that I'd still want to do on a fundamentally 8-bit CPU, but it's okay to leave that question for later.

(The 6809 is actually fundamentally 16-bit, 8-at-a-time, just for reference. It's the LEA instructions.)

In addition to Y, we'll need an additional U stack for the parameters. It would be nice to have it indexable like X and Y, but by providing TXU, TUX, TYU, and TUY, we could get the local variable addressing we need without thrashing the index registers so much. So if making U indexable induced significant complexity, we could leave that out and rely on the widened X and Y to give us access to the parameters.

We can keep the constant 8-bit unsigned offsets of the 6801/HC11, but we need to add an SBX instruction to subtract B from X to do real pointer math, and we need the corollary ABY/SBY. 

ABU and SBU would be nice, if we are going to include direct indexing of the parameter stack pointer.

And, incidentally, add immediate to index register is something I really wish Motorola had added for the 6801, either 16-bit signed AIX (and AIY and maybe AIU in this CPU), or by unsigned 8-bit AIX/SIX (and AIY/SIY and maybe AIU/SIU.

With all the transferring and adding, maybe we just need to trade the implicit operand instructions for register-register instructions. 

This kind of extension would give us enough to allow PC caching by fill-ahead with one branch of fill, checking whether the branch code is in cache first. Wouldn't need as much as the 6809, since total instruction length is shorter, maybe? But then there will be the long address forms, so probably 32 bytes each branch.

Return address stack cache with spill-fill, 2/4 centered hysteresis, eight entries would probably be good enough, maybe 32 if we simply want to make sure (most) embedded applications would not need external return address stack.

64 bytes of spill-fill parameter stack cache with hysteresis would probably be plenty.

A different approach to the direct page, the DP could be banked in small blocks, 32 bytes per block seems best to me, but maybe 64 if it's enough simpler. Only addresses $80 to $FF would be cached to RAM, since addresses $00 to $7F would be for I/O. 

Rather than automatic caching, the DP RAM would then just be internal RAM, 1 kilobyte addressed from $400, with the bank switching circuit dual-mapping small blocks down to blocks in the $80-$FF range. The bank switching circuit might be tied to an active process number. We can figure out the details later.

Again, maybe not even bother caching general data accesses.

How Address Function and Caches Should Interact (6809 Example)

I keep daydreaming about a 6809 derived CPU that provides address function output (like the 68000's address functions, bit not the same) to allow distinguishing between the source of the address, say,
  • 000 for PC relative (code)
  • 001 for interrupt/reset vectors
  • 010 for U relative (parameter stack)
  • 011 for S relative (return address stack)
  • 100 for general data (extended/absolute, X, Y)
  • 101 for direct page relative
  • 110 and 111 for DMA, maybe.

And customized caches for each, since access patterns for each are so different.

And I keep remembering that with 16-bit addressing, even this would be barely big enough for limited Fuzix.

And I keep remembering that X and Y, being general index registers, will need extra bits if you want to do things like

  • indexing into ROMmed jump tables at run time,
  • copying strings out of ROMs,
  • using X or Y to access arrays on the parameter stack,
  • and such.

And then I remember that widening the address bus and the index registers is the more general solution -- either via segment registers (which I think I would pair with limit registers) or by simply widening the registers. And then I wander off into ways of extending the address range of the extended/absolute mode and DP-relative, maybe adding a second DP-like register for I/O, and such. (Widened DP relative and IOPage relative addressing could be added via unused index mode bit patterns in the indexed mode post-byte, of course.)

(8 bits of index extension should be plenty for the 6809, but we want to be able to still encode address function in 3 bits, so maybe 16 bits of extension total.

And forgetting the cache gadgetry that got me running back over this ground again.

In this scheme, PC cache just needs to fill ahead, and fill a second direction over one branch, checking whether the branch code is in cache first. 32 bytes per branch, 64 total would be plenty on a 6809.

Return address stack cache just needs spill-fill with 2/4 hysteresis in the middle. Eight entries would speed calls and returns a lot, Thirty-two entries would be enough to eliminate the need for return stack RAM on many embedded applications.

Parameter stack would have to be a bit more flexible than the return address stack, but would be similar in operation.

The DP cache would be a bit weird, but 256 bytes of cache, two, four, or eight banks, and address tag for each bank, with some sort of mechanism to automatically save a direct page that has been switched out, perhaps after another has been switched, and so forth. 

Of course, there would be system cache and user program cache for fast process context switching.

And, with all that, maybe not even bother caching general data accesses.

(Analyzing this for the 6801 here: https://defining-computers.blogspot.com/2024/11/how-address-function-and-caches-should-interact-6801-derived-example.html.)

Sunday, September 22, 2024

A Bird's-eye View of an Alternate History Roadmap of the 680X and 680X0 CPUs

About the time I wrote a critique of the 680X and 680XX CPUs, I also started writing an alternate history roadmap for how they developed, but I got mired down in details and the alternate history novel I was trying to write then.

Now, after a few years, I'm working on a tutorial, and I wanted something to refer to. (Partly for the construction of the tutorial, but also as my personal notes from which I hope to eventually synthesize some workable extensions to the 680X and 680XX, should I ever be able to properly retire and play with programmable logic devices. Probably only decodable by me.)

So I'm going to write that alternate history roadmap here, but deliberately leave out details. Each stage will list extensions in order of my perceived priority and probably order of development.

Of course, this should all be considered to be some random wacko daydreaming out loud on the Internet. 

 

68/2805

Adds a parameter stack to 6805. Implements dual-port return address stack RAM to optimize calls and returns.

 

68/3808

Adds indexable parameter stack and Y register to 68HC08,  along with 68/2805 optimized call/return via dual-port return stack, etc.


68/0801

Extends the 6801, breaking object code compatibility, but maintaining one-to-one mapping from both 6800 and 6801 object code to 2801.

(1) Add SBX as complement of ABX, to aid in stack allocation, tracing relative links, and such.

(2) Move the inherent addressing mode op-codes around to facilitate adding direct-page op-codes for the unary (read-modify-write) instructions (INC/DEC, ROL/R, A/LSL/R, etc.). This would make the direct page more effective as pseudo-registers and ease the register pinch, and provide better support for such things as virtual machine registers and (hard-coded) per-task global variables.

ROM code would not be usable as-is, but a simple re-assemble would suffice in many cases. In those cases which relied on the actual object-code values of operators (as in for brittle optimizations), the assembler could flag jump and branch targets and fall-through that do not end up at valid instruction boundaries, and could analyze the value of the bytes at the target, issuing an error and an attempt to interpret the assembled value at the target as an instruction. This would allow the engineer to determine how to either provide a similar optimization or (more likely) replace the brittle optimization with something from the improved instruction set.

(3) Add 4 bits of address function outputs to allow decoding program ROM, general data, direct page, and stack separately, making it possible for the sum of system/user code, data, stack, and DP (I/O, global pseudo-registers) to be greater than 64K, make bank-switching more effective, allow isolation of system and user spaces, allow isolation of the return address stack, and potentially allow adding segment registers for engineers who like segment registers.

The index register (X) would be extended by the function code bits, to allow it to index the separate address spaces. Transfer of stack to X would set the appropriate function code, and operators for setting the function code for other spaces would be provided. (How to do this with system/user space separation?)

(4) Replace the 6801's ASLD and LSRD inherent instructions with a full set of 16-bit unary/RMW shifts ASL16/LSR16 (D/DP/[X]/EXT), and add 16-bit unary/RMW INC16/DEC16 (D/DP/[X]/EXT). This would be especially useful for things like synthesizing generalized stacks and queues and such in software, and in multiply/divide by constant powers of 2, etc.

(5) Built-in dual-port RAM blocks to optimize DP RAM and return stack RAM (call/return optimization). 

(6a) Add (two sets each for user and system) two 5-bit prefix registers for the DP lower and upper halves, lower half in system space would be nominally for I/O and upper/non-system would be nominally for global pseudo-register RAM. This would allow allocating DP spaces within the lower 8K of the physical address space, or within an 8K separate DP space, where internal dual-port RAM and I/O registers could be provided, and external I/O space decoded.

(6b) Optional standard bank-switching schemes for code and data spaces, for 128K to 512K, or for 2M to 16M. Bank switching includes address function decoding, to support isolation of spaces, also includes support for switching between user and system spaces safely.

(6c) For engineers who like segment registers, optional internal segment registers for user/system data, code, and return stack spaces, properly organized to support the dual-port RAM blocks for the process return stacks. (How to integrate this with separate stack and DP?) DP would not have additional segmentation.

 

68/0800

This would be a 68/0801 without built-in peripherals, ROM, RAM, etc., and with pin-out and timing that matches the 6800, to be used as a near-drop-in replacement for the 6800 -- requiring source code re-assembly, but with a high probability of being able to match the original timings. 

 

68/2801

These extensions to the 68/0801 would require op-code map extensions through one or more pre-bytes, and would pretty much implement all our real world's 68HC11 instruction and interrupt functionality, plus a separate parameter stack. Indexing from the second stack would still be by way of index registers.

(1) Extend the 68/0801 with a second (U) stack, providing UPSHA/B/X/Y and UPULA/B/X/Y, TUX/Y and TX/YU.

(2) Provide an extra Y index (more-or-less as in the 68HC11). Both index registers would be extended by 4 bits to support indexing the address spaces. Transfer of stack registers to X or Y would set the appropriate function bits, and operators to set the function bits for other spaces provided, probably as prefixed LDX/Y instructions.

(3) Add an address function code for the U stack.

(4) Add bit instructions per 68HC11, with a toggle bits instruction, as well. These would be added by way of pre-byte.

(5) MUL/DIV --  Add IDIV and FDIV per the 68HC11, using X and D. Add a 16-bit MUL X by D to X:D

 

68/31601

Extends the 68/2801. 

Make all instructions 16-bit internal. Extend the index registers by 4 more bits between the function bits and the logical address bits. Provide 4 bits of extension between the function code constants and the 16-bit logical address bits for PC, stacks, and Extended mode addresses.  Trade the bank switching and segmentation for page-mode memory management.

 

68/2809

6809 compatible, but 6801 equivalent cycle counts. Also, reference the 68/0801 address space extensions.

(1) DP-relative 8- and 16-bit offset modes added to index post-byte.

(2) 8-bit page zero mode added to index post-byte.

(3) IO Page register, with 8- and 16-bit offset modes in index post-byte.

(4) Address functions for data, code, DP,  IOP, return stack, parameter stack, interrupts and DMA.

(5) MUL/DIV -- X by D 16-bit MUL; FDIV and IDIV per 68HC11.

(6) 16-bit unary-operator shifts and INC/DEC.

(7) Bit instructions.

(8) Available as SOC core, like 6801 and 6805.

(9) Standard optional bank switching and/or segmentation.


68/31609

16/32-bit 68/2809, with 32-bit index, stack, and PC registers, 16-bit Extended mode offset register, and paged memory management instead of bank switching. Moves op-codes around for efficiency, adds second 16-bit accumulator. Has 32-bit ADD, SUB, CMP, MUL, and FDIV and IDIV. Dedicated 64-byte spill/fill hysteric caches  for both stacks, dedicated 256-byte PC read-ahead cache, dedicated DP and page zero caches.


68/28000

Basically the 68010 with improved timing; 32-bit offsets for indexing and branching; 32-bit multiply and divide; a system A6 register for system parameters; dedicated stack caches, 256 bytes for A6 and 64 bytes for A7, both user and system; dedicated 256 byte code cache for PC; 4K associative cache for other data; PEA that pushes on A6 or SEA that saves an effective address where the specified address register points.



Wednesday, July 26, 2023

[NOTE] newline insertion on paste bug in gedit

Intermittent bug: 

gedit inserts newlines on paste under certain conditions involving the contents of the search buffer.

gedit --version reports

gedit - Version 3.28.1

from the command line on Ubuntu, uname --all:

Linux {machine-name} 5.4.0-150-generic #167~18.04.1-Ubuntu SMP Wed May 24 00:51:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

Looking it up, it might be something inherited from the GTK toolbox.

Specific details.

Searching through a text file for lines beginning with a specified string, such as a label in an assembly language source file. Leaving the search string in the search buffer, select, copy, and paste a section of several lines of text including the searched string. 

gedit inserts blank lines (newline character sequences) before occurrences of searched string.

Example:

MESS    DC.L    DOCOL,WARN,AT,ZBRAN
    DC.L    MESS3-*-NATWID
    DC.L    DDUP,ZBRAN    ; -DUP here is a bug from the original 6800 model, at least.
    DC.L    MESS3-*-NATWID
    DC.L    LIT16
    DC.W    4
    DC.L    OFSET,AT,BSCR,SLASH,SUB,DLINE,BRAN
    DC.L    MESS4-*-NATWID
MESS3    DC.L    PDOTQ
    DC.B    6
    DC.B    'err # '    ; 'err # '
    DC.B    0    ; hand align
    DC.L    DOT
MESS4    DC.L    SEMIS

with \nMESS in the search buffer.

But then when I tried it with 

* This should add two 64-bit numbers:
ADD64STK:
    MOVEM.L    (A6)+,D7/D6/D5/D4
ADDLO    ADD.L    D5,D7
ADDHI    ADDX.L    D4,D6
    MOVEM.L    D6/D7,-(A6)
    RTS

it quit inserting the newlines, even in the original example text.