ZX-Ревю 1994 №1 1993 г.

Страничка iS-DOS - Адаптация игровых программ системы TR-DOS к профессиональной системе iS-DOS.


Темы статьи: Программирование  

Адаптация игровых программ системы TR-DOS к профессиональной системе iS-DOS

© Михаил Головин тел. (095) 148-50-04, ноябрь 1993 года.

Летом 1993 года на рынке программных средств машин класса ZX появилась качественно новая профессиональная дисковая операционная система iS-DOS. Удобный интерфейс, многокаталоговая файловая система, наличие контекстно-зависимой подсказки и многооконный интерфейс делают эту систему приятной и удобной в повседневной работе.

Несмотря на наличие программ, разработанных и поставляемых с iS-DOS, многие интересующие нас программные средства пока работают только под управлением TR-DOS. Примером таких программ могут служить наборы игрушек, которые есть почти у каждого пользователя. В связи с тем, что диски, работающие в TR-DOS, имеют другую логическую и физическую структуру, чем в iS-DOS, может возникнуть ряд проблем при переносе игр из TR-DOS в iS-DOS. Решить их Вам поможет программа-загрузчик игровых программ TR-DOS, описанная в данной статье (Листинг приведен ниже).

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

Зададимся вопросом: "Как можно адаптировать игры или другие полезные программы к iS-DOS?" Существуют два решения этой проблемы. Первое: Адаптация с помощью средств iS-DOS. Второе: Написать свой собственный загрузчик. В данной статье будут рассмотрены оба варианта.

Многие могут спросить: "А зачем нужна вся эта кутерьма?! Мы и в TR-DOS неплохо играем и работаем." На этот вопрос можно ответить так. iS-DOS многокаталоговая файловая система и каждая игрушка может иметь свой каталог и хранить там свои служебные файлы. Они никогда не перепутаются, как это частенько бывает в TR-DOS. И надо выбрать для себя что лучше: куча дисков одни в TR-DOS, другие в iS-DOS или все диски под одной системой. Надо наводить порядок.

Итак, первый способ адаптации - это адаптация с помощью средств iS-DOS, называемых CDPACKER.COM, NMIPACK.COM, SPACKER.COM. Первый позволяет паковать и делать запускаемыми файлы типа CODE, второй нужен для упаковки MAGIC файлов, а третий для упаковки картинок. Созданные с помощью упаковщиков файлы можно запустить из iS-DOS применив программу EXEPACK.COM и EXESCR.COM соответственно. Как пользоваться всеми перечисленными файлами можно прочесть в системном руководстве к ним (в help файлах).

У этого способа на первый взгляд нет никаких недостатков. Но как только вы начнете его применять на практике к хорошим игрушкам, которые почти не пакуются, вы получите сообщение системы о том, что ей не хватает памяти для работы (распаковки), и Вы ничего с этим сделать не сможете. И напоследок, когда я пробовал использовать CDPACKER.COM, мной была замечена некорректная работа со стеком, в итоге игрушки просто отказывались работать, повисали или просто сбрасывались. Эти и другие причины привели к тому, что в итоге пришлось написать свой собственный загрузчик лишенный многих этих недостатков.

Итак, способ второй.

Используем специально написанный загрузчик (смотри листинг). Чтобы понять работу Game Loader^) нужно разобраться с физической и логической структурой диска, работающего под iS-DOS. С физической точки зрения диски под iS-DOS бывают двух видов: отформатированные под TR-DOS (не загружаемые) и отформатированные под iS-DOS (загружаемые). Первые имеют на каждой дорожке 16 секторов по 256 байт на сектор, а вторые 5 секторов по 1024 байта соответственно (это позволяет сделать их автозагружаемыми). С логической точки зрения все диски это устройства с одинаковой структурой: блоками данных по 256 байт, количество которых записано в заголовке устройства (на диске). Система сама производит при своей работе необходимые пересчеты и поэтому для пользователя этот процесс является прозрачным (не видимым). Многие игрушки для запуска требуют порой почти всю доступную основную память, поэтому все необходимые расчеты должен производить сам загрузчик, так как во

время его работы система iS-DOS из памяти полностью выгружается.

Теперь рассмотрим листинг программы. В качестве средства программирования избран Zeus Assembler (версия входящая в PHT 3.6), позволяющий переустанавливать несколько раз адрес начала ассемблирования директивой ORG и компилирующий прямо на диск с помощью директивы OPEN. Это дало возможность совместить две части загрузчика: Интерфейсную (0110 - 1520) и Основную (1530 - 2670) в одной программе, не требующей настройки адресов последней. Первая часть программы производит настройку второй (системные параметры диска), вторая часть и является собственно загрузчиком.

Строка 0140 содержит имя файла данных (картинка + блок кодов), который будет загружен (о создании этого файла смотри далее).

Строки 0160-0240 и 0260-0310 содержат текст, который появляется при загрузке или ошибке.

Строки 0360-0550 выводят окно с поясняющей надписью на экран, перемещают Основную Часть в буфер принтера (#5B00), вызывают подпрограмму инициализации системных переменных, устанавливает Первый Режим Прерываний и стандартный обработчик сообщений об ошибках (для корректной работы TR-DOS), устанавливает верхнюю границу стека (из расчета Адрес Загрузки Кодов минус 256*3) и передает управление Основной Части (перемещенной уже в буфер принтера: #5B00).

Строки 0590-1120: подпрограмма инициализации системных переменных. Читается заголовок текущего устройства, по соответствующим смещениям определяются и инициализируются Размер Сектора, Количество Секторов на треке, Данные о Секторах на треке Основной Части. Затем производится поиск файла, имя которого записано по адресу FNAME, определяется Номер Блока Описателя Сегмента, Атрибут Состояния Файла и если файл не сегментирован, то Номер Блока Описателя Сегмента будет номером первого блока данных файла (он записывается в переменную FDISP). Если файл сегментирован то читается Блок Описателя Сегмента и проверяется количество сегментов у файла. Если их больше одного, то совершается переход на подпрограмму обработки ошибок (ERROR), иначе номер первого сегмента (блока данных файла) заносится в переменную FDISP. Сбрасывается флаг ошибок (C=0) в регистре флагов, и происходит возврат в основную программу.

Строки 1160-1350: подпрограмма обработки ошибок. Выводит окно с сообщением об ошибке, "бибикает" и выходит в систему.

Строки 1390-1520: подпрограмма звукового сигнала. Формирует звуковой сигнал, с миганием рамки. Затем происходит возврат в вызывающую программу.

Строки 1509-1680 загружают картинку, вызывают распаковщик, загружают блок кодов и передают ему управление.

Строки 1740-2330: подпрограмма чтения секторов. Вызывается подпрограмма преобразования Номера Первого Сегмента в Трек, Сектор, Смещение в секторе (нужно для секторов размером 1024 байта). Изменяется переменная FDISP, чтобы она указывала на следующий блок данных (для этого файл данных должен быть непрерывным). Если Смещение не нулевое, то адрес загрузки файла корректируется соответствующим образом. Это накладывает небольшое ограничение: перед файлом и после него в памяти должно быть пустое (не используемое) место, в котором НЕЛЬЗЯ ни чего располагать, так как оно может использоваться при загрузке. Затем производятся необходимые расчеты для переменных Трек, Сектор. Происходит вызов TR-DOS и загрузка кода данных. Далее берется следующий сектор, если он выходит за пределы трека, то берется следующий трек. И так до тех пор, пока не загрузится нужное количество секторов.

Строки 2350-2650: подпрограмма дешифрации номера блока в номера Трека, Сектора, Смещения.

Строка 2670 содержит Данные о Секторах на Треке (номера секторов).

Что мы должны сделать, чтобы наша программа заработала?

Пусть у нас есть заархивированый файл-картинка SCREEN.CODE 32768,4800 разархивирующийся по команде RANDOMIZE USR 32768 и файл игрушка GAME.CODE 26000,30000 запускаемый командой RANDOMIZE USR 26000. Теперь из этих двух файлов нужно создать один файл данных, назовем его gamefile.dat. Создается он посредством склейки SCREEN и GAME, длина каждого из них должна быть кратной 256 байт. Файлы склеиваются в памяти или прямо на TR-DOS диске. Они записываются друг за другом и у первого файла в директории изменяется количество занимаемое им секторов на суммарное для обоих файлов, также изменяется слово длины файла (оно должно быть кратно 256 байт) , затем первый файл копируется на другой диск или сразу же в iS-DOS.

ВНИМАНИЕ!!!

На том диске, где вы изменяли параметры файла, вы должны восстановить исходное значение количества секторов и слово длины первого файла. Для этих целей можно использовать функции PHT 3.6: записи и восстановления каталога на 80 треке.

Некоторые дисковые мониторы позволяют проделывать операцию склейки автоматически.

Итак файл данных создан. Далее вносим изменения в листинг (строки 0140: вместо <ИМЯ ФАЙЛА ДАННЫ1Х> пишем gamefiledat (без точки !), 0540: <ВЕРШИНА СТЕКА>=26000-256*3 (рассчитать самим), 1610: < ДЛИНА КАРТИНКИ>=19 (блоков по 256 байт), 1620: <АДРЕС ЗАГРУЗКИ>=32768, 1640: <АДРЕС РАЗ АРХИВ АТОР А>=32768, 1650: < ДЛИНА ИГРУШКИ>=118 (блоков по 256 байт), 1660:<АДРЕС ЗАГРУЗКИ>=26000, 1680: <СТАРТОВЫЙ АДРЕС>=26000.

Ассемблируем получившийся листинг в .com файл, переносим в iS-DOS не забыв исправить с помощью команды rename (iS-DOS) или аналогичной команды PHT 3.6 стартовый адрес на тот, который указан в строке 0080, перенося в этот же каталог файл данных, получим экземпляр игрушки загружающейся в iS-DOS.

Примечания.

1. Обращение к системным функциям iS-DOS происходит через RST #10. Код вызываемой функции помещается в регистр C, остальные регистры инициализируются по мере необходимости. При возврате обычно используется альтернативный набор регистров. Если возникает ошибка, то флаг C в регистре флагов устанавливается, иначе сбрасывается.

2. Длинные файлы (более 127 блоков) при копировании получаются всегда сегментированными. Если они копируются из TR-DOS посредством from_trd.com или при помощи модифицированной мной программы filecopy.com с ключом /l, то этого можно избежать.

3. Следует помнить, что при копировании файлов в iS-DOS учитывается не сколько он занимает блоков, а его реальная длина. Так если файл занимает 10 блоков и имеет длину 1 байт, то в iS-DOS скопируется только этот байт.

Листинг программы-загрузчика игровых программ TR-DOS. iS-DOS Utility: Game Loader v1.00 25-Nov-1993 (C) by M.Helloween

0010 0020 0030 0040 0050 0060 0070 0080 0090 0100 0110 0120 0130 0140 0150 0160 0170 0180 0190 0200 0210 0220 0230 0240 0250 0260 0270 0280 0290 0300 0310 0320 0330 0340 0350 0360 0370 0380 0390 0400 0410 0420 0430 0440 0450 0460 0470 0480

0490 0500 0510 0520 0530

ORG JP

"<ИМЯ ФАЙЛА ДАННЫХ>"

FNAME DM

TEXT1

"iS-DOS "Loader #0D,

#0D,

" iS-DOS #0D,

" by

#03

Game" v1.00"

DM DM DB DM DB DM DB DM DB

DM DB DM DB DM DB

DB DB

LD

LD

LD

RST

LD

LD

RST

LD

LD

LD

LDIR

CALL

RET

DI

IM

LD

LD

TEXT2

ВНИМАНИЕ!

Zeus Assembler ( PHT v3.6 )

Адрес загрузки .com файла: #5DC0 (24000)

#5DC0 START

Данные о .dat файле и тело "Интерфейсной Части"

"Имя .dat Файла"

"Текст Заставки"

&

Game Adaptation"

M.Helloween"

"Текст Ошибки"

# 0D, # 0D,

"Файл Данных должен быть'

# 0D,

" НЕПРЕРЫВНЫМ"

#03

4, 9, 6, 24, 58,5 9, 24

IX,V_WND A,2 C,#61 #10

HL,TEXT1 C,#67 #10

HL,GAMLO DE,_GAM_

bc,#0100

;Перекинуть INITS

C 1

A, #C9 (#5CC2),A

V WND

START

"Вектор Окна"

; Адрес " Вектора Окна "

;Код: "Вывод Окна"

;Адрес "Текста Заставки" ;Код: "Печать Текста (HL)

Окне"

'Основную Часть"

буфер принтера Инициализировать системные переменные

Включить 1 :Установить

Режим Прерываний стандартный обра

ботчик сообщений об ошибках

LD SP,<ВЕРШИНА CTEKA>

JP _GAM_

;

;Инициализация системных переменных ;

INITS LD C,#06

LD

RST

RET

EXX

LD

ADD

LD

LD

INC

LD

LD

LD ADD LD LD

LDIR

LD

LD

RST

RET

EXX

PUSH

LD

ADD

LD

INC

LD

POP

LD

ADD

LD

AND

JR

LD

DE,#0000 #10

C

BC,00024 HL,BC A,(HL) (SSIZE),A HL

A,(HL) (QSECT),A

BC,00039 HL, BC DE,STBUF

bc,#0010

HL,FNAME

C, #34 #10

C

HL

BC,#0011 HL, BC E,(HL) HL

D,(HL) HL

BC,00011 HL, BC A,(HL) #40

NZ, NEXT9 C, #06

0970 0980 0990

1000 RST #10

1010 EXX

1020 LD A, (HL)

1030 DEC A

104 0 JP NZ,ERROR

1050 INC HL

1060 LD E, (HL)

1070 INC HL

1080 LD D, (HL)

1090

1100 NEXT 9 LD (FDISP) ,DE

1110 XOR A

1120 RET

1130 ;

114 0 ;Ошибка: Файл сегментирован

1150 ;

1160 ERROR LD IX,V_WND

0540 0550 0560 0570 0580 0590 0600 0610 0620 0630 0640 0650 0660 0670 0680 0690 0700 0710 0720 0730 0740 0750 0760 0770 0780 0790 0800 0810 0820 0830 0840 0850 0860 0870 0880 0890 0900 0910 0920 0930 0940 0950 0960

;Переход на "Основную Часть"

;Код: "Загружает Блок (DE) ;текущего устройства и возвращает ;его адрес в регистровой паре HL"

;Инициализация "Размера Сектора'

;Инициализация "Колличества ;Секторов на Треке"

;Инициализация "Данных ;о Секторах на Треке" ;Адрес "Имени .dat Файла" ;Код:"Поиск и Открытие Файла"

;DE= Номер Блока Описателя Сегмента

; Атрибут Состояния Файла

; Переход, если Файл не ; Сегментирован ; Код: "Загружает Блок (DE) ; текущего устройства и возвращает ;его адрес в регистровой паре HL"

; Переход, если Файл Сегментирован

;DE = Номер Блока первого сегмента, ; если Файл Данных ОдноСегментен

; Сбросить Флаг Ошибок

; Адрес " Вектора Окна "

1170

LD

(IX+4),23

1180

LD

(IX+6),10

1190

LD

A, 2

1200

LD

C,#61

;Код: "Вывод Окна"

1210

RST

#10

1220

LD

HL,TEXT2

;Адрес "Сообщения об Ошибке"

1230

LD

C,#67

;Код: "Печать Текста (HL) в Окне"

1240

RST

#10

1250

CALL

BEEP

;"Посигналить" об Ошибке

1260

POP

HL

1270

LD

C, #07

; Код: "Ввод Символа (A)"

1280

RST

#10

1290

XOR

A

1300

LD

A, #F4

;Код: "Выход с Очисткой Экра-

1310

;на, инициализацией системных

1320

;переменных, переключение на

1330

; основное устройство печати в

1340

;прямом режиме"

1350

RET

1360

;

1370

;

Звуковой сигнал

1380

;

1390

BEEP

XOR

A

1400

LD

B, A

1410

BEEP 1

DEC

H

1420

JR

NZ,BEEP2

1430

XOR

#11

1440

OUT

(#FE),A

1450

LD

H, #EE

1460

BEEP2

DEC

L

1470

JR

NZ,BEEP1

1480

XOR

#11

1490

OUT

( #FE) ,A

1500

LD

L, #FE

1510

DJNZ

BEEP1

1520

RET

1530

1540

iS-DOS GAME

LOADER V1.00

1550

("Основная часть")

1560

1570

Адре

с загрузки: #5B00 (23296)

1580

1590

GAMLO

EQU

$

1600

ORG

#5B00

1610

_GAM_

LD

C,<ДЛИНА КАРТИНКИ>

; Длина Картинки в блоках (256 байт)

1620

LD

HL,<АДРЕС ЗАГРУЗКИ>

;Адрес Буфера загрузки Картинки

1630

CALL

READS

1640

CALL

<АДРЕС РАЗАРХИВАТОРА>

; Вывод Картинки на Экран

1650

LD

C,<ДЛИНА ИГРУШКИ>

; Длина Игрушки в блоках (256 байт)

1660

LD

HL,<ДДРЕС ЗАГРУЗКИ>

; Адрес Буфера загрузки Игрушки

1670

CALL

READS

1680

JP

<СТАРТОВЫЙ АДРЕС>

; Запуск игрушки

1690

;

1700

;

Подпрограмма чтения сектора

1710

;

HL =

Адрес

буфера

1720

;

C =

Количество секторов

1730

;

1740

READS

CALL

G_TSD

; Инициализация переменных

1750

;"Трека, Сектора, Смещения"

1760

PUSH

HL

1770

LD

B, #00

1780

LD

HL, (FDISP)

1790

ADD

HL, BC

;HL = Номер Блока следующего

;сегмента

1800

LD

(FDISP),HL

1810

POP

HL

1820

DISPL

EQU

$ + 1

1830

LD

A, #00

1840

LD

B, A

1850

INC

B

1860

LD

DE,#0100

1870

_LOOP

OR

A

1880

SBC

HL, DE

1890

INC

C

1900

DJNZ

_LOOP

1910

ADD

HL, DE

1920

DEC

C

1930

LD

A, C

1940

LOOP 1

PUSH

AF

1950

TRACK

EQU

$+1

1960

LD

D,0

1970

PUSH

HL

1980

SECTR

EQU

$+1

1990

LD

C,0

2000

LD

B, #00

2010

LD

HL,STBUF

2020

2030

ADD

HL, BC

2040

LD

E,(HL)

2050

POP

HL

2060

PUSH

HL

2070

LD

BC,#0105

2080

CALL

#3D13

2090

POP

HL

2100

LD

A,(SSIZE)

2110

LD

B, A

2120

LD

DE,#0100

2130

???00

ADD

HL, DE

2140

DJNZ

???00

2150

LD

A, (SECTR)

2160

INC

A

2170

QSECT

EQU

$+1

2180

2190

CP

0

2200

JR

NZ,NEXT1

2210

LD

A,(TRACK)

2220

INC

A

2230

LD

(TRACK),A

2240

XOR

A

2250

NEXT1

LD

(SECTR),A

2260

SSIZE

EQU

$+1

2270

LD

C, #01

2280

POP

AF

2290

OR

A

2300

SBC

A, C

2310

JR

Z,NEXT2

2320

JR

NC,LOOP1

2330

NEXT2

RET

2340

;

2350

G_TSD

PUSH

HL

2360

FDISP

EQU

$+1

2370

LD

HL,#0000

2380

LD

A,(SSIZE)

2390

LD

E,A

2400

XOR

A

2410

LD

(SECTR),A

2420

LD

(TRACK),A

;Адрес Переменой "Смещение"

;Адрес Переменной "Трека"

;Адрес Переменной "Сектора'

;HL = Адрес "Данных ;о Секторах на Треке"

Код: "Считать Один Сектор

в TR-DOS" Системный вызов TR-DOS

;A = Размер Сектора

;A = Номер Сектора

;Адрес "Переменной Количество ; Секторов"

; Адрес " Переменной Размер Сектора "

;A = Номер Трека

;A = Размер Сектора

;Начальная установка переменных: "Сектора и Трека"

2430

LD

D,A

2440

LOOP3

OR

A

2450

SBC

HL, DE

2460

JR

C,NEXT4

2470

LD

A,(SECTR)

2480

INC

A

2490

PUSH

HL

2500

LD

HL,QSECT

2510

2520

CP

(HL)

2530

POP

HL

2540

JR

NZ,NEXT3

2550

LD

A,(TRACK)

2560

INC

A

2570

LD

(TRACK),A

2580

XOR

A

2590

NEXT3

LD

(SECTR),A

2600

JR

LOOP3

2610

NEXT4

ADD

HL, DE

2620

LD

A, L

2630

LD

(DISPL),A

2640

POP

HL

2650

RET

2660

;

2670

STBUF

DS

#10

;A = Номер Сектора

;"Данные о Секторах на Треке'

;HL = Адрес Переменной ;"Количество Секторов"

;A = Номер Трека

;A = Смещение в секторе




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Вступление - содержание номера.
О всем про все - "Проклятые места России".
Статьи - "FAQ "ZX-Traders"
Анкета - Mast.
CC000 Report - Jocker & Klim побывали на Chaos Constructions 2000 и делятся впечатлениями.

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