#define VGA ((unsigned char __far*)0xA0000000L)

/*void outofmemory(void);

unsigned char __far *dbuff;

void init_dbuff(void)
{
  if(!(dbuff = _fmalloc(64000)))
    outofmemory();
}

void put_pixel(unsigned x, unsigned y, unsigned char color)
{
  dbuff[(y<<6)+(y<<8)+x] = color;
}

void fill_screen(unsigned char color)
{
  _fmemset(dbuff, color, 64000);
}

void draw_rectangle(signed x, signed y, unsigned w, unsigned h,
                    unsigned char color)
{
  unsigned n;

  while(h--)
    for(n=0;n<w;n++)
      put_pixel(x+n, y+h, color);
}
*/

void outword(unsigned word, unsigned port);
#pragma aux outword = \
  "out dx, ax" \
  parm [ax] [dx] modify exact [];

void outbyte(unsigned char byte, unsigned port);
#pragma aux outbyte = \
  "out dx, al" \
  parm [al] [dx] modify exact [];

unsigned char inbyte(unsigned port);
#pragma aux inbyte = \
  "in al, dx" \
  parm [dx] value [al] modify exact [ax];

void update_screen(void)
{
  unsigned char plane;
  unsigned char *ptr = dbuff;

  while ((inbyte(0x3DA) & 0x08));
  outbyte(0x02, 0x3c4);
  while (!(inbyte(0x3DA) & 0x08));

  for(plane=0x08;plane;plane>>=1)
  {
    outbyte(plane, 0x3c5);
    _fmemcpy(VGA, ptr, 8000);
    ptr += 8000;
  }
}

void update_screenr(unsigned x, unsigned y, unsigned width, unsigned height, unsigned char wait)
{
  unsigned char plane;
  unsigned char *ptr = dbuff;
  unsigned char *trg;
  unsigned char *src;
  unsigned copy_count = (width>>3)+1;
  unsigned offset = dbuff_offset_nomask(x, y);
  unsigned char r;

  if(wait)
  {
    while ((inbyte(0x3DA) & 0x08));
    outbyte(0x02, 0x3c4);
    while (!(inbyte(0x3DA) & 0x08));
  }

  for(plane=0x08;plane;plane>>=1)
  {
    outbyte(plane, 0x3c5);
    src = ptr+offset;
    trg = VGA+offset;
    for(r=height;r--;)
    {
      memcpy(trg, src, copy_count);
      trg += 40;
      src += 40;
    }
    ptr += 8000;
  }
}

void restore_display_mode(void)
{
  __asm
  {
    mov ax, 0x0003
    int 0x10
  }
}

#define KEY_ENTER 0x0D
#define KEY_ESC 27
#define KEY_UP (72 | 0x80)
#define KEY_DOWN (80 | 0x80)
#define KEY_LEFT (75 | 0x80)
#define KEY_RIGHT (77 | 0x80)
#define KEY_F5 (63 | 0x80)
#define KEY_F7 (65 | 0x80)
#define KEY_F8 (66 | 0x80)
#define KEY_F9 (67 | 0x80)
#define KEY_F11 (133 | 0x80)
#define KEY_F12 (134 | 0x80)
#define SCANCODE_UNKNOWN 0

int poll_keycode(void)
{
  int c = getch();
    if(!c)
      return getch() | 0x80;
  return c;
}

//#define poll_keypress() poll_keycode()

int poll_keypress(void)
{
  if(!kbhit())
    return SCANCODE_UNKNOWN;
  return poll_keycode();
}

volatile unsigned char key_pressed;
void __far *old_kbdhdl;

void __interrupt kbdhdl(void)
{
  key_pressed = 1;
  _chain_intr(old_kbdhdl);
}

void set_keypress_handler(void)
{
  key_pressed = 0;

  old_kbdhdl = _dos_getvect(0x09);
  _dos_setvect(0x09, kbdhdl);
}

void unset_keypress_handler(void)
{
  _dos_setvect(0x09, old_kbdhdl);
}
