#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include "vidlib.h"

char *CRTCdregnames[] = { "Horizontal total", "Horizontal display enable end",
     "Start horizontal blanking", "End horizontal blanking",
     "Start horizontal retrace", "End horizontal retrace", "Vertical total",
     "Overflow", "Preset row scan", "Maximum scan line address",
     "Cursor start", "Cursor end", "Start address high", "Start address low",
     "Cursor location high", "Cursor location low", "Vertical retrace start",
     "Vertical retrace end", "Vertical display enable end",
     "Offset (logical line width)", "Underline location",
     "Start vertical blanking", "End vertical blanking", "Mode Control",
     "Line compare"
};

char *Sequencernames[] = { "Reset", "Clocking mode", "Map mask",
     "Character map select", "Memory mode"
};

char *GCdregnames[] = { "Set/reset", "Enable set/reset",
     "Color compare", "Data rotate/function select",
     "Read map select", "Graphics mode", "Miscellaneous",
     "Color don't care", "Bit mask"
};

char *ACdregnames[] = { "Attribute mode control", "Border color",
     "Color plane enable", "Horizontal pixel panning", "Color select"
};

/* ---------------------------- m a i n ----------------------------------- */
void main(void)
{
   int i, temp1, temp2, temp3, vrs, svb;
   unsigned char v, overflow, ehr, msl, shb, shr;
   union REGS r;

   r.h.ah=0x0f;
   int86(0x10, &r, &r);  /* get video mode */
   printf("Current video mode = %02hx\n", r.h.al);

   printf("\nSequencer registers:\n");
   printf("-----------------------------------------------\n");
   for (i=0; i<5; i++) {
       v=SQread_reg(i);
       printf("%2hxh: %02hxh  %3hu  :%s\n",i,v,v,Sequencernames[i]);
   }

   printf("\nMiscellaneous output register\n");
   printf("   : %02hxh       :\n", v=MOread_reg());


   overflow=CRTCread_reg(7);  /* overflow: many different calculations */

   printf("\nCRTC data register contents:\n");
   printf("-----------------------------------------------\n");

   v=CRTCread_reg(0);
   printf("%2hxh: %02hxh  %3hu  :%s (+5= %3hu)\n",0,v,v,CRTCdregnames[0],v+5);

   v=CRTCread_reg(1);
   printf("%2hxh: %02hxh  %3hu  :%s\n",1,v,v,CRTCdregnames[1]);

   shb=v=CRTCread_reg(2);
   printf("%2hxh: %02hxh  %3hu  :%s\n",2,v,v,CRTCdregnames[2]);

   v=CRTCread_reg(3); ehr=CRTCread_reg(5);
   temp1=(shb%64); temp2=(v%32+(ehr & 0x80)/4);
   if (temp2 > temp1)
      temp3=(shb&0xc0)+temp2;
   else
      temp3=(shb&0xc0)+temp2+64;
   printf("%2hxh: %02hxh  %3hu  :%s (= %3hu)\n",3,v,v,CRTCdregnames[3],temp3);

   shr=v=CRTCread_reg(4);
   printf("%2hxh: %02hxh  %3hu  :%s\n",4,v,v,CRTCdregnames[4]);

   temp1=(shr&0xe0); temp2=(ehr%32); temp3=temp1+temp2;
   if (temp3 < shr) temp3+=32;
   printf("%2hxh: %02hxh  %3hu  :%s (= %3hu)\n",
                  5,ehr,ehr,CRTCdregnames[5],temp3);
   v=CRTCread_reg(6);
   printf("%2hxh: %02hxh  %3hu  :%s (= %3d)\n",
                  6,v,v,CRTCdregnames[6],
                  (int)(v+(overflow&0x20)*16+(overflow&0x01)*256));

   v=overflow;
   printf("%2hxh: %02hxh  %3hu  :%s\n",7,v,v,CRTCdregnames[7]);
   printf("   : Bit 9 :%1u - Vertical Retrace start\n",
                  (overflow&0x80)/128);
   printf("   : Bit 9 :%1u - Vertical Display enable end\n",
                  (overflow&0x40)/64);
   printf("   : Bit 9 :%1u - Vertical Total\n",
                  (overflow&0x20)/32);
   printf("   : Bit 8 :%1u - Line compare\n",
                  (overflow&0x10)/16);
   printf("   : Bit 8 :%1u - Start vertical blank\n",
                  (overflow&0x08)/8);
   printf("   : Bit 8 :%1u - Vertical Retrace start\n",
                  (overflow&0x04)/4);
   printf("   : Bit 8 :%1u - Vertical Display enable end\n",
                  (overflow&0x02)/2);
   printf("   : Bit 8 :%1u - Vertical Total\n", (overflow&0x01));

   v=CRTCread_reg(8);
   printf("%2hxh: %02hxh  %3hu  :%s\n",8,v,v,CRTCdregnames[8]);
   msl=v=CRTCread_reg(9);
   printf("%2hxh: %02hxh  %3hu  :%s (= %3hu)\n",9,v,v,CRTCdregnames[9],v%32);
   if (v&0x80) printf("   :           :double scan set to 1\n");
      else     printf("   :           :double scan set to 0\n");
   for (i=10; i<16; i++) {
       v=CRTCread_reg(i);
       printf("%2hxh: %02hxh  %3hu  :%s\n",i,v,v,CRTCdregnames[i]);
   }
   v=CRTCread_reg(16);
   vrs=v+(overflow&0x80)*4+(overflow&0x04)*64;
   printf("%2hxh: %02hxh  %3hu  :%s (= %3d)\n",16,v,v,CRTCdregnames[16],
                  vrs);

   v=CRTCread_reg(17);
   temp1=(vrs&0xfff0); temp2=(v%16); temp3=temp1+temp2;
   if (temp3 < vrs) temp3+=16;
   printf("%2hxh: %02hxh  %3hu  :%s (= %3d)\n",17,v,v,CRTCdregnames[17],
                  temp3);
   if (v&0x80)
     printf("   :           :CRTC registers 0 to 7 write protected.\n");
   else
     printf("   :           :CRTC registers 0 to 7 not write protected.\n");
   printf("   :           :Refresh Cycle Select=%1u\n",(v&0x40)/64);
   printf("   :           :(not)Enable vertical interrupt=%1u\n",
               (v&0x20)/32);
   printf("   :           :(not)Clear vertical interrupt=%1u\n",
               (v&0x10)/16);

   v=CRTCread_reg(0x12);
   printf("%2hxh: %02hxh  %3hu  :%s (= %3d)\n",18,v,v,CRTCdregnames[18],
                  v+(overflow&0x40)*8+(overflow&0x02)*128);
   v=CRTCread_reg(0x13);
   printf("%2hxh: %02hxh  %3hu  :%s\n",19,v,v,CRTCdregnames[19]);
   v=CRTCread_reg(0x14);
   printf("%2hxh: %02hxh  %3hu  :%s (= %3hu)\n",20,v,v,CRTCdregnames[20],
                  v%32);
   printf("   :           :Double word mode=%1u\n",(v&0x40)/64);
   printf("   :           :Count by 4 mode=%1u\n", (v&0x20)/32);

   v=CRTCread_reg(0x15);
   svb=v+(msl&0x20)*16+(overflow&0x08)*32;
   printf("%2hxh: %02hxh  %3hu  :%s (= %3d)\n",21,v,v,CRTCdregnames[21],svb);
   v=CRTCread_reg(0x16);
   temp1=(svb&0xff00); temp3=temp1+v;
   if (temp3 < svb) temp3+=256;
   printf("%2hxh: %02hxh  %3hu  :%s (= %3d)\n",
                  22,v,v,CRTCdregnames[22],temp3);

   v=CRTCread_reg(0x17);
   printf("%2hxh: %02hxh  %3hu  :%s ()\n",23,v,v,CRTCdregnames[23]);
   v=CRTCread_reg(0x18);
   printf("%2hxh: %02hxh  %3hu  :%s ()\n",24,v,v,CRTCdregnames[24]);


   printf("\nAttribute controller registers:\n");
   printf("-----------------------------------------------\n");
   for (i=0; i<16; i++) {
       v=ACread_reg(i);
       printf("%2hxh: %02hxh  %3hu  :Palette color #%d\n",i,v,v,i);
   }
   for (i=16; i<0x15; i++) {
       v=ACread_reg(i);
       printf("%2hxh: %02hxh  %3hu  :%s\n",i,v,v,ACdregnames[i-16]);
   }

   printf("\nGraphics controller registers:\n");
   printf("-----------------------------------------------\n");
   for (i=0; i<9; i++) {
       v=GCread_reg(i);
       printf("%2hxh: %02hxh  %3hu  :%s\n",i,v,v,GCdregnames[i]);
   }

   printf("\n");
   exit(0);

}
