Mail Archives: djgpp/1997/09/29/13:55:02
--Message-Boundary-7620
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Mail message body
That's a reply to various posts on the topic.
><spector AT EnchantedLearning DOT com> wrote:
>> Can a DJGPP program running in a DOS box under Windows 95
>> communicate with another currently-running program (either
>> another DJGPP program in a different DOS box or a regular
>> Win32 app)?
I wrote:
>> I think one solution could be a real mode TSR loaded before windows.
And Eli replied
>This might or might not work with Windows 95, because it catches
>real-mode interrupts on different levels and not always lets them go
>all the way down to your TSR.
The Michael TSR was tested under W95, so no problems here.
And Michael wrote:
>I wrote a quick demo that allows "talking" between DJGPP programs
>sitting inside different DOS boxes. You'll have to install a TSR before
>you start Win95. The TSR is written in NASM (search for nasm095.zip).
>Currently, the "talking" capability is limited to set and retrieve one
>word value.
To him I'll reply:
Bill did it in a better way, you can setup the size of memory used to
comunicate the programs and as a plus this memory can be used as a common
transfer buffer too. In fact the TSR was for that.
Mitchell Spector <spector AT EnchantedLearning DOT com>
Experimented the use of the WindOldAp API and found:
> I ran it in a DOS box under Windows95, and found that I got
>40-50 iterations per second. That's slow, but that's not the
>surprising part. The surprising part came when I launched
>Rhide, spawned a DOS shell from within Rhide (using the DOS shell
>menu item), and found that I got between 700 and 850 iterations per
>second!
I got in the range of 800 under Win3.1 but in a 486DX4 100!, seems 95 is
trully slower.
But the slower routine is the one that reports the size, as Eli pointed it
can be avoided. But the solution with TSRs is much more faster. The problem
is that you must load the TSR, the advantage is that this buffer is
shared only by DJGPP applications and hence can be arbitred better than
the Lose clipboard.
Bill proposed your TB TSR. I tested it and works OK. The idea of sharing
the TB is good but I must admit that is a little complex to use the TB
for communication between unsyncronized DJGPP applications. Anyways the
TSR can be used for one or both purposes.
Is easy to communicate only 2 process but for more I think is more complex.
Any ideas?
I attached source code that works with the Bill's TB TSR, you can type in one
box and see the text in other box.
SET
------------------------------------ 0 --------------------------------
Visit my home page: http://www.geocities.com/SiliconValley/Vista/6552/
Salvador Eduardo Tropea (SET). (Electronics Engineer)
Alternative e-mail: set-sot AT usa DOT net - ICQ: 2951574
Address: Curapaligue 2124, Caseros, 3 de Febrero
Buenos Aires, (1678), ARGENTINA
TE: +(541) 759 0013
--Message-Boundary-7620
Content-type: text/plain; charset=US-ASCII
Content-transfer-encoding: 7BIT
Content-description: Text from file 'test.cc'
#include <stdio.h>
#include <go32.h>
#include <libc/dosio.h>
#include <conio.h>
#include <sys/movedata.h>
#include <string.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/stat.h> /* for mode definitions */
#include <dpmi.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#define __tb_size _go32_info_block.size_of_transfer_buffer
#define MAGIC 0x13254687
typedef struct
{
unsigned len;
unsigned segment;
} djgpp_tb;
int channelOff;
void *localCopy;
time_t MyID;
time_t OtherID;
int I_Started=0;
typedef struct
{
int magic;
int type;
int size;
time_t from;
time_t to;
} Message;
#define TO_ALL 0xFFFFFFFF
#define TM_REQCON 1
#define TM_GRANTCON 2
#define TM_ASCIICHAR 3
#define TypeM(a) (a->type)
int OpenChannel(void)
{
int fd;
djgpp_tb tb_i;
__dpmi_regs regs;
int tbOff=(__tb_segment<<4)+__tb_offset;
fd=open("djgpp tb",O_RDONLY);
if (fd<0)
return 0;
//tb_i.segment=0;
//tb_i.len=0;
regs.x.cx=0x0006;
regs.x.bx=fd;
regs.x.ax=0x4402;
regs.x.dx=__tb_offset;
regs.x.ds=__tb_segment;
__dpmi_int(0x21,®s);
tb_i.segment=0;
dosmemget(tbOff,6,&tb_i);
close(fd);
printf("tb_i seg :%04x\n",tb_i.segment);
printf("tb_i size:%04x\n",tb_i.len);
localCopy=malloc(tb_i.len);
channelOff=tb_i.segment<<4;
return localCopy!=0;
}
void HandleBroadCast(Message *m)
{
printf("I got an unexpected broadcast type: %d\n",m->type);
}
int GetMessage(Message *m, int toAll=0)
{
int clear=0;
dosmemget(channelOff,sizeof(Message),m);
// Filter messages from me ;-) and to others
if (m->magic==MAGIC && m->from!=MyID && (m->to==MyID || m->to==TO_ALL))
{
if (m->size)
dosmemget(channelOff+sizeof(Message),m->size,localCopy);
// Clearing the magic I indicate the channel is free
_dosmemputl(&clear,1,channelOff);
if (!toAll && m->to==TO_ALL)
{
HandleBroadCast(m);
return 0;
}
return 1;
}
return 0;
}
void GetMessageWait(Message *m, int toAll=0)
{
while (!GetMessage(m,toAll));
}
int SendMessage(int type, time_t to=0, void *data=0, int size=0)
{
Message m;
// Check if the channel is in use
dosmemget(channelOff,sizeof(Message),&m);
if (m.magic==MAGIC)
return 0;
// Ok go ahead
m.type=type;
m.from=MyID;
if (to)
m.to=to;
else
m.to=OtherID;
m.magic=MAGIC;
m.size=size;
dosmemput(&m,sizeof(Message),channelOff);
if (data)
dosmemput(data,size,channelOff+sizeof(Message));
return 1;
}
void CleanBuffer(void)
{
Message m;
m.magic=0;
dosmemput(&m,sizeof(Message),channelOff);
}
long timeOut1=18*10;
void SendMessageWait(int type, time_t to, void *data=0, int size=0)
{
long t1=rawclock()+timeOut1;
while (!SendMessage(type,to,data,size) && rawclock()<t1);
if (rawclock()>=t1)
{
printf("Time out!");
CleanBuffer();
exit(1);
}
}
int StablishChannel(void)
{
Message m;
MyID=time(0);
long t1=rawclock()+timeOut1;
// Look if there are other application
do
{
if (GetMessage(&m,1))
{ // Yes!
if (m.type!=TM_REQCON)
{
printf("Error other copies are talking\n");
return 0;
}
OtherID=m.from;
SendMessageWait(TM_GRANTCON,OtherID);
return 1;
}
if (rawclock()>=t1)
{
printf("Time out!");
CleanBuffer();
exit(1);
}
}
while (!SendMessage(TM_REQCON,TO_ALL));
// Nobody so wait for one
GetMessageWait(&m);
I_Started=1;
// Yes!
if (m.type!=TM_GRANTCON)
{
printf("Error other copies are talking\n");
return 0;
}
OtherID=m.from;
return 1;
}
void SendChar(int c)
{
SendMessageWait(TM_ASCIICHAR,0,&c,4);
}
int GetChar(void)
{
Message m;
do
{
GetMessageWait(&m);
}
while (m.type!=TM_ASCIICHAR);
return *((int *)localCopy);
}
int main(int argc, char *argv)
{
printf("tb seg :%04x\n",__tb_segment);
printf("tb offs:%04x\n",__tb_offset);
printf("tb size:%04x\n",__tb_size);
if (!OpenChannel())
{
printf("No TSR loaded\n");
return 1;
}
printf("Waiting for another application\n");
if (!StablishChannel())
return 1;
printf("I found a clon! I'm so happy ;-)))\n");
setbuf(stdout,0);
int c;
if (I_Started)
{
printf("I born first so I'm the master ]:-), go on, type here\n");
do
{
c=getch();
SendChar(c);
if (c=='\r')
putc('\n',stdout);
else
putc(c,stdout);
}
while (c!=27);
}
else
{
printf("I'm an slave :-(, just look:\n");
do
{
c=GetChar();
if (c=='\r')
putc('\n',stdout);
else
putc(c,stdout);
}
while (c!=27);
}
return 0;
}
--Message-Boundary-7620--
- Raw text -