What's new

Metro VG420 Multi interest and development thread?

I had two major problems: Programs involving latches, despite producing sensible looking equations in the intermediate files, failing to produce a working jed file, and state machines that just failed to compile (again with bizarre error messages), but worked once I resolved them into plain equations.
 
I am rooting for you. You can do it!
 

Attachments

  • images (3).jpeg
    images (3).jpeg
    15.6 KB · Views: 17
So now that I've got Pang Pom's Working I've turned my attention to the "mystery" game I mentioned. well that game is Poitto.
This is a weird one because Poitto was only released on the later MTR5260, BUT it's the only game on that hardware that uses the correct video chip and clock speeds that match the VG420/VG460 releases, so it's theoretically possible that it could work.

I'm sure this is going to be "dolphin speak" to a lot of you but I figured I'd nerd out a bit about how I'm tackling this problem. It wont hurt my feelings if you don't care about any of this but hey maybe some of you will find this interesting :D

I've been banging my head against the wall on this one because from all outward appearances this should be really straight forward to make work. the only real difference in the mame driver is the is in the 0x80000# address range, which is for inputs, dips, and coins. Literally everything else lines up exactly, this is the only area where the MTR PCB differs from the VG420 PCB. Most of the time conversions like that would just boot but the controls would be messed up and you'd have to do a little patching to fix it.... but poitto wont even BOOT.

What happens in in a normal boot process with these Metro Games
1. the monitor gets a sync signal with a black screen
2. a full screen of video garbage appears
3. the screen goes black momentarily
4. RAM CHECK appears on screen
5. the game enters attract mode

Poitto gets to step 3, but never reaches step 4, this is enough to confirm that my address remapping works (so it's not a similar problem to Pang Pom's which wouldn't even reach step 1). Even remapping the dips and controls to patch them into the right spots there was no change.

So what I started doing is running remapped code in MAME, essentially intentionally breaking the normal poitto game, and what I found is that MAME stops booting the game in the same spot on the boot process when I remap the "coins" input.

I don't actually think any of the dips or input mappings matter, but one other little tiny thing mixed in here is the "sound status" bit, some kind of IRQ...

Now my initial assumption was that sound status was was mapped essentially the same in both games.
The difference being that VG240 Reads AND writes to the address, while MTR only writes (no read at all), and that shouldn't be a problem.

this is last fortress:
Code:
map(0xc00001, 0xc00001).rw(FUNC(metro_upd7810_state::soundstatus_r), FUNC(metro_upd7810_state::soundstatus_w)); // From / To Sound CPU

this is poitto
Code:
	map(0x800001, 0x800001).w(FUNC(metro_upd7810_state::soundstatus_w));  // To Sound CPU

Now I'm doing the high level address remapping to change the 0x80000# to a 0xC0000#, so these should be the same right? WRONG!
lets look at the coins mapping...
in last fortress:
Code:
map(0xc00004, 0xc00005).portr("IN0");

in poitto:
Code:
map(0x800000, 0x800001).portr("IN0");

you might think, ok they're at different addresses, so just patch it. poitto does the annoying thing where they're using the same address for two different things reading to 0x800001 for coins but writing to 0x800001 for sound status... but thats where I was wrong.

If we look at the input definition for each game
on last fortress:
Code:
static INPUT_PORTS_START( lastfort )
	PORT_START("IN0")   /*$c00004*/
	COINS

...

on poitto:
Code:
static INPUT_PORTS_START( poitto )
	PORT_START("IN0") //$800000
	COINS_SOUND

...

do you see it? last for is importing "COINS", but poitto is importing "COINS_SOUND"... WTF is coins_sound?

COINS:
Code:
#define COINS \
	PORT_BIT(  0x0001, IP_ACTIVE_LOW,  IPT_SERVICE1 ) \
	PORT_BIT(  0x0002, IP_ACTIVE_LOW,  IPT_TILT     ) \
	PORT_BIT(  0x0004, IP_ACTIVE_LOW,  IPT_COIN1 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0008, IP_ACTIVE_LOW,  IPT_COIN2 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0010, IP_ACTIVE_LOW,  IPT_START1   ) \
	PORT_BIT(  0x0020, IP_ACTIVE_LOW,  IPT_START2   ) \
	PORT_BIT(  0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN  ) \
	PORT_BIT(  0x0080, IP_ACTIVE_HIGH, IPT_UNKNOWN  )

COINS_SOUND:
Code:
#define COINS_SOUND \
	PORT_BIT(  0x0001, IP_ACTIVE_LOW,  IPT_SERVICE1 ) \
	PORT_BIT(  0x0002, IP_ACTIVE_LOW,  IPT_TILT     ) \
	PORT_BIT(  0x0004, IP_ACTIVE_LOW,  IPT_COIN1 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0008, IP_ACTIVE_LOW,  IPT_COIN2 ) PORT_IMPULSE(2) \
	PORT_BIT(  0x0010, IP_ACTIVE_LOW,  IPT_START1   ) \
	PORT_BIT(  0x0020, IP_ACTIVE_LOW,  IPT_START2   ) \
	PORT_BIT(  0x0040, IP_ACTIVE_HIGH, IPT_UNKNOWN  ) \
	PORT_BIT(  0x0080, IP_ACTIVE_HIGH, IPT_CUSTOM  ) PORT_READ_LINE_MEMBER(FUNC(metro_upd7810_state::custom_soundstatus_r))   /* From Sound CPU */

those mother f-ers burred the sound-status read inside the same call as the coin and start switches 🤬

I'm convinced this is the problem that's keeping the game from booting. I don't know how to patch it out yet, there are 12 different read calls to this address and I'll have to analyze the code for each one of them to determine what it's doing with the data after the read and then handle it appropriately.

Even after I get past this there is some annoying patching required to get controls working since they're not just different addresses but also arranged differently.
 
I stared at the code for a few hours last night and woke up this morning with some ideas to try...

View: https://youtu.be/Vwcboft2cQE


IT BOOTS!

Still some work to do, it boots now but there is no sound which means I need to do more digging to further untangle the sound status flag from the input controls.

booting - YES!
sound IRQ - not yet working
coin inputs - fully working
P1 controls - fully working
P2 controls - not yet patched
Coin DIPS - fully working
settings DIPS - not yet patched

The good news is, this is enough that I should be able to start moving the hardware to prototyping.
 
I stared at the code for a few hours last night and woke up this morning with some ideas to try...

View: https://youtu.be/Vwcboft2cQE


IT BOOTS!

Still some work to do, it boots now but there is no sound which means I need to do more digging to further untangle the sound status flag from the input controls.

booting - YES!
sound IRQ - not yet working
coin inputs - fully working
P1 controls - fully working
P2 controls - not yet patched
Coin DIPS - fully working
settings DIPS - not yet patched

The good news is, this is enough that I should be able to start moving the hardware to prototyping.
Epic job!
 
maybe some of you with 68K assembly eyes can see something I don't.

on poitto the 0x800000 address is used for 3 things
1 - it sometimes reads coin inputs (coins, start, service, test, tilt) at which case it should read a 0x003F if nothing is being pushed
2 - it sometimes writes 0x0001 here to set the sound status flag
3 - it sometimes reads here to check the sound status flag, which returns as 0x80, or when combined with the coin inputs 0x00BF (yes you read that right it's reading from a different position than it's writing)

on other VG240 games they separate this out.
the sound status is read and written to 0x800000, as 0x0001 and read as 0x0001
and the coin inputs are read at 0x800004 and should read as 0x003F when nothing is being pushed.
... simple

now on Poitto I'm pretty sure the coin inputs is only really read from this chunk of code:
Code:
0006CC: 48E7 8000                movem.l D0, -(A7)
0006D0: 2039 0080 0000           move.l  $800000.l, D0
0006D6: 2039 0080 0000           move.l  $800000.l, D0
0006DC: 2039 0080 0000           move.l  $800000.l, D0
0006E2: 2039 0080 0000           move.l  $800000.l, D0
0006E8: 4CDF 0001                movem.l (A7)+, D0
0006EC: 4E75                     rts
I'm honestly not entirely sure how it's interpreting this as it looks to me like it's just moving the data to D0 then immediately overwriting it. I'm also not 100% confident it's NOT doing something with the sound status here.
in my patched code I've moved all of these addresses to 0x800004 to match the VG420 hardware

I'm also pretty sure this is the chunk of code for sound status:
Code:
000F0C: 33FC 0001 0080 0000      move.w  #$1, $800000.l
000F14: 33FC 00FF 00C7 88A8      move.w  #$ff, $c788a8.l
000F1C: 3039 0080 0000           move.w  $800000.l, D0
000F22: 0240 0080                andi.w  #$80, D0
000F26: 66F4                     bne     $f1c
000F28: 60C0                     bra     $eea
000F2A: 33FC 0001 0080 0000      move.w  #$1, $800000.l
000F32: 33FC 00FF 00C7 88A8      move.w  #$ff, $c788a8.l
000F3A: 3039 0080 0000           move.w  $800000.l, D0
000F40: 0240 0080                andi.w  #$80, D0
000F44: 66F4                     bne     $f3a
000F46: 33FC 0001 0080 0000      move.w  #$1, $800000.l
000F4E: 1039 0040 E046           move.b  $40e046.l, D0
000F54: 0240 00FF                andi.w  #$ff, D0
000F58: 33C0 00C7 88A8           move.w  D0, $c788a8.l
000F5E: 3039 0080 0000           move.w  $800000.l, D0
000F64: 0240 0080                andi.w  #$80, D0
000F68: 66F4                     bne     $f5e
000F6A: 6000 FF7E                bra     $eea
000F6E: 0C39 00FE 0040 E046      cmpi.b  #-$2, $40e046.l
000F76: 6600 0002                bne     $f7a
000F7A: 0839 0006 0040 E043      btst    #$6, $40e043.l
000F82: 6700 001E                beq     $fa2
000F86: 0C39 0003 0040 E002      cmpi.b  #$3, $40e002.l
000F8E: 6500 0012                bcs     $fa2
000F92: 0C39 0007 0040 E002      cmpi.b  #$7, $40e002.l
000F9A: 6200 0006                bhi     $fa2
000F9E: 6000 0066                bra     $1006
000FA2: 33FC 0001 0080 0000      move.w  #$1, $800000.l
000FAA: 33FC 00FF 00C7 88A8      move.w  #$ff, $c788a8.l
000FB2: 3039 0080 0000           move.w  $800000.l, D0
000FB8: 0240 0080                andi.w  #$80, D0
000FBC: 66F4                     bne     $fb2
000FBE: 33FC 0001 0080 0000      move.w  #$1, $800000.l
000FC6: 1039 0040 E046           move.b  $40e046.l, D0
000FCC: 0240 00FF                andi.w  #$ff, D0
000FD0: 33C0 00C7 88A8           move.w  D0, $c788a8.l
000FD6: 3039 0080 0000           move.w  $800000.l, D0
000FDC: 0240 0080                andi.w  #$80, D0
000FE0: 66F4                     bne     $fd6
000FE2: 33FC 0001 0080 0000      move.w  #$1, $800000.l
000FEA: 1039 0040 E047           move.b  $40e047.l, D0
000FF0: 0240 00FF                andi.w  #$ff, D0
000FF4: 33C0 00C7 88A8           move.w  D0, $c788a8.l
000FFA: 3039 0080 0000           move.w  $800000.l, D0
001000: 0240 0080                andi.w  #$80, D0
001004: 66F4                     bne     $ffa
001006: 6000 FEE2                bra     $eea
So you can see it's writing 0x0001 to 0x800000
then it's doing something with the graphics chip at 0xc788a8 (which is also involved with the sound IRQ)
then it's reading from 0x800000 into D0
then ANDing D0 against 0x0080 to check the sound status flag.
What I've done in my patch is replace 0x0080 with 0x0001, and that's what has allow the game to boot.

Now there is one other odd-ball section that I'm not sure is used for coins or sound or both:
Code:
000DBA: 7E02                     moveq   #$2, D7
000DBC: 2039 0080 0000           move.l  $800000.l, D0
000DC2: 2239 0080 0004           move.l  $800004.l, D1
000DC8: B0B9 0080 0000           cmp.l   $800000.l, D0
000DCE: 66EA                     bne     $dba
000DD0: B2B9 0080 0004           cmp.l   $800004.l, D1
000DD6: 66E2                     bne     $dba
000DD8: 51CF FFEE                dbra    D7, $dc8
000DDC: 4680                     not.l   D0
000DDE: 13C0 0040 E005           move.b  D0, $40e005.l
000DE4: 4A39 0040 E25A           tst.b   $40e25a.l
000DEA: 6700 0026                beq     $e12
000DEE: 41F9 0001 ED9A           lea     $1ed9a.l, A0
now this appears to load 0x800000 into D0 then a line later compares 0x800000 to D0, I'm assuming this is to check if a change has been made
the inclusion of 0x800004 (which is dip-switches on Poitto) makes me think that this is coin related, but it's also possible that this chunk of code is checking for BOTH sound-status and coin inputs at the same time.
 
You asked for Assembly eyes, let me entertain you with a wild noob guess instead:

now on Poitto I'm pretty sure the coin inputs is only really read from this chunk of code:
0006CC: 48E7 8000 movem.l D0, -(A7) 0006D0: 2039 0080 0000 move.l $800000.l, D0 0006D6: 2039 0080 0000 move.l $800000.l, D0 0006DC: 2039 0080 0000 move.l $800000.l, D0 0006E2: 2039 0080 0000 move.l $800000.l, D0 0006E8: 4CDF 0001 movem.l (A7)+, D0 0006EC: 4E75 rtsI'm honestly not entirely sure how it's interpreting this as it looks to me like it's just moving the data to D0 then immediately overwriting it. I'm also not 100% confident it's NOT doing something with the sound status here.
in my patched code I've moved all of these addresses to 0x800004 to match the VG420 hardware
Maybe a heavy handed approach to solve a Race condition?
 
Maybe a heavy handed approach to solve a Race condition?
probably.
Still not sure what this particular code does as it seems to make no difference whether I point this to coin inputs or to the sound flag
 
Last edited:
Spent all day yesterday pouring over assembly trying different things and finally cracked how the sound flag is handled in code
The last piece of the puzzle is that the flag handling is inverted between MTR board and the VG boards.

I now have full sound on Poitto! and the game no longer locks up when certain sounds are triggered.
All that's left now is to finish patching the Player 2 controls and dip switches, which I have a path to, I just need to implement it.

In other news I got some of the logic components in for the heart of the multi that will handle all of the real conversion work.
Initial test compile of my logic it's apparently too complex to fit on the chip. BUT I can make it table driven so I'm going to try that . Once that's successful I should have all of the necessary confidence to send the prototype PCB design to fab.


EDIT:
....AAAAAND it's done. Poitto patched and fully working. only bit left now is the hardware :D
 
Last edited:
IMG_20250302_221729778.jpg


Updated my proto PCB to test out the actual planned circuit and components for the multi to great success!

I couldn't get the table based logic working but was able to get my original logic simplified enough to confirm functionality. Found a few minor tweak still needed to the multi PCB before I can send it off.
 
If you keep that speed up you will have finished your multi before i have found a donor 😵‍💫 (Yes this is a not so subtile hint to message if someone has a fitting donor for sale)
 
Back
Top