Из журнала ZX Format #3, Санкт-Петербург, 03.1996 АДАПТАЦИЯ ПРОГРАММ НА ДИСК ДЛЯ НАЧИНАЮЩИХ. (C) Аксенов А.М. 1996 ________________________________ Небольшое предисловие. Данная работа состоит из двух частей. В первой части речь пой- дет о дискетировании самых прос- тых программ. Во второй части я попытаюсь осветить некоторые сложные случаи и расскажу о 128 играх. Кроме того, в дополнение к "Адаптации Программ...", в разделе ПРОГРАММИСТАМ есть еще две статьи - о закрытых кодах и о том,как сделаться бессмертным. ________________ Часть Первая ____ Адаптация программ с бейсиковским загрузчиком. Я полагаю, что читатель имеет некоторое представление о бейси- ке, поэтому, если некоторые со- четания латинских букв в тексте Вам покажутся незнакомыми, - от- ложите эту статейку и потруди- тесь почитать руководство по программированию. Для движения по пути наименьшего сопротивле- ния я очень рекомендую Вам при- обрести любой копировщик лента - диск, например, P.Copier либо L-COPY и программу типа DISK DOCTOR (все это можно купить в LOGROS'е, а что касается "докто- ра", - советую использовать con- ver commander). Если у Вас нет ничего из вышеперечисленного, не беда, можно обойтись и без это- го. Как Вы, наверное, замечали, практически все большие програм- мы состоят из нескольких от- дельных частей. Первая - сравни- тельно маленькая, всегда имеющая вид basic-файла - загрузчик. Да- лее может идти файл, содержащий заставку, либо сразу коды прог- раммы. Кодовых файлов может быть несколько. Все кодовые файлы необходимо переписать на диск. Для удобства работы перепишите туда и загруз- чик. Если Вы имеете специальный копировщик,то данная операция не вызовет проблем. Если же копи- ровщика нет, то перезапись можно осуществить так: 1.грузите ленточный копировщик. 2.загружаете адаптируемую про- грамму в копировщик. 3.записываете в тетрадь длины и адреса загрузки ("стартовые ад- реса") каждого файла. Нужно отметить, что адрес за- грузки содержится в заголовке файла, там же где и название. Если файл не имеет заголовка то возникает небольшая проблема с записью на диск и большая с пе- ределкой загрузчика - "безголо- вый" файл всегда означает, что загрузчик написан в кодах. Если все в порядке, то далее произведите следущие действия: отмотайте пленку к началу файла; введите LOAD"name"CODE (name - имя файла, который Вы переписы- ваете). Напоминаю, что ввод строки должен завершаться нажа- тием на "enter". Запустите плен- ку. Если Вы получили сообщение ОК то далее введите RANDOMIZE USR 15619: REM: SAVE"name"CODE start,len start - стартовый адрес; len - длина файла. Если файл является заставкой и при загрузке выво- дится на экран, то скопируйте его при помощи такой программки: 10 CLEAR 25000:LOAD"name"SCREEN$ 20 RANDOMIZE USR 15619: REM: SAVE"name"CODE 16384,6912 Следует отметить, что имя не должно быть длиннее 8 символов, а работать лучше в BASIC-48. Ес- ли Вам удалось скопировать все файлы программы (можете считать что Вам крупно повезло), то нас- тало время заняться загрузчиком (какие могут возникнуть пробле- мы, я опишу далее). Попробуйте загрузить загрузчик командой MERGE"". Здесь возможно нес- колько вариантов, например, ком- пьютер сбросится или зависнет. А может и сказать "ОК". Если пос- леднего не произошло, то сделай- те так: введите LOAD""; загрузи- те загрузчик и остановите магни- тофон; после этого нажмите BREAK. Если при этом компьютер не повиснет и не сбросится, то, возможно, Вы увидите листинг программы, который будет выгля- деть примерно так: 10 BORDER 0:PAPER 0:INK 7:CLEAR 24999:LOAD"name1"CODE 20 LOAD"name2"CODE 30 RANDOMIZE USR 55000 Здесь следует обратить внима- ние на команды, относящиеся к загрузке, т.е. LOAD "..." При работе с лентой загрузку произ- водит программа, находящаяся в ПЗУ, обращение к которой проис- ходит по команде LOAD. Для рабо- ты с диском требуется программа, находящаяся в другой части ПЗУ. Переход туда производится по ко- манде RANDOMIZE USR 15616. Для того, чтобы после перехода в часть ПЗУ TR-DOS сразу выполня- лась команда, следует применить комбинацию вида: RANDOMIZE USR 15619: REM:..., где после REM стоит требуемая команда (например, load). Таким образом, чтобы вышеприведенный загрузчик работал с диском, его следует переделать так: 10 BORDER 0:PAPER 0:INK7:CLEAR 24999:RANDOMIZE USR 15619: REM:LOAD"name1"CODE 20 RANDOMIZE USR 15619:REM: LOAD"name2"CODE 30 RANDOMIZE USR 55000 После чего следует выйти в TR-DOS (RANDOMIZE USR 15616) и ввести SAVE"name"LINE 10. Важно помнить, что при обращении к диску после REM: может стоять только ОДНА команда, которая должна быть последней в строке, иначе программа будет работать неправильно. Если все указанные действия удалось осуществить без затруд- нений, то работа окончена и Вы можете смело запускать игру с диска. Теперь - проблемы, которые могут возникуть. Вам не удалось получить ос- мысленный листинг программы.Ес- ли это произошло из-за того, что программа не грузится по команде MERGE"" или сбрасывается по BREAK, то можно попробовать сде- лать так: введите заголовок от длинной программы, поменяйте кассету и загрузите ту часть загрузчика, что идет после его заголовка (говоря проще, - под- мените заголовок на заголовок от более длинной программы). Если Вы не имеете более длинной прог- раммы, сделайте ее сами - напри- мер наберите десяток строк типа: 10 PRINT " (здесь набейте много пробелов)" и отгрузите эту программу на ленту командой SAVE"name". По окончании загрузки компью- тер выдаст "tape loading error". Не пугайтесь, так и должно быть. После этого можно попытаться просмотреть листинг. Как прави- ло, если приходится прибегать к таким суровым мерам, то листинг будет, в лучшем случае, трудно- читаемым. Поробуйте ввести LIST. Возможно что после этого Вы не увидите текста, но обязательно получите какое-нибудь сообщение- например "ОК" или "invalid color". Затем попробуйте ввести LIST 1, или LIST (любой номер больше чем у первой строки). Возможно, что Вы увидете нор- мальный листинг. Если виден ос- мысленный текст, то можно спо- койно переделывать его для рабо- ты с диском. Если от любой строки виден только номер, а за ним - пусто- та, либо строка, в которой не видно символов, то это скорее всего означает, что в тексте есть "управляющие символы", т.е. цифры, определяющие параметры печати текста на экране (напри- мер - цвета чернил и бумаги). Естественно, если текст выводит- ся чернилами цвета бумаги, то его невозможно прочесть. Вызови- те строку на редактирование. Ес- ли при этом машина будет задум- чиво гудеть, то введите POKE 23608,1. Вызвав строку, можно попытаться стереть эти коварные коды, как простой символ в стро- ке. Для этого включите звук громче и двигайте курсор, прис- лушиваясь к щелчкам. Когда про- исходит "наезд" на управляющий символ, курсор не двигается по экрану пока код не будет прой- ден, однако при каждом нажатии на курсорную клавишу слышен щел- чок (при этом происходит измене- ние адреса, на который указывает курсор). Итак, найдя код, сде- лайте два "щелчка" за него и после этого жмите DELETE. Затерев код, Вы можете уви- деть текст, а можете и не уви- деть, так как кодов обычно ста- вится много и стереть необходимо все. Есть несколько более простых способов получить осмысленный листинг. Простейший: перепишите заг- рузчик на диск, запустите disk doctor и введите команду open file. Обычно сия команда отдает- ся нажатием кнопочки "O". Ес- тественно, что при запросе имени файла нужно ввести то имя, под которым Вы переписывали загруз- чик. Тип файла - B (basic). От- крыв файл, введите команду "B". Как правило, в ответ доктор вы- дает Вам листинг, который имеет смысл. Перепишите его в свой "протокол вскрытия". Если в лис- тинге за любым числом стоит чис- ло в скобках (некоторые доктора выделяют это число еще и цве- том), то переписывайте содержи- мое этих скобок. В качестве при- мера возьмем такую строку: 30 CLEAR 0(24499):POKE 23874 (23874),0(0):LOAD"sw.1"CODE 50000(16384):RANDOMIZE USR 60000(16384) В Вашем протоколе должно быть записано: 30 CLEAR 24499:POKE 23874,0:LOAD "sw.1"CODE 16384:RANDOMIZE USR 16384 Другой способ: используйте copy-copy или любой подобный ко- пировщик. Загрузите загрузчик в него, сотрите управляющие коды и отгрузите программу обратно на ленту. Для подобной операции по- лезно знать, что строка имеет следующее строение: NN.LL._______.13. здесь NN - два байта, составляю- щие номер строки; LL - два байта длины строки; ____ - собственно содержимое строки и число 13 (#0D) - символ конца строки (enter). Управляющие коды: 7 - "," 8 - Backspace 16 - ink 17 - paper 18 - flash 19 - bright 20 - inverse 21 - over 22 - AT 23 - TAB К слову: и при помощи докто- ра, и при помощи copy-copy можно просмотреть текст программы по кодам команд, но здесь придется немного поднапрячь мозги, так как необходимо различать - какой код является командой, а какой просто совпадает по значению с оной. Для этого полезно помнить структуру строки и одну тон- кость, которая касается пред- ставления числа в бейсике. Напо- минаю, в чем соль: если число в строке указано таким образом: CLEAR VAL"24999", то это значит, что оператор CLEAR выполняется по 24999, но если Вы видите, на- пример, CLEAR 24999, то это сов- сем не означает, что и в данном случае оператор имеет аргумент 24999. Когда число стоит без оператора VAL его коды выглядят так: _____.#0E._____. здесь первые несколько байт - это коды символьной формы числа (т.е. того, что Вы видите на эк- ране); #0E = десятичное 14 - префикс, разделяющий символьную форму и пять байт цифрового зна- чения; последние 5 байт опреде- ляют истинное значение числа. Третий и четвертый байты после префикса задают модуль числа. Можно точно сказать, что если при таком просмотре не обнару- жится ни одного LOAD, то загруз- чик реализован в кодах. О кодо- вых загрузчиках я расскажу поз- же. Сейчас переходим к проблемам копирования файлов на диск. Та- ких проблем, пожалуй, всего три: очень длинный файл, неверный байт четности и плохой стартовый адрес (при ручном копировании). Последнее выражается в том, что после загрузки файла машина вис- нет или сбрасывается. Избежать этого очень просто - достаточно загружать файл по LOAD"name" CODE adr, предварительно выпол- нив CLEAR "adr-1", где adr - ад- рес загрузки. Адрес можно брать не меньше 24400, иначе машина будет отлынивать от работы всеми доступными ей средствами. При этом файлу может оказаться мало- вато места, - возникает проблема номер один - слишком длинный файл. Случай с неверным байтом чет- ности выражается в том, что при попытке использовать готовый ко- пировщик лента-диск по окончании загрузки Вы получаете сообщение типа load error, но при этом программа нормально работает с ленты. Если программа не работа- ет и с ленты, это значит, что там просто плохая запись. С этим можно бороться только аппаратны- ми методами. Запись с плохим байтом чет- ности применялась почти на всех кассетах студии "МАСТЕР". Обойти эту проблему можно, переписав программу на ленте копировщиком TF-Copy 2 (если все файлы имеют заголовки) либо OMNY COPY, или использовать копировщик лента - диск TD-COPY. Этот копировщик позволяет не обращать внимания на ошибки, но делает файлы, ко- торые медленно грузятся. Послед- нее средство - перезапись вруч- ную, с подменой заголовка. Заго- ловок делается так: наберите SAVE "name" CODE 1,65535 и запи- шите только сам заголовок. Имя может быть любым, а при загрузке файла рекомендую делать таким образом: набрать CLEAR 24499, далее - LOAD "name" CODE 24500, по окончании загрузки Вы увидите "tape loading error", после чего набирайте RANDOMIZE USR 15619: REM: SAVE "name"CODE 24500,len len - длина, которую Вы, конеч- но, не забыли записать в прото- кол. Кстати, иногда так можно копировать и безголовые файлы. Специально для тех, кому ле- ниво прибегать к вышеописанному способу, в ПРИЛОЖЕНИЕ включена моя программка, которая может немного облегчить перезапись не- удобных файлов. Называется она "->МАСТЕР" и может следующее: 1. переписать в нормальном виде файлы с затерянной четностью (и- ногда не слишком хорошая запись работает, но не идет в копиров- щик) 2. переписать файлы с кассет студии МАСТЕР (тех, на которых сделана первая попытка защиты от копирования, которая мешает пе- реписать их копировщиком лента-- диск) 3. пришить заголовки к безголо- вым файлам (все файлы будут иметь тип "C") Программка работает с единич- ной порцией информации, т.е. загрузив любой фрагмент, Вам нужно будет записать его. Пишет она, естественно, только на лен- ту. Управление очень простое - сначала нужно определить режим работы, а далее - просто нажи- мать на "enter", не забывая пе- реставлять кассеты. Для синтеза заголовков на вопрос HEADERLESS? ответить "Y", если подшивать за- головки не нужно, то "N". При работе с "защищенными" кассетами на второй вопрос ответить "Y". В последнем случае будет срезаться лишний байт (последний), который и вносит ошибку в работу копи- ровщика. Предупреждаю, что сие произ- ведение было написано примерно за 40 минут, считая время отлад- ки, так что если оно будет да- вать глюки, - прошу не ругаться. Зато на этой программке можно потренироваться стирать управля- ющие коды. Переходим к главной загвоздке - длинным файлам. Прежде всего - почему вообще возникает такой вопрос? Здесь дело в том, что системе TR-DOS требуется некото- рый объем памяти для ее систем- ных переменных и примерно 256 байт для оперативных нужд. Ввиду этого при инициализации TR-DOS происходит изменение адреса на- чала пользовательской памяти. До инициализации память бейсика на- чинается с 23755, после - с 23867. Что можно сделать, если у Вас нет особого копировщика, позволяющего переписывать файлы любой длины? Ответ один - рас- членить его на короткие куски. Есть много разных методов разде- ления файлов на части, но пос- кольку я решил говорить о пути наименьшего сопротивления, при- вожу только два: 1.с разделением на ленте. 2.для счастливых обладателей Scorpion, - отгрузка по час- тям на диск из монитора. Действуя по первому методу, необходимо воспользоваться еще одной моей программкой из прило- жения. Она имеет страшное назва- ние DISMEMBER и может отрезать от чрезмерно длинного файла ку- сок длиной в один экран (с нача- ла файла). Для тех, кто понимает ас- семблер, привожу текст кодовой части: LFFD7 DI LD IX,#24FF LD DE,#FFFF SCF CALL #0556 LFFE3 LD A,#7F IN A,(#FE) BIT 0,A JR NZ,LFFE3 LD DE,#C000 ADD IX,DE PUSH IX POP DE LD IX,#4000 LD A,#FF CALL #04C2 JR LFFD7 Порядок операций: Поставьте пленку в начало опери- руемого файла (!если файл име- ет заголовок, то его (заголовок) следует пропустить и поставить на начало тела файла), загрузите расчленитель и запустите пленку. По окончании загрузки переставь- те пленку,нажмите на магнитофоне запись и "space" на клавиатуре. По окончании этой стадии Вы по- лучите безголовый файл типа "C". Далее следует пришить к нему за- головок (если будете копировать его вручную) и осуществить тор- жественный перенос урезанного файла на диск. Затем, если у ис- ходного файла не имелось заго- ловка, ему следует его пришить и переписать отрезанную часть. Это можно сделать так: LOAD""CODE 40000,6912 По окончании загрузки будет выдано "tape loading error"; да- лее следует ввести RANDOMIZE USR 15619: REM: SAVE"name" CODE 40000,6912 При этом, естественно, полу- чится файл с адресом загрузки 40000, но его легко можно изме- нить доктором. Вообще для того, чтобы программа работала, файлы нужно помещать туда, куда они грузились при работе с лентой. При выгрузке файлов на диск монитором следует, закончив заг- рузку, выйти в монитор и ввести команду save nameC 25000,40535, затем save nameC #5b00,1704. Ес- тественно, что имена должны быть разными, но они также обязатель- но должны быть длиной 8 символов - любых, хоть пробелов. Таким образом Вы выгрузите всю память на диск, но при этом появится другая проблемма - найти точку запуска программы. Это связано с тем,что после загрузки программы обычно декомпрессуются, настраи- ваются на прерывания, настраива- ют регистры и, под конец, стира- ют процедуры настройки. Если почти все вышепрочитан- ное было для Вас полезным и но- вым, то, скорее всего, адаптиро- вать программу, переписанную та- ким способом, будет нелегко. ________________ Часть Вторая ____ Кодовые загрузчики. Начнем с самого простого - коды в BASIC-программе, не имею- щие отношения к загрузке. Как правило, эти коды применяются, когда нужно поместить загружен- ный файл на его родное место. В этом случае есть два варианта. Первый: адаптируемая программа грузится в такие адреса, что системе TR-DOS не хватает места для работы, но при этом она име- ет не слишком длинный файл. Вто- рой вариант: файл просто длинно- ват (например - занимает место с 24500 до конца памяти (65535)). Немножко теории: для комфорт- ной работы DOS требуется, чтобы конец рабочей области бейсика был установлен оператором CLEAR на адрес 24999, или около того. Можно брать адреса больше, но не меньше, при попытке работать с RAMTOP<24499 произойдет то- тальное заглючивание, из которо- го можно выйти только по сбросу. Напоминаю, что RAMTOP - это гра- ница рабочей области бейсика, a устанавливается она оператором CLEAR adr. При работе TR-DOS вся информация в адресах от RAMTOP и меньше будет забита служебной информацией. Если при этом конец бейсика окажется слишком близко к RAMTOP то произойдет отказ в работе программы. Если повезет, то Вы отделаетесь сообщением "out of memory", в тяжелых слу- чаях возможна порча системной дорожки диска. И с весьма боль- шой вероятностью тяжелые пос- ледствия будут при загрузке ко- дов "не взирая" на RAMTOP - т.е., например, граница рабочей области установлена на 25000, а файл грузится, начиная с 24500. В такой ситуации этот файл ни- когда в жизни не загрузится, за- то почти наверняка диск будет запорчен. Кстати, поэтому я ре- комендую предохранять рабочие диски от порчи. Для этого удобно не заклеивать диск, т.к. на него то и дело приходится записывать, а просто просунуть в прорезь дисковода вместе с диском узкую полоску черной бумаги, так, что- бы закрыть прорезь защиты от за- писи (для тех, кто вчера впервые увидел диск: на ребре конверта есть маленький прямоугольный вы- рез, - если он закрыт, то запись на диск невозможна). Итак, первый вариант. Напом- ню: программа грузится в такие адреса, что не дает TR-DOS раз- вернуться во всем своем велико- лепии. В этом случае файл можно заг- рузить по адресу, большему, чем ему нужно, а после поместить его на нужный адрес. Делается это с помощью кодовой программки, ко- торая помещается в строке бейси- ковской программы в виде коммен- тария. Будет проще показать это на конкретном примере: игра A.Force 2 состоит из бейсик-заг- рузчика и одного блока кодов длиной 36000 с адресом загрузки 24500. Загрузчик выглядит так: 10 BORDER 0:PAPER 0:CLEAR 24499: LOAD"A.FORCE2"CODE 20 DRAW USR 24500,USR 51213 Дисковый загрузчик можно сде- лать таким: 5 REM 10 BORDER NOT PI : PAPER NOT PI: CLEAR VAL "24999": RANDOMIZE USR VAL "15619": REM: LOAD "A.FORCE2"CODE 25000 20 RANDOMIZE USR VAL "23872" В первой строке, после REM, в докторе набрать такие коды: 31 B3 5F 21 A8 61 11 B4 5F 01 A0 8C ED B0 CD B4 5F CD 0D C8 Коды в докторе набираются в левом окне, правое окно отражает символьную форму левого. Первая строка должна иметь размер в 20 пробелов после REM. Теперь переведем эти коды на человеческий язык. 31 B3 5F <> LD SP,#5FB3 - эквивалент CLEAR 24499 (#5FB3 - шестнадцатиричное зна- чение 24499) 21 A8 61 <> LD HL,#61A8 - адрес, с которого начинается файл #61A8=25000 11 B4 5F <> LD DE,#5FB4 - адрес, на который переедет нача- ло файла #5FB4=24500 01 A0 8C <> LD BC,#8CA0 - длина файла #8CA0=36000 ED B0 <> LDIR- перенос файла CD B4 5F <> CALL #5FB4 - RANDOMIZE USR 24500 CD 0D C8 <> CALL #C80D - RANDOMIZE USR 51213 Последнее замечание по этому поводу: адрес загрузки файла можно изненить доктором, внеся коррективы прямо в системную до- рожку. Стартовый адрес содержит- ся в 2-х байтах, идущих после байта типа файла (доктор имеет ширину окон по 8 байт, первую строку занимает имя файла,во второй находятся: T.SS.LL.l.Y.X, где T-тип файла, LL-два байта длины файла, SS-два байта, со- держащих адрес загрузки файла, l-байт длины файла в секторах, Y-номер первого сектора файла, X-номер первой дорожки файла). Второй случай (слишком длин- ный файл). Нужно отметить, что подобные ситуации бывают доста- точно редко. Простым вариантом решения будет отделить от начала файла выходящий за пределы нормы кусок информации, загрузить его в область экрана, а затем пере- нести его на место программкой вроде вышеописанной. Попробую привести пример: мы имеем файл с адресом загрузки 24400, длиной 41135. Разбить такой файл на части можно прямо из бейсика так: CLEAR 24399: LOAD"name" CODE: CLEAR 24999: RANDOMIZE USR 15619: REM: SAVE"name2"CODE 25000,40535 затем LOAD"name"CODE 25000,600: RANDOMIZE USR 15619: REM: SAVE"name1"CODE 25000,600 Загрузчик можно реализовать так: 1 REM 2 CLEAR VAL"24999":RANDOMIZE USR VAL"15619": REM: LOAD "name2"CODE 3 RANDOMIZE USR VAL"15619":REM: LOAD"name1"CODE 16384 4 RANDOMIZE USR VAL"23872" Адрес запуска 32768=#8000; адрес подгрузки второго блока - 16384=#4000; длина второго блока 600=#258. Тогда коды, которые нужно набрать в первой строке: 31 4F 5F 21 00 40 11 50 5F 01 58 02 ED B0 C3 00 08 Ассемблерный листинг: LD SP,#5F4F <> CLEAR 24399 LD HL,#4000 | перенос LD DE,#5F50 | отрезанного LD BC,#258 | блочка LDIR | JP #8000 <> RANDOMIZE USR 32768 Первая строка состоит из 18-и пробелов после REM. 23872-адрес второго символа первой строки. (первый символ REM = #ЕА) Надеюсь, что вся вышеизложен- ная информация наполнила Ваш мозг полезными знаниями, а не густым непроглядным туманом. Ес- ли Вы устали, то советую сделать перерыв и почитать другие рубри- ки журнала, так как дальше пой- дет сложный материал. Итак, с бейсиком покончено. Практически, более половины заг- рузчиков всех программ делаются в кодах, более того - кодовый загрузчик часто гораздо удобнее чем бейсиковый. Очень рекомендую Вам научиться пользоваться ка- ким-либо монитором-отладчиком. Лучшими мониторами на данный мо- мент являются STS 3.2 и теневой монитор Scorpion'а В принципе, достаточно удобны MONS_4 и Mon3. Также нелишним будет знание ас- семблера, хотя начинать можно и без оного. Весь нижеследующий материал написан, исходя из то- го, что Вы умеете работать с от- ладчиком. Начнем, пожалуй, с кодов в ленточных загрузчиках. При рабо- те на Scorpion'е все достаточно просто - нужно запустить загруз- чик с ленты и, лихо щелкнув MAGIC'ом, нажать BREAK. Необхо- димо только проследить, чтобы не произошло двойного выхода в мо- нитор - как только программа ос- тановится, нужно отпустить обе кнопки. Выход в теневое меню тогда, когда идет загрузка с ленты стандартным образом невоз- можен, ввиду этого нужно нажать MAGIC и, удерживая ее, создать "помеху" в загрузке, - как уже было сказано, - нажать BREAK или, например, остановить магни- тофон. После выхода в монитор набрать mem pc и смотреть дизас- семблер на несколько шагов на- зад. При использовании других мо- ниторов можно загрузить монитор, выйти из него, ввести загрузчик с подменой заголовка и затем вернутся в монитор (так можно работать с MONS, а если Вы имете STS, то лучше переписать загруз- чик копировщиком на диск и заг- ружать его командой монитора LOAD (клавиша L), адрес загрузки 23755). После помещения загрузчика на место нужно смотреть дизас- семблер с адреса 23759 - это на- чало первой строки. Конечно, ис- кать коды в загрузчике имеет смысл только если они там есть. Признаком сего могут служить безбашенные файлы, нестандартная загрузка (например - с полосами не того цвета или с заполнением экрана задом наперед (так было в SPOOKED)), или то, что весь заг- рузчик содержит только RANDOMIZE USR. Если LOADER содержит одну загрузку кодового файла и его запуск, а программа состоит из нескольких кодовых файлов, то кодовый загрузчик находится в загружаемом файле. Такое встре- чается крайне редко - например я видел это только в одной прог- рамме - DRACONUS. Иногда коды сливают с заставкой (было в SAI COMBAT), тогда заставку можно подгрузить например с 32768 и просматривать монитором, помня о смещении кодов (начало экрана - #4000, а 32768=#8000). Итак, мы имеем монитор и коды в памяти. Что нужно искать? Вот пример самого простого загрузчи- ка (как раз от DRACONUS): LD DE,#1B00 <-длина файла LD IX,#4000 <-адрес загрузки LD A,#FF <-"флаг" SCF <-признак загрузки CALL #0556 <- загрузка LD HL,#4010 | в стек вносится PUSH HL | адрес возврата LD DE,#9C00 <-длина файла LD IX,#6400 <-адрес загрузки LD A,#FF ... SCF ... JP #0556 <-загрузка и переход по содержимому стека (#4010) При выполнении CALL в стек вносится адрес, следующий за этим CALL; когда программа дохо- дит до команды RET - она перехо- дит по адресу, который записан в стеке. Команды CALL и RET анало- гичны GO SUB и RETURN в бейсике. Здесь используется стан- дартная подпрограмма загрузки с ленты, находящаяся в ПЗУ по ад- ресу #556. Все подпрограммы ПЗУ оканчиваются на RET. Команда PUSH HL помещает содержимое ре- гистра HL в стек. JP - аналог GOTO - просто переход по адресу. Адрес #4010 находится в области экрана, заставка программы со- держит по этому адресу JP #6600. Таким образом DRACONUS можно адаптировать, переписав его фай- лы на диск, выставив стартовые адреса, - для заставки #4000, для основного блока #6400, и на- писав такой загрузчик: 10 BORDER 0:PAPER 0:INK 0: CLEAR 26111: RANDOMIZE USR 15619: REM: LOAD"drac$"CODE 20 RANDOMIZE USR 15619:REM:LOAD "dracC"CODE 30 RANDOMIZE USR 26112 Просто, правда? Однако не слишком изящно. Если программа будет содержать несколько фай- лов, да еще и "плохой" RAMTOP, для подобного загрузчика просто не хватит места. В простых слу- чаях можно попытаться сократить объем загрузчика при помощи уменьшения количества строк и сжатия чисел: 10 INK NOT PI: PAPER NOT PI: BORDER NOT PI: CLEAR VAL "24499" 20 RANDOMIZE USR VAL "15619": REM: LOAD "rex I"CODE 30 RANDOMIZE USR VAL "24500": REM:POKE VAL "39402",NOT PI: POKE VAL "40057",NOT PI 40 CLEAR VAL "24599" : RANDOMIZE USR VAL "38010" Это загрузчик REX-I. Несмотря на большой, казалось бы, объем текста, он займет места байт на 50 меньше, чем был ленточный. Дело в том, что при использова- нии VAL число имеет только сим- вольное представление (помните, я показывал, как выглядит число само по себе), т.е. оно короче на 3 байта - 6 байт уходят, и прибавляется 3 - VAL и две ка- вычки. NOT PI=0, но занимает 2 байта против 7 - обычной записи нуля. Иногда кодовые загрузчики ис- пользуют нестандартный адрес входа в подпрограмму загрузки (например, #562), либо вообще свою процедуру. В последнем слу- чае загрузка идет обычно особо извращенным методом, - например, задом наперед в шахматном поряд- ке. Преодолеть это достаточно сложно, и это - работа для про- фессионалов. Могу только посове- товать использовать процедуру отгрузки на ленту для получения нормального формата файла (#4C2, старт - IX, длина - DE, A - флаг). Что касается стандартных загрузок, то они обязательно по- мещают адрес начала загрузки в регистр IX, длину файла - в DE. Флаг - это первый байт файла, который не помещается в память, а используется для опознания ти- па файла (стандарт: заголовок - 0, тело файла - 255). Загрузка с диска также воз- можна в кодах. Для вызова проце- дур TR-DOS используется CALL #3D13, код процедуры помещается в регистр C. Есть два варианта загрузки: по имени файла и по секторам (т.е. загрузка в память по адресу HL содержимого N сек- торов с места на диске, которое указано в регистре DE, коли- чество секторов - в регистре B; код процедуры C=5). При загрузке по имени, имя и тип файла зано- сятся по адресу #5CDD, по адресу #5CF9 ставится 0; если стартовый адрес берется из заголовка, то A=0, если А=3, то адрес берется из регистра DE. Когда загрузка идет по секторам, то всю прог- рамму можно представить на диске как один файл - выставить в за- головке загрузчика длину в сек- торах, равной суммарной длине всей программы, и переписать на другой диск (переписывать прос- тым boot'ом, ни в коем случае не CONVER COMMANDER'ом). Когда Вы достаточно разбере- тесь с загрузкой по секторам, адаптировать программы сможете прямо на диске, доктором. Вот пример: лента диск LD IX,#0000 DI LD DE,#0011 LD DE,(#5CF4) XOR A LD HL,#61D8 SCF LD BC,#4005 CALL#5C7F NOP LD IX,#61D8 NOP LD DE,#3F70 NOP LD A,#FF CALL#3D13 SCF LD IX,#0000 CALL#5C7F LD DE,#0011 LD IX,#0000 XOR A LD DE,#0011 SCF XOR A LD DE,(#5CF4) SCF LD HL,#4000 CALL#5C7F LD BC,#0A05 LD IX,#4000 NOP LD DE,#09FD NOP LD A,#FF NOP SCF CALL#3D13 CALL#5C7F IN A,(#1F) IN A,(#1F) CALL#61FE CALL#61FE LD BC,(#5C80) LD BC,(#5C80) LD HL,#0556 LD HL,#0556 AND A AND A SBC HL,BC SBC HL,BC JR Z,L5DA2 >- JR Z,L5DA2 >- IN A,(#9F) | IN A,(#9F) | LD IX,#0000<- LD IX,#0000 <- LD DE,#0011 LD DE,#0011 XOR A XOR A SCF SCF LD DE,(#5CF4) CALL#5C7F LD HL,#4056 LD IX,#4056 LD BC,#0A05 LD DE,#0930 NOP LD A,#FF NOP SCF NOP CALL#5C7F CALL#3D13 JP #6201 JP #6201 Пожалуй,здесь нужно небольшое пояснение. По адресу #5CF4 TR- DOS помещает номер текущей до- рожки и текушего сектора. Тако- выми становятся те, на которых остановилась загрузка, т.е. если загружен файл длиной в один сек- тор, то текущим сектором будет следующий за ним, а это уже бу- дет первый сектор следующего файла. При загрузке с ленты по адресу #5C7F было помещено JP #556. Как видите, адаптировать программы можно "в лоб", даже не вникая в суть работы загрузчика - достаточно просто переписать подряд все файлы на диск. Имеет- ся только одна тонкость: TR-DOS недолюбливает второй режим пре- рываний, ввиду чего рекомендует- ся по выходу из INTRO программы (конечно, если оно есть, и Вы решили сохранить его) поставить команду IM 1, а если нужно, то по окончании загрузки вернуть второй режим командой IM 2. При обращении к TR-DOS лучше запре- щать прерывания ( DI ). Относительно программ на 128/ 256 и т.д., могу только посове- товать работать в кодах. Полно- ценный загрузчик для 128 прог- раммы на бейсике сделать просто невозможно. При работе старай- тесь избегать команд типа "пойди туда, не знаю куда, а попутно выведи туда #14". В стандартном компьютере есть порт #7FFD, ко- торый служит для переключения страниц памяти, ПЗУ и экранов. Если Вы являетесь счастливым об- ладателем такого дубового ком- пьютера, который в ответ на LD A,#14; OUT (#FD),A установит 4-ю страницу ОЗУ и на этом закончит, то, конечно, можете делать пе- реключение страниц по OUT (#FD),A, только никому не пока- зывайте свои программы. Если Вы хотите выпустить свою дисковую версию в свет, то запомните, что страницы памяти переключаются c помощью вывода числа в порт 7FFD при выключенных прерываниях. Приведу пример лобовой адап- тации программы с режимом 48/ 128. Исходный текст (на ленте): DI <-L5D00 LD SP,#61A7 LD HL,#4000 LD DE,#4001 LD BC,#1AFF XOR A OUT (#FE),A LD (HL),A LDIR LD HL,#3D00 LD DE,#8000 LD (#5C36),DE INC D PUSH DE LD BC,#0300 LD A,(HL) <-L5D22 RRA OR (HL) LD (DE),A INC HL INC DE DEC BC LD A,B OR C JR NZ,L5D22 POP HL LD B,#60 PUSH BC <-L5D30 LD B,#04 INC HL INC HL INC HL INC HL LD A,(HL) <-L5D37 RLA NOP DJNZ L5D37 POP BC DJNZ L5D30 LD A,#02 CALL #1601 LD HL,L5E42 CALL L5E2A LD HL,#C000 | LD A,#11 | настройка LD BC,#7FFD | 48/128 LD (HL),A | OUT (C),A | CP (HL) | JR NZ,L5D65 | LD A,#C9 | LD (L5DF0),A | LD HL,L5E90 CALL L5E2A JR L5D6B LD HL,L5EAC <-L5D65 CALL L5E2A LD HL,#5B00 <-L5D6B LD DE,#5B01 LD BC,#026B LD (HL),L LDIR LD A,#07 <-L5D77 OUT (#FE),A LD IX,#61A8 LD DE,#2F12 CALL #5E32 JR NC,L5D77 CALL #61A8 LD A,#07 <-L5D8A OUT (#FE),A LD A,#10 LD BC,#7FFD OUT (C),A LD IX,#61A8 LD DE,#835C CALL L5E32 JR NC,L5D8A CALL L5DF0 LD HL,L5DB2 LD DE,#5B02 LD BC,#003E LDIR JP #5B02 DI <-L5DB2 LD SP,#5F56 LD A,#10 LD BC,#7FFD OUT (C),A CALL #61A8 LD A,(#5B00) CP #02 JR NZ,L5DD0 XOR A LD (#8B9F),A LD A,#C3 LD (#8BA0),A LD A,(#5B01) <-L5DD0 CP #01 JR Z,L5DDF LD A,#C9 LD (#5FFD),A LD (#5FE3),A EI <-L5DDF LD HL,#7327 LD DE,#7328 LD (HL),#74 LD BC,#01FF LDIR JP #5F57 LD A,#07 <-L5DF0 OUT (#FE),A LD A,#11 LD BC,#7FFD OUT (C),A LD IX,#C000 LD DE,#235F CALL L5E32 JR NC,L5DF0 CALL #C000 LD A,#07 <-L5E0A OUT (#FE),A LD A,#17 LD BC,#7FFD OUT (C),A LD IX,#C000 LD DE,#09B1 CALL L5E32 JR NC,L5E0A CALL #C000 LD A,#01 LD (#5B01),A RET LD A,(HL) | <-L5E2A CP #FF |процедура печати RET Z | RST #10 | INC HL | JR L5E2A | SCF | <-L5E32 LD C,#00 | INC D | процедура EX AF,AF' | DEC D | DI | загрузки CALL #056A | PUSH AF | XOR A | OUT (#FE),A | POP AF | RET DEFB #16,#09,#02 <-L5E42 DEFB #11,#00,#10 DEFB #07,#13,#01 DEFB "DIZZY-X:, DEFB "JOURNEY TO DEFB "RUSSIA !" DEFB #16,#0B,#00 DEFB #11,#00,#10 DEFB #03,#13,#01 DEFB "CRACKED BY" DEFB "PAUL O'MELLY " DEFB "07.05.94",#FF DEFB #16,#0E,#08 <-L5E90 DEFB #11,#00,#13 DEFB #01,#10,#05 DEFB "48K MODE " DEFB "LOADING..",#FF DEFB #16,#0E,#07 <-L5EAC DEFB #11,#00,#13 DEFB #01,#10,#05 DEFB "128K MODE DEFB "LOADING..",#FF Программа имеет INTRO с музы- кой и установкой бессмертия, грузящееся перед основной прог- раммой. Вот текст дисковой вер- сии: DEFB "dx.0 C" L5D40 LD HL,L5D40 LD DE,#5CDD LD BC,#0009 LDIR CALL L5E6D CALL #61A8 LD SP,#61A7 LD HL,#C000 | LD A,#11 | настройка LD BC,#7FFD | LD (HL),A | 48/128 OUT (C),A | CP (HL) | JR Z,L5D6F | XOR A | LD (L5D73),A | CALL L5E61 L5D6F JR L5D8E LD A,#11 LD BC,#7FFD OUT (C),A CALL L5E5A CALL #C000 LD A,#17 LD BC,#7FFD OUT (C),A CALL L5E69 CALL #C000 LD HL,L5D9C L5D8E LD DE,#5B02 LD BC,#003E LDIR JP #5B02 DI L5D9C LD SP,#5F56 LD A,#10 LD BC,#7FFD OUT (C),A CALL #61A8 LD A,(#5B00) CP #02 JR NZ,L5DBA XOR A LD (#8B9F),A LD A,#C3 LD (#8BA0),A LD A,(#5B01) L5D8A CP #01 JR Z,L5DC9 LD A,#C9 LD (#5FFD),A LD (#5FE3),A EI L5DC9 LD HL,#7327 LD DE,#7328 LD (HL),#74 LD BC,#01FF LDIR JP #5F57 LD A,#01 L5E5A LD (#5B01),A L5E5C JR L5E69 DI L5E61 LD A,#10 L5E62 LD BC,#7FFD L5E64 OUT (C),A LD HL,#5CE0 L5E69 INC (HL) L5E6C DI L5E6D XOR A L5E6E LD (#5CF9),A LD C,#0E L5E72 CALL #3D13 L5E74 RET Как видно, в данном загрузчи- ке файлы грузятся по именам и сюда включен кусок ленточного LOADER'а. ________________ Полагаю, что для вводного курса информации достаточно. Ес- ли остались неясности, просмот- рите еще раз последние два при- мера. Кому не поможет - почитай- те книгу Н. Родионова - там за- острено внимание на некоторых отдельных вопросах, но зато чи- тать повеселее. ________________________________ Из журнала ZX Format #4, Санкт-Петербург, 15.06.1996 Адаптация #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 ________________________________