Intersteller to Esh's Conversion Video
Esh Test ROM
Written by Matt Ownby in late 2020 (and updated in late 2021), this replaces the H8 ROM on the Esh PCB and quickly runs through a bunch of tests to mostly determine whether the PCB is working correctly. Source code included.
|0xE000-0xE7FF||CPU RAM (B8)|
|0xF000-0xF7FF||Video RAM (F3)|
Z80 Port Map
|0xF0||In||Control panel input. Only lower 6 data bits are used. Active low.
|0xF1||In||Control panel input. Only lower 6 data bits are used. Active low.
|0xF2||In||Control panel input. Only lower 6 data bits are used.|
|0xF3||In||Control panel input. Only lower 6 data bits are used.|
|0xF4||In/Out||LD-V1000 data. Writing queues a command to be sent on the next command strobe. Reading reads the most recent byte received during last the status strobe.|
|0xF8||Out||0 disables start 1 button lamp. 1 enables.|
|0xF9||Out||Start 2 button lamp. 0 disables, 1 enables.|
|0xFA||Out||0 disables action button lamp. 1 enables.|
|0xFB||Out||0 disables joystick lamp. 1 enables.|
|0xFE||Out||0 holds IRQ' line high (disabled) by forcing a latch to be clear. 1 stops forcing latch to be clear, which allows IRQs to set the latch. To allow a future IRQ, this port must have 0 followed by 1 written to it.|
|0xFF||Out||0 holds NMI' line high (disabled) by forcing a latch to be clear. 1 stops forcing latch to be clear, which allows NMIs to set the latch. To allow a future NMI, this port must have 0 followed by 1 written to it.|
NMI: Caused by LD-V1000 status strobe going low (becoming active)
IRQ: Caused by D2 output (pin 10) on vertical PROM (C6) transitioning from 0 to 1. This ends up being 60 Hz (vsync).
Video RAM Structure
Screen is divided into 32x32 tiles. The first tile is the top left.
0xF000-0xF3FF contain which tile to show.
0xF400-0xF7FF contain tile attributes. For example, 0xF400 would have attributes about the tile index at 0xF000.
|0-3||Which color palette to use for the tile.|
|6-7||Blink frequency. 0: no blinking, 1: blink at about 15 Hz, 2: blink at about 7.5 Hz, 3: blink at about 4.3 Hz ; The blink frequency is controlled by the Z80 program, and is not a hardware restriction.|
How video RAM is accessed
Video RAM is accessed in a repeating pattern:
- CPU can either write to video RAM or the address lines are ignored. When writing to video RAM, CS' and OE' both are low while VRAM_WR' is low. The same video RAM location may be written to twice in a row due to a very long WR' pulse from the CPU which is interrupted by the way the video RAM is designed to switch between CPU access and screen refresh. If the CPU is not trying to write to video RAM, CS' and OE' will be high (disabled) and the address lines will often reflect the lower CPU address lines but not always.
- An address from 0-0x3FF is put on address lines (from horizontal/vertical counters and MUX chips) and the data at that address is loaded into H3
- An address from 0x400-0x7FF is put on address lines (the previous address with 0x400 added to it) and the data at that address is loaded into H4
This screenshot shows 0x52 written to CPU address 0xF1CA and 0x0E written to CPU address 0xF4CA.
Tile and color palette details
The tile bitmaps are stored in M3, L3, and K3 EPROMs (also labeled as "A", "B", and "C" with stickers). Each tile pixel is represented by a color index ranging from 0-7 (3 bit). Each EPROM contains 1 bit of this color index. M3 contains the least significant bit, L3 the middle, and K3 the most significant bit. Each byte in the EPROM represents a tile row of 8 pixels. To find the data for a tile, take the tile index (for example 0x40 for a solid block) and multiply by 8 (8 rows per tile). Continuing our example, this would take you to offset 0x200 where you would find 8 consecutive 0xFF bytes to represent the solid block. Each color index would be 7 in this example (because each bit would be 1, so 111 binary is 7 decimal). This value of 7 would make up the least significant bits in the color PROM address (A0-A2). The color palette value (4 bits) would be the next significant bits of the color PROM address (A3-A6) (so there are 16 possible color palettes available to choose from). A7 determines the background color if laserdisc video is hidden (0 for black, 1 for blue when using the values inside the Esh color PROM). A8 is used for a blinking effect where 0 means a blink is 'in progress' and 1 otherwise.
|Color PROM Address Bit||Description|
|0||Color index from M3|
|1||Color index from L3|
|2||Color index from K3|
|3-6||Which color palette to use.|
|7||0: Black or transparent (laserdisc video shown) background. 1: Blue background.|
|8||0: Blinking is 'in effect' so display background color. 1: Blinking is 'disabled' so display selected color normally.|
Color PROM output
|Color PROM data bit||Description|
|7||Transparency (0 = opaque, 1 = transparent)|
NOTE : the transparency bit is only honored if the 'misc' value is set accordingly. Else it is ignored.
Color PROM to RGB calculation
Red has 3 bits (0-7), green and blue have 2 bits (0-3). Red goes through 3 resistors: 220, 470 and 1000 Ohms. Blue and green go through two resistors: 220, 470. For red, parallel resistance should be taken account (sometimes two of the resistors will have high inputs or two will have low inputs). For green/blue, if the inputs to the resistors are different (one high, one low), one can imagine a circuit with two resistors in series that create a voltage divider. For each color, the highest resistance is the least significant bit of the color index.
Caveat: Just because these are the theoretical values does not mean the Esh color PROM is guaranteed to use all of them.
The PROM's high output level is about 3.3V but this may vary between PROMs. 3.3V is a decent number to settle on.
H and V PROMs are MB7052. I've replaced them with a single CPLD chip, the Xilinx XC9536XL-5VQG44C.
RGB PROM is MB7124. MB7124 are compatible with 82s147 proms which I have found to work. If these become unavailable, the CPLD option is my recommendation.
Sampled from pin 1 of the audio connector on the Esh PCB (CN1).
D2 on the Esh PCB will connect lamp lines to ground when the lamp is to be enabled. Therefore, if testing with, for example, a 20mA LED and 12V power, you would need to to wire one end of the LED to 12V and a 820 ohm resistor, and the other end to the output of one of the D2 lines. Once a path to ground is created, the LED will light up.
- LAMP_JOYSTICK will light up when a valid joystick move needs to be made in order to not die.
- LAMP_ACTION will light up when a valid action button move needs to be made in order to not die.
- LAMP_START1 and LAMP_START2 light up when the associated buttons may be pressed to start a game.
How sync is generated
Horizontal counters are reset when CHD0 goes low, which is when HA[7:0] is between 0x38-0x9F (inclusive). when they are reset, HA gets a value of 0xB0 due to the wiring of D0-D3 of B5. B6 gets a value of 6, but only bit 0 matters (the bit that represents the 15.6 kHz clock). This bit is toggled every time HA goes from 0xFF to 0x00.
When HA is 0xB0, HD0 goes high again but HD1 stays low (HD1 is eventually output as the hsync portion of the csync signal). So having HA at 0xB0 is the start of the hsync pulse.
The 15.6kHz clock (pin 14 of B6) goes high when HA becomes 0, which suppresses all HD output (sets it to all high). It then goes low again when HA becomes 0 again. So a full horizontal lines lasts from HA going from 0-0x38 (57 counts) and 0xB0-0 (80 counts) and then to 0 again (256 counts). Some of those values may be off by 1, so this may not be exact. Approximate math is (256+57+80 cycles at 6.144 MHz (162.76 ns period) or 393*162.76ns or 63.965 microseconds. I am not sure why I needed to use the 6.144MHz clock instead of the frequency of pin 14 of B4 but I took measurements and experimented and it seems to be correct.
I haven't studied this one as closely. It looks like it's designed to increment VA once every other horizontal line. So the horizontal counters need to be working properly for the vertical counters to work.
Unplug edge connector and apply only 5V/GND to PCB edge. Unplugging edge connector removes ambiguity about whether timing is coming from laserdisc player sync or PCB-generated sync (which is slightly different).
Check B7, pin 3. Must be stable 18.432 MHz clock. If not stable, check resistors/cap near clock.
Check B7, pin 10. Must be stable 6.144 MHz clock. If not stable, check B3 and A5.
With sync PROMS removed, check B7 pin 14. Must be stable 12 kHz clock. (this is the 6.144MHz clock divided by 512)
With sync PROMS removed, check D6 pin P2. Should be about 6.25 kHz. If not seeing any activity, A5 may be the problem (driving pin 13 instead of reading it like it is supposed to).
With sync PROMS removed, check C7 pin P9. Should be about 45 Hz. If not, could be A5.
With sync PROMS installed, check B7, pin 14. Must be stable 15.63 kHz clock. If not stable, check H PROM (C5) and all of the horizontal counters (B6, B5, B4, and B3).
Check D7, pin 12. Must be stable 59.5 Hz clock. If not, check vertical counters (C7, D7), A5, A6 and V PROM (C6).
Check H7, pin 9 (CPU clock source). Must be stable 3.07 MHz clock.
(image not available)
If all is working, you can install the normal edge connector again.
"No Video" Troubleshooting
Check to see if CPU RESET' is held low (a common problem due to solder bridging on the reset circuit).
- Install Matt's Esh Test ROM into H8.
- Remove F8 ROM and B8 RAM to help isolate the problem.
- Attach logic analyzer to Z80 and power on PCB. Take logic analyzer capture of CPU's address/data lines after CPU has been on for a second or so. Make sure that CPU is looping in the "RAM BAD" part of the test ROM code (0xA1D - 0xA4E if using v3 of the Esh Test ROM). If it isn't, check K7 to make sure that basic routing is working.
- Check pin 21 (write) of F3, the video RAM, to make sure it is pulsing low.
- Check pin 11 of H1 (load) to make sure it is going high and low. Check pin 12 to make sure it is high.
Having problems getting past Stage 4 after the giant sand fish emerges? Are you playing without the superimpose board? Make sure the edge connector pin 19 (DISC_VSYNC') is connected and edge connector pin V (DISC_CSYNC') is connected. Otherwise, you will not be able to play beyond this point. If you don't have a superimpose board, you can attach to Dexter's vsync and csync signals as a temporary workaround.
Video tile corruption
Seeing random tiles that aren't supposed to be there?
Too slow video RAM
Your video RAM may be too slow.
Hitachi HM6116P-70 RAM may not work even though it is supposedly 70 ns. I had problems with these.
NEC D446C-2 RAM may be fast enough in most cases. 200ns access time, 200ns cycle time. It may not be fast enough in all cases (such as when LD video is being displayed) but tests have shown that this isn't a noticeable problem. Try to get 150 ns RAM if possible.
Original video RAM is Fujitsu MB8128-15 (150ns).
WAIT state not being properly set for Z80
This one was a very tricky defect for me to track down. The game is designed to wait an extra CPU cycle when video RAM is accessed but the WAIT flag was not being asserted properly. I finally tracked this down to a too slow M5 chip (74LS02) where the output needs to update in about 10 ns of the input changing but the 74LS02 I was using wasn't updating until 30 ns. This has the effect of raising at the same time as M6 pin 10 which causes the WAIT line to deactivate immediately. It is supposed to raise a little before M6 pin 10 raises for normal operation.
I noticed that touching an unpowered multimeter probe to HA1 would make the video tile corruption worse, so you can try that as a quick way to see if this might be your problem.
Z80 behaving very oddly
Check to see if any address lines are tied together. I had a case where A2 and A3 were tied together and the whole Z80 was completely freaking out :)
Monitor sync problems
Attach scope to A4 pin 9 (vsync) and A4 pin 10 (hsync), see which one is misbehaving (or both) and work your way backward.
Learnings from the past
A5 is a very critical IC and has been bad for me at least twice. For the second time, the symptoms were extremely odd, random and widespread. They include:
- losing sync randomly for brief periods, especially when laserdisc video is visible.
- touching _unpowered_ multimeter probe to 6.144 MHz clock (pin 10 of A5) causes A5 pin 8 to drop to about 4 MHz (it's supposed to also be around 6.144 MHz) which completely messes up the timing for the rest of the system. This _may_ happen even on a properly working system but I wasn't able to find out for sure because my PCB had multiple random problems.
LDP not skipping at the right places during gameplay
This ended up being due to a low voltage battery (~1.8V instead of 3.6V) which was affecting the program RAM. Make sure battery is fully charged or remove the battery to help diagnose this problem.