It was thus said that the Great Cini, Richard once stated:
Hello, all:
I have another C issue that I can't seem to see the answer for, so I
thought I'd throw it out to the masses.
I'm deep into the Altair 680b emulation project (base code done,
working on telnet access) and I'm experiencing problems reading a file
stream into the memory array. Here's snippets of the code:
<SNIP>
First off, ``//'' is not a valid ANSI C-89 comment marker. I think it is
now allowed under ANSI C-99 but I haven't read the spec yet. I'll assume
your compiler allows it, since you are using it, but just forwarned---you
can't assume an ANSI-C compiler supports it (and yes, I've had problems with
that before).
byte *ppmem ; // pointer into memory array
byte ucMem[3*65536] ; // actual memory-see defines below for usage
Technically this should probably be:
byte ucMem[3ul * 65536ul];
// roms[] is an array of structures defining
start-time loaded ROMs. Only
one ROM now
//(the monitor PROM), but flexible enough to allow bank-switched ROMs (not applicable
//in the 680b but a leftover from the 6800 processor emulation code that was borrowed
//for the project)
//
//MEM_xxx are defines for the offset into the ucMem array to various areas
#define MEM_RAM 0
#define MEM_ROM 0x10000
#define MEM_FLAGS 0x20000
#define MEM_RAM 0ul
#define MEM_ROM 0x10000ul
#define MEM_FLAGS 0x2000ul
(sorry to be so pedantic, but it helps narrow down the problems)
// Read ROM directly to memory. This works.
ppmem = &ucMem[roms[i].iROMStart + MEM_ROM] ;
fread(ppmem, sizeof(byte), roms[i].iROMLen, pFH) ;
//this doesn't work...
//fread(&ucMem[roms[i].iROMStart + MEM_ROM], sizeof(byte), roms[i].iROMLen, pFH) ;
//...nor does this
//fread((char *)ucMem[roms[i].iROMStart + MEM_ROM], sizeof(byte), roms[i].iROMLen, pFH)
;
So here's where I'm missing it. Under all three fread scenarios, the
compiler doesn't throw a warning...they all compile cleanly. But only the
first works.
This sounds like one of those "What's the Bug" ads from DDJ. What am
I missing?
Make sure you are including stdio.h
#include <stdio.h>
in the file; that will bring in the prototype for fread():
size_t fread(const void *ptr,size_t size,size_t nobj,FILE *stream);
What type are
roms[].iROMStart
roms[].iROMLen
If they aren't of type size_t, then you might want to change them to that,
and see if they work then. I might be tempted to say you are triggering a
compiler bug but you would have to check the generated code to make sure.
You don't need the cast to (char *) in the third fread() example (since the
pointer to fread() is void *) since the conversion will go:
(void *((char *)ucMem...))
If my suggestions don't help, see if you can see the code its generating.
-spc (So far, have found one compiler bug (IRIX ANSI C compiler under IRIX
4.0.x) and one Standard C library bug (GLIBC 2.mumble for the
DEC Alpha architecture))