Address Translation RAM
The address translation RAM is used to eliminate expensive address cycles
when addressing hardwired sequences of non-contiguous bytes.
This is useful for EPP devices to eliminate address cycles
and for PCI devices to allow slaves to be accessed with burst transfers.
It also allows PCI DMA to group all reads and all writes into sigle operations
The address RAM give indirect access to all internal registers.
Translation RAM, 256 deep by 16 bit wide address translation RAM
0x7800 Translation RAM byte address 0
0x7804 Translation RAM byte address 1
...
0x7BFC Translation RAM byte address 255
Data in translation RAM is LS 16 bits (MS 16 bits are unused)
of 32 bit word.
For EPP and USB (byte wide) devices, Bit 15 is StrobeBit.
For PCI devices, the strobe bit is unused.
For read sequences, the StrobeBit must be
OR'ed with the first translation RAM address entry of a read sequence,
for write sequences, the StrobeBit must be OR'ed with the last
translation RAM address of the write sequence.
To use address translation, there is a 256 byte window where addresses are
translated:
7C00 Translation region byte 0 (controlled by Trans RAM address @ 0x7800
7C01 Translation region byte 1 (controlled by Trans RAM address @ 0x7804
...
7CFF Translation region byte 255 (controlled by Trans RAM address @ 0x7BFC
Here is an example of using address translation (With EPP) to write one 24 bit
I/O port, read the next 24 bit I/O port and read and 4 quadrature counters,
skipping the timestamp, and update 4 PWM generators.
First initialize the translation RAM (Only done once at program startup)
write32 0x7800 0x1000 First byte of port write
write32 0x7804 0x1001 Second byte of port write
write32 0x7808 0x9002 Third byte of port write (Note: OR'ed with StrobeBit)
write32 0x780C 0x9004 First byte of read (Note OR'ed with StrobeBit)
write32 0x7810 0x1005 Second byte of read
write32 0x7814 0x1006 Third byte of read
write32 0x7818 0xB000 First byte of Qcounter0 (Note: OR'ed with StrobeBit)
write32 0x781C 0x3001 Second byte of Qcounter0
write32 0x7820 0xB004 First byte of Qcounter1 (Note: OR'ed with StrobeBit)
write32 0x7824 0x3005 Second byte of Qcounter1
write32 0x7828 0xB008 First byte of Qcounter2 (Note: OR'ed with StrobeBit)
write32 0x782C 0x3009 Second byte of Qcounter2
write32 0x7830 0xB00C First byte of Qcounter3 (Note: OR'ed with StrobeBit)
write32 0x7834 0x300D Second byte of Qcounter3
write32 0x7838 0x4002 First byte of PWMGen0 (in MS word)
write32 0x783C 0xC003 Second byte of PWMGen0 (Note: OR'ed with StrobeBit)
write32 0x7838 0x4004 First byte of PWMGen1 (in MS word)
write32 0x783C 0xC005 Second byte of PWMGen1 (Note: OR'ed with StrobeBit)
write32 0x7838 0x4008 First byte of PWMGen2 (in MS word)
write32 0x783C 0xC009 Second byte of PWMGen2 (Note: OR'ed with StrobeBit)
write32 0x7838 0x400C First byte of PWMGen3 (in MS word)
write32 0x783C 0xC00D Second byte of PWMGen3 (Note: OR'ed with StrobeBit)
Once these 22 address translation table entries are initialized,
the following sequence of EPP operations will do all the data transfers:
writeaddr 0x00
writeaddr 0xFC This sets up the 16 bit EPP address as 0xFC00
= translation region (0x7C00) with auto-inc (0x8000)
writedata write port 0 Byte 0
writedata write port 0 Byte 1
writedata write port 0 Byte 2
readdata read Port 1 byte 0
readdata read Port 1 byte 1
readdata read Port 1 byte 2
readdata read Qcounter 0 byte 0
readdata read Qcounter 0 byte 1
readdata read Qcounter 1 byte 0
readdata read Qcounter 1 byte 1
readdata read Qcounter 2 byte 0
readdata read Qcounter 2 byte 1
readdata read Qcounter 3 byte 0
readdata read Qcounter 3 byte 1
writedata write PWMVal 0 byte 0
writedata write PWMVal 0 byte 1
writedata write PWMVal 1 byte 0
writedata write PWMVal 1 byte 1
writedata write PWMVal 2 byte 0
writedata write PWMVal 2 byte 1
writedata write PWMVal 3 byte 0
writedata write PWMVal 3 byte 1
Notes: For compatibility reasons, basic register access is still 32 bits
even with address translation, so a 32 bit write is always done even if
only a single byte is written. This is usually not important, but does
have some subtle side effects. For example if a 24 bit wide I/O
port is defined with 16 input bits and 8 output bits (say to interface
with a 7I37), the 8 output bits can be updated in a single byte write
thats part of a sequence in the translation RAM. The side effect of this
is that the 16 unused output bits that coorespond to the input bits on
the port _will_ be written with random data.