Адаптация программ к системе TR-DOS. 1992 г.

Глава 5 - как бороться с RAMTOP'ом.


Глава 5

КАК  БОРОТЬСЯ  С  RAMTOP'OM

 

Часто спрашивают: «Как переделать программу на диск, если граница RAMTOP установлена слишком низко и не позволяет нормально работать с системой TR-DOS?». Попытаюсь ответить на этот вопрос.

В одной из предыдущих глав предлагался способ экономии памяти посредством разбиения загрузчиков на несколько частей. Однако такой способ является далеко не самым изящным, да и помогает не всегда. Сложности начинаются уже тогда, когда RAMTOP опускается до адреса 24500. На всякий случай напомню, что RAMTOP — это не фамилия, это адрес последней ячейки памяти, используемой Бейсиком. Устанавливается RAMTOP оператором CLEAR <адрес>.

При попытке переделать на диск программу с наипростейшим загрузчиком

 

     10 BORDER  1: PAPER 1: INK 1: CLS

     20 CLEAR 24199

     30 LOAD  ""CODE

     40 RANDOMIZE  USR 49152

 

проблемы начинаются уже в тот момент, когда Вы успешно вывалились в Бейсик по Break и пытаетесь выйти в TR-DOS с помощью оператора RANDOMIZE  USR  15616. Лаконичное сообщение Out of memory не упустит шанса появиться на экране. Вероятно, после нескольких попыток Вы решите, что эту программу гораздо приятней загружать с кассеты или «скинуть» @безьяньей кнопкой.

Мне рассказывали, как горе-программисты меняют CLEAR 24000 на CLEAR 25000, записывают программу таким образом, и она у них даже как-то работает. Я же Вам скажу следующее: этого делать нельзя ни в коем случае. Если Вы полтора миллиона раз подряд сбросите программу @безьяной, то, скорее всего, навредите ей меньше, чем подобной заменой.

Давайте лучше подумаем, как решить эту задачу более изящным способом. Вы не хуже меня понимаете, что если системе TR-DOS не хватает рабочего места, это место нужно освободить. А именно, необходимо поднять RAMTOP примерно до адреса 24700 или выше, то есть спрятать куда-нибудь примерно 500—700 байт. Здесь, в зависимости от длины и расположения файлов программы, могут возникнуть две ситуации. Первая — кодовый файл программы достаточно короткий, вторая — кодовый файл длинный и занимает всю или почти всю память, начиная от RAMTOP и до самого верха (до адреса 65535).

Сначала рассмотрим более простой — первый случай.

Предположим, что кодовый файл, для которого необходимо написать загрузчик с диска, имеет адрес начала 24200 и длину 40800, а загружается с ленты и запускается приведенным выше загрузчиком. Если подсчитать, то получится, что адрес последнего занимаемого файлом байта равен 64999, а 536 байт с адреса 65000 фактически остаются свободными*. Итак, установив этот факт, Вы обзовете идиотом того, кто поместил файл именно в эти адреса, в результате чего 536 байт вверху пропадают, а внизу так тесно, что ощущаешь себя пассажиром троллейбуса в час пик (или скорее потенциальным пассажиром, безуспешно пытающимся залезть в переполненный троллейбус). Надо заметить, что обзывать никого не стоит, поскольку у автора программы могли быть веские причины на то, чтобы поместить ее именно туда, куда он ее поместил. Кроме того, автор, вероятно, не предполагал, что кому-то приспичит переделывать его программу на диск да к тому же в системе TR-DOS.

Первое, что приходит на ум, — это загрузить файл чуть выше (в данном случае логично использовать все 536 байт), а затем, когда обращений к диску уже не будет (то есть системе теперь не понадобится память под буферы и т. п.), поставить файл на место и запустить. Все, казалось бы, проще простого, и не исключено, что Вы поспешили написать на Бейсике нечто вроде

 

     FOR n=24736  ТО 65535: POKE n-536,PEEK n: NEXT n

 

Если у Вас хватило терпения дождаться результатов работы этой маленькой, но гаденькой программки, то  Вы, вероятно, убедились, что она честно выполняет свое дело, но запускать ее нужно вечером, а утром, почистив зубы, можно будет поиграть в игрушку, которая наконец заняла свое привычное место и запустилась.

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

 

                        33,SL,SH     LD HL,SOURCE

                        17,TL,TH     LD DE,TARGET

                        1,LL,LH      LD BC,LENGTH

                        195,195,51   JP 13251(или просто LDIR)

 

— где SOURCE — адрес настоящего местоположения файла; TARGET — адрес желаемого местоположения файла; LENGTH — его длина. В нашем случае значения будут равны, соответственно, 24736, 24200 и 40800.

___________________________________________________________________

* Если не верите — можете посчитать на пальцах; кстати, Вы зря смеетесь: если использовать двоичную систему счисления, то на пальцах без особых ухищрений можно показать число в диапазоне от 0 до 1023, а если прибавить еще шесть спичек, то вся память Speccy будет у Вас как на ладони.

Если Вы не знаете толком, что такое ассемблер и кому в голову взбрело его изобрести, то Вас больше заинтересует левое поле. Это коды приведенных мнемоник в десятичной системе счисления. Загадочные SL, SH, TL, TH, LL и LH означают старшие (Н) и младшие (L) байты двухбайтовых чисел. Как известно, байт может принимать значения от О до 255, поэтому для размещения в памяти числа 24736 необходимы как минимум два байта. Младший байт для SOURCE вычисляется как

 

     LET SL=SOURCE-256*INT  (SOURCE/256)

 

—  старший как

 

     LET SH=INT (SOURCE/256)

 

Остальные числа рассчитываются аналогичным способом. Для получения значений байтов можно применить и другой, более интересный приемчик:

 

     RANDOMIZE  SOURCE:  LET SL=PEEK 23670:

        LET SH=PEEK 23671

 

Итак, скрупулезно разложив все исходные данные на отдельные байты, Вы получили некий набор чисел. Для уверенности можете проверить правильность проведенных операций:

 

     LET SOURCE=SL+256*SH

 

Набор чисел в нашем примере будет выглядеть так:

 

     33,160,96

     17,136,94

     1,96,159 195,195,51

 

Теперь Вы спросите, что же с ними делать. Числа можно приписать к началу Вашего файла (он, таким образом, станет на 12 байт длиннее) и сохранить его в новом виде. Ввести числа в память можно, непосредственно выполняя операторы РОКЕ один за другим:

 

     РОКЕ  24724,33

     РОКЕ  24725,160

     РОКЕ  24726,96

 

и.т.д., либо написав несколько строк На Бейсике;

 

 

     10 FOR п=24724 ТО  24735

     20 READ  s

     30 POKE  n,s

     40 NEXT  n

     50 DATA  33,160,96,17,196,94,1,96,159,195,195,51

 

Имеется в виду, что файл уже загружен в память на 536 байт выше (например, оператором LOAD "name"CODE 24736).

Подготовив файл таким образом, запишите его на диск:  

 

     SAVE  "name"CODE 24724,40812

 

и напишите загрузчик с диска:

 

     10 BORDER  1: PAPER 1: INK 1

     20 CLEAR 24723

     30 RANDOMIZE  USR 15619: REM : LOAD"name"CODE

     40 CLEAR 24199

     50 RANDOMIZE  USR 24724

     60 RANDOMIZE  USR 49152

 

Обратите внимание, что первый CLEAR устанавливает RAMTOP на единицу меньше, чем адрес загрузки файла, затем, после загрузки файла, устанавливается «оригинальный» RAMTOP и выполняется написанный нами фрагмент в машинных кодах (строка 50), который и помещает файл на нужное место. Затем программа нормально запускается (строка 60).

Если в той программе, которую Вы захотите адаптировать, адрес загрузки файла примерно такой же, как в приведенном примере, то проблем возникать не должно. Однако нередки ситуации, когда граница RAMTOP, которую устанавливает загрузчик, настолько низка, что при попытке выполнения второго оператора CLEAR, Вы получите уже знакомое сообщение об ошибке: 4 Out of memory, 40:1. Такая ситуация может возникнуть в связи с тем, что, как уже говорилось, TR-DOS резервирует под свои системные переменные 112 байт.

С этим бороться несколько сложнее, однако тоже можно. Ниже приводится программа в кодах, которая поможет решить эту проблему. Необходимо заметить, что работать она будет только в том случае, если адаптируемая программа запускается единожды и в Бейсик больше не возвращается.

 

     49,CL,CH     LD         SP,STACK

     33,EL,EH     LD         HL,ENTRY 

     229          PUSH       HL

     33,SL,SH     LD         HL,SOURCE

     17,TL,TH     LD         DE,TARGET

     1,LL,LH      LD         BC,LENGTH

     195,195,51   JP         13251

 

— где STACK — адрес размещения машинного стека (для решаемых нами задач он должен совпадать с параметром оператора CLEAR); ENTRY — входная точка программы (то есть число, которое следовало за оператором RANDOMIZE  USR в исходном загрузчике). В нашем примере STACK будет равен 24199, a ENTRY — 49152.

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

 

     10 BORDER  1: PAPER 1: INK 1

     20 CLEAR 24716

     30 RANDOMIZE  USR 15619: REM : LOAD "name"CODE   

     40 RANDOMIZE  USR 24716

 

Обратите внимание, что в новом загрузчике, в отличие от предыдущего, нет ни оператора CLEAR 24199, ни RANDOMIZE USR 49152, эти операции выполняются приведенной подпрограммой в машинных кодах.

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

                  ________________________

 

С этими довольно простыми случаями Вы, вероятно, уже разобрались (иначе — читайте все с начала; если и это не поможет — обзовите автора неприличным словом как несостоявшегося).

Теперь разберем более сложную и неприятную ситуацию, когда, после тщательных расчетов (быть может, на пальцах), Вы пришли к прискорбному выводу, что файл занимает всю память от RAMTOP и выше, а так необходимые 500—700 байт взять совершенно негде. Не пугайтесь, это еще не повод для беспокойства. Вы забыли о довольно большом резерве — видеопамяти и буфере принтера. Использование буфера принтера предпочтительнее, но он имеет объем лишь 256 байт (с адреса 23296), поэтому может помочь только, если недостает каких-нибудь 200-250 байт.

По большому счету, в случае длинного файла (имеется в виду файл, занимающий все пространство от RAMTOP и выше) организация загрузки и запуска будет во многом аналогична организации загрузки и запуска короткого файла. Единственным принципиальным отличием будет то, что длинный файл придется разбить на два коротких. Способов разбиения файлов на куски существует достаточно много. Это можно сделать и непосредственно на диске, с помощью программы Disk Doctor*.

Подробнее рассмотрим ситуацию, когда исходный файл находится еще на кассете. Самое простое — загрузить файл в память, не забыв установить правильный (оригинальный) RAMTOP, и записать два файла на кассету оператором SAVE. При этом имейте в виду, что выходить в TR-DOS ни до, ни после загрузки файла ни в коем случае нельзя.

Предположим, Вы захотели адаптировать программу со следующими исходными данными:

 

загрузчик:

 

     10 CLEAR  23999: LOAD ""CODE

     20 RANDOMIZE   USR 24000

 

файл: адрес загрузки — 24000, длина — 41536.

 

Сбросьте машину (аккуратно, так, чтобы телевизионный кабель не оборвался), затем проделайте следующие операции:

 

     CLEAR  23999

     LOAD  ""CODE

 

 — загрузите файл, далее выполните

 

     SAVE "1"СОDЕ  24000,1000

     SAVE "2"CODE  25000,40536

 

Итак, на кассете Вы получили два файла. Вновь сбросьте машину и загрузите первый (более короткий) файл в область экрана оператором

 

     LOAD "1"СОDЕ  16384

 

— затем запишите его на диск:

 

     RANDOMIZE  USR  15619: REM : SAVE "1"СОDЕ 16384,1000

 

Второй файл перенесите на диск любым доступным способом.

 

Можно несколько ускорить операцию разбиения файла, если после записи на кассету первого куска (длиной 1000 байт) выполнить оператор CLEAR  24999 (для данного примера, разумеется). Таким образом, мы освобождаем место для работы TR-DOS, поэтому второй файл можно будет записать на диск непосредственно из памяти, избежав промежуточных стадий. Обращаю Ваше внимание на то, что после выполнения оператора CLEAR 24999 область памяти с этого адреса и ниже отводится под Бейсик, и тем самым портится кусок программы, но поскольку мы только что этот кусок сохранили на кассете, бояться абсолютно нечего.

Итак, мы имеем на диске два файла, и если просмотрим  каталог оператором LIST системы TR-DOS, то увидим, что адрес загрузки первого файла 16384 и длина  1000, второго — 25000 и 40536, соответственно (чего, в общем-то, и следовало ожидать). С этими файлами необходимо поступать следующим образом: первым, без всяких хитростей (RAMTOP  должен быть установлен ниже адреса загрузки файла), загружается файл "2", а лишь потом — "1". Поскольку загружаться файл "1" будет в экранную область, перед его загрузкой, из эсте-

* Как автор этой программы рекомендую пользоваться версиями с номерами не менее 3.2. В настоящий момент последняя версия имеет номер 4.3. Программой же DISK DOCTOR фирмы Technology Researsh, которая поставлялась в комплекте с системой TR-DOS, пользоваться можно только после принятия некоторой дозы алкоголя.

тических соображений, рекомендуется сделать цвет INK и PAPER одинаковыми и очистить экран. Если в программе есть заставка, то она должна загружаться первой, затем длинный файл, и после очистки экрана — короткий.

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

 

            LD    HL,24000

            PUSH  HL

            LD    SP,23999

            LD    HL,16384

            LD    DE,24000

            LD    ВС,1000

            JP    13251

 

Опять-таки имейте в виду, что адаптированная программа будет работать только в том случае, если она не возвращается в Бейсик.

 

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

 

 




  Оставте Ваш отзыв:

  НИК/ИМЯ
  ПОЧТА (шифруется)
  КОД



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

Похожие статьи:
ENLIGHT RULEZ?! - ENLIGHT 1997 - к чему он прирулит? (день четвертый и пятый).
Интервью - интервью с KONEX-ом по поводу годовщины творческой группы "Antares".
заключение - авторы и т.д.
Новые программы - И.Рощин. HELP_Z80. В.Давыдов. Catalog's Base v1.8.
Risk - мысли risk'a o genz'e 3.5

В этот день...   29 марта