1

I'm building a minimal, minimum mode 8088 computer. I started with an 80C88-2 (CMOS, static variant) CPU. My configuration is really simple. One CPU, one 74HCT245 (DTR->DT/R) for the data lines, two 74HCT573 (LE->ALE, OE->GND) for the address latch, and a clock source.

My problem:

I'm running a nop test. After reset the CPU starts at FFFF0, it's ok. It reaches FFFFF, then continues from 00000, again ok. But, when it reaches 0FFFF it becomes crazy, in the next cycle the A16-A19 lines blink one for a moment, I see a really short peek (5V) on this lines, but it's goes low before ALE goes low, then the cpu starts again from 00000 and this repeats every times when it reaches again the 0FFFF address. (This lines are multiplexed with the status lines, I think this is the source of my problem, but the latch not helps.)

I tried other CPU, every works like this, I tried to replace the latch, run on high clock, slow clock, use pullups, nothing helped. I have no idea, why this lines are good only once after reset. What can be wrong with the four highest address lines?

1 Answer 1

10

It's simply how the 8086 works. it's a straight 16 bit CPU, isn't it?

The CPU sees memory not as an 20 bit address space, only the BIU does (*1) when generating an access, but a 16 bit segment number, in CS, and a 16 bit PC in IP. The BIU uses a result derivated from CS and IP to access memory. When fetching instructions (without an MMU like in the 286) the BIU simply multiplies CS by 16, adds IP and fetches the next byte (or word) from there (*2).

The PC gets incremented according to instructions (NOP) read. So what happens with a 16 bit register with a value of FFFFh when incremented by one? Exactly, 0000h!

So, as mentioned, it does exactly what it's supposed, it loops thru the 64 Kib of 'code' the segment pointed to by CS offers. You discovered segmentation.


Which brings up a point were your observations are a bit off - by 16 bytes to be exact.:

After Reset CS is set to FFFFh while IP is set to 0000h (*3). This means the first fetch happens from FFFF:0000h or FFFF0h on the bus. the next from FFFF:0001h and o on. When it hits FFFF:0010h, a first warp around will happen, as FFFF0h + 0010h equals 100000h - a carry to A20 (*4), not existing at the 8086, so what it outputs is 00000h. With monotonous increments it will hit FFFF:FFFFh at some point, which translates to the memory address of 0FFEFh.

Having hit FFFFh, IP wraps and goes back to 0000h, now addressing again FFFF:0000h, or FFFF0h. Our hero finished his journey thru the wild lands of low memory and is back at a safe FFFF:0000h :)

So what you see is not a 'blip' at A16..A19, but them being high for exactly 16 fetches reading the bytes from FFFF:0000h thru FFFF:000Fh and then going low for the next 65520 fetches covering FFFF:00010h to FFFF:FFFFh and so on, ad infinitum.


*1 - BIU or Bus Interface Unit. The 8086 is structured into two somewhat independent units. The Execution Unit (EU) doing the computation and the BIU doing all interfacing. It contains everything that is memory related. that includes the PC and all Segment registers. That way it can (re) order access as needed and read ahead to fill the prefetch queue. An Answer to a prefetch related question may give more details.

*2 - It's a bit more complicated, as fetches move the IP ahead of execution, to fill the prefetch queue. It gets corrected to the next instruction to be executed whenever it needs to be accessed - essentially only with CALL.

*3 - See table 2.4 in section System Reset on page 2-29 of the 8086 Family Manual

*4 - Yes, exactly that A20 were the gate is located - and the whole hardware behind the ability to access 1088 KiB minus 16 bytes on a 286 and later in real mode - but that's a different story.

8
  • Thanks! This is a logic answer and I slapped my head. :D Only one thing. If the CS not modified, then the 4 highest lines why goes to zero after the first 16 nops? The start address is FFFF0, so CS must be F000, FF00, FFF0 or FFFF, so A16-A19 must remain high. Or not?
    – Pethical
    Apr 12, 2021 at 22:48
  • 2
    @Pethical Because tehre is no A20? Also, do you really think any designer would use such odd values? It's FFFFh for CS and 0000h for IP. Just check Table 2.4 in section System Reset on page 2-29 of the 8086 family manual showing all initial values.
    – Raffzahn
    Apr 12, 2021 at 22:52
  • Don't JMP, conditional branches etc. also flush the prefetch queue?
    – Lorraine
    Apr 13, 2021 at 13:44
  • @OmarL Sure, but they only set it. The remark is about accessing (reading) it for turning it into a state visible from the outside (i.e. push it onto the stack). It's one of that little nifty design elements not really visible from the outside (to programmers) at all, but a true brain-twister as soon as one tries to implement an 8086 - people come up with solutions using up to three connected IP and fetch pointers and juggle with them. And yes, all changes to the PC will ofc flush the prefetch queue.
    – Raffzahn
    Apr 13, 2021 at 14:50
  • 1
    @SingleMalt I'd say its simply done when the PC gets written out. After all, the EU has to signal the BIU to do so, as IP is part of the BIU.
    – Raffzahn
    Apr 14, 2021 at 17:25

You must log in to answer this question.

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