EmbeddedRelated.com
Forums
The 2026 Embedded Online Conference

x86 real mode

Started by Don Y October 17, 2014
Tauno Voipio <tauno.voipio@notused.fi.invalid> wrote:

(snip, I wrote)

>> OS/2 1.x allowed for 8K segment selectors for a user process, >> each could be up to 64K, so 512MB. With DOS, only 640K, or if >> you use the right display board, you can go up a litle more.
> This was (and is) an architectural limitation of the segment > descriptor system: there are 13 bits for local descriptor > table indices.
When debugging with OS/2 1.x, I would allocate each array to its own segment, calling the OS/2 allocate routine. Calling malloc() allocates 64K segments, and then parcels them out. The limit of 8K segments (minus the code segments) could have been a problem, but usually wasn't. Allocating one segment per array allows for a hardware trap going outside the array, fetch or store. Compilers at the time didn't do array bounds checking, and it is still not so common for C. -- glen
On Sat, 18 Oct 2014 09:06:45 +0000 (UTC), glen herrmannsfeldt
<gah@ugcs.caltech.edu> wrote:

>upsidedown@downunder.com wrote: > >(snip, I wrote) >>>Systems with (externally) bank switched RAM weren't all that >>>unusual, so maybe putting something like bank switch inside >>>the chip wouldn't have been so strange. > >> One of the (pre-release) selling point was that the 8086 was 8080 >> compatible. When 8086 details finally released, this appeared to be >> some degree of assembler mnemonics similarity. > >Most 8080 instructions translate to a single 8086 instruction, >but some need two or three. The number of bytes might be a >little more, so it won't fit into 64K anymore. > >Someone might still have the program that Intel sent out >to do the conversion.
It was usually pretty easy to also convert the program to small model, allowing 64KB of both code and data. Also, on a system like MS-DOS, the OS no longer took any of your 64KB address space for a tiny/com format program (well, except for the 256 byte PSP). As to the conversion program, I haven't seen a copy in decades, but I do have a hardcopy of the instruction equivalences, that I've been meaning to put online for years... Most of the 8080 instruction that needed two 8086 instructions were the conditional branches (if the range didn't fit in the 8086s 8 bit relative offset), and the (rarely used) conditional calls and returns (which 8086, of course, doesn't have, needing to be turned into a reversed sense conditional branch around the actual call or return). In addition LDAX/STAX and PUSH/POP PSW needed two instruction sequences. There were four* 8080 instructions that needed more than two 8086 instructions to emulate (DAD, INX, DCX and XTHL), none more than five instructions, although the first three** could be replaced with a single 8086 instruction if you didn't care about exact flag behavior, leaving a three instruction replacement for XTHL. *In the past I've posted that it was five instructions, but now that I'm actually looking at the doc, it appears to be only four... **Which are the three instructions that operate on 16 bit registers, and on 8080 don't set the flags the same way as the 8-bit instructions.
Am Sat, 18 Oct 2014 09:06:45 +0000 (UTC) schrieb glen herrmannsfeldt:

> upsidedown@downunder.com wrote: > >> One of the (pre-release) selling point was that the 8086 was 8080 >> compatible. When 8086 details finally released, this appeared to be >> some degree of assembler mnemonics similarity. > > Most 8080 instructions translate to a single 8086 instruction, > but some need two or three. The number of bytes might be a > little more, so it won't fit into 64K anymore. > > Someone might still have the program that Intel sent out > to do the conversion.
CONV86. I used it to port a 8080 program to the then new PC. It really worked but the generated code sometimes was ugly in order to prevent compatibility issues. Don't thave CONV86 anymore, though... -gerd
On 10/18/2014 1:10 AM, upsidedown@downunder.com wrote:
> On Fri, 17 Oct 2014 15:39:20 -0700, Don Y <this@is.not.me.com> wrote: > >> On 10/17/2014 3:25 PM, glen herrmannsfeldt wrote: >>> Don Y <this@is.not.me.com> wrote: >>> >>>>> Well, the 8086 was an upgrade from the 8080 or 8085. >>> >>>> The 8085 was essentially an 8080 with an internal clock driver >>>> (and a couple of other little fixups -- RIM/SIM, INT5.5/6.5/7.5, >>>> etc.) >>> >>> And a 5V only power supply. >> >> Note that most practical memory still required two (even *three*!) >> power supplies. > > Only if you used DRAMs.
cf. 1702, 2708, TI's 2716 (I've been designing embedded systems for a LONG time -- long before they were called such! Starting at i4004)
> Apart from some early (1702) EPROMs, most EPROMs were single supply as > well as small SRAMs.
SRAM's were *really* small. E.g. 2114's.
>>>>> They knew by then that people were running out of address space. >>> >>>> Yes, an Our Hero, Bill figured 640K was more than anyone would >>>> EVER need! :-/ >>> >>>> [How much nicer things would have been had the 68K won that design-in] >>> >>> Might have been a 68008, though. They seem to like the 8 bit bus. >> >> But, there was a SEEMLESS path upward from the 68000. Intel gave us all these >> "backward compatibility issues" to carry forward (into the 31st century!). >> It was just a memory bandwidth tradeoff (08, 010, 020, etc.) moving forward. > > You seem to think that the "computer" was invented by the > semiconductor industry,
Where do I make that claim? I cut my teeth on a small IBM mainframe, a Nova 1 and a PDP 8e (or i... can't recall, now). Then, 10's, 11's/VAXen, Eclipse, etc. But, putting something that existed "in a large box with a large power supply" onto a single, commercially viable DIP doesn't mean you can just pick whatever architecture you want, turn the crank and start spitting out chips! E.g., the i4004 was a DOG in comparison to the 8080 (or even 8008). Instruction execution times were ~10-20us -- almost "audio frequency". And, you're just dealing with nybbles! Despite the fact that "big iron" coexisted (gee, why couldn't they pick some of those features???)
> in fact there was a quarter of a century > computers before that.
> With higher levels of integration possible, more and more > functionality could be integrated into a "single" chip. First you > might have needed a few hundred TTL chips, then the key functionality > could be put into a few LSI chips and finally you could announce the > world first 4/8/16/32 bit chip, but still needing a large amount of > auxiliary chips.
Before the i4004, most bigger machines were massive amounts of MSI. In the late 70's, we were shipping Reading Machines (an "embedded system" the CPU the size of a washing machine) with *core*. A 4KW "semiconductor" memory was a 16"x16" (?) PCB. (This is contemporary with i4004 "embedded systems")
>>>> IIRC, the original "ISA" bus wasn't even formally characterized >>>> until after the fact. >>> >>> IBM always was, and still is, good at documented what they did, >>> though not always why they did it. There are manuals that give lots >>> of detail on every line of the bus, and BIOS listings with comments. >>> >>> But then there were mistakes along the way. Edge triggered >>> interrupts make it hard to share INT lines. >> >> I think documentation exists *now* but not "back then". I can recall >> having one helluva time trying to design "ISA bus" cards with any >> sort of *guarantee* that they would work in ANY pc (even genuine big blue). >> You ended up designing empirically and to "typical" numbers as there were >> no hard and fast numbers that you could rely upon from a PC vendor. > > There had been various minicomputer busses before the first > microcomputers, so it should have been possible to pick the best > features.
The Market OFTEN doesn't pick the "best qualified" solution.
On 10/18/2014 1:53 AM, upsidedown@downunder.com wrote:
> On Fri, 17 Oct 2014 14:32:20 -0700, Don Y <this@is.not.me.com> wrote: > >> Hi George, >> >> On 10/17/2014 12:29 PM, George Neuner wrote: >>> On Fri, 17 Oct 2014 07:23:40 -0700, Don Y <this@is.not.me.com> wrote: >>> >>>> What are the most conservative, *practical* expectations I can >>>> make living in x86 real mode: TEXT of 64K and DATA of (disjoint) >>>> 64K? BSS in it's own segment? Or, shared with DATA? >>> >>> If you use the tiny (64K code+data) or small (64K code, 64K data) >>> model, .bss and stack share space with your data. If you choose a >>> model with multiple data segments, .bss and stack can be separate (but >>> tool dependent you may have to ask for it explicitly). >> >> It seems the "safest" (most conservative) assumption is to figure >> a single 64KB address space. If, instead, the x86 ALWAYS prepared >> a separate data space (etc), then I could assume a larger model. >> >> Or, if the tiny model was IMPRACTICAL for any use (and was just >> included as an homage to the 8085). >> >> Or, if ints were always 32b, etc. >> >> I.e., it seems safe to assume the tiny model was intended to be >> *usable* and not just "an engineering/marketing exercise". > > What is the problem with 64 KiB program address space with much larger > total system memory ?
Given a CLEAN SLATE, there's no problem with *anything*! :> The "problem" lies in living within existing constraints AND writing portable code. E.g., no "near"/"far" nonsense. Take the machine the way it existed when your code was invoked, "do your thing" -- and leave the machine in the state that you found it (or, explore ALL of the consequences of ANY changes you may have introduced to its state)
> In a previous company, my department used machines with 64 KiB or 128 > KiB (I+D) and we never had problems with the program address space > limits. Just split the functionality into a sufficient number of > tasks.
Sure, and I've written UNIX-like OS's to run on Z80's (bankswitching instead of swapping). No reason the terminal handler needs to co-reside in the same address space as the OS; no reason for the OS to share an address space with the application, either! But, that sort of code is anything BUT "portable". The next host architecture may have an entirely different set of constraints imposed by its hardware.
> Of course if you need to access a huge data base, this was > problematic.
On Sat, 18 Oct 2014 08:20:35 -0700, Don Y <this@is.not.me.com> wrote:

>On 10/18/2014 1:10 AM, upsidedown@downunder.com wrote: >> On Fri, 17 Oct 2014 15:39:20 -0700, Don Y <this@is.not.me.com> wrote: >> >>> On 10/17/2014 3:25 PM, glen herrmannsfeldt wrote: >>>> Don Y <this@is.not.me.com> wrote: >>>> >>>>>> Well, the 8086 was an upgrade from the 8080 or 8085. >>>> >>>>> The 8085 was essentially an 8080 with an internal clock driver >>>>> (and a couple of other little fixups -- RIM/SIM, INT5.5/6.5/7.5, >>>>> etc.) >>>> >>>> And a 5V only power supply. >>> >>> Note that most practical memory still required two (even *three*!) >>> power supplies. >> >> Only if you used DRAMs. > >cf. 1702, 2708, TI's 2716 (I've been designing embedded systems for a >LONG time -- long before they were called such! Starting at i4004) > >> Apart from some early (1702) EPROMs, most EPROMs were single supply as >> well as small SRAMs. > >SRAM's were *really* small. E.g. 2114's.
That is a big one with 1024x4 bits :-) The original 6800 sample system was 6830 ROM with 1024 bytes ROM and 6810 with 128 bytes of RAM.
>But, putting something that existed "in a large box with a large power supply" >onto a single, commercially viable DIP doesn't mean you can just pick whatever >architecture you want, turn the crank and start spitting out chips! > >E.g., the i4004 was a DOG in comparison to the 8080 (or even 8008). >Instruction execution times were ~10-20us -- almost "audio frequency". >And, you're just dealing with nybbles! Despite the fact that "big iron" >coexisted (gee, why couldn't they pick some of those features???)
The i4004 was just a repurposed handhold calculator chip, A handhold four banger calculator doesn't need high speed due to the slow human entry speed.
On 18/10/14 00:25, glen herrmannsfeldt wrote:
> Don Y <this@is.not.me.com> wrote: >
>> [How much nicer things would have been had the 68K won that design-in] > > Might have been a 68008, though. They seem to like the 8 bit bus. >
It was the real 68000 that the engineers wanted - one of the main reasons for the PHB's moving to the 8088 was to get an 8-bit bus and therefore "half" the cost of the memory and bus. And as the PHB's viewed the machine as merely a marketing exercise to see what people wanted, and it was thus a throw-away design, the technical deficiencies of the Intel chip didn't matter.
On 10/18/2014 10:34 AM, upsidedown@downunder.com wrote:
> On Sat, 18 Oct 2014 08:20:35 -0700, Don Y <this@is.not.me.com> wrote: > >>> Apart from some early (1702) EPROMs, most EPROMs were single supply as >>> well as small SRAMs. >> >> SRAM's were *really* small. E.g. 2114's. > > That is a big one with 1024x4 bits :-)
Everything is relative. At the time, we were shipping product with 8155's (?) (not sure I remember the P/N correctly... 256x8 RAM, counter and PIO's in a DIP40? Maybe DIP28?? <shrug> I.e., 512 total bytes of RAM in a (commercial product) system (8085-based successor to the i4004 product described below). When you think how "big" lat-lons are and the math required to convert hyperbolic coordinates on an oblate sphere to a cartesian projection, you can see how quickly you start counting *bits*!
> The original 6800 sample system was 6830 ROM with 1024 bytes ROM and > 6810 with 128 bytes of RAM. > >> But, putting something that existed "in a large box with a large power supply" >> onto a single, commercially viable DIP doesn't mean you can just pick whatever >> architecture you want, turn the crank and start spitting out chips! >> >> E.g., the i4004 was a DOG in comparison to the 8080 (or even 8008). >> Instruction execution times were ~10-20us -- almost "audio frequency". >> And, you're just dealing with nybbles! Despite the fact that "big iron" >> coexisted (gee, why couldn't they pick some of those features???) > > The i4004 was just a repurposed handhold calculator chip, A handhold > four banger calculator doesn't need high speed due to the slow human > entry speed.
We used it in the "first" commercial LORAN-C position plotter (take hyperbolic LORAN-C coordinates and convert them to a cartesian map projection in real time to drive a pen plotter).
upsidedown@downunder.com wrote:

(snip, I wrote)

>>Not so unusual to keep DS and SS together.
>>Also, even for the 8080 you could have separate address space >>for stack and data. There was a way to decode which data references >>were to the stack. I don't know anyone ever did that, though.
> Some of the 8080 support chip had some exotic outputs that you could > determine what type of access was intended, but did also include > data/stack access and not just instruction/RWdata access ?
I believe all three. You can have separate address spaces for code, stack, and data. Among others, Intel claimed a 64K entry call stack, though as it is two bytes each it should only be 32K. Maybe with extra logic you can make it 64K. But only if it is a separate address space from code and data. -- glen
On 10/18/2014 2:06 AM, glen herrmannsfeldt wrote:
> upsidedown@downunder.com wrote: > > (snip, I wrote) >>> Systems with (externally) bank switched RAM weren't all that >>> unusual, so maybe putting something like bank switch inside >>> the chip wouldn't have been so strange. > >> One of the (pre-release) selling point was that the 8086 was 8080 >> compatible. When 8086 details finally released, this appeared to be >> some degree of assembler mnemonics similarity. > > Most 8080 instructions translate to a single 8086 instruction, > but some need two or three. The number of bytes might be a > little more, so it won't fit into 64K anymore. > > Someone might still have the program that Intel sent out > to do the conversion. > >>> But yes, I am pretty sure that Intel didn't expect the 80286 >>> to mostly be used in systems only running real mode. > >> The 80286 was some kind of stop gap between the 8080 and >> the iAPX432, which proved to be disastrous. > > The four protection levels, as I understand, are from Multics > and its host. But yes, the 432 was way too complicated for > what was needed at the time.
Buttlicks actually *intended* 64 rings, IIRC. 0-31 for "system" use and 32-63 for "user". But, actually, only *8* rings were implemented (not 4!). Effectively, a "program" only executes in two rings -- a "user" ring ("4") and the "system" ring ("0"). As with many technical issues, coming up with the "right number" is hard. Too few and you lose the value they present. Too many and a "program" spends too much time crossing protection domains ("for little value")
The 2026 Embedded Online Conference