Saturn A-BUS时序 ================ 时钟: 28Mhz左右 周期大约36ns 地址: 早于CS一个周期发出, CS结束后维持1到2个周期 RD: 早于CS一个周期发出, 在CS结束后一个周期结束 WR: 与CS一起发出 FC0/FC1: 普通读写时均为高. FC1: 非读写时,每14.32us出现一次. 疑似刷新周期. AAS: 与CS一样宽度 TIM0: 与地址一起发出.在CS结束前一个周期结束. TIM1: 在写数据时,与数据一起发出.与TIM0一起结束 TIM2: 在TIM1后一个周期发出.与CS一起结束 看起来TIM1用于数据周期指示. 写数据在WR开始后一个周期出现, WR0对应SS_DATA[ 7:0], WR1对应SS_DATA[15:8]. ABUS的CS2空间比较特殊: 1: ASR寄存器不能配置等待周期.ADDR[18-15]的值相当于等待周期配置. 2: CS2是32位空间,ADDR[19]用于选择空间类型: 0: 32位空间. 会进行连续两次的访问以返回一个32位的数据.(会发出A1) 1: 16位空间. 每次访问返回一个高16位数据. 低16位无法访问到.(A1始终为0) CDBLOCK模块, 用ADDR[14-12]作为高位地址, ADDR[5-2]作为低位地址. 00: DATA_PORT 08: HIRQ 0C: HIRQ_MASK 18: CR1 1C: CR2 20: CR3 24: CR4 28: MPEGRGB #define HIRQ_CMOK 0x0001 #define HIRQ_DRDY 0x0002 #define HIRQ_CSCT 0x0004 #define HIRQ_BFUL 0x0008 #define HIRQ_PEND 0x0010 #define HIRQ_DCHG 0x0020 #define HIRQ_ESEL 0x0040 #define HIRQ_EHST 0x0080 #define HIRQ_ECPY 0x0100 #define HIRQ_EFLS 0x0200 #define HIRQ_SCDQ 0x0400 #define STATUS_BUSY 0x00 #define STATUS_PAUSE 0x01 #define STATUS_STANDBY 0x02 #define STATUS_PLAY 0x03 #define STATUS_SEEK 0x04 #define STATUS_SCAN 0x05 #define STATUS_OPEN 0x06 #define STATUS_NODISC 0x07 #define STATUS_RETRY 0x08 #define STATUS_ERROR 0x09 #define STATUS_FATAL 0x0a #define STATUS_PERIODIC 0x20 #define STATUS_TRANSFER 0x40 #define STATUS_WAIT 0x80 #define STATUS_REJECT 0xff Saturn MemoryMap ================ 07ffffff +------------------+-----+ 06100000 +------------------+ | | WorkRAM_H: 1M | CS3 | 06000000 +------------------+-----+ 05fe00d0 +------------------+ | | SCU: 208 | | 05fe0000 +------------------+ | 05f80120 +------------------+ | | VDP2: 288 | | 05f80000 +------------------+ | 05f01000 +------------------+ | | VDP2: 4K | | 05f00000 +------------------+ | 05e80000 +------------------+ | | VDP2: 512K | | 05e00000 +------------------+ | 05d00018 +------------------+ | | VDP1: 24 | CS2 05d00000 +------------------+ | 05cc0000 +------------------+ | | VDP1: 192K | | 05c00000 +------------------+ | 05b00ee4 +------------------+ | | Sound: 1M | | 05a00000 +------------------+ | 05900000 +------------------+ | | ABUS CS2:1M | | 05800000 +------------------+ | | ABUS Dummy:8M | | 05000000 +------------------+ | | | | | ABUS CS1:16M | | | | | 04000000 +------------------+-----+ | | | | | | | | | | ABUS CS0:32M | CS1 | | | | | | | | | | 02000000 +------------------+-----+ 01800004 +------------------+ | | SINT: 4 | | 01800000 +------------------+ | 01000004 +------------------+ | | MINT: 4 | | 01000000 +------------------+ | 00300000 +------------------+ | | WorkRAM_L: 1M | | 00200000 +------------------+ | 00190000 +------------------+ | | SRAM: 64K | CS0 | 00180000 +------------------+ | 00100080 +------------------+ | | SMPC | | 00100000 +------------------+ | 00080000 +------------------+ | | ROM: 512K | | 00000000 +------------------+-----+ ========================================================================= SAROOO 土星地址端口: 基地址0x25807000 +00: 卡ID标志, 0x5253("SR") +02: 卡版本, 0x1101 -> 硬件1.1版,软件0.1版 +04: 卡控制寄存器 +08: 卡状态寄存器 +0c: 一个32位的计时器, 以1M的频率计数.0c是高位,0e是低位. +10: 发往STM32的命令寄存器. 写这个寄存器,STM32端会产生中断. 定义0x22800000开始的sdram空间,为土星和STM32交换数据的空间. 目前sdram空间不支持字节访问. +14: STM32与土星数据交换寄存器. +18: FIFO数据端口(只读). 卡控制寄存器: bit15: CDC寄存器使能. 为0时读的是系统的CDC寄存器. 为1时读的卡带自己的CDC寄存器. 此时系统应该处于CDOFF状态.否则读出的数据是错误的. 写CDC寄存器时,系统自己的寄存器和卡上的寄存器都会被写入.这提供一种手段让STM32可以 监控CDC的写入数据. bit13: bit12: CS0空间的类型. 00: Bootrom 01: data卡 10: 1M的RAM卡 11: 4M的RAM卡 bit8 : 控制LED1 卡状态寄存器 bit11: fifo满状态 bit10: ... bit0 : fifo数据计数 ========================================================================= SAROOO STM32地址端口 基地址0x60000000 +00: 卡ID标志, 0x5253("SR") (只读) +02: 卡版本, 0x1101 -> 硬件1.1版,软件0.1版 (只读) +04: 卡控制寄存器 +06: 卡状态寄存器(只读) +08: FIFO数据端口(只写) +0c: FIFO状态寄存器 +10: 土星CMD寄存器(写复位) +12: STM32与土星数据交换寄存器 +14: 土星控制寄存器(只读) +18: CDC的RESP1(只读) +1a: CDC的RESP2(只读) +1c: CDC的RESP3(只读) +1e: CDC的RESP4(只读) +20: CDC的CR1 | 读的时候是CRn寄存器 +22: CDC的CR2 | 写的时候是RESPn寄存器 +24: CDC的CR3 | +26: CDC的CR4 | +28: CDC的HIRQ(写1置位) +2a: CDC的HIRQ_MASK +2c: CDC的HIRQ(写1复位)(只写) +2e: CDC的MRGB(未使用) 卡控制寄存器 bit9 : fifo字节序: 0:小端 1:大端 bit8 : fifo复位. bit2 : FIFO中断使能. FIFO半空. bit1 : cmd中断使能. 土星写CMD寄存器,会产生中断. bit0 : cdc中断使能. 土星写CR4寄存器,会产生中断. 卡状态寄存器 bit15: FPGA的100Mhz时钟工作正常指示. bit14: ST_IRQ状态. bit12: in_cmd状态. 写CR1置位, 读CR4复位. bit2 : fifo中断状态.写1清楚中断状态. bit1 : cmd中断状态. 写1清楚中断状态. bit0 : cdc中断状态. 写1清楚中断状态. FIFO状态寄存器 bit11: fifo满状态 bit10: ... bit0 : fifo数据计数 土星端: 22000000-22400000 4M Saturn可用 22400000-22800000 4M ram卡用 22800000-22a00000 2M Saturn与STM32 可用 22a00000-23000000 6M STM32用 ========================================================================= 61800000-61820000 : 128K 存放扫描的disc信息 00000-01000: 存放disc路径指针, 共1024个. 01000-20000: 存放disc路径字符串. ========================================================================= 关于光盘的格式 -------------- 红皮书: CD-DA音频CD标准. 黄皮书: CD_ROM数据光盘标准. 是红皮书的扩展. CD-DA: 采样率44100Hz, 精度16bit, 双声道. 逻辑层: 每秒176400字节的数据.(44100x2x2) 一帧6次采样,共24字节的数据. 一个扇区98帧, 98x24=2352字节. 每秒包含75扇区. 176400/2352=75. 物理层: Frame1: 一帧的24字节的有效数据 Frame2: Frame1加上8字节的校验码 Frame3: Frame2加上1字节的控制数据,即subcode数据 Frame3再加上3字节的同步头(不经过EFM编码),经过EFM(8-14)编码,写入光盘介质上. 两个EFM编码之间另有3bit的间隔码. +----------+---------+-----------------+------+------------------+------+ | SyncBits | SubCode | LeftChannel | Qchk | RightChannel | Pchk | | 3 | 1 | 12 | 4 | 12 | 4 | 物理层 +----------+---------+-----------------+------+------------------+------+ .....24.3.....14.3.....14.3.14.3...14.3.14.3.....14.3.14.3........14.3... EFM物理层 subcode: 包含8个通道: P Q R S T U V W 一般分成3组: subcode-Q, subcode-P, subcode-RW subcode-P和subcode-Q包含一些控制信息. 可以实时恢复出来. subcode-RW存储图像等CD-DA扩展数据. MDF/MDS格式的镜像,可以包含这些信息. ISO/CUE等不包含. 默认读出为0. CD-ROM/XA: 对CD-DA的2352字节的逻辑层进行重新定义 0-11: 12字节的同步头: 00 FF FF FF FF FF FF FF FF FF FF 00 12-14: 扇区地址. 格式: MM(分钟) SS(秒) FF(Frame, 扇区) 15: 类型. 00: 全0的扇区. 一般用于标记光盘的Lead_in和Lead_Out区域 +------+------+------+ | Sync | Addr | Zero | | 12 | 4 | 2336 | +------+------+------+ 01: 用于存储数据 +------+------+------+-----+-------+-----+ | Sync | Addr | Data | CRC | Unuse | ECC | | 12 | 4 | 2048 | 4 | 8 | 276 | +------+------+------+-----+-------+-----+ 02: 用于存储音视频数据 +------+------+------+ | Sync | Addr | Data | | 12 | 4 | 2336 | +------+------+------+ 02: XA/Form1. 用于存储数据 +------+------+--------+------+-----+-----+ | Sync | Addr | SubHdr | Data | CRC | ECC | | 12 | 4 | 8 | 2048 | 4 | 276 | +------+------+--------+------+-----+-----+ 02: XA/Form2. 用于存储音视频数据 +------+------+--------+------+-----+ | Sync | Addr | SubHdr | Data | CRC | | 12 | 4 | 8 | 2324 | 4 | +------+------+--------+------+-----+ SubHdr: sub-header FN CN SM CI FN CN SM CI FN: File Number 本块属于哪个文件 CN: Channel Number 回放通道选择 SM: Sub-Mode CI: Coding infomation TOC --- 光盘中各个轨道的信息描述. ISO默认为一条轨道. MDS/MDF/NRG/CUE等可以描述多轨道光盘. 需要在加载光盘镜像时重建这些信息. track与session -------------- 一个session包含若干个轨道. 后面session的轨道中包含的文件, 应该能覆盖前面session中的文件. 只有MDS/MDF支持多个session. 土星的光盘,有多session的情况吗? 我想应该没有.又不是多次刻录生成的光盘. Langrisser 3 (J)是nrg格式, track01是数据轨. track02也是数据轨,但内容全0,100多兆.纯粹占空间用. 土星相关 -------- 土星内部的扇区buffer, 统一为2352字节. 前24字节是各种header的保留空间, 填充为0. ========================================================================= cdc_get_file_scope: fid最小为2, fnum最大为254. drend不知道意义 cdc_read_dir: 当fid为0xffffff时,返回最多254个文件信息(不包括.和..) file scope: fid=200 fnum=254 drend=0 此时调用cdc_get_file_info(2, finfo), 会返回REJECT. 这说明, get_file_info中的参数fid,指的是当前目录的顺序id,而不是当前页面的id. fid指定为203,则可以正确返回结果. ========================================================================= cdc_read_file(int selnum, int fid, int offset) cdb内部将selnum设置为: mode=0x41 fad=[start+offset] range = [fad_size] selnum对应的partition将被先清除. selnum被填满以后, 读取暂时停止, 直道有可用的block才继续. 然后以EFLS结束. ========================================================================= //假设1中有192个扇区 cdc_get_del_data(1, 0, 0xffffff); //但只传输了100个扇区 cdc_trans_data(sbuf, 2048*100); cdc_end_trans(NULL); // 调用end_trans后, 即使没有传输的92个扇区,也将被删除. // 目前的代码需要修改,来匹配这个情况. ========================================================================= cdc_get_del_data执行后,不管有没有传输数据, cdc_get_numsector返回的是已经删除后的扇区数. 看起来传输数据时, block没有被立即释放. 直道end_trans, 才会释放数据.这样才能保证数据的 安全性. ========================================================================= 3D手柄详细协议: https://nfggames.com/forum2/index.php?topic=5055.0 ========================================================================= <重装机兵: 雷诺斯2> play_cd: start=0080874a end=00800001 mode=00 这个命令执行后,如果延迟太大,导致读数据在play_end之前,则会卡住。 ========================================================================= Saturn的时钟配置: +------+---------+------+-----------+-----------+ | | XTAL | DIV | 1708(320) | 1820(352) | +------+---------+------+-----------+-----------+ | PAL | 14.318 | 910 | 26.873875 | 28.636000 | +------+---------+------+-----------+-----------+ | NTSC | 17.7344 | 1135 | 26.687538 | 28.437540 | +------+---------+------+-----------+-----------+ ========================================================================= Saturn存档格式(BackUPram) BUP位于0x00180000处,大小64K。因为此处地址空间是16位的,但所用的SRAM芯片是8位的,所以偶 地址数据悬空(读出为FF),奇地址才是有效数据。所以BUP实际大小32K。 BUP中的数据以64字节为一块来组织。一共有512个块。前两个块系统保留。块0是标志, "BackUpRam Format"重复4次。块1全0。 其余的块,头部4个字节是标志。0x80000000表示一个save的开始。0x00000000表示普通块。块的空闲 与否需要解析每个save来判断。 save开始块结构: 00: 80000000 04: 存档名,11字节。 0f: 语言标志。 10: 存档注释,10个字节。 1a: 存档日期编码,4字节。 1e: 存档字节大小,4字节。 22: 存档所占块列表。以0000结束。开始块用完则延续到下一个块。需要跳过块的前4个字节。 注意,如果20指示的存档大小可以放在开始块之内,则不需要占用块列表了。 块列表后面就是实际存档数据了。块列表不包括开始块。 ========================================================================= 自定义存档格式(SaroSave) 前64字节是文件头,接着64字节是块占用位图。 32K的存档,块大小是64字节,共512个块,可用64字节的位图表示。 存档大小加倍,则块大小也加倍,这样位图大小不变。 存档开始块占用一个块。存档数据占用的块也用64字节位图描述。数据位图不包括开始块与位图块。 若是32K存档,位图占用开始块后面的块。若是大于32K的存档,位图位于开始块内部。 文件头 00: "SaroSave" 08: 存档字节大小 0c: 块大小 0e: 空闲块数量 20: 游戏ID 3e:第一个save的块编号 save开始块结构: 00: 存档名,11字节。 0c: 存档字节大小,4字节。 10: 存档注释,10个字节。 1a: 00 1b: 语言标志。 1c: 存档日期编码,4字节。 3e: 下一个save的块编号。 =========================================================================