/*
        This file is part of the cFos project,
        Copyright (c) 1993 by Martin Winkler, Christoph Lders

        This file contains direct screen I/O routines for the IBM/PC.


        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program in the file COPYING; if not, write to the
        Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/


#include <string.h>
#include <stdarg.h>

#include "vars.h"



static short scrlen;
static byte disp_rows, disp_cols;
static byte now_atb, _FAR *scrbuff, _FAR *scrptr;
static byte now_row, now_col, now_page;




/*
   attribute tables:
   0    normal text
   1    invers
   2    underline
   3    highlighted
   4    input field
   5
   6
   7
   8
   9
  10
  11
  12
  13    window text (background)
  14    window border (foreground)
  15    window border (background)
*/

static unsigned char *disp_atb_tab;
unsigned char disp_atb_mono[DISP_MAX_ATB] =
                        {0x07, 0x70, 0x01, 0x0e, 0x07, 0x07, 0x07, 0x07,
                         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x70, 0x07};

unsigned char disp_atb_color[DISP_MAX_ATB] =
                        {0x07, 0x70, 0x01, 0x0e, 0x07, 0x07, 0x07, 0x07,
                         0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x70, 0x07};



void disp_init (void)
{
   union REGS r;

   now_page = 0;

   r.h.ah = 0x0f;
   myint86 (0x10, &r, &r);
   disp_cols = r.h.ah;

   if (r.h.al == 7) {
       disp_rows = 25;
       scrbuff = (unsigned char _FAR *) 0xb0000000L;
       disp_atb_tab = disp_atb_mono;
   } else {
       scrbuff = (unsigned char _FAR *) 0xb8000000L;
       disp_atb_tab = disp_atb_color;
       if ((disp_rows = *((unsigned char _FAR *) 0x00400084L) + (byte) 1) == 1)
          disp_rows = 25;
   }

   if (r.h.bh != 0) {                /* screen page */
      r.h.ah = 5;
      r.h.al = 0;
      myint86 (0x10, &r, &r);          /* set page 0 */
   }

   r.h.ah = 3;
   r.h.bh = now_page;
   myint86 (0x10, &r, &r);             /* get cursor pos */
   now_col = r.h.dl;
   now_row = r.h.dh;

   now_atb = *disp_atb_tab;
   scrptr = scrbuff + now_row*disp_cols*2 + now_col*2;
   scrlen = disp_rows * disp_cols * 2;
}



void _disp_char (char c)
{
   unsigned char _FAR *cp;
   short i/* , cur_upd=0*/;

   switch (c) {
      case 12:
         for (cp=scrbuff,i=0; i<scrlen; i++) {
            *cp++ = ' ';
            *cp++ = now_atb;
         }
         now_row = 0;
         now_col = 0;
         /* cur_upd = 1; */
         scrptr = scrbuff;
         break;

      case '\t':
         i = ((now_col/8)+1)*8;
         for (; i!=(int) now_col;)
            _disp_char (' ');
         scrptr += (i-now_col)*2;
         break;

      case '\n':
         scrptr += disp_cols*2;
         now_row++;

      case '\r':
         scrptr -= now_col*2;
         now_col = 0;
         /* cur_upd = 1; */
         break;

      case '\b':
         if (now_col > 0) {
            scrptr -= 2;
            now_col--;
            /* cur_upd = 1;*/
         }
         break;

      default:
         *scrptr++ = c;
         *scrptr++ = now_atb;
         now_col++;
         break;
   }
   if (now_col >= disp_cols) {
      now_col -= disp_cols;
      now_row++;
   }
#if 0
   if (now_row >= disp_rows) {         /* gotta scroll */
      memcpy3 (scrbuff, scrbuff+disp_cols*2, scrlen-disp_cols*2);
/*      for (i=0; i<scrlen-disp_cols*2; i++)
         scrbuff[i] = scrbuff[i+disp_cols*2];*/
      scrptr -= disp_cols*2;
      now_row--;
      for (cp=scrbuff+scrlen-disp_cols*2,i=disp_cols; i>0; i--) {
         *cp++ = ' ';
         *cp++ = now_atb;
      }
   }

   if (cur_upd)
      mygotoxy (now_row, now_col);
#endif
}



#if 0
void disp (char *text)
{
   while (*text)
      _disp_char (*text++);
}
#endif



void mygotoxy (short x, short y)
{
/*   union REGS r; */

   if (x != -1)
      now_row = (byte) x;
   now_col = (byte) y;

   scrptr = scrbuff + (now_row*disp_cols + now_col)*2;

#if 0
   r.h.ah = 2;
   r.h.bh = now_page;
   r.h.dh = now_row;
   r.h.dl = now_col;
   myint86 (0x10, &r, &r);          /* set cursor */
#endif
}



void set_atb (short atb)
{
   now_atb = disp_atb_tab[atb%DISP_MAX_ATB];
}



#if 0
int myprintf (const char *format, ...)
{
   int len;

   va_list argptr;
   va_start (argptr, format);
   len = _output ((int (*)(int, int)) _disp_char, 0, NULL, format, argptr);
   va_end (argptr);

   return len;
}
#endif



/* --- eof disp.c */
