{"id":1076,"date":"2016-10-29T22:56:18","date_gmt":"2016-10-29T21:56:18","guid":{"rendered":"http:\/\/blog.blockos.org\/?p=1076"},"modified":"2016-11-01T14:57:37","modified_gmt":"2016-11-01T13:57:37","slug":"final-match-sewashinasa-bijin","status":"publish","type":"post","link":"https:\/\/blog.blockos.org\/?p=1076","title":{"rendered":"Final Match Sewashinasa Bijin"},"content":{"rendered":"<p>Some times ago, some fellas from the <a href=\"http:\/\/forum.necstasy.net\">Necstasy forum<\/a> discussed the fact that parts of <strong>Human Sports Festival<\/strong> can be extracted into standalone games. <strong>Human Sports Festival<\/strong> (or <b>HSF<\/b> for the connoisseurs) is a sports compilation made of a <strong>Fine Shot Golf<\/strong>, <strong>Formation Soccer Human Cup 92<\/strong> and last but not least <strong>Final Match Tennis Ladies<\/strong>.<br \/>\n<img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0000.png\" alt=\"human-sports-festival-j-0000\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-1057\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0000.png 256w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0000-166x150.png 166w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0000-150x136.png 150w\" sizes=\"(max-width: 256px) 100vw, 256px\" \/><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0003.png\" alt=\"human-sports-festival-j-0003\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-1060\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0003.png 256w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0003-166x150.png 166w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0003-150x136.png 150w\" sizes=\"(max-width: 256px) 100vw, 256px\" \/><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0005.png\" alt=\"human-sports-festival-j-0005\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-1062\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0005.png 256w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0005-166x150.png 166w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0005-150x136.png 150w\" sizes=\"(max-width: 256px) 100vw, 256px\" \/><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0006.png\" alt=\"human-sports-festival-j-0006\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-1063\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0006.png 256w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0006-166x150.png 166w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/Human-Sports-Festival-J-0006-150x136.png 150w\" sizes=\"(max-width: 256px) 100vw, 256px\" \/><\/p>\n<p>The first thing to do is to find the sectors where the game is stored and more importantly, is there any CD-ROM access during the game?<br \/>\nInstead of mindlessly put a breakpoint on the cd_read routine (<b>$e009<\/b>), a less painful and efficient alternative is to use the mednafen logger. Press <b>alt<\/b>+<b>d<\/b> then <b>alt<\/b>+<b>4<\/b> to view it. Don&#8217;t forget to press <b>T<\/b> to enable logging. The next screenshot shows what you get when you launch <b>Final Match Tennis Ladies<\/b><br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl00.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl00-150x150.png\" alt=\"fmtl00\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-1069\" \/><\/a><br \/>\nHopefully nothing more shows up during the game. This means that the last read command loads the whole game. Let&#8217;s take a look at it.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">Read: start=0x000011c8(track=2, offs=0x000003c2), cnt=0x00000080<\/pre>\n<p>Remember that the offset and count refers to sectors. A sector being 2048 bytes long, we will open the 2nd track with our favorite hexadecimal editor (here <a href=\"http:\/\/home.gna.org\/bless\/\" target=\"_blank\">bless<\/a>), jump to the offset <b>0x1e1000<\/b> (that is 0x3c2 * 2048) and dump the following <b>262144<\/b> bytes (0x80 * 2048). <\/p>\n<p>But it&#8217;s not over yet! We must take a look at what is done after the game is loaded in <b>HSF<\/b> just in case we have to add the IRQ and other stuffs to make it work. Let&#8217;s check it!<br \/>\nFirst, we put a breakpoint on the <b>cd_read<\/b> (<b>$e009<\/b>) and painstakingly walk along it until we reach the <b>rts<\/b> instruction and jump back to the calling code.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl01.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl01-150x150.png\" alt=\"fmtl01\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-1070\" \/><\/a><br \/>\nWe land back at <b>$2309<\/b>.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl02.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl02-150x150.png\" alt=\"fmtl02\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-1068\" \/><\/a><br \/>\nThe whole routine in text form:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n22ef: sta $fc\r\n22f1: lda #$03\r\n22f3: sta $fd\r\n22f5: lda #$c2\r\n22f7: sta $fe\r\n22f9: lda #$06\r\n22fb: sta $ff\r\n22fd: lda $22d0\t\t; = 68\r\n2300: sta $fa\r\n2302: lda #$80\r\n2304: sta $f8\r\n\r\n2306: jsr $e009\r\n\r\n2309: and #$ff\r\n230b: bne $22ed\r\n\r\n230d: sei\r\n230e: lda #$ff\r\n2310: sta $1402\r\n2313: stz $0C01\r\n2316: jsr $e081\r\n2319: jsr $e087\r\n\r\n231c: cli\r\n231d: lda $22d0\r\n2320: tam #$80\r\n2322: jmp $e000\r\n<\/pre>\n<p>From <b>$22ef<\/b> to <b>$2304<\/b> the parameters to <b>cd_read<\/b> is set. At <b>$2306<\/b> <b>cd_read<\/b> is called. What follows is very interesting. If no error occurred during the cd read, first the interrupts are disabled by calling <b>sei<\/b> and setting all the bits of <b>$1402<\/b> to <b>1<\/b>. The timer is disabled by setting <b>$0C01<\/b> to <b>0<\/b>. Then <b>$e081<\/b> (<b>ex_rcroff<\/b>) and <b>$e087<\/b> (<b>ex_irqoff<\/b>) routines are called. Those 2 routines respectively disables system card <b>hsync<\/b> and <b>IRQ<\/b> handlers.<br \/>\nAfter that, the <b>CD-ROM<\/b> <b>RAM<\/b> bank where the game is stored is mapped to <b>mpr #7<\/b>. Then we dive into the unknown by jumping to <b>$e000<\/b>.<br \/>\nThere&#8217;s something important to note here. As the whole game data is stored in RAM and mapped to the <b>mpr #7<\/b>, <b>IRQ<\/b> vectors will be the one stored in <b>RAM<\/b> and not the ones from the system card. That&#8217;s a pretty good news. We are not forced to butcher the ROM to force feed <b>IRQ<\/b> vectors into it.<br \/>\nAs free cakes are always dubious, we will see what <b>$e000<\/b> is made of.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl03.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl03-150x150.png\" alt=\"fmtl03\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-1071\" \/><\/a><br \/>\nA simple jump to <b>$e072<\/b>. Fantastic!<br \/>\nThis routine looks like a standard <b>RESET<\/b> interrupt handler.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl04.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl04-150x150.png\" alt=\"fmtl04\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-1072\" \/><\/a><\/p>\n<p>Let&#8217;s test the extracted <b>ROM<\/b>&#8230; Blimey! The screens is jogging. The controls are sloppy. And the game freezes after player selection.<\/p>\n<p>Oh mighty quick-tempered bearded fanciful overlord, why have you forsaken me?<\/p>\n<p>Let&#8217;s look back at the <b>mednafen<\/b> debugger.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl05.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl05-150x150.png\" alt=\"fmtl05\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-1106\" \/><\/a><br \/>\nWe see that <b>SPD<\/b> (the <b>CPU<\/b> speed mode) is set to <b>0<\/b>. The <b>PC Engine<\/b> <b>CPU<\/b> is in <b>SLOW<\/b> mode.<br \/>\nIf we look at Final Match Tennis for cross-reference, we see that the CPU is in <b>HI-SPEED<\/b> mode.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl06.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2016\/10\/fmtl06-150x150.png\" alt=\"fmtl06\" width=\"150\" height=\"150\" class=\"alignnone size-thumbnail wp-image-1107\" \/><\/a><\/p>\n<p>We will have to find a place where we can safely put the necessary instruction to switch the <b>CPU<\/b> to the required mode. <b>$e074<\/b> is a relatively promising spot. <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\ne074: cla\r\ne075: sta $22d1\r\n<\/pre>\n<p>The <b>cla\/sta<\/b> combo can be rewritten with a single <b>stz<\/b>, leaving us with an extra byte where to put the <b>csh<\/b> instruction that will set our <b>CPU<\/b> at the correct speed.<\/p>\n<p>Another issue was reported by one of the good old chap from the necstasy forum. During a set, a soft reset (<b>SEL<\/b>+<b>RUN<\/b>) will crash the game. To keep things short and entertaining, instead of jumping to the <b>RESET<\/b> <b>IRQ<\/b> vector, it jumps to <b>$22d6<\/b> in <b>RAM<\/b>. That bugger is at <b>$e027<\/b>.<\/p>\n<p>And voil\u00e0, you should be able to enjoy <b>Final Match Tennis Ladies<\/b> on a <b>HuCard<\/b>.<br \/>\nThe following IPS patch will fix the aforementioned issues on the extracted <b>ROM<\/b>.<\/p>\n<ul>\n<li><a href=\"http:\/\/blockos.org\/releases\/pcengine\/mods\/fmtl\/Final%20Match%20Tennis%20Ladies.pce.ips\" target=\"_blank\">Final Match Tennis Ladies.pce.ips<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Some times ago, some fellas from the Necstasy forum discussed the fact that parts of Human Sports Festival can be extracted into standalone games. Human Sports Festival (or HSF for the connoisseurs) is a sports compilation made of a Fine Shot Golf, Formation Soccer Human Cup 92 and last but\u2026 <a class=\"continue-reading-link\" href=\"https:\/\/blog.blockos.org\/?p=1076\">Continue reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,6],"tags":[27,30],"_links":{"self":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/1076"}],"collection":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1076"}],"version-history":[{"count":47,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/1076\/revisions"}],"predecessor-version":[{"id":1126,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/1076\/revisions\/1126"}],"wp:attachment":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1076"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1076"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1076"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}