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

📄 init.asm

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 ASM
📖 第 1 页 / 共 2 页
字号:

@@5:	and dh,0F0h			; clear avail bits
	mov dl,07h			; set page as user/writeable/present
	mov es:[di],edx			; set linear memory addr
	add di,4			; increment pointer
	add edx,4096			; increment address
	loop @@4

@@done:	pop ebx				; restore EBX counter
	ret





;=============================================================================
x_init:	mov ah,07h			; query A20
	call dword ptr xms_call
	mov A20_state,al
	mov ah,03h			; global enable A20
	call dword ptr xms_call
	mov bx,0007h			; error code 0007h in case of error
	dec ax				; error enabling A20?
	stc
	jnz init_done			; if yes, exit with error 0007h

	mov eax,xms_data		; get KB of free XMS memory
	mov edx,pm32_maxextmem		; get requested amount of memory
	shr edx,10			; convert to KB
	cmp edx,eax
	jbe @@1
	mov edx,eax

@@1:	mov esi,edx
	test edx,edx			; check if no extended memory is to
	jz @@done			;  be allocated, if so, then jump

	call xms_allocmem		; allocate EDX KB memory
	dec ax
	jnz @@done			; no memory has been allocated
	mov xms_handle,dx		; store handle

	mov ah,0Ch			; lock extended memory
	call dword ptr xms_call
	dec ax
	jz @@2				; if no error, jump
	xor dx,dx
	xchg dx,xms_handle		; reset handle: no mem allocated
	mov ah,0Ah			; free allocated extended memory
	call dword ptr xms_call
	jmp @@done

@@2:	mov word ptr mem_ptr[0],bx	; store linear pointer to memory
	mov word ptr mem_ptr[2],dx
	shl esi,10			; convert to bytes
	mov dword ptr mem_free,esi	; store amount of memory allocated
@@done:	jmp xr_init                     ; go to XMS/raw continue init





;=============================================================================
r_init:	call enable_A20			; enable A20
	mov bx,0007h			; error code 0007h
	jc init_done			; exit if error enabling A20

	xor eax,eax
	mov ah,88h			; how much extended memory free
	int 15h
	test ax,ax			; if none, done with raw init
	jz xr_init

	shl eax,10			; EAX = size of memory (bytes)
	lea edx,[eax+100000h]		; EDX = base of memory

	cmp eax,pm32_maxextmem		; check how much memory to alloc
	jbe @@1				; pick lowest value
	mov eax,pm32_maxextmem

@@1:	add eax,000003FFh		; align memory to KB
	and eax,0FFFFC00h
	sub edx,eax
	mov mem_ptr,edx			; store extended memory base
	mov mem_free,eax		; store size of extended memory
	shr eax,10			; convert to KB
	mov mem_used,ax			; set used memory

xr_init:                                ; XMS/raw common init tail
	mov word ptr picslave,0870h
	mov rmtopmswrout,offs xr_rmtopmsw; set XMS/raw mode switch addresses
	mov pmtormswrout,offs xr_pmtormsw




;=============================================================================
vxr_init:				; VCPI/XMS/raw common init tail
	call install_ints		; install interrupts and except handl.

	xor eax,eax
	mov ax,es
	mov idtseg,ax			; set IDT segment base address
	mov ebx,eax
	shl ebx,4
	mov idtbase,ebx			; set IDT linear base address

	add ax,80h			; size of IDT
	mov rmstackbase,ax

	movzx bx,pm32_rmstacks		; set top and base of real mode stack
	mov cx,pm32_rmstacklen
	mov rmstacklen,cx
	imul bx,cx			;  area for interrupt redirection
	add ax,bx
	mov rmstacktop,ax
	mov rmstacktop2,ax

	shl eax,4
	mov pmstackbase,eax		; set next data area to end of RM stk

	movzx ebx,pm32_pmstacks		; set protected mode stack area top
	movzx ecx,pm32_pmstacklen	;  for callbacks
	shl ecx,4
	mov pmstacklen,ecx		; protected mode stack size in bytes
	imul ebx,ecx
	add eax,ebx
	mov pmstacktop,eax		; protected mode stack area top
	mov pmstacktop2,eax

	mov callbackbase,eax		; top of stacks is base of callbacks
	shr eax,4			; BX = seg of callback area
	mov callbackseg,ax
	mov es,ax			; ES = seg of callback area

	call allocate_callbacks		; allocate callbacks

	xor eax,eax
	mov ax,es			; set GDT base address
	mov gdtseg,ax			; store segment of GDT
	shl eax,4
	mov gdtbase,eax
	movzx ecx,pm32_selectors	; set GDT limit
	lea ecx,[8*ecx+8*SYSSELECTORS-1]
	mov gdtlimit,cx
	xor di,di			; clear GDT with all 0
	inc cx
	shr cx,1
	xor eax,eax
	rep stos word ptr es:[di]

	cmp pmodetype,2			; if under VCPI, do VCPI GDT set up
	jne @@f0
	pop ax				; restore TSS seg from stack
	shl eax,4			; set up TSS selector in GDT
	mov es:[SELVCPITSS+2],eax
	mov byte ptr es:[SELVCPITSS],67h	; limit
	mov byte ptr es:[SELVCPITSS+5],89h	; access rights
	add eax,64h-4*9			; unused part of TSS is also
	mov vcpiswitchstack,eax		;  temporary switch stack
	mov di,SELVCPICODE		; copy 3 VCPI descriptors from stack
	mov si,sp			;  to GDT
	mov cl,4*3
	rep movs word ptr es:[di],ss:[si]
	add sp,8*3                      ;***NOTE: (VCPI) adjust stack

@@f0:	mov ax,0FFFFh
	mov word ptr es:[SELZERO],ax		; set SELZERO limit
	mov word ptr es:[SELCALLBACK],ax	; set callback DS limit
	mov ax,0DF92h
	mov word ptr es:[SELZERO+5],ax		; set SELZERO rights
	mov word ptr es:[SELCALLBACK+5],ax	; set callback DS rights

	mov ax,cs			; AX = base
	mov bx,SELCODE			; BX = index to SELCODE descriptor
	mov cx,0FFFFh			; CX = limit (64k)
	mov dx,109Ah			; DX = access rights
	call vxr_initsetdsc
	mov bx,SELDATA			; BX = index to SELDATA descriptor
	mov dx,1092h			; DX = access rights
	call vxr_initsetdsc
	mov ax,0040h
	mov bx,SELBIOSDATA
	call vxr_initsetdsc

	mov bx,8*SYSSELECTORS		; BX = base of free descriptors
	push bx                         ; store selector
	mov ax,ss			; set caller SS descriptor
	mov dx,5092h
	call vxr_initsetdsc
	mov ax,[bp]                     ; set caller DS descriptor
	mov [bp],bx                     ; put DS selector on stack for exit
	call vxr_initsetdsc

	push bx				; get PSP segment
	mov ah,51h
	int 21h
	mov si,bx			; SI = PSP segment
	pop bx

	push ds
	mov ds,si			; set caller environment descriptor
	mov ax,ds:[002Ch]
	test ax,ax			; is environment seg 0?
	jz @@f1				; if yes, dont convert to descriptor
	mov ds:[002Ch],bx		; store selector value in PSP
	call vxr_initsetdsc
	mov ax,si                       ; set caller PSP descriptor
@@f1:	mov cx,0FFh			; limit is 100h bytes
	call vxr_initsetdsc
	pop ds

	sub bx,8
	mov cx,bx			; CX = ES descriptor, PSP
	pop dx                          ; DX = SS descriptor, from stack
	mov ax,SELZERO                  ; AX = DS descriptor, SELZERO
	movzx ebx,sp                    ; EBX = SP, current SP - same stack
	mov si,SELCODE                  ; target CS is SELCODE, same segment
	mov edi,offs @@swpm		; target EIP
	jmp rmtopmswrout                ; jump to mode switch routine
;
; now we are in protected mode
;
@@swpm:	cli
	mov edi,cs:codebase		; EDI = offset of _KERNEL from 0
	mov eax,cs:vcpi_cr3		; EAX = CR3
	mov cr3,eax			; reload CR3 register to flush TLB
	xor eax,eax
	mov cr2,eax			; reset CR2 page fault addr register
	mov eax,cr0
	mov oldcr0[edi],eax		; preserve original CR0

	cmp cs:fputype,0
	setnz virtualfpu[edi]		; set client fpu status
	mov eax,ds:[4*1Bh]		; preserve INT 1Bh - (CTRL-Break)
	mov oldint1Bh[edi],eax
	mov eax,ds:[4*1Ch]		; preserve INT 1Ch - (timer ticks)
	mov oldint1Ch[edi],eax
	mov eax,ds:[4*21h]		; preserve INT 21h - (DOS API)
	mov oldint21h[edi],eax
	mov eax,ds:[4*23h]		; preserve INT 23h - (DOS CTRL-C)
	mov oldint23h[edi],eax
	mov eax,ds:[4*24h]		; preserve INT 24h - (DOS Critical)
	mov oldint24h[edi],eax
	mov eax,ds:[4*2Fh]		; preserve INT 2Fh - (Multiplex)
	mov oldint2Fh[edi],eax
	mov ax,cs:kernel_code		; install real mode INT 21h
	shl eax,16
	mov ax,offs int21h
	mov ds:[4*21h],eax

	mov eax,ds:[4*15h]		; get INT 15h vector
	mov oldint15h[edi],eax		; store old INT 15h vector
	cmp cs:pmodetype,0		; is system raw
	jnz @@1				; if not, we are done
	cmp cs:id32_process_id,0
	jnz @@1
	mov ax,cs:kernel_code
	shl eax,16
	mov ax,offs int15h
	mov ds:[4*15h],eax		; install new INT 15h handler

@@1:	push ds es edi
	push cs
	pop ds				; DS = code base (executable)
	mov es,seldata			; ES = code base (writeable)
	mov ax,0303h
	mov esi,offs int1Bh		;** NOTE: EDI points to init_code
	mov edi,offs @callback_data+00h	;** EDI = callback data structure
	int 31h				;** which will be used only once
	push cx dx			;** at startup.
	mov si,offs int1Ch
	mov di,offs @callback_data+32h
	int 31h
	push cx dx
	mov si,offs int23h
	mov di,offs @callback_data+64h
	int 31h
	push cx dx
	mov si,offs int24h
	mov di,offs @callback_data+96h
	int 31h
	push cx dx
	mov ds,seldata			; DS = data selector
	pop newint24h
	pop newint23h
	pop newint1Ch
	pop newint1Bh
	pop edi es ds

	xor eax,eax
	mov ebx,cs:mem_ptr		; EBX = base of extended memory
	mov ecx,cs:mem_free		; ECX = size of extended memory
	mov edx,ebx			; align ptr to memory on para boundary
	add ebx,0Fh
	and bl,0F0h
	mov esi,ebx
	sub esi,edx			; get the difference
	add esi,10h			; plus 16 bytes for 1st block header
	sub ecx,esi			; reduce size of free memory
	ja @@2				; if no error, jump
	mov mem_ptr[edi],eax		; not enough memory even for one
	mov mem_free[edi],eax		; memory block header, done now
	jmp @@done

@@2:	mov eax,12345678h		; header id
	mov [ebx+00h],eax
	mov [ebx+0Ch],eax
	movzx eax,id32_process_id
	mov [ebx+08h],eax		; set current process id
	mov [ebx+04h],ecx		; set first block unused/currentsize
	lea edx,[ebx+ecx+10h]		; get pointer to next block (mem_top)
	mov mem_top[edi],edx		; set top of memory
	mov mem_ptr[edi],ebx		; set base of memory
	mov mem_free[edi],ecx		; set size of memory

@@done:	sti
	jmp dvxr_init			; go to DPMI/VCPI/XMS/raw init tail







;-----------------------------------------------------------------------------
install_ints:
	xor di,di                       ; set up IDT
	xor ecx,ecx
	mov dx,word ptr picslave

@@1:	lea eax,[SELCODE*10000h+ecx*4+offs int_matrix]
	stos dword ptr es:[di]
	mov eax,8E00h			; interrupt gate type (IF=0)
	mov bl,cl			; isolate high 5 bits of int num
	and bl,0F8h
	test cl,0F0h			; one of the low 16 interrupts?
	jz @@2				; if yes, store as interrupt gate
	cmp bl,dl			; one of the high IRQs?
	je @@2				; if yes, store as interrupt gate
	cmp bl,dh			; one of the low IRQs?
	je @@2				; if yes, store as interrupt gate
	mov ax,8F00h			; set to trap gate type (IF=unchanged)
@@2:	stos dword ptr es:[di]
	inc cl                          ; increment interrupt number
	jnz @@1				; loop if more interrupts to go

	mov word ptr es:[8*21h],offs int21 ; protected mode INT 21h
	mov word ptr es:[8*31h],offs int31 ; protected mode INT 31h

	push ds es			; copy IRQ vectors into table
	push ds
	pop es
	xor ax,ax
	mov ds,ax
	mov di,offs irqtab_rm
	movzx si,dh
	shl si,2
	mov cx,8
	rep movs dword ptr es:[di],ds:[si]
	movzx si,dl
	shl si,2
	mov cl,8
	rep movs dword ptr es:[di],ds:[si]
	pop es ds

	test pm32_mode,00000010b	; if exception handling is off
	jz @@done			; we are done
;
; install INT 00h-0Eh exceptions
;
	mov ax,offs irq_fail		; offset of fail routine
	sub ax,offs int_matrix+4	; calculate offset displacement
	mov di,offs int_matrix+2	; DI = pointer into CALL matrix
	mov cl,15
@@l1:	mov ds:[di],ax			; modify CALL address
	sub ax,4			; PUSH + CALL = 4 byte
	add di,4
	loop @@l1
;
; install IRQ 0-15 (PIC dependent)
;
	movzx dx,picmaster		; install IRQ 0-7 (INT 08-0Fh)
	call setup_irqs
	movzx dx,picslave		; install IRQ 8-15 (INT 70-77h)
	call setup_irqs

	cmp picmaster,10h		; setup IRQ 7 (damn it!)
	jae @@done
	mov ax,(offs irq_normal) - (offs int_matrix+4) - 0Fh*4
	mov word ptr int_matrix[0Fh*4+2],ax	; restore INT 0Fh (IRQ 7)

@@done:	ret


setup_irqs:
	cmp dl,10h
	mov ax,offs irq_tester		; if DX is in range INT 00h - 0Fh
	jb @@4				;  install as IRQ check handler
	mov ax,offs irq_normal		; else no IRQ check is needed
@@4:	shl dx,2
	sub ax,offs int_matrix+4
	sub ax,dx
	mov di,offs int_matrix+2
	add di,dx
	mov cl,8			; 8 IRQs to go
@@l3:	mov ds:[di],ax
	sub ax,4			; PUSH + CALL is 4 bytes
	add di,4			; next entry in IDT
	loop @@l3			; loop
	ret


;-----------------------------------------------------------------------------
allocate_callbacks:
	movzx cx,pm32_callbacks		; CL = number of callbacks
	jcxz @@done			; if no, done with this part
	xor di,di			; location within callback seg
	mov ax,6866h
	mov dx,kernel_code

	push ds
	push es
	pop ds
@@1:	mov word ptr ds:[di],6066h	; PUSHAD instruction
	mov byte ptr ds:[di+2],ah	; PUSH WORD instruction
	mov word ptr ds:[di+3],0	; immediate 0 used as free flag
	mov word ptr ds:[di+5],ax	; PUSH DWORD instruction
	mov byte ptr ds:[di+11],0B9h	; MOV CX,? instruction
	mov word ptr ds:[di+14],ax	; PUSH DWORD instruction
	mov byte ptr ds:[di+20],0EAh	; JMP FAR PTR ?:? intruction
	mov word ptr ds:[di+21],offs callback
	mov word ptr ds:[di+23],dx
	add di,25			; increment ptr to callback
	loop @@1			; if more callbacks to do, loop
	pop ds

	add di,0Fh			; align next data area on paragraph
	shr di,4
	mov ax,es
	add ax,di
	mov es,ax			; set ES to base of next data area
@@done:	ret


;-----------------------------------------------------------------------------
vxr_initsetdsc:                         ; set descriptor for VCPI/XMS/raw init
	push ax
	movzx eax,ax                    ; EAX = base of segment
	shl eax,4
	mov word ptr es:[bx],cx         ; limit = CX
	mov dword ptr es:[bx+2],eax     ; base address = EAX
	mov word ptr es:[bx+5],dx       ; access rights = DX
	add bx,8                        ; increment descriptor index
	pop ax
	ret


;-----------------------------------------------------------------------------
xms_allocmem:
	push edi
	mov edi,edx
	mov ah,89h
	call dword ptr xms_call
	cmp ax,0001h
	jz @@ok
	mov dx,di
	mov ah,09h
	call dword ptr xms_call
@@ok:	pop edi
	ret


⌨️ 快捷键说明

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