Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!sun-barr!newstop!sun!imagen!qmsseq!pipkins From: pipkins@qmsseq.imagen.com (Jeff Pipkins) Newsgroups: comp.sys.ibm.pc Subject: Re: Need Help with ROM/empty address distinction Message-ID: <90@qmsseq.imagen.com> Date: 16 Jan 90 17:16:28 GMT References: <1990Jan15.162053.14109@ee.rochester.edu> Reply-To: pipkins@qmsseq.UUCP (Jeff Pipkins) Organization: QMS Inc., Mobile, Alabama Lines: 66 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.