How I restored a rare game from TAP file

How this began

The other day Gianluca approached me with a request to help him with the dumps of an Italian game from 1986: “Nashiro Hazu – La roccia del destino”.

Nashiro Hazu title screen by Luigi Di Fraia

Nashiro Hazu title screen

He had made 15 dumps with his DC2N but none of them was working: apparently an area of the tape was damaged.

Some forum-cowboy-of-WAV-method suggested Gianluca to try an import via WAV file. Thank goodness Gianluca thought it was time to contact me rather than waste time with the WAV approach. I am ashamed that in 2012 there is still people talking about audio sampling of tapes for preservation purposes.

How I approached the issues

Well, first thing I selected one of the DMP files Gianluca made available. I picked the one that looked healthier than the others. Saves a lot of work down the line.

As I only manipulate TAP files, the one I ended working with was: dump0262(advtime_n2_a1_sidea-nushell-nudatassette).tap

First issue

There were joined pulses in the first Biturbo file. These do not require any content analysis in order to be reliably fixed. The two occurrences we have here can be overridden (using a Hex editor) in reverse order so the offsets do not move ahead after each change:

Offset: BA78
Value: 0×33
Override with: 0x1B, 0x1B

Offset: BA75
Value: 0×34
Override with: 0x1B, 0x1B

After this change, the file passes checkbyte validation. As the pulse offsets that were fixed are so close, they cannot have altered bits in the same position but in different bytes, which would have made the checkbyte check unreliable.

Second issue

This is a bit more complex as there is a damaged area on the tape and quite a few pulses were stretched in a way that we can’t simply override them.

NH Tape motor issue by Luigi Di Fraia

NH Tape motor issue

What we need here is to decode the information itself and attempt a reconstruction of the data that was lost.

From TAPClean:

File Type: BITURBO
Location: $8878D -> $8978D -> $E2795 -> $E2F65
LA: $0801 EA: $BA01 SZ: 45569
Pilot/Trailer Size: 495/1993
Checkbyte Actual/Expected: $00/$59, FAIL
Read Errors: 4
Unoptimized Pulses: 240305
CRC32: 0E1697AD
 - Read Error on byte @$994D5 (prg data offset: $1FAB)
 - Read Error on byte @$994DD (prg data offset: $1FAC)
 - Read Error on byte @$994E5 (prg data offset: $1FAD)
 - Read Error on byte @$994ED (prg data offset: $1FAE)

PRG data as shown in TAPClean Front End (damaged area within square brakets):

00001F80 49 22 3B 3A 99 22 52 4C 41 20 20 46 49 4E 4F 20 I";:."RLA FINO 
00001F90 20 41 44 20 20 55 4E 41 20 50 4F 5A 5A 41 20 44 AD UNA POZZA D
00001FA0 27 41 43 51 55 41 20 20 53 43 55[69 69 69 69]A7 'ACQUA SCUiiii.
00001FB0 2A 22 A9 27 27 90 10 22 22 A6 26 20 90 28 AA A0 *".''.."".& .(..
00001FC0 A6 22 91 1D 9D 4C 91 10 28 2A A7 A4 90 2B 22 A2 ."...L..(*...+".

As it is obvious from the PRG contents above, the tape is damaged at a point where there is a plain text message. The damage also caused the rest of the bits not to be byte aligned, so that what we need to do first is to re-align the data after the damage, as this will give us an idea of how much was lost, based on the remainder of the text message.

It is rather simple to realign bits so that next data is text:

A7 2A 22 A9 = 1[0100111001010100010001010101001.]
01001110010101000100010101010010 = 4E 54 45 52 = N T E R

Now, in order to realign the data within the tap file itself, we can simply insert a few 0x1B pulses immediately after the damaged area. As the above pattern suggests, we need to insert 7 pulses to byte align the stream (look at the single bit outside of the brakets on the left).

So the whole sentence is as per below (damaged data in square brakets):

RLA FINO AD UNA POZZA D'ACQUA SCU[???]NTERNO DELLA QUALE
PUOI VEDERE DIVERSI UOMINI  IN  ATTESA. DAVANTI  ALLE

We can make a hypothesis on what should be in the brakets and see what happens.
The first attempt would be to assume the sentence reads:

RLA FINO AD UNA POZZA D'ACQUA SCU[RA ALL'I]NTERNO DELLA QUALE
PUOI VEDERE DIVERSI UOMINI  IN  ATTESA. DAVANTI  ALLE

However, if you look at the whole file, you will see we are 2 bytes short as the the last byte in the data is obviously part of the trailer (value 0×00). The checkbyte (likely to be the last non zero byte: 0×50) ended up into the data file as well. Hence what I am saying that the file is 2 bytes too short.

The most natural reconstruction at this point is to put blank spaces:

RLA FINO AD UNA POZZA D'ACQUA SCU[RA   ALL'I]NTERNO DELLA QUALE
PUOI VEDERE DIVERSI UOMINI  IN  ATTESA. DAVANTI  ALLE

That way the file has the right size but the checkbyte check fails. We are getting there though. The expected checkbyte value suggests that we should have a 0x2C value somewhere. 0x2C is the value for comma, so it’s easy to reconstruct the whole sentence:

RLA FINO AD UNA POZZA D'ACQUA SCU[RA,  ALL'I]NTERNO DELLA QUALE
PUOI VEDERE DIVERSI UOMINI  IN  ATTESA. DAVANTI  ALLE

So, the corrupted data within the file (including the spare bit 1 and the 0x1B pulses we inserted earlier) has to be replaced with:

"RA,  ALL'I" = 52 41 2C 20 20 41 4C 4C 27 49 = 01010010, 01000001, 00101100, 00100000, 00100000, 01000001, 01001100, 01001100 = 0x1B, 0x27, 0x1B, 0x27, 0x1B, 0x1B, 0x27, 0x1B, ...

Once the above is done, the checkbyte check passes and the file loads and executes fine.

As this is a frozen file, the fact it executes along with the checkbyte test passing and the reconstructed sentence reading properly are good enough to state that the reconstruction work did not alter the original data.

Nashiro Hazu game start by Luigi Di Fraia

Nashiro Hazu game start

There you go: Another rare title preserved forever.

This entry was posted in Retrocomputing and tagged , , . Bookmark the permalink.

4 Responses to How I restored a rare game from TAP file

  1. Tommi Lempinen says:

    Sadly many think that if the cheapest, easiest way doesn’t produce good results why bother as the better solution is likely more costly and not that many care about the issue at hand anyway.

  2. Oreste says:

    Nice job. I agree with you about the preservation of tapes: it should be done with datassetes and in TAP format directly. Though, in some cases of corruption, I think an audio clip sampled from the tape could be helpful for one thing: figuring out how much data was lost, perhaps through some calculation based on the typical length of the pulses for that particular type of turbo data. As you surely know, if a section of a tape is accidentally silenced or overwritten, you’ll end up with a TAP file that has one or more “jumps” and is shorter than it should be, because when no pulses are found, nothing is stored in the file. The fact remains, that these reconstruction operations are only feasible on TAP files.

    • luigidifraia says:

      “As you surely know, if a section of a tape is accidentally silenced or overwritten, you’ll end up with a TAP file that has one or more “jumps” and is shorter than it should be, because when no pulses are found, nothing is stored in the file.”

      The above statement is entirely wrong.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s