Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!mit-eddie!mintaka!olivea!samsung!usc!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!haven!umbc3!gmuvax2!2113av From: 2113av@gmuvax2.gmu.edu (John Porter) Newsgroups: comp.os.msdos.programmer Subject: Re: WANTED: list of useful BIOS locations Message-ID: <2867@gmuvax2.gmu.edu> Date: 10 Nov 90 07:06:55 GMT References: <90304.161727DLV101@psuvm.psu.edu> Reply-To: 2113av@gmuvax2.UUCP (John Porter) Organization: George Mason Univ. Fairfax, Va. Lines: 154 In article <90304.161727DLV101@psuvm.psu.edu> DLV101@psuvm.psu.edu (Dwaine VanBibber) writes: >I'm looking for all those neat memory locations and what they do. For Please allow me to suggest the following hack, devised by myself, for accessing the BIOS data area in an IBM-PC/compatible computer, from a C program. It works like this: A structure type is defined (NOT ALLOCATED!) to label each byte, word, etc. in the BIOS data area; a pointer is (theoretically) declared to point to a structure of this type; the pointer is initialized to zero (that's numerical 0000:0000, not logical NULL (for you purists (like me))). any dereference of this pointer looks for fields in the actual BIOS data area in low ram, including the interrupt vector table. That's why it starts at zero. I have provided a file, BIOSAREA.H, which does all this; just include it in your C source. Actually, this file does not declare a pointer; that would not be fair. Instead, I made a macro which, when given a field name, takes a ZERO long, casts it to be a pointer to one of these structs, and dereferences to the given field. Works as lvalue, in case you're wondering. Please be aware that this file was made by me, for me. If you don't like the way I've commented it, or other things, change them. If you have any questions, ask me. For example, you may have already defined a type byte, or word. If you don't think it's worth it to define another whole type for something so simple, by god, undo it. MOST IMPORTANT OF ALL!!!!! the compiler directive #pragma pack(1) ABSOLUTELY MUST BE IN EFFECT!!!! I'm sorry I couldn't take the time to comment each field; some of the names aren't very descriptive. If you don't know what a field is for, don't touch it. Generally speaking, any name starting with 'res' meanes that the best info I could find on that field gave no clue as to its purpose. If you find anything not included in this list, please let me know, I'll update this. Thanks. JP /* BIOSAREA.H * Allows easy access to the important data areas in low ram. * Note: the fields in the biosarea struct are in order, and should not * be shuffled. Also important is the pragma directive to align on byte * boundaries. * By John Porter, 1989. */ #ifndef BIOSAREA #define BIOSAREA typedef unsigned char byte; typedef unsigned int word; #pragma pack(1) struct biosarea { void int_vect[0x100]; // 00:00-30:FF word serport[4]; // 40:00-40:07 word ptrport[4]; // 40:08-40:0F word eqlist; // 40:10-40:11 byte POSTstat; // 40:12 NOTE: for PC Convertible only. word usable; // 40:13-40:14 byte res3[2]; // 40:15-40:16 word kbdstat; // 40:17-40:18 byte altkeypad; // 40:19 word kbdhead; // 40:1A-40:1B word kbdtail; // 40:1C-40:1D word kbdbuf[0x10]; // 40:1E-40:3D byte recalstat; // 40:3E byte motorstat; // 40:3F byte motorcount; // 40:40 byte floppyresult; // 40:41 byte floppystat[7]; // 40:42-40:48 byte vidmode; // 40:49 word rowlen; // 40:4A-40:4B word scrnsize; // 40:4C-40:4D word pageofs; // 40:4E-40:4F union { word w; // 40:50-40:5F struct { byte col, row; } b; } cursloc[8]; byte curscan2; // 40:60 byte curscan1; // 40:61 byte pageno; // 40:62 word crtport; // 40:63-40:64 byte crtportmode; // 40:65 // also called 3x8 Register setting byte cgacoloreg; // 40:66 // also called 3x9 Register setting byte tapectl[5]; // 40:67-40:6B // may be instead a far ptr to some reset code. dword masterclock; // 40:6C-40:6F byte midnight; // 40:70 byte ctlbrk; // 40:71 word bootflag; // 40:72-40:73 byte hdiskresult; // 40:74 byte harddisks; // 40:75 byte XThd; // 40:76 // Note: XT only byte XThdport; // 40:77 // " byte ptrtimout[4]; // 40:78-40:7B byte auxtimout[4]; // 40:7C-40:7F word kbdbufstart; // 40:80-40:81 word kbdbufend; // 40:82-40:83 byte scrnrows; // 40:84 word charheight; // 40:85-40:86 word vidstates; // 40:87-40:88 word vidinfo; // 40:89-40:8A byte mediacontrol; // 40:8B byte hdstat; // 40:8C byte hderror; // 40:8D byte hdint; // 40:8E byte res5_1; // 40:8F byte mediastate[2]; // 40:90-40:91 word res5_2; // 40:92-40:93 byte cylinder[2]; // 40:94-40:95 byte kbdflags; // 40:96 byte ledflags; // 40:97 vfp uwcfa; // 40:98-40:9B points to byte: User Wait Complete Flag dword uwaitcount; // 40:9C-40:9F byte waitactive; // 40:A0 byte res6[7]; // 40:A1-40:A7 vfp vidtbl; // 40:A8-40:AB a complex structure byte res7[4]; // 40:AC-40:AF byte res8[0x40]; // 40:B0-40:EF byte ica[0x10]; // 40:F0-40:FF byte int5stat; // 50:00 status of print-screen operation. byte res9[3]; // 50:01-50:03 byte drivemimic; // 50:04 byte resA[11]; // 50:05-50:0F word basicDS; // 50:10-50:11 vfp basiclockhdlr; // 50:12-50:15 in some version of ROM basic. vfp basicbrkhdlr; // 50:16-50:19 vfp basicdiskerrhdlr; // 50:1A-50:1D }; // a macro pseudofunction to reference a field of this structure: #define BA(F) ((*((struct biosarea *)0L)).F) // note that in the case of fields which are arrays, you can place the // square brackets inside OR outside the parens for BA: // BA(cursloc[0]) == BA(cursloc)[0] !!! #endif