📄 int31h.asm
字号:
;
; Copyright (C) 1996-2002 Supernar Systems, Ltd. All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are
; met:
;
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
;
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; 3. The end-user documentation included with the redistribution, if any,
; must include the following acknowledgment:
;
; "This product uses DOS/32 Advanced DOS Extender technology."
;
; Alternately, this acknowledgment may appear in the software itself, if
; and wherever such third-party acknowledgments normally appear.
;
; 4. Products derived from this software may not be called "DOS/32A" or
; "DOS/32 Advanced".
;
; THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS" AND ANY EXPRESSED
; OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
; ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
;
;=============================================================================
; INT 31h INTERFACE
;=============================================================================
evendata
int31tab label word
dw 0300h ; simulate real mode int
dw int310300
dw 0301h ; call rm proc RETF
dw int310301
dw 0302h ; call rm proc IRET
dw int310302
;---------------------------------------------------------------------
dw 0000h ; allocate descriptor
dw int310000
dw 0001h ; free descriptor
dw int310001
dw 0002h ; map seg to sel
dw int310002
dw 0003h ; get sel increment value
dw int310003
dw 0006h ; get sel base addr
dw int310006
dw 0007h ; set sel base addr
dw int310007
dw 0008h ; set sel limit
dw int310008
dw 0009h ; set sel access rights
dw int310009
dw 000Ah ; create alias sel
dw int31000A
dw 000Bh ; get descriptor
dw int31000B
dw 000Ch ; set descriptor
dw int31000C
dw 000Eh ; get multi descriptors
dw int31000E
dw 000Fh ; get multi descriptors
dw int31000F
;---------------------------------------------------------------------
dw 0100h ; alloc DOS memory
dw int310100
dw 0101h ; free DOS memory
dw int310101
dw 0102h ; resize DOS memory
dw int310102
;---------------------------------------------------------------------
dw 0200h ; get real mode int
dw int310200
dw 0201h ; set real mode int
dw int310201
dw 0202h ; get pm exception vector
dw int310202
dw 0203h ; set pm exception vector
dw int310203
dw 0204h ; get pm int
dw int310204
dw 0205h ; set pm int
dw int310205
;---------------------------------------------------------------------
dw 0303h ; alloc callback
dw int310303
dw 0304h ; free callback
dw int310304
dw 0305h ; get state save/restore addr
dw int310305
dw 0306h ; get raw mode switch addr
dw int310306
;---------------------------------------------------------------------
dw 0400h ; get DPMI version
dw int310400
;---------------------------------------------------------------------
dw 0500h ; get free mem info
dw int310500
dw 0501h ; alloc mem
dw int310501
dw 0502h ; free mem
dw int310502
dw 0503h ; resize mem
dw int310503
dw 050Ah ; get linear mem block and size
dw int31050A
;---------------------------------------------------------------------
dw 0600h ; lock linear region ***VM*
dw int310600
dw 0601h ; unlock linear region ***VM*
dw int310601
dw 0602h ;
dw int310602
dw 0603h ;
dw int310603
dw 0604h ; get page size ***VM*
dw int310604
;---------------------------------------------------------------------
dw 0702h ; mark page ***VM*
dw int310702
dw 0703h ; discard page ***VM*
dw int310703
;---------------------------------------------------------------------
dw 0800h ; physical mem mapping
dw int310800
dw 0801h ; free mapped mem
dw int310801
;---------------------------------------------------------------------
dw 0900h ; get/disable VIS
dw int310900
dw 0901h ; get/enable VIS
dw int310901
dw 0902h ; get VIS
dw int310902
;---------------------------------------------------------------------
dw 0A00h ; vendor specific
dw int310A00
;---------------------------------------------------------------------
dw 0E00h ; get FPU status
dw int310E00
dw 0E01h ; set FPU emulation
dw int310E01
;---------------------------------------------------------------------
dw 0EEFFh ; PMODE/W compatible call
dw int31EEFF
dw 0FFFFh
dw 0FFFFh
;=============================================================================
int31: cli
cld
push ds es fs gs ; push registers on stack
pushad
push bx
xor bx,bx
mov ds,cs:selzero ; DS -> 0 (beginning of memory)
@@0: cmp ax,cs:int31tab[bx] ; found function value?
je @@1
cmp word ptr cs:int31tab[bx],0FFFFh
je @@2
add bx,4
jmp @@0
@@1: mov bx,cs:int31tab[bx+2] ; yes, go to appropriate handler
xchg bx,[esp]
ret
@@2: pop bx ; no function found
;-----------------------------------------------------------------------------
int31fail8001: ; INT 31h return fail with error 8001h
mov al,01h
jmp int31failx
int31fail8010: ; INT 31h return fail with error 8010h
mov al,10h
jmp int31failx
int31fail8011: ; INT 31h return fail with error 8011h
mov al,11h
jmp int31failx
int31fail8012: ; INT 31h return fail with error 8012h
mov al,12h
jmp int31failx
int31fail8013: ; INT 31h return fail with error 8013h
mov al,13h
jmp int31failx
int31fail8015: ; INT 31h return fail with error 8015h
mov al,15h
jmp int31failx
int31fail8016: ; INT 31h return fail with error 8016h
mov al,16h
jmp int31failx
int31fail8021: ; INT 31h return fail with error 8021h
mov al,21h
jmp int31failx
int31fail8022: ; INT 31h return fail with error 8022h
mov al,22h
jmp int31failx
int31fail8023: ; INT 31h return fail with error 8023h
mov al,23h
jmp int31failx
int31fail8024: ; INT 31h return fail with error 8024h
mov al,24h
jmp int31failx
int31fail8025: ; INT 31h return fail with error 8025h
mov al,25h
int31failx:
mov ah,80h
mov [esp+28],ax ; set AX on stack to 8010h for POPAD
jmp int31fail
;-----------------------------------------------------------------------------
int31failbx: ; INT 31h return fail with BX,AX
mov word ptr [esp+16],bx ; put BX onto stack for POPAD
jmp int31failax
int31failcx: ; INT 31h return fail with CX,AX
mov word ptr [esp+24],cx ; put CX onto stack for POPAD
int31failax: ; INT 31h return fail with AX
mov word ptr [esp+28],ax ; put AX onto stack for POPAD
;-----------------------------------------------------------------------------
int31fail: ; INT 31h return fail, pop all regs
popad
pop gs fs es ds
int31failnopop: ; INT 31h return fail with carry set
or byte ptr [esp+8],01h ; set carry in EFLAGS on stack
iretd
;-----------------------------------------------------------------------------
int31okedx: ; INT 31h return ok with EDX,CX,AX
mov [esp+20],edx ; put EDX onto stack for POPAD
jmp int31okcx
int31okdx: ; INT 31h return ok with DX,CX,AX
mov [esp+20],dx ; put DX onto stack for POPAD
jmp int31okcx
int31oksinoax: ; INT 31h return ok SI,DI,BX,CX
mov ax,[esp+28] ; get old value of AX for restore
int31oksi: ; INT 31h return ok SI,DI,BX,CX,AX
mov [esp+4],si ; put SI onto stack for POPAD
mov [esp+0],di ; put DI onto stack for POPAD
int31okbx:
mov [esp+16],bx ; put BX onto stack for POPAD
int31okcx: ; INT 31h return ok with CX,AX
mov [esp+24],cx ; put CX onto stack for POPAD
int31okax: ; INT 31h return ok with AX
mov [esp+28],ax ; put AX onto stack for POPAD
;-----------------------------------------------------------------------------
int31ok: ; INT 31h return ok, pop all regs
popad
pop gs fs es ds
int31oknopop: ; INT 31h return ok with carry clear
and byte ptr [esp+8],0FEh ; clear carry in EFLAGS on stack
iretd
;=============================================================================
; DESCRIPTOR FUNCTIONS
;=============================================================================
;-----------------------------------------------------------------------------
int31testsel: ; test for valid selector BX
pop bp ; pop return address
cmp bx,cs:gdtlimit ; selector BX out of range?
ja int31fail8022 ; if yes, fail with error 8022h
mov edi,cs:gdtbase ; get base of GDT
and ebx,0FFF8h ; mask offset table index and RPL
test byte ptr ds:[edi+ebx+6],10h; is descriptor used?
jz int31fail8022 ; if descriptor not used, fail 8022h
jmp bp ; return ok
;-----------------------------------------------------------------------------
int31testaccess: ; test access bits in CX
pop bp ; pop return address
test ch,20h ; test MUST BE 0 bit in CH
jnz int31fail8021 ; if not 0, error 8021h
test cl,90h ; test present and MUST BE 1 bits
jz int31fail8021 ; if both 0, error 8021h
jpo int31fail8021 ; if unequal, error 8021h
test cl,60h ; test DPL
jnz int31fail8021 ; if not 0, error 8021h
test cl,8 ; if code, more tests needed
jz @@0 ; if data, skip code tests
test cl,2 ; readable?
jz int31fail8021
test cl,4 ; non-conform?
jnz int31fail8021
@@0: jmp bp ; return ok
;-----------------------------------------------------------------------------
checkint:
push edx
movzx ebx,bl ; EBX = interrupt number
mov edx,ebx
mov al,bl
and dl,07h ; EDX = INT number in range 00-07h
and al,0F8h ; AL = masked out low 3 bits
cmp al,picmaster ; if 1st PIC,
lea esi,[edx+0] ; then ESI = EDX
jz @@done
cmp al,picslave ; if 2nd PIC,
lea esi,[edx+8] ; then ESI = EDX+8
jz @@done
or esi,-1
@@done: pop edx ; return ZF reset to 0 if an IRQ
ret ; otherwise ZF is set to 1
;=============================================================================
int310000: ; allocate descriptors
test cx,cx ; if CX = 0, error 8021h
jz int31fail8021
mov edx,cs:gdtbase ; get base of GDT
movzx eax,cs:gdtlimit ; EAX = last selector index
and al,0F8h
mov bx,cx ; BX = number of selectors to find
@@l0: test byte ptr [edx+eax+6],10h ; is descriptor used?
jnz @@f0
dec bx ; found free descriptor, dec counter
jnz @@f1 ; continue if need to find more
mov ebx,eax ; found all descriptors requested
@@l1: mov dword ptr [edx+ebx],0 ; set entire new descriptor
mov dword ptr [edx+ebx+4],109200h
add bx,8 ; increment selector index
loop @@l1 ; dec counter of descriptors to mark
jmp int31okax ; return ok, with AX
@@f0: mov bx,cx ; reset number of selectors to find
@@f1: sub ax,8 ; dec current selector counter
cmp ax,8*SYSSELECTORS ; more descriptors to go?
jae @@l0 ; if yes, loop
jmp int31fail8011 ; did not find descriptors
;=============================================================================
int310001: ; free descriptor
mov ax,cs
cmp ax,bx
jz int31fail8022 ; cannot free CS selector
mov ax,ss
cmp ax,bx
jz int31fail8022 ; cannot free SS selector
call int31testsel ; test for valid selector BX
xor eax,eax
mov [edi+ebx+0],eax ; mark descriptor as free
mov [edi+ebx+4],eax
mov cx,4 ; zero any segregs loaded with BX
lea ebp,[esp+32] ; EBP -> selectors on stack
@@l0: cmp word ptr [ebp],bx ; selector = BX?
jne @@f0 ; if no, continue loop
mov [ebp],ax ; zero selector on stack
@@f0: add ebp,2 ; increment selector ptr
loop @@l0 ; loop
jmp int31ok ; return ok
;=============================================================================
int310002: ; map segment to selector
mov ds,cs:seldata
mov cx,16 ; max 16 selectors
mov si,offs segmentbases ; check, if segment already mapped
@@0: mov ax,[si+0] ; is selector zero (free entry)
test ax,ax
jz @@1 ; if yes, loop
cmp bx,[si+2] ; compare segment values
jz int31okax ; if already mapped, done
@@1: add si,4
loop @@0
mov cl,16
mov si,offs segmentbases ; search for a free entry
@@2: cmp word ptr [si],0 ; this field free?
jz @@3 ; if yes, use it
add si,4
loop @@2
jmp int31fail8010 ; no entry free
@@3: mov [si+2],bx ; store segment
movzx edi,bx ; convert to linear address
shl edi,4
mov cl,1
xor ax,ax
int 31h ; allocate selector
jc int31failax
mov [si+0],ax ; store selector
mov bx,ax
xor cx,cx
mov dx,-1
mov ax,8
int 31h ; set descriptor limit 64k
mov dx,di
shr edi,16
mov cx,di
mov ax,7
int 31h ; set descriptor base
mov cx,0092h
mov ax,9
int 31h ; set access rights
mov ax,bx ; return selector
jmp int31okax
;=============================================================================
int310003: ; get selector increment value
mov ax,8 ; selector increment value is 8
jmp int31okax ; return ok, with AX
;=============================================================================
int310006: ; get segment base address
call int31testsel ; test for valid selector BX
mov dx,word ptr ds:[edi+ebx+2] ; low word of 32bit linear address
mov cl,byte ptr ds:[edi+ebx+4] ; high word of 32bit linear address
mov ch,byte ptr ds:[edi+ebx+7]
jmp int31okdx ; return ok, with DX, CX, AX
;=============================================================================
int310007: ; set segment base address
call int31testsel ; test for valid selector BX
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -