如何在Commodore PET 20xx/30xx机型上实现VBLANK间隔等待?
Commodore PET 20xx/30xx(2.0 ROM)等待VBLANK的实现方案
一、轮询VBLANK的可靠方法
你提到的$E840是PET的视频状态寄存器,它的第7位(最高位)对应VBLANK状态:该位为1时处于垂直消隐期,为0时处于显示周期。之前轮询失败大概率是没抓准状态切换的逻辑,正确的轮询流程需要分两步,确保拿到完整的VBLANK周期:
- 先等待当前VBLANK结束,确认进入显示周期
- 再等待下一次VBLANK启动,此时即可安全执行屏幕更新
对应的6502汇编代码:
; 等待VBLANK结束(进入显示周期) WAIT_VBL_END: LDA $E840 BMI WAIT_VBL_END ; 最高位为1=仍在VBLANK,继续等待 ; 等待VBLANK启动(进入消隐期) WAIT_VBL_START: LDA $E840 BPL WAIT_VBL_START ; 最高位为0=仍在显示,继续等待 ; 此处已进入VBLANK,可执行屏幕更新操作
二、用中断实现自动VBLANK触发
如果你习惯C64的中断模式,PET 2.0 ROM支持通过垂直中断自动触发VBLANK处理,步骤如下:
- 先禁用总中断,避免初始化过程中触发冲突
- 修改中断向量
$E81C/$E81D,指向你的自定义处理程序 - 通过
$E841寄存器启用视频中断 - 重新开启总中断
汇编示例:
; 初始化VBLANK中断 INIT_VBL_INT: SEI ; 禁用总中断 LDA #<VBL_HANDLER ; 写入处理程序地址低字节 STA $E81C LDA #>VBL_HANDLER ; 写入处理程序地址高字节 STA $E81D LDA $E841 ORA #%01000000 ; 置位第6位,启用视频中断 STA $E841 CLI ; 开启总中断 RTS ; VBLANK中断处理程序 VBL_HANDLER: ; 在此处执行屏幕更新逻辑 ; ... LDA $E840 ; 读取状态寄存器,清除中断标志 JMP $E81E ; 必须跳回ROM中断收尾流程,否则系统崩溃
三、关于BASIC PRINT的参考
你提到BASIC的PRINT会等待VBLANK,它的核心逻辑就是轮询$E840的最高位,和上面的轮询代码逻辑一致,只是额外做了更多的输入输出边界处理。
内容的提问来源于stack exchange,提问作者Chris Coslor
相关产品推荐
相关产品推荐

