Поведение прерывания 6502 в автономном тесте по сравнению с Commodore PET

Я строю Commodore PET на FPGA. Я реализовал собственное ядро ​​6502 в Kansas Lava (код доступен по адресу https://github.com/gergoerdi/mos6502-kansas-lava) и достаточное количество операций ввода-вывода (https://github.com/gergoerdi/eightbit-kansas-lava) Я смог загрузить на нем оригинальный Commodore PET ROM, получить мигающий курсор и начать печатать.

Однако, набрав классическую программу BASIC

10 PRINT "HELLO WORLD"
20 GOTO 10

он вылетает через некоторое время (через несколько секунд) с

?ILLEGAL QUANTITY ERROR IN   10

Потому что мой код имеет достаточно разумное тестовое покрытие для каждого кода операции и проходит AllSuiteA, я подумал, что стоит изучить тесты для более сложного поведения, и так я пришел к Комплект прерываний Клауса Дорманна. Запуск его в симуляторе Kansas Lava выявил массу ошибок в моей исходной реализации прерывания:

  • Не был установлен флаг I при входе в обработчик прерывания
  • Флаг B был повсюду
  • Прерывания IRQ полностью игнорировались, если только I не было сброшено, когда они прибыли (правильное поведение, по-видимому, состоит в том, чтобы ставить прерывания в очередь, когда I установлено, и когда оно сбрасывается, их все равно следует обрабатывать)

После их исправления я теперь могу успешно запустить тест Клауса Дорманна, поэтому я надеялся, что, загрузив мою машину обратно на настоящую FPGA, если повезет, сбой BASIC исчезнет.

Однако новая версия, в которой все эти ошибки с прерываниями исправлены и пройдена проверка прерывания в симуляторе, теперь не реагирует на ввод с клавиатуры или даже просто мигает курсором на реальном ПЛИС. Обратите внимание, что и ввод с клавиатуры, и мигание курсора выполняются в ответ на внешнее IRQ (подключенное от сигнала экрана VBlank), поэтому это означает, что исправленная версия каким-то образом нарушила всю обработку прерываний...

Я ищу любые расплывчатые предложения, что может пойти не так или как я могу начать отлаживать это.

Полный код доступен по адресу https://github.com/gergoerdi/mos6502-kansas-lava/tree/interrupt-rewrite, ошибочный коммит (тот, который исправляет тест и ломает PET) — 7a09b794af. Я понимаю, что это полная противоположность минимально жизнеспособному воспроизведению, но само изменение крошечное, и поскольку я понятия не имею, где что-то пойдет не так, и поскольку для воспроизведения проблемы требуется машина, достаточно функциональная для загрузки стандартного Commodore 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

person Cactus    schedule 04.07.2015    source источник


Ответы (1)


Прерывания не ставятся в очередь; строка прерывания выбирается в предпоследнем цикле каждой инструкции, и если она тогда активна, а я не установлен, то затем вместо выборки/декодирования происходит переход к прерыванию. Может ли быть путаница в том, что IRQ запускается по уровню, а не по фронту, и обычно удерживается на высоком уровне в течение периода, а не одного цикла? Таким образом, очистка I приведет к немедленному прерыванию, если оно уже было запущено. Похоже, что прерывание PET остается активным до тех пор, пока ЦП не подтвердит его?

Также обратите внимание на семантику: SEI и CLI настраивают флаг в последнем цикле. Решение о переходе к прерыванию было принято предыдущим циклом. Таким образом, SEI в качестве последней вещи, когда приходит прерывание, вы войдете в процедуру прерывания с установленным I. Если прерывание активно, когда вы нажмете CLI, то процессор выполнит операцию после CLI до ветвления.

Я разговариваю по телефону, поэтому сложно оценить более тщательно, чем предложить эти банальности; Я постараюсь сделать обзор позже. Что-нибудь из этого полезно?

person Tommy    schedule 05.07.2015
comment
Да! Очень много полезного, спасибо! Мне придется просмотреть свой код, чтобы выяснить, почему тест не прошел, если только я не поставил в очередь прерывания (я просто предположил, что так и должно быть). Но я тоже в телефонном банкомате ???? - person Cactus; 05.07.2015
comment
В конце концов я принял этот ответ, потому что корень моего замешательства заключался в том, что я думал, что ввод IRQ поставлен в очередь. К сожалению, оказалось, что исправление прерываний, чтобы они работали в тесте и в PET, по-прежнему не устраняет сбой бесконечного цикла; у этого, кажется, другая причина... - person Cactus; 07.07.2015
comment
Пробовали ли вы какие-либо другие тестовые программы? В дополнение к работе AllSuiteA и Клауса Доорманна хороша работа Вольфганга Лоренца. Он даже изначально сообщает в PETSCII. - person Tommy; 07.07.2015
comment
Спасибо, посмотрю! Я думаю, что меня это обескуражило, потому что я увидел, что он связан как «набор тестов C64», и я чувствую, что мне еще далеко до создания полноценного C64. Но если хотя бы часть его можно будет запустить на bare-bone 6502, или PET, то проверю. - person Cactus; 07.07.2015
comment
Да — это огромное количество отдельных тест-кейсов, подавляющее большинство из которых — обычные инструкции 6502. Только последние несколько связаны с аппаратным обеспечением C64; даже если ваша тестовая реализация позволяет каждому тесту загружать следующий, есть единственная точка, в которой вы можете остановиться и не пропустить ничего общего. Нет необходимости в полном белом списке. Одна конкретная вещь, которую затрагивает набор тестов, которой не касаются два других, — это drcimal ADC/SBC с аргументами, отличными от BCD. Но в основном это просто хорошее дополнительное покрытие. - person Tommy; 07.07.2015