⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 _pmsmx.asm

📁 AT91RM9200-U-Boot at91rm9200u-boot移植源代码
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        iret                    ; Return from interrupt

cprocend

;----------------------------------------------------------------------------
; PM_chainPrevTimer - Chain to previous timer interrupt and return
;----------------------------------------------------------------------------
; Chains to the previous timer interrupt routine and returns control
; back to the high level interrupt handler.
;----------------------------------------------------------------------------
cprocstart  PM_chainPrevTimer

ifdef   TNT
        push    eax
        push    ebx
        push    ecx
        pushfd                  ; Push flags on stack to simulate interrupt
        mov     ax,250Eh        ; Call real mode procedure function
        mov     ebx,[_PM_prevRealTimer]
        mov     ecx,1           ; Copy real mode flags to real mode stack
        int     21h             ; Call the real mode code
        popfd
        pop     ecx
        pop     ebx
        pop     eax
        ret
else
        SWAPSTK TmStack         ; Swap back to previous stack
        pushf                   ; Save state of interrupt flag
        pushf                   ; Push flags on stack to simulate interrupt
ifdef   USE_NASM
        call far dword [_PM_prevTimer]
else
        call    [_PM_prevTimer]
endif
        popf                    ; Restore state of interrupt flag
        SWAPSTK TmStack         ; Swap back to C stack again
        ret
endif

cprocend

; Macro to delay briefly to ensure that enough time has elapsed between
; successive I/O accesses so that the device being accessed can respond
; to both accesses even on a very fast PC.

ifdef   USE_NASM
%macro  DELAY 0
        jmp     short $+2
        jmp     short $+2
        jmp     short $+2
%endmacro
%macro  IODELAYN 1
%rep    %1
        DELAY
%endrep
%endmacro
else
macro   DELAY
        jmp     short $+2
        jmp     short $+2
        jmp     short $+2
endm
macro   IODELAYN    N
    rept    N
        DELAY
    endm
endm
endif

;----------------------------------------------------------------------------
; PM_rtcISR - Real time clock interrupt subroutine dispatcher
;----------------------------------------------------------------------------
; Hardware interrupt handler for the timer interrupt, to dispatch control
; to high level C based subroutines. We save the state of all registers
; in this routine, and switch to a local stack. Interrupts are *off*
; when we call the user code.
;
; NOTE: This routine switches to a local stack before calling any C code,
;       and hence is _not_ re-entrant. Make sure your C code executes as
;       quickly as possible, since a timer overrun will simply hang the
;       system.
;----------------------------------------------------------------------------
cprocfar    _PM_rtcISR

        push    ds                  ; Save value of DS
        push    es
        pushad                      ; Save _all_ extended registers
        cld                         ; Clear direction flag

; Clear priority interrupt controller and re-enable interrupts so we
; dont lock things up for long.

        mov     al,20h
        out     0A0h,al
        out     020h,al

; Clear real-time clock timeout

        in      al,70h              ; Read CMOS index register
        push    _ax                 ;  and save for later
        IODELAYN 3
        mov     al,0Ch
        out     70h,al
        IODELAYN 5
        in      al,71h

; Call the C interrupt handler function

        LOAD_DS                     ; Load DS register
        cmp     [BYTE RtcInside],1  ; Check for mutual exclusion
        je      @@Exit
        mov     [BYTE RtcInside],1
        sti                         ; Re-enable interrupts
        NEWSTK  RtcStack            ; Switch to local stack
        call    [CPTR _PM_rtcHandler]
        RESTSTK RtcStack            ; Restore previous stack
        mov     [BYTE RtcInside],0

@@Exit: pop     _ax
        out     70h,al              ; Restore CMOS index register
        popad                       ; Restore all extended registers
        pop     es
        pop     ds
        iret                        ; Return from interrupt

cprocend

;----------------------------------------------------------------------------
; PM_keyISR - keyboard interrupt subroutine dispatcher
;----------------------------------------------------------------------------
; Hardware interrupt handler for the keyboard interrupt, to dispatch control
; to high level C based subroutines. We save the state of all registers
; in this routine, and switch to a local stack. Interrupts are *off*
; when we call the user code.
;
; NOTE: This routine switches to a local stack before calling any C code,
;       and hence is _not_ re-entrant. However we ensure within this routine
;       mutual exclusion to the keyboard handling routine.
;----------------------------------------------------------------------------
cprocfar    _PM_keyISR

        push    ds              ; Save value of DS
        push    es
        pushad                  ; Save _all_ extended registers
        cld                     ; Clear direction flag

        LOAD_DS                 ; Load DS register

        cmp     [BYTE KyInside],1   ; Check for mutual exclusion
        je      @@Reissued

        mov     [BYTE KyInside],1
        NEWSTK  KyStack         ; Switch to local stack
        call    [CPTR _PM_keyHandler]   ; Call C code
        RESTSTK KyStack         ; Restore previous stack
        mov     [BYTE KyInside],0

@@Exit: popad                   ; Restore all extended registers
        pop     es
        pop     ds
        iret                    ; Return from interrupt

; When the BIOS keyboard handler needs to change the SHIFT status lights
; on the keyboard, in the process of doing this the keyboard controller
; re-issues another interrupt, while the current handler is still executing.
; If we recieve another interrupt while still handling the current one,
; then simply chain directly to the previous handler.
;
; Note that for most DOS extenders, the real mode interrupt handler that we
; install takes care of this for us.

@@Reissued:
ifdef   TNT
        push    eax
        push    ebx
        push    ecx
        pushfd                  ; Push flags on stack to simulate interrupt
        mov     ax,250Eh        ; Call real mode procedure function
        mov     ebx,[_PM_prevRealKey]
        mov     ecx,1           ; Copy real mode flags to real mode stack
        int     21h             ; Call the real mode code
        popfd
        pop     ecx
        pop     ebx
        pop     eax
else
        pushf
ifdef   USE_NASM
        call far dword [_PM_prevKey]
else
        call    [_PM_prevKey]
endif
endif
        jmp     @@Exit

cprocend

;----------------------------------------------------------------------------
; PM_chainPrevkey - Chain to previous key interrupt and return
;----------------------------------------------------------------------------
; Chains to the previous key interrupt routine and returns control
; back to the high level interrupt handler.
;----------------------------------------------------------------------------
cprocstart  PM_chainPrevKey

ifdef   TNT
        push    eax
        push    ebx
        push    ecx
        pushfd                  ; Push flags on stack to simulate interrupt
        mov     ax,250Eh        ; Call real mode procedure function
        mov     ebx,[_PM_prevRealKey]
        mov     ecx,1           ; Copy real mode flags to real mode stack
        int     21h             ; Call the real mode code
        popfd
        pop     ecx
        pop     ebx
        pop     eax
        ret
else

; YIKES! For some strange reason, when execution returns from the
; previous keyboard handler, interrupts are re-enabled!! Since we expect
; interrupts to remain off during the duration of our handler, this can
; cause havoc. However our stack macros always turn off interrupts, so they
; will be off when we exit this routine. Obviously there is a tiny weeny
; window when interrupts will be enabled, but there is nothing we can
; do about this.

        SWAPSTK KyStack         ; Swap back to previous stack
        pushf                   ; Push flags on stack to simulate interrupt
ifdef   USE_NASM
        call far dword [_PM_prevKey]
else
        call    [_PM_prevKey]
endif
        SWAPSTK KyStack         ; Swap back to C stack again
        ret
endif

cprocend

;----------------------------------------------------------------------------
; PM_key15ISR - Int 15h keyboard interrupt subroutine dispatcher
;----------------------------------------------------------------------------
; This routine gets called if we have been called to handle the Int 15h
; keyboard interrupt callout from real mode.
;
;   Entry:  AX  - Hardware scan code to process
;   Exit:   AX  - Hardware scan code to process (0 to ignore)
;----------------------------------------------------------------------------
cprocfar    _PM_key15ISR

        push    ds
        push    es
        LOAD_DS
        cmp     ah,4Fh
        jnz     @@NotOurs       ; Quit if not keyboard callout

        pushad
        cld                     ; Clear direction flag
        xor     ah,ah           ; AX := scan code
        NEWSTK  Ky15Stack       ; Switch to local stack
        push    _ax
        call    [CPTR _PM_key15Handler] ; Call C code
        _add    sp,2,4
        RESTSTK Ky15Stack       ; Restore previous stack
        test    ax,ax
        jz      @@1
        stc                     ; Set carry to process as normal
        jmp     @@2
@@1:    clc                     ; Clear carry to ignore scan code
@@2:    popad
        jmp     @@Exit          ; We are done

@@NotOurs:
ifdef   TNT
        push    eax
        push    ebx
        push    ecx
        pushfd                  ; Push flags on stack to simulate interrupt
        mov     ax,250Eh        ; Call real mode procedure function
        mov     ebx,[_PM_prevRealKey15]
        mov     ecx,1           ; Copy real mode flags to real mode stack
        int     21h             ; Call the real mode code
        popfd
        pop     ecx
        pop     ebx
        pop     eax
else
        pushf
ifdef   USE_NASM
        call far dword [_PM_prevKey15]
else
        call    [_PM_prevKey15]
endif
endif
@@Exit: pop     es
        pop     ds
        retf    4

cprocend

;----------------------------------------------------------------------------
; PM_breakISR - Control Break interrupt subroutine dispatcher
;----------------------------------------------------------------------------
; Hardware interrupt handler for the Ctrl-Break interrupt. We simply set
; the Ctrl-Break flag to a 1 and leave (note that this is accessed through
; a far pointer, as it may well be located in conventional memory).
;----------------------------------------------------------------------------
cprocfar    _PM_breakISR

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -