wiz*_*wor 6 assembly c64 6502 6510
我打算在我的新C64项目中使用多色字符模式的软件精灵.我的想法是使用叠加'bullet'精灵数据来平铺数据.
我想我可以在地址'TILESET'处获得tileset数据,在地址'SPRITE'处有精灵数据.我可以结合这两个来准备一个动态计算背景的子弹字符并存储在地址'SUPERIMPOSED'
我编写了以下代码和循环计数来检查它是否可行.而且我认为不是.循环吃了219个循环.近四条光栅线.并且我没有在此循环之前包含所需的其他必要计算.像计算目标地址一样.
当我想在屏幕上有16个子弹时,它将需要64个栅格或8个字符行.所以我变得怀疑.这是正确的方法吗?或者还有其他更优化的方法来完成同样的工作吗?
cycles
---------
ldy #$07 4 x1 = 4
- LDA TILESET,x 3 x8 = 24
AND SPRITE,x 4 x8 = 32
STA SUPERIMPOSED,x 5 x8 = 40
dey 2 x8 = 16
cpy 4 x8 = 32
bne - 3 x8-1 = 71
----------
219 Cycle
Run Code Online (Sandbox Code Playgroud)
我正在考虑在背景中重复模式.这样我就可以使用相同的子弹牌而无需重新计算.
作为小丑建议,作为第一优化重复刚才的lda,and,sta和dey八倍.消除cpy和bne.那将立即节省103个周期.即使你想保持正式循环,请注意dey设置零标志,这样你就不需要了cpy.
作为第二个优化,请考虑编译的精灵.您不必执行读取操作sprite, x,而是将这些值直接编码到您的例程中,为每个精灵创建一个独特的例程.那又减少了16个周期.
话虽这么说,你lda在对齐的表格中将是4个周期,而不是3.所以有8个你没有考虑到.意味着展开加上专门用于你的精灵= 102个循环(省略了最后的dey).
在不知道C64体系结构和/或其余代码的作用的情况下,如果任何SUPERIMPOSED提取都可以从堆栈页面执行此操作,请考虑将输出写入堆栈而不是通过索引寻址.只需加载s适当的种子值并通过以下方式存储新结果pha.这将为每个商店节省两个周期,但需要12个额外的设置和恢复周期.
根据这个想法,如果你对这些表的外观有自由,那么考虑切换它们的格式 - 而不是一个包含所有8个字节的TILESET表,使用8个表,每个表都包含一个字节.这样就无需y在循环中进行调整; 只需在每次展开的迭代中使用不同的目标表.
假设两个TILESET并且SUPERIMPOSED可以是八个表格,可以帮助您:
LDA TILESET1, x
AND #<value>
STA SUPERIMPOSED1, x ; * 8
[... LDA TILESET2, x ...]
Run Code Online (Sandbox Code Playgroud)
...总共88个周期.如果SUPERIMPOSED是线性但在堆栈页面中则:
TSX
TXA
LDX #newdest
TXS
TAX ; adds 10
LDA TILESET1, y
AND #<value>
PHA ; * 8
[... LDA TILESET2, y ...]
TXS ; adds 2
Run Code Online (Sandbox Code Playgroud)
......这是84个周期.
迟到:
如果您愿意将索引预乘x8,有效地将可索引范围减少到32个tile,那么您可以继续填充线性输出数组而不调整y,如下所示:
LDA TILESET, x
AND #<value1>
STA SUPERIMPOSED, x
LDA TILESET+1, x
AND #<value2>
STA SUPERIMPOSED+1, x
... etc ...
Run Code Online (Sandbox Code Playgroud)
因此,您需要具有不同表基地址的该例程的八个副本,以便能够达到256个输出切片.假设你有20个精灵,这使得你的精灵绘图程序总共有20*8 = 160个副本,每个都可能是100个字节的数量级,所以你花了大约16kb.
如果你的游戏在一种精灵上比在其他精灵上重得多 - 例如通常两三艘宇宙飞船相互射击成千上万的子弹 - 那么显然你可以非常有选择地进行优化并保持总体足迹下降.