/*	Title	All-Pro Diagnostics*/
/******************************************************************************/
/*				     Ibmint				      */
/*			       All-pro Diagnostic IBM interface tests	      */
/*									      */
/* Module ...................... IBMINT 				      */
/* Title ....................... All-pro Diagnostic IBM interface tests       */
/* Developing Engineer ......... Steven T. Harr 			      */
/* Company ..................... Logical Devices			      */
/* Revision Level .............. 1.00					      */
/* Date of Last Revision ....... 09-14-89				      */
/* Last Revision by ............ STH					      */
/*									      */
/*									      */
/******************************************************************************/
/*	Subttl	Includes*/
#include "stdio.h"
#include "ctype.h"
#include "pindrivr.h"
#include "diag2.h"
#include "windows.h"
#include "window.h"
#include "tic.h"

extern unsigned int UdiSegment;
extern unsigned int pin_base_address [];
extern unsigned int phys_pin_offset;
static int msg_pos;
static unsigned int checksum;
static int eof_flag;

pc_rd_loop ();
pc_wr_loop ();
cpu_rd_loop ();
cpu_wr_loop ();
io_wr_loop ();

int func_null();
int rot_addr_map();
wtgen_test();
wtgen_test_cpu();
trouble_shoot ();
detect_card ();
pump();
half_pump ();
unpump();
card_test ();
fifo_test();
ram_test();
execute();
addr_rot_rd();
fifo_rd_loop();
fifo_wr_loop();
reg_card_test ();


unsigned char fifodata[] =
{
    0xb1,0x55,0x20,		/* Ldb	   20h,#55h  */
    0xc7,0x01,0x00,0x40,0x20,	/* Stb	   20h,4000h */
    0xf0			/* Ret		     */
};
unsigned char fifotest2[] =
{
    0xb1,0x55,0x20,		/* Ldb	   20h,#55h  */
				/* Loop:	     */
    0xc7,0x01,0x00,0x50,0x20,	/* Stb	   20h,5000h */
    0xb3,0x01,0x00,0x50,0x21,	/* Ldb	   21h,5000h */
    0x27,0xf4			/* Sjmp Loop	     */
};

struct menu_struc menu_ibmint [] =
{
    { '?',*func_null,      4, 'C', "PC INTERFACE DIAGNOSTIC"},
    { '1',*card_test,      6, 'L', "1. Test Turbo Card CPU section."},
    { '2',*wtgen_test,     7, 'L', "2. PC Wait State Check."},
    { '3',*wtgen_test_cpu, 8, 'L', "3. Processor Wait State Check."},
    { '4',*rot_addr_map,   9, 'L', "4. Rotate ADDR MAP Register."},
    { ' ',*func_null,     11, 'L', "   The R/W tests require an ALLPRO."},
    { '5',*reg_card_test, 12, 'L', "5. R/W Test (Regular Card)."},
    { '6',*execute,       13, 'L', "6. R/W Test (Turbo Card)."},
    { '9',*trouble_shoot, 15, 'L', "9. TroubleShooting."},
    { '\0',*func_null,  0,  0, "" }
};

struct menu_struc trouble_shoot_menu [] =
{
    { '?',*func_null,   4, 'C', "PC INTERFACE DIAGNOSTIC TroubleShooting Menu"},
    { ' ',*func_null,   5, 'L', "   The ALLPRO should NOT be connected."},
    { '0',*pump,        6, 'L', "0. Pump. Enable CPU and Map."},
    { '1',*half_pump,   7, 'L', "1. Half Pump. Enable CPU only."},
    { '2',*unpump,      8, 'L', "2. Unpump. Disable CPU and Map."},
    { '3',*pc_rd_loop,  9, 'L', "3. PC Read Loop."},
    { '4',*pc_wr_loop, 10, 'L', "4. PC Write Loop."},
    { '5',*cpu_rd_loop,11, 'L', "5. CPU Read Loop."},
    { '6',*cpu_wr_loop,12, 'L', "6. CPU Write Loop."},
    { '7',*fifo_rd_loop,13, 'L', "7. FIFO Read Loop. (312-313h)"},
    { '8',*fifo_wr_loop,14, 'L', "8. FIFO Write Loop.(312-313h)"},
    { '9',*io_wr_loop, 15, 'L', "9. Pump/Unpump Loop."},
    { '\0',*func_null,  0,  0, ""}
};

addr_rot_rd()
{
    int i;
    print_running_msg(menu_ibmint[3].set_menu_row);
    while(keyboard_status() == -1)
    {
#asm
	Push	es
	mov	ax,word ptr DS:[UdiSegment_]
	mov	es,ax
	mov	al,byte ptr es:[0ffeh]
	mov	al,byte ptr es:[0ffdh]
	mov	al,byte ptr es:[0ffbh]
	mov	al,byte ptr es:[0ff7h]
	mov	al,byte ptr es:[0fefh]
	mov	al,byte ptr es:[0fdfh]
	mov	al,byte ptr es:[0fbfh]
	mov	al,byte ptr es:[0f7fh]
	mov	al,byte ptr es:[0effh]
	mov	al,byte ptr es:[0dffh]
	mov	al,byte ptr es:[0bffh]
	mov	al,byte ptr es:[07ffh]
	Pop	es
#endasm
    }
    delete_running_msg();
}

fifo_test()
{
    int ctr;
    int status = TRUE;

    printf ("  Testing FIFO. Please wait...");
    for (ctr = 1; (ctr <= 10) && (status == TRUE); ctr++)
    {
	half_pump ();
	delay_ms (1);
	if (cpu_test () == FALSE)
	{
	    status = FALSE;
	    print_fail_msg ();
	    pause ();
	}
	unpump ();
    }
    return (status);
}

detect_card ()
{
    int ctr;
    int status = TRUE;

    printf ("  Detecting Card. Please wait...");
    for (ctr = 1; (ctr <= 10) && (status == TRUE); ctr++)
    {
	half_pump ();
	delay_ms (1);
	if (detect_tic () == FALSE)
	{
	    status = FALSE;
	    print_fail_msg();
	    pause ();
	    /*printf ("     Version = %2d", get_tic_version ());*/
	}
	unpump ();
    }
    return (status);
}

func_ibmint()
{
    select_command ( menu_ibmint );
}

trouble_shoot ()
{
    select_command (trouble_shoot_menu);
}

rot_addr_map()
{
    int i = 1;
    print_running_msg(menu_ibmint[4].set_menu_row);
    unpump ();
    /*(select_command (rot_addr_msg);*/
    while (keyboard_status() == -1)
    {
	outportb(UdiMemMapPort,i);
	i <<= 1;
	if(i > 0x80) i = 1;
    }
    delete_running_msg();
}


wtgen_test()
{
    int dummy = UdiSegment;
    print_running_msg(menu_ibmint[2].set_menu_row);
    pump();
    while(keyboard_status() == -1)
    {
#asm
    push    es
    mov     ax,word ptr [UdiSegment_]
    mov     es,ax
    cli
    mov     byte ptr es:[00],00h
    mov     byte ptr es:[00],00h
    mov     al,byte ptr es:[00h]
    mov     al,byte ptr es:[00h]
    sti
    pop     es
#endasm
    }
    unpump();
    delete_running_msg();
}

print_running_msg(row)
{
    msg_pos = row;
    write_window(WND_FUNC_SELECT,row,'C',"Running");
/*
    crt_pos_cursor(row,1,0);
    printf("-->");
*/
}

delete_running_msg()
{
    write_window(WND_FUNC_SELECT,msg_pos,'C',"       ");
/*
    crt_pos_cursor(msg_pos,1,0);
    printf("   ");
*/
}

print_pass_msg()
{
    int row = 1;
    int col = 70;
/*
    crt_pos_cursor(row,col,0);
    printf("PASS");
*/
    print_error_msg("PASS");
}
print_fail_msg()
{
    int row = 1;
    int col = 70;
/*
    crt_pos_cursor(row,col,0);
    printf("FAIL");
*/
    print_error_msg("FAIL");
}

print_error_msg(msg_str,args)
char *msg_str;
int args;
{
    char buffer [80];
    format_string(buffer,msg_str,&args);
    clear_window_line(WND_FUNC_SELECT,18);
    write_window(WND_FUNC_SELECT,18,'C',buffer);
}


ram_test()
{
    unsigned int data;
    unsigned int status;

    status = TRUE;

    half_pump ();
    printf ("  Testing RAM. Please wait...");

    for (data = 0; (status == TRUE) && (data <= 0xff) && (keyboard_status () == -1); data++)
    {
	outportb (FifoCmdPort, 0x80);
	outportb (FifoCmdPort, 0x80);
	outportb (FifoDataPort, FILLRAM);
	outportb (FifoDataPort, data);
	outportb (FifoDataPort, data);
	tic_wait ();

	outportb (FifoCmdPort, 0x80);
	outportb (FifoCmdPort, 0x80);
	outportb (FifoDataPort, VERRAM);
	outportb (FifoDataPort, data);
	outportb (FifoDataPort, data);
	if (tic_wait () == 0)
	{
	    status = FALSE;
	    print_pass_msg();
	    pause ();
	}
	else
	{
	    print_pass_msg();
	    printf ("  Filling with %02x. Verifying...", data);
	}
    }
    unpump ();
    return (status);
}


execute()
{
    int status = TRUE;
    unsigned int pin, ctr;
    unsigned int voltage;

    phys_pin_offset = 0;

    setup_supplies (400, 200, 400, 128);
    print_running_msg(menu_ibmint[7].set_menu_row);

    if(system_info.interface_type > 0 && download_lib ("tic.hex") == 0)
    {
	init_data_segment ();  /* prepare cpu data RAM */

	for (pin = 1; (pin <= 40) && (status == TRUE); pin++)
	{
	    /* set to all 1's */
	    for (ctr = 1; (ctr <= 40) && (status == TRUE); ctr++)
	    {
		set_pin_cnf (ctr, PU_DRIVER_ON);
	    }
	    /* turn on ground driver of a pin */
	    set_pin_cnf (pin, GD_DRIVER_ON);

	    for (ctr = 1; (ctr <= 40) && (status == TRUE); ctr++)
	    {
		if (ctr == pin)
		{
		    if (read_zif_pin (pin) != 0)
		    {
			status = FALSE;
		    }
		}
		else
		{
		    if (read_zif_pin (ctr) == 0)
		    {
			status = FALSE;
		    }
		}
	    }
	}

	/* set to all 0's before the next test */
	for (ctr = 1; (ctr <= 40) && (status == TRUE); ctr++)
	{
	    set_pin_cnf (ctr, PU_DRIVER_ON);
	}

	/* test processor read write */
	for (pin = 1; (pin <= 40) && (status == TRUE); pin++)
	{
	    /* set to all 1's */
	    for (ctr = 1; (ctr <= 40) && (status == TRUE); ctr++)
	    {
		set_pin_cnf_196 (ctr, PU_DRIVER_ON);
	    }
	    /* turn on ground driver of a pin */
	    set_pin_cnf_196 (pin, GD_DRIVER_ON);

	    for (ctr = 1; (ctr <= 40) && (status == TRUE); ctr++)
	    {
		if (ctr == pin)
		{
		    if (read_zif_pin_196 (pin) != 0)
		    {
			status = FALSE;
		    }
		}
		else
		{
		    if (read_zif_pin_196 (ctr) == 0)
		    {
			status = FALSE;
		    }
		}
	    }
	}
    }
    else
    {
	status = FALSE;
    }

    if	(status == TRUE)
    {
	set_pin_cnf (1, SRC_DRIVER_ON);
	set_pin_dac (1, 500);

	voltage = read_pin_voltage (1);
	if ((voltage >= 480) && (voltage <= 520))
	{
	    status = TRUE;
	}
	else
	{
	    status = FALSE;
	}
	set_pin_dac (1, 0);
    }

    if	(status == TRUE)
    {
	set_pin_cnf_196 (1, SRC_DRIVER_ON);
	set_pin_dac_196 (1, 500);

	voltage = cpu_read_pin_voltage (1);
	if ((voltage >= 480) && (voltage <= 520))
	{
	    status = TRUE;
	}
	else
	{
	    status = FALSE;
	}
	set_pin_dac (1, 0);
    }

    setup_supplies (0, 0, 0, 0);
    unpump();
    delete_running_msg();
    if (status == TRUE)
    {
	print_pass_msg();
    }
    else
    {
	print_fail_msg();
    }
    pause ();
}


reg_card_test ()
{
    int status = TRUE;
    unsigned int pin, ctr;
    unsigned int voltage;

    phys_pin_offset = 0;

    setup_supplies (400, 200, 400, 128);
    print_running_msg(menu_ibmint[6].set_menu_row);

    for (pin = 1; (pin <= 40) && (status == TRUE); pin++)
    {
	/* set to all 1's */
	for (ctr = 1; (ctr <= 40) && (status == TRUE); ctr++)
	{
	    set_pin_cnf (ctr, PU_DRIVER_ON);
	}
	/* turn on ground driver of a pin */
	set_pin_cnf (pin, GD_DRIVER_ON);

	for (ctr = 1; (ctr <= 40) && (status == TRUE); ctr++)
	{
	    if (ctr == pin)
	    {
		if (read_zif_pin (pin) != 0)
		{
		    status = FALSE;
		}
	    }
	    else
	    {
		if (read_zif_pin (ctr) == 0)
		{
		    status = FALSE;
		}
	    }
	}
    }

    if	(status == TRUE)
    {
	set_pin_cnf (1, SRC_DRIVER_ON);
	set_pin_dac (1, 500);

	voltage = read_pin_voltage (1);
	if ((voltage >= 480) && (voltage <= 520))
	{
	    status = TRUE;
	}
	else
	{
	    status = FALSE;
	}
	set_pin_dac (1, 0);
    }

    setup_supplies (0, 0, 0, 0);
    unpump();
    delete_running_msg();
    if (status == TRUE)
    {
	print_pass_msg();
    }
    else
    {
	print_fail_msg();
    }
    pause ();
}

set_pin_cnf_196 (pin, cnf)
unsigned int pin;
unsigned int cnf;
{
    load_196_reg (WORD_PARM1, pin);
    load_196_reg (WORD_PARM2, cnf >> 8);
    execute_function (0);
    tic_wait ();
}

set_pin_dac_196 (pin, data)
unsigned int pin;
unsigned int data;
{
    load_196_reg (WORD_PARM1, pin);
    load_196_reg (WORD_PARM2, data);
    execute_function (5);
    tic_wait ();
}

read_zif_pin_196 (pin)
unsigned int pin;
{
    load_196_reg (WORD_PARM1, pin);
    execute_function (1);
    return (tic_wait ());
}


init_data_segment ()
{
    /* load phys_pin_offset */
    load_data_word (phys_pin_offset, FIXED_DATA);
    /* load pin addresses */
    move_data_block (0x8200, FIXED_DATA+2, 48);
    /* load jump table */
    move_data_block (0x8000, JUMP_TABLE, 10);
}

cpu_write_mem (address, data)
unsigned int address;
unsigned int data;
{
    load_196_reg (WORD_PARM1, address);
    load_196_reg (WORD_PARM2, data);
    execute_function (4);
    tic_wait ();
}

cpu_read_mem (address)
unsigned int address;
{
    load_196_reg (WORD_PARM1, address);
    execute_function (3);
    return (tic_wait ());
}


/* This will write a pulse train on pin 1. The wait line on the cpu may */
/*  also be checked (read and write). */
wtgen_test_cpu ()
{
    int status = TRUE;
    phys_pin_offset = 0;

    setup_supplies (400, 200, 400, 128);
    print_running_msg(menu_ibmint[3].set_menu_row);

    if(system_info.interface_type > 0 && download_lib ("tic.hex") == 0)
    {
	init_data_segment ();  /* prepare cpu data RAM */

	while (keyboard_status () == -1)
	{
	    load_196_reg (WORD_PARM1, 1);
	    execute_function (2);
	    tic_wait ();
	}
    }
    else
    {
	print_fail_msg();
	pause ();
    }

    setup_supplies (0, 0, 0, 0);
    unpump();
    delete_running_msg();
}


pc_rd_loop ()
{
    unsigned int get_address ();
    unsigned int address;

    address = get_address ();

    reset_allpro ();
    while (keyboard_status () == -1)
    {
	print_running_msg(trouble_shoot_menu[5].set_menu_row);
	printf ("....Reading %02x at address %04xh", read_mem (address), address);
    }
    unpump ();
    delete_running_msg();
}

pc_wr_loop ()
{
    unsigned int get_address ();
    unsigned char get_data ();
    unsigned int address;
    unsigned char data;

    address = get_address ();
    data = get_data ();

    print_running_msg(trouble_shoot_menu[6].set_menu_row);
    printf ("....Writing %02xh to %04xh", data, address);
    reset_allpro ();
    while (keyboard_status () == -1)
    {
	udi_write_mem (address, data);
    }
    unpump ();
    delete_running_msg();
}

cpu_rd_loop ()
{
    unsigned int get_address ();
    unsigned int address;

    address = get_address ();
    reset_allpro ();
    half_pump ();
    if(download_lib ("tic.hex") == 0)
    {
	init_data_segment ();  /* prepare cpu data RAM */
	while (keyboard_status () == -1)
	{
	    print_running_msg(trouble_shoot_menu[7].set_menu_row);
	    printf ("....Reading %02x at address %04xh", cpu_read_mem (address), address);
	}
    }
    else
    {
	print_fail_msg ();
	pause ();
    }
    unpump();
    delete_running_msg();
}

cpu_wr_loop ()
{
    unsigned int get_address ();
    unsigned int address;
    unsigned char get_data ();
    unsigned char data;

    address = get_address ();
    data = get_data ();
    print_running_msg(trouble_shoot_menu[8].set_menu_row);
    printf ("....Writing %02xh to address %04xh", data, address);
    reset_allpro ();
    half_pump ();
    if(download_lib ("tic.hex") == 0)
    {
	init_data_segment ();  /* prepare cpu data RAM */
	while (keyboard_status () == -1)
	{
	    cpu_write_mem (address, data);
	}
    }
    else
    {
	print_fail_msg ();
	pause ();
    }
    unpump();
    delete_running_msg();
}

io_wr_loop ()
{
    print_running_msg(trouble_shoot_menu[11].set_menu_row);
    while (keyboard_status () == -1)
    {
	pump ();
	unpump ();
    }
    delete_running_msg();
}

unsigned int get_address ()
{
    char str [10];
    unsigned int address;
    write_window (WND_FUNC_LIST, 20, 'L', "       Enter hex address: ");
    gets (str);
    sscanf (str, "%x", &address);
    clear_window_line (WND_FUNC_LIST, 20);
    return (address);
}

unsigned char get_data ()
{
    char str [10];
    unsigned char data;
    write_window (WND_FUNC_LIST, 20, 'L', "       Enter hex data: ");
    gets (str);
    sscanf (str, "%x", &data);
    clear_window_line (WND_FUNC_LIST, 20);
    return (data);
}

read_mem (address)
unsigned int address;
{
#asm
	Push	ES
	Mov	AX,word ptr DS:[UdiSegment_]
	Mov	ES,AX
	Mov	BX,[BP+4]
	Mov	AL,byte ptr ES:[BX]
	Pop	ES
	Xor	AH,AH
#endasm
}

read_io (address)
unsigned int address;
{
#asm
	Mov	DX,[BP+4]
	In	AL,DX
	Xor	AH,AH
#endasm
}

write_io (address, data)
unsigned int address;
unsigned int data;
{
#asm
	Mov	DX,[BP+4]
	Mov	AX,[BP+6]
	Out	DX,AL
#endasm
}

pause ()
{
    while (keyboard_status () == -1){}
}

fifo_rd_loop ()
{
    unsigned int get_address ();
    unsigned int address;

    while (1)
    {
	address = get_address ();
	if ((address == FifoCmdPort) || (address == FifoDataPort))
	{
	    break;
	}
    }

    while (keyboard_status () == -1)
    {
	print_running_msg(trouble_shoot_menu[9].set_menu_row);
	printf ("....Reading %02x at address %04xh", read_io (address), address);
    }
    delete_running_msg();
}

fifo_wr_loop ()
{
    unsigned int get_address ();
    unsigned char get_data ();
    unsigned int address;
    unsigned char data;

    while (1)
    {
	address = get_address ();
	if ((address == FifoCmdPort) || (address == FifoDataPort))
	{
	    break;
	}
    }
    data = get_data ();

    print_running_msg(trouble_shoot_menu[10].set_menu_row);
    printf ("....Writing %02xh to %04xh", data, address);
    while (keyboard_status () == -1)
    {
	write_io (address, data);
    }
    delete_running_msg();
}

card_test ()
{
    print_running_msg(menu_ibmint[1].set_menu_row);
    if (fifo_test () == TRUE)
    {
	print_running_msg(menu_ibmint[1].set_menu_row);
	if (detect_card () == TRUE)
	{
	    print_running_msg(menu_ibmint[1].set_menu_row);
	    ram_test ();
	}
    }
}


cpu_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	 */
    {
	cpu_write_mem (THRESH_HOLD_DAC, approx + guess);	/* set comp drive	 */
	delay_ms (1);
	if (read_zif_pin_196 (pin))				/* was it too low?	 */
	{
	    approx = approx + guess;				/* yes - restore AND add */
	}
    }

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

