我见过在屏幕边框区域显示精灵的很酷的C64演示。这应该是不可能的,我想他们以某种方式欺骗了图形芯片。他们到底是怎么做到的?
发布于 2009-09-25 14:18:05
是的,你需要汇编器。这是一个中断计时技巧。VIC可以在边框中显示精灵,但框架只是将它们隐藏起来,所以精灵可以滑到它后面。它连接到VIC显示的扫描线上。对于下/上边界,它非常简单:
对于左/右边界中的精灵,它更复杂,因为每个扫描线都必须重复该过程:
问题是,所有这些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
发布于 2009-09-25 14:16:39
这一切都依赖于时机。C64有一种方法,可以在绘制屏幕时查询电子束的确切垂直位置。当一个新的行开始时,你必须等待几个周期(你可以使用NOP指令来计时),然后你必须设置视频芯片的硬件寄存器,它负责设置屏幕模式(和边框宽度)。通过精确地选择时间,并在每条扫描线上重复一次,整个边框就消失了。
底部边框也使用了类似的技巧。在垂直边框开始的确切扫描线上,您也必须设置禁用该帧的底部边框的视频代码。
事实上,这整个事情都必须在组装中完成。否则,您永远不可能获得完全正确的时机。
顺便说一句,我认为边订单技巧归功于1001机组人员(一个荷兰小组)。我不确定是谁完成了第一个底部边框的把戏。
发布于 2010-04-11 23:44:07
有关在C64上打开边界这一主题的很好的教程,请查看Pasi Ojala在C=Hacking Issue 6上的优秀文章。
在不涉及太多技术的情况下,这个技巧使用了VIC芯片的一个功能,可以让你在25/24行和40/38列的文本/图形之间切换,并涉及在正确的时刻进行这种切换,以欺骗VIC认为它已经打开了边框,而实际上并非如此。请查看上面的文章,以获得更详细的代码示例解释。
https://stackoverflow.com/questions/1477444
复制相似问题