head 4.4; access ; symbols ; locks oasisa:4.4; strict; comment @ * @; 4.4 date 2001.06.19.12.16.15; author oasisa; state Exp; branches ; next ; desc @New Repository; 6/19/2001 (klh) @ 4.4 log @New Repository; 6/19/2001 (klh) @ text @/****************************************************************************/ /* Copyright 1991-4 MBARI */ /****************************************************************************/ /* $Header: usrcmds.c,v 1.1 2001/06/19 11:45:12 oasisa Exp $ */ /* Summary : User Interface Commands for OASIS Mooring Controller */ /* Filename : usrcmds.c */ /* Author : Robert Herlien (rah) */ /* Project : OASIS Mooring */ /* $Revision: 1.1 $ */ /* Created : 02/15/91 */ /* */ /* MBARI provides this documentation and code "as is", with no warranty, */ /* express or implied, of its quality or consistency. It is provided without*/ /* support and without obligation on the part of the Monterey Bay Aquarium */ /* Research Institute to assist in its use, correction, modification, or */ /* enhancement. This information should not be published or distributed to */ /* third parties without specific written permission from MBARI. */ /* */ /****************************************************************************/ /* Modification History: */ /* 15feb91 rah - created */ /* $Log: usrcmds.c,v $ * Revision 1.1 2001/06/19 11:45:12 11:45:12 oasisa (Oasis users) * Initial revision * * Revision 4.3 99/06/16 10:21:39 10:21:39 bobh (Bob Herlien) * Mar/May '99 Deployments of M3/M2 * * Revision 4.2 98/09/09 10:48:08 10:48:08 bobh (Bob Herlien) * Sept/Oct '98 deployments of M1, Eqpac 1 & 2 * * Revision 4.1 98/05/12 09:35:15 09:35:15 bobh (Bob Herlien) * June '98 turnaround for EqPac * * Revision 3.9 97/10/28 13:59:57 13:59:57 bobh (Bob Herlien) * EqPac Deployment of Nov 1997 * * Revision 3.8 97/09/12 10:51:03 10:51:03 bobh (Bob Herlien) * Redeploy M1 * * Revision 3.7 97/07/23 11:18:22 11:18:22 bobh (Bob Herlien) * July '97 M1 deployment, new shutter code * * Revision 3.6 96/10/30 14:00:26 14:00:26 bobh (Bob Herlien) * Release for EqPac, M2 Test Replacement * * Revision 3.5 96/07/17 13:20:18 13:20:18 bobh (Bob Herlien) * July '96 deployment of M2 with ARGOS code * * Revision 3.4 96/06/18 19:09:32 19:09:32 bobh (Bob Herlien) * June '96 deployment of M1 * * Revision 3.3 95/04/13 13:47:05 13:47:05 hebo (Bob Herlien) * Drifter Deployment for Coop (flip) cruise * * Revision 3.2 95/04/11 14:03:34 14:03:34 hebo (Bob Herlien) * Drifter Deployment on IronEx * * Revision 3.1 95/03/09 19:31:06 19:31:06 hebo (Bob Herlien) * March '95 Deployment of M1A * * Revision 3.0 95/02/21 18:42:51 18:42:51 hebo (Bob Herlien) * February '95 Deployment * * Revision 2.6 94/09/16 14:35:08 14:35:08 hebo (Bob Herlien) * Change CTD to use "TS" for opto-isolated CTD interface * * Revision 2.5 94/01/11 17:42:39 17:42:39 hebo (Bob Herlien) * Fixed bug in "getlog", changed PRR format * * Revision 2.4 93/10/29 11:12:49 11:12:49 hebo (Bob Herlien) * November 1993 Deployment * * Revision 2.1 93/01/08 10:43:25 10:43:25 hebo (Bob Herlien) * Fixed bug with 24 hr radio silence. M2 swap due to failed electronics. * * Revision 2.0 92/08/22 18:54:35 18:54:35 hebo (Bob Herlien 408-647-3748) * August 1992 Deployment * * Revision 1.3 92/03/03 16:41:33 16:41:33 hebo (Bob Herlien 408-647-3748) * New defaults, restart check, perm power stuff, analog command * */ /****************************************************************************/ #include /* MBARI type definitions */ #include /* MBARI constants */ #include /* OASIS controller definitions */ #include /* OASIS I/O definitions */ #include /* OASIS task dispatcher */ #include /* PWR_PERM definition */ #include <80c196.h> /* 80196 Register mapping */ #include /* Standard I/O */ #include /* String library functions */ #include /* Standard ctype.h defs */ #define CONNECT_RING 1024 /* 1K Buffer each direction for con */ #define RESET_DELAY 10 /* Dflt delay to startup after reset*/ typedef struct /************************************/ { /* Param - User Parameter STRUCT */ char *pt_name; /* Name of parameter */ Int16 *pt_parm; /* Pointer to parameter */ Int16 pt_dflt; /* Default value */ Word pt_flags; /* Flags, see below */ char *pt_help; /* Help string for parameter */ } Param; /************************************/ #define PARM_HEX 1 /* Show in hex format */ #define PARM_INVISIBLE 2 /* Don't show to user */ typedef struct /************************************/ { /* StringParm - User String Parameter*/ char *sp_name; /* Name of parameter */ char **sp_parm; /* Pointer to string ptr */ char *sp_dflt; /* Default value */ } StringParm; /************************************/ /********************************/ /* External Functions */ /********************************/ Extern Void bankCopy( Nat16 bank, const Byte *src, Byte *dst, Nat16 len ); Extern Int16 ser_getc( Nat16 port ); Extern MBool ser_putc( Nat16 port, Byte c ); Extern Void ser_break( Nat16 port, Int16 count ); Extern Void ser_init( Nat16 port, Nat16 mode ); Extern Void xputc( Int16 c ); Extern Void xputs( const char *s ); Extern Void xprintf( const char *format, ... ); Extern Void newline(); Extern Int16 xgetc_tmout( Nat16 tmout ); Extern Int16 xgets_tmout( char *s, Int16 len, Nat16 tmout ); Extern Int16 xgetn_tmout( char *s, Int16 len, Nat16 tmout ); Extern Void xflush_ser( Nat16 tmout ); Extern MBool getnum( char **s, Int16 *result, Nat16 radix ); Extern char *find_str( char *src, char *tgt ); Extern Void drv_ser_port( Driver *dp ); Extern Void drv_ser_release( Driver *dp ); Extern Void drv_pwroff( Driver *dp ); Extern Driver *drvr_find( char *name ); Extern Void drvr_timechange( Int32 diff ); Extern Void get_analog( Nat16 port, Nat16 nports, Nat16 samples, Nat16 *result ); Extern MBool clk_read( Void ); Extern Void clk_write( DateTime *dtp ); Extern Void logColdInit(Void); /* Cold init of log routines */ Extern char *cmp_ulc( char *s, char *cs ); Extern Void tnc_converse( Void ); Extern Void bcopy( const Byte *src, Byte *dst, Nat16 len ); Extern char *permMalloc( Nat16 size ); Extern Void permFree( char *ptr ); Extern Nat16 chkProgRam( Void ); Extern char *tmpMalloc( Nat16 size ); Extern Void tmpFree( char *ptr ); Extern Int16 ser_sndsts( Nat16 port ); Extern Void xdrain_ser( Nat16 tmout ); /* Drain serial output */ Extern Void ring_init( Ring *ring_ptr, Byte *buffer, Nat16 size ); Extern Void io_power( Word pwrbits ); Extern Void io_term(Void); /* Power down I/O module */ Extern Void clk_alarm(Nat16 altime); /* Set RTC alarm */ Extern Void clk_pwrdown(Void); /* Power down */ /********************************/ /* External Data */ /********************************/ Extern Nat16 progRamChksum; /* Checksum on program RAM */ Extern Nat16 sys_init; /* Set to MAGIC at system init */ Extern Reg Nat16 port; /* Dflt ser port, saved by dispatch */ Extern Reg Word sermode; /* Serial mode (see ser_init()) */ /* Port and sermode are special variables: they get saved/restored */ /* during task swap, so they're always valid */ Extern Semaphore ser_sem[NSER_PORTS]; /* Mutex sems for ser ports */ Extern Reg Word error; /* Error vector */ Extern Nat16 pwr_perm; /* Devices to leave powered on */ Extern Nat16 iopwrbits; /* Power bit vector */ Extern const Nat16 free_mem; /* Start of free memory */ Extern const Nat16 mem_size; /* Free memory size */ Extern Reg TimeOfDay tod; /* Current time in TimeOfDay format */ Extern Reg DateTime dttm; /* Current date & time in DateTime */ Extern MBool send_ascii; /* TRUE to send samples in ASCII */ Extern Nat16 tmpRamStart; /* Start of tmpMalloc RAM */ Extern Nat16 tmpRamLen; /* Length of tmpMalloc RAM */ Extern Ring tx_ring[NSER_PORTS]; /* Serial IO transmit data structs */ #ifdef YMODEM Extern Nat16 ymodemFileNum; /* Number part of file name */ #endif #ifdef GPS_TYPE /* GPS support variables */ #if ( (GPS_TYPE == 10) || (GPS_TYPE == 12) ) /* Full-feature GPS driver */ Extern Int16 gpsInitLat; /* Initial GPS latitude */ Extern Int16 gpsInitLong; /* Initial GPS longitude */ Extern Int16 gpsInitAlt; /* Initial GPS altitude */ Extern Int16 gpsElMask; /* GPS elevation mask */ Extern Int16 gpsVelAvg; /* GPS velocity averaging time */ #endif /* End 10 channel, full feature */ #if ((GPS_TYPE == 9) || (GPS_TYPE == 10)) /* Magellan 10 channel board */ Extern Int16 gpsAlmanacAge; /* GPS almanac age */ #endif /* End 10 channel */ #endif /* End GPS */ /********************************/ /* Global Data */ /********************************/ Global Int16 con_dsc; /* Disconnect character for CONNECT */ Global Nat16 con_tmout; /* Timeout during CONNECT */ Global Nat16 radio_tmout; /* Timeout for radio reset */ Global Nat16 sync_tmout; /* Timeout for drvSync */ Global Nat16 xoff_tmout; /* Timeout for xoff */ Global Nat16 logStatus; /* Log on power up/down */ Global Int16 gmtOffset; /* Local offset from GMT */ Global char *adcp_dstr; /* Discon string for adcp */ Global char *pco2_cmd; /* Command string for pCO2 */ #ifdef CALCO2 Global char *co2_cal0; /* Set Cal string for pCO2 */ Global char *co2_cal1; Global char *co2_cal2; Global char *co2_cal3; Global char *co2_cal4; #endif Global char *tnc_name; /* TNC node name */ Global Byte patch_data[256]; /* Rsvd for data reqd by patches */ #ifdef TNC Global Int16 tncchr; /* TNC command character */ Global MBool tnc_connected; /* TRUE if we're connected to TNC */ #endif /********************************/ /* Module Local Data */ /********************************/ MLocal Reg Nat16 dbank; /* Bank to display/set */ MLocal Reg Byte *dispnext; /* Where to display memory next */ MLocal Int16 brkchr; /* Character that sends break */ const Param parmtbl[] = { {"DISCHR", &con_dsc, 4, PARM_HEX, "DISCONNECT char"}, {"BRKCHR", &brkchr, 2, PARM_HEX, "BREAK char"}, {"con_tmout", (Int16 *)&con_tmout, 180, 0, "CONNECT Timeout (secs)"}, #ifdef TNC {"TNCCHR", &tncchr, 3, PARM_HEX, "TNC command char"}, #endif #ifdef RADIO {"radio_tmout", (Int16 *)&radio_tmout, DFLT_RADIO_TMOUT, 0, #ifndef REDUCE_STRINGS "Hours of radio silence before reset"}, #else ""}, #endif #endif {"PwrPerm", (Int16 *)&pwr_perm, PWR_PERM, PARM_HEX, "Devices permanently powered"}, {"ASCII", (Int16 *)(&send_ascii), 0, 0, "0 sends binary, 1 ASCII"}, {"xoff_tmout", (Int16 *)&xoff_tmout, DFLT_XOFF_TMOUT, 0, ""}, {"sync_tmout", (Int16 *)&sync_tmout, DFLT_SYNC_TMOUT, 0, #ifndef REDUCE_STRINGS "Seconds to wait for drvr sync"}, #else ""}, #endif #ifdef LOCAL_OFFSET {"gmtOffset", &gmtOffset, LOCAL_OFFSET, 0, "Offset from GMT"}, #endif #ifdef LOG_STATUS {"logStatus", (Int16 *)&logStatus, LOG_STATUS, PARM_HEX, "Log pwr up/down"}, #endif #ifdef YMODEM {"fileNum", (Int16 *)&ymodemFileNum, 0, 0, ""}, #endif #ifdef GPS_TYPE #if ( (GPS_TYPE == 10) || (GPS_TYPE == 12) ) /* Full feature Magellan 10 channel or Garmin 12 ch*/ {"gpsLat", &gpsInitLat, GPS_LAT, 0, "Init GPS Latitude (dddmm)"}, {"gpsLong", &gpsInitLong, GPS_LONG, 0, "Init GPS Longitude (dddmm)"}, {"gpsAlt", &gpsInitAlt, GPS_ALT, 0, "Init GPS Altitude (meters)"}, {"gpsVelAvg", &gpsVelAvg, 60, 0, "GPS Velocity averaging time (secs)"}, #endif #if ( GPS_TYPE == 10 ) /* Magellan 10 channel board */ {"gpsElMask", &gpsElMask, 10, 0, "GPS Elevation mask (degrees)"}, #endif #if ( (GPS_TYPE == 9) || (GPS_TYPE == 10) ) /* Magellan 10 channel board */ {"gpsAlmanacAge", &gpsAlmanacAge, 10000, 0, #ifndef REDUCE_STRINGS "Age of GPS almanac (weeks)"}, #else ""}, #endif /* REDUCE_STRINGS */ #endif /* GPS_TYPE == 9 | 10 */ #endif /* GPS_TYPE */ {"error", (Int16 *)&error, 0, PARM_HEX, "OASIS error vector"}, #ifdef DATA_PARM {"data", (Int16 *)&tmpRamStart, TEMP_RAM, PARM_HEX, "Start of malloc space"}, {"datalen", (Int16 *)&tmpRamLen, TEMP_RAM_SIZE, PARM_HEX, "Length of malloc space"} #endif }; const StringParm stringtbl[] = { #ifdef TNC {"TNC", &tnc_name, TNC_NAME}, #endif #ifdef ADCP_TYPE {"ADCP", &adcp_dstr, "S255"}, #endif {"pCO2", &pco2_cmd, "*1323,21,42,43"} #ifdef CALCO2 ,{"CO2CAL0", &co2_cal0,"*0136.3,18169,0.14484,1.1004E-05,6.8620E-09,-8.5528E-13,5.9278E-17,370.68"}, {"CO2CAL1",&co2_cal1,"*7159.039"}, {"CO2CAL2",&co2_cal2,"*720.01499"}, {"CO2CAL3",&co2_cal3,"*7343"}, {"CO2CAL4",&co2_cal4,"*7403"} #endif }; /************************************************************************/ /* Function : set_string */ /* Purpose : Set String Parameter */ /* Inputs : Parm Mask, String name, new string */ /* Outputs : OK */ /************************************************************************/ Int16 set_string( Nat16 pmask, char *name, char *string ) { Nat16 i; const StringParm *sp; Reg char *p; Reg Nat16 len; for ( i = Number(stringtbl), sp = stringtbl; i--; sp++ ) if ( (pmask & 3) == 3 ) { if ( cmp_ulc(name, sp->sp_name) != NULL ) { if ( (p = *sp->sp_parm) != NULL ) permFree( p ); len = strlen( string ) + 1; if ( (p = permMalloc(len)) == NULL ) return( ERROR ); bcopy( (Byte *)string, (Byte *)p, len ); *sp->sp_parm = p; } } else xprintf( "%12s = %s\n", sp->sp_name, *sp->sp_parm ); return( OK ); } /* set_string() */ /************************************************************************/ /* Function : analog */ /* Purpose : Get A/D port value */ /* Inputs : Parm Mask, Port number */ /* Outputs : OK */ /************************************************************************/ Int16 analog( Nat16 pmask, Nat16 port ) { Nat16 val; get_analog(port, 1, 100, &val); xprintf("A/D %d = %d\n", port, val); return( OK ); } /* analog() */ /************************************************************************/ /* Function : parmColdInit */ /* Purpose : Reset userif parameter defaults due to cold (full) init*/ /* Inputs : None */ /* Outputs : None */ /************************************************************************/ Void parmColdInit( Void ) { Reg Nat16 i; Reg const Param *parmp; Reg const StringParm *sp; for ( i = Number(parmtbl), parmp = parmtbl; i; i--, parmp++ ) *(parmp->pt_parm) = parmp->pt_dflt; /* Init parameters */ tmpRamStart = free_mem; /* fix up tmpRam parms */ tmpRamLen = mem_size; for ( i = Number(stringtbl), sp = stringtbl; i; i--, sp++ ) { *sp->sp_parm = NULL; set_string( 3, sp->sp_name, sp->sp_dflt ); } } /* parmColdInit() */ /************************************************************************/ /* Function : quit */ /* Purpose : User command to exit User I/F */ /* Inputs : None */ /* Outputs : ABORT */ /************************************************************************/ Int16 quit( Void ) { return( ABORT ); } /* quit() */ #ifdef TNC /************************************************************************/ /* Function : radiomsg */ /* Purpose : Process TNC message, which begins with "***" */ /* Inputs : Parm Mask, tail of TNC message */ /* Outputs : OK or ABORT */ /************************************************************************/ Int16 radiomsg( Nat16 pmask, char *tail ) { if ( find_str(tail, "DISCONNECT") != NULL ) { tnc_connected = FALSE; return( ABORT ); } return( OK ); } /* radiomsg() */ #endif /* TNC */ /************************************************************************/ /* Function : reset */ /* Purpose : Reset System */ /* Inputs : Parm Mask, String, restart delay in seconds */ /* Outputs : OK */ /* Comments : If not "LOG", never returns, resets all RAM and system */ /************************************************************************/ Int16 reset( Nat16 pmask, char *s, Nat16 startupDelay ) { if ( cmp_ulc(s, "LOG") != NULL ) logColdInit(); else if ( cmp_ulc(s, "ALL") != NULL ) { progRamChksum = 0; /* Clear checksum and sys_init */ sys_init = 0; /* to ensure cold start */ if ( (pmask & 2) && (startupDelay > 0) ) { clk_alarm(60 * startupDelay); /* Set alarm to wake up later */ io_term(); /* Tell I/O system about pwr down*/ clk_pwrdown(); /* Power down the system */ asm idlpd #2; /* Power down CPU while sys power*/ task_delay(TICKS_PER_SECOND); /* turns off */ } asm rst; /* Reset system now */ } return( OK ); } /* reset() */ /************************************************************************/ /* Function : params */ /* Purpose : Show or set user parameters */ /* Inputs : Parm Mask, Parm name, Parm value in ASCII */ /* Outputs : None */ /************************************************************************/ Int16 params( Nat16 pmask, char *name, char *value ) { Nat16 i; const Param *parmp; Reg char *fmt; Reg Nat16 radix; for ( i = Number(parmtbl), parmp = parmtbl; i--; parmp++ ) { if ( parmp->pt_flags & PARM_HEX ) { fmt = "%14s = %6x Hex %s\n"; radix = 16; } else { fmt = "%14s = %6d Decimal %s\n"; radix = 10; } if ( (pmask & 3) == 3 ) { if ( cmp_ulc(name, parmp->pt_name) != NULL ) getnum( &value, (Int16 *)(parmp->pt_parm), radix ); } else if ( (parmp->pt_flags & PARM_INVISIBLE) == 0 ) { xprintf( fmt, parmp->pt_name, *(parmp->pt_parm), parmp->pt_help ); } } return( OK ); } /* params() */ /************************************************************************/ /* Function : usr_power */ /* Purpose : Temporarily turn on/off power bits */ /* Inputs : Parm Mask, Power bit vector */ /* Outputs : OK */ /************************************************************************/ Int16 usr_power( Nat16 pmask, Nat16 pwrvec ) { if ( pmask & 1 ) io_power( pwrvec ); xprintf( "Power vector = %x hex\n", iopwrbits ); return( OK ); } /* usr_power() */ /************************************************************************/ /* Function : connect */ /* Purpose : Connect user to an instrument's serial port */ /* Inputs : Parm Mask, Instrument name */ /* Outputs : OK or ERROR */ /************************************************************************/ Int16 connect( Nat16 pmask, char *name, Nat16 unused1, Nat16 unused2, Byte *buffer ) { Driver *idp; /* Instrument driver pointer */ Nat16 iport, oport; /* Instrument ser port, ours */ Word omode; /* Our serial mode */ Reg Int16 ic, oc; /* Char buffers each direction */ Reg Nat16 secondTimeout; /* Timeout counters */ Int16 tickTimeout; Byte *ringbuf; /* Ring buffer pointer */ if ( !(pmask & 1) ) /* If no instr. name, */ return( ERROR ); /* abort */ if ( (idp = drvr_find(name)) != DRV_NULL ) iport = idp->drv_parms[SER_PORT]; /* Get drvr ptr to instr*/ else return( ERROR ); if ( (iport == NO_SERIAL) || (iport == port) ) /* If no instr or no */ return( ERROR ); /* serial port, error*/ oc = TRUE; /* Used here as msg boolean*/ while ( ser_sem[iport].sem_cnt < 1 ) /* Wait for semaphore */ { if ( oc ) /* If busy, tell user */ xputs("Serial line busy. Waiting..."); if ( xgetc_tmout(1) != ERROR ) /* Abort on any key */ { /* Wait 1 sec between tests*/ xputs("Aborted\n"); return( OK ); } oc = FALSE; /* Clear boolean */ } if ( (ringbuf = (Byte *)tmpMalloc(CONNECT_RING)) != NULL ) { xdrain_ser( TICKS_PER_SECOND ); /* Wait for output to drain */ ring_init( &tx_ring[port], ringbuf, CONNECT_RING ); } /* Increase output ring size*/ oport = port; /* Save our serial port */ omode = sermode; /* Save our serial mode */ drv_ser_port( idp ); /* Acquire instrument's port*/ sermode = idp->drv_parms[SER_SETUP]; secondTimeout = con_tmout; /* Init timeouts */ tickTimeout = TICKS_PER_SECOND; ic = (*idp->drv_serwake)(idp,TRUE,buffer); /* Wake up instrument */ port = oport; /* Restore output port */ sermode = omode; /* Restore serial mode */ if ( !ic ) /* If wakeup failed, */ xputs("In use. Try later\n"); /* tell user and skip conn */ else { /* If wakeup OK, */ xprintf( "Connected\n" ); /* Print connected message */ for ( oc = ERROR; (oc != con_dsc) && secondTimeout; ) { /* Loop til tmout or discon */ while ( (ser_sndsts(iport) < CONNECT_RING-1) && ((oc = ser_getc(oport)) != ERROR) && (oc != con_dsc) ) { /* Drain user serial buffer */ if ( oc == brkchr ) /* If BREAK char */ ser_break( iport, TICKS_PER_SECOND ); /* send a BREAK to instr */ else /* If not break or disconn */ ser_putc( iport, oc ); /* char, send to instr */ secondTimeout = con_tmout; /* Reset timeout */ } while ( (ser_sndsts(oport) < CONNECT_RING-1) && ((ic = ser_getc(iport)) != ERROR) ) { /* Drain instr serial buffer*/ xputc( ic ); /* Send instr buf to user */ secondTimeout = con_tmout; /* Reset timeout */ } if ( --tickTimeout <= 0 ) /* Check timeouts */ { tickTimeout = TICKS_PER_SECOND; secondTimeout--; } asm push oc; asm push secondTimeout; task_delay( 1 ); /* Run loop once per tick */ asm pop secondTimeout; asm pop oc; } /* for */ } /* else */ port = iport; /* Set instr port for wake */ (*idp->drv_serwake)(idp,FALSE,buffer); /* Put instr. back to sleep */ drv_ser_release( idp ); /* Release instrument's port*/ drv_pwroff( idp ); /* Turn instr power off */ port = oport; /* Restore our serial port */ if ( ringbuf != NULL ) { /* If using mallocd ring buf*/ xdrain_ser( TICKS_PER_SECOND ); /* Wait for output to drain */ ser_init( port, sermode ); /* Re-init xmit ring */ tmpFree( (char *)ringbuf ); /* Free the buffer */ } newline(); /* Start new line */ if ( secondTimeout == 0 ) { /* If timed out, */ xputs("TIMEOUT\n"); /* tell user */ return( ABORT ); /* and disconnect */ } return( OK ); } /* connect() */ /************************************************************************/ /* Function : time */ /* Purpose : Get/Set Time and Date */ /* Inputs : Parm Mask, String */ /* Outputs : OK */ /************************************************************************/ Int16 time( Nat16 pmask, char *s) { Reg Nat16 i; Int16 j; Nat32 oldtime; if ( pmask & 1 ) { oldtime = tod; for ( i = 0; i < sizeof(DateTime); i++ ) if ( getnum(&s, &j, 10) ) *((Byte *)(&dttm) + i) = (Byte)j; clk_write( &dttm ); clk_read(); drvr_timechange( tod - oldtime ); } xprintf("%02d:%02d:%02d %d/%d/%d\n", dttm.dt_hr, dttm.dt_min, dttm.dt_sec, dttm.dt_yr + ((dttm.dt_yr < YEAR0) ? 2000 : 1900), dttm.dt_mo, dttm.dt_day ); return( OK ); } /* time() */ #ifdef TNC /************************************************************************/ /* Function : using_radio */ /* Purpose : Check whether user if connected to OASIS via Radio/TNC */ /* Inputs : None */ /* Outputs : TRUE if connected via radio, else FALSE */ /************************************************************************/ MBool using_radio( Void ) { return ( cmp_ulc(task_get()->td_name, "Radio") != NULL ); } /* using_radio() */ /************************************************************************/ /* Function : tnc_cmd */ /* Purpose : Send command string to Packet Radio TNC */ /* Inputs : Parm Mask, String */ /* Outputs : OK */ /************************************************************************/ Int16 tnc_cmd( Nat16 pmask, char *cmd, Nat16 unused1, Nat16 unused2, Byte *buffer ) { Int16 i; if ( (pmask & 1) && using_radio() ) { xprintf("%c%s\r", tncchr, cmd ); /* Put TNC in cmd mode, send the cmd*/ i = xgetn_tmout((char *)buffer, USR_BUFSIZE-1, 3); xflush_ser( TICKS_PER_SECOND/2 ); buffer[i] = '\0'; /* End of string delimiter */ tnc_converse(); /* Back to converse mode */ xprintf("%s\n", buffer ); /* Send user the reply */ return( OK ); } else return( ERROR ); } /* tnc_cmd() */ #endif /* TNC */ /************************************************************************/ /* Function : display */ /* Purpose : Display Memory */ /* Inputs : Parm Mask, Start address, Bank number, Length */ /* Outputs : OK */ /************************************************************************/ Int16 display( Nat16 pmask, Nat16 start, Nat16 bank, Nat16 len ) { Int16 lines, i; Byte buff[16]; if ( pmask & 1 ) dispnext = (Byte *)start; if ( pmask & 2 ) dbank = bank; lines = (pmask & 4) ? ((len + 15) >> 4) : 8; for ( ; lines > 0; lines--, dispnext += 16 ) { xprintf("%2d:%04x ", dbank, (Nat16)dispnext); bankCopy( dbank, (Byte *)dispnext, buff, 16 ); for ( i = 0; i < 16; i++ ) xprintf("%02x ", (Nat16)buff[i] ); xputs(" "); for ( i = 0; i < 16; i++ ) xputc( isprint(buff[i]) ? buff[i] : '.' ); newline(); if ( xgetc_tmout(0) != ERROR ) break; dispatch(); } return( OK ); } /* display() */ /************************************************************************/ /* Function : set */ /* Purpose : Set Memory */ /* Inputs : Parm Mask, Memory address, Bank */ /* Outputs : OK or ERROR */ /* Comments : Uses 20 byte buffer for user to enter an 8 bit number */ /* If user wants to enter a lot of white space, he's SOL */ /************************************************************************/ Int16 set( Nat16 pmask, Byte *addr, Nat16 bank ) { Byte *p; char reply[20], *q; Int16 c; MBool doit; p = addr; do { doit = FALSE; c = 0; bankCopy( bank, p, (Byte *)&c, 1 ); xprintf( "%2d:%04x %02x ", bank, p, c ); q = reply; if ( xgets_tmout(reply, 20, 60) > 0 ) if ( doit = getnum(&q, &c, 16) ) bankCopy( bank, (Byte *)&c, p++, 1 ); } while ( doit ); progRamChksum = chkProgRam(); return( OK ); } /* set() */ @