nedoPC.org

Community of electronics hobbyists established in 2002

...
Atom Feed | View unanswered posts | View active topics It is currently 26 Feb 2020 12:51



Reply to topic  [ 159 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11  Next
Paguo-86PK - XXI BEK 
Author Message
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
barsik wrote:
Похоже память у Вас хорошая. Три первые из четырёх картинок я видел ранее и игры эти у всех есть.
Почeму-то в архивах не нахожу :oops:
barsik wrote:
Бейсики в компьютерах первой волны (1975-1978) применяли просто оттого, что вообще ничего другого не было и даже было невозможно в силу слабости железа. Но как только на микрокомпьютерах появились ассемблер, а затем ДОС и ЯВУ, то резидентный бейсик превратился в нонсенс, глупость.
Хорошо, что не дядя Кобол (Кабул акя)! :lol:
barsik wrote:
Кстати, т.к операнды задаются триадами битов, когда работают в маш.кодах восьмиричная система удобнее. Вот почему в книге Буреева и Дудко "Простейшая микро-ЭВМ на КР580" используют восьмиричную систему и во многих советских справочниках про КР580 система команд КР580 приведена в восьмиричной системе.
Свой x80 я и слепил переорганизацией блоков команд из i8080/z80 в тетрады, так как всегда напрягало в уме хексы переводить в восьмиричку, когда бил/читал дампы…
barsik wrote:
И потому привыкнув к этому даже теперь не можете перейти к нормальным инструментам.
Пока эти дни сидел без интернета, за ночь взломал rkr-формат ассемблера и на HTML/JavaScript накидал редактор ассемблерных листингов с экспортом в rkr…
Сам редактор «Ed.Mikron» файлы проглатывает и не ругается. Потому, я могу пользоваться теперь визуальными плюшками HTML и сохранять всё в rkr-файлы…
Пришлось пару часиков визуально изучать фрагмент дампа с подпрограммой вывода на магнитофон и подключить интуицию, чтобы понять, где - контрольная сумма, а где - длина листинга. Сохранял парочку коротких файликов и сравнивал их дампы… :rotate:

Сегодня днём написал три подпрограммы:
  • Умножалку HL на A
  • Делилку HL на A
  • Вывод десятичного числа HL
  • Вывод дампа десятичными числами
Подпрограммы активно используют стек и вместо циклического замыкания на метку просто помещают в стек стопку ссылок на участок подпрограммы.
Сравнил производительность…
  • Стандартный дамп 0000…1FFF - 61 секунда
  • Дамп 8-битных десятичных - 81 секунда
  • Дамп 16-битных десятичных - 80 секунд

barsik wrote:
А кто заставляет выводить дамп с 16-ю байтами в строке? В Специалисте, ОРИОНЕ и ИРИШЕ выводят в дампе по 8 байтов в строке и никто ещё не жаловался.
Оказывается в том же эмуляторе в Мониторе «Микро-80» дамп выводится не отдельными байтами, а словами + справа и текст помещается! Как я до этого не додумался‽

К тому же в Emu80 с SD-картой директивами «R,71»+«G» запускается оболочка Нортона.
Пока интернета не было, много как наковырялся! :lol:

К тому же, проверил режим 80×50 - он идеально умещается в диапазон 7000…7F9F и ячейки 7FA0…7FFF можно использовать под Мониторные…
А чтобы не было проблем с регенерацией ОЗУ, знакогенератор нужно перенастроить даже не на 6×8, а 6×6. Я как-то проводил опыты и дампом бил (не редактором) свой фонт укороченный. Правда, чем его искать, легче с нуля опять набить… :roll:
(Я nes-файлы игр Денди так пытался руссифицировать. Одолел лишь «Battle City»).

Кстати, тот же Emulator3000 ZX-Spectrum поддерживает: Отчего мою демку с дампом там не прогнали? :mrgreen:

Кстати…
Если выводы A0/A1 микросхемы D14 перевести на A11/A12, то получим следующее:
  • A000…A7FF - канал «A»
  • A800…AFFF - канал «B»
  • B000…B7FF - канал «C»
  • B800…BFFF - управляющий регистр
Как Вы предлагали, внешнее ПЗУ подключить ещё и к шине адреса процессора…
Тем самым, в регионе A000…A7FF всегда будем иметь окно ПЗУ в 2 Кб, которое уже не нужно директивой «R» копировать в ОЗУ. А с каналами «B» и «C» получим уже 65536 страниц по 2 Кб ≈128 Мб! Но тут уже порт «A» ППА клавиатуры задействовать нельзя, иначе было бы уже 32 Гб! :esurprised:

И о «Windows'86»!
Планирую сделать своеобразную пародию технологии DirectX…
В частности, зарезервировать в Мониторе подпрограммы, которые из-вне можно будет вызывать для получения указателей на экранную область и т.д…
Об этом я задумывался ещё в 90-х, даже до знакомства с MS-DOS.

Монитор имеет две функции чтения статуса экранной области: Чтение позиции курсора и чтение символа на экране под курсором.
Мною планируется просто выделить несколько подпрограмм из «PUT_C»: Перемещение курсора и коррекция позиции.
Вроде бы пустяк. Но с ними, в принципе, можно организовать переносимую динамичную обстановку!

P.S.: В общем, работы много проделал… Мартышкиной! :lol:
(В своей оконной подпрограмме выиграл ещё 4 байта!)


Attachments:
File comment: Десятичный дамп
Запуск через «G0» сначала прогонит 8 Кб байтами, а после нажатия любой клавиши - те же 8 Кб 16-битными словами…
Рекомендую сначала заполнить область 0100…1FFF мусором и засечь затем время вывода этих дампов

DecimalDump.rkr.zip [479 Bytes]
Downloaded 11 times
File comment: Микро-80 с Монитором РК
SuperDump.png
SuperDump.png [ 44.14 KiB | Viewed 465 times ]
05 Feb 2020 12:24
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 04:46
Posts: 467
Location: С-Петербург
Reply with quote
Post 
Paguo-86PK wrote:
редактор «Ed.Mikron»...
Раз уж упомянули редакторы, скажу, что тема текстовых редакторов для РК всё ещё актуальна (в отличие от ROM-BIOS-ов, т.е хороший текстов редактор нужен, а вот новый ROM-BIOS никем не востребован). Вам бы написать для тренировки в экономии кода (или хотя бы ради спортивного интереса) экранный текстовый редактор для РК86 размером в 2 кб.

 редакторы для РК86
.
Эд_Микронов - два. Один журнальный из 1987 года, - полное убожество, даже не полноэкранный, а не пойми какой, очень неудобный (зато размером всего в 2 кб). И второй журнальный Эд_Микрон-2 из 1991 года размером аж в 4 кб. Который удобный и вполне приличный (с 1993 используют его версию для работы с дискетой RK-DOS).

Для РК актуален приличный текстов редактор размером не более 2-х килобайт. И такого редактора до сих нет. Есть только убогий Микрон-1, который никуда не годится. Кстати, до 1991 ничего другого из РК-редакторов вообще не было.

Потому Эд_Микрон-1 встраивали и в макроассемблер и в Паскаль и в Best-Си. Я с ними имел дело уже не на РК, а на Специалисте. И хотя для Специалиста сдуру адаптировали и убогий Микрон-1, но на Специалисте уже в 1988 был приличный полноэкранный редактор SCREEN размером тоже всего 2 кб. SCREEN мал, т.к по максимуму использовал п/п-ммы ПЗУ Специалиста. При адаптации SCREEN на ОРИОН, где нет в ПЗУ некоторых подпрограмм (и с добавкой чтения/записи файлов квазидиска из ОЗУ) размер разбух аж до 3 кб. И только выкинув МГ-функции, работу с квазидиском и Хелп, мне удалось упихать SCREEN для ОРИОНА в 2 кб. Это надо было для того, чтобы и на ОРИОНЕ использовать эр-кашные Паскаль, Си и макроассемблер (которым нужен текстов редактор именно размером до 2 кб, т.к все они работают с $800.

У меня есть исходник полноценного текстового редактора с блоками (без DOS и для RAMDOS), не хуже, чем Микрон-2, но у него размер даже более 4 кб. Написать текстов редактор размером в 2 кб сейчас я бы смог, но точно не получится компактнее, чем SCREEN. Проще адаптировать SCREEN для РК. Я уже адаптировал SCREEN в 90-тые и для ИРИШИ и для ОРИОНА. Дорабатывать немного, лишь переписать подпрограммы быстрого ролика экрана вверх и вниз (стеком). Я этим возможно займусь, но позднее, т.к РК86 меня вообще не интересует в силу отсутствия в нём графики. РК использую в эмуляторе лишь потому, что там есть поддержка и дисковода и эл.диска (а в эмуляции Специалиста пока только эл.диск), а для отладки без разницы встраивать директивы для обслуживания DOS и ROM-диска в монитор Специалиста или РК86.
.

Paguo-86PK wrote:
barsik wrote:
Paguo-86PK wrote:
https://zx-pk.ru/threads/10161-radio-86rk-igry.html?p=1037831&viewfull=1#post1037831 - скриншоты... нарисовал по памяти
Три первые из четырёх картинок я видел ранее
Почeму-то в архивах не нахожу
Игры распространённые. Первая называется MARS2, вторая MARS3. Третья игра Saboteur немного не похожа на ваш рисунок, но ясно, что это она.
Paguo-86PK wrote:
написал три подпрограммы:
  • Умножалку HL на A
  • Делилку HL на A
  • Вывод десятичного числа HL
Эти подпрограммы нужны всегда. У каждого они есть, но обычно их пишут тупо в лоб, чтобы не искать и самому особо не напрягаться. Скорость обычно не важна. А при использовании линкующего ассемблера проще использовать фрагменты написанные на ЯВУ, подпрограммы оформляются внешними процедурами на ЯВУ. Это экономит силы и время. Особенно, если нужна точность, т.е арифметика с плавающей точкой.
Paguo-86PK wrote:
в Emu80 с SD-картой директивами «R,71»+«G» запускается оболочка Нортона.
Было бы интереснее, если бы с SD-карты грузилась и работала бы с ней как с приводом, - RK-DOS, CP/M или любая другая DOS, а так - это просто запускалка. Хотя для тех, кому надо только запускать, этого достаточно.
Paguo-86PK wrote:
проверил режим 80×50 - он идеально умещается в диапазон 7000…7F9F и ячейки 7FA0…7FFF можно использовать под Мониторные
80 символов в строке на реале без замены кварца не получить. Нужен кварц 20 МГЦ вместо 16 МГЦ. Это будет уже другой компьютер несовместимый с РК86.
Paguo-86PK wrote:
Emulator3000 ZX-Spectrum поддерживает: Отчего мою демку с дампом там не прогнали?
Я не держу эмуляторов ZX-Spectrum, тем более не отечественных. Синклер меня бы интересовал, если бы в зоновскую плату как-нибудь несложно встроить режим 512*192 моно, добавив банку 565РУ6 (или статики). К сожалению, в 80-тые годы никто не слышал о клоне Timex с таким экраном и вместо такой простой доработки изобрели навороченные ATM и Профи. Сам я мечтал это сделать, но в железе слаб и не люблю сложные доработки МГТФ-ом.
Paguo-86PK wrote:
Кстати… Если выводы A0/A1 микросхемы D14 перевести на A11/A12, то... в регионе A000…A7FF всегда будем иметь окно ПЗУ в 2 Кб, которое уже не нужно директивой «R» копировать в ОЗУ
Хорошая идея, если код сможет работать прямо оттуда. Код в адресном пространстве ценнее, чем код перекачиваемый в ОЗУ. Возможно это ПЗУ придётся иметь скоростным (или немного тормозить одним тактом WAIT). Команды чтения портов часто тормозят одним тактом WAIT, в Z180/HD64180 есть даже возможность задавать на сколько тактов удлинять I/O операции.
Paguo-86PK wrote:
В своей оконной подпрограмме выиграл ещё 4 байта!
Это не впечатляющие темпы, я за то же время выиграл ~30 байтов, причём уже на ранее сильно уплющенном коде.

Выяснилось, что эмулятор EMU80 не позволяет изменить адрес ППА ROM-диска. Приходится переходить на EMU. Сделал поддержку ROM-диска в мониторе РК86. Пока временно с директивой L (т.е ASCII не выводит, хотя код остался). Но из ROM-диска не надо грузить, а надо запускать. Теперь всё как в ОРИОНЕ - по ВК вывод каталога, по пробелу запуск. Но в отличие от ORDOS имя не требуется писать целиком (если не возникает неоднозначности). Например, если есть только один файл с именем на букву X, то для запуска достаточно ввести пробел, нажать клавишу X и затем ENTER.

Image


05 Feb 2020 20:07
Profile
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
barsik wrote:
Вам бы написать для тренировки в экономии кода (или хотя бы ради спортивного интереса) экранный текстовый редактор для РК86 размером в 2 кб.
Набросoк кода для вставки символа в строку прямо на экране (как в Бейсике Atari-XE) штатными подпрограммами Монитора занимает 220 байтов. Курсор активно бегает влево-вправо и всё подтормаживает при длинных строчках.
Если же идти хаком и напрямую в буфере экрана работать - совместимость пострадает…
Можно и в общем буфере хранить, как в Микроне. Возиться нужно…
Хоть бери и в ПЗУ всё вычищай и реализуй! :mrgreen:
Вот не пойму, почему редакторы в начале памяти сидят? Приходилось всегда программы с 1100 копировать в 0000. Прямо хочется этот Микрон подкорректировать на 5000 хотя бы. Но я не знаю всех нюансов рабочей области…
barsik wrote:
Три первые из четырёх картинок я видел ранее… немного не похожа на ваш рисунок, но ясно, что это она.
А где эти файлы в сети вообще?
Некоторые паки имеют несколько игр, но при выборе всё вылетает или виснет.
barsik wrote:
80 символов в строке на реале без замены кварца не получить. Нужен кварц 20 МГЦ вместо 16 МГЦ. Это будет уже другой компьютер несовместимый с РК86.
Почему же?
На реальном РК я настраивал ВГ75/ВТ57 на экран 64×25. Растр хоть и был искажён позиционированием, но всё было устойчивым.
Если верить онлайн описанию ВГ75, можно прикинуть:
Code:
A0|D8|Bits Descriptions
--+--+--------+--------
 1|00|00000000|--------
--+--+--------+--------
 0|4D|sHHHHHHH|78 столбцов
 0|1D|vvRRRRRR|30 строк + 1 строка КСИ
 0|99|UUUULLLL|10 линия подчёркивания и 10 линий в символе
 0|93|MfCCZZZZ|мигающее подчёркивание и 8 символов ССИ

В оригинале:
(30+1)*10 = 310 линий растра
(78+8)*6  = 516 пикселей в линии
310*516   = 159960
Периоды ПДП - 3100

Экспериментально:
(50+2)*6  = 312 линий растра
(80+6)*6  = 516 пикселей в линии
312*516   = 160992
Периоды ПДП - 5167
Тем самым, если знакогенератор сплющить, то вполне можно добиться устойчивого матраца…
Правда в эмуляторах скроллинг такого экрана существенно тормозит. Потому и толку будет мало от такого режима для динамики. Только для статики…

barsik wrote:
Это не впечатляющие темпы…
Эти байты я сразу же занял под параметры зуммера, чтобы они могли указываться в рабочих ячейках Монитора. Например, в 7607/7608…


06 Feb 2020 00:45
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 04:46
Posts: 467
Location: С-Петербург
Reply with quote
Post 
Paguo-86PK wrote:
Если же... напрямую в буфере экрана работать... Набросoк кода для вставки символа в строку прямо на экране штатными подпрограммами Монитора занимает 220 байтов... и всё подтормаживает при длинных строчках.
А зачем подпрограммами монитора? 64 символа строки на время её редактирования становятся строчным буфером. И для редактирования используется та же подпрограмма, в которой символы кладутся в буфер процессором командой LD (HL),A. На текстовой машине это одновременно и текст сохраняет и визуализирует.

И вообще очень-очень странно, что на текстовой машине работа с текстом тормозит, вероятно у Вас применён очень неудачный алгоритм. Ведь при редактировании строки на графической машине не только редактируется буфер редактирования, но и выводятся символы в экран, что на графической машине в сто раз медленнее и то даже там абсолютно никаких тормозов при редактировании строки нет. А скорее всего дело в паршивом онлайн-эмуляторе, который искажает времянки.

Эта идея даже выгодна с точки зрения экономии объёма кода. Отпадает копирование из текстового буфера в буфер редактирования, т.к вместо него используется экран, куда текст попадает при визуализации текущего окна редактирования. Но по уходу с отредактированной строки на соседнюю всё-равно надо строку нормализовывать (вставляя табуляции, где возможно и откидывая пробелы после последнего отображаемого символа), а затем копировать строку в текстовый буфер, соответственно раздвигая или сдвигая соседние строки, если новый размер строки изменился в большую или меньшую стороны. Вообще хороший текстов редактор для тормозной машины не так прост.
Paguo-86PK wrote:
Вот не пойму, почему редакторы в начале памяти сидят? Приходилось всегда программы с 1100 копировать в 0000. Прямо хочется этот Микрон подкорректировать на 5000 хотя бы.
Лучше сразу на 9000 или E000, модернизировав для работы в ПЗУ, чтобы не тратить ОЗУ.
Paguo-86PK wrote:
Но я не знаю всех нюансов рабочей области
IDA в помощь. Но нет смысла связываться с Эд_Микрон-1. Зачем нужен редактор с изначально извратной идеологией. Надо написать нормальный редактор и это не так уж сложно. Если есть опыт в редакторах, то пишется за один день, если опыта нет, то за три дня.
Paguo-86PK wrote:
А где эти файлы в сети вообще?
Есть тема "Игры для РК86" на ZX-PK.ru, там есть некоторые ссылки, а так гуглится "программы для РК86" и всё подряд закачивается и потом разбирается. Во вложении три игры.
Paguo-86PK wrote:
при выборе всё вылетает или виснет
Полноценно эмулировать РК сложно, потому некоторые рабочие РК-игры в эмуляторе не работают или искажают картинку.
Paguo-86PK wrote:
(78+8)*6 = 516 пикселей в линии
. . . .
(80+6)*6 = 516 пикселей в линии
Откуда возьмутся видимые 80 символов. Раз частота пиксель клока та же, то видимыми останутся те же 64-65 символов в строке. А вот если кварц заменить (чтобы общее число пикселей стало 640) и ССИ сделать аппаратным, то будут видны 80 символов.
Paguo-86PK wrote:
Правда в эмуляторах скроллинг такого экрана существенно тормозит.
Этого в реале не может быть, т.к экран 64*50= всего 3200 байт. А даже тормозная ИРИША с эффективным тактом в 1 МГЦ сдвигает экран 16 кб за 0.25 секунды. У Вас неправильный эмулятор и неправильный алгоритм (стеком такой экран сдвинется за 0.1 сек, т.е мгновенно). Вредное псевдонаучное слово скролинг. Даже в английском языке это жаргон, а по русски это ролик экрана.


Attachments:
any games.rar [8.24 KiB]
Downloaded 16 times


Last edited by barsik on 06 Feb 2020 16:01, edited 1 time in total.

06 Feb 2020 08:35
Profile
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
barsik wrote:
А зачем подпрограммами монитора?
A как же кроссплатформенность‽ :lol:
barsik wrote:
64 символа строки на время её редактирования становятся строчным буфером.
В 90-х я написал свой полудрайвер. По АР2+I/O экран грузился на ленту / с ленты. По АР2+1…3 менялась форма курсора.
Строки раздвигались/схлопывались… Тогда я все накопленные знания там применил и на ленте у меня целые конспекты такими голыми экранами хранились и даже схемы:roll:
barsik wrote:
И вообще очень-очень странно, что на текстовой машине работа с текстом тормозит, вероятно у Вас применён очень неудачный алгоритм.
Прикрепил файл - изучайте (плесенью попахивает) :roll:
barsik wrote:
Лучше сразу на 9000 или E000, модернизировав для работы в ПЗУ, чтобы не тратить ОЗУ.
Ага… Ещё в A000…A7FF! :D
barsik wrote:
Во вложении три игры.
Спасибо!
Они самые. Правда Saboteur несколько иной: Всё на английском, череп в заставке вместо взрыва, флаг на базе вместо атомного гриба и справа вертикальная полоса видимая…
barsik wrote:
Откуда возьмутся видимые 80 символов. Раз частота пиксель клока та же, то видимыми останутся те же 64-65 символов в строке.
На своём УЛПЦТ том я так настраивал кадровую/строчную развёртки, что даже самые крайние символы видны были. Правда, сплющенные и завёрнутые, но видны были! :idea:
barsik wrote:
У Вас неправильный эмулятор…
Emu80 неправильный?
barsik wrote:
и неправильный алгоритм (стеком такой экран сдвинется за 0.1 сек, т.е мгновенно).
Весь экран двигать в XXI веке‽
Дамп ПЗУ «Windows'86» есть - можете подглянуть на прокрутку ограниченной прямоугольником области: Она аккурат впритык к FE01..
Там скроллер не такой, как в оригинале с копированием (HL),(DE) в цикле. А адаптирован под любой размер окна и ширину видеостроки. Потому он подтормаживает.

А режим 80×50 я именно на своём ПЗУ и тестировал, так как в других Мониторах дамп со скроллингом так просто в один взмах пальца не проверишь.

Хотя, даже директивой «T4050 4FFF 4000» Монитора экран прокручивается на строку вверх довольно медленно! А к директиве «T» претензий быть не может!

P.S.: Может понравится что-нибудь из моего собственного хлама:
Танковое поле - мультик, Генератор комиксов, Befunge - 25 лет
P.P.S.: Обновил редактор…
Написал более аккуратно и продуманнее. Всё равно тормоза сильные и ничто с этим не поделаешь.
Строки раздвигать нужно в недрах самой подпрограммы печати символа. И, как Вы знаете, Escape-перехват я предусмотрел. Нужно лишь добавить процедуры. К тому же сам скроллер (FDD4…FE00) ограниченного прямоугольника устроен так, что прокручивать можно прямо над текущей позиции курсора (нужно лишь в ПЗУ добавить эту «Esc+0A» без принудительного смещения курсора (FECE…FDD3) вниз).
Нужно прокрутку вниз написать значит (регистр BC с -78 переделать на +78) - то есть просто написать парочку команд и прыгнуть на адрес FDEC…
 Фрагмент Escape-драйвера
Code:
  PUSH D
  PUSH H
  CALL GOTO_X0
  LD   A,(CUR_MIN+1)
  CPL
  INC  A
  ADD  A,D
  JP   0FDDFH
Кстати… Спасибо!
Теперь я в своей подпрограмме нашёл изъян: там «ADD A,B» стоит, хотя «ADD A,D» не меняет сути логики, но Escape-драйвер из-за этого дублирует все эти 7 команд!
То есть в самом ПЗУ можно просто «JMP» где нужно поставить! :idea:


Attachments:
File comment: Сырец редактора.
F2 и Забой удаляют

rk86{7000-7134}.zip [445 Bytes]
Downloaded 13 times
File comment: Тест дампа на большом экране.
Загрузите файл, запустите «G0» и наберите «D0,1FFF» - ужасные тормоза!

rk86{0000-005D}.zip [2.08 KiB]
Downloaded 11 times


Last edited by Paguo-86PK on 06 Feb 2020 18:00, edited 1 time in total.

06 Feb 2020 12:02
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 04:46
Posts: 467
Location: С-Петербург
Reply with quote
Post 
Paguo-86PK wrote:
A как же кросс-платформенность?
Кроме РК-подобных остальные бытовые машинки графические, нетекстовые (сделанные в трёх экземплярах Микро-80 и ЮТ88 нельзя считать платформами). А для графической машины даже говорить о редактировании текста в самом экране бессмысленно. Да и кого волнует совместимость с другими платформами, когда даже от самых массовых платформ с сотнями тысяч машин едва осталось несколько десятков машин, да и на программы для них большинству их владельцев плевать.
barsik wrote:
64 символа строки на время её редактирования становятся строчным буфером.
Если от идеи редактирования строки прямо в экране машины с текстовым адаптером пойти ещё дальше, то приходим к идее редактирования буфера размером сразу в 25 строк, т.е всего экрана. С таким подходом можно даже уместить текстовый редактор всего в 1 кб (хотя потребность - уместиться лишь в 2 кб). По сути это редактор экрана, к которому добавляются две процедуры - загрузки в экран, начиная со строки номер такой-то, и запись
25-ти строк на исходное место. Это будет проще и по объёму кода меньше, но немного тормознее, чем когда (с раздвижкой/сдвижкой) в тексте обновляется всего одна строка.
Paguo-86PK wrote:
Весь экран двигать в XXI веке?
Именно так и делается ролик экрана (если только нет рулона, - аппаратного задания номера первой строки, что обеспечивает мгновенный ролик, как сделано в БК-010 и Океан-240).

Ещё раз подчеркну: ролик даже в медленной, но текстовой машине - почти мгновенный и проблем с ним из-за скорости не может быть. И я даже могу это неопровержимо доказать используя свои знания арифметики.

Для сдвижки 64*50= 3200 байтов, ролик делается 50-ю сдвигами кусков по 64 байта. Это занимает 131457 машинных тактов. Допустим эффективный такт при 50-ти строках 1 МГЦ, период маш.такта - 1 МКС. Итого ролик делается за 0.132 секунды. А экран в 25 строк роликуется всего за 0.066 секунды. Ролик стеком будет ещё на 25% быстрее. Это убедительно доказывает, что никаких скоростных проблем для ролика в РК86 нет.

Кстати, если двигать экран командой LDIR, что в РК невыгодно, т.к тогда из-за наличия в РК программного бордюра слева и справа от видимой части экрана надо двигать бОльший массив, - уже не 3200 байт, а 78*50= 3900 байт. LDIR тратит 21 такт на байт и при периоде маш.такта в 1 МКС на сдвиг уйдет 1*21*3900 байт = 0.081 секунды.

А экран в 25 строк командой LDIR роликуется всего за 0.04 секунды. Т.е при Z80 даже базовой скорости хватит на просмотр видео с разрешением 128*50 с частотой 25 кадров в секунду. Правда при столь высоком битрейте всей памяти РК в 32К хватит всего на 0.8 секунды такого видео.

У КР580 команды LDIR нет и её для КР580 в ПЗУ РК заменяют вот такой кучкой команд:
Code:
@LDIR:  LD      A,(HL)          ; пересылка блока размером [BC]
        LD      (DE),A          ; (HL) --> (DE)
        INC     HL
        INC     DE
        LOOP    @LDIR
при которой на байт тратится уже 50 тактов. Что более, чем вдвое тормознее, чем у Z80. Ролик 50-ти строк при этом занимает уже 0.195 секунды. Именно так неоптимально по скорости, но экономично по байтам, и сделан ролик в ПЗУ РК86. 25 строк сдвигаются за ~0.1 секунды. Это почти мгновенно. А при необходимости ролик можно ускорить вдвое, но разницу удастся заметить только, если сделать не однократный ролик, а непрерывный.
Paguo-86PK wrote:
Может понравится что-нибудь из моего собственного хлама
Демо с танчиками и выстрелами не оставляет сомнений в том, что добавив в это Демо ещё немного труда можно из этого сделать вполне играбельный вариант стрелялки типа "Commando" или "Ikari".

А просмотр Демо на 50 строк требует специального фонта, где посимвольный шаг в 6 байт, а в эмуляторах по умолчанию стоит фонт с шагом 8 байт. Картинка получается такой.


Last edited by barsik on 07 Feb 2020 02:55, edited 1 time in total.



06 Feb 2020 17:57
Profile
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
barsik wrote:
Если от идеи редактирования строки прямо в экране машины с текстовым адаптером пойти ещё дальше, то приходим к идее редактирования буфера размером сразу в 25 строк, т.е всего экрана. С таким подходом можно даже уместить текстовый редактор всего в 1 кб (хотя потребность - уместиться лишь в 2 кб).
Попробовaть, конечно, всё можно. Даже ради интереса :idea:
barsik wrote:
Именно так и делается ролик экрана (если только нет рулона, - аппаратного задания номера первой строки, что обеспечивает мгновенный ролик, как сделано в БК-010 и Океан-240).
Вся эта затея именно ради оконности, так как давно хотел проверить. Потому и прокрутку я делаю именно окна, а не всего экрана :roll:
barsik wrote:
Демо с танчиками и выстрелами не оставляет сомнений в том, что добавив в это Демо ещё немного труда можно из этого сделать вполне играбельный вариант стрелялки типа "Commando" или "Ikari".
Если заметили, все поля - интерактивные: Если в них что-то изменить, через пару секунд анимация перезапустится. Именно так я и накидал эту сценку… :mrgreen:
barsik wrote:
А просмотр Демо на 50 строк требует специального фонта, где посимвольный шаг в 6 байт, а в эмуляторах по умолчанию стоит фонт с шагом 8 байт. Картинка получается такой.
У меня та же картинка :D
Причём, на реальном РК была почти такая же. Но вот, если почти вслепую набрать «D0,1FFF», то тормоза будут очевидными…

Кстати, сейчас прикрепил нестабильную версию Монитора и файл с демкой.
Скролл работает от позиции курсора в обе стороны:
  • «Esc+Вверх» (1B 19) - прокрутка вверх
  • «Esc+Вниз» (1B 1A) - прокрутка вниз
  • «Esc+Стр» (1B 1F) - очистка окна
  • «Esc+Символ» (1B 20…7F) - эскейп-драйвер/заглушка
Во-первых, чтобы уместить код, пришлось его полностью переписать и прибегнуть к вызовам процедур. Из-за чего он стал заметно тормозить.
Во-вторых, стабильность нарушилась: Если набрать неверную комбинацию, прокрутка будет непредсказуемой. Из-за чего данная версия Монитора опасна для некоторых игр…

Более быстрый код прокрутки вылез за свои пределы и очень сильно сбоил.
Видимо, нужно серьёзнее им заняться и перепродумать. :roll:

P.S.: Таким усердием я добился малого, но ценой головной боли и пониженного давления…
Нужно хотя бы недельку отдохнуть от всего этого… :obye:


Attachments:
File comment: Нестабильная версия
okna-86.zip [2.23 KiB]
Downloaded 12 times
07 Feb 2020 00:31
Profile WWW
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
Переписaл практически 45% всего кода Монитора.
Все директивы на месте, но кое-что изменил:
  • Вызов адреса F836 передаёт управление обработчику ошибки ввода/вывода
  • Директива «B» как расширение «R0,7F,0» грузит загрузчик с внешнего ROM-диска
  • Директива «D» выдаёт дамп вместе с текстом
  • Директива «E» передаёт управление на адрес E000
  • Директива «G» работает как CALL и второй параметр указывает так же точку останова, но без порчи ячеек 0030…0032
  • Директива «L» исключена
  • Директива «M» выводит данные строчкой до восьми байтов
  • Директива «X» не отображает указатель «PC»
  • Печать символа теперь ограничивается не абсолютной пограничной координатой, а размером
  • Комбинация «АР2+ПС» прокручивает область над курсором, а «АР2+СТР» очищает текущее окно
  • Код 07 воспроизводит теперь любую тональность
Рабочие ячейки Монитора:
  • 7607:7608 - Длительность и высота «звонка» по коду 07
  • 7610:7611 - Координаты окна (Left:Top) <стандартно 8:3>
  • 7612:7613 - Размеры окна (Width:Height) <стандартно 63:24> (раньше был крайний угол 71:27)
  • 7620:7621 - Пользовательский драйвер Esc-комбинаций
  • 7622 - Размер экранной строки <стандартно 78> (используется выводом символа и прокруткой окна)
  • 76CD:76CE - Адрес обработчика ошибки ввода/вывода <стандартно F86C>
Пришлось слегка изменить логику некоторых подпрограмм. Так, при вводе строки нажатие «ВК» совершает возврат без печати этого символа. Это позволило директиве «M» выводить цепочку байтов строкой, а при запуске «G»-директивой курсор остаётся на месте.

Тем самым, сохранив весь привычный функционал, удалось чуточку модернизировать Монитор. А значит, кому не нужно, может высвободить ячейки FF72…FFFF (142 байта), добавляя свой функционал… :mrgreen:

Подчёркиваю: Моя версия Монитора имеет весь привычный функционал, но с некоторыми плюшками.

P.S.: Как я не додумался в 90-х директивой «X» изменить SP на 76CD: После этого «G» работает не как JMP, а как CALL :oidea:
Внимание!
Прошлый код содержал досадную ошибку: Директива «R» содержала «LD (08001H),HL» вместо «LD (0A001H),HL» и делала невозможным работать с ROM-диском!
Рекомендую перекачать файл…


Attachments:
File comment: Монитор:
B - быстрая загрузка ROM-диска, аналогично R0,7F,0
D - вывод дампа байтов и символов
G - вызов подпрограммы, отладка без порчи
E - передача управления на E000
M - модификация не столбиком, а строкой
X - просмотр/модификация регистров HL BC DE SP AF

okoshki.zip [1.91 KiB]
Downloaded 7 times
File comment: Вверху: Директивы «X» и «G»
Внизу: Тест режима 80×50 со знакогенератором 6×6

Okoski86_X.png
Okoski86_X.png [ 41.68 KiB | Viewed 307 times ]
File comment: Директивы «D» и «M»
Okoski86.png
Okoski86.png [ 35.87 KiB | Viewed 317 times ]
10 Feb 2020 17:29
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 04:46
Posts: 467
Location: С-Петербург
Reply with quote
Post 
Т.к исходника не было выложено, то из корыстных целей (с целью заимствования каких-либо идей по уплющиванию) дизассемблировал файл "okoshki.zip" и привёл полученный текст в читабельный и транслируемый вид. Используя этот исходник автор может продолжить дальнейшие модификации уже в текстовом редакторе, что намного удобнее, чем в отладчике.
Paguo-86PK wrote:
кому не нужно, может высвободить ячейки FF72…FFFF (142 байта), добавляя свой функционал…
Этот исходник мало оптимизирован, в нём легко с'экономить ещё многие десятки байтов, из чего сразу ясно, что неэффективно программировать в отладчике.

В результате трансляции, можно узнать какие стандартные внутренние входные точки сдвинуты. Кстати, константа чтения в данном алгоритме МГ-записи всегда ровно в 1.5 раза больше, чем константа записи, а в этом коде обе МГ-константы от балды. В реале читаться не будет, да и в эмуляторе при вводе WAV-файлов - тоже.

Директива X не нужна. Если нет встроенного мини-ассемблера и мини-дизассемблера, какой смысл в директиве X? С середины 80-тых годов уже даже в нашей стране никто не программирует в машинных кодах, потому директивы X/G абсолютно впустую отнимают ~90 байтов. Как директива G со стоп точкой может работать по CALL? Она должна работать по сохранённым регистрам. Так что фраза "изменить SP на 76CD... после чего «G» работает... как CALL" не только непонятна, но и бессмысленна.

По поводу кода РК ПЗУ. Подпрограмма COUT_A в ПЗУ РК портит регистр C. Это большой недостаток. Авторы РК для борьбы с ним используют вход в середину подпрограмм, где стек не выровнен. Делается PUSH BC и уход в подпрограмму, где до того также сделан PUSH BC. Это непрофессиональный и вредный стиль программирования.

Для борьбы с такой практикой в ассемблерах 8086 даже придумали оформлять подпрограммы словом procedure, потому там никто не делает вход на внутренние точки процедур. А для 8-ми разрядок программы непрофессиональных программистов отличаются именно таким наглым обращением со стеком. Выигрыш нескольких байтов за счёт надругательства над стеком запутывает код и это чревато ошибками в ходе развития программ и сопровождения. Кстати, ещё 50 лет назад против запутывания кода JMP-ами выступал Э.Дейкстра в своей известной статье против оператора GOTO.

С учётом того, что п/п-мма HEX_A в данном коде неэффективная (на целых 3 байта длиннее, чем моя), то при переделке COUT_A в SCOUTA число байтов увеличивается незначительно. Кстати, имя SCOUTA это акроним от фразы: Saved registers Console OUTput from A.
Code:
HEX_A:  PUSH    AF
        RRCA
        RRCA
        RRCA
        RRCA
        CALL    NIBBLE
        POP     AF
NIBBLE: AND     0FH
        CP      10
        CCF
        ADC     A,30H
        DAA
SCOUTA:
        PUSH    BC
        LD      C,A
        CALL    COUT_C
        POP     BC
        RET
Вот (не самый удачный) пример, что делают авторы РК:
Code:
HEXABL: PUSH    BC
@HEXA@: CALL    HEX_A         ; некорректный вход
        LD      C,20H
        CALL    COUT_C
        POP     BC
        RET
Эта и другие процедуры монитора короче, когда COUT_A чуть изменена, не портит BC и некорректных входов нет:
Code:
HEXABL: CALL    HEX_A
SPACE:  LD      A,20H
        JP      SCOUTA


 
Code:
; Дизассемблированное ПЗУ из файла "okoshki.zip" (с вышеупомянутым исправлением в DIR_R):

        .Z80
        aseg
        ORG     100H

RABADR  EQU     0F800H
DOPPPA  EQU     0A000H

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
CBEEP   EQU     BASE+07H
LAST_K  EQU     BASE+09H        ; эти 2 байта должны следовать подряд
COUNT   EQU     BASE+0AH        ; счётчик опросов (вначале 15)
APVFLG  EQU     BASE+0BH        ; флаг автоповтора
FRELOC  EQU     BASE+0CH        ; эта ячейка не используется

TMPSTK  EQU     BASE+0DH        ; временно храним стек при МГ п/п-ммах
WINKOO  EQU     BASE+10H        ; Левый верхний угол окна
DH      EQU     BASE+12H        ; ширина окна -1       
DV      EQU     BASE+13H        ; высота окна -1
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
ABREAK  EQU     BASE+20H
LNSTEP  EQU     BASE+22H
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+0CFH       ; стек монитора

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

VG_75   EQU     0C000H
VT_57   EQU     0E000H
RKDOS   EQU     0E000H
XROM    EQU     0F000H

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

; ----------------------------------------------

        .phase  0F800H

        JP      START
        JP      CONIN
        JP      LDBYTE
        JP      COUT_C
        JP      WRBYTE
        JP      COUT_C
        JP      STATUS
        JP      HEX_A
        JP      MSGH
        JP      XF81B
        JP      ASKCUR
        JP      RD_SCR
        JP      RD_BLK
        JP      WR_BLK
        JP      CHSUMM
        JP      PUSK_VG
ASKTOP: LD      HL,(RAMTOP)
        JP      SETTOP
ABORT:  LD      HL,(BASE+0CDH)
        JP      (HL)

; ----------------------------------------------

START:  LD      HL,PU
        LD      (HL),8AH
AF83F:
        DEC     HL
        LD      (HL),0
        LD      A,H
        CP      75H
        JP      NZ,AF83F
        LD      (RAMTOP),HL
       
        LD      HL,221DH                ; 1D2AH
        LD      (KNS_RD),HL
       
        LD      HL,P_JMP
        LD      (HL),0C3H

        LD      HL,(WARMST+1)           ; STACK
        LD      (R_SP),HL
       
        LD      SP,HL

        LD      HL,TITR
        CALL    MSGH
       
        CALL    PUSK_VG
       
        LD      HL,5F0H
        LD      (CBEEP),HL
       
if      $ ne RABADR + 06CH
        if1
        .printx * Standard subroutine WARMST shifted ! *
        endif
endif

WARMST:
        LD      SP,STACK

        CALL    RST_18
        defb    13,10,':','>'+80H
       
        LD      HL,XORA
        LD      (ABREAK),HL
       
        LD      HL,WARMST
        PUSH    HL
       
        CALL    GETLIN
       
        LD      A,(COMBUF)
       
        SBC     A,'A'-1
        LD      C,A
        LD      A,92H
        LD      HL,0CB1DH
        LD      DE,MASKA
AF891:  INC     DE
        INC     DE
AF893:  ADD     HL,HL
        ADC     A,A
        JP      Z,XROM
        DEC     C
        JP      C,AF893
        JP      NZ,AF891
       
        EX      DE,HL
        LD      E,(HL)
        INC     HL
        LD      D,(HL)
        PUSH    DE
        CALL    GETPRM
        LD      A,L
        LD      HL,(PAR_BC)
        LD      C,L
        LD      B,H
        LD      HL,(PAR_DE)
        EX      DE,HL
        LD      HL,(PAR_HL)
        RET

; ----------------------------------------------

TITR:   defb    1Fh,'oko{e~ki-86rk '

MASKA:  DW      1010100100111010B

TABLE:  DW      DIR_C
        DW      DIR_D
        DW      DIR_F
        DW      DIR_G
        DW      DIR_I
        DW      RKDOS
        DW      DIR_M
        DW      DIR_O
        DW      DIR_R
        DW      DIR_S
        DW      DIR_T
        DW      DIR_X

; ----------------------------------------------

ZABOJ:  OR      H
        JP      P,GTLLO2
        DEC     H
        DEC     L
        DEC     DE
        CALL    RST_18
        defb    8,32,8+80H
        JP      GTLLO2

; ----------------------------------------------

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

GETLIN: LD      HL,3FF0H
GTLLO1: LD      DE,COMBUF
        ADD     HL,HL
        RET     Z
GTLLO2: CALL    CONIN
        CP      '.'
        JP      Z,ABORT
        CP      8
        JP      Z,ZABOJ
        CP      7FH
        JP      Z,ZABOJ
        LD      (DE),A
        CP      13
        CALL    NZ,COUT_A
        JP      Z,GTLLO1
        INC     H
        INC     L
        JP      Z,ERROR
        INC     DE
        JP      GTLLO2

; ----------------------------------------------

RST_18: EX      (SP),HL
        CALL    MSGH
        INC     HL
        EX      (SP),HL
        RET

; ----------------------------------------------

MSGLOO: INC     HL
MSGH:   LD      A,(HL)
        OR      A
        RET     Z
        CALL    COUT_A
        RET     M
        JP      MSGLOO

; ----------------------------------------------

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

GETPRM: LD      HL,PAR_HL
        LD      DE,FLG_P2
        LD      C,0
        CALL    DIR_F
        LD      DE,BASE+34H
        CALL    GET_HL
        LD      (PAR_HL),HL
        LD      (PAR_DE),HL
        RET     C
        LD      A,0FFH
        LD      (FLG_P2),A
        CALL    GET_HL
        LD      (PAR_DE),HL
        RET     C
        CALL    GET_HL
        LD      (PAR_BC),HL
        RET     C
        NOP
        NOP
        NOP
GET_HL: LD      HL,0
        LD      BC,ERROR
AF960:  LD      A,(DE)
        INC     DE
        CP      13
        SCF
        RET     Z
        CP      ','
        RET     Z
        CP      20H
        JP      Z,AF960
        PUSH    BC
        SUB     30H
        RET     M
        CP      10
        JP      M,JJJ_01
        CP      11H
        RET     M
        CP      17H
        RET     P
        SUB     7
JJJ_01: ADD     HL,HL
        ADD     HL,HL
        ADD     HL,HL
        ADD     HL,HL
        ADD     A,L
        LD      L,A
        POP     BC
        JP      AF960

; ----------------------------------------------

SETTOP: LD      (RAMTOP),HL
        RET

; ----------------------------------------------

        LD      A,H
        CP      D
        RET     C

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

; ----------------------------------------------

AF996:  CALL    AF9A1
AF999:  CALL    CMPDH
        INC     HL
        RET     NZ
        DEC     HL
POPAF:  POP     AF
        RET

; ----------------------------------------------

AF9A1:  CALL    XF81B
AF9A4:  CP      27
        RET     NZ
        CALL    PUSK_VG
        JP      ERROR

; ----------------------------------------------

if      $ ne RABADR + 01B0H
        if1
        .printx * Internal subroutine RIGHT4 shifted ! *
        endif
endif

RIGHT4: CALL    RST_18
        defb    13,10,18h,18h,18h +128
        RET

; ----------------------------------------------

LDXHX@: LD      A,(HL)
HEXABL: PUSH    BC
@HEXA@: CALL    HEX_A
        LD      C,20H
        CALL    COUT_C
        POP     BC
        RET

; ----------------------------------------------

DIR_D:  CALL    Z,CHXHL@
        PUSH    HL
AF9C6:  CALL    LDXHX@
        INC     HL
        LD      A,L
        AND     3
        LD      C,8
        CALL    NZ,COUT_C
        LD      A,L
        AND     0FH
        JP      NZ,AF9C6
        POP     HL
AF9D9:  LD      A,(HL)
        LD      C,A
        SUB     20H
        CP      60H
        JP      C,AF9E4
        LD      C,'.'
AF9E4:  CALL    COUT_C
        CALL    AF996
        LD      A,L
        AND     0FH
        JP      NZ,AF9D9
        JP      DIR_D

; ----------------------------------------------

DIR_C:  LD      A,(BC)
        CP      (HL)
        JP      Z,AFA02
        CALL    CHXHL@
        CALL    LDXHX@
        LD      A,(BC)
        CALL    HEXABL
AFA02:  INC     BC
        CALL    AF996
        JP      DIR_C

; ----------------------------------------------

DIR_F:  LD      (HL),C
        CALL    AF999
        JP      DIR_F

; ----------------------------------------------

DIR_S:  LD      A,C
        CP      (HL)
        CALL    Z,CHXHL@
        CALL    AF996
        JP      DIR_S

; ----------------------------------------------

DIR_T:  LD      A,(HL)
        LD      (BC),A
        INC     BC
        CALL    CMPDH
        JP      DIR_T

; ----------------------------------------------

DIR_M:  CALL    Z,CHXHL@
        CALL    LDXHX@
        PUSH    HL
        CALL    GETLIN
        POP     HL
        JP      NC,AFA3E
        LD      C,';'
        CALL    COUT_C
        PUSH    HL
        CALL    GET_HL
        LD      A,L
        POP     HL
        LD      (HL),A
AFA3E:  INC     HL
        LD      A,L
        AND     7
        JP      DIR_M

; ----------------------------------------------

AFA45:  PUSH    BC
        SBC     A,A
        LD      B,A
        LD      A,(LNSTEP)
        XOR     B
        SUB     B
        LD      C,A
        ADD     HL,BC
        LD      A,B
        SCF
        ADC     A,A
        ADD     A,D
        LD      D,A
        POP     BC
        RET

; ----------------------------------------------

AFA56:  DEC     L
        LD      HL,(EK_ADR)
        JP      Z,AFA6B
        JP      PO,AFD9D
        JP      P,AFDAB
        CP      27
        JP      NZ,AFCEF
        LD      A,1
        RET

; ----------------------------------------------

AFA6B:  CP      1FH
        JP      Z,AFD80
        CP      10
        JP      NZ,AFDB7
        SCF
        CALL    AFDD5
XORA:   XOR     A               ; CY=0
        RET

; ----------------------------------------------

ASKCUR: LD      HL,(POSX)
        RET

; ----------------------------------------------

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

; ----------------------------------------------

DIR_I:  LD      A,(FLG_P2)
        OR      A
        JP      Z,AFA91
        LD      A,E
        LD      (KNS_RD),A
AFA91:  CALL    RD_BLK
        CALL    CHXHL@
        EX      DE,HL
        CALL    CHXHL@
        EX      DE,HL
        PUSH    BC
        CALL    CHSUMM
        LD      H,B
        LD      L,C
        CALL    CHXHL@
        POP     DE
        CALL    CMPDH
        RET     Z
        EX      DE,HL
        CALL    CHXHL@
ERROR:
        CALL    RST_18
        defb    7,'?'+128
        JP      ABORT

; ----------------------------------------------

RD_BLK: LD      A,255
        CALL    LD_BC
        PUSH    HL
        ADD     HL,BC
        EX      DE,HL
        CALL    LDBCBS
        POP     HL
        ADD     HL,BC
        EX      DE,HL
        PUSH    HL
        CALL    AFB0A
        LD      A,255
        CALL    LD_BC
        POP     HL

if      $ ne RABADR + 02CEH     ; FACE
        if1
        .printx * Internal subroutine PUSK_VG shifted ! *
        endif
endif

PUSK_VG:
        PUSH    HL
        LD      HL,VG_75+1
        LD      (HL),0
        DEC     HL
        LD      (HL),4DH
        LD      (HL),1DH
        LD      (HL),99H
        LD      (HL),93H
        INC     HL
        LD      (HL),27H
        LD      A,(HL)

AFAE1:  LD      A,(HL)
        AND     20H
        JP      Z,AFAE1
        LD      HL,VT_57+8
        LD      (HL),80H
        LD      L,4
        LD      (HL),0D0H
        LD      (HL),76H
        INC     L
        LD      (HL),23H
        LD      (HL),49H
        LD      L,8
        LD      (HL),0A4H
        POP     HL
        RET

; ----------------------------------------------

LDBCBS: LD      A,8
LD_BC:  CALL    LDBYTE
        LD      B,A
        LD      A,8
        CALL    LDBYTE
        LD      C,A
        RET

; ----------------------------------------------

AFB0A:  LD      A,8
        CALL    LDBYTE
        LD      (HL),A
        CALL    AF999
        JP      AFB0A

; ----------------------------------------------

CHSUMM: LD      BC,0
CHSLOO: 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      CHSLOO

; ----------------------------------------------

DIR_O:  LD      A,C
        OR      A
        JP      Z,AFB35         ; если не указано константы
        LD      (KNS_WR),A
AFB35:  PUSH    HL
        CALL    CHSUMM
        POP     HL
        CALL    CHXHL@
        EX      DE,HL
        CALL    CHXHL@
        EX      DE,HL
        PUSH    HL
        LD      H,B
        LD      L,C
        CALL    CHXHL@
        POP     HL
WR_BLK:
        PUSH    BC
        LD      BC,0
AFB4D:  CALL    WRBYTE
        DEC     B
        EX      (SP),HL
        EX      (SP),HL
        JP      NZ,AFB4D
       
        LD      C,0E6H
        CALL    WRBYTE
        CALL    WR_HL
        EX      DE,HL
        CALL    WR_HL
        EX      DE,HL
        CALL    AFB86
        LD      HL,0
        CALL    WR_HL
        LD      C,0E6H
        CALL    WRBYTE
        POP     HL
        CALL    WR_HL
        JP      PUSK_VG

; ----------------------------------------------

if      $ ne RABADR + 0378H
        if1
        .printx * Internal subroutine CHXHL@ shifted ! *
        endif
endif

CHXHL@: PUSH    BC              ; <ВК>, HEX_HL, SPACE
        CALL    RIGHT4
        LD      A,H
        CALL    HEX_A
        LD      A,L
        JP      @HEXA@

; ----------------------------------------------

        DS      2

; ----------------------------------------------

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

; ----------------------------------------------

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

; ----------------------------------------------

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

LDBYTE: PUSH    HL
        PUSH    BC
        PUSH    DE
        LD      D,A
AFB9C:  LD      A,80H
        LD      (VT_57+8),A
        LD      HL,0
        ADD     HL,SP
        LD      SP,0
        LD      (TMPSTK),HL
        LD      C,0
        LD      A,(PC)
        RRCA
        RRCA
        RRCA
        RRCA
        AND     1
        LD      E,A
AFBB7:  POP     AF
        LD      A,C
        AND     7FH
        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     12H
AFBDC:  LD      B,A
AFBDD:  POP     AF
        DEC     B
        JP      NZ,AFBDD
        INC     D
        LD      A,(PC)
        RRCA
        RRCA
        RRCA
        RRCA
        AND     1
        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
        LD      A,0FFH
        LD      (INV_MG),A
AFC09:  LD      D,9
AFC0B:  DEC     D
        JP      NZ,AFBB7
        LD      HL,VT_57+4
        LD      (HL),0D0H
        LD      (HL),76H
        INC     HL
        LD      (HL),23H
        LD      (HL),49H
        LD      A,27H
        LD      (VG_75+1),A
        LD      A,0E0H
        LD      (VG_75+1),A
        LD      L,8
        LD      (HL),0A4H
        LD      HL,(TMPSTK)
        LD      SP,HL
        LD      A,(INV_MG)
        XOR     C
        JP      POPDBH

; ----------------------------------------------

AFC34:  LD      HL,(TMPSTK)
        LD      SP,HL
        CALL    PUSK_VG
        LD      A,D
        OR      A
        JP      P,ERROR
        CALL    AF9A4
        JP      AFB9C

; ----------------------------------------------

if      $ ne RABADR + 0446H
        if1
        .printx * WRBYTE for emulator B2M need be at FC46 ! *
        endif
endif

WRBYTE: PUSH    HL
        PUSH    BC
        PUSH    DE
        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,0
        XOR     C
        LD      (PC),A
        DEC     D
        LD      A,(KNS_WR)
        JP      NZ,AFC7A
        SUB     14
AFC7A:  LD      B,A
AFC7B:  POP     AF
        DEC     B
        JP      NZ,AFC7B
        INC     D
        DEC     D
        JP      NZ,AFC58
        LD      SP,HL
        LD      HL,VT_57+4
        LD      (HL),0D0H
        LD      (HL),76H
        INC     HL
        LD      (HL),23H
        LD      (HL),49H
        LD      A,27H
        LD      (VG_75+1),A
        LD      A,0E0H
        LD      (VG_75+1),A
        LD      L,8
        LD      (HL),0A4H
        POP     AF
POPDBH: POP     DE
        POP     BC
        POP     HL
        RET

if      $-1 ne 0FCA4H
        if1
        .printx * Internal point 0FCA4H (need for emulator B2M) shifted ! *
        endif
endif

; ----------------------------------------------

HEX_A:  PUSH    AF
        RRCA
        RRCA
        RRCA
        RRCA
        CALL    NIBBLE
        POP     AF
NIBBLE: AND     0FH
        CP      10
        JP      M,JJJ_02
        ADD     A,7
JJJ_02: ADD     A,30H

COUT_A:
        LD      C,A
COUT_C: PUSH    HL
        PUSH    BC
        PUSH    DE
        PUSH    AF
        CALL    STATUS
        LD      A,C
        AND     7FH
        LD      HL,(WINKOO)
        EX      DE,HL
        LD      HL,(DH)
        ADD     HL,DE
        LD      B,H
        LD      C,L
        LD      HL,(POSX)
        EX      DE,HL
        LD      HL,(ESC_F)
        CALL    AFA56
        LD      (ESC_F),A
        LD      (EK_ADR),HL
        LD      HL,VG_75+1
        LD      (HL),80H
        DEC     L
        LD      (HL),E
        LD      (HL),D
        EX      DE,HL
        LD      (POSX),HL
        POP     AF
        POP     DE
        POP     BC
        POP     HL
        RET

; ----------------------------------------------

AFCEF:  CP      8
        EX      (SP),HL
        INC     HL
        INC     HL
        INC     HL
        EX      (SP),HL
        JP      Z,COD_08
        CP      18H
        JP      Z,COD_18
        CP      1AH
        JP      Z,COD_1A
        CP      19H
        JP      Z,COD_19
        CP      1FH
        JP      Z,CLS
        CP      0CH
        JP      Z,HOME
        CP      13
        JP      Z,COD_0D
        CP      10
        JP      Z,COD_0A
        CP      7
        JP      NZ,AFDC6
        PUSH    HL
        LD      HL,(CBEEP)
        EX      (SP),HL
        POP     BC
BEEP:
        LD      A,B
BP1:    EI
        DEC     A
        JP      NZ,BP1
        LD      A,B
BP2:    DI
        DEC     A
        JP      NZ,BP2
        DEC     C
        JP      NZ,BEEP
        RET

; ----------------------------------------------

COD_18: INC     HL
        LD      A,E
        INC     E
        CP      C
        RET     C
        CALL    COD_0D
COD_1A: CALL    AFA45
        DEC     A
        CP      B
        RET     C
AFD46:  LD      A,(WINKOO+1)
        CP      D
        RET     NC
        CALL    AFA45
        JP      AFD46

; ----------------------------------------------

AFD51:  INC     HL
        INC     E
        LD      A,E
        CP      C
        JP      NZ,AFD51
COD_19: LD      A,(WINKOO+1)
        CP      D
        JP      C,AFA45
AFD5F:  CALL    AFA45
        CP      B
        CCF
        JP      NC,AFD5F
        RET

; ----------------------------------------------

CLS:    LD      A,78
        LD      (LNSTEP),A
        LD      HL,308H
        LD      (WINKOO),HL
        EX      DE,HL
        LD      HL,183FH
        LD      (DH),HL
        ADD     HL,DE
        LD      B,H
        LD      C,L
        LD      HL,SCBASE
AFD80:  CALL    HOME
AFD83:  XOR     A
        CALL    AFDC6
        LD      A,D
        CP      B
        SBC     A,A
        OR      C
        SUB     E
        JP      NZ,AFD83
        LD      (HL),A
HOME:
        CALL    AFD46
COD_0D: LD      A,(WINKOO)
        SUB     E
        RET     Z
        DEC     E
        DEC     HL
        JP      COD_0D

; ----------------------------------------------

AFD9D:  SUB     1CH
AFD9F:  CP      4
        RET     Z
        PUSH    AF
        CALL    NC,COD_1A
        POP     AF
        DEC     A
        JP      AFD9F

; ----------------------------------------------

AFDAB:  SUB     1FH
AFDAD:  DEC     A
        RET     Z
        PUSH    AF
        CALL    COD_18
        POP     AF
        JP      AFDAD

; ----------------------------------------------

AFDB7:  PUSH    HL
        LD      HL,(ABREAK)
        EX      (SP),HL
        CP      'Y'
        RET     NZ
        POP     AF
        CALL    HOME
        LD      A,2
        RET

; ----------------------------------------------

AFDC6:  LD      (HL),A
        INC     HL
        LD      A,E
        INC     E
        CP      C
        RET     C
        CALL    COD_0D
COD_0A: LD      A,B
        DEC     A
        CP      D
        JP      NC,AFA45
AFDD5:  PUSH    DE
        PUSH    HL
        SBC     A,A
        LD      B,A
        LD      A,(WINKOO+1)
        XOR     B
        SBC     A,B
        ADD     A,D
        INC     D
        LD      D,A
        CALL    COD_0D
        LD      A,C
        SUB     E
        LD      E,A
        LD      A,(LNSTEP)
        XOR     B
        SBC     A,B
        LD      C,A
AFDED:  PUSH    DE
        PUSH    HL
        XOR     A
AFDF0:  LD      E,(HL)
        LD      (HL),A
        ADD     HL,BC
        LD      A,E
        DEC     D
        JP      P,AFDF0
        POP     HL
        POP     DE
        INC     HL
        DEC     E
        JP      P,AFDED
        POP     HL
        POP     DE
STATUS: LD      A,(PC)
        AND     80H
        JP      Z,AFE0E
        LD      A,(KBDFLG)
        OR      A
        RET     NZ
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

; ----------------------------------------------

AFE2A:  DEC     H
        JP      NZ,AFE21
        INC     A
        JP      Z,AFE22
        INC     A
        JP      Z,AFE51
        PUSH    BC
        LD      BC,5003H
        CALL    BEEP
        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

; ----------------------------------------------

AFE51:  LD      A,(PC)
        AND     80H
        JP      Z,AFE51
        LD      A,(RUSLAT)
        CPL
        LD      (RUSLAT),A
        JP      AFE1A

; ----------------------------------------------

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

; ----------------------------------------------

XF81B:  LD      A,(PC)
        AND     80H
        JP      NZ,AFE7D
        LD      A,0FEH
        RET

; ----------------------------------------------

AFE7D:  XOR     A
        LD      (PA),A
        LD      (PC),A          ; ненужное и вредное
        LD      A,(RUSLAT)
        AND     1
        OR      6
        LD      (PU),A
        LD      A,(PB)
        INC     A
        JP      NZ,AFE97
        DEC     A
        RET

; ----------------------------------------------

AFE97:  PUSH    HL
        LD      L,1
        LD      H,7
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

; ----------------------------------------------

AFEB3:  LD      L,20H
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

; ----------------------------------------------

TABK1:  defb    9,0AH,0DH,7FH,8,19H,18H,1AH
TABK2:  defb    0CH,1FH,1BH,0,1,2,3,4,5

; ----------------------------------------------

AFEF3:  LD      A,H
        LD      HL,TABK2
        JP      AFEFE

; ----------------------------------------------

AFEFA:  LD      A,H
        LD      HL,TABK1
AFEFE:  ADD     A,L
        LD      L,A
        LD      A,(HL)
        CP      40H
        POP     HL
        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

; ----------------------------------------------

AFF1A:  LD      A,(RUSLAT)
        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

; ----------------------------------------------

AFF3B:  LD      A,L
        AND     00101111B
        LD      L,A
AFF3F:  LD      A,L
        CP      40H
        POP     HL
        RET     P
        PUSH    HL
        LD      L,A
        AND     0FH
        CP      0CH
        LD      A,L
        JP      M,POPHL
        XOR     10H
POPHL:  POP     HL
        RET

; ----------------------------------------------

COD_08: LD      A,(WINKOO)
        CP      E
        JP      NC,AFD51
        DEC     HL
        DEC     E
        RET

; ----------------------------------------------

DIR_R:  OUT     (80H),A
        LD      A,90H
        OUT     ((high PDA)+3),A        ; 0A3H
DIRRLO: LD      (PDB),HL
        IN      A,(high PDA)            ; 0A0H
        LD      (BC),A
        INC     BC
        CALL    AF999
        JP      DIRRLO

; ----------------------------------------------

DIR_G:  CALL    CMPDH
        JP      Z,AFF86         ; если нет 2-го параметра
        EX      DE,HL
       
        LD      A,(HL)
        LD      (TMP_COD),A
       
        LD      (HL),0CDH
        INC     HL
        LD      SP,HL
        POP     HL
        LD      (STOP_A),HL
       
        LD      HL,AFF94
        PUSH    HL
       
AFF86:  LD      SP,R_BC
        POP     BC
        POP     DE
        POP     HL
        POP     AF
        LD      SP,HL
        LD      HL,(R_HL)
        CALL    P_JMP
AFF94:  LD      (R_HL),HL
        PUSH    AF
        POP     HL
        LD      (R_AF),HL
        POP     HL
        LD      (POINT),HL
        LD      HL,-2
        ADD     HL,SP
        LD      SP,R_AF
        PUSH    HL
        PUSH    DE
        PUSH    BC
        LD      HL,(POINT)
        LD      SP,HL
        LD      HL,(STOP_A)
        PUSH    HL
        DEC     SP
        POP     HL
        LD      A,(TMP_COD)
        LD      L,A
        PUSH    HL
        JP      WARMST

; ----------------------------------------------

DIR_X:  CALL    RST_18
        defb    13,10,'HL'
        defb    13,10,'BC'
        defb    13,10,'DE'
        defb    13,10,'SP'
        defb    13,10,'AF'
        defb    19H,19H,19H,19H,19H +128
        LD      HL,R_HL
        LD      B,5
AFFDD:  LD      E,(HL)
        INC     HL
        LD      D,(HL)
        PUSH    BC
        PUSH    HL
        EX      DE,HL
        CALL    CHXHL@
        CALL    GETLIN
        JP      NC,AFFF5
        CALL    GET_HL
        POP     DE
        PUSH    DE
        EX      DE,HL
        LD      (HL),D
        DEC     HL
        LD      (HL),E
AFFF5:  POP     HL
        POP     BC
        DEC     B
        INC     HL
        JP      NZ,AFFDD
        RET

; ----------------------------------------------

        defb     3AH,2DH,44H

        .dephase
       
        END


12 Feb 2020 12:34
Profile
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
barsik wrote:
Т.к исходника не было выложено, то из корыстных целей (с целью заимствования каких-либо идей по уплющиванию) дизассемблировал файл "okoshki.zip" и привёл полученный текст в читабельный и транслируемый вид.
Спасибо!
Любопытно глянуть на свой код глазами другого человека.
В основном - метки именованы иначе…
Нормального текста пока нет. Но по мере битья листинга, дамп в окне дополняется и все бреши заполняются моим кодом.
 Примерно вот так
Attachment:
File comment: Мой дамп Монитора
raw-dump.png
raw-dump.png [ 80.52 KiB | Viewed 222 times ]

barsik wrote:
Этот исходник мало оптимизирован, в нём легко с'экономить ещё многие десятки байтов, из чего сразу ясно, что неэффективно программировать в отладчике.
Quote:
Переписaл практически 45% всего кода Монитора.
Ещё не занимался кодом работы с магнитофоном и клавиатурой.
И такты пересчитывать пока лень…
Если я не набаламутил с тактами, то получается следующее:
 Такты оригинальной подпрограммы
Code:
WRBYTE: PUSH    HL              ; 11    {{
        PUSH    BC              ; 11
        PUSH    DE              ; 11
        PUSH    AF              ; 11
        LD      A,80H           ; 7
        LD      (VT_57+8),A     ; 13
        LD      HL,0            ; 10
        ADD     HL,SP           ; 4
        LD      SP,0            ; 10
        LD      D,8             ; 7     }} = 95
AFC58:  POP     AF              ; 10    {{
        LD      A,C             ; 5
        RLCA                    ; 4
        LD      C,A             ; 5
        LD      A,1             ; 7
        XOR     C               ; 4
        LD      (PC),A          ; 13
        LD      A,(KNS_WR)      ; 13
        LD      B,A             ; 5     }} = 66                                 :: x8 = 528
AFC66:  POP     AF              ; 10    {{
        DEC     B               ; 5
        JP      NZ,AFC66        ; 10    }} = 25 * KNS_WR                        :: x8 = 200 * KNS_WR
        LD      A,0             ; 7     {{
        XOR     C               ; 4
        LD      (PC),A          ; 13
        DEC     D               ; 5
        LD      A,(KNS_WR)      ; 13
        JP      NZ,AFC7A        ; 10
        SUB     14              ; 7
AFC7A:  LD      B,A             ; 5     }} = 57 / 64                            :: x8 = 520
AFC7B:  POP     AF              ; 10    {{
        DEC     B               ; 5
        JP      NZ,AFC7B        ; 10    }} = 25 * KNS_WR:25 * (KNS_WR - 14) + 7 :: x8 = 200 * KNS_WR - 350
        INC     D               ; 5     {{
        DEC     D               ; 5
        JP      NZ,AFC58        ; 10    }} = 20                                 :: x8 = 160
        LD      SP,HL           ; 5     {{
        LD      HL,VT_57+4      ; 10
        LD      (HL),0D0H       ; 11
        LD      (HL),76H        ; 11
        INC     HL              ; 5
        LD      (HL),23H        ; 11
        LD      (HL),49H        ; 11
        LD      A,27H           ; 7
        LD      (VG_75+1),A     ; 13
        LD      A,0E0H          ; 7
        LD      (VG_75+1),A     ; 13
        LD      L,8             ; 7
        LD      (HL),0A4H       ; 11
        POP     AF              ; 10
POPDBH: POP     DE              ; 10
        POP     BC              ; 10
        POP     HL              ; 10
        RET                     ; 10    }} = 172
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; = 1475 + 376.667 * KNS_WR
 95
...
528 + x25
399 + x25  +  64 + x25 - 350 = 463 + x25 - 350 = 113 + x25
...
160
...
176 = 431 + 641 + x25 = 1072 + x25
 Такты моей подпрограммы
Code:
WRBYTE: PUSH    HL              ; 11    {{
        PUSH    BC              ; 11
        PUSH    DE              ; 11
        PUSH    AF              ; 11
        LD      A,080H          ; 7
        LD      (VT_57+8),A     ; 13
        LD      HL,00000H       ; 10
        ADD     HL,SP           ; 4
        LD      SP,00000H       ; 10
        EX      HL,DE           ; 4
        LD      L,C             ; 5
        LD      H,001H          ; 7     }} = 104
WRBYTE1:POP     AF              ; 10    {{
        ADD     HL,HL           ; 4
        SBC     A,A             ; 4
        AND     00EH            ; 7
        LD      C,A             ; 5
        LD      A,H             ; 5
        XOR     001H            ; 7
        LD      (PC),A          ; 13
        LD      A,(KNS_WR)      ; 13
        LD      B,A             ; 5     }} = 73                                 :: x8 = 584
WRBYTE2:POP     AF              ; 10    {{
        DEC     B               ; 5
        JNZ     WRBYTE2         ; 10    }} = 25 * KNS_WR                        :: x8 = 200 * KNS_WR
        LD      A,H             ; 5     {{
        LD      (PC),A          ; 13
        LD      A,(KNS_WR)      ; 13
        SUB     C               ; 4
        LD      B,A             ; 5     }} = 40                                 :: x8 = 320
WRBYTE3:POP     AF              ; 10    {{
        DEC     B               ; 5
        JNZ     WRBYTE3         ; 10    }} = 25 * KNS_WR : 25 * (KNS_WR - 14)   :: x8 = 200 * KNS_WR - 350
        DEC     C               ; 5     {{
        JP      M,WRBYTE1       ; 10    }} = 15                                 :: x8 = 120
        EX      HL,DE           ; 4     {{
        LD      SP,HL           ; 5
        LD      HL,VT_57+4      ; 10
        LD      (HL),0D0H       ; 11
        LD      (HL),76H        ; 11
        INC     HL              ; 5
        LD      (HL),23H        ; 77
        LD      (HL),49H        ; 11
        LD      A,27H           ; 7
        LD      (VG_75+1),A     ; 13
        LD      A,0E0H          ; 7
        LD      (VG_75+1),A     ; 13
        LD      L,8             ; 7
        LD      (HL),0A4H       ; 11
        POP     AF              ; 10
POPDBH: POP     DE              ; 10
        POP     BC              ; 10
        POP     HL              ; 10
        RET                     ; 10    }} = 176
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; = 1304 + 376.667 * KNS_WR
У меня явные расхождения по тактам - 73 против 40. Почти в два раза.
Есть мысль не отнимать 14 на восьмом цикле, а прибавлять что-то в первых семи циклах.
Здесь нужно возомнить себя великим математиком и серьёзно произвести вычисления всего этого дела… :egeek:
Если «XOR 1» заменить на «DEC A» или «CPL» - суть не изменится, но будет экономия на байт и такты…
 Более выровненный вариант
Code:
WRBYTE: PUSH    HL              ; 11    {{
        PUSH    BC              ; 11
        PUSH    DE              ; 11
        PUSH    AF              ; 11
        LD      A,080H          ; 7
        LD      (VT_57+8),A     ; 13
        LD      HL,00000H       ; 10
        ADD     HL,SP           ; 4
        LD      SP,00000H       ; 10
        EX      HL,DE           ; 4
        LD      L,C             ; 5
        LD      H,001H          ; 7     }} = 104
WRBYTE1:POP     AF              ; 10    {{
        LD      A,L             ; 5
        RLCA                    ; 4
        CPL                     ; 4
        LD      (PC),A          ; 13
        LD      A,(KNS_WR)      ; 13
        LD      B,A             ; 5     }} = 54                                 :: x8 = 432
WRBYTE2:POP     AF              ; 10    {{
        DEC     B               ; 5
        JNZ     WRBYTE2         ; 10    }} = 25 * KNS_WR                        :: x8 = 200 * KNS_WR
        ADD     HL,HL           ; 4     {{
        SBC     A,A             ; 4
        AND     00EH            ; 7
        LD      C,A             ; 5
        LD      A,H             ; 5
        LD      (PC),A          ; 13
        LD      A,(KNS_WR)      ; 13
        SUB     C               ; 4
        LD      B,A             ; 5     }} = 60                                 :: x8 = 480
WRBYTE3:POP     AF              ; 10    {{
        DEC     B               ; 5
        JNZ     WRBYTE3         ; 10    }} = 25 * KNS_WR : 25 * (KNS_WR - 14)   :: x8 = 200 * KNS_WR
        DEC     C               ; 5     {{
        JP      M,WRBYTE1       ; 10    }} = 15                                 :: x8 = 120
        EX      HL,DE           ; 4     {{
        LD      SP,HL           ; 5
        LD      HL,VT_57+4      ; 10
        LD      (HL),0D0H       ; 11
        LD      (HL),76H        ; 11
        INC     HL              ; 5
        LD      (HL),23H        ; 77
        LD      (HL),49H        ; 11
        LD      A,27H           ; 7
        LD      (VG_75+1),A     ; 13
        LD      A,0E0H          ; 7
        LD      (VG_75+1),A     ; 13
        LD      L,8             ; 7
        LD      (HL),0A4H       ; 11
        POP     AF              ; 10
POPDBH: POP     DE              ; 10
        POP     BC              ; 10
        POP     HL              ; 10
        RET                     ; 10    }} = 176
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
104
...
432 + x25
420 + x25  +  60 + x25 - 350 = 480 + x25 - 350 = 130 + x25
...
120
...
176 = 400 + 562 + x25 = 962 + x25
barsik wrote:
В результате трансляции, можно узнать какие стандартные внутренние входные точки сдвинуты.
В основном - директивы.
barsik wrote:
Кстати, константа чтения в данном алгоритме МГ-записи всегда ровно в 1.5 раза больше, чем константа записи, а в этом коде обе МГ-константы от балды. В реале читаться не будет, да и в эмуляторе при вводе WAV-файлов - тоже.
В оригинале - 2A и 1D. У меня - 1D и 22… :oops:
Опечатался :o
Спасибо за замечание! :idea:
Оказывается код
Code:
F860 .. 21 2A 1D|22 2F 76
прочёл как
Code:
F860 .. .. 21 1D|22|2F 76
Видимо, так глаза забинарились, что две команды слились! :mrgreen:
barsik wrote:
Директива X не нужна.
Эта тема уже обсуждалась. Я сторонник полного функционала.
Тем более, в журнале РАДИО и директиву «R» выпилили в одной из публикаций. Если мне не изменяет память, под ту самую «W» для поиска по двум байтам.
В то время «R» не была так важна рядовым пользователям. А сейчас она необходима в тех же эмуляторах.
Тем не менее, эти «R», «G» и «X» я отправил в самый конец, как уже поняли. Можно там выпиливать, пропиливать и допиливать их как хотите! :D
barsik wrote:
Как директива G со стоп точкой может работать по CALL?
Запустите оригинальный Монитор, в «X», измените SP на 76CD, затем последовательно исполните «GF803» и «GF815».
barsik wrote:
По поводу кода РК ПЗУ. Подпрограмма COUT_A в ПЗУ РК портит регистр C. Это большой недостаток.
Ещё больший недостаток в том, что тот же RST_18 портит и A, и C. У меня есть вариант кода, не портящий аккумулятор:
Code:
MSGH:   LD      C,(HL)
        DEC     C
        INC     C
        RET     Z
        CALL    COUT_C
        RET     M
        INC     HL
        JP      MSGH
Но я не знаю, какие последствия могут быть…
barsik wrote:
Авторы РК для борьбы с ним используют вход в середину подпрограмм, где стек не выровнен. Делается PUSH BC и уход в подпрограмму, где до того также сделан PUSH BC. Это непрофессиональный и вредный стиль программирования.
Изначально Монитор задуман как законченный код, без наращивания и приращивания. Потому и подобные трюки не так плохи… :roll:
И код можно переписать вот так:
Code:
COUT_A: PUSH AF
        JP   COUT_C1
COUT_C: PUSH AF
        LD   A,C
COUT_C1:AND  07FH
barsik wrote:
С учётом того, что п/п-мма HEX_A в данном коде неэффективная (на целых 3 байта длиннее, чем моя), то при переделке COUT_A в SCOUTA число байтов увеличивается незначительно.
Своими 45% я ещё толком и половины не перелопатил! :no:
Основное усердие я проявил в комбинированной «D», чтобы слиять её с «L». А так как коды этих директив безобразным образом разделялись «C», «F», «S» и «T», то пришлось всё сместить ради исключения лишнего «JMP»…

P.S.: Параллельно пытаюсь писать Escape-драйвер с минимальной привязкой к рабочим ячейками Монитора. Однако, для унификации неплохо было бы иметь отдельную таблицу JMP'ов для доступа к внутренним ресурсам. Но у меня уже всё забито. А выбрасывать тот же «X» - не хорошо в моём случае.
Хотя смещения окна целиком я уже добился по горизонтали.
И прокрутку одной строки сделал для вставки символа: Область 64×25 полностью (64 раза) прокручивается за 8 секунд - 8 кадров в секунду. Вполне подходит для игры-скроллера…
P.P.S.: Досадная проблема: Оболочка-подобие Нортона запускает программы, предварительно сильно загадив область экранного буфера. А так как моя подпрограмма печати очищает лишь область 64×25, экран сильно сбоит и срываются циклы ПДП. По 1F нужно обнулять весь буфер целиком. Но мой код размерами этого никак не позволяет!
P.P.P.S.: Из многих онлайн-редакторов дампа этот достаточно удобный:roll:
И книга, оказывается, есть «ДИЗАССЕМБЛИРОВАНИЕ В УМЕ» :lol:


Attachments:
File comment: Код опроса клавиатуры
«Рус/Lat» всё ещё не внедрил
«СС»+«Пробел» выдают код знака подчёркивания

KeyBoard.zip [373 Bytes]
Downloaded 8 times
13 Feb 2020 13:26
Profile WWW
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
Вылизaл код, как мог…
Не знаю, имеются ли косяки. Но по подсчётам тактов баланс практически 1 в 1 и на 2 байта короче…
 Сбалансированный вариант
Code:
WRBYTE: PUSH    HL              ; 11    {{
        PUSH    BC              ; 11
        PUSH    DE              ; 11
        PUSH    AF              ; 11
        LD      A,080H          ; 7
        LD      (VT_57+8),A     ; 13
        LD      HL,00000H       ; 10
        ADD     HL,SP           ; 4
        EX      HL,DE           ; 4
        LD      L,C             ; 5
        LD      H,001H          ; 7
        LD      SP,HL           ; 5     }} = 99
WRBYTE1:POP     AF              ; 10    {{
        LD      A,L             ; 5
        RLCA                    ; 4
        CPL                     ; 4
        LD      (PC),A          ; 13    -- 36 vv 85 тактов от второго LD (PC),A
        LD      A,(KNS_WR)      ; 13
        LD      B,A             ; 5     }} = 54                                 :: x8 = 432
WRBYTE2:POP     AF              ; 10    {{
        DEC     B               ; 5
        JP      NZ,WRBYTE2      ; 10    }} = 25 * KNS_WR                        :: x8 = 200 * KNS_WR
        ADD     HL,HL           ; 4     {{
        SBC     A,A             ; 4
        AND     00EH            ; 7     -- 11 для компенсации на 275 тактов (99+176); 14 - на 315 тактов
        INC     A               ; 4
        LD      C,A             ; 5
        LD      A,H             ; 5
        LD      (PC),A          ; 13    -- 38 ^^ 85 тактов от первого LD (PC),A
        LD      A,(KNS_WR)      ; 13
        SUB     C               ; 4
        LD      B,A             ; 5     }} = 64                                 :: x8 = 480
WRBYTE3:POP     AF              ; 10    {{
        DEC     B               ; 5
        JP      P,WRBYTE3       ; 10    }} = 25 * KNS_WR : 25 * (KNS_WR - 14)   :: x8 = 200 * KNS_WR
        DEC     C               ; 5     {{
        JP      Z,WRBYTE1       ; 10    }} = 15                                 :: x8 = 120
        EX      HL,DE           ; 4     {{
        LD      SP,HL           ; 5
        LD      HL,VT_57+4      ; 10
        LD      (HL),0D0H       ; 11
        LD      (HL),76H        ; 11
        INC     HL              ; 5
        LD      (HL),23H        ; 77
        LD      (HL),49H        ; 11
        LD      A,27H           ; 7
        LD      (VG_75+1),A     ; 13
        LD      A,0E0H          ; 7
        LD      (VG_75+1),A     ; 13
        LD      L,8             ; 7
        LD      (HL),0A4H       ; 11
        POP     AF              ; 10
POPDBH: POP     DE              ; 10
        POP     BC              ; 10
        POP     HL              ; 10
        RET                     ; 10    }} = 176
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 92 bytes. Ticks: 275 + 133 + 25 x KNS_WR


Last edited by Paguo-86PK on 16 Feb 2020 19:53, edited 1 time in total.



16 Feb 2020 09:21
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 04:46
Posts: 467
Location: С-Петербург
Reply with quote
Post 
Paguo-86PK wrote:
Вылизaл код, как мог
Столь большие усилия ради того, чтобы выиграть два байта - совершенно напрасные.

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

 
Code:
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

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,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),low SA     ; 0D0H
        LD      (HL),high SA    ; 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
        POP     AF
POPREG: POP     BC
        POP     DE
        POP     HL
LD_BAK: RET

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

Первый байт выигрывается за счёт замены команды LD A,0 на команду XOR A или команду LD A,B. Второй байт выигрывается, если заметить, что регистр E свободен и в подпрограмме стоят почти подряд две команды LD A,(KNS_WR): вторая загрузка экономится, если после первой команды LD A,(KNS_WR) вставить команду LD E,A, а вместо второй загрузки поставить LD A,E, что два байта вместо трёх.

Во-вторых, ради эмулятора EMU от b2m мы вообще не можем двигать вход WRBYTE и байт RET по адресу FCA4. Т.о изменять на 2 байта длину подпрограммы WRBYTE мы вообще не можем. Потому я в этой подпрограмме не менял ни байта. Кстати, ещё 3 байта освобождаются просто переносом подпрограммы WR_HL на место сразу перед меткой WRBYTE.

А в третьих, имело смысл оптимизировать подпрограмму WRBYTE и LDBYTE иначе. А именно, - взять алгоритм этой подпрограммы из монитора-3 ОРИОНА, где она вдвое короче. Подпрограммы мониторов в Микроше и РК86 излишне усложнены (про Микро-80 я просто не знаю, т.к не разбирался). Возможно это необходимость из-за низкой тактовой частоты процессора и ВГ75. В алгоритме сдвига входного и выходного байта при вводе/выводе задержка для последнего бита байта оказывается иной, чем для других битов. Алгоритм РК это выравнивает, а в ОРИОНЕ это не делается и качество ввода там ничуть не менее надёжное.

И у меня есть вопрос к авторам ПЗУ РК86. Зачем при выводе каждого байта перепрограммировать ПДП? На что тратится куча тактов и байтов. Ведь по одному байту не читают. Читают блоками байтов. Если ввести флаг настройки видео, то при первом вводе/выводе байта ПДП стопорится, экран гаснет, а регенерация ОЗУ поддерживается периодическими POP-ами. После ввода/вывода блока делается CALL PUSK_VG и работа ВТ57+ВГ75 по отображению восстанавливается. На этом экономится ~50 байтов.

Ещё у меня есть вопрос к железячникам, тем, кто разбирался в возможностях 580 ВТ57. Можно ли организовать на время магнитофонного ввода/вывода регенерацию динамического ОЗУ с помощью ПДП (может быть другого канала)? Примерно так как это делалось в IBM PC XT в 1982 году. Но (чтобы сохранить более-менее равномерный темп прогона) сделать закачку не одной сплошной пачки в 128 байт (что требовалось для регенерации DRAM 4116), а 32-х (или более) пачек размером по 4 или менее (если возможно) байтов. Метод МГ-ввода без гашения экрана в РК86 (в многоблочных защищённых от копирования кооперативных играх) и режим работы с дискетой достигнут установкой длины пачки в 4 байта (в оригинале 8 байт).

И ещё теоретически возможен ввод/вывод с регенерацией не с помощью POP-ов, а с помощью команд загрузки из ОЗУ с косвенной адресацией LD A,(RR). Это при включении команд LD и INC RR в петлю паузы. Я считаю, что это вполне возможно, потому, что в ленинградском мониторе Специалиста с пользой используя эти же временные задержки за время ввода/вывода всего одного байта (и даже со скоростью передачи втрое больше, чем в РК) успевалось выводить на экран 4 HEX-цифры, на что явно уходило больше, чем всего 256 команд LD и INC.


Last edited by barsik on 16 Feb 2020 19:52, edited 2 times in total.



16 Feb 2020 19:10
Profile
Online
Senior
User avatar

Joined: 12 Apr 2011 21:43
Posts: 183
Location: Tashkent
Reply with quote
barsik wrote:
Столь большие усилия ради того, чтобы выиграть два байта - совершенно напрасные.
Дажe ради эксперимента? :no:
barsik wrote:
Во-первых, потому что два байта выигрываются совсем без усилий сразу же после первого взгляда на код.
Интересно было просто переписать всё в своём стиле…
barsik wrote:
Во-вторых, ради эмулятора EMU от b2m мы вообще не можем двигать вход WRBYTE и байт RET по адресу FCA4. Т.о изменять на 2 байта длину подпрограммы WRBYTE мы вообще не можем. Потому я в этой подпрограмме не менял ни байта. Кстати, ещё 3 байта освобождаются просто переносом подпрограммы WR_HL на место сразу перед меткой WRBYTE.
А через конфиги никак не настраиваемо?
barsik wrote:
И у меня есть вопрос к авторам ПЗУ РК86.
Всегда мучался этим вопросом :lol:

P.S.: Тем не менее, моя подпрограмма хорошо сбалансирована. Но я не знаю, является ли дисбаланс оригинала самой логикой задачи?


16 Feb 2020 19:43
Profile WWW
Doomed
User avatar

Joined: 19 Feb 2017 04:46
Posts: 467
Location: С-Петербург
Reply with quote
Post 
Paguo-86PK wrote:
на 2 байта короче
Ещё в МГ-подпрограммах в ПЗУ РК байты выигрываются за счёт смены порядка PUSH-POP-ов. В ПЗУ РК есть два типа PUSH-POP-ов - один традиционный порядок - PUSH HL, DE, BC и извращённый - PUSH HL, BC, DE. Соответственно в таком же порядке есть две цепочки POP-ов. Сравнив последовательность PUSH-POP-ов в вашем варианте WRBYTE и моём, Вы увидите, что исправив извращённый порядок следования PUSH-ей на традиционный, я выиграл три байта, т.к тогда один вход POPREG и цепочка POP-ов для восстановления регистров только одна.
Paguo-86PK wrote:
barsik wrote:
ради эмулятора EMU от b2m мы вообще не можем двигать вход WRBYTE и байт RET по адресу FCA4.
А через конфиги никак не настраиваемо?
Да, в конце конфига EMU как раз и задаются эти два (с учётом LDBYTE четыре) адреса. Но пользователи эмуляторов настолько ленивы и некомпетентны, что ругались, плевались и проклинали разработчика при попытке использовать в эмуляторах существенно улучшенные мониторы РК/Ориона/Специалиста, в которых эти абсолютно нестандартные точки, естественно, сдвинуты (что нормально, т.к это не стандартизовано и программам не вредит). Потому что те, кто пользовался 8-ми разрядками 30 лет назад и обладали полнотой информации и разбирались в теме, уже практически все вымерли, а из современных пользователей серъёзных, грамотных пользователей эмуляторов единицы.

Мне несложно подгонять любые внутренние точки в мониторах РК/Ориона/Специалиста под требования не только некорректных (к стандартам входных точек ПЗУ) программ, но и к эмуляторам. Это просто выгоднее и удобнее, чем при каждом изменении (которых обычно тысячи) редактировать конфиг. Возникнет неудобство и породится ненужная путаница, если для каждой версии ПЗУ надо иметь свой конфиг.

В EMU80 отлавливаются только входные точки LDBYTE/WRBYTE, а в EMU отлавливаются не только входные точки, но и адреса выходных RET-ов. Это потому, что в этих эмуляторах одинаковый принцип определения начала МГ-обмена, но по разному определяется конец МГ-обмена (в EMU - по точке выхода из п/п-рамм, а в EMU80 по CALL CONIN).
Paguo-86PK wrote:
метка в исходнике: WRBYTE2
Ассемблеры CP/M используют только 6 символов в имени метки (остальные символы в метке писать можно, но они игнорируются). Это потому, что (чтобы шаг был 8 байтов) в таблицы меток, переменных и констант ассемблер заносит 6 байтов имени и 2 байта значения, что экономит расход ОЗУ и резко ускоряет сканирование. Потому две метки с именами WRBYTE2 и WRBYTE3 в родных ассеблерах (т.е тех, что в кодах Z80/КР580) дадут ошибку: "Двойное определение метки". И если это не исправить, то придётся использовать убогие самодельные ассемблеры, что любители 8-ми разрядок понаделали для Windows (в них число значащих символов в именах может быть большим).

Кстати, длинные имена только загромождают исходник, почти ничего не улучшая. Вполне "говорящие" имена можно иметь и в 6 символов. К тому же никто не мешает любителю длинных имен применять имена в 15 символов, лишь надо следить, чтобы первые 6 символов были уникальными.

PS. Насчёт того, чтобы сделать ввод/вывод с магнитофона без гашения экрана стоит попробовать (только в реале) задать число байтов в пачке ПДП минимальное и попробовать читать писать МГ-подпрограммами от Микро-80, Специалиста или ОРИОНА, поставив для начала максимально большую константу. Можно также попробовать формат MSX из ленинградского монитора Специалиста, т.к в этом формате есть больше времени между фронтами (потому при вводе с ленты там возможны "чудеса" типа считающего до нуля графического счётчика или рисовка картинки прямо в экран Специалиста в виде, как это рисуется при вводе в экран ZX).


16 Feb 2020 20:26
Profile
Doomed
User avatar

Joined: 19 Feb 2017 04:46
Posts: 467
Location: С-Петербург
Reply with quote
Post 
Если делать альтернативное ПЗУ для РК86 никак не заморачиваясь идеологией оригинального ПЗУ РК86, то можно выиграть намного больше байтов. Я это делал, когда писал ROM-BIOS для компьютера с нормальным текстовым адаптером (без ВГ75). И у меня в ту же РФ2 в 2 кб без проблем влезли не только все п/п-ммы ввода/вывода, но и RAM-монитор с более качественными директивами и проблем нехватки места вообще не было.

Драйвер вывода на экран в ПЗУ РК86 написан нетрадиционно. Авторы, видимо с целью ускорения, старались избежать вычислений экранных координат при выводе символа, что делается в драйверах всех остальных 8-ми разрядных компьютеров. Потому в ПЗУ РК нет вот такой типовой процедуры:

Code:
EKRAN   EQU     76D0H +3*78 +8

; Вход: L - H-координата
;       H - V-координата
;       C - код символа

SCREEN: LD      A,L
        LD      B,H
        INC     B
        LD      HL,EKRAN-78
        LD      DE,78
LOOP:   ADD     HL,DE
        DEC     B
        JP      NZ,LOOP
        CALL    AADDHL
        LD      (HL),C
        RET

AADDHL: ADD     A,L
        LD      L,A
        RET     NC
        INC     H
        RET
.
Хранится не только традиционная экранная коодината в виде POSX и POSY, но и хранится и, главное, динамически меняется экранный адрес для вывода следующего символа. После каждого вывода делается не только POSX++, но и EK_ADR++. Где раб.ячейка EK_ADR (7600) это адрес в экране где находится курсор и куда должен вставляться очередной символ. За счёт этого отпадает длительная вышеприведённая процедура расчёта экранной позиции (вместо неё в общем случае одна команда INC HL). Это ускоряет вывод.

Значение EK_ADR в ПЗУ ставится только при CLS и никогда не рассчитывается. Зато, если хоть раз внаглую изменить ячейки EK_ADR, то весь последующий вывод исказится. Внаглую игры меняют ячейки EK_ADR, чтобы подпрограммами F809/F818 вывести что-то вне основного экрана 64*25.

Кстати, вышеприведённый код я использовал когда-то, но его можно оптимизировать. Нужна лишь быстрая процедура умножения на 78 (со сдвигами).


Last edited by barsik on 17 Feb 2020 08:40, edited 1 time in total.



17 Feb 2020 07:45
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 159 posts ]  Go to page Previous  1 ... 6, 7, 8, 9, 10, 11  Next

Who is online

Users browsing this forum: Paguo-86PK and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group
Designed by ST Software.