物理 C64调制编码方式

1980年左右,家用电脑时代,许多电脑都使用FSK(频移键控)对磁带上的“1”和“0”进行编码,每个“1”和“0”使用不同的频率,例如堪萨斯城标准。Commodore Datassette 使用了一种脉冲长度编码,《PET 揭秘》称其优于 FSK。
有三种类型的脉冲可供使用:
- 短 176 µs 脉冲(2840 Hz)
- 中等256 µs脉冲(1953 Hz)
- 长 336 µs 脉冲(1488 Hz)
NTSC和PAL制式机器的脉冲持续时间有所不同。由于 NTSC 时钟频率大约快 3.8%(NTSC 为 1.0227273 MHz,PAL 为 0.9852486 MHz),因此 PAL 脉冲长度也长 3.8%。不过,在 NTSC 和 PAL 制式的 C64 机之间交换磁带没有问题。磁带马达的速度也不同,因此数据解码过程中集成了同步算法。
不同的 PAL 脉冲长度和频率为:
- 短 182.7 µs 脉冲(2737 Hz)
- 中等265.7 µs脉冲(1882 Hz)
- 长 348.8 µs 脉冲(1434 Hz)
NTSC 机器上字节标记的计算持续时间为 1184 µs,而在 PAL 系统上则为 1229 µs。
读取信号与写入信号反相。写入信号的脉冲宽度是在上升沿之间测量的,而读取信号的脉冲宽度是在下降沿之间测量的。
实际上,脉冲以相应频率的一个完整周期出现,因此短脉冲为 176 µs 的高电平和 176 µs 的低电平等。
位值和所需标记通过两个脉冲周期的组合进行编码。
- 位值“0”被编码为一个短脉冲周期,随后是一个中等脉冲周期
- 位值“1”被编码为一个中等脉冲周期,随后是短脉冲周期
- 字节标记被编码为一个长脉冲周期,随后是一个中脉冲周期
- 数据结束标记被编码为一个长脉冲周期,后跟一个短脉冲周期
字节编码
数据集字节编码
字节标记指示字节的开始。位记录方式为,最低有效位 (LSB) 先记录,最高有效位 (MSB) 后跟奇偶校验位(奇校验)。
“奇校验”是指数据位加上校验位后“1”的数量为奇数。例如,对于 00100010(1 的数量为偶数),校验位为 1;对于 00000111(1 的数量为奇数),校验位为 0。奇校验是通过对“1”和所有 8 个有效载荷位 进行顺序异或运算生成的。
每个字节的记录持续时间为 8.96 毫秒。
数据块编码
文件和数据块的结构
192字节的有效载荷在一个块中存储两次。除了校验和之外,这还用于检测由于自动丢失而导致的数据完整性问题。
每个数据块都以一个短脉冲(NTSC 制式为 2840 Hz)的同步前导开始。该前导可以是第一个数据块的 10 秒,也可以是每隔一个数据块的 2 秒。前导为磁带电机提供了达到正确速度的时间。此外,由于磁带速度可能因电机而异,内核在此期间会计算速度校正系数。正因如此,尽管 PAL 和 NTSC 的时钟频率不同,但在不同系统之间交换磁带仍然没有问题。
每个有效载荷数据块前面都有一个倒计时字节序列。倒计时字节序列在有效载荷数据的第一个副本中设置 MSB,计数范围从 $89 到 $81;在有效载荷数据的第二份副本中清零 MSB,计数范围从 $09 到 $01。
每个数据块后面跟着一个单字节校验和。校验和是通过对 $00 和所有有效载荷字节进行异或运算计算得出的。
记录间间隙以一个长脉冲周期开始,接着是 60 个短脉冲周期(2840 Hz)。
数据结束标记是一个可选符号,标记最后一个数据块。
标题块
标头块是文件中的第一个数据块,长度恰好为 192 字节。标头有效负载由文件类型、起始和结束地址(用于某些标头类型)以及文件名组成。
字节 | 长度 | 内容 |
---|---|---|
1 | 1 | 标头类型 |
2 | 1 | 起始地址(低字节) |
3 | 1 | 起始地址(高字节) |
4 | 1 | 结束地址(低字节) |
5 | 1 | 结束地址(高字节) |
6 - 21 | 16 | 文件名,显示在 FOUND 消息中 |
22 - 192 | 171 | 文件名,未显示在 FOUND 消息中 |
如果文件名少于 16 个字符,则会用空格填充(ASCII:$20)。第 22 到 192 个字节通常用 $20 填充。如果文件名长度超过 16 个字节,则 FOUND 消息中仅显示前 16 个字符,所有其他字符仍然有效,但不会显示在 found 消息中。不过,可以使用PEEK指令访问这些字符。
标头类型
价值 | 标头类型 |
---|---|
$01 | 可重定位(BASIC)程序 |
$02 | ASCII/顺序文件的数据块 |
$03 | 不可重定位程序(通常是机器语言) |
$04 | ASCII 文件头 |
$05 | 磁带末端标记 (EOT) |
标题类型 $01
此头文件类型表示可重定位程序。通常,这些程序是 BASIC 程序,它们不需要位于特定地址。这些程序会加载到 BASIC RAM 的起始位置。
标题类型 $02
此类型表示顺序 (ASCII) 文件的数据块。字节 1-192(共 191 个字节)包含有效负载数据。此块不使用起始地址和结束地址。
标题类型 $03
此类型表示不可重定位程序 - 通常是机器语言程序或包含机器语言部分的程序。它们需要加载到特定的起始地址。
标题类型 $04
此类型表示 ASCII 文件的头部。除了头部类型之外,此块的有效负载还包含文件名。
标题类型 $05
此类型表示磁带结束块。如果在到达包含所需文件名的头之前就到达了磁带结束块,则会报告 “设备不存在”错误。
标头类型和辅助地址
保存或打开文件进行写入时使用的辅助地址会影响磁带上记录的标题类型。
程序
载入中
LOAD"Name",1 | 在 BASIC 内存的起始地址处加载一个头文件类型为 $01 的程序。类型为 $03 的程序将被加载到记录的起始地址处 |
---|---|
LOAD"Name",1,1 | 始终将程序加载到记录的起始地址 |
保存
SAVE"Name",1 | 保存标题类型为 $01 的 (BASIC) 程序 |
---|---|
SAVE"Name",1,1 | 保存一个(机器语言)程序,标题类型为 $03 |
SAVE"Name",1,2 | 保存一个(BASIC)程序,其标题类型为 $01,并带有一个附加的 EOT 块 |
SAVE"Name",1,3 | 保存一个带有标题类型 $03 的(机器语言)程序,并附加一个 EOT 块 |
打开和 ASCII 文件
OPEN1,1,0,"Name" | 打开文件进行读取 |
---|---|
OPEN1,1,1,"Name" | 打开文件进行写入 |
OPEN1,1,2,"Name" | 打开一个文件,使用附加的 EOT 块进行写入 |