Использованне переменной #5D16
(С) Сергей Рюмик,
г.Чернигов, 1995.
В ZX-PEBI0-93, N1-2, на стр.23 ставился вопрос о назначении системной переменной TR-DOS #5D16 (23830), содержащей копию системного регистра. Важность этой переменной ощущается при работе с двумя дисководами. Имеется, ряд игровых программ, таких, как Mr.HELLI (дисковая версия Ап4у Chernikov, 1992), BUTCHER HILL (дисковая версия С.Скоробогатов, 1991), BACK ТО THE FUTURE-3 (дисковая версия А.Васильев, 1993) и т.д., в которых очередной уровень или блок кодов вводится только с дисковода "А".
Для системы TR-DOS подобные программы следует признать некорректными, так как TR-DOS допускает работу с четырьмя дисководами. Качественная дисковая версия должна загружаться до конца с любого дисковода.
Анализ "некорректных" программ позволяет сделать вывод о наличии хаккерских неточностей, а именно, небрежное отношение к системной переменной TR-DOS #5D16 и применение нестандартных точек входа в ПЗУ TR-DOS.
Система TR-DOS имеет регистр с адресом #FF (ZX-PEBD-94, N4, стр.10), который доступен как порт для записи и для чтения.
При записи кода в разряды DO и D1 порта #FF происходит выбор одного из четырех возможных дисководов: код 00 - "А", 01 - "В", 10 - "С", 11 - "D".
Копия содержимого системного регистра #FF заносится в ячейку #5D16 и используется системой TR-DOS для выполнения своих функций. Копия нужна, так как микроконтроллер на микросхеме 1818ВГ93 "не знает", с каким дисководом он работает в данный момент времени [1].
Аппаратно в контроллере дисковода не предусмотрена возможность чтения разрядов DO и D1 порта #FF.
При первом запуске TR-DOS обращение всегда передается на дисковод "А", в ячейку #5D16 операционная система заносит код #ЗС. При смене стороны дискеты код будет #2С, а при смене дисковода, например, на "В" - соответственно коды #3D или #2D и т.д.
Если в области системных переменных TR-DOS (#5СВ6 - #5D25) в процессе работы программист ничего не изменял, то программа, использующая стандартные точки входа в TR-DOS, будет гарантированно загружаться до конца с любого дисковода.
К основным программным точкам входа в TR-DOS в данном олучае следует отнести [1]: #3D00 (15616), #3D03 (15619), #3D21 (15649), #3D13 (15635). Иногда вместо #3D13 используют #3D14 (15636).
"Некорректные" программы довольно грубо вторгаются в область системных переменных; преследуя, очевидно, следующие цели: защита от копирования MAGIC-кнопкой, создание собственной системной области с заданными параметрами, использование системной области как части ОЗУ.
Например, в программе OPERATION THUNDERBOLT (disked by LAPTEV) сначала обнуляется область памяти от #4000 до #F000, затем заносятся четыре константы в самые важные точки системной области: #5СЗА - #FF, #5СС2 - #С9, #5СС8 -#83, #5D0C - #FF. И все! Для загрузки информации с очередных секторов диска через подпрограмму TR-DOS CALL #3D14 при С=5, этого вполне достаточно, но в ячейке #5D16 уже находится число #00 (разряды D0 и D1 содержат "нули4'), что определяет обращение только к дисководу "А".
Другой пример. Игра R-TYPE (disked by Andy Chernikov). При работе программы в область системных переменных TR-DOS, начиная с адреса #5СВ6, транслируется заранее подготовленная область переменных (112 байт), расположенная по адресам #5F7F - #5FEF. Далее происходит чтение секторов диска, но все это только с дисковода "А", так как в ячейке #5FDF, которая при трансляции переносится в ячейку #5D16, содержится код #зс.
В программе ASTRO MARINE CORPS (АМС-128, disked by ZYX SOFTWARE - Екатеринбург, 1993) кодовый блок содержит фрагмент непосредственного программирования микроконтроллера 1818ВГ93 (листинг 1 на следующей странице).
Подпрограмма TR-DOS #3D2F (15663) содержит две команды: НОР и RET, а подпрограмма #2А53 (10835) содержит две команды: OUT (С),А и RET.
Следовательно, в листинге 1 происходит непосредственное занесение в системный порт #FF кода, определяемого содержимым регистра А в строке #5D91. "Маски", накладываемые на .регистр А, однозначно определяют ввод данных с дисковода "А", так как числа #2С и #ЗС содержат в разрядах DO и D1 -"нули".
Еще один характерный случай встретился в программе ALIENS-128 (disked by ZAYATS & ED - Киев, 1992). В кодовом блоке было обнаружено обращение к нестандартной программе TR-DOS #2F45. После чего, очередной блок секторов диска считывался только с дисковода "А".
Оказалось, что внутри подпрограммы #2F45 в самом ПЗУ TR-DOS версии 5.03 есть переход в точку #2F4B, содержащую команды LD А,#2С и OUT (#FF),А. Значит, опять имеет место непосредственное программирование микроконтроллера, но уже с использованием внутренней подпрограммы ПЗУ, определяющей дальнейшую работу только с дисководом "А".
Рекомендации для пользователей.
его самостоятельно. Например, для игры АМС-128 (листинг 1) достаточно изменить при помощи DISK-DOCTOR следующие 16 байт в первом секторе BASIC-блока, считая, что первый байт в этом секторе имеет адрес #5D3B. По адресам #5DF7-#5P04: #21, #16, #5D, #7Е, #Е6, #03, #21, #F2, #9С, #В6, #77, #СЗ, #40, #9С; по адресам #5Е1В, #5Е1С: #F7, #5D.
Принцип коррекции заключается в переносе содержимого разрядов DO и D1 системной переменной #5D16 в разряды DO и D1 "маски" аккумулятора А ячейки #5D92 (листинг 1).
3. Далеко не все "некорректные" программы можно исправить так просто, обычно обращений к дисководу несколько и они разбросаны в самых разных местах программы. Кроме того, пройдя, например, несколько десятков циклических защит, не всегда можно быстро разобраться в логике дальнейшей работы программы. В некоторых случаях проще сделать собственную версию дисковой программы из кассетной, чем глубоко вскрывать чужую.
Рекомендации для программистов.
1. Если в программе по каким-то причинам будет изменяться область системных переменных
TR-DOS, то сохраните где-нибудь в ОЗУ копию переменной #5D16. Перед очередным вызовом функций системы TR-DOS, обязательно восстановите это значение или, по крайней мере, содержимое разрядов DO и D1*
СЕКРЕТЫ TR-DOS
Листинг 1.
5D8E |
F6 |
EF |
|
OR |
#EF |
; "Маска": A=#EF или A=#FF. |
5D90 |
2F |
|
|
CPL |
< |
; Инверсия A. |
5D91 |
F6 |
2С |
|
OR |
#2C |
; "Маска": A«#2C или A=#3C. |
5D93 |
0Е |
FF |
|
LD |
C, #FF |
; Адрес порта #FF (TR-DOS). |
5D95 |
DD |
21 |
53 2А |
LD |
IX,#2A53 |
; Точка входа в п/п TR-DOS. |
5D99 |
CD |
DA |
5D |
CALL |
#5DDA |
; П/п перехода в ПЗУ TR-DOS |
5DDA |
DD |
Е5 |
|
PUSH |
IX |
; |
|
СЗ |
2F |
3D |
OP |
#3D2F |
; |
2 При непосредственном программировании микроконтроллера 1818ВГ93 используйте ранее запомненное значение переменной #5D16 для изменения разрядов DO и D1 аккумулятора А Например, для листинга 1 изменению подлежит код "маски" #2С в ячейке #5D92.
3 Применяя нестандартные точки входа в TR-DOS, проверьте, не захватят ли они фрагменты ПЗУ, содержащие команду OUT (#FF),A. В зависимости от содержимого аккумулятора А это может привести к смене дисковода. Для TR-DOS версий 5 01, 5.03 (и выше) таких "опасных" точек - десять (табл.1)
4 Проверьте созданные Вами ранее программные продукты на возможность ввода с любого дисковода от "А" до "Д".
Если простыми путями нельзя сделать программу универсальной для всех дисководов, то предупредите об этом пользователя. К примеру, в игре STRIDER-2 (версия Andy Chernikov, 1992) перед вводом очередного уровня хаккер напоминает* "INSERT DISK IN DRIVE A" .