Поведение прерывания 6502 в автономном тесте по сравнению с Commodore PET
Я строю Commodore PET на ПЛИС. Я реализовал свое собственное ядро 6502 в Канзас-Лаве (код доступен по адресу https://github.com/gergoerdi/mos6502-kansas-lava) и поместил в него достаточно ввода-вывода ( https://github.com/gergoerdi/eightbit-kansas-lava) Я смог загрузить на него оригинальную ПЗУ Commodore PET, получить мигающий курсор и начать печатать.
Тем не менее, после ввода в классической программе BASIC
10 PRINT "HELLO WORLD"
20 GOTO 10
он падает через некоторое время (через несколько секунд) с
?ILLEGAL QUANTITY ERROR IN 10
Поскольку мой код имеет достаточно разумное тестовое покрытие для каждого кода операции и проходит AllSuiteA, я подумал, что буду искать тесты для более сложного поведения, как я и пришел к тестовому пакету прерываний Клауса Дормана. Запуск его в симуляторе Kansas Lava выявил массу ошибок в моей первоначальной реализации прерываний:
I
флаг не был установлен при входе в обработчик прерыванийB
флаг был повсюду- Прерывания IRQ полностью игнорировались, если только
I
был сброшен, когда они прибыли (правильное поведение, по-видимому, в очереди прерываний, когдаI
и когда он не установлен, они все равно должны быть обработаны)
После исправления этих ошибок я теперь могу успешно запустить тест Клауса Дормана, поэтому я надеялся загрузить свою машину обратно на настоящую ПЛИС, с некоторой удачей, что сбой ОСНОВНОГО ПРОДУКТА может уйти.
Однако новая версия со всеми исправленными ошибками прерывания и прохождением теста прерывания в симуляторе теперь не может реагировать на ввод с клавиатуры или даже просто мигать курсором на реальной ПЛИС. Обратите внимание, что как ввод с клавиатуры, так и мигание курсора выполняются в ответ на внешний IRQ (связанный с сигналом VBlank экрана), так что это означает, что фиксированная версия каким-то образом прервала всю обработку прерываний...
Я ищу какие-то смутные предложения о том, что может пойти не так или как я могу начать отлаживать это.
Полный код доступен по адресу https://github.com/gergoerdi/mos6502-kansas-lava/tree/interrupt-rewrite, ошибочный коммит (тот, который исправляет тест и нарушает PET) - 7a09b794af. Я понимаю, что это полная противоположность минимальному жизнеспособному воспроизведению, но само изменение является крошечным, и потому что я понятия не имею, где оно идет не так, и потому что для воспроизведения проблемы требуется машина, достаточно функциональная для загрузки стокового ПЗУ Commodore PET, я не понимаю не знаю, как я мог уменьшить это...
Добавлено:
Мне удалось воспроизвести ту же проблему на том же оборудовании с очень простым (я бы сказал, минимальным) ПЗУ вместо стандартного ПЗУ:
.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
1 ответ
Прерывания не ставятся в очередь; строка прерывания выбирается в предпоследнем цикле каждой инструкции, и если она активна, то, и я сбрасываю, затем происходит переход к прерыванию вместо выборки / декодирования. Может ли путаница заключаться в том, что IRQ срабатывает по уровню, а не по фронту, и обычно поддерживается на высоком уровне в течение периода, а не одного цикла? Поэтому очистка приведет к немедленному прерыванию, если оно уже происходит. Похоже, что прерывание PET остается активным до тех пор, пока процессор не подтвердит его?
Также обратите внимание на семантику: SEI
а также CLI
настроить флаг в последнем цикле. Решение о том, следует ли перейти к прерыванию, было принято циклом раньше. Так что SEI
В конце концов, когда приходит прерывание, вы входите в процедуру прерывания с установленным мной. Если прерывание активно, когда вы нажмете CLI
тогда процессор выполнит операцию после CLI
перед ветвлением.
Я разговариваю по телефону, поэтому трудно оценить более тщательно, чем предлагать эти банальности; Я постараюсь рассмотреть правильно позже. Что-нибудь из этого полезно?