{"id":811,"date":"2013-03-24T17:17:37","date_gmt":"2013-03-24T16:17:37","guid":{"rendered":"http:\/\/blog.blockos.org\/?p=811"},"modified":"2014-09-21T17:07:11","modified_gmt":"2014-09-21T16:07:11","slug":"roger-quartermain-and-the-lost-script-of-the-heisei-era","status":"publish","type":"post","link":"https:\/\/blog.blockos.org\/?p=811","title":{"rendered":"Roger Quartermain and the lost script of the Heisei era."},"content":{"rendered":"<p>Roger is happy. He bought a cheap PC-Engine CDRom game called &#8220;Nishimura Kyotaro Mystery.: Hokutosei No Onna&#8221;. It seems to be a detective game like <a href=\"http:\/\/en.wikipedia.org\/wiki\/J.B._Harold_Murder_Club\">J.B. Harold Murder Club<\/a>, <a hreaf=\"http:\/\/en.wikipedia.org\/wiki\/Jake_Hunter\">Jake Hunter<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Ace_Attorney\">Ace Attorney<\/a>, <a href=\"http:\/\/en.wikipedia.org\/wiki\/Mortville_Manor\">Le Manoir de Mortevielle<\/a> or <a href=\"http:\/\/en.wikipedia.org\/wiki\/Maupiti_Island_%28game%29\">Maupiti Island<\/a>. It was published by Naxat (now <a href=\"http:\/\/www.kaga-create.co.jp\/\">Kaga Create<\/a>) in 1990.<br \/>\nHe remembers that some games have a language option. For example, the japanese version of J.B Harold Murder Club <a href=\"https:\/\/iwasateenagepcenginefan.wordpress.com\/2011\/02\/16\/so-uh-how-do-i-play-j-b-harold-murder-club-in-english\/#comments\">can be played in english<\/a>. Unfortunately such option was nowhere to be found in Hokutosei No Onna&#8230; Nevermind! Roger Quartermain grabs his boots, his hat and jumps into the game dark bowels!<br \/>\nThe introduction seems to be about some dude stabbed in his room, 2 girls going to a train station and another guy who is apparently stalking them.<\/p>\n<div style=\"text-align:center;\">\n<img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-0000.png\" alt=\"Nishimura-0000\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-821\" \/><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-0013.png\" alt=\"Nishimura-0013\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-838\" \/><br \/>\n<img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-0004.png\" alt=\"Nishimura-0004\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-822\" \/><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-0005.png\" alt=\"Nishimura-0005\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-823\" \/><br \/>\n<img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-0006.png\" alt=\"Nishimura-0006\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-824\" \/><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-0007.png\" alt=\"Nishimura-0007\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-825\" \/>\n<\/div>\n<p>As it&#8217;s a CDRom game, it must use the BIOS function for displaying text. Roger took his <a href=\"http:\/\/debuglife.free.fr\/docs\/Hu7CD_final.7z\">old notes<\/a> and search for any text related routine. Here it is! <strong>ex_fnt<\/strong> located at <strong>$e060<\/strong>. He draw <a href=\"http:\/\/mednafen.sourceforge.net\/\">his favorite emulator<\/a> and set a breakpoint to it.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger00.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger00-300x241.png\" alt=\"debugger00\" width=\"300\" height=\"241\" class=\"aligncenter size-medium wp-image-845\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger00-300x241.png 300w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger00-372x300.png 372w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger00.png 864w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a>It fires just after the introduction when what seems to be the savegame selection screen appears.<\/p>\n<div style=\"text-align:center;\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-00081.png\" alt=\"Nishimura-0008\" width=\"256\" height=\"232\" class=\"alignnone size-full wp-image-850\" \/><a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger01.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger01-300x241.png\" alt=\"debugger01\" width=\"300\" height=\"241\" class=\"alignnone size-medium wp-image-846\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger01-300x241.png 300w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger01-372x300.png 372w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger01.png 864w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/div>\n<p>Roger is not really interested in the <strong>ex_fnt<\/strong> routine but more in the calling environment. So he sent breakpoints to the potential <strong>rts<\/strong>. A gentle pression to the <strong>R<\/strong> key sends him to <strong>$f1e2<\/strong>. Another push to the <strong>S<\/strong> key brings him the the caller.<\/p>\n<div style=\"text-align:center;\"><a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger02.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger02-300x241.png\" alt=\"debugger02\" width=\"300\" height=\"241\" class=\"aligncenter size-medium wp-image-858\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger02-300x241.png 300w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger02-372x300.png 372w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger02.png 864w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/div>\n<p> Here it is at <strong>$566b<\/strong>.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger03.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger03-300x241.png\" alt=\"debugger03\" width=\"300\" height=\"241\" class=\"aligncenter size-medium wp-image-859\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger03-300x241.png 300w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger03-372x300.png 372w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger03.png 864w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nAccording to the notes, the shift-jis is loaded from <strong>$41<\/strong>, <strong>$42<\/strong> to <strong>$f8<\/strong> and <strong>$f9<\/strong>. The logical next step is to put a write breakpoint to <strong>$41<\/strong> and <strong>$42<\/strong>.<br \/>\n<a href=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger04.png\"><img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger04-300x241.png\" alt=\"debugger04\" width=\"300\" height=\"241\" class=\"aligncenter size-medium wp-image-869\" srcset=\"https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger04-300x241.png 300w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger04-372x300.png 372w, https:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/debugger04.png 864w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><br \/>\nThe write breakpoint is triggered at <strong>$5b20<\/strong>. The code is pretty simple.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">5b1c: ldy #$00\r\n      lda ($3c), Y\r\n5b20: sta $41\r\n      iny\r\n      lda ($3c), Y\r\n      iny\r\n      sta $42<\/pre>\n<p>The next step is to search where the <strong>$3c<\/strong> pointer. Once again Roger has to set a new write breakpoint at <strong>$3c<\/strong> and <strong>$3d<\/strong>.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">5a18: lda #$90\r\n      bra $5a22\r\n      lda #$40\r\n      bra $5a22\r\n      lda #$80\r\n5a22: sta $c0\r\n5a24: sty $3d\r\n      cpy #$00\r\n      beq $5a2f\r\n      stx $3c\r\n      smb5 $c0\r\n      rts<\/pre>\n<p>Unfortunately the caller is not that obvious to discover. But the good news is that the text is not compressed. By keeping track of the values stored at <strong>$41<\/strong> and <strong>$42<\/strong>, Roger manages to extract the string <\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">40 81 40 81 40 81 C7 82 CC 82 54 8B E4 88 59 8C 96 8E C5 82 6E 8E DF 82 DC 82 B7 82 A9 82 48 81 0D 00 FF 00<\/pre>\n<p> The endiannes must be swapped. He hopefully has some handsome perl script at hand <a href=\"http:\/\/cires.colorado.edu\/~braup\/software\/swap_endian\">swap_endian.pl<\/a>. The last 4 characters looks like some control code. His long time experience enables him to deduce that <strong>00 0D<\/strong> is some kind of <strong>newline<\/strong> code and <strong>00 FF<\/strong> may be for <strong>end of text<\/strong>. Here&#8217;s the string.<br \/>\n<center><code>\u3000\u3000\u3000\u3069\u306e\u4e80\u4e95\u5211\u4e8b\u3067\u59cb\u3081\u307e\u3059\u304b\uff1f<\/code><\/center><br \/>\nBut this doesn&#8217;t tell Roger where the <strong>$3c<\/strong> pointer is set. Roger knows that on CDRom systems, the data is first transfered to RAM before being executed. This means that the code can be self-modifiable. Unluckily this is the case here. Roger has to set a breakpoint where the jump is done and run it until he finally reaches the pointer initialization code. Time passes and he ends up at <strong>$724d<\/strong> <\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">724d: ldx #$fc\r\n      ldy #$74\r\n      jmp $5a18<\/pre>\n<p>He restarts the game with only the write breakpoint at <strong>$41<\/strong> and <strong>$42<\/strong>. As expected he ends up at the same code as before for the first sentence. The next run lands at a different location <strong>acb4<\/strong>.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">acae: lda $4f\r\n      asl A\r\n      tay\r\n      lda ($50), Y\r\nacb4: sta $41\r\n      iny\r\n      lda ($50), Y\r\n      beq $acd8\r\n      sta $42\r\n      lda $2922\r\n      sta $3f\r\n      lda $2923\r\n      sta $40\r\n      lda #$01\r\n      jsr $5655<\/pre>\n<p> The pointer <strong>$50<\/strong> is initialized at <strong>ac92<\/strong>.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">ac8a: tay\r\n      lda $312a, Y\r\n      asl\r\nac8e: tay\r\nac90: lda ($9f), Y\r\n      sta $50\r\n      iny\r\n      lda ($9f), Y\r\n      sta $51<\/pre>\n<p> So the pointer is set up from a table. He gets the values\t<\/p>\n<ul>\n<li>b1b6<\/li>\n<li>bdb6<\/li>\n<li>cdb6<\/li>\n<li>d9b6<\/li>\n<li>e7b6<\/li>\n<\/ul>\n<p> Hopefully the indices for this pointers are 2,3,4,5,6. Roger searchs in the iso for <strong>b1 b6 bd b6 cb b6 d9 b6 e7 b6<\/strong>. He ends up at the offset <strong>$11f49<\/strong>. The place is filled with what looks like pointers. Some bytes after the string he recognises byte swapped shit-jis values. It starts at <strong>$11f53<\/strong>. So The pointer soup must contain some value equals to <strong>$53Xf<\/strong>. He scrolls up and finds <strong>$53af<\/strong> at <strong>$11d45<\/strong>. Tadam, he has his first table and string bloc. As all the pointers are in increasing order, Roger deduces that the option strings are stored from <strong>$11f53<\/strong> to <strong>$126f4<\/strong>. But just after this, he notices some other shift-jis symbols. It goes from <strong>$126f5<\/strong> to <strong>$132f5<\/strong>.<br \/>\nOnce the options are display, he jumps to another screen where some grumpy old cop is talking to you.<br \/>\n<img decoding=\"async\" loading=\"lazy\" src=\"http:\/\/blog.blockos.org\/wp-content\/uploads\/2013\/03\/Nishimura-0009.png\" alt=\"Nishimura-0009\" width=\"256\" height=\"232\" class=\"aligncenter size-full wp-image-827\" \/><br \/>\nOnce again, he set his breakpoints to <strong>$41<\/strong> and <strong>$42<\/strong>. But then he remembers <strong>$5a18<\/strong>. It starts with<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">5a18: lda #$90\r\n      bra $5a22\r\n5a1c: lda #$40\r\n      bra $5a22\r\n5a20: lda #$80\r\n5a22: sta $c0<\/pre>\n<p> So he can get here from <strong>$5a18<\/strong>, <strong>$5a1c<\/strong> or <strong>$5a20<\/strong>. This gives him 3 more breakpoints. <strong>$5a20<\/strong> is the one and as expected it comes from RAM initialized code (<strong>$59ab<\/strong>). He prepares for a painful ride. And painful it is. Nevertheless, he finds out that that <strong>$5a20<\/strong> is reached from <strong>$6c5e<\/strong>.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">6c5e: ldy $a5\r\n      lda ($a8), Y\r\n      sta $00\r\n      iny\r\n      lda ($a8), Y\r\n      sta $01\r\n      iny\r\n      sty $a5\r\n      and $00\r\n      cmp #$ff\r\n      beq $6c79\r\n      ldx $00\r\n      ldy $01\r\n      jmp $5a20<\/pre>\n<p> The first sentence of the grumpy cop comes from <strong>$89c9<\/strong> (iso offset <strong>$1339c9<\/strong>). This address comes from a table pointed by <strong>$a8<\/strong>. It&#8217;s setup at <strong>$707e<\/strong>.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">707e: lda #$00\r\n      sta $00\r\n      lda #$80\r\n      sta $01\r\n      lda ($00), Y\r\n      sta $a8\r\n      iny\r\n      lda ($00), Y\r\n      sta $a9\r\n      stz $a5\r\n      stz $a6\r\n      lda #$03\r\n      jmp $619c<\/pre>\n<p> The pointer is store at <strong>$13308c<\/strong>. Roger is perplex. It&#8217;s not just a simple pointer table. There is some extra data. He needs to figure out how it works but he is tired and there&#8217;s <a href=\"http:\/\/www.rottentomatoes.com\/m\/night_of_the_creeps\/\">Night of the Creeps<\/a> on TV.<br \/>\nHe streches, closes the emulator and his laptop and prepares himself for 90 minutes of pure 80&#8217;s badassery.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Roger is happy. He bought a cheap PC-Engine CDRom game called &#8220;Nishimura Kyotaro Mystery.: Hokutosei No Onna&#8221;. It seems to be a detective game like J.B. Harold Murder Club, Jake Hunter, Ace Attorney, Le Manoir de Mortevielle or Maupiti Island. It was published by Naxat (now Kaga Create) in 1990.\u2026 <a class=\"continue-reading-link\" href=\"https:\/\/blog.blockos.org\/?p=811\">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":[6],"tags":[27,30,19],"_links":{"self":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/811"}],"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=811"}],"version-history":[{"count":47,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/811\/revisions"}],"predecessor-version":[{"id":950,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=\/wp\/v2\/posts\/811\/revisions\/950"}],"wp:attachment":[{"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=811"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=811"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.blockos.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=811"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}