ZX-Forum №3 1995 г.

Секреты TR-DOS - Полная адаптация программ к диску без использования системных переменных TR-DOS.


СЕКРЕТЫ TR-DOS

Полная адаптация программ к диску без использования системных переменных TR-DOS

(На примере игры DUNDARACH фирмы GARGOYLE GAMES)

© Станислав Шилов, г. Пермь, 1995.

В последнее время на дисках появилось множество адвентюрных программ с одним недостатком - у них нет выгрузки на диск. На диск программу перевести не так уж сложно, а вот сделать приличную процедуру загрузки/выгрузки положения игры с диска, куда сложнее. Зачастую стандартными приемами TR-DOS здесь не обойдешься, т.к. большинство игр с выгрузками расположены сразу после системных переменных Бейсика или вообще занимают всю память, так что для системных переменных TR-DOS, тем более для буфера TR-DOS совершенно нет места. Как же поступают в таком случае? Самое простое, что можно сделать - это сделать программу записывающей выгрузки саму в себя. Все кодовые блоки такой программы, обычно соединяют вместе в один бейсик-блок и оставляют несколько секторов после всех кодовых блоков для выгрузки. Для записи и загрузки положения можно воспользоваться двумя подпрограммами в ПЗУ TR-DOS: #2D73 -запись сектора, #2F1B - чтение сектора. Для чтения/записи блока секторов придётся писать собственную программку (уже готовая есть в SPECTROFON^ № 3). Но у этого способа адаптации есть несколько недостатков. Перечислю их. Во-первых, если попытаться записать положение игры на защищенный от записи диск, то на экране появится сообщение "READ ONLY...", после чего можете спокойно сбрасывать игру и перезагружать снова. Аналогичная ситуация возникает при сбойном секторе, только возникнет сообщение "DISK ERROR.". Например, если в дисковод поставить IS-DOS диск и попробовать загрузить положение игры, то на экране возникнет вышеупомянутое сообщение. Во-вторых, очень сильно пользователя ограничивает только одна выгрузка в игре, тем более сложной.

Как же избежать этих недостатков? В приведенных в этой статье программах устранены все перечисленные ошибки, но есть один недостаток, т.к. в DUNDARACH совершенно не было места для процедур чтения/записи, поэтому можно поступить следующим образом. Подгружать все программы чтения/записи файлов с диска, а в памяти оставить только программу чтения секторов с диска. Программу, которая загружает сектора, и постоянно находится в памяти, будет в дальнейшем назваться - "считывающей", а программа, которая загружается в память с диска - "основной".

"Основная" программа подгружается в экранную область с диска с помощью "считывающей" программы, которая находится в памяти вместо кассетных подпрограмм. После чего запускается " основная" программа и выполняет запись или загрузку файла с выгрузкой. Сначала рассмотрим, так называемую "считывающую" программу. При вызове опции 2 (SAVE GAME) или 3 (RESTORE GAME) меню OPTIONS, программа переходит соответственно на метки JRSAVE и JRLOAD. Затем очищается экран (строка 170), после чего инициализируется дисковод методом прямого обращения к ВГ-93 (об этом методе я расскажу позже). Затем читаем несколько секторов в экранную область с адреса #4B00 (переменная DATPLC) с "основной" программой (строки 240-660, 810-940). После этого проверяем считанную информацию, если первые два байта равны #A7, #1F, то значит, в дисководе стоит нужный диск, иначе программа просто выйдет в меню OPTIONS. После этого запускается "основная" программа. Теперь объясняю, как всё работает в "основной" программе. Сначала запрашиваем версионную букву выгрузки (подпрограмма ENTNAM), затем считываем каталог диска (подпрограмма RDCAT) с адреса #5000 (пер. CAT). После чего проверяется длина каждого файла, если длина файла соответствует длине выгрузке, то данные этого файла переносятся на адрес #5000, затем #5010 и т.д. Затем сравнивается каждое имя прошедшего проверку файла с данными нужного нам имени с адреса #AF2C-FNAME (подпрограмма FINDAF), если файл соответствует нужной выгрузке, то процедура LOAD загружает данные файла сначала в буфер с адреса #4000, а затем перекидывает нужное количество байтов в память программы командой LDIR. Если процедура SAVE находит файл, соответствующий выгрузке, то сразу переходит на процедуру записи данных, т. е. попросту перезаписывает его, иначе создает новый файл в каталоге диска (подпрограмма NEWF). При создании нового файла с адреса #4F00-CATDAT загружаются данные диска, вносятся требуемые изменения, после чего они записываются на диск. Затем загружается сектор с последним файлом и в этот сектор заносится имя нового файла, после чего подпрограмма SVE записывает данные в файл. Ну, вот в принципе и вся работа "основной" программы.

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

1. Попытка записи на защищенный диск;

2. Попытка записи на не отформатированный диск;

3. Попытка чтения выгрузки с диска со сбойными секторами или с не TR-DOS диска.

В случае этих ошибок программа будет ждать пока Вы не вставите другой диск или не нажмете клавишу SPACE для выхода в меню OPTIONS. Если в дисководе нет диска, то программа будет ждать до тех пор, пока Вы его не вставите. Ошибки, которые сопровождаются сообщением:

1. Нет выгрузок на диске (NO FILE(S) ON DISK);

2. Файл не найден (FILE ABSENT);

3. Нет места на диске (NO SPACE ON DISK).

Вот и все возможные ошибки, которые могут возникнуть у Вас при работе с диском.

Третьей отдельной программой, которая входит в дисковый DUNDARACH - это программа START. Компилируется она вместе со "считывающей" программой, т.к. вносит изменения именно в эту программу. Она настраивает программу на текущий дисковод (A...D), на тип дисковода (односторонний, двухсторонний) и дает "считывающей" программе координаты "основной" программы (дорожка, сектор). Ну, вот я и объяснил все что мог, остальное ищите в комментариях к программам.

Теперь объясню метод обращения напрямую к ВГ-93. Приведенные в этой статье программы пользуются только тремя подпрограммами TR-DOS.

Занесение в регистры ВГ-93 команд.

#20B8 OUT (C),D ;В регистре C номер порта, в регистр D - число

#2 0B8 OUT

(C) ,D

;В регистре C номер порта, в регистр D - число

DJNZ

#2 0B1

;В регистре B обязательно должна быть 1.

RET

;Выход.

Жалко, что разработчики TR-DOS не догадались написать аналогичную подпрограммку для

чтения портов. Если бы она была, то можно было читать регистр состояния ВГ-93.

Запись данных на диск.

#3FCA IN

A, (#FF)

;Регистр состояния ВГ-93.

AND

#C0

;Ожидание

JR

Z,# 3 FCA

;готовности ВГ-93.

RET

M

,'Выход, если ВГ-93 окончил запись.

OUT I

;Вывод байта на диск.

JR

#3FCA

'Переход на запись следующего байта.

Чтение данных с диска.

#3FE5 IN

A, (#FF)

'Регистр состояния ВГ-93.

AND

#C0

; Ожидание

JR

Z,#3FE5

'готовности ВГ-93.

RET

M

;Выход, если ВГ-93 окончил загрузку.

INI

;Ввод байта с диска.

JR

#3FE5

'Переход на загрузку следующего байта.

Все остальное, относящееся к ВГ-93 Вы можете прочитать в ZX-РЕВЮ № 4, 1994, стр. 10 и в ZX-РЕВЮ № 5, 1994, стр. 19. Для читателей, которые хотят применять "основную" программу для собственных, даю подпрограмму PRINT, без которой ничего работать не будет отдельно от игры.

PRINT

POP

HL

' адрес возврата из подпрограммы в регистре HL

CALL

PRN

'Вызываем подпрограмму печати.

JP

(HL)

'Выходим на следующий после текста оператор.

PRN

LD

A,(HL)

'В регистре A символ.

INC

HL

'HL=HL+1

CP

П a П "%"

' Конец текста?

RET

Z

'Если да, то выход.

PUSH

HL

RST

#10

'Печатаем символ.

POP

HL

JR

PRN

'Переход на следующий символ.

FNAME

DEFM

"dun

H

;имя файла (8 байтов).

LETTER

DEFB

II и

;Версионная буква.

DEFB

#20,

#20

DEFB

#20,

#20

TYPE

DEFB

"С"

;тип файла "С" - CODE.

LSTR

DEFB

00

; стартовый адрес файла

HSTR

DEFB

00

LLEN

DEFB

AC

;длина файла.

HLEN

DEFB

0A

SLEN

DEFB

0B

;длина в секторах.

SSECT

DEFB

00

;Начальный сектор.

STRK

DEFB

00

;Начальная дорожка.

Если Вы используете другие данные в описании файла, то не забудьте в "основной" программе исправить строки 1440, 1470, 1490.

Считывающая программа.

;Переход на следующий символ. Ещё хочу сказать, что с адреса на которую указывает переменная FNAME, должны быть все данные о файле. Т.е. если Вы хотите использовать программу в своих целях, то вместо команды FNAME EQU #AF2C вставьте:

10

ORG

#AFE5 'Адрес компиляции программы.

2 0 SAVE

EQU

#4C9B 'Адрес подпрограммы записи.

3 0 LOAD

EQU

#4C14 'Адрес подпрограммы загрузки.

4 0 DATPLC

EQU

#4B00 'Адрес загрузки основных подпрограмм.

5 0 PRINT

EQU

#AD1A 'Адрес подпрограммы печати.

60 RDCAT

EQU

#4B96 'Адрес подпрограммы чтения каталога.

7 0 MENU

EQU

#AF3C 'Адрес выхода в меню.

8 0 BLKLNG

EQU

#0300 'Длина в секторах загрузочного блока.

90 CLS

LD

HL,#5800 'Подпрограмма очистки экрана.

100

LD

DE,#5801 '

110

LD

BC,#02 FF '

120

LD

(HL),L '

130

LDIR

'

140

RET

'

15 0 JRSAVE

LD

HL,SAVE 'Сюда осуществляется переход

160

JR

LOADAT ' из опции 2 (SAVE GAME),

170 JRLOAD

LD

HL,LOAD ' из опции 3 (RESTORE GAME)

180 LOADAT

LD

(COMAND+1),HL 'Установка перехода.

190

CALL

CLS 'Очищаем экран.

200

CALL

BG93

Инициализируем дисковод.

210

DEFB

#1F

220

RES

DEFB

#0C

230

CALL

RESET

Очистка ВГ-93.

240

CALL

BG93

Устанавливаем головку дисковода на

250

DEFB

#7 F

нужную дорожку в регистр данных.

260

TRACK

DEFB

#00

Номер дорожки.

270

CALL

BG93

Устанавливаем системный регистр

280

DEFB

#FF

(#3^сторона 1, #2^сторона

290

SIDE1

DEFB

#3C

0 для дисковода A).

300

CALL

BG93

Команда ВГ-93 поиска

310

DEFB

#1F

дорожки и стороны.

320

DEFB

#1C

#1C=000111000b.

330

CALL

RESET

Очистка ВГ-93.

340

LD

HL,DATPLC

Адрес загрузки в памяти.

350

SECTOR

LD

BC,BLKLNG

Регистр B-длина, регистр C-сектор.

360

LOOP

PUSH

BC

Сохранение BC.

370

PUSH

HL

Сохр. адр. начала загрузки.

380

LD

A, C

Устанавливаем

390

LD

(SECTPL),A

сектор из

400

CALL

BG93

регистра С

410

DEFB

#5 F

в порт #5F

420

SECTPL

DEFB

#01

TR-DOS.

430

CALL

BG93

Команда ВГ-93 -

440

DEFB

#1F

- чтение сектора.

450

DEFB

#80

#80=10000000b.

460

POP

HL

В HL - адрес

470

PUSH

HL

начала загрузки.

480

CALL

R_LOAD

Вызов подпрограмма чтения сектора.

490

POP

DE

Проверка

500

PUSH

DE

на ошибку

510

INC

D

чтения,

520

AND

A

если HL

530

SBC

HL, DE

не

540

POP

HL

равен 0,

550

POP

BC

то

560

JR

NZ,EXIT

выход в меню.

570

LD

A, #7 F

Если нажата

580

IN

A, (#FE)

клавиша

590

AND

#01

SPACE, то

600

JR

Z,EXIT

выход в меню.

610

INC

H

Адрес=адрес+#0100.

620

INC

C

Увеличение номера сектора.

630

LD

A, C

Если номер=#11 (конец дорожки),

640

CP

#11

то переход на следующую

650

JR

Z,NEXTRK

дорожку или сторону.

660

DJN

DJNZ

LOOP

Чтение следующего сектора.

670

LD

HL,DATPLC

Если первые

680

LD

A, #A7

два байта

690

CP

(HL)

прочитанного

700

JR

NZ,EXIT

блока

710

LD

A, #1F

не равны #A7,#1F,

720

INC

HL

то

730

CP

(HL)

выход

740

JR

NZ,EXIT

в меню.

750

CALL

NAST

Настройка номера дисковода.

760

EI

770

CALL

RDCAT

Чтение каталога.

780

COMAND

CALL

#0000

вызов подпрограмм SAVE или LOAD.

790

EXIT

EI

Выход

800

JP

MENU

в меню OPTIONS.

810

NEXTRK

Подпрограмма перехода

820

PUSH

BC

на следующую дорожку.

830

PUSH

HL

840

NOFORW

CALL

BG93

Команда сдвига головки

850

DEFB

#1F

дисковода на 1 шаг, если

860

FORWRD

DEFB

#5C

сектор находится между 0 и

870

CALL

RESET

1 дорожками, то с метки NOFORW

880

JMP

CALL

BG93

при старте программы будет

890

DEFB

#FF

поставлена команда JR JMP.

900

SIDE0

DEFB

#2C

Установка стороны 1 или 0.

910

POP

HL

920

POP

BC

930

LD

C, 1

Установка номера сектора=1.

940

JR

DJN

Переход на чтение следующий сектор

950

BG93

EX

(SP),HL

Берем после CALL

960

LD

C, (HL)

в регистр C - порт TR-DOS,

970

INC

HL

а в регистр D - число,

980

LD

D, (HL)

посылаемое в этот порт.

990

INC

HL

1000

EX

(SP),HL

На стеке - адрес возврата+2.

1010

PUSH

HL

Посылаем HL на стек.

1020

LD

HL, #20B8

В HL - адрес в ПЗУ TR-DOS

1030

LD

B, #01

подпрограмма записи числа

1040

JR

TRDOS

в порт TR-DOS.

1050

RESET

LD

HL,#00 00

Подпрограмма очистки ВГ-93.

1060

R_LOAD

LD

DE,#00 00

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

1070

LD

C, #7 F

адрес начала загрузки.

1080

PUSH

HL

Сохраняем HL.

1090

LD

HL,#3FE5

В HL-адрес подпрограммы чтения сектора

1100

TRDOS

DI

1110

EX

(SP),HL

Меняем содержимое стека и HL.

1120

JP

#3D2 F

Переход в ПЗУ TR-DOS.

1130

NAST

LD

A,(SIDE1)

Настройка

1140

OR

#10

загруженной

1150

LD

(#4906),A

подпрограммы

1160

AND

#EF

на номер

1170

LD

(#4 90A) ,A

дисковода (0...3).

1180

RET

1185

;-----

1190

START

Подпрограмма запуска.

1200

LD

A, (#5CF4)

В регистр A - текущий сектор.

1210

INC

A

увеличиваем на 1.

1220

LD

(SECTOR+1),A

сохраняем в программе.

1230

LD

A, (#5CF6)

В регистре A - номер дисковода.

1240

LD

E, A

Сохраняем в регистре E.

1250

ADD

A, #C8

В регистре

1260

LD

L, A

HL - адрес кода, определяющего

1270

LD

H, #5C

режим работы дисковода.

1280

LD

A, #3C

В регистре A - код системного

9

1290

ADD

A, E

регистра ВГ-93, для стороны 1.

1300

LD

E, A

1310

LD

D, A

1320 SIDE1

BIT

1,(HL)

Проверка типа дисковода.

1330 SSIDE

LD

A,(#5CF5

)

В A - номер текущего трека.

1340

JR

Z, SSIDE

Если односторонний, то переход.

1350

AND

A

Проверка

1360

RRA

текущей стороны,

1370

JR

C, SIDE1

если флаг C, то сторона 0.

1380

RES

4, D

В D системного регистра для стороны 0.

1390

LD

HL,#0618

Установка перехода в подпрограмму

1400

LD

(NOFORW)

, HL

сдвига головки.

1410

JR

SSIDE

1420

RES

4, E

1430

LD

(TRACK) ,

A

Установка дорожки.

1440

LD

A, D

1450

LD

(SIDE0),

A

Установка текущей стороны.

1460

LD

A, E

1470

LD

(SIDE1),

A

Установка следующей стороны. Старт программы.

Основная программа.

10

ORG

#4B00

;Адрес компиляции программы.

2 0 WYGR

EQU

#B0D6

;WYGR - начало выгрузки.

3 0CATDAT

EQU

#4 F0 0

;CATDAT-адрес, с которого будут загружены ;данные диска (дорожка 0,сектор 9).

4 0 BUFFER

EQU

#4000

;Начало буфера выгрузки.

5 0 LENGHT

EQU

#0AAD

;Длина выгрузки в DUN DARACH.

60 CAT

EQU

#5000

;Адрес загрузки каталога.

7 0 FNAME

EQU

#AF2C

;Начало имени файла выгрузки.

8 0 PRINT

EQU

#AD1A

;Адрес процедуры печати.

90 CLS

EQU

#AFE5

;Адрес процедуры очистки экрана.

100 RDSECT

EQU

#0B00

;

110 RDS1

EQU

#000B

; Количество секторов в выгрузке.

120 RDS2

EQU

#0B

;/

130 LETTER

EQU

#AF2F

;Буква в имени файла выгрузки.

140 GO TR

AND

A

;GO TR-Подпрограмма поиска дорожки.

;В регистре

A должна

быть

установлена искомая дорожка.

150 SDRIVE

RRA

;Проверка стороны.

160

LD

(TRACK) ,

A

^охранение дорожки деленной на 2.

170

LD

A, #3C

;#3C-код 1 стороны для диска A.

180

JR

NC,SIDE1

;Если флаг NC, то переход,

190

LD

A, #2C

; иначе установка стороны 0.

200 SIDE1

LD

(SYSREG)

,A

;Сохранение определенной стороны.

210

CALL

BG93

;Установка стороны диска

220

DEFB

#FF

;в порту ВГ-93.

230 SYSREG

DEFB

#3C

;Сторона дисковода.

240

CALL

BG93

;Установка регистра дорожки.

250

DEFB

#7 F

;Адрес порта дорожки-#7F.

2 60 TRACK

DEFB

#00

;Номер дорожки.

270

CALL

BG93

;

280

DEFB

#1F

;Порт команд-состояния ВГ93.

290

DEFB

#18

;#18=00011000-поиск дорожки.

300

CALL

RESET

;Очиска ВГ-93.

310

RET

;

320 CATSAV LD HL,CATDAT ;ONDISK-Процедура записи сектора на диск.

/Параметры: HL-начало записываемого блока в памяти, после CALL должен ;стоять номер сектора.

330

ONDISK

LD

A,#A4

Подпрограмма записи данных каталога.

#A4=10100100b-запись сектора.

340

LD

(S OR L),A

Установка переменных записи.

350

LD

DE,R SAVE

В DE адрес подпрограммы вывода на диск

360

JR

JMP1

370

LOAD C

LD

HL,CATDAT

Подпрограммы загрузки каталога.

380

FROM D

LD

A,#8 0

#80-команда чтения сектора.

390

LD

(S OR L),A

Установка переменных загрузки.

400

LD

DE,R LOAD

В DE - адрес подпрограммы чтения.

410

JMP1

LD

(ROUTIN+1),DE

Установка перехода.

420

EX

(SP),HL

Обмен содержимым стека с НL.

430

LD

A, (HL)

В регистр A номер сектора.

440

INC

HL

увеличить адрес возврата на 1.

450

EX

(SP),HL

Обратный обмен HL и стека.

460

LD

(SECTOR) ,A

Установка сектора.

470

LOOP1

PUSH

HL

Сохранение HL.

480

CALL

BG93

Номер сектора - в регистр.

490

DEFB

#5 F

#5F-регистр сектора.

500

SECTOR

DEFB

#01

Номер сектора.

510

CALL

BG93

Команда записи или загрузки,

520

DEFB

#1F

в зависимости от установленных

530

SORL

DEFB

#80

раннее переменных.

540

POP

HL

Восстановление первоначаль

550

PUSH

HL

ного значения HL.

560

ROUTIN

CALL

R LOAD

Исполнение SAVE или LOAD.

570

LD

A, #7 F

Проверка нажатия клавиши

580

IN

A, (#FE)

SPACE, если клавиша нажата,

590

AND

#01

то выход из подпрограммы.

600

JR

Z,BREAK

610

LD

DE,#0100

Проверка считанного или записанного

620

AND

A

сектора, если он

630

SBC

HL, DE

не равняется 256 байтам, то

640

POP

DE

повтор записи или считывания

650

PUSH

DE

660

SBC

HL, DE

670

BREAK

POP

HL

680

JR

NZ,LOOP1

Повтор чтения/записи при ошибке.

690

RET

700

BG93

EX

(SP),HL

Берем после CALL BG93

710

LD

C, (HL)

в регистр C-порт TR-DOS,

720

INC

HL

в регистр D-число, которое

730

LD

D, (HL)

нужно занести в этот порт.

740

INC

HL

750

EX

(SP),HL

Восстановить адрес возврата+2.

760

PUSH

HL

770

LD

HL, #20B8

В HL-адрес подпрограммы записи

780

LD

B, 01

в порты TR-DOS.

790

JR

TRDOS

800

RESET

810

LD

HL,#0000

Очистка ВГ-93.

820

R LOAD

LD

DE,#00 00

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

830

LD

C, #7 F

840

PUSH

HL

850

LD

HL,#3FE5

860

TRDOS

DI

870

EX

(SP),HL

Меняем регистры HL со стеком.

880

JP

#3D2 F

Вход в ПЗУ TR-DOS.

890

R SAVE

LD

DE,#00 00

Подпрограмма вывода на диск.

900

LD

C, #7 F

910

PUSH

HL

920

LD

HL,#3FCA

930

EX

(SP),HL

940

JP

#3D2 F

Вход в ПЗУ TRDOS.

950

RDCAT

CALL

ENTNAM

RDCAT-Подпрограмма чтения каталога

;и сортировки имен. Установка буквы в имени файла.

960

CALL

CLS

Очистка экрана.

970

XOR

A

Установка головки на

980

CALL

GO TR

нулевую дорожку.

990

CALL

LOAD C

Загрузка каталога в память.

1000

DEFB

#09

Сектор 09, дорожка 0.

1010

LD

A,(CATDAT+#E3)

Проверка количества секторов на

1020

BIT

3,A

одной дорожке, если 8, то

1030

JR

Z,DDRIVE

происходит смена

1040

XOR

A

переменных для

1050

LD

(SDRIVE),A

одностороннего

1060

LD

A, #08

дисковода.

1070

LD

(SSECT+1),A

1080

DDRIVE

LD

HL,CAT

Считывание имен файлов с

1090

LD

C, #08

диска в память с адреса #5000.

1100

LOOP2

PUSH

BC

Счетчик на чтение первых

1110

LD

A, #09

8 секторов каталога.

1120

SUB

C

A=A-C

1130

LD

( SECT1) ,A

установка текущего сектора.

1140

CALL

FROM D

считывание сектора.

1150

SECT1

DEFB

#09

1160

POP

BC

Восстановление BC.

1170

LD

DE,#0010

Проверка имен файлов.

1180

LD

B, E

Установка счётчика на 16 имён.

1190

LOOP3

LD

A,(HL)

Проверка первой буквы

1200

AND

A

имени, если она

1210

JR

Z,C FILE

равна 0, то выход,

1220

ADD

HL, DE

иначе проверка

1230

DJNZ

LOOP3

следующего имени файла.

1240

DEC

C

Переход на считывание

1250

JR

NZ,LOOP2

следующего сектора.

1260

C FILE

Отбор файлов по длине.

1270

LD

DE,CAT

DE - на начало каталога.

1280

PUSH

DE

1290

POP

HL

HL=DE

1300

XOR

A

Обнуление счетчика файлов.

1310

LD

(NFILES),A

Сохранение.

1320

LOOP4

LD

BC,#0010

Кол-во байт в заголовке.

1330

LD

A, (HL)

В A - первый байт имени файла,

1340

AND

A

если он равен 0 (конец

1350

JR

Z, ENDCAT

каталога), то выход из подпрограммы

1360

CP

#01

Если=1 (стертый файл),

1370

JR

Z,A TYPE

то проверка следующего файла.

1380

PUSH

HL '

1390

POP

IX 'IX=HL

1400

LD

A, (IX+8) 'Тип файла: BASIC, CODE или

1410

TYPE

NOP 'другой тип. Здесь можно

1420

NOP

'вставить XOR [ASCII CODE].

1430

LD

A,(IX+11) 'Младший байт длины. После

1440

LLEN

XOR

#AC ' его проверки можно отсеять

1450

JR

NZ,A TYPE 'остальные файлы.

1460

LD

A,(IX+12) 'Проверка младшего байта.

1470

HLEN

XOR

#0A 'Проверка старшего

1480

JR

NZ,A TYPE 'байта длины.

1490

SLEN

LD

A,RDS2 'Проверка на количество секторов.

1500

SUB

(IX+13) 'Если не равно переменной

1510

JR

NZ,A TYPE 'RDS2, то это не выгрузка.

1520

LDIR

'Перенос проверенного имени.

1530

LD

A, (NFILES) 'Увеличение счетчика

1540

INC

A 'отобранных файлов.

1550

LD

(NFILES),A 'Сохранение счётчика.

1560

A TYPE

ADD

HL,BC 'Проверка следующего файла.

1570

JR

LOOP4 '

1580

ENDCAT

XOR

A 'Занесение после последнего

1590

LD

(DE),A 'отобранного файла 0.

1600

RET

'Выход из подпрограммы.

1610

NFILES

DEFB

#00 'Количество отобранных файлов.

1620

LOAD

'Подпрограмма загрузки положения игры.

1630

LD

A,(NFILES) 'Проверка количества выгрузок,

1640

CP

#00 'если ни одной, то выход с

1650

JP

Z,ERR1 'сообщением об их отсутствии.

1660

CALL

FINDAF 'Поиск имени файла, если файла

1670

JP

C,ERR2 'нет то выход с ошибкой.

1680

LD

HL,FROM D 'Настройка переменных чтения.

1690

LD

(CDLORS+1),HL '

1700

CALL

SORL 'Вызов подпрограммы загрузки.

1710

JR

Z,ENDLD 'Выход из подпрограммы при ошибке.

1720

LD

HL,BUFFER 'Перенос выгрузки из буфера

1730

LD

DE,WYGR 'в программу.

1740

LD

BC,LENGHT '

1750

LDIR

'

1760

ENDLD

RET

'

1770 SORL

'буфер

1780

LD а, в LD

A,(IX+15) зависимости от пер (FINDTR+1),A

Подпрограмма чтения или записи из )еменных. IX-данные файла. Поиск начальной дорожки.

1790

CALL

FINDTR

1800

LD

A,(IX+14)

В A - начальный сектор.

1810

LD

HL,BUFFER

В HL начало буфера.

1820

LD

BC,RDSECT

BC количество секторов в буфере.

1830 LOOP5

PUSH

BC

Сохранение BC.

1840

INC

A

Увеличение номера сектора.

1850

PUSH

HL

1860

PUSH

AF

1870

LD

(SECT2),A

Установка сектора.

1880

CDLORS

CALL

FROM D

Чтение/запись сектора.

1890

SECT2

DEFB

#00

1900

POP

AF

1910

POP

HL

1920

INC

H

Увеличение адреса на 256.

1930

CP

#10

проверка сектора, если не

1940

JR

NZ,LAB

16, то переход на дальнейшее

1950

PUSH

HL

чтение/запись, иначе

1960

LD

A, (FINDTR+1)

сдвиг головки

1970

INC

A

вперед на 1 трек.

1980

LD

(FINDTR+1),A

1990

CALL

GO TR

2000

POP

HL

2010

XOR

A

Обнуление сектора.

2020

LAB

2030

POP

BC

Восстановление BC.

2040

DJNZ

LOOP5

Дальнейшее чтение.

2050

RET

2060

FINDTR

LD

A,01

Поиск дорожки.

2070

CALL

GO TR

2080

RET

2090

FINDAF

LD

HL,CAT ;Подпрограмма поиска имени файла среди

; отобр

анных

по длине. HL-начало имени первого файла.

2100

L1

LD

A,(HL)

Проверка конца каталога.

2110

AND

A

Если первый байт имени

2120

JR

Z, END

файла=0, то выход.

2130

PUSH

HL

2140

LD

DE,FNAME

В DE - имя искомого файла.

2150

LD

BC,#0800

Количество байт в имени 8.

2160

L2

LD

A,(DE)

Провер.первого байта имени.

2170

INC

DE

DE=DE+1

2180

AND

A

проверка A на ноль.Если да,

2190

JR

Z, L3

то проверка следующего имени.

2200

CP

(HL)

сравнение байтов имен.

2210

INC

HL

увеличение адреса следующей

2220

JR

NZ, L3

буквы. Если не равны, то

проверка следующего имени.

2230

DJNZ

L2

иначе проверка следующей буквы.

2240

POP

IX

IX-адрес найденного имени.

2250

SCF

выключение флага переноса.

2260

CCF

2270

RET

2280

L3

POP

HL

2290

LD

DE,#0010

Адрес следующего имени:

2300

ADD

HL, DE

равен HL=HL+16

2310

JR

L1

Проверка, если файл

2320

END

SCF

не найден, то включение

2330

RET

флага переноса и выход.

2340

SAVE

Подпрограмма записи положения игры.

2350

LD

HL,WYGR

Перенос выгрузки из

2360

LD

DE,BUFFER

программы в буфер.

2370

LD

BC,LENGHT

2380

LDIR

2390

CALL

FINDAF

Поиск имени.

2400

JP

C, NEWF

Если файл не найден, создание нового файла.

2410

SVE

LD

HL,ONDISK

Иначе перезапись старого.

2420

LD

(CDLORS+1),HL

Настройка переменных.

2430

LD

A,(IX+15)

Дорожка начала файла.

2440

LD

(FINDTR+1),A

2450

CALL

FINDTR

Поиск дорожки.

2460

LD

A,(IX+14)

Сектор начала файла.

2470

LD

HL,BUFFER

В HL - начало буфера.

2480

LD

BC,RDSECT

В BC - количество секторов.

2490

CALL

SORL

Запись блока секторов.

2500

RET

2510

NEWF

CALL

BG93

Создание нового файла.

2520

DEFB

#1F

Команда восстановления.

2530

DEFB

#0C

#^-регистр команд.

#0C=00 00110 0-восстановление.

2540

CALL

RESET

RESET ВГ93.

2550

CALL

LOAD C

Загрузка данных каталога.

2560

DEFB

#09

2570

LD

HL,(CATDAT+#E5)

проверка оставшихся сект.

2580

LD

DE,RDS1

на диске, если меньше RDS1,

2590

SBC

HL, DE

то выход с сообщением об

2600

JP

C, ERR3

ошибке (no space on disk!).

2610

LD

(CATDAT+#E5) , HL

2620

LD

HL,CATDAT+#E4

Проверка количества файлов на

2630

INC

(HL)

диске, если 128, то выход с

2640

BIT

7, (HL)

сообщением об ошибке.

2650

JP

NZ, ERR3

2660

LD

HL,(CATDAT+#E1)

Изменение данных последнего

2670

LD

E, L

трека/сектора.

2680

LD

D, H

2690

PUSH

DE

2700

LD

A,RDS2

В А количество секторов.

2710

SSECT

LD

B,#10

В - количество секторов в треке.

2720

ADD

A, E

2730

L5

CCF

2740

SUB

B

2750

JR

C, L6

2760

INC

D

2770

JR

L5

2780

L6

ADD

A,B

2790

LD

E, A

2800

EX

DE, HL

2810

LD

(CATDAT+#E1) , HL

Сохранение последнего трека/сектора.

2820

CALL

CATSAV

Запись измененных данных.

2830

DEFB

#09

2840

LD

A,(CATDAT+#E4)

A - количество файлов на диске.

2850

DEC

A

Первоначальное количество файлов.

2860

RRCA

В результате этих манипуляций

2870

RRCA

получаем в А номер сектора

2880

RRCA

(от 1 до 8), в котором

2890

RRCA

находится имя последнего

2900

PUSH

AF

файла на диске. На стеке

2910

AND

#07

имеем номер файла в

2920

INC

A

секторе (1-16).

2930

LD

(SECT3),A

Ввод переменных в программу.

2940

LD

(SECT4),A

2950

CALL

LOAD C

Читаем сектор.

2960

SECT3

DEFB

#00

2970

POP

AF

2980

AND

#F0

Создаём в памяти имя файла.

2990

LD

E, A

3000

LD

D, #00

3010

ADD

HL, DE

3020

PUSH

HL

3030

POP

IX

3040

EX

DE, HL

Копируем имя.

3050

LD

HL,FNAME

3060

LD

BC,#000E

3070

LDIR

3080

EX

DE, HL

3090

POP

DE

Вводим начальный

3100

LD

(HL),E

сектор

3110

INC

HL

и

3120

LD

(HL),D

трек.

3130

CALL

CATSAV

Записываем на диск

3140

SECT4

DEFB

#00

измененный сектор.

3150

JP

SVE

На запись данных файла.

3160

ERR1

CALL

PRINT

Ошибка 1.

3170

DEFB

#16

Если на диске нет

3180

DEFB

#10

выгрузок игры,

3190

DEFB

#03

то выдается

3200

DEFB

#10

это сообщение.

3210

DEFB

#07

3220

DEFB

#11

3230

DEFB

#00

3240

DEFM

"no file(s) of restore game!%"

3250

CALL

ANYKEY

3260

JP

PAUSE

3270

ERR2

CALL

PRINT

Ошибка 2.

3280

DEFB

#16

Файл не найден.

3290

DEFB

#10

3300

DEFB

#09

3310

DEFB

#10

3320

DEFB

#07

3330

DEFB

#11

3340

DEFB

#00

3350

DEFM

"file absent!%"

3360

CALL

ANYKEY

3370

JP

PAUSE

3380

ERR3

CALL

PRINT

Ошибка 3.

3390

DEFB

#16

Нет места на диске.

3400

DEFB

#10

3410

DEFB

#07

3420

DEFB

#10

3430

DEFB

#07

3440

DEFB

#11

3450

DEFB

#00

3460

DEFM

"no space on disk!%"

3470

CALL

ANYKEY ;

3480

JP

PAUSE ;

3490

ANYKEY

3500

CALL

PRINT

3510

DEFB

#16

3520

DEFB

#12

3530

DEFB

#09

3540

DEFB

#10

3550

DEFB

#07

3560

DEFB

#11

3570

DEFB

#00

3580

DEFB

#13

3590

DEFB

#01

3600

DEFM

"press any key%"

3610

RET

;

3620

PAUSE

3630

NEXTP

XOR

A

Подпрограмма ожидания нажатия

3640

IN

A, (#FE)

любой клавиши.

3650

CPL

3660

AND

#1F

3670

JR

Z,NEXTP

3680

RET

3690

ENTNAM

CALL

PRINT

Подпрограмма ввода версии выгрузки.

3700

DEFB

#16

3710

DEFB

#10

3720

DEFB

#05

3730

DEFB

#10

3540

DEFB

#06

3750

DEFB

#11

3760

DEFB

#00

3770

DEFM

"enter version letter%"

3780

XOR

A

3790

LD

(#5C08),A

3800

LL

LD

A,(#5C08)

3810

AND

#DF

3820

CP

#41

3830

JR

C, LL

3840

CP

#5B

3850

JR

NC, LL

3860

LD

(LETTER) ,A

3870

RET




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Нужна помощь - Внимание, All! Кто может помочь Werewolves'у?
Чудо техники - Десять байт.
Очумелые ручки - Самозащита: схема электрошока.
Новинки - обзор новинок: Deja Vu 7, ZX Format 8, Черный ворон, Зеркало, Monster Land, Сталкер.
Игры - прохождение игры ЧЕРНЫЙ ВОРОН-I. (люди)

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