Дизассемблер/Отладчик

Советский компьютер Радио-86РК (1986) и его клоны

Moderator: Shaos

User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Дизассемблер/Отладчик

Post by Alikberov »

Слегка дополнив код своего дизассемблера, попытался сделать простейший отладчик.

После запуска, клавиша F1 последовательно выполняет текущую инструкцию со входом в CALL-вызов, отображаемую на экране. А клавиша F2 позволяет обойти CALL-вызов.
Остальные клавиши - прерывают отладку с возвратом в Монитор.

P.S.: Код довольно сырой и глючит в отдельных моментах.
Если удастся этот отладчик отладить (каламбур :mrgreen: ), открою отдельную тему.
You do not have the required permissions to view the files attached to this post.
User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Дизассемблер/Отладчик для ПЗУ

Post by Alikberov »

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

Как уже говорилось раннее, все непонятные директивы Монитор передаёт на рассмотрение коду по F000.
Конкретно данный вариант отзывается на цифру:
  • «1,0» - Запуск отладки с адреса 0000h со скоростью 10h
  • «01234» или «01 234» - Продолжить отладку со скоростью 01h на 234h циклов
  • «9FFFF» или «9F FFF» - Продолжить отладку на максимальной скорости 9Fh на FFFh циклов
  • «9FFFF,,37» или «9FFFF,,33» - Продолжить отладку с подавлением вывода дампов
Здесь первые две цифры указывают частоту отображения информации о регистрах на экран, а остальные три цифры - продолжительность выполнения до возврата в Монитор.
Третий параметр - маска:
  • 1 - Подавить дамп регистровой пары BC
  • 2 - Подавить дамп регистровой пары DE
  • 3 - Подавить дампы регистровых пар DE и BC
  • 4 - Подавить дамп регистровой пары HL
  • 5 - Подавить дампы регистровых пар HL и BC
  • 6 - Подавить дампы регистровых пар HL и DE
  • 7 - Подавить дампы регистровых пар HL, DE и BC
  • 10 - Подавить дамп счётчика команд PC
  • 20 - Подавить дамп указателя стека SP
  • 30 - Подавить дампы указателей PC и SP
  • 37 - Подавить все дампы

 Посмотреть


P.S.: Если аудитория проявит интерес - после более детальной отладки открою отдельную тему. Пока - пусть повисит тут.
P.P.S.: Обновил код, исправил глюки - "Цирк" и "Ксоникс" работают почти без проблем, так как добавил подавление дампов маской третьего параметра. :obye:
You do not have the required permissions to view the files attached to this post.
Last edited by Alikberov on 22 Feb 2024 09:43, edited 1 time in total.
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер/Отладчик

Post by Shaos »

Отделил в новую тему
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Дизассемблер/Отладчик

Post by Alikberov »

Shaos wrote:Отделил в новую тему
Спасибо за проявленный интерес.

Однако, так дело не пойдёт: Если по адресу F000 уже имеется Победит, отладчик этот - как запускать?
Тумблером чтоли? :mrgreen:

Нужно определиться:
  • Стоит ли развивать этот код (F000-F7FF) дальше?
  • Или придумать способ переключения страниц (в эмуляторах он отсутствует)
Как быть?
Пока этот прожэкт разрабатывался для индивидуальных целей (конкретно: проверить обработку инструкций IN/OUT с перехватом, вместо системных вызовов), чтобы прощупать возможные нюансы и подводные камни. :lol:
(Да, код отладчика содержит такую вот пасхалку!)

Как пример, вот этот код:

 Показать

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;
;                       ;
; Проверка IN/OUT       ;
;                       ;
;;;;;;;;;;;;;;;;;;;;;;;;;
HIWORD: EQU     002H    ; Порт "старшего слова"
GETKEY: EQU     003H    ; Порт чтения с клавиатуры
PUTCHR: EQU     009H    ; Порт печати символа
CHEKEY: EQU     012H    ; Порт опроса клавиатуры
PUTHEX: EQU     015H    ; Порт печати байта
PUTEXT: EQU     018H    ; Порт печати текста
CURX:   EQU     01EH    ; Порт X-координаты курсора
CURY:   EQU     01FH    ; Порт Y-координаты курсора
CURCHR: EQU     021H    ; Порт символа в позиции курсора

        ORG     00000H
        LXI     SP,075FFH
        IN      CURX    ; Читаем позицию курсора по X
        MOV     C,A     ; Запоминаем в регистре C
        IN      CURY    ; Читаем позицию курсора по Y
        MOV     B,A     ; Запоминаем в регистре B
        LXI     H,HELLO ; Ссылка на приветствующее сообщение
        MOV     A,H     ; Старший байт адреса
        OUT     HIWORD  ; Фиксируем в вспомогательный порт
        MOV     A,L     ; Адрес на первый символ сообщения
        OUT     PUTEXT  ; выводим в порт печати текста
        MOV     A,C     ; Сначала отобразим координаты курсора
        OUT     PUTHEX  ; Байтом координаты X
        MVI     A,02CH  ; Разделитель координат - запятая
        OUT     PUTCHR  ; отображаем её
        MOV     A,B     ; Отобразим координату Y
        OUT     PUTHEX  ; байтом
        MVI     A,WAITCR; Сообщение ожидания пользователя
        OUT     PUTEXT  ; выводим на экран
WAIT:   IN      GETKEY  ; Читаем клавишу с ожиданием
        CPI     00DH    ; Клавиша ВК?
        JNZ     WAIT    ; Продолжаем ожидать!
        ;;;;;;;;;;;;;;;;;
        MVI     C,03FH  ; Позиция X рисования рамки
FRAMEX: MOV     A,C     ; Координату X
        ADI     008H    ; Смещаем на 8 позиций
        OUT     CURX    ; И перемещаем курсор
        MVI     A,003H  ; Константа смещения верхней строки
        OUT     CURY    ; Перемещаем курсор
        MVI     A,02BH  ; Символ "+"
        OUT     CURCHR  ; Непосредственное отображение на экран
        MVI     A,01BH  ; Константа смещения нижней строки
        OUT     CURY    ; Перемещаем курсор
        MVI     A,02BH  ; Символ "+"
        OUT     CURCHR  ; Непосредственное отображение на экран
        DCR     C       ; Продолжаем цикл
        JP      FRAMEX  ; для всех 64 позиций
        ;;;;;;;;;;;;;;;;;
        MVI     C,018H  ; Позиция Y рисования рамки
FRAMEY: MOV     A,C     ; Координату Y
        ADI     003H    ; Смещаем на Y позиции
        OUT     CURY    ; И перемещаем курсор
        MVI     A,008H  ; Константа смещения левого символа
        OUT     CURX    ; Перемещаем курсор
        MVI     A,02BH  ; Символ "+"
        OUT     CURCHR  ; Непосредственное отображение на экран
        MVI     A,047H  ; Константа смещения правого символа
        OUT     CURX    ; Перемещаем курсор
        MVI     A,02BH  ; Символ "+"
        OUT     CURCHR  ; Непосредственное отображение на экран
        DCR     C       ; Продолжаем цикл
        JP      FRAMEY  ; для всех 25 позиций
        ;;;;;;;;;;;;;;;;;
        HLT
;;;;;;;;
HELLO:  DB      1BH,'Y,0POSITION IS ',0
WAITCR: DB      1BH,'Y-0PRESS ENTER KEY',0

Хоть и выглядит не совсем обычно для РК, но под отладчиком - работает!
Запускается по «9F» (быстро) или «00FFF» (медленно) в Emu80…
(Напомню, перезапуск - добавление запятой, типа «0,».)
You do not have the required permissions to view the files attached to this post.
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер/Отладчик

Post by Shaos »

Есть ещё область E000...EFFF куда ПЗУ можно воткнуть

P.S. А это чего за IN/OUT такие? Вроде для 8080A старшая и младшая части должны совпадать если деления на порты и память нету, то вместо порта N будет обращение к адресу N*257 - т.е. OUT 1F будет писать в ячейку памяти 1F1F, но в вывешенной программе там вроде бы ничего нету...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Дизассемблер/Отладчик

Post by Alikberov »

Shaos wrote:Есть ещё область E000...EFFF куда ПЗУ можно воткнуть
А как же «Победит»?
Создалась ситуация, когда любая неизвестная директива передаёт управление на F000, а в Emu80 директива U передаёт управление на E000.
Так как передача управления по U происходит до чтения параметров - по адресу F88B…F890, это делает невозможным передавать какие-либо параметры.
В том-то и складывается ситуация, что - либо Победит, либо Отладчик!

Так как отладчик реагирует только на Директиву-Цифру, можно отладчик разместить по E000 и в случае ошибки, переходить на Победит по F000.

Как вариант, можно попробовать использовать свой дополнительный регистр для переключения страниц ПЗУ через адрес 8001, который всегда используется на чтение, а запись - ППА клавиатуры D20 игнорирует.

P.S.: Исправил досадную ошибку в обработке RST-команд, из-за чего Бейсик вообще не мог работать: Теперь даже PLOT/LINE работают и видно весь процесс отрисовки линии. А также, порты работают (см. скриншот). :P
Советую перекачать архив!
(К сожалению, VOLCANO так и не работает.)
You do not have the required permissions to view the files attached to this post.
User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Дизассемблер/Отладчик 64 Кб

Post by Alikberov »

В общем, реализовал всё то, ради чего и затеял написание дизассемблера с отладчиком! 8)
А именно:
  1. Виртуальные порты ввода-вывода высокого уровня
  2. Виртуальные верхние 32 Кб памяти
Тем самым, хотя бы виртуально можно прощупать всё это.

Если запустить под отладчиком «Бейсик Радио-86РК» (не «Микрон», где OUT/INP заблокированы), то можно всё проверить…
Запуск Бейсика по «9FFFF,,FF37» разрешит виртуализацию всех 64 Кб и портов:
  • «PRINT PEEK(-2045)» не вернёт код 195 (с F800 Монитора не видно)
  • «PRINT INP(3)» напечатает код нажатой клавиши (сработает вызов F803)
  • «OUT 9,127» напечатает символ 7Fh (сработает вызов F809)
Ниже - архив с ПЗУ и файл вывода дампа (запускается по «9FFFF»).
(Хотя, многим она не пригодится, так как виртуализация УВВ и всех 64 Кб - никому не нужна!)

Не у всех верхние 32 Кб отобразятся, хотя, самые внимательные, изучив стоп-кадры видео, поймут, как я этот трюк провернул!
You do not have the required permissions to view the files attached to this post.
User avatar
Shaos
Admin
Posts: 24080
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Дизассемблер/Отладчик

Post by Shaos »

Alikberov wrote:
Shaos wrote:Есть ещё область E000...EFFF куда ПЗУ можно воткнуть
А как же «Победит»?
Создалась ситуация, когда любая неизвестная директива передаёт управление на F000, а в Emu80 директива U передаёт управление на E000.
Ну перепатчи образ ПЗУ обратно как было в оригинале :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Дизассемблер/Отладчик

Post by Alikberov »

Shaos wrote:Ну перепатчи образ ПЗУ обратно как было в оригинале :)
В смысле? :roll:
Это никак не помогает.
Что U будет ссылаться на F000, что любое другое.

Есть другая мысль: Если отладчик будет всегда в доступности, отладочные функции директивы G можно упразднить, что освободит некоторое место в пространстве ПЗУ Монитора (директиву X не трогаем, так как отладчик связан с нею служебными ячейками).

Но, с другой стороны, мои разработки жёстко завязываются именно на интеграции с оригинальным Монитором. Остаётся лишь F000.
Нужно там что-то универсальное разместить, что будет предоставлять возможность выбора вспомогательного средства без лишних вопросов.
User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Дизассемблер/Отладчик

Post by Alikberov »

Оказывается, в Бейсике-Микрон были заблокированы оператор OUT и функция INP: Просто генерировали синтаксическую ошибку.
Около суток ушло на то, чтобы хоть как-то разобраться с этим (поиск битой ссылки на INP много времени занял). Но, тем не менее, в архиве - исправленный вариант Бейсика-Микрон.

Внимание/!\ Из-за известных особенностей схемы РАДИО-86РК, нельзя пользоваться оператором OUT без знания и соблюдения нюансов!

Тем не менее, под режимом отладки - можно!
Итак, прежде всего, в архиве обновлённый код отладчика DEBUGU.ROM, где всего лишь добавлен флаг подавления любой отладочной информации, что несколько повысило скорость и не засоряет экран.
Бейсик стоит после загрузки запустить по G0, чтобы загрузить файл с условным названием «PORTUGAL». Однако, запускать по RUN не рекомендуется, так как отсутствует защита с проверкой на предмет запуска из-под отладчика и операторы OUT просто могут повредить код самого Бейсика…

Затем, выходим в Монитор (в Бейсике - клавиша «СТР») и запускаем Бейсик уже под отладчиком…
  • «9FFFF» простой запуск с кучей информации на экране, медленный и без бутафорских 64 Кб
  • «9FFFF,,80» запустит Бейсик с подавлением отладочной информации (код «80»)
  • «9FFFF,,FF80» запустит Бейсик с подавлением информации и симуляцией всех 64 Кб (маска «FF» третьего параметра)
После того, как Бейсик запустится, на вопрос «NEW?», соответственно, отвечаем «N» и набираем директиву «RUN».
Конечно, следует набраться терпения… :roll:

Однако, можно поиграться и с оператором OUT («OUT 31,1») или функцией INP («PRINT INP(3)»).
You do not have the required permissions to view the files attached to this post.
User avatar
Alikberov
Doomed
Posts: 355
Joined: 14 Oct 2019 18:10
Location: Tashkent

Дизассемблер/Отладчик - Порты

Post by Alikberov »

Shaos wrote:P.S. А это чего за IN/OUT такие? Вроде для 8080A старшая и младшая части должны совпадать если деления на порты и память нету, то вместо порта N будет обращение к адресу N*257 - т.е. OUT 1F будет писать в ячейку памяти 1F1F, но в вывешенной программе там вроде бы ничего нету...
Да, есть кое-какие соображения... :roll:

Схематически перехватывать коды D3 и DB в цикле M1, блокируя ШД и подставляя некий свой код (например, CD):
  • Код «DB 03» («IN 03») перехватывается и подставляется как «FD FD FD» («CALL* FDFD»)
  • Код «D3 0F» («OUT 0F») перехватывается и подставляется как «FD FD FD» («CALL* FDFD»)
А по адресу FDFD размещается подпрограмма, типа:

Code: Select all

FDFD:   XTHL            ; Извлекаем адрес из стека.
        PUSH    PSW     ; Сохраняем Аккумулятор.
        DCX     H       ; Корректируем адрес PC
        DCX     H       ; на три шага назад,
        DCX     H       ; чтобы прочитать
        MOV     A,M     ; код инструкции.
        INX     H       ; Переходим к следующему байту.
        CPI     0D3H    ; Код инструкции OUT?
        MOV     A,M     ; Считываем индекс порта.
        INX     H       ; Корректируем адрес PC.
        JZ      FDFD@O  ; Переходим к исполнению OUT.
        ;;;;;;;;;;;;;;;;;
FDFD@I: INX     SP      ; Аккумулятор на IN не нужен,
        INX     SP      ; потому и удаляем PSW из стека.
        XTHL            ; Возвращаем PC-адрес в стек.
        PUSH    H       ; Сохраняем HL.
        MOV     L,A     ; Формируем адрес
        MVI     H,0F8H  ; в диапазоне F800-F8FF
        XTHL            ; и помещаем его в стек
        RET             ; с исполнением.
        ;;;;;;;;;;;;;;;;;
FDFD@O: STA     08000H  ; Временно сохраняем в ППА - ничего не случится.
        POP     PSW     ; Восстанавливаем аккумулятор.
        XTHL            ; Возвращаем PC-адрес в стек.
        PUSH    H       ; Сохраняем HL.
        LHLD    08000H  ; Восстанавливаем сохраннённый порт и формируем адрес
        MVI     H,0F8H  ; в диапазоне F800-F8FF
        XTHL            ; и помещаем его в стек
        RET             ; с исполнением.
Получаем изящную систему, где никаких «CALL F803…F833» в три байта не нужны и порты УВВ полностью виртуализируются (в РК и виртуализировать нечего - портов как таковых нет) в искусственные порты, где «IN/OUT» в два байта компактно вызывают API-Монитора (проекция ПЗУ Монитора вообще не нужна и ПЗУ включается лишь по сигналу перехвата кодов «IN/OUT») и приложению незачем использовать «CALL» вообще…
Монитор работает в режиме супервизора, а у пользователя - все 65536 байтов ОЗУ с теневым ПЗУ. :roll:

Вот в рамках отладчика это и эмулируется. :mrgreen: