Monday, 6 May 2013

Arkanoid Controller


Arkanoid Controller


Haven't done wood work since I left school, and that was a hell of a while ago.. ;)
So being the bank-holiday I borrowed a drill to put up some garden fixtures & got a little side tracked *ahem* (the garden furniture never did get fixed).

I decided to convert a cigar box into an Arkanoid spinner controller! (hate cigars anyway)



Was lucky in finding a drill bit that fitted the diameter of a arcade button.. (It came with my son-in-law's car-camera kit!?! & he didn't need it.)



Meh - should have practiced, even after marking out the wood I managed to get one of the button holes 1mm too far to the left & managed to chip the veneer (though it will be covered by the plastic plate under the spinner).



Dismantled the spinner & bolted her in..



Gotta love heat-shrink cable wrap!



Used the cable from an ex-Dreamcast pad that I converted to Jamma previously.. 
For brevity I just soldered the control wires directly to the Arkanoid-to-Jamma adapter.
(I'll work out a plug arrangement perhaps.)



Coin-up is still done by the service button on my test loom.. still don't know why all my boards ignore the 'coin' wires & use 'service'?



Just need some proper player 1/2 buttons to finish it off.. but at least for now I can now play Arkanoid comfortably!! 



Thanks (again) to Ben76 (Over on J+) for the Arkanoid power plug & to Rob for the drill bit! :D

Long term I'd like to re-jig my BarTop into being able to have its monitor rotated & then I'll attempt to build a custom CP for this game (with a more authentic layout), but for now... It's all good!

Friday, 8 February 2013

Bomberman World - Repair Log


Bomberman World - Repair Log


Picked up a (rather cheap) iRem Bomberman World (Global Quest) arcade board from eBay today..



Looked visually to be in good condition, but the seller did say it had been stored for a while.

Plugged it into my BarTop and all seemed well.. coined it up & started a couple of games..

But, about 5 minutes things got a little odd.. :S

When ever the game made a loud-bang (such as when the bombs went off) the screen would go all frizzy & wobble out of sync.. & the VGA converter would then loose signal-lock for a few seconds. 

This carried on for a bit, then all of a sudden...
                    BOOM!


Made everyone jump a mile!! ... The main smoothing cap on the 12 volt line (to the Amp) went bye, bye in a most violent way! (..and the misses got rather pissed off too :/)

Bits of capacitor flew everywhere & hit me in the arm! :(




A nice quick fix though..

De-soldered & pulled the cap out, cleaned the board & dropped in a 40 volt replacement from the spares box (the original was rated 25v).



Will probably re-cap the whole power section at some point, the games a good 21 years old now (no surprise a cap has dried out after all this time).

Have turned the board upside down, in case it goes bang again ;) ..soak tested it & looking good so far. :D



Loved Bomberman on the Snes bitd & played a lot of the PCEngine version - well chuffed to finally own an original iRem version..!



Saturday, 5 January 2013

Dual Boot R-Type 1 & 2 Arcade PCB - Day 6

 Dual Boot R-Type 1 & 2 Arcade PCB - Day 6


Devised a solution for the game select switch mechanism:


  • Cut a square of ABS plastic from some scrap from an IKEA cupboard corner (packing material)..

  • Melted a hole through the middle with the soldering iron & fitted a single pole dual throw toggle switch.

The whole assembly was then located in order that the switch sat within a retangular cut that was already present on the board:


Quick-dry Araldite was used to bond the plastic down to the PCB.

Two wires were connected to the left & right most pins of the switch & were soldered directly to the solder-pads of a nearby de-coupling capacitor (providing the required 0 & 5v signals).

The bydo-orange master A/B game-select line is tied to the switches middle pin.

The main idea of mounting the switch upside down between the boards is to avoid switching during game play.. The power must be disconnected while switching between games.

Perhaps a future iteration could perform a system-wide reset when the switch is toggled?

Fin.

DIY Jamma To USB Converter

  DIY Jamma To USB Converter


A couple of days ago there seemed to be an onslaught of soap-opera's :/ so it was back into the lab (read corner) to play with some tech..

In the past I had built a custom adapter that read the PS2-Keyboard signals from my HotRod Joystick controller & spat out USB joystick and Jamma switching signals (so I could play Mame & run my Jamma boards).

This time I wanted to be able to connect my lap-top to my BarTop (or indeed any other Jamma cabinet), so I grabbed one of the fingerboards kindly provided by Jenginner & a Teensy 2 board.

The end result was this:



And from below...



It's a pretty stright forward setup, the Teeny 2 processor has 22 I/O pins - so I connected 21 of them to the Player 1 & 2 joystick, coin & button (& service) connections of the finger board.

The power for the Teensy is provided by the computer connected to the USB, and the ground wire from the Jamma connector was wired to the Teensy's ground pin.

This arrangement allows the Teensy's I/O pins to be short circuited to ground by the controls in the cabinets CP. (My BarTop is based on a VGA LCD panel, so there is a VGA cable that can be brought out to the lap-top - handling the visual side of things :D)

Teensy 2's are available at: http://www.pjrc.com/teensy/ for $16 and for this project I used Teensyduino which is detailed on the same site.

Teensyduino basically puts the Teensy into a state where it thinks it's an Arduino, and as such is rendered much simpler to program.

Part of the Teensyduino integration is the ability to put the Teensy into a mode where it thinks it's a USB keyboard/mouse/Joystick (simultaniously as it goes), see:

http://www.pjrc.com/teensy/td_download.html
http://www.pjrc.com/teensy/td_joystick.html

Using the provided Teensy/Arduino editor (that can be found on the site above) I wrote the following program (don't worry - it's not too complicated):

//
// Jamma to USB converter... (BarTop Edge connector interface)
//

void setup()
{
  // Set all I/O pins to input (With pull-up!)...
  for (int p = 0; p < 21; p++)
  {
    pinMode(p, INPUT);
    digitalWrite(p, HIGH);
  }
 
  Joystick.useManualSend(true);
}

void loop()
{
  // Read all the Input pins...
  for (int p = 0; p < 21; p++)
  {
    Joystick.button(p+1, !(digitalRead(p) & 1));
  }

  Joystick.send_now();
 
  delay(5);
}


Once uploaded to the chip, the program scans the I/O pins 0 -> 20 which are setup as Inputs (using: pinMode(p, INPUT);) and the pins 5v pull-ups activated (by: digitalWrite(p, HIGH);).
This makes the pins sit at 5v, which can then be grounded by the switches within the Jamma controls.

The main loop basically loops over every one of the 21 pins we're interested in, reads the value of each one (using: !(digitalRead(p) & 1) (notice I'm inverting the signal with the ! NOT keyword)) & then outputs a corresponding USB-Joystick button press (using: Joystick.button()).
(I had to invert the signal read back from the pins as with the 5v pull-up - the signal is high when nothing is happening & low when a button / joystick direction is pressed.)

Joystick.useManualSend(true); stops the USB ouputing anything until you call: Joystick.send_now(); inorder that all the button presses make it to the lap-top at the same time.

And the delay(5); is to stop the chip kicking the shit out of the USB port - 200hz is more than enough..

And that's about it - after redefining the 'keys' in Mame, I loaded Puzzle-Bobble up & the misses was a happy bunny. :)

Edit:

Had to move a couple of wires around, ended up using the wires destined for Coin# 1 & 2 for Service & Test. Oh, and I had a bug - the Joystick.button() function only takes a button number starting from 1 - so I added +1 to the 'p' variable being passed into the first parameter (and remapped the keys again).

Edit #2: 


Had to work through a problem I was having with my cab->to->laptop adapter.. namely why Mame was forgetting some of it's key mappings on start-up.

The above code mapped the two player sticks & buttons across 20 USB joystick buttons.. and Mame does see them all when you configure the keys. But when you re-load Mame, half of the button mappings appear as N/A

I just noticed this morning that any buttons numbered 1-15 were okay.. so it looks like while the system does recognise my 32 button USB device.. the loading system only loops through and sets up the first the first 16!! :( (maybe normal USB controllers support 16 buttons max?)

So I did a re-write and moved the Player 1 stick to the analog X & Y Joystick axis and moved the Player 2 stick to the Left & Right analog shoulder axis.  The remaining Player 1 & 2: Fire 1-4, Coin, Start & Service buttons were then mapped to the first (lower) 12 USB button indices.

All works sweetly now & I can even use other DirectInput games on my cab, things like ZSnes, Sega Fusion, Etc..!! ¦)

The code became:

//
// Jamma to USB converter... (BarTop Edge connector interface)
//

uint16_t lastPlayer1 = 0x0000;
uint16_t lastPlayer2 = 0x0000;
uint16_t lastTest = 0x0000;

void setup()
{
  // Set all I/O pins to input (With pull-up!)...
  for (int p = 0; p < 21; p++)
  {
    pinMode(p, INPUT);
    digitalWrite(p, HIGH);
  }
 
  Joystick.useManualSend(true);
}

void loop()
{
  uint8_t p1Coin  = !(digitalRead(0) & 1);
  uint8_t p1Up    = !(digitalRead(18) & 1);
  uint8_t p1Down  = !(digitalRead(17) & 1);
  uint8_t p1Left  = !(digitalRead(16) & 1);
  uint8_t p1Right = !(digitalRead(15) & 1);
  uint8_t p1Fire4 = !(digitalRead(11) & 1);
  uint8_t p1Fire3 = !(digitalRead(12) & 1);
  uint8_t p1Fire2 = !(digitalRead(13) & 1);
  uint8_t p1Fire1 = !(digitalRead(14) & 1);
  uint8_t p1Start = !(digitalRead(19) & 1);
 
  uint8_t p2Coin  = !(digitalRead(10) & 1);
  uint8_t p2Up    = !(digitalRead(8) & 1);
  uint8_t p2Down  = !(digitalRead(7) & 1);
  uint8_t p2Left  = !(digitalRead(6) & 1);
  uint8_t p2Right = !(digitalRead(5) & 1);
  uint8_t p2Fire4 = !(digitalRead(1) & 1);
  uint8_t p2Fire3 = !(digitalRead(2) & 1);
  uint8_t p2Fire2 = !(digitalRead(3) & 1);
  uint8_t p2Fire1 = !(digitalRead(4) & 1);
  uint8_t p2Start = !(digitalRead(9) & 1);
 
  uint8_t testButton = !(digitalRead(20) & 1);

  // Read all the Input pins...
  Joystick.button(7, p1Coin); // Coin 1
  Joystick.button(8, p1Fire4); // P1 - Button 4
  Joystick.button(9, p1Fire3); // P1 - Button 3
  Joystick.button(10, p1Fire2); // P1 - Button 2
  Joystick.button(11, p1Fire1); // P1 - Button 1
  Joystick.button(12, p1Start); // P1 - Start
 
  Joystick.button(1, p2Coin);    // Coin 2
  Joystick.button(2, p2Fire4);   // P2 - Button 4
  Joystick.button(3, p2Fire3);   // P2 - Button 3
  Joystick.button(4, p2Fire2);   // P2 - Button 2
  Joystick.button(5, p2Fire1);   // P2 - Button 1
  Joystick.button(6, p2Start);   // P2 - Start
 
  Joystick.button(13, testButton); // Test
 
  uint16_t player1X = 511;
  if(p1Right) player1X = 1023;  // P1 - Right
  if(p1Left) player1X = 0;     // P1 - Left 
  Joystick.X(player1X);

  uint16_t player1Y = 511;
  if(p1Up)   player1Y = 0;    // P1 - Up
  if(p1Down) player1Y = 1023; // P1 - Down 
  Joystick.Y(player1Y);

  uint16_t player2X = 511;
  if(p2Right) player2X = 1023;  // P2 - Right
  if(p2Left)  player2X = 0;     // P2 - Left 
  Joystick.sliderLeft(player2X);

  uint16_t player2Y = 511;
  if(p2Up)   player2Y = 0;     // P2 - Up
  if(p2Down) player2Y = 1023;  // P2 - Down 
  Joystick.sliderRight(player2Y);

  // Gather all the bits together to test if anything has changed..
  int player1 = p1Coin | (p1Up << 1) | (p1Down << 2) | (p1Left << 3) | (p1Right << 4) | (p1Fire1 << 5) | (p1Fire2 << 6) | (p1Fire3 << 7) | (p1Fire4 << 8) | (p1Start << 9);
  int player2 = p2Coin | (p2Up << 1) | (p2Down << 2) | (p2Left << 3) | (p2Right << 4) | (p2Fire1 << 5) | (p2Fire2 << 6) | (p2Fire3 << 7) | (p2Fire4 << 8) | (p2Start << 9);

  // Only send USB data if something changes (stops Mame stalling)
  if ((player1 != lastPlayer1) || (player2 != lastPlayer2) || (testButton != lastTest))
  {
    Joystick.send_now();
  }
 
  lastPlayer1 = player1;
  lastPlayer2 = player2;
  lastTest = testButton;

  delay(2);    // 2 ms
}

On reflection, I might move the player 1 buttons to the first 4 USB buttons (in order: 1,2,3,4) so that games that can't have their keys redefined will see the cab's CP as a regular USB controller.. :D

Sunday, 30 December 2012

Dual Boot R-Type 1 & 2 Arcade PCB - Day 5

 Dual Boot R-Type 1 & 2 Arcade PCB - Day 5


Okay.. bit of a last-minute update, but..

I went and carried out the last "mod-routing" and only ended up needing two of the 74LS157 chips I had fitted.

(The last mod was where a logic chip had it's pin cut - I used one section of the second multiplexer to switch between "cut & patched" and "uncut")

Beyond that I discovered why the sprites were solid-blocks of colour (in the R-Type 2 mode).. really kicked my self.

Turned out that in my haste to burn those double-size Roms, I accidentely put the N0,1,2,3 data onto 4Mbit chips - instead of the 2Mbit type needed! :/ *facepalm*

That ment the middle of the Rom - in memory terms (where R-Type 2 sits) was in the wrong place! ¦D



Had to wipe 4 of the original Par-Type 1 (27C020) chips, as I had none left..



Dropped in some minty fresh dual-boot 27C020's into the N0,1,2&3 locations - and wired A17 (rather than A18 as with the larger chips) to the orange game-select wiring.. and the sprites came back!



Next I had to solve the problem of dual-booting the audio Rom..

Problem was that the next chip up in size had 4 more pins :'(

- luckly most pins match & only some minimal patching is required (Big thanks to t-m for suggesting this!!! a great idea!).



Here's the upgraded (double-sized 27512) SP chip using a 27C010:



Tidy hack this one ¦)



The four spare (patched) pins hang over the end of the socket - but to no ill effect.



And here she is in all her glory! <3



One orange wire bridges across from the top to the bottom board.. might fashion a removable plug / patch cord for this :/ hmm..



..All that's left to do now is replace the Major-Title VO-Rom (sound-sample) chip with the R-Type 2 version.. (in the morning, I'm tired now!)

..and, that will fix the dodgy RT2 samples playing crowd noises!.. and that folks.. is pretty much it!

 
 I think we can safely declare this one Job Done! :D

Again, a huge thank you to Paul Swan & Chris Hardy for the original conversion techniques!!
(hope you guys approve of what became of it..) ¦)

And a million thanks to all of the members on Jamma+ - without whom I would never have happened across the knowledge, tools and techniques needed to carry out this job, cheers!!!

And Happy New Year!

Saturday, 29 December 2012

Dual Boot R-Type 1 & 2 Arcade PCB - Day 4

 Dual Boot R-Type 1 & 2 Arcade PCB - Day 4


Have made progress with the dual-boot electronics, and feel about half way towards finishing the job.!

First I installed three 74LS157 Multiplexers into the three remaining spare chip-sites (lovingly provided by iRem \o/). <3


(The green hoops bring +5v to the chips VCC pins of the 157's - as the top corner pins of the chip-sites are wired to the 5v rail)

Next I wired all the /CS (chip select) pins to ground.. which switches the three chips on permanently..



Then back on the top side; the orange wire carries the game-A/B (0v/5v signal from the hack above), this is wired to the select pins of the multiplexers - which will switch between the R-Type 1 & R-Type 2 signals.


Next I moved the four green wires that went into the board where the tracks were cut (in the original mod (on the left)) to the A0, A1, A2 & A3 inputs of the first multiplexer. These green wires carry the modified R-Type 1 signals.

I then took four yellow wires from the Y0, Y1, Y2 & Y3 outputs to the four points on the board (where the green wires came from)..



Then from below I found 4 board locations that connected to the original four traces that were cut in the original R-Type 1 mod & connected them to the B0, B1, B2 & B3 inputs of the multiplexer.. The red wires carry the original unmodified signals, which are used by R-Type 2.



Upon booting her up, I was greeted with a lovely sight: a nice R-Type 2 boot screen and working backgrounds!! ¦D

Later tonight I'll route the remaining board mods through the second 74LS157 and hopefully bring the sprites back! 
I then plan to use the third chip (if neccesary) to handle the audio Rom selection duties..

Fingers crossed It should all be running this side of the New Year!! :D

Wednesday, 28 November 2012

Dual Boot R-Type 1 & 2 Arcade PCB - Day 3

 Dual Boot R-Type 1 & 2 Arcade PCB - Day 3


Here's the circuit I would need to correctly select between two Rom chips - using a single hi/low "game select" signal:



(I made a mistake with my first Rom-select design (The NOT & AND gate thingy) in the first post)..

The /CS (chip select) line on the Roms activates the chip when it goes low..! 

So here, I use two sections of a 74157 to pass either the hi/(active)low /CS signal (or) a 5v signal.

This should correctly disable the unused Rom chip with the positive signal while passing the /CS to the other one.

Also..

Just programmed the 27C040 ROMs for C0-3 & N0-3, wired up the A18 address pins to the previous orange wire patch and observed the following:

* R-Type 1 is still fully functional (as expected).
* R-Type 2 has some visual errors, which are related to the extra electronics & board modifications...
** Minor erroneous background tiles.. Not bad, but a few wrong (similar in nature to RT1 prior to the logic/board mods).
** All sprites are a block of solid colour.

So it looks as if I will have to add those multiplexers to switch the modifications in & out.. cool. :)

Also have to do something with the audio Rom.. And since I'm going to use those multiplexers, I think I'll go with the new Rom selection logic above (and be switched with all the other board signals).