Tuesday, April 4, 2017

Modifying Star Rider to send triggers to logic analyzer

Star Rider has a RAM that was never installed, U7.

If I write to this address, I can trigger my logic analyzer to start capturing exactly where I want it.

But I need to modify the ROM to make this happen.

Some ideas ...

ROM1:1B68 ThinkActualFrameNumIsExpected:          ; CODE XREF: SendPifCmdsAndMore+5E P
ROM1:1B68                                         ; SendPifCmdsAndMore+98 P
ROM1:1B68                 lda     SlowPifCounter  ; may throttle how often we check for seek complete among other things
ROM1:1B6B                 beq     CompareActualPicNumWithExpected
ROM1:1B6D                 dec     SlowPifCounter  ; may throttle how often we check for seek complete among other things
ROM1:1B70                 beq     ReadActualPicNumIfAvailable
ROM1:1B72                 jsr     QueueNopCmdToPif ; make sure that this gets called again
ROM1:1B75                 clra                    ; sets Z flag to indicate success
ROM1:1B76                 rts
ROM1:1B77 ; ---------------------------------------------------------------------------
ROM1:1B77 ReadActualPicNumIfAvailable:            ; CODE XREF: ThinkActualFrameNumIsExpected+8 j
ROM1:1B77                 lda     #4
ROM1:1B79                 sta     SlowPifCounter  ; may throttle how often we check for seek complete among other things
ROM1:1B7C                 dec     SlowerPifCounter
ROM1:1B7F                 beq     Error507        ; if this counter expires, it's an error
ROM1:1B81                 lda     FieldsLeftBeforeStability ; If this is 0, it means it's safe to read the VBI picture number. (See 1B81)
ROM1:1B81                                         ; Gets decremented by IRQ if it is not 0.
ROM1:1B81                                         ; It indicates how many fields the IRQ needs to see before it considers the software/hardware field values to be stable. (see e488)
ROM1:1B81                                         ; It gets set to non-zero any time the hardware field value does not match the software field value.
ROM1:1B84                 bne     Skip4TracksForward ; skip 4 tracks forward
ROM1:1B84                                         ; (to recover from bad VBI read?)
ROM1:1B86                 jsr     ConvertBCDPicNumToHexPicNum ; Converts the last read BCD picture number (from laserdisc VBI) to a hex picture number.
ROM1:1B86                                         ; Carry will be clear on success or set on failure.
ROM1:1B86                                         ; 'D' and $A133 will contain the converted picture number, or 50000 (decimal) on failure.
ROM1:1B89                 bcc     CompareActualPicNumWithExpected
ROM1:1B8B Skip4TracksForward:                     ; CODE XREF: ThinkActualFrameNumIsExpected+1C j
ROM1:1B8B                 lda     #$10            ; skip 4 tracks forward
ROM1:1B8B                                         ; (to recover from bad VBI read?)
ROM1:1B8D                 sta     PifArray1ByteSpecial ; This byte will be sent to the pif board if it is non-zero.
ROM1:1B8D                                         ; It is special in that it can receive a higher priority to be sent (I don't fully understand it yet).
ROM1:1B90                 clra
ROM1:1B91                 rts

I am going to try writing to D800 at 1B7C and 1B8B to see if it reveals anything.

Monday, April 3, 2017

Major Star Rider / PR-8210A / Dexter break through!

I'm pleased to announce that I've finally made a break through with regards to understanding in a very detailed way how Star Rider and the PR-8210A interact with each other, and thus how to properly support Star Rider with Dexter.

In order to explain why the knowledge I've gained is significant, I need to step back and give some context.

Star Rider is the only laserdisc game that I know of that uses the PR-8210A.  How is the PR-8210A different from a regular PR-8210?  The PR-8210 (and also PR-8210A) uses commands which are relatively slow to be transmitted.  A command must be sent 2-3 times (all of the games send it 3 times) in a row in order for it to be accepted by the player and this can take a complete frame or two if the disc is playing.  The PR-8210A exposes some internal signals on a centronics-24 connector (the PR-7820 and LD-V1000 also use this connector) that allow a connecting device (such as an arcade PCB) to control the forward/backward motion of the disc both quickly and accurately.  This allows one to develop the kind of game that Star Rider is: a racing game where the disc speeds up and slows down.  The way that this is done is via a signal called the Jump Trigger.

What is the jump trigger?  It's normally an internal signal that tells the disc whether to jump ahead a track or backward a track.  For example, if the disc is paused, at the beginning of every frame, the player will internally generate a jump trigger to tell the disc to jump back 1 frame.  This creates the illusion to the viewer that the disc isn't moving at all but it actually is moving, it is just skipping backward continuously to achieve this illusion.  The jump trigger is also used for stuff like 2X and 3X forward and reverse playback.

Since the PR-8210 commands are so slow, as I mentioned before, they are not suitable for a racing type game.  However, if the game (Star Rider) can instead control the jump trigger, then a racing game suddenly becomes possible.  This is what the PR-8210A provides that a normal PR-8210 does not.

So why have I been having so much trouble with Dexter and Star Rider?  It's because the exact behavior of the jump trigger is not documented (at least not where I can find) so I basically have to take some guesses and/or observe how a real player works.

For the past N years, I've been doing the former, taking educated guesses, and getting close.  But I was running into things like the jump trigger getting sent at odd times from the game and not understanding how Dexter should respond in this situation.  So I finally broke down and got a real PR-8210A setup going (as shown in a previous blog post).  Coupled with a logic analyzer, I was able to finally see what I've been missing for years!

First, how does a search look?

Star Rider will send each command three times in a row.  It looks something like this if it wanted to search to frame 68:
seek seek seek
disp disp disp null
0 0 0 null
0 0 0 null
0 0 0 null
6 6 6 null
8 8 8 null
seek seek seek

Notice "Z2-5 jtrg in" from the above screenshot.  This is the internally generated jump trigger from the player that comes out to the external centronics-24 connector on the back of the player.  It is maintaining the disc in a paused state during the incoming search command.  Notice "Z2-6 jtrg out."  It is the 'final' jump trigger signal that the player actually acts upon.  The Star Rider PCB has the opportunity to override this signal and provide its own.  In this case, Star Rider is not overriding the signal (jtrig int/ext', line #1, is raised) and so what comes into the centronics-24 connector is the same thing that goes back out.

What happens during a search?

A few things happen here:

  • "Stand by" starts toggling at approximately 2 Hz.
  • Video sq' (video squelch) goes low.
  • Z2-5 and Z2-6 start becoming very active.  The player actually uses jump triggers in order to perform a search.  Neat, eh?

What happens when a search completes?

  • Video squelch goes high.
  • The player starts internally generating jump triggers via Z2-5 again (ie the disc is in a paused state)

Notice toward the end of the above screenshot, Star Rider sends three play commands.  This is where I was getting hung up because it was very unclear to me what would happen here.  I could tell that Star Rider wanted take over jump trigger duties and that by putting the player in the 'playing' state that the player would stop generating internal jump triggers.  But I couldn't tell whether there was a bug in Star Rider that caused the player to jump an extra track forward or backward.

Examining these three play commands more closely is very interesting.

In the high-lighted area, the player is generating internal jump triggers and Star Rider is also generating them AND trying to override the player's internal jump triggers.  This appears to be a defect in Star Rider's program.  It should not be trying to do this.  But it is what it is.  There seems to be a contention here.  So what actually happens?  Does the player process two jump triggers?  Does Star Rider manage to override the internal jump trigger before it kicks off?  Is a second jump trigger ignored?  It's really hard to say... unless we zoom in :)

This may seem to be a straight forward screenshot of straight forward information, but let me assure you, it took me YEARS to finally figure this out!  I can only guess, but my speculation is that the Star Rider developers were not aware of this bug in their code because, conveniently, the PR-8210A apparently ignores the second jump trigger.    The reason that this is a bug is because Star Rider overrides the PR-8210A's jump trigger after the PR-8210A has already generated it.  Why does the PR-8210A ignore the second jump trigger?  Perhaps because it occurs to close to the first one?  I really have no way of knowing without further study.

Conclusion: I should be able to make Dexter ignore an external jump trigger from Star Rider the same way that the PR-8210A ignores it.  It will take a bit of trial and error, but I am confident that I can make it happen.  Having the original player available to study was extremely helpful!

Thursday, March 30, 2017

PR-8210 to PR-8210A conversion! (successful!)

I'm really close with Star Rider support for Dexter but there are a few quirks of the game that make me want a real laserdisc player for research.  I decided to try Andrew Hepburn's guide to convert a dead PR-8210A to a working PR-8210.

Sunday, February 26, 2017

Wrote a custom analyzer for Saleae Logic 16

Trying to troubleshoot Star Rider was hard enough without trying to decode the laserdisc commands "by hand."  I wrote a custom analyzer for my Saleae Logic 16 to decode the commands automatically:

Tuesday, February 21, 2017

Star Rider : Playing a 1984 piece of hardware with an xbox 360 wireless controller?

It started innocently enough... the 'DISC SEARCH' test wasn't working and I wanted to fix this.  Eventually, I ended up creating a custom PCB in conjunction with an xbox 360 wireless controller just to get the dang test working :)

I use a (IMO) very cool troubleshooting technique involving the ROM program disassembly and a logic analyzer to track the issue down.

Monday, February 13, 2017

Hacks to troubleshoot Star Rider controls I/O problem

Warren hacked up an Arduino to allow a playstation 2 controller to hook up to Star Rider.  I am having trouble getting this working, so I reprogrammed the Arduino with the original PS2 example code which uses serial output to show what's going on.  The only problem is I don't have a USB to 5V TTL adapter.  So I thought about what I did have.  I had a Papilio One FPGA dev board with a USB connection on it.  I could program the FPGA to just pass the RX/TX signals through two of its I/O pins.  However, this uses 3.3V, not 5V.  So I couldn't just plug it directly into the Arduino.  I needed something to shift the voltage level.  Then I remembered my Disk ][ breakout board which I hadn't yet soldered up.  This board does exactly what I need!  So I ended up hooking the Arduino up to the Disk ][ breakout board to convert the 5V TTL to 3.3V TTL and then hooking that up to my Papilio One which is hooked up to my desktop.  It works! :)

Saturday, February 4, 2017

Fixing Steve Bower's PIF board

I made a new 25 minute video showing me troubleshooting and eventually fixing a problem with Steve Bower's Star Rider PIF board, after going down several wrong paths.

This hardware is incredibly difficult to keep running :)

Saturday, January 21, 2017

Everything I ever wanted to know about the Apple IIgs RGB monitor signals

My favorite 80's computer by far is the Apple IIgs.  I had this machine as a kid growing up and thought it was awesome.  I think I was even more stubbornly loyal because so many of my peers refused to give it the respect that it deserved.

Well, the Apple IIgs stock RGB monitor is intriguing to me because it is relatively small and I do a lot of work with arcade game PCBs in a bench type setting.  I have a need of a nice compact RGB monitor for testing and so if I can somehow use the Apple IIgs monitor for this purpose, that would be awesome.

asked a question on Facebook about the Apple IIgs RGB signals and got no response.  Either no one knew the answer or no one knew why I possibly would want to know. :)

Never one to rely on other people to achieve my goals, I decided to take matters into my own hands and created a little break-out PCB so that I could 'sniff' the RGB signals myself and get my own answers.

The first step was to whip up the schematic in Eagle:

I whipped this up as fast as possible because I knew that I would only need this board once and then probably would never use it again.

I spent an equally short amount of time on the PCB layout:

This was a mistake to rush through this, but not a fatal one.

On a recommendation from a friend, I decided to use pcbway.com to make the PCB.  To my shock, I had the PCB in my hands in only 7 days after placing the order.  And it was from China!!  Only cost me $10 for 10 boards (why buy one when you can get ten? lol) and $20 for shipping which is a steal in my book.  Awesome!

After ordering the rest of the parts I needed from digikey.com, I whipped out my soldering iron and got to work.

It was then that I realized my mistake.  I wasn't paying close attention to the DB15 datasheet and ended up having the two connectors facing INWARD instead of outward.  That simply was not going to work!!!

Not to be defeated, I decided to solder on wires and hack the thing together enough to do what I wanted.

I plugged it in ...

and turned on my IIgs ...

it was working!! WOOHOO!!!

Once I got this far, I decided to hook up my Rigol scope to the CSYNC and BLUE signals to see what kind of voltage levels I was getting.

I decided to use a nice nearly solid blue screen so that I could see what the full blue intensity would be.

First I wanted to see what vsync looked like:
Interestingly, the blue signal seems to also contain sync information.  I really don't understand why they would do this and I strongly suspect that this monitor will probably work without the sync info being part of the color voltages.  But I guess I'll find out.  At any rate, I observed that the sync was a fairly typical negative composite sync signal going from 0-5V with hsync being mixed with vsync.  I've seen it both ways where the vsync is a solid low pulse and where vsync has hsync mixed in with it.  This is, I believe, what the jamma csync looks like (or is pretty close at least).

Next was to see what the voltage range of the blue signal was by going to a random line in the middle of the field/frame:

 It looked like the voltage was going from 0-1V.  I'm glad I checked this because I would've assumed it would've been from 0-5V.  If I do rig up arcade PCBs to talk to this monitor, I'll probably need to drop the voltage down to avoid damaging stuff.

Next I wanted to zoom in on an hsync pulse and see how wide it was:

Nothing earth-shattering here.  Just wanted to document it :)

Just to be sure I was seeing what I thought I was seeing, I decided to switch the screen to a black background with blue border:

This is what I was expecting.  By zooming in a single line, I was expecting to see 1V near the beginning of the line, followed by a drop in voltage to indicate black, followed by 1V again toward the end of the line, and that's exactly what I am seeing here.  Interestingly enough, black seems to be around 0.3V, not 0V.  It seems that 0V is reserved for sync signals.  This is pretty similar to how NTSC composite works.

Again, I suspect that it is not necessary for the sync signals to be part of the blue signal, but maybe I'm wrong.  Why would Apple go to the trouble of including it if they didn't have to?  Maybe it was part of the RGB encoder they used. *shrug*

The last thing I wanted to document was whether this signal had fields like an NTSC signal.  The NTSC signal's vsync pulse is slightly different depending on whether it is a top or bottom field.  I wanted to see whether this RGB sync had the same kind of characteristics.

Using a scope was probably not the best way since I didn't have a good way to trigger on vsync.  Therefore, I switched to using my Saleae logic analyzer to measure distance between vsync pulses:

Here's a logic analyzer capture zoomed in on a vsync pulse.  It looks similar to what it looked like on the scope except more well defined :)

Zooming out, I was able to put time markers on each vsync to see the intervals:

As you can see, the interval between each vsync pulses is "exactly" 16.689 ms with no variation.  This means that it is a ~60 Hz signal but that it not like NTSC composite where top and bottom field vary.  However, I am not sure what it _does_ mean :)  I don't  have a lot of experience with progressive signals, but if I were to guess, I'd say that this is a progressive signal and that the entire frame is being sent 60 times per second.  The hsync pulses were similar to NTSC (63.5uS apart) so I'd guess that this means that this signal is describing 525/2 lines just like NTSC (~262.5ish but without the decimal since it's progressive).  That would kinda make sense since the IIgs can display 200 vertical lines and it has this extra border on the top and bottom.  But I'm kinda just speculating at this point.

At any rate, I've concluded that in order to get this monitor to work with arcade games, I'm going to need to do a few things:

a) if arcade game has separate positive vsync and hsync, I'm going to need something like an xnor gate to combine them.  Otherwise if it's just a jamma csync signal, I may be able to use it unmodified.
b) if arcade game RGB voltages are 0-5V, I'll probably have to add some resistors to drop the voltage down to 0-1V.  This may be something that I play around with until I find values I like.

I hope you enjoyed my journey.

Friday, January 20, 2017

An interesting Time Traveler troubleshooting video

We've almost got Time Traveler fully working with Dexter.

Warren put together a video showing how he cleverly tracked down one of the last known issues before we can declare Time Traveler fully supported: