;---------------------------------------------------------------------------- 
; READ DOT  --  WRITE DOT 
;Эта программа ссчитывает/записывает точку (пиксель) в указанной ячейке 
;Вход: 
;  DX -номер элементарной строки (0-199) 
;  CX -номкр элементарной колонки (0-639) 
;  AL - точка для вывода (1,2 или 4 бита в зависимости от режима записи точки, 
;       выровнены по правому краю). Если бит 7=1, то необходимо выполнить 
;       операцию XOR над AL и текущим значением точки. 
;  DS - сегмент данных 
;  ES - сегмент (области) буфера регенерации 
;Выход: 
;  AL - значение точки, выровненное по правому краю 
;---------------------------------------------------------------------------- 
        ASSUME CS:CODE,DS:DATA,ES:DATA 
READ_DOT        PROC   NEAR   ;Чтение точки 
        CALL    R3            ;Определить позицию байта точки 
        MOV     AL,ES:[SI]    ;Получить байт 
        AND     AL,AH         ;Маска на другие биты в байте 
        SHL     AL,CL         ;Выровнять значение 
        MOV     CL,DH         ;Получить число битов 
        ROL     AL,CL         ;Выровнять по правому краю результат 
        JMP     VIDEO_RETURN  ;Возврат из ВИДЕО 
READ_DOT        ENDP 
 
WRITE_DOT       PROC   NEAR   ;Запись точки 
        PUSH    AX            ;Сoхранить значение точки 
        PUSH    AX            ;Дважды 
        CALL    R3            ;Определить позицию байта точки 
        SHR     AL,CL         ;Сдвиг для установки битов при выходе 
        AND     AL,AH         ;Сбросить остальные биты 
        MOV     CL,ES:[SI]    ;Получить текущий байт 
        POP     BX            ;Восстановить флаг для XOR (бит 7) 
        TEST    BL,80H        ;Установлен? 
        JNZ     R2            ;Да, операция XOR для точки 
        NOT     AH            ;Установить маску для передачи указанных битов, 
                              ; или новое значение этих битов 
        AND     CL,AH 
        OR      AL,CL          
R1: 
        MOV     ES:[SI],AL    ;Записать байт в память 
        POP     AX 
        JMP     VIDEO_RETURN  ;Возврат из ВИДЕО 
R2:                           ;XOR_DOT 
        XOR     AL,CL         ;XOR для точки 
        JMP     R1            ;Конец записи точки 
WRITE_DOT       ENDP 
;-------------------------------------------------------------------------- 
;Эта программа определяет относительный адрес байта (внутри буфера 
;регенерации), по которому должна быть считана/записана точка с заданными 
;координатами в графических режимах 
;Вход: 
; DX - номер элементарной строки (0-199) 
; CX - номер колонки (0-639) 
;Выход: 
; SI - смещение байта точки в буфере 
; AH - маска для выделения битов точки 
; CL - количество сдвигов битов маски в AH 
; DH - число бит значения точки 
;----------------------------------------------------------------------------- 
R3      PROC    NEAR 
        PUSH    BX                   ;Сохранить регистры 
        PUSH    AX 
; 
;------Определение 1-го байта заданной строки умножением на 40. 
;      Младший бит строки определяет четно/нечетную 80-байтовую строку 
; 
        MOV     AL,40 
        PUSH    DX                   ;Сохранить значение строки 
        AND     DL,0FEH              ;Сброс бита чет/нечет 
        MUL     DL                   ;AX содержит адрес 1-го байта указанной 
                                     ;строки 
        POP     DX                   ;Восстановить значение 
        TEST    DL,1                 ;Проверить на чет/нечет 
        JZ      R4                   ;Переход, если строка четная 
        ADD     AX,2000H             ;Смещение для нахождения нечетных строк 
R4:                                  ;Четная строка 
        MOV     SI,AX                ;Передать указатель в SI 
        POP     AX                   ;Восстановить значение 
        MOV     DX,CX                ;Значение колонки в DX 
; 
;-------Определение параметров графических режимов для непосредственного 
;       воздействия 
;Установить регистры в соответствии с режимом: 
;  CH - маска для младшей части адреса колонки (3/2 для высокого/среднего 
;       разрешения) 
;  CL - количество битов адреса в значении колонки (3/2 для в/с ) 
;  BL - маска выбора битов из указанного байта (80H/C0H для в/с ) 
;  BH - количество бит, определяющее точку(1/2 для в/с) 
 
        MOV     BX,2C0H 
        MOV     CX,302H              ;Установка параметров для режима среднего 
                                     ; разрешения 
        CMP     CRT_MODE,6 
        JC      R5                   ;Обработка для среднего разрешения 
        MOV     BX,180H 
        MOV     CX,703H              ;Установить параметры для режима высокого 
                                     ; разрешения 
; 
;------Определение смещения бита в байте по маске колонки 
R5: 
        AND     CH,DL 
; 
;------Определение смещения байта по этому биту в колонке 
; 
        SHR     DX,CL                ;Сдвиг для коррекции 
        ADD     SI,DX                ;Инкремент указателя 
        MOV     DH,BH                ;Получить количество битов в DH 
; 
;------Умножить BH (значащие биты в байте) на CH (смещение бита) 
; 
        SUB     CL,CL                ;Очистить 
R6: 
        ROR     AL,1                 ;Выравнивание значения в AL 
                                     ;(Для записи) 
        ADD     CL,CH                ;Прибавить значение смещения бита 
        DEC     BH                   ;Счетчик цикла 
        JNZ     R6                   ;На выход, CL содержит счетчик сдвигов 
                                     ;Для обрабатываемых битов 
        MOV     AH,BL                ;Получить маску в AH 
        SHR     AH,CL                ;Сдвинуть маску для коррекции 
        POP     BX                   ;Восстановить регистр 
        RET                          ;Возврат с установленными параметрами 
R3      ENDP 
 
;---------------------------------------------------------------------------- 
;SCROLL UP 
;  Эта программа перемещает блок информации вверх по экрану (для графики) 
;Вход: 
; CH,CL -левый верхний угол окна прокрутки, 
; DH,DL -нижний правый угол окна прокрутки, 
; BH -   код заполнителя для освобождающихся строк 
; AL -   количество строк прокрутки (AL=0 означает очистку всего окна) 
; DS -   сегмент данных 
; ES -   сегмент буфера регенерации 
;---------------------------------------------------------------------------- 
GRAPHICS_UP     PROC   NEAR 
        CALL    UP_GRAPHICS 
        JMP     VIDEO_RETURN 
 
UP_GRAPHICS: 
        MOV     BL,AL                ;Число строк в BL 
        MOV     AX,CX                ;Позиция левого верхнего угла в AX 
 
;------Использовать программу для позиционирования 
;      Адрес возвращается умноженный на 2 для коррекции значения 
 
        CALL    GRAPH_POSN 
        MOV     DI,AX                ;Сохранить результат как адрес приемника 
; 
;------Определение размера окна 
; 
        SUB     DX,CX 
        ADD     DX,101H              ;Скорректированное значение 
        SAL     DH,1                 ;Умножить на 4, так-как имеем 8 
                                     ; точек/символ по вертикали 
        SAL     DH,1 
; 
;-------Определить режим 
; 
        test    CRT_MODE,2           ;Среднее разрешение? 
        JNZ     R7                   ;Определить адрес источника для высокого 
                                     ; разрешения 
; 
;------Прокрутка вверх (среднее разрешение) 
; 
        SAL     DL,1                 ;Число колонок * 2, т.к. 
                                     ;  имеем 2 байта/символ 
        SAL     DI,1                 ;Смещение * 2, т.к. имеем 2 байта /символ 
; 
;------Определить адрес источника в буфере 
; 
R7:                                  ;Найти источник 
        PUSH    ES                   ;Получить сегменты обоих указателей 
                                     ;  буфера регенерации 
        POP     DS 
        SUB     CH,CH                ;Очистить старший байт счетчика 
        SAL     BL,1                 ;Умножить число строк на 4 
        SAL     BL,1 
        JZ      R11                  ;Если 0, то полная очистка окна 
        MOV     AL,BL                ;Получить число строк в AL 
        MOV     AH,80                ;80 на строку 
        MUL     AH                   ;Определить смещение источника 
        MOV     SI,DI                ;Установить источник 
        ADD     SI,AX                ;Прибавить смещение к нему 
        MOV     AH,DH                ;Число строк в блоке 
        SUB     AH,BL                ;Определить число сдвигов 
; 
;------Цикл, перемещающий одну строку за один проход 
;      (и четные и нечетные поля) 
R8:                                  ;Цикл по строке 
        CALL    R17                  ;Передвинуть одну строку 
        SUB     SI,2000H-80          ;Указатель на следующую строку 
        SUB     DI,2000H-80 
        DEC     AH                   ;Число строк прокрутки 
        JNZ     R8                   ;Продолжать, пока все пепреместятся 
; 
;------Заполнение освобожденных строк 
R9:                                  ;Вход очистки 
        MOV     AL,BH                ;Атрибут заполнения 
R10: 
        CALL    R18                  ;Очистка строки 
        SUB     DI,2000H-80          ;Указатель на следующую строку 
        DEC     BL                   ;Число строк для заполнения 
        JNZ     R10                  ;Цикл очистки 
        RET                 ;Все сделано 
 
R11:                                 ;Элемент заполнения 
        MOV     BL,DH                ;Установить счетчик заполнения 
                                     ;  для всего окна 
        JMP     R9                   ;На очистку окна 
GRAPHICS_UP     ENDP 
 
;----------------------------------------------------------------------------- 
;SCROLL DOWN 
;  Эа программа перемещает блок информации вниз по экрану (для графики) 
;Вход: 
;  CH,CL - верхний левый угол окна прокрутки 
;  DH,DL - нижний правый угол окна прокрутки 
;  BH -    код запаолнителя для освобождающихся строк 
;  AL -    количество строк прокрутки (AL=0 означает очистку всего окна) 
;  DS -    сегмент данных 
;  ES -    сегмент буфера регенерации 
;----------------------------------------------------------------------------- 
 
GRAPHICS_DOWN   PROC   NEAR 
        CALL    DOWN_GRAPHICS 
        JMP     VIDEO_RETURN 
 
DOWN_GRAPHICS: 
        STD                          ;Установить направление 
        MOV     BL,AL                ;Счетчик строк в BL 
        MOV     AX,DX                ;Нижний правый угол окна в AX 
; 
;------Использовать подпрограмму для позиционирования. 
;      Адрес возвращается умноженным на 2 для коррекции значения 
; 
        CALL    GRAPH_POSN 
        MOV     DI,AX                ;Сохранить результат как адрес приемника 
; 
;------Определение размера окна 
; 
        SUB     DX,CX 
        ADD     DX,101H              ;Скорректированное значение 
        SAL     DH,1                 ;Умножить число строк на 4, т.к. имеем 
                                     ; 8 точек на символ по вертикали 
        SAL     DH,1 
; 
;------Определение режима 
; 
        TEST    CRT_MODE,2           ;Среднее разрешение? 
        JNZ     R12                  ;Определить адрес источника для высокого 
                                     ; разрешения 
; 
;------Проурутка вниз (среднее разрешение) 
; 
        SAL     DL,1                 ;Число колонок * 2, т.к. имеем 2 
                                     ; байта/символ 
 
        SAL     DI,1                 ;Смещение *2 т.к. имеем 2 байта/символ 
        INC     DI                   ;Указатель на последний байт 
; 
;------Определение адреса источника в буфере 
R12:                                 ;Адрес источника прокрутки 
        PUSH    ES                   ;Оба сегмента буфера регенерации 
        POP     DS 
        SUB     CH,CH                ;Очистить старший байт счетчика 
        ADD     DI,240               ;Указатель последней строки пикселей 
        SAL     BL,1                 ;Умножить число строк на 4 
        SAL     BL,1 
        JZ      R16                  ;Если 0, то очистить все окно 
        MOV     AL,BL                ;Число строк в AL 
        MOV     AH,80                ;80 байт на строку 
        MUL     AH                   ;Определить смещение источника 
        MOV     SI,DI                ;Установить источник 
        SUB     SI,AX                ;Вычесть смещение 
        MOV     AH,DH                ;Число строк в окне 
        SUB     AH,BL                ;Определить число сдвигов 
; 
;------Цикл, премещающий одну строку за один раз (четные и нечетные поля 
;       одновременно) 
R13:                                 ;Цикл по строке 
        CALL    R17                  ;Сдвинуть одну строку 
        SUB     SI,2000H+80          ;Перейти к следующей строке 
        SUB     DI,2000H+80 
        DEC     AH                   ;Число строк для прокрутки 
        JNZ     R13                  ;Прдолжать, пока все переместятся 
; 
;------Заполнение освобожденных строк 
R14:                                 ;Вход очистки 
        MOV     AL,BH                ;Атрибут заполнения 
R15:                                 ;Вход очистки 
        CALL    R18                  ;Очистить строку 
        SUB     DI,2000H+80          ;Указатель на следующую строку 
        DEC     BL                   ;Число строк для заполнения 
        JNZ     R15                  ;Цикл очистки 
        CLD                          ;Сбросить флаг направления 
        RET              ;Все сделано 
 
R16:                                 ;Элемент заполнения 
        MOV     BL,DH                ;Установить счетчик заполнения 
                                     ; для всего окна 
        JMP     R14                  ;На очистку окна 
 
GRAPHICS_DOWN   ENDP 
 
;------Программа перемещения одной строки информации 
 
R17     PROC    NEAR 
        MOV     CL,DL                ;Число байт в строке 
        PUSH    SI 
        PUSH    DI                   ;Сохранить указатели 
        REP     MOVSB                ;Вернуть счетчик 
        POP     DI 
        POP     SI 
        ADD     SI,2000H 
        ADD     DI,2000H             ;Указатель нечетного поля 
        PUSH    SI 
        PUSH    DI                   ;Сохранить указатели 
        MOV     CL,DL                ;Вернуть счетчик 
        REP     MOVSB                ;Сдвинуть нечетное поле 
        POP     DI 
        POP     SI                   ;Вернуть указатели 
        RET                          ;Возврат 
R17     ENDP 
; 
;------Очистка одной строки 
; 
R18     PROC    NEAR 
        MOV     CL,DL                ;Число байт в поле 
        PUSH    DI                   ;Сохранить указатель 
        REP     STOSB                ;Заслать заполнитель 
        POP     DI                   ;Вернуть указатель 
        ADD     DI,2000H             ;Указатель нечетного поля 
        PUSH    DI 
        MOV     CL,DL 
        REP     STOSB                ;Заполнить нечетное поле 
        POP     DI 
        RET                          ;Возврат 
R18     ENDP 
;--------------------------------------------------------------------------- 
;GRAPHICS WRITE 
;Эта программа записывает символ в ASCII в текущую позицию на экране 
; (графические режимы) 
;Вход: 
; AL - символ для записи, 
; BL - атрибут цвета, который должен использоваться в качестве цвета символа. 
;       Если бит 7=1, то выполняется операция XOR над текущим байтом буфера 
;       регенерации и заданным, 
; CX - число символов для записи, 
; DS - сегмент данных, 
; ES - сегмент буфера регенерации 
; 
;GRAPHICS READ 
;  Эта программа считывает символ в ASCII в текущей позиции экрана 
;  преобразованием точек экрана с помощью генератора символов в код 
;  (графические режимы) 
;Вход: 
; Нет  (0 - определяет цвет фона) 
;Выход: 
; AL - прочитанный символ (0, если  не найден) 
; 
;Для обеих программ матрицы символов (8*8 точек) хранятся в ПЗУ. 
; Вторая половина кодов (128...255) - матрицы хранятся в ОЗУ. Доступ через 
; парерывание INT 1FH (7CH) - указатель на таблицу. 
;------------------------------------------------------------------------ 
        ASSUME CS:CODE,DS:DATA,ES:DATA 
GRAPHICS_WRITE  PROC   NEAR 
        CALL    WRITE_GRAPHICS 
        JMP     VIDEO_RETURN 
 
WRITE_GRAPHICS: 
        MOV     AH,0 
        PUSH    AX                   ;Сохранить код символа 
; 
;-------Определение позиции в буфере регенерации для засылки кодов точек 
; 
        CALL    S26                  ;Определить ячейку в буфере регенерации 
S1A:    MOV     DI,AX                ;Указатель буфера - в DI 
; 
;------ Определить область для извлечения кодов точек 
; 
        POP     AX                   ;Восстановить код 
S1B: 
        CMP     AL,80H               ;Вторая половина кодов (128-255)? 
        JAE     S1                   ;Да 
; 
;------ Матрица (изображение) есть в первой половине, содержится в ПЗУ 
; 
        MOV     SI,OFFSET CRT_CHAR_GEN      ;Смещение матрицы 
        PUSH    CS                          ;Сохранить сегмент в стеке 
        JMP     SHORT S2                    ;Определить режим 
; 
;------ Матрицы второй половины кодов (русские) хранятся в пользовательском ОЗУ 
; 
S1:                                  ;Символы расширенного набора 
        SUB     AL,80H               ;Очистить источник для второй половины 
        PUSH    DS                   ;Сохранить указатель данных 
        SUB     SI,SI 
        MOV     DS,SI                ;Установить вектор адресации 
        ASSUME  DS:ABS0 
        LDS     SI,EXT_PTR           ;Получить смещение таблицы 
        MOV     DX,DS                ;Получить сегмент таблицы 
        ASSUME  DS:DATA 
        POP     DS                   ;Восстановить сегмент данных 
        PUSH    DX                   ;Сохранить сегмент таблицы 
; 
;------ Определение графического режима операции 
; 
S2: 
        SAL     AX,1                 ;Умножить значение кода на 8 
        SAL     AX,1 
        SAL     AX,1 
        ADD     SI,AX                ;SI- смещение требуемого кода в таблице 
        MOV     AL,CRT_MODE 
        POP     DS            ;Восстановить указатель сегмента таблицы 
        TEST    AL,2       ;Режим 2? 
        JNZ     S201                  ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 
        JMP     S7 
S201:    TEST    AL,4      ;Режим 4? 
        JNZ     S3 
; 
;------ Текстовый режим высокого разрешения 
; 
SS3: 
 
        PUSH    DI            ;Сохранить указатель буфера регенерации 
        PUSH    SI            ;Сохранить указатель кода 
SSS: 
        MOV     DH,4          ;Количество циклов 
SS4: 
        LODSB                 ;Получить байт по указателю в AL 
        TEST    BL,78H        ;ПРИСУТСТВУЕТ интенсивность или реверс 
        JNZ     SS6           ;ВЫДАТЬ СИМВОЛ В цвете 
        STOSB                 ;Засылка в буфер регенерации 
        LODSB 
SS5: 
 
        MOV     ES:[DI+2000H-1],AL     ;Заслать во вторую половину 
        ADD     DI,79         ;Передать следующую строку в буфер регенерации 
        DEC     DH            ;Выполнить цикл 
        JNZ     SS4 
 
        POP     SI 
        POP     DI            ;Восстановить указатель буфера регенерации 
        INC     DI            ;Указатель на позицию следующего символа 
 
        CALL    AN_STR 
        CMP     DI,8000-80*3 
        JNB     S5_S2 
        LOOP    SS3    ;Цикл записи символа 
 
S5_S2: 
        RET 
SS6: 
        OR      AL,80H        ;УСТАНОВИТЬ БИТ ЦВЕТА 
        STOSB                 ;ЗАПИСАТЬ БАЙТ 
        LODSB                 ;ВЗЯТЬ СЛЕДУЮЩИЙ БАЙТ 
        OR      AL,80H        ;УСТАНОВИТЬ БИТ ЦВЕТА 
        JMP     SS5            ;Вернуться 
; 
;------ Графический режим высокого разрешения 
; 
S3: 
        PUSH    DI            ;Сохранить указатель буфера регенерации 
        PUSH    SI            ;Сохранить указатель кода 
        MOV     DH,4          ;Число циклов 
S4: 
        LODSB                 ;Получить байт 
        TEST    BL,080H       ;Проверка, должна ли использоваться операция XOR 
        JNZ      S6           ; при засылке символа в буфер регенерации 
        STOSB                 ; Нет. Заслать в буфер регенерации 
        LODSB 
S5: 
 
S51:    MOV     ES:[DI+2000H-1],AL     ;Заслать во вторую половину 
        ADD     DI,79         ;Передать следующую строку в буфер регенерации 
        DEC     DH            ;Выполнить цикл 
        JNZ     S4 
        POP     SI 
        POP     DI            ;Восстановить указатель буфера регенерации 
        INC     DI            ;Указатель на позицию следующего символа 
 
 
 
        LOOP    S3            ;Цикл записи символа 
        RET 
S6: 
        XOR     AL,ES:[DI]    ;Операция XOR с текущим значением 
        STOSB                 ;Заслать код точки 
        LODSB                 ;Повторить для нечетного поля 
        XOR     AL,ES:[DI+2000H-1]     ; 
        JMP     S5            ;Вернуться 
; 
;------ Запись в режиме среднего разрешения 
; 
S7: 
;        CLI 
        MOV     DL,BL         ;Сохранить старший бит цвета 
        SAL     DI,1          ;Умножить смещение на 2, т.к. имеем 
                              ;  2 байта на символ 
        CALL    S19           ;Расширить BL до слова 
S8: 
 
 
        PUSH    DI            ;Сохранить указатель буфера регенерации 
        PUSH    SI            ;Сохранить указатель кода 
        MOV     DH,4          ;Число циклов 
S9: 
        LODSB                 ;Получить код точки 
        CALL    S21           ;Дублировать все биты 
        AND     AX,BX         ;Преобразовать их в цвет фона (0) 
        TEST    DL,80H        ;Есть операция XOR 
        JZ      S10           ;Нет, заслать такой, какой есть 
        XOR     AH,ES:[DI]    ;Выполнить XOR с одной половиной 
        XOR     AL,ES:[DI+1]  ; И с другой половиной 
S10:                          ; 
        MOV     ES:[DI],AH    ;Заслать первый байт 
        MOV     ES:[DI+1],AL  ;Заслать второй байт 
        LODSB                 ;Получить код точки 
        CALL    S21 
        AND     AX,BX         ;Преобразовать цвет 
        TEST    DL,80H        ;Снова: есть операция XOR? 
        JZ      S11           ;Нет, запомнить значения 
        XOR     AH,ES:[DI+2000H]       ;Операция XOR с первой половиной 
        XOR     AL,ES:[DI+2000H+1]     ;И со второй половиной 
S11:                          ; 
        MOV     ES:[DI+2000H],AH 
        MOV     ES:[DI+2000H+1],AL     ;Заслать во вторую часть буфера 
        ADD     DI,80         ;Указатель на следующую ячейку 
        DEC     DH 
        JNZ     S9     ;Повторить 
        POP     SI            ;Восстановить указатель цикла 
        POP     DI            ;Восстановить указатель буфера регенерации 
        INC     DI            ;Указатель на позицию следующего символа 
        INC     DI 
 
 
        CALL    AN_STR 
        CMP     DI,8000-80*3 
        JNB     S5_S21 
 
 
        LOOP    S8            ;Цикл записи 
S5_S21: 
;        STI 
        RET 
GRAPHICS_WRITE  ENDP 
;----------------------------------- 
; Чтение в графических режимах 
;----------------------------------- 
GRAPHICS_READ   PROC   NEAR 
        CALL    S26           ;Возвращает смещение в буфере регенерации 
        MOV     SI,AX         ;Сохранить в SI 
        SUB     SP,8          ;Распределить область для хранения кода 
                              ; считанной точки 
        MOV     BP,SP         ;Указатель для хранения области 
; 
;------ Определение графических режимов 
; 
        TEST    CRT_MODE,2 
        PUSH    ES 
        POP     DS 
        JZ      S13 
; 
;------ Чтение в режиме высокого разрешения 
;------ Получить значения из буфера регенерации и преобразовать в код точки 
; 
        MOV     DH,4          ;Число проходов цикла 
S12: 
        MOV     AL,[SI]        ;Получить первый байт 
        MOV     [BP],AL        ;В область сохранения 
        INC     BP             ;Следующая ячейка 
        MOV     AL,[SI+2000H]  ;Получить байт из младшей области буфера 
                               ; регенерации 
        MOV     [BP],AL        ;Выровнять и сохранить 
        INC     BP 
        ADD     SI,80         ;Указатель в буфере регенерации 
        DEC     DH            ;Цикл 
        JNZ     S12           ;Выполнить еще раз 
        JMP SHORT S15         ;Переход к сохраненным кодам точек 
; 
;------ Чтение в режиме среднего разрешения 
; 
S13: 
        SAL     SI,1          ;Смещение *2, т.к. имеем 2 байта на символ 
        MOV     DH,4          ;Число проходов цикла 
S14: 
        CALL    S23           ;Взять пару байтов из буфера регенерации 
        ADD     SI,2000H      ;Переход к младшей части буфера регенерации 
        CALL    S23           ;Взять пару для сохранения 
        SUB     SI,2000H-80   ;Вернуть указатель на старшую часть буфера 
        DEC     DH 
        JNZ     S14           ;Выполнить 8 раз 
; 
;------ Сохранить обдасть, содержащую символ, упорядочить 
; 
S15:                          ;Найти символ 
        MOV     DI,OFFSET CRT_CHAR_GEN      ;Смещение матрицы 
        PUSH    CS 
        POP     ES 
        SUB     BP,8          ;Выровнять указатель на начало области 
                              ; сохранения 
        MOV     SI,BP 
        CLD                   ;Установить направление 
        MOV     AL,0          ;Текущий отмеченный код точки 
S16: 
        PUSH    SS            ;Установить адресацию стека 
        POP     DS            ;Для сравниваемой строки 
        MOV     DX,128        ;Число повторов проверки 
S17: 
        PUSH    SI            ;Сохранить указатель области сохранения 
        PUSH    DI            ;Сохранить указатель кода 
        MOV     CX,8          ;Число байтов для сравнения 
        REPE    CMPSB         ;Сравнить 8 байтов 
        POP     DI            ;Восстановить указатели 
        POP     SI 
        JZ      S18           ;Если 0, пара найдена 
        INC     AL            ;Нет пары, на следующий 
        ADD     DI,8          ;Следующий код точки 
        DEC     DX            ;Цикл 
        JNZ     S17           ;Выполнить по всем 
; 
;------ Символ не совпал, возможно используется во второй половине 
; 
        CMP     AL,0          ;Если AL<>0, то проверена только первая половина 
        JE      S18           ;Если AL=0, то проверены обе 
        SUB     AX,AX 
        MOV     DS,AX         ;Установить адресацию вектора 
        ASSUME  DS:ABS0 
        LES     DI,EXT_PTR    ;Получить указатель 
        MOV     AX,ES         ;Проверить, существует ли указатель 
        OR      AX,DI         ;Если все 0, то не существует 
        JZ      S18           ;Нет смысла просматривать 
        MOV     AL,128        ;Начало для второй половины 
        JMP     S16           ;Вернуться и попытаться для нее 
        ASSUME  DS:DATA 
; 
;------ Координаты символа найдены (AL=0, если не найдены) 
S18: 
; 
        ADD     SP,8          ;Очистка стека, все что сохраняли 
        JMP     VIDEO_RETURN  ;Все сделано 
GRAPHICS_READ   ENDP 
;-------------------------------------------------------------------- 
;EXSPAND_MED_COLOR 
; Эта программа распространяет младшие 2 бита регистра BL (цвет символа), 
; заполняя регистр BX (2*8) - для преобразования символа в цветовую матрицу 
; точек 
;Вход: 
; BL - атрибут цвета (младшие 2 бита) 
;Выход: 
; BX - цвет точек (8 копий 2-х битов цвета) 
;------------------------------------------------------------------------ 
S19     PROC    NEAR 
 
        PUSH    BX            ;********************** 
        MOV     BH,BL 
        TEST    BL,0F0H 
        JNZ     S190 
        POP     BX 
        JMP     S191 
 
S190:   AND     BH,03H 
        CMP     BL,BH 
        POP     BX 
        PUSH    CX 
        MOV     CL,4 
        SHR     BL,CL 
        JNZ     S1901 
        INC     BL 
S1901: POP     CX 
 
S191:   AND     BL,3          ;Выделить биты цвета 
        MOV     AL,BL         ;Скопировать в AL 
        PUSH    CX            ;Сохранить регистр 
        MOV     CX,3          ;Количество выполнений 
S20: 
        SAL     AL,1 
        SAL     AL,1          ;Сдвиг влево на 2 
        OR      BL,AL         ;Другая версия цвета в BL 
        LOOP    S20           ;Заполнить весь BL 
        MOV     BH,BL         ;Заполнить верхнюю часть BX 
        POP     CX            ;Восстановить регистр 
        RET                   ;Все сделано 
S19     ENDP 
;------------------------------------------------------------------------ 
; EXPAND_BYTE 
;  Эта программа берет байт в AL и удваивает все биты, превращая 8 бит в 16 бит 
;  Результат возвращается в AX. 
;------------------------------------------------------------------------- 
S21     PROC    NEAR 
        PUSH    DX            ;Сохранить регистры 
        PUSH    CX 
        PUSH    BX 
 
        TEST    DL,0F0H       ;******************************* 
        JZ      S211 
        NOT     AL            ;******************************** 
 
S211:   MOV     DX,0          ;Регистр результата 
        MOV     CX,1          ;Регистр маски 
S22: 
        MOV     BX,AX         ;База на шаг 
        AND     BX,CX         ;Использовать маску для выделения бита 
        OR      DX,BX         ;Поместить в регистр результата 
        SHL     AX,1 
        SHL     CX,1          ;Сдвинуть базу и маску на 1 
        MOV     BX,AX         ;База на шаг 
        AND     BX,CX         ;Выделить тот же бит 
        OR      DX,BX         ;Поместить в результат 
        SHL     CX,1          ;Сдвинуть теперь только маску 
        JNC     S22           ;Использовать бит маски, если не конец 
        MOV     AX,DX         ;Результат в регистр параметра 
        POP     BX 
        POP     CX            ;Восстановить регистры 
        POP     DX 
        RET                   ;Все сделано 
S21     ENDP 
 
 
