|
|
|
|
Управление отображением на экране
Учитывая ранее приведенные ограничения в сервисе видео ROM-BIOS, для непосредственного управлении аппаратурой отображения на экран часто
требуется TSR. Прямое чтение и запись на экран ускоряют процесс переключения дисплеев, когда горячий ключ активизирует TSR, устраняет проблему,
связанную с изменением между текстовым и и графическим режимами, может уменьшить прямой доступ к контроллеру 6845 CRT.
------------------------------------------------------------------
ПРЕДУПРЕЖДЕНИЕ:
Прямой доступ к аппаратуре отображения может быть опасен.
Ошибка при такой обработке может разрушить Ваш монитор.
------------------------------------------------------------------
|
Перед тем, как попытаться программировать дисплей, надо себе представлять, как он работает. Нижеследующее обсуждение является просто обзором;
подробнее см. в "Hardware Technical Reference Manual".
Есть два способа для изменения содержимого экрана. Один способ заключается в поддержке двух буферов: один из них содержит образ экрана TSR, а
другой - образ экрана приложений DOS. Второй способ замещает видео-память одного из этих буферов; это сохраняет некоторую память за счет незначительного
замедления ответа.
Листинг 4-9 демонстрирует способ дублирования буферов. При нажатии горячего ключа текущий экран копируется в буфер приложений DOS, и затем
содержимое буфера TSR перемещается в память дисплея. Вы можете в этот момент пересылать больший блок данных, так что используйте команду пересылки
строк. Расчет временных циклов предполагает, что эта процедура займет около 21 мс для вы полнения на 8088 процессоре с частотой 4.77 MHz. Реальные
замеры дают около 29 мс. Разница частично вызвана погрешностями метода расчета временных циклов; остальное относится за счет одновременного обращения к
неразделяемому ресурсу. Замер времени был сделан при включенном дисплее - в худшем варианте.
Листинг 4-9. Переключение экранов
с использованием двух буферов
----------------------------------------------------------------
_text SEGMENT WORD PUBLIC 'CODE'
ASSUME cs:_text, ds:_text, es:_text
VideoSEG DW 0b000h
DOSBuffer DW 25*80 DUP (0)
TSRBuffer DW 25*80 DUP (720h)
Switct PROC NEAR
cld ; флаг направления <== UP
lea di,DOSBuffer ; di <== смещение буфера
mov ax,cs
mov es,ax ; es:di <== буфер DOS
xor si,si ; si <== смещение видео
mov ds,VideoSEG ; ds:si <== память видео
mov cx,25*80 ; cx <== слова на отображении
rep movsw ; DOSBuffer <== память видео
mov ds,ax
lea si,TSRBuffer ; ds:si <== буфер TSR
mov es,VideoSEG ;
xor di,di ; es:di <== видео память
mov cx,25*80 ; cx <== слова на отображении
rep movsw ; память видео <== буфер TSR
ret
Switch ENDP
----------------------------------------------------------------
|
Следующий листинг использует только один буфер. Использование отдельного буфера замедляет последовательность mov/xchg и требует для изменения
экрана при включенном дисплее приблизительно 45 мс. Такая производительность вполне приемлема. Заметим, что выравнивание буфера по границе параграфа
обходится в дополнительную команду add, но это изменение не влияет на производительность.
Листинг 4-10. Переключение экрана
с использованием отдельного буфера
----------------------------------------------------------------
_text SEGMENT WORD PUBLIC 'CODE'
ASSUME cs:_text, ds:_text, es
VideoSEG DW 0b000h
TSRBuffer DW 25*80 DUP (720h)
Switch PROC NEAR
cld ; проверка, что мы подвинулись
lea si,TSRBuffer ; si <== смещение буфера TSR
xor di,di ; di <== смещение видеопамяти
mov bx,2 ; bx <== размер сдвига
mov es,VideoSEG ; ds:si <== видеопамять
mov cx,25*80 ; cx <== слова на экране
_nb mov ax,[si]; ax <== слово из буфера TSR
xchg ax,es:[di] ; видеопамять <== буфер TSR
; ax <== слово из видеопамяти
mov [si],ax; буфер TSR <== видеопамять
аdd si,bx
add di,bx
loop _nd
ret
Switch ENDP
----------------------------------------------------------------
|
|
|