assembly 应用负HMP 0值时渲染ATARI-2600 Sprite时出现问题

qaxu7uf2  于 2022-12-13  发布在  其他
关注(0)|答案(1)|浏览(203)

有人质疑ATARI-2600吗?

当一个字节存储在TIA HMP 0寄存器中时,对粗调光束位置进行位置微调。Stella手册规定该值可以是-8到7之间的任何值。其中-8是(1000二进制),7是(0111二进制),因为半字节是作为二进制补码读取的。
我的问题是当应用任何负的精细位置值时,观察Sprite 0渲染的对角线,这是HMOVE按栅格线移动的结果。但是,当应用的值具有高位1时(又名负)子画面消失,扫描线上什么都没有。为了比较,子画面1渲染为屏幕长度的直线B/C,没有应用精细位置。
可见行循环的代码如下:

ScanLoop
    REPEAT 10   ; wait to 
      nop       ;   get beam 
    REPEND      ;       arbitrarily near center
        
    ; All we do here is ++ the hi nibble in the Accumulator
    ; and apply it to HMP0 to adjust the fine position.
    ; QUESTION FOR READER: WHY DOESN'T THE SPRITE RENDER WHEN
    ; THE VALUE EQUATES TO A NEGATIVE VALUE (-7...-1?)

    clc
    adc #%00010000  ; Add (UI) '1' to high nibble in A

    sta HMCLR   ; Due diligence - clear all Motion values
    sta HMP0    ; Set fine P0 Sprite pos to incremented value (*)
    sta RESP0   ;   set coarse position of P0 Sprite
    sta RESP1   ; Set coarse position (only) of P1 Sprite
    sta WSYNC   ; Wait for next scanline
    sta HMOVE   ; Apply fine tweak
    stx COLUBK  ; Set the background color
        
    dex     ; decrement the scanline
    bne ScanLoop
    ;(*)PS: Tried putting HMP0 after RESP's, didn't help

这个代码的项目是githubs上的here,在线Atari模拟器8bitworkshop上的项目是here
据我所知,如果提供了一个解决方案,那么左边的Sprite将在每一行上呈现,而不使用点位置2的补码位模式。

lsmd5eda

lsmd5eda1#

玩家对象在重置时不显示(即当你点击RESP0时);存在一个延迟,导致您设置的位置在下一行而不是当前行有效。引用TIA_HW_Notes.txt
无论好坏,手动“复位”信号(RESP 0)不会为图形输出产生START信号。这意味着您必须始终执行“复位”,然后等待计数器回绕(160 CLK之后),播放器的主副本才会出现。
因此,当您将偏移量指定到播放器对象的原始位置的右侧时,您看不到播放器对象出现的原因很简单,因为在对象输出开始之前,您在下一行命中了RESP0,这会延迟一行。
相反,如果您将其移到左侧,则输出会在您点击重置之前开始,因此是可见的。
为了提供更多的细节,即使可能是多余的,2600的播放器对象:

  • 使用160值计数器,每个像素输出递增一次,不包括边界区域;
  • 每次计数器溢出时触发对象输出;和
  • 可以由程序员在任何时间重置,以便重新定位对象。

重置不同于溢出,因此不会触发对象显示。
对于精细移动,硬件允许您:

  • 触发器HMOVE,其将左边界扩展8个像素,从而由于没有计数器计时而将所有对象向右移动8个像素;和
  • 指定一个HMPx值,它是一个最多15个额外时钟的数目,可以在边界期间将其推送到对象的计数器。

因此,您可以取消HMOVE丢失的任意数量的时钟,甚至可以添加多达7个额外的时钟,从而使对象比其他情况下更早地被触发。为了方便起见,您提供的二进制补码数的最高位被反转。
所以,我认为你的代码发生了什么:
对于显示对象的行,您可以:
1.重新设置对象位置;和
1.安排足够的额外边界时钟,以便在下一行再次重置它之前触发它。
因此,其显示为已定位。
对于未显示对象的行,您可以:
1.重新设置对象位置;
1.设置HMOVEHMP0,使计数器在您刚刚复位计数器的位置之后的下一行溢出;但是,
1.在下一行中,在计数器达到该值之前,再次重置计数器。
所以计数器永远不会溢出,对象也不会出现。

相关问题