ZX Format #04
14 июня 1996
  TR-DOS  

Программистам - Адаптация программ под TR-DOS #2.

         Адаптация #2.

(C) Ржавельщик.
________________________________

   Публикуем продолжение саги об
адаптации (см. ZX-Format #3).
        ________________

   Итак,  продолжим. Использовав
материалы первой серии, Вы имели
возможность  научиться адаптиро-
вать на диск беззащитные и защи-
щенные программы, имеющие тради-
ционную  организацию  (т.е. заг-
рузчик,  работающий до победного
конца и тело, с которым он рабо-
тает).   Последний  комментарий:
упоминание  того, что TR-DOS не-
долюбливает  INT  MODE  2, имело
своей  целью прозрачно намекнуть
Вам,  что во избежание трагичес-
кого непонимания между Вашим мо-
нолоадером  и  DOS'ом  стоит  до
окончания  загрузки  сделать IM1
(конечно если Вы используете для
загрузки процедуры самой DOS).
   Теперь мы покидаем мир здоро-
вых и полноценных программ,чтобы
заглянуть  в  Tomb of mutilated,
где  покоятся  неудачливые прог-
раммы,    изнасилованные   всеми
"мултифейсами"   и  искалеченные
хакерами тех мест,что лежат меж-
ду  нашей страной и производите-
лями   этих  программ.  Наиболее
распостраненная клиническая кар-
тина  выглядит  так:  у  клиента
имеется   один  маленький  такой
LOAD'ер  и  одно монолитное тело
(малость побольше), которое гру-
зится  непрерывно  и  от  начала
RAM.  Т.е.  начиная с заставки и
почти  до  конца памяти. Я пола-
гаю,  что  многие,  следуя моему
инструктажу,   жестоко  изорвали
сие  тело  на  две - три части и
смели  останки  на диск (кстати,
поздравляю  тех,  кто  догадался
переписать  DISMEMBER '& ->MACTER
на свой рабочий диск, обнаружив,
что из журнала они не запускают-
ся).
   После  проведения этой опера-
ции  требуется сшить куски файла
в  один  целый, оставив заставку
отдельно. Сделать это можно, до-
пустим, так: записать подряд все
части   в  их  исходном  порядке
(так,  как  они  шли  в файле на
ленте),  затем войти в доктор и,
выискав заголовок первого куска,
торжественно присвоить ему длину
в  секторах,  равную  длине всех
кусков. Полезно также скорректи-
ровать его размер в байтах. Дабы
не  утруждаться сложением, длину
в секторах можно узнать, пометив
все  сшиваемые  файлы в каталоге
(CONVER и другие commander'ы по-
казывают  количество  отмеченных
секторов). Произведя сие неслож-
ное  действо,  лучше  переписать
новый  файл  на рабочий диск (на
тот же) и стереть то, из чего он
был  получен  (чтобы не путалось
под  руками);  перезапись  можно
осушествлять boot'ом,который по-
нимает  длину в секторах (CONVER
нужно  переключать, а свой режим
он  не  показывает). Полученному
таким образом файлу следует при-
своить адрес загрузки #5b00 (ес-
ли  игра имела означенную клини-
ку).  Подготовительная  фаза за-
кончена.
   После   проделаной  опции  Вы
сравнялись с владельцами ZS-256,
которые   скинули  программу  на
диск  из  своего монитора. А вот
теперь начинается самое интерес-
ное - создание LOAD'ера. Напоми-
наю,  что  должен делать загруз-
чик:
   1.  Поместить программу в па-
мять на нужные адреса.
   2. Выполнить запуск.

   Начнем  с  запуска. Что нужно
для запуска программы? Как мини-
мум нужно знать стартовый адрес.
Для проведения дознания обратим-
ся к ленточному LOAD'еру.

   1. Работающие коды.
   Здесь  имеется нормальный ко-
довый загрузчик, который при за-
пуске  переносится в самые стар-
шие  адреса, которые не накрыва-
ются  программой при загрузке. В
ту же область помещается и стек.
О  подобном  уже  было сказано в
первой  серии. Возможен вариант,
когда  только стек переносится в
ненакрываемую зону, а коды оста-
ются  там,  где  стояли. В таком
случае запуск программы происхо-
дит  через  стек  (делается PUSH
стартового  адреса и JP в проце-
дуру загрузки ПЗУ). В обоих слу-
чаях  загрузчик содержит искомый
адрес в явном виде.

   2.  Запуск  через  измененный
стек.
   Кодовый   загрузчик  вызывает
любым способом процедуру загруз-
ки из ПЗУ, но стек при этом име-
ет такой адрес, что по ходу заг-
рузки файл игры на него наедет и
переедет.  При этом в стеке ока-
жется  требуемый адрес, по кото-
рому  произойдет возврат из ПЗУ.
Для  того, чтобы найти стартовый
адрес  Вам  нужно  узнать  адрес
стека. Если он не устанавливает-
ся  лоадером, то это значит, что
он  имеет  стандартное значение,
которое Вы можете узнать из сис-
темной   переменной   по  адресу
23730.  Узнав адрес стека, кото-
рый имеет место во время загруз-
ки  программы,  запишите  его  в
протокол.  Далее владельцы скор-
пов  загружают  файл через мони-
тор,  владельцы  128-х и более -
грузят сшитый файл в STS и, пока
счастливые  юзеры 48к едут поку-
пать ADM_2.7, смотрят содержимое
файла  по вышеупомянутому адресу
стека.(Те,  кто  уже  имеет ADM,
могут сделать то же самое, отмо-
тав  курсор к этому адресу вруч-
ную.  Физический адрес отобража-
ется  в левой нижней части экра-
на).
   Данный адрес содержит то, что
мы  и искали - адрес точки входа
в программу. Последний раз напо-
минаю, что хакеру голова дана не
для  того,  чтобы ей есть, а для
того, чтобы думать. Так что если
в  означенном  месте  Вы нашли 0
(итп)  то это значит, что искали
не  там (намек: посмотрите в ок-
рестности  SP).  В  любом случае
адрес  следует проверить на дос-
товерность,  т.е.  посмотреть по
нему  содержимое файла. Если ад-
рес  указывает на таблицу преры-
вания  или  на  спрайт, то стоит
подвергнуть  сомнению его истин-
ность.

   3. Бейсик.
   Иногда  встречаются  BASIC  -
лоадеры, аналогично использующие
запуск  по  измененному  SP. Они
выглядят примерно так:

 0 CLEAR 30000:LOAD""CODE

   В  таком  случае  адрес входа
ищется как и в пункте 2.
   Второй  распостраненный вари-
ант:  грузящийся  файл  содержит
новый бейсик (естественно он со-
держит  и  системные переменные,
нужные  для  работы  BASIC'а). В
таком  случае  Вам следует найти
адрес  команды  LOAD  в исходном
загрузчике  (ADM'ом либо STS'ом,
помня,  что  с ленты бейсик гру-
зится  по адресу 23755 (#5CCB)).
Записав  адрес LOAD, грузим файл
и смотрим, что находится за ним.
Скорее  всего  там будет команда
RANDOMIZE USR ... (#F9 #C0 ...).
Как  просматривать бейсик по ко-
дам, я уже где-то объяснял и по-
лагаю, что Вам не составит труда
узнать    стартовый   адрес   из
BASIC'a.
   Последний вариант (из области
дурной фантастики): лоадер пере-
устанавливает  переменную ERR_SP
(23613)  так,  что  по окончании
загрузки  машина, наткнувшись на
кодовый мусор, не печатает "Non-
sense  in  basic ", а производит
запуск  игры  (честно  говоря, я
такого изврата никогда не встре-
чал).

   Итак, стартовый адрес найден.
Осталась  сущая  мелочь - загру-
зить файл игры из TR-DOS. Тут-то
и  возникнет  проблема: файл ма-
лость длинноват. Прежде чем сно-
ва  рвать  его  на  части, стоит
внимательно   рассмотреть   ВЕСЬ
файл на предмет сокращения объе-
ма. Начинаем с области загрузчи-
ка.  Если клиент грузился накры-
ваемым бейсиком, то его коды на-
чинаются  не  с конца экрана, а,
как  минимум,  с  конца бейсика.
Следовательно всю часть от #5b00
и до начала кодов самой програм-
мы  можно  опустить. Далее стоит
посмотреть  на  старшие  адреса,
начиная  примерно от #E000. Если
с  некотрого  адреса  там пойдут
нули, то, проверив - не является
ли сие место спрайтом, его можно
отбрасывать.  Проверку  на кхм..
спрайтовость   можно  произвести
при  помощи  программы  FDE либо
SCE  (по-моему FDE намного удоб-
нее).   Оканчивается  файл,  как
правило,  следами  использования
стека, на которые можно не обра-
щать  внимание,  т.к. при старте
программа сама ставит SP куда ей
нужно. Даже если очевидного кон-
ца кодов не найдется, вниматель-
но  разберите все процедуры, ко-
торые  Вы  найдете на этих адре-
сах. Если программа имеет упомя-
нутую клинику, то там может най-
тись  программка, при помощи ко-
торой  игра была приведена к та-
кому виду. При нахождении подоб-
ной  подпрограммки можете отбро-
сить  все, начиная с нее, однако
тщательно   проверьте  стартовый
адрес  -  он может оказаться ма-
лость лажовым.
   Из практики: Игра TLL, в слу-
чае  урезания  этой самой проце-
дурки,  выходила в начальное ме-
ню,  но при выборе "START" сбра-
сывалась.  При внимательном рас-
смотрении  оказалось,  что обра-
ботка IM2 начиналась у нее с ад-
реса #FFFF, где в исходном файле
стояло #18 (JR). При старте игры
по адресу, выкопанному из бейси-
ка,  она не устанавливала преры-
вания. Настоящая процедура стар-
та  делала настройку на прерыва-
ния,  и после переходила (JP) по
этому адресу.
#   Кстати, "урезание" файла сво-
дится  просто  к  опции "SAVE" с
нужного адреса, если у Вас прод-
винутый SPECCY, а если Вы имеете
48-й,  то  придется  прибегать к
долгим манипуляциям на ленте.

   После всех манипуляций Вы за-
имели сильно сократившийся файл,
который  можно  грузить и запус-
кать. Для наведения блеска стоит
этот  файл скомпрессовать. Очень
удобен  и  эффективен  для этого
дела  LPC. Самый тяжелый случай:
все  данные,  от #5B00 до #FFFF,
являют  собой  полезную информа-
цию,  которая не подлежит сокра-
щению  (либо Вам ну очень лениво
разбираться). Тогда можно посту-
пить  так:  отрезаем  от  начала
файла  кусок длиной 1704 (#6A8);
остаток  со страшной силой комп-
рессуем; грузим заставку; грузим
упакованную  часть, развертываем
ее;  гасим экран; грузим кусочек
1704 в экранную область; перено-
сим остаток лоадера туда же, (на
свободное   место,  естественно)
делаем  переход  в  него, ставим
нужный SP и переносим отрезанные
байты  на их родное место, после
чего выполняем запуск программы.
Длинная  часть файла будет начи-
наться с 25000,что позволит сде-
лать  всю  загрузку  из BASIC'а,
написав коды только для переноса
и запуска. Не забудьте перенести
эту  процедурку в экран, так как
при  помещении отрезанных байтов
загрузчик будет накрыт и не смо-
жет запустить программу.

   Теперь  рассмотрим  какую-ни-
будь гадость, например такую:
   Игра  имеет  файлы приличного
размера, но подозрительно похожа
на кинутую MAGIC'ом (пачкает эк-
ран  и после загрузки делает POP
всех регистров из "грязи"). Фай-
лы  такой  игры  содержат  массу
"излишеств",   выкинув   которые
можно  сильно выиграть в объеме.
Также  сие  явление  имеет левый
адрес  запуска. По поводу лишних
байтов  ничего  конкретного ска-
зать  нельзя,  так как они будут
заполнены не нулями. Стоит поис-
кать рабочую область (буферную),
теневой  экран (/окно) и систем-
ные переменные BASIC'а. Со стар-
товым  адресом  немного попроще:
прежде   всего   нужно  смотреть
настройку  IM2.  Найдя процедуры
настройки,  нужно  искать ссылки
на них, а так же куда идет прог-
рамма после их выполнения. Можно
с  уверенностью  утверждать, что
если   Вы   нашли  подпрограммку
настройки прерываний, кончающую-
ся  на  JP,  на которую никто не
ссылается,  то  это и есть точка
входа. Точка старта может выгля-
деть и как серия CALL, среди ко-
торых  есть и настройка прерыва-
ний. Если игра не использует IM2
(>;->), то найдите процедуру пе-
чати начального меню и проследи-
те путь к ней. Т.е. в любом слу-
чае  нужно  найти первое звено в
цепочке   CALL'ов.  Найдя  точку
входа,   можно  сразу  отбросить
"мусор"  с  данными  о состоянии
регистров, которым портится зас-
тавка. Выбросив все лишнее, мож-
но  писать лоадер по Вашему при-
вычному  образцу, на чем адапта-
ция вообщем-то и заканчивается.
        ________________

   Ну вот, пожалуй по части соб-
ственно  адаптации  программ  на
диск  сказать  больше  и нечего.
Подводя общий итог, скажу только
одно: ассемблер, ассемблер и еще
раз ассемблер.

   P.S. Не могу не добавить пару
слов  о software - хотя я и имею
ZS-256,  я  все  равно пользуюсь
STS'ом,  который во многих отно-
шениях удобней scorp'ового тене-
вика.  Ну и раз уж начал, то и о
железе  замечу:  Владельцы 48-х!
Если Вы умеете работать паяльни-
ком,  то  довесить памяти до 128
обойдется Вам максимум в 15 тонн
и  часа  два простенькой работы,
зато Вы получите в свое распоря-
жение  такую  мощную систему как
STS и TASM!




Темы: Игры, Программное обеспечение, Пресса, Аппаратное обеспечение, Сеть, Демосцена, Люди, Программирование

Похожие статьи:
Реклама - Если Вам необходима pеклама в нашем издании, то звоните.
От авторов - Редакция.
Анкета - Я заполню анкету, чтобы показать как ею пользоваться.

В этот день...   23 октября