
|
8BIT OPERATING SYSTEM FOR ZX-SPECTRUM
\history\doors2000
DOORS
2000 (часть 1)
(год
2000, ветер перемен, сорвавший крышу, напрочь,..)
Что
такое D2K или в чем отличия DOORS 2000 от DOORS’96,97,98,99
Итак, самое главное отличие D2K от предыдущих версий в
самой идее работы с керналем. Раньше (как вы могли ознакомится
выше) обращение к керналю было через отдельные точки входа,
типа вызвал процедуру нарисовать кнопку, она нарисована
и для системы не имеет никакого значения, т.е. было необходимо
самостоятельно обрабатывать координаты стрелки, события,
когда ее нажали (отпустили) и так далее…
Теперь же идеология написания программы изменилась. Керналь
и программа неотъемлемая часть друг друга и работают вместе,
а не как раньше одна вызывала другую. Программа представляет
собой некий сценарий действий и условий – что делать и
как вести себя керналю в той или иной ситуации. За основу
керналя можно взять интерфейс работы со стрелкой (забегая
вперед, скажу что без мыши работы с d2k нельзя считать
полноценной). Именно он задает event’ы (события). “Что
в данной ситуации происходит?” – нажали правую кнопку
мыши или навели курсор на объект все это отображается
в event’ах. Далее следует оконный интерфейс. Хотя, честно
говоря, его даже следовало бы отнести к приоритетному
компоненту, поскольку построение любой программы стоит
начать именно с создания окна :) , а затем только уже
размещать декорацию, обрамления, кнопки и так далее.
Так что же такое d2k? OS или набор команд? Честно говоря,
вопрос довольно-таки риторический… Поскольку прежде чем
на него ответить, стоит определится что же для тебя OS?
Если в первую очередь чисто дисковые функции, то ответ
бут однозначным – нет :( Для меня же главное удобный и
практичный интерфейс для пользователя, именно эту цель
я преследовал, создавая систему. С изменением идеологии
написания программ под d2k (спасибо KVA) интерфейс стал
не только удобным для пользователей, но и для кодеров,
которые будут писать собственные программы под d2k (по
крайней мере, я так надеюсь…).
D2K / 2 (В РАЗРЕЗЕ)
(DOORS 2000 – так с чем же тебя есть ? :)
Тут я решил уже покончить с переливанием из пустого в
порожний и перейти непосредственно к рассмотрению самой
системы в целом.
Итак, начнем с работы с памятью. По умолчанию d2k понимает
любую машину как zx-spectrum 128 , как это не прискорбно,
но с 48 Кб система не будет работать. Для того, что бы
работать с расширенной памятью, необходимо проинсталлировать
драйвер расширенной памяти. И совершенно не важно, какая
у вас машина pentagon,
kay или profi. Если драйвер корректный и
программа работает только через него, а не ломится напрямую
рулить банками, то успех гарантирован :) Для того, что
бы написать свой драйвер памяти необходимо придерживаться
определенных точек входа. А если быть точнее, то необходимо
иметь следующий заголовок:
BEGIN |
ORG #C000
DEFB LEN
JP START
JP EX_RAM
JP ONPAGE
JP MAI_SCR
JP EXT_SCR
|
;Размер самого драйвера в байтах
;Инициализация драйвера
;Работа с расширенной памятью (физическая)
;Работа с расширенной памятью (косвенная)
;Вызов основного экрана (#4000)
;Вызов дополнительного экрана (#С000) |
Далее, я думаю, стоит обратить внимание на структуру основной
памяти (т.е. 128 Кб). Она состоит из: основного экрана,
буфера принтера, области системных переменных и области
доступной для использования:
#4000
- #5AFF |
Область
основного экрана |
#5B00
- #5BFF |
Область
для драйвера принтера |
#5A00
- #5FFF |
Область
системных переменных BASIC & TR-DOS |
#6000
- #FFFF |
Область
доступная для использования. |
Область
доступную для использования можно в свою очередь разбить
на:
#6000
- #97FF |
Область
– нижняя память (LowMem) |
#9800
- #BFFF |
Сам
керналь d2k |
#C000
- #F0FF |
Область
– верхняя память (HighMem) Bank #10 |
#F100
- #F6FF |
Область
– шрифт 5X5 |
#F700
- #FFFF |
Область
– пропорциональный шрифт |
Не
обязательно, что шрифт 5x5 и пропорциональный шрифт должны
грузится в отведенную выше область, просто переменные
pFONT5 и pFONT по умолчанию указывают на значения #F100
и #F700. При начальной инициализации их в систему достаточно
указать адрес и банк памяти, где они будут храниться!
Однако стоит обратить ваше внимание на то что, эти манипуляции
можно делать во время написания и отладки вашей программы.
Когда же вы будите запускать вашу программу из системы,
то драйвер памяти, размещение шрифтов и другие элементы
будут располагаться в памяти так как они были настроены
именно в системе !!! По этому и не стоит привязываться
к жесткой адресации! Но об этом мы поговорим немного позже,
в главе о создании законченного приложения под d2k.
Ну
теперь, я думаю общая идея работы с памятью ясна и самое
время перейти к клавиатуре и мышке. Повторяясь, скажу
еще раз что без kempston mouse управление очень и очень
не удобно, поэтому очень настоятельно рекомендую подключить
сей девайс! Но если у вас он отсутствует, то это не фатально.
При работе с клавиатурой взята идея по принципу EMS (E-mage
Modem Station), т.е. если нужно управлять стрелкой, то
вы спокойно используете клавиши Q,A,O,P,SPACE,M – вверх,
вниз, влево, вправо и актив. Если же нужно ввести текст,
то переключаемся на этот режим путем нажатия CS+SPACE
так же и обратно. При вводе текста для переключения различных
режимов используются следующие комбинации: CAPS LOCK -
строчные/прописные, EDIT(CS+1) – рус/лат. Ну и соответственно
SHIFT, SPACE и ENTER – по прямому их назначению.
Что
же касается остальных девайсов, таких как, AY-mouse, kempston
joystick, то они пока не поддерживаются керналем (версии
3), но будущем они планируются подержатся при помощи специальных
драйверов.
Ну вот когда покончено с памятью и девайсами, самое время
поговорить об изюминке системы – сценарий! Рассмотрим
простейший пример открытие окна:
Код
Сценария |
IX |
DW 0,0 |
-7,6 -9,8 |
DW RET_I |
-5,4 |
DB 4 |
-3 |
DW DAT2 |
-2,1 |
DAT1 DB 0 |
0 |
DB 0,0 |
+1,+2 |
DB 32,24*8 |
+3,+4 |
DB #28,#0E |
+5,+6 |
DB 0,0,0 |
+7,8,9 |
DB “D2K window”,0 |
+10 |
На первый взгляд куча цифр и ничего не понятно, за исключением
наверное фразы “D2K window” :) Но как говорится, первые
впечатления обманчивы. Забегая вперед, скажу, что для
работы с элементами сценария нам понадобится вновь регистровая
пара IX , поэтому смещения относительно нее и приведены
в правом столбце, вот только значения поменялись (относительно
Doors’96-99).
Итак
обо всем по порядку:
IX смещение |
Данные |
Комментарии |
Внимание!
Данные только при работе с компонентом window (создать
окно) |
-9,8 |
0,0 |
Адрес процедуры синхронизации (0-стандартная) Синхронизацию
мы рассмотрим немного позже. |
-7,6 |
0,0 |
Адрес процедуры обработки клавиатуры (0-стандартная)
Об этом тоже немного позже.
|
Далее следует стандартный заголовок для каждого
элемента (-5,-4,-3,-2,-1,0) |
-5,-4 |
RET_I |
Адрес обработки событий (event). В нашем случае
он указывает на RET. То есть что бы не происходило
никак окну не реагировать. |
-3 |
4 |
Маска событий (event) на какие реагировать. В нашем
случае 4 – только что нажали левую кнопу мыши. В
принципе можно было бы поставить и 0, поскольку
мы все ровно не собирались предпринимать ни каких
действий.(таблица событий (event’ов) ниже) |
-2,-1 |
DAT2 |
Адрес следующего элемента, если #0000, то это последний
элемент и означает конец сценария! Следующий элемент
сценария вовсе не обязательно размещать сразу за
предыдущим, можно их разбросать хоть вообще по всей
памяти :) |
+00 |
0 |
Здесь указывается команда керналю, что делать. В
данном случае 0 – указывает, что будет создано окно.
|
Далее следует описание характерное только для компонента
window: |
+01 |
0 |
Начальная координата X(a). Начальная, поскольку
при дальнейшем перемещении окна она будет изменятся
вместе с его положением относительно всего экрана.(a)
– означает что координаты задаются в атрибутных
единицах (курсорах) и могут принимать значение от
1 до 32. |
+02 |
0 |
Начальная координата Y(p). Все выше сказанное, так
же относится и координате Y, при дальнейшем перемещении
окна она будет изменятся вместе с его положением
относительно всего экрана.(p) – означает что координаты
должны задаваться в pix и могут принимать значение
от 1 до 192, но в данном случае рекомендуется задавать
значения кратные 8 (0,8,16,24,32…). Для чего? Дело
все в том что при выводе окна, керналь конечно сам
округлит значения до кратных 8, но вот при дальнейшем
выводе текста и декораций, начнутся глюки :) поскольку
данные он будет использовать, которые дали ему вы…
|
+03 |
32 |
Size X(a) – размер окна по горизонтали (1-32) |
+04 |
24*8 |
Size Y(p) – размер окна по вертикали (1-192) Так
же рекомендуется задавать значения кратные 8! |
+05 |
#28 |
Атрибуты самого окна |
+06 |
#0E |
Атрибуты заголовка окна |
+7,8,9 |
0,0,0 |
Данные ячейки зарезервированы под нужды керналя!
Рекомендуется оставить их в покое! :) |
+10 |
“D2K window”,0 |
Текст в заголовке окна, обязательно оканчивающийся
кодом #00 ! |
Вот так, в принципе и строится сценарий. Он может состоять
как из стандартных компонентов, так и из ваших собственных.
Так же возможна работа с библиотечками (LIBS),
но как говорится всему свое время.
Заканчивая разговор о “разрезе” :) Doors вдоль и поперек,
хотелось бы заострить ваше внимание на одной изюминке
системы, переменной – pTEKID. Чем же она так примечательна?
А вот чем… она является элементом одной интересной ветки
керналя. В ней хранится уникальный номер приложения… чувствуете
к чему я клоню? YESSSSSSS!!!!! Многозадачность на Спектруме!
Если в начале одной программе присвоить pTEKID=1,
а второй pTEKID=2, то затем меняя значение этой
переменной можно прыгать то в одно приложение, то в другое!
У вас конечно же напрашивается вопрос: А кто же будет
присваивать эти номера и переключатся между приложениями?
Закономерный вопрос, заниматься этим будет File
manager – но его создание еще в проекте и поэтому
говорить об этом рано :( Однако! Другая переменная pTEKSD
– хранит уникальный номер окна, что позволяет не запутаться
когда много вложенных окон, да они еще все и тягаются…
EVENTS (СОБЫТИЯ)
(Работа с мышкой of coz…)
BIN
|
HEX
|
Комментарии
|
%xxxxxxx1
|
#01
|
Нажата
левая кнопка мыши (аналога клавиатуры нет)
|
%xxxxxx1x
|
#02
|
Отжата
левая кнопка мыши (аналога клавиатуры нет)
|
%xxxxx1xx
|
#04
|
Только
что нажали левую кнопку мыши (аналога клавиатуры
нет) |
%xxxx1xxx
|
#08
|
Только
что отжали левую кнопку мыши (аналога клавиатуры
нет) |
%xxx1xxxx
|
#10
|
Нажата
правая кнопка мыши (аналог клавиатуры – SPACE,M)
|
%xx1xxxxx
|
#20
|
Отжата
правая кнопка мыши (аналог клавиатуры – SPACE,M)
|
%x1xxxxxx
|
#40
|
Только
что нажали правую кнопку мыши (аналог клавиатуры
– SPACE,M) |
%1xxxxxxx
|
#80
|
Только
что отжали правую кнопку мыши (аналог клавиатуры
– SPACE,M) |
%11111111
|
#FF
|
Ничего
не нажимали, но курсор находится над объектом, удобно
при изменении внешнего вида курсора, в зависимости
от наведенного объекта. |
X – означает что здесь может быть как 0, так и 1-ца.
То есть если мы хотим получить комбинацию событий, типа:
левую кнопку мыши нажали и держат уже продолжительное
время, а правую только что нажали, то мы получим код:
BIN %00000101 , HEX #05 . т.е. по сути они просто
складываются. Более подробно о событиях мы еще поговорим.
ПРОГРАММА ПОД D2K
(С чего же начать?…)
Здесь мы с вами рассмотрим начальные строки любой программы
под d2k и плавно перейдем к компонентам самой системы.
(небольшое замечание: здесь и далее приведены
примеры исходных текстов написанных под ALASM 4.2, но
их не составит большого труда экспортировать в другие
ассемблеры, такие как TASM, STORM, XAS, ZXASM и другие…)
Итак, с чего же начать?…В первую очередь определится,
что мы пишем? Если это будет небольшая программа в пределах
8 – 10 Кб, или резидент (а о резидентах мы еще поговорим
отдельно), то вполне ей хватит места в LowMem (#6000 -
#9800). Ну а если даже и не хватит :) , то всегда можно
kick’нуть workbench aka file explorer (с него мы собственно
только запускать программу и будем). Если же у нас
более глобальный проект, например текстовый редактор,
то тут дела обстоят несколько сложнее, поскольку перед
началом написания проекта необходимо расписать все нюансы
и необходимую память, поскольку ее (память) нам попросту
надо будет выпрашивать у керналя :) как это сделать мы
рассмотрим далее по тексту, а сейчас пойдем дальше. После
того как мы определились и разобрались с памятью, перейдем
непосредственно к кодам:
ORG #F100
INCBIN "FONTS"
Сначала подгружаем блок шрифтов 5x5 и пропорциональный.
ORG #9800
INCBIN "DOOR"
Затем загружаем сам керналь.
ORG #8000
INCLUDE "MDOOR2K"
Ну и теперь сами метки керналя, без них ни к одной процедуре
керналя не реально обратится. В данном файле “MDOOR2K”
метки для керналя версии 2, поскольку он несколько изменился
в отличии от версии 0 и 1. Описание меток и адресов можно
будет найти в приложении.
RUNOF |
LD A,(rPAGES)
CALL mINIT
XOR A
CALL rPAGE
LD HL,FONTP
LD D,0
XOR A
CALL mMAKEFNTPS
LD HL,FONT5
LD D,0
XOR A
CALL mMAKEFNT5X5S
LD A,1
LD
(pTEKID),A
CALL PROG
DI
LD HL,#2758
EXX
LD
IY,#5C3A
IM
1
EI
RET
|
;
ГЛАВНАЯ ПРОЦЕДУРА (ОСНОВНОЙ ЦИКЛ)
;
Всего доступно страниц памяти
;
Инициализация керналя
;
Выбираем начальную страницу памяти
; Устанавливаем пропорциальный
; шрифт в систему
; Устанавливаем шрифт 5X5
;
в систему
; индетефикатор приложения
; Вызываем твою программу
; Завершение работы
; приложения
|
Вот
так, собственно выглядит начальный заголовок любого
приложения, вы можете использовать этот или написать
свой, в любом случае это не столь важно. Куда важнее,
как он будет выглядеть в конечном итоге, когда программа
написана, отлажена и готова к употреблению. Как сделать
из нее полноценный модуль? Так что бы он запускался
из системы (WB)? Вот об этом мы поговорим в главе о
компиляции финального модуля, а сейчас самое время рассмотреть
компоненты d2k.
|
|