After disassembling my
R3361A (firmware version C14) in Ghidra, I have found the undocumented
GPIB incantation used to directly read/write memory.
This could be
useful to backup/modify/exchange the factory calibration data stored in
the EEPROM - what Advantest calls frequency characteristics compensation
data EROM.
$[R/W][M/S][B/W/L][H][ADDRESS],[DATA]
[R/W] - Read / Write
[M/S]
M - select memory
S - unknown (think it might be related to a controller option I don't have, to pass a GPIB command through, so I'd avoid using it especially with write)
[B/W/L] - word length
B - read/write byte at address (1 byte)
W - read/write word at address (2 bytes)
L - read/write long at address (4 bytes)
[H] - if set, arguments / return values are in ASCII hex format (0 to F), if not set, arguments / return values are in ASCII decimal format (0 to 9)
[ADDRESS] - e.g. 001a0000 with 'H' argument
',' comma used as separator
[DATA] - only for write operation. Length depends on word length setting (e.g. byte ff, word ffff, long ffffffff with 'H' argument)
Example usage:
(READ)
$RMLH0 - read the first 4 bytes from address 0x00000000 (will return the 32 bit stack pointer address from ROM)
$RMWH1a0000 - read the first word from EROM (as EEPROM on this system is only 16 bits wide, we use 'W' to get 2 bytes)
$RMWH1a0002 - read the second word from EROM etc.
(WRITE)
$WMWH1a3ffe,ffff - writes 0xffff to 0x001a3ffe in EROM
As far as I could tell, the entire system memory is available for manipulation. Obviously use write with caution!
I
will leave writing a script to backup the EROM (0x001a0000 -
0x001a3fff) as an exercise to the reader, as GPIB setups come in all
shapes and sizes.
You can find the contents of my EROM here for comparison:
https://github.com/macafeeje/R3361AIf
changing/modifying the compensation data in the EROM, there is a
checksum. The size of the compensation data, and therefore the location
of the checksum, depends on a status word also stored in the EROM at
0x001a3fd0 (in my R3361A, this equals 0x1111).
(I have no idea
what this status word is for, maybe there is some other option that has a
smaller compensation data set? Maybe if you have an R3x61 and that
value is not 0x1111 then we can figure out the difference) short* stored_checksum;
short size_of_array;
if (EROM_001a3fd0 == 0x1111) {
size_of_array = 0x290;
stored_checksum = &EROM_001a0520;
}
else {
size_of_array = 0x280;
stored_checksum = &EROM_001a0500;
}
The
checksum itself is calculated as the sum of words from 0x001a0000 to
0x001a051e with the checksum value stored at 0x001a0520 (or 0x001a0000
to 0x001a04fe /w chksm at 0x001a0500 if 0x001a3fd0 is not 0x1111).
short SUM_U16_PTR(short *addr_ptr, short size) //ROM 0x000474c0
{
/* takes a pointer to a 16 bit word aligned array of data, the size of the array, and returns the sum */
short sum = 0;
for (short l = 0; l < size; l = l + 1) {
sum = *addr_ptr + sum;
addr_ptr = addr_ptr + 1;
}
return sum;
}
It does not appear any other data in the EROM is protected by a checksum.
Also,
interestingly, there is a table of strings in the ROM which look like
GPIB commands (I'm lead to believe only in C14?) which threw me for a
bit, but they are not the method used to parse GPIB commands.
Instead
it takes the first letter of the command, applies it to a look up table
to get a pointer to another table, this table contains the remaining
letters of the command and their (presumably) associated function
pointers to be called to carry out said command.
Most of the work to decode the EROM has already been done, and we have OE3CPA on the Advantest IO forum
https://groups.io/g/advantestinstrument to thank for this.
I will summarise their work here for completeness;
The
compensation data is split into 7 sections. The first section is a
table of 41 frequencies (each a frequency the compensation value applies
to).
[ address ] [ MHz part ][ Hz part ]
0x001a0000 : 0x00000000, 0x00000000 (F1 = 0MHz + 0Hz)
0x001a0008 : 0x00000000, 0x00015f90 (F2 = 0MHz + 90'000Hz)
...
0x001a0138 : 0x00000dac, 0x00000000 (F40 = 3'500MHz + 0Hz)
0x001a0140 : 0x00000e10, 0x00000000 (F41 = 3'600MHz + 0Hz)
The
remaining 6 sections contain the compensation data, each containing 41
values and each section is thought to represent a different attenuator
setting (currently unknown which corresponds to which).
As a
complete guess, the compensation data is then interpolated between
frequencies as the currently selected span requires.
[ address ] [ compensation ]
0x001a0148 : 0x00000117 (+279 compensation for F1)
0x001a014c : 0x00000117 (+279 compensation for F2)
...
0x001a01e4 : 0xffffffbd (-67 compensation for F40)
0x001a01e8 : 0xffffffbd (-67 compensation for F41)
(block repeats for each attenuator position, and the checksum word is appended to the end)
(believed to be int16_t as 1/1000 of a dB)
Additionally at the end of the EROM are some option settings, they are documented here:
https://www.eevblog.com/forum/testgear/hacking-the-advantest-r3*61-spectrum-analyzers/A
bit more complicated than my usual 8085 disassembly but it was very
interesting to learn a little about the 68000 architecture.
Hopefully this is useful to someone, as I now sleep soundly in the knowledge that my EROM is safe
