6502汇编随机数问题

5
我在这里尝试使用6502汇编语言:http://skilldrick.github.io/easy6502 我已经制作了一个程序,它会在屏幕上的随机位置放置一个随机颜色的像素点:
LDY #$00    ; Clear Y

loop:
 JSR genPos ; Put new position in memory
 LDA $fe    ; Get random number for color
 STA ($10), Y   ; Put pixel on screen
 JMP loop

genPos:
 STA $10    ; Store accumulator in low
 LDA $fe    ; Get new random number (WHY, oh why?)
 AND #$03   ; Mask out low two bits (=numbers 0-3)
 CLC        ; Clear carry flag
 ADC #2     ; Add 2 (= numbers 2-5)
 STA $11    ; Store number in high
 RTS

我尽量使用尽可能少的指令。我的问题是,如果我在genPos子例程中不加额外的LDA $fe,像素会以非常奇怪的方式绘制,如果我有额外的LDA,则代码可以完美地工作。我无法理解原因 - 有人能给我提示吗?
问候, Jacob

是的 - 2个字节。低位在$10,高位在$11。我不明白的是,累加器中的随机数(用于上一个循环中的颜色)应该成为屏幕地址的一个很好的低字节。 - jriff
@i486:@jriff链接了他正在使用的JavaScript模拟器。它在$fe处有随机数,键盘输入在$ff处。 - Lynn
3个回答

10

它已经成为一个很好的低字节!这行代码:

LDA $fe    ; Get new random number (WHY, oh why?)

进一步决定了高位字节,如果您不生成新的随机数,则y值将取决于x值的最低两位,导致您看到的对角线: x&3的值始终等于正在绘制的屏幕段,这意味着您会得到像这样的图案

█   █   █   █   █   █   █   █    \
█   █   █   █   █   █   █   █     |
█   █   █   █   █   █   █   █     |  x & 3 == 0  in $200-$2FF
█   █   █   █   █   █   █   █     |
█   █   █   █   █   █   █   █    /
 █   █   █   █   █   █   █   █   \
 █   █   █   █   █   █   █   █    |
 █   █   █   █   █   █   █   █    |  x & 3 == 1  in $300-$3FF
 █   █   █   █   █   █   █   █    |
 █   █   █   █   █   █   █   █   /
  █   █   █   █   █   █   █   █  \
  █   █   █   █   █   █   █   █   |
  █   █   █   █   █   █   █   █   |  x & 3 == 2  in $400-$4FF
  █   █   █   █   █   █   █   █   |
  █   █   █   █   █   █   █   █  /
   █   █   █   █   █   █   █   █ \
   █   █   █   █   █   █   █   █  |
   █   █   █   █   █   █   █   █  |  x & 3 == 3  in $500-$5FF
   █   █   █   █   █   █   █   █  |
   █   █   █   █   █   █   █   █ /

非常感谢您的研究和解释。我现在明白了。 - jriff

6
应用于LDA的算法是:
[random 1] -> [11:10]
[random 1] -> [10]
[random 2]&3 + 2 -> [11]
(repeat)

如果您无法从 $fe 重新加载 a,则可能出现以下问题:
[random 1] -> [11:10]
[ramdom 1] -> [10]
[random 1]&3 + 2 -> [11]
(repeat)

因此,所寻址像素的低字节和高字节都是相同随机数的函数。它们不是独立的。这就在你看到的图案中产生了相关性。如果你假装屏幕有256个像素宽,那么它将是一个直接的对角线;基于你看到8条带,我可以推断出你的输出实际上必须是256/8=32个像素宽。
问题不在于你说“累加器中的随机数…应该成为屏幕地址的很好的低字节”,而是你也将其用于高字节。你同时使用了它们。高字节是低字节的直接函数。因此,有许多高字节你永远无法达到,因为它们不满足约束条件high=(low&3)+2。这些像素保持未点亮状态。

非常感谢您的解释。很抱歉我不能在您和Mauris之间平分荣誉 - 你们俩都值得赞扬。 - jriff
有人决定将其踩票,这是因为它写得很差吗? - Tommy

1
原因其实很简单。当你把任何东西加载到累加器中时,累加器只是那个时候的一个副本。寄存器有一个基本规则,如果你不改变它们,它们的值将会一直保持不变。
虽然存储在$fe的值每个周期都会更改,但是除非你使用另一个指令来更改累加器的内容,否则从$fe加载后累加器中的内容不会改变。这与以下情况没有区别:
LDA $0200
INC $0200 ;the value at $0200 is now 1 higher than the accumulator.

因此,如果您从未使用新的随机值重新加载累加器,则存储为高字节的值基于您用于低字节的值。


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