Solved

How to write to memory.

Posted on 1997-05-07
11
306 Views
Last Modified: 2012-08-13
I am using an I/O card and can write to it in basic at address 0300h.
I have tried writing this:

char *p;
p = 0x300;
p[i]=mydata

but the compiler does not let an address be asigned an integer.

How can I poke a byte to a defined address in memory ?
I really need to access 300, 301, 302 etc,
so the array pointer approach would be quite useful.
I am new to C so this may be quite obvious.
0
Comment
Question by:Carlos032497
  • 4
  • 3
  • 3
  • +1
11 Comments
 

Expert Comment

by:phillips
ID: 1250276
What you can do is enlarge an specific variable into an specific address in memory with realloc. Something like:

  char *p;
  p=0x300;
  realloc(p, sizeof(char));

But this will work only if the position 0x300 in memory is not busy or protected. Be careful with that.

I hope this will help you

--phillips
0
 
LVL 1

Expert Comment

by:prc
ID: 1250277
What kind of rubbish is this?  'realloc' is to change the size of a malloc'ed block!  Or is it some sort of surrealist joke that I'm missing?

To the questioner.  From the address, I suspect you actually want to do an IO read/write, which means you have to use special functions 'inp' and 'outp'.  Check them out in your development system docs (I assume you're using a 16-bit DOS compiler, otherwise it's going to get difficult).  It would go something like:

  outp(0x300+i, mydata);

If you really want to do a memory read/write, you're on the right track.  All you have to do is force the compiler to do what you want with a cast, like this:

p=(char *)0x300;

If this is you want, reject the above answer and ask me to enter a null answer to give me the points.
0
 

Author Comment

by:Carlos032497
ID: 1250278
phillips, thank you for your answer. I do not believe it will work
though. Sorry.....miss.
prc I like your answer, but would like to try it. I will be happy to give you the points then. Your asumptions are right. Please enter your null answer.
0
 

Author Comment

by:Carlos032497
ID: 1250279
I have tried

 outp(0x300+i, mydata);

although this does compile, the result is wrong. I have checked the documentation and outp(port, data) is the right syntac.
This does not work. Please try again.
0
 
LVL 4

Expert Comment

by:jos010697
ID: 1250280
prc is right in two ways: using reallic is idiotic and calling
function outp() is the way to go if you want to write
bytes to an I/O channel. Show us your BASIC program
(just the relevant parts please) and I'm sure one of us can
translate it to the equivalent C stuff ...

kind regards,

Jos

ps. I won't steal the answer away from prc ;-)
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Expert Comment

by:prc
ID: 1250281
You'll have to reject the answer that is locking the question to get any further with this.  I agree with 'jos', let's see the BASIC.

jos - My main concern here is to kill off completely stupid answers like the above, which are becoming depressingly frequent - if you can solve the guy's problem, you're welcome to the points.


0
 
LVL 4

Expert Comment

by:jos010697
ID: 1250282
My guess is that it's not the outp() stuff that's causing
the problems; if it works in BASIC it should work in C;
I guess it's the C stuff itself that goofs (Carlos admitted
he's new to C, so ...)

Let's just sit back and wait for the BASIC ;-)

kind regards,

Jos

ps. I still won't take those points; my parents raised me (long ago)
this way to be polite (and I'm still suffering from it ;-)

0
 

Author Comment

by:Carlos032497
ID: 1250283
Here is the basic programme, which tests the I/O card.

10 bASEADD% = &H300
20 OUT bASEADD% + 3, 128
25 FOR J = 1 TO 10
30 OUT bASEADD%, &HFF
40 OUT bASEADD% + 1, &HFF
50 OUT bASEADD% + 2, &HFF
60 PRINT "LOGIC 1"
70 GOSUB 140
80 OUT bASEADD%, 0
90 OUT bASEADD% + 1, 0
100 OUT bASEADD% + 2, 0
110 PRINT "LOGIC 0"
120 GOSUB 140
130 NEXT J
135 END
140 FOR i = 1 TO 10000
150 NEXT i
160 RETURN

line 20 sets the card to output. The program then
outputs FF to set all bits in 3 bytes to 1. Then
writes all zeros. Once I can access the card I can
extend the program to application.

I have marked the original answer as F.
How else can I reject the answer?
0
 
LVL 4

Expert Comment

by:jos010697
ID: 1250284
Here's a line by line translation of your BASIC program:

/* 10 bASEADD% = &H300  */
int main() {

void gosub140(void);
int bASEADD = 0x300;
int j;

/* 20 OUT bASEADD% + 3, 128 */
outp(bASEADD+3, 128);

/* 25 FOR J = 1 TO 10 */
for (j= 1; j <= 10; j++) {

/* 30 OUT bASEADD%, &HFF */
outp(bASEADD, 0xff);

/* 40 OUT bASEADD% + 1, &HFF */
outp(bASEADD, 0xff);

/* 50 OUT bASEADD% + 2, &HFF */
outp(bASEADD+2, 0xff);

/* 60 PRINT "LOGIC 1"  */
printf("LOGIC 1\n");

/* 70 GOSUB 140 */

gosub140();

/* 80 OUT bASEADD%, 0 */
outp(bASEADD, 0);

/* 90 OUT bASEADD% + 1, 0 */
outp(bASEADD+1, 0);

/* 100 OUT bASEADD% + 2, 0 */
outp(bASEADD+2, 0);

/* 110 PRINT "LOGIC 0"  */
printf("LOGIC 0\n");

/* 120 GOSUB 140 */
gosub140();

/* 130 NEXT J */
}

/* 135 END */
return 0;

}

/* 140 FOR i = 1 TO 10000 */
/* 150 NEXT i  */
/* 160 RETURN  */

void gosub140() {

int i;

for (i= 1; i < 10000; i++)
   ;

}

Note that this type of delay is extremely unreliable; it depends
on your machine, your clock, other processes, and sometimes
even the face of the moon ... ;-)

kind regards,

Jos

ps. Wait for prc to submit his (empty?) answer and grade him
  for this, 'cause he came up with the essential clues to the
  answer of your question.
0
 
LVL 1

Accepted Solution

by:
prc earned 50 total points
ID: 1250285
That's very nice, thank you.  There should be a way of splitting the points between exports, I think.

Just so it doesn't seem I'm getting something for nothing, jos is right that that kind of delay in C is very dubious.  Of course, 10000 loops in C are a hell of a lot faster than BASIC, anyway, but as written, a good optimising compiler can (and will) remove that loop entirely, on the basis that it doesn't do anything, and no-one is interested in the value of 'i' at the end of it.

To ensure that it doesn't throw the loop away, you have to make 'i' volatile, which says "I know something magic about this which means you can't optimise it".

So, the last bit should be

void gosub140()
{
  volatile int i;

  for (i= 0; i < 10000; i++)
    ;

}

Note that I start from zero - as written it only does 9999 loops (sorry to nitpick, jos!).  You could also use <= to make it more like the BASIC, but counting from zero is the standard way in C.

If you want a delay longer than a tenth of a second, you can use 'clock()' to get an exact time which will work whatever the speed of your processor.

Try this:

void gosub140()
{
  clock_t start = clock();

  /* Delay for half a second */
  while (clock() < start + CLOCKS_PER_SEC/2)
   ;
}
 
While on the subject of volatile, I forgot to say that if you use a 'char *' to write to memory, this ought to be volatile as well, otherwise the compiler might say, "I'm writing two values to the same place here - I'll just do the last one".  Doesn't look like you need to do this, though.

Cheers

Paul

0
 

Author Comment

by:Carlos032497
ID: 1250286
Well guys. I am impressed. I tried the program and it worked first time. The leds are flashing merrily. Now the real work begins.

I am sorry that jos does not get more credit for this as his coding was good, bar the small coding error on line 40.

Thanks for your help. Good job.

I shall be back!
0

Featured Post

Top 6 Sources for Identifying Threat Actor TTPs

Understanding your enemy is essential. These six sources will help you identify the most popular threat actor tactics, techniques, and procedures (TTPs).

Join & Write a Comment

Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now