Subversion Repositories shark

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * PC/HW routine collection v1.0 for DOS/DJGPP
 *
 *  Copyright (C) 2002 - Borca Daniel
 *  Email : dborca@yahoo.com
 *  Web   : http://www.geocities.com/dborca
 */


                .file   "pc_irq.S"

                .text

#define IRQ_STACK_SIZE  16384

#define IRQ_WRAPPER_LEN (__irq_wrapper_1-__irq_wrapper_0)
#define IRQ_OLD         (__irq_old_0-__irq_wrapper_0)
#define IRQ_HOOK        (__irq_hook_0-__irq_wrapper_0)
#define IRQ_STACK       (__irq_stack_0-__irq_wrapper_0)

                .balign 4
common:
                movw    $0x0400, %ax
                int     $0x31

                movl    %ss:8(%ebp), %ebx
                cmpl    $15, %ebx
                jbe     0f
        fail:
                orl     $-1, %eax
                popl    %edi
                popl    %ebx
                leave
                ret

        0:
                movl    %ebx, %edi
                imull   $IRQ_WRAPPER_LEN, %edi
                addl    $__irq_wrapper_0, %edi

                cmpb    $7, %bl
                jbe     1f
                movb    %dl, %dh
                subb    $8, %dh
        1:
                addb    %dh, %bl
                ret

                .balign 4
                .global _pc_install_irq
_pc_install_irq:
                pushl   %ebp
                movl    %esp, %ebp
                pushl   %ebx
                pushl   %edi

                call    common

                cmpl    $0, IRQ_HOOK(%edi)
                jne     fail

                pushl   $IRQ_WRAPPER_LEN
                pushl   %edi
                call    __go32_dpmi_lock_code
                addl    $8, %esp
                testl   %eax, %eax
                jnz     fail

                pushl   $IRQ_STACK_SIZE
                call    _pc_malloc
                popl    %edx
                testl   %eax, %eax
                jz      fail
                addl    %edx, %eax
                movl    %eax, IRQ_STACK(%edi)

                movl    %ss:12(%ebp), %eax
                movl    %eax, IRQ_HOOK(%edi)

                movw    $0x0204, %ax
                int     $0x31
                movl    %edx, IRQ_OLD(%edi)
                movw    %cx, IRQ_OLD+4(%edi)
                movw    $0x0205, %ax
                movl    %edi, %edx
                movl    %cs, %ecx
                int     $0x31

        done:
                xorl    %eax, %eax
                popl    %edi
                popl    %ebx
                leave
                ret

                .balign 4
                .global _pc_remove_irq
_pc_remove_irq:
                pushl   %ebp
                movl    %esp, %ebp
                pushl   %ebx
                pushl   %edi

                call    common

                cmpl    $0, IRQ_HOOK(%edi)
                je      fail

                movl    $0, IRQ_HOOK(%edi)

                movw    $0x0205, %ax
                movl    IRQ_OLD(%edi), %edx
                movl    IRQ_OLD+4(%edi), %ecx
                int     $0x31

                movl    IRQ_STACK(%edi), %eax
                subl    $IRQ_STACK_SIZE, %eax
                pushl   %eax
                call    _free
                popl    %eax

                jmp     done

#define WRAPPER(x)                                                         ; \
                .balign 4                                                  ; \
__irq_wrapper_##x:                                                         ; \
                pushal                                                     ; \
                pushl   %ds                                                ; \
                pushl   %es                                                ; \
                pushl   %fs                                                ; \
                pushl   %gs                                                ; \
                movl    %ss, %ebx                                          ; \
                movl    %esp, %esi                                         ; \
                movl    %cs:___djgpp_ds_alias, %ss                         ; \
                movl    %cs:__irq_stack_##x, %esp                          ; \
                pushl   %ss                                                ; \
                pushl   %ss                                                ; \
                popl    %es                                                ; \
                popl    %ds                                                ; \
                movl    ___djgpp_dos_sel, %fs                              ; \
                pushl   %fs                                                ; \
                popl    %gs                                                ; \
                call    *__irq_hook_##x                                    ; \
                movl    %ebx, %ss                                          ; \
                movl    %esi, %esp                                         ; \
                testl   %eax, %eax                                         ; \
                popl    %gs                                                ; \
                popl    %fs                                                ; \
                popl    %es                                                ; \
                popl    %ds                                                ; \
                popal                                                      ; \
                jz      __irq_ignore_##x                                   ; \
__irq_bypass_##x:                                                          ; \
                ljmp    *%cs:__irq_old_##x                                 ; \
__irq_ignore_##x:                                                          ; \
                iret                                                       ; \
                .balign 4                                                  ; \
__irq_old_##x:                                                             ; \
                .long   0, 0                                               ; \
__irq_hook_##x:                                                            ; \
                .long   0                                                   ; \
__irq_stack_##x:                                                           ; \
                .long   0

                WRAPPER(0);
                WRAPPER(1);
                WRAPPER(2);
                WRAPPER(3);
                WRAPPER(4);
                WRAPPER(5);
                WRAPPER(6);
                WRAPPER(7);
                WRAPPER(8);
                WRAPPER(9);
                WRAPPER(10);
                WRAPPER(11);
                WRAPPER(12);
                WRAPPER(13);
                WRAPPER(14);
                WRAPPER(15);