#include <stdio.h>
/* dostv - (C) Copyright ムンパッパ (MHB02550)     
 *               	      Ver. 1.0 1990/5/27
 *               	      Ver. 1.1 1990/5/31
 *               	      Ver. 1.2 1991/1/ 2
 * tvmode - (C) Copyright ムンパッパ (MHB02550)     
 *               	      Ver. 0.5 1991/1/ 6
 *               	      Ver. 1.0 1991/4/11
 *
 * このソフトウェアは自由にコピ−、改変、配布が出来ます。
 */
#include <dos.h>
#include "tvmode.h"

int		    bright;
static int	    off_flg = 0;
static int	    mode = 5; /* DOS TV ON */
static int	    priority = 5;
static int	    ctr = 0x15;
static short	    *table = on_tbl;
static unsigned char	    *palette = don_plt;
static unsigned char	    plt_buf[96];

main(argc, argv) 
    int    argc;
    char    *argv[];
{

    register int    i;
    static union REGS regs;
    static struct SREGS sregs;

    readplt(plt_buf);
    for (i = 0; i < MAXMODE; ++i) {
	if (!pltcmp(plt_buf, now_plt[i])) {
	    mode = i;
	    table = new_tbl[mode];
	    palette = new_plt[mode];
	    priority = pritab[mode];
	    off_flg = (mode & 1)?0:1;
	    goto chkarg;
	}
    }
chkarg:
    getarg(argc, argv);

    outportb(0x440, 30);
    if (!off_flg && !(inport(0x442) & 0x100)) { /* ビデオ入力なし */
    	table[28] &= 0xbfff;			/* 内部同期  */
    	table[28] |= 0x00c0;			/* ス−パ−インポ−ズ無効 */
    }

    for (i = 0; i < MAXBLK; ++i) {
        outportb(0x440, (unsigned char)i);
	outport(0x442, table[i]);
    }
    setplt16(palette);
    if (off_flg) {
        outportb(0x448, (unsigned char)0);
        outportb(0x44a, 0x15);
        outportb(0x448, (unsigned char)1);
        outportb(0x44a, priority);
        outportb(0xfda0, 0xf);
	outportb(0x440, (unsigned char)28);
	outport(0x442, 0x803f);         /* ビデオ　スタ−ト */
        /* 電子ボリュ−ム */
        outportb(0x04e1, 0x0);		/* LINE 左 OFF     */
        outportb(0x04e1, 0x1);		/* LINE 右 OFF     */
        outportb(0x04e0, 0x0);		/* ボリュ−ム MIN  */
    }
    else {
        outportb(0x448, (unsigned char)0);
        outportb(0x44a, ctr);
        outportb(0x448, (unsigned char)1);
        outportb(0x44a, priority);
        outportb(0xfda0, 0xf);
	outportb(0x440, (unsigned char)28);
	outport(0x442, table[28] | 0x8000);         /* ビデオ　スタ−ト */

        /* 電子ボリュ−ム */

        outportb(0x04e1, 0x04);		/* LINE 左 ON      */
        outportb(0x04e1, 0x05);		/* LINE 右 ON      */
        outportb(0x04e0, 0x3f);		/* ボリュ−ム MAX  */
    }
}
getarg(argc, argv) 
	int	argc;
	char	**argv;
{
    register int    i, argcnt;
    for (argcnt = 1; argc >= 2; --argc, ++argcnt) {
	if ((!strcmp(argv[argcnt],"off"))||(!strcmp(argv[argcnt],"OFF"))) {
	    off_flg = 1;
	    mode &= 0xfffe;
	    table = new_tbl[mode];
	    palette = new_plt[mode];
	    priority = pritab[mode];
	}
	else if ((!strcmp(argv[argcnt],"on"))||(!strcmp(argv[argcnt],"ON"))) {
	    off_flg = 0;
	    mode |= 1;
	    table = new_tbl[mode];
	    palette = new_plt[mode];
	    priority = pritab[mode];
	}
	else if ((!strcmp(argv[argcnt],"ful"))||(!strcmp(argv[argcnt],"FUL"))) {
            table[30] = 3;                          /* フルト−ン */
	}
	else if ((!strcmp(argv[argcnt],"high"))||(!strcmp(argv[argcnt],"HIGH"))) {
            priority &= 0xfb;                        /* 高輝度 */
	}
	else if ((!strcmp(argv[argcnt],"cmp"))||(!strcmp(argv[argcnt],"CMP"))) {
            priority |= 0x8;                         /* ス−パ−インポ−ズOFF */
            table[28] &= 0xbf;                      /* 内部同期 */
	}
	else if ((!strcmp(argv[argcnt],"video"))||(!strcmp(argv[argcnt],"VIDEO"))) {
            ctr = 0x10;                              /* DISPLAY OFF */
	}
	else if ((!strncmp(argv[argcnt],"ap=",3))||(!strncmp(argv[argcnt],"AP=",3))) {
            apset(palette, &(argv[argcnt][3]));          /* analog palette set */
	}
	else {
	    for (i = 0; i < MAXMODE; ++i) {
		if ((!strcmp(argv[argcnt],mode1[i]))||
			(!strcmp(argv[argcnt],mode2[i]))) {
		    mode = i;
		    off_flg = (mode & 1)?0:1;
		    table = new_tbl[mode];
		    palette = new_plt[mode];
		    priority = pritab[mode];
		    goto next_arg;
		}
	    }
	    fprintf(stderr,"USAGE: %s [mode] [options...]\n", argv[0]);
	    fprintf(stderr,"mode\n");
	    fprintf(stderr,"    dos   : MS-DOS モ−ド\n");
	    fprintf(stderr,"    plt   : MOPTERM オ−トパイロットモ−ド\n");
	    fprintf(stderr,"    rtc   : MOPTERM チャットモ−ド\n");
	    fprintf(stderr,"    ori   : ORICON モ−ド\n");
	    fprintf(stderr,"    dmy   : DMYCON モ−ド\n");
	    fprintf(stderr,"option\n");
	    fprintf(stderr,"    off   : ＴＶを切る\n");
	    fprintf(stderr,"    on    : ＴＶをつける\n");
	    fprintf(stderr,"    ful   : フルト−ン(デフォルトはハ−フト−ン)\n");
	    fprintf(stderr,"    high  : 高輝度(デフォルトは低輝度)\n");
	    fprintf(stderr,"    cmp   : コンピュ−タ出力のみ(デフォルトはス−パ−インポ−ズ)\n");
	    fprintf(stderr,"    video : ビデオ出力のみ(デフォルトはス−パ−インポ−ズ)\n");
	    fprintf(stderr,"    ap=ファイル名 : ファイル名のアナログパレットを使う\n");
	    exit(1);
next_arg:
	}
    }
}
setplt16(plt16)
	unsigned char	*plt16;
{
	register int	i;
        outportb(0x448, (unsigned char)1);
        outportb(0x44a, 1);          /* 16色パレットレイア0 */
	for (i = 0; i < 16; ++i) {
	    outportb(0xfd90, i);
	    outportb(0xfd92, *plt16++);
	    outportb(0xfd94, *plt16++);
	    outportb(0xfd96, *plt16++);
	}

        outportb(0x448, (unsigned char)1);
        outportb(0x44a, 0x21);          /* 16色パレットレイア1 */

	for (i = 0; i < 16; ++i) {
	    outportb(0xfd90, i);
	    outportb(0xfd92, *plt16++);
	    outportb(0xfd94, *plt16++);
	    outportb(0xfd96, *plt16++);
	}
}
readplt(pltbuf)
	unsigned char *pltbuf;
{
	register int	i;

        outportb(0x448, (unsigned char)1);
        outportb(0x44a, 5);         /* 16色パレットレイア0 */

	for (i = 0; i < 16; ++i) {
	    outportb(0xfd90, i);
	    *pltbuf++ = inportb(0xfd92) & 0xf0;
	    *pltbuf++ = inportb(0xfd94) & 0xf0;
	    *pltbuf++ = inportb(0xfd96) & 0xf0;
	}

        outportb(0x448, (unsigned char)1);
        outportb(0x44a, 0x25);          /* 16色パレットレイア1 */

	for (i = 0; i < 16; ++i) {
	    outportb(0xfd90, i);
	    *pltbuf++ = inportb(0xfd92);
	    *pltbuf++ = inportb(0xfd94);
	    *pltbuf++ = inportb(0xfd96);
	}
}
pltcmp(plt_buf, now_plt)
    unsigned char	*plt_buf;
    unsigned char	*now_plt;
{
    register int	i;
    for (i = 0; i < 96; ++i) {
	if (plt_buf[i] != now_plt[i]) {
    	    return(1);
	}
    }
    return(0);
}
apset(palette, fname)
    unsigned char	*palette;
    char		*fname;
{
    FILE		*ifp;
    register int	i;
    static int		tmp1,tmp2,tmp3;
    static char		dust[BUFSIZ];
    
    if ((ifp = fopen(fname,"r"))==NULL) {
        fprintf(stderr,"Can't open \"%s\"\n",fname);
        exit(1);
    }
    for (i = 0; i < 32; ++i) {
    	fscanf(ifp, "%d%d%d%[^\n]\n", &tmp1, &tmp2, &tmp3, dust);
	palette[i*3+0] = tmp1;
	palette[i*3+1] = tmp2;
	palette[i*3+2] = tmp3;
     /* printf("%4d%4d%4d\n", palette[i*3+0], palette[i*3+1], palette[i*3+2]);*/
    }
}
