5
\$\begingroup\$

I want to do something that I assume must be fairly common in digital logic/bus design. It’s for a new expansion card for an old 8088-based computer. This isn’t some kind of college homework project.

I want to create an 8-bit R/W IO port register (port A) whose address is software defined. By which I mean its address can be software defined by a write to a 16-bit IO port register (port B) – let’s say port B is at 100h, just for example.

So if I write 60h to IO address 100h (port B), then subsequent IO reads and writes to 60h are reading or writing the contents of port A.

I was thinking I could use some 74x373/573s to create IO port registers A and B.

I’d take the outputs from port B to the P inputs of a 2x 74x688 comparators, with the Q inputs coming from the latched address lines.

If an address on A0..15 matches the value in port B (100h in my example), the comparator outputs would enable a 74x363 connected as my IO port A.

That means that a read or write to IO address (60h) defined by Port B would read or write to register IO port A. I know I’d have to use IO/M-, RD- and WR- appropriately.

I drafted a schematic - does this look right? The port B address is decoded on the left (I know I have to take care of the higher-order address lines).

I'll have latched address lines going into the two comparators.

My RD- and WR- are IO Read and Write, active low.

I thought I'd need a bus transceiver like a HC245 - but isn't the HC373 good enough on its own??

Bus

\$\endgroup\$
9
  • \$\begingroup\$ Hi! How fast is the expansion bus clocked in case of your machine? \$\endgroup\$ Oct 31, 2020 at 19:06
  • \$\begingroup\$ also, just from a gut feeling: If I was surprisingly to go for gate-level ICs here, my comparators would be XORs (with inverted address bits as one of two inputs) or XNORs (with uninverted address bits), logically OR'ed (by means of series resistors pulling up a larger resistor) instead of magnitude comparators like the 74866 \$\endgroup\$ Oct 31, 2020 at 19:22
  • \$\begingroup\$ what is the end goal for wanting a programmable address of a hardware device? ... which problem are you trying to solve? \$\endgroup\$
    – jsotola
    Oct 31, 2020 at 19:33
  • \$\begingroup\$ @jsotola - Good question! I want to be able to emulate non-existent hardware for debugging purposes. Having IO ports whose address can be specified via software gives me that capability. I can then, for example, write a value to a port via an ISR, so that when legacy software tries to read it then the correct value is presented. An example would be I don't have a real keyboard controller - but I can detect a keypress, generate an interrupt to write a valid keyboard scan code to IO port 60h, so that an application that relies on the scan being at 60h sees it there. \$\endgroup\$
    – David00
    Oct 31, 2020 at 21:32
  • \$\begingroup\$ @Marcus Müller - It's not an actual PC, but an 8088-based computer running at 10 Mhz max. The bus signals are slightly different from standard PC ones. I'm not averse to gate-level logic, but want to keep package count down \$\endgroup\$
    – David00
    Oct 31, 2020 at 21:36

2 Answers 2

4
\$\begingroup\$

Approximately correct. One fixed port to write in data, which compares with the address where the second port will respond to.

But as the motherboard and most cards decode only 10 bits of the address, selecting 1000h would be a bad idea, as the motherboard will think you are writing to addess 0h which is the DMA controller.

Also since decoding only 10 bits enough, you simply could settle on just decoding 8, to settle on single 8-bit config port to set 8 bits of the address. So the variable port responds to 4 contiguous ports.

For reference you can read IBM manuals for reference schematics, basically AEN needs to be decoded too, with address and IORD and IOWR.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks @Justme. This isn't for a PC, I have the full 64k of IO address space. I should have made the clearer. \$\endgroup\$
    – David00
    Nov 27, 2020 at 18:30
2
\$\begingroup\$

Well, this sounds like all you want to achieve can be done in one package: Get a tiny (tiny in complexity) FPGA, or a CPLD.

This might sound scary at first, but really, it's not that scary. Thing is, making such a thing toggle an LED when you press a button is about as hard as what you describe.

If you've heard of Hardware Description languages like Verilog or VHDL (or, more exotically, nMigen or Chisel) before, it's really a breeze. Otherwise:

Looking at the voltages of the 8088 and the speed, the Lattice ICE40 family definitely suffices. And while certainly a bit more expensive then a bunch of discrete registers, I don't think an additional dollar will be the problem for this project.

Why I mention this specific FPGA family is that there's an ecosystem around these, based on the facts that people sat down and reverse-engineered the format of the bitstream with which these devices are programmed. That means there's open source software that takes your logic design, converts it to a memory dump that you can then burn into an SPI flash/eeprom and then the FPGA just uses that to configure itself, i.e. to become the logic you specified.

To design for these boards, I mention hardware description languages, but there's also IceStudio, which really takes more of a logic gate/mux layout graphical approach.

IceStudio

I think the Intel 8088 has a 2.5 V LVCMOS bus, right? That's something that these FPGAs can drive directly, incl tristating. (such small FPGAs are typically mostly used as "logic glue": a bit of level/timing conversion, a bit of serialization/deserialization, addressing logic... exactly what you're doing here.)

There's plenty of logic space and memory inside the FPGAs to implement your flexible address decode. In fact, you can even configure a small CPU into the FPGA that has a memory region mapped to the bus, if you want to (I've seen people E1 bus-to-USB adapters with an embedded 32 bit CPU in exactly these FPGAs).

\$\endgroup\$
2
  • \$\begingroup\$ Thanks! Longer term I'd like to learn about FPGA tools, it's clearly the way to go. But think I should prototype using discrete packages first, so when things go wrong I can get to intermediate signal lines easily. \$\endgroup\$
    – David00
    Nov 1, 2020 at 17:01
  • \$\begingroup\$ @David00 you can bring out any internal signal to an arbitrary IO pad on an FPGA. You can also do a cycle-accurate simulation of a HDL design, if that's your thing, or build in debugging probes (that's very common in larger designs) that can tell you about internal signals e.g. over a serial bus :) \$\endgroup\$ Nov 1, 2020 at 17:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.