delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/05/03/01:37:04

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

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:







- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019