/*	Title	Global Data*/
/******************************************************************************/
/*				    Diag2				      */
/*			      Allpro diagnostic 3			      */
/*									      */
/* Project .................... Allpro - Universal Programmer		      */
/* Module ..................... DIAG2.C 				      */
/* Title ...................... Allpro diagnostic 3			      */
/* Developing Engineer ........ Steven T. Harr				      */
/* Company .................... Logical Devices 			      */
/* Revision Level ............. v3.00					      */
/* Date of Last Revision ...... 10-16-89				      */
/* Last Revision by ........... STH					      */
/* Developing System .......... IBM PC or compatible			      */
/* Target System .............. IBM PC or compatible			      */
/* Language ................... C					      */
/* Compiler ................... Manx Aztec C v3.20e			      */
/* Compiler Command(s) ........ cc Diag3				      */
/*									      */
/* Interpreter ................ none					      */
/*									      */
/* Synopsis ................... This module contains the MAIN entrance	      */
/*				point and the main menu.		      */
/*									      */
/* Revision History:							      */
/*  v3.00   10-16-89		Original version - STH			      */
/*									      */
/******************************************************************************/
/*	Subttl	Includes    */
#include <stdio.h>
#include <ctype.h>
#include "cmdfile.h"
#include "pindrivr.h"
#include "keybrd.h"
#include "diag2.h"


/*	Subttl	Equates    */
#define TRUE				1
#define FALSE				0
#define MAX_DEPTH			8

/*     Subttl  Externals*/



/*     Subttl  Variables and Tables*/

unsigned char at_286_flag;
unsigned int se6440_flag;
unsigned int allpro88_flag;
unsigned int UdiSegment = 0xa000;   /* default segment */
int vid_mod;
int cursor_top;
int cursor_bottom;

int func_null ();
int func_analog_cont ();
int func_pin_driver_test ();
int func_help ();
int func_trblsht ();
int func_edit ();
int func_config ();
int func_ibmint ();
int func_controller();
int func_se6440();


struct menu_struc menu_main [] =
{
    { '?',*func_help,  4, 'C', "Main Menu" },
    { '?',*func_help,  5, 'C', "Written by Steven T. Harr" },
    { '1',*func_ibmint,           9,  'L', "1. TEST PC INTERFACE CARD." },
    { '2',*func_null,            10,  'L', "2. TEST MOTHER BOARD." },
    { '3',*func_controller,      11,  'L', "3. TEST CONTROLLER." },
    { '4',*func_analog_cont,     12,  'L', "4. TEST ANALOG CONTROL." },
    { '5',*func_pin_driver_test, 13,  'L', "5. TEST PIN DRIVERS" },
    { '6',*func_trblsht,         15,  'L', "6. TROUBLE SHOOT" },
    { '7',*func_config,          16,  'L', "7. DIAGNOSTIC CONFIGURATION." },
    { '8',*func_se6440,          18,  'L', "8. TEST SE6440." },
    { '\0',*func_null, 0,  0, "" }
};



struct menu_struc menu_help [] =
{
    { '0',*func_null,  4, 'C', "ALLPRO DIAGNOSTIC HELP MENU" },
    { '0',*func_null,  6, 'C', "No help at this time" },
    { '\0',*func_null, 0,  0, "" }
};



struct menu_struc menu_null [] =
{
    { '0',*func_null,  4, 'C', "ALLPRO DIAGNOSTIC" },
    { '0',*func_null,  6, 'C', "This command is not available at this time" },
    { '\0',*func_null, 0,  0, "" }
};



char menu_depth [MAX_DEPTH];
int menu_level;


/*	Subttl Main entrance for allpro diagnostic 2   */

main (argc, argv)
int argc;
char *argv [];
{

    int func_null ();
    int i;

    for ( i = 0; i < MAX_DEPTH ; i++ )
    {
	menu_depth [i] = 0;
    }

    if (!initialize_diagnostic ())
    {
	printf ("No .cfg File Found");
	keybrd_getc ();
    }

    pump ();							/* unlock udi interface for access		*/

    reset_allpro ();						/* initialize all-pro and interface mem map	*/

    identify_machine ();					/* identify machine running on			*/

    menu_level = 0;
    menu_depth [menu_level] = '1';                 /* select main menu */
    select_command ( menu_main );

    reset_allpro();
    unpump ();							/* lock udi interface from access		*/
								/* done 					*/
    crt_pos_cursor (22,25,0);
    printf ( "Have a nice day !!!");
    exit (0);
}



/*	Subttl	Select command */
/******************************************************************************/
/* Select command prints a menu on the screen, controls cursor movement and   */
/* allows the operator to select an item from the menu. When an item is       */
/* selected, the function pointer for that selection is called. 	      */
/*									      */
/* Enter:   menu_struc_ptr	= pointer to structure containing menu info.  */
/*									      */
/* Call:    select_command	(menu_struc_ptr)			      */
/*									      */
/* Return:  selected function						      */
/*									      */
/******************************************************************************/

select_command ( menu_struc_ptr )
struct menu_struc menu_struc_ptr [];
{
    int keychar;
    char command;
    int i;
    int remain;
    int cur_row;
    int cur_col;
    int cmnd;

    print_menu ( menu_struc_ptr );
    if(se6440_flag) {}
    cur_col = 4;
    cmnd = menu_pos_cursor ( menu_struc_ptr );	  /* get position of first command */
    for ( remain = TRUE; remain == TRUE; )
    {
	if ( cmnd )
	{
	    crt_pos_cursor ( menu_struc_ptr [cmnd].set_menu_row, 4, 0 );
	}

	switch (keychar = keybrd_getc ())
	{
	    case KEY_ESC:
	    {
		remain = FALSE;
		break;
	    }
	    case KEY_F9:
	    {
		if(se6440_flag) select_zif_socket();
		print_menu ( menu_struc_ptr );
		break;
	    }
	    case KEY_CURSOR_UP:
	    {
		if ( menu_struc_ptr [cmnd].match_char > '1' && menu_struc_ptr [cmnd].match_char <= '9')
		{
		    cmnd--;
		}
		break;
	    }
	    case KEY_CURSOR_DOWN:
	    {
		if ( menu_struc_ptr [cmnd + 1].match_char != '\0' )
		{
		    cmnd++;
		}
		break;
	    }
	    case KEY_CR:
	    {
		keychar = menu_struc_ptr [cmnd].match_char;
	    }
	    case '1':
	    case '2':
	    case '3':
	    case '4':
	    case '5':
	    case '6':
	    case '7':
	    case '8':
	    case '9':
	    case '?':
	    {
		for ( i = 0; (menu_struc_ptr[i].match_char != keychar)
		&& (menu_struc_ptr [i].match_char != '\0'); i++ );
		if ( menu_struc_ptr [i].match_char )
		{
		    cmnd = i;
		    menu_depth [++menu_level] = menu_struc_ptr [i].match_char;
		    (*menu_struc_ptr[i].func)();
		    menu_depth [menu_level--] = 0;
		    print_menu ( menu_struc_ptr );
		}
		break;
	    }
	}
    }
}




func_help ()
{
    select_command ( menu_help );
}





int func_null ()
{
    select_command ( menu_null );
}






/*	Subttl	Determine Machine Type*/
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");
/*
	get_command_line ();

	string_to_upper (command_buffer);

	if (strncmp ("AT", command_buffer, 2) == 0)
	{
	    at_286_flag = TRUE;
	}
	else
	{
	    at_286_flag = FALSE;
	}
*/
    }
    get_video_mode ();
    if (vid_mod == 7 || vid_mod == 15)	     /*  monochrome  */
    {
	cursor_top = 12;
	cursor_bottom = 13;
    }
    else
    {
	cursor_top = 6;
	cursor_bottom = 7;
    }

}



/*	Subttl	Print menu ( from data in menu_ptr )  */
print_menu ( menu_ptr )
struct menu_struc menu_ptr[];
{
    int i;

    setup_window(WND_FUNC_SELECT);
    write_window_border(WND_FUNC_SELECT,'C', menu_ptr [0].message );
    for ( i = 1; menu_ptr[i].match_char != '\0'; i++ )
    {
	write_window (WND_FUNC_SELECT,menu_ptr[i].set_menu_row,menu_ptr[i].set_menu_col,menu_ptr[i].message);
    }
}

menu_pos_cursor ( menu_ptr )
struct menu_struc menu_ptr [];
{
    int i;

    for ( i = 0; menu_ptr [i].match_char != '\0'; i++ )
    {
	if ( menu_ptr [i].match_char >= '1' && menu_ptr [i].match_char <= '9')
	{
	    return ( i );
	}
    }
    return ( 0 );
}






/*	Subttl	Initialize All-Pro*/
reset_allpro ()
{
    int pin, pins;						      /* pin counter to reset pins		      */

    pump();
    udi_write_mem(0x298,0xff);	 /*  enable all sockets se6440 */
    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);

    if(se6440_flag) pins = 40;
    if(allpro88_flag) pins = MAX_DEVICE_PINS;

    for (pin = 1; pin <= pins; pin++)
    {
	set_pin_cnf (pin, PD_DRIVER_ON);
	set_pin_dac (pin, 0);
    }
    /* clear all registers on zif module */
    if(!se6440_flag)
    {
	for(pin = 0x280;pin < 0x290;pin++)
	{
	    udi_write_mem(pin,0);
	}
    }
}



get_video_mode ()
{
    struct intstruc
    {	int	AX;
	int	BX;
	int	CX;
	int	DX;
	int	SI;
	int	DI;
	int	DS;
	int	ES;
    }
    intcall;
    intcall.AX = 0x0f00;
    sysint (0x10,(struct intstruc *) &intcall,(struct intstruc *) &intcall);
    vid_mod = (intcall.AX & 0x00ff);
}
