为 Sega Genesis #4 编写汇编

在这篇文章中,我将介绍如何使用 Sega Genesis 控制台的 VDP 模拟器绘制精灵。
渲染精灵的过程与渲染图块非常相似:

  1. 将颜色加载到 CRAM
  2. 将部分精灵 8×8 上传到 VRAM
  3. 在 VRAM 中填充精灵表

例如,让我们取一个带有剑的骷髅精灵,大小为 32×32 像素

Skeleton Guy [Animated] by Disthorn

CRAM

使用 ImaGenesis,我们将其转换为用于汇编程序的 CRAM 颜色和 VRAM 模式。之后,我们将得到两个asm格式的文件,然后我们将颜色重写为字大小,并且图块必须按照正确的顺序放置才能绘制。
有趣的信息:您可以通过 0xF 寄存器将 VDP 自动递增切换为字大小,这将从 CRAM 颜色填充代码中删除地址增量。

显存

将棋手册对于大精灵有正确的图块顺序,但我们更聪明,所以我们将从博客中获取索引ChibiAkumas,让我们从索引 0 开始计数:

0 4 8 12

1 5 9 13

2 6 10 14

3 7 11 15

为什么一切都是颠倒的?你想要什么,控制台是日本的!甚至可以从右到左!
让我们手动更改 asm sprite 文件中的顺序:

	dc.l	$11111111	; Tile #0 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111	; Tile #4 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111
	dc.l	$11111111	; Tile #8 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111111 
	dc.l	$11111122 
	dc.l	$11111122 
	dc.l	$11111166 
	dc.l	$11111166	; Tile #12 
	dc.l	$11111166 
	dc.l	$11111166 
	и т.д. 

像常规图块/图案一样加载精灵:

  lea Sprite,a0 
  move.l #$40200000,vdp_control_port; write to VRAM command 
  move.w #128,d0 ; (16*8 rows of sprite) counter 
SpriteVRAMLoop: 
  move.l (a0)+,vdp_data_port; 
  dbra d0,SpriteVRAMLoop 

要绘制精灵,剩下的就是填写精灵表

精灵表

精灵表被填充在VRAM中,其所在位置的地址被输入到VDP寄存器0x05中,这个地址又很棘手,你可以在手册中看到它,地址F000的例子:

Ок, теперь запишем наш спрайт в таблицу. Для этого нужно заполнить “структуру” данных состоящую из четырех word. Бинарное описание структуры вы можете найти в мануале. Лично я сделал проще, таблицу спрайтов можно редактировать вручную в эмуляторе Exodus.
结构体参数从名字上就很明显了,例如XPos、YPos–坐标,瓷砖–绘制起始图块的编号、HSize、VSize –精灵尺寸通过添加第 8×8、HFlip、VFlip– 部分来实现。精灵水平和垂直的硬件旋转。

记住精灵可以离开屏幕非常重要,这是正确的行为,因为……从内存中卸载离屏精灵 –相当耗费资源的活动。
模拟器中填充数据后,需要从VRAM复制到地址0xF000,Exodus也支持此功能。
类比绘制图块,我们首先访问VDP控制端口从地址0xF000开始写入,然后将结构体写入数据端口。
让我提醒您,VRAM寻址的描述可以在手册或博客中阅读 无名算法 .

简而言之,VDP 寻址的工作原理如下:
[..DC BA98 7654 3210 …. …。 …。 ..FE]
其中 hex 是所需地址中的位位置。前两位是请求的命令类型,例如 01 –写入 VRAM。那么对于地址 0XF000 结果是:
0111 0000 0000 0000 0000 0000 0000 0011 (70000003)

结果我们得到代码:

  move.l #$70000003,vdp_control_port 
  move.w #$0100,vdp_data_port 
  move.w #$0F00,vdp_data_port 
  move.w #$0001,vdp_data_port 
  move.w #$0100,vdp_data_port 

之后,骨骼精灵将显示在坐标 256, 256 处。很酷吧?

链接

https://gitlab.com/demensdeum /segagenesissamples/-/tree/main/7Sprite/vasm
https://opengameart.org/content/skeleton-guy-animated

来源

https://namelessalgorithm.com/genesis/blog/vdp/
https://www.chibiakumas.com/68000/platform3.php#LessonP27
https://plutiedev.com/sprites

Leave a Comment

Your email address will not be published. Required fields are marked *