⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 amccpci.c

📁 详细介绍了一篇关于pci开发的接口芯片
💻 C
字号:
/*
**
**  File: AMCCPCI.C
**
**  Function: Contains routines necessary for the
**            main AMCCPCI program.  Also contains
**            "library" functions used throughout
**            AMCCPCI program.
**
*/
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <time.h>

#include <conio.h>
#include <io.h>
#include <dos.h>

#include "cxldef.h"
#include "cxlkey.h"
#include "cxlmou.h"
#include "cxlstr.h"
#include "cxlvid.h"
#include "cxlwin.h"

#include "amcc.h"
#include "amccpci.h"

static void initialize(void);
static void open_back_wind(void);
static void open_stat_wind(void);
static void open_titl_wind(void);
static void parse_cmd_line(int, char **);
static void pre_main_menu(void);
static void main_menu(void);
static void pre_help(void);

int n_pci_devs;
struct pci_devices pci_devices[MAX_PCI_DEVICES];
enum device_type current_device_type = UNKNOWN_DEVICE_TYPE;
int cur_pci_dev = -1;

int background_color[] = {
	_BLACK, _BLUE, _GREEN, _CYAN, _RED, _MAGENTA, _BROWN, _LGREY
};

int menu_border_color 		= LCYAN | _BLUE;
int menu_window_color 		= LCYAN | _BLUE;
int menu_selection_color 	= WHITE | _BLACK;   // BLUE  | _CYAN;
int menu_disabled_sel_color	= GREEN | _BLUE;    // LBLUE | _BLUE;
int menu_qsel_color 		= YELLOW| _BLUE;

int submenu_border_color 	= BLUE  | _LGREY;
int submenu_window_color 	= BLUE  | _LGREY;
int submenu_selection_color = LGREY | _BLUE;
int submenu_qsel_color 		= WHITE | _LGREY;

int shadow_color 			= LGREY | _BLACK;

WINDOW title_window, main_menu_window, edit_menu_window;
WINDOW edit_base_menu_window, edit_other_menu_window;

static word supported_device_types[] = {
  0x5920,
  0x5933
};

static char *device_type_strs[] = {
  "PCI S5920",
  "PCI S5935"
};

/*
** Error Message Table
*/
static char *error_text[]= {
	NULL,   							/* errnum =  0, no error	    */
	NULL,   							/* errnum == 1, windowing error */
	"Syntax:  NVBUILD -switches]\n\n"
		"\t -c = CGA snow elimination\n"
		"\t -b = BIOS screen writing\n"
		"\t -m = force monochrome text attributes",
	"Memory allocation error",
	"Too many PCI devices\n"
};

void
display_pci_bus(struct pci_devices *pci, int n_pci)
{
	struct pci_devices *opci;
	int len, ndx, row, max;
	static char buf[256];

	/*
	** Determine the longest string so we can decide on the
	** size of the window.
	*/
	opci = pci;
	for (max = ndx = 0; ndx < n_pci; pci++, ndx++) {
		len = sprint_dev_config(pci, buf, 255);
		max = len > max ? len : max;
	}

	if (!wopen(8, ((80 - max) / 2) + 3, n_pci + 13, max + 3 + 4, 0,
		(LCYAN | _BLUE), (LCYAN | _BLUE)))
			error_exit(1);
	add_shadow();
	wtitle("[ PCI Bus Devices ]", TCENTER, (LCYAN | _BLUE));

	pci = opci;
	for (row = 1, ndx = 0; ndx < n_pci; pci++, ndx++, row++) {
		sprint_dev_config(pci, buf, 255);
		wgotoxy(row, 1);
		cxl_wprintf("%s", buf);
	}

	press_a_key(row + 1);
	wclose();
}

void
main(int argc,char *argv[])
{
	parse_cmd_line(argc, argv);
	initialize();
	n_pci_devs = find_all_pci_devices(pci_devices, MAX_PCI_DEVICES);
	open_back_wind();
	open_stat_wind();
	open_titl_wind();

	display_pci_bus(pci_devices, n_pci_devs);
	main_menu();
	normal_exit();
}

/*
** Parse the command line for valid invocation switches.  If any valid
** switches are found, the appropriate video variable will be set.  If
** any invalid parameters are found, a syntax message is displayed.
*/
static void
parse_cmd_line(int argc, char **argv)
{
	int i, j;
	char *p;

	for (i = 1; i < argc; i++) {
		p = argv[i];
		if (*p == '-' || *p == '/')
		{
			for (j = 1; *(p + j); j++) {
				switch(tolower(*(p + j))) {
					case 'c':
						setvparam(VP_CGA);
						break;
					case 'b':
						setvparam(VP_BIOS);
						break;
					case 'm':
						setvparam(VP_MONO);
						break;
					default:
					  error_exit(2);
				}
			}
		} else
			error_exit(2);
	}
}

static short int *savescrn;
static int crow, ccol;

/*
** Initialize CXL's video, mouse, keyboard, and help systems.
** It also calls all sub-system initialization routines.
*/
static void
initialize(void)
{
	/* initialize the CXL video system and save current screen info */
	videoinit();
	readcur(&crow,&ccol);
	hidecur();
	if ((savescrn = ssave()) == NULL)
		error_exit(3);

	/* attach [Alt-X] to the confirm_quit() function */
	setonkey(0x2d00,confirm_quit,0);

	/* initialize help system, help key = [F1] */
	whelpdef("AMCCPCI.HLP", 0x3b00,
		YELLOW|_RED, YELLOW|_RED, WHITE|_RED, RED|_LGREY, pre_help);

	/* Initialize all sub-systems */
	initialize_nvbuild();
}

/*
** Open the background window.
*/
static void
open_back_wind(void)
{
	wfillch(176);
	if (!wopen(0, 0, 23, 79, 5, 0, LRED | _CYAN))
		error_exit(1);
	wfillch(' ');
}

/*
** Open the status window (last row on screen)
*/
static void
open_stat_wind(void)
{
	wfillch('\260');
	wopen(24, 0, 24, 79, 5, 0, LGREY | _RED);
	wprints( 0, 1, LGREY|_RED, "[F1]=Help");
	wcenters(0, LGREY|_RED, "AMCCPCI v" VERSION_NUMBER_STR);
	wrjusts( 0, 78, LGREY|_RED, "[Alt-X]=Quit");
	wfillch(' ');
}

/*
** Open the title window.
*/
static void
open_titl_wind(void)
{
	if (!(title_window = wopen(1, 12, 6, 67, 0, LRED|_MAGENTA, LRED|_MAGENTA)))
		error_exit(1);
	add_shadow();
	wcenters(0, WHITE|_MAGENTA, "AMCCPCI v" VERSION_NUMBER_STR 
		" (" __DATE__ ")");
	wcenters(1, WHITE|_MAGENTA, "S5920 and S5935 PCI Utility");
	wcenters(3, LCYAN|_MAGENTA, "Copyright (c) 1994-1998 AMCC");
}

static void
s5920_nvbuild_menu(void)
{
	current_device_type = S5920;
	nvbuild_menu();
}

static void
s5933_nvbuild_menu(void)
{
	current_device_type = S5933;
	nvbuild_menu();
}

/*
** Display the main selection menu to determine the sub-system to be used.
*/
static void
main_menu(void)
{
	int row;

	/* push global help category onto help stack, so when   */
	/* [F1] is pressed while selection bar is on an item    */
	/* without help, the global help category will be used. */
	whelpushc(H_GLOBAL);

	/* define and process the main menu */
	wmenubeg(8,20,22,60,0,menu_border_color,menu_window_color,pre_main_menu);

	row = 3;
	wmenuitem(row, 2, "1) S5920 Non-volatile Memory Builder", '1', 1,
		0, s5920_nvbuild_menu ,0, H_NVBUILD);
	row += 2;
	wmenuitem(row, 2, "2) S5935 Non-volatile Memory Builder", '2', 2,
		0, s5933_nvbuild_menu ,0, H_NVBUILD);
	row += 2;
	wmenuitem(row, 2, "3) Exit Program", '3', 3, 0, NULL , 0, 0);

	wmenuend(1, M_VERT, 0, 6, menu_border_color, menu_qsel_color,
			menu_disabled_sel_color, menu_selection_color);
	if (wmenuget() == -1 && _winfo.errno > W_ESCPRESS)
		error_exit(1);

	/* pop the global help category off of the stack, and into the void */
	whelpopc();
}

/*
** This is called during the setup of the main menu.  It is called by
** wmenuget() right after the main menu's window is opened.
*/
static void
pre_main_menu(void)
{
	hidecur();
	add_shadow();
	wtitle("[ Select Main Operation ]", TCENTER, menu_border_color);
	main_menu_window = whandle();
}

/*
** Handles abnormal termination.  If it is passed an error code of 1,
** then it is a windowing system error.  Otherwise the error message is
** looked up in the error message table.
*/
void
error_exit(int errnum)
{
	if (errnum) {
		printf("\n%s\n", errnum == 1 ? werrmsg() : error_text[errnum]);
		exit(errnum);
	}
}

/*
** Handles normal termination.  The original screen and cursor
** coordinates are restored before exiting to DOS with ERRORLEVEL 0.
*/
static void
normal_exit(void)
{
	hidecur();
	srestore(savescrn);
	gotoxy_(crow,ccol);
	showcur();
	exit(0);
}

/*
** Pop open a window and confirms that the user really wants to quit.
** If so, it terminates the program.
*/
static void
confirm_quit(void)
{
	struct _onkey_t *kblist;

	kblist = chgonkey(NULL);  /* hide any existing hot keys */
	if (!wopen(9, 26, 13, 55, 0, WHITE | _BROWN, WHITE | _BROWN))
		error_exit(1);
	add_shadow();
	wputs("\n    Quit, are you sure? \033A\156Y\b");
	clearkeys();
	showcur();
	if (wgetchf("YN", 'Y') == 'Y')
		normal_exit();
	wclose();
	hidecur();
	chgonkey(kblist);       /* restore any hidden hot keys */
}

/*
** Called just prior to displaying the help menu.
*/
static void
pre_help(void)
{
	add_shadow();
	setonkey(0x2d00, confirm_quit, 0);
}

/*
** This will add a shadow to the active window 
*/
void
add_shadow(void)
{
	wshadow(shadow_color);
}

/*
** Checks the input to make sure the user entered a "y" or a "n".
*/
int
check_y_n(char *yes_no_ch)
{
	int ch;

	ch = toupper(*yes_no_ch);
	if (ch == 'Y' || ch == 'N')
		return(0);
	wperror("Press Y for Yes, or N for No", YES);
	return(1);
}

/*
** Display a pause message then pauses for a keypress
*/
void
press_a_key(int wrow)
{
	int attr;

	attr = (BLINK | YELLOW) | ((_winfo.active->wattr >> 4) << 4);
	wcenters(wrow,attr,"Press a key");
	hidecur();
	waitkey();
	wcenters(wrow, attr, "           ");
}

/*
** Displays a generic message to the screen.
*/
void
wdisp_message(char *message)
{
	int msg_length, col, ecol;

	if ((msg_length = strlen(message)) > 76) {
		wperror("wdisp_message length too long", YES);
		error_exit(3);
	}

	col = 37 - msg_length / 2;
	ecol = col + msg_length + 4;
	if (!wopen(11, col, 17, ecol, 0, WHITE | _MAGENTA, WHITE | _MAGENTA))
		error_exit(1);
	wcenters(1, WHITE|_MAGENTA, message);
	press_a_key(3);
	wclose();
}

/*
** Prompt user to select PCI device
*/
int
select_pci_device(void)
{
	int pci_device_index, index, row, col, erow, ecol;
	char *str[MAX_PCI_DEVICES+1];
	struct _wrec_t *wrec;

	erow = 8 + 4 + n_pci_devs;
	if (erow > 23)
		erow = 23;
	if (!wopen(8, 17, erow, 63, 0, menu_border_color, menu_window_color))
		error_exit(1);
	add_shadow();
	wtitle("[ Select PCI Device ]", TCENTER, menu_border_color);

	wcenters(0, menu_window_color, " Bus    Device   Vendor  Base    Sub");
	wcenters(1, menu_window_color, "Number    ID       ID    Class  Class");
	wcenters(2, menu_window_color, "------  ------   ------  -----  -----");
	for (index = 0; index < n_pci_devs; index++) {
		if ((str[index] = malloc(60)) == NULL)
			error_exit(3);
		sprintf(str[index], "%2.2xh    %4.4xh    %4.4xh    %2.2xh    "
			"%2.2xh", pci_devices[index].bus, pci_devices[index].device_id,
				pci_devices[index].vendor_id, pci_devices[index].base_class,
					pci_devices[index].sub_class);

	}
	str[n_pci_devs] = NULL;
	wrec = wfindrec(whandle());
	row = wrec->srow + 4;
	erow = wrec->erow - 1;
	if (erow == 22) {
		erow--;
		wgotoxy(13, 18);
		cxl_wprintf("More %c", 0x19);
	}
	col = wrec->scol + 1;
	ecol = wrec->ecol - 1;
	pci_device_index = wpickstr(row, col, erow, ecol, 5, menu_border_color,
			menu_window_color, menu_selection_color, str,
				cur_pci_dev, NULL);
	if (pci_device_index == -1)
	{
		if (_winfo.errno > W_ESCPRESS)
			error_exit(1);
		goto ErrorOccurred;
	}
	cur_pci_dev = pci_device_index;

	for (index = 0; index < n_pci_devs; index++) {
		free(str[index]);
		str[index] = NULL;
	}
	wclose();
	return(OK);

ErrorOccurred:
	wclose();
	return(ERROR_OCCURRED);
}

/*
** MAP_MEMORY_ADDRESS
**
** Take a memory address and form a segment and offset.  If the memory
** address is a real-mode address, use segment 0x34, which is already
** allocated by Pharlap.  If a protected mode address, must allocate a new
** segment in the LDT and map the physical page into that segment.
*/
int
map_memory_address(dword mem_addr, word *segment, dword *offset)
{
	struct _SREGS sregs;   /* processor segment registers for intdosx call */
	union _REGS regs;      /* processor registers for intdos(x) calls */
	dword base;            /* PM base address (must be 4K boundary) */

	/* Determine if mem_addr is a Protected Mode Address */
	if (mem_addr > (0xfffffL - CONF_SPACE_SIZE + 1)) {

		/* Allocate Segment in LDT */
		regs.d.eax = 0x4800;
		regs.d.ebx = 0;
		_intdos(&regs, &regs);
		if (regs.x.cflag & CARRY_FLAG) {
			wperror("Unable to allocate segment in LDT", YES);
			return(ERROR_OCCURRED);
		}
		*segment = regs.w.ax;		/* Segment selector returned from call */

		/*
		** Compute base & offset
		*/
		*offset = (mem_addr - (mem_addr / (4*1024) * (4*1024)));
		base = mem_addr - *offset;

		/* Map physical page into segment */
		sregs.es = *segment;
		_asm mov sregs.cs,cs
		_asm mov sregs.ds,ds
		_asm mov sregs.ss,ss
		regs.d.ebx = base;			/* Phys addr to map */
		regs.d.ecx = 1;    			/* Map 1 segment */
		regs.d.eax = 0x250a;		/* Map Physical Memory at End of Segment */
		_intdosx(&regs, &regs, &sregs);
		if (regs.x.cflag & CARRY_FLAG) {
			wperror("DPMI Server does not allow needed function (Map Phys)",
				YES);
			deallocate_segment(*segment);
			return(ERROR_OCCURRED);
		}
		return(OK);
	}

	/*
	** Real Mode Address
	*/
	*offset = mem_addr;
	*segment = SS_DOSMEM;		/* Pharlap Real Memory segment selector */
	return(OK);
}

/****************************************************************************/
/*                                                                          */
/* DEALLOCATE_SEGMENT                                                       */
/*                                                                          */
/* Delete an LDT segment selector that was allocated by map_memory_address, */
/* unless the address was a real-mode address ( < 1MB).                     */
/*                                                                          */
/****************************************************************************/
void
deallocate_segment(word segment)
{
	union _REGS regs;
	struct _SREGS sregs;

	if (segment != SS_DOSMEM) {
		/* Deallocate segment previously allocated */
		regs.h.ah = 0x49;
		sregs.es = segment;
		_asm mov sregs.cs,cs
		_asm mov sregs.ds,ds
		_asm mov sregs.ss,ss
		_intdosx(&regs, &regs, &sregs);
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -