// Video register dump program
// By [TheFlash]

#include <dos.h>
#include <stdio.h>

#define VGA_AC_INDEX 0x3C0
#define VGA_AC_WRITE 0x3C0
#define VGA_AC_READ 0x3C1
#define VGA_SEQ_INDEX 0x3C4
#define VGA_SEQ_DATA 0x3C5
#define VGA_CRTC_INDEX 0x3D4
#define VGA_CRTC_DATA 0x3D5
#define VGA_GC_INDEX 0x3CE
#define VGA_GC_DATA 0x3CF
#define VGA_MISC_READ 0x3CC
#define VGA_MISC_WRITE 0x3C2
#define VGA_STATUS 0x3DA

FILE *output;

void switchMode(int mode)
{
    union REGS inputRegs, outputRegs;

    inputRegs.x.ax = mode & 0xFF;
    int86(0x10, &inputRegs, &outputRegs);
}

void dumpRegisters(void)
{
    int i;

    fprintf(output, "Misc register: 0x%02X\r\n", inp(VGA_MISC_READ));
    fprintf(output, "Sequencer registers:\r\n");
    for (i = 0; i < 5; i++)
    {
        outp(VGA_SEQ_INDEX, i);
	fprintf(output, "0x%02X ", inp(VGA_SEQ_DATA));
    }

    fprintf(output, "\r\nGC registers:\r\n");
    for (i = 0; i < 9; i++)
    {
	outp(VGA_GC_INDEX, i);
	fprintf(output, "0x%02X ", inp(VGA_GC_DATA));
    }

    fprintf(output, "\r\nCRTC registers:\r\n");
    for (i = 0; i < 25; i++)
    {
	outp(VGA_CRTC_INDEX, i);
	fprintf(output, "0x%02X ", inp(VGA_CRTC_DATA));
    }

    fprintf(output, "\r\nAC registers:\r\n");
    for (i = 0; i < 21; i++)
    {
        inp(VGA_STATUS);
	outp(VGA_AC_INDEX, i);
	fprintf(output, "0x%02X ", inp(VGA_AC_READ));
    }
    fprintf(output, "\r\n\r\n");
}

int main(void)
{
    int i;

    output = fopen("VGAREGS.DMP", "w");
    if (output == NULL)
    {
        printf("Cannot create file!\r\n");
	return 1;
    }

    for (i = 0; i <= 0x13; i++)
    {
	switchMode(i);
	fprintf(output, "***** MODE %02Xh *****\r\n\r\n", i);
	dumpRegisters();
    }

    switchMode(0x03);
    fclose(output);
    
    return 0;
}
