From: "John S. Fine" Newsgroups: comp.os.msdos.djgpp Subject: Re: Nasm and real-mode ISRs (bimodal) Date: Mon, 26 Jul 1999 16:21:41 -0400 Lines: 98 Message-ID: <379CC355.D47@erols.com> References: <379739de DOT 5187825 AT news DOT ntplx DOT com> <37987832 DOT ADD AT erols DOT com> <379858cf DOT 153478 AT news DOT ntplx DOT com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: 4ORDiqXERS6OoOQUaIVn67YSmXqkXuz9FZX+na3PTCU= X-Complaints-To: abuse AT rcn DOT com NNTP-Posting-Date: 26 Jul 1999 20:23:45 GMT X-Mailer: Mozilla 3.01 (Win95; U) To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com Rock wrote: > vectors. I'm copyig the code into my DOS mem, for which I have a > segment and a 0 offset. I'm then using this segment:offset to set the > real-mode vector via the DPMI. Now since I've told the DPMI that the > offset is zero, shouldn't I get CS = segment and ip = 0 when my ISR > gets called? Yes. > If the vector was set the way I told it, then cs SHOULD > be coming in pointing right to my routine/DOS mem. Yes, but that doesn't mean what you think it means. On entry to your ISR, IP is zero and CS is the segment to which you moved your ISR; However, and use in your asm code of any of its own labels won't give a value relative to that segment. Instead it will give a value relative to wherever your 16-bit code was originally loaded within the 32-bit program (excepting "relative" jumps and calls which are "position independent"). > > One solution I do understand is to assemble your module > >through NASM twice: . . . > Yikes. Kind of lost me here. I'll put this on hold for now. Sorry, to hear that, because the double assembly is probably the easiest solution. > > None of the limits are in the tools. The difficulties are inherent > >in your decision to load a chunk of 16-bit code as part of a 32-bit > >program > My decision? Is there another way to do bi-modal interrupts without > copying the real-mode isr? Not that I know of. I guess you're right. Either DJGPP or its documentation, or my understanding of it, is limited because it is not obvious how to create a "private" segment. I was reacting mainly to your complaints about NASM. I still don't think anything in the NASM design is making any aspect of this problem harder. > I just do that because that's how Watcom does it. I don't know how Watcom does it. I assume they have more obvious support for private segments, but I can't even guess how they distinguish between the address of the load copy of the ISR as viewed from the 32-bit code and the internal addresses of the relocated isr as viewed by itself. Even Intel OMF format has no right way to do that. (Unless you mean 16-bit DPMI, in which case there is a clear right answer). > only reason I added the real-mode isr was because the program was > crashing without it from some RMCB. Now it still crashes, but with a > different problem. I think I know why, but don't how to fix it. Any > ideas? First idea is that you don't need a real-mode isr at all. You just need to fix that bug in your protected mode isr (which is probably the register use bug you already identified). > My protected mode ISR is using data from the standard DS segment, as > well as data from low memory (i.e. my DOS memory). I'm loading es for > the DOS selector, and WAS assuming that DS always pointed to the > program's 'default' data section. But with DJGPP, that isn't true. I doubt that it would be true in any DPMI system. > it gets called. I guess I need to load ds with the default DS > selector, but how can I do that. Re-ask just that question here (or search dejanews). I don't remember the answer, but the question has been asked and answered here before. (It might even be in the FAQ). > The nasm docs says that you never have to change selectors, especially > using DJGPP. Are they on drugs?!??!?! If you were totally precise in any piece of documentation (covered every exception case) your documentation would all be impossible to understand. What you read was written to support people writing subroutines to be called directly from C. Writing interrupt service routines is a whole different activity and the normal rules don't apply. However, I think there is something in the FAQ about wrapper routines in the DJGPP library that handle all that for you. If you use those rather than setting up the interrupt directly, you could even write the interrupt service routine in C. If you can write it in C then you can also write it in NASM with all the register use assumptions in the NASM/DJGPP documentation. --- http://www.erols.com/johnfine/ http://www.geocities.com/SiliconValley/Peaks/8600/