{"id":2234,"date":"2017-04-23T04:26:42","date_gmt":"2017-04-23T04:26:42","guid":{"rendered":"http:\/\/blog.system11.org\/?p=2234"},"modified":"2017-05-21T22:55:01","modified_gmt":"2017-05-21T22:55:01","slug":"using-mame-to-assist-with-repairing-nova-2001","status":"publish","type":"post","link":"https:\/\/blog.system11.org\/?p=2234","title":{"rendered":"Using MAME to assist with repairing Nova 2001"},"content":{"rendered":"<p>If you&#8217;ve seen my recent new arrivals post, you may have noticed a broken Nova 2001 PCB.\u00a0 I&#8217;d had a quick look at it when it arrived\u00a0 and managed to at least capture the error message, but today I decided to really sit down and put some time into it.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix1.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2220\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix1.jpg\" alt=\"\" width=\"827\" height=\"571\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix1.jpg 827w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix1-300x207.jpg 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix1-768x530.jpg 768w\" sizes=\"(max-width: 827px) 100vw, 827px\" \/><\/a><\/p>\n<p>So this is what I was faced with &#8211; the game would try to boot and then reset halfway through, the only way I managed to get a photo of the error itself was by making a video and stepping through it frame by frame.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix2.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2221\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix2.jpg\" alt=\"\" width=\"1280\" height=\"720\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix2.jpg 1280w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix2-300x169.jpg 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix2-1024x576.jpg 1024w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix2-768x432.jpg 768w\" sizes=\"(max-width: 1280px) 100vw, 1280px\" \/><\/a><\/p>\n<p>You can see that the CRLRAM bank allegedly has a fault, which could mean a RAM chip or it could just as easily be some logic between the RAM and CPU (in this case a Z80) testing it.\u00a0 The biggest problem though is that we don&#8217;t actually know which RAM chips to look at on the board.\u00a0 I&#8217;d already checked all of them with a logic probe to see if there was anything obviously wrong, but nothing stuck out as being faulty.\u00a0 When faced with this kind of problem on a booting game we can try various methods of disrupting the RAM to try to isolate which bank is at fault, but this is not possible when you&#8217;re stuck with a rapidly looping test mode.<\/p>\n<p>This is where MAME can be really useful, since the functional memory areas are mapped out even if they may not quite match the labelling or usage on the actual PCB.\u00a0 The error screen above appears after the four code ROMs have been checked, and the names would imply that a foreground and background layer have been checked successfully.\u00a0 This is from the comments of the Nova 2001 MAME driver:<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix3.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2222\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix3.jpg\" alt=\"\" width=\"652\" height=\"337\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix3.jpg 652w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix3-300x155.jpg 300w\" sizes=\"(max-width: 652px) 100vw, 652px\" \/><\/a><\/p>\n<p>I was willing to bet that the first two RAM banks were the foreground and scrolling playfield layers, so it would be a fair bet that the sprite RAM would be checked next.\u00a0 While the error message stated CRLRAM, on a working board or testing in MAME the success message would normally say CELRAM which could also hint at it being the sprite memory.<\/p>\n<p>The next step was to run the game in MAME and use the debugger to set a watch point on the sprite RAM memory address at $B000. In the following pictures I also set a breakpoint at $16AC, which happens to be a jump at the end of the message display code &#8211; I was able to find this by carefully stepping through the program.\u00a0 We can see that the first interesting write is 47 into $B000, and MAME pauses here due to the watchpoint.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix4.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2223\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix4.png\" alt=\"\" width=\"1920\" height=\"1200\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix4.png 1920w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix4-300x188.png 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix4-1024x640.png 1024w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix4-768x480.png 768w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix4-1536x960.png 1536w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<p>RAM tests are usually performed by writing into the RAM and then reading it back to see if it matches, and using the debugger memory viewer we can actually change that data mid program.\u00a0 After replacing the value with 00, I set it running again.\u00a0 We can see a very familiar error message now, and due to the breakpoints I set at the end of the message display routine, it doesn&#8217;t immediately vanish before it can be read.\u00a0 This confirms that the RAM area at $B000 is definitely the area of RAM that the game is struggling with.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix5.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2224\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix5.png\" alt=\"\" width=\"1920\" height=\"1200\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix5.png 1920w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix5-300x188.png 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix5-1024x640.png 1024w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix5-768x480.png 768w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix5-1536x960.png 1536w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<p>This is all very interesting, but it still doesn&#8217;t tell us which chips we need to be looking at on the PCB, but MAME hasn&#8217;t finished helping us yet.\u00a0 When we first looked at the watchpoint, there was an area of code highlighted on the right which is responsible for actually writing the test data.\u00a0 What if we modified that code so it just kept writing indefinitely?<\/p>\n<p>It&#8217;s difficult to make meaningful changes right in the middle of code, but far less difficult if you just want to make a change to some data without changing the length of it.\u00a0 In the screenshot below the highlighted code is going to cause the CPU to jump to address $1693, and 1693 is just a two byte piece of data.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix6.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2225\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix6.png\" alt=\"\" width=\"745\" height=\"495\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix6.png 745w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix6-300x199.png 300w\" sizes=\"(max-width: 745px) 100vw, 745px\" \/><\/a><\/p>\n<p>We want the program to go back to $14E1 right at the top which is the entry point for the RAM test.\u00a0 Time to open ROM 1 in a hex editor and find the code at $14F7 (C3 93 16):<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix7.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2226\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix7.png\" alt=\"\" width=\"594\" height=\"79\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix7.png 594w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix7-300x40.png 300w\" sizes=\"(max-width: 594px) 100vw, 594px\" \/><\/a><\/p>\n<p>You can see that the two bites of the address are reversed so we replace 93 16 with E1 14 ($14E1).<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix8.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2227\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix8.png\" alt=\"\" width=\"597\" height=\"81\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix8.png 597w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix8-300x41.png 300w\" sizes=\"(max-width: 597px) 100vw, 597px\" \/><\/a><\/p>\n<p>I&#8217;d already extracted the MAME set to a folder, so saved and overwrote the original file, let&#8217;s see what happens in MAME now with the same watchpoint and breakpoint as before.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix9.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2228\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix9.png\" alt=\"\" width=\"1920\" height=\"1200\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix9.png 1920w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix9-300x188.png 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix9-1024x640.png 1024w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix9-768x480.png 768w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix9-1536x960.png 1536w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<p>Unfortunately since the game checks the integrity of the code ROMs at boot we&#8217;ve created a version that resets even quicker.\u00a0 Since I couldn&#8217;t easily find where this check takes place, I decided to modify other data in the ROM to restore the checksum.\u00a0 Fortunately right at the top this one are nearly 32 bytes which appear to be of little importance (FF\/00),\u00a0 so I adjusted them a little to compensate.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix10.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2229\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix10.png\" alt=\"\" width=\"590\" height=\"80\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix10.png 590w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix10-300x41.png 300w\" sizes=\"(max-width: 590px) 100vw, 590px\" \/><\/a><\/p>\n<p>I worked on calculating the difference between the data originally in the file and what I had changed it to, and adjusted two bytes by the same amount.\u00a0 The first time I tried this it worked perfectly but the second time (after I corrected the jump address) it didn&#8217;t.\u00a0 There&#8217;s a hole in my guesswork somewhere and I&#8217;m not sure what it is, but it only took a couple of attempts to readjust it and fool the boot time ROM check.<\/p>\n<p>Now we have a version of the program code which just sits there trying to check the sprite RAM for all eternity&#8230;<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix11.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2230\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix11.png\" alt=\"\" width=\"1920\" height=\"1200\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix11.png 1920w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix11-300x188.png 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix11-1024x640.png 1024w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix11-768x480.png 768w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix11-1536x960.png 1536w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<p>There is one final problem though.\u00a0 The PCB has watchdog hardware and if it notices the CPU appears to have stalled, it resets it (MAME emulates this too).\u00a0 Testing the new code on the PCB did however prove that it was lingering slightly longer in the RAM test before the watchdog kicked in.\u00a0 This is what the relevant parts of the watchdog and reset circuit look like:<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2231\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12.jpg\" alt=\"\" width=\"2144\" height=\"1424\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12.jpg 2144w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12-300x199.jpg 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12-1024x680.jpg 1024w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12-768x510.jpg 768w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12-1536x1020.jpg 1536w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix12-2048x1360.jpg 2048w\" sizes=\"(max-width: 2144px) 100vw, 2144px\" \/><\/a><\/p>\n<p>The red line is the actual reset line, this is normally high and driven by the 74LS08 at position 4B.\u00a0 The LS 08 is an AND device, if inputs A and B are both high then the output is high, else the output is low.\u00a0 The inputs in this case are the power-on reset circuit in blue which is essentially just a capacitor on the 5v line, and in green a feed from part of the watchdog circuit (the 74LS161).\u00a0 To disable the watchdog what we have to do is either cut one of the chip legs or the track to disconnect input A and then join that to input B so that the power-on is driving both inputs.\u00a0 There are pros and cons to both methods, you could even remove one of the chips, fit a socket and leave one of the legs hanging out.\u00a0 In this case I opted for using a scalpel on the track directly below the 161.\u00a0 It was a very small transition track and very easy to rejoin later.<\/p>\n<p>Sure enough the game booted up and immediately got stuck looping the sprite RAM test, and using a logic probe it was very easy to work out which RAM was being accessed &#8211; one of the three surface mount 6116 chips.\u00a0 It&#8217;s not possible to get chips of the exact same size any more as these were early surface mount RAM, but ones that fit the pad layout are easily available.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix13.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2232\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix13.jpg\" alt=\"\" width=\"1499\" height=\"680\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix13.jpg 1499w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix13-300x136.jpg 300w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix13-1024x465.jpg 1024w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix13-768x348.jpg 768w\" sizes=\"(max-width: 1499px) 100vw, 1499px\" \/><\/a><\/p>\n<p>Of course just because a RAM test fails, it doesn&#8217;t mean that the RAM is definitely faulty.\u00a0 As I pointed out earlier it could be the logic between the CPU and the RAM but in this case it really was that simple.\u00a0 That blue rectangle bottom left is just part of the OSD on the television.<\/p>\n<p><a href=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix14.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-2233\" src=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix14.jpg\" alt=\"\" width=\"600\" height=\"977\" srcset=\"https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix14.jpg 600w, https:\/\/blog.system11.org\/wp-content\/uploads\/2017\/04\/nova_fix14-184x300.jpg 184w\" sizes=\"(max-width: 600px) 100vw, 600px\" \/><\/a><\/p>\n<p>Without the assistance of MAME I would have had to replace all of those chips since none of them appeared to be faulty with normal testing, and if it had been a logic fault I probably would have continued around the board replacing all the other RAM I could find due to the way the boot test works.<\/p>\n<p>Not only does MAME preserve games so that people can enjoy them in a world where prices are rising and supply drying up, but it also helps us to preserve the hardware that still exists, both as a source of vital documentation and a means of testing.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve seen my recent new arrivals post, you may have noticed a broken Nova 2001 PCB.\u00a0 I&#8217;d had a quick look at it when it arrived\u00a0 and managed to at least capture the error message, but today I decided to really sit down and put some time into it. So this is what I [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":50,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,13],"tags":[],"class_list":["post-2234","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arcade","category-tech"],"_links":{"self":[{"href":"https:\/\/blog.system11.org\/index.php?rest_route=\/wp\/v2\/posts\/2234"}],"collection":[{"href":"https:\/\/blog.system11.org\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.system11.org\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.system11.org\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.system11.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2234"}],"version-history":[{"count":4,"href":"https:\/\/blog.system11.org\/index.php?rest_route=\/wp\/v2\/posts\/2234\/revisions"}],"predecessor-version":[{"id":2238,"href":"https:\/\/blog.system11.org\/index.php?rest_route=\/wp\/v2\/posts\/2234\/revisions\/2238"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.system11.org\/index.php?rest_route=\/wp\/v2\/media\/50"}],"wp:attachment":[{"href":"https:\/\/blog.system11.org\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2234"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.system11.org\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2234"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.system11.org\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2234"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}