PlayStation的CD格式
来源:互联网 发布:环保工作有哪些 知乎 编辑:程序博客网 时间:2024/05/16 07:36
前言
本文的内容算是一个学习笔记,主要资料来源于张晓波(pinokio)翻译的《Everything You Have Always Wanted to Know about the Playstation But Were Afraid to Ask.》,这个资料Agemo的主页那边有下载,在【新手必读硬件资料】目录下面。里面有两个章节和CD有关,一个是CDROM,另一个是CD,其中CDROM主要讲PS中和CD相关的各种指令和设置。CD这章才描述CD格式,另外这一章并不存在于原版的《Everything》中,应该是pinokio自己整理的PS CD格式资料。
关于CD格式,要分成三个部分来说,首先是扇区格式,然后是光盘结构,最后是文件系统。这些内容都在CD这一章节中,但是光盘结构这部分描述得不太清楚,本文会略做详解。实际上这三部分是由不同的标准制定的。比如扇区格式、光盘结构等来自于Sony和Philips等大公司制定的彩虹书(Rainbow Book),文件系统使用的是ISO9660,它们各有各的渊源。
扇区格式
首先来说一下扇区格式,PS使用的扇区格式包括Mode2 form1和Mode2 form 2,这两个格式的大小都是0x930,区别在于form1包含ECC(纠错码),用来保存重要的数据,那么实际存放数据的大小只有0x800。form2仅含有EDC(检错码),适合用来存放视频、音频之类的数据,相应的也多出了ECC的276个字节。
下面具体的看一下这两个格式的构成:
类型 #2: Mode 2 (XA), form 1
-----------------------------------------------------
0 1 2 3 4 5 6 7 8 9 A B C D E F
0000h 00 FF FF FF FF FF FF FF FF FF FF 00 [-ADDR-] 02
0010h [--FLAGS--] [--FLAGS--] [---DATA...
...
0810h ...DATA---] [---EDC---] [---ECC...
...
0920h ...ECC---]
-----------------------------------------------------
类型 #3: Mode 2 (XA), form 2
-----------------------------------------------------
0 1 2 3 4 5 6 7 8 9 A B C D E F
0000h 00 FF FF FF FF FF FF FF FF FF FF 00 [-ADDR-] 02
0010h [--FLAGS--] [--FLAGS--] [---DATA...
...
0920h ...DATA---] [---EDC---]
-----------------------------------------------------
注:
ADDR: 扇区地址,用BCD编码成 分:秒:帧
FLAGS: 在Mode 2 (XA)扇区中用来描述扇区类型,冗余重复一次
DATA: 扇区里包含实际数据的区域
EDC: Error Detection Code检错码
ECC: Error Correction Code纠错码
上面这些内容来自pinokio的文档,值得注意的是ADDR的组成是分:秒:帧(原文是sector,扇区,而且这个单位一般称作分秒),具体的换算是1 minute = 60 seconds = 4500 sectors, 1 second = 75 sectors。光驱头一秒读取75个扇区叫做1倍速,有时候也称1倍速是150k/s,但这要看扇区格式是什么,所以这个说法并不准确。
这两个扇区格式来自于Sony和Philips制定的Yellow Book和White Book,Mode1来自于Red Book,这些标准还有不少,统称Rainbow Book。不过这些标准并不是公开的(要花钱买),所以也没有参考文档。我所能知道也就是pinokio文章中所提到的那些,这里不再赘述了。
光盘结构
块
描述
额外信息
000000-000015
数据轨引导块
共16个扇区
000016-024520
数据轨程序区
Mode2 Form1或2
024521-024670
数据轨后空隙
最少150扇区
024671-024820
第1音轨前间隙
最少150扇区
024821-048326
音轨#1
048327-048476
第2音轨前间隙
0或150扇区
048477-072485
音轨#2
. .
191281-191430
第9音轨前间隙
191431-214349
音轨9
214350-??????
导出轨
由刻录机写入,不可读
这段内容是CD章节的第一部分,原文应该来自PSX CD-Info,也可以参考。
但我觉得解释并不太明确,不能解释我的一些疑问,所以从网上找了一些资料。
首先打开一个PS光盘镜像,你可以看到第一个扇区的时间是0:2:0,而看pscx的源代码,也能看到他直接读取0:2:16来获取root的信息。那么为什么从0:2:0开始?其实文章也提到“有的raw镜像在最前面还包含有光盘导入轨,是一片连续的空白扇区,忽略它”。我很怀疑这个说法,前面的2秒(150扇区)应该是pre-gap。一个光盘一般包括一个导入轨,若干个数据轨和一个导出轨,数据轨编号从1开始,最多可以有99个。每个数据轨的前后可以有pre-gap和post-gap,gap的大小一般是150扇区,也就是2秒。这些间隙的功能其实是提示系统扇区模式发生变化,也是为了给系统转模式提供缓冲时间(同一个轨道内的扇区模式必须一样,似乎form可以不一样(?))。那么如果扇区模式没有变化,其实并不需要gap,这就是为什么上表中音轨之间的gap是0或者150扇区。另外,数据轨的post-gap和音轨的pre-gap虽然都是空白,但是它们的mode其实不一样。
上表还有一个容易混淆的地方,首先它将数据轨分成了3块,boot block,program area和post-gap,其实16扇区的boot block是ISO 9660的标准,这个见下节,并不需要写在这里。这种分法容易和光盘的结构搞混。光盘其实分成leadin,program和leadout(导入区,节目区和导出区,其实也就对应一个导入轨,若干个数据轨和一个导出轨,这个说法也不够准确,应该是一个session包含这3部分,一般光盘都是单session的,也有多session的光盘),这里故意写英文是因为boot(引导区)和leadin(导入区)中文看起来十分的相像。另外program其实是节目的意思,因为CD一开始就是放歌曲的。一首歌一轨道,轨道的概念也是源自于此。数据CD往往就一轨了事了,我看到的PS光盘大多如此。
关于音轨我也有点疑惑,首先音轨其实是一个特殊的概念,“每个扇区各存放588个立体声取样数据,无模式之分”,而且必须放在最后。PS光盘的扇区格式必须是mode 2 form 1/2,可能是有些特殊的游戏光盘使用了音轨。
下面说一下导入轨,导入轨包含TOC(Table Of Content,内容表),指出每个数据轨的起点。所以不可能是连续空白的扇区。但是一般的ISO镜像并没有导入轨,ccd文件中内容也许就是导入轨的内容。
这里总结一下,首先CD可以由多个Session组成,每个Session包括三个部分:导入区,节目区和导出区。导入区只包含一条导入轨,里面有TOC,包含该Session中的每个数据轨的信息。节目区中则可以有多条数据轨,数据轨前后可以有间隙,一般原则是前后模式不同则加间隙给读取设备缓冲。导出区只包含一条导出轨,里面没有内容,只是标明结束。
文件系统:ISO 9660
接着说一下文件系统,ISO 9660是为CD制定的标准,Yellow Book,White Book等与之兼容。PS使用的是ISO 9660 level 1。和level 2、3相比,要求限制更加多一些,比如文件名、目录名使用字符和长度限制。
ISO 9660来源于High Sierra,1986年被ECMA采用并修改成为Ecma-119,提交到ISO后成为了ISO 9660:1988,目前最新的版本是ISO 9660:1999。
所以本章的参考文档是Ecma-199。不过下面还是称呼为ISO 9660。
ISO 9660分成两部分,系统区和数据区。
1. 系统区
指0-15这16个扇区,叫做系统区是因为这部分是给系统使用的,比如VCD,就是给VCD机使用,是PS就是给PS机用,里面存放什么东西,什么格式,都是由各个系统决定的。
这里说的0-15,指的是0:2:0开始的数据,应该是以第一条数据轨作为起点,之后的extent都是以此为起点。
PS的系统区前5个扇区包含区域信息,有JAP,EUR和USA三种。
2. 数据区
从扇区16开始,之后有4种描述符来描述数据区存放的数据:
l 卷描述符
l 文件描述符
l 目录描述符
l 路径表
1. 卷描述符 Volume Descriptor
卷描述符分成5种,但是我只看到过主卷描述符(Primary Volume Descriptor)和卷描述集终止符(Volume Descriptor Set Terminator)。
下面主要说一下主卷描述符,我找一下相关的代码,在各种linux源码中基本上都有iso_fs.h之类的文件,里面就有相关的定义。一般如下:
typedef struct iso_primary_descriptor {
U8 type [ISODCL ( 1, 1)]; /* 711 */
U8 id [ISODCL ( 2, 6)];
U8 version [ISODCL ( 7, 7)]; /* 711 */
U8 unused1 [ISODCL ( 8, 8)];
U8 system_id [ISODCL ( 9, 40)]; /* achars */
U8 volume_id [ISODCL ( 41, 72)]; /* dchars */
U8 unused2 [ISODCL ( 73, 80)];
U8 volume_space_size [ISODCL ( 81, 88)]; /* 733 */
U8 unused3 [ISODCL ( 89, 120)];
U8 volume_set_size [ISODCL (121, 124)]; /* 723 */
U8 volume_sequence_number [ISODCL (125, 128)]; /* 723 */
U8 logical_block_size [ISODCL (129, 132)]; /* 723 */
U8 path_table_size [ISODCL (133, 140)]; /* 733 */
U8 type_l_path_table [ISODCL (141, 144)]; /* 731 */
U8 opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
U8 type_m_path_table [ISODCL (149, 152)]; /* 732 */
U8 opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
U8 root_directory_record [ISODCL (157, 190)]; /* 9.1 */
U8 volume_set_id [ISODCL (191, 318)]; /* dchars */
U8 publisher_id [ISODCL (319, 446)]; /* achars */
U8 preparer_id [ISODCL (447, 574)]; /* achars */
U8 application_id [ISODCL (575, 702)]; /* achars */
U8 copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
U8 abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
U8 bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
U8 creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
U8 modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
U8 expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
U8 effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
U8 file_structure_version [ISODCL (882, 882)]; /* 711 */
U8 unused4 [ISODCL (883, 883)];
U8 application_data [ISODCL (884, 1395)];
U8 unused5 [ISODCL (1396, 2048)];
}ISO_PVD;
解释一下后面的注释,如711,指的是ecma-119中的7.1.1所描述的数据类型,dchar等也在第7章有说明,请自行查找。
其中比较重要的两个字段是type_l_path_table和root_directory_record,其中前者指向path table,这张表共有4份,区别在于大尾小尾的不同。root_directory_record则直接存放了根目录的信息,注意并不是一个指向directory_record的指针。
2. 文件和目录描述符
这两个描述符都统一在directory record结构中。
typedef struct iso_directory_record {
U8 length [ISODCL ( 1, 1)]; /* 711 */
U8 ext_attr_length [ISODCL ( 2, 2)]; /* 711 */
U8 extent [ISODCL ( 3, 10)]; /* 733 */
U8 size [ISODCL (11, 18)]; /* 733 */
U8 date [ISODCL (19, 25)]; /* 7 by 711 */
U8 flags [ISODCL (26, 26)];
U8 file_unit_size [ISODCL (27, 27)]; /* 711 */
U8 interleave [ISODCL (28, 28)]; /* 711 */
U8 volume_sequence_number [ISODCL (29, 32)]; /* 723 */
U8 name_len [ISODCL (33, 33)]; /* 711 */
U8 name [0];
} __attribute__((packed)) ISO_DR;
文件的入口和大小分别定义在extent和size中。ISO 9660中所有文件都是连续的,所以只要起始扇区和扇区数量就可以确定一个文件。要注意的是extent的单位是扇区,如果要转成时间的话需要额外加上2秒,size的单位则是字节。目录也被当成一个特殊的文件来看待,目录中保存的信息就是directory record列表,所以这种结构是树状的,只要给出root,就能一层层遍历所有的目录和文件。
3. 路径表
路径表的表项定义如下
typedef struct iso_path_table{
U8 name_len [ISODCL ( 1, 1)]; /* 721 */
U8 ext_attr_length [ISODCL ( 2, 2)]; /* 711 */
U8 extent [ISODCL ( 3, 6)]; /* 731 */
U8 parent [ISODCL ( 7, 8)]; /* 721 */
U8 name [0];
} __attribute__((packed)) ISO_PTR;
这张表只保存目录,而且各级目录都放在这张表中,只用一个parent加以区别。用这张表应该可以更快捷的定位。
实用
上面这些内容看起来有些枯燥,那么下面举一些具体实用的例子,帮助巩固一下。
1. Agemo的iso patch
这个软件叫做iso patch,但实际是对Yellow Book的扇区标准进行支持。主要功能是给定地址,文件后,可以将目标文件写入到iso镜像中,并且自动重算ECC和EDC。对Mode1也支持,但是PS不使用这个标准,Mode 2 Form 2则未经测试。所以基本上有用的就是默认的Mode 2 Form 1了。
要使用这个软件,首先要给出文件在光盘中的地址。有两种方法可以使用,一个是从root directory record开始,遍历所有文件,然后找到extent字段,把这个字段乘上0x930(2352),再加上0x18(Header部分),才是这个文件真正开始的地方。另一种方法也类似,就是遍历path table,也可以找到所有的文件。
程序pscd的算法就是遍历path table,里面略微麻烦一些的地方是path table可能跨多个扇区,需要进行一些操作。所以编写这个程序要对扇区格式,Primary Volume Descriptor和path table有一些了解。
Agemo专门写过一篇文章《PS光盘格式简介》,也可供参考。
2. debugger的filelist
Agemo_debugger有cdrom read monitor功能,显示如下:
cdrom $80045800 <- 64:53:06($473f7), 2048 bytes
其实这个显示的可读性还是很差,我略微修改了一下,程序可以读取filelist目录下的文件列表,在显示的时候,可以直接显示文件名。文件列表格式如下:
// 文件名,起始扇区,大小(扇区数),大小(字节数)
INIT.BS,00ce,0010,7e64
暂时只有前3个数据有效,这个文件的构造方法和上面几乎一致,唯一的区别就是要通过size来计算占用的扇区数。另外有些游戏将很多文件都打包在一个大文件中,如果找到入口表就能写代码生成各个子文件的地址,方便调试。
历史:
第一版:2010年9月25日9:29:38
- PlayStation的CD格式
- Playstation 3的编程环境比Playstation 2显著改善
- PlayStation Portable开发环境的搭建
- Sony playstation 2 游戏机的程序开发网
- 如何获得免费的Playstation 3(PS3)
- svg格式的中国地图轮廓图,用cd画的,有需要的拿
- 喜欢听音乐CD的请进:[技术贴]介绍APE+CUE格式的音乐文件
- 把CD上的一个图保存为bmp格式的图
- linux下的su,su -,以及cd,cd - ,cd ~总结
- DTS CD转出为MP3格式
- linux下cd 和cd /的区别
- 我喜欢的CD
- 订购的CD到了
- 年末的CD收获
- CD review的注意事项
- cd的替代命令
- cd的用法小结
- 强大的cd命令
- 如何选择最适合的Linux版本
- MyEclipse Java Project、Web Project 、Web Service Project的区别
- const到底是什么 二. 基本用法
- 少儿英语趣味小精灵软件界面收录
- 详细分析Linux服务器内存
- PlayStation的CD格式
- vc开发一些处理
- 字典树
- 心情
- 循环双击文字出现编辑文本框的JS代码(csdn 自己回贴处理的JS)
- 猴王算法精简版 Python实现
- 人生的第一篇博客要献出去了!
- JavaScript版本一览
- window.open 与 window.showModalDialog比较