📄 cw32.asm
字号:
@@pl3: push es
mov ax,KernalZero
mov es,ax
mov esi,GDTLinear
add esi,KernalTS-3
mov es:b[esi+5],DescPresent+DescPL3+Desc386Tss
pop es
;
;Setup initial segment variables.
;
push ds
mov ax,MainDS
mov ds,ax
assume ds:_cwMain
or w[SystemFlags],32768 ;Flags us in protected mode.
mov RealSegment,KernalZero
mov PspSegment,MainPSP
mov EnvSegment,MainENV
mov CodeSegment,MainCS
mov DataSegment,MainDS
mov StackSegment,MainSS
assume ds:_cwRaw
pop ds
;
;Make sure A20 is enabled.
;
push ds
mov ax,InitDS
mov ds,ax
assume ds:_cwInit
mov IErrorNumber,7
assume ds:_cwRaw
pop ds
mov ax,1
push cs
push offset @@1
push KernalCS
push offset A20Handler
retf
@@1: jnz InitError
;
;Now get extended memory sorted out, move the page tables into extended memory
;for a start.
;
push ds
mov ax,InitDS
mov ds,ax
assume ds:_cwInit
mov IErrorNumber,5
assume ds:_cwRaw
pop ds
mov ax,KernalZero
mov es,ax
;
;Allocate 2nd page table so we can map extended memory.
;
call d[fPhysicalGetPage]
jc InitError
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov eax,1
mov esi,PageDIRLinear
mov es:d[esi+eax*4],edx ;store this tables address.
mov esi,PageAliasLinear ;get alias table address.
mov es:d[esi+eax*4],edx ;setup in alias table as well.
call d[fCR3Flush]
mov edi,1024*4096*1023 ;base of page alias's.
mov eax,1024*4 ;get the entry number again.
add edi,eax
mov ecx,4096/4
xor eax,eax
cld
db 67h
rep stosd
call d[fCR3Flush]
mov LinearEntry,1024
;
;Setup DET page alias.
;
call d[fPhysicalGetPage] ;get page for new page 1st DET.
jc InitError
mov LinearEntry+8,edx ;store physical address.
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov eax,LinearEntry ;get the entry number again.
mov esi,1024*4096*1023 ;base of page alias's.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
mov edi,LinearEntry
shl edi,12
mov ecx,4096/4
xor eax,eax
cld
db 67h
rep stosd ;clear it.
mov eax,LinearEntry
shl eax,12 ;get linear address.
mov PageDETLinear,eax
mov eax,1022
mov esi,PageDIRLinear
mov edx,LinearEntry+8 ;get physical address again.
or edx,111b
mov es:[esi+eax*4],edx ;put new page into the map.
mov esi,PageALIASLinear
mov es:[esi+eax*4],edx ;put new page into the map.
call d[fCR3Flush]
inc LinearEntry
;
;Setup DET page 1st.
;
call d[fPhysicalGetPage] ;get page for new page 1st.
jc InitError
mov LinearEntry+8,edx ;store physical address.
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov esi,1024*4096*1023 ;base of page alias's.
mov eax,LinearEntry ;get the entry number again.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
mov edi,LinearEntry
shl edi,12
mov ecx,4096/4
mov eax,MEM_FILL
cld
db 67h
rep stosd ;copy old to new.
mov esi,PageDETLinear
mov eax,0
mov edx,LinearEntry+8 ;get physical address again.
or edx,111b
mov es:[esi+eax*4],edx ;put new page into the map.
call d[fCR3Flush]
inc LinearEntry
;
;Allocate 2nd page DET
;
call d[fPhysicalGetPage] ;get page for new page 1st.
jc InitError
mov LinearEntry+8,edx ;store physical address.
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov esi,1024*4096*1023 ;base of page alias's.
mov eax,LinearEntry ;get the entry number again.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
mov edi,LinearEntry
shl edi,12
mov ecx,4096/4
mov eax,MEM_FILL
cld
db 67h
rep stosd ;copy old to new.
mov esi,PageDETLinear
mov eax,1
mov edx,LinearEntry+8 ;get physical address again.
or edx,111b
mov es:[esi+eax*4],edx ;put new page into the map.
call d[fCR3Flush]
inc LinearEntry
;
;Move page alias into extended memory.
;
call d[fPhysicalGetPage] ;get page for new page 1st.
jc InitError
mov LinearEntry+8,edx ;store physical address.
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov eax,LinearEntry ;get the entry number again.
mov esi,1024*4096*1023 ;base of page alias's.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
push ds
mov esi,PageAliasLinear
mov edi,LinearEntry
shl edi,12
mov ecx,4096/4
push es
pop ds
cld
db 67h
rep movsd ;copy old to new.
pop ds
mov eax,PageALIASLinear
mov PageALIASLinear+4,eax
mov eax,LinearEntry
shl eax,12 ;get linear address.
mov PageALIASLinear,eax
mov esi,PageDIRLinear
mov eax,1023
mov edx,LinearEntry+8 ;get physical address again.
or edx,111b
mov ecx,es:[esi+eax*4] ;get origional value.
mov PageALIASLinear+8,ecx
mov es:[esi+eax*4],edx ;put new page into the map.
mov esi,PageALIASLinear
mov eax,1023
mov edx,LinearEntry+8 ;get physical address again.
or edx,111b
mov es:[esi+eax*4],edx ;put new page into the map.
call d[fCR3Flush]
inc LinearEntry
; MED 09/19/96
COMMENT !
;
;Move page 1st into extended memory.
;
call d[fPhysicalGetPage] ;get page for new page 1st.
jc InitError
mov LinearEntry+8,edx ;store physical address.
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
;
;Map it into general linear address space.
;
mov eax,LinearEntry ;get the entry number again.
mov esi,1024*4096*1023 ;base of page alias's.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
;
;Copy table to new memory.
;
push ds
mov esi,Page1stLinear
mov edi,LinearEntry
shl edi,12
mov ecx,4096/4
push es
pop ds
cld
db 67h
rep movsd ;copy old to new.
pop ds
;
;Make variables point to new memory.
;
mov eax,Page1stLinear
mov Page1stLinear+4,eax ;store old address.
mov eax,LinearEntry
shl eax,12 ;get linear address.
mov Page1stLinear,eax ;set new linear address.
;
;Set new address in page dir.
;
mov edx,LinearEntry+8 ;get physical address again.
or edx,111b
;
mov esi,PageDIRLinear
mov eax,0
mov ecx,es:[esi+eax*4] ;get origional value.
mov Page1stLinear+8,ecx
mov es:[esi+eax*4],edx ;put new page into the map.
call d[fCR3Flush]
;
;Set new address in page dir alias.
;
mov esi,PageALIASLinear
mov eax,0
mov es:[esi+eax*4],edx ;put new page into the map.
call d[fCR3Flush]
inc LinearEntry
END COMMENT !
;
;Move page dir into extended memory.
;
call d[fPhysicalGetPage] ;get page for new page DIR.
jc InitError
mov LinearEntry+8,edx ;store physical address.
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
;
;Map it into normal linear address space.
;
mov eax,LinearEntry ;get the entry number again.
mov esi,1024*4096*1023 ;base of page alias's.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
;
;Copy table to new memory.
;
push ds
mov esi,PageDIRLinear
mov edi,LinearEntry
shl edi,12
mov ecx,4096/4
push es
pop ds
cld
db 67h
rep movsd ;copy old to new.
pop ds
;
;Make variables point to new memory.
;
mov eax,PageDirLinear
mov PageDIRLinear+4,eax ;store old value.
mov eax,LinearEntry
shl eax,12 ;get linear address.
mov PageDIRLinear,eax ;set new value.
mov eax,VCPI_CR3
mov PageDIRLinear+8,eax ;store old physical address.
mov eax,LinearEntry+8
mov VCPI_CR3,eax ;set new physical address.
movzx edi,KernalTSSReal
shl edi,4
mov es:[edi].tCR3,eax ;set CR3 in TSS as well.
call d[fCR3Flush]
inc LinearEntry
;
;Setup IDT.
;
call d[fPhysicalGetPage] ;get page for new page DIR.
jc InitError
mov LinearEntry+8,edx ;store physical address.
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov eax,LinearEntry ;get the entry number again.
mov esi,1024*4096*1023 ;base of page alias's.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
mov eax,LinearEntry
shl eax,12
mov d[IDTVal+2],eax
mov w[IDTVal],0+(256*8)-1
;
mov bp,256 ;number of vectors.
mov ecx,offset InterruptHandler ;code address.
mov esi,DpmiEmuCS0 ;gate to use.
mov al,0
mov ah,DescPresent+DescPL3+Desc386Int
mov edi,d[IDTVal+2]
@@3: call MakeDesc2
add edi,8 ;next table address.
add ecx,8 ;/
dec bp
jnz @@3
inc LinearEntry
;
;Re-load IDT value.
;
push es
mov edi,offset MemIntBuffer
push ds
pop es
mov Real_CS[edi],_cwInit
mov Real_IP[edi],offset IDTFlush
mov Real_SS[edi],0
mov Real_SP[edi],0
call d[fRawSimulateFCALL]
pop es
;
;Get extended memory for DPMI emulator.
;
push ds
mov ax,InitDS
mov ds,ax
assume ds:_cwInit
mov IErrorNumber,5
assume ds:_cwRaw
pop ds
;
mov ebp,offset cwDPMIEMUEnd-cwDPMIEMUStart
add ebp,4095
shr ebp,12 ;Get number of pages needed.
mov eax,LinearEntry
shl eax,12
mov LinearEntry+4,eax ;Store start address.
@@2: call d[fPhysicalGetPage] ;try to allocate a page.
jc InitError
and ecx,1 ;put user bits in useful place.
shl ecx,10
and edx,not 4095 ;lose user bits.
or edx,111b ;present+user+write.
or edx,ecx ;set use flags.
mov eax,LinearEntry ;get the entry number again.
mov esi,1024*4096*1023 ;base of page alias's.
mov es:d[esi+eax*4],edx ;set physical address.
call d[fCR3Flush]
inc LinearEntry ;update pointer.
dec ebp
jnz @@2
;
;Copy DPMI emulator code into extended memory we just allocated.
;
mov edi,LinearEntry+4 ;Get the destination.
mov si,_cwDPMIEMU
movzx esi,si
shl esi,4 ;Point to the source.
mov ecx,offset cwDPMIEMUEnd-cwDPMIEMUStart
shr ecx,2
push ds
push es
pop ds
cld
db 67h
rep movsd ;Copy it up their.
pop ds
;
;Setup DPMI emulator selectors.
;
push es
mov ax,GDTData
mov es,ax
mov esi,LinearEntry+4
mov ecx,offset cwDPMIEMUEnd-cwDPMIEMUStart
mov al,1 shl 6
mov ah,DescPresent+DescPL3+DescMemory+DescERCode
mov di,DpmiEmuCS
call MakeDesc
mov esi,LinearEntry+4
mov ecx,offset cwDPMIEMUEnd-cwDPMIEMUStart
mov al,1 shl 6
mov ah,DescPresent+DescPL0+DescMemory+DescERCode
mov di,DpmiEmuCS0
call MakeDesc
mov esi,LinearEntry+4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -