CompuServe Thread

Forum unknown · Programming

#Opps!

21 messages in this thread
#14886From: Kevin GressApr 15, 1986 9:37 PM
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
#14964From: Bela Lubkin/SysopApr 16, 1986 2:27 AM
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
#15015From: Steve AllenApr 16, 1986 8:44 PM
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; }
#15033From: Bela Lubkin/SysopApr 16, 1986 11:11 PM
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
#15033From: Bela Lubkin/SysopApr 16, 1986 11:11 PM
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
#15015From: Steve AllenApr 16, 1986 8:44 PM
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; }
#15193From: Wayne DavisonApr 18, 1986 1:27 AM
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
#15194From: Bela Lubkin/SysopApr 18, 1986 1:30 AM
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
#15196From: Wayne DavisonApr 18, 1986 1:48 AM
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!!
#15205From: Bela Lubkin/SysopApr 18, 1986 2:24 AM
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
#15221From: John FoustApr 18, 1986 9:57 AM
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. 🙂
#15269From: Bela Lubkin/SysopApr 18, 1986 8:43 PM
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
#15269From: Bela Lubkin/SysopApr 18, 1986 8:43 PM
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
#15221From: John FoustApr 18, 1986 9:57 AM
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. 🙂
#15205From: Bela Lubkin/SysopApr 18, 1986 2:24 AM
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
#15196From: Wayne DavisonApr 18, 1986 1:48 AM
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!!
#15194From: Bela Lubkin/SysopApr 18, 1986 1:30 AM
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
#15193From: Wayne DavisonApr 18, 1986 1:27 AM
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
#15396From: Nick FrabottaApr 19, 1986 6:30 PM
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.
#15396From: Nick FrabottaApr 19, 1986 6:30 PM
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.
#14964From: Bela Lubkin/SysopApr 16, 1986 2:27 AM
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