Forum unknown
· Programming
#Opps!
21 messages in this thread
I meant to leave the message in programming section but when I first put it
in, I saved it in Hardware section by accident – or should I confess and say
that I FAT FINGERED THE KEYBOARD! 3333333333 Well, your C doesnt look shaky
to me! I really dont understand but I will give it a shot. Can you put values
in the address that way to (POKE) or was that the command to look at the
address (PEEK). Seems strange I can build somthing for my computer but cant
write a program to control it!! Course I could do it in BASIC but yuk!!
thanks for your help. Kevin Gress 74326,143
The question did make sense for either the Hardware or Programming sections
— what I objected to was the fact that you posted it in both. No biggie…
Here are a bunch of peek & poke routines. I don't guarantee them, and I
figure there are probably better ways to do these things. Would some "real"
C programmer please check them and tell me that I haven't screwed up too
badly… or that I have?
char peek(address);
long address;
{
return *((char *) address);
}
int peekw(address);
long address;
{
return *((int *) address);
}
long peekl(address);
long address;
{
return *((long *) address);
}
void poke(address,value);
long address;
char value;
{
char *pointer;
pointer = (char *) address;
*address = value;
}
void pokew(address,value);
long address;
int value;
{
int *pointer;
pointer = (int *) address;
*address = value;
}
void pokel(address,value);
long address;
long value;
{
long *pointer;
pointer = (long *) address;
*address = value;
}
– Bela
On the Amiga there is some disagreement between C compilers about the length
of an int (may be 16 or 32 bits), but no disagreement about the length of a
short (always 16 bits) or a long (always 32 bits). Accordingly,
short peekw(address)
and
void pokew(address,value) long address; short value;
will tend to be more portable.
Also, can't you just say for poke(),
void poke(address,value)
long address;
char value;
{ *address = value;
}
Right, I thought of short vs. int a few minutes ago, as I was reading an old
issue of Programmer's Journal. Dumb mistake. As to poke, can you just
dereference a long like that? I'm sure you can, but I mean isn't there a
good reason to cast it to a pointer type? Tell me… I'm trying to learn C!
– Bela
Right, I thought of short vs. int a few minutes ago, as I was reading an old
issue of Programmer's Journal. Dumb mistake. As to poke, can you just
dereference a long like that? I'm sure you can, but I mean isn't there a
good reason to cast it to a pointer type? Tell me… I'm trying to learn C!
– Bela
On the Amiga there is some disagreement between C compilers about the length
of an int (may be 16 or 32 bits), but no disagreement about the length of a
short (always 16 bits) or a long (always 32 bits). Accordingly,
short peekw(address)
and
void pokew(address,value) long address; short value;
will tend to be more portable.
Also, can't you just say for poke(),
void poke(address,value)
long address;
char value;
{ *address = value;
}
Hi Bela. Your code looks like it will work (in Aztec where int == word), but
your routines are pretty scummy, even for C code. You are assuming that all
pointers are stored in a long (and in the Amiga you are right), but it is
better to avoid assumtions, and coerce the pointer in the call (it's usually
a compile-time function anyway), so that the values passed on the stack are
known to be of the correct length. What I'm trying to say looks like this:
char peek(address)
char *address;
{
return *address;
}
and
void poke(address,value)
char *address, value;
{
*address = value;
}
To be called by:
c = peek( (char *)num); or poke( (char *)num, c);
This makes sure that the correct value length (for a pointer) is passed onto
the stack without assumptions. However, the routines are SO simple, that
they should probably be code macros or inline code. Like:
#define pokew(ptr,x) ((short *)ptr = x)
#define peekl(ptr) ((long *)ptr)
(notice the lack of semi-colons in the definitions, since they are supplied
in the actual code they are substituting into. The extra parens help to keep
the item well grouped in any type of code). I hope at least some of this was
useful. –Wayne
Thanks, Wayne! This is why I'm more interested in going directly to assembler
than C… I >know< how assembler works. C is screwy. (Now I'm in for it!
<grin>) – Bela
No prob, Bela. I did realize, however, that your parameter passing
intentions were probably to give the functions a long literal rather than an
pre-existing pointer as an argument, so I may have called your code "scum"
unjustly. However, the aforementioned code macros do work for pointers and
non-pointers alike. If you're getting into C, the compile-time define
statements can come in real handy. –Wayne
P.S. C may be screwy, but just THINKING about using a strongly-typed lang.
like Modula-2 or Pascal gives me the willies! (But then, I'm a systems
software nut). Long live assembler!!
Yes, my intention was to be able to pass long literals for the addresses —
but your macros are obviously way better than anything else.
I've been using strongly typed Turbo Pascal for about two years now, and
it's great. Though it's strongly typed, it has all kinds of escape hatches
that let you circumvent the strong typing — it extends Pascal downward,
similar to how the proposed ANSI standard C would extend C upward with
function prototypes. Turbo lets you pass generic parameters, override types,
access memory directly, and anything else you can do in C — but not
unintentionally. Now if the Amiga version were only out… – Bela
Bela: It's kind of funny, the way you look at C vs. assembler. I see it the
other way: when I was learning C, and I didn't understand the way something
worked, I mentally translated it to assembler, as if C was a funny macro
language. Then all the *(*foo)()s made sense.
.
Then again, I didn't do much 8086 family assembler work until after I grokked
C, so my primary exposure to real-life-computer macro assembly languages and
architectures was the PDP-11 series, which certainly influenced C's design.
Maybe your problems are related to still thinking of things in segments. 🙂
No, it's not segments… I still think of stuff in linear address terms, and
then have to translate, when I'm working with 8088 assembly. Before I
learned 8088, I knew 6502 and Z80 very well, and VAX Macro pretty well… –
Bela
No, it's not segments… I still think of stuff in linear address terms, and
then have to translate, when I'm working with 8088 assembly. Before I
learned 8088, I knew 6502 and Z80 very well, and VAX Macro pretty well… –
Bela
Bela: It's kind of funny, the way you look at C vs. assembler. I see it the
other way: when I was learning C, and I didn't understand the way something
worked, I mentally translated it to assembler, as if C was a funny macro
language. Then all the *(*foo)()s made sense.
.
Then again, I didn't do much 8086 family assembler work until after I grokked
C, so my primary exposure to real-life-computer macro assembly languages and
architectures was the PDP-11 series, which certainly influenced C's design.
Maybe your problems are related to still thinking of things in segments. 🙂
Yes, my intention was to be able to pass long literals for the addresses —
but your macros are obviously way better than anything else.
I've been using strongly typed Turbo Pascal for about two years now, and
it's great. Though it's strongly typed, it has all kinds of escape hatches
that let you circumvent the strong typing — it extends Pascal downward,
similar to how the proposed ANSI standard C would extend C upward with
function prototypes. Turbo lets you pass generic parameters, override types,
access memory directly, and anything else you can do in C — but not
unintentionally. Now if the Amiga version were only out… – Bela
No prob, Bela. I did realize, however, that your parameter passing
intentions were probably to give the functions a long literal rather than an
pre-existing pointer as an argument, so I may have called your code "scum"
unjustly. However, the aforementioned code macros do work for pointers and
non-pointers alike. If you're getting into C, the compile-time define
statements can come in real handy. –Wayne
P.S. C may be screwy, but just THINKING about using a strongly-typed lang.
like Modula-2 or Pascal gives me the willies! (But then, I'm a systems
software nut). Long live assembler!!
Thanks, Wayne! This is why I'm more interested in going directly to assembler
than C… I >know< how assembler works. C is screwy. (Now I'm in for it!
<grin>) – Bela
Hi Bela. Your code looks like it will work (in Aztec where int == word), but
your routines are pretty scummy, even for C code. You are assuming that all
pointers are stored in a long (and in the Amiga you are right), but it is
better to avoid assumtions, and coerce the pointer in the call (it's usually
a compile-time function anyway), so that the values passed on the stack are
known to be of the correct length. What I'm trying to say looks like this:
char peek(address)
char *address;
{
return *address;
}
and
void poke(address,value)
char *address, value;
{
*address = value;
}
To be called by:
c = peek( (char *)num); or poke( (char *)num, c);
This makes sure that the correct value length (for a pointer) is passed onto
the stack without assumptions. However, the routines are SO simple, that
they should probably be code macros or inline code. Like:
#define pokew(ptr,x) ((short *)ptr = x)
#define peekl(ptr) ((long *)ptr)
(notice the lack of semi-colons in the definitions, since they are supplied
in the actual code they are substituting into. The extra parens help to keep
the item well grouped in any type of code). I hope at least some of this was
useful. –Wayne
Bela, for the most part (actually, they'll work) your right. But a more
esthetic way of doing it would be something like:
char peekc(address)
char *address;
{
return (*address);
}
short peekw(address)
short *address;
{
return(*address);
}
void pokew(addr, value)
short *addr;
int value; /* remember, anything shorter than int get converted to int
when passed as an argument */
{
*addr = value;
}
*OR* so you don't have to call a function….
define a structure like:
struct BYTE {
char byte;
};
with the above struct BYTE,
if you're talking hardware addresses, you can just
#define REGISTER 0xFF0000 /* or whatever */
then, just peek by:
a = (REGISTER)->byte;
and poke by:
(REGISTER)->byte = 1; /* set it to one. */
you should be able to do it with variables too, just substitute it
for REGISTER. You may have to cast the variable using something line
(woops, like)
((struct BYTE *) variable)->byte
if your compiler complains about 'separate structure space'.
Nick.
Bela, for the most part (actually, they'll work) your right. But a more
esthetic way of doing it would be something like:
char peekc(address)
char *address;
{
return (*address);
}
short peekw(address)
short *address;
{
return(*address);
}
void pokew(addr, value)
short *addr;
int value; /* remember, anything shorter than int get converted to int
when passed as an argument */
{
*addr = value;
}
*OR* so you don't have to call a function….
define a structure like:
struct BYTE {
char byte;
};
with the above struct BYTE,
if you're talking hardware addresses, you can just
#define REGISTER 0xFF0000 /* or whatever */
then, just peek by:
a = (REGISTER)->byte;
and poke by:
(REGISTER)->byte = 1; /* set it to one. */
you should be able to do it with variables too, just substitute it
for REGISTER. You may have to cast the variable using something line
(woops, like)
((struct BYTE *) variable)->byte
if your compiler complains about 'separate structure space'.
Nick.
The question did make sense for either the Hardware or Programming sections
— what I objected to was the fact that you posted it in both. No biggie…
Here are a bunch of peek & poke routines. I don't guarantee them, and I
figure there are probably better ways to do these things. Would some "real"
C programmer please check them and tell me that I haven't screwed up too
badly… or that I have?
char peek(address);
long address;
{
return *((char *) address);
}
int peekw(address);
long address;
{
return *((int *) address);
}
long peekl(address);
long address;
{
return *((long *) address);
}
void poke(address,value);
long address;
char value;
{
char *pointer;
pointer = (char *) address;
*address = value;
}
void pokew(address,value);
long address;
int value;
{
int *pointer;
pointer = (int *) address;
*address = value;
}
void pokel(address,value);
long address;
long value;
{
long *pointer;
pointer = (long *) address;
*address = value;
}
– Bela