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

📄 tsip_utl.c

📁 gps开发专用的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * *************************************************************************
 *
 * Trimble Navigation, Ltd.
 * OEM Products Development Group
 * P.O. Box 3642
 * 645 North Mary Avenue
 * Sunnyvale, California 94088-3642
 *
 * Corporate Headquarter:
 *    Telephone:  (408) 481-8000
 *    Fax:        (408) 481-6005
 *
 * Technical Support Center:
 *    Telephone:  (800) 767-4822	(U.S. and Canada)
 *                (408) 481-6940    (outside U.S. and Canada)
 *    Fax:        (408) 481-6020
 *    BBS:        (408) 481-7800
 *    e-mail:     trimble_support@trimble.com
 *
 * *************************************************************************
 *
 * Vers		Date		   Changes									 Author
 * ----		---------   ----------------------------------------	----------
 * 1.1		16 Jun 93	Initial version								 pvwl
 * 1.12		14 Feb 94	Revisions      								 pvwl
 * 1.12a	   31 Mar 94	Added cts display window				pvwl
 * 1.20      5 Jun 95   Revisions: timezone                         ahl
 *          26 Jul 95   Communications above 9600 bps
 *          28 Aug 95   Revision: ask_byte() for maxage
 *
 * *************************************************************************
 *
 * TSIP_UTL.C contains five types of functions:
 * 
 * 1) Borland-compatible window control functions:  The Borland version of
 * TSIPCHAT supports two windows: a command and report window and an auto
 * window.  The command and report window displays the command list, command
 * entries and parameters, and display of requested packets.  The auto window
 * scrolls through unrequested reports, which are generated according to the
 * I/O options specified.
 *
 * The following are Borland C++ functions used to create text windows.  If
 * suitable functions can be found in the Microsoft Visual C++ Compiler, the
 * windowing feaures may be recreated. (Creating TSIPCHAT without BORLAND
 * defined results in all commands, both auto and requested, scrolling up the
 * screen.)
 *
 *    ;; create a window
 *    void window (short left, short top, short right, short bottom) 
 *
 *    ;; set backgrounf and foreground colors
 *    void textattr (char attr)
 *
 *    ;; go to row x, colw y w.r.t window origin
 *    void gotoxy (short x, short y)
 *
 *    ;; report row relative to window origin
 *    short wherex (void)
 *
 *    ;; report column relative to window origin
 *    short wherey (void)
 *
 *    ;; clear window to the end of the line
 *    void clrscr (void), clreol (void)
 *
 *    ;; get text attributes
 *    void gettextinfo (struct *textinfo)
 *
 * 2) User interface functions:  Specifically, these are functions that query
 * integer, double, or YES/NO inputs.  There is also a function for toggling
 * file storage on and off.
 *
 * 3) Storage file functions:  These functions open and close binary
 * storage files.
 *
 * 4) DOS-specific time functions:  These functions synchronize the receiver
 * and PC clocks.
 *
 * 5) Serial port functions:  These functions send, receive, and set
 * parameters.  They are DOS-specific.
 *
 * *************************************************************************
 *
 */

#define END_STRING '\0'
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <ctype.h>
#include <dos.h>
#include <time.h>
#include "tsip_ifc.h"
#include "tsipincl.h"

const short days_in_year[32] =
{
	361, 365, 365, 365, 366, 365, 365, 365,			/* 1980-1987 */
	366, 365, 365, 365, 366, 365, 365, 365,			/* 1988-1995 */
	366, 365, 365, 365, 366, 365, 365, 365,			/* 1996-2003 */
	366, 365, 365, 365, 366, 365, 365, 365			/* 2004-2011 */
};
	/*
		Note:	1980 is short because GPS time starts midnight 1/6/1980.
				2000 IS a leap year.
	*/

const unsigned char leap_year[32] =
{
	1, 0, 0, 0, 1, 0, 0, 0,  
	1, 0, 0, 0, 1, 0, 0, 0,  
	1, 0, 0, 0, 1, 0, 0, 0,
	1, 0, 0, 0, 1, 0, 0, 0
};

const char days_in_month[2][12] =
{
	{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
	{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};

/**/
/*  *******************  1. CONSOLE WINDOW CONTROL ****************** */
/*
 * The following routines set up two windows: one which prints only
 * commands and requested reports, the other only unrequested reports.
 * The routines are set up for Borland compilers.  Similar functions can
 * be found with Microsoft compilers.  Generic versions are included
 * for non-Borland compilers.
 */

/* backspace, enter, printable characters except control characters */
#include <conio.h>
#define MENUWIN 2

/* text attributes for different screen functions */
static short
	auto_y,
	text_color[3];
static struct text_info
	t_info,
	w_info[2];

/* current window = command or requested reply, or auto report */
/* TRUE if current window is command window */
static short
	curr_win = AUTOWIN;

void show_crlf (void)
{
	clreol ();
	xprintf ("\r\n");
	clreol ();
}

short which_window (void)
{
	return (curr_win);
}

void switch_window (short new_win)
{
	struct text_info *old_info, *new_info;

	old_info = &w_info[curr_win];
	gettextinfo (old_info);
	if (new_win == curr_win) {
		return;
	}
	curr_win = new_win;
	new_info = &w_info[curr_win];

	switch (new_win) {
	case AUTOWIN:
		/* auto window is the bottom of the screen; unrequested reports */
		/* are printed here in scrolled mode */
		window (1, old_info->cury + 1, 80, 24);

		textattr (text_color[new_win]);
		/* start at bottom of auto window and scroll */
		gotoxy (80, auto_y - (old_info->cury + 1));
		break;

	case CMDWIN:
		/* cmd window is the top of the screen; commands and requested  */
		/* reports are printed in scrolled mode in blue or reverse text */

		/* autowin absolute line coordinate */
		auto_y = old_info->cury + old_info->wintop;

		window (1, 1, 80, 24);
		textattr (text_color[new_win]);
		gotoxy (new_info->curx, new_info->cury);
		clreol ();
	  break;
	}
}

void new_cmd_window (void)
{
	/* blank out old command window */
	if (curr_win == AUTOWIN) {
		gettextinfo (&w_info[curr_win]);
		auto_y = w_info[curr_win].cury + w_info[curr_win].wintop;
	}
	textattr (text_color[AUTOWIN]);
	if (w_info[CMDWIN].cury > 1) {
		window (1, 2, 80, w_info[CMDWIN].cury);
		clrscr ();
	}
	w_info[CMDWIN].cury = 1;
	w_info[CMDWIN].curx = 1;

	/* perch in the auto window at the last location */
	curr_win = AUTOWIN;
	window (1, 2, 80, 24);
	gotoxy (80, auto_y - 2);

	switch_window (CMDWIN);
	clreol ();
	highvideo ();
	textbackground (BANNER_BACKGROUND);
	textcolor (BANNER_TEXT);
	xprintf (
		"       TSIPCHAT %s(%s)    Use <Esc> to Exit; Use '?' for Help Screen",
		TSIPCHAT_VERNUM, TSIP_VERNUM);
	clreol ();
	normvideo ();
	textcolor (LIGHTGRAY);
	textbackground (BLUE);
	gotoxy (1, 1);
}

void clr_cmd_window (short mode)
{
	short
		i;
	static short
		endline;
	switch_window (CMDWIN);
	if (mode) {
		for (i = w_info[CMDWIN].cury + 1; i <= endline; i++) {
			gotoxy (1, i);
			clreol ();
		}
	} else {
		endline = w_info[CMDWIN].cury;
		for (i = 1; i <= endline; i++) {
			gotoxy (1,i);
			clreol ();
		}
		gotoxy (1, 1);
		highvideo ();
		textbackground (BANNER_BACKGROUND);
		textcolor (BANNER_TEXT);
		xprintf (
			"            TSIPCHAT %s:%s     Use <CR> to Return to Normal Mode",
			TSIPCHAT_VERNUM, TSIP_VERNUM);
		clreol (); show_crlf ();
		normvideo ();
		textcolor (LIGHTGRAY);
		textbackground (BLUE);
	}
	switch_window (AUTOWIN);
}

void start_menu_window (void)
{
	textattr (text_color[MENUWIN]);
}

void end_menu_window (void)
{
	textattr (text_color[CMDWIN]);
}

void initialize_screen (void)
{
	/* get initial text attributes and save for restore before exit. */
	gettextinfo (&t_info);
	clrscr();
	text_color[AUTOWIN] = LIGHTGRAY + (BLACK << 4);
	text_color[CMDWIN]  = LIGHTGRAY + (BLUE  << 4);
	text_color[MENUWIN] = LIGHTGRAY + (BLUE  << 4);
	w_info[CMDWIN].cury = 1;
	w_info[CMDWIN].curx = 1;

	/* start in auto window */
	textattr (text_color[AUTOWIN]);
	clrscr ();
	gotoxy (1, 25);
}

void reset_screen (void)
{
	window (1,1,80,25);
	/* return text to original */
	textattr (t_info.normattr);
	gotoxy (80, 25);
	show_crlf ();
   clrscr();
}

/**/
/* ****************** 2. USER INPUT PROMPTS ********************* */
/* 
 * Prompt functions: allows user to supply a character string in response 
 * to a prompt.
 */

/* These routines are to set cmdesc (TRUE = abort command).
 * Used in TSIP_CMD.C.
 */
static short cmd_abort = FALSE;

short cmd_esc (void)
{
   return cmd_abort;
}

void set_cmd_esc (short x)
{
   cmd_abort = x;
}

/* Common prompt escape sequence. */
static short esc_out (char c) {
	short cmdesc;
	/* backspace, <CR>, printable characters except control characters */
	cmdesc = (c != 0x08) && (c != 0x0D) && (!isprint (c) || iscntrl (c));
	set_cmd_esc (cmdesc);
	return cmdesc;
}

static short get_prompt_string (char kbbuf[], short maxi)
{
	char kbch;
	short i;
	
	i = 0;
	for (i = 0; i < maxi; ) {
		kbch = read_rpts_wait_for_kbhit ();
		if (kbch == 0x08) {		      /* backspace */
			xprintf ("%c", kbch);
			if (i) i--;
		} else if (kbch == 0x0D) {    /* <CR> */
			break;
		} else if (esc_out(kbch)) {
			i = 0;
			break;
		} else {
			xprintf ("%c", kbch);
			kbbuf[i] = kbch;
			i++;
		}
	}
	/* terminate string */
	kbbuf[i] = END_STRING;
	show_crlf();
	set_cmd_esc (!i);
	return i;
}

/* prompt for an integer from user */
short ask_byte (char *prompt)
{
	short	n;
	char kbbuf[30];

   n = 0;
	clreol ();
	xprintf (prompt);
	if (get_prompt_string (kbbuf, 30)) {
		set_cmd_esc (sscanf (kbbuf, "%d", &n) < 1);
	}
	return n;
}

/* prompt for a choice from among nine or fewer */
short pick_one (char *prompt, char *code_txt[], short nopts)
{
	short i, j, kbch;

	set_cmd_esc (FALSE);
	/* cycle through a series of choices & allow user to choose one. */
	/* Routine returns numerical value corresponding to choice. */
	xprintf ("%s(<Space> cycle, <CR> select, ^Z abort)", prompt);
	kbch = read_rpts_wait_for_kbhit ();
	clreol ();
	if (esc_out(kbch)) {
		return 0;
	}
	/* direct choice by digit (0..9) */
	j = (kbch - '0');
	i = 0;
	if ((j < nopts) && (j >= 0)) {
      if (code_txt[j][0] != END_STRING) {
         i = j;
      }
   }
   xprintf ("\r%s                                      ", prompt);
	for ( ; ; i++) {

		xprintf ("\r%s", prompt);
		if (i >= nopts) i -= nopts;
		/* skip choices with null character string */
		if (code_txt[i][0] == END_STRING) continue;

      highvideo ();
		xprintf ("%s (%d)", code_txt[i], i);
		lowvideo ();
		clreol ();

		for ( ; ; ) {  /* wait for <CR> or <space> or digit selection */
			kbch = read_rpts_wait_for_kbhit ();
			if (kbch == 0x0D) {  /* <CR>: choice is made */
				show_crlf ();
				return i;
			} else if (kbch == 0x20) { /* <Space>: drops out to new choice */
				break;
			} else if (esc_out(kbch)) {
				show_crlf();
				return 0;
			} else {
				j = (kbch - '0');
				if ((j < nopts) && (j >= 0)) {
					if (code_txt[j][0] != END_STRING) {
						/* direct choice by digit (0..9); offset at top of loop */
						i = j - 1;
						break;
					}
				}
			}
		}
	}
}

/* prompt user to enter an double */
double ask_dbl (char *prompt)
{
	double d = 0.0;
	char kbbuf[30];

	clreol ();
	xprintf (prompt);
	if (get_prompt_string (kbbuf, 30)) {
		set_cmd_esc (sscanf (kbbuf, "%lf", &d) < 1);
	}
	return d;
}

/* ask user for up to 4 hex codes */
unsigned char ask_hex_string (char *prompt, unsigned char *h)
{
	char kbbuf [30];

	clreol ();
	xprintf (prompt);
	if (get_prompt_string (kbbuf, 30)) {
		if (6==sscanf(kbbuf,"%2x %2x %2x %2x %2x %2x",
			&h[0],&h[1],&h[2],&h[3],&h[4],&h[5])) return 6;
		if (5==sscanf(kbbuf,"%2x %2x %2x %2x %2x",
			&h[0],&h[1],&h[2],&h[3],&h[4])) return 5;
		if (4==sscanf(kbbuf,"%2x %2x %2x %2x",
			&h[0],&h[1],&h[2],&h[3])) return 4;
		if (3==sscanf(kbbuf,"%2x %2x %2x",
			&h[0],&h[1],&h[2])) return 3;
		if (2==sscanf(kbbuf,"%2x %2x",
			&h[0],&h[1])) return 2;
		if (1==sscanf(kbbuf,"%2x",&h[0])) return 1;
		set_cmd_esc (TRUE);
	}
	return 0;
}


/* prompt user to verify choice with a 'Y' or 'y' */
short ask_verify (void)
{
	unsigned char kbch;
	short affirm;

	xprintf (" (Y/N) ");
	kbch = read_rpts_wait_for_kbhit ();
	if (esc_out(kbch)) return FALSE;
	affirm = ((kbch == 'Y') || (kbch == 'y'));
	xprintf (affirm ? "YES" : "NO");
	show_crlf ();
	return affirm;
}

short ask_verify_nocmdcrlf (void)
{
	unsigned char kbch;
	short affirm;

	xprintf (" (Y/N) ");
	kbch = read_rpts_wait_for_kbhit ();
	if (esc_out(kbch)) return FALSE;
	affirm = ((kbch == 'Y') || (kbch == 'y'));
	xprintf (affirm ? "YES" : "NO");
	return affirm;
}

/**/
/* ********************  3. TIMING ROUTINES *********************** */

/* logical indicating desire to set time */
static double
	timezone_hrs = -24.0;		/* timezone offset, hours; nonsense value to start */
static short
	timezone_set = FALSE;
const short days_of_month [12] = {
		  0,  31,  59,  90, 120, 151,
		181, 212, 243, 273, 304, 334};

double raw_PC_time (void)
{
	/*
	** Note: Borland routines have a timezone implicit in them, most often
	** -5 hours.  We use DOS access directly so this does not screw us up.
	*/
	union REGS
		regs;
	double
		day, year,
		gpsday,
		hour, minute, second;
	short
		month;

	regs.h.ah = 0x2A;	/*  get date from DOS  */
	intdos (&regs, &regs);
	year = regs.x.cx;			/*  year  */
	month = regs.h.dh;		/*  month  */
	day = regs.h.dl;			/*  day  */
	gpsday = day + days_of_month[month - 1] + (year - 1980) * 365 - 6;
	/* leap years - add one for every fourth previous February */
	gpsday += (short)(12*(year-1976)+month-3)/48;

	regs.h.ah = 0x2C;			/*  get time from DOS  */
	intdos (&regs, &regs);
	hour = regs.h.ch;			/*  hours  */
	minute = regs.h.cl;		/*  minutes  */
	second = regs.h.dh;		/*  seconds  */
	return (second + 60. * (minute + 60. * (hour + 24. * gpsday)));
}

short set_raw_PC_time (double gpstime)
{
	long	days;
	short		days_this_month, years, months;
	union REGS
		regs;
	short
		hour, minute, second,
		year, month, day;

//=========================
	days = (long)(gpstime / 86400.);

	/* determine elapsed years since start of GPS */
	years = 0;
	while(TRUE)
	{
		if(days < days_in_year[years])
			break;
		days -= days_in_year[years];
		years++;
	}
	year = 1980 + years;

	/* determine elapsed months since start of year */
	months = 0;
	while (TRUE)
	{
		if (leap_year[years])

⌨️ 快捷键说明

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