jal@ee.rochester.edu (John Lefor) (01/16/90)
I am trying to write a program which can tell me what is going at at various memory locations. I am trying to distinguish between RAM, ROM and nothing at all addresses. Now I have no problem distinguishing between RAM and ROM, but how do I distinguish between ROM and nothing. In my experiments nothing sometimes is read as the same hex data and other times the data changes between reads. ANy suggestions would be much appreciated. Thanks. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - I program ... therefore I am. John Lefor University of Rochester Dept of E. Engineering 716-275-8265 jal@ee.rochester.edu uunet!ur-valhalla!jal
emmo@moncam.co.uk (Dave Emmerson) (01/16/90)
In article <1990Jan15.162053.14109@ee.rochester.edu>, jal@ee.rochester.edu (John Lefor) writes: > [deleted] but how do I distinguish between > ROM and nothing. In my experiments nothing sometimes is read as the > same hex data and other times the data changes between reads. The problem is that empty memory is just that, you could literally read *any* valid bit pattern from *any* empty adrress *any* number of times on many systems. What you need is a method to force empty locations to a known state. The simplest, cheapest and safest method (which *should* be standard practice on any well-designed system) is to put a 10K ohm pull-up resistor on each data bus line. If your motherboard has an empty ROM socket (2 if it's an AT) it's an ideal place to fit them. All unused locations then show up as hex 'FF'. I won't go into detail, I suspect you want your software to work on any machine without modification. To do that, write known pseudo-random data to a small-ish area (16-256 bytes), read back and compare the results, and *store them too*. If it doesn't match, either it's not RAM, or something is overwriting it (an interrupt routine etc..), or it's empty. Now read it back again (a few times if necessary), this time comparing with the first readback. If it fails to re-match it's most likely empty, otherwise, unless it's all HEX FF's it's almost certainly ROM (probably, but not necessarily, a valid BIOS ROM). On other machines, I have found it worthwhile using different opcodes for the second and third passes, it seems like the data bus had enough capacitance to retain the last valid data for several uSec, so it always seemed to read the exact same data ( the last byte/word of the read instruction ). If you're using a high level language, this might be difficult. I haven't gotten my hands that dirty with a PC yet, so I can't offer any further suggestions. Hope that helps, Dave E.
pipkins@qmsseq.imagen.com (Jeff Pipkins) (01/17/90)
In article <1990Jan15.162053.14109@ee.rochester.edu> jal@ee.rochester.edu writes: >I am trying to write a program which can tell me what is going at >at various memory locations. I am trying to distinguish between >RAM, ROM and nothing at all addresses. Now I have no problem >distinguishing between RAM and ROM, but how do I distinguish between >ROM and nothing. In my experiments nothing sometimes is read as the >same hex data and other times the data changes between reads. The following code is an excerpt from a program similar to the one you describe. It works because of a convention set forth in the IBM AT Tech Ref. Manual that says what add-on rom modules must look like in order to be recognized by the BIOS. Because add-on rom is only allowed from C800:0000 to E000:0000, the following statement is used to call the check_rom() function: puts("\nChecking for added ROM from C8000 to E0000..."); check_rom((addr) 0xC0008000, (addr) 0xE0000000); Here is the code for check_rom(), along with a function that it needs: /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This routine checks for optional ROM code from "address" to "limit" * * * * Each 2K block from "address" up to "limit" has the potential to contain * * ROM. If ROM is present, the first word will be AA55 and the next byte * * will contain the number of 512 byte blocks. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ void check_rom(address, limit) unsigned int huge *address; unsigned int huge *limit; { unsigned int blocks; while (address < limit) { if (*address == 0xAA55) { blocks = *(address+1) & 0x00FF; printf(" %lX: %uK bytes.\n", adr8086(address), blocks>>1); address += (blocks * 512)/2; }else { address += 2048/2; } } } /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This function takes as input a 32-bit long and returns another 32-bit * * long that is the screwed-up 8086 address version. In other words, * * the high word is shifted left 4 bits and then added to the low word * * to produce a 20-bit address. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ unsigned long adr8086( adr) unsigned long adr; { return( ((adr>>12)&0x000FFFF0L) + (adr&0x0000FFFFL) ); } Any opinions expressed here (including the expression "screwed-up") are my own, and not necessarily shared by my employer. So there.
johne@hpvcfs1.HP.COM (John Eaton) (01/18/90)
<<< > but how do I distinguish between >ROM and nothing. In my experiments nothing sometimes is read as the >same hex data and other times the data changes between reads. ---------- Bus capacitance can be a big problem when trying to identify non-existant memory since you normally will read the last valid data on the buss. I once did a PC-compatible design using an 8086 that had several problems with this. It would randomly fail its POST by jumping into nonexistant ROM space. I traced it and found that it was reading a rom location to see if it was AA55. The code was such that when executed on a 8086 that the cycle before the read was a prefetch of the AA55 that the read was to be compared with. It passed! It then did a checksum on the "Rom" by adding all of its bytes to see if they sum to 00. This was done in a loop so that the value read was always the same value that was in the loop before the read. Since rom sizes were always a multiple of 256 bytes the sum always came out to 00. Many applications that search for memory rely on the program cycle accesses to trash the buss between the time they write something and read it back. We had seperated the 8 bit buss from the 16 bit cpu buss so that you could write a byte to the 8 bit buss and it would still be there the next time you did a 8 bit read. A lot of applications would think they found memory or I/O cards until we added circuitry to trash the buss between accesses. There are quite a few applications that search for the presence of a plug in card on the PC buss that really don't work in theory but work enough of the time that nobody notices. John Eaton !hpvcfs1!johne