应用负 HMP0 值时渲染 ATARI-2600 Sprite 时出现问题

Qui*_*ver 4 assembly 6502 atari-2600 batari-basic

有人质疑 ATARI-2600 吗?

在此输入图像描述

当一个字节存储在 TIA HMP0 寄存器中时,精细位置调整将应用于粗略光束位置。Stella 手册称该值可以是 -8 到 7 之间的任何值。其中 -8 是(二进制 1000),7 是(二进制 0111),因为半字节被读取为二进制补码。

我的问题是,当应用任何负的精细位置值时,我无法让 Sprite 渲染。作为演示,请观察由于 HMOVE 按栅格线移动的结果而为 Sprite 0 渲染的对角线。然而,当应用的值的高位为 1(也称为负数)时,精灵就会消失,并且该扫描线上没有任何内容。为了进行比较,Sprite 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
Run Code Online (Sandbox Code Playgroud)

该代码的项目位于githubs上,在线 Atari 模拟器 8bitworkshop 上的项目位于此处

据我了解,如果提供了解决方案,那么左侧的精灵将在每一行上渲染,而不会用点位置二进制补码位模式进行中断。

Tom*_*mmy 5

重置时(即当您点击 时),玩家对象不会显示RESP0;存在延迟,导致您设置的位置在下一行生效,但在当前行无效。引用TIA_HW_Notes.txt

无论好坏,手动“重置”信号 (RESP0) 不会生成用于图形输出的 START 信号。这意味着您必须始终进行“重置”,然后等待计数器结束(160 CLK 后),然后播放器的主副本才会出现。

因此,当您指定原始位置右侧的偏移量时,您看不到玩家对象出现的原因很简单,您在RESP0对象输出开始之前点击了下一行,这会延迟一行。

相反,如果您将其移至左侧,输出会在您点击重置之前开始,因此是可见的。


为了提供更多细节,即使可能是多余的,2600 的玩家对象:

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

重置与溢出不同,因此不会触发对象显示。

对于精细运动,硬件允许您:

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

因此,您可以撤消任意数量的丢失时钟HMOVE,甚至可以添加最多 7 个额外时钟,从而导致对象比原本应该更早地触发。为了方便起见,您提供的二进制补码的最高位被反转。


所以,我认为你的代码发生了什么:

对于对象确实出现的行,您:

  1. 重置物体位置;和
  2. 安排足够的额外边界时钟,以便在下一行再次重置它之前触发它。

因此它看起来是定位的。

对于没有出现该对象的行,您可以:

  1. 重置物体位置;
  2. 设置HMOVEHMP0使得计数器在您刚刚重置它的位置之后的下一行溢出;但
  3. 在下一行中,您需要在计数器到达之前再次重置计数器。

因此计数器永远不会溢出,并且该对象不会出现。