Справочник программиста на персональном компьютере фирмы IBM. Вывод на терминал - Вывод на экран одного символа. Часть 3

ОГЛАВЛЕНИЕ

   Низкий уровень.


   На  нижнем  уровне  весь вывод на экран  осуществляется  через
отображение в память.  Эту  технику  не рекомендуют использовать,
чтобы не столкнуться с проблемой совместимости с будущими поколе-
ниями машин, однако до сих пор IBM делало видеобуфер своих микро-
компьютеров устроенным одинаково и расположенным в одних и тех же
адресах памяти.  Поскольку буфер устроен таким образом, что байты
атрибутов  перемежаются с байтами символов, то символьные  данные
не могут просто пересылаться из памяти в буфер инструкцией MOVSB,
поскольку  указатель  в буфере должен увеличиваться на два  после
каждого переноса байта.  Однако,  использование  этой техники су-
щественно  ускоряет  вывод на экран.  Отметим, что отображение  в
память не работает при выводе  символов  в  графическом режиме. В
этом  случае размер видеобуфера 16K или 32K и BIOS рисует  каждый
символ поточечно.  Отметим также, что при отображении в память не
используется  курсор для указания на символ.  При  желании  можно
перемещать курсор по мере ввода  [4.2.1] или выключить его и соз-
дать свой псевдокурсор [4.2.6].

;---в сегменте данных
SAMPLE_STRING  DB   'PRINT THIS STRING$'

;---вывод строки
       MOV  AX,0B000H            ;монохромный дисплей
       MOV  ES,AX                ;указываем на видеобуфер
       LEA  BX,SAMPLE_STRING     ;BX указывает на строку
       MOV  DI,CURSOR_START      ;начальная позиция в буфере
NEXT:  MOV  AL,[BX]              ;берем символ
       CMP  AL,'$'               ;проверка на конец строки
       JE   ALL_DONE             ;если да, то выход
       MOV  ES:[DI],AL           ;иначе помещаем символ в буфер
       INC  DI                   ;увеличиваем указатель на 2
       INC  DI                   ;
       INC  BX                   ;переходим к обработке следу-
       JMP  SHORT NEXT           ;щего символа
ALL_DONE:

   У  цветного графического адаптера и PCjr (но не у EGA) имеется
проблема, связанная с  отображением  в память. Когда запись в бу-
ферную  память происходит одновременно с чтением ее для вывода на
экран, то на экране возникает интерференция. Эта проблема решает-
ся  ожиданием  сигнала "все чисто" (all clear)  перед  записью  в
видеобуфер. Надо непрерывно читать значение из порта 3DAH.  Когда
бит 0 равен 1, то можно спокойно писать.  (3DAH - это порт, через
который PCjr посылает данные массиву ворот дисплея; когда из него
читаем,  то он возвращает регистр статуса, как и у цветного адап-
тора.)

;---ожидаем пока все чисто
        MOV  DX,3DAH          ;порт регистра статуса
CHECK_AGAIN:   IN   AL,DX     ;получаем значение
        TEST AL,1             ;проверка первого бита
        JNE  CHECK_AGAIN      ;если он 0, то обратно
;---теперь выводим сообщение
        LEA  BX,MESSAGE       ;сообщение в сегменте данных
        MOV  DI,2000          ;начинаем вывод с центра экрана
        MOV  AH,01000001B     ;атрибут синий на красном
NEXT_CHAR:   MOV  AL,[BX]     ;берем символ
        CMP  AL,'$'           ;проверяем на конец строки
        JE   ALL_DONE         ;если конец, то на выход
        MOV  ES:[DI],AX       ;иначе выводим символ
        INC  BX               ;увеличиваем указатель строки
        INC  DI               ;увеличиваем указатель буфера
        INC  DI               ;
        JMP  SHORT NEXT_CHAR  ;обрабатываем следующий символ
ALL_DONE:

   Вы можете поэкспериментировать  сколько  символов за один цикл
может выводить Ваша процедура без появления интерференции. Имейте
ввиду, что при первом выполнении цикла тестируемый бит может быть
равным  единице, но может не оставаться времени, чтобы  завершить
операцию записи.
   PCjr  специально  сконструирован   таким  образом, что вывод в
адреса, используемые буфером цветного графического дисплея  пере-
направляется в ту  область  памяти,  где  на самом деле находится
буфер.   Это  свойство позволяет делать программное  обеспечение,
подходящее для обоих систем.