<?xml version="1.0" encoding="utf-8"?>
        <?xml-stylesheet type="text/css" href="http://daifukkat.su/blog/styles/feed.css"?>
<rss version="2.0"
 xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:admin="http://webns.net/mvcb/"
 xmlns:atom="http://www.w3.org/2005/Atom"
>
<channel>
<title>Daifukkat.su</title>
<atom:link href="http://daifukkat.su/blog/rss.xml" rel="self" type="application/rss+xml" />
<link>http://daifukkat.su/blog</link>
<description>They've gone too far...?</description>
<dc:language>en-us</dc:language>
<dc:creator>trap15</dc:creator>
<dc:date>2023-06-22T04:31:29+00:00</dc:date>
<admin:generatorAgent rdf:resource="http://nanoblogger.sourceforge.net" />

<item>
<link>http://daifukkat.su/blog/archives/2019/12/25/presents_for_nmk/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2019/12/25/presents_for_nmk/</guid>
<title>Presents for NMK</title>
<dc:date>2019-12-25T00:00:33+00:00</dc:date>
<dc:creator>trap15</dc:creator>
<dc:subject> arcade, reverse_engineering</dc:subject>
<description><![CDATA[<p>Been a long ol' time since I updated this. I've released a formalized version of my <a href="http://daifukkat.su/hacks/gunnail_alarm/">Gunnail alarm hack</a>; it's no different from the version I laid out in <a href="https://shmups.system11.org/viewtopic.php?f=1&t=65376">a post on shmupsforum</a>, but should be simpler to apply. But that's not all.</p>
<p>I'm also releasing a hack of P-47 Aces, which fixes the sound engine to play sound effects on time. You can get that here: <a href="http://daifukkat.su/hacks/p47aces_sfx/">http://daifukkat.su/hacks/p47aces_sfx/</a>. The original behavior is pretty deficient in my opinion, and the fix ended up rather interesting and helping emulation, so I'm glad I went and did it. Though it was amusing to see the end stage screens with constant explosions, I'm hoping having properly timed sound effects will make the game even more enjoyable.</p>
<p>I'm hoping to start posting on this blog again more, some fun stuff coming ahead. For now, happy end of year festivities, whatever they may be. To a pleasant 2020~</p>
<p>Update 2019/12/28: I fixed the P-47 Aces fix, so now it works everywhere.</p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2016/01/24/thus_endth_the_story/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2016/01/24/thus_endth_the_story/</guid>
<title>Thus Endth The Story</title>
<dc:date>2016-01-24T23:07:34+00:00</dc:date>
<dc:creator>trap15</dc:creator>

<description><![CDATA[<div class="flimage float_r">
<a href="http://daifukkat.su/blog/images/karatour.jpg"><img src="http://daifukkat.su/blog/images/karatour_pv.jpg"/></a>
</div>
<p>Completely out of left field, this one. I was at a friend's place the other day, and he had Mitchell Corporation's <i>The Karate Tournament</i> running. I'd never played the game but thought it looked interesting so I gave it a few rounds and thought it was pretty damn interesting.</p>
<p>Then I was told that the dumped version doesn't have English voice acting and has much slower "cutscenes". Of course, this means it's time to break out the ROM reader.</p>
<p>Another friend dumped the ROMs and I added it to MAME, and now it's coming your way. The driver that emulates this isn't in the best shape, so I intend to go fix it up at some point, but for now it seems to work fine, I noticed no significant problems.</p>
<p>Credits to The Dumping Union and Anonymous for this one. Get it while it's hot: <a href="http://daifukkat.su/files/karatour.zip">http://daifukkat.su/files/karatour.zip</a>, and a compiled MAME that can play it: <a href="http://daifukkat.su/files/karatemame.7z">http://daifukkat.su/files/karatemame.7z</a></p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2015/08/19/restructuring/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2015/08/19/restructuring/</guid>
<title>Restructuring</title>
<dc:date>2015-08-19T03:44:08+00:00</dc:date>
<dc:creator>trap15</dc:creator>

<description><![CDATA[<p>As you maybe noticed, I've removed dodonpachi.daifukkat.su. It was something I'd been thinking about doing for a while, finally bothered to follow through with it. Please excuse the mess as I re-link everything for the new placement, but all old links should still work and redirect to the new URLs.</p>
<p><strong>EDIT:</strong> All done now!</p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2015/07/11/wonderswan_hardware_tests/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2015/07/11/wonderswan_hardware_tests/</guid>
<title>WonderSwan Hardware Tests</title>
<dc:date>2015-07-11T09:00:08+00:00</dc:date>
<dc:creator>trap15</dc:creator>
<dc:subject> emulation, reverse_engineering, wonderswan</dc:subject>
<description><![CDATA[<p>A few weeks ago I was working on my WonderSwan game project, Fire Lancer, and was trying to optimize further for speed to try to remove the lingering slowdown. I noticed I was very often copying large chunks of memory around, and figured that'd be an easy win if I could optimize it. Unfortunately, the V30MZ CPU lacks many opportunities to optimize memory copy. Luckily, the WonderSwan Color has a DMA engine which I felt could be put to great use in this case. While this sounded great, I was also skeptical that it could work on hardware, as I'm using on-cart SRAM for all of my RAM, only using the IRAM for tasks it's required for (sprite list, tiles, BG tilemap, palette), and I wasn't entirely sure if the DMA engine could access SRAM. For the time being, I implemented the DMA as Mednafen supported DMA from and to anywhere, intending to later test on hardware if I could indeed perform such a DMA.</p>
<p>A few nights ago I decided to start testing that, but as usual my scope exploded and woops now I'm checking instruction cycle timings and DMA intricacies. I wrote a test harness and log parsing tool that I can now use to test the timings of anything and easily get data and specifics off of a real WonderSwan. Naturally, I used my WonderWitch for this task, as it provides a very easy way for me to write code and get it running on a real console, and has a <i>very</i> small iteration overhead, allowing me to test many versions very quickly.</p>
<p>I'd like to explain my method of getting precise cycle timings, but I'm afraid I need to give a bit of back story first. Over the past few weeks at work I've been implementing a libc for our platform to get rid of the pile of garbage known as newlib. In the process of this, I had to implement <code>rand()</code>, which I decided to temporarily implement as a simple LFSR. With LFSRs on the brain, and being very mindful that any seed produces the same series of outputs that never have duplicates until the entire period has been exhausted, I devised a plan for getting precise timings from the WonderSwan.</p>
<p>Now, the WonderSwan has a noise mode for one sound channel on its sound chip. It's implemented as a 15-bit LFSR with 2 taps, one configurable and one fixed. The default tap configuration has a period of 32767 cycles, which is maximal length for a 15-bit LFSR. There are two properties of this LFSR that make it particularly interesting: the update speed is controlled by the channel's frequency register, and the current value of the LFSR can be read by the CPU. The first property is even more interesting when one considers the range of frequencies allowed by the register. The output frequency is <code>f = MCLK / (2048 - reg)</code>, where the register can range from 0 to 2047. This means we can have the LFSR update at a rate of <i>one update per master clock</i>.</p>
<p>The more adept of you may already see where I'm going with this. Essentially what I can do is start the LFSR at maximum frequency, save the LFSR value, perform some operation, then save the LFSR value after that. From these saved LFSR values, I can convert them back to a cycle index using the property of LFSRs that causes all outputs to be unique. Now that I have a cycle index for before and after the operation, I can subtract the latter index from the former, and get a <i>100% accurate time delta with complete precision</i> between the two sample points. With a small test, I can also check the cycle overhead of sampling the LFSR, and discard that overhead from real test results. This gives me perfect timings of any operation I wish to perform.</p>
<p>From here, I can simply schedule a series of DMA transfers of varying lengths and retrieve the timings of each, then correlate the data to get a final algorithm. From my tests, a DMA transfer takes <code>5 + 2n</code> cycles, with <code>n</code> being the number of words to transfer. I discovered a few other things in the process, but those will be put up into a new version of WSMan soon enough.</p>
<p>I've open-sourced my hardware testing infrastructure and tools on my bitbucket at <a href="https://bitbucket.org/trap15/wswan_hwtest">https://bitbucket.org/trap15/wswan_hwtest</a>.</p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2015/03/30/its_turbo_time/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2015/03/30/its_turbo_time/</guid>
<title>It's Turbo Time</title>
<dc:date>2015-03-30T00:21:06+00:00</dc:date>
<dc:creator>trap15</dc:creator>
<dc:subject> arcade, reverse_engineering</dc:subject>
<description><![CDATA[<p>A few things to say today. I've released two new hacks in the past few days, and did a fairly quick commission hack that was released recently as well.</p>
<strong>Metal Slug 2 Turbo</strong><hr/>
<p>I made a hack for <b>system11</b> that makes <i>Metal Slug 2</i> not a laggy piece of garbage. In the end, the old rumor that it was caused by "updating the game logic twice per video update" was incorrect. The real issue was <i>much</i> more dumb, and much more puzzling. The way they wrote their code to lock to 30 FPS is something like this:<br/>
<pre>void vblank_callback(void)
{
  if(vblank_counter != 0xFF)
    vblank_counter++;
  if(vblank_counter != 2)
    return;
  vblank_occurred = 0xFF;
  // do things...
}
void game_update(void)
{
  // do things...
  for(;;) {
    if(vblank_occurred & 0x80) {
      vblank_occurred &= ~0x80;
      break;
    }
    vblank_occurred &= ~0x80;
  }
  vblank_counter = 0;
  // do things...
}</pre></p>
<p>At first, this code seems reasonable, and not particularly odd or troublesome. But now think of the problem case: what happens if the game update misses the 'every odd frame' update window? Now the game is waiting <i>two entire frames</i> to get back on sync. Because of this, instead of a drop from 30 FPS to 20 FPS, it is now effectively a drop to <i>15 FPS</i>. If it drops to 15 FPS, it's not affected, but if it would drop to 10 FPS, it drops to <i>7.5 FPS</i>. This is very very significant, and is what makes the game run at a snail's pace. Most of the time the game is not even dropping to 15, it's only displaying as such because of the poor frame limiter code. Yes, this is <i>actually</i> why it runs so poorly.</p>
<p>Now that I've discussed the problem, let's discuss how I fixed it.  Essentially, I replaced their code with the code listed below. This new code is faster to execute, simpler to understand, and works better than the original. This is what I implemented in my hacked version:<br/>
<pre>void vblank_callback(void)
{
  vblank_counter = 2; // this needs to be done for other functions to update properly
  vblank_occurred++;
  // do things...
}
void game_update(void)
{
  // do things...
  while(vblank_occurred < 2); // wait for 2 frames to have elapsed
  vblank_occurred = 0;
  // do things...
}</pre></p>
<p>You may look at <b>system11</b>'s post on the release at <a href="http://blog.system11.org/?p=1442">http://blog.system11.org/?p=1442</a>, including a very enlightening comparison video and instructions on how to replace the ROM on a physical cartridge.</p>
<strong>Same!Same!Same! NEW VER!</strong><hr/>
<p>I've made a more subtle hack this time around, opting to merely fix problems in the original game, rather than turn it into something entirely different. With <i>NEW VER!</i>, I have added built-in 30Hz autofire that doesn't break the flamethrower, rebalanced the powerup order, changed how long items last on screen, and rebalanced difficulty, in a way that I think makes the game both more fun, and more recoverable. That said, it's still an <i>extremely</i> difficult game, and that was one thing I actively tried to keep with these changes. In the end, I think this makes the game much more fair, and much more playable and approachable.</p>
<p>You can get it here: <a href="http://dodonpachi.daifukkat.su/hacks/samenew/">http://dodonpachi.daifukkat.su/hacks/samenew/</a>.</p>
<strong>Ketsui Arrange 1.7</strong><hr/>
<p>I've released one last version of Ketsui Arrange, which removes the suicide bullets added in 1.5, and tweaks various parameters and colorations. This is the definitive version of Ketsui Arrange, and it will be the last.</p>
<p>I don't have much else to say about this, you can get it here: <a href="http://dodonpachi.daifukkat.su/hacks/ketarr/">http://dodonpachi.daifukkat.su/hacks/ketarr/</a>.</p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2014/11/09/wonderwitch_dumped/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2014/11/09/wonderwitch_dumped/</guid>
<title>WonderWitch Dumped</title>
<dc:date>2014-11-09T03:27:38+00:00</dc:date>
<dc:creator>trap15</dc:creator>
<dc:subject> emulation, reverse_engineering, wonderswan</dc:subject>
<description><![CDATA[<p>A few weeks ago I picked up WonderSwan hacking again, and thought it might be a good idea to preserve the WonderWitch software and get it emulated. So I used a cart dumper I wrote a while ago to dump my WonderWitch's ROM, and sent it to <a href="http://mednafen.sourceforge.net/">Ryphecha</a>, developer of Mednafen. After a few days of tinkering, she managed to get it working and was able to communicate to the emulated WonderWitch. Great success! Now I also wanted the released dumps of this to be completely clean, without any of the software I had on there and without my dumper. So she spent a bit of time figuring out how to do that, and thus we have it. In addition, she graciously reflashed the firmware, to be completely sure that it was clean, and also flashed a second version of the firmware, so we now have two dumped versions! I know there are more around, but for now we have <i>FreyaOS 1.2.0</i> and <i>FreyaOS 1.1.5</i>. This is a release post, so here are the necessary ROM images. They will not work on any current version of any WonderSwan emulator, but I believe it will be in a Mednafen release at some point. Most importantly, the software is now preserved.</p>
<ul>
<li><a href="http://daifukkat.su/blog/files/WonderWitch%20%5bFreyaOS%201.2.0%5d.ws">WonderWitch [FreyaOS 1.2.0].ws</a></li>
<li><a href="http://daifukkat.su/blog/files/WonderWitch%20%5bFreyaOS%201.1.5%5d.ws">WonderWitch [FreyaOS 1.1.5].ws</a></li>
</ul>
<p>Once again, massive thanks to Ryphecha for putting in a lot of work to clean these dumps up for release!</p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2014/09/13/nmk004_rom_dumping_part_5_the_release/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2014/09/13/nmk004_rom_dumping_part_5_the_release/</guid>
<title>NMK004 ROM Dumping, Part 5: The Release</title>
<dc:date>2014-09-13T07:04:11+00:00</dc:date>
<dc:creator>trap15</dc:creator>
<dc:subject> arcade, nmk004, mame, emulation, reverse_engineering</dc:subject>
<description><![CDATA[<p>This post is the final part of a series. I highly recommend reading the previous articles, or this one may not make much sense: <a href="http://daifukkat.su/blog/archives/2014/09/05/nmk004_rom_dumping_progress/">Part&nbsp;1</a> <a href="http://daifukkat.su/blog/archives/2014/09/07/nmk004_rom_dumping_part_2/">Part&nbsp;2</a> <a href="http://daifukkat.su/blog/archives/2014/09/09/nmk004_rom_dumping_part_3_the_previous/">Part&nbsp;3</a> <a href="http://daifukkat.su/blog/archives/2014/09/12/nmk004_rom_dumping_part_4_the_newer/">Part&nbsp;4</a>.</p>
<div class="flimage float_l">
<img src="http://daifukkat.su/blog/images/nmk004/nmk_love.jpg"/><br/>
</div>
<p>The time has finally come for <b>the release</b>. This will be my final post on the NMK004 dump. As of this post, the patches have been added to MAME, and will definitely be included in the next stable release.</p>
<p>Let's start out with what everybody has been waiting for, the NMK004 internal ROM dump. You may obtain the dump here: <a href="http://daifukkat.su/files/nmk004.zip">http://daifukkat.su/files/nmk004.zip</a>.</p>
<p>Next, I'm also releasing my dumping tools. This is split into two repositories, both hosted on bitbucket. <i>OPNCAP</i> is located at <a href="https://bitbucket.org/trap15/opncap">https://bitbucket.org/trap15/opncap</a>, and <i>nmk004-trojan</i> is located at <a href="https://bitbucket.org/trap15/nmk004-trojan">https://bitbucket.org/trap15/nmk004-trojan</a>.</p>
<p>Lastly, I have a special secret extra bonus, but you'll have to put up with story time for a bit. A few months ago, I bought a <i>Hacha Mecha Fighter</i> PCB off of eBay. I knew it looked somewhat strange, being mostly EPROMs instead of mask ROMs, and lacking the NMK-110 protection MCU that's usually on the PCB. When I got it, I realized almost instantly that it had to have been a bootleg conversion from <i>Thunder Dragon</i>. After playing and comparing to PCB recordings of a genuine board, I knew that what I had was gold: an unprotected version of <i>Hacha Mecha Fighter</i>. I never bothered to dump it until I started on this project, but I felt now was the right time. So I dumped the program ROMs and sent them off to Haze to have them added to MAME. As expected, it works perfectly in MAME, and now it's possible for anyone to play it properly. In the future, I'd like to actually figure out the protection on <i>Thunder Dragon</i> and <i>Hacha Mecha Fighter</i>, but having unprotected versions works just as well.</p>
<p>You can get this ROM set from <a href="http://daifukkat.su/files/hachamfb.zip">http://daifukkat.su/files/hachamfb.zip</a>.</p>
<div class="flimage float_r">
<img src="http://daifukkat.su/blog/images/nmk004/hacha.png"/><br/>
Title screen of Hacha Mecha Fighter
</div>
<p>The following MAMETesters bugs may now be closed:<ul>
<li><a href="http://mametesters.org/view.php?id=1117">http://mametesters.org/view.php?id=1117</a></li>
<li><a href="http://mametesters.org/view.php?id=3395">http://mametesters.org/view.php?id=3395</a></li>
<li><a href="http://mametesters.org/view.php?id=2422">http://mametesters.org/view.php?id=2422</a></li>
<li><a href="http://mametesters.org/view.php?id=2417">http://mametesters.org/view.php?id=2417</a></li>
</ul></p>
<p>Last but not least, I'd like to give some shout outs to those who made this all possible:<ul>
<li><a href="http://mamedev.emulab.it/haze/">David "Haze" Haywood</a></li>
<li><a href="http://cgfm2.emuviews.com/">Charles MacDonald</a></li>
<li>Jonathan "Lord Nightmare" Gevaryahu</li>
<li><a href="http://mamelife.blogspot.com/">Nicola Salmoria</a></li>
<li>austere</li>
<li>#raidenii</li>
<li>Beer and coffee</li>
</ul></p>
<p>As a cute little aside, I've uploaded the work log I kept while doing this. Maybe somebody will find it interesting. There's a lot of content, lots of information on my thought process, a few diagrams and tables, stuff like that. Pretty unfiltered though, so don't be offended by anything I have written. <a href="http://daifukkat.su/files/NMK004-WORK-NOTES.txt">http://daifukkat.su/files/NMK004-WORK-NOTES.txt</a></p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2014/09/12/nmk004_rom_dumping_part_4_the_newer/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2014/09/12/nmk004_rom_dumping_part_4_the_newer/</guid>
<title>NMK004 ROM Dumping, Part 4: The Newer</title>
<dc:date>2014-09-12T22:47:52+00:00</dc:date>
<dc:creator>trap15</dc:creator>
<dc:subject> arcade, nmk004, mame, emulation, reverse_engineering</dc:subject>
<description><![CDATA[<p>This is post is part of a series. I highly recommend reading the previous articles, or this one may not make much sense: <a href="http://daifukkat.su/blog/archives/2014/09/05/nmk004_rom_dumping_progress/">Part&nbsp;1</a> <a href="http://daifukkat.su/blog/archives/2014/09/07/nmk004_rom_dumping_part_2/">Part&nbsp;2</a> <a href="http://daifukkat.su/blog/archives/2014/09/09/nmk004_rom_dumping_part_3_the_previous/">Part&nbsp;3</a>.</p>
<p>Hold on to your hats, this post is gonna be a long one.</p>
<strong>Planning the process</strong><hr/>
<div class="flimage float_r">
<img src="http://daifukkat.su/blog/images/nmk004/gunnail.png"/><br/>
Title screen of GunNail
</div>
<p>As mentioned in part 1, I revisited the NMK004 dumping project late last month, and made good quick progress. The first thing I did was attach my Saleae Logic logic analyzer to the OPN on my <i>Thunder Dragon</i> board. I started a song and used the logic analyzer to look at a few of the signals. Unfortunately, my model only has 8 probes, so I wasn't able to get a full picture of the interfacing activity. I managed to figure out how to detect a write to the chip, but the lack of probes meant I wouldn't be able to fully grasp the exact activity. Compounded with how many "dummy" writes were constantly being done, I knew I had to move onto writing FPGA code next.</p>
<p>After installing Quartus II, I had to spend a bit of time remembering VHDL's syntax, since I hadn't used it for a while. I spent about an hour writing the initial logging code and making it compile. I'm not as good with VHDL programming as other conventional languages, so I ended up having some broken logic that took me about an hour and a half to fix. Once it worked, I added a filter to make the FPGA only record PSG writes. It turns out that all upkeep pokes that the NMK004 does are exclusively on the FM registers; the PSG registers are only poked when their values need to be changed. This saved a <i>lot</i> of space on my FPGA's relatively small 512KB SRAM. Saving space allows for more bytes to be dumped at once, making the dumping process much faster.</p>
<p>From here, I started probing the possible attack vectors. I knew that the most likely targets would be the note frequency tables and the volume envelope tables for the PSG. I wrote some small testing ROMs to do a quick check, and was dismayed when I found that the volume envelope table could only directly dump 4 bits at a time, and the note frequency table could only directly dump 12 bits. While contemplating what to do, I realized that I could extract an extra 8 bits out of the volume envelope table by simply looking at the timing between writing the new volume. This still essentially only gives me an 8-bit dump per channel that skips every other byte, but it also gives me an additional 4 bits of verification. This particularly came in handy when I realized that the length value ends up being <i>exactly the same</i> for a $00 byte and a $01 byte. Using the 4 bits from the volume value lets me determine exactly which value it is. In addition, since we're just recording values being written to the sound chip, I can now multiplex the three PSG channels to get triple dump speed. Armed with this knowledge, I knew that this was going to be my attack vector, and exactly what I was going to do to make it work.</p>
<strong>Writing the tools</strong><hr/>
<div class="flimage float_l">
<img src="http://daifukkat.su/blog/images/nmk004/strahl.png"/><br/>
Title screen of Koutetsu Yousai Strahl
</div>
<p>After carefully planning out my attack, I started writing the tools that I would need to make the dump process smooth and easy. With a few hours of work, I had code that would analyze the captured register activity and turn it into a log of activity over time. I also wrote a fair bit of code that would allow querying for when a register changes, finding the next register activity, and such similar things. It ended up being a nicely full featured suite for capture analysis. I still needed some more data from the NMK004 before I could make the tool actually reconstruct the capture into ROM data though. I needed to get the real-time length for the values in the volume envelope table. To accomplish this, I made a bogus ROM that had the length values $00,$01,$02,$04,$08,$10,$20,$40,$80,$FF. I figured this would give me a very good idea of how long each value takes, and it ended up being very spot on. It takes approximately <i>30250 × value</i> capture ticks for each length value, where $00 is the same as $01. One thing that stood out during this test was that the first tone would last slightly shorter than the rest. 2500 ticks shorter, to be specific. This was an easy fix, but it could have <i>definitely</i> tripped me up if I didn't notice it.</p>
<p>As part of my attack strategy, I utilized an interesting concept in the conversion tool that I call a <i>prioritized usage map</i>. For each incoming nibble -- 2 nibbles for length, 1 nibble for volume register value -- I would store the channel it was captured from, and where that nibble came from. In the case of a volume register value, I gave it the highest priority, 3. For a length nibble, I would give it the lowest priority, 1. If the length byte was determined to be $01, I would use the high nibble and give it medium priority, and ignore the bottom nibble. If a priority value in the usage map is 0, it would mean that the corresponding nibble has not yet been defined for the dump. Because of this system, if two overlapping nibbles were ever different, the tool could print out a warning, and use the value of the higher priority nibble. With this system in place, I felt very confident that the dump would be accurate, or at the very least be extremely obvious when a dump error occurred.</p>
<p>With the data analysis part done, I needed to make the program actually save the results. I decided on making the conversion tool "stackable", in that it takes a <i>working state</i> binary, loads it, performs its task, then saves it back. This way, multiple capture files can combine to create a final ROM image. While I was working on adding this feature, I noticed an interesting behavior in the volume envelope table handling on the NMK004. I originally thought that each table would last forever, but it turns out that it will actually <i>wrap</i> every $100 bytes. I didn't think that this would matter much, as I decided to play it safe and only dump a spread of $C0 bytes per channel per song, but I'd later find that I was dead wrong. It only affected two of the later songs, which I of course hadn't done testing with, so I ignored the behavior.</p>
<p>Considering 3 channels and that each set needs to be run through twice, each song is able to dump approximately $120 full bytes. I performed a test on the first song, and received an all too familiar message: "<b>All Music,Effect Software(C)1990 N M K Corporation</b>". After seeing that message, I decided it was finally time for bed, and put off further work for later.</p>
<strong>Documentation and the dump</strong><hr/>
<div class="flimage float_r">
<img src="http://daifukkat.su/blog/images/nmk004/macross.png"/><br/>
Title screen of Choujikuu Yousai Macross
</div>
<p>After having spent so long on that one day, I took a break for about a week. When I came back, I decided I should start documenting all of my processes and software that I'd developed, as I knew I wanted to release them all along with the ROM itself. I also split up the project into two separate but related projects: <i>OPNCAP</i> and <i>nmk004-trojan</i>. <i>OPNCAP</i> consists of: <i>opncap-fpga</i>, the FPGA code for capturing OPN register activity; <i>reccat</i>, a PC tool to combine capture files; and <i>opncap-pc</i>, a PC library used to parse and use the data in a capture file. <i>nmk004-trojan</i> does what it says on the tin, and consists of: <i>trogen</i>, a tool to generate trojan ROMs; and <i>opnrom</i>, a tool that uses the <i>opncap-pc</i> library to convert a capture file to a ROM image. Once I'd finished splitting stuff out, I continued to spend a good amount of time doing documentation. Writing the documentation was fairly painless and easy, since all the procedures were still pretty ingrained from my marathon work. Doing most of the documentation in one go ended up being a great idea, as it let me work on the project in a different way that I wasn't burned out on, and let me recover from that burn out in a productive manner.</p>
<p>Eventually I felt satisfied with the state of the documentation, and thus decided that I should finally do the dump. I generated a set of ROMs and burned them to 27C512 EPROMs that I had lying around. On my first few tries, I spotted several bugs in <i>opnrom</i> that I had to fix before continuing. Thankfully, I knew I wouldn't have to redump from my PCB because of how simple and fool-proof the actual capturing is. It took me about an hour to fix the <i>opnrom</i> bugs, but once that was done I had absolutely no problems. After cleaning everything up, I proceeded to dump more of the ROM.</p>
<p>Unfortunately, not everything was well. There were two song IDs that caused massive havoc with my capture setup. On the 13th song, the song filled up the SRAM extremely quickly, and I lost all my capture progress from that dumping set. I realized that the cause of this peculiarity was that the section is mostly filled with very low values, causing the dump to write lots of data very quickly. Because each song is a fixed length and the previously mentioned looping behavior of the volume envelope table, it would loop the dump continuously. This combined behavior led to the SRAM filling and then overflowing within a few minutes. My solution to this problem was a bit inelegant, but worked well. When the SRAM was nearly full, I would flip a switch that would pause capturing activity. Then I would copy off the contents, wait for the mischievous track to end, then begin the next song. In this way, I managed to recover the data from the two troublesome tracks and not require any strange hacks in the actual project code.</p>
<p>Once everything was captured, I knew there was only one step left for the dump to be complete: conversion of all capture files into a single ROM image. I ran <i>opnrom</i> over all of the capture files, to produce the final nmk004.bin. The conversion program gave only a single nibble warning, which I have verified to be a non-issue. I was ecstatic. The dump was finally done, I finally had the binary.</p>
<strong>Integration with MAME</strong><hr/>
<div class="flimage float_l">
<img src="http://daifukkat.su/blog/images/nmk004/acrobat.png"/><br/>
Title screen of Acrobat Mission
</div>
<p>Once I had the dump complete, I asked the fantastic <a href="http://mamedev.emulab.it/haze/">David "Haze" Haywood</a> for assistance in hooking up the ROM to MAME. Within a day, he had it hooked up and mostly working, though there were some parts that were hacked to work because they weren't understood. I helped out a bit, fixing the 16-bit timer behavior in the TMP90C840 core, and fixing NMI behavior. I had also noticed that the channel balance was very wrong for the newly emulated games, so I spent a while comparing the output from MAME to various PCB recordings, and eventually found values that sound very close. This change actually fixes sound for more than just the NMK004 games, it fixes almost every game in the nmk16.c driver.</p>
<p>There was also a mysterious issue where the emulated NMK004 would reset itself after a set amount of time, and kill all the sound. After tracing pins around my PCB, I deduced that it was attempting to reset the entire system when that happened, and provided Haze with the information necessary to hook that up. According to Haze, the suicide would be prevented if the NMK004 got an NMI within a set amount of time from the last NMI, so I then traced the NMI pin from the NMK004. It led to another ASIC on the board (NMK005), which is the GPIO controller. Eventually, it was deduced that the main CPU pokes the GPIO controller to give the NMK004 an NMI when it needs it. It seems like this setup was done to turn the NMK004 into a watchdog of sorts. Once all that had been hooked up, everything seemed to work very well.</p>
<p>Except for two specific games: <i>Black Heart</i>, by NMK; and <i>Uchuu Senkan Gomorrah</i>, by UPL. These two games would not work with this setup, and I was mystified for a while. Figuring that there must have been some interrupt that was needed that just wasn't firing, I looked at the IRQ implementations for <i>Black Heart</i>. Seeing that IRQ2 was <i>exclusively</i> dedicated to kicking the sound NMI, I realized that was probably the greater issue. Thanks to the wonderful <a href="http://upl-gravedigger.boo.jp/pcb_info/">NMK PCB manual located at upl-gravedigger</a>, we were able to massively clean up and improve the accuracy of the IRQ behavior in the NMK driver. This change, much like the sound balance one, affects nearly all games in the nmk16.c driver, so look for that! Sadly, this fixed behavior still didn't fix <i>Gomorrah</i>. In the end, we settled for a game-specific hack that inverts the level of the NMI signal. The reason <i>Gomorrah</i> still wouldn't work is strange, it <i>does</i> kick the sound NMI occasionally, but it often kicks it just slightly too late, and gets reset before the kick happens. We believe this issue may be caused by inaccuracies in the TLCS-90 CPU emulation speed, but it's such a bizarre and difficult issue that we both felt that it wasn't worth trying to fix it at this point in time.</p>
<p>The last change we made is something that might be a bit controversial. Haze mentioned that MAME, as it currently stands, has sprite "wobble" -- indicative of missing sprite buffering -- and asked me if I knew if the sprites were buffered. According to the previously mentioned manual, sprite RAM is indeed DMA'd on each frame, adding 1 frame of sprite delay. However, as part of some investigation I've been doing the past year or so, I also knew that the sprite hardware was framebuffer-based, and double-buffered. This adds a second frame of sprite delay. Therefore, NMK PCBs have <i>2 frames</i> of sprite delay. We have added this to the MAME driver to preserve accuracy.</p>
<strong>Finishing up</strong><hr/>
<p>The next and final post in the series will be coming very soon. The next post will include the NMK004 ROM, the release of all of my dumping tools, as well as a secret extra bonus that I think will make many people excited. I am also going to give Haze the go-ahead to submit the MAME changes once the next post is up, so everyone will be able to experience the joy that is NMK.</p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2014/09/09/nmk004_rom_dumping_part_3_the_previous/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2014/09/09/nmk004_rom_dumping_part_3_the_previous/</guid>
<title>NMK004 ROM Dumping, Part 3: The Previous</title>
<dc:date>2014-09-09T22:52:23+00:00</dc:date>
<dc:creator>trap15</dc:creator>
<dc:subject> arcade, nmk004, mame, emulation, reverse_engineering</dc:subject>
<description><![CDATA[<div class="flimage float_r">
<img src="http://daifukkat.su/blog/images/nmk004/tdragon.png"/><br/>
Title screen of Thunder Dragon
</div>
<p>This is post is a sequel to a previous post. I highly recommend reading it before this article, or this one may not make much sense: <a href="http://daifukkat.su/blog/archives/2014/09/07/nmk004_rom_dumping_part_2/">http://daifukkat.su/blog/archives/2014/09/07/nmk004_rom_dumping_part_2/</a></p>
<p>In the time since the last post I have finished dumping, reconstructing, and verifying the <i>NMK004</i> internal ROM. With the help of <a href="http://mamedev.emulab.it/haze/">David "Haze" Haywood</a>, it has been hooked up to MAME. As a result, all of the previously listed games now have perfectly working sound. With the sprite priority fixes I submitted a while ago, I think this pushes the emulation quality of almost all games on NMK's hardware up to "acceptably accurate" at the very least. Expect to see these changes come to MAME within a week or two.</p>
<p>In August 2013, I had submitted fixes to the sprite priority emulation on NMK hardware. Later in the month, I decided to probe the Emuversal shoutbox for opinions on my work. While on the subject, I also mentioned the NMK sound's poor state, and that I hoped it would be fixed soon. Haze replied, and told me that the <i>NMK004</i> internal ROM was probably only extractable with a decap. There was also a mention that someone speculated that it would be possible to extract the internal ROM by playing it out as sound data, but that the setup would be complex and that nobody had tried to do it yet.</p>
<p>After a bit, I asked for and was given some <i>TLCS-90</i> datasheets (the same CPU used in the <i>NMK004</i>) as it was assumed that's what it was. Unfortunately, the <i>NMK004</i> ended up not being the same MCU model as were in any of those datasheets, but I eventually found the correct one much later. The actual model seems to be a TMP90C840, datasheet available at: <a href="http://raidenii.net/files/datasheets/cpu/tmp90c840.pdf">http://raidenii.net/files/datasheets/cpu/tmp90c840.pdf</a></p>
<div class="flimage float_l">
<img src="http://daifukkat.su/blog/images/nmk004/vandyke.png"/><br/>
Title screen of Vandyke
</div>
<p>The next day, I spent some more time probing things and poking people on the Emuversal shoutbox, trying to get a feel for the possibilities for dumping. I concluded that I should try to play out the internal ROM with one of the tables, record the outputs, then analyze the sound files to recover the internal ROM. Within a few hours I had cooked up a sample ROM that attempted to play things out from the internal ROM. I did a short test in MAME just to verify that it would make sound, and it did. From there I made a <i>reference ROM</i> that I could use to compare the various values. By this time I had decided on using PSG note length as my dumping table, due to its long spread and easy reconstruction method.</p>
<p>I had tried to ask people to make a reconstruction tool for me, but this never materialized. I figured it'd be trivial enough, so I wrote my own (extremely ghetto) tool that could analyze the resulting WAV files from recordings. My recording setup involved using an RCA->3.5mm adapter to connect the sound output of my supergun to my PC's microphone port. From there I would open Audacity and let that record until it stopped. When it would stop, I would save the output as a WAV file, perform the conversion, then compress the WAV file down to a good quality OGG and throw away the WAV file. Writing the tool for analysis took a good couple hours, though the tool ended up being pretty solid and worked very well.</p>
<p>After the tool was written, I started dumping the first 256-byte block of the internal ROM. This block was one of the quicker ones to dump, and took five and a half hours for just the first 256 bytes. The next day, I decoded the dump, and got my first validation that everything I was doing was correct and working: "<b>All Music,Effect Software(C)1990 N M K Corporation</b>". You wouldn't believe how excited I was when I saw this message, one that is likely to have never been seen by a single person in <i>literally 20 years</i>, in the converted dump. Unfortunately, the rest of the dump was far from as exciting. Waiting 8 hours for each 256 bytes to dump is absolutely not the best way to keep motivation high, especially when the ROM to dump is 16384 bytes long. Each block takes so long to dump because of the way I'm doing the dumping. Since I was using note lengths, a small 16-bit value would dump extremely quickly, and a high one would dump extremely slowly. For reference, a $FFFF value takes about 7 minutes to dump. Multiply that by 128, and a 256-byte block of $FFFF takes 15 hours to dump. Luckily nothing was that absurd in the blocks that I had dumped.</p>
<p>Eventually I gave in to the length. Sadly, looking back on it, I noticed I was very close to the end of actual data. My last set was $1200-$12FF, and the actual contents of the ROM end at approximately $1400. Everything from $1400 to $1FFF is just an $FF fill, which would have taken ages to dump if I had bothered to do so. It's been about a year since that last excursion, and I'm very glad that I went back and finally got it done. The previous attempt was a serious headache, and I knew that if I made the procedure less of a total headache, I could get it done.</p>
<p>I realize this hasn't been that technical of a write-up, but the lack of notes makes it not too easy for me to write about the technical side and what didn't work. What it essentially came down to, technically, was setting the <i>Shared note length table</i>'s pointer to point into the area to dump, then having a bogus song that would play out a note of each length. I seem to recall I also used a padding note between each actual dump note, to help segment them up and make the conversion tool simpler, but I couldn't say for sure anymore.</p>
<p>The next post will be around in a few days, detailing the final attempt all the way down to the nitty gritty. I'm still undecided how I want to release the ROM, but I think I'll figure it out before publishing the next post.</p>]]></description>

</item>
<item>
<link>http://daifukkat.su/blog/archives/2014/09/09/comments_are_go/</link>
<guid isPermaLink="true">http://daifukkat.su/blog/archives/2014/09/09/comments_are_go/</guid>
<title>Comments are go</title>
<dc:date>2014-09-09T18:20:42+00:00</dc:date>
<dc:creator>trap15</dc:creator>

<description><![CDATA[<p>Real quick post. I've added comments to nanoblogger, thanks to <a href="http://miek.nl/posts/2009/Jan/26/nanoblogger-comments-update/">Miek Gieben</a>. All comments are moderated, and require a name and email. Hopefully this will work out well. NMK004 stuff is very close to ready, I should have a blog post or two on that coming shortly.</p>]]></description>

</item>
</channel>
</rss>
