From: boylesgj AT lion DOT cs DOT latrobe DOT edu DOT au (Gregary J Boyles) Newsgroups: comp.os.msdos.djgpp Subject: Help needed with ISR wrapper design. Date: 2 May 1997 14:44:59 GMT Organization: Comp.Sci & Comp.Eng, La Trobe Uni, Australia Lines: 208 Distribution: world Message-ID: <5kculb$quo@lion.cs.latrobe.edu.au> NNTP-Posting-Host: lion.cs.latrobe.edu.au To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk I have attempted to emulate Alaric Williams's ISR wrappers. I have consulted his source file wrappers.s and an example key board handler by Martynas Kunigelis. In the example key board handler Martynas appears to put all his data and code in the .text section, which I assume corresponds to the code segment. He surrounds it with two labels (start_lock_region & end_lock_region) and locks the whole lot as follows: leal start_lock_region, %ecx leal end_lock_region, %edi subl %ecx, %edi addl ___djgpp_base_address, %ecx shldl $16, %ecx, %ebx shldl $16, %edi, %esi movw $0x0600, %ax # lock linear region int $0x31 Now I assume ___djgpp_base_address corresponds to the our_ds in your wrappers.s and that in my initialization function I will have to do the following: extern short int our_ds; our_ds=_my_ds(); so that the above locking will work properley. Also I will have to add an addition function down the bottom to do this locking and I will have to call this function from my initialization function. How am I doing so far? isr_address is used to store the address of the new ISR so that it can be called from the wrapper. Now I will have to load this variable from the data members of the _go32_dpmi_seginfo struct, which _dpmi_get_protected_mode_interrupt_vector(...) fills in, from my install ISR function. I am unsure of which data members or how. Could you write a short C++ code segment to show me how to do it? Obviously my C code which controls this whole thing will have to keep track of which wrappers are currently in use etc etc etc. What purpose do .align directives fulfill and should you use .align 2or .align 4? Can you see any other errors below? /* File wrappers.s Provides locked wrappers for user defined ISR's. The design is based upon Alaric.B.William's Hardware Interrupt Handling Library and an example key board handler by Martynas Kunigelis. */ .text .align 2 start_lock_region: .align 2 .globl our_ds our_ds: .word 0 .align 2 stack_size .long 100*1024 // Macro to generate a number of wrappers. #define MAKE_WRAPPER(ID) // Address of the old ISR .align 2 .globl isr_address_##ID isr_address_##ID: .long 0 // A 100K stack for the ISR. .align 2 start_stack_##ID: .space stack_size,0 end_stack_##ID: // The wrapper code. .align 2 .globl isr_wrapper_##ID isr_wrapper_##ID: // Save the flags and all clobbered registers. pushal pushw %ds pushw %es pushw %fs pushw %gs pushl %eax pushl %ebx pushl %ecx .byte 0x2e // When the ISR is called the data registers may contain // the address of some other data segment so we need to // copy the address of our data segment into them. movw our_ds,%ax movw %ax,%ds movw %ax,%es movw %ax,%fs movw %ax,%gs // The current stack may not be big enough so we need to // change to the one defined above. // Copy the registers ss and sp (the current stack) to // registers bx and ecx. movw %ss,%bx movl %esp,%ecx // The new stack is located in our data segment (which is // currently loaded in register ax) so we need the address // of our data segment to register sp. movw %ax,%ss // Now we need to copy the address of the end of our stack // to register ss. movl $end_stack_##ID,%esp // Save the old contents of registers ss and esp on the new // stack. pushw %bx pushl %ecx // Copy the address of the new ISR to register ax and call it. movl isr_address_##ID,%eax call *%eax // Retrieve the old contents of registers ss and esp from the // new stack into the registers bx and ecx. popl %ecx popw %bx // Restore the original contents of registers ss and esp. movw %bx,%ss movl %ecx,%esp // Restore the original contents of all clobbered registers. popl %ecx popl %ebx popl %eax popw %gs popw %fs popw %es popw %ds popal // Re-enable interrupts and return. sti iret // The actual wrappers. MAKE_WRAPPER(1) MAKE_WRAPPER(2) MAKE_WRAPPER(3) MAKE_WRAPPER(4) MAKE_WRAPPER(5) MAKE_WRAPPER(6) MAKE_WRAPPER(7) MAKE_WRAPPER(8) MAKE_WRAPPER(9) MAKE_WRAPPER(10) .align 2 start_lock_region: