我该如何在6502汇编中将nibbles转换为值?

3

我正在为我的NES项目编写一个二进制格式的解压算法,用于存储屏幕文件。NES屏幕分辨率为260x240。我正在创建2x2像素格式的元瓷砖。压缩格式将指定应该写入屏幕的哪些2x2文件。

我选择的格式将被写成:

0000xxxx: right nibble = value of tile 1 - 16
xxxx0000; left nibble  = number of times a tile is written on that row 1 - 16

在上面的例子中,11110001会告诉导入程序写入1号图块16次。
我还没有想出如何将左边的半字节转换为十六进制。 我遇到的同样问题是如何将右边的半字节用作值。
我不确定是否可以使用位运算符来解决这个问题。 我需要一种有效的方法来解决这个问题。

NES不是320x240吗? - alex
实际上是256x240。精灵位置寄存器宽度为8位,单个命名表为32x30个图块。很可能不是256x256,因此有属性表的空间。在分辨率可以为320x240的Commodore 64上,精灵位置寄存器具有第九位(所有第九位都在自己的寄存器中)。 - LawrenceC
2个回答

4

假设你有一个带压缩(实际上应该用"打包"更为准确)数据的.A文件,你需要执行以下操作:

(假设tile_id_to_writewrite_it_this_many_times是你想将此数据解包到的零页位置.)

lda packed_data,X             ;or however you're iterating through the packed data
and #%00001111                ;strip off top 4 bits; this is what AND dones
sta tile_id_to_write          ;store that somewhere
lda packed_data,X             ;get the original packed data again
lsr                           ;shift right 4 times
lsr 
lsr 
lsr
sta write_it_this_many_times

根据您阅读打包数据的方式,你可能会有不同的操作,而不是使用 lda packed_data,X。我相信lsr会把0放在最高位。请记住,旋转指令会将进位重新旋转到最高位,因此通常使用asllsr进行移位或乘除2的操作。


2

我刚才想到了:

实现这个的方法如下:

val = %11110001
LDA #val
AND #%00001111 ; mask left nibble
STA rightn
LDA #val
AND #%11110000 ; mask right nibble
ROR
ROR
ROR
ROR ; rotate high bits 4 times
STA rightn

7
如果在编写代码之前设置了进位标志,那么应该使用LSR而不是ROR;否则会得到错误的结果。另外,第二个AND可以省略。 - Tommy
2
@Tommy 绝对没错,ASL/LSR通常是这种位操作的更好选择,除非你需要旋转进位。如果OP使用LSR,那么第二个AND就是多余的,因为它从左边旋转零,所以预先屏蔽低四位是浪费周期的。此外,您可以在第一个LDA之后使用TAX,然后使用TXA而不是第二个LDA,以节省一个字节和“n”个周期(取决于LDA的寻址模式)。或者冒险一点,第一次使用LAX,消除TAX。哦,最后的'STA rightn'应该是'STA leftn'。 - Eight-Bit Guru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接