
     /* ibmpc.c */
     /*  Функции  нижнего уровня,   обращающиеся к  BIOS и  аппаратным
     средствам  РС  */
     #pragma  inline 
     #include <dos.h> 
     static union REGS rg;

     /* позиция курсора */
     void cursor(int x,int y) {
        rg.x.ax = 0x0200;
        rg.x.bx = 0;
        rg.x.dx = ((y << 8) & 0xff00) + x;
        int86( 16, &rg, &rg);
     }

     /* возвратить позицию курсора */
     void curr_cursor( int *x, int *y )
     {
        rg.x.ax = 0x0300;
        rg.x.bx = 0;
        int86( 16, &rg, &rg );
        *x = rg.h.dl;
        *y = rg.h.dh;
     }

     /* установить тип курсора */
     void set_cursor_type( int t )
     {
        rg.x.ax = 0x0100;
        rg.x.bx = 0;
        rg.x.cx = t;
        int86( 16, &rg, &rg );
     }
     char attrib = 7;

     /* очистить экран */
     void clear_screen()
     {
        cursor(0, 0);
        rg.h.al = ' ';
        rg.h.ah = 9;
        rg.x.bx = attrib;
        rg.x.cx = 2000;
        int86( 16, &rg, &rg );
     }

     /* возвратить режим работы видеоконтроллера*/
     int vmode()
     {
        rg.h.ah = 15;
        int86( 16, &rg, &rg);
        return rg.h.al;
     }




     /* проверить клавишу Scroll Lock */
     int scroll_lock()
     {
        rg.x.ax = 0x0200;
        int86( 0x16, &rg, &rg);
        return rg.h.al & 0x10;
     }
     void (* helpfunc)();
     int helpkey = 0;
     int helping = 0;

     /* принять символ от клавиатуры */
     int get_char()
     {
        int c;
        while (1)   {
            rg.h.ah = 1;
            int86(0x16, &rg, &rg);
            if (rg.x.flags & 0x40)  {
        int86(0x28, &rg, &rg);
        continue;
            }
            rg.h.ah = 0;
            int86(0x16, &rg, &rg);
            if (rg.h.al == 0)
        c = rg.h.ah | 128;
            else
        c = rg.h.al;
            if (c == helpkey && helpfunc)   {
        if (!helping)   {
            helping = 1;
            (*helpfunc)();
            helping = 0;
            continue;
        }
            }
            break;
        }
         return c;
     }

     /* занести код символа и его атрибуты в видеопамять */
     void vpoke(unsigned vseg, unsigned adr, unsigned chr)
     {
         if (vseg == 45056)     /* монохромный режим */
     poke(vseg, adr, chr);
         else    {
     _DI = adr; /* смещение до адреса символа в видеопамяти */
     _ES = vseg; /* адрес сегмента видеопамяти */
     asm cld;
     _BX = chr; /* атрибуты и код символа */
     _DX = 986; /* состояние видеопорта */

     /* ждать начала обратного хода луча*/
     do
         asm in al,dx;
     while (_AL & 1);








     /* ждать завершения обратного хода луча */
     do
         asm in al,dx;
     while (!(_AL & 1));
     _AL = _BL;
     asm stosb;    /* запомнить символ */

     /* ждать начала обратного хода луча */
     do
         asm in al,dx;
     while (_AL & 1);

     /* ждать завершения обратнога хода луча */
     do
         asm in al,dx;
     while (!(_AL & 1));
     _AL = _BL;
     asm stosb;     /* запомнить атрибуты */
          }
     }

     /* считать код символа и его атрибуты из видеопамяти */
     int vpeek(unsigned vseg, unsigned adr)
     {
         int ch, at;
         if (vseg == 45056)   /* монохромный режим */
     return peek(vseg, adr);
         asm push ds;
         _DX = 986;    /* состояние видеопорта */
         _DS = vseg;   /* адрес сегмента видеопамяти */
         _SI = adr;/* смещение до адреса символа в видеопамяти */
         asm cld;

         /* ждать начала обратного хода луча */
         do
     asm in al,dx;
         while (_AL & 1);

         /* ждать завершения обратного хода луча */
         do
            asm in al,dx;
         while (!(_AL & 1));
         asm lodsb;     /* считать символ */
         _BL = _AL;

         /* ждать начала обратного хода луча */
         do
     asm in al,dx;
         while (_AL & 1);

         /* ждать завершения обратного хода луча */
         do
     asm in al,dx;
         while (!(_AL & 1));
         asm lodsb;     /* считать атрибут */
         _BH = _AL;
         _AX = _BX;
         asm pop ds;
         return _AX;
     }
