home *** CD-ROM | disk | FTP | other *** search
- /* --- asDriver.c V1.0 Jan 1994 (windows version) ---
- **
- ** ASCII driver.
- **
- ** Copyright(C) 1994 by MarshallSoft Computing, Inc.
- ** All rights are reserved.
- */
-
- #define DEBUG 0
-
- #include <stdio.h>
- #include <string.h>
- #include "windows.h"
- #include "pcl4w.h"
- #include "ascodes.h"
- #include "errcodes.h"
- #include "ascii.h"
- #include "asdriver.h"
- #include "term_io.h"
- #include "file_io.h"
- #include "paint.h"
- #include "info.h"
- #include "dir_io.h"
-
- extern HWND hMainWnd;
- extern HWND hInfoWnd;
-
- /*** ascDriver functions & variables */
-
- long FileLength(int); /* returns file length */
- static char Temp[255]; /* temporary buffer */
- static void XOFF_Test(int);
- static void XON_Test(int);
-
- #define BUFFER_SIZE 1000
-
- /*** ascDriver state variables ***/
-
- static int ascActive=FALSE; /* TRUE if initialized */
- static char ascBuffer[BUFFER_SIZE+1]; /* data packet buffer */
- static int ascBufferSize; /* # bytes in ascBuffer */
- static int ascBufferIndex; /* index to next char */
- static long ascCharCount; /* # chars sent or received */
- static int ascErrorCode; /* last error code */
- static int ascErrorState; /* state in which last error occured */
- static char ascFilename[64]; /* filename */
- static long ascFileSize; /* file size */
- static char ascFileSpec[64]; /* current file specification */
- static int ascHandle; /* file Handle */
- static int ascPort; /* serial port */
- static int ascState; /* current driver state */
- static int ascLastState; /* last driver state */
- static int ascStateCount; /* # times last state called */
- static int ascCharPace; /* ms delay after sending each char */
- static char ascTermChar; /* termination char ( 0x00 => none) */
- static int ascEchoFlag; /* echo flag */
- static int ascLastXchar; /* last XON/XOFF received */
- static long ascMarkTime; /* time last char received */
- static long ascSendTime; /* time to send next char */
- static int ascLowWater; /* RX buffer low water mark */
- static int ascHighWater; /* RX buffer high water mark */
- static int ascMaxBurst; /* # chars to send in burst */
-
- static char *XONptr = "XON ";
- static char *XOFFptr = "XOFF ";
-
- int SetASCerror(int);
-
- /*** ascDriver functions ***/
-
- int ascAbort(void)
- {int i;
- DisplayLine("Aborting...");
- ascErrorCode = NO_ERROR;
- ascErrorState = 0;
- ascState = ASC_IDLE;
- for(i=0;i<6;i++) if(PutChar(ascPort,CAN)==-1) break;
- SioRxFlush(ascPort);
- return(0);
- }
-
- int ascGetErrorCode(void)
- {
- ascDriver();
- return( ascErrorCode );
- }
-
- int ascGetErrorState(void)
- {
- ascDriver();
- return( ascErrorState );
- }
-
- char *ascGetFilename(void)
- {
- ascDriver();
- return( ascFilename );
- }
-
- int ascGetState(void)
- {
- ascDriver();
- return( ascState );
- }
-
- long ascGetFileLength()
- {
- ascDriver();
- return( ascFileSize );
- }
-
- long ascGetCharCount()
- {
- ascDriver();
- return( ascCharCount );
- }
-
- int ascInit(Port)
- int Port;
- {
- #if DEBUG
- sprintf(Temp,"ascInit: Port=COM%d",Port+1);
- DisplayLine(Temp);
- ascLastState = -1;
- ascStateCount = 0;
- #endif
- ascActive = TRUE;
- ascPort = Port;
- ascState = ASC_IDLE;
- ascHandle = -1;
- ascFilename[0] = '\0';
- ascErrorCode = NO_ERROR;
- return(0);
- }
-
- int ascStartTx(char *Filename, /* File name */
- int CharPace, /* char pace in ms */
- char TermChar, /* termination char */
- int EchoFlag) /* echo flag */
- {
- #if DEBUG
- sprintf(Temp,"ascStartTx:Filename='%s' TermChar='%c' EchoFlag=%d",
- Filename,TermChar,EchoFlag);
- DisplayLine(Temp);
- #endif
- ascErrorCode = NO_ERROR;
- ascErrorState = 0;
- strcpy(ascFileSpec,Filename);
- ascState = TX_START;
- ascFileSize = 0;
- ascCharPace = CharPace;
- if(ascCharPace<5) ascCharPace = 5;
- ascMaxBurst = 250 / ascCharPace;
- ascTermChar = TermChar;
- ascEchoFlag = EchoFlag;
- ascLastXchar = XON;
- ascCharCount = 0L;
- ascDriver();
- return(0);
- } /* ascStartTx */
-
- int ascStartRx(char *Filename, /* File name */
- int RxQueSize, /* RX queue size */
- char TermChar, /* termination char */
- int EchoFlag) /* echo flag */
- {
- #if DEBUG
- sprintf(Temp,"ascStartRx:Filename='%s' RxQueSize=%d TermChar='%c' EchoFlag=%d",
- Filename,RxQueSize,TermChar,EchoFlag);
- DisplayLine(Temp);
- #endif
- ascErrorCode = NO_ERROR;
- ascErrorState = 0;
- strcpy(ascFilename,Filename);
- ascState = RX_START;
- ascFileSize = 0;
- ascLowWater = RxQueSize / 4;
- ascHighWater = RxQueSize / 2;
- ascTermChar = TermChar;
- ascEchoFlag = EchoFlag;
- ascLastXchar = XON;
- ascCharCount = 0L;
- ascDriver();
- return(0);
- } /* end ascStartRx */
-
- int ascDriver()
- {int i, n;
- char c;
- char *Ptr;
- int Code; /* return code */
- /* start */
- if(!ascActive)
- {SetASCerror(NOT_ACTIVE_ERROR);
- return(TRUE);
- }
- #if DEBUG
- if(ascLastState!=ascState)
- {sprintf(Temp,"%ld: State = %d ",GetTickCount(),ascState);
- DisplayLine(Temp);
- }
- #endif
- if(ascLastState==ascState) ascStateCount++;
- else
- {ascStateCount = 1;
- ascLastState = ascState;
- }
- /* process according to state */
- switch(ascState)
- {
-
- case ASC_IDLE:
-
- /* return TRUE for IDLE */
- return( TRUE );
-
- /*** Transmit states ***/
-
- case TX_START:
-
- if(FindFirst(&ascFileSpec[0],&ascFilename[0]))
- {/* got match ! */
- ascState = TX_NEWFILE;
- }
- else
- {/* no file found */
- SetASCerror(NO_SUCH_FILE_ERROR);
- }
- break;
-
- case TX_NEWFILE:
-
- ascHandle = _lopen(&ascFilename[0],OF_READ|OF_SHARE_DENY_WRITE);
- if(ascHandle<0)
- {SetASCerror(CANNOT_OPEN_ERROR);
- break;
- }
- ascFileSize = FileLength(ascHandle);
- /* clear comm port */
- SioRxFlush(ascPort);
- ascState = TX_READ_DISK;
- break;
-
- case TX_READ_DISK:
-
- /* read next block from disk */
- Code = _lread(ascHandle,ascBuffer,BUFFER_SIZE);
- if(Code<0)
- {SetASCerror(DISK_READ_ERROR);
- break;
- }
- if(Code==0) ascState = TX_DONE;
- else
- {ascBufferSize = Code;
- ascBufferIndex = 0;
- ascState = TX_WAIT4_XON;
- }
- break;
-
- case TX_WAIT4_XON:
-
- if(ascLastXchar==XOFF)
- {
- Code = GetChar(ascPort);
- if((char)Code==XON)
- {ascLastXchar = XON;
- ascState = TX_SEND_DATA;
- InfoStatus(XONptr);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- break;
- }
- if((char)Code==CAN)
- {ascState = ASC_IDLE;
- break;
- }
- }
- else ascState = TX_SEND_DATA;
- break;
-
- case TX_SEND_DATA:
-
- /* send burst */
- n = min(ascMaxBurst,ascBufferSize-ascBufferIndex);
- if(n>0)
- {/* send byte(s) */
- if(ascEchoFlag) WriteTheString(&ascBuffer[ascBufferIndex],n);
- for(i=0;i<n;i++) Code = PutChar(ascPort,ascBuffer[ascBufferIndex++]);
- ascCharCount = ascCharCount + n;
- }
- /* buffer empty ? */
- if(ascBufferIndex==ascBufferSize) ascState = TX_READ_DISK;
- else
- {ascSendTime = GetTickCount() + (long)ascCharPace;
- ascState = TX_PACE;
- }
- /* check for incoming XON or XOFF */
- Code = GetChar(ascPort);
- if(((char)Code==XON)&&(ascLastXchar==XOFF))
- {ascLastXchar = (char)XON;
- InfoStatus(XONptr);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- }
- if(((char)Code==XOFF)&&(ascLastXchar==XON))
- {ascLastXchar = (char)XOFF;
- InfoStatus(XOFFptr);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- }
- break;
-
- case TX_PACE:
-
- if(GetTickCount() < ascSendTime) break;
- ascState = TX_WAIT4_XON;
- break;
-
- case TX_DONE:
-
- if(ascTermChar) PutChar(ascPort,ascTermChar);
- _lclose(ascHandle);
- ascState = ASC_IDLE;
- break;
-
- /*** Receive states ***/
-
- case RX_START:
-
- /* clear comm port */
- SioRxFlush(ascPort);
- ascState = RX_OPEN_FILE;
- break;
-
- case RX_OPEN_FILE:
-
- /* open file passed in Filename[] for write */
- ascHandle = _lcreat(&ascFilename[0],0);
- if(ascHandle<0)
- {SetASCerror(CANNOT_OPEN_ERROR);
- break;
- }
- ascMarkTime = GetTickCount();
- ascBufferIndex = 0;
- ascState = RX_GET_DATA;
- break;
-
- case RX_GET_DATA:
-
- XON_Test(ascLowWater);
- n = 0; Ptr = &ascBuffer[ascBufferIndex];
- /* gather up line */
- for(i=0;i<82;i++)
- {Code = GetChar(ascPort);
- if(Code==-1)
- {/* byte not ready */
- if(GetTickCount() > ascMarkTime + (long)TEN_SECS) ascState = RX_DONE;
- break;
- }
- /* received char */
- if((char)Code==ascTermChar)
- {ascState = RX_DONE;
- break;
- }
- if((char)Code==CAN)
- {DisplayLine("Cancelled by sender");
- ascState = RX_DONE;
- break;
- }
- /* save data in buffer */
- c = (char)Code;
- ascBuffer[ascBufferIndex++] = c;
- ascCharCount++; n++;
- if(ascBufferIndex>=BUFFER_SIZE)
- {ascState = RX_WRITE_DISK;
- break;
- }
- else ascMarkTime = GetTickCount();
- } /* end for(i) */
- if(ascEchoFlag && (n>0)) WriteTheString(Ptr,n);
- XOFF_Test(ascHighWater);
- break;
-
- case RX_WRITE_DISK:
-
- XOFF_Test(0);
- /* write Buffer to disk */
- _lwrite(ascHandle,ascBuffer,ascBufferIndex);
- ascBufferIndex = 0;
- ascMarkTime = GetTickCount();
- ascState = RX_GET_DATA;
- break;
-
- case RX_DONE:
-
- if(ascBufferIndex) _lwrite(ascHandle,ascBuffer,ascBufferIndex);
- _lclose(ascHandle);
- ascState = ASC_IDLE;
- break;
-
- default:
-
- sprintf(Temp,"INTERNAL ERROR: Bad state = %d",ascState);
- DisplayLine(Temp);
- SetASCerror(INTERNAL_ERROR);
- break;
- } /* end switch */
- return(FALSE);
- } /* end ascDriver */
-
- int SetASCerror(int Code)
- {int i;
- ascErrorCode = Code;
- ascErrorState = ascState;
- ascState = ASC_IDLE;
- if(Code!=NO_ERROR) for(i=0;i<6;i++) PutChar(ascPort,CAN);
- SioRxFlush(ascPort);
- if(Code)
- {sprintf(Temp,"ascDriver: Error=%d ascLastState=%d ascStateCount=%d",
- Code,ascLastState,ascStateCount);
- DisplayLine(Temp);
- }
- return(Code);
- } /* end SetASCerror */
-
- void XON_Test(int LowWater)
- {int RxQueSize;
- /* do we need to send XON ? */
- if(ascLastXchar==XOFF)
- {RxQueSize = SioRxQue(ascPort);
- if(RxQueSize <= LowWater)
- {PutChar(ascPort,(char)XON);
- ascLastXchar = XON;
- InfoStatus(XONptr);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- }
- }
- } /* end XON_Test */
-
- void XOFF_Test(int HighWater)
- {int RxQueSize;
- /* do we need to send XOFF ? */
- if(ascLastXchar==XON)
- {RxQueSize = SioRxQue(ascPort);
- if(RxQueSize >= HighWater)
- {PutChar(ascPort,(char)XOFF);
- ascLastXchar = XOFF;
- InfoStatus(XOFFptr);
- SendMessage(hInfoWnd,WM_USER,0,0L);
- }
- }
- } /* end XOFF_Test */