ZX-Ревю 1996 №1-2 1996 г.

Читатель - читателю - система "ROM-Drive".


ЧИТАТЕЛЬ - ЧИТАТЕЛЮ

ROM-Drive

Ни для кого не секрет, что в последнее время "Спектрумы" испытывают сильную конкуренцию со стороны всевозможных видеоприставок. Одно из несомненных преимуществ последних - "мгновенная" загрузка игр из ПЗУ картриджа. Высокая стоимость картриджей, судя по всему, не является препятствием для любителей игр на приставках.

Разработанная, мной система "ROM-Drive", которую я хочу предложить Вашему вниманию, основана на применении микросхем ПЗУ D2764-D27512 с записанными в них программами пользователя (1111). Она позволит Вам:

а). Имея ROM-версии любимых игр, загружать их нажатием одной кнопки за несколько миллисекунд;

б). Иметь под рукой "запас" системных и прикладных программ, которые не только "мгновенно" загружаются, но и не подвержены ошибкам при загрузке (по этому пути пошли и разработчики одного из самых популярных компьютеров "Скорпион" при разработке профессионального ПЗУ). Долговечность таких программ на несколько порядков выше, чем у кассет или дискет;

в). Будучи применённой в школах (учебные программы, "зашитые" в ПЗУ) или в игровых автоматах, позволит сэкономить массу времени.

При всем этом система нисколько не ухудшает совместимости компьютера с программным обеспечением на кассетах и дискетах.

Аппаратная часть системы очень проста и может быть собрана радиолюбителем за 1 час. Доработка компьютера заключается в установке 3-х дополнительных микросхем: D1, D2-K555JIJI1, D3-K555TM2 и панельки под ПЗУ пользователя D4. Вся схема может быть подключена через системный разъём или смонтирована внутри компьютера - в этом случае панелька под ПЗУ устанавливается на корпусе компьютера. Принципиальная схема приведена на рис.1.

Система работает по принципу "теневого ПЗУ". В ПЗУ пользователя (ПЗУ-П) D04 записывается программа пользователя (ПП) по приведённым ниже правилам. Система начинает работу, если при замкнутом S1 нажать кнопку "сброс". При этом происходит следующее:

а). системное ПЗУ (ПЗУ-С) отключается (/CSSYS=1), вместо него включается ПЗУ-П (/CSUSR=0) объёмом от 8 до 64 Кб. С адреса 0000H в нём находится ROM-загрузчик ПП, который сразу начинает делать своё дело.

б). запрещается чтение данных из ОЗУ (сигналом /CSSYS), и мы получаем как бы два адресных пространства: первое-ПЗУ-П с 0000H до FFFFH (при объёме ПЗУ 64 Кб), работающее только на чтение, и второе-ОЗУ, работающее только на запись.

в). ROM-загрузчик ПП с помощью одной или нескольких команд LDIR перемещает блоки кодов из ПЗУ-П в необходимые места ОЗУ. В частности, Вы можете загрузить что-нибудь в любую страницу дополнительного ОЗУ 128-х машин, т.к. работа портов не нарушается.

г). как только размещение программы в ОЗУ закончено, ей передается управление с помощью команды JP ADDR, где ADDR - стартовый адрес программы (в диапазоне 4000H-FFFFH), При этом вырабатывается импульс /SET=0 и триггер D3 отключает ПЗУ-П, подключает ПЗУ-С, разрешает чтение ОЗУ (в общем, почти как в контроллере дисководов). Программа пользователя начинает работать как ни в чём не бывало.

D0-D7

D27128

ПЗУ-П

ПЗУ-С

D27512

А0-А15

ROM

ROM

ШД

ШД

А0-А13

ША

ША

RDROM

20

20

О CS

О CS

22

22

г

ОЕ

ОЕ

ю

L

4-

RESET

О-

D2.1

+5V

MREQ

а

S1

С1'

RD

R1 10К

а

VD1

и-

CSUSR

"lOH/OFF" 9

+5VO-

D2.2

Л

А15

11

CSSYS

12

о

ОЕ

QO

10

А14

<

CSRAM

13

О

D3 555ТМЗ

-Ou

D34.4

6

SET

D1.4

D2.3

D1.2

ИР22 (ИР23)

D1, D2 K555I11 D34 К555ЛН1

MREQ

О

(Свободный

элемент

компьютера)

С2 200

М1

О

BUF

D1.1

Рис. 1

Обратите внимание, что если S1 остается замкнутым, новое нажатие кнопки "сброс" не приведёт к очистке памяти, а снова запустится ROM-загрузчик, который, если его написать соответствующим образом, может, например, подгрузить уровень блочной игры или выполнить другие задачи (скажем, POKES).

Правила написания ROM-версий программ.

Программа для ROM-Drive представляет собой файл или несколько файлов, которые будут записываться в ПЗУ пользователя.

В принципе, программу писать не надо, а надо написать простейший загрузчик в кодах, стартующий с адреса 0000Н и расположит в ПЗУ блок (блоки) кодов с какого-то адреса (адресов) "Обязанности" загрузчика заключаются в том, что обычно делает BASIC: устанавливает цвет бордюра, системные переменные, делает POKES и т.п.; а также в том, чтобы перебросить командами LDIR блоки кодов на свои места (с адресов в ПЗУ - по адресам, которые известны из BASICa.) Причём не нужно заботиться о неперекрытии областей блока-источника и блока-назначения: всё равно данные считываются только из ПЗУ, а записываются в "другое адресное пространство" - ОЗУ, даже если их адреса одинаковы.

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

а). Во время работы загрузчика системное ПЗУ недоступно. Например, если Вам очень нужно вывести сообщение, Вы должны либо иметь в ПЗУ-П подпрограмму вывода символов и символьный набор, либо "не мудрить" и нарисовать сообщение в ART-STUDIO. Вывод картинки с сообщением на экран сведётся к одной команде LDIR.

б). Во время работы загрузчика нельзя ничего прочитать из ОЗУ (туда можно только записать): в частности, нельзя пользоваться стеком и командами CALL, RST. Поэтому

27

ЧИТАТЕЛЬ - ЧИТАТЕЛЮ

подпрограммы загрузчика не должны хранить что-либо в ОЗУ: сохранить-то сохранишь, но не прочитаешь, пока не передашь управление в ОЗУ.

в). Во время работы загрузчика прерывания должны быть запрещены, в противном случае Вы должны будете разместить с адреса 003 8Н программу обработки прерываний (простейшая программа состоит из одного оператора RET).

Приведу для примера целый загрузчик игровой программы, очень простой для понимания основной идеи.

Пусть мы имеем "игрушку", состоящую из бейсиковского загрузчика, заставки длиной 6912 байт и блока кодов длиной 38000 байт, причём в бейсике сказано: 10 BORDER 0: PAPER 0: INK 0: CLEAR 25999 20 LOAD "SCREEN"CODE 16384 3 0 LOAD "codeHCODE 2 6000 40 POKE 32550,201 50 RANDOMIZE USR 60000

Подсчитав сумму длин 2-х блоков кодов (6912+38000= 44912), приходим к выводу, что нам нужно ПЗУ типа D27512 объёмом 64К. В свободном месте ПЗУ (около 20К) можно разместить ещё одну небольшую программу, но об этом пока говорить не будем. Недолго думая, пишем ROM-загрузчик, основываясь на тексте бейсика:

00000

DI

прерывания лучше запретить

XOR

А

А=0

LD

(23624),А

установка чёрного цвета бордюра

OUT

(# FE) , A

LD

SP,25999

примерно то же, что и CLEAR (цвета чернил и бумаги менять не будем)

LD

HL,00256

с этого адреса в ПЗУ будет блок SCREEN

LD

DE,16384

на этот адрес он будет переброшен

LD

ВС,06912

это его длина

LDIR

заставка уже на экране!

LD

ВС,#7 FFE

ждём нажатия "пробела", иначе картинка сразу пропадет

IN

А,(С)

LOOP

BIT JR

0, А

NZ,LOOP

LD

HL, (256+6912)

сразу за заставкой в ПЗУ расположим блок code, поэтому его адрес-такой.

LD

DE,26000

адрес назначения блока code

LD

ВС,38000

длина блока code

LDIR

кодовый блок загружен!

LD

А, 201

число для РОКЕ

LD

(32550),А

РОКЕ готово!

JP

60000

3апуск!!!

00056

RET

это "программа обработки прерываний"

00256

<здесь

находится блок

SCREEN>.

07168

<а здесь - блок code

(

(07168=256+6912)>

г) Обратите внимание на то, чтобы передача управления в ОЗУ была сделана ОДНИМ оператором JP. Например, если загрузчик исходной кассетной версии заканчивался словами: LOAD "ABC" CODE 25000: RANDOMIZE USR 25000: RANDOMIZE USR 43560

ЧИТАТЕЛЬ - ЧИТАТЕЛЮ

т.е. два вызова подпрограмм, то в ROM-загрузчике Вы должны разместить, эти вызовы (запускающий модуль) в ОЗУ и передать управление на первый из них. У Вас должно получиться

CALL 25000 JP 43560

16384 ; Выход из ПЗУ пользователя и запуск программы

Можно сделать и по другому - иметь готовый запускающий модуль в ПЗУ, перебросить его в ОЗУ и передать на него управление.

ROMADR CALL 2 5000 JP 43560

что-то вроде:

LD

HL,<адрес

начала блока ABC в ПЗУ>

LD

DE,25000

LD

ВС,<длина

блока АВС>

LDIR

; загрузили блок в ОЗУ

LD

HL,16384

; здесь в ОЗУ будет запускающий

LD

A, #CD

; код инструкции CALL

LD

(HL),A

; в ОЗУ его !

INC

HL

; следующий адрес

LD

ВС, 25000

; операнд для CALL

LD

(HL) ,С

; младший байт - в ОЗУ!

INC

HL

LD

(HL) ,В

; старший байт - в ОЗУ!

INC

HL

LD

А,#С3

; код инструкции JP

LD

(HL),А

; в ОЗУ!

INC

HL

LD

ВС, 43560

; операнд для JP

LD

(HL) ,С

; младший байт - в ОЗУ!

INC

HL

LD

(HL) ,В

; Теперь с адреса 16384 у нас е

JP

LD

HL,

<адрес

начала блока ABC в ПЗУ>

LD

DE,

25000

LD

ВС,

<длина

блока АВС>

LDIR

; загрузили блок в ОЗУ

LD

HL,

ROMADR

; адрес запускающего модуля в ПЗУ

LD

DE,

16384

; сюда будет переброшен запускающий

LD

ВС,

00006

; длина которого 6 байт

LDIR

; загрузили запускающий модуль

JP

163

со

; и - вперёд!

Это и есть

наш запускающий модуль

А А А А А

В общем, адаптация программ под ROM-Drive не сложнее, чем адаптация кассетных версий под TR-DOS. Однако, к каждой программе нужен, индивидуальный подход.

Если кто-то знает способ запуска Magic-файлов в TR-DOSe, может попытаться написать ROM-загрузчик таких файлов из ПЗУ. Преимущества очевидны: этот загрузчик может быть универсальным (или почти универсальным) для всех 1111 и производство ROM-версий можно "поставить на поток".

В конечном результате у Вас должен получиться файл длиной 8, 16, 32 или 64Кб. В последнем случае проще сделать 2 файла по 32Кб. Неиспользованную часть ПЗУ лучше заполнить кодами #FF - это облегчит внесение изменений.

Полученный файл должен быть записан в ПЗУ соответствующей ёмкости: 8Кб - D2764 или К573РФ4(РФ6)

16Кб - D27128

32Кб - D27256 или К573РФ8

64K6 - D27512

Если в Вашей местности нет программаторов к "Спектруму", перенесите файл на IBM-овский диск (например, через iS-DOS). Возможно, у кого-то найдется IBM с программатором.

Наиболее оправданным (по соотношению цена/ёмкость) я считаю D27512. (Её цена на рынках разных городов составляет 2-3$). В случае записи нескольких ПП в одно ЦЗУ, нужно ввести в ROM-загрузчик программу, позволяющую пользователю выбрать необходимую ПП (например, из меню).

Что ещё не сделано?

Недостатки системы очевидны:

а). малая ёмкость ПЗУ-картриджа - 64К при использовании D27512;

б). невозможность поочередной "подгрузки" уровней в блочных играх и других программах (без применения кнопки "сброс").

Возможные пути их устранения:

а). Можно применить страничную организацию ПЗУ-П и устанавливать либо несколько микросхем D27512, либо микросхему D271000 (128Кб при цене 5-6$) или D274000 (512Кб при цене 12-15$). Для управления страницами вполне возможно использовать порт FEH.

б). Посмотрите на схему контроллера дисководов Beta Disk Interface. Схема селектора адресов, применённая для входа в ПЗУ TR-DOS'a (обычно делается на микросхеме К555ЛА2), вполне подойдёт для входа в ПЗУ-П, только диапазон адресов для входа должен быть иным. Не исключена возможность использования общего селектора TR-DOSом и ROM-Drive, однако тогда будет нужен коммутатор "диск"-"ПЗУ".

Мной сделана ROM-версия игры TETRIS-2 фирмы Golden Triangle, записанная в ПЗУ D27256. Работа игры проверена на компьютере "Ленинград-1", оборудованом ROM-Drive. При замкнутом переключателе S1 (см. рис. 1) игра начинается сразу после включения компьютера, однако хочу предупредить, что лучше в общем случае сначала произвести обычный сброс, а потом включать ROM-Drive.

*************************************************************************************




СОДЕРЖАНИЕ:


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

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



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

Похожие статьи:
Sofтинка - MEMDISK - файловая система для хранения файлов в областях памяти.
От автора - управление, действие иконок в статье, о следующих номерах, связь.
Интервью - Интервью с одним из известнейших спектрумистов - Андреем Ларченко.
Разберемся - Подробное описание игры LASER SQUAD
Письмо №285 - Московская обл, г Воскресенск

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