如何显示在C64边境的精灵?(How do I show sprites in the border

2019-07-19 14:53发布

我见过酷C64演示显示在屏幕的边框面积精灵。 它不应该是可能的; 我认为他们设法以某种方式欺骗图形芯片。 他们究竟是如何做到的呢?

Answer 1:

是的,你需要汇编。 这是一个中断时间的把戏。 维克能够显示在边境精灵,但是框架只是躲在他们,所以精灵可以在后面滑动。 它连接到扫描由VIC显示的行。 对于下/上边框也很简单:

  • PROGRAMM中断,同步在一定的扫描线,下边框前7像素或类似的东西开始。
  • 设置在VIC寄存器使边境小。 (还有就是能做到这一点的寄存器。)
  • VIC现在认为,边境已经开始,并且不开始绘制它。
  • - >在底部无边框。
  • PROGRAMM真实的边界陆续中断设置回原来的。

对于在左/右边界的精灵,它更复杂,因为过程必须重复每次扫描线:

  • PROGRAMM中断,同步在一定的扫描线开始。
  • 然后做一些NOP指令,直到你在正确的边界前7个像素。
  • 设置在VIC寄存器使边境小。
  • - >在右侧的无边框。
  • 做一些NOP指令,直到你真正的边境后,并设置寄存器回原来的值。
  • 再做一些NOP指令,直到第2步。

问题是,所有这些NOP指令忙等待并窃取你有你的东西循环。

我能找到一些代码对你来说,从下边框的精灵卷轴。 下面是代码。 (这是从一些演示撕开。)

C198  78        SEI
C199  20 2E C1  JSR C12E     # clear sprite area
C19C  20 48 C1  JSR C148     # init VIC
C19F  A9 BF     LDA #BF      # set up IRQ in C1BF
C1A1  A2 C1     LDX #C1
C1A3  8D 14 03  STA 0314
C1A6  8E 15 03  STX 0315
C1A9  A9 1B     LDA #1B
C1AB  8D 11 D0  STA D011
C1AE  A9 F7     LDA #F7
C1B0  8D 12 D0  STA D012
C1B3  A9 01     LDA #01
C1B5  8D 1A D0  STA D01A
C1B8  A9 7F     LDA #7F
C1BA  8D 0D DC  STA DC0D
C1BD  58        CLI
C1BE  60        RTS

----------------------------------
# init VIC
C148  A2 00     LDX #00
C14A  BD 88 C1  LDA C188,X
C14D  9D 00 D0  STA D000,X   # set first 16 values from table
C150  E8        INX
C151  E0 10     CPX #10
C153  D0 F5     BNE C14A
C155  A9 FF     LDA #FF
C157  8D 15 D0  STA D015
C15A  A9 00     LDA #00
C15C  8D 1C D0  STA D01C
C15F  A9 FF     LDA #FF
C161  8D 17 D0  STA D017
C164  8D 1D D0  STA D01D
C167  A9 C0     LDA #C0
C169  8D 10 D0  STA D010
C16C  A9 F8     LDA #F8
C16E  A2 00     LDX #00
C170  9D F8 07  STA 07F8,X
C173  18        CLC
C174  69 01     ADC #01
C176  E8        INX
C177  E0 08     CPX #08
C179  D0 F5     BNE C170
C17B  A9 0E     LDA #0E
C17D  A2 00     LDX #00
C17F  9D 27 D0  STA D027,X
C182  E8        INX
C183  E0 08     CPX #08
C185  D0 F8     BNE C17F
C187  60        RTS

----------------------------------
# data set into VIC registers
C188  00 F7 30 F7 60 F7 90 F7
C190  C0 F7 F0 F7 20 F7 50 F7

----------------------------------
# main IRQ routine
C1BF  A2 08     LDX #08
C1C1  CA        DEX
C1C2  D0 FD     BNE C1C1
C1C4  A2 28     LDX #28      # 40 or so lines
C1C6  EA        NOP          # "timing"
C1C7  EA        NOP
C1C8  EA        NOP
C1C9  EA        NOP
C1CA  CE 16 D0  DEC D016     # fiddle register
C1CD  EE 16 D0  INC D016
C1D0  AC 12 D0  LDY D012
C1D3  88        DEY
C1D4  EA        NOP
C1D5  98        TYA
C1D6  29 07     AND #07
C1D8  09 18     ORA #18
C1DA  8D 11 D0  STA D011
C1DD  24 EA     BIT   EA
C1DF  EA        NOP
C1E0  EA        NOP
C1E1  CA        DEX
C1E2  10 E4     BPL C1C8     # repeat next line
C1E4  A9 1B     LDA #1B
C1E6  8D 11 D0  STA D011
C1E9  A9 01     LDA #01
C1EB  8D 19 D0  STA D019
C1EE  20 00 C0  JSR C000   # call main code
C1F1  4C 31 EA  JMP EA31   # finish IRQ


Answer 2:

这一切都依赖于时机。 的C64不得不查询电子束的精确的垂直位置,同时将其绘制在屏幕的方法。 当一个新的行启动,你不得不等待几个周期(你可以这个时间使用NOP指令),然后您必须设置这是负责制定screenmode(和边框宽度)videochip的硬件寄存器。 通过定时完全正确,并再次做它的每一个扫描线,整个sideborder消失。

底部边框还带走了类似的伎俩。 在哪里垂直边界开始的准确扫描线你也必须设置禁用它底边框该帧的:视频模式。

事实上,这件事曾在组装工作要做。 否则,你永远无法得到时间分毫不差。

作为一个方面说明,我觉得sideborder把戏记入1001船员(荷兰组)。 我不知道谁被拉断第一底边框的把戏。



Answer 3:

有关在C64开放边界的主题一个很好的教程,请帕西奥亚拉在优秀文章C =黑客第6期 。

没有得到太多的技术,诀窍使用VIC芯片的功能,让您25/24行和文本/图形三十八分之四十零列之间切换,并且涉及在准确适当的时候作出此开关VIC误以为它已经切换的时候,其实它并没有对边界。 看看上面的文章与代码示例更全面的解释。



Answer 4:

那是很久以前的事。

我知道的是,在监测的频率依赖的解决方案。

用CRT,当前像素被即使它是正常的屏幕以外公知的。 所以,你可以操纵的射线。

某处在我junkpile必须有一些C64的书籍。

Offtopic,但图形与VIC20(C64的的前身)很有趣。 有没有办法来处理每一个像素,但你可以改变现有的字符。 所以,你所有的字符填充的屏幕从0到...,改变了人物设定像素到屏幕上。 ;-)。



Answer 5:

时机是关键。 该图像是在边界通过改变过扫描(边框)颜色创建为CRT的光束移动由左到右。 有以产生图像需要两个定时信号 - 垂直刷新和水平刷新。 通过在水平方向和垂直刷新时就可以开始的汇编指令的序列来改变边框颜色以产生图像检测。 你需要计算出每个边界像素CPU的时钟周期数,并用它来创建代码,改变在正确的点上边框的颜色。

当谈到编写游戏的CPU开销是有太大而随时升降来处理用户输入和游戏状态它并不能很好地工作。



文章来源: How do I show sprites in the border on C64?