SMS(Sega Master System)主机架构

Rodrigo Copetti 的实用分析

这是原文的志愿翻译。如果您发现任何错误,请帮助改进。谢谢!

如果您使用无障碍阅读工具、电子书或旧版浏览器,切换到“经典”版




相关影像

型号

Image
SMS(Sega Master System)。
1985年10月20日在日本发布,1986年9月在美国发布,1987年6月在欧洲发布。

主板

Image
主板
声音芯片嵌入在视频处理器中。
Image
带有重要部件标签的主板

图示

Image
主架构图

引言

SMS源自一个长期的传承系列。 最初只是一系列现成部件的集合,现在由于世嘉的工程技术,它已获得了新的身份。


型号和变种

起初阅读关于世嘉发布的不同型号时我有些困惑,因此这里总结了主要讨论的型号,以避免进一步的混淆:

从现在开始,我将使用术语“SMS”来指代所有这些,除非谈论特定型号的独家功能。


中央处理器 (CPU)

世嘉决定采用全功能的Zilog Z80CPU,运行频率约为3.58 MHz。 也是ZX Spectrum和Amstrad CPC等其他机器的热门CPU选择。

Z80中央处理器有一个有趣的背景,因为它是由英特尔8080的创造者(费德里科·法金和岛正敏)创作的,他们由于对英特尔的方向不再抱有幻想,并决定在1974年创办自己的硅公司——齐洛格(Zilog)。 他们首次推出的产品可以被认为是英特尔8080的非官方继任者,其具有以下特性:

文章开头的主板图片显示了一颗 NEC D780C-1 CPU,这只是世嘉将芯片交由不同厂商代工的结果,其他版本甚至包含了由 Zilog 制造的芯片。 但对于本文而言,不论 CPU 是哪家制造的都不重要,因为其内部特性保持不变。

相对比较

请注意,NES 中搭载的 6502 CPU 运行频率仅为约 2 MHz。 这大约只有SMS芯片运行速度的一半。 再加上 Z80 拥有更大的寄存器文件,人们可能会认为SMS的性能毫无疑问地超越 NES。

相反,如果我们深入探究,会发现 6502 拥有一个更大的(8 位)ALU。 因此,在 6502 上只需两个周期完成的算术操作,在 Z80 上则需要消耗四个周期。 归根结底,这说明像 CPU 时钟频率或寄存器文件大小这样的相对特性,如果孤立地分析,可能会产生误导。 Z80 和 6502 在不同的任务上各有优势和劣势,最终取决于程序员的本事。

可用内存

正如前面所述,Z80 拥有 16 位地址总线,这意味着 CPU 可以寻址高达 64 KB 的内存。 在SMS的内存映射中,你会发现有 8 KB 的 RAM 供通用用途使用[2],这部分内存还被镜像到另外一块 8 KB 区域。 最后,最多可映射 48 KB 的游戏 ROM

访问其它组件

从上一段我们可以了解到,主 RAM 和部分卡带 ROM 是唯一出现在地址空间中的组件,那么程序如何访问其他硬件呢? 与任天堂的 Famicom/NES 不同,SMS并非所有的硬件都是通过内存地址映射的。 相反,一些外设位于 I/O 空间中

这是因为 Z80 家族包含了一个有趣的功能称为 I/O 端口,它使得 CPU 可以与其它硬件通信而不占用内存地址。 为此,存在一个专门用于“I/O 设备”的地址空间,称为端口,并且这些端口与内存共享相同的数据和地址总线。 不同之处在于,端口是通过 INOUT 指令来读取和写入的——而传统的载入/存储指令 (LD) 则不适用于此。

当执行 INOUT指令时,Z80 设置地址线指向特定的外设(例如键盘),并标记其 IORQ 引脚表示已发起 I/O 请求,最后根据是 IN 还是 OUT 指令分别标记 RDWR 引脚。 被寻址的外设必须手动检查地址总线和 I/O 引脚,并执行所需的操作。 在执行 IN 指令的情况下,CPU 将接收到的值存储在一个预定义的寄存器中。

Image
SMS的寻址布局。

世嘉这种 CPU 与其余组件互联的方式不仅使得可以访问其数值,还可以选择性地显示或隐藏某些组件,使其不出现在内存映射中。

有趣的是,GB(Game Boy) 使用了一种省略了 I/O 端口的 Z80“变体”。 因此,它不得不将所有东西都放在内存映射中。

向后兼容性

这台游戏机的架构与其前身 Sega SG-1000非常相似,因此SMS实现了与 SG-1000 的向后兼容性。 不过,这一点仅适用于日版机型,因为其他版本使用了不同的卡带插槽。


图形

屏幕上的图像由一个名为“视频显示处理器”(Video Display Processor ,简称 VDP)的专有芯片产生。 在内部,它的设计与 SG-1000 中使用的德州仪器 TMS9918 相同[3],但增强了更多功能,我们将在接下来的部分中讨论这些增强的功能。

硬件组织

Image
VDP的内存架构。

VDP 旁边连接了 16 KB 的 VRAM (视频随机存取存储器),VDP 可以通过 16 位数据总线访问这些 VRAM(Sega 修改了原始设计,使其能够同时访问两个带有 8 位总线的内存芯片[4])。 如果你再次查看主板的照片,你会注意到 RAM 和 VRAM 芯片大致相同,只是 VRAM 使用的是型号末尾为 ‘20’ 的芯片,具有更低的延迟[5]

对于 SMS 而言,VRAM 存储了 VDP 渲染所需的所有数据(除了颜色 RAM)。 CPU 通过写入特定的 VDP 寄存器来填充 VRAM,这些寄存器随后会将值转发给 VRAM。 由于 VDP 是通过 I/O 端口访问的,CPU 必须使用 INOUT 指令。

构造帧

VDP 以最高 256x192 像素的分辨率渲染帧,后续修订版增加了对 256x224 像素和 256x240 像素的支持;然而,为了与所有型号保持兼容性,开发者们只能坚持使用标准分辨率。 该芯片的工作模式与任天堂的 PPU 相同,也就是说,图形是即时渲染的。

另一方面,VDP 具有四种不同的工作模式,这些模式会改变帧的特性(色彩深度和分辨率):

现在让我们一步步地看看一帧是如何绘制的。为此,我将借用刺猬索尼克的素材。 此外,为了让解释更简单,我将会专注于世嘉建议的用于组织图形内容的标准内存布局(只需记住 VDP 在这方面非常灵活,因此游戏可以对其进行优化)。

图块

Image
所有图块。
Image
一个图块。
在VRAM中找到图块。

模式 IV 基于图块系统。 回顾之前关于图块引擎的解释,图块就是 8x8 像素的位图,渲染器从中获取来绘制游戏图形。 在 VDP 的情况下,帧由两层组成,背景层和精灵层。

在VRAM 中,有一个专门用于存储图块的区域,称为角色生成器(世嘉称图块为“角色”),其容量设定为 14 KB。 每个图块占用 32 字节,因此我们最多可以存储 448 个图块。

每个图块定义了 64 个像素,VDP 规定每个像素必须占用 4 位,这意味着可以从 16 种颜色中选择。 这些位引用颜色 RAM 或简称“CRAM”中的单一条目。 这个区域位于 VDP 内部,存储着颜色调色板。 颜色调色板系统有助于减少内存中图块的大小,并允许程序员更改颜色而不必存储多个副本。

颜色 RAM 存储两个各含 16 种颜色的调色板。 每个条目宽 6 位,每组 2 位定义 RGB 模型中的一个颜色。 这意味着可选的颜色总数为 64 种。

背景层

Image
已分配的屏幕地图。
Image
已分配的屏幕地图,带有选定区域标记。
已分配的屏幕映射,其中标记了选定区域。

背景层是一个大的平面,静态图块被绘制于此。 为了在此处放置内容,VRAM 中还有一个名为屏幕地图的区域,它占用 1.75 KB 的空间。

这使得开发者能够构建一个包含 896 个图块(32x28 图块)[6] 的图层,但如果计算一下就会发现,这个图层实际上比该游戏机的显示分辨率还要大。 实际上,只有 其中的768 个图块(32x24 图块)是可见的,而这个可见区域是由程序员手动选定的。 因此,通过缓慢地改变选定区域的 X 和 Y 坐标,就可以实现滚动效果

地图中的每个条目宽 2 字节(与 VDP 数据总线一样宽),包含了图块在字符生成器中的地址以及以下属性:

  • 水平翻转和垂直翻转
  • 优先比特位(是否将图块全部或部分置于精灵图前方)
  • 使用的颜色调色板

有趣的是,在这里中有 3 个未使用的位,游戏可以将其用于其他目的(例如,用于辅助游戏引擎的额外标志)。

精灵图

Image
渲染的精灵图层。

精灵图只不过是能够自由移动的图块而已。 VDP(视频显示处理器)最多可以使用单一图块(8x8 像素)或两个垂直堆叠的图块(8x16 像素)来光栅化多达 64 个精灵图

精灵图属性表是在 VRAM 中的一个 256 字节区域,它包含所有定义好的精灵图的数组,其条目与背景层类似,只不过每个精灵图还包含两个额外的值,代表 X/Y 坐标。

VDP 在每一水平扫描线上最多只能显示八个精灵图[7]。 而且,如果有多个精灵图重叠,列表中的第一个将会被显示。

结果

Image
嗒哒——!

VDP 自动将这两层融合以形成最终的画面。 渲染过程是一行一行地完成的,因此 VDP 实际上并不知道整个画面会是什么样子,只有当图像在电视上构建完成后用户才能看到。

如果你观察示例图像,可能会注意到画面左侧有一列垂直的条纹。 这是因为屏幕地图的高度足以提供垂直滚动而不产生伪影,但宽度不足以支持水平滚动。 因此,VDP 可以用一个 8 像素宽的列来遮罩最左侧,以防止显示中间的图块,保护图像不被破坏。

为了更新下一帧的画面而不破坏正在显示的图像,VDP 会向 CPU 发送两种类型的中断信号。 一种是在 CRT 电视完成指定数量的扫描线后发出的通知(称为水平中断),另一种是在 CRT 完成最后一行扫描线的绘制时发出的通知(称为垂直中断),表明一帧已经结束。 在这两个事件期间,CRT 的电子束正在重新定位以绘制下一行(空白区间),因此对 VDP 状态的任何改变都不会撕裂图像。 水平空白期的时间比垂直空白期短,但它仍然允许改变颜色调色板等操作。 这样仍然可以实现一些效果。

秘密和限制

乍看之下,VDP 可能看起来就像是另一个我们现在习以为常的功能有限的芯片。 不过,它确实吸引了当时大量对任天堂产品本应关注的目光。 那么为什么会这样呢?

碰撞检测

首先,VDP 能够判断两个精灵是否发生了碰撞。 这是通过检查其状态寄存器来完成的[8]。 虽然它不能检测出具体是哪两个精灵发生了碰撞,但这个限制可以通过读取其他寄存器来解决,比如扫描线计数器寄存器。 你可以把它想象成一种“三角定位”的方法。

这项特性其实并不新鲜,因为 TMS9918 也包含了这一功能,因此 SG-1000 也有碰撞检测能力。

模块化的需求

在我之前分析任天堂 PPU 的设计时,我强调了它的内部内存架构。 虽然有限制,但某些约束实际上是有益的,因为它使得系统可以通过在游戏卡带中加入额外硬件的方式进行扩展,同时降低了成本。

VDP 并没有利用这种模块化的方法。 相反,世嘉采取了一种不同的解决方案,这反过来节省了卡带的成本。 较小的背景层和水平中断就是这种方案的例子。

3D眼镜

Image
世嘉3-D眼镜[9]
美国版通过卡槽连接。

原来世嘉还将“3D眼镜”作为官方配件发货! 这副眼镜能与CRT显示器同步工作。 在游戏过程中,游戏会在不同的帧之间切换物体的位置。 每个镜片上都装有一个LCD屏幕,可以变黑以阻挡视线。 因此,正确的图像闪烁与快门交替最终在你的大脑中形成了立体图像。 这样就产生了“3D”效果。

快门由几个内存地址控制,但这些地址都不会告诉主机是否插上了眼镜,因此支持这一配件的游戏会包含一个设置选项,允许用户手动激活该功能。

LCD控制器通过插孔线缆与主机接口,这条线缆插入主机中。 欧洲和美版没有这个插孔输入口,所以它们依赖卡槽来连接适配器(我们稍后会详细介绍卡槽)。

视频输出

这套系统的视频输出接口非常实用。 它提供了复合信号(译注:AV端子)RGB 信号输出,可以想象这是视频质量的两个“极端”。

不利的一面是,它不提供“复合同步”信号,因此使用RGB信号时需要从复合信号中提取同步信号,而且这样做并不理想。


音频

这套主机的音频能力与80年代的其他设备基本保持一致。 在VDP芯片内部,我们发现了一个略微定制版的德州仪器SN76489[10],这是一种可编程声音生成器,简称“PSG”。 这种类型的PSG与NES/Famicom所使用的相同,尽管它们的功能有所不同。

功能

PSG只能合成有限几种波形,每个通道分配一种波形。 如果你想要了解更多关于这种声音合成的信息,我在关于NES和Game Boy的文章中已经介绍过一些PSG。

对于SMS来说,PSG是通过上述I/O端口改变其一组外部寄存器来进行编程的。

现在让我们来看看SN76489能够产生的各种波形:

脉冲

刺猬索尼克(1991)。
脉冲通道。

脉冲/音调波形产生了标志性的8位声音。 声波是由电压的突然上升并保持稳定然后迅速下降而产生的。 以恒定速率重复这个过程,就会产生一个音调。

波的周期定义了声音的频率(即音乐音符)。 它的占空比影响音色。

这一切都是由PSG处理的,它可以同时产生三个脉冲波。 特别是SN76489在每个通道上都暴露了一个10位计数器,用于内部以高频率进行锁定,从而产生一个可编程频率的脉冲波。

噪声

刺猬索尼克(1991)。
噪声通道。

噪声是一种与干扰相关的信号类型。 当输出到扬声器时,它听起来像是静电噪音。

SN76489包含一个线性反馈移位寄存器(Linear Feedback Shift Register,简称”LFSR”),该寄存器接收输入并通过循环产生伪随机信号。 它有一些参数可以选择白噪声周期噪声,后者会占用第三个脉冲通道,并通过LFSR产生类似低音的声音(脉冲音降低四个八度)。

所使用的振荡器也可以被调整来改变音高,有四种选项可供选择。

游戏通常使用噪声通道来产生打击乐器效果和/或音效

混音器

刺猬索尼克(1991)。
全音频通道。

目前为止,我们分别讨论了每个通道的作用,但是电视接收到的是一个将所有通道混合后的单声道信号。

最后,芯片还包含了可编程衰减器,用来降低每个通道的分贝值,实际上起到了音量控制的作用。

秘密和限制

就像VDP一样,PSG的设计也是直截了当的,但它隐藏了一些有趣的功能:

FM扩展

PSGFM
双截龙(1987)。

日版SMS内置了一个额外的音频芯片,名为 YM2413,由雅马哈制造。 它与之前的PSG有着根本的不同,因为它采用了频率调制技术来生成声音。 如果你感兴趣的话,我在MD的文章中简要解释了它是如何工作的。

这款芯片特别拥有九个音频通道。 每个通道都可以选择16种预设乐器之一,或者通过编程载波和调制器来定义一个自定义乐器。 不幸的是,一次只能允许一个自定义乐器。 另一方面,新的乐器提供了一些有趣的功能,例如ADSR包络控制和反馈。

YM2413还有一个称为节奏模式的第二种操作模式,它提供了六个通道,并补充了五个专门用于节奏乐器的额外通道

最终的声音输出由YM2413生成,它将自身的通道与PSG的通道混合在一起。

Mark III版本并没有包括这个芯片,但FM声音可以通过一个称为FM Sound Unit的扩展单元获得。 其余版本(欧版和美版的SMS)则只能使用PSG,尽管后来出现了一些第三方安装方案。

模拟器精确性

Image
使用模拟器比较脉冲波形。
NES的波形显示出一些衰减,而SMS的则是方形的。

在阅读SMS Power(一个收集大量系统技术信息的网站)的过程中,我遇到了一个有趣的章节,叫做“不完美的SN76489”[11],它讨论了我在撰写文章时遇到的一些差异。

如果你再次查看脉冲波的例子视频,你会看到它几乎呈现为一个完美的方波。 脉冲发生器通过锁定电压来产生音调。 然而,在电子电路中,元件并不会瞬间从零变为一(或反之亦然),总会存在一个过渡期(主要归因于电路中存在的滤波器)。

现在,我使用模拟器来捕捉独立的通道并在录制过程中避免干扰,尽管模拟器并不总是考虑过渡因素,因此它们的结果可能更接近于“理想情况”,而不是80年代电子产品中的实际情况。 请看示例图片。 这两个样本都来自模拟器,但似乎NES的那个可能表现得更接近模拟世界。

我现在没有必要的工具来确认SMS是否也会表现出类似的特性。 但如果确实如此,并不意味着你听到的声音是错误的,只是音量略有不同(几乎察觉不到)。

采样播放

亚历克斯小子:失落的星星(译注:似乎更多被称为天空魔城?Alex Kidd - The Lost Stars )(1986)。
1位PCM样本。

虽然SN76489没有PCM通道来重放样本,但有一些技巧可以用来模拟这一功能。

这些技巧依赖于脉冲通道,人们发现如果将音调级别固定在1,那么音量级别(改变幅度)将会影响波形的形状。

smspower.org描述了不同的设计方案,可以用来播放1位、4位和8位的PCM样本。 尽管随着样本分辨率和采样率的增加,存储需求会急剧上升,因此这些技巧的最佳应用是在自制游戏中。

值得一提的是,流式播放样本会消耗大量的CPU周期,而这套系统中只有一个处理器,因此游戏可能需要短暂停止。


I/O

与同代的其他系统一样,CPU主要负责处理I/O。 在这种情况下,Z80处理器因其特殊的I/O寻址而独特,但仍会有CPU周期用于在组件之间移动位。

另一方面,SMS使用了一个专用的I/O控制器芯片,不仅用于接口手柄,还可以启用和禁用系统的一部分,这会改变地址映射。 此外,这个控制器对于支持FM扩展至关重要,因为FM模块暴露的端口与其他系统部分冲突(也就是说,如果没有I/O芯片的介入)。

接口

除了两个手柄接口之外,系统还包括一个专有的卡带插槽、一个“Sega Card”插槽以及一个预留的扩展插槽,用于未来的配件。 后者除了在Mark III上的FM扩展之外从未被使用。 即便如此,SMS和Mark III具有不同的扩展端口设计[12]

顶层中断

这套主机的另一个特点是,在其机壳顶部有两个按钮:PAUSERESET,你可以猜到它们的功能!

Image
机壳顶部[13]

当按下PAUSE 按钮时,会向CPU发送一个不可屏蔽中断[14]。 中断向量存储在游戏中本身,这意味着是否响应按下取决于游戏本身的处理。

相比之下,出于某种奇怪的原因,RESET 按钮像手柄上的按键一样被处理。


操作系统

主板上安装了一个小型的8 KB BIOS ROM,每当主机启动时都会执行该ROM中的程序。 这个程序本身并不属于“操作系统”的范畴,更像是一个启动管理器

介质选择

BIOS的主要目标是引导一个有效的游戏(无论来自哪个插槽),优先级如下:Sega Card、卡带和扩展模块。

启动过程如下:

  1. 主机被打开。
  2. BIOS将其部分代码复制到主RAM中。
    • 这是一个关键步骤,因为程序将开始操控I/O端口,这将在某个时刻禁止访问ROM!
  3. 显示启动画面(仅在美版/欧版)。
  4. 检查每个插槽是否有有效游戏。
    • 这是通过与I/O控制器芯片通信来激活所需的插槽完成的。 然后,启动程序从每个插槽复制游戏头部(16字节)以检查游戏内容是否有效(即正确插入)。 头部必须包含TMR SEGA编码。
  5. 执行区域检查。
  6. 重定向执行游戏。

意外时的屏幕显示

如果任何检查失败,控制台将无限循环并显示提示用户插入有效游戏的屏幕:

美版/欧版错误消息(初始启动画面之后)。
日版“错误”消息(通过FM芯片增强!)。

由于地区不同,这些屏幕在设计上也有所差异。 例如,在日版本中,首次听到那段音乐时,我以为它来自于Electric Light Orchestra(一支乐队),但实际上这段音乐出自游戏《太空哈利》。 顺便说一下,地面上的透视效果是通过更改颜色调色板实现的。

更多地区差异

因为日本版兼容SG-1000,所以游戏头部检查被替换成了一个“完整性检查”,该检查会多次读取前256字节的数据来检测是否为无效数据。

此外,Mark III没有BIOS,插槽通过硬件开关激活,并且卡带具有最高的优先级。

可更新性及后续的BIOS芯片

BIOS ROM本质上是不可更新的。 不过,随着新的控制台版本进入市场,人们发现世嘉也对BIOS程序进行了更新。

后来的BIOS甚至内嵌了一款完整的游戏! 因此,ROM芯片变得更大,并且配备了一个专用的映射器。


游戏

简单来说,游戏是用纯Z80汇编语言编写的,就是这样。 如果你一直在阅读关于较新游戏机的文章,这里没有编译器或辅助软件(除了汇编器)。

存储介质

SMS提供了两种不同的游戏分发媒介:


反盗版和锁区

与任天堂不同,世嘉并没有采用激进的方法来控制他们游戏的分发,但他们确实通过改变卡带插槽的形状和使用不同的ROM头部检查来阻止北美和欧洲的系统运行日本游戏。

此外,北美和欧洲系统的头部必须包含前述的TMR SEGA代码。 所以我推测这使得他们能够利用商标法来防止未经授权的分发。


这就是全部了,伙计们。

在之前撰写了Nintendo DS的文章之后,我真正体会到了技术变得多么复杂。 从这个角度来看,SMS非常直接,即使我在文中偶尔进行了一些“技术细节的挑剔”。

无论如何,我希望这篇文章帮助你们整体了解了80年代初期至中期的技术状态。 我也想感谢smspower.org社区和/r/Emulation Discord频道的成员们,他们审阅了初稿并指出了许多错误和建议。

下篇文章见!
Rodrigo

本文献给Jacinto ‘Pocho’ Fornasier的记忆。


参与贡献

这篇文章是 游戏主机架构 系列的一部分。如果您觉得我的文章很有趣,请考虑捐赠。您的资助将用于购买工具和资源,以帮助我提高现有文章和即将发表的文章的质量。

Donate with PayPal
Become a Patreon

你也可以购买英语版本的电子书。我会将获得的利润视为捐赠。

Image

特别感谢下列人员的捐助:

- Alberto Cordeddu
- Alexander Perepechko
- Andrew Woods
- Colin Szechy
- David Bradbury
- David Sawatzke
- Eric Haskins
- Guillermo Angeris
- Josh Enders
- Sanqui
- Sébastien Lethuaire

或者,您可以通过 建议更改添加翻译 来提供帮助。


Copyright and permissions

This work is licensed under a Creative Commons Attribution 4.0 International License. You may use it for your work at no cost, even for commercial purposes. But you have to respect the license and reference the article properly. Please take a look at the following guidelines and permissions:

Article information and referencing

For any referencing style, you can use the following information:

For instance, to use with BibTeX:

@misc{copetti-mastersystem,
    url = {https://www.copetti.org/zh-hans/writings/consoles/master-system/},
    title = {SMS(Sega Master System)主机架构 - 一份实证分析},
    author = {Rodrigo Copetti},
    year = {2020}
}

or a IEEE style citation:

[1]R. Copetti, "SMS(Sega Master System)主机架构 - 一份实证分析", Copetti.org, 2020. [Online]. Available: https://www.copetti.org/zh-hans/writings/consoles/master-system/. [Accessed: day- month- year].
Special use in multimedia (Youtube, Twitch, etc)

I only ask that you at least state the author’s name, the title of the article and the URL of the article, using any style of choice.

You don’t have to include all the information in the same place if it’s not feasible. For instance, if you use the article’s imagery in a Youtube video, you may state either the author’s name or URL of the article at the bottom of the image, and then include the complete reference in the video description. In other words, for any resource used from this website, let your viewers know where it originates from.

This is a very nice example because the channel shows this website directly and their viewers know where to find it. In fact, I was so impressed with their content and commentary that I gave them an interview 🙂.

Appreciated additions

If this article has significantly contributed to your work, I would appreciate it if you could dedicate an acknowledgement section, just like I do with the people and communities that helped me.

This is of course optional and beyond the requirements of the CC license, but I think it’s a nice detail that makes us, the random authors on the net, feel part of something bigger.

Third-party publishing

If you are interested in publishing this article on a third-party website, please get in touch.

If you have translated an article and wish to publish it on a third-party website, I tend to be open about it, but please contact me first.


来源 / 继续阅读

音频

CPU

图形

I/O

影像


Rodrigo Copetti

Rodrigo Copetti

希望你能喜欢这篇文章!如果想了解本文作者的相关信息,点击这里 如果你想支持他,请点击这里

rsslinkedintwittergithub facebookreddit