Tuesday, March 24, 2015

Freedom Fighter PIF Board

I've been working on improving the VP-931 code for Dexter (used by Firefox) so this was a good time for me to take a look at Freedom Fighter also.  I've reversed engineered the schematics for the PIF prototype board and also written a little utility to "decrypt" the PIF ROM.

Here's the utility:

// Freedom Fighter PIF board has the ROM data lines scrambled, presumably to try to prevent reverse engineering.
// Here is how the ROM data lines match up to the CPU's data lines (verified using multimeter):

// CPU data line ROM data line
// 0 2
// 1 6
// 2 5
// 3 4
// 4 3
// 5 7
// 6 1
// 7 0

#include <stdio.h>
#include <stdexcept>

using namespace std;

int main(int argc, char **argv)
if (argc != 3)
fprintf(stderr, "Usage: %s [src scrambled rom file] [destination unscrambled rom file]\n");
return 1;

unsigned char u8 = 0;
FILE *F = fopen(argv[1], "rb");

if (!F)
throw runtime_error("Cannot open src file");
FILE *G = fopen(argv[2], "wb");

if (!G)
throw runtime_error("Cannot open destination file");

for (;;)
int i = fgetc(F);

// EOF ?
if (i == EOF)

// do bit manipulation
u8 = 0;
u8 |= (((i >> 7) << 0) & (1 << 0));
u8 |= (((i >> 6) << 1) & (1 << 1));
u8 |= (((i >> 0) << 2) & (1 << 2));
u8 |= (((i >> 4) << 3) & (1 << 3));
u8 |= (((i >> 3) << 4) & (1 << 4));
u8 |= (((i >> 2) << 5) & (1 << 5));
u8 |= (((i >> 1) << 6) & (1 << 6));
u8 |= (((i >> 5) << 7) & (1 << 7));

fputc(u8, G);


return 0;
catch (std::exception &ex)
fprintf(stderr, "%s\n", ex.what());
return 1;

Monday, March 23, 2015

How many microseconds is one CPU cycle?

I had to figure this out (again), so I am writing this down for future reference.

(1*10^6 microseconds/1second)(1second/CpuHz)1 cycle = ? microseconds

For example, if my CPU is 18.432MHz, then the formula would be:

(1000000/18432000) = microseconds of 1 CPU cycle, which is 0.054 uS

Wednesday, March 11, 2015

Star Rider and the changes that Freedom Fighter prototype made

Some of you may be aware that the prototype of Freedom Fighter was mostly based off of Star Rider hardware.  I've said before that I believe that someone intimately familiar with Star Rider was on the Freedom Fighter team because it would otherwise be far too costly to pay someone to learn the Star Rider hardware (I, of course, could be wrong about this).

If you have seen Star Rider in action ( youtube link ), you will note that top 2/3 of the screen pans left and right while the bottom does not pan at all.  This panning effect is called "the expander" internally because the video is expanded by a factor of 2 and can be panned left or right.  This is one of the really revolutionary things that the Star Rider hardware could do (and which Freedom Fighter takes advantage of) which was really ahead of its time.

While studying the schematics, I stumbled upon how the expander is able to only pan the top 2/3 of the screen while leaving the bottom of the screen untouched:

These two ICs, U61 and U77, are 74LS85's which are simple 4-bit comparers.  They can be chained together to form arbitrary huge numbers.  In this case, having two of them means an 8-bit number will be compared.  The number, in this case, to be compared is the current vertical counter value (which is approximately the same as the current vertical line but not quite).  If the current vertical counter value is greater than 0xB4, then expander always gets disabled no matter what via pin 5 of U77 going high.

Here is how it looks on the actual PCB.  Interestingly, these ICs are in about the middle of the board in a seemingly arbitrary spot.

Pin 5 of U77 is not the only thing that can disable the expander:

Pin 5 of U77 goes into pin 8 of U65 which is a NOR gate.  Another input to this gate is pin 9, which on the schematic is labeled "EXPAND DISABLE".  This is controlled ultimately by the main CPU, which means that the ROM program can disable the expander at will.  However, since this is a NOR gate, it means that the ROM program cannot interfere with the "hard-wired" hardware design that forces the expander to be disabled beyond vertical count of 0xB4.  Stated differently, the ROM program can force the expander to be disabled but can never force it to be enabled unconditionally.

Here is U65 on the board with some notes.  Pin 8 is the top-right pin, pin 9 is to the left of it, and pin 10 is to the left of pin 9.  Pin 10 is the final authority on whether the expander actually gets disabled/enabled.

So, I've understood this for a while now.  But I recently was thinking (again) that Freedom Fighter does not exhibit this behavior as far as I can recall.  In fact, Freedom Fighter will expand the full screen unless I am greatly mistaken.

This caused me to be extremely curious.  If Freedom Fighter can expand the entire screen, then whoever worked on the prototype must've disabled the hardware that disables the expander passed vertical count 0xB4!  Get it?  Someone must've disabled the disabler! :)

Rife with curiosity, I brought out the Freedom Fighter board to see if I could find where this modification took place.  Having already found how the original design worked, I had a very good idea about where to look.  It didn't take me long to find it!
Pin 5 of U77 on Freedom Fighter (as you can hopefully see) has been clipped off.  This means that the neat little 8-bit comparer comprised of U61 and U77 now does nothing.  However, one cannot simply clip off this pin without grounding what it is connected to!  So I looked to see what they did with pin 8 of U65.

As I suspected, someone hooked up pin 8 of U65 (formerly hooked up to pin 5 of U77 which has been cut off) to pin 6 of U84, and it appears that someone cut off this pin from the PCB as well (although I didn't notice this until after I had put the board away).  I haven't bothered to find where U84 is on the schematic or what it does, but I am going to make a very educated guess that it most likely is somehow tied to ground.  Why is this my guess?  Because ground will send a logical 0 to pin 8 of U65.  Remember that U65 is a NOR gate.  Sending 0 to a NOR input is essentially converting the gate to a NOT gate, where the other input is the only input that matters.  The goal (I believe) is for the expander to be controlled exclusively by the CPU, and not by a hard-wired hardware configuration.  So the logical way to accomplish this is to do what I just described.  I am somewhat curious what U84 is but am out of time tonight to find out.

UPDATE : U84 pin 6 is VSYNC' from the laserdisc.  As this does not currently make sense to me, I am going to defer judgment until I have a chance to reverse engineer the Freedom Fighter PIF board and see what it is sending to the VGG board instead of Composite Sync, because that would change the interpretation of what U84 pin 6 means.

Friday, March 6, 2015

Today's Dexter Progress

I've made a bunch more progress on Dexter since my last blog post.

Here is a summary of things that I've improved:

  1. When switching disc player modes on the Dexter board, the firmware tries to clean up itself better.  This is just an internal change that will hopefully make Dexter more stable.
  2. Improved my VP-931 tester and made it flag more problems in the serial port log.
  3. Improved VP-931 mode and made it more robust and safer.
  4. Improved DIAGNOSE mode.  Now when DIAGNOSE is pressed, the current picture number (using VBI style encoding) will be displayed as well as the build date.  This is to help the end user have some visibility into what's going on if all they see is a blank screen.
  5. Intelligent reprogramming.  Now Dexter will automatically try to do a hardware reprogram of itself if one part of it can't talk to the other part.  So if your firmware gets corrupted, the program running on the Raspberry Pi will automatically reprogram the firmware for you after 30 seconds of inactivity.  Neat, eh?
  6. The USB stick no longer has to be in the Pi for Dexter to operate.  The USB stick will continue to used only for updates.  Dexter can now operate solely from the SD card. (woohoo!)

Here are some screenshots of how the VP-931 interface should look if it is working properly.

This first picture is zoomed out.  The solid blue bar at the bottom is the composite sync signal which is changing once every line.  Notice that the Read (RDEN') and Write (WREN') are staggered so that they don't stomp on each other?

Here's a medium zoom showing the beginning of a new field (notice the FIELD transition) and where Dexter is sending the status bytes (DAV' and RDEN') relative to this field.  This is a little after where it happens on a real VP-931 but it really doesn't matter and it can be tweaked easily.

Here is a zoom in of the six status bytes being sent by Dexter.  Notice the handshaking?  DAV' goes low, then RDEN' goes low, then DAV' goes high, then RDEN' goes high.  That's the game and the player stay in sync when communicating.

Wednesday, March 4, 2015

Testing VP-931/Firefox with Dexter

Dexter has supported Firefox for literally years, but I've never been able to personally test it because I do not own any Firefox hardware.  On my TODO list has been to make a "firefox tester" so that I can test the VP-931 mode of Dexter without having a real Firefox boardset.  Over the last few days, I finally worked up the will to create this tester and I decided to make a video to show what I've been working on.

I will be less afraid to improve the VP-931 mode in Dexter now that I can test it.

Monday, March 2, 2015

Just learned something about Dragon's Lair that I never knew

Sorry for the absence in updates.  I hope to be posting more frequently in the near future :)

For LD-V1000 operation, I always thought that Dragon's Lair kept the LD-V1000 ENTER line (pin 17, not to be confused with the PR-7820 ENTER line) tied to ground (ie always active).  However, I am wrong about this.  Looking at the schematics, I just noticed that LD-V1000 Pin 17 is actually tied to the output of an LS374 (an 8-bit latch, called U16 on the schematic).  This latch is written to via memory location 0xE008 in the ROM program.  This means that the ROM program must actively set bit 7 of memory location 0xE008 to 0 in order for commands to be accepted by the LD-V1000.  Setting this bit to 1 would disable command receipt.  I actually have no recollection of whether the ROM ever sets this bit to anything other than 0, and , frankly, I can't see any reason to do this since the LD-V1000 (I am pretty sure) has internal pull-ups to force a 0xFF "NO ENTRY" command if no data is put onto the bus during the command strobe window.

Anyway, just something interesting that I never noticed before.  The LD-V1000 suggests tying pin 17 to the command strobe (pin 7), but I think tying it to ground would also work.