/*
* DataExch.c
*/
/* from module "SoftcardDataExchImpl" */
#include "DataExch.h"
IOZone myZone = (IOZone) FSBACKDOOR;
IOZone hisZone = (IOZone) (FSBACKDOOR+ZONESIZE);
ClearZones()
{
long i, *p, *start, lengh;
start = (long *) myZone;
lengh = ZONESIZE/2; /* ZONESIZE is in bytes */
p = start;
for (i = lengh; i != 0; i--) {
*p = 0;
p++;
}
}
void Pause(ms)
unsigned ms;
{
unsigned i, dummy;
dummy = 0;
for (i = ms; i != 0; i--) {
dummy = dummy+1;
}
};
unsigned TouchSpace(z, h, h1, head, tail)
IOZone z;
Header h, h1;
Block head;
Block tail;
{
Header nextH;
Block target;
unsigned size=0;
nextH = h;
while (size==0) {
if ((nextH==MAXHDRS-1)) nextH = 0;
else nextH = nextH+1;
if (nextH==h1) return(0);
size = z->headers[nextH].size;
};
target = z->headers[nextH].b;
if ((tail < target)) return(0);
else return((head > tail));
}
void CopyTo(from, start, len, to, first)
char *from;
unsigned start;
unsigned len;
IOZone to;
unsigned first;
{
char *p1, *p2, *p3;
if (len==0) return;
if (len+first>BUFSIZE) XRllDebugger();
p1 = from+start;
p2 = p1+len;
p3 = to->buffer+first;
while ( p1<p2) *p3++ =*p1++;
/* to->buffer[first+i] = from[start+i]; */
}
void CopyFrom(to, start, len, from, first)
char *to;
unsigned start;
unsigned len;
IOZone from;
unsigned first;
{
char *p1, *p2, *p3;
if (len==0) return;
if (len+first>BUFSIZE) XRllDebugger();
p1 = to+start;
p2 = p1+len;
p3 = from->buffer+first;
while ( p1<p2) *p1++ =*p3++;
/* to[start+i] = from->buffer[first+i]; */
}
void PutPacket(type, data1, data2, r, len)
unsigned type;
unsigned data1;
unsigned data2;
char *r;
unsigned len;
{
Header h;
Block bufHead, bufTail, prevBlock;
unsigned prevSize;
Header myLastWrittenPacket;
myLastWrittenPacket = myZone->lastWrittenPacket;
prevBlock = myZone->headers[myLastWrittenPacket].b;
prevSize = myZone->headers[myLastWrittenPacket].size;
prevSize = prevSize+(prevSize%2);
if (prevBlock+prevSize>BUFSIZE) bufHead = prevBlock+prevSize-BUFSIZE;
else bufHead = prevBlock+prevSize;
if (bufHead+len>BUFSIZE) bufTail = bufHead+len-BUFSIZE;
else bufTail = bufHead+len;
if (myLastWrittenPacket==MAXHDRS-1) h = 0;
else h = myLastWrittenPacket+1;
while (h==hisZone->lastRedPacket || TouchSpace(myZone, hisZone->lastRedPacket, myLastWrittenPacket, bufHead, bufTail) ) Pause(outputWaitingTime);
myZone->headers[h].b = bufHead;
myZone->headers[h].size = len;
myZone->headers[h].type = type;
myZone->headers[h].data1 = data1;
myZone->headers[h].data2 = data2;
if (bufHead <= bufTail) {
(void) CopyTo(r, 0, len, myZone, bufHead);
}
else {
(void) CopyTo(r, 0, (BUFSIZE-bufHead), myZone, bufHead);
(void) CopyTo(r, (BUFSIZE-bufHead), bufTail, myZone, 0);
};
myZone->lastWrittenPacket = h;
}
void WatchPacketsIn()
{
ActionProc *aProc;
Block bufHead, bufTail;
HeaderRec hVal;
Header h;
while (1) {
if ((myZone->lastRedPacket==MAXHDRS-1)) h = 0;
else h = myZone->lastRedPacket+1;
while (hisZone->lastWrittenPacket==myZone->lastRedPacket) Pause(inputWaitingTime);
hVal = hisZone->headers[h];
if (hVal.type==QUIT) {myZone->lastRedPacket = h; return;};
aProc = registration[hVal.type].a;
bufHead = hVal.b;
if ((bufHead+hVal.size > BUFSIZE)) bufTail = hVal.size-BUFSIZE+bufHead;
else bufTail = bufHead+hVal.size;
if (registration[hVal.type].t!=-1) {
if ((bufHead <= bufTail)) {
(*aProc)(&(hisZone->buffer[bufHead]), hVal.size, hVal.type, hVal.data1, hVal.data2);
}
else {
(*aProc)(&(hisZone->buffer[bufHead]), BUFSIZE-bufHead, hVal.type, hVal.data1, hVal.data2);
((*aProc)(&(hisZone->buffer[0]), bufTail, hVal.type, hVal.data1, hVal.data2));
};
myZone->lastRedPacket = h;
}
else {
char tempSpace[256];
if (hVal.size>256) XRllDebugger();
if ((bufHead <= bufTail)) {
CopyFrom(tempSpace, 0, hVal.size, hisZone, bufHead);
}
else {
CopyFrom(tempSpace, 0, BUFSIZE-bufHead, hisZone, bufHead);
CopyFrom(tempSpace, BUFSIZE-bufHead, bufTail, hisZone, 0);
};
myZone->lastRedPacket = h;
(*aProc)(tempSpace, hVal.size, hVal.type, hVal.data1, hVal.data2);
}
};
}