movedata() function

newcastlenellie

Junior Member
Jan 14, 2006
20
0
0
hello, I'm (attempting) to write a driver for a motion control board for use in player/stage robot server.

player stage site

I have written most of the driver but cannot work out how to address the motion control card (which is fairly major!).
I have a programme which works in windows to interface with the motion controller car ( a PMC DCX PC100, its many many years old).

the code looks like this:

void dcxcmd(board,count,cmd,...)
int board,count,cmd;
{
int far *cmmdptr;

cmmdptr = &cmd; /* Set pointer to commands on PC stack. */
while(1)
{
/* Get present count from command block. */
movedata(DCXSEG+(board*0x100),CMDCNT,
FP_SEG(bytptr),FP_OFF(bytptr),1);
/* If count is nonzero, last command has not been processed by DCX. */
if (byt==0)
{
/* Move commands from PC stack to DCX dual port. */
movedata(FP_SEG(cmmdptr),FP_OFF(cmmdptr),
DCXSEG+(board*0x100),CMDBLK,count*6);
/* Set reply counter to 0. */
byt = 0;
movedata(FP_SEG(bytptr),FP_OFF(bytptr),
DCXSEG+(board*0x100),RPYCNT,1);
/* Set command counter tonumber of valid bytes in command block. */
byt = (unsigned char)count*6;
movedata(FP_SEG(bytptr),FP_OFF(bytptr),
DCXSEG+(board*0x100),CMDCNT,1);
return;
}
}
}



(sorry for the epic post this is turning into!)

How it works is buy moving bytes from the main system memory into 4kb of memory on the motion control card. Depending on where the data is put in the memory on the car changes what commands the card issues to the motors.

As you can see it uses the movedata() function, which I have been reliably informed is great for windows/dos, but does not work under Linux, and as Player runs in Linux that is a bit of a stumbling block. I am ok at programming but my no means an good. I was just wondering if anybody knew the equivalent command for Movedata() in Linux!

I have tried google, but only find where people say that movedata() is like memcpy() but memcpy is only for windows/dos too.

Thanks for any help offered!

again apologies for the epic post!

ps. should probably say that the motion control card is on the ISA bus!
 

Markbnj

Elite Member <br>Moderator Emeritus
Moderator
Sep 16, 2005
15,682
14
81
www.markbetz.net
I don't think it's a simple matter of finding an equivalent API routine. DOS has a number of memory management models available to it, and any code can access low memory by switching temporarily to protected mode. In Linux you have effectively a 32-bit version of tiny model on DOS, so you have 4 gigs of flat addess space. I'm not very expert on low-level tasks in Linux, but from some quick reading I think you'll have to add code to remap the area of memory you want into user mode, and rewrite the way addressing is calculated so that you have flat pointers, then use one of the memcpy-like routines from the C library.

Someone else here may be able to give you some more detailed advice.
 

tfinch2

Lifer
Feb 3, 2004
22,114
1
0
Originally posted by: newcastlenellie
I have tried google, but only find where people say that movedata() is like memcpy() but memcpy is only for windows/dos too.

memcpy is not Windows/Dos only.
 

newcastlenellie

Junior Member
Jan 14, 2006
20
0
0
tfinch2: apologies I believed the first site I read, my mistake, have now seen that it is a standard command in string.h

Reading the manual again, I says that the 4Kb of memory on the board is Dual Port Ram, and when it is plugged into an IBM-PC a portion of the DCX's memory appears in the PC's memory map. Having just checked the board it is set to occupy D0000h to D0fffh, with various offsets depending on the command issued.

There is a command buffer at address offset 901h - 9ffh, so if I write commands to here then they would be done by the board.

So if I use memcpy which has the format of

void *memcpy(void *dest, const void *src, size_t n);

the destination would be D0901h , how would I be able to know where the variables that I want to send to the buffer will be located (so that the Source address is known, or can C do this when it compiles automatically?!) and the the size would be dependant on the number of commands sent.

I fear I have shown my ignorance here which I apologise for.

If for example I wanted to send an integer to the buffer could I go:

int cmd;
cmd =8;
memcpy(D0901h, cmd, 1)

would that work, I know that that isnt very good code but is that the correct idea?

Thanks again for everything?

hope that makes sense!