我正在FPGA上构建Commodore PET。我已经在Kansas Lava中实现了我自己的6502核心(代码可以在https://github.com/gergoerdi/mos6502-kansas-lava获得),并且通过在其周围放置足够的IO(https://github.com/gergoerdi/eightbit-kansas-lava),我能够启动原始的Commodore PET ROM它,获得一个闪烁的光标并开始输入。
但是,在输入经典的BASIC程序后
10 PRINT "HELLO WORLD"
20 GOTO 10
它会在一段时间后(几秒钟后)崩溃
?ILLEGAL QUANTITY ERROR IN 10
因为我的代码具有相当合理的每操作码测试覆盖率,并且它通过了AllSuiteA,我想我会考虑更复杂行为的测试,这就是我到达Klaus Dormann's interrupt testsuite的方式。在Kansas Lava模拟器中运行它已经在我的原始中断实现中指出了大量的错误:
I
标志B
旗帜到处都是I
在它们到达时未设置(正确的行为似乎是在设置I
时排队中断,并且当它未设置时,它们仍应被处理)< / LI>
修好这些之后,我现在可以成功运行Klaus Dormann测试,所以我希望通过将我的机器加载到真正的FPGA上,运气好的BASIC崩溃可能会消失。
然而,修复了所有这些中断错误并在模拟器中通过中断测试的新版本现在无法响应键盘输入甚至只是在真实FPGA上闪烁光标。请注意,键盘输入和光标闪烁都是响应外部IRQ(从屏幕VBlank信号连接)完成的,所以这意味着固定版本以某种方式破坏了所有中断处理 ......
我正在寻找任何可能出错的模糊建议或如何开始调试。
完整代码可在https://github.com/gergoerdi/mos6502-kansas-lava/tree/interrupt-rewrite获得,违规提交(修复测试并打破PET的提交)为7a09b794af。我意识到这与最小可行再现完全相反,但变化本身很小,因为我不知道它出错了,并且因为重现问题需要一台功能足以引导库存Commodore PET ROM的机器,我不知道#39;我知道如何缩小它......
加了:
我设法在相同的硬件上用一个非常简单的(我敢说的最小)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
答案 0 :(得分:2)
中断没有排队;中断线在每条指令的倒数第二个周期被采样,如果它是有效的,然后我取消设置,则接下来发生跳转到中断而不是取指/解码。令人困惑的是,IRQ是水平触发的,而不是边缘触发的,并且通常在一段时间内保持高位,而不是一个周期?因此清除I将导致中断立即发生,如果它已经在进行中。看起来PET中断是否保持有效直到CPU确认它?
还要注意语义:SEI
和CLI
调整最后一个循环中的标志。关于是否跳转到中断的决定是之前的循环。所以当一个中断进入最后一个SEI
时,你将进入我设置的中断例程。如果在遇到CLI
时中断处于活动状态,则处理器将在分支前CLI
之后执行操作。
我正在打电话,所以很难评估得比提供这些陈词滥调更彻底;我稍后会尝试正确复习。这有什么用处吗?