从30年前的源代码盘重建丢失的NES游戏

2020-06-02 02:33:48

里奇·怀特豪斯2020年6月1日你好,我是VGHF创始人弗兰克·西法尔迪。今天,我将与里奇·怀特豪斯合作,为你们带来一个关于我们如何恢复和重新组装“雷霆的日子”的故事,这是一个未发行的、从未见过的标题,由Mindscape的克里斯·奥伯斯(Chris Oberth)合著。

程序员兼设计师克里斯·奥伯斯(Chris Oberth)在2012年去世之前,在视频游戏行业有着漫长而多样的职业生涯。我认为,对我们大多数人来说,克里斯·奥伯斯(Chris Oberth)最终的游戏是食蚁兽(Anteater),这是他在斯特恩工作期间设计和设计的街机游戏(或者你可能知道克里斯自己为家用电脑写的克隆游戏--Aardvark Ardy-或者他没有写的那个-Oil‘s Well)。对其他人来说,这可能是64号准将的冬季奥运会,也可能是他后来在令人难以置信的科技公司(Uncredible Technologies)的街机活动,比如时代杀手(Time Killers)或世界级保龄球(World Class Bowling),或者是他在70年代末和80年代初在他的Apple II上开发的几个游戏(他喜欢吹嘘的是序列号为201的Apple II)。

2020年初,奥伯斯幸存家人的一位朋友找到视频游戏历史基金会,帮助他们理解他留下的材料。在他经常工作的家里地下室里,多年没有碰过的是成堆的旧电脑、CD-R备份、软盘、笔记、盒式磁带、EPROM和数据磁带,这些都可以追溯到他70年代末最早的Apple II作品,他的家人同意借给我们进行评估。

就像在查看这样的档案时经常出现的情况一样,我们的首要任务是试图找回克里斯丢失的任何作品-他开发的游戏,由于这样或那样的原因,从来没有商业化过。不幸的是,我们几乎没有发现他在斯特恩的遗迹,这意味着他未发行的以Wumpus为灵感的街机游戏“地窖”很可能永远消失了。但收藏品的其余部分让我们对他后来的家用电脑和控制台工作寄予厚望。

一张5.25英寸的软盘尤其让我们眼前一亮,上面有手写的标签,上面写着“任天堂热棒出租车决赛”。这并不是一个已知的游戏名称,但我们知道克里斯至少为任天堂娱乐系统开发了一款游戏-美国角斗士(American Gladiators)。当时我们对他的职业生涯知之甚少,但幸运的是,Oberth晚年至少对早期复古游戏爱好者网站进行了两次采访-一次是采访德里克的地下室拱廊,另一次是2006年为“复古时代”采访的三人组(特别是在“复古时代月刊”第21期、第24期和第27期)。就是在后者中,克里斯简短地提到了一款未发布的NES游戏--为Mindscape制作的未发布版本的“雷霆三重天”(由Beam Software进行的另一次尝试最终取代了它的位置)。“热棒出租车”是我们失去的雷霆时代吗?或许被剥夺了电影许可证头衔?

答案原来是…。说大也大吧。也许吧。在对磁盘进行了一次干净的通量撕裂,并根据其源代码和图形数据组装了一个二进制文件之后,我们剩下了一个可玩的NES游戏,虽然历史上很有趣,但还不是一个很好的游戏。如果说有什么不同的话,那就是这似乎是早期的概念验证工作,也许是奥伯斯第一次在一个对他来说是全新的平台上涉足。

我们还有另外一个地方要看:一大堆大部分贴着标签的硬盘备份,跨越了几年,分布在近40张软盘上。这些不仅仅是文件上的磁盘,它们是用(多个)硬盘备份工具完成的,这意味着文件被分割和加密。我们要恢复这些东西的唯一方法是将整个堆栈数字化,然后再重新组装。

我们在寻找“雷霆之日”剩余部分的第一个任务是从可用的存储介质中恢复尽可能多的数据,这些存储介质主要由5.25英寸的旧磁盘组成。其中一些磁盘有无法读取的扇区,但许多仍然完好无损。一些磁盘也可以立即读取,FAT12文件系统是在MS-DOS下创建的。然而,最有希望的一组是由21个磁盘组成的集合,其中包含4个独立硬盘分区的备份,采用PC Tools 5.1生成的专有格式。我们得到了一些帮助来解决这个问题,“PCTools 5.10。标签上写着“备份”。

最初,我尝试通过DOSBox运行PC Tools备份程序,希望能够通过仿真恢复备份。我没有任何运气让程序识别DOSBox下的磁盘映像,我认为我可能必须对模拟器本身做一些更改才能走这条路。在这一点上,我决定绕道直接理解数据,并着手挖掘这些备份磁盘映像中的原始扇区数据。

数据的结构并不太复杂。每个目录和文件记录都存储在压缩流中,其中命令字节用于指示3件事中的1件。0xDA表示“目录记录”,要追加到当前目录堆栈中。0xDB表示“文件记录”,后面紧跟实际的文件数据。0xDC表示“POP目录”,用于从目录堆栈中删除最新的目录。在记录中,我还能够识别MS-DOS样式的日期/时间字,这使我们能够在备份中的每个文件上放置准确的日期。

这是一个很有希望的开始,使我们能够生成备份中包含的文件列表。我们很快就发现了许多源代码和数据,它们似乎几乎肯定代表了大奖:“雷霆重生”(Days Of Thundern)。不幸的是,仍然存在一个问题。尽管我能够从备份中生成完整的路径列表,但我们需要的大部分数据都是使用专有算法压缩的。查看这里使用的压缩可能很容易,但是加密也是在已经压缩的数据之上应用的。幸运的是,应用于数据的加密是通用的,而不是基于用户指定的密钥,否则我很可能仍然在逐步恢复数据,而不是键入这个!

因此,从这里开始,我考虑了几种方法。第一种方法是创建自定义版本的DOSBOX,以便使PC Tools备份程序在与原始备份映像的仿真下正常运行。第二种方法是对PC工具使用的加密和压缩进行反向工程,这意味着要花很长时间来反汇编(理想情况下,调试)原始程序。我对反汇编比这更庞大、更复杂的系统并不陌生,但我认为自定义构建的DOSBOX在这种方法中都会是一个有用的工具,所以我只需要在备份数据以某种方式损坏的情况下就可以做到这一点。在这种情况下,我必须了解它的每一点,以便从残骸中抢救出一切可能的东西。

第三种方法比上面任何一种方法都简单得多:使用真实的硬件!不幸的是,我手头没有必要的硬件,但我们能够立即得到有硬件的人的帮助。Foone能够启动并运行基于硬件的解决方案,虽然我们确实需要重新撕毁其中一个备份磁盘集来让PC工具将其吞噬,但我们最终能够恢复这4个硬盘分区中的每一个分区上的每一位数据。

因为第三种方法起作用了,所以我从来没有深入到对PC工具使用的压缩算法进行逆向工程的战壕中。然而,坊间传闻,它似乎很可能是类似LZSS的东西。我使用PC Tools集合中的pcsecure.exe进行了一些简单的测试,它使用的压缩似乎与备份程序使用的压缩非常相似(虽然不完全相同,但基于从匹配数据压缩所获得的结果)。我还注意到,对于您通常认为对LZSS不利的某些情况,压缩失败并产生了更大的最终结果,例如一系列完全唯一的字节,从而产生了我期望的那种使用控制字节堆积数据的开销。

乍一看,我们没有看到任何突出的预置ROM映像。当然,那太容易了。因此,有了4个硬盘分区要筛选的数据,我从名为C:\ROMX\BTR的目录开始,当我们只需查看文件名列表时,这是我们最想看到的目录。这个目录似乎包含了“雷霆之日”的所有源代码和一些数据。许多最初用于开发游戏的工具,包括汇编器/链接器,也都备份在C:\util中。最初的汇编程序是X6502,它是公元2500年软件公司的6502交叉汇编程序。这里的汇编器和链接器都标记为版本4.03b。

我构建了源代码,并将所有对象链接在一起,从而生成了6个独立的二进制文件。这将我们带到这个过程的下一部分,一个名为ROMX的程序。此程序是GTEK,Inc.提供的ROMulator软件包的一部分。值得注意的是,在撰写本文时,该公司的网站仍在运行。在我们的例子中,ROMX程序用于通过PC的RS232端口进行通信,将数据直接放入NES显像带的PRG/CHR存储器中。这使得开发人员可以

ROMX PB0.TSK[TS,M\,%%0000,@0000-FFFF]ROMX PB1.TSK[%%0000,@4000-7fff]ROMX PB2.TSK[%%0000,@8000-BFFF]ROMX PB3.TSK[%%0000,@C000-FFF]ROMX PB4.TSK[%%0000,@10000-13fff]ROMX PB7.tsk[%%0000,@。

上面的代码告诉我们应该将6个代码二进制文件(我之前提到的那些代码二进制文件)和2个预先生成的声音二进制文件放在哪里。当其中一个开发人员想要从PRG或CHR内存生成平面二进制文件时,而不是在另一个PC端进程中复制所有这些信息,他们只需运行ROMX并带参数从硬件转储所有数据并将其存储到一个文件中。

在构建游戏的这一点上,很明显,我们仅根据PRG银行的数量就需要某种类型的映射器,所以我查看了源代码,看到了一些明确地与MMC1寄存器一起工作的代码。我用我的128KB PRG ROM构造了一个Ines头,相应地设置了映射器位,然后将一些随机垃圾扔到CHR ROM中进行测试。这款游戏在模拟器中成功启动,并开始在一大堆随机的磁贴数据上播放音乐,我认为这些数据可能应该是一个标题屏幕。

通过在CHR ROM中运行带有一堆随机数据的游戏,我可以看到我们正在查看相当多的独特的瓷砖数据。这些数据的一些痕迹仍然留在震源及其周围。具体地说,有一个定制工具可以从Pictor CLP文件中解析出分块块,将它们写入临时文件,然后通过ROMX将它们上传到显式的cr地址。这一过程被一些小型汽车和扳手瓷砖套装所调用。然而,在很大程度上,大量的CHR数据都下落不明,也没有迹象表明CHR数据通常是如何通过ROMX上传的。

在另一个目录C:\ROMX\CHEDIT中,我发现了一个自定义的NES磁贴编辑器,其中包含似乎属于《雷霆天下》的剩余数据。我能够将这里导出的一些.map和.pal数据与正在组装到PRG中的数据进行匹配,因为这是匹配的,所以我认为这里的.chr文件也将与任何属于CHR的文件相匹配。我从一个名为CAR.CHR的文件开始,着手找出它在CHR内存中的确切位置。这个问题的答案是0x3000,我通过查看标题屏幕成功地验证了这一点,即使CHR的其余部分充满了随机数据:

验证这个特定的数据是否属于cr ROM是很好的,但是我仍然遗漏了很多数据,而且我在一个动画实用程序的脚本中发现了一些引用,这些引用指向驱动器路径上的跟踪和平铺图像,而这些路径在我们还原的备份中实际上并不存在。我担心会出现最坏的情况,那就是我们丢失了一大堆CHR数据以及重建它的源数据。

知道我已经有了一个很好的大块CHR ROM的可能候选者,我从CAR.CHR中提取了一个唯一的字节字符串,并在备份中的每个文件中进行二进制搜索,希望我能幸运地命中一个预构建的CHR ROM块。第一次尝试没有运气。在这一点上,我选择了核选项。我提取了每个驱动器备份中所有已知格式的每个存档,并对我们设法恢复的每个其他磁盘映像执行了相同的操作。我再次搜索了整个文件,只找到了一个128KB的二进制文件。哦,是的。

我很谨慎,不知道那个大小方便的128KB二进制文件是否真的会与我正在使用的源地图和磁贴地图匹配,特别是因为命中来自另一组单独的磁盘。不过,在这一点上看不到其他选择,我拿出该文件,并使用它来占据我构建的NES ROM中的整个CHR ROM,它就在那里。一切似乎都在它应该在的地方!

终于,三十多年来第一次在这里看到了久违的雷霆之日!

有了这些,我们的任务就成功了。不幸的是,我们似乎确实丢失了很多源数据,我仍然怀疑Said数据位于我们恢复的主备份中未包括的其他硬盘分区中的某个位置。如果不是因为我们成功地从一组看似无关的数据中找到了cr二进制文件,我们可能永远无法完整地恢复这款游戏,或者我们可能最终创作了自己的瓷砖,只是为了看看预期的可玩体验的一些外观。这正好说明,每一张软盘都很重要!

在得到Chris Oberth家人的许可后,我们将在不久的将来在GitHub上发布可构建的源代码。与此同时,一群复古游戏爱好者为奥伯斯的遗孀举办了一系列与任天堂娱乐系统兼容的小打小闹的《雷霆三重天》(Days Of Think)墨盒,作为筹款活动。在这里可以买到。

多亏了你们慷慨的慈善捐助,我们才得以花了几周时间关注奥伯斯的档案!如果没有像你这样的人,这种水平的工作真的是不可能的。如果你是VGHF的新手,或者你只是欣赏我们正在做的工作,如果可以的话,请考虑给予。每一美元都有帮助。

我们正在保存视频游戏的历史,一次保存一个字节。现在捐赠