📄 int31h.asm
字号:
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 + -