The Hema TA2 is some very special specimen of ISA interface cards. IMHO it’s the last and most sophisticated interface you can run in an ISA bus. These are the feature highlights:
- 16 bit ISA interface
- half-size card
- 4 TRAM sockets
- TTL and RS422 link connectors (if RS422 drivers are fitted, TTL is not usable)
- B004 compatible ‘Fast Mode’ as well as 100% vanilla ‘Slow Mode’
The TA2 implements an Idea which can be found in some documents from those days, about getting the maximum speed from the sluggish ISA bus and a link-interface chip like the IMS C011/012:
Overlapping acknowledge by using FIFO buffers and a controlling FPGA.
This is how the TA2 looks like:
I’ve marked the the important parts with colors/arrows:
- red arrow – the IMS C012
- orange arrow – the IMS C011 connected to
- blue – two 1KB FIFOs controlled by
- yellow – a MACH 110 CPLD and
- green arrow – a PAL
- purple – a XILINX 3030 FPGA doing the control logic
- cyan & magenta – TTL and RS422 link connectors
And here’s the block-schematic using the same colors:
The schematic also mentioned the two other cool features of the Hema TA2:
Four TRAM slots and the “hema LINK-Bus”, a proprietary two row DIN 41612 connector which provides all links/subsystem which were used otherwise by the 4 TRAMs.
Finally there is a 4-bit microswitch (upper right corner) to set a unique ID for the card so you can identify up to 16 cards in a single system.
Software
Using the provided control program “CTA2” everything can be set by software, e.g.
- Base addresses for the fast- and slow link (0x150/0x158 by default)
- Swapping fast/slow link configuration
- Linkspeed for every link (fast/slow/TRAM/hema-bus)
- Up- /Down-subsystem control
- Interrupts per link
- Waitstates
All the hardware wise ‘jumping through hoops’ still doesn’t do the job alone. To reach the ultimate ISA speed (the docs are talking about up to 1mbps) the communication needs to be tuned, too.
Lets talk a bit x86 assembler here (ahhhh), and DOS-only for sure:
It’s not enough to use simple in
and out
port instructions and constantly poll the C011/12 status register – that’s way too slow. You’ll need to go for the string variant(s) ins[b|w|d]
combined with the rep
instruction. Here’s an example for a C insb
wapper function:
void insb(UINT16 port, void *buf, int count)
{
_ES = FP_SEG(buf); /* Buffer Segment */
_DI = FP_OFF(buf); /* Buffer Offset */
_CX = count; /* Bytes to read */
_DX = port; /* from Port xy */
asm REP INSB;
}
Same goes for outs[b|w|d]
respectively. But there’s another extra to care for: The TA2 provides special registers to give you deeper insight into its status, e.g. FiFo fill-rate (empty, half-full, full), FiFo interrupt settings.
So in effect, you couple the fast ins/outs
instructions with interrupts attached to e.g. input half-full and output full.
That said, there are some caveats. ins[b|w]
and outs[b|w]
are supported from the i8018x and V20 on. insd and outsd needs a 386.
And then there are possible speed penalties with 32nit processors (i.e. 386 and up) as they optimized the port instructions for virtualization (Virtual 8088 mode, not todays VM!) resulting in 100+ cycles per call.
So when everything is 100% optimal, hema says in its documents these are the possible transfer speeds to reach:
Function/Array size | 1K | 10K | 100K | 1MB |
Read FiFo | 150kB/s | 390kB/s | 570kB/s | 615kB/s |
Read Polled | 160kB/s | 160kB/s | 160kB/s | 160kB/s |
Read Direct | 600kB/s | 610kB/s | 610kB/s | 610kB/s |
Write FiFo | 565kB/s | 600kB/s | 610kB/s | 610kB/s |
Write Polled | 160kB/s | 160kB/s | 160kB/s | 160kB/s |
Write Direct | 610kB/s | 610kB/s | 610kB/s | 610kB/s |
FiFo – Using interrupts and syncing status of fill level.
Polled: Each byte is synchronized with the C012 status
Direct: Like FiFo but no syncing.
Well, this has to be proved yet. Seem I need to write a benchmark… someday 😉