home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 9
/
MEDIASHARE_09.ISO
/
comm
/
hydrakit.zip
/
HSRC_100.ARJ
/
SYSPC.C
< prev
Wrap
C/C++ Source or Header
|
1993-01-11
|
14KB
|
494 lines
/*=============================================================================
HydraCom Version 1.00
A sample implementation of the
HYDRA Bi-Directional File Transfer Protocol
HydraCom was written by
Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT
COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
The HYDRA protocol was designed by
Arjen G. Lentz, LENTZ SOFTWARE-DEVELOPMENT and
Joaquim H. Homrighausen
COPYRIGHT (C) 1991-1993; ALL RIGHTS RESERVED
Revision history:
06 Sep 1991 - (AGL) First tryout
.. ... .... - Internal development
11 Jan 1993 - HydraCom version 1.00, Hydra revision 001 (01 Dec 1992)
For complete details of the Hydra and HydraCom licensing restrictions,
please refer to the license agreements which are published in their entirety
in HYDRACOM.C and LICENSE.DOC, and also contained in the documentation file
HYDRACOM.DOC
Use of this file is subject to the restrictions contained in the Hydra and
HydraCom licensing agreements. If you do not find the text of this agreement
in any of the aforementioned files, or if you do not have these files, you
should immediately contact LENTZ SOFTWARE-DEVELOPMENT and/or Joaquim
Homrighausen at one of the addresses listed below. In no event should you
proceed to use this file without having accepted the terms of the Hydra and
HydraCom licensing agreements, or such other agreement as you are able to
reach with LENTZ SOFTWARE-DEVELOMENT and Joaquim Homrighausen.
Hydra protocol design and HydraCom driver: Hydra protocol design:
Arjen G. Lentz Joaquim H. Homrighausen
LENTZ SOFTWARE-DEVELOPMENT 389, route d'Arlon
Langegracht 7B L-8011 Strassen
3811 BT Amersfoort Luxembourg
The Netherlands
FidoNet 2:283/512, AINEX-BBS +31-33-633916 FidoNet 2:270/17
arjen_lentz@f512.n283.z2.fidonet.org joho@ae.lu
Please feel free to contact us at any time to share your comments about our
software and/or licensing policies.
=============================================================================*/
#include <time.h>
#include <stdio.h>
#include <stdarg.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <io.h>
#include <process.h>
#include <signal.h>
#include <alloc.h>
#include <sys\stat.h>
#include "hydracom.h"
#include "async.h"
struct _fos_info {
word strsize; /* size of the structure in bytes */
byte majver; /* FOSSIL spec driver conforms to */
byte minver; /* rev level of this specific driver */
char far *ident; /* FAR pointer to ASCII ID string */
word ibufr; /* size of the input buffer (bytes) */
word ifree; /* number of bytes left in buffer */
word obufr; /* size of the output buffer (bytes) */
word ofree; /* number of bytes left in the buffer */
byte swidth; /* width of screen on this adapter */
byte sheight; /* height of screen " " */
byte speed; /* ACTUAL speed, computer to modem */
};
struct _fos_speedtable {
word speed;
byte bits;
};
/* HJW 1/4/93
NOTE: The topspeed compiler generates for _DX = port the following
assembler instructions:
Mov AX,[port]
Mov DX, AX
Thus AX is overwritten. Any construct that loads a register
using the _XX register indicators should be examined carefully.
It is very likely that other compilers use the same strategy.
Example:
#define fossil_int(func) { _AH = func; _DX = port; geninterrupt(0x14); }
should be changed to:
*/
#define fossil_int(func) { _DX = port; _AH = func; geninterrupt(0x14); }
#define dosext_int(func) { _AH = func; geninterrupt(0x15); }
#define dos_int(func) { _AH = func; geninterrupt(0x21); }
#define dossched_int() { geninterrupt(0x28); }
#define FOS_SIGNATURE 0x1954
#define FOS_SETSPEED 0x00
#define FOS_PUTC 0x01
#define FOS_GETSTATUS 0x03
#define FOS_INIT 0x04
#define FOS_DEINIT 0x05
#define FOS_SETDTR 0x06
#define FOS_DUMP 0x09
#define FOS_PURGE 0x0a
#define FOS_SETFLOW 0x0f
#define FOS_MAXBUFLEN 1024
static boolean dv_active;
static boolean fossil;
static struct _fos_info fos_info;
static byte fos_inbuf[FOS_MAXBUFLEN];
static word fos_inwrite,
fos_inread;
static struct _fos_speedtable fos_speedtable [] = {
{ 300U, 0x40 },
{ 1200U, 0x80 },
{ 2400U, 0xA0 },
{ 4800U, 0xC0 },
{ 9600U, 0xE0 },
{ 19200U, 0x00 },
{ 38400U, 0x20 },
{ 0U, 0 }
};
void dtr_out (byte flag)
{
if (fossil) {
_AL = flag;
fossil_int(FOS_SETDTR);
}
else
AsyncHand(flag ? (DTR | RTS) : RTS);
}
void com_flow (byte flags)
{
if (fossil) {
_AL = flags;
fossil_int(FOS_SETFLOW);
}
else {
AsyncCTS(flags & 0x02);
}
}
void com_setspeed (word speed) /* set speed of comport */
{
register byte i;
if (!speed) return;
if (fossil) {
for (i = 0; fos_speedtable[i].speed; i++) {
if (speed == fos_speedtable[i].speed) {
_AL = (fos_speedtable[i].bits | (parity ? 0x1a : 0x03));
fossil_int(FOS_SETSPEED);
break;
}
}
}
else
AsyncSet(speed,(parity ? (BITS_7 | EVEN_PARITY) : BITS_8) | STOP_1);
}
static word fos_getstatus (void)
{
fossil_int(FOS_GETSTATUS);
return (_AX);
}
static int get_fos_info (void)
{
struct SREGS sregs;
union REGS regs;
regs.x.ax = 0x1b00;
regs.x.cx = sizeof (struct _fos_info);
regs.x.dx = port;
segread(&sregs);
sregs.es = FP_SEG(&fos_info);
regs.x.di = FP_OFF(&fos_info);
int86x(0x14,®s,®s,&sregs);
return (regs.x.ax == sizeof (struct _fos_info));
}
static int fos_fillinbuf (void)
{
struct SREGS sregs;
union REGS regs;
if (!(fos_getstatus() & 0x0100))
return (0);
regs.x.ax = 0x1800;
regs.x.dx = port;
regs.x.cx = FOS_MAXBUFLEN;
segread(&sregs);
sregs.es = FP_SEG(fos_inbuf);
regs.x.di = FP_OFF(fos_inbuf);
int86x(0x14,®s,®s,&sregs);
fos_inwrite = regs.x.ax;
fos_inread = 0;
return (fos_inwrite);
}
void com_putblock (byte *s, word len)
{
if (fossil) {
struct SREGS sregs;
union REGS regs;
while (len && carrier()) {
regs.x.ax = 0x1900;
regs.x.dx = port;
regs.x.cx = len;
segread(&sregs);
sregs.es = FP_SEG(s);
regs.x.di = FP_OFF(s);
int86x(0x14,®s,®s,&sregs);
len -= regs.x.ax;
s += regs.x.ax;
}
}
else {
while (len-- > 0 && carrier()) com_putbyte(*s++);
}
}
static int fos_init (void)
{
fossil_int(FOS_INIT);
return ((_AX != FOS_SIGNATURE || _BH < 5 || _BL < 0x1b) ? 0 : 1);
}
void sys_init(void) /* all system dependent init should be done here */
{
_CX = 0x4445; /* DE */ /* DESQview presence check */
_DX = 0x5351; /* SQ */
_AL = 0x01;
dos_int(0x2b);
dv_active = (_AL != 0xff && _BX) ? true : false;
fossil = true;
if (!noinit && !fos_init()) {
if (AsyncInit(port)) {
cprint("%s internal com-routines can't find a comport %u\n",
PRGNAME, port + 1);
endprog(2);
}
fossil = false;
}
else if (!get_fos_info() || fos_info.majver < 5) {
if (!noinit) fossil_int(FOS_DEINIT);
cprint("%s requires a revision 5 FOSSIL driver (funcs upto 1B)\n",PRGNAME);
endprog(2);
}
if (fossil) {
if (fos_info.obufr < 4096)
message(6,"!FOSSIL transmit buffer size %u, should be >= 4096",fos_info.obufr);
if (fos_info.ibufr < 4096)
message(6,"!FOSSIL receive buffer size %u, should be >= 4096",fos_info.ibufr);
}
if (!noinit) com_flow(flowflags);
fos_inread = fos_inwrite = 0;
}
void sys_reset(void) /* same as above for de-init */
{
if (!noinit) com_flow(0);
if (fossil) {
if (!noinit) fossil_int(FOS_DEINIT);
}
else
AsyncStop();
}
void sys_idle (void)
{
#if WIN_AGL
win_idle();
#else
if (dv_active) {
_AL = 0; /* int15 ax=1000 */
dosext_int(0x10); /* dv time slice */
}
else
dossched_int(); /* DOS scheduler */
#endif
}/*sys_idle()*/
int com_outfull (void) /* Return the amount in fossil output buffer */
{ /* Ie. remaining no. bytes to be transmitted */
if (fossil) {
get_fos_info();
return (fos_info.obufr - fos_info.ofree);
}
else
return (AsyncOutStat());
}
int carrier(void) /* Return carrier status */
{
int i;
if (nocarrier) return (1);
if (fossil) {
fossil_int(FOS_GETSTATUS);
/* HJW 4/1/93
Here we have the same problem, machinecode generated for
return (_AX & dcdmask);
is
Mov AX,[dcdmask]
And AX,AX
so it should be changed to:
*/
i = _AX;
return(i & dcdmask);
}
else {
i = AsyncStat();
return (((i >> 8) & dcdmask) | ((i << 8) & dcdmask));
}
}
void com_flush(void) /* wait till all characters have been sent */
{
if (fossil) {
while (!(fos_getstatus() & 0x4000) && carrier());
}
else {
while (AsyncOutStat() && carrier());
}
}
void com_putbyte (byte c)
{
if (fossil) {
_AL = c;
fossil_int(FOS_PUTC);
}
else
AsyncOut(c);
}
void com_purge (void)
{
if (fossil) {
fossil_int(FOS_PURGE);
fos_inread = fos_inwrite = 0;
}
else
AsyncPurge();
}
void com_dump (void)
{
if (fossil) {
fossil_int(FOS_DUMP);
}
else
AsyncDump();
}
int com_getbyte(void)
{
if (fossil) {
return (((fos_inread < fos_inwrite) || fos_fillinbuf()) ?
fos_inbuf[fos_inread++] : EOF);
}
else
return (AsyncInStat() ? AsyncIn() : EOF);
}
void setstamp(char *name,long tim) /* Set time/date of file */
{
int fd;
struct tm *t;
union REGS regs;
if ((fd = dos_open(name,0)) < 0)
return;
if (tim == 0L)
time(&tim);
t = localtime((time_t *) &tim);
regs.x.cx = (t->tm_hour << 11) |
(t->tm_min << 5) |
(t->tm_sec/2);
regs.x.dx = ((t->tm_year-80) << 9) |
((t->tm_mon+1) << 5) |
(t->tm_mday);
regs.x.bx = fd;
regs.x.ax = 0x5701; /* DOS int 21 fn 57 sub 1 */
intdos(®s,®s); /* Set a file's date/time */
close(fd);
}
long freespace(char *drivepath) /* get free diskspace for specified drive */
{
union REGS regs;
if (drivepath[0] && drivepath[1] == ':' && isalpha(drivepath[0]))
regs.h.dl = (toupper(drivepath[0]) - 64);
else
regs.h.dl = 0;
regs.h.ah = 0x36;
intdos(®s,®s);
return ((long)regs.x.cx * (long)regs.x.ax * (long)regs.x.bx);
}
static char ff_dta[58];
char *ffirst(char *filespec)
{
struct SREGS sregs;
union REGS regs;
regs.h.ah = 0x1a;
segread(&sregs);
sregs.ds = FP_SEG(ff_dta);
regs.x.dx = FP_OFF(ff_dta);
intdosx(®s,®s,&sregs);
regs.x.cx = 0;
regs.h.ah = 0x4e;
sregs.ds = FP_SEG(filespec);
regs.x.dx = FP_OFF(filespec);
intdosx(®s,®s,&sregs);
if (regs.x.cflag)
return (NULL);
return (ff_dta+0x1e);
}
char *fnext(void)
{
struct SREGS sregs;
union REGS regs;
regs.h.ah = 0x1a;
segread(&sregs);
sregs.ds = FP_SEG(ff_dta);
regs.x.dx = FP_OFF(ff_dta);
intdosx(®s,®s,&sregs);
regs.h.ah = 0x4f;
intdosx(®s,®s,&sregs);
if (regs.x.cflag)
return (NULL);
return (ff_dta+0x1e);
}
/* end of syspc.c */