

// пример разделения экрана дисплея на две части при помоши
// регистра сравнения линий контроллера ЭЛТ

#include <dos.h>
#include <stdio.h>

void Split(unsigned);


main(void) {

     int   i;

     for(i = 0; i < 25; i++)
			 printf("Строка номер %d.\n",i);

     getch();

// разделяем экран по линии 200

	  Split(200);

     getch();

// после завершения программы значения регистров не восстанавливеются!
}


/**
*.Name    Split
*
*.Title   Разделение экрана.
*
*.Descr   Функция разделяет экран на две части. Функция работает
*         только на EGA и VGA.
*
*.Proto   void Split(unsigned split_line)
*
*.Params  split_line - линия горизонтальной развертки, в которой
*                      происходит разделение экрана дисплея.
*
*.Return  Не используется.
*
*.Sample  split.c
**/
void Split(unsigned split_line) {

     _asm {

; устанавливаем регистр es на начало оперативной памяти

          xor   ax,ax
          mov   es,ax

; получаем адрес порта индексного регистра контроллера ЭЛТ
; (3B4h/3D4h),
; в монохромных режимах для адресации к индексному регистру
; используется порт с адресом 3B4h, а в цветных - порт 3D4h

          mov   dx,es:[463h]

; вычисляем адрес порта регистра состояния 1,
; в монохромных режимах для адресации к регистру состояния 1
; используется порт с адресом 3BAh, а в цветных - порт 3DAh

          add   dx,6


; ожидаем начало обратного вертикального хода луча

          in    al,dx
          nop

; если бит D3 равен единице, то происходит обратный
; вертикальный ход луча

          test  al,8
          jz    wait_on

     wait_off:

          in    al,dx

          ; задержка

          nop
          test  al,8
          jnz    wait_off

     wait_on:

          in    al,dx
          nop
          test  al,8
          jz    wait_on


; вычисляем адрес порта индексного регистра контроллера ЭЛТ

; (3B4h/3D4h)

          sub   dx,6

; выбираем для обмена регистр сравнения линий

          mov   al,18h
          out   dx,al

; вычисляем адрес порта регистра данных контроллера ЭЛТ,
; в монохромных режимах для адресации к регистру данных
; используется порт с адресом 3B5h, а в цветных - порт 3D5h

          inc   dx


; определяем линию горизонтальной развертки, в которой происходит
; разделение экрана дисплея

          mov   ax,split_line

; у видеоадаптера EGA регистр сравнения линий состоит из 9 бит,
; доступ к девятому биту происходит через дополнительный регистр
; контроллера ЭЛТ;
; видеоадаптер VGA имеет еще и десятый бит, расположенный в регистре
; высоты символов текста

; записываем младшие 8 битов в регистр сравнения линий

          out   dx,al

; вычисляем адрес порта индексного регистра контроллера ЭЛТ

          dec   dx

; вызываем функцию чтения конфигурации видеосистемы

          mov   ax,1A00h
          int   10h

; если после вызова функции регистр al не равен 1Ah, то используемый
; видеодаптер не VGA

          cmp   al,1Ah
          je    vga
          jmp   ega

     vga:

; считываем в al состояние дополнительнго регистра

          mov   al,7
          out   dx,al
          inc   dx
          in    al,dx

; модифицируем бит D4 дополнительного ргистра

          mov   bx,split_line
          mov   cl,4
          shl   bh,cl
          and   bh,00010000b

          and   al,11101111b
          or    al,bh
          out   dx,al

; сбрасываем бит D6 регистра высоты символов текста

          dec   dx
          mov   al,9
          out   dx,al
          inc   dx
          in    al,dx
          and   al,10111111b
          out   dx,al
          jmp   quit_split

     ega:

          mov   bx,split_line
          mov   cl,4
          shl   bh,cl
          and   bh,00010000b

          cmp   dx,3B4h       ; монохромный режим?
          je    default_1Fh

; определяем наличие улучшенного цветного дисплея по положению
; переключателей на плате EGA

          mov   al,es:[488h]
          and   al,0Fh

; положение переключателей "off off on on" ?

          cmp   al,3
          je    default_1Fh

; положение переключателей "off on on off" ?

          cmp   al,9
          je    default_1Fh

; для видиосистем с монохромным или цветным дисплеями, дополнительный
; регистр по умолчанию содержит 11h

          or    bh,1
          jmp   set_overflow

; для видиосистем с улучненным цветным дисплеем или в монохромных
; текстовых режимах дополнительный регистр по умолчанию содержит 1Fh

     default_1Fh:

          or    bh,0Fh

; устанавливаем дополнительный регистр

     set_overflow:

          mov   al,07h
          out   dx,al
          inc   dx
			 mov   al,bh
          out   dx,al

     quit_split:

     }
}
