简介最具标志性的软盘保护故事之一是“地下城大师”。1987年12月发布的“地下城大师”将先进的物理光盘格式(模糊位)与嵌入游戏本身的偷偷摸摸的保护检查相结合。
我强烈推荐这篇文章,在对雅达利圣地牢主盘上的模糊位保护进行非常全面的概述之前,这篇文章给出了一个很好的软盘概述。还有这篇优秀的文章,它更深入地讲述了围绕着地牢大师保护的故事。它引用了一位“地下城大师”作者的话:
我们的优势是拥有软盘复制保护方案的专利,该方案需要40,000美元的专门硬件设备才能写入磁盘。如果没有这个硬件,就不可能创建磁盘映像,而且硬件本身也已停产。
高价标签的原因很可能是可靠地创建模糊位所需的定时精度。所需的精度是在世界上大部分地区仍在以微秒为单位进行测量的时候,以纳秒为单位测量的。
BBC Micro有一个2 MHz6502CPU,它最简单的指令需要2个周期,也就是1微秒。在这样的约束下,有没有希望写出模糊位呢?我们看看能走多远。这项工作被称为“涂油的水獭”项目。
为了让我们进入气氛,并结束介绍,这里有一张3.5;软盘复印机的图片。它看起来很像复印机,这让我觉得很好笑,只是漏斗拿的是光盘而不是纸张!看起来Advanced World Products甚至可能还会卖给你一台。
BBC Micro以出色的可扩展性而闻名,包括所谓的用户端口。此端口由运行速度为1 MHz的6522多功能接口适配器驱动。端口本身提供8个数据引脚和2个控制引脚。对这些别针有很大的控制权。数据引脚可以单独配置为输入或输出,输出逻辑电平可以根据需要设置为高或低。
我们为什么要查看用户端口?那么,我们将尝试直接从用户端口驱动磁盘驱动器。通过将软盘控制器从等式中移除,我们希望将其排除在外,并实现对磁盘驱动器及其来往数据流的更直接控制。
上图是连接用户端口和磁盘驱动器的可爱电缆。连接器是标准的,它们之间的导线只是跳线。我诚心诚意地想要创造一些在前一天就能做到的东西,现在我不允许任何额外的电子产品。
从这种布线设置中得到的主要好处是,光盘驱动器接口可能比您想象的要简单。我们只需8个引脚就可以驱动光盘驱动器并查询其重要状态。这很简单。假设您要启动驱动器,请将PB0和PB1上的逻辑电平设置为低。假设您想要等待光盘旋转到轨道的起始处,您可以查询PB6上的逻辑电平,直到您看到高-低转换。步进只是为步进与步出设置一个逻辑电平,然后降低步长引脚。
到目前一切尚好。我们已经基本控制了驱动器,但还没有写入任何内容。
简短地说一下电击头疼是有必要的,因为我碰到了一些。将随机的组件对连接在一起有时可能会起作用,有时可能需要精心处理。以下是最初在驱动器的W/Data引脚上看到的电压示波器视图:
逻辑1电压约为3.4V,逻辑0电压约为1.5V。这是一个严重的问题!可接受的TTL电压电平定义良好:
当相对于接地端子在0V和0.8V之间时,TTL输入信号被定义为低,当在2V和Vcc(5V)之间时,TTL输入信号被定义为高,并且如果在0.8V和2.0V之间的电压信号被发送到TTL门的输入,则门没有确定的响应,因此它被认为是不确定的。
1.5V的逻辑0电压被认为是不确定的,而且根本不会。事实上,我正在使用的驱动器没有使用上述信号写入任何内容。
已通过从驱动器上卸下软线终端电阻器解决此问题。这是一张我的驱动器的照片,插入式终端电阻器阵列用红色圈起来:
这完美地解决了电压电平问题,然后一切都能正常工作。它似乎比许多BBC Micro的端口(除了光盘端口)没有足够的吸引力来驱动端接的电缆。但是等一下--大概这个电阻器一开始就是有原因的吧?是。移除它有两个警告:
注意您的电缆长度。较长的电缆在未端接时容易导致信号恶化。
注意未连接的电线上的电压电平。我在驱动器的S/SEL(侧选择)引脚上看到1.32V的电压电平。这是不好的,因为它再次处于TTL的不确定范围内。驱动器将在哪里写入数据?可能是上边,也可能是下边。或者两个都不是,或者两个都不是!这是通过连接每根重要的导线并根据需要将其驱动到高或低来解决的。
房间里的问题是:我们如何向W/Data引脚提供信号?这是硬销。它具有高带宽和精确的定时要求。让我们暂时停止对纳秒级模糊位的幻想,尝试将基本的调频脉冲写入驱动器。
大多数BBC微盘都是调频(又名。又名DFM。单密度)以250 kHz编码。要写一首调频曲目实际上是相当简单的。确保驱动器正在旋转并且写入门已打开。现在,每隔4微秒,脉冲W/DATA低,然后回到高(1位)或不高(0位)。大多数情况下,每隔一位必须为1(维持时序和同步的时钟位)。
使用CPU驱动W/DATA是没有希望的。4微秒等于8个CPU周期--当然不足以加载一个字节,将其移位,然后将0和1写入用户端口逻辑电平。一个简单的循环很可能是12微秒以上,这远远超出了范围。相反,为了希望足够快地驱动W/DATA,我们必须考虑6522 VIA芯片的功能。
我们的任务最明显的候选者是移位寄存器。移位寄存器是8位寄存器。在适当模式下,加载移位寄存器将导致芯片通过用户端口的一个引脚顺序发出8位。这很好--这些位是与主CPU的执行并行处理的,所以CPU可以自由地花时间计算下一组要开始移位的位。
不幸的是,我无法让它工作。唯一有可能足够快的移位模式是以系统时钟速率移出。西部设计中心6522数据表有一个很好的图表:
VIA系统时钟为1 MHz,因此移位时钟将是500 kHz信号,我们可以输出的位的分辨率为250 kHz。那正好够了。然而,我没有想出如何让轮班时钟连续而平稳地运行。即使尝试重新加载移位寄存器的精确时序,移位时钟引脚的示波器输出始终如下所示:
看起来,在仅有的足够快的移位模式中,重新加载移位寄存器在移位恢复之前会导致延迟。这是不合适的。
6522的一个鲜为人知的特点是它的脉冲输出模式。并不是每个6522版本的数据表都涵盖了它,但以下是MOS技术数据表中的一个小条目:
这一次,数据手册似乎准确地描述了行为。我们对这种模式非常感兴趣,因为对通孔的一次写入承诺了两种截然不同的效果:输出引脚将变为逻辑低电平,然后在1个周期(1微秒)后再次升至逻辑高电平,无需我们做进一步的工作。正因为如此,用它来驱动250 kHz的输出信号是很容易处理的。CPU非常紧凑;循环是不可能的,但是线性6502代码块可以做到这一点,例如:
这很管用。CPU的马力正好可以做到这一点。8个周期是4微秒,这是盘脉冲之间的最短时间。
不幸的是,它非常占用内存。每个FM编码比特需要2字节的线性6502码。一个有用的数据比特是2个FM比特,因为每隔一个比特是一个时钟比特。轨道为3125字节,因此这需要3125*8*2*2==100KB的线性代码。BBC Micro有32KB的RAM,所以我们在这里不走运。可以写入单个(较小)扇区,包括一些功能强大的新型磁盘保护机制。但我们不能写入大(1024字节)扇区或完整磁道。要正确写入许多光盘,这两件事都是必需的。此外,我们的定时分辨率为1微秒,不足以写入许多高级保护和光盘表面。
考虑到这些限制,我们可以很高兴我们得到了一些正在工作的东西,但这并不是一个完全令人满意的解决方案。
幸运的是,我和像移位者集体这样的聪明人在一起。(请马上去看最新的演示,邪恶的影响!)。在一次斯拉克的谈话中,汤姆·塞登(b2仿真器的作者)建议.。使用RGB端口的输出??
一开始我可能会对这个想法嗤之以鼻,但我越仔细思考,它似乎越有可能实现。BBC Micro使用6845视频芯片进行计时。和6522一样,它也是一只古怪的野兽,但至少人们很好地理解了它的怪癖,因为比特移者的演示滥用了6845。我还做了一些反向工作,使jsbeeb仿真器正确地模拟日立6845。让我们看一下这段视频中涂了油的水獭的工作情况,然后描述一下我们看到的情况:
它是通过异常配置6845芯片来工作的。6845的运行频率为1 MHz,帧定时设置为每帧32微秒/32字节扫描线。当输出每一帧时,6845的视频存储器寄存器被重写,以便从可能不同的位置获取下一个32字节。因此,每隔32微秒,从输出图案表中选择不同的输出图样。我们已将RGB引脚配置为每微秒发射8个像素,即每个输出图案256个像素。这提供了大量不同的可能输出模式。但是,由于我们正在编写32微秒的磁盘调频编码块,因此只有几个模式有意义。在32微秒内,我们可以容纳8个FM脉冲/位。4比特是时钟比特,通常都是1.4比特。4比特是数据比特,其中只有16个组合。
例如,如果我们正在写入数据半字节0x5,则32微秒的输出需要如下所示:
视频数据字节将为00FFFFFFFFFFFFFF00FFFFFF00FFFFFF00FFFFFFFFFFFFFF00FFFFFF00FFFFFF.。第一个、第二个、第四个和第五个00是时钟位。在时钟位之间的是数据位模式0101或0x5。
CPU和内存限制很好地平衡了。最后,这是一种类似于VIA移位寄存器工作的设置:一些小型协处理器(视频芯片)忙于发出一串调频比特,而CPU则被释放出来加载并提供下一种模式。内存要求非常合理。由于使用了特殊的线性寻址模式,所需的32微秒输出块的表可以轻松地容纳在1024字节内。整个曲目的查找索引列表大约是12kB,所以一切都很适合BBC Micro的32KB内存。
当然,要让它正常工作,不是没有被一些有趣的怪癖绊倒的。第一个是6845的怪癖,它为每个扫描线的最后一个字符输出黑色。它似乎既是唱片先驱,也是演示作家的祸根。这是我最近的一次演讲中的一张幻灯片,展示了这个问题:
在左边,有一个演示效果,由于最后一个字符/列是黑色的问题而被垂直的黑色条纹所困扰。多条6845条扫描线被放置在单个光栅光束扫描线内,不幸的是,黑色条纹是不需要的。当用来驱动光盘时,效果可能更差:黑色条纹代表写入光盘的不需要的脉冲。
在右边,有一张解决方案的图像:提交给光盘的波形被简单地反转。现在可以将最后一列设置为黑色(以橙色轮廓显示),因为那里始终需要零值。从技术上讲,这违反了将W/DATA设为低脉冲的一些光盘驱动器的时序要求。这是一个时代驱动的时序图,三菱M4852/M4853:
根据该图,逻辑0应保持2100 ns。对于反向波形,预期为3000 ns以上。但是,我所使用的驱动器只关心负向数据脉冲,而不关心保持时间。这并不令人惊讶。这将是可能的周围抖动一些事情,以避免6845怪异,也提交规范保持时间,但这并没有被证明是必要的,所以它没有进行。
DRAM腐烂是一件可怕的事。这是当您刷新DRAM失败时发生的情况。摘自维基百科关于记忆刷新的文章:
";此过程由存储电路在后台自动执行,并且对用户是透明的。";
在现代系统上是可以的,但在BBC Micro上就不是这样了。在BBC Micro上,DRAM刷新是视频子系统的副作用。它依赖于这样一个事实,即标准屏幕模式在短时间内遍历所有DRAM行。也许你能看到这是怎么回事……。我们用于输出32微秒帧的特殊视频模式非常不是标准的屏幕模式。它不能保证访问所有DRAM行,因此会发生DRAM衰减!DRAM腐烂可不是闹着玩的。由于意外的DRAM衰减,我丢失了各种程序和光盘内容。为了搞笑,下面是一个基本的程序,它会在不到一秒的时间内导致DRAM自身衰变:
DRAM衰减的坏消息是,如果你被它咬了,你很容易丢失数据。
关于DRAM衰变的好消息是,如果您期待它,您通常可以很容易地解决它。在涂油的水獭的情况下,6845视频芯片处于不寻常的状态,存在各种关键循环。对于其中的每一个,都使用手动递增的内存获取来保持DRAM刷新。
现在我们有了一个可以正常工作的光盘写入系统,绕过了软盘控制器,我们能用它做什么呢?我们已经在上面的视频中演示了写入任意FM编码光盘的能力。
但我们在这段旅程中获得了非常幸运的机会。由于威盛移位寄存器的不足迫使我们寻找视频输出引脚解决方案,我们可以在W/DATA引脚上获得更精细的定时分辨率。我们使用的是BBC Micro MODE4,它使用8 MHz像素时钟。这意味着我们可以每125 ns输出一次黑色或白色像素,从而触发125 ns粒度的写入脉冲。如果我们想在更大的表上花费一点额外的内存(我们确实有),我们可以使用MODE0,它使用16 MHz像素时钟,提供62.5 ns的分辨率。125 ns已经被证明对所有测试的磁盘保护都很好,但是有一点留在水箱里是一种很好的感觉。
我最喜欢的光盘保护是长磁道保护。它在阿米加时代很流行。我不相信它曾经在BBC Micro上使用过。我喜欢长磁道保护,因为它是非常基本的:软盘控制器对不同的读取速度有广泛的容忍度(因为磁盘驱动器以不同的速度旋转),但它只以一个正确的速度写入。
高级长磁道保护是在同一磁道上写入两个扇区,其中一个扇区以更快的速率记录。复制保护检查是比较读取两个扇区所花费的时间。以较快速率记录的扇区读取速度应可测量且明显更快。
涂了油的水獭能写出这样的音轨吗?是的,相当容易。考虑到125 ns的输出分辨率,很容易创建几个输出表项,这些表项与普通表项相似,但每1微秒就会减少125 ns。以下是创建长磁道保护并检查其读取方式的视频:
我们可能早就应该回到我们开始的地方了:模糊位保护。涂油的水獭能在1981年的技术上制造模糊的比特吗?让我们试一试吧。这里是一张用油制水獭的fuzz命令写入扇区几次后读取该扇区的结果的图像。
fuzz命令写入0x8数据半字节,数据位逐渐延迟125 ns增量。这类似于描述地下城主控模糊位是如何写入的。如截图所示,0x88数据字节很快开始回读不正确且不确定的内容。但是方差不是100%随机的,不像弱位那样--方差是0x8位是否晚到有机会被错过。如果错过了,你仍然可以看到有模式和主题的疯狂。
上述结果实际上是模糊比特原则对FM编码数据的应用。在FM编码中,每个数据位都与一个时钟位交织。这有时会导致时钟位大量流入数据流(参见上面第一次运行中的0xFF字节--它们很可能是时钟位)。地下城主保护结合MFM使用模糊位。这会导致更平静的情况,模糊位在两个有效的数据位编码之间漂移,并且不会扰乱时钟!当然,上了油的水獭可以编写MFM、GCR或任何你能想到的编码。对于我们的基本原语来说,这只是所有不同的协议,能够在任何时候以良好的分辨率向驱动器发送脉冲。
为了更好地衡量,这里是磁盘上模糊位的示波器视图。峰值有些不规则,当两个脉冲非常接近时(1微秒左右,对于任何编码标准来说都太近了),驱动器检测到的磁通反转的强度甚至开始变弱。
任务完成。我们获得了写入粒度为125 ns的盘脉冲的能力。这完全足以创建高级磁盘保护,包括长磁道、弱位和模糊位。对于1981年最快1微秒指令的硬件来说还不错!