• Please review our updated Terms and Rules here

Roast my design: 16-bit ISA memory board

ab0tj

Experienced Member
Joined
Mar 4, 2015
Messages
116
Location
Colorado, USA
Inspired by the Lo-Tech 1MB RAM board which is great for adding UMBs to XT class systems, I set out to design a 16 bit version for AT class systems. It can selectively fill 0-512K in 64KB chunks (which is probably already maxed out on most ATs) and 512-1024K in 32K chunks, though obviously some of those areas won't ever be available for memory anyway.

Attached are the schematics and design I came up with. After they're tested and debugged, I intend to make PCBs and maybe built boards available to the community. Anyone feel like taking a look to tell me what mistakes I've made?

Schematic: https://drive.google.com/file/d/17V2zu1NKI3wbEPl9qkvuWUZT8U-jKmxk/view?usp=sharing
Board Layout: https://drive.google.com/file/d/1T_tJj_RjK2Zs6zy09Ox9cGhOANk3G1Av/view?usp=sharing
GAL code: https://drive.google.com/file/d/1dv9bP9okc4JlIlSiGOcfOpW9wE8lbC8h/view?usp=sharing
 
Two things:

1) In order to get true 0-wait, I think you are going to need to assert MEMCS16# before the lower 20 bits of address are on the bus. I.e. before the rising edge of BALE

2) CEH = MEMSEL & BHE;
I don't think this is going to work. The system board holds SBHE# low when doing a word transfer.

If I were you, I would just ignore the SBHE# signal. Your card is not intended to be backwards compatible with 8-bit buses nor does it have any steering logic to put the high byte on the lower data bus, so I don't see why you'd need it as long as you assert MEMCS16# appropriately.
 
Last edited:
Two things:

1) In order to get true 0-wait, I think you are going to need to assert MEMCS16# before the lower 20 bits of address are on the bus. I.e. before the rising edge of BALE

2) CEH = MEMSEL & BHE;
I don't think this is going to work. The system board holds SBHE# low when doing a word transfer.

If I were you, I would just ignore the SBHE# signal. Your card is not intended to be backwards compatible with 8-bit buses nor does it have any steering logic to put the high byte on the lower data bus, so I don't see why you'd need it as long as you assert MEMCS16# appropriately.

Thanks for the input! You bring up some good points...

1) Well that's unfortunate... So it seems zero wait states might not be possible for this board then. Asserting MEMCS16# based on a decode of LA17-LA23 like the 5170 technical manual suggests wouldn't work as that only gives us 256k "chunks" of memory and in the UMB area that might clash with things like VGA BIOS ROMs that could be 8-bit. I was hoping some of the references I can find online that seem to suggest MEMCS16# is samples after BALE goes high were correct (here for example)

2) I'm getting conflicting info on the polarity of BHE. The technical manual and HwB agree that it is active high, but other sites like here say it is SBHE#... I'll take your word for it and fix that in the GAL code ;)

As for ignoring it entirely, that makes sense for reads, but are all writes guaranteed to be 16 bit?
 
Thanks for the input! You bring up some good points...

1) Well that's unfortunate... So it seems zero wait states might not be possible for this board then. Asserting MEMCS16# based on a decode of LA17-LA23 like the 5170 technical manual suggests wouldn't work as that only gives us 256k "chunks" of memory and in the UMB area that might clash with things like VGA BIOS ROMs that could be 8-bit. I was hoping some of the references I can find online that seem to suggest MEMCS16# is samples after BALE goes high were correct (here for example)

2) I'm getting conflicting info on the polarity of BHE. The technical manual and HwB agree that it is active high, but other sites like here say it is SBHE#... I'll take your word for it and fix that in the GAL code ;)

As for ignoring it entirely, that makes sense for reads, but are all writes guaranteed to be 16 bit?

First let me say I'm no expert, I've just only designed my first ISA card recently (documented here: http://www.vcfed.org/forum/showthread.php?71494-Designing-a-16-bit-ROM-card/

I think different chipsets sample MEMCS16# differently. I'm still trying to figure that out myself.

As for SBHE#, it is definitely active low. I believe that all writes will in fact be 16-bit if MEMCS16# is properly asserted. We had better hope so, because if the system does a split transfer to an odd address, it's going to write to D[7:0] so you're screwed anyway
 
Last edited:
First let me say I'm no expert, I've just only designed my first ISA card recently (documented here: http://www.vcfed.org/forum/showthread.php?71494-Designing-a-16-bit-ROM-card/

I think different chipsets sample MEMCS16# differently. I'm still trying to figure that out myself.

As for SBHE#, it is definitely active low. I believe that all writes will in fact be 16-bit if MEMCS16# is properly asserted. We had better hope so, because if the system does a split transfer to an odd address, it's going to write to D[7:0] so you're screwed anyway

Thanks. I'll definitely be reading the whole thread about your ROM card, that's some good info. It sounds like I *might* be OK asserting MEMCS16# as soon as the address lines match, since BALE goes high (making the address latches transparent) before any of the memory strobes go active. Of course none of this logic stuff happens with zero delay, but I think it might even get asserted before BALE goes back low. I'll keep researching this topic because I see no other way of making 0WS happen in this memory area :)

On the 8-bit writes I wasn't thinking of a split 16-bit transfer, but specifically an 8 bit write to an odd address. MOV m8,AL for example. I'm not sure if that is a thing in x86 land but it seems conceivable.
 
Just a third confirmation, the 5170 schematic shows SBHE# is just latched and buffered from the CPU's BHE# signal. Yes, definitely active low.
 
http://www.minuszerodegrees.net/oa/OA%20-%20IBM%20PC%20AT%20128KB%20Memory%20Expansion%20Option.pdf
This is interesting. Looks like IBM's "official" memory expansion board controls the data buffers in the same way - low bits controlled by A0 low and high bits controlled by BHE# low. They also derive MEMCS16# from a direct decode of the LA23-LA17 lines, so that doesn't really help me on if it's possible to add SA19-SA15 into that equation and still meet timing to get 16-bit transfers. And at that rate, it's not yet clear to me if I'm making things better or worse by latching the LA lines as part of that equation.

Research shows that 0WS might not be worth pursuing as the timing requirements might be impossible to meet on an 8MHz AT no matter how fast the logic is. I'll leave the jumper in there anyway and see how things go.
 
Last edited:
Looks like maybe even 1WS 16-bit transfers aren't possible on the AT/5170 unless using 128k blocks: https://en.wikipedia.org/wiki/Talk%3AIndustry_Standard_Architecture#8/16-bit_Incompatibilities
:(

You can achieve 1 wait but not zero unless you decode LA and assert combinatorially within 1 CLK in combination with asserting ZWS# within 1 cycle of the strobe assertions.

BTW, your .oe logic is messed up in the CUPL file. For a single-side drive (high or low + Z), you should be setting the value of the FF to a 1 or 0 and assigning the non-Z logic to the .oe expression; not both.
 
In my revised ROM card design, I'm asserting MEMCS16# as soon as the 688 matches an address on SA[19:14] but both of my VLSI chipset based boards (one based on the VL82CPCAT-QC (VL82C10x chips) and the other the VL82CPCAT-16QC (VL82C20x chips)) still ignore it and split the transfer into 2 8-bit cycles.

I don't think it's propagation delay. The LS688 is rated at a max of 23ns and then it goes through 2 OC inverters (max 7ns per inverter). So only 37ns from the time that a matching address is on the bus to my card pulling MEMCS16# low, but these VLSI boards are still ignoring the assertion. I tried it on a 440BX for giggles and it works in 16-bit mode no problem
 
Last edited:
BTW, your .oe logic is messed up in the CUPL file. For a single-side drive (high or low + Z), you should be setting the value of the FF to a 1 or 0 and assigning the non-Z logic to the .oe expression; not both.

good catch I overlooked that

it should look like:
NOWS = 'b'1;
NOWS.oe = MEMSEL & MEMOP;
 
You can achieve 1 wait but not zero unless you decode LA and assert combinatorially within 1 CLK in combination with asserting ZWS# within 1 cycle of the strobe assertions.

Thanks. Do you know if this works on an IBM 5170? That's my intended audience.


it should look like:
NOWS = 'b'1;
NOWS.oe = MEMSEL & MEMOP;

Wow, thanks for that! I've tried in the past to do that but I guess I was missing the 'b' - it compiles cleanly if I use that notation.
 
Thanks. Do you know if this works on an IBM 5170? That's my intended audience.

I'm afraid that my VLSI chipsets, being some of the earliest of their kind, are accurately emulating the 5170 system board's logic with respect to MEMCS16#. I'd love to get more opinions on this since I'm still trying to learn myself, but it sure seems like if you miss the first sample point for MEMCS16# (which appears to occur on one of the edges of BALE?) on these boards you don't get a second chance.
 
Hmm... so the way I see it, I have 3 choices.

1) Roll the dice, run the board as-is (with fixes pointed out here) and see if the 5170 cooperates or not. Or maybe try to wire up something to test on a protoboard
2) Redesign it to use 128K blocks of memory, and maybe even get a small speed boost by replacing system ram with 0WS RAM (my 5170 is 6MHz). I'm not using EMS so maybe D0000-EFFFF would work for UMBs.
3) Scrap it, buy a Lo-Tech 1MB board and get some UMBs even if they're slow due to being 8 bits wide.

This is going to take some thinking.
 
I'm torn between 1/2

1) because I want more data points on this issue and I don't own a 5170 yet
2) because it would be the most performant outcome for your situation

8-bit memory on an AT is just gross :p
 
I think I have some '688s in my junk box. Maybe I can wire something up to make some nice logic analyzer traces to look at. Not exactly sure what that would look like without making a fullblown memory board but I'll fire up KiCad and see what I can come up with, haha
 
I think I have some '688s in my junk box. Maybe I can wire something up to make some nice logic analyzer traces to look at. Not exactly sure what that would look like without making a fullblown memory board but I'll fire up KiCad and see what I can come up with, haha

I'd be happy to share a kicad file of the ISA edge connector's physical dimensions if you would like. I measured dozens of cards and it fits like a charm in every board I've tried
 
That actually would be helpful. The dimensions for this memory board were just based on some dimensions I found online, not sure how accurate it is. In the short term I have some ISA prototyping boards I can play with.
 
Screen Shot 2019-11-24 at 5.47.32 PM.jpg

So this may shed some light on it. Looks like MEMCS16# is latched by ALE on the 5170 motherboard. The latched signal goes into a PAL which seems to be doing the data steering stuff. Sooo, it looks like one would have to beat ALE going back low in order to get 16-bit transfers. That would explain why the technical manual says to derive it from a direct decode of the LA lines.
 
Back
Top