跳转至内容

Signetics 2650 & 2636 编程/对象完成同步

75% developed
来自维基教科书,开放书籍,共建自由世界

教程 - 对象完成同步

[编辑 | 编辑源代码]

PVI 有四个主对象,可以重新编程以在屏幕上显示。此处显示的屏幕截图,由 本教程的程序 创建,仅使用对象 1。主对象是白色矩形,第一个副本是黄色三角形,第二个副本是绿色三角形。每个事件的形状、颜色、大小和位置必须在每一帧上编程。编程的时机必须 与 VRST 同步,这在另一个教程中已经介绍过,还必须与对象视频显示的完成同步。

检测完成状态

[编辑 | 编辑源代码]

当 PVI 输出对象的最后一行时,它会生成一个中断并设置寄存器 $1FCA 中的相应位,在本程序中称为 objectstatus

字节 7 6 5 4 3 2 1 0
1FCA
对象/网格碰撞
1 2 3 4
对象显示完成
1 2 3 4

处理中断将在后面的章节中讨论,由于处理器没有其他工作要做,因此该程序将在一个循环中轮询该寄存器,等待相应位被设置。这由子程序 WaitObj 完成

              :;=================================================================
              :;subroutine - wait for object to finish            
              :;     enter with r1=mask for bit to be tested:
              :;     obj1=$08, obj2=$04, obj3=$02, obj4=$01
              :WaitObj:
00B7  0C1FCA  :        loda,r0 objectstatus
00BA  41      :        andz    r1
00BB  187A    :        bctr,eq waitobj
00BD  17      :        retc,un

程序以 r1 = $08 调用该子程序,该值用作掩码来测试 objectstatus 寄存器 $1FCA 中的特定位。如果相应的对象完成位没有被设置,则 andz 指令的结果将为零,因此程序将循环回并再次尝试,直到该位被设置,andz 操作产生非零结果并且子程序退出。

编程主对象及其副本

[编辑 | 编辑源代码]

一旦 VRST 变为高电平,就会设置对象 1 的初始状态。这由子程序 Object1A 完成,该子程序设置其形状、大小、颜色(一个小白色矩形)及其水平和垂直坐标。它还设置第一个副本的水平坐标和垂直偏移量。

然后,程序等待主对象显示完成,此时子程序 Object1B 会设置新的形状、大小和颜色(黄色三角形)。它还设置第二个副本的垂直偏移量。

最后,程序等待第一个副本显示完成,此时子程序 Object1C 会设置新的形状、大小、颜色(绿色三角形)和第二个副本的水平坐标。它还将第三个副本的垂直偏移量设置为一个较大的值,以确保它不在屏幕上并且没有显示。

然后,程序循环回并等待 VRST 信号的开始。

        bsta,un Vsync0          ; make sure VRST hasn't started
endless:
        bsta,un Vsync1          ; wait for VRST to start
        bsta,un Object1A        ; set initial state of object 1
        bsta,un Vsync0          ; wait for VRST to end (SEE BELOW)
        lodi,r1 $08
        bsta,un WaitObj         ; wait for primary object 1 to complete 
        bsta,un Object1B        ; set first duplicate of object 1
        lodi,r1 $08
        bsta,un WaitObj         ; wait for first duplicate to complete 
        bsta,un Object1C        ; set second duplicate of object 1:
        bctr,un endless

objectstatus 寄存器中的 对象完成 位由 PVI 重置,无论是在读取寄存器时还是在 VRST 的下降沿时。等待 VRST 结束 的代码行是为了确保在开始处理新帧之前这些位被清除。如果将该行修补掉,您将看到黄色对象不再显示。

发生的情况是,我们没有测试第二個副本是否在帧结束时完成,因此在下一帧中,主对象会在 VRST 期间被错误地检测为完成。如果在循环结束时插入对对象 1 完成的测试,您将看到问题已解决。

但是,在循环开始时等待 VRST 的下降沿是一个更简洁的解决方案

  • 在更复杂的程序中,很可能会有多个副本在帧结束时设置状态位。
  • 在循环的第一次传递中,我们不能确定状态位的条件。

创建形状,WithCarry 和 Rotate

[编辑 | 编辑源代码]

在本例中,没有使用数据表来定义三个对象的形状,而是以算法方式创建它们。

创建矩形,子程序 Object1A,是将 $FF 写入形状数组的全部十个字节的简单情况。

三角形是通过将 FF 写入底行,然后是 7F、3F 等来创建的。

        lodi,r3 10
        lodi,r0 $FF
        ppsl    withcarry     ; include carry in rotate instructions
loop1B:
        stra,r0 shape1,r3-    ; triangle shape
        cpsl    carrybit
        rrr,r0                ; shift right with 0 from the carry bit
        brnr,r3 loop1B

这段代码片段首先设置程序状态字中的 withcarry 位。现在,当执行旋转指令时,它将进位位包含在循环中并作为九位旋转操作。通过在每次旋转之前清除进位位,它的行为更像一个移位寄存器,将 1 移出并移入 0。

时间可视化

[编辑 | 编辑源代码]
更改屏幕颜色以观察等待对象完成的时间

有时,可视化程序花费多少时间仅仅等待对象的完成非常有用。这可以通过在子程序 WaitObj 执行时更改屏幕颜色来轻松实现

WaitObj:
	lodi,r0 $19		; blue
	stra,r0 backgnd
wo2
	loda,r0 ocomplete
	andz	r1
	bctr,eq	wo2                        
	lodi,r0 $00		; black
	stra,r0 backgnd
	retc,un

在本文的屏幕截图中,通常为黑色的屏幕在 WaitObj 期间变为蓝色。在本例中,我们通常有大量时间可以浪费,但也有一些动画使一些蓝色线条几乎消失。仍然有很多编程要做,这展示了在帧的哪些地方有时间进行编程。

华夏公益教科书