Adventurer #06
28 февраля 1997

Обмен опытом - Как сделать дисковую версию программы ?..

<b>Обмен опытом</b> - Как сделать дисковую версию программы ?..
                (C) RAY
    (C) Музыка PHANTOM LORD/ACCEPT CORP.
╔───────────────────────────────────────╗
│ ──── КАК СДЕЛАТЬ ДИСКОВУЮ ВЕРСИЮ ──── │
╚───────────────────────────────────────╝

     Вам, безусловно, знакома такая ситу-
ация:  при  загрузке  некоторой программы
(неважно, игра или системка) выдается со-
общение "Disked by ...", a затем, при по-
пытке,  скажем,  загрузить что-то, вы ви-
дите  помаргивающий  бордер.  Какие слова
будут сказаны в адрес того самого "диске-
тизатора",  надеюсь, вы сами догадаетесь.
В  общем,  я  считаю так : можно писать в
загрузчике,  что  программа дискетирована
только тогда, когда сделана ПОЛНАЯ ДИСКО-
ВАЯ версия. Если же просто приляпан  дис-

ковый  loader,  то уж лучше ничего не пи-
сать  или  отметить,  что-де не полностью
прога дискетирована. Правда последний ва-
риант мало кого может устроить, поэтому я
поделюсь  с  вами некоторой информацией о
том, как сделать полную  дисковую  версию
программы.
     Итак, у вас есть некий кодовый блок,
в котором надо изменить загрузку/выгрузку
каких-либо данных с ленты на диск. Снача-
ла  смотрим  адрес загрузки блока. Обычно
на единицу меньше этого адреса устанавли-
вается  стек.  (ВНИМАНИЕ : убедитесь, что
после запуска программа не изменяет свое-
го  положения  в  памяти, в частности, не
перебрасывает ли себя ниже этого адреса!)
Обычно  минимальный  адрес бывает  24500.
Если  у  блока  такой адрес или больший -
все О.к., 90%, что проблем  с  переделкой
под диск не возникнет.  Если же нет - си-
туация чуть более сложная и ее рассмотрим
позже (в этой статье рассматривается дис-
кетизация стандартными методами TR-DOS). 

     Перед тем, как искать точки входа  в
ленточные процедуры загрузки/записи,  по-
лезно просмотреть всю память  на  предмет
нахождения незанятого  программой  места.
Как  показала  практика,  в  любой  проге
всегда найдется байт 150..200  свободного
места (можно кусками, байт по 45). А это-
го с лихвой хватит для наших целей.  Если
же нет - можно использовать место,  кото-
рое занимает BASIC-загрузчик.
     Теперь начинаем искать  точки входа.
Тут тоже может быть два варианта:
1) программа использует собственные  про-
   цедуры загрузки/записи;
2) программа  пользуется  процедурами  из
ПЗУ.
     В первом случае искать  точки  входа
труднее, но зато не нужно будет потом на-
ходить  свободное место в программе, т.к.
новые  подпрограммы  как раз уместятся на
месте старых.
     Во  втором  случае  можно попытаться
найти вызовы ПЗУ.

     Рекомендую сначала найти точку входа
в SAVE, т.к. в ней легче определить пара-
метры отгружаемого блока (начальный адрес
/обычно в регистре IX/ и длину /рег. DE/).
     Приведу некоторые  точки  входа  для
ленточных подпрограмм в  ПЗУ,  вытащенные
из разных программ:

       мнемоника       байты для поиска
─────────────────────────────────────────
SAVE:  CALL 1218           CD C2 04
       CALL 1222           CD C6 04

LOAD:  CALL 1366           CD 56 05
       CALL 2050           CD 02 08
       CALL 1378           CD 62 05
       CALL 1889           CD 61 07
─────────────────────────────────────────
Кроме этого  встречаются  и  экзотические
способы:
       CALL #0605
       где SAVE или LOAD определяется
       по ячейке 23688 = 0 - SAVE
                         1 - LOAD 

     Еще более интересный способ:
SAVE: CALL 2416,
где
      IX - первые 17 байт - заголовок,
затем данные;
      длина задается так:

      LD DE, длина
      LD (IX+11),D
      LD (IX+12),E .

     Если  же  у  вас  подозрение,  что в
программе используются собственные проце-
дуры  работы  с  лентой, то можно сделать
следующее.  Т.к.  обычно  такие процедуры
делаются  на  основе  ПЗУ'шных,  то ищите
такую последовательность:

      код     мнемоника
      ──────────────────
      08      EX  AF,AF'
      13      INC DE
      DD 2B   DEC IX
      F3      DI 

Это кусочек из процедуры, расположенной в
ПЗУ по адресу 1222 (#04C6). Если вы нашли
нечто подобное, значит это начало (почти)
подпрограммы записи  на  ленту.  Осталось
только найти, где осуществляется ее вызов
и  определить параметры отгружаемого бло-
ка.
     Если  ничего  из вышеприведенного не
помогло - попробуйте  поискать сообщения,
которые  программа  выдает  при  работе с
лентой.  Обычно  эти  сообщения находятся
рядом с соответствующими процедурами.

     Итак, все мы нашли.  Замените адреса
вызова найденных подпрограмм на приведен-
ные ниже. Правда, есть еще один момент:
может  быть  три  варианта  отгрузки (для
загрузки - аналогично):

1) в один и тот же файл;
2) в одно и то же место на диске или
   "в себя";
3) в разные  файлы  (наиболее  предпочти-
   тельно).

     В первом случае имя файла фиксирова-
но. Во втором оно вообще не  нужно.  А  в
третьем нужно его как-то  вводить  (такое
обычно встречается в адвентюрных  играх).

     Рассмотрим эти случаи...

1. В один Файл:
───────────────
SAVE
       CALL   SET_NAME   ; готовим сист.
                         ; переменные
       LD     C,10       ; ищем файл
       CALL   15635
       LD     A,C
       BIT    7,C
       JR     NZ,SAV_BL  ; его нет

       LD     DE,(23878) ; нашли, rewrite
       LD     BC,#nn06
       LD     HL,адрес
       CALL   15635
       RET  

SAV_BL                   ; создаем новый
       LD     HL,адрес
       LD     DE,размер
       LD     C,11
       CALL   15635
       RET

где    адрес  - адрес начала отгружаемого
                блока;
       размер - его размер в байтах;
       nn     = его размер в секторах.

LOAD
       CALL   SET_NAME   ; готовим сист.
                         ; переменные
       LD     C,10       ; ищем файл
       CALL   15635
       LD     A,C
       BIT    7,C
       JR     Z,LD_1
; Сообщение "файл не найден" или...
       RET  

LD_1                     ; грузим...
       LD     A,C
       LD     C,8
       CALL   15635
       XOR    A
       LD     (23801),A
       LD     (23824),A
       LD     C,14
       CALL   15635
       RET
; Подпрограмма установки сист.переменных
SET_NAME
       LD     HL,NAME    ; перекидываем
       LD     DE,23773   ; имя файла
       LD     BC,8
       LDIR
       LD     A,"C"      ; тип файла м.б.
       LD     (23781),A  ; любой, кроме
                         ; "#","D","B"
       LD     A,9        ; поиск файла
       LD     (23814),A  ; по 9 символам
       RET

NAME   DEFM   "filename" 

2. В одно и то же место ("в себя"):
───────────────────────────────────
SAVE
       LD     HL,адрес
       LD     DE,(T_S)
       LD     BC,#nn06
       CALL   15635
       RET
LOAD
       LD     HL,адрес
       LD     DE,(T_S)
       LD     BC,#nn05
       CALL   15635
       RET
T_S    DEFW   #SSTT ; дорожка и сектор,
                    ; куда писать/читать

3. В разные файлы:
──────────────────
Случай  аналогичный 1,  только  процедуру
SET_NAME надо заменить на INP_NAME.

* Если  вы  дискетируете  адвентюру,   то
лучше найти в программе  процедуру  ввода

строки и использовать  ее для ввода имени
файла. Как это можно использовать - пока-
зано ниже. В противном случае вам придет-
ся написать ее самостоятельно.

NAME   EQU   ; адрес, куда считывается
             ; строка
INPUT  EQU   ; адрес процедуры считывания
             ; строки
FROM   EQU   ; параметр "адрес"
LEN    EQU   ; параметр "длина" (BYTES)

INP_NAME
       LD     HL,NAME   ; очищаем имя
       LD     DE,NAME+1 ; файла
       LD     BC,7
       LD     (HL),#20
       LDIR

       CALL   INPUT     ; см. *

       LD     A,"C"      ; тип файла м.б.
       LD     (23781),A  ; любой, кроме
                         ; "#","D","B"

       LD     A,9        ; поиск файла
       LD     (23814),A  ; по 9 символам

       LD     HL,NAME
       LD     B,8
CHECK  LD     A,(HL)
       CP     NN         ; признак конца
       JR     NZ,NEXTS   ; строки код NN
       LD     A,#20      ; заменяем на
       LD     (HL),A     ; пробел
NEXTS  INC    HL
       DJNZ   CHECK
       LD     HL,NAME
       LD     DE,23773
       LD     BC,8
       LDIR
       RET


     И в заключение хочу поделиться одной
подпрограммкой, которая позволяет сменить
дисковод:

вызов: LD     D,n        ; n-номер диска
       CALL   CNG_D      ; 0-A, 1-B, 2-C
       ....

CNG_D  DI
       LD     A,#C9      ; отключаем  об-
       LD     (#5CC2),A  ; работку ошибок
                         ; (см. ADV #5)

       LD     (IY+0),#FF ; сбрасываем
       XOR    A          ; все коды
       LD     (23824),A  ; ошибок

       LD     A,D        ; устанавливаем
       LD     (23833),A  ; системные пе-
       LD     (23798),A  ; ременные TRDOS

       LD     C,1        ; выбор
       CALL   #3D13      ; дисковода

       LD     C,#18      ; настройка на
       CALL   #3D13      ; диск
       EI
       RET 



P.S. Если не делать настройку на диск, то
при смене дисковода может получиться так,
что он будет читать только нулевой трек.


P.P.S. Приведенные в ADV #5 и этом номере
процедуры не являются  идеальными, хотя и
вполне работоспособными. Если кто-то зна-
ет как можно сделать  лучше (или еще луч-
ше - драйвер с прямым программирование ВГ
и обработкой ошибок, например, так: стан-
дартный вызов,  а  по завершению работы в
регистре A код ошибки),  то мы с удоволь-
ствием опубликуем его достижения. Дерзай-
те, виртуозы клавиатуры!


     На этом позволю себе закончить. Если
что-то не понятно - пишите.

         ───────────────────────── 
     Мы продолжаем цикл статей, посвящен-
ных дисковым  загрузчикам.  Слово  нашему
корреспонденту.

            (C) Nicolas Viper

               "Чем ленивее человек, тем
               больше любой его поступок
               похож на подвиг."

                       Народная мудрость


     Задержка великовата, ну а кому нынче
легко ?  Доставайте свои мозги из баночек
с растворами,  протрите,  у  кого запыли-
лись, и вникайте.

     Прежде  всего  необходимо  заметить,
что  утверждение,  будто  в проверке пра-
вильности чтения (далее: ППЧ) ДОС нам по-
мочь не может оказалось НЕВЕРНЫМ. Только,
в свою очередь,  мы  должны  помочь  ему.

Взгляните на листинг:


        ORG   40000
        DI              ;Инсталляция:
        LD    HL,#FD00  ;-Пре
        LD    A,H       ;    ры
        LD    DE,#FD01  ;      ва
        LD    BC,256    ;        ний
        LD    (HL),#FE
        LDIR
        LD    I,A
        IM    2
        CALL  MUSRUN    ;-Музыки
        EI
        LD    DE,#0100  ;-Откуда,
        LD    HL,16384  ; куда и
        LD    B,27      ; сколько будем
        CALL  LOADER    ; грузить
        JP    MUSRUN    ; Music off + RET


*************** ГРУЗИМ *****************

LOADER
        LD    IX,#2F65  ;Раскрутка
        CALL  DOS
L1
        PUSH  DE
        PUSH  BC
        LD    A,D
        OR    A
        RRA
        LD    C,A
        LD    A,#3C
        JR    NC,L2
        LD    A,#2C
L2
        LD    IX,#2F4D  ;Ставим череп на
        CALL  DOS       ;дорогу
        POP   BC
        POP   DE

        PUSH  HL
        PUSH  DE
        PUSH  BC 

        CALL  LOA_COM
        POP   BC
        POP   DE
        POP   HL
                        ;Пересчет:
        INC   H         ;- адреса
        LD    A,E       ;- сек
        INC   A         ;     то
        AND   15        ;       ра
        LD    E,A
        JR    NZ,L5     ;- дороги
        INC   D
L5
        DJNZ  L1        ;Новый сектор

        DI              ;Выход
        IM    1
        EI
        RET

Эта часть не поменялась со времен первого
пришествия. А вот самое важное:

LOA_COM
        LD    C,#5F     ;Пересчет номера
        LD    A,E       ;сектора, засыл-
        INC   A         ;ка в регистр
        LD    IX,#2A53  ;сектора ВГ-шки
        CALL  GODOS
TRY1
        PUSH  HL        ;На стек
        PUSH  DE
TRYMET
        XOR   A            ;Ошибок нет
        LD    (ERRFLG+1),A ;(пока :)
        LD    B,A          ;B=0
        LD    C,#1F     ;Команда
        LD    A,#80     ;"чтение
        LD    IX,#2A53  ;       сектора"
        CALL  DOS
        LD    C,#7F     ;Чтение сектора
        LD    IX,#3FE5
        CALL  GODOS
        POP   DE        ;Взяли со стека
        POP   HL 

ERRFLG
        LD    A,0       ;Проверка на
        OR    A         ;ошибки во время
        JR    NZ,TRY1   ;чтения. (под-
        LD    D,1       ;робнее описано
        LD    IX,#2F2F  ;ниже)
        JP    GODOS

DOS
        HALT
GODOS
        PUSH  IX
        JP    #3D2F
IMCOM                    ;Словили преры-
        LD    (STACK),SP ;вание
        PUSH  IX
        PUSH  HL         ;Тут тоже в
        PUSH  DE         ;двух словах
        PUSH  AF         ;не опишешь :)
        PUSH  BC         ;Ищите подроб-
        CALL  MUSIC      ;ности ниже.
        LD    HL,(STACK)
        LD    E,(HL)
        INC   HL     

        LD    D,(HL)
        LD    A,D
        CP    #40
        JR    NC,RETOS
        CP    #3F
        JR    NZ,PA_CNT
        POP   BC
        PUSH  BC
        LD    A,B
        LD    (ERRFLG+1),A
PA_CNT
        LD    HL,0-#2F3A
        OR    A
        ADC   HL,DE
        JR    Z,RTBR
        LD    A,#C3
POPALL
        LD    (CHANGE),A
        POP   BC
        POP   AF
        POP   DE
        POP   HL
        POP   IX
        EI 

CHANGE
        JP    #3D2F
RETOS
        LD    A,#C9
        JR    POPALL

RTBR
        LD    SP,(STACK)
        POP   AF
        EI
        JP    TRYMET

STACK   DW    0

        ORG   #C000
        INSERT  "MUSIC"

        ORG   #FEFE
        JP    IMCOM

MUSRUN  EQU   #C000
MUSIC   EQU   #C006 

По адресу #2F2F в TR-DOS:

#2F2F   IN    A,(#1F)
        AND   #7F
        RET   Z
        DEC   D
        PUSH  HL
        PUSH  DE
        JR    NZ,#2EXX   ;Неважно куда
        HALT             ;) Ловим!

Кратенько:

По поводу IMCOM : задача этой процедуры -
проверить,  когда пришло прерывание.
     Возможны варианты:
- в ОЗУ.  Тогда нам все по барабану - иг-
  раем музыку и вертаемся.
- в ПЗУ (считаем, что это ДОС!!! По-идее,
  мы в СОС не попадаем).  Тогда  тоже ва-
  рианты:
  - Схватили с  адреса  #2F3A - это  зна-
  чит,  что  мы  словили HALT (см. выше),
  что, в свою очередь, говорит о том, что

  при чтении  произошла  одна  из  "стан-
  дартных"  ошибок  -  потеря данных, не-
  совпадение контрольных сумм и т.п.
  - ...с адреса #3FXX  (XX - любое значе-
  ние) - опять-таки, по идее,  мы там мо-
  жем перехватить  только  процедуру чте-
  ния сектора.  Это  значит,  что, увы, у
  нас  неопределенное  положение  -  надо
  закончить процедуру,  но из-за задержки
  на  проигрывание  мелодии  и  т.п.   мы
  упустили время и чтение  придется  пов-
  торить.

     При возникновении ошибки,  мы кладем
по адресу (ERRFLG + 1) НЕ ноль - это  го-
ворит,  что необходимо перечитать  сектор
(см. с метки ERRFLG).

     Все  остальное  не так сложно и было
расписано  раньше.  Пишите,  если  что не
так, в редакцию или мыльте мне:

         nicky@univ.uniyar.ac.ru 

     Хотя, судя  по предыдущим публикаци-
ям,  вы,  дорогие  читатели, все равно не
обратили  на  данную  процедуру  никакого
внимания -  глюков  в  ней  было полно, а
никто так и  не  написал: "...из-за этого
Вашего #@$&$-го прога я себе дискету  ис-
портил, любимую!"

        (C)  Котов А.В. (CAV Inc.)




Другие статьи номера:

Презентация - Новелла вступление к игре Return Home 4.

Презентация - Презентация новых игр: Новая игра от K.KAV'a - "Return to Home 5".

Система - Oбзор системных новинок: FREE FORMAT v8.3, ALASM v2.8, OMEGA COMMANDER v1.5, PERFECT COMMANDER v1.52, F-COMMANDER v4.02, CHEMNEBASE v0.6, SPRITELAND v1.9, MAXSOFT SCREEN PACKERv1.0, ANIMICROPROTECTOR v1.0), MICRO EDITOR,DISK LEVEL, MAY BE MY BANK v5.1,AFRODITA v3.0, FLOOPY FORMAT UTILITY v1.0, DIGITAL STUDIO PLAYER v1.0, PRO TRACKER PLAYERv1.10, UNRECOGNIZED FORMATING OBJECT v1.1, ZX-WINWORD v1.0

Обзор - Обзор новых игровых программ : KOMANDO-2, PEDRO NA OSTROVE PIRATOV, DIRT TRACK RACER, DOUBLE DRAGON-2, THE CYCLES, STUNT MAN SEYMOUR, CHOY LEE FUT KUNG FU WARRIOR, ARKARUM, KING VALLEY, MURK 3320, THE MYSTER of ARKHAM MAVOR, СКАЗЫ ДРЕВНЕЙ РУСИ: ВИТЯЗЬ СВЯТОГОР И КОЛДУН КАРАЧУН, MAGICIAN LAND, RALLY CROSS, MOVING TARGET, KLADEMINER , LOST CAVES and the TOMB of DOOM, WIZARD WILLY.

Интерфейс - Cheat к игре Heavy Metal Mover. Мнение об ассемблере (какой лучше ?). Вопросы по адвентюрным играм: Last Raider, Витязь Святогор и колдун Карачун, Средневековая история.

Интерфес - разбор почты. Письма от читателей: Колотушкин Сергей, Дмитрий Шадринов, Берников Евгений.

Интерфес - мошенничество на Спектруме - поддельные игры от Overfile.

Интерфейс - Новости : KAV разрабатывает аркадную адвентюру "Ежики мутанты", Nicodim работает над игрой "Legend of Kyrandia", Microfucker. Горячая десятка игр и пятерка электронных журналов из города Ярославля.

Презентация - Презентация новых программ: Road Fighter demo, Font Editor.

Раскрутка - Описание адвентюрных и стратегических игр: Appolo и Чужой, Lord of Chaos, War Game 1, Страна Мифов, Sorcerer Lord.

Оттяг - Терминология юзера или современный разговорный язык.

Оттяг - Маразминки : 10 причин,почему вымерли динозавры. 10 соперников для черепашек-нинзя. 10 вещей,которые не смог бы сделать В.Ван Гог. 10 вещей,которые можно крикнуть , подкравшись сзади к своему дедуле. 10 вещей,которые было бы глуппо говорить тому, кто пришел покупать твой дом. 10 вещей,которые можно подарить глухому родственнику.

Оттяг - крутой ли ты демомейкер?

Оттяг - Что не стоит говорить или делать, если ты нажрался водки.

Оттяг - тест: Есть ли у тебя друзья ?

Оттяг - Китайские пословицы.

Оттяг - "Русские народные чернушки"(сканированные картинки от SERGA)

Обмен опытом - Как сделать дисковую версию программы ?..

Обмен опытом - Что мы выбираем: преимущества и недостатки PC и Амиги.

Обмен опытом - о вирусе в игре Last Battle. Как написать свой вирус.

Обмен опытом - Методы защиты программного кода.

Юбилей - Журналу 1 год (6 номер - юбилейный номер журнала).

Юбилей - Наш юбилей - 15 лет SPECCY и 57 лет Синклеру!

Новелла - Новелла "Черный берет" по игре "Sabouter".

Конкурс - Конкурс GFX - первые работы ...

Реклама - Реклама и объявления.


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

Похожие статьи:
От автора - автора: об авторах журнала.
Навiны - местные новости.
Преамбула - сегодня наша газета выходит в новой оболочке.
Адвентюра - прохождение адвентюрной игры Sea Quest.
Gameland - Игра Шестнашки.

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