在Commodore 64

时间:2015-09-27 09:24:54

标签: assembly 6502 c64 6510

我打算在我的新C64项目中使用多色字符模式的软件精灵。我的想法是使用叠加' bullet'精灵数据到平铺数据。

我认为我可以在地址' TILESET',精灵数据地址' SPRITE'中设置拼贴数据。我可以将这两个结合起来,准备一个动态计算背景的子弹字母并存储在地址中“超级显示”'

我编写了以下代码和循环计数来检查它是否可行。而且我认为不是。循环吃了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

我考虑在背景中重复模式。这样我就可以使用相同的子弹牌而无需重新计算。

1 个答案:

答案 0 :(得分:7)

正如Jester建议的那样,作为第一次优化,只需重复ldaandstadey八次。消除cpybne。那将立即节省103个周期。即使你想保持正式循环,请注意dey设置零标志,这样你就不需要cpy

作为第二个优化,请考虑编译的精灵。您不必从sprite, x执行读取操作,而是将这些值直接编码到您的例程中,为每个精灵创建一个独特的例程。那又减少了16个周期。

话虽这么说,你的lda在对齐的表格中将是4个周期,而不是3.所以有8个你没有考虑到。意味着展开并专门用于精灵= 102个循环(省略了最终dey)。

在不了解C64架构和/或其余代码的作用的情况下,如果从堆栈页面中摄取SUPERIMPOSED的任何人都可以这样做,请考虑将输出写入堆栈而不是通过索引编址。只需使用适当的种子值加载s,然后通过pha存储新结果。这将为每个商店节省两个周期,但需要12个额外的设置和恢复周期。

根据这个想法,如果您对这些表的外观有自由,那么考虑切换它们的格式 - 而不是一个包含TILESET的所有八个字节的表,使用八个表,每个表保存一个字节它的。这样就无需在循环中调整y;只需在每次展开的迭代中使用不同的目标表。

假设TILESETSUPERIMPOSED都可以是八个表格,可以帮助您:

LDA TILESET1, x
AND #<value>
STA SUPERIMPOSED1, x    ; * 8

[... LDA TILESET2, x ...]

...总共88个周期。如果SUPERIMPOSED是线性的,但在堆栈页面中则是:

TSX
TXA
LDX #newdest
TXS
TAX                ; adds 10

LDA TILESET1, y
AND #<value>
PHA                ; * 8

[... LDA TILESET2, y ...]

TXS                ; adds 2

......这是84个周期。

迟到:

如果您愿意将x中的索引预乘8,有效地将可索引范围减少到32个tile,那么您可以继续填充线性输出数组而不调整y,如下所示:

LDA TILESET, x
AND #<value1>
STA SUPERIMPOSED, x

LDA TILESET+1, x
AND #<value2>
STA SUPERIMPOSED+1, x

... etc ...

因此,您需要具有不同表基地址的该例程的八个副本仍然能够达到256个输出切片。假设你有20个精灵,它总共有20 * 8 = 160个精灵绘图程序副本,每个副本可能大约为100个字节,所以你花费大约16kb。

如果你的游戏在一种精灵上比在其他精灵上重得多 - 例如它通常是两三艘宇宙飞船相互射击成千上万的子弹 - 显然你可以非常有选择地进行优化并保持总体足迹。