 
;----INT 10--------------------------------------------------- 
;VIDED_IO 
;       Эта программа обеспечивает интерфейс видеорежимов. 
;       Следующие функции реализованы: 
;       (AH)=0 Установка режима (AL) Содержит значение режима. 
;               (AL)=0 40*25 Черно/белый (BW) 
;               (AL)=1 40*25 Цветной 
;               (AL)=2 80*25 Черно /белый 
;               (AL)=3 80*25 Цветной 
;               Графические режимы 
;               (АL)=4 320*200 Цветной 
;               (AL)=5 320*200 Черно/белый 
;               (AL)=6 640*200 Черно/белый 
;               CRT MODE=7 80*25 Черно/белый (режим CRT) 
;               ***NOTE BW MODES OPERATE SAME AS COLOR MODES,BUT COLOR 
;               BURST IS NOT ENABLED 
;       (AH)=1 Установка типа курсора 
;               (CH)= Биты 4-0= строка начала курсора 
;                      ** Аппаратно всегда вызываются мерцания 
;                      ** Биты 5 и 6 вызывают неравномерное мерцание 
;                         или исчезновение курсора 
;               (CL)= Биты 4-0= строка исчезновения курсора 
;       (AH)=2 Установка позиции курсора 
;               (DH,DL)= Строка, колонка (0,0) Левый верхний угол 
;               (BH)= Номер страници (0 Для графического режима) 
;       (AH)=3 Чтение позиции курсора 
;               (BH)= Номер страници (0 Для графического режима) 
;               На выходе (DH,DL)= Строка, колонка текущей позиции курсора 
;                         (CH,CL)= Текущий режим курсора 
;       (AH)=4 Чтение позиции светового пера 
;              (в БМ ЭВМ нереализовано,световое перо отсутсвует) 
;               (AH)=0-- LIGHT REN SWITCH NOT DOWN/NOT TRIGGERED 
;               (AH)=1-- VALID LIGHT REN VALUE IN REGISTERS 
;                      (DH,DL)= ROW,COLUMN OF CHARACTER LP POSN 
;                      (CH)= RASTER LINE(0-199) 
;                      (BX)=PIXEL COLUMN(0-319,639) 
;       (AH)=5 Выбор активной страницы (только для текстовых режимов) 
;               (AL)= Значение новой страницы (0-7 для режимов 0 или 1, 
;                      0-3 для режимов 2 или 3) 
;       (AH)=6 Прокрутка активной страницы вверх 
;               (AL)= Число строк проктрутки (освобождающиеся строки 
;                     внизу окна заполняются пробелами) 
;                     AL=0 Очистка всего окна 
;               (CH,CL)= Строка, колонка верхнего левого угла окна 
;               (DH,DL)= Строка, колонка правого нижнего угла окна 
;               (BH)= Атрибут для строк заполнения окна 
;       (AH)=7 Прокрутка активной страницы вниз 
;               (AL) = Число строкпрокрутки (освобождающиеся строки 
;                      вверху окна заполняются пробелами) 
;                      AL = 0 Очистка всего окна (пробелами) 
;               (CH,CL)= Строка, колонка верхнего левого угла окна 
;               (DH,DL)= Строка, колонка нижнего правого угла окна 
;               (BH)= атрибут для строк заполнения 
; 
;       Режим обработки символов 
; 
;       (AH)=8 Чтение атрибута/символа втекущей позиции курсора 
;               (BH)= Номер страницы (только для текстового режима) 
;               На выходе: 
;               (AL)= Прочитанный символ 
;               (AH)= Атрибут прочитанного символа (только для 
;                     текстового режима) 
;        (AH)=9 Запись атрибута/символа в текущую позицию курсора 
;               (BH)= Номер страницы (только для текстовых режимов) 
;               (CX)= Счетчик символов (повторений) для записи 
;               (AL)= Символ для записи 
;               (BL)= Атрибут символа (текст) или цвет (графика) 
; 
;       (AH)=10 Запись только символа в текущую позицию курсора 
;               (BH)= Номер страницы (только для текстовых режимов) 
;               (CX)= Счетчик символов (повторений) для записи 
;               (AL)= Символ для записи 
;       Для записи/чтения символов в графическом режиме знаки 
;               формируются в знакогенераторе, который находится в ПЗУ 
;               (только первые 128 знаков). Для считывания/записи вторых 
;               128 знаков пользователь должен через прерывание 1FH 
;               (ячейка 0007С) инициализировать указатель на 1К таблицу, 
;               содержащую коды вторых 128 знаков. 
; 
;       При записи символов в графических режимах счетчик СХ будет дейст- 
;               вовать только для текущей строки. Переход в следующую 
;               строку будет некорректным. 
; 
; 
;       Режимы обработки графики 
;       (AH)=11 Установка цветовой палитры 
;               (BH)= Цветовая палитра (0-127) 
;               (BL)= Управление цветом (для текущей цветовой 
;                  палитры, только для графики 320*200 
;                      ВН=0 Выбор цвета фона, BL (0-15) 
;                      BH=1 Выбор палитры: 
;                           BL=0 - зеленый (1), красный (2), желтый (3) 
;                           BL=1 - циан (1), мажента (2), белый (3) 
; 
; 
;       (AH)=12 Запись точки 
;               (DX)= Номер строки 
;               (CX)= Номер колонки 
;               (AL)= Значение цвета 
;                      Если бит 7 AL=1, тогда значение цвета образуется 
;                      операцией ХOR заданного значения и текущего 
;       (AH)=13 Чтение точки 
;               (DX)= Номер строки 
;               (CX)= Номер колонки 
;               (AL)= Возвращается прочитанная точка 
; 
;Вывод в режиме телетайпа кода ASCIL 
; 
;       (AH)=14 Запись в режиме телетайпа 
;               (AL)= Символ для записи 
;               (BL)= Цвет знакоместа в графическом режиме 
;               (BH)= Номер страницы в тектовом режиме 
;               Замечание: размер экрана определяется предварительно 
;                          заданным режимом 
;       (AH)=15 Текущий видеорежим 
;               возвращает текущее состояние 
;               (AL)= Текущий установленный режим 
;               (AH)= Номер колонки символа на экране 
;               (BH)= Текущая активная страница 
; 
;       CS,SS,DS,ES,BX,CX,DX Cохраняются программой, 
;       остальные портятся 
;-------------------------------------------------------- 
        ASSUME CS:CODE,DS:DATA,ES:VIDEO_RAM 
 
M1      LABEL   WORD   ; Таблица программ ВИДЕО ввод/вывод 
        DW      OFFSET SET_MODE         ; установка режима 
        DW      OFFSET SET_CTYPE        ; установка размера курсора 
        DW      OFFSET SET_CPOS         ; установка текущей позиции курсора 
        DW      OFFSET READ_CURSOR      ; чтение текущей позиции курсора 
        DW      OFFSET READ_LPEN        ; чтение текущей позиции светового пера 
        DW      OFFSET ACT_DISP_PAGE    ; установка активной страницы видео 
        DW      OFFSET SCROLL_UP        ; перемещение блока вверх по экрану 
        DW      OFFSET SCROLL_DOWN      ; перемещение блока вниз по экрану 
        DW      OFFSET READ_AC_CURRENT  ; чтение символа и атрибута в позиции курсора 
        DW      OFFSET WRITE_AC_CURRENT ; запись символа и атрибута в позицию курсора 
        DW      OFFSET WRITE_C_CURRENT  ; запись только символа в текущую позицию курсор
        DW      OFFSET SET_COLOR        ; установка цветовой палитры 
        DW      OFFSET WRITE_DOT        ; запись точки (пикселя) 
        DW      OFFSET READ_DOT         ; чтение точки (пикселя) 
        DW      OFFSET WRITE_TTY        ; дисплей в режиме телетайпа 
        DW      OFFSET VIDEO_STATE      ; состояние ВИДЕО 
M1L     EQU     $-M1 
 
VIDEO_IO        PROC   NEAR 
        STI                   ; разрешить прерывания 
        CLD                   ; указатель направления - вперед 
        PUSH    ES 
        PUSH    DS            ; сохранение регистров 
        PUSH    DX 
        PUSH    CX 
        PUSH    BX 
        PUSH    SI 
        PUSH    DI 
        PUSH    AX            ; сохранить АХ 
        MOV     AL,AH         ; сохранить старший байт в AL 
        XOR     AH,AH         ; очистить АН 
        SAL     AX,1          ; умножить на 2 для просмотра таблицы 
        MOV     SI,AX         ; поместить в SI для ветвления 
        CMP     AX,M1L        ; проверка АХ на <= 15 (граница кода) 
        JB      M2            ; переход по допустимому значению 
        POP     AX            ; вернуть параметр 
        JMP     VIDEO_RETURN  ; выход, АХ неверно 
M2:     MOV     AX,DATA 
        MOV     DS,AX 
        MOV     AX,START_BUFFER   ; сегмент для цветного адаптера 
        MOV     ES,AX         ; установить начало области памяти ВИДЕО 
        POP     AX            ; восстановить значение 
        MOV     AH,CRT_MODE          ; получить текущий режим в АХ 
        JMP     WORD PTR CS:[SI+OFFSET M1] 
VIDEO_IO        ENDP 
;-------------------------------------------------------- 
;SET_MODE 
;       Эта программа инициализирует параметры 
;       выбора режима. Экран очищается. 
;Вход 
;       (AL)= содержит заданный режим (0-7) 
;Выходных данных нет 
; 
;------------------------------------------------------- 
;-------- COLUMNS 
; Tаблицы параметров выбранных режимов 
VIDEO_PARMS     LABEL        BYTE 
M8      LABEL   BYTE 
        DB      CHAR_40_MODE, CHAR_40_MODE, CHAR_80_MODE, CHAR_80_MODE 
        DB      MED_RES_MODE, MED_RES_MODE, HIGH_RES_MODE, HIGH_RES_MODE 
 
M9      LABEL   WORD    ; таблица регистрации размеров 
        DW      2048    ; 40x25 
        DW      4096    ; 80x25 
        DW      16384   ; графика 
        DW      16384   ; 
 
SET_MODE        PROC   NEAR 
        PUSH    AX           ; сохранить регистр AX 
 
        CMP     AL, 8        ; проверка границы параметра 
        JB      MM3          ; переход, если < 
CURSOR_BLINK: 
        CMP     CURSOR_ON,0FH   ; проверка флага установки курсора 
        JZ      MMM15 
;        TEST    CURSOR_ON,0FFH 
;        JNZ     CUR1 
;        TEST    CURSOR_MODE,0FFH 
;        JZ      MMM15 
CUR1:   MOV     AX,EXTRA_BUFFER ; конец сегмента видео-буфера (16К) 
        MOV     ES,AX 
        CALL    M21 
        NOT     CURSOR_ON 
 
        POP     AX           ; востановить регистр AX 
 
MMM15:  JMP     VIDEO_RETURN  ; Возврат из ВИДЕО 
MM3: 
        CLI 
        MOV     AH,AL 
        IN      AL,TRAP_A     ; запретить прерывания 
        MOV     AL,AH         ; сброс тиггера HMI (ловушка) 
        MOV     SI,AX         ; сохранить режим в AL 
        MOV     CRT_MODE,AL   ; сохранить режим и SL 
        MOV     BX, OFFSET M8 
        XLAT    CS:M8 
        OUT     SCR_MODE,AL   ; ветвление 
        MOV     ADDR_6845,REG3D4  ; установить режим 
; 
;-------Разрешение/запрет цвета (вит D7) 
; 
        CMP     AH,3 
        JNZ     ED1 
        MOV     AL,40H       ; Цветной 
        JMP     ED3 
ED1:    CMP     AH,2 
        JNZ     ED2 
        MOV     AL,40H 
        JMP     ED3 
ED2:    MOV     AL,80H       ; Черно/белый 
ED3:    OUT     P6A,AL 
; 
;-------Заполнение и очистка области регенрации 
; 
        XOR DI,DI             ; Установить режим для регенирации 
        MOV  CRT_START,DI     ; Начальный адрес 
        MOV     CX,8192       ; Число слов в буфере регенирации 
        CMP     AH,4          ; Проверка на графику 
        JAE     M12           ; Не графические режимы 
        CALL    NMI_DISABLE   ; Запрет NMI на время очистки 
        MOV     AX,0720H      ; Символ заполнения для текстовых режимов 
        PUSH    CX 
        REP     STOSW         ; Очистка буфера для текстовых режимов 
        POP     CX 
        CALL    NMI_ENABLE    ; Разрешить NMI 
M12:                          ; Очистка буфера регенирации 
        XOR     AX,AX         ; Заполнение для графических режимов 
        REP     STOSW         ; Очистка области регенирации 
        MOV     ACTIVE_PAGE,AL         ; Установить активную страницу 0 
; 
;------Разрешение ВИДЕО 
; 
        MOV     CURSOR_MODE,607H       ; Установить текущий режим курсора 
        MOV     CRT_MODE_SET,29H       ; Сохранить значение 
        MOV     AL, 80 
        MOV     BX,SI 
; 
;------Определить число колонок для любого видео 
;      и число, используемое для TTY интерфейса 
; 
        TEST    BL,2 
        JNE     M13 
        SAR     AX,1 
M13: 
        MOV     CRT_COLS,AX          ; Числоколонок на экране (40 или 80) 
; 
;-------Установить позицию курсора (очистить курсор для графического режима) 
; 
        AND     SI,06H        ; Смещение индекса по таблице размеров 
        MOV     CX,CS:[SI+OFFSET M9]   ; Размер для очистки 
        MOV     CRT_LEN,CX    ; Сохранить размер (не используется для ч/б) 
        MOV     CX,8          ; Очистить все позиции курсора 
        MOV     DI,OFFSET CURSOR_POSN 
        PUSH    DS            ; Установить сегмент 
        POP     ES            ; Адресация для 1К байта таблицы 
        XOR     AX,AX 
        REP     STOSW         ; Заполнить пулями 
        MOV     CURSOR_ON,AL  ; Указать, что курсор не установлен 
; 
;------Установка регистра сканирования------ 
; 
        MOV     AL,3DH        ; Значение 3DN для всех режимов, кроме 640*200 
        CMP     BL,6          ; Режим 640*200 Ч/Б 
        JNZ     M14           ; Если нет, то возврат 
        MOV     AL,3FH        ; Если да, то установить 3FH 
M14:                          ; Выдать скоректированое значение в порт 3D9 
        MOV     CRT_PALLETTE,AL ; Сохранить значение для будушего использования 
; 
;------Инициализация вектора NMI 
; 
        XOR     AX,AX 
        MOV     ES,AX 
        MOV     AX,OFFSET NMI_SERVICE 
        MOV     DI,8 
        STOSW 
        PUSH    CS 
        POP     AX 
        STOSW 
 
        POP     AX         ;востановление регистра AX 
 
; 
;------Нормальный возврат из всех ВИДЕО-возвратов 
; 
VIDEO_RETURN: 
        POP     DI 
        POP     SI 
        POP     BX 
M15:                          ; Возврат ВИДЕО 
        POP     CX 
        POP     DX 
        POP     DS 
        POP     ES            ; Восстановление регистров 
        IRET                  ; все сделано, возврат 
SET_MODE        ENDP 
 
 
;------------------------------------------------------------------------- 
; SET_CTYPE 
;       Эта программа устанавливает размер курсора 
; Вход 
;       (CX)-Содержит размер курсора CH-верхняя граница CL-нижняя граница 
;--------------------------------------------------------------------------- 
SET_CTYPE       PROC   NEAR 
 
        MOV     CURSOR_MODE,CX       ; Сохранить в области данных 
        JMP     VIDEO_RETURN 
 
SET_CTYPE       ENDP 
 
;--------------------------------------------------------------------------- 
; SET_CPOS 
;       Эта пограмма устанавливает текущую позицию курсора 
;       По заданным X-Y коофицентам 
; Вход 
;       DX-строка, колонка нового положения 
;       BH-страница экрана для курсора 
;-------------------------------------------------------------------------- 
SET_CPOS        PROC   NEAR 
 
        PUSH    AX           ; сохранить регистр AX 
 
        CMP     DH,25 
        JNB     MM171 
 
        MOV     CL,BH                ; Страница 
        XOR     CH,CH                ; Установить счетчик цикла 
        SAL     CX,1                 ; Смещение слова 
        MOV     SI,CX                ; Используем индексный регистр 
        CMP     ACTIVE_PAGE,BH       ; Активная страница 
        JNE     MM17 
                                     ; На возврат 
M17: 
        CMP     CRT_MODE,4           ; Графический режим 
        JAE     MM17                 ; Да, переход 
        MOV     AX,EXTRA_BUFFER 
        MOV     ES,AX 
        MOV     AX,DATA 
        MOV     DS,AX 
;        PUSHF                        ; Сохранить флаги 
        CLI                          ; Запретить прерывания 
        CMP     CURSOR_ON,0FFh        ; Если курсор сброшен инчего не делать 
        JNE     M125                   ; Переход, если установлен 
        CALL    M21                   ; Инвертировать курсор 
M125:   MOV     CURSOR_ON,00          ; Сбросить флаг курсора 
;        POPF                         ; Восстановить флаги 
        mov     cursor_count,2 
MM17: 
        MOV     [SI+OFFSET CURSOR_POSN],DX     ; Сохранить указатель 
        STI                                    ; Возврат 
MM171: 
        POP     AX         ;востановление регистра AX 
 
        JMP     VIDEO_RETURN 
 
SET_CPOS        ENDP 
 
; 
;-----Запретить/разрешить мерцание курсора 
; 
BLINK_DISABLE  PROC    NEAR 
        CLI 
        PUSH   AX 
        MOV    AX,DATA 
        MOV    DS,AX 
        MOV    CURSOR_ON,0Fh         ; Запретить мерцание курсора 
        POP    AX 
        RET 
BLINK_DISABLE  ENDP 
 
BLINK_ENABLE  PROC    NEAR 
        CLI 
        PUSH   AX 
        MOV    AX,DATA 
        MOV    DS,AX 
        MOV    CURSOR_ON,0           ; Разрешить мерцание курсора 
        POP     AX 
        RET 
BLINK_ENABLE  ENDP 
 
; 
;-----Получить позицию курсора, AX содержит стр/колонку 
; 
REMOVE_CURSOR  PROC    NEAR          ;AX содержат строку/колонку для курсора 
        PUSH   AX 
        MOV    AX,DATA 
        MOV    DS,AX 
;        PUSHF                        ; Сохранить флаги 
        CLI                          ; Запретить прерывания 
        CMP    CURSOR_ON,0FFh        ; Если курсор сброшен инчего не делать 
        JNE    M25                   ; Переход, если установлен 
        CALL   M21                   ; Инвертировать курсор 
M25:    MOV    CURSOR_ON,00          ; Сбросить флаг курсора 
;        POPF                         ; Восстановить флаги 
        POP    AX 
        RET 
REMOVE_CURSOR  ENDP 
 
M21:    ; Инвертировать курсор на экране 
        PUSH   SI                    ; сохранить SI 
        CALL   S26                   ; Вычислить адрес курсора 
        ADD    AX,050H               ; 
        MOV    SI,AX                 ; Заслать адрес курсора в SI 
        TEST   CRT_MODE,2            ; Режим 80x25 ? 
        JNZ    M24 
        SHL    SI,1                  ; Для 40x25, умножим адрес на 2 
        ADD    SI,050H 
        NOT    ES: BYTE PTR [SI]     ; инвертировать 4 байта курсора 
        INC    SI 
        NOT    ES: BYTE PTR [SI] 
        ADD    SI,2000H 
        NOT    ES: BYTE PTR [SI] 
        DEC    SI 
M21A:   NOT    ES: BYTE PTR [SI] 
        POP    SI                    ; Востановить SI 
        RET 
M24:    ADD    SI,0A0H 
        NOT    ES: BYTE PTR [SI]     ; Для режима 80x25, 
        AND    ES: BYTE PTR [SI],07FH  ;\ 
        ADD    SI,2000H              ; инвертируем 2 байта курсора 
        OR     ES: BYTE PTR [SI],80H  ;\ 
        JMP    M21A 
 
;------------------------------------------------------------------------- 
; READ_CURSOR 
; Прочесть текущее положение курсора 
;        та программа читает текущее значение положения курсора 
;       форматирует и возвращает вызывающей программе 
; Вход: 
;       BH-Номер страницы для курсора 
; Выход: 
;       DX-Строка/колонка текущей позиции курсора 
;       CX-Текущий режим курсора 
;-------------------------------------------------------------------------- 
READ_CURSOR     PROC   NEAR 
        MOV     BL,BH 
        XOR     BH,BH 
        SAL     BX,1                 ; Смещение слова 
        MOV     DX,[BX+OFFSET CURSOR_POSN]  ; Позиция курсора для страницы ВН 
        MOV     CX,CURSOR_MODE 
        POP     DI 
        POP     SI 
        POP     BX 
        POP     DS                   ; CX и DX не востараиливаем 
        POP     DS 
        POP     DS 
        POP     ES 
        IRET 
READ_CURSOR     ENDP 
 
;------------------------------------------------------------------------- 
; ACT_DISP_PAGE 
;       Эта программа устанавливает активную страницу ВИДЕО, 
;       используя заполнение видеобуфера для управления ВИДЕО 
; Вход 
;       AL-Hомер новой страницы 
; Выход 
;       Контроллер сбрасывается для установки новой страницы 
;-------------------------------------------------------------------------- 
ACT_DISP_PAGE   PROC   NEAR 
 
        PUSH    AX 
 
        TEST    CRT_MODE,4       ; Графика 320Х200 
        JNZ     A_D_RET 
        MOV     BP,ES            ; Сохранить величину 0B800h 
        MOV     BX,EXTRA_BUFFER 
        MOV     ES,BX 
        CALL    REMOVE_CURSOR    ; Убрать курсор с экрана 
        MOV     ACTIVE_PAGE,AL   ; Установить новую страницу 
; 
;-------Вычислить новый начальный адрес видеобуфера 
; 
        CBW                      ; Преобразовать байт в слово 
        MUL     CRT_LEN          ; Умножить на размер экрана 
        MOV     CRT_START,AX     ; Начальный адрес страницы 
; 
;-------Установить указатели 
; 
        MOV     SI,AX            ; Указатель источника (изображения) 
        XOR     DI,DI            ; Указатель приемника 
; 
;-------Визировать новую страницу 
; 
        MOV     CL,25            ; Для 25 строк 
BEG: 
        MOV     CH,BYTE PTR [CRT_COLS] ;Для 40 или 80 колонок 
        PUSH    DS               ; Сохранить сегмент данных 
COL: 
        MOV     DS,BP            ; Установить 0B800h в DS 
        LODSW                    ; Чтение символа/атрибута 
        MOV     BL,AH            ; Сконировать атрибут 
        XOR     AH,AH 
        POP     DS               ; Востановить сегмент данных 
        PUSH    DS               ; Снова сохранить DATA 
        PUSH    CX               ; Сохранить счетчик 
        PUSH    SI               ; Сохранить указатели 
        PUSH    DI 
        MOV     CX,1             ; Только для 1 символа 
        CALL    S1B              ; Нарисовать изображение 
        POP     DI 
        INC     DI 
        POP     SI               ; Востановить указатели 
        POP     CX               ; Востановить счетчик 
        DEC     CH               ; следующая колонка 
        JNZ     COL 
        ADD     DI,120           ; Установить указатель на следующую строку 
        POP     DS               ; Востановить сегмент данных 
        TEST    CRT_MODE,2       ; 40X25 ? 
        JZ      A_D_NEXT         ; Да, 
        ADD     DI,120           ; Прибавить 
A_D_NEXT: 
        LOOP    BEG              ; На следующую строку 
A_D_RET: 
 
        POP     AX 
 
        JMP     VIDEO_RETURN 
ACT_DISP_PAGE   ENDP 
;------------------------------------------------------------------------- 
;SET COLOR 
;       Эта программа устанавливает цветную политру для режимов 
;       среднего разрешения 
;Вход 
;       (BH) HAS COLOR ID 
;                  BH=0-Цвет фона устанавливается 
;                       Для цвета 0 по мл. 5 битам BL (0-31), 
;                  BH=1-Выбор политры на основе 
;                       мл. бита BL: 
;                             0=Зеленый, красный, желтый для цветов 1,2,3 
;                             1=Голубой, циан, фиолетовый для цветов 1,2,3 
;       (BL) HAS THE COLOR VALUE TO BE USED 
; Выход 
;       Установка цветовой палитры 
;--------------------------------------------------------------------------- 
SET_COLOR       PROC   NEAR 
 
        PUSH    AX 
 
        MOV     AH,CRT_PALLETTE      ; Значение текущей политры 
        IN      AL,SCR_MODE          ; Режим экрана 
        OR      BH,BH                ; Цвет 0 (ВН=0) 
        JNZ     M20                  ; Переход на цвет 1 (ВН=1) 
; 
;------Обработка цвета 0-установка цвета фона 
; 
        MOV     BH,BL 
        AND     AX,0E0C8H            ; Получить текущие мл. 5 битов 
        AND     BX,01F37H            ; Старшие 3 бита входного знчения 
        OR      AX,BX                ; Получить значение в режиме 
M19:                                 ; Вывод политры 
        MOV     CRT_PALLETTE,AH      ; Сохранить значение цвета 
        OUT     SCR_MODE,AL 
 
        POP     AX 
 
        JMP     VIDEO_RETURN 
; 
;------Обработка цвета 1-установка требуемой политры 
; 
M20: 
        AND     AX,0EFEFH            ; Сбросить бит выбора политры 
        SHR     BL,1                 ; Проверить младший бит BL 
        JNC     M19                  ; Уже сделано 
        OR      AX,1010H             ; Установить бит выбора палитры 
        JMP     M19 
SET_COLOR       ENDP 
 
;-------------------------------------------------------------------------- 
;VIDEO STATE 
; Программа возвращает текущее состаяние ВИДЕО в AX 
; AH = Количество колонок 
; AL = Текущий режим ВИДЕО 
; BH = Номер текущей активной страницы 
;---------------------------------------------------------------------------- 
VIDEO_STATE     PROC   NEAR 
        MOV     AH,BYTE PTR CRT_COLS ; Получить число колонок 
        MOV     AL,CRT_MODE          ; Текущий режим 
        MOV     BH,ACTIVE_PAGE       ; Получить текущую активную странцу 
        POP     DI                   ; Востановить режим 
        POP     SI 
        POP     CX 
        JMP     M15                  ; Возврат к вызывающей программе 
VIDEO_STATE     ENDP 
 
;---------------------------------------------------------------------------- 
; POSITION 
;       Эта программа вычисляет адрес буфера 
;       регенирации символов в текстовом режиме 
;Вход 
;       AX = Строка, колонка позиции 
;Выход 
;       AX = Смещение позиции символа в буфере регенерации 
;---------------------------------------------------------------------------- 
POSITION        PROC   NEAR 
        PUSH    BX                   ; Сохранить регистр 
        MOV     BX,AX 
        MOV     AL,AH                ; строку в AL 
        MUL     BYTE PTR CRT_COLS    ; Определить число байт для строки 
        XOR     BH,BH 
        ADD     AX,BX                ; Добавить значение колонки 
        SAL     AX,1                 ;* 2 для байтов атрибутов 
        POP     BX 
        RET 
POSITION        ENDP 
 
NMI_DISABLE PROC NEAR 
        PUSH    AX 
        IN      AL,SCR_MODE 
        OR      AL,8                 ; установить бит разрешения NMI 
        OUT     SCR_MODE,AL 
        POP     AX 
        RET 
NMI_DISABLE ENDP 
 
NMI_ENABLE PROC NEAR 
        PUSH    AX 
        IN      AL,SCR_MODE 
        AND     AL,0F7H              ; Сбросить бит разрешения NMI 
        OUT     SCR_MODE,AL 
        POP     AX 
        RET 
NMI_ENABLE ENDP 
 
;------------------------------------------------------------------------------ 
;SCROLL UP 
;       Эта программа перемещает блок символов 
;       вверх по экрану (прокрутка) 
;Вход 
;       (AH)= Текуший режим 
;       (AL)= Количество сдвигаеьых строк 
;       (CX)= Строка/колонка-кординаты левого угла окна 
;       (DX)= Строка/колонка-кординаты нижнего правого угла окна 
;       (BH)= Атрибуты символа пробела (для освобождаемых строк) 
;       (DS)= Сегмент данных 
;       (ES)= Сегмент буфера регенирации 
;Выход 
;       NONE-Модифицырованый буфер регенирации 
;------------------------------------------------------------------------------ 
        ASSUME  CS:CODE,DS:DATA,ES:DATA 
SCROLL_UP       PROC   NEAR 
        MOV     BL,AL                ; Сохранить счетчик строк 
        CMP     AH,4                 ; Проверка на графический режим 
        JC      N1                   ; Обрабатывается отдельно 
        JMP     GRAPHICS_UP          ; На графические режимы 
N1:                                  ; Продолжить текст 
        PUSH    AX 
        PUSH    BX 
        PUSH    CX 
        PUSH    DX 
        PUSH    DS 
        CALL    NMI_DISABLE          ; Разрешить NMI 
        PUSH    BX                   ; Сохранить атребут заполнения 
        MOV     AX,CX                ; Верхний левый угол окна 
        CALL    SCROLL_POSITION      ; Установить для прокрутки 
        JZ      N7                   ; Поле пробела (заполнения) 
        ADD     SI,AX                ; С адреса (начало) 
        MOV     AH,DH                ; Число строк в окне 
        SUB     AH,BL                ; Число передвигаемых строк (блок) 
N2:                                  ; Цикл по строкам 
        CALL    N10                  ; Сдвинуть одну строку 
        ADD     SI,BP 
        ADD     DI,BP                ; Указатель на следующую строку в блоке 
        DEC     AH                   ; Счетчик строк сдвига 
        JNZ     N2                   ; Цикл по строкам 
N3:                                  ; Вход очистки 
        POP     AX                   ; Востановление атрибута в AH 
        MOV     AL,' '               ; Заполнение пробелами 
N4:                                  ; Цикл очистки 
        CALL    N11 
        ADD     DI,BP                ; Указатель на следующую строку 
        DEC     BL                   ; Счетчик строк прокрутки 
        JNZ     N4                   ; Цикл очистки 
N5:                                  ; Конец прокрутки 
        POP     DS 
N6:                                  ; Возврат из ВИДЕО 
        CALL    NMI_ENABLE           ; Возвращение NMI 
        POP     DX 
        POP     CX 
        POP     BX 
        MOV     AX,EXTRA_BUFFER 
        MOV     ES,AX 
        POP     AX 
        MOV     BH,0                 ; Поле заполнения 
 
        PUSH    AX 
 
        CALL    REMOVE_CURSOR        ; Переместить курсор 
        CALL    BLINK_DISABLE        ; Запретить мерцание 
        CALL    UP_GRAPHICS 
SCROLL_RET: 
        CALL    BLINK_ENABLE         ; Разрешить мерцание 
 
        POP     AX 
 
        JMP     VIDEO_RETURN         ; Возврат из ВИДЕО 
N7:                                  ; Поле заполнения 
        MOV     BL,DH                ; Получить счетчик строк 
        JMP     N3                   ; На очистку этой области 
SCROLL_UP       ENDP 
 
;------Общая часть обработки заданной прокрутки 
 
SCROLL_POSITION PROC NEAR 
N9:     CALL    POSITION             ; Преобразовать указатель области регенирации 
        ADD     AX,CRT_START         ; Смещение активной страницы 
        MOV     DI,AX                ; Прокрутка до адреса (конец) 
        MOV     SI,AX                ; Прокрутка с адреса (начало) 
        SUB     DX,CX                ; DX=строка/колонка в блоке 
        INC     DH 
        INC     DL                   ; Инкремент до 0 
        XOR     CH,CH                ; Очистить старший байт счетчика 
        MOV     BP,CRT_COLS          ; Получить число колонок экрана 
        ADD     BP,BP                ; Удвоить для байта атрибута 
        MOV     AL,BL                ; Получить счетчик строк 
        MUL     BYTE PTR CRT_COLS    ; определить смещение начального адреса 
        ADD     AX,AX                ; Удвоить для байта атрибута 
        PUSH    ES                   ; Установить адресацию буфера регенирации 
        POP     DS                   ; Для обоих указателей 
        CMP     BL,0                 ; 0-Конец прокрутки области заполнения 
        RET                          ; Возврат с установленными флагами 
SCROLL_POSITION ENDP 
 
;-----Сдвинуть строку (прокрутка) 
N10     PROC    NEAR 
        MOV     CL,DL                ; Получить число колонок для сдвига 
        PUSH    SI 
        PUSH    DI                   ; Сохранить начальные адреса 
        REP     MOVSW                ; Сдвинуть строку на экране 
 
        POP     DI 
        POP     SI                   ; Востановить адреса 
        RET 
N10     ENDP 
 
;-----Очистить строку (прокрутка) 
N11     PROC    NEAR 
        MOV     CL,DL                ; Получить число колонок для прокрутки 
        PUSH    DI 
        REP     STOSW                ; Засылка символа заполнения 
 
        POP     DI 
        RET 
N11     ENDP 
;------------------------------------------------------------------------ 
;SCROLL_DOWN 
;       Эта программа перемещает символ с указаного блока 
;       вниз по экрану (прокрутка) заполняя верхние (освободившиеся) 
;       строки заданным символом 
;Вход 
;       (AH) = Текущий режим 
;       (AL) = Количество строк прокрутки 
;       (CX) = Верхний левый угол окна 
;       (DX) = Нижний правый угол окна 
;       (BH) = Символ заполнения 
;       (DS) = Сегмент данных 
;       (ES) = Сегмент буфера регенирации 
;Выход 
;       Модифицированное содержимое экрана 
;--------------------------------------------------------------------------- 
 
SCROLL_DOWN     PROC   NEAR 
        STD                          ; Направление для прокрутки вниз 
        MOV     BL,AL                ; Счетчик строк в BL 
        CMP     AH,4                 ; Проверка на графику 
        JC      N12 
        JMP     GRAPHICS_DOWN        ; На графические режимы 
N12:                                 ; Продолжить (текст) 
        PUSH    AX 
        PUSH    BX 
        PUSH    CX 
        PUSH    DX 
        PUSH    DS 
        CALL    NMI_DISABLE          ; Запретить NMI 
        PUSH    BX                   ; Сохранить атрибут в BH 
        MOV     AX,DX                ; Нижний правый угол окна 
        CALL    SCROLL_POSITION      ; Получить область регенерации (параметры прокрутки
        JZ      N16 
        SUB     SI,AX                ; Адрес начала 
        MOV     AH,DH                ; Получить общее число строк 
        SUB     AH,BL                ; Счетчик сдвигов прокрутки 
N13: 
        CALL    N10                  ; Сдвинуть одну строку (прокрутка) 
        SUB     SI,BP 
        SUB     DI,BP 
        DEC     AH 
        JNZ     N13 
N14: 
        POP     AX                   ; Восстановить атрибут  в АН 
        MOV     AL,' ' 
N15: 
        CALL    N11                  ; Очистить одну строку (прокрутка) 
        SUB     DI,BP                ; На следующую строку 
        DEC     BL 
        JNZ     N15 
                                     ; Возврат из ВИДЕО 
        POP     DS 
        CALL    NMI_ENABLE           ; Разрешить NMI 
        POP     DX 
        POP     CX 
        POP     BX 
        MOV     AX,EXTRA_BUFFER      ; Адрес буфера регенерации 
        MOV     ES,AX 
        POP     AX 
        MOV     BH,0 
 
        PUSH    AX 
 
        CALL    REMOVE_CURSOR 
        CALL    BLINK_DISABLE 
        CALL    DOWN_GRAPHICS 
        JMP     SCROLL_RET 
N16: 
        MOV     BL,DH 
        JMP     N14 
SCROLL_DOWN     ENDP 
 
;--------------------------------------------------------------------------- 
;READ_AC_CURRENT 
;       Эта программа считывает символ и атрибут в текущей позиции курсора 
;Вход 
;       (AH) = Текущий режим 
;       (BH) = Номер страницы (только для текстовых режимов) 
;       (DS) = Сегмент данных 
;       (ES) = Сегмент буфера регенирации 
;Выход 
;       (AL) = Прочитанный символ 
;       (AH) = Прочитанный атрибут 
;---------------------------------------------------------------------------- 
        ASSUME  CS:CODE,DS:DATA,ES:DATA 
READ_AC_CURRENT PROC    NEAR 
        CMP     AH,4                 ; Это графика ? 
        JC      P1 
        JMP     GRAPHICS_READ        ; На чтение в графических режимах 
P1:                                  ; Продолжить (текст) 
        CALL    FIND_POSITION        ; Определить позицию курсора для страницы 
        MOV     SI,BX                ; Установить адресацию в SI 
        PUSH    ES                   ; Установить: cегмент данных = экстра-сегмент 
        POP     DS                   ; Получить символ/атрибут 
        LODSW                        ; Возврат 
        JMP     VIDEO_RETURN 
READ_AC_CURRENT ENDP 
 
FIND_POSITION   PROC   NEAR 
        MOV     CL,BH                ; Определение позиции курсора для страницы 
        XOR     CH,CH                ; Номер текущей страницы в cх 
        MOV     SI,CX                ; Передать в SI как индекс, умноженный 
        SAL     SI,1                 ; на 2 (слово смещения) 
        MOV     AX,[SI+ OFFSET CURSOR_POSN]    ; Получить строку/колонку для этой страни
        XOR     BX,BX                ; Начальный адрес = 0 
        JCXZ    P5                   ; Страница найдена 
P4:                                  ; Цикл по страницам 
        ADD     BX,CRT_LEN           ; Длина буфера 
        LOOP    P4 
P5:                                  ; Страница найдена 
        CALL    POSITION             ; Определить ячейку в области регенерации 
        ADD     BX,AX                ; Прибавить к началу области 
        RET 
FIND_POSITION   ENDP 
 
;--------------------------------------------------------------------------- 
;WRITE_AC_CURRENT 
;       Эта программа записывает символ и атрибут в текущую позицию курсора 
;Вход: 
;       (AH) = Текущий режим 
;       (BH) = Номер страницы 
;       (CX) = Счетчик (количество повторений символа) 
;       (AL) = Символ для записи 
;       (BL) = Aтрибут символа для записи (или цвет для графики) 
;       (DS) = Сегмент данных 
;       (ES) = Сегмент области (буфера) регенерации 
;--------------------------------------------------------------------------- 
 
WRITE_AC_CURRENT        PROC  NEAR 
        CMP     AH,4                 ; Графика ? 
        JC      P6 
        JMP     GRAPHICS_WRITE       ; На графические режимы 
P6:                                  ; продолжение (текст) 
        PUSH    AX 
        PUSH    BX 
        PUSH    CX 
        PUSH    DS 
        CALL    NMI_DISABLE          ; Запретить NMI 
        MOV     AH,BL                ; Получить атрибут в AH 
        PUSH    AX                   ; Сохранить атрибут/символ 
        PUSH    CX                   ; Счетчик записи 
        CALL    FIND_POSITION        ; Определить позицию курсора для страницы 
        MOV     DI,BX                ; Адрес в DI 
        POP     CX                   ; Восстановить счетчик 
        POP     AX                   ; Символ/атрибут 
        REP     STOSW                ; Записать символ/атрибут столько раз, 
                                     ; сколько требуется (сх) 
        CALL    NMI_ENABLE           ; Разрешить NMI 
        POP     DS 
        POP     CX 
        POP     BX 
        MOV     AX,EXTRA_BUFFER      ; Пересылка в буфер регенерации заданной страницы 
        MOV     ES,AX 
        POP     AX 
        CMP     ACTIVE_PAGE,BH 
        JE      P7A 
        JMP     VIDEO_RETURN 
P7A: 
 
        PUSH    AX 
 
        CALL    REMOVE_CURSOR 
        CALL    WRITE_GRAPHICS 
        JMP     SCROLL_RET 
 
WRITE_AC_CURRENT        ENDP 
 
;---------------------------------------------------------------------------- 
;WRITE_C_CURRENT 
;       Эта программа записывает символ в текущую позицию курсора, 
;       атрибут не изменяется. В графике BL содержит атрибут цвета. 
;Вход: 
;       (AH) = Текущий режим 
;       (BH) = Номер страницы 
;       (CX) = Счетчик (количество повторений символа) 
;       (AL) = Символ для записи 
;       (DS) = Сегмент данных 
;       (ES) = Сегмент области (буфера) регенерации 
;OUTPUT 
;       NONE 
;----------------------------------------------------------------------------- 
WRITE_C_CURRENT PROC    NEAR 
        CMP     AH,4                 ; Графика ? 
        JC      P10 
        JMP     GRAPHICS_WRITE       ; На графические режимы 
P10: 
 
        PUSH    AX 
 
        MOV     AH,BH                ; Сохранить номер страницы 
        CALL    NMI_DISABLE          ; Запретить NMI 
        PUSH    AX                   ; Сохранить в стеке 
        PUSH    CX                   ; счетчик записи 
        CALL    FIND_POSITION        ; Определить позицию курсора для страницы 
        MOV     DI,BX                ; Адрес в DI 
        POP     CX                   ; Cчетчик записи 
        POP     AX                   ; BL = символ для записи 
P11:                                 ; цикл записи 
        STOSB                        ; Записать символ 
        CMP     ACTIVE_PAGE,AH 
        JNE     PP11 
        MOV     BL,ES:[DI] 
        PUSH    ES 
        PUSH    DS 
        PUSH    CX 
        PUSH    DI 
        PUSH    AX 
        MOV     DX,EXTRA_BUFFER 
        MOV     ES,DX 
        MOV     CX,1 
        CALL    REMOVE_CURSOR 
        CALL    WRITE_GRAPHICS 
        POP     AX 
        POP     DI 
        POP     CX 
        POP     DS 
        POP     ES 
pp11: 
        INC     DI                   ; Пропустить атрибут 
        LOOP    P11                  ; Цикл записи символа по счетчику 
        CALL    NMI_ENABLE 
 
        POP     AX 
 
        JMP     VIDEO_RETURN 
WRITE_C_CURRENT ENDP 
 
 
