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

📄 int31h.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	setc al				; set AL = carry (IF flag from EFLAGS)
	jmp int31oknopop		; return ok, dont pop registers






;=============================================================================
; REAL/PROTECTED MODE TRANSLATION FUNCTIONS
;=============================================================================

;=============================================================================
int310301:				; call real mode FAR procedure
int310302:				; call real mode IRET procedure
	mov ebp,dword ptr es:[edi+2Ah]	; get target CS:IP from structure
	jmp int3103			; go to common code


;=============================================================================
int310300:				; simulate real mode interrupt
	movzx ebx,bl			; get real mode INT CS:IP
	mov ebp,dword ptr ds:[ebx*4]	; read from real mode interrupt table

int3103:				; common to 0300h, 0301h, and 0302h
	mov gs,cs:seldata
	movzx ebx,word ptr es:[edi+2Eh]	; EBX = SP from register structure
	movzx edx,word ptr es:[edi+30h]	; EDX = SS from register structure
	mov ax,bx			; check if caller provided stack
	or ax,dx
	jnz @@f3			; if yes, go on to setup stack

	mov dx,cs:rmstacktop		; DX = SS for real mode redirection
	mov bx,cs:rmstacklen		; get size of real mode stack
	sub dx,bx			; adjust DX to next stack location
	cmp dx,cs:rmstackbase		; exceeded real mode stack space?
	jb int31fail8012		; if yes, error 8012h
	mov gs:rmstacktop,dx		; update ptr for possible reenterancy
	shl bx,4			; adjust BX from paragraphs to bytes

@@f3:	lea edi,[edx*4]			; EDI -> top of real mode stack
	lea edi,[edi*4+ebx]

	mov ax,ss
	xchg ax,gs:rmstackss		; preserve and set new top of stack
	push ax				; parms for possible reenterancy
	lea eax,[esp-4]
	xchg eax,gs:rmstackesp
	push eax

	movzx ecx,cx
	mov ax,cx			; EAX = length of stack parms
	add ax,ax			; convert words to bytes
	sub bx,2Eh			; adjust real mode SP for needed vars
	sub bx,ax			; adjust real mode SP for stack parms

	push ds	es			; swap DS and ES
	pop ds es

	std				; string copy backwards
	sub edi,2			; copy stack parms from protected mode
	lea esi,[ecx*2+esp+3Eh]		; stack to real mode stack
	rep movs word ptr es:[edi],ss:[esi]

	mov esi,[esp+06h]		; ESI = offset of structure from stack
	mov ax,ds:[esi+20h]		; AX = FLAGS from register structure
	cmp byte ptr [esp+22h],1	; check AL on stack for function code
	jz @@f4				; if function 0301h, go on
	and ah,0FCh			; 0300h or 0302h, clear IF and TF flag
	stos word ptr es:[edi]		; put flags on real mode stack
	sub bx,2

@@f4:	cld				; string copy forward
	lea edi,[edx*4]			; EDI -> bottom of stack
	lea edi,[edi*4+ebx]
	mov cl,8			; copy general regs to real mode stack
	rep movs dword ptr es:[edi],ds:[esi]
	add esi,6			; copy FS and GS to real mode stack
	movs dword ptr es:[edi],ds:[esi]

	mov word ptr es:[edi+8],_KERNEL	; return address from call
	mov word ptr es:[edi+6],offs @@f1
	mov word ptr es:[edi+4],ax	; store FLAGS for real mode IRET maybe
	mov dword ptr es:[edi],ebp	; put call address to real mode stack
	mov ax,[esi-6]			; real mode DS from register structure
	mov cx,[esi-8]			; real mode ES from register structure
	mov si,_KERNEL			; real mode target CS:IP
	mov di,offs @@f0
	db 66h				; JMP DWORD PTR, as in 32bit offset,
	jmp word ptr cs:pmtormswrout	;  not seg:16bit offset

@@f0:	popad				; load regs with call values
	pop fs gs
	iret				; go to call address

@@f1:	push gs fs ds es		; store registers on stack
	pushf				; store flags on stack
	cli
	pushad

	xor eax,eax
	mov ax,ss			; EAX = linear ptr to SS
	xor ebp,ebp
	shl eax,4
	mov bp,sp			; EBP = SP
	add ebp,eax			; EBP -> stored regs on stack

	mov dx,cs:rmstackss		; get protected mode SS:ESP from stack
	mov ebx,cs:rmstackesp
	mov ax,SELZERO			; DS selector value for protected mode
	mov cx,SELDATA			; ES selector value for protected mode
	mov si,SELCODE			; target CS:EIP in protected mode
	mov edi,offs @@f2
	jmp cs:rmtopmswrout		; go back to protected mode

@@f2:	push es
	pop gs
	pop es:rmstackesp
	pop es:rmstackss
	mov esi,ebp			; copy return regs from real mode
	mov edi,[esp]			; get structure offset from stack
	mov es,[esp+24h]
	mov ecx,15h			;  stack to register structure
	cld
	rep movs word ptr es:[edi],ds:[esi]

	cmp dword ptr es:[edi+4],0	; stack provided by caller?
	jne int31ok			; if yes, done now
	mov ax,cs:rmstacklen		; restore top of real mode stack
	add gs:rmstacktop,ax
	jmp int31ok			; return ok


;=============================================================================
int310303:				; allocate real mode callback address
	mov bl,cs:pm32_callbacks	; CL = total number of callbacks
	test bl,bl			; are there any?
	jz int31fail8015		; if no, error 8015h

	mov edx,cs:callbackbase		; EDX -> base of callbacks
	mov ecx,edx			; for later use

@@l0:	cmp word ptr [edx+3],0		; is this callback free?
	jz @@f0				; if yes, allocate
	add edx,25			; increment ptr to callback
	dec bl				; decrement loop counter
	jnz @@l0			; if more callbacks to check, loop
	jmp int31fail8015		; no free callback, error 8015h

@@f0:	mov bx,[esp+38]			; BX = caller DS from stack
	mov [edx+3],bx			; store callback parms in callback
	mov [edx+7],esi
	mov [edx+12],es
	mov [edx+16],edi
	sub edx,ecx			; DX = offset of callback
	shr ecx,4			; CX = segment of callback
	jmp int31okdx			; return ok, with DX, CX, AX


;=============================================================================
int310304:				; free real mode callback address
	cmp cx,cs:callbackseg		; valid callback segment?
	jne int31fail8024		; if no, error 8024h

	movzx ebx,dx			; EBX = offset of callback
	xor ax,ax			; check if valid offset
	xchg dx,ax
	mov cx,25
	div cx
	test dx,dx			; is there a remainder
	jnz int31fail8024		; if yes, not valid, error 8024h
	test ah,ah			; callback index too big?
	jnz int31fail8024		; if yes, not valid, error 8024h
	cmp al,cs:pm32_callbacks	; callback index out of range?
	jae int31fail8024		; if yes, not valid, error 8024h

	add ebx,cs:callbackbase		; EBX -> callback
	mov word ptr [ebx+3],0		; set callback as free
	jmp int31ok			; return ok






;=============================================================================
; MISC FUNCTIONS
;=============================================================================

;=============================================================================
int310305:				; get state save/restore addresses
	add esp,26h			; adjust stack
	pop ds				; restore DS
	xor ax,ax			; size needed is none
	mov bx,cs:kernel_code		; real mode seg of same RETF
	mov cx,offs vxr_saverestorerm	; same offset of 16bit RETF
	mov si,cs			; selector of routine is this one
	mov edi,offs vxr_saverestorepm	; offset of simple 32bit RETF
	jmp int31oknopop		; return ok, dont pop registers


;=============================================================================
int310306:				; get raw mode switch addresses
	add esp,26h			; adjust stack
	pop ds				; restore DS
	mov si,cs			; selector of pmtorm rout is this one
	mov edi,cs:pmtormswrout		; offset in this seg of rout
	mov bx,cs:kernel_code		; real mode seg of rmtopm rout
	mov cx,cs:rmtopmswrout		; offset of rout in real mode
	jmp int31oknopop		; return ok, dont pop registers


;=============================================================================
int310400:				; get version
	add esp,26h			; adjust stack
	pop ds				; restore DS
	mov ax,005Ah			; return version 0.9
	mov bx,0003h			; capabilities
	cmp cs:pmodetype,2
	jnz @@1
	mov bl,1
@@1:	mov cl,cs:cputype		; processor type
	mov dx,word ptr cs:picslave	; master and slave PIC values
	jmp int31oknopop		; return ok, don't pop registers


;=============================================================================
int310A00:				; vendor specific extensions
	add esp,26h			; adjust stack
	pop ds				; restore DS

	push es edi ecx esi		; save regs that will be modified
	push cs				; ES = CS
	pop es

	mov ecx,15			; search for vendor1 string
	mov edi,offs @@str1
	push esi
	repe cmps byte ptr ds:[esi],es:[edi]
	pop esi
	mov edi,offs @@ent1		; ES:EDI = sel:offset of entry SUNSYS
	jz @@0				; if found, jump
	test cs:pm32_mode,10000000b	; check if to ignore DOS/4G extensions
	jnz @@err			; if not, we are done
	mov cl,16			; search for vendor2 string
	mov edi,offs @@str2
	repe cmps byte ptr ds:[esi],es:[edi]
	jnz @@err			; if not found, done
	mov edi,offs @@ent2		; ES:EDI = sel:offset of entry DOS/4G
	pop esi ecx
	add esp,6
	jmp int31oknopop

@@0:	add esp,14
	xor eax,eax			; clear high words
	mov ebx,eax
	mov ecx,eax
	mov edx,eax
	mov ax,cs:client_version	; AX = DOS Extender Version Number
	mov bl,cs:pm32_mode		; BL = kernel configuration
	mov bh,cs:pmodetype		; BH = system software type
	mov cl,cs:cputype		; CL = processor type
	mov ch,cs:fputype		; CH = FPU type
	mov dx,word ptr cs:picslave	; DX = PIC values (unremapped)
	jmp int31oknopop

@@err:	pop esi ecx edi es		; if none of the strings was idetified
	mov ax,8001h			; return with AX=8001h
	jmp int31failnopop

@@str1	db 'SUNSYS DOS/32A',0		; vendor1 API ID-string (DOS/32A)
@@str2	db 'RATIONAL DOS/4G',0		; vendor2 API ID-string (DOS/4G)

@@ent2:	mov al,84h			; vendor2 API entry point (DOS/4G)
	jmp dword ptr cs:client_call

@@ent1:	test al,al			; vendor1 API entry point (DOS/32A)
	jz API_func00
	cmp al,01h
	jz API_func01
	cmp al,02h
	jz API_func02
	cmp al,03h
	jz API_func03
	cmp al,04h
	jz API_func04
	cmp al,05h
	jz API_func05
	cmp al,06h
	jz API_func06
	cmp al,07h
	jz API_func07
	cmp al,08h
	jz API_func08
	cmp al,09h
	jz API_func09
	stc
	db 66h
	retf



API_func00:			; API function 00h: get access to IDT & GDT
	mov bx,SELZERO
	movzx ecx,cs:gdtlimit	; ECX = GDT limit
	movzx edx,cs:idtlimit	; EDX = IDT limit
	mov esi,cs:gdtbase	; BX:ESI = pointer to GDT
	mov edi,cs:idtbase	; BX:EDI = pointer to IDT
	jmp API_funcok

API_func01:			; API function 01h: get access to PageTables
	mov bx,SELZERO
	movzx ecx,cs:pagetables		; ECX = number of allocated pagetables
	movzx edx,cs:pm32_maxfpages	; EDX = number of allocated phystables
	mov esi,cs:pagetablebase	; BX:ESI = pointer to 0th pagetable
	mov edi,cs:phystablebase	; BX:EDI = pointer to phystable
	inc cx
	jmp API_funcok

API_func02:			; API function 02: get access to INT tables
	mov bx,SELDATA
	mov esi,offs irqset_rm	; BX:ESI = pointer to INT switches
	mov edi,offs irqtab_rm	; BX:EDI = pointer to INT tables
	jmp API_funcok

API_func03:			; API function 03: get access to EXT memory
	mov bx,SELZERO
	mov ecx,cs:mem_free	; ECX = size of allocated memory
	mov edx,cs:mem_ptr	; EDX = pointer to allocated memory
	mov esi,cs:mem_top	; ESI = top of allocated memory
	jmp API_funcok

API_func04:			; API function 04: get access to rm-stacks
	mov bx,SELZERO
	movzx ecx,cs:rmstacklen		; ECX = size of one stack
	movzx edx,cs:rmstacktop		; EDX = pointer to top of stack
	movzx esi,cs:rmstackbase	; ESI = base of stack area
	movzx edi,cs:rmstacktop2	; EDI = default top of stack
	jmp API_funcok

API_func05:			; API function 05: get access to pm-stacks
	mov bx,SELZERO
	mov ecx,cs:pmstacklen	; ECX = size of one stack
	mov edx,cs:pmstacktop	; EDX = pointer to top of stack
	mov esi,cs:pmstackbase	; ESI = base of stack area
	mov edi,cs:pmstacktop2	; EDI = default top of stack
	jmp API_funcok

API_func06:			; API function 06: get kernel selectors
	mov bx,SELCODE				; BX = Kernel code selector
	mov cx,SELDATA				; CX = Kernel data selector
	mov dx,SELZERO				; DX = Kernel zero selector
	movzx esi,word ptr cs:kernel_code	; ESI = Kernel code segment
	mov di,word ptr cs:client_call[2]	; DI = Client code selector
	jmp API_funcok

API_func07:			; API function 07: get critical handler entry
	mov cx,cs:client_call[2]	; CX = default 16bit selector
	mov dx,cs:client_call[0]	; DX = default 16bit offset
	jmp API_funcok

API_func08:			; API function 08: set critical handler entry
	push ds
	mov ds,cs:seldata
	mov client_call[2],cx		; CX = custom 16bit selector
	mov client_call[0],dx		; DX = custom 16bit offset
	pop ds
	jmp API_funcok

API_func09:			; API function 09: get access to p. counters
	mov cx,SELDATA			; CX = Kernel data selector
	mov edx,offs _pc_base		; EDX = base of performance counters

API_funcok:
	clc
	db 66h
	retf






;=============================================================================
; MEMORY FUNCTIONS
;=============================================================================

;=============================================================================
int310500:				; get free memory information
	or eax,-1
	mov ecx,0Ch
	push edi
	rep stos dword ptr es:[edi]
	pop edi
	mov eax,cs:mem_ptr
	or eax,cs:mem_free
	jz @@1
	call int31_checkblocks
	call int31_getfreemem

@@1:	mov ebx,eax
	mov edx,eax			; EDX = largest free block
	mov eax,cs:mem_free
	shr eax,12			; EAX = total memory pages
	shr ebx,12			; EBX = free pages left
	shr ecx,12			; ECX = total allocated memory
	push es
	pop ds
	mov [edi+00h],edx		; 00h - largest free block
	mov [edi+04h],ebx		; 04h - max unlocked pages
	mov [edi+08h],ebx		; 08h - max locked pages
	mov [edi+0Ch],eax		; 0Ch - total linear space
	mov [edi+10h],ebx		; 10h -
	mov [edi+14h],ecx		; 14h -
	mov [edi+18h],eax		; 18h - total pages
	mov [edi+1Ch],ecx		; 1Ch - total free mem in pages
	jmp int31ok


;=============================================================================
int310501:				; allocate memory block
	call int31_checkifmemavail
	call int31_testbxcxtoebx	; convert BX:CX to EBX
	call int31_checkblocks
	mov esi,cs:mem_ptr		; get pointer to memory
@@1:	mov eax,[esi+04h]		; get block size
	btr eax,31			; check if memory block is used
	jc @@2				; if yes, jump
	cmp eax,ebx			; check if block is large enough
	jae int31_allocblock		; if yes, allocate block
@@2:	lea esi,[esi+eax+10h]		; load address of next memory block
	cmp esi,cs:mem_top		; check if at top of memory
	jb @@1				; if not, loop
	jmp int31fail8013		; fail: not enough memory


;=============================================================================
int310502:				; free memory block
	shl esi,16			; convert SI:DI to ESI
	mov si,di
	call int31_checkifmemavail
	call int31_checkblocks
	call int31_checkhandle
	btr dword ptr [esi+04h],31	; set block as free
	call int31_linkfreeblocks
	jmp int31ok


;=============================================================================
int310503:				; resize memory block
	shl esi,16			; convert SI:DI to ESI
	mov si,di
	call int31_checkifmemavail
	call int31_testbxcxtoebx	; convert BX:CX to EBX
	call int31_checkblocks
	call int31_checkhandle

	mov eax,[esi+04h]		; get size of this block
	btr eax,31			; check if block is used
	jnc int31fail8023		; if block is free, fail
	cmp eax,ebx			; check if enough memory
	jae int31_allocblock		; if yes, reallocate block

⌨️ 快捷键说明

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