RUЭВМ
Вы хотите отреагировать на этот пост ? Создайте аккаунт всего в несколько кликов или войдите на форум.
Май 2021
ПнВтСрЧтПтСбВс
     12
3456789
10111213141516
17181920212223
24252627282930
31      

Календарь Календарь

Последние темы
» ПЗУ F800 для РК86
автор Viktor2312 Сегодня в 16:21

» AHMB-1. Личная тех. тема.
автор Viktor2312 Вс Май 02 2021, 22:26

» Новости цифровых активов, разное...(eng)
автор Viktor2312 Вс Май 02 2021, 13:20

» Новости цифровых активов, разное...(rus)
автор Viktor2312 Вс Май 02 2021, 12:40

» Радио-86РК: По страницам журнала "Радио" и не только...
автор tchv71 Ср Апр 28 2021, 22:05

» км1809вг6 - аналог 6845
автор Viktor2312 Ср Апр 28 2021, 21:30

» Samsung Innovation Campus - AI Lectorium
автор Viktor2312 Вт Апр 27 2021, 22:25

» Языки программирования. Статьи, заметки, очерки, разное...
автор Viktor2312 Пн Апр 26 2021, 10:17

» Контроллер SD и USB клавиатуры на STM32
автор ведущий_специалист Сб Апр 24 2021, 16:19

» Контроллер FDD с DMA на ВГ93
автор tchv71 Сб Апр 24 2021, 15:48

» cpuminer-opt-rplant
автор Viktor2312 Вт Апр 20 2021, 14:45

» Xmrig
автор Viktor2312 Пн Апр 19 2021, 09:35

» T-Rex
автор Viktor2312 Пн Апр 19 2021, 09:33

» SRBMiner
автор Viktor2312 Пн Апр 19 2021, 09:26

» NPlusMiner
автор Viktor2312 Пн Апр 19 2021, 09:24

» NiceHash-miner
автор Viktor2312 Пн Апр 19 2021, 09:22

» NBMiner
автор Viktor2312 Пн Апр 19 2021, 09:20

» MindMiner
автор Viktor2312 Пн Апр 19 2021, 09:17

» Nanominer
автор Viktor2312 Пн Апр 19 2021, 08:49

» lolMiner
автор Viktor2312 Пн Апр 19 2021, 08:46

» KBMiner
автор Viktor2312 Пн Апр 19 2021, 08:43

» Hash Auger
автор Viktor2312 Пн Апр 19 2021, 08:40

» GMiner
автор Viktor2312 Пн Апр 19 2021, 08:37

» cpuminer-opt
автор Viktor2312 Пн Апр 19 2021, 01:37

» bminer
автор Viktor2312 Пн Апр 19 2021, 01:34

Самые активные пользователи за месяц
Viktor2312
ПЗУ F800 для РК86 Vote_l10ПЗУ F800 для РК86 Voting10ПЗУ F800 для РК86 Vote_r10 
prokushev
ПЗУ F800 для РК86 Vote_l10ПЗУ F800 для РК86 Voting10ПЗУ F800 для РК86 Vote_r10 
vzuravlo
ПЗУ F800 для РК86 Vote_l10ПЗУ F800 для РК86 Voting10ПЗУ F800 для РК86 Vote_r10 
kanzler
ПЗУ F800 для РК86 Vote_l10ПЗУ F800 для РК86 Voting10ПЗУ F800 для РК86 Vote_r10 

Поиск
 
 

Результаты :
 


Rechercher Расширенный поиск


ПЗУ F800 для РК86

Перейти вниз

ПЗУ F800 для РК86 Empty ПЗУ F800 для РК86

Сообщение  barsik Пн Янв 20 2020, 03:01

1
Если Ваша задача только спаять, отладить платку РК86, поместить её в изящный корпус и, погоняв десяток РК-игр из сезона 1988 года, убрать на полку под стекло, то дальше не читайте. В этой теме я выложу коды и исходники нескольких версий ПЗУ для РК86, которые могут быть интересны более творческим людям.

Обычно творческим людям нужен исходник ROM-BIOS со свободным местом, куда можно встроить свой дополнительный код. Например, если Вам надо подключить дополнительную периферию, но Вы испытываете трудности в том, чтобы освободить в ПЗУ РК86 свободное место для её инициализации по сбросу. Или, например, Вам нужно найти место в ПЗУ для размещения в нём стартового загрузчика, что "раскручивает" загрузку ПО для контроллера microSD (что грузить с МГ-ленты глупо).

Освободить несколько десятков байт свободного места в ПЗУ не особо сложно. Удалив ненужную директиву X, можно освободить ровно 48 байт. Убрав стоп-точку из директивы G, и переделав её правильно (чтобы передавались параметры в регистрах и возврат в монитор был по RET) освобождается ещё около 40 ячеек. Догадаться, что это надо сделать несложно и доступно каждому.

А вот дальше освобождать ячейки уже можно только оптимизацией кода. Это не такая простая задача. За один день не сделаешь. Мне в течение пары лет постепенно удалось уплющить ПЗУ РК86 на 209 байтов. А при замене на Z80 выигрывается ещё полсотни ячеек.

Если этого числа свободных ячеек всё-равно не хватает для Ваших задач, то придётся жертвовать какими-то не самыми популярными директивами. Впрочем, на этом особо много не выиграть, т.к почти все эти директивы короткие. Например, DIR_L, DIR_S и DIR_C. DIR_R тоже стоИт удалить, т.к грузить файлы вручную указывая адреса в ПЗУ это вообще детский лепет. Возможно это было уместно в 1982 году, но не в конце 80-тых. Для работы с файлами ROM-диска нужна отдельная программа.

На Специалисте и РК86 я использовал программку ROM-Service. Это всего 300 байтов, выдаёт каталог программ, которые запускаются цифрой. Причём программы в ПЗУ не обязаны идти впритык и ROM-диск можно набрать из отдельных ПЗУ с программами. Положение программ в ROM-диске не позиционное, а находится по сигнатуре. Я взял эту идею из одной книги на венгерском языке.

Но вместо внешней программки удобнее включить в ПЗУ F800 директивы работы с ROM-диском из М3 ОРИОНА. Тогда ROM-диск должен быть в формате ORDOS. Если делать запуск по имени, точно как в ОРИОНЕ, то предполагаю, что для этого 209 свободных байтов хватит притык (хотя м.быть даже чуть не хватит). Но вывод каталога ROM-диска и запуск файлов не по имени, а по порядковому номеру легко уложится всего в сотню байтов.

Вот версия исходника РК-ПЗУ в которой свободно для расширений 209 байтов. Для трансляции просто запустите BAT-файл (если у Вас убогая Windows, что не умеет запускать программы MSDOS, то запускайте BAT-файл под DosBox).

- - - Добавлено - - -

Возможно, когда у меня в очередной раз случится припадок интереса к ПЗУ РК86, то попробую встроить в монитор РК86 вывод каталога ROM-диска и запуск файлов из ROM-диска.

Замечу, что наличие ROM-диска решает проблему нехватки объёма ПЗУ для улучшения монитора. Если ROM-диск есть, можно существенно улучшить качество и объём директив монитора. Понятно, что процедуры ввода/вывода менять нельзя. Если есть верхнее ОЗУ, то по сбросу туда может грузиться расширение монитора MRK-EXT, который расширяет количество директив и улучшает качество имеющихся.

Если верхнего ОЗУ нет, то чтобы существенно не опускать RAMTOP, можно ввести в ПЗУ оверлейные директивы. При этом в вершине RAMTOP от основного ОЗУ будет отниматься небольшой объём (менее 100 байт). Для обслуживания директивы её исполнительный код будет подгружаться в ОЗУ из ROM-диска и исполняться. Пользователь не заметит разницы, но такой трюк также позволит резко поднять качество и объём директив.

В связи с тем, что недавно для эмулятора EMU80 появился конфиг для РК86 который расширяет ОЗУ РК86 на 512 кб (это доп.ОЗУ прокачивается в окне A000...BFFF), то появилась возможность странслировать на РК86 кучу разных DOS. Как DOS только работающих в окне верхнего ОЗУ с внешним приводом, так и использующих доп.ОЗУ 512 кб в виде эл.диска.

Для работы именно из эл.диска наиболее оптимальной является RAMDOS написанная в 1989 г. В.Ивинских из Тольятти. RAMDOS не только ОС наиболее оптимальная для диска из ОЗУ, имеет объём всего 2 кб, но и по интерфейсу пользователя оформлена как расширение монитора. Потому её можно считать расширением монитора и рассматривать в разделе монитора.

После инициализации RAMDOS (что заключается в инициализации железа и форматировании, если холодный рестарт) в список добавляются новые директивы, а некоторые старые директивы меняют работу. Так директива D без параметров выдаёт каталог, директива L грузит в ОЗУ, директива S записывает на диск, директива K уничтожает, директива R переименовывает, а директива X запускает на прогон программу.

Интерфейс программиста (т.е функции BDOS) также прост и удобен. В отличие от CP/M и MSDOS обмен не посекторный. RAMDOS позволяет или цельно файловый или побайтовый обмен (почти как в ORDOS, только ограничения в объём диска 60 кб нет). RAMDOS в оригинале рассчитана на автоинкрементный RAM-диск. RAM-диск из обычного ОЗУ будет раза в 2 тормознее.

Грузить DOS с магнитофона глупо. Потому RAMDOS или будет прошита в резидентном ПЗУ (например на 9000) или грузиться в верхнее ОЗУ из ROM-диска холодным загрузчиком, прошитым в ПЗУ F800.

- - - Добавлено - - -

Тут на одном форуме человек под ником Paguo-86PK занялся усовершенствованием ПЗУ РК86. Чтобы найти место для модификации п/п-ммы F809 он открыл много идей по ужатию объёма кода. Используя его идеи, а также свои новые открытия, я нашёл возможность ещё ужать код. Вот коды версии ПЗУ РК86, в которой свободно 213 байтов, а также коды версии ПЗУ РК86 в которой директивы D и M, а также интерпретатор ком.строки (CCP) взяты от Специалиста: https://yadi.sk/d/_usAW8c76grYww

Попутно была вспомнена идея оверлейного монитора, который работает только с ROM-диском. Суть идеи в том, что исполнительный код некоторых директив при их вызове загружается из ROM-диска в основное ОЗУ (под вершину RAMTOP) и там прогоняются. Для пользователя нет разницы, но т.к снимается ограничение на объём кода из-за нехватки объёма ПЗУ, то это позволяет не только улучшить качество и увеличить количество директив, но и освободить в ПЗУ F800 свободное место (объёмом до 1 кб, меньше никак, т.к в ПЗУ должны оставаться п/п-ммы ввода/вывода).

- - - Добавлено - - -

Заимствуя свежие идеи по сжатию кода от Paguo-86PK удалось ещё больше уплющить код ПЗУ РК86. Теперь в ПЗУ свободно для расширений уже 224 байта. Исходник и коды вот здесь.

- - - Добавлено - - -

Удалось ещё немного уплющить код ПЗУ РК86. Теперь в ПЗУ свободно уже 244 байта. Исходник и коды вот здесь.


Последний раз редактировалось: barsik (Пт Янв 31 2020, 01:57), всего редактировалось 2 раз(а)
barsik
barsik
Ветеран

Сообщения : 1150
Дата регистрации : 2016-11-10
Откуда : С-Петербург

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty .

Сообщение  barsik Вс Фев 02 2020, 06:29

2
Провёл ещё десяток часов в текстовом редакторе и вот наконец вот здесь исходник и коды варианта плющенного ПЗУ F800 для РК86, в котором число свободных байтов доведено до 272.

ПЗУ F800 для РК86 Dump_262.1580703773

Здесь я сделал курсор нормальным, т.е большим на всё знакоместо, вместо мизерной крошечной чёрточки на 10-й линии знакоместа. Если найдётся приверженец старого уродливого крошечного курсора, то ему достаточно только изменить ключ K_ORIG на ненулевое значение и запустить BAT-файл (если не Win XP, то под DosBox).

Если 272 байтов Вам всё-равно не хватает, то вот здесь рекордная версия, где свободно аж 280 ячеек. Эта доп.экономия получена за счёт удаления сдвижки влево на 4 знакоместа (это в сущности не особо надо, сделано отчасти для эстетики и, чтобы символ '?' при ошибке был на свободном от цифр участке) и убрано дублирование выдачи звуков на магнитофон (что надо для Z80). В принципе ещё один байт можно выиграть, если использовать особенность КР580 (тогда уже вообще не будет работать на Z80).

Кроме того, я странслировал версию с изменяемым курсором, в котором в латинском регистре курсор такой же большой, а в русском регистре снова становится крошечной чёрточкой в 10-й линии знакоместа. Изменение формы курсора для индикации включённого регистра используется во всех развитых компьютерах. Смена формы курсора в РК  достигается реинициализацией ВГ75 при каждом нажатии клавиши РУС/ЛАТ, т.к в ВГ75 нет отдельной команды для смены формы курсора.

Т.о форма курсора задаётся только в команде настройки режима ВГ75, когда также задаётся адрес экранной области. Естественно, по нажатию РУС/ЛАТ для реинициализации ВГ75 используются стандартные параметры (т.е экран на 76D0 и всего 25 видимых строк).

Однако существуют так называемые псевдографические игры, в которых режим ВГ75 перенастраивается. Обычно устанавливается 32 видимых строки, а экранный буфер перемещается с 76D0 куда-нибудь ниже раб.ячеек ПЗУ, т.е ниже 7600 (часто экран ставят на 4000).

Некоторые игры имеют свой драйвер опроса матрицы клавиш, но большинство использует стандартную п/п-мму F81B, при которой клавиша РУС/ЛАТ обслуживается. Если в такой игре с перемещённым экраном и командами CALL F81B нажать на клавишу РУС/ЛАТ, то экранный буфер переустановится на стандартный адрес 76D0 и псевдографический экран пропадёт. Вывод простой: в псевдографических играх держи руки подальше от клавиши РУС/ЛАТ.

Вот здесь исходники и коды такой версии ПЗУ с индикацией регистра формой курсора. Попутно изменено сообщение об ошибке (вместо глупого '?' причём в начале строки команды, выводится слово ERROR в следующей строке, как во всех остальных мониторах). Также добавил пару мелочей, что должны были быть сделаны изначально. При выходе на промпт всегда включается ЛАТ-регистр и директива D выводит дамп, а не один байт, если вводить только один параметр. Из-за этих вполне оправданных затрат тут свободных байтов лишь 249.


Последний раз редактировалось: barsik (Пт Фев 14 2020, 07:18), всего редактировалось 5 раз(а)
barsik
barsik
Ветеран

Сообщения : 1150
Дата регистрации : 2016-11-10
Откуда : С-Петербург

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty ROM-BIOS РК с поддержкой ROM-диска

Сообщение  barsik Сб Фев 08 2020, 19:08

3
Т.к вряд ли кому-нибудь удастся ещё более уплющить код ПЗУ РК86, то пора начинать хоть как-то с пользой использовать ровно 280 свободных ячеек в ПЗУ РК86, что я освободил оптимизацией.

Первое самое очевидное и полезное расширение директив монитора - это введение поддержки ROM-диска. Для поддержки этого в РК ранее придумали неудобный для практического использования метод. При котором применялся неудобный для компоновки формат ROM-диска с каталогом и отдельная внешняя программка для запуска файлов. Для использования ROM-диска требовалось с ленты или, помня адреса, из самого ROM-диска директивой R загрузить на адрес 7400 маленькую программку, которая выводила каталог программ ROM-диска и позволяла их запуск.

ПЗУ F800 для РК86 ROM-diskRKzhurnalnyj.1581177631

Гораздо удобнее иметь директивы для ROM-диска в резидентном мониторе и запускать программы как в обычной DOS. Потому я странслировал версию ПЗУ F800 с директивами для обслуживания ROM-диска. Вот здесь можно скачать исходник и коды такой версии для базового железа (т.е с ППА D14 на A000). Сам я использую версию ПЗУ с запасным ППА перенесённым на адрес 8400, что позволяет прокачивать доп.ОЗУ в окне A000...BFFF, т.к РК86 без дополнительного ОЗУ и ПЗУ неинтересен. В началах исходников кратко описаны добавки в работу монитора.

На скрин-шоте видно как каталог выдаётся по нажатию на <ВК> на пустой строке (как в ОРИОНЕ). В принципе, директива загрузки из ROM-диска не нужна, нужна только директива для запуска. Но т.к это стоило немного, то сделал и загрузку по L, т.к после загрузки по L делается вывод адресов загрузки и КС. В версии ПЗУ с переставленным адресом ППА D14 на 8400 загрузка возможна в основное ОЗУ (до 7600) и в область дополнительного ОЗУ A000...BFFF. В версии странслированной для базового РК с адресом ППА D14 на A000 загрузка только в основное ОЗУ.

В этой версии ПЗУ директива D оставлена убогой базовой (без вывода ASCII), потому приходится сохранять и директиву L для просмотра дампа в виде текста. Чтобы букву L можно было одновремнно использовать в качестве команды LOAD используется разделитель пробел. Для работы директив базового ПЗУ РК, параметры (адреса) вводят сразу же за буквой команды без пробела. Это позволяет использовать пробел вставленный после буквы L в качестве признака команды LOAD. Т.о, чтобы загрузить файл надо ввести букву L, пробел, имя файла и <ВК>. А директива L в старом формате (т.е без пробела и с двумя HEX-параметрами) позволяет выводить текст.

Имя файла можно набирать не полностью (если нет файла с похожим именем и не возникает неоднозначности). Например, если есть два файла с именами начинающимися на букву X, то по команде: L X<ВК> будет запущен первый по ROM-диску файл начинающийся с буквы X.

Как в ОРИОНЕ по <ВК> на пустой строке выводится каталог файлов ROM-диска, а по команде <пробел> выполняется запуск программы из ROM-диска. Формат ROM-диска аналогичен формату ROM-диска ОРИОНА, только в именах символ '$' как флаг запуска не нужен и файлы в ROM-диске начинаются сразу с отступом 0, а не с отступом 800. Размер файлов должен обязательно быть кратен 10H (т.е младший ниббл размера всегда 0).

Компоновать такой стандартный для РК и ОРИОНА ROM-диск очень удобно, даже нет никакой нужды в отдельной программе для этого. Достаточно редактора UltraEdit (т.к он позволяет редактировать в HEX-виде и вставлять в редактируемый в HEX-виде файл другие файлы) или любого другого редактора в HEX-виде и просто добавлять файлы в ORD-виде в конец файла ROM-диска (следя, чтобы размер файла ROM-диска не превысил 64 кб).

Директива R теперь не нужна, но пока оставил её (т.к директива R м.быть полезна для считывания ПЗУ через платку УФ-прошивателя). На скриншоте директивой R считана метка первого файла. В метке файла с отступом 14 (в байтах 0E,0F) можно записывать контрольную сумму или точный размер файла. К сожалению оперативно заменить ROM-диск эмулятор не позволяет.

Кстати, если бы эмулятор поддерживал и страничность ROM-диска, то можно было бы поддержать и многостраничный ROM-диск (т.к осталось ещё немного места, этого может хватить). Тогда файлов в ROM-диск умещалось бы много и имело бы смысл нацарапать простенькую графическую оболочку для запуска файлов из ROM-диска.

ПЗУ F800 для РК86 ROM-disk_RK86.1580959226


- - - Добавлено - - -

Один человек с ником Радио-86РК на другом форуме подсказал, как освободить в ПЗУ ещё 5 байтов. Заменил выложенную выше версию с 280-ю свободными байтами на версию с 285-ю свободными байтами.

ПЗУ F800 для РК86 285bytesfree.1582694278



- - - Добавлено - - -

По просьбам фанатов мнемоники КР580 с помощью CP/M-программы для конверсии исходников XIZ.COM конвертировал исходник в мнемонике Z80 в идентичный исходник в мнемонике КР580 и заменил тот же архивный файл по ссылке. Архивный RAR-файл в вышеуказанной ссылке для исключения путаницы переименован в версию 1.01' (т.е к старому названию прибавлен апостроф).

Также по просьбам тех, кто всё ещё не ценит нормальную кодировку с псевдографикой, исходник для КР580 конвертирован в кодировку Windows (которая неудобна для программиста полным отсутствием псевдографики). А исходник для Z80 мне было лениво конвертировать (и мне самому это не надо) и пока он оставлен тем же, что и был (т.е в нормальной альтернативной кодировке CP866).

Тот кому понадобится и этот Z80-исходник в кодировке Windows (что неудобно для исходников 8-ми разрядок), тот может сам легко конвертировать кодировку с помощью любого подходящего конвертора текстовых кодировок (а в приличных текстовых редакторах, например, UltraEdit версий 7...9 конвертор кодировок встроенный).

- - - Добавлено - - -

После того, как выяснилось, что для РК86 удобнее и (якобы) намного эффективнее писать игры не на ассемблере КР580, а писать их используя компиляторы ЯВУ для CP/M, то по-видимому самое оптимальное расходование 285 свободных байт в ПЗУ это размещение в РК-ПЗУ так называемого имитатора консольных функций CP/M. Который позволяет прогонять те CP/M-программы, что не лезут в дисковод и используют вывод на TTY-терминал. Т.е те программы, что не используют стандартных (для экранных, графических и цветных терминалов) искейп-кодов для управления экраном.

А искейп-кодами не пользуются все системные CP/M-программы, кроме нортонов, табличных процессоров, табличных баз данных и текстовых редакторов. В 285 байт конечно не влезет эмуляция, например, стандартного популярного терминала VT52 (для которого инсталлированы многие CP/M-пакеты имеющие хождение в СССР), но если расширить ПЗУ РК до 8 Кб, то и это возможно.
barsik
barsik
Ветеран

Сообщения : 1150
Дата регистрации : 2016-11-10
Откуда : С-Петербург

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty Re: ПЗУ F800 для РК86

Сообщение  prokushev Пн Май 03 2021, 12:24

4
300 байт. Жесткого тестирования не было.


Код:


;.xlist
;  МОНИТОР РК86 для КР580 совместимый с Z80
;  ════════════════════════════════════════

; Last modify: 03.05.2021

; Свободно 300 ячеек

; Звук только на INTE
; В CCP принудительно включается ЛАТ-регистр.
; Удалена директива X. Директива G теперь не имеет второго параметра -
; стоп точки. Зато теперь введён возврат из запуска по G по RET. И можно
; передавать два параметра (второй и третий, они передаются в DE и BC).

CHK MACRO adr, msg
IF adr-$
ERROR msg
ENDIF
ENDM

CPU 8080
Z80SYNTAX EXCLUSIVE
ORG     0F800H

RABADR EQU 0F800H
DOPPPA EQU 0A000H

K_ORIG EQU 0 ; если не 0, то оригинальный курсор
BASE    EQU 7600H ; ниже D0H байтов - служебные ячейки

EK_ADR  EQU BASE ; текущий адрес на экране
POSX EQU BASE+02H
POSY EQU BASE+03H
ESC_F   EQU BASE+04H
KBDFLG EQU BASE+05H ; если =0, то есть символ в SYMBUF
RUSLAT  EQU BASE+06H ; допустимо только 0 или FF
LAST_K EQU BASE+09H ; эти 2 байта должны следовать подряд
COUNT EQU BASE+0AH ; счётчик опросов (вначале 15)
APVFLG  EQU BASE+0BH ; флаг автоповтора
FRELOC EQU BASE+0CH ; эта ячейка не используется

TMPSTK  EQU BASE+0DH ; временно храним стек при МГ п/п-ммах
POINT   EQU BASE+14H ; адрес откуда произошёл RST_30H
R_HL EQU BASE+16H
R_BC EQU BASE+18H
R_SP EQU BASE+1CH
R_AF EQU BASE+1EH ; ниже откладываются AF,HL,DE,BC
STOP_A  EQU BASE+23H
TMP_COD EQU BASE+25H
P_JMP EQU BASE+26H        ; для байта C3H (JMP)
PAR_HL  EQU BASE+27H
PAR_DE  EQU BASE+29H
PAR_BC  EQU BASE+2BH
FLG_P2 EQU BASE+2DH ; флаг, что есть параметры 2 или 2,3
INV_MG EQU BASE+2EH
KNS_RD EQU BASE+2FH
KNS_WR EQU BASE+30H
RAMTOP EQU BASE+31H
COMBUF EQU BASE+33H        ; буфер ввода директивы
STACK EQU BASE+0D0H ; стек монитора

SA EQU 076D0H ; 76D0 начало экранной области
SCBASE  EQU 077C2H ; 77C2 ЛЕВ.ВЕРХН.УГОЛ ЭКР.

VG_75   EQU 0C000H
VT_57   EQU 0E000H

PA EQU     8000H
PB EQU PA+1
PC EQU PA+2
PU EQU PA+3

PDA EQU DOPPPA
PDB EQU PDA+1
PDC EQU PDA+2
PDU EQU PDA+3

; ──────────────────────────────────────────────

LOOP MACRO ADDR
DEC BC
LD A,B
OR C
JP NZ,ADDR
ENDM

; ──────────────────────────────────────────────

JP XF800 ; +0
JP CONIN ; +3
JP LDBYTE ; +6
JP COUT_C ; +9
JP WRBYTE ; +C
JP COUT_C ; +F   это д.быть PRINT
JP STATUS ; +12
JP HEX_A ; +15
JP MSGH   ; +18
JP XF81B ; +1B
JP ASKCUR ; +1E
JP RD_SCR ; +21
JP RD_BLK ; +24
JP WR_BLK ; +27
JP CHSUMM ; +2A
JP PUSK_VG ; +2D
ASKTOP: LD HL,(RAMTOP) ; +30
SETTOP: LD (RAMTOP),HL ; +33
RET

; ──────────────────────────────────────────────

AFB86: LD C,(HL) ; 10 bytes
CALL    WRBYTE
CALL AF999
JP AFB86

; ──────────────────────────────────────────────

XF800: LD HL,BASE-1
LD (RAMTOP),HL
LD SP,HL

LD A,8AH
LD (PU),A

CALL    PUSK_VG

INC HL ; LD HL,BASE
LD C,L ; 0
LD DE,COMBUF+2CH
CALL    DIR_F

CALL RST_18
TITR: DB    1FH,'radio-86r','k' + 80H

LD HL,1D2AH
LD (KNS_RD),HL

CHK 0f86ch, "* Standard subroutine WARMST shifted ! *"
;if $ ne RABADR + 6CH
; if1
; .printx * Standard subroutine WARMST shifted ! *
; endif
;endif
WARMST: ; Warm_BOOT
LD SP,STACK

LD A,90H
LD (PDU),A

CALL RST_18
PROMPT: DB 13,10,'-','-','>'+128

CALL GETLIN

LD HL,WARMST
PUSH HL

LD HL,COMBUF
LD A,(HL)

PUSH AF
CALL GETPRM
LD HL,(PAR_BC) ; Z80: LD BC,(PAR_BC)
LD C,L
LD B,H
LD HL,(PAR_DE) ; Z80: LD DE,(PAR_DE)
EX DE,HL
LD HL,(PAR_HL)
POP AF

SUB     'C'                     ;CP 'C'
JP      Z,DIR_C
DEC A ;CP      'D'
JP      Z,DIR_D
SUB 3 ;CP      'G'
JP      Z,DIR_G
SUB 2 ;CP      'I'
JP      Z,DIR_I
SUB 3 ;CP      'L'
JP      Z,DIR_L
DEC A ;CP      'M'
JP      Z,DIR_M
SUB 2 ;CP      'O'
JP      Z,DIR_O
SUB 3 ;CP      'R'
JP      Z,DIR_R
DEC A ;CP      'S'
JP      Z,DIR_S
DEC A ;CP      'T'
JP      Z,DIR_T
ADD A, 'T'-'F' ;CP      'F'
JP NZ,ERROR
DIR_F:
LD (HL),C
CALL AF999
JP      DIR_F
; ──────────────────────────────────────────────

;HEX_A: PUSH AF ; 24 bytes
; RRCA
; RRCA
; RRCA
; RRCA
; CALL NIBBLE
; POP AF
;NIBBLE: AND 0FH
; CP 10
; CCF
; ADC A,30H
; DAA
;
HEX_A:  PUSH    AF ; 23 bytes
       RRCA
       RRCA
       RRCA
       RRCA
       CALL    NIBBLE
       POP     AF
NIBBLE: AND     0FH
       CP      10
       SBC     A,2FH
       DAA
SCOUTA:
PUSH BC
LD C,A
CALL COUT_C
POP BC
RET

; ──────────────────────────────────────────────

ASKCUR: LD HL,(POSX) ; 4 bytes
RET

; ──────────────────────────────────────────────

DIR_G: JP      (HL) ; 1 bytes

; ──────────────────────────────────────────────
CHK 0F8EEH, "* Internal subroutine GETLIN shifted ! *"

;if $ ne RABADR + 0EEH
; if1
; .printx * Internal subroutine GETLIN shifted ! *
; endif
;endif

GETLIN: LD HL,COMBUF
LD D,H
LD E,L
AF8F1:
XOR A
LD B,A ; чтобы на выходе получить флаг пустой строки
CALL SET_RL
AF8F3: CALL    CONIN ; используется в DIR_M
CP      8
JP Z,BAKSTP
CP      7FH
JP Z,BAKSTP
LD (HL),A
CALL    SCOUTA
CP      13
JP Z,AF91A
CP      '.'
JP      Z,WARMST
LD B,E ; B=76H --> бит D7=0
LD A, (COMBUF & 00FFh)+31
CP L
JP      Z,ERROR
INC HL
JP AF8F3

; ──────────────────────────────────────────────

TABK2: DB 09,0AH,0DH,7FH,08H,19H,18H,1AH ; 8 bytes

; ──────────────────────────────────────────────

SET_RL: LD (RUSLAT),A ; 6 bytes
JP PUSK_VG

; ──────────────────────────────────────────────

CHK 0F92cH, "* Internal subroutine GETPRM shifted ! *"

;if $ ne RABADR + 012CH
; if1
; .printx * Internal subroutine GETPRM shifted ! *
; endif
;endif

GETPRM: LD HL,BASE+27H
LD DE,BASE+2DH
LD C,0
CALL    DIR_F

;if high (BASE+34H) eq high BASE
LD E,34H
;    else
; .printx *      Wrong BASE (Low BASE need be < 0E0H) !
;endif
CALL GET_HL
LD (PAR_HL),HL
LD (PAR_DE),HL
RET C
LD (FLG_P2),A

CALL GET_HL
LD (PAR_DE),HL
RET C

CALL GET_HL
LD (PAR_BC),HL
RET C
JP      ERROR

; ──────────────────────────────────────────────

AFE97: PUSH HL ; 27 bytes
LD HL,7 << 8 + 1
AFE9C: LD A,L
RRCA
LD L,A
CPL
LD (PA),A
LD A,(PB)
CPL
OR A
JP NZ,AFEB3
DEC H
JP P,AFE9C
AFEAF: LD A,0FFH
POP HL
RET

; ──────────────────────────────────────────────

XF81B: LD A,(PC) ; 30 bytes
RLA
LD A,0FEH
RET NC
AFE7D:
XOR A
LD (PA),A
LD A,(RUSLAT)
AND 00000001B
OR      00000110B ; зажигаем/гасим светодиод
LD (PU),A
LD A,(PB)
INC A
JP NZ,AFE97
DEC A
RET

; ──────────────────────────────────────────────

CHK 0F990H, "* Internal subroutine CMPDH shifted ! *"
;if $ ne RABADR + 0190H
; if1
;  .printx * Internal subroutine CMPDH shifted ! *
; endif
;endif

CMPDH: LD A,H
CP D
RET NZ
LD A,L
CP E
RET

; ──────────────────────────────────────────────

BAKSTP: LD A,E ; 15 bytes
CP L ; начало буфера ввода ?
JP Z,AF8F1
CALL RST_18
TZABOJ: DB    8,32,8+128
DEC HL
JP AF8F3

; ──────────────────────────────────────────────

DIR_S: LD A,C ; 11 bytes
CP (HL)
CALL    Z,CHXHL_
CALL AF996
JP      DIR_S

; ──────────────────────────────────────────────

CHK 0F9B0H
;if $ ne RABADR + 01B0H
; if1
; .printx * Internal subroutine CR shifted ! *
; endif
;endif

CR: CALL RST_18
DB    13,10 + 80H
RET

; ──────────────────────────────────────────────

DIR_I: LD A,(FLG_P2) ; 46 bytes
OR A
JP Z,AFA91
LD A,E
LD (KNS_RD),A
AFA91: CALL    RD_BLK

CALL JJJ2
EX DE,HL

PUSH BC
CALL    CHSUMM
CALL DIRK1
POP DE

CALL    CMPDH
RET Z
CALL    CHXDE_
ERROR: CALL RST_18
DB '?'+80H
JP      WARMST

; ──────────────────────────────────────────────

DIR_L: CALL    CHXHL_ ; 30 bytes
AFA0B: LD A,(HL)
OR A
JP M,AFA15
CP 20H
JP NC,AFA17
AFA15: LD A,'.'
AFA17: CALL    SCOUTA
CALL AF996
LD A,L
AND     0FH
JP      Z,DIR_L
JP AFA0B

; ──────────────────────────────────────────────

; ВХОД: E=POSX, D=POSY
;       HL= экранный адрес

COD_18: ; 29 bytes
       LD A,E ; POSX
INC HL ; следующий экранный адрес
INC E               ; POSX ++
CP      8+63 ; последняя колонка ?
RET NZ              ; если была не последняя колонка
LD E,8             ; нач.позиция по X на новой строке
LD BC,-64
ADD     HL,BC           ; Вычесть 64 = экр.поз в начало строки
COD_1A: LD A,D
CP      3+24 ; последняя строка ?
LD BC,78
JP NZ,AFDD3        ; если не последняя строка
LD D,2             ; если последняя строка, то на первую строку
LD BC,-24*78
AFDD3: INC D
ADD     HL,BC ; вычесть 24*78
RET

; ──────────────────────────────────────────────

AFF3B: LD A,L ; 23 bytes
AND 2FH
LD L,A
AFF3F: LD A,L
CP 40H
POP HL
RET P
PUSH HL
LD L,A
AND 00FH
CP 00CH
LD A,L
JP M,AFF50
XOR 10H
AFF50: POP HL
RET

; ──────────────────────────────────────────────

CHSUMM: LD BC,0 ; 23 bytes
AFB19: LD A,(HL)
ADD A,C
LD C,A
PUSH AF
CALL    CMPDH
JP Z,POPAF
POP AF
LD A,B
ADC A,(HL)
LD B,A
CALL AF999
JP AFB19

; ──────────────────────────────────────────────

DIR_M: CALL JJJ_02 ; 22 bytes
PUSH HL
CALL GETLIN
POP HL
JP NC,AFA3B
PUSH HL
CALL GET_HL
LD A,L
POP HL
LD (HL),A
AFA3B: INC HL
JP      DIR_M

; ──────────────────────────────────────────────

DIR_R:
AFA6D: LD (PDB),HL
LD A,(PDA)
LD (BC),A
INC BC ; 19 bytes
CALL AF999
JP AFA6D

; ──────────────────────────────────────────────

DIR_D: CALL    CHXHL_ ; 18 bytes
AF9C8: CALL LDXHX_
CALL AF996
LD A,L
AND 0FH
JP      Z,DIR_D
JP AF9C8

; ──────────────────────────────────────────────

KEY_FE: LD A,(PC) ; 17 bytes
RLA
JP NC,KEY_FE ; ждём отпускания РУС/ЛАТ
LD A,(RUSLAT)
CPL
CALL SET_RL
JP AFE1A

; ──────────────────────────────────────────────

BYTE3: LD A,C ; 18 bytes
SUB 20H
LD C,A
AFD77: DEC C
LD A,4
JP M,SETESC
PUSH BC
CALL COD_1A
POP BC
JP AFD77

; ──────────────────────────────────────────────

MSGH: LD A,(HL) ; 11 bytes
OR A
RET Z
CALL    SCOUTA
INC HL
RET M
JP      MSGH

; ──────────────────────────────────────────────

DIR_T: LD A,(HL) ; 9 bytes
LD (BC),A
INC BC
CALL AF999
JP      DIR_T

; ──────────────────────────────────────────────

RST_18: EX (SP),HL ; 6 bytes
       CALL MSGH
       EX (SP),HL
       RET

; ──────────────────────────────────────────────

RD_BLK: ;LD A,0FFH
;CALL _LD_BC
CALL LDBCSS
PUSH HL
ADD HL,BC
EX DE,HL
CALL LDBCBS
POP HL
ADD HL,BC
EX DE,HL
PUSH HL
CALL LD_BLK
;LD A,0FFH ; с поиском СБ
;CALL _LD_BC
CALL LDBCSS
POP     HL              ; БЫСТРЕЕ DB 06 -> LD B,NN

CHK 0FACEH, "* Internal subroutine PUSK_VG shifted ! *"
;if $ ne RABADR + 02CEH ; FACE
; if1
; .printx * Internal subroutine PUSK_VG shifted ! *
; endif
;endif

PUSK_VG: ; 1001.0011
; 1100.0011

PUSH HL
LD HL,VG_75+1
LD (HL),0   ; reset commando
DEC HL       ; адрес VG_75
LD (HL),04DH ; 0.1001101  77+1 знакомест
LD (HL),01DH ; 00.011101  29+1 строк

       LD (HL),99H ; 1001.1001  9 +1 линия подчерк.
        ; 9+1 линий в знакоместе
if K_ORIG
LD (HL),93H
else
LD (HL),0C3H
endif

INC     HL ; адрес VG_75+1
LD (HL),27H ; start display commando
LD A,(HL) ; read status
AFAE1: LD A,(HL) ; read status
AND     20H ; mask 'Interrupt request flag'
JP      Z,AFAE1         ; ждем конца строки
LD HL,VT_57+8
LD (HL),80H
LD L,4             ; VT_57+04
LD (HL),SA & 00FFh ; 0D0H
LD (HL),SA>>8 ; 076H
INC     L               ; адрес VT_57+5
LD (HL),23H
LD (HL),49H
LD L,8             ; VT_57+8
LD (HL),0A4H
POP HL
RET

; ──────────────────────────────────────────────

DIR_O: LD A,C
OR A
JP Z,AFB35
LD (KNS_WR),A
AFB35: PUSH HL
CALL    CHSUMM
POP HL

CALL JJJ2
EX DE,HL

PUSH HL
CALL DIRK1
POP HL
WR_BLK:
PUSH BC ; КС

LD BC,0 ; выводим 256 байтов 00 (пилотон)
AFB4D: CALL WRBYTE
EX (SP),HL ; это задержка 38 тактов
EX (SP),HL
DEC B
JP NZ,AFB4D

LD C,0E6H   ; выводим синхробайт E6
CALL WRBYTE

CALL WR_HL ; выводим НА
EX DE,HL
CALL WR_HL ; выводим КА

EX DE,HL
CALL AFB86 ; выводим блок

LD HL,0
CALL WR_HL ; выводим 2 байта 00

LD C,0E6H   ; снова выводим с/байт E6
CALL WRBYTE

POP HL
CALL WR_HL ; выводим КС

JP PUSK_VG


; ──────────────────────────────────────────────

; Вводит в HL HEX-число из строки по (DE) до нажатия ВК

GET_HL: LD HL,0 ; 48 bytes
AF95D: LD A,(DE) ; Выход: CY=1 если разделитель <ВК>
INC DE
CP      13
SCF
RET Z
CP      ','
RET Z
CP 20H
JP Z,AF95D

LD BC,ERROR
PUSH BC

SUB '0'
RET C ; JP C,ERROR

CP      9+1
JP C,AF982

CP      'A'-'0'
RET C ; JP C,ERROR

CP 'F'-'0'+1
RET NC ; JP NC,ERROR

SUB     'A'-('9'+1)
AF982:
ADD HL,HL
ADD HL,HL
ADD HL,HL
ADD HL,HL
RET C ; JP C,ERROR

OR L
LD L,A

POP AF
JP AF95D

; ──────────────────────────────────────────────

JJJ2: CALL CHXHL_

;if $+1 ne RABADR + 0378H
; if1
; .printx * Internal subroutine CHXHL_ shifted ! *
; endif
;endif

DIRK1: LD D,B
LD E,C
CHXDE_: EX DE,HL
CHK 0FB78H, "* Internal subroutine CHXHL_ shifted ! *"
CHXHL_: CALL    CR
HEXHL_: LD A,H
CALL    HEX_A
LD A,L
JP HEXABL

; ──────────────────────────────────────────────

DIR_C: LD A,(BC) ; 19 bytes
CP (HL)
JP Z,AF9E6
CALL JJJ_02
LD A,(BC)
CALL    HEXABL
AF9E6: INC BC
CALL AF996
JP      DIR_C

; ──────────────────────────────────────────────

AFEF3: LD A,H ; 7 bytes
LD HL,TABK1
JP AFEFE

; ──────────────────────────────────────────────

LDBS: LD A,8

;if $ ne RABADR + 0398H
; if1
; .printx * LDBYTE for emulator B2M need be at FB98 ! *
; endif
;endif

; CHK 0FB98H, "* LDBYTE for emulator B2M need be at FB98 ! *"
LDBYTE: PUSH    HL
PUSH DE
PUSH BC
LD D,A
AFB9C: LD A,80H
LD (VT_57+8),A

LD HL,0
LD C,L
ADD HL,SP
LD (TMPSTK),HL

LD SP,0
LD A,(PC)
RRCA
RRCA
RRCA
RRCA
AND     1
LD E,A
AFBB7: POP AF
LD A,C
AND 07FH
RLCA
LD C,A
LD H,0
AFBBF: DEC H
JP Z,AFC34
POP     AF ; Регенерация ОЗУ
LD A,(PC)
RRCA
RRCA
RRCA
RRCA
AND     1
CP      E
JP Z,AFBBF
OR C
LD C,A
DEC D
LD A,(KNS_RD)
JP NZ,AFBDC
SUB 012H
AFBDC: LD B,A
AFBDD: POP     AF ; Регенерация ОЗУ
DEC B
JP NZ,AFBDD
INC D
LD A,(PC)
RRCA
RRCA
RRCA
RRCA
AND 001H
LD E,A
LD A,D
OR A
JP P,AFC0B
LD A,C
CP      0E6H ; ПРЯМОЙ СИНХРО-БАЙТ ?
JP NZ,AFBFF
XOR A
LD (INV_MG),A ; ПРИЗНАК ИНВЕРСИИ МАГНИТОФОНА
JP AFC09

; ──────────────────────────────────────────────

AFBFF: CP      19H ; ОБРАТНЫЙ С/БАЙТ
JP NZ,AFBB7 ; 58 bytes
LD A,0FFH
LD (INV_MG),A ; Tape inverse flag
AFC09: LD D,9
AFC0B: DEC D
JP      NZ,AFBB7

LD HL,VT_57+4
LD (HL), SA & 00FFH ; 0D0H
LD (HL), SA >>8 ; 076H
INC HL
LD (HL),023H
LD (HL),049H
LD A,27H ; start display commando
LD (VG_75+1),A
LD A,0E0H ; reset count
LD (VG_75+1),A
LD L,8
LD (HL),0A4H

LD HL,(TMPSTK)
LD SP,HL

LD A,(INV_MG)
XOR     C ; with Tape Inverse flag
JP      POPREG

; ──────────────────────────────────────────────


WR_HL: LD C,H
CALL    WRBYTE
LD C,L

;if $ ne RABADR + 0446H
; if1
; .printx * WRBYTE for emulator B2M need be at FC46 ! *
; endif
;endif
;        CHK 0FC46H, "* WRBYTE for emulator B2M need be at FC46 ! *"
WRBYTE: PUSH    HL
PUSH DE
PUSH BC
PUSH AF
LD A,80H
LD (VT_57+8),A
LD HL,0
ADD HL,SP ; временно храним стек
LD SP,0 ; для регенерации
LD D,8
AFC58: POP AF
LD A,C
RLCA
LD C,A
LD A,1
XOR C
LD (PC),A
LD A,(KNS_WR)
LD B,A
AFC66: POP AF
DEC B
JP NZ,AFC66
LD A, B ;LD A,0 ; XOR A = LD A,B (в данном случае незачем)
XOR C
LD (PC),A
DEC D
LD A,(KNS_WR)
JP NZ,AFC7A
SUB     14
AFC7A: LD B,A

AFC7B: POP     AF            ; подъем стека на [рег.B] ячеек
DEC B
JP NZ,AFC7B
INC D
DEC D
JP NZ,AFC58

LD SP,HL
LD HL,VT_57+4
LD (HL), SA & 00FFh ; 0D0H
LD (HL), SA >> 8 ; 076H
INC     HL ; VT_57+5
LD (HL),23H
LD (HL),49H
LD A,27H ; start display commando
LD (VG_75+1),A ; 001.sss.bb    001.001.11
LD A,0E0H ; сброс счетчиков строк и знакомест ???
LD (VG_75+1),A
LD L,8
LD (HL),0A4H        ; VT_57+8
POPREGA: POP AF
POPREG: POP BC
POP     DE
POP HL
; CHK 0FCA4H, "* Internal point 0FCA4H (need for emulator B2M) shifted ! *"
LD_BAK: RET

; ──────────────────────────────────────────────


;if LD_BAK ne 0FCA4H
; if1
; .printx * Internal point 0FCA4H (need for emulator B2M) shifted ! *
; endif
;endif

; ──────────────────────────────────────────────

COUT_C: PUSH HL
PUSH DE
PUSH BC
PUSH    AF

CALL    STATUS
LD HL,TOBACK
PUSH HL
LD HL,(POSX)
EX DE,HL
LD HL,(EK_ADR)
LD A,(ESC_F)
OR A
JP Z,NO_ESC
DEC A
JP Z,BYTE2 ; если второй байт ('Y')
DEC A
JP Z,BYTE3 ; если третий байт
LD A,C     ; четвёртый байт
SUB 20H
LD C,A
AFCDD: DEC C
JP      M,ESCRES         ; СБРОС ESC_F И ВЫХОД
PUSH BC
CALL COD_18
POP BC
JP AFCDD

; ──────────────────────────────────────────────

NO_ESC: LD A,C
AND     7FH
CP      7
JP Z,BEEP
CP      8
JP Z,COD_08
CP      10
JP Z,COD_0A
CP      0CH
JP      Z,HOME
CP      13
JP Z,COD_0D
CP      1FH
JP      Z,CLS
LD C,A
SUB 18H
JP Z,COD_18
DEC A
JP Z,COD_19
DEC A
JP Z,COD_1A
DEC A
JP      Z,COD_1B

LD (HL),C ; Видимый на экране символ
CALL COD_18 ; сместить на следующее знакоместо
LD A,D
CP      3 ; мы на первой строке ?
RET NZ ; если не на первой строке
LD A,E
CP      8 ; мы в первой колонке ?
RET NZ ; если не на первой колонке
CALL COD_19
COD_0A: LD A,D
CP      3+24 ; мы на последней строке ?
JP NZ,COD_1A ; если не на последней строке

PUSH    HL ; РОЛИК ЭКРАНА
PUSH DE
LD HL,SCBASE+78
LD DE,SCBASE
LD BC,25*78
MOVLOO: LD A,(HL)          ; пересылка блока размером [BC]
LD (DE),A ; (HL) --> (DE)
INC HL
INC DE
LOOP MOVLOO
POP DE
POP HL
RET

; ──────────────────────────────────────────────

AFEB3: LD L,20H ; 47 bytes
AFEB5: LD A,(PB)
CPL
OR A
JP Z,AFEAF
DEC L
JP      NZ,AFEB5
LD L,8
AFEC3: DEC L
RLCA
JP NC,AFEC3
LD A,H
LD H,L
LD L,A
CP      1
JP Z,AFEFA
JP C,AFEF3
RLCA
RLCA
RLCA
ADD A,20H
OR H
CP      5FH
JP NZ,AFF06
LD A,20H
POP HL
RET

; ──────────────────────────────────────────────

AFE2A: DEC H ; в рег.A=код клав, в рег.H- COUNT
JP NZ,AFE21 ; 39 bytes
INC A
JP Z,AFE22 ; если код FF, то сброс флагов
INC A
JP Z,KEY_FE ; если код FE (RUSLAT)

PUSH BC ; КЛИК
LD BC,5003H
CALL SND_BC
POP BC

LD A,(APVFLG)
LD H,0E0H
DEC A
LD (APVFLG),A
JP Z,AFE4C
LD H,40H
AFE4C: LD A,0FFH
JP AFE22

; ──────────────────────────────────────────────

; После 15 вызовов STATUS при нажатой клавише выставляется флаг KBDFLG

STATUS: LD A,(PC) ; 38 bytes
RLA
JP NC,AFE0E ; если нажат RUS/LAT
LD A,(KBDFLG)
OR A
RET NZ ; если в SYMBUF уже есть символ
AFE0E: PUSH HL
LD HL,(LAST_K)
CALL    XF81B
CP L
LD L,A
JP Z,AFE2A
AFE1A: LD A,1
LD (APVFLG),A
LD H,15H ; число опросов, чтобы зафиксировать код
AFE21: XOR A
AFE22: LD (LAST_K),HL
POP HL
LD (KBDFLG),A
RET

; ──────────────────────────────────────────────

AFF1A: LD A,(RUSLAT) ; 33 bytes
OR A
JP Z,AFF2A
LD A,L
CP 40H
JP M,AFF2A
OR 20H
LD L,A
AFF2A: LD A,H
AND 20H
JP NZ,AFF3F
LD A,L
CP 40H
JP M,AFF3B
LD A,L
XOR 20H
POP HL
RET

; ──────────────────────────────────────────────

AFEFA: LD A,H ; 32 bytes
LD HL,TABK2
AFEFE: ADD A,L
LD L,A
LD A,(HL)
CP 40H
POP HL
AFF04: RET     C
PUSH HL
AFF06: LD L,A
LD A,(PC)
LD H,A
AND 40H
JP NZ,AFF1A
LD A,L
CP 40H
JP M,AFF3F
AND 1FH
POP HL
RET

; ──────────────────────────────────────────────

COD_08: ; ВХОД: E=POSX, D=POSY
                               ;       HL= экранный адрес

LD A,E ; 29 bytes
DEC HL
DEC E
CP      8 ; были в первой колонке ?
RET NZ ; если были не в первой колонке
LD E,8+63 ; POSX последней колонки
LD BC,64
ADD HL,BC ; экр.адрес в последнюю колонку
COD_19: LD A,D
CP      3 ; это первая строка ?
LD BC,-78
JP NZ,AFDF0
LD D,3+25
LD BC,24*78
AFDF0: DEC D
ADD     HL,BC           ; Вычесть 78 или прибавить 24*28
RET

; ──────────────────────────────────────────────

TOBACK: LD     (EK_ADR),HL ; 23 bytes
EX DE,HL
LD (POSX),HL
LD A,80H
LD (VG_75+1),A
LD A,L
LD (VG_75),A
LD A,H
LD (VG_75),A
;POP AF
JP POPREGA

; ──────────────────────────────────────────────

AFC34: LD HL,(TMPSTK) ; 18 bytes
LD SP,HL
CALL    PUSK_VG
LD A,D
OR A
JP      P,ERROR
CALL CHK_F4
JP AFB9C

; ──────────────────────────────────────────────

CLS: LD HL,76D0H ; 17 bytes
CLSLOO: XOR A
LD (HL),A
INC HL
OR H
JP P,CLSLOO
HOME: LD DE,308H
LD HL,SCBASE
RET

; ──────────────────────────────────────────────

JJJ_02: CALL    CHXHL_ ; 12 bytes
LDXHX_: LD A,(HL)
HEXABL: CALL    HEX_A
SPACE: LD A,20H
JP SCOUTA

; ──────────────────────────────────────────────

LD_BLK: CALL    LDBS ; 10 bytes
LD (HL),A
CALL AF999
JP LD_BLK

; ──────────────────────────────────────────────

TABK1: DB 0CH,1FH,1BH,0,1,2,3,4,5  ; 9 bytes

; ──────────────────────────────────────────────

CHK 0FE63H, "* Internal point FE63 (need for emulator emu80) shifted ! *"
;if $ ne 0FE63H
; if1
; .printx * Internal point FE63 (need for emulator emu80) shifted ! *
; endif
;endif

CONIN: CALL    STATUS
OR A
JP      Z,CONIN
XOR A
LD (KBDFLG),A
LD A,(LAST_K)
RET

; ──────────────────────────────────────────────
AF91A: SUB B ; 2 bytes
RET

; ──────────────────────────────────────────────

BEEP: LD BC,05F0H ; 20 bytes
SND_BC: LD A,B
BPLOO1: EI
DEC A
JP NZ,BPLOO1
LD A,B
BPLOO2: DI
DEC A
JP NZ,BPLOO2
DEC C
JP NZ,SND_BC
RET

; ──────────────────────────────────────────────

COD_0D: LD A,L ; 13 bytes
SUB     E
JP NC,AFDF9
DEC H
AFDF9: LD L,A
LD BC,8
LD E,C
ADD HL,BC
RET

; ──────────────────────────────────────────────

CHK_F4: CALL    XF81B ; 12 bytes
CP      3
RET NZ
CALL    PUSK_VG
JP      ERROR

; ──────────────────────────────────────────────

AF996: CALL    CHK_F4 ; 11 bytes
AF999: CALL    CMPDH
INC HL
RET NZ
DEC HL
POPAF: POP AF
RET

; ──────────────────────────────────────────────

; загр.BC без поиска СБ                        
; без поиска СБ, если A=8, с поиском, если A=FF
LDBCSS: LD A, 0FFH
DB 1 ; LD BC, ..
LDBCBS: LD A,8 ; 11 bytes
_LD_BC: CALL    LDBYTE
LD B,A
CALL    LDBS
LD C,A
RET

; ──────────────────────────────────────────────

RD_SCR: PUSH    HL ; 7 bytes
LD HL,(EK_ADR)
LD A,(HL)
POP HL
RET

; ──────────────────────────────────────────────

;DIRK1: LD H,B ; 5 bytes
; LD L,C
; JP CHXHL_

; ──────────────────────────────────────────────

BYTE2: LD A,C ; 14 bytes
CP      'Y'
JP NZ,ESCRES
CALL    HOME
LD A,2             ; ПРИНЯТО 2 БАЙТА ESC,'Y'
DB 06H ; LD B, ... функционально JP SETESC
COD_1B: INC A             ; 2 bytes LD A,1
DB 06H ; LD B, ... функционально JP SETESC
ESCRES: XOR A ; 5 bytes
SETESC: LD (ESC_F),A
RET

; ──────────────────────────────────────────────

;COD_1B: INC A             ; 4 bytes LD A,1
; JP SETESC

; ──────────────────────────────────────────────


; ──────────────────────────────────────────────

;DIR_G: JP      (HL) ; 1 bytes

; ──────────────────────────────────────────────

;if RABADR EQ 0F800H
;  if $ eq 0
; if1
; .printx * Totally fit in 2K size ! *
; endif
;  endif

;  if $ ne 0

;      if high $ gt 0F8H
; @FREE EQU 1000H - ($ and 0FFFH)
;   rept 256
; if $ ne 0
;   defb 255
; endif
; endm
;      endif
;  endif

;  if $ ge 1
; if1
;  .printx * Code length over 2048 bytes ! *
; endif
; @OVER EQU $
;  endif

;endif ; RABADR EQ 0F800H

END


prokushev
новичёк

Сообщения : 4
Дата регистрации : 2021-05-01

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty Re: ПЗУ F800 для РК86

Сообщение  vzuravlo Сегодня в 01:08

5
Я тут нечаянно товарищу минус поставил. Как убрать?

vzuravlo
новичёк

Сообщения : 1
Дата регистрации : 2020-07-07

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty .

Сообщение  Viktor2312 Сегодня в 06:25

6
Это так важно ?

Напиши ему большой "+" пост.

_________________
"ЛП & ТИ"
Viktor2312
Viktor2312
Гуру+

Сообщения : 14881
Дата регистрации : 2012-08-10
Возраст : 42
Откуда : Пятигорск

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty Re: ПЗУ F800 для РК86

Сообщение  prokushev Сегодня в 10:47

7
Я в исходнике не стал поддерживать точки входа Б2М, т.к. они настраиваются в конфиге эмулятора. А вот с EMU80 я не знаком, поэтому контроль точки входа оставил. Если emu80 поддерживает настройку hook-ов, то я бы и эту проверку убрал, т.к. 4 байта я не смогу ужать, скорее всего. А они нужны для реализации поддержки VT52. Может, конечно, и смогу нарыть, но не проверял. Да и ограничение не очень удобно иметь. В противном случае придется потерять дополнительно байт 6 для "обхода" точки входа EMU80.

Я для пробы накидал поддержку VT52 и симулятор CP/M. В остатке получилось 14 байт свободных (это без ужимания кода VT52 и симулятора. Там есть чего поужимать). Они сожрутся для развертывания системной страницы. Симулятор, думаю, лучше "включать" при вызове программы с адреса 100H. Есть другие варианты?

При включении эмулятора VT52 некоторые функи нужно будет упростить (типа, автозаворачивание экрана при достижении границы) для соответствия логике работы VT52, а это даст некоторое пространство для реализации недостающих 2-3 эскейп-кодов VT52. Плюс, монитор не содержит поддержи контрольного кода HT (TAB), который надо будет добавить. Т.е., по предварительной оценке, все можно утрамбовать в 2 кб.

Эмуляцию дисковых фунок для работы с, например, ROM-диском воткнуть вряд ли получится, но можно попробовать, используя оверлеи, как ранее говорил barsik.

Было бы еще интересно посмотреть на исходник РК-ДОС (2.9 или 2.95) в части возможности эмуляции CP/M через его код. Но я нашел только исходник версии 1.0.

prokushev
новичёк

Сообщения : 4
Дата регистрации : 2021-05-01

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty .

Сообщение  Viktor2312 Сегодня в 13:48

8
Я не претендую на оригинальность, просто зашёл на свой диск "физический" глянул, а что там есть, там такое есть, там много чего есть, но выложу это, хотя я тут где-то уже выкладывал, но, пусть будет, может и то что нужно:

Dos29.rar https://disk.yandex.ru/d/FsNQw4Ud7ZPeSw

RK_DOS_2_9_DUMP.rar https://disk.yandex.ru/d/WL112R2nnXun9w

FORTRAN-TXT_1_3 https://disk.yandex.ru/d/hH3mQkNOulu0wQ


Спойлер:
ПЗУ F800 для РК86 Rk_dum10

ПЗУ F800 для РК86 Rk_dum11

ПЗУ F800 для РК86 Rk_dum12



.

_________________
"ЛП & ТИ"
Viktor2312
Viktor2312
Гуру+

Сообщения : 14881
Дата регистрации : 2012-08-10
Возраст : 42
Откуда : Пятигорск

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty Re: ПЗУ F800 для РК86

Сообщение  prokushev Сегодня в 15:11

9
309 байт. Исходник и бинарник живет на github. Ссылки дам позже, как форум разрешит. Код VT-52 и CP/M просто набросан, не вычитывался/запускался/тестился. Поэтому бинарник не собирался. Присутствует чисто для оценки достаточности места. В варианте сборки с VT-52 и CP/M никакой проверки на точки входа эмулятора EMU80 нет, т.к. версия 4 поддерживает настройку хуков. Дальше я контроль этой точки поддерживать не буду, т.к. не вижу смысла. Ужимать больше исходник не планирую, если только будет явная необходимость.


Последний раз редактировалось: prokushev (Чт Май 06 2021, 15:21), всего редактировалось 2 раз(а)

prokushev
новичёк

Сообщения : 4
Дата регистрации : 2021-05-01

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty Re: ПЗУ F800 для РК86

Сообщение  prokushev Сегодня в 15:16

10
Viktor2312 пишет:Я не претендую на оригинальность, просто зашёл на свой диск "физический" глянул, а что там есть, там такое есть, там много чего есть, но выложу это, хотя я тут где-то уже выкладывал, но, пусть будет, может и то что нужно:

FORTRAN-TXT_1_3


Спасибо, это все есть. А фортран адаптированный под ркдос?

Я просто видел, что barsik где-то выкладывал дисзассемблированный код ркдос. Может кто успел его себе утянуть - я не нашел.

prokushev
новичёк

Сообщения : 4
Дата регистрации : 2021-05-01

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty .

Сообщение  Viktor2312 Сегодня в 16:21

11
Спасибо, это все есть. А фортран адаптированный под ркдос?

Без понятия, не разбирался, и если честно, не хочу, но выложил на случай, а вдруг кому-то нужно, а нет. Я так припоминаю где взял, и ник человека знакомый, но это было лет 6 тому назад, в readme так написано:


Содержимое фирменных дисков "Лианозово"
для контроллера НГМД Радио-86РК.

SE.COM и SE.EXE записаны в оригинальном виде.

Не хватает файлов PASCAL2.TXT, PASCAL3.TXT.
Все контрольные суммы проверены.

+ Бонус
Оригинальная прошивка контроллера НГМД - DOS 2.90.

23/05/2015
cy6er (cy6)
http://c6lab.org



Даже аватарку помню этого человека...

https://disk.yandex.ru/d/FEy4a-W6gpZbIQ



.

_________________
"ЛП & ТИ"
Viktor2312
Viktor2312
Гуру+

Сообщения : 14881
Дата регистрации : 2012-08-10
Возраст : 42
Откуда : Пятигорск

Вернуться к началу Перейти вниз

ПЗУ F800 для РК86 Empty Re: ПЗУ F800 для РК86

Сообщение  Спонсируемый контент

12

Спонсируемый контент


Вернуться к началу Перейти вниз

Вернуться к началу


 
Права доступа к этому форуму:
Вы не можете отвечать на сообщения