
#include <stdio.h>
#include <ctype.h>
#include "pindrivr.h"
#include "keybrd.h"
#include "diag2.h"
#include "windows.h"
#include "window.h"

extern int scr_putc();
extern char *_fmtcvt();
/*extern char *_fmtcvt(void *,int,char *,int);*/

    unsigned char left_pin = 182;
    unsigned char right_pin = 199;
    unsigned char top_ic [16]  = {201,205,205,205,205,205,184, 32,213,205,205,205,205,205,187,0};
    unsigned char bott_ic [16] = {200,205,205,205,205,205,205,205,205,205,205,205,205,205,188,0};

unsigned int phys_pin_offset = 0;
unsigned char at_286_flag;
unsigned int UdiSegment = 0xa000;   /* default segment */


int pin_voltage [41];


extern FILE *fptr, *fopen ();

main(argc,argv)
int argc;
char **argv;
{
    int pin;
    int row;
    int col;
    int ch;
    FILE *fp,*fopen();

    if(strcmp(argv[1],"-i"))
    {
	fp = fopen("dp.dat","r");
	if(fp == NULL)
	{
	    printf("Unable to open file: 'DP.DAT'\n");
	    exit(1);
	}
	fread(pin_voltage,1,sizeof(pin_voltage),fp);
	fclose(fp);
    }


    crt_scroll_up (0, 0,0,24, 79, 0x17);
    identify_machine();

    pos_printf(5,54,"DAC per PIN");
    pos_printf(7,51,"Proof / Benchmark");
    pos_printf(10,47,"Verify pin voltage with DVM");
    if(strcmp(argv[1],"-a") == 0)
    {
	pos_printf(12,48,"Can anyone else do this?!?");
    }
    else
    {
	pos_printf(12,48,"Can DATA I/O do this?!?");
    }

    reset_allpro();
    udi_write_mem(ANALOG_CONTROL, DAC_REFERENCE_BIT | GREEN_LED_OFF_BIT);
    udi_write_dac (SLEW_RATE_DAC, 100); 			/* use maximum slew				*/
    udi_write_dac (PU_CONTROL_DAC, 600);

    udi_write_dac (SUPPLY1_POWER_DAC, 2500); /* initialize power dacs			 */
    for ( pin = 1; pin <= 40; pin++)
    {
	set_pin_cnf (pin, SRC_DRIVER_ON | PD_DRIVER_ON);
	set_pin_dac (pin, pin_voltage[pin]);
    }

    delay_ms (400);	 /* allow switchers to come up to power 	 */


    pos_printf(1,12,"%s",top_ic);
    row = 2;
    for ( pin = 1; pin <= 20; pin++ )
    {
	pos_printf (row,12,"%c %2d       %2d %c", left_pin, pin, 41 - pin , right_pin  );
	row++;
    }
    pos_printf(22,12,"%s",bott_ic);

    for(pin = 1;pin <= 20; pin++)
    {
	pos_printf (pin+1,7,"%02d.%01d", pin / 2, (pin % 2) * 5);
	pos_printf (pin+1,28,"%02d.%01d", (41-pin) / 2, ((41-pin) % 2) * 5);
    }

    while (1)
    {
loop:
	crt_pos_cursor(0,0,0);
	ch = keybrd_getc();
	if(ch == KEY_ESC) break;
	if(ch == KEY_ALT_F1)
	{
	    pin = 1;
	    while(1)
	    {
		highlight_pin(pin,1);
		crt_pos_cursor(0,0,0);
		ch = keybrd_getc();
		highlight_pin(pin,0);
		switch(ch)
		{
		    case KEY_ESC:
			goto end;
		    break;
		    case KEY_END:
			fp = fopen("dp.dat","w");
			fwrite(pin_voltage,1,sizeof(pin_voltage),fp);
			fclose(fp);
			goto loop;
		    break;
		    case KEY_HOME:
			for(pin = 1;pin <= 40;pin++)
			{
			    pin_voltage[pin] = pin * 50;
			    set_pin_dac (pin, pin_voltage[pin]);
			}
			pin = 1;
		    break;
		    case KEY_CURSOR_UP:
			if(pin > 20) {if(++pin > 40) pin--;}
			else if(--pin == 0) pin++;
		    break;
		    case KEY_CURSOR_DOWN:
			if(pin > 20) {if(--pin <= 20) pin++;}
			else if(++pin > 20) pin--;
		    break;
		    case KEY_CURSOR_LEFT:
			if(pin > 20) pin = 41 - pin;
		    break;
		    case KEY_CURSOR_RIGHT:
			if(pin <= 20) pin = 41 - pin;
		    break;
		    case '-':
			pin_voltage[pin] -= 10;
			set_pin_dac (pin, pin_voltage[pin]);
		    break;
		    case '+':
			pin_voltage[pin] += 10;
			set_pin_dac (pin, pin_voltage[pin]);
		    break;
		}
	    }
	}
    }
end:
    udi_write_dac (SUPPLY1_POWER_DAC, 0);			/* shut down all power dacs			*/
    udi_write_mem (ANALOG_CONTROL,0);			  /* make sure dac reference is shut down	  */
    unpump();
    crt_scroll_up (0, 0,0,24, 79, 0x07);
}


highlight_pin(pin,flag)
int pin,flag;
{
    if(pin <= 20)
    {
	highlight(pin+1,13,15,flag?0x71:0x17);
    }
    else
    {
	highlight(42-pin,23,25,flag?0x71:0x17);
    }
}


read_pin_voltage (pin)
unsigned int pin;
{
    unsigned int approx;
    unsigned int guess;

    approx = 0; 						/* initial approximation			*/

    for (guess = 0x80; guess > 0; guess >>= 1)			/* addend and control				*/
    {
	udi_write_mem (THRESH_HOLD_DAC, approx + guess);	/* set comp drive				*/

	if (udi_read_bit (pin)) 	      /* was it too low?			      */
	{
	    approx = approx + guess;				/* yes - restore AND add			*/
	}
    }

    return (approx * 10);					/* return pinvalue				*/
}


reset_allpro ()
{
    int pin, pins;						      /* pin counter to reset pins		      */

    pump();
    udi_write_bit (DAC_REFERENCE_BIT, OFF);			/* make sure vcc power is shut down		*/
    udi_write_dac (SUPPLY1_POWER_DAC, 0);			/* high power dac to 0 volts			*/
    udi_write_dac (THRESH_HOLD_DAC, 0);


    for (pin = 1; pin <= 40; pin++)
    {
	set_pin_cnf (pin, PD_DRIVER_ON);
	set_pin_dac (pin, 0);
    }
    for(pin = 0x280;pin < 0x290;pin++)
    {
	udi_write_mem(pin,0);
    }
}

sc_putc(ch)
char ch;
{
    crt_wr_teletype (ch,1,0);
}


pos_printf(row,col,fmt,vars)
int row,col;
char *fmt;
int vars;
{
    crt_pos_cursor(row,col,0);
    format(sc_putc,fmt,&vars);
}


static char *
_fmtcvt(ap, base, cp, len)
void *ap; char *cp;
{
	unsigned long val;
	static char digits[]="0123456789abcdef";

	if (len == sizeof(long))
		val = *(long *)ap;
	else if (base > 0)
		val = *(unsigned *)ap;
	else
		val = *(int *)ap;

	len = 0;
	if (base < 0) {
		base = -base;
		if ((long)val < 0) {
			val = -val;
			len = 1;
		}
	}

	do {
		*--cp = digits[(int)(val%base)];
	} while ((val /= base) != 0);
	if (len)
		*--cp = '-';
	return cp;
}

format(putsub, fmt, argp)
int (*putsub)(); char *fmt; char *argp;
{
	int c;
	union {
		int *ip;
		char *cp;
		char **cpp;
#ifdef FLOAT
		double *dp;
#endif
	} args;
	int charcount;
	int rj, fillc;
	int maxwidth, width;
	int i, k;
	char *cp;
	auto char s[200];

	charcount = 0;
	args.cp = argp;
	while ( (c = *fmt++) != 0 ) {
		if ( c == '%' ) {
			s[14] = 0;
			rj = 1;
			fillc = ' ';
			maxwidth = 10000;
			if ((c = *fmt++) == '-') {
				rj = 0;
				c = *fmt++;
			}
			if (c == '0') {
				fillc = '0';
				c = *fmt++;
			}
			if (c == '*') {
				width = *args.ip++;
				c = *fmt++;
			} else {
				for (width = 0 ; isdigit(c) ; c = *fmt++)
					width = width*10 + c - '0';
			}
			if ( c == '.' ) {
				if ((c = *fmt++) == '*') {
					maxwidth = *args.ip++;
					c = *fmt++;
				} else {
					for (maxwidth = 0 ; isdigit(c) ; c = *fmt++)
						maxwidth = maxwidth*10 + c - '0';
				}
			}
			i = sizeof(int);
			if (c == 'l') {
				c = *fmt++;
				i = sizeof(long);
			} else if (c == 'h')
				c = *fmt++;

			switch ( c ) {
			case 'o':
				k = 8;
				goto do_conversion;
			case 'u':
				k = 10;
				goto do_conversion;
			case 'x':
				k = 16;
				goto do_conversion;

			case 'd':
				k = -10;
	do_conversion:
				cp = _fmtcvt(args.cp, k, s+14, i);
				args.cp += i;
				break;

			case 's':
				i = strlen(cp = *args.cpp++);
				goto havelen;
#ifdef FLOAT
			case 'e':
			case 'f':
			case 'g':
				ftoa(*args.dp++, s, maxwidth==10000?6:maxwidth, c-'e');
				i = strlen(cp = s);
				maxwidth = 200;
				goto havelen;
#endif

			case 'c':
				c = *args.ip++;
			default:
				*(cp = s+13) = c;
				break;
			}

			i = (s+14) - cp;
		havelen:
			if ( i > maxwidth )
				i = maxwidth;

			if ( rj ) {
				if ((*cp == '-' || *cp == '+') && fillc == '0') {
					--width;
					if ((*putsub)(*cp++) == -1)
						return -1;
				}
				for (; width-- > i ; ++charcount)
					if ((*putsub)(fillc) == -1)
						return -1;
			}
			for ( k = 0 ; *cp && k < maxwidth ; ++k )
				if ((*putsub)(*cp++) == -1)
					return -1;
			charcount += k;

			if ( !rj ) {
				for (; width-- > i ; ++charcount)
					if ((*putsub)(' ') == -1)
						return -1;
			}
		} else {
			if ((*putsub)(c) == -1)
				return -1;
			++charcount;
		}
	}
	return charcount;
}

identify_machine ()
{
    unsigned int status;

    unsigned char machine_id;

    machine_id = peek (0xFFFE, 0xF000);

    if (machine_id <= 0xFF && machine_id >= 0xFC)
    {
	if (machine_id == 0xFC)
	{
	    at_286_flag = TRUE;
	}
	else
	{
	    at_286_flag = FALSE;
	}
    }
    else
    {
	printf ("Unknown PC Macine ID. Enter PC for PC Compatible or AT for AT Compatible");
    }

}

highlight (row, col1, col2, attr)
int row, col1, col2, attr;
{
    int i;

    for (i = col1; i <= col2; i++)
    {
#asm
	Push	BP
	Mov	DH, [bp + 4]
	Mov	DL, [bp - 2]
	Mov	BH, 0
	Mov	AH, 2	    ;set cursor position
	Int	010H

	Mov	AH, 08h     ;read char
	Xor	BX, BX
	Int	10h

	Mov	BL, [bp + 10]	;write the same char
	Mov	AH, 9		;with specified attribute
	Mov	CX, 1
	Int	10h
	Pop	BP
#endasm
    }
}

