raw_vcpi.asm
来自「开放源码的编译器open watcom 1.6.0版的源代码」· 汇编 代码 · 共 2,338 行 · 第 1/5 页
ASM
2,338 行
;
;Check if Windows enhanced mode has been started.
;
assume ds:nothing
cmp cs:InWindows,0
assume ds:_cwRaw
jz rv30_Normal
popf
retf
;
rv30_Normal:
push ax
push bp
push ds
mov ax,_cwRaw
mov ds,ax
mov bp,sp
mov ax,[bp+2+2+2+2] ;get return address
mov RetAdd,ax
mov ax,[bp+2+2+2] ;get flags
mov [bp+2+2+2+2],ax ;ovewrite return address.
mov StackAdd,bp
add StackAdd,2+2+2+2+2 ;correct for stacked registers.
mov StackAdd+2,ss
pop ds
pop bp
pop ax
add sp,2 ;remove local return address.
;
push eax
push ebx
push ecx
push edx
push esi
push edi
push ebp
push ds
push es
push fs
push gs
mov ax,_cwRaw
mov ds,ax ;make our data addresable.
mov es,ax
mov fs,ax
mov gs,ax
mov VCPI_SP,sp
mov VCPI_SP+2,ss
;
;Check if this call back is int &| busy.
;
mov ax,RetAdd ;get return address.
sub ax,CallBackSize ;back to start of call back entry.
sub ax,offset CallBackList ;offset from start of list.
xor dx,dx
mov bx,CallBackSize
div bx ;entry number.
mov bx,size CallBackStruc
mul bx ;get offset into table.
mov bx,offset CallBackTable
add bx,ax ;point to this entry.
;
;switch to protected mode.
;
mov cx,KernalSS
mov edx,RawStackPos
sub RawStackPos,RawStackDif
call Real2Protected
;
mov ax,RetAdd ;get return address.
sub ax,CallBackSize ;back to start of call back entry.
sub ax,offset CallBackList ;offset from start of list.
jz rv30_zero
xor dx,dx
mov bx,CallBackSize
div bx ;entry number.
rv30_zero: mov bx,size CallBackStruc
mul bx ;get offset into table.
mov bx,offset CallBackTable
add bx,ax ;point to this entry.
movzx esi,w[VCPI_SP+2] ;point to stacked registers.
shl esi,4
movzx eax,w[VCPI_SP]
add esi,eax
mov ax,KernalZero ;/
mov fs,ax ;/
;
les edi,CallBackStruc.CallBackRegs[bx] ;get register structure.
mov ax,fs:[esi]
mov es:RealRegsStruc.Real_GS[edi],ax
mov ax,fs:[esi+2]
mov es:RealRegsStruc.Real_FS[edi],ax
mov ax,fs:[esi+4]
mov es:RealRegsStruc.Real_ES[edi],ax
mov ax,fs:[esi+6]
mov es:RealRegsStruc.Real_DS[edi],ax
mov eax,fs:[esi+8]
mov es:RealRegsStruc.Real_EBP[edi],eax
mov eax,fs:[esi+12]
mov es:RealRegsStruc.Real_EDI[edi],eax
mov eax,fs:[esi+16]
mov es:RealRegsStruc.Real_ESI[edi],eax
mov eax,fs:[esi+20]
mov es:RealRegsStruc.Real_EDX[edi],eax
mov eax,fs:[esi+24]
mov es:RealRegsStruc.Real_ECX[edi],eax
mov eax,fs:[esi+28]
mov es:RealRegsStruc.Real_EBX[edi],eax
mov eax,fs:[esi+32]
mov es:RealRegsStruc.Real_EAX[edi],eax
mov ax,fs:[esi+36]
mov es:RealRegsStruc.Real_Flags[edi],ax
mov ax,RetAdd
mov es:RealRegsStruc.Real_IP[edi],ax
mov ax,_cwRaw
mov es:RealRegsStruc.Real_CS[edi],ax
mov ax,StackAdd
mov es:RealRegsStruc.Real_SP[edi],ax
mov ax,StackAdd+2
mov es:RealRegsStruc.Real_SS[edi],ax
;
test BYTE PTR RawSystemFlags,1
jz rv30_Use32Bit12
mov ax,w[CallBackStruc.CallBackProt+4+bx]
mov w[rv30_CallB0+2],ax
mov eax,d[CallBackStruc.CallBackProt+bx]
mov w[rv30_CallB0],ax
jmp rv30_Use16Bit12
rv30_Use32Bit12: mov ax,w[CallBackStruc.CallBackProt+4+bx]
mov w[rv30_CallB0+4],ax
mov eax,d[CallBackStruc.CallBackProt+bx]
mov d[rv30_CallB0],eax
rv30_Use16Bit12: push bx ;save call back structure pointer.
;
rv30_oops: ;
;Setup stack referance.
;
push eax
push ebx
push esi
push edi
push es
movzx esi,es:RealRegsStruc.Real_SS[edi]
shl esi,4
mov ax,KernalZero
mov es,ax
movzx eax,w[CallBackStruc.CallBackStackSel+bx]
and ax,not 7
mov edi,GDTLinear
add edi,eax
mov es:[edi+2],si ;store low word of linear base.
shr esi,16
mov bx,si
mov es:[edi+4],bl ;store mid byte of linear base.
mov es:[edi+7],bh ;store high byte of linear base.
pop es
pop edi
pop esi
pop ebx
pop eax
mov ds,w[CallBackStruc.CallBackStackSel+bx]
movzx esi,es:RealRegsStruc.Real_SP[edi]
;
assume ds:nothing
test BYTE PTR cs:RawSystemFlags,1
jz rv30_Use32Bit13
pushf
call DWORD PTR cs:[rv30_CallB0]
jmp rv30_Use16Bit13
rv30_Use32Bit13: pushfd
call FWORD PTR cs:[rv30_CallB0]
rv30_Use16Bit13: cli
assume ds:_cwRaw
mov ax,KernalDS ;make our data addresable.
mov ds,ax
pop bx ;restore call back structure.
;
movzx esi,es:RealRegsStruc.Real_SS[edi] ;point to stacked registers.
mov w[VCPI_SP+2],si
shl esi,4
movzx eax,es:RealRegsStruc.Real_SP[edi]
sub eax,(2)+(4+4+4+4+4+4+4)+(2+2+2+2)+(2+2)
mov w[VCPI_SP],ax
add esi,eax
mov ax,KernalZero ;/
mov fs,ax ;/
mov ax,es:RealRegsStruc.Real_GS[edi]
mov fs:[esi],ax
mov ax,es:RealRegsStruc.Real_FS[edi]
mov fs:[esi+2],ax
mov ax,es:RealRegsStruc.Real_ES[edi]
mov fs:[esi+4],ax
mov ax,es:RealRegsStruc.Real_DS[edi]
mov fs:[esi+6],ax
mov eax,es:RealRegsStruc.Real_EBP[edi]
mov fs:[esi+8],eax
mov eax,es:RealRegsStruc.Real_EDI[edi]
mov fs:[esi+12],eax
mov eax,es:RealRegsStruc.Real_ESI[edi]
mov fs:[esi+16],eax
mov eax,es:RealRegsStruc.Real_EDX[edi]
mov fs:[esi+20],eax
mov eax,es:RealRegsStruc.Real_ECX[edi]
mov fs:[esi+24],eax
mov eax,es:RealRegsStruc.Real_EBX[edi]
mov fs:[esi+28],eax
mov eax,es:RealRegsStruc.Real_EAX[edi]
mov fs:[esi+32],eax
mov ax,es:RealRegsStruc.Real_Flags[edi]
mov fs:[esi+36],ax
mov ax,es:RealRegsStruc.Real_IP[edi]
mov fs:[esi+38],ax
mov ax,es:RealRegsStruc.Real_CS[edi]
mov fs:[esi+40],ax
;
;Switch back to v86 mode.
;
mov cx,VCPI_SP+2
mov dx,VCPI_SP
call Protected2Real
add RawStackPos,RawStackDif
pop gs
pop fs
pop es
pop ds
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
popf
retf
rv30_CallB0: ;
df ?,0
RAWCallBack endp
;-------------------------------------------------------------------------------
RAWICallBack proc near
cli
assume ds:nothing
pop cs:RetAdd ;get return address.
;
;Check if this call back is busy.
;
push ax
push bx
push dx
mov ax,cs:RetAdd ;get return address.
sub ax,CallBackSize ;back to start of call back entry.
sub ax,offset ICallBackList ;offset from start of list.
xor dx,dx
mov bx,CallBackSize
div bx ;entry number.
mov bx,size CallBackStruc
mul bx ;get offset into table.
mov bx,offset CallBackTable
add bx,ax ;point to this entry.
mov WORD PTR cs:[rv31_CallTab],bx
;
cmp cs:InWindows,0
jnz rv31_ForceOld
;
test cs:CallBackStruc.CallBackFlags[bx],128 ;call back busy?
jz rv31_NotBusy
;
;This is a busy int call back so pass control to old real mode vector.
;
rv31_ForceOld: mov ax,WORD PTR cs:[CallBackStruc.CallBackReal+2+bx] ;fetch old real mode vector address.
mov WORD PTR cs:[rv31_tVCPI_SP+2],ax
mov ax,WORD PTR cs:[CallBackStruc.CallBackReal+bx]
mov WORD PTR cs:[rv31_tVCPI_SP],ax
pop dx
pop bx
pop ax
jmp DWORD PTR cs:[rv31_tVCPI_SP] ;pass onto old handler.
rv31_tVCPI_SP: ;
dd ?
;
rv31_NotBusy: or cs:CallBackStruc.CallBackFlags[bx],128 ;mark it as busy.
mov bx,sp
mov ax,ss:[bx+(2+2+2)+(2+2)]
and ax,0000110011010101b
or ax,0000000000000010b
mov WORD PTR cs:[rv31_FlagsStore],ax
pop dx
pop bx
pop ax
;
;Switch to new stack.
;
mov WORD PTR cs:[rv31_tVCPI_SP],sp ;store current stack.
mov WORD PTR cs:[rv31_tVCPI_SP+2],ss
mov ss,cs:RawStackReal ;_cwRaw ;use new stack.
mov esp,cs:RawStackPos
sub cs:RawStackPos,RawStackDif
push DWORD PTR cs:[rv31_tVCPI_SP] ;put old stack onto new one.
;
;Preserve registers.
;
push eax
push ebx
push ecx
push edx
push esi
push edi
push ebp
push ds
push es
push fs
push gs
;
;Make our data addresable.
;
mov ax,_cwRaw
mov ds,ax ;make our data addresable.
assume ds:_cwRaw
mov w[rv31_tVCPI_SP],sp
mov w[rv31_tVCPI_SP+2],ss
;
;Switch to protected mode.
;
mov cx,KernalSS
xor edx,edx
mov dx,sp
; mov edx,RawStackPos
; sub RawStackPos,RawStackDif
call Real2Protected
;
;Get protected mode code address.
;
mov bx,w[rv31_CallTab]
mov bl,CallBackStruc.CallBackNum[bx] ;get int number.
push ax
push ebx
push ds
mov ax,KernalDS
mov ds,ax
movzx eax,bl
mov ebx,eax
shl ebx,1 ;*2
mov eax,ebx
shl ebx,1 ;*4
add ebx,eax ;*6
assume ds:_cwDPMIEMU
add ebx,offset InterruptTable
assume ds:_cwRaw
push ds
mov ax,DpmiEmuDS
mov ds,ax
mov edx,[ebx] ;get offset.
mov cx,4[ebx] ;get segment selector.
pop ds
pop ds
pop ebx
pop ax
test BYTE PTR RawSystemFlags,1
jz rv31_Use32Bit12
mov w[rv31_CallB0+2],cx
mov w[rv31_CallB0],dx
jmp rv31_Use16Bit12
rv31_Use32Bit12: mov w[rv31_CallB0+4],cx
mov d[rv31_CallB0],edx
rv31_Use16Bit12: ;
;Retrieve register values.
;
mov ax,KernalZero
mov fs,ax
movzx esi,w[rv31_tVCPI_SP+2]
shl esi,4
movzx eax,w[rv31_tVCPI_SP]
add esi,eax ;Point to stacked registers.
pushfd
pop eax
shr eax,16
mov w[rv31_FlagsStore+2],ax
mov eax,fs:[esi+32]
mov ebx,fs:[esi+28]
mov ecx,fs:[esi+24]
mov edx,fs:[esi+20]
mov edi,fs:[esi+12]
mov ebp,fs:[esi+8]
mov esi,fs:[esi+16]
push d[rv31_tVCPI_SP]
push w[rv31_CallTab]
push ds
test BYTE PTR RawSystemFlags,1
jz rv31_Use32Bit13
push w[rv31_FlagsStore]
; pushf ;dummy return flags.
push cs ;dummy return address.
push w[rv31_zero] ;/
push w[rv31_FlagsStore]
call d[rv31_CallB0]
lea esp,[esp+(2*3)]
; pushf
; add sp,2*3
; popf
jmp rv31_Use16Bit13
rv31_Use32Bit13:
; pushfd ;dummy return flags.
push d[rv31_FlagsStore]
push 0 ;\
push cs ;dummy return address.
push d[rv31_zero]
push d[rv31_FlagsStore]
call f[rv31_CallB0]
lea esp,[esp+(4*3)]
rv31_Use16Bit13: ;
pop ds
pushfd
cli
pop d[rv31_FlagsStore]
pop w[rv31_CallTab]
pop d[rv31_tVCPI_SP]
push esi
push eax
mov ax,KernalZero
mov fs,ax
movzx esi,w[rv31_tVCPI_SP+2]
shl esi,4
movzx eax,w[rv31_tVCPI_SP]
add esi,eax ;Point to stacked registers.
;
;Set new register values.
;
pop eax
mov fs:[esi+32],eax
mov fs:[esi+28],ebx
mov fs:[esi+24],ecx
mov fs:[esi+20],edx
pop eax
mov fs:[esi+16],eax
mov fs:[esi+12],edi
mov fs:[esi+8],ebp
;
;Update flags.
;
movzx eax,WORD PTR fs:[(2+2+2+2)+(4+4+4+4+4+4+4)+esi]
movzx esi,WORD PTR fs:[(2+2+2+2)+(4+4+4+4+4+4+4)+(2)+esi]
shl esi,4
add esi,eax
mov ax,w[rv31_FlagsStore]
and ax,1111100011111111b
and WORD PTR fs:[(2+2)+esi],0000011100000000b
or fs:[(2+2)+esi],ax
;
mov bx,w[rv31_CallTab] ;restore call back structure.
and CallBackStruc.CallBackFlags[bx],255-128 ;clear busy flag.
;
;Switch back to v86 mode.
;
mov cx,w[rv31_tVCPI_SP+2]
mov dx,w[rv31_tVCPI_SP]
call Protected2Real
; add RawStac
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?