ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

把法国CII Mitra-15搬进SIMH:一场复古模拟器的进行时

把法国CII Mitra-15搬进SIMH:一场复古模拟器的进行时 在复古计算项目的归档里我见过很多比 README 更真实的标题。有一条让我停留了很久只有一行字“French CIIs Mitra-15 in SIMH. Work in Progress.” 没有启动界面展示没有演示 GIF也没有“已完成百分之多少”的路标。这个标题之所以抓人是因为它用一句话交代清楚了三个关键信息目标机器是法国 CII 公司的小型机 Mitra-15载体是历史模拟器框架 SIMH状态是正在进行中。这三件事看似平淡组合起来却很特别。没有 Mitra-15它只是一个普通的模拟器开发项目没有 SIMH它可能变成一套难维护的孤岛代码没有“Work in Progress”它会错过这类复古保存工作的真正特征——不是“完成了”而是“今天比昨天多弄懂一点”。所以这篇文章想从这行标题出发聊一个更具体的问题为什么把一台冷门法国小型机放进 SIMH是一件值得做、也很有讲究的事情。顺便我也想拆开“Work in Progress”这几个词背后真正的复古模拟器工作到底长什么样。1. 在谈模拟之前先认识 CII Mitra-151.1 一台不算庞大、却被历史折叠的小型机在中文技术社区里Mitra-15 这个名词的知名度远低于 PDP-11 或 VAX。它来自法国 CII全称大约是 Compagnie Internationale pour lInformatique。这是上世纪六十年代法国“Plan Calcul”政策背景下成立的计算机公司。CII 最初的使命简单说就是要在美国主导的计算机产业之外建立一个以法国和欧洲为基地的计算机工业能力。Mitra-15 是 CII 产品线中的一款小型机。按照一般流传下来的公开资料它采用 16 位字长面向工业控制、实验室数据采集、实时通信等领域在 1970 年代初期投入市场。它不像大型机那样需要专用机房也不像后来的个人计算机那样普及。在当时的实际场景中它更像一个“系统部件”被嵌入到一台测量设备、一套通信装置或一个过程控制系统里。对很多使用者来说它不是一个需要被记住的名字而是一个负责运算和控制的黑色机箱。今天如果去搜索 Mitra-15能找到的资料和搜索 PDP-8 完全不在一个量级。这带来一个很直接的后果它没有成为复古计算收藏界的宠儿但也没有被彻底遗忘。在一些法语系复古计算网站和档案项目里还能找到当年的手册扫描件、纸带镜像片段、以及少量爱好者讨论。对一个想把它“救回来”的人而言这些碎片是比代码本身更重要的资产。1.2 “Work in Progress”不是免责而是这类项目的本来状态很多人看到 Work in Progress第一反应是“还没做完先看看”。在普通软件项目里可能是这个意思但在模拟器开发里这个状态意味着一个更具体的位置底层 CPU 指令可能已经有一部分能执行但外设、中断时序、操作系统引导流程还没有完全串起来。在复古机器仿真里“完成”其实是一个很模糊的词。到底是指 CPU 跑通全部指令还是指能够加载原始操作系统又或者指能运行某个原始应用程序对 Mitra-15 这种机器来说后两者几乎是最严格的标准。它的操作系统、汇编器、应用软件都不是随手能从网上复制下来的。就算有一台 CPU 模拟器在逻辑上完全正确如果缺少终端、纸带或磁盘镜像还是只能看到底层指令循环却得不到任何有意义的输出。所以一个诚实的复古模拟器项目更愿意让自己停留在 Work in Progress 状态。这个状态不是失败而是保存工作的一种真实记录。它告诉后来者这个项目没有假装什么都支持也没有把不确定的指令语义用模拟器“焊死”。它仍然欢迎有人加入从一张门级电路图或一小段监控程序入手把缺掉的那部分补上。2. 为什么偏偏是 SIMH而不是自己从头写一个模拟器2.1 SIMH 是什么它不是 QEMU也不是 MAMESIMH 是一套历史计算机模拟器框架最早可以追溯到 Bob Supnik 对 DEC 机器模拟的需求后来扩展成一个覆盖几十种机型的大家族。它的设计目标是“可移植、可调试、可复现”而不是像现代虚拟机那样追求顺畅的运行体验。有人会把 SIMH 和 QEMU、MAME 放在一起比较。对 Mitra-15 这种工作来说差别很大。QEMU 擅长把常见 x86/ARM 硬件做成性能可用的虚拟机MAME 偏向游戏机和微型计算机的界面还原。SIMH 更像是一个“能让操作系统认为自己在真实硬件上运行的实验设备”。它的主要交互手段是控制台命令、日志输出、内存和寄存器转储而不是图形界面。这种取向正好适合 Mitra-15因为这类项目的目的是理解机器本身而不是把它的外壳画在屏幕上。2.2 使用 SIMH相当于把问题边界收敛到“机器逻辑”要在模拟器里实现一台机器通常要写四类东西CPU 内核、内存系统、外部设备、以及把它们串起来的控制台和调试机制。如果完全从零开始大量精力会花在与“机器逻辑”无关的通用组件上。SIMH 的价值在于把这些通用部分直接借过来命令行接口、镜像文件读写、定时器、选项开关、日志系统都已经具备。对 Mitra-15 项目来说这意味着工作重心可以从“造一个新框架”转变成“把 CII 这台机器的内部逻辑讲清楚”。反过来如果有人在资料不全的情况下从零写模拟器又加入一堆自创脚本和界面支持项目往往会在早期变得非常脆弱。等真实文档、镜像或诊断程序出现时才发现底层指令模拟已经有不少错误需要推翻重来。SIMH 给的底座可以让你把精力投在真正不确定的地方而不是基础设施上。2.3 SIMH 模拟器常见的开发节奏外设一点点“接上去”一个正在开发中的 SIMH 模拟器通常遵循一条重复路径先建一个空设备对象注册到 SIMH确认EXAMINE和DEPOSIT这类基础命令能工作。让 CPU 能执行简单指令至少能在控制台上输出一个字符或数字。再实现内存和 I/O 编址把设备状态寄存器和中断接上。最后尝试加载某种原始二进制观察它停在什么地方。对 Mitra-15 这种资料稀缺的机器来说中间任何一步都可能卡住很久。尤其是外设部分如果不知道控制台控制器的寄存器地址或者不明白纸带阅读器的中断向量CPU 再正确也暴露不出任何行为。这也是我很欣赏 SIMH 框架的地方——每发现一层新事实就可以把它落实成一个测试用例每次运行都是一个可复现的考古实验。3. 把一台几十年老机器“复现”出来的四个现实步骤3.1 资料搜集阶段先建立“指令级词典”而不是先打开编辑器复古模拟器项目里最忌讳的是凭印象写指令集。比如看到LDA三个字母就想当然认为它和别的机器上的LDA一样。实际上不同机器的LDA可能带不同寻址方式可能影响不同状态位也可能在特定内存区域触发异常。这些细节一旦搞错后续工作全部会受影响。因此第一步至少要做下面这些事拿到 CPU 手册、编程手册和 I/O 设备手册哪怕是扫描版 PDF。把指令集整理成一张表逐条记录长度、寻址方式、对条件码的影响。弄清机器复位后的行为从哪个地址取指有没有引导 ROM控制台如何输入第一个程序如果可能找原始汇编器或编译器通过交叉编译生成一些已知输入输出。这个阶段没有捷径。你能模拟到什么程度取决于对手册理解的深度。如果文档不够不应盲目扩展指令集而应先把已知范围固定下来。必要时甚至可以从类似型号的指令系统做参考但必须把“参考”和“确认”分开记录否则容易把两台机器的差异混在一起。3.2 最小可执行闭环一条指令一个寄存器一个可见输出在 SIMH 中实现 CPU 内核时不要期待一周内跑通全部指令。更可行的做法是先实现取指、译码、基础执行和内存读写。用一段手工汇编的极简单程序验证。例如把一个数送进累加器加一写回内存再读取循环。如果机器有控制台字符输出指令就实现它让最小的程序能往终端输出一个字符或一个数字。每增加指令就配一个对应的测试程序确保新指令没有破坏已有指令。这个“最小闭环”的好处是能很快暴露基础语义的误会。比如字的字节序、负数表示方式、调用栈的方向、复位向量位置。这些问题如果前期没发现后面越堆越难修。如果要用代码片段描述可以看下面的常见结构未必是 Mitra-15 真实助记符但流程是通用的ORG 0 LDA VALUE ADD ONE STA RESULT OUT HLT VALUE: 5 ONE: 1 RESULT: 0把这段程序手工翻译成机器码再通过 SIMH 的存取命令放入内存。如果运行后RESULT是 6终端有输出说明最小链路通了。这一步很基础但它是一切更复杂功能的起点。3.3 外设优先级先控制台再存储最后考虑高级功能很多模拟器开发者在 CPU 跑通之后第一个念头就是“赶紧把磁盘模拟出来”。我建议不要这样做。Mitra-15 那个年代的机器外围设备差异很大。在资料不全的情况下应该优先做控制台和纸带阅读器/打孔机原因很简单控制台是人机唯一的窗口没有它什么都看不到纸带是当时最重要的程序载体几乎所有软件都是通过纸带或磁带送进机器的。磁盘、实时时钟、矢量终端等高级外设对时序、数据格式和控制逻辑要求更高容易把项目带入泥潭。比较稳妥的顺序是控制台输入输出。纸带阅读器或纸带打孔机。简单的批量存储设备比如磁鼓或软盘。实时时钟和复杂中断系统。每一步都要回到最小闭环做一个功能再写一个测试验证它是否真的工作。顺序错乱常常会导致项目卡在“系统无法启动”上但其实底层的某个早期外设早就坏了。3.4 黄金对照表把你的模拟器埋在“已知行为”里一个 Work in Progress 项目最容易犯的错是不给行为留回归测试。今天修好了跳转明天可能又把算术改坏。为了避免这种情况应该为每个已验证的行为注册黄金对照。这里给一个通用表格结构可以直接用到自己的项目里测试对象输入样例期望结果当前状态算术运算LDA #5; ADD #7; STA MEMMEM 0x000C通过条件跳转比较累加器大于 0 则跳转跳过后续指令通过控制台输出输出字符A终端出现A待实现纸带读取中断启动读取产生中断CPU 进入读取中断向量待验证引导加载从地址 0 启动进入读取第一条指令待验证这张表看起来简单却是长期模拟器项目的“骨骼”。普通功能测试只能证明“今天没有报错”黄金对照表证明的是“你复现的是机器本身而不是某个人的臆想”。4. 模拟器不工作时该怎么一步步把问题找出来4.1 先看现象是“完全卡死”还是“输出错误”排查的第一步不是打开内存转储而是先描述现象。在 Mitra-15 这类复古模拟项目里常见现象有三类程序执行到某条指令后无限循环CPU 在几条地址之间反复横跳。有输出但字符完全不对出现乱码或位置错乱。没有输出系统像断电一样安静。三种现象指向不同层级。无限循环多半与中断向量、跳转条件或栈操作有关输出乱码多半与字符编码、字节序或控制台设备状态机有关完全没有输出则可能连最基本的控制台写指令都还没走到。4.2 第二层看输入指令编码和字节序是常见的“隐藏凶手”旧机器的纸带、磁带和磁盘镜像有时并不是网上常见的那种“方便加载”的格式。一个用交叉汇编器生成的目标文件可能带有文件头、地址重定位表甚至以 ASCII 文本形式保存。如果直接把这种文件塞进模拟器即使 CPU 完全正确也会读到一堆看起来像垃圾的指令。如果运行结果不对先检查三件事镜像文件到底是原始二进制还是文本编码字节序是否符合 Mitra-15 的存储方式加载地址是多少是否需要手工在内存起始位置填入跳转指令这一步能避免大量无效调试。很多“模拟器 bug”本质不是模拟器的问题而是“喂”给它的镜像格式不对。4.3 第三层看 CPU 状态用寄存器快照定位分歧如果镜像输入没有问题就要使用 SIMH 的调试命令在特定地址暂停程序检查 PC、累加器、状态标志、栈指针和内存窗口。然后手动计算一遍看看 CPU 是否走到了正确路径。很多古董机还有一个特性不同子型号或不同维护版本之间指令语义存在细微差异。比如条件码是否在特定时刻更新、索引寄存器是否溢出陷阱、中断时压栈的顺序等。如果你碰巧面对一个不常见的版本就无法用“按常理推测”的方式解决只能回到原始手册或原始诊断程序里找答案。4.4 第四层看外设时序中断和握手不能只做“看起来对”在模拟器里实现外设最简单的方式是“事件发生立即产生中断”。但真实硬件不会这样。纸带阅读器需要时间启动磁盘控制器要等待寻道终端设备可能只接收固定波特率的数据。操作系统在等待这些设备时依赖状态位、中断 pending 位以及“清除中断”的写操作来同步。如果模拟器把时序简化得太厉害操作系统就会陷入死循环或不断重复触发中断。排查外设可以按这个顺序来先确认中断请求位何时被置位。再检查程序是否通过读状态寄存器“看到”了这个事件。接着看中断向量是否正确跳转。最后确认在完成服务后程序是否用设备命令寄存器清除了中断标志。如果找不到原始设备的时序手册这一步通常最耗时。没有别的方法只能靠各种最小程序和对照打印来反推。4.5 把每次调试记录成一份“考古日志”对 Work in Progress 项目来说最终产出不只是模拟器还有一份调试记录。我建议每个关键发现都写一小段现象是什么、怀疑哪里、验证方法、最终结论。这样既能帮自己理清思路也让后来者不用重复走弯路。很多情况下模拟器源代码只能告诉别人“怎么实现的”加上调试日志才能告诉别人“为什么这样实现”。后者恰恰是复古模拟项目最有价值的部分。5. 这个项目真正值得留在“Work in Progress”状态的原因5.1 CII 和 Mitra-15在产业政策夹缝中生长出来的小型机CII 的历史不能只理解成一家公司。它是法国在二十世纪六十年代推动“Plan Calcul”的产物目标是在大型计算机产业上建立国家能力。这个宏大目标后来经历了并购、重组和战略摇摆CII 最终并入 Honeywell-Bull 体系。在变迁过程中小型机产品线服务过不少工业和科研用户却在后来的商业叙事里逐渐失声。Mitra-15 生产年代并不算特别久远却因为公司变迁、软件专有化和使用者群体较小留存资料极少。今天有些法国大学或机构的档案里还能看到它的痕迹但能够完整解释它操作系统和汇编器细节的人已经越来越少了。这使它处在一种“曾经被广泛嵌入系统却很难完整还原”的状态。5.2 模拟器是让历史“可运行”的最好载体之一纸质文档和架构图很宝贵但不能让软件跑起来。一个正在进行的 SIMH 模拟器能提供一种非常特殊的验证方式文档上写着“这条指令把内存中的内容与累加器相加”你在模拟器里输入一条机器码看到累加器确实发生了变化。这种“可运行性”让历史从“可阅读”变成“可实验”。对 Work in Progress 项目来说它相当于公开了一间试验室。未来如果有人从某个老实验室翻出一卷 Mitra-15 纸带至少有机会在一个基线正确的模拟器里把它读出来。这个前景比“找到一台还能通电的原机”更现实也更容易持续维护。5.3 为什么这类内容值得写成长文而不只是在代码仓库里留注释代码仓库里的注释通常只写给维护代码的开发者。但像 Mitra-15 这样的机器潜在受众不只是模拟器作者还包括技术史研究者、博物馆策展人、当年用过它的老工程师。一篇博客可以把“模拟器工作进展”翻译成更通用的语言这台机器到底怎么工作它的软件生态为什么是今天这个样子以及我们还有没有机会找回一部分数字记忆。这也是我在本文里反复把重点放在“不是凭指令表造 CPU而是连接档案、调试和验证”上面的原因。复古模拟器项目表面在写代码实际上是在做计算史的叙事重建。6. 如果你想做类似的事从哪里开始才算比较稳6.1 明确动机是“玩机器”还是“研究机器”想参与这类项目的人通常有两种动机。一种是想像普通玩家一样尽快看到老软件运行起来另一种是把模拟器开发当作理解计算机结构的方式。两种动机都合理但它们对应的路径完全不同。如果只是想玩不建议从 Mitra-15 这样资料稀少的系统开始。更好的做法是先玩成熟的模拟器比如 PDP-11、AltairZ80等熟悉复古计算的基本工作流后再进入更稀缺的机器。如果目标就是研究机器本身那么一个文档不完整的项目反而容易逼你搞懂底层原理。因为你需要同时理解指令集、中断、I/O 机制和软件加载流程而不是靠现成的视频教程速成。6.2 一个可复用的项目推进清单如果你打算自己启动一个类似的复古模拟器项目下面的清单能减少无用功明确目标机器列出所有已知硬件模块。找到至少一份 CPU 手册和一份外设手册并做成摘要笔记。研究 SIMH 框架里已有的最小模拟器示例弄懂设备注册和命令行选项怎么用。用最小测试程序验证基础指令再逐步扩展指令集。为每一项已验证行为建立黄金对照表。定期写日志记录新增指令、外设改动和验证方法。把代码放在独立分支或仓库里让“Work in Progress”状态可见。遇到问题求助时不要只说“不工作”而要附上寄存器转储、内存快照、命令行操作步骤和日志。6.3 现实判断这个方向值得长期投入吗要清醒一点仿真一台冷门法产小型机即使最终成功也不会有现代软件那种“上新”效果。它的价值在时间维度。十年后再有人想研究 Mitra-15如果这个 Work in Progress 仓库还在至少有一条可以逐步复现的路径。这种价值比一两个演示截图重要得多。从技术层面看这类项目也是一堂极好的计算机系统课。它会在很小的规模内让你完整经历“硬件手册—指令执行—外设交互—操作系统启动”的链路。这里面的认知对做嵌入式、编译器、系统软件的人都有长期启发。我原以为一个标题里带着 Work in Progress 的项目吸引人的地方应是“有朝一日它会完成”。看过越多类似项目后我现在的判断完全变了。这类项目最有力量的地方不是未来某个版本的完成状态而是它把一台被断层历史包裹的机器从纸质档案搬进了可运行的模拟环境把所有还没能还原的部分诚实地留在原地。Mitra-15 也许不会有太多人天天使用但它值得这些反复尝试。如果你也正准备为某台冷门机器写模拟器不用急着删掉 Work in Progress 这几个字。先把已经弄清楚的逻辑跑起来再把还没弄清楚的部分交代清楚这本身就是对远古数字世界最好的保存方式。
返回列表