October 22, 2026

MOD_EMUP - ports and IO

Usually the ISA card to talk to the EMUP is configure with base address 0x2E0. When this is done, the EMUP appears as two IO ports. This is probably a surprise, but it is that simple, as follows:
0x2E0 is a write only "ID" port
0x2E2 is a read/write "Data" port
The game is to write a "selector" into the ID port, then a subsequent read or write from the data port interacts with the selected "register" inside the EMUP.

EMUP registers

What internal registers are there and what do they do? One option is to take apart an EMUP and begin reverse engineering the schematic. I have done some of that. Another option is to disassemble one of the executables that talk to the EMUP and look for all of the IN and OUT instructions and study what they do. I have done some of that also.

A wonderful resource is this document for the ALL-03 (which is just an EMUP with different branding). What follows are my own notes from studying this document.

All devices get set to zero by reset.

Caution Before applying any DAC controlled voltage to a pin, the TTL control for that pin must be set high. Otherwise the pin will be connected to ground and damage to the DAC supply voltage will occur.

The three DAC's

A Voltage drop of 0.6 volts exists between the DAC sources and the test socket. These must be considered when making the DAC settings:

VCC -- 0.6 volts = 15 steps
VHH -- 0.6 volts = 10 steps
VOP -- 0.6 volts = 6 steps

I see these offsets handled in the "write to DAC" routines in the code.

0xe5 - VOPID DAC (10.2 to 25.5 volt) 400 mA
0xe6 - VHHID DAC (5.1 to 15.3 volt) 400 mA
0xe7 - VCCID DAC (0.0 to 10.2 volt) 1000 mA
The VCC dac is 15.3 volts full range, with a resolution of 0.04 volts.
So the output voltags = val * 0.04
I see the values 0x7d and 0x89 used in the code.
0x7d = 125 --- 125*.04 = 5.0 volts (how about that?)
0x89 = 137 --- 137*.04 = 5.48 volts (why would this be used?

The VOP dac is 25.5 volts full range, with a resolution of 0.1 volts.
So the output voltage = val * 0.1
I see the value 0x32 in the code.

0x32 = 50 --- 50*0.1 = 5.0 volts
I see this in the epp512.exe program which handles common EPROM chips like the 2764 -- these have a 5 volt programming pulse, so this makes sense.

The VHH dac is 15.3 volts full range, with a resolution of 0.06 volts.
So the output voltage = val * 0.06

This dac is never used in epp512.exe and must exist for other devices.
Our document says for a value of 85 --- 85*0.06 = 5.1 volts.

Note the comment about minimum values for the VCC and VHH dacs. The scaling starts at zero, so who knows what causes these limits. They are no doubt an aspect of whatever circuitry is used.

Register details

0xe0 - TTLID-0
0xe1 - TTLID-1
0xe2 - TTLID-2
0xe3 - TTLID-3
0xe4 - TTLID-4

0xe5 - VOPID DAC (10.2 to 25.5 volt) 400 mA
0xe6 - VHHID DAC (5.1 to 15.3 volt) 400 mA
0xe7 - VCCID DAC (0.0 to 10.2 volt) 1000 mA

0xe8 - VOP_EN_ID-0
0xe9 - VOP_EN_ID-1
0xea - VOP_EN_ID-2
0xeb - VOP_EN_ID-3
0xec - VOP_EN_ID-4

0xed - VCC_EN_ID-0
0xee - VCC_EN_ID-1

0xef - OTHER_EN_ID

0xf0 - VHH_EN_ID-0
0xf1 - VHH_EN_ID-1
0xf2 - VHH_EN_ID-2
0xf3 - VHH_EN_ID-3
0xf4 - VHH_EN_ID-4

0xf5 - VHH_ENC_ID-0
0xf6 - VHH_ENC_ID-1	(not currently used)

0xf7 - "mystery" port that is definitely access (not in original documentation)
0xf8 - "secret" port (see below, not in original documentation)
The device socket has 40 pins, so 5 registers of 8 bits allow us to specify any pin. In general, each pin can have one of four configurations: All pins are not wired up to be able to use all options. The following indicates what is possible

TTL pins

All 40 pins may be used.
pin 1 is the LSB of port 0xe0
pin 40 is the MSB of port 0xe4
To read from a pin, you must write a high to it first.

VHH pins

The 40 pins are mapped the same as for TTL, but VHH is not available on all of them. Writing a high (1) for a pin will apply the VHH to that pin.
Never apply VHH to any pin for more than 1 hour.

VHH_ENC pins

These are those controled by ports 0xf5 and 0xf6. The difference between these and regular VHH is that there is no 22 ohm current limiting resistor in series with the socket. This allows high current and voltage for certain PAL devices.
This is only available for 5 pins:
0xf5  bit 3 -- pin 32
0xf5  bit 4 -- pin 31
0xf5  bit 5 -- pin 30
0xf5  bit 6 -- pin 29
0xf5  bit 7 -- pin 28
Port 0xf6 is not currently used.

VOP pins

The 40 pins are mapped the same as for TTL, but VOP is not available on all of them. Writing a high (1) for a pin will apply the VOP to that pin.
Never apply VOP to any pin for more than 1 hour.

VCC pins

Here we have only 2 registers with only certain bits available.
0xed  bit 0 -- pin 40
0xed  bit 1 -- pin 36
0xed  bit 2 -- pin 34
0xed  bit 3 -- pin 32
0xed  bit 4 -- pin 31
0xed  bit 5 -- pin 30
0xed  bit 6 -- pin 29
0xed  bit 7 -- pin 28

0xee  bit 0 -- pin 27
0xee  bit 1 -- pin 26
0xee  bit 2 -- pin 9
0xee  bit 3 -- pin 7
0xee  bit 4 -- pin 5
0xee  bit 5 -- pin 1
0xee  bit 6 -- not used
0xee  bit 7 -- not used

OTHER pins

Here we have a single register (0xef) with 6 bits defined
0xef  bit 0 -- low set pin 20 to ground, high sets pins 11 and 30 to ground
0xef  bit 1 -- output VOP (source-2.4) to pin 7
0xef  bit 2 -- output VOP (source-2.4) to pin 25
0xef  bit 3 -- TTL oscillator to pins 2 and 3 (one inverse of the other
0xef  bit 4 -- TTL oscillator to pins 18 and 19 (one inverse of the other
0xef  bit 5 -- high selects 4.432 Mhz, low selects 2.216 Mhz oscillator
0xef  bit 6 - not used
0xef  bit 7 - not used

read and write

Some study indicates the following, though this is subject to correction as I learn more

We have 3 groups of 8 addresses.

e0 - e7 = read and write
e8 - ef = write only
f0 - f7 = write only
And, all on its own:
f8 -- secret read port
Note that e0 - e4 are the TTL read/write where read/write makes sense.
The ports e5, e6, and e7 are the DAC control, where write makes sense.
Reading from e5, e6, e7 is almost certainly some other device and not the dac

I do see the code reading from port e7 (the VCC dac address).

MYSTERY port

This is port 0xf7. I have discovered this from my disassembly. We have no idea what it does, but it definitely does get written to. Hardware reverse engineering is the only answer unless some surprise documentation turns up.

SECRET port

This is port 0xf8. This port was discovered by the MOD-EMUP over USB project. They ran some of the software in a simulator (dosbox) they patched to log every access to the EMUP ports (2e0 and 2e2). They discovered the following:

Identification (every program, at start and before each operation): a function check(n, expect) writes E7 = 00, 01, 00, 02, then n pulses (03, 02), then 00; selects register F8 (not in all03info.txt) and compares its low nibble with "expect".
...
So the box has some clocked logic readable at F8; a plain binary counter, a 4040's bit pairs, small LFSRs and running totals don't fit, so it needs the real box (or its schematic) to settle. BPPGM.EXE's check is at file offset 6C82; patching the jne at 6D44 to two NOPs (scratch copy only) skips it.
This is something I can investigate -- I have the EMUP disassembled and boards laying in a box, and I am busy disassembling some of the software I have.

Further notes on the "secret" port

While software does check this, it keeps going regardless (at least it does under DosEMU). So this seems to be just a cautionary check? We won't believe it until we have used the EMUP sucessfully to do something without the official software.

Another possibility is that this game somhow unlocks the programmer itself. Once again, we will have to experiment to find out. I have scanned the PCB for any kind of chip that would be a counter, and there is nothing of the sort. So unless a counter was implemented in one of the GAL devices (which is possible, but unlikely), I am baffled.


Have any comments? Questions? Drop me a line!

Tom's Electronics pages / tom@mmto.org