Данная статья написана в 2003 году для газеты «Абзац» и была опубликована в 16 номере. Это моя первая статья на тему расширенного экрана компьютера «Profi».
Когда я начинал работать с CP/M, то оказался перед проблемой отсутствия, каких либо конкретных данных по этой системе, и, в частности, по расширенному экрану. Затем ситуация изменилась в лучшую сторону, но экран Профи так и остался черным пятном: почти все пришлось узнавать экспериментальным путем. Возможно, кто-то столкнулся с такой же проблемой. Вот с этими людьми мне и хотелось бы поделиться своими наработками.
Расширенный экран «Профи» имеет размер 512*240(h) пикселей, и занимает 32Кб (16Кб информация о пикселях и 16Кб цвета). Можно сказать это два независимых экрана с одинаковым строением, только в одном хранится пиксельная информация (страница 6), а в другом о цвете (страница 3A). Поэтому сейчас я остановлюсь только на обработке пиксельной информации (так сказать, черно-белого экрана). С остальным, думаю, несложно будет разобраться самостоятельно.
Карта памяти CP/M в корне отличается от привычной Спектрумовской. В ней нет ПЗУ, а система занимает верхние адреса. Очень важно иметь четкое представление о строении нижних 64Кб, в дальнейшем это поможет грамотно организовывать работу программы. Как выглядит карта памяти, можно посмотреть на рисунке 1.
Где:
BIOS - соглашения базовой системы ввода/вывода. На этих соглашениях базируется работа BDOS.
BDOS - базовые функции дисковой операционной системы.
Область дополнительных команд - сюда могут загружаться дополнительные системные программы: отладчик, интерпретаторы командных языков и т.п.
Область транзитных программ - именно сюда интерпретатор команд загружает прикладные программы для исполнения.
Базовая страница памяти - включает в себя несколько сегментов кодов и данных, обеспечивающих вход в BDOS и содержащих некоторые системные параметры.
Как видно из рисунка, экран открывается между двумя окнами на место второй страницы. В каждое окно может быть открыта любая страница памяти (в том числе 6 и 3А). Важной особенностью CP/M является то, что у запускаемых файлов нет стартового адреса, все они загружаются и начинают исполняться сразу за базовой страницей, с адреса #100. Это также следует учитывать.
Какое же строение имеет расширенный экран? По вертикали он идентичен экрану Спектрума, только не 192, а 240 пикселей в высоту. И тут для него справедливо все написанное для стандартного экрана.
Основное его отличие - по горизонтали. Следует отметить, что экран представлен не единым «куском», а как бы разрезанным на две части. Это можно сравнить с наличием двух, вытянутых по вертикали, стандартных экранов, расположенных в памяти друг за другом и выводимых одновременно. Первый экран начинается с адреса #A000, второй с адреса #8000. Работа с ними, по отдельности, ничем не отличается от работы со стандартным экраном. Все бы ничего, да только на мониторе они чередуются в линии: байт с первого, байт со второго, с первого, со второго... Расширенный экран получатся разделеным на колонки шириной в одно знакоместо. И попытка работать только с одной частью, приведет к тому, что изображение будет разрезано на вертикальные полоски. Чтобы было понятнее, приведу карты расширенного экрана по знакоместам и по пиксельным линиям.
Карта расширенного экрана по знакоместам выглядит так, как это изображено на рисунке 2.
Дальше столбцы продолжают чередоваться. Попиксельная карта расширенного экрана имеет вид изображенный на рисунке 3.
Как видите, структура расширенного экрана не очень сложная, проблемы возникают только при горизонтальном переходе, здесь уже командой INC L не обойтись. Как же осуществить необходимый переход? Для решения этой проблемы посмотрим на начальные адреса двух половинок экрана в двоичной форме:
Первое знакоместо #A000 = 10100000 00000000
Второе знакоместо #8000 = 10000000 00000000
Третье знакоместо #A001 = 10100000 00000001
Видно, что для перехода из первого знакоместа во второе достаточно выключить 5-тый бит в старшем регистре. Для перехода в третье знакоместо потребуется не только включить 5-тый бит, но и выполнить команду INC L. Так как включение бита вернет нас только в другую половинку расширенного экрана, причем на первое знакоместо. Тут как раз вступает в игру чередование половинок, что и позволяет совершить переход на третье знакоместо. Для примера приведу процедуру расчета адреса знакоместа справа от текущего.
RIGHT: PUSH AF
BIT 5,H
JR NZ,RIGHT1
INC L
SET 5,H
POP AF
RET
RIGHT1: RES 5,H
POP AF
RET
На входе в нее в регистровой паре HL находится адрес текущего знакоместа, на выходе в HL адрес знакоместа справа.
Теперь мы знаем все о строении расширенного экрана, но как его включить? Ведь обычно на месте экрана находится вторая страница. Это можно сделать прямым обращением к портам. Но в CP/M, по возможности, следует избегать подобного решения. Внутри системы почти все уже предусмотрено заранее. Это касается не только расширенного экрана. Обращение к BIOS’у позволит избежать конфликтов между разными версиями CP/M и при использовании периферийных устройств, осуществлять работу с ними через драйвера. Вот две небольшие процедуры для включения и отключения экрана, использующих BIOS в своей работе:
; Включение экрана
SCRON: LD DE,1AFFH
CALL 0F82DH
RET
; Выключение экрана
SCROFF: LD DE,09B8H
CALL 0F82DH
RET
После включения экран занимает адреса с #8000 по #C000, замещая находящуюся там информацию. О чем не следует забывать и не размещать в данной области нужных в этом случае процедур и данных. А это, согласитесь, не совсем удобно, особенно если программа не использует расширенную память.
При необходимости можно пожертвовав скоростью, использовать возможности драйвера дисплея DSPK.DRV (разумеется, он должен быть загружен).
У него имеется обширный набор команд, применение которых позволит без проблем работать не только с пиксельной информацией, но и с цветом. Более подробно узнать о них можно из «Руководства пользователя драйвера дисплея DSPK.DRV», сейчас же я остановлюсь только на одной из его команд. Вот выдержка из руководства:
ESC+i Нарисовать пиктограмку. Сама пиктограмма описывается с адреса 80H:
ORG 80H
DB позиция, строка верхнего левого угла;
DB длина, ширина пиктограммы в знакоместах;
DW указатель на битовую карту точек;
DW указатель на битовую карту палитр.
; При вызове параметры портятся. Структура карт: знакоместа описываются последовательно
; слева направо, строки - сверху вниз.
; Описание одного знакоместа в битовой карте - 8 байт, по байту на строку растра,
; аналогично и в карте палитры.
LD HL,ICON ; желтая стрелка на красном поле
LD DE,80H
LD BC,8
LDIR
.OUTCHAR ESC
.OUTCHAR «i»
ICON:
DB 3,7 - позиция (7,3)
DB 2,1 - размеры 1х2
DW POINTS
DW PALLETS
POINTS:
DB 0,0,0,0FH,0FH,0,0,0
DB 0,40H,60H,0F0H
DB 0F0H,60H,40H,0
PALLETS:
REPT 16
DB 8*red*yellow
ENDM
Как видите, все достаточно элементарно. Данные примеры рассчитаны на использование ассемблера М80+, поэтому в них приведены специфические для него конструкции.
.OUTCHAR - это макрос который определен в файле DEVICE.H.
REPT X - все что находится между этими командами
(в данном случае yyyyy) будет повторено X раз.
yyyyy
ENDM
Ниже я приведу упрощенный вариант .OUTCHAR, который вы можете использовать в простых программах. В больших проектах лучше работать с DEVICE.H и другими подобными файлами, это избавит, в дальнейшем, от многих проблем.
.OUTCHAR MACRO CHR
IF CHR
LD C,CHR
ENDIF
LD D,02
CALL 0FB06H
ENDM
Следует помнить, что макрос должен быть объявлен до его использования. В работе вам могут понадобиться некоторые стандартные константы:
black EQU 0
blue EQU 1
red EQU 2
magenta EQU 3
green EQU 4
cyan EQU 5
yellow EQU 6
white EQU 7
ESC EQU 1BH
Вот пожалуй и все, что я хотел рассказать. Тема далеко не исчерпана, но этого достаточно для начальной самостоятельной работы. Если она кого-то заинтересовала, или у вас есть другие вопросы по поводу CP/M, пишите по адресу: tae1980@yandex.ru