Данная статья написана в 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

Комментарии (0)