Click here to Skip to main content
13,900,747 members
Click here to Skip to main content
Add your own
alternative version

Stats

9.3K views
445 downloads
20 bookmarked
Posted 1 Feb 2019
Licenced CPOL

MAME.NET

, 6 Mar 2019
Rate this:
Please Sign up or sign in to vote.
C# arcade emulator, ROM hacking

MAME.NET user interface

Introduction

MAME (Multiple Arcade Machine Emulator) is a free and open source emulator designed to recreate the hardware of arcade game system in software on modern personal computers and other platforms. MAME.NET is a C# based arcade emulator, and it maintains the same architecture of MAME. By using C# and the powerful integrated development environment -- Microsoft Visual Studio, there is no macro and you can debug the supported arcade game anywhere. There are some classic boards supported by now: CPS-1, CPS-1(Qsound), CPS2, Neo Geo, Namco System 1, IGS011, PGM(PolyGame Master).

MAME.NET runs at following steps: load the ROMs, initialize the machine, soft reset the machine, and loop "cpuexec_timeslice" operation. The "cpuexec_timeslice" operation means sequentially execute every CPU for a time slice, and execute timer callbacks. Timer callbacks contains: video update, soft reset, CPU interrupt, sound update, watchdog reset and other interrupts. By these steps, MAME.NET emulates the arcade board successfully. MAME.NET has more functions: save and load state, record and replay input, cheat, cheat search, IPS (patch main ROM), board debugger, CPU debugger.

Load the ROMs

As an emulator, MAME.NET loads ROMs first.

There are 2 CPUs working in CPS-1, CPS-1(Qsound), CPS2, Neo Geo, PGM boards: a Motorola M68000 CPU and a Zilog Z80 CPU. There are 24-bits address and 16-bits data in M68000. There are 16-bits address and 8-bits data in Z80.

For CPS-1 board, the M68000 CPU runs at 10MHz (12MHz for some games). The program loads the file "maincpu.rom" as M68000 ROM. Size of "maincpu.rom" should be no greater than 0x400000 bytes. The file "gfx.rom" contains tile data to display on screen. The Z80 CPU runs at 3579545 Hz. The program loads the file "audiocpu.rom" as Z80 ROM. Size of "audiocpu.rom" should be no greater than 0x18000 bytes. There are two sound chips: Yamaha YM2151, Oki MSM6295. The program loads the file "oki.rom" as the Oki MSM6295 ROM.

For CPS-1(QSound) board, the M68000 CPU runs at 12MHz. The program loads the file "maincpu.rom" as M68000 ROM. Size of "maincpu.rom" should be no greater than 0x400000 bytes. The file "gfx.rom" contains tile data to display on screen. The Z80 CPU runs at 8MHz with Kabuki encrypted code. The program loads the file "audiocpu.rom" as Z80 ROM for ReadMemory only, the file "audiocpuop.rom" as the Z80 ROM for ReadOp only. Size of "audiocpu.rom" should not be greater than 0x50000 bytes. There is a Q-Sound chip. The program loads the file "qsound.rom" as the Q-Sound chip ROM.

For CPS2 board, the M68000 CPU runs at 11.8MHz. The original M68000 ROM is encrypted. The program loads the file "maincpu.rom" as M68000 ROM for memory code, the file "maincpuop.rom" as M68000 ROM for opcode. The file "gfx.rom" contains tile data to display on screen. The Z80 CPU runs at 8MHz. The program loads the file "audiocpu.rom" as Z80 ROM. Size of "audiocpu.rom" should not be greater than 0x50000 bytes. There is a Q-Sound chip. The program loads the file "qsound.rom" as the Q-Sound chip ROM.

For Neo Geo board, the M68000 CPU runs at 12MHz. The program loads the file "maincpu.rom" as M68000 ROM. The file "sprites.rom" contains tile data to display on screen. The file "fixed.rom" is a graphic related ROM. The Z80 CPU runs at 4MHz. The program loads the file "audiocpu.rom" as Z80 ROM. There are two sound chips: General Instrument AY8910, Yamaha YM2610. The program loads the file "ymsnd.rom" and the optional file "ymsnddeltat.rom" as the Yamaha YM2610 ROM.

For PGM board, the M68000 CPU runs at 20MHz. The program loads the file "maincpu.rom" as M68000 ROM. The files "sprcol.rom", "sprmask.rom", "tiles.rom" contain tile data to display on screen. The program dynamically writes the Z80 ROM. There is an ICS2115 sound chip.

There are four CPUs working in Namco System 1 board: three Motorola M6809 CPUs and one Hitachi HD63701 CPU. There are 16-bits address and 8-bits data in the four CPUs.

For Namco System 1, the four CPUs run at 1536000Hz. The Namco Custom 117 MMU provides a 23 bits virtual address for the first and second M6809 CPUs. The program loads the file "user1.rom" as the two CPU ROM. The files "gfx1.rom", "gfx2.rom", "gfx3.rom" contain tile data to display on screen. The program loads the file "audiocpu.rom" as the third M6809 CPU ROM. The program loads the file "voice.rom" as the HD63701 CPU ROM. There are three sound chips: Yamaha YM2151, Namco 8-voice stereo chip, DAC chip.

For IGS011 board, the M68000 CPU runs at 7333333Hz. The program loads the file "maincpu.rom" as M68000 ROM. The file "gfx1.rom" contains tile data to display on screen. There are two sound chips: Oki MSM6295 and Yamaha YM3812. The program loads the file "oki.rom" as the Oki MSM6295 ROM.

The ROM format of MAME.NET is the simplest. You can open and disassemble "maincpu.rom" and "audiocpu.rom" (only not opcode encrypted) with IDA Pro directly. There is no combination of multiple ROMs, no graphic effects decoding, no various decoding, and no byte swap. So the IPS file (.cht extension, the same as cheat file) is easy to understand. ROM hackers can focus on the real address-value pair and neglect ROM encoding and decoding. You can also disassemble CPU ROMs with the M68000 debugger and Z80 debugger functions in MAME.NET.

Common Usage

Build environment: I only test on Windows 7 Ultimate X64, Microsoft Visual Studio 2008.

Operating environment: Microsoft .NET Framework 3.5 or higher.

Hotkey: F3 -- soft reset, F7 – load state, Shift+F7 – save state, F8 – replay input, Shift+F8 – record input (start and stop), 0-9 and A-Z after state related hotkey – handle certain files, F10 – toggle global throttle, P – pause and continue, Shift+P - skip a frame.

Control Key

  • 1 -- P1 start
  • 2 -- P2 start
  • 5 -- P1 coin
  • 6 -- P2 coin
  • R -- Service 1
  • T -- Service
  • W -- P1 up
  • S -- P1 down
  • A -- P1 left
  • D -- P1 right
  • J -- P1 button1
  • K -- P1 button 2
  • L -- P1 button 3
  • U -- P1 button 4
  • I -- P1 button 5
  • O -- P1 button 6
  • Up -- P2 up
  • Down -- P2 down
  • Left -- P2 left
  • Right -- P2 right
  • NumPad1 -- P2 button 1
  • NumPad2 -- P2 button 2
  • NumPad3 -- P2 button 3
  • NumPad4 -- P2 button 4
  • NumPad5 -- P2 button 5
  • NumPad6 -- P2 button 6

When the ROMs of a game are loaded, the emulator is auto paused. You can apply IPS and dip-switch now and press P to continue. You can get the proper dip-switch value from running MAME.

Occasionally, GDI+ error occurs and a red cross is shown. You can click "File-Reset picturebox" to handle the error.

You can make the MAME.NET cheat file refer to cheat file of MAME or other emulators. You should make the ^1 operation to the cheat address for some emulators (for example: Winkawaks).

There are two files for record input. The .sta file records the initial state and the .inp file records the input key.

ROM Hacking

You can hack the ROMs effectively with the M68000 debugger and Z80 debugger functions of MAME.NET. For a beginner, M68000 ROM hacking contains the following steps: determine the key mainram address and value, debug M68000 CPU "backward" until get the certain mainrom address and value, patch the object mainrom. Now I show one example.

1. Samurai Shodown II, Select the Hidden Characters

Referring to "samsho2.xml" cheat file, I get the following code:

<cheat desc="Select Character PL1"> <comment>Free player selection.
 Activate between rounds or just after selection.</comment>
              <parameter>
                       <item value="00">Off</item>
                       <item value="01">Haohmaru</item>
                       <item value="02">Nakoruru</item>
                       <item value="03">Hanzo</item>
                       <item value="04">Galford</item>
                       <item value="05">Wan-Fu</item>
                       <item value="06">Ukyo</item>
                       <item value="07">Kyoshiro</item>
                       <item value="08">Gen-An</item>
                       <item value="09">Earthquake</item>
                       <item value="10">Jubei</item>
                       <item value="11">Charlotte</item>
                       <item value="12">Genjuro</item>
                       <item value="13">Cham Cham</item>
                       <item value="14">Sieger</item>
                       <item value="15">Nicotine</item>
                       <item value="16">Mizuki</item>
                       <item value="17">Kuroko</item>
              </parameter>
              <script state="run">
                       <action condition="(param==01)">main.pb@100D0B=00</action>
                       <action condition="(param==02)">main.pb@100D0B=01</action>
                       <action condition="(param==03)">main.pb@100D0B=02</action>
                       <action condition="(param==04)">main.pb@100D0B=03</action>
                       <action condition="(param==05)">main.pb@100D0B=04</action>
                       <action condition="(param==06)">main.pb@100D0B=05</action>
                       <action condition="(param==07)">main.pb@100D0B=06</action>
                       <action condition="(param==08)">main.pb@100D0B=07</action>
                       <action condition="(param==09)">main.pb@100D0B=08</action>
                       <action condition="(param==10)">main.pb@100D0B=09</action>
                       <action condition="(param==11)">main.pb@100D0B=0B</action>
                       <action condition="(param==12)">main.pb@100D0B=0C</action>
                       <action condition="(param==13)">main.pb@100D0B=0D</action>
                       <action condition="(param==14)">main.pb@100D0B=0E</action>
                       <action condition="(param==15)">main.pb@100D0B=0F</action>
                       <action condition="(param==16)">main.pb@100D0B=10</action>
                       <action condition="(param==17)">main.pb@100D0B=11</action>
              </script>
    </cheat>

I abbreviate Haohmaru as c00, Nakoruru as c01… The characters are arranged in selection scene as follows:

Selection scene
character id:
03 0e 06 00 0c 02 0b 04
 07 01 09 05 0d 08 0f

There are two hidden characters: c10 and c11. I'll hack the ROM to show them.

Replay "1" record input. Find when the M68000 code writes the mainram[0xD0B] to 0x06, and then debug backward until you find out the object mainrom position.

7864CAC 01474A: 1030 0000             move.b   (A0,D0.w), D0 D0=00100004->00100006 
                                                          A0=000142CC mainrom[0x142D0]=0x06
7864CBA 01474E: 0240 00FF             andi.w   $FF, D0
7864CC2 014752: 1540 000B             move.b   D0, ($B,A2) D0=00100006 A2=00100D00 mainram[0xD0B]=0x06

I examine the "maincpu.rom" file at the offset 0x142CC, and find the following code:

Maincpu ROM

The marked code is about character id. The base address of character id is 0x000142CC.

I will extend the selection scene to:

character id:
 03 0e 06 00 0c 02 0b 04
11 07 01 09 05 0d 08 0f 10

I find the following code read the address 0x000142CC.

6F75559 0141E4: 49F9 0001 42CC        lea      $142CC.l, A4
6F75565 0141EA: 7A00                  moveq    $0, D5
6F75569 0141EC: 7C0E                  moveq    $E, D6

Replace data in maincpu ROM from 0x000142CC to 0x000142CB. Replace $E to $10 because two characters will be added.

I debug backward from the PPC 01474A:

6F8679D 01471A: 720F                  moveq    $F, D1
6F867A1 01471C: 0240 000F             andi.w   $F, D0 D0=00105200->00100000
6F867A9 014720: 41F9 0001 478A        lea      $1478A.l, A0
6F867B5 014726: 1030 0000             move.b   (A0,D0.w), D0 D0=00100000 A0=0001478A
6F867C3 01472A: 1400                  move.b   D0, D2 D2=53540000
6F867C7 01472C: 4880                  ext.w    D0 
6F867CB 01472E: D051                  add.w    (A1), D0 D0=00100000->00100006 
                                                     A1=00100C00 mainram[0xC00]=0x0006
6F867D3 014730: 6B00 0004             bmi      $14736
6F867DF 014734: 4441                  neg.w    D1 D1=0000000F->0000FFF1
6F867E3 014736: 0C40 000E             cmpi.w   $E, D0 D0=00100006
6F867EB 01473A: 6300 0004             bls      $14740
6F867F5 014740: 3280                  move.w   D0, (A1) A1=00100C00 mainram[0xC00]=0006
6F867FD 014742: 41F9 0001 42CC        lea      $142CC.l, A0
6F86809 014748: 3011                  move.w   (A1), D0 D0=00100006
6F86811 01474A: 1030 0000             move.b   (A0,D0.w), D0 D0=00100006->00100000 
                                                          A0=000142CC mainrom[0x142D2]=0x00
6F8681F 01474E: 0240 00FF             andi.w   $FF, D0
6F86827 014752: 1540 000B             move.b   D0, ($B,A2) D0=00100000 A2=00100D00 mainram[0xD0B]=0x00

Replace data $F to $11, $E to $10 because two characters will be added.

So I get the following cheat code:

[17 select 1]
ON=1387D,CB;141E9,CB;141ED,10;142CB,11;142DB,10;1471B,11;14739,10;14747,CB

After applying the above cheat code, I get the following selection scene:

Selection scene

The function is right. The remaining thing is to add the head images for c10 and c11.

Using the neogeo debug function, I find the first character(c03) image head code:

063 0C80 B102 CB06 0FFF

Neogeo debugger
sprite_number=0x063, neogeo_videoram[0x8463]=0x0C80, neogeo_videoram[0x8263]=0xB102, 
neogeo_videoram[0x18C0]=0xCB06, neogeo_videoram[0x8063]=0x0FFF

By replaying "1" record input several times, I debug backward until I find out how the mainrom draws the head image of c03.

6F75C59 014206: 7000                  moveq    $0, D0 D0=0000FFFF->00000000
6F75C5D 014208: 101C                  move.b   (A4)+, D0 D0=00000000->00000003 
                                                      A4=000142CC mainrom[0x142CC]=0x03
6F75C65 01420A: E748                  lsl.w    3, D0 D0=00000003->00000018 A4=000142CD
6F75C71 01420C: 337C 0013 0064        move.w   $13, ($64,A1) D0=00000018 
                                                             A1=00105DE0 mainram[0x5E44]=0x0013
6F75C81 014212: 3373 0000 0066        move.w   (A3,D0.w), ($66,A1) D0=00000018 
                                      A1=00105DE0 A3=0001423C mainram[0x5E46]=mainrom[0x14254]=0x0070
6F75C97 014218: 3373 0002 004E        move.w   (A3,D0.w,$2), ($4E,A1) 
                                                mainram[0x5E2E]=mainrom[0x14256]=0x0029
6F75CAD 01421E: 3373 0004 0050        move.w   (A3,D0.w,$4), ($50,A1) 
                                                mainram[0x5E30]=mainrom[0x14258]=0x00AE
…
6F7D90B 00344E: 3D6E 004E 005C        move.w   ($4E,A6), ($5C,A6) A6=00105DE0 
                                                mainram[0x5E3C]=mainram[0x5E2E]=0x0029
6F7D91F 003454: 3D6E 0050 005E        move.w   ($50,A6), ($5E,A6) A6=00105DE0 
                                                mainram[0x5E3E]=mainram[0x5E30]=0x00AE

6F7D975 003470: 202E 0064             move.l   ($64,A6), D0 D0=mainram[0x5E44]=0x00130070 A6=00105DE0
…
6F7DA11 0036AC: 302E 0064             move.w   ($64,A6), D0 D0=00130070->00130013 
                                                A6=00105DE0 mainram[0x5E44]=0x0013
6F7DA1D 0036B0: D040                  add.w    D0, D0 D0=00130013->00130026
6F7DA21 0036B2: D040                  add.w    D0, D0 D0=00130026->0013004C
6F7DA25 0036B4: 43F9 0022 0280        lea      $220280.l, A1
6F7DA31 0036BA: 2271 0000             movea.l  (A1,D0.w), A1 D0=0013004C A1=mainrom[0x1202CC]=002AC948
6F7DA43 0036BE: 302E 0066             move.w   ($66,A6), D0 A6=00105DE0 mainram[0x5E46]=0x0070
6F7DA4F 0036C2: D040                  add.w    D0, D0 D0=00130070->001300E0
6F7DA53 0036C4: D040                  add.w    D0, D0 D0=001300E0->001301C0
6F7DA57 0036C6: 2D71 0000 006C        move.l   (A1,D0.w), ($6C,A6) D0=001301C0 
                                                A1=002AC948 A6=00105DE0 
                                                mainram[0x5E4C]=mainrom[0x1ACB08]=0x002AE40A
…
6F7DA85 0034A0: 206E 006C             movea.l  ($6C,A6), A0 A0=mainram[0x5E4C]=0x002AE40A A6=00105DE0
…
6F7DAAF 0034D6: 1C18                  move.b   (A0)+, D6 A0=002AE40A->002AE40B
…
6F7DAC5 0034DC: 1A18                  move.b   (A0)+, D5 A0=002AE40B->002AE40C
…
6F7DADD 0034E6: 3D58 0074             move.w   (A0)+, ($74,A6) A0=002AE40C->002AE40E
…
6F7DB27 0036CE: 5448                  addq.w   2, A0 A0=0002AE40E->002AE410
…
6F7DDA9 0035F6: 3030 3000             move.w   (A0,D3.w), D0 D0=00101040->00103958 
                                               D3=20200000 A0=002AE410 mainrom[0x1AE410]=0x3958
6F7DDB7 0035FA: 0280 0000 7FFF        andi.l   $7FFF, D0  D0=0010395A->0000395A
6F7DDC5 003600: 3740 0018             move.w   D0, ($18,A3) D0=00003958 A3=00101040 
                                                    mainram[0x1058]=0x3958
…
6F7DE5F 00362C: 376E 005C 0010        move.w   ($5C,A6), ($10,A3) A3=00101040 
                                                A6=00105DE0 mainram[0x1050]=mainram[0x5E3C]=0x0029
6F7DE73 003632: 376E 005E 0012        move.w   ($5E,A6), ($12,A3) A3=00101040 
                                                A6=00105DE0 mainram[0x105E]=mainram[0x5E3E]=0x00AE
…
6F8DB1F 003318: 382E 0018             move.w   ($18,A6), D4 D4=FFFF0003->FFFF3958 
                                                         A6=00101040 mainram[0x1058]=0x3958
6F8DB2B 00331C: 4EB9 0000 4120        jsr      $4120.l
6F8DB3F 004120: 0284 0000 FFFF        andi.l   $FFFF, D4 D4=FFFF3958->00003958
6F8DB4D 004126: D884                  add.l    D4, D4 D4=00003958->000072B0
6F8DB55 004128: D884                  add.l    D4, D4 D4=000072B0->0000E560
6F8DB5D 00412A: 43F9 0007 2000        lea      $72000.l, A1 A1=00072000
6F8DB69 004130: 2AB1 4800             move.l   (A1,D4.l), (A5) D4=0000E560 
                                      A5=00108000 mainram[0x8000]=mainrom[0x80560]=0x410BB296
6F8DB83 004134: 3015                  move.w   (A5), D0 D0=00100000->0010410B 
                                                mainram[0x8000]=0x410BB296
6F8DB8B 004136: 0255 0007             andi.w   $7, (A5) D0=0010410B 
                                      A5=00108000 mainram[0x8000]=0x410BB296->0003B296
6F8DB9B 00413A: 2255                  movea.l  (A5), A1 A1=mainram[0x8000]=0x0003B296 A5=00108000
6F8DBA7 00413C: 4295                  clr.l    (A5) mainram[0x8000]=0x00000000
6F8DBBB 00413E: D3C9                  adda.l   A1, A1 A1=0003B296->0007652C
6F8DBC3 004140: D3FC 0008 2004        adda.l   $82004, A1 A1=0007652C->000F8530
…
6F8DD6F 003D82: D259                  add.w    (A1)+, D1 D1=00000000->0000ED10 
                                                A1=000F8530->000F8532 mainrom[0xF8530]=0xED10
6F8DD77 003D84: B541                  eor.w    D2, D1 D1=0000ED10 D2=00400000
6F8DD7B 003D86: C26D 8B7E             and.w    ($8B7E,A5), D1 D1=0000ED10 
                                                A5=00108000 mainram[B7E]=0xFFFF
6F8DD87 003D8A: 3419                  move.w   (A1)+, D2 D2=00400000->0040CB06 
                                                A1=000F8532 mainrom[0xF8532]=0xCB06
6F8DD8F 003D8C: 1A3B 50E4             move.b   (PC,D5.w,-$1C), D5 D5=00000001->00000070 
                                                mainrom[0x3D73]=0x70
6F8DD9D 003D90: 3943 FFFE             move.w   D3, ($FFFE,A4) D3=000018C0
6F8DDA9 003D94: 4EFB 5002             jmp      (PC,D5.w,$2)
6F8DDB7 003E08: 3942 0000             move.w   D2, ($0,A4) D2=0040CB06 neogeo_videoram[0x18C0]=0xCB06 
                                                    code_2=Neogeo.neogeo_videoram[sprite_number<<6]
…
6F8DEDB 003394: 302E 0012             move.w   ($12,A6), D0 D0=00000000->000000AE 
                                                         A6=00101040 mainram[0x1052]=0x00AE
6F8DEE7 003398: 9041                  sub.w    D1, D0 D0=000000AE->0000009E D1=00000010
6F8DEEB 00339A: 4440                  neg.w    D0 D0=0000009E->0000FF62
6F8DEEF 00339C: EF48                  lsl.w    7, D0 D0=0000FF62->0000B100
6F8DF03 00339E: 806E 0008             or.w     ($8,A6), D0 D0=0000B100->0000B102 
                                                        A6=00101040 mainram[0x1048]=0x0002
6F8DF0F 0033A2: 36C0                  move.w   D0, (A3)+ D0=0000B102 A3=001007C4 mainram[0x7C4]=0xB102
…
6F8DF99 0033E8: 302E 0010             move.w   ($10,A6), D0 A6=00101040 D0=mainram[0x1050]=0x0029
6F8DFA5 0033EC: 9041                  sub.w    D1, D0 D0=00000029->00000019 D1=00000010
6F8DFA9 0033EE: EF48                  lsl.w    7, D0 D0=00000019->00000C80
6F8DFBD 0033F0: 3880                  move.w   D0, (A4) D0=00000C80 A4=003C0002 neogeo_videoram
                                      [0x8463]=0x0C80 x_2=Neogeo.neogeo_videoram[0x8400|sprite_number]
…
6F9D0C5 0031FE: 3898                  move.w   (A0)+, (A4) A0=001007C4 A4=003C0002 
                                      neogeo_videoram[0x8263]=mainram[0x7C4]=0xB102 
                                      y_control=Neogeo.neogeo_videoram[0x8200|sprite_number]

I find out that the following marked code determines the coordinate and sprite code of c00-c11 head image:

Maincpu ROM

The original coordinates of the 15 characters:

x coordinate:
29 4B 6D 8F B1 D3 F5 117
 39 5B 7D 9F C1 E3 105
y coordinate:
AE AA A7 A5 A5 A7 AA AE
 D0 CC C9 C8 C9 CC D0

I'll extend the coordinates to 17 characters:

x coordinate:
 29 4B 6D 8F B1 D3 F5 117
17 39 5B 7D 9F C1 E3 105 127
y coordinate:
 AE AA A7 A5 A5 A7 AA AE
D5 D0 CC C9 C8 C9 CC D0 D5

So I get the following cheat code:

[17 select 2]
ON=1387D,CB;141E9,CB;141ED,10;142BE,01;142BF,27;142C1,D5;142C7,17;142C9,
D5;142CB,11;142DB,10;1471B,11;14739,10;14747,CB

After applying the above cheat code, I get the following selection scene:

Selection scene

By Neogeo debugging, I find the following sprite_gfx offset of the 17 characters:

character id mainrom sprite code sprite_gfx offset
07 6F 1CB0200
03 70 1CB0600
00 71 1CB0A00
05 72 1CB0E00
0B 73 1CB1200
08 74 1CB1600
01 75 1CB1A00
04 76 1CB1E00
09 77 1CB2200
02 78 1CB2600
06 79 1CB2A00
0C 7A 1CB2E00
0E 7B 1CB3200
0F 7C 1CB3600
0D 7D 1CB3A00
11 7E 1CDC600
10 ? 1F5A700

Now I'll calculate the mainrom sprite code of c10 from the known sprite_gfx offset.

The known calculation of c03:

0x03*8=0x18
0x1423C+0x18=0x14254
mainrom[0x14254]=0x0070
0x70*4=0x1C0
0x2AC948+0x1C0=0x2ACB08
mainrom[0x1ACB08]=0x002AE40A
0x1AE40A+0x06=0x1AE410
mainrom[0x1AE410]=0x3958
0x3958*4=0xE560
0x72000+0xE560=0x80560
mainrom[0x80560]=0x410BB296
0x410BB296&0x7FFFF=0x3B296
0x3B296*2=0x7652C
0x7652C+0x82004=0xF8530
0xF8530+2=0xF8532
mainrom[0xF8532]=0xCB06
CB06->1CB0600

The calculation of c10:

1F5A700->F5A7
The reasonable mainrom address is 0xA62B6.
mainrom[0xA62B6]=0xF5A7
0xA62B6-2=0xA62B4
0xA62B4-0x82004=0x242B0
0x242B0/2=0x12158
0x12158+(0x410BB296-0x3B296)=0x41092158
The mainrom address is 0x77198.
mainrom[0x77198]=0x41092158
0x77198-0x72000=0x5198
0x5198/4=0x1466
The reasonable mainrom address is 0x1B21D8
mainrom[0x1B21D8]=0x1466
0x1B21D8-6=0x1B21D2
The mainrom address is 0x1AD530.
mainrom[0x1AD530]=0x002B21D2
0x2AD530-0x2AC948=0xBE8
0xBE8/4=0x2FA
0x10*8=0x80
0x1423C+0x80=0x142BC

I'll change the mainrom[0x142BC] to 0x02FA. So I get the following cheat code:

[17 select]
ON=1387D,CB;141E9,CB;141ED,10;142BC,02;142BD,FA;142BE,01;142BF,27;142C1,
D5;142C7,17;142C9,D5;142CB,11;142DB,10;1471B,11;14739,10;14747,CB

The hack ROM is done as the title image.

Conclusion

I've finished MAME.NET. It figures out how the arcade games work. You can make any other game supported by referring to MAME source code. By the translation from C to C#, there is little unsafe code and the code is much more readable. I've preserved the main architecture of MAME. Programmers can refer to the MAME.NET source code and emulate more arcade game systems by C#.

History

  • 2019-02-01: Finish MAME.NET, support 792 games (build 20190201)

References

  1. MAME-Multiple Arcade Machine Emulator - https://github.com/mamedev
  2. MSDN - https://msdn.microsoft.com
  3. BizHawk M68000 and Z80 code - https://github.com/TASVideos/BizHawk/tree/master/BizHawk.Emulation.Cores/CPUs
  4. VCMAME detail by Bryan McPhail - https://www.codeproject.com/Articles/4923/VCMAME-Multiple-Arcade-Machine-Emulator-for-Visual
  5. MAME and MAMEUI Visual C Project Files - http://www.mikesarcade.com/arcade/vcmame.html
  6. CPS1.NET - https://www.codeproject.com/Articles/998595/CPS1-NET-A-Csharp-Based-CPS1-MAME-Emulator

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

No Biography provided

You may also be interested in...

Comments and Discussions

 
Praise好棒 Pin
Member 1135874920-Mar-19 23:27
memberMember 1135874920-Mar-19 23:27 
PraiseIt looks great! Pin
WJW-Davy12-Mar-19 21:17
memberWJW-Davy12-Mar-19 21:17 
QuestionMany thanks Pin
Cesar to Dnn7-Mar-19 2:01
professionalCesar to Dnn7-Mar-19 2:01 
QuestionMissing ROMS Pin
Geca4-Feb-19 21:08
memberGeca4-Feb-19 21:08 
AnswerRe: Missing ROMS Pin
shunninghuang5-Feb-19 1:05
membershunninghuang5-Feb-19 1:05 
GeneralRe: Missing ROMS Pin
Geca5-Feb-19 1:36
memberGeca5-Feb-19 1:36 
GeneralRe: Missing ROMS Pin
shunninghuang5-Feb-19 18:36
membershunninghuang5-Feb-19 18:36 
GeneralRe: Missing ROMS Pin
Geca5-Feb-19 21:40
memberGeca5-Feb-19 21:40 
QuestionThanks Pin
Geca3-Feb-19 21:17
memberGeca3-Feb-19 21:17 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web01 | 2.8.190306.1 | Last Updated 7 Mar 2019
Article Copyright 2019 by shunninghuang
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid