mrcook/jetpac-disassembly

GitHub: mrcook/jetpac-disassembly

一个基于 SkoolKit 的 JETPAC 经典游戏 ROM 反汇编项目,还原并注释原始二进制代码。

Stars: 66 | Forks: 11

# JETPAC 卡带 ROM 反汇编 一个非官方的 JETPAC 反汇编版本,经典 8 位电脑游戏, 于 1983 年为 16K ZX Spectrum 家用电脑发布。 [这个反汇编](https://github.com/mrcook/jetpac-disassembly) 是 基于原始 ZX Spectrum JETPAC 卡带 ROM 的二进制数据, 使用 [SkoolKit](http://skoolkit.ca) 反汇编工具包创建。 ## 游戏介绍 一款面向 8 位家用电脑系统的快节奏射击游戏。 Jetpac 是 Jetman 系列的第一部作品,后续还有 _1983 年的 Lunar Jetman_ 和 _1990 年的 Solar Jetman: Hunt for the Golden Warpship_。 **“Acme Interstellar Transport Company”正在向太阳系中的各个行星 运送 SPACESHIP KITS;而作为首席试飞员,你 所要做的就是组装火箭,并推动它前往下一个目的地。** **但!由于你并不总能获得免费穿越银河的机会,而太空旅行 又是如此昂贵,现在是你致富的好机会!你可以在旅途中顺道访问几颗 行星,收集奇怪的宝石、元素或黄金,并将它们带回。** **听起来很简单,不是吗!** 但!在让自己成为宇宙中最富有的人之前,你必须记得每次 降落星球时用 6 个燃料舱为飞船加油。其他你收集到的 物品都可以归你所有。降落之后,你会发现自身装备了最新的 Hydrovac **JET PAC**, 它可以自动空投几乎任何火箭阶段、燃料舱或贵重物品到你选定的位置, 并在飞船基地释放它们,同时配备强大的四光子激光相位器, 用于击落任何可能对你访问提出异议的讨厌小外星人。 而你懂的!当你收集完它们的所有财物并悄悄离开, 连一句告别都没有时,这些外星人会变得多么愤怒。 _JETPAC 由 Chris Stamper 和 Tim Stamper 于 1983 年为 16K 和 48K 的 Sinclair ZX Spectrum 设计开发。_ ## 项目状态 此反汇编可能已经完成。 - 所有代码块都已标记并注释。 - 所有变量都已标记并注释。 - 所有数据都已分离并注释。 - 所有文本数据都已注释。 - 所有图形都已注释(瓦片、精灵)。 - 所有游戏缓冲区(敌机/可收集物)都已注释。 不过,仍有一些代码和变量部分 值得进一步深入分析。 欢迎反馈与提交! ## Skoolkit 使用说明 当 ZX Spectrum 从卡带启动时, 位于地址 `$0000` 的 _loader_ 例程会被执行。该例程将加载屏幕复制到 Spectrum 显示文件, 并等待玩家按键。随后,游戏代码和数据会被复制到电脑 RAM 的地址 `$6000` (十进制为 `24499`)。 因此为了让反汇编位于正确地址,Skoolkit 需要指定一个起始写入地址。 以下命令可以从 `.rom` 镜像中提取游戏(镜像未包含在本仓库中), 应用反汇编注释,并将生成的源代码写入 `.skool` 文件: ``` $ sna2skool.py -c jetpac.ctl -Hl -o 24499 jetpac.rom > jetpac.skool ``` ## 汇编代码 Skoolkit 可以生成有效的 Z80 汇编代码,命令如下: ``` $ skool2asm.py -H -crs jetpac.skool > jetpac.asm ``` 生成的 `asm` 文件在没有 loader 例程的情况下无法启动游戏。 一个基础示例可在文件中找到: [`loader.asm`](https://github.com/mrcook/jetpac-disassembly/blob/master/loader.asm)。 [Pasmo Assembler](http://pasmo.speccy.org/) 可用于将源代码汇编为可用的 ZX Spectrum 磁带镜像。 ``` $ pasmo --tzxbas loader.asm jetpac.tzx ``` ## 磁带版本反汇编说明 本节包含关于卡带版与磁带版 Jetpac 差异的注释。 两者的代码基本相同,区别仅在于: - 内存加载位置略有不同; - 磁带版支持 Kempston 摇杆而非 Interface 2; - 还包含一个用于磁带加载的 _代码移动例程_。 BASIC 磁带加载器是一条长指令序列,已在此重新排版以适配显示。 ``` 1 CLEAR 24575: BEEP .1,1: BEEP .1,2: BEEP .1,3: BEEP .1,4: BEEP .1,5: PAPER 0: INK 7: BRIGHT 1: CLS : PRINT BRIGHT 1;INK 7; AT 9,7;"JETPAC IS LOADING"; AT 12,10;"PLEASE WAIT": PRINT AT 0,0: LOAD ""SCREEN$ : INK 0: PAPER 0: PRINT AT 5,0: LOAD ""CODE : PRINT AT 5,0: LOAD ""CODE : PRINT AT 5,0: LOAD ""CODE : PRINT AT 5,0: LOAD ""CODE : PRINT USR 24576 ``` 以下是用于反汇编 TZX 镜像文件的 skoolkit `t2s` 配置文件: ``` ; tap2sna.py file for Jetpac cassette version. Run ; ; $ tap2sna.py @jetpac.t2s ; ; to create a Z80 snapshot. jetpac.tzx jetpac.z80 ; Skoolkit handles these automatically, ; but listing here for reference. ; ram load: 4,16384 # load screen (JPSP) ; ram load: 6,24576 # load game code/data ; ram load: 8,23424 # load `mover` routine ; ram load: 10,23728 # load `JP (HL)` opcode ; ram load: 12,23672 # load game start check variables ; After the game loads the PC starts at $6000: ; ; c$6000 DI ; $6001 JP $5B80 ; ; The `mover` routine at $5B80 moves bytes 24580-32772 down to 24576-32768. ; This routine is loaded from tape block #8 (see above). --ram move=$6004,$2000,$6000 ; Initialize all game variables and data so the source code is clean. --ram poke=$5CCB-$5FFF,$00 --reg sp=$5CF0 --reg pc=$61E5 ``` 如你所见,`--ram move=$6004,$2000,$6000` 模拟了磁带上 找到的代码移动例程。 对此感兴趣的朋友,该例程如下: ``` ; Skoolkit code mover disassembly for Jetpac ; Disassembly of the code mover routine, which copies 8192 bytes from address ; $6004 down to $6000, before then jumping to the game start routine. c$5b80 ld hl,$6004 ; $5b83 ld de,$6000 ; $5b86 ld bc,$2000 ; $5b89 ldir ; $5b8b jp $61e5 ; ; Tape block #6 ("The Game") is loaded at this address, starts running, then ; calls the above routine, which then overwrites these instructions. c$6000 di ; $6001 jp $5b80 ; ``` Kempston 摇杆菜单项: ``` $62dc defm "4 KEMPSTON JOYSTIC" $62f0 defb $cb ; ASCII "K" ($4B) + EOL control bit ``` 摇杆读取例程及其在代码中的使用方式存在一些细微差异。 以下是主要的读取例程本身: ``` ; Joystick Input (Kempston) ; ; Output:A Joystick direction/button state. @label=ReadKempstonJoystick c$733a in a,($1f) ; Joystick port $733c cpl ; Invert all bits in #REGa $733d ret ; ``` ### 128K Spectrum 修复 在键盘读取代码中存在一条 `out ($fd),a` 指令, 在 128K Spectrum 上似乎会导致问题,因此需要将其改为 `NOP` 指令。 ``` ; jetpac.skool - $7326 out ($fd),a ; Set port for reading keyboard + $7326 nop + $7327 nop ``` ## 版权信息 本反汇编、注释和支持文件版权归 Michael R. Cook © 2020 所有。 JETPAC 版权、ULTIMATE PLAY THE GAME。版权与商业名称,1983 年 Ashby Computers & Graphics Ltd。保留所有权利。
标签:1983, 8位游戏, Jetman系列, Jetpac, ROM分析, SkoolKit, Wayback Machine, ZX Spectrum, 像素射击, 反汇编, 复古游戏, 太空射击, 安全报告生成, 开源反汇编, 快速连接, 汇编语言, 游戏ROM, 游戏开发历史, 游戏源码, 游戏逆向工程, 电子游戏考古, 系统运维工具, 经典游戏, 街机射击, 逆向工具