但是,在输入经典的BASIC程序之后
10 PRINT "HELLO WORLD" 20 GOTO 10
它会在一段时间后(几秒钟后)崩溃
?ILLEGAL QUANTITY ERROR IN 10
因为我的代码具有相当合理的每操作码测试覆盖率,并且它通过了AllSuiteA,我想我会考虑更复杂行为的测试,这就是我到达Klaus Dormann’s interrupt testsuite的方式.在堪萨斯熔岩模拟器中运行它指出了大量的我原来的中断实现中的错误:
>进入中断处理程序时未设置I标志
> B旗满满的
> IRQ中断被完全忽略,除非我们在他们到达时未设置(正确的行为似乎是在我设置时排队中断,当它被取消时,它们仍应被处理)
修好这些之后,我现在可以成功运行Klaus Dormann测试,所以我希望将我的机器加载到真正的FPGA上,运气好的BASIC崩溃可能会消失.
然而,修复了所有这些中断错误并在模拟器中通过中断测试的新版本现在无法响应键盘输入,甚至只是在真实FPGA上闪烁光标.请注意,键盘输入和光标闪烁都是响应外部IRQ(从屏幕VBlank信号连接)完成的,所以这意味着固定版本以某种方式打破了所有中断处理…
我正在寻找任何可能出错的模糊建议或如何开始调试.
完整的代码可以在https://github.com/gergoerdi/mos6502-kansas-lava/tree/interrupt-rewrite获得,违规提交(修复测试和打破PET的那个)是7a09b794af.我意识到这与最小可行再现完全相反,但是改变本身很小,因为我没有想法哪里出错了,因为重现问题需要一台功能足以引导库存Commodore PET ROM的机器,我不知道如何缩小它……
添加:
我设法在同一个硬件上用一个非常简单的(我敢说最小的)ROM而不是库存PET ROM重现相同的问题:
.org $C000 reset: ;; Initialize PIA LDY #$07 STY $E813 LDA #30 STA $42 STA $8000 CLI JMP * irq: CMP $E812 ; ACK irq DEC $42 BNE endirq LDX $8000 INX STX $8000 LDA #30 STA $42 endirq: RTI .res $FFFC-* .org $FFFC resetv: .addr reset irqv: .addr irq
解决方法
还要注意语义:SEI和CLI在最后一个周期中调整标志.关于是否跳转到中断的决定是之前的循环.所以当SEI作为最后一个中断进入时,你将进入我设置的中断例程.如果在命中CLI时中断处于活动状态,则处理器将在分支之前执行CLI之后的操作.
我正在打电话,所以很难评估得比提供这些陈词滥调更彻底;我稍后会尝试正确复习.有什么有用的吗?