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

📄 woarlm.asm

📁 Dos6.0
💻 ASM
📖 第 1 页 / 共 5 页
字号:
	mov     bx,OriginalDosBlockSize ;get the original size
	mov     ax,4a00h                ;resize call
	int     21h                     ;dos block resized

; now set back the original arena type.

	mov     ax,es                   ;currently pointing to the block
	dec     ax                      ;the arena segment
	mov     es,ax                   ;point to the arena
	mov     al,OriginalBlockType    ;get the actual arena type
	mov     es:[0],al               ;restore it

; now switch back to WOA PDB

	mov     bx,WoaPSP               ;WOA PDB segment
	mov     ax,5000h                ;set PDB call
	int     21h                     ;back to legal PDB

; we can now go back in protected mode and swap windows in.

	pop     ax                      ;get back exec code
	popf                            ;get back flags
	jc      @f                      ;if error, do not reset ax
	xor     ax,ax                   ;to signify that old app exited
	
@@:
	mov     bx,WoaInt15UsershApp    ;return ID of guy using INT 15
	ret

RealModeWoa     endp

;----------------------------------------------------------------------------;
;                        WOA HOOKED INTERRUPT HANDLERS                       ;
;----------------------------------------------------------------------------;

;----------------------------------------------------------------------------;
; Int1CISR:                                                                  ;
;                                                                            ;
; The Switcher hooks this interrupt to timeout Switch requests that cannot   ;
; be satisfied within a resonable frame of time. The number of timer ints    ;
; that we wait since a SwitchOut Request has been made is governed by a      ;
; constant.                                                                  ;
;                                                                            ;
; Also, if we are in the middle of a switch, we should reset the tickcount   ;
; and activate it again when we are done with the switch.                    ;
;----------------------------------------------------------------------------;

Int1CISR  proc far

	test    cs:[WoaHotkeyState],WOA_SWITCH
	jz      Int1CNoSwReq            ;no switch request has been registered

	inc     cs:[PendingTime]        ;we have seen one more tick

; have we waited long enough.

	cmp     cs:[PendingTime],TIMEOUT_TICK_COUNT
	jae     Int1CAbortSwitch        ;abort the switch.
	jmp     short ChainInt1COn      ;chain it on.

Int1CNoSwReq:

	mov     cs:[PendingTime],0      ;reset
	jmp     short ChainInt1COn      ;chain it on.

Int1CAbortSwitch:

; if we are in the process of switching, do not reset the hotkeystate.

	test    cs:[SwitchInProgress],SIP_SWITCHING
	jnz     ChainInt1COn            ;in the middle of switching

	mov     cs:[WoaHotkeyState],0   ;reset the switch request
	call    OEMBeep                 ;let user know about this

ChainInt1COn:

	jmp     cs:[ActualInt1C]        ;chain it on.

Int1CISR endp
;----------------------------------------------------------------------------;
; Int09ISR:                                                                  ;
;                                                                            ;
; This traps the keyboard hardware interrupt. It detects the types of keys   ;
; and sets flags when it detects the HOT KEYS. It also passes control to the ;
; original Int09 handler once it is done with the checkings.                 ;
;                                                                            ;
; We have a local list of HotKeys and each app in the shell stublet will have;
; it's own hotkeys. Both these lists have to be scanned.                     ;
;----------------------------------------------------------------------------;

Int09ISR  proc  far                     

; because of the hot key search, we might take some time in this routine. 
; we will enable interrupts here.

	sti                             ;enable interrupts      
	push    ds
	push    ax                      ;save callers data seg and ax

; if 'fNoSwitch' flag is set, simply chain on the interrupt.

	test    cs:[WoaBehavior],fNoSwitch;switch prevented ?
	jnz     ChainInt09ISR           ;chain on

; read the key and the scan code.

	xor     ax,ax                   ;need access to 0:
	mov     ds,ax                   ;DS points to seg at 0:

; read in the key code.

	in      al,60h                  ;al has the code for the key pressed

	mov     ah,ds:[KEYSTATE]        ;get the state flag
	and     ah,0fh                  ;mask off the unused bits

	smov    ds,cs                   ;get the code seg
	assumes ds,StubSeg

; we are assuming that we will not have any valid hotkey without SHIFT, CTRL
; or ALT. 

	jz      LeaveInt09ISR           ;can't be a hot key
	test    ah,3                    ;any shift key down ?
	jz      @f                      ;no
	or      ah,3                    ;both shift keys down
@@:


; try to find a match in the hotkey list

	pushem  ax,dx                   ;save
	call    MatchHotKeyList         ;try to match against know hotkeys
	popem   ax,dx                   ;restore scan code and shift state
	jnc     EndInt09ISR             ;a match was found, end the int

; we did not find a match in the hot key list, must chain the INT on.

LeaveInt09ISR:

; save the last key so that keys which need to check for the extended key
; sequences may look at it (like 0eh 37h  is PRTSC but just 37h is NUMPAD '*')

	mov     LastScanCode,al         ;save the last scan code

ChainInt09ISR:

	pop     ax
	pop     ds                      ;restore the registers
	assumes ds,nothing
	jmp     cs:[ActualInt09]        ;jump down the chain

EndInt09ISR:

	mov     LastScanCode,al         ;save the last scan code
	call    SwallowKey              ;eat up the interrupt
	pop     ax
	pop     ds                      ;restore the registers
	iret                            ;and go back

Int09ISR endp
;----------------------------------------------------------------------------;
; MatchLocalHotKeyList:                                                      ;
;                                                                            ;
; This takes a scan code in AL and a shift state in AH and looks for a match ;
; in the local hot key list. If a match is found, AL will return the switch  ;
; type and carry will be reset else carry will be set and AL will return 0.  ;
; This routine will also OR in the switch out flags if a match is found.     ;
;----------------------------------------------------------------------------;

MatchHotKeyList proc near

	assumes ds,StubSeg
	
	pushem  bx,cx,di,es             ;save
	smov    es,ds                   ;load our segment

; see if there is a match in the table of scan codes.

	mov     di,StubSegOFFSET ScanCodeTable
	mov     cx,MAX_NUM_PROGRAMS+MAX_FIXED_HOT_KEYS
	cld                             ;set proper direction flag

MHKL_Loop:

	repne   scasw                   ;look for a match
	jnz     MHKL_NoMatch            ;no match found

; get the index of the matching node.

	push    di                      ;save
	sub     di,2                    ;back over to the matching one
	.errnz  SIZE ScanCodeStruc - 2

	sub     di,StubSegOFFSET ScanCodeTable

; see if a prefix scan code is required and if it matches, if it does, get 
; the other details. Also, make sure that the key has not been disabled.

	shl     di,1                    ;offset into other table
	.errnz  SIZE HotKeyInfoStruc - 4
	add     di,StubSegOFFSET HotKeyInfoTable

; now there are two things to match here. The key must be enabled (that is,
; HKIS_State must be 0) and if the prefix scan code is not 0, it should match
; the LastScanCode.

	xor     bx,bx                   ;BL=enable state, BH needed for other
	mov     dx, wptr [di.HKIS_State];get enable flag and prefix scan code
	cmp     bh,dh                   ;carry set if DH is not 0
	sbb     bh,0                    ;BH=0 if DH = 0, else it is 0FFH
	and     bh,LastScanCode         ;BH = LastScanCode if DH !=0, else 0
	cmp     bx,dx                   ;do they match ?
	jnz     MHKL_Continue           ;no, look for another
	mov     dl,[di.HKIS_NodeNum]    ;logical node number

; if we are trying to hot-key to the current app, we should just pretend that
; the hot key did not match.

	cmp     dl,AppsLogicalNodeNum   ;is it the current app ?
	jz      MHKL_Continue           ;yes, look for another

	pop     bx                      ;balance the stack, don't need saved di

; we have found a hot key, get all the details.

	mov     al,[di.HKIS_Type]       ;type of the switch
	or      WoaHotkeyState,al       ;save the return value
	mov     WoaNodeToSwitchTo,dl    ;save the app's NodeID
	clc                             ;match obtained
	jmp     short MHKL_Ret          ;done.

MHKL_Continue:

	pop     di                      ;points after last match
	jcxz    MHKL_NoMatch            ;no more to search
	jmp     short MHKL_Loop         ;continue looking for more

MHKL_NoMatch:

	stc                             ;no match obtained

MHKL_Ret:

	popem   bx,cx,di,es             ;save
	ret

MatchHotKeyList endp
;----------------------------------------------------------------------------;
; PrepareAppHotKeyList:                                                      ;
;                                                                            ;
; This routine traverses the global switcher structure and fills in the table;
; of Scan codes and hotkey information in the two corresponding tables. This ;
; done once before starting the app and after every switch back to the app.  ;
;----------------------------------------------------------------------------;

PrepareAppHotKeyList proc near

	assumes ds,StubSeg

; first zero out the scan code and hotkey info tables that are specific to
; apps.

	push    es                      ;save
	cld
	smov    es,ds                   ;load our segment into es
	xor     ax,ax                   ;will zero out
	mov     di,StubSegOFFSET AppsScanCodeTable
	mov     cx,MAX_NUM_PROGRAMS * SIZE ScanCodeStruc
	rep     movsb                   ;zero out first table
	mov     di,StubSegOFFSET AppsHotKeyInfoTable
	mov     cx,MAX_NUM_PROGRAMS * SIZE HotKeyInfoStruc
	rep     movsb                   ;zero out first table

; now rebuild the tables.

	les     di,lpGlobalSwtchStr     ;get a pointer to the structure
	xor     bx,bx                   ;start at the top of the table
	mov     cx,MAX_NUM_PROGRAMS     ;number of entries
	mov     dl,SIZE Switch_Entry    ;size of each entry

; walk through the list gathering information about scan codes and hot keys.

	xor     ah,ah                   ;zero out for 'mul' below
	mov     al,es:[di].First_In_list;get the first entry
	mul     dl                      ;ax has the node offset
	lea     si,[di].Program_List    ;es:si points to the first program entry
	add     si,ax                   ;point to the right node.
	xor     dh,dh                   ;logical node number

PAHKL_Loop:

; stuff in the scan codes.

	mov     al,es:[si].HK_Scan_Code_2             ;second scan code
	mov     AppsScanCodeTable[bx.SCS_ScanCode],al ;save scan code.
	mov     al,es:[si].HK_Shift_State             ;get the shift state

; if any shift bit is set, set both.

	test    al,ST_RSHIFT+ST_LSHIFT                ;any shift set ?
	jz      @f                                    ;no.
	or      al,ST_RSHIFT+ST_LSHIFT                ;set both.
@@:
	mov     AppsScanCodeTable[bx.SCS_ShiftState],al ;save shift state


; save the rest of the information about the hotkeys in the other table

	shl     bx,1                                          ;index into the other table
	.errnz SIZE HotKeyInfoStruc - SIZE ScanCodeStruc * 2  ;assert the assumption
	mov     AppsHotKeyInfoTable[bx.HKIS_State],0          ;enabled
	mov     al,es:[si].HK_Scan_Code_1                     ;first scan code
	mov     AppsHotKeyInfoTable[bx.HKIS_PrefixScanCode],al;prefix scan code
	mov     AppsHotKeyInfoTable[bx.HKIS_NodeNum],dh       ;save shift state
	mov     AppsHotKeyInfoTable[bx.HKIS_Type],WOA_ALT_ESC ;type of switch

⌨️ 快捷键说明

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