diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 3473b6a..275f61b 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -11,4 +11,6 @@ * [Umd Stream Composer](/wiki/Umd_Stream_Composer.md) * 收集的一些文档 Document Collections * PSX介绍中文版 - * [中央处理器(CPU)R3000A](/doc/PSX_introduces_CN/中央处理器(CPU)R3000A.md) \ No newline at end of file + * [中央处理器(CPU)R3000A](/doc/PSX_introduces_CN/中央处理器(CPU)R3000A.md) + * [内存](/doc/PSX_introduces_CN/内存.md) + * [图形处理芯片](/doc/PSX_introduces_CN/图形处理芯片(GPU).md) \ No newline at end of file diff --git "a/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_13-10-14.png" "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_13-10-14.png" new file mode 100644 index 0000000..9ea43e6 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_13-10-14.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_13-31-28.png" "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_13-31-28.png" new file mode 100644 index 0000000..19d08a7 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_13-31-28.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_14-00-46.png" "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_14-00-46.png" new file mode 100644 index 0000000..d534f12 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/PixPin_2024-07-21_14-00-46.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/ps_con.gif" "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/ps_con.gif" new file mode 100644 index 0000000..3887db3 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\206\205\345\255\230/ps_con.gif" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/20240721144750.png" "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/20240721144750.png" new file mode 100644 index 0000000..c946ca3 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/20240721144750.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/20240721145223.png" "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/20240721145223.png" new file mode 100644 index 0000000..9ea4531 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/20240721145223.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-10-20.png" "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-10-20.png" new file mode 100644 index 0000000..9ffa7b4 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-10-20.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-11-41.png" "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-11-41.png" new file mode 100644 index 0000000..c1d7dc6 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-11-41.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-22-47.png" "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-22-47.png" new file mode 100644 index 0000000..ab1b1cd Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-22-47.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-35-30.png" "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-35-30.png" new file mode 100644 index 0000000..b6faaa1 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-35-30.png" differ diff --git "a/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-37-57.png" "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-37-57.png" new file mode 100644 index 0000000..503d6a5 Binary files /dev/null and "b/docs/doc/PSX_introduces_CN/img/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207/PixPin_2024-07-21_14-37-57.png" differ diff --git "a/docs/doc/PSX_introduces_CN/\344\270\255\345\244\256\345\244\204\347\220\206\345\231\250\357\274\210CPU\357\274\211R3000A.md" "b/docs/doc/PSX_introduces_CN/\344\270\255\345\244\256\345\244\204\347\220\206\345\231\250\357\274\210CPU\357\274\211R3000A.md" index 289d0f0..6fca78a 100644 --- "a/docs/doc/PSX_introduces_CN/\344\270\255\345\244\256\345\244\204\347\220\206\345\231\250\357\274\210CPU\357\274\211R3000A.md" +++ "b/docs/doc/PSX_introduces_CN/\344\270\255\345\244\256\345\244\204\347\220\206\345\231\250\357\274\210CPU\357\274\211R3000A.md" @@ -38,7 +38,7 @@ R3000A使用32个32位的寄存器,一个32位的指令指针,两个32位的 | LO | 乘法运算64位结果的低32位,或除法运算的商 | | PC | 指令指针 | -尽管每个寄存器都有自己的名字,但它们都是一样的,除了2个:R0(ZR)是由硬件指定永远为0的;R31(RA)用于Link或Jump到子程序时保存返回地址,它可以象普通寄存器那样被其他指令读写。 +尽管每个寄存器都有自己的名字,但它们都是一样的,除了2个:R0(ZR)是由硬件指定永远为0的;R31(RA)用于Link或Jump到子程序时保存返回地址,它可以像普通寄存器那样被其他指令读写。 ## R3000A指令集 @@ -274,5 +274,3 @@ R3000A指令可以分为下面几个基本组: | 1 | TLBP | | | | | | | | | 2 | RFE | | | | | | | | | 3 | | | | | | | | | - - diff --git "a/docs/doc/PSX_introduces_CN/\345\206\205\345\255\230.md" "b/docs/doc/PSX_introduces_CN/\345\206\205\345\255\230.md" new file mode 100644 index 0000000..85bc54f --- /dev/null +++ "b/docs/doc/PSX_introduces_CN/\345\206\205\345\255\230.md" @@ -0,0 +1,305 @@ +内存 +== + +PSX有4个512K共2M的60ns SRAM芯片,它的编址是0x00xxxxxx、0xA0xxxxxx和0x80xxxxxx,都指向相同的物理内存。PSX用Cop0来处理内存管理的几乎每一个方面,先看一下内存是如何安排的。 + +## 内存映像图 + +| 开始地址 | 用途 | 结束地址 | +| --------- | ---------------- | --------- | +| 0000_0000 | 内核 64K | 0000_FFFF | +| 0001_0000 | 用户内存 1.9M | 001F_FFFF | +| 1F00_0000 | 并行口 64K | 1F00_FFFF | +| 1F80_0000 | 便笺本 1K | 1F80_03FF | +| 1F80_1000 | 硬件寄存器 8K | 1F80_2FFF | +| 8000_0000 | 内核和用户内存镜像 2M,缓冲 | 801F_FFFF | +| A000_0000 | 内核和用户内存镜像 2M,不缓冲 | A01F_FFFF | +| BFC0_0000 | BIOS 512K | BFC7_FFFF | + +空白格表示没有内存,镜像主要是用来缓冲和进行中断处理,内核也和用户内存一样被镜像。 + +## 虚拟内存 + +PSX使用虚拟内存体系来帮助普通系统内存和缓存的管理,简单地说,PSX把2M的内存映射到3个不同的虚拟地址空间段,它们的名字是Kuseg、Kseg0和Kseg1。 + +Kuseg从0x0000_0000到0x001F_FFFF,你可以把它叫做“真实”内存,内核可以方便的通过它访问用户内存区域。 + +Kseg0位于虚拟地址的0x8000_0000到0x801F_FFFF,它转换到从0开始的2M的物理线性地址空间,所有通过这个段的调用都是可缓冲的。当虚拟地址的最高3位是‘100’的时候,虚拟地址驻留在Kseg0,将‘100’替换为‘000’就得到物理地址。 + +Kseg1位于虚拟地址的0xA000_0000到0xA01F_FFFF,它也是指向从0开始2M线性空间。当虚拟地址的最高3位是‘101’的时候,虚拟地址驻留在Kseg1,将‘101’替换为‘000’就得到物理地址。不同于Kseg0的是,通过Kseg1的调用是不缓冲的。 + +更深入一点了解R3000A的虚拟内存,32位虚拟地址的高20位叫做虚拟页面号码(VPN),而其中只用到了最高的3位来做虚拟地址和物理地址的转换。) + +![](./img/内存/PixPin_2024-07-21_13-10-14.png) + +虚拟地址的三个最高位指示了处理器正在使用哪个虚拟内存段,这些段关联到各自的映射算法和是否被缓冲,页面通过替换虚拟地址的20位VPN到20位的物理帧号码(PFN)来映射。这个映射是通过译码检索缓冲器(TLB)来进行的,这个TLB是一个全相联储存器,包含64个条目,提供64个4KB页面的映射,每个TLB条目的宽度是64位,当虚拟调用Kuseg时,每一个TLB条目都会被检查是否对应到相应的VPN。 + +下图是TLB的示意图,整个子系统都是由Cop0来操作的。 + +![](./img/内存/ps_con.gif) + +## Cop0 系统控制处理器 + +这个单元实际是R3000A的一部分,它由原来的R3000A的Cop0增加了小量的寄存器和函数改制而成,Cop0包含16个32位的控制寄存器,用来进行内存管理、系统中断管理和断点的多方面控制。大多数是和普通的R3000A兼容的,下面是寄存器一览表。 + +| 号码 | 助记符 | 名字 | 读/写 | 用途 | +| --- | ------- | ------------------------------ | --- | ------------------------------ | +| 0 | INDX | Index | 读/写 | 64条目TLB文件的条目索引 | +| 1 | RAND | Random | 读 | 为软件提供随机的TLB条目来写入正确的译码 | +| 2 | TLBL | TBL low | 读/写 | 提供对TLB文件进行读、写和检索操作的数据路径(前32位) | +| 3 | BPC | Breakpoint PC | 读/写 | 设置运行中断的断点地址 | +| 4 | CTXT | Context | 读 | BADV寄存器的副本,但它的格式更适应于软件的TLB中断处理 | +| 5 | BDA | Breakpoint data | 读/写 | 设置装入/储存操作的断点地址 | +| 6 | PIDMASK | PID Mask | 读/写 | 进程标识符 | +| 7 | DCIC | Data/Counter interrupt control | 读/写 | 断点控制 | +| 8 | BADV | Bad Virtual Address | 读 | 引起中断的调用的地址 | +| 9 | BDAM | Break data mask | 读/写 | 数据提取地址和这个值进行‘与’操作,然后和BDA的值比较 | +| 10 | TLBH | TBL high | 读/写 | 提供对TLB文件进行读、写和检索操作的数据路径(后32位) | +| 11 | BPCM | Break point counter mask | 读/写 | 指令指针和这个值进行‘与’操作,然后和BPC的值比较 | +| 12 | SR | System status register | 读/写 | 包含全部主要的状态标志 | +| 13 | CAUSE | Cause | 读 | 指示最近发生的中断 | +| 14 | EPC | Exception Program Counter | 读 | 中断返回地址 | +| 15 | PRID | Processor ID | 读 | Cop0的型号和版本 | +| 16 | ERREG | ??? | ? | ???? | + +### TLB相关寄存器: + +Index寄存器:32位可读写寄存器,其中6位用来指示TLB中的条目,最高位是状态位用来表示TLB检索(tlbp)指令是成功还是失败,失败时被设为1。它也用来指定TBL读写指令的目的条目。结构如下:(0是保留的,必须写0,读的时候也返回0) + +| P | 0 | Index | 0 | +| --- | ----- | ----- | --- | +| 1位 | 17位 | 6位 | 8位 | +| 32 | 31-14 | 13-8 | 7-0 | + +Random寄存器:32位只读寄存器,其中6位用来指示TLB中随机的一个条目。它是一个每个时钟周期都递减的计算器,但是计数范围是从63到8,这就是可以保证Random寄存器永远不指向TLB前8个条目,这些条目就可以被软件“锁定”到TLB文件,保证在使用这些虚拟地址时TLB不会发生未命中中断,这对于操作系统尤为重要。Random寄存器最典型的是用在TLB未命中中断中,它提供一个“推荐”的TLB条目来写入正确的译码,尽管它的效率不如最近最少使用算法(LRU),但是在允许很简单的硬件软件管理条件下,提供了非常接近的性能。要进行一个TLB替换,使用TLB写随机(tlbwr)指令来写到这个寄存器指向的条目。就算使用随机TLB替换算法,两个处理器也能同步工作。在系统复位时,计算器被预置为63。软件也可以直接读这个寄存器,尽管它在设备测试和诊断之外几乎没有用处。结构如下:(0是保留的,读的时候返回0) + +| 0 | Random | 0 | +| ----- | ------ | --- | +| 18位 | 6位 | 8位 | +| 32-14 | 13-8 | 7-0 | + +TLB High和TLB Low寄存器:这两个寄存器提供了读、写和检索TLB文件的数据路径,它的格式和TLB条目格式是一样的,如下:PID是6位的进程标识符,TBL是允许多进程共享的,当不同的进程用同一个虚拟地址指向不同物理地址时,用PID来区别条目; +N是Non-Cacheable,当它被设置时,表示页面是不可缓冲的; +D是Dirty,当它被设置时表示页面是脏的,即是可写,可以把它看作一个“写保护"标志,软件可以用它来防止数据被修改; +V是Valid,当它被设置时表示TLB条目有效,否则表示TLBL或TLBS未命中发生; +G是Global,当它被设置时将忽略PID的匹配检查,在kseg2里,它允许内核访问全部映射的数据而不要保存或恢复PID值。 +0是保留的,必须写0,读的时候也返回0。 + +![](./img/内存/PixPin_2024-07-21_13-31-28.png) + +## 中断处理 + +程序运行中总有些时候需要挂起当前任务去处理一些其他硬件或软件功能,R3000A提供的中断(异常)处理功能是用来确保控制权从执行程序有秩序地转移到内核。中断可以大致分为2类:一是由指令或者指令序列产生,包括一些不正常地条件出现;二是由外部事件产生,例如硬件中断。当R3000A检测到中断发生,正常的指令序列会被暂停和悬挂起来,处理器会被迫进入内核模式,来处理一些不正常的或不同步的事件,下表列出了R3000A所认识的中断: + +| 中断 | 助记符 | 触发 | +| -------------------- | ------------------------- | ---------------------------------------------------------------- | +| Reset | Reset | 复位信号,把控制权转移到指定的虚拟地址0xBFC0_0000(BIOS的开始) | +| Bus Error | IBE DBE(Data) | 总线输入错误,外部事件引起。如总线超时,底层内存错误,无效物理地址或访问类型 | +| Address Error | AdEL(Load)
AdES(Store) | 常识装入、提取或储存一个不联结的字,也即一个字或半字不均匀地分成4或2份;
在用户模式,调用一个最高有效位被设置的虚拟地址 | +| Overflow | Ovf | 加或减溢出 | +| System Call | Sys | 执行SYSCALL陷阱指令 | +| Breakpoint | Bp | 执行break指令 | +| Reserved Instruction | RI | 执行未定义的或保留的大操作码(31:26位)或特殊的未定义的小操作码(5:0)指令 | +| Co-processorUnusable | CpU | 执行一个协处理器指令而该协处理器的CU(Co-processor  usable)位未被设置 | +| TLB Miss | TLBL(Load)
TLBS(Store) | 调用的TLB条目的Valid位未被设置 | +| TLB Modified | Mod | 执行储存指令时,相应TLB条目的Valid位被设置而Dirty位没有被设置 | +| Interrupt | Int | 六个硬件中断中的一个有输入或Cause寄存器的两个软件中断中的一个被设置 | + +### 中断相关寄存器: + +Cause寄存器:指示最近发生的中断,5位的中断代码,指示了当前的中断,其他位包含了这个中断的详细信息。除了SW位,其他位都是只读的。结构如下: +BD:Branch Delay,如果中断发生在转移指令执行的时候,这个位会被设置,EPC会返回到跳转指令的地方,在中断返回之后重新判断转移方向,重执行转移指令; +CE:Coprocessor Error,因为某个协处理器没有在SR里被使能,而导致协处理器指令出错发生中断的这个协处理号码; +IP:Interrupt Pending,指示了哪个中断在处理中,而不管它是否被屏蔽了,IP区可以用来测定那个中断正在处理; +SW:Software Interrupts,SW可以用写来设置或复位软件中断,只要SW的任何一个位被设置,并且在SR的中断掩字里相应的位也被设置,则发生一个中断。 +0:保留,必须写0,读取的时候返回0。 +EXECODE:Exception Code,描述中断发生的类型,见下表: + +| 号码 | 助记符 | 描述 | +| ----- | ---- | ----------------- | +| 0 | INT | 外部中断 | +| 1 | MOD | TLB修改中断 | +| 2 | TLBL | TLB未命中中断(读取或指令取出) | +| 3 | TLBS | TLB未命中中断(储存) | +| 4 | ADEL | 地址错误中断(读取或指令取出) | +| 5 | ADES | 地址错误中断(储存) | +| 6 | IBE | 总线错误中断(指令取出) | +| 7 | DBE | 总线错误中断(数据装入或储存) | +| 8 | SYS | SYSCALL中断 | +| 9 | BP | 断点中断 | +| 10 | RI | 保留的指令中断 | +| 11 | CPU | 协处理器不可用中断 | +| 12 | OVF | 算术运算溢出中断 | +| 13-31 | - | 保留 | + +| BD | 0 | CE | 0 | IP | SW | 0 | EXECODE | 0 | +| --- | --- | ----- | ----- | ----- | --- | --- | ------- | --- | +| 1位 | 1位 | 2位 | 12位 | 6位 | 2位 | 1位 | 5位 | 2位 | +| 31 | 30 | 29、28 | 27-16 | 15-10 | 9、8 | 7 | 6-2 | 1、0 | + +EPC寄存器: +Exception Program +Counter,32位的EPC寄存器保存了发生中断时正常指令的虚拟地址,亦即中断服务完成后的返回地址,当中断发生在转移指令中,EPC保存的是转移指令的地址,中断后从新执行转移指令。 + +BADV寄存器: +保存了任何发生地址错误中断的错误虚拟地址,只读。 + +Context寄存器: +部分BADV寄存器的副本,但是它的格式更方便于软件TLB中断处理程序的使用。Context寄存器用来使软件快速测定页面表条目里错误地址在主记忆体里的地址,也使软件能快速地用一个9指令的代码序列来更新TLB。结构如下: +0:保留,读写都是0; +BADV:失效虚拟页面号码(由硬件设置,和BADV一样是只读的); +PTE Base:页面表条目的基址(由内核设置); + +| PTE Base | BADV | 0 | +| -------- | ---- | --- | +| 11位 | 19位 | 2位 | +| 31-21 | 20-2 | 1、0 | + +Status寄存器: +这个寄存器包含了全部主要的状态位,任何中断都把系统置于内核模式,除了TS(TLB +Shutdown)位是只读的之外,其他所有位都是可读可写的。这个寄存器里的KU(Kernel/User)位和IE(Interrupt)位有3层‘栈’(current,previous和old),每发生一个中断就压一次‘栈’,然后由中断指令的Restore来出‘栈’,这些位也是可读可写的。复位的时候,SWc,KUc和IEc位被设为0,BEV被设为1,TS被设为0,其他位在复位的时候没有被定义。寄存器结构如下: +CU:Co-processor +Usability,这些位分别控制用户级访问协处理器的操作,包括BrCond输入端口的表决和系统控制协处理器(CP0)如何处理。CU2是GTE,CU1是FPA(在PSX里没有用到); +RE:Rverse +Endianess,R3000A允许系统在复位时决定内核模式字节顺序的习惯和用户模式的缺省设置。如果该位被清除,当前用户任务使用和内核模式一样的字节顺序;如果被设置,用户任务就用相反的字节顺序。这个位对内核模式没用影响。 +BEV:Bootstrap Exception +Vector。这个位的值决定了处理器中断向量的位置,BEV=1,处理器处于自举模式,中断向量位于BIOS +ROM里;BEV=0,处理器处于正常模式,中断向量处于RAM里; +TS:TLB Shutdown,这个位反映了TLB是否工作; +PE:Parity Error,在起动的时候这个位应该被写一个“1”,一旦初始化之后,读这个位就总会返回“0”; +CM:Cache +Miss,当缓存未命中发生时这个位被设置,这个在确定内部子系统缓存的大小和操作方面很有用; +PZ:Parity Zero,这个位应该写0; +SwC:Swap +Caches,设置这个位会引起执行核心将芯片内的指令缓存当作数据缓存来用,而将它清除则不交换缓存。这个在某些操作例如缓存填充上很有用,而在正常操作中不应该交换缓存; +IsC:隔离缓存,如果这个位被设置,数据缓存是和主存隔离的;也就是储存数据时修改数据缓存不会引起主存的改变,读取数据时也只从缓存返回而不管缓存是否命中。在多种操作里,这个位也是很有用的,例如填充; +IM:Interrupt +Mask,这个8位的域用来对执行引擎屏蔽硬件和软件中断,也就是不允许他们引起中断。IM(1:0)用了屏蔽软件中断,IM(7:2)屏蔽6个外部中断。0禁止一个特定的中断,1使能这个中断。注意IE位是一个全局的中断使能,也就是说,如果IE禁止了中断,特殊屏蔽位的值就不起作用了,如果IE使能中断,指定的中断将受这个域内的屏蔽位影响; +KUo:Kernel/User old,这是两个中断之前的特权状态,0表示内核模式; +IEo:Interrupt Enable +old,这是两个中断之前的全局中断使能状态。1表示中断使能,受到IM屏蔽的影响; +KUp:Kernel/User previous,这是当前中断之前的特权状态,0表示内核模式; +IEp:Interrupt Enable +previous,这是当前中断之前的全局中断使能状态。1表示中断使能,受到IM屏蔽的影响; +KUc:Kernel/User current,这是当前特权状态,0表示内核模式; +IEc:Interrupt Enable current,这是当前全局中断使能状态。1表示中断使能,受到IM屏蔽的影响; +0:保留,必须写0,读取也返回0。 + +| CU | 0 | RE | 0 | BEV | TS | PE | CM | PZ | SwC | IsC | IntMask | 0 | KUo | IEo | KUp | IEp | KUc | IEc | +| ----- | ----- | --- | ----- | --- | --- | --- | --- | --- | --- | --- | ------- | --- | --- | --- | --- | --- | --- | --- | +| 4位 | 2位 | 1位 | 2位 | 1位 | 1位 | 1位 | 1位 | 1位 | 1位 | 1位 | 8位 | 2位 | 1位 | 1位 | 1位 | 1位 | 1位 | 1位 | +| 31-28 | 27、26 | 25 | 24、23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15-8 | 7 | 5 | 4 | 3 | 2 | 1 | 0 | + +PRID寄存器: +这个寄存器对于软件确定用处理器的哪个版本执行代码很有用,格式如下: +Imp:3代表CoP0型号R3000A,7代表IDT单元(3041)使用REV来确定正确的配置; +Rev:版本。 + +| 0 | Imp | Rev | +| ----- | ---- | --- | +| 16位 | 8位 | 8位 | +| 31-16 | 15-8 | 7-0 | + +### 中断向量位置: + +R3000A把中断分到3个向量空间。每个向量的值都与状态寄存器的BEV位有关,它可以交替使用两套向量(因此有两套代码片断)。一般地说,这是用了在缓存可用之前用来分析测试的,处理器复位强迫BEV位的值变为1。 + +![](./img/内存/PixPin_2024-07-21_14-00-46.png) + +### 中断优先权: + +| Reset | 任何时候(最高) | +| ----- | ---------------- | +| AdEL | 内存(载入指令) | +| AdES | 内存(储存指令) | +| DBE | 内存(载入和储存) | +| MOD | ALU(数据TLB) | +| TLBL | ALU(DTLB未命中) | +| TLBS | ALU(DTLB未命中) | +| Ovf | ALU | +| Int | ALU | +| Sys | RD(指令译码) | +| Bp | RD(指令译码) | +| RI | RD(指令译码) | +| CpU | RD(指令译码) | +| TLBL | I-Fetch(ITLB未命中) | +| AdEL | IVA(指令虚拟地址) | +| IBE | BD(I-Fetch结束,最低) | + +## 断点管理 + +下面是Cop0里用来做断点管理的寄存器,这些寄存器在低级调试中很有用。 + +BPC寄存器:执行断点,设置执行时的断点地址。 + +BDA寄存器:数据访问断点,设置要中断的载入和储存操作地址。 + +DCIC寄存器:断点控制,要使用执行断点,设PC位1;要使用数据访问断点,设DA为1或者设置R,W两者的任意组合。两种断点都可以相似地使用,当遇到断点时PSX跳到0x0000_0040。寄存器结构如下: +W:1表示‘写’时中断; +R:1表示‘读’时中断; +DA:1表示数据访问中断使能; +PC:1表示执行中断使能。 + +| 1 | 1 | 1 | 0 | W | R | DA | PC | 1 | 0 | +| --- | --- | --- | --- | --- | --- | --- | --- | --- | ---- | +| 1位 | 1位 | 1位 | 1位 | 1位 | 1位 | 1位 | 1位 | 1位 | 23位 | +| 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22-0 | + +BDAM寄存器:数据访问断点掩码,数据提取地址和这个值进行‘与’操作,然后和BDA比较。 + +BPCM寄存器:执行断点掩码,指令指针和这个值进行‘与’操作,然后和BPC比较。 + +## DMA + +为了让一个设备直接访问内存,PSX需要不时地把CPU从总线上撤下来。这些可以控制总线地设备是CD-ROM,MDEC,GPU,SPU和并行口。一共有7个DMA通道,其中GPU和MDEC各使用2个,DMA寄存器位于0x1F80_1080到0x1F80_10F4之间。DMA通道寄存器从0x1F80_1080开始,每个通道的基地址如下: + +| 基地址 | 通道号码 | 设备 | +| ----------- | ---- | ---------------- | +| 0x1F80_1080 | DMA0 | MDECin | +| 0x1F80_1090 | DMA1 | MDECout | +| 0x1F80_10A0 | DMA2 | GPU(列表+图像数据) | +| 0x1F80_10B0 | DMA3 | CD-ROM | +| 0x1F80_10C0 | DMA4 | SPU | +| 0x1F80_10D0 | DMA5 | PIO | +| 0x1F80_10E0 | DMA6 | GPU OTC(反向清除顺序表) | + +每个通道都有3个32位控制寄存器,他们是DMA内存地址寄存器(D_MADR)位于基地址,DMA块控制寄存器(D_BCR)位于基地址+4,和DMA通道控制寄存器(D_CHCR)位于基地址+8。为了使用某个DMA通道,这个通道必须通过DMA主控制寄存器(DPCR,位于0x1F80_10F0)来使能。 + +DMA主控制寄存器(DPCR),0x1F80_10F0,在这个寄存器里为每个通道分配了一个4位的控制块,要使能一个通道,第3位必须被设为1,其他位作用未明。 + +| | DMA6 | DMA5 | DMA4 | DMA3 | DMA2 | DMA1 | DMA0 | +| ----- | ----- | ----- | ----- | ----- | ---- | ---- | ---- | +| 4位 | 4位 | 4位 | 4位 | 4位 | 4位 | 4位 | 4位 | +| 31-28 | 27-24 | 23-20 | 19-26 | 25-12 | 11-8 | 7-4 | 3-0 | + +如前所述,每个设备有3个32位控制寄存器位于自己的DMA地址空间里,下面描述了他们的功能。n代表了8,9,A,B,C,D,E,分别相对于0,1,2,3,4,5,6通道。 + +DMA内存地址寄存器(D_MADR),0x1F80_10n0 +MADR:指向DMA读取/写入的开始地址 + +| MADR | +| ---- | +| 32位 | +| 31-0 | + +DMA块控制寄存器(D_BCR),0x1F80_10n4,通道将传输BA个BS大小的字块。注意不要把尺寸设置大于对于单元所有的缓存大小(GPU和SPU都是$10字大小的缓存)。块尺寸越大,传输越快。 +BA:块数目; +BS:块尺寸。 + +| BA | BS | +| ----- | ---- | +| 16位 | 16位 | +| 31-16 | 15-0 | + +DMA通道控制寄存器(D_CHCR),0x1F80_10n8 +TR:0表示没有DMA传输忙,1表示开始DMA传输或DMA传输忙; +LR:1表示传送连接列表; +CO:1表示传送数据连续流; +DR:传送方向。 + +| 0 | TR | 0 | LI | CO | 0 | DR | +| ----- | --- | ----- | --- | --- | --- | --- | +| 7位 | 1位 | 13位 | 1位 | 1位 | 8位 | 1位 | +| 31-25 | 24 | 23-11 | 10 | 9 | 8-1 | 0 | + +DMA中断控制寄存器(DICR),0x1F80_10F4,是用来了控制DMA中断的,用法到现在还不知道。 diff --git "a/docs/doc/PSX_introduces_CN/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207\357\274\210GPU\357\274\211.md" "b/docs/doc/PSX_introduces_CN/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207\357\274\210GPU\357\274\211.md" new file mode 100644 index 0000000..81d063c --- /dev/null +++ "b/docs/doc/PSX_introduces_CN/\345\233\276\345\275\242\345\244\204\347\220\206\350\212\257\347\211\207\357\274\210GPU\357\274\211.md" @@ -0,0 +1,790 @@ +# 图形处理芯片(GPU) + +GPU控制了一个1MB的帧缓存,提供了一个最大1024×512分辨率16位像素的屏幕。它同时也包括了一个2KB的材质高速缓存。可以以15位或24位色显示。 + +因为PSX缺乏一个FPU,所以增加了第二个协处理器,成为几何变换引擎 +GTE(Geometry Transformation Engine)。GTE是PSX上所有3D运算的核心,它能够进行向量和矩阵运算,视角转换,颜色平衡等等。它对这些操作比CPU快得多,作为第二个协处理器(Cop2),它没有分配物理地址。 + +1MB的帧缓存不能被CPU访问,只能通过向GPU发送命令或者DMA传送数据。它有一个64字节的命令FIFO缓存,可以保存3条命令,它连接到一个DMA通道用来传送图像数据和链接命令列表(通道2)和一个DMA通道用来反向清楚一个顺序表(通道6)。 + +## 通讯和顺序表(OT) + +所有的绘图和绘图环境数据都作为信息包送到GPU。每一个信息包都告诉GPU怎样和在哪里绘一个图元,或者设置一个绘图环境参数。显示环境通过GPU的控制端口用一个单字命令设置。 + +信息包可以通过数据端口逐字送到GPU也可以用DMA大量传送。所以创建了一个特殊的DMA模式来方便地传送和管理大量的信息包。在这种模式,发送的是一个包列表。其中每一个条目都包含了一个头部(一个包含了下一个条目地址和信息包大小的字)和包本身。这样做的好处是信息包没有必要进行顺序储存,使得容易控制信息包被处理的顺序。GPU按照获得信息包的顺序处理它们,所以列表的第一个条目最先被画出。要插入一个包,只需要进行链表的插入操作,修改地址。 + +顺序表OT(OrderingTable)用来辅助在列表中寻找位置。在一开始,它是一个0字节包的链接条目,仅仅是包头部列表,没一个条目指向下一个条目。由程序生成的图元可以加入到这个表的某一个索引中。先读取表条目中的地址,将它替换成新包的地址,然后将表中的地址存到包里。当所有的包都生成后,只需要将第一个列表条目的地址传到DMA,就能够按照你输入表的顺序画出各个信息包。表中包条目索引值低的比索引值高的先画出。输入同一个索引的包,最后输入的最先画出。 + +在3D作图中,通常希望高Z值的图元先画出,所以Z值可以用作索引值。很简单,只要做一个表,其中每一个条目指向前一个条目,然后在最后一个表条目开始DMA。可以用一个特殊的DMA通道辅助你创建这样的表。 + +## 帧缓存 + +帧缓存是储存了所有GPU在绘图和显示图像过程中能够访问和处理的图像数据的内存,它个内存不能被CPU直接访问。大小是1MB,可以看作1024×512像素,每个像素大小是一个字(16bit)。它不像通常内存那样线性访问,而是通过坐标访问,左上角(0,0),右下角(1023,511)。 + +当数据从帧缓存中显示的时候,在这个记忆体中按照指定的坐标读取一个矩形区域。区域的大小可以从几种硬件定义的类型中选择。注意这些硬件大小只有在‘X和Y停止/开始’寄存器处于缺省值的时候才有效。显示的区域可以用两种颜色格式显示:15位直接或24位直接,数据格式如下: + +15位直接显示 + +![](./img/图形处理芯片/PixPin_2024-07-21_14-10-20.png) + +也就是每种颜色值是0~31,最高位(M)是掩码。 + +24位直接显示 + +![](./img/图形处理芯片/PixPin_2024-07-21_14-11-41.png) + +GPU也可以设置为24位模式,这种情况下,一个像素3个字节,每种颜色1字节。这样2个显示像素用3个帧缓存像素编码,显示为[R0,G0,B0] [R1,G1,B1]。 + +## 图元 + +GPU能够绘制的基本图形叫做图元,它可以绘制下面这些东西: + +### 多边形 + +GPU可以画3点和4点多边形,每一点指定了帧缓存中的一点。可以带辐射阴影。4点多边形定点的顺序如下 + +| 1 | | 2 | +| --- | --- | --- | +| | | | +| 3 | | 4 | + +一个4点多边形在内部当作2个3点多边形处理。GPU画多边形的时候最右边和最下边的边不会画出,所以(0,0)-(32,32)实际画出(0,0)-(31,31)。要使两个多边形相接,只要使它们坐标相同就可以了。 + +### 带材质的多边形 + +这种图元和上一种是相同的,特别之处是它可以用材质。多边形的每个顶点映射到帧缓存中的材质页中的一点。也可以带辐射阴影。 + +### 矩形 + +一个矩形用左上角定点和宽度、高度来定义,宽度和高度可以是任意的、8×8的或者是16×16的。它画得比多边形快得多,但是没有辐射阴影。 + +### 精灵 + +一个精灵是一个材质矩形,在材质页面的坐标上定义一个矩形。如同矩形那样画得比多边形快,但是没有辐射阴影。虽然它也叫做精灵,但是它和传统意义上的精灵没有任何相同之处,仅仅是一个矩形图像小片。传统的精灵和PSX精灵不同,它不是画到位图里的,而是在显示的时候特别送到屏幕上的特殊位置的。 + +### 直线 + +一条直线是两点之间的连线,可以有阴影。特殊的形式是多点线,可以指定任意多的点。 + +### 点 + +点图元在指定的位置用指定的颜色绘制一个像素,实际是一个特殊的矩形,大小是1×1。 + +## 材质 + +材质是放到多边形或精灵的一个图像,它需要预先在帧缓存中准备好数据。这个图像叫做材质图案,材质图案放在帧缓存中某个地方的标准大小的材质页中。材质数据可以用3中不同的模式存放。 + +### 15位直接模式 + +| 索引0 | | | | +| --- | --------- | --------- | -------- | +| S | 蓝 | 绿 | 红 | +| 15 | 14     10 | 9       5 | 4      0 | + +这表示了每种颜色的值是0~31,最高有效位(S)用来表明这个像素是否半透明的。 + +### 8位调色板模式 + +每个像素用8位定义,它的值通过调色板转换为15位的颜色,很像标准VGA图片。这样可以使用256种15位精度的颜色。 + +| 索引1 | 索引0 | +| ------ | ------ | +| 15   8 | 7    0 | + +索引0是左边像素的调色板索引值,索引1是右边的。 + +### 4位调色板模式 + +和上面的一样,除了只有16种颜色,数据安排如下: + +| 索引3 | 索引2 | 索引1 | 索引0 | +| ------ | ------ | ------ | ------ | +| 15  12 | 11   8 | 7    4 | 3    0 | + +索引0到索引3先后从左到右绘制。 + +### 材质页 + +材质页是一个256×256像素的单元,什么颜色模式对它没有影响。就是说,在帧缓存中它在4位调色板模式时是64像素宽,8位调色板模式时128像素宽,15位直接模式时256像素宽。像素的寻址是相对于材质页的位置,而不是帧缓存。所以材质页左上角的材质坐标是(0,0),右下是(255,255),页面可以位于帧缓存中的X乘以64和Y乘以256的地方。可以建立多个材质页,但是图元只能使用一个材质页里的材质。 + +### 材质窗口 + +材质窗口里面的区域是材质页的重复,数据实际上并不知存在于整个材质页,但是GPU当它们存在而重复读取。X和Y和H和W必须乘以8。 + +### 调色板 + +调色板在帧缓存中作如下安排:8位调色板模式是256×1的图像,4位调色板模式是16×1的图像。每个像素是16位的值,前15位用作15位颜色,第16位作半透明标志。调色板数据可以安放在帧缓存中X乘以16(0,16,32,48等等)和Y(0~511)的位置。可以有多个调色板,但是一个图元只能够使用一个。 + +### 材质高速缓存 + +如果要显示带材质的多边形,GPU需要从帧缓存中读取这些东西,将会减慢绘图过程,导致在给定的时间内能够绘制的多边形减少。因此GPU配上了一个材质高速缓存,材质高速缓存的大小依据材质颜色模式而不同。在4位调色板模式,它的大小是64×64,8位调色板模式是32×64,15位直接模式是32×32。 + +### 高速缓存块 + +材质页被分割为不重叠的高速缓存块,每块的大小依据颜色模式。这些高速缓存块被平铺在材质页中。 + +| 高速缓存块0 | 1 | 2..... | +| --------------------- | --- | ------ | +| .

.

. | | | + +### 高速缓存条目 + +每个高速缓存块分为256个高速缓存条目,按顺序编号,8字节宽,所以一个高速缓存条目包含了16个4位调色板像素,或者8个8位调色板像素,或者4个15位直接像素。 + +4位和8位调色板: + +| 0 | 1 | 2 | 3 | +| --- | --- | --- | --- | +| 4 | 5 | 6 | 7 | +| 8 | 9 | ... | | +| c | ... | | | + +15位直接: + +| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | +| --- | --- | --- | --- | --- | --- | --- | --- | +| 8 | 9 | a | b | c | d | e | f | +| 10 | 11 | ... | | | | | | +| 18 | ... | | | | | | | +| ... | | | | | | | | + +高速缓存只能保存一个高速缓存条目。 + +## 描绘选项 + +有3种模式影响GPU向帧缓存描绘图元。 + +### 半透明 + +当设置一个像素是半透明时,GPU会读取帧缓存中的目标像素和需要进行半透明的源像素,然后根据选择的半透明模式计算新目标像素的颜色。处理器速度也因此会减慢下来,GPU共有4种半透明模式。 + +B是从帧缓存读取的像素,F是半透明像素。 + +●1.0×B+0.5×F + +●1.0×B+1.0×F + +●1.0×B-1.0×F + +●1.0×B+0.25×F + +每个图元都可以设置新的半透明模式,没有材质的图元可以选择半透明模式。有材质的图元最高有效位是半透明标志,所以一些像素可以设为半透明,其他可以是不透明的。对于调色板模式,半透明位从调色板中取得。 + +当颜色是黑色(BGR=0),半透明的处理方法和不是黑色(BGR<>0)时不同,如下表: + +| 透明处理(命令包的第1位) | | | | +| ------------- | ----- | --- | --- | +| BGR | 半透明标志 | 关 | 开 | +| 0,0,0 | 0 | 透明 | 透明 | +| 0,0,0 | 1 | 不透明 | 不透明 | +| x,x,x | 0 | 不透明 | 不透明 | +| x,x,x | 1 | 不透明 | 透明 | + +### 阴影 + +GPU有阴影功能,可以比例缩放图元的颜色到指定的亮度。有2种阴影:单调阴影和辐射阴影。单调阴影用一个亮度值指定整个图元的,辐射阴影则可以指定每个顶点的亮度,中间点自动进行插值。 + +### 掩码 + +掩码功能可以阻止GPU向帧缓存中特定的像素写东西,就是说GPU向一个掩码区域画图元的时候,先读取它要写向的坐标点的像素,检查掩码标志,如果设置了就不写这个像素。掩码标志是像素的最高有效位,和不透明标志一样。GPU提供了一个掩码模式来设置这些位,写像素的同时设置它们的最高有效位。如果掩码和掩码检测都打开了,GPU就不向设置了最高有效位的像素写东西,而写没有设置的那些像素,同时把它们也设置成掩码像素。 + +### 绘图环境 + +绘图环境设置GPU绘制图元所需的全部全局参数。 + +●绘图偏移 + +绘图区域的左上角坐标,图元坐标的原点设在这点上。所以绘图偏移是(0,240),一个多边形顶点坐标是(16,20),则它会被画到帧缓存的(0+16,240+20)的地方。 + +●绘图修剪区域 + +指定了GPU绘制图元的最大范围,用它来制定绘图区的左上角和右下角。 + +●抖动使能 + +当抖动使能时,GPU绘制阴影时会抖动该区域。内部以24位色运行,抖动颜色后再转会15位色。当它关闭时,只是简单的发散每个颜色的最低3位。 + +●画到显示区使能 + +使能/禁止画到当前显示区域。 + +●掩码使能 + +使能时,所有画到帧缓存的像素,GPU都会加上掩码标志(设置最高有效位)。 + +●掩码判断使能 + +绘图时是否判断帧缓存中的掩码数据。 + +### 显示环境 + +包含了显示信息和显示区域。 + +●帧缓存中的显示区域 + +指定了显示的分辨率,可以是以下大小: + +宽度:256,320,384,512或者640像素 + +高度:240或者480像素 + +- 这些设置仅仅是指定了显示分分辨率,指明绘制多少像素。 + +●显示(开始/结束) + +指定屏幕的显示区域和发送多少数据到屏幕,屏幕显示区域大小只有在水平/垂直、开始/结束处于缺省值时才有效。可以通过改变这些来放大/缩小显示屏幕。大多数电视机在周围有一些黑边,可以设置使屏幕早一点开始晚一点结束来消除。像素的大小不会被这些设置改变,GPU只是简单地发送多一些数据到屏幕。 + +●隔行扫描 + +当使能的时候,GPU会交错显示奇数行和偶数行。当使用480行而电视机屏幕又没有480条扫描线时需要使用这个功能。 + +●15位/24位色直接显示 + +切换15位/24位色显示模式 + +●视频模式 + +选择视频模式是PAL或者NTSC制式。 + +## GPU控制寄存器 + +有2个32位IO端口用于GPU,分别是0x1F80_1810的GPU数据寄存器和0x1F80_1814的GPU控制/状态寄存器。数据寄存器用于交换数据,控制/状态寄存器在读取时给出GPU状态,在写入时设置控制位。 + +### 控制/状态寄存器 + +0x1F80_1814(读取) + +![](./img/图形处理芯片/PixPin_2024-07-21_14-22-47.png) + +Width(宽度) + +| W0 | W1 | | +| --- | --- | ----- | +| 00 | 0 | 256像素 | +| 01 | 0 | 320 | +| 10 | 0 | 512 | +| 11 | 0 | 640 | +| 00 | 1 | 384 | + +Height(高度) + +| 0 | 240像素 | +| --- | ----- | +| 1 | 480 | + +Video(视频) + +| 0 | NTSC | +| --- | ---- | +| 1 | PAL | + +isrgb24(颜色模式) + +| 0 | 15位直接模式 | +| --- | ------- | +| 1 | 24位直接模式 | + +isinter(扫描模式) + +| 0 | 隔行扫描关闭 | +| --- | ------ | +| 1 | 隔行扫描打开 | + +den(显示使能) + +| 0 | 显示使能 | +| --- | ---- | +| 1 | 显示禁止 | + +busy(忙) + +| 0 | GPU忙(例如正在绘制图元) | +| --- | -------------- | +| 1 | GPU空闲 | + +img(影像) + +| 0 | 未准备好发送图像(信息包$C0) | +| --- | ---------------- | +| 1 | 准备好 | + +com(命令) + +| 0 | 未准备好接收命令 | +| --- | -------- | +| 1 | 准备好 | + +dma(DMA) + +| 00 | DMA关闭,通过GP0通讯 | +| --- | ------------- | +| 01 | 未知 | +| 10 | DMA CPU-->GPU | +| 11 | DMA GPU-->CPU | + +lcf(交错行) + +| 0 | 偶数行交错描绘 | +| --- | -------- | +| 1 | 非偶数行交错描绘 | + +tx(材质页X) +材质页X=tx×64 + +ty(材质页Y) + +| 0 | 0 | +| --- | --- | +| 1 | 256 | + +abr(半透明状态) + +| 00 | 0.5×B+0.5×F | +| --- | ------------ | +| 01 | 1.0×B+0.5×F | +| 10 | 1.0×B-1.0×F | +| 11 | 1.0×B+0.25×F | + +tp(材质页颜色模式) + +| 00 | 4位调色板 | +| --- | ----- | +| 01 | 8位调色板 | +| 10 | 15位 | + +dtd(抖动模式) + +| 0 | 抖动关闭 | +| --- | ---- | +| 1 | 抖动开启 | + +dfe(画到显示区域) + +| 0 | 禁止画到当前显示区域 | +| --- | ---------- | +| 1 | 允许画到当前显示区域 | + +md(掩码模式) + +| 0 | 不设置绘图像素的掩码标志 | +| --- | ------------ | +| 1 | 设置绘图像素的掩码标志 | + +me(掩码检测) + +| 0 | 不检测掩码标志 | +| --- | ------- | +| 1 | 检测掩码标志 | + +### 控制/状态寄存器 0x1F80_1814(写入) + +| 命令 | 参数 | +| -------- | -------- | +| 31    16 | 15     0 | + +一个控制命令组成如上表,每个命令的参数都不一样。 + +复位GPU + +| 命令 | 0x00 | +| --- | ----------------------------- | +| 参数 | 0x000000 | +| 描述 | 复位GPU,同时关闭屏幕。(设置状态为$14802000) | + +复位命令缓存 + +| 命令 | 0x01 | +| --- | -------- | +| 参数 | 0x000000 | +| 描述 | 复位命令缓存 | + +复位IRQ + +| 命令 | 0x02 | +| --- | -------- | +| 参数 | 0x000000 | +| 描述 | 复位IRQ | + +显示使能 + +| 命令 | 0x03 | +| --- | --------------------------------------- | +| 参数 | 0x000000 显示禁止

0x000001 显示使能 | +| 描述 | 关闭和打开显示,关闭屏幕时如果选择了NTSC模式会使PAL屏幕发送NTSC闪烁 | + +DMA设置 + +| 命令 | 0x04 | +| --- | ------------------------------------------------------------------------------------------------- | +| 参数 | 0x000000 DMA禁止

0x000001 未知DMA功能

0x000002 DMA CPU到GPU

0x000003 DMA GPU到CPU | +| 描述 | 设置DMA方向 | + +开始显示区域 + +| 命令 | 0x05 | +| --- | ------------------------------------------------------------------ | +| 参数 | 0x00-0x09位 X(0-1023)

0x0A-0x12位 Y(0-512)

即=Y<<10+X | +| 描述 | 确定显示区域的左上角 | + +水平显示范围 + +| 命令 | 0x06 | +| --- | ---------------------------------------------------------------------------------------------------- | +| 参数 | 0x00-0x0B位 X1(0x1F4-0xCDA)

0x0C-0x17位 X2

即=X1+X2<<12 | +| 描述 | 指定水平显示范围,显示相对于显示开始位置,所以X坐标0位于X1。显示结束位置和开始位置无关。在320模式发送到屏幕的像素个数是(X2-X1)/8。实际可见数依赖于电视机(通常是0x260-0xC56) | + +垂直显示范围 + +| 命令 | 0x07 | +| --- | -------------------------------------------------------------------------------------------------------------------- | +| 参数 | 0x00-0x09位 Y1

0x0A-0x14位 Y2

即=Y1+Y2<<10 | +| 描述 | 指定垂直显示范围,显示相对于显示开始位置,所以Y坐标0位于Y1。结束位置和开始位置无关。在240模式发送到显示器的像素数目是Y2-Y1。(缺省值不确定,大概是NTSC
0x010-0x100,PAL 0x023-0x123) | + +显示模式 + +| 命令 | 0x08 | +| --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 参数 | 0x00-0x01位 宽度0

0x02        高度

0x03        视频模式

0x04        Isrgb24

0x05        Isinter

0x06        宽度1

0x07        方向标志 | +| 描述 | 参见显示模式 | + +未知 + +| 命令 | 0x09 | +| --- | ------------- | +| 参数 | 0x000001 ?? | +| 描述 | 使用时值为0x000001 | + +GPU信息 + +| 命令 | 0x10 | +| --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 参数 | 0x000000

0x000001

0x000002

0x000003 绘图区域左上角

0x000004 绘图区域右下角

0x000005 绘图偏移

0x000006

0x000007 GPU类型,对标准的GPU返回2 | +| 描述 | 返回请求信息,从GP0读取结果。似乎0,1也是返回绘图区域左上角,6也是返回绘图偏移 | + +????? + +| 命令 | 0x20 | +| --- | ------------- | +| 参数 | ?????? | +| 描述 | 使用时值是0x000504 | + +## 命令包,数据寄存器 + +图元命令包使用8位命令,它包含了一个3位的类型区段和一个5位的选项区段,选项根据类型不同而不同。 + +类型 + +| 000 | GPU命令 | +| --- | ----- | +| 001 | 多边形图元 | +| 010 | 直线图元 | +| 011 | 精灵图元 | +| 100 | 传输命令 | +| 111 | 环境命令 | + +配置图元的选项块如下: + +| 多边形 | | | | | | | | +| --- | --- | --- | --- | --- | --- | --- | --- | +| 类型 | 类型 | 类型 | 选项 | 选项 | 选项 | 选项 | 选项 | +| 0 | 0 | 1 | IIP | VTX | TME | ABE | TGE | +| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + +| 直线 | | | | | | | | +| --- | --- | --- | --- | --- | --- | --- | --- | +| 类型 | 类型 | 类型 | 选项 | 选项 | 选项 | 选项 | 选项 | +| 0 | 1 | 0 | IIP | PLL | 0 | ABE | 0 | +| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | + +| 精灵 | | | | | | | +| --- | --- | --- | ---- | --- | --- | --- | +| 类型 | 类型 | 类型 | 选项 | 选项 | 选项 | 选项 | +| 1 | 0 | 0 | Size | TME | ABE | 0 | +| 7 | 6 | 5 | 4或3 | 2 | 1 | 0 | + +| IIP | 0 简单阴影
1 辐射阴影 | +| ---- | --------------------------------------------------------------- | +| VTX | 0 3顶点多边形

1 4顶点多边形 | +| TME | 0 材质映射关闭

1 材质映射打开 | +| ABE | 0 半透明关闭

1 半透明打开 | +| TGE | 0 映射材质时计算亮度

1 关闭(只描绘材质) | +| Size | 00 自由尺寸(通过W/H指定)

01 1×1

10 8×8

11 16×16 | +| PLL | 0 单线(2个顶点)

1 多段线(n个顶点) | + +●颜色信息 + +颜色信息是24位传送的,被GPU解析为15位的。 + +| 蓝色 | 绿色 | 红色 | +| ------- | ------- | ------- | +| 23   16 | 15    8 | 7     0 | + +●阴影信息 + +带材质图元阴影数据用这个包传送,和颜色数据一样排列,RGB值控制了各种颜色(0x00-0x7F)的亮度。颜色值为0x80将取前者作为数据。 + +| 蓝色 | 绿色 | 红色 | +| ------- | ------- | ------- | +| 23   16 | 15    8 | 7     0 | + +材质包信息 + +![](./img/图形处理芯片/PixPin_2024-07-21_14-35-30.png) + +| TX | 0x0-0xF X×64 材质页X坐标 | +| --- | -------------------------------------------------------------------------------------------------------------- | +| TY | 0       0    
材质页Y坐标

1       256 | +| ABR | 0       0.5×B+0.5×F 半透明模式

1       1.0×B+1.0×F

2       1.0×B-1.0×F

3       1.0×B+0.25×F | +| TP | 0       4位调色板

1       8位调色板

2       15位调色板 | + +●调色板ID + +指定调色板数据的位置 + +![](./img/图形处理芯片/PixPin_2024-07-21_14-37-57.png) + +### 包列表 + +包作为成组数据传送到GPU,每个都是一个字长。数据必须顺序写到GPU数据寄存器(0x1F801810),当所有的数据都被接收后,GPU开始操作。 + +#### 包命令一览: + +●图元绘图包 + +| 0x20 | 单色3点多边形 | +| ---- | --------- | +| 0x24 | 材质3点多边形 | +| 0x28 | 单色4点多边形 | +| 0x2C | 材质4点多边形 | +| 0x30 | 渐变3点多边形 | +| 0x34 | 渐变材质3点多边形 | +| 0x38 | 渐变4点多边形 | +| 0x3C | 渐变材质4点多边形 | +| 0x40 | 单色直线 | +| 0x48 | 单色多段线 | +| 0x50 | 渐变直线 | +| 0x58 | 渐变多段线 | +| 0x60 | 矩形 | +| 0x64 | 精灵 | +| 0x68 | 点 | +| 0x70 | 8×8矩形 | +| 0x74 | 8×8精灵 | +| 0x78 | 16×16矩形 | +| 0x7c | 16×16精灵 | + +●GPU命令和传送包 + +| 0x01 | 清除高速缓存 | +| ---- | --------- | +| 0x02 | 帧缓存矩形绘图 | +| 0x80 | 在帧缓存中移动图像 | +| 0xA0 | 发送图像到帧缓存 | +| 0xC0 | 从帧缓存拷贝图像 | + +●绘图模式/环境设置包 + +| 0xE1 | 绘图模式设置 | +| ---- | --------- | +| 0xE2 | 材质窗口设置 | +| 0xE3 | 设置绘图区域左上角 | +| 0xE4 | 设置绘图区域右下角 | +| 0xE5 | 绘图便宜 | +| 0xE6 | 掩码设置 | + +### 包描述 + +#### 图元包 + +![](./img/图形处理芯片/20240721144750.png) + +#### GPU命令和传输包 + +![](./img/图形处理芯片/20240721145223.png) + +#### 绘图模式/环境设置包 + +其中有些也是图元包,无论什么情况它都是GPOU最后接收的包。所以如果一个图元设置了材质页信息,它会覆盖存在的数据,即使它是由0xE?包发送的。 + +| 0xE1 绘图模式设置 | | | | | | | | +| ----------- | ------ | --- | --- | ------- | ------- | --- | ------ | +| 31 24 | 23 11 | 10 | 9 | 8     7 | 6     5 | 4 | 3    0 | +| 0xE1 | | dfe | dtd | tp | abr | ty | tx | + +对于某些不是标准类新的GPU(0x10000007命令不返回2),状态寄存器的第11-13位似乎也可以用这个命令传送。 + +| 0xE1 材质窗口设置 | | | | | | +| ----------- | ------ | ------ | ------ | ----- | ----- | +| 31 24 | 23 10 | 19 15 | 14 10 | 9 5 | 4 0 | +| 0xE2 | | twx | twt | tww | twh | + +| twx | 材质窗口X,(twx×8) | +| --- | ------------------ | +| twy | 材质窗口Y,(twy×8) | +| tww | 材质窗口宽度,256-(tww×8) | +| twh | 材质窗口高度,256-(twh×8) | + +| 0xE3 设置绘图区域左上角 | | | | +| -------------- | ------ | ------ | ------ | +| 31 24 | 23 16 | 15 8 | 7 0 | +| 0xE3 | | Y | X | + +设置绘图区域左上角,X和Y是帧缓存绝对坐标。 + +| 0xE4 设置绘图区域右下角 | | | | +| -------------- | ------- | ------ | ------ | +| 31     24 | 23   16 | 15   8 | 7    0 | +| 0xE4 | | Y | X | + +| 0xE5 绘图偏移 | | | | +| --------- | -------- | ------- | ----- | +| 31    24 | 23    16 | 15    8 | 7   0 | +| 0xE5 | | Y便宜 | X便宜 | + +偏移Y=Y<<11,设置绘图区域便宜。X和Y是帧缓存中的便宜。 + +| 0xE6 绘图掩码 | | | | +| ---------- | --------- | --- | --- | +| 31      24 | 23      2 | 1 | 0 | +| 0xE6 | | 掩码2 | 掩码1 | + +掩码1:绘图时设置掩码位,1=开 + +掩码2:绘图掩码检测,1=开 + +## DMA和GPU + +GPU有两个DMA通道。DMA通道2用来发送链接包列表到GPU以及和帧缓存传送图像数据。DMA通道6用来建立一个空的链接列表,其中每个条目指向前一个条目(例如方向清空一个顺序表OT)。 + +第二DMA内存地址寄存器(D2_MADR) +0x1F80_10A0 + +| 31          0 | +| ------------- | +| MADR | + +MADR:指向DMA将开始读写的虚拟地址。 + +第二DMA块控制寄存器(D2_BCR) 0x1F80_10A4 + +| 31    0 | | +| ------- | --- | +| BA | BS | +| 16 | 16 | + +BA: 块的总数 + +BS:块的大小(按字计算) + +设置DMA块,当开始DMA后将会发送BA个BS字长的块。不要设置块大小大于0x10字,因为GPU命令缓存只有64字节。 + +第二DMA通道控制寄存器(D2_CHCR) 0x1F80_10A8 + +| 31    0 | | | | | | | +| ------- | --- | --- | --- | --- | --- | --- | +| 0 | TR | 0 | LI | CO | 0 | DR | +| 7 | 1 | 13 | 1 | 1 | 8 | 1 | + +| TR | 0 没有DMA传输忙
1 开始DMA传输/DMA传输忙 | +| --- | -------------------------------- | +| LR | 1 传输链接列表(只限于GPU) | +| CO | 1 传输连续流数据 | +| DR | 1 方向:从内存

0 方向:向内存 | + +用来配置DMA通道,当第18位被设置时开始DMA,当第18位被清除DMA立刻结束。要向VRAM发送或接收数据,先向GPU发送适当的包(0xA0/0xC0)。 + +第六DMA内存地址寄存器(D6_MADR) 0x1F80_10E0 + +| 31          0 | +| ------------- | +| MADR | + +MADR:指向DMA将开始读写的虚拟地址。 + +第六DMA块控制寄存器(D6_BCR) 0x1F80_10E4 + +| 31          0 | +| ------------- | +| BC | + +BC:列表条目数 + +第六DMA通道控制寄存器(D6_CHCR) 0x1F80_10E8 + +| 31     0 | | | | | | | +| -------- | --- | --- | --- | --- | --- | --- | +| 0 | TR | 0 | LI | CO | 0 | DR | +| 7 | 1 | 13 | 1 | 1 | 8 | 1 | + +| TR | 0 没有DMA传输忙
1 开始DMA传输/DMA传输忙 | +| --- | -------------------------------- | +| LR | 1 传输链接列表(只限于GPU) | +| CO | 1 传输连续流数据 | +| DR | 1 方向:从内存

0 方向:向内存 | + +用来配置DMA通道,当第18位被设置时开始DMA,当第18位被清除DMA立刻结束。要向VRAM发送或接收数据,先向GPU发送适当的包(0xA0/0xC0)。当这个寄存器被设为0x11000002,DMA通道会创建一个D6_BCR个条目地址位于D_MADR的空链接列表。每个条目大小是0,指向前一个条目。如果D6_MAD=0x80100010,D6_BCR=0x00000004,会生成一个列表如下: + +| 0x8010_0000 | 0x00FF_FFFF | +| ----------- | ----------- | +| 0x8010_0004 | 0x0010_0000 | +| 0x8010_0008 | 0x0010_0004 | +| 0x8010_000C | 0x0010_0008 | +| 0x8010_0010 | 0x0010_000C | + +DMA主控制寄存器(DPCR) 0x1F80_10F0 + +| | DMA6 | DMA5 | DMA4 | DMA3 | DMA2 | DMA1 | DMA0 | +| --- | ---- | ---- | ---- | ---- | ---- | ---- | ---- | +| 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | + +在这个寄存器中每个寄存器分配了一个4位的控制块。 + +| 位3 | 1=DMA使能 | +| --- | ------- | +| 2 | 未知 | +| 1 | 未知 | +| 0 | 未知 | + +### 一步步建普通GPU函数 + +●初始化GPU + +| 1 | 复位GPU(GP1命令0x000),同时关闭显示器 | +| --- | ---------------------------- | +| 2 | 设置水平和垂直开始/结束(GP1命令0x06,0x07) | +| 3 | 设置显示模式(GP1命令0x08) | +| 4 | 设置显示偏移(GP1命令0x05) | +| 5 | 设置绘图模式(GP0命令0xE1) | +| 6 | 设置绘图区域(GP0命令0xE3,0xE4) | +| 7 | 设置绘图便宜(GP0命令0xE5) | +| 8 | 使能显示 | + +●发送链接列表 + +通常发送大量图元是使用链接列表DMA传送,列表最后一个条目的指针应该是0xFFFFFF,是终止符。如果条目大小设为0,没有数据被传送到GPU,然后处理下一个条目。要发送一个列表应该: + +| 1 | 等待GPU准备好接收命令(第0x1C位=1) | +| --- | ---------------------------------------- | +| 2 | 使能第二DMA通道 | +| 3 | 设置GPU到DMA CPU-->GPU模式(0x04000002) | +| 4 | 设置D2_BCR为0 | +| 5 | 设置D2_CHCR到链接模式,内存-->GPU和使能DMA0x01000401) | + +●通过DMA上传图像: + +| 1 | 等待GPU空闲和DMA完成。如果必要,使能第二DMA通道 | +| --- | ------------------------------------------------------------------------------------------------------------------------- | +| 2 | 发送‘发送图像到VRAM’图元(可以通过DMA发送,使用上面描述的链接列表) | +| 3 | 设置DMA到CPU-->GPU(0x04000002)(如果你没有在前面完成了这个步骤) | +| 4 | 设置D2_MADR到列表的开始 | +| 5 | 设置D2_BCR的第31-16位=要发送的字数(H×W/2)

             
15-0位=块大小为1个字(0x01)

如果H×W是奇数,加1。(像素是2个字节,发送一个额外的空像素填补内容) | +| 6 | 设置D2_CHCR到连续模式,内存-->GPU和使能DMA(0x01000201) | + +注意,H,W,X和Y总是以帧缓存像素为单位,即使你传送的图像数据是其他格式的。如果需要更快的速度,可以使用大一点的块尺寸。如果要发送的字数不是块大小的整数倍,则要单独发送剩下的部分,因为GPU只能接受一个额外的半字。同时注意不要使用大于0x10的块尺寸,因GPU命令缓存只有64字节(=0x10字)。 + +●等待发送命令 + +你可以在DMA终了和GPU准备好时发送新的命令 + +| 1 | 等待D2_CHCR的0x18位变为0 | +| --- | ------------------ | +| 2 | 等待GP1的0x1C位变为1 | diff --git a/docs/index.html b/docs/index.html index 9ca32c3..1344537 100644 --- a/docs/index.html +++ b/docs/index.html @@ -33,7 +33,9 @@ '/wiki/Summary_of_Computer_File_Attributes', '/wiki/pmftools', '/wiki/Umd_Stream_Composer', - '/doc/PSX_introduces_CN/中央处理器(CPU)R3000A' + '/doc/PSX_introduces_CN/中央处理器(CPU)R3000A', + '/doc/PSX_introduces_CN/内存', + '/doc/PSX_introduces_CN/图形处理芯片(GPU)' ], editButton: { title: "在Github上编辑",