代码之家  ›  专栏  ›  技术社区  ›  Danko Durbić

如何在C64上显示边界中的精灵?

  •  37
  • Danko Durbić  · 技术社区  · 17 年前

    5 回复  |  直到 14 年前
        1
  •  33
  •   Nisse Engström sting_roc    9 年前

    是的,你需要汇编程序。这是一个中断计时技巧。受害者可以在边界上显示精灵,但画面只是隐藏了它们,所以精灵可以在它后面滑动。它连接到受害者显示的扫描线。对于下/上边框,它非常简单:

    • 编程一个中断,同步开始于某一扫描线,在下边框前7像素或类似的位置。
    • 在VIC中设置寄存器,使边框变小(有一个寄存器可以做到这一点。)
    • 维克现在认为,边界已经开始,并没有开始绘制。
    • 在真实边界后编程另一个中断,将其设置回原始状态。

    对于左/右边框中的精灵,它更复杂,因为必须对每个扫描行重复该过程:

    • 编程一个中断,同步到某一扫描行开始。
    • 然后做一些NOP,直到距离右边框7像素。
    • 执行一些NOP操作,直到达到真实边界,并将寄存器设置回原始值。
    • 再次做一些NOP,直到第2步。

    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
    
        2
  •  10
  •   Nisse Engström sting_roc    9 年前

    这一切都取决于时机。C64有一种方法可以在绘制屏幕时查询电子束的准确垂直位置。 当新行开始时,您必须等待几个周期(您可以使用NOP指令计时),然后您必须设置负责设置屏幕模式(和边框宽度)的视频芯片的硬件寄存器。 通过精确地调整时间,并且每扫描一次,整个侧边消失了。

    底部边界用类似的技巧消失了。在垂直边框开始的确切扫描线上,您也必须设置视频模式,该模式禁用该帧的底部边框。

    作为旁注,我认为侧边技巧归功于1001名船员(一个荷兰团队)。我不知道是谁耍了第一个底边把戏。

        3
  •  9
  •   Lars Haugseth    16 年前

    有关在C64上打开边框主题的良好教程, 查看Pasi Ojala在中的精彩文章 C=Hacking Issue 6 .

    芯片使您可以在25/24行和40/38列文本/图形之间切换,以及 认为它已经打开了边界,而事实上它 没有。查看上面的文章以获得更全面的解释 使用代码示例。

        4
  •  1
  •   Toon Krijthe    17 年前

    我知道有一种解决方案依赖于监视器的频率。

    对于CRT,即使当前像素在正常屏幕之外,也可以知道它。

    在我的垃圾堆里一定有一些C64的书。

        5
  •  1
  •   user14699696 user14699696    5 年前

    如前所述,你必须愚弄受害者认为边界已经开始,但我写这篇文章的原因是因为上面的答案有点不准确:我完全无法找到一个登记簿来缩小边界,所以这就是你做这件事的方式(至少在顶部和底部):你等到受害者到达第25个字符行,然后你 启用24行

        6
  •  -1
  •   Tim Cooper    14 年前

    时间是关键。当CRT的光束从左向右移动时,通过改变过扫描(边框)颜色在边框中创建图像。产生图像需要两个定时信号——垂直刷新和水平刷新。通过检测何时发生水平和垂直刷新,您可以启动一系列汇编指令来更改边框颜色以生成图像。您需要计算出每个边框像素的CPU时钟滴答数,并使用它来创建在正确点更改边框颜色的代码。

    当涉及到编写游戏时,它的工作不是很好,因为CPU开销太大,没有时间处理用户输入和游戏状态。

    推荐文章