1、V27.ASM
;
; v27.asm
;
;
.386p
data segment use16 public
data ends
code segment use16 public
assume cs:code,ds:data
code ends
os32_code segment use32 public
assume cs:os32_code,ds:data
os32_code ends
NULL_seg segment use16 public
NULL_seg ends
include s27.inc
include d27.inc
include HZ27.inc
include bios27.inc
include i27.inc
code segment use16 public
assume cs:code,ds:data
save_ss dw ?
save_sp dw ?
save_ds dw ?
save_idt dq ?
start_16:
call SetGraphMode
sidt save_idt
cli
lidt qword ptr IDTpword
lgdt qword ptr GDTpword
mov ax,ss ;save all segregs
mov cs:save_ss,ax
mov ax,sp
mov cs:save_sp,ax
mov ax,ds
mov cs:save_ds,ax
mov eax,cr0
or al,01h
mov cr0,eax
db 0eah
dw offset flush
dw OS16CodeSel
flush:
;jmp far ptr cs:entry_32
db 0eah ;change to 32 bits
dw offset start_32
dw OS32CodeSel
exit_16:
mov ax,OS16DataSel ;change all segregs
mov ds,ax ;to 16 bits
mov es,ax
mov ss,ax
mov eax,cr0
and al,0feh
mov cr0,eax
db 0eah
dw offset flush1
dw code
flush1:
mov ax,cs:save_ss
mov ss,ax
mov ax,cs:save_sp
mov sp,ax
mov ax,cs:save_ds
mov ds,ax
lidt save_idt ;In real mode,IDT.limit=03ffh,
;IDT.base=0
sti
call SetTextMode
mov ax,4c00h
int 21h
code ends
data segment use16 public
string db 'HZ DOS 0.9 by W X Z 1995.8',00h
data ends
data segment use16 public
dd 128 dup (?)
os_stack_top label dword
dd 4 dup (?)
ker_to_v8086_stack_top label dword
dw offset v8086_start,0 ;eip
dw code,0 ;cs
dw 3002h,02h ;eflags
dw offset v8086_stack_top,0
dw data,0 ;sp,ss
dw data,0 ;es
dw data,0 ;ds
dw data,0 ;fs
dw data,0 ;gs
dd 4 dup (?)
data ends
os32_code segment use32 public
assume cs:os32_code,ds:data
releave_32:
call DisablePage
db 0eah ;return start code 16
dw offset exit_16,0,OS16CodeSel
start_32:
mov ax,TmpTSSSel
ltr ax
;jmp far KerTSS
db 0eah
dw offset restart_32,0,KerTSSSel
restart_32:
call FillPageTable
call SetOurA0000H
; call SetA0000HExpend
call EnablePage
mov esp,offset ker_to_v8086_stack_top ; IRET virtual stack
clts ;clear taskgate
iretd ; enter v8086
SetOurA0000H proc near
mov ebx,PageE0000HBase
mov eax,0a0000h
mov ecx,64/4
mov dl,7
cld
exLoop2:
mov es:[ebx],eax
mov es:[ebx],dl
add ebx,4
add eax,4096
loop exLoop2
ret
SetOurA0000H endp
SetA0000HExpend proc near ; a0000 to b7fff
mov ebx,PageA0000HBase
mov eax,VirtualPage2Address
mov ecx,96/4
mov dl,7
cld
exLoop:
mov es:[ebx],eax
mov es:[ebx],dl
add ebx,4
add eax,4096
loop exLoop
mov eax,cr3
mov cr3,eax
ret
SetA0000HExpend endp
RestoreA0000H proc near
mov ebx,PageA0000HBase
mov eax,0a0000h
mov ecx,96/4
mov dl,7
cld
exLoop1:
mov es:[ebx],eax
mov es:[ebx],dl
add ebx,4
add eax,4096
loop exLoop1
mov eax,cr3
mov cr3,eax
ret
RestoreA0000H endp
FillPageTable proc near ;b8000 to expend memory e0000 to b8000
mov ebx,PageTableBase
mov ecx,1024
mov eax,0
loop1:
mov dl,7 ; s/u,r/w,p all allowed
cmp eax,0e0000h
jz loop12
cmp eax,0a0000h
jz loop11
cmp eax,0b8000h
jz loop10
jmp loop2
loop10:
; mov dl,7 ; p=1,u=1,r/w=0 read only =1 r/w
push eax
mov PageB8000HBase,ebx ; text display base
mov eax,VirtualPageAddress
mov es:[ebx],eax
mov es:[ebx],dl
pop eax
jmp loop3
loop11:
mov PageA0000HBase,ebx ; expended memory
jmp loop2
loop12:
mov GraphDataBase,eax ; e0000h is graph base
mov PageE0000HBase,ebx
loop2:
mov es:[ebx],eax
mov es:[ebx],dl
loop3:
add ebx,4
add eax,4096
loop loop1
;FillPageDir
mov eax,PageTableBase
mov ebx,PageDirBase
mov dl,7
mov es:[ebx],eax
mov es:[ebx],dl
ret
FillPageTable endp
EnablePage proc near
;EnablePage
mov eax,PageDirBase
mov cr3,eax
mov eax,cr0
or eax,80000000h ;PG=1
mov cr0,eax
jmp pageflush
pageflush:
mov eax,cr3
mov cr3,eax
ret
EnablePage endp
DisablePage proc near
mov eax,cr0
and eax,7fffffffh ;PG=0
mov cr0,eax
jmp pageflush2
pageflush2:
mov eax,cr3
mov cr3,eax
ret
DisablePage endp
SetPageInvalid proc near
mov ebx,PAgeB8000HBase
mov al,es:[ebx]
or al,40h
mov es:[ebx],al
mov eax,cr3
mov cr3,eax
ret
SetPageInvalid endp
;RET: al=0 clean,al!=0 not clean
GetPageIsNotClean proc near
mov ebx,PageB8000HBase
mov al,es:[ebx]
mov cl,al
and cl,40h
cmp cl,0
jz not_use
and al,7
mov es:[ebx],al
mov eax,cr3
mov cr3,eax
not_use:
xor eax,eax
mov al,cl
ret
GetPageIsNotClean endp
os32_code ends
include p27.inc
code segment use16 public
assume cs:code,ds:data
v8086_start:
; mov ax,Real32CodeSEG
mov ax,NULL_seg
sub ax,RealDataSEG
add ax,100
mov dx,ax
mov ax,3100h
int 21h ;quit
code ends
data segment use16 public
dd 128 dup(?)
v8086_stack_top dw ?
data ends
end begin
2、BIOS27.INC
;
; BIOS27.INC
;
;
data segment use16 public
BIOSCurX db 0
BIOSCurY db 0
CurFirstLine db 0
CurLastLine db 0
isArrow dd 0
biostmpchar db 0
biostmpcolor db 0
biostmpttycolor db 7
data ends
os32_code segment use32 public
assume cs:os32_code,ds:data
;para al:char,ah:attrib
BIOSGetCharAndAttrib proc near
push edx
call GetNumber
mov edx,ScreenBufBase
add edx,eax
mov ax,es:[edx]
pop edx
ret
BIOSGetCharAndAttrib endp
;ret al:char,bl:attrib,cx:rep
BIOSPutCharAndAttrib proc near
mov biostmpchar,al
mov biostmpcolor,bl
call GetNumber
mov esi,ScreenBufBase
add esi,eax
mov al,biostmpchar
mov es:[esi],al
mov al,biostmpcolor
ret
BIOSPutCharAndAttrib endp
BIOSPutCharAndNotPutAttrib proc near
mov biostmpchar,al
call GetNumber
mov esi,ScreenBufBase
add esi,eax
mov al,biostmpchar
mov es:[esi],al
ret
BIOSPutCharAndNotPutAttrib endp
os32_code ends
data segment use16 public
scr_lines db 0
scr_attr db 0
scr_x db 0
scr_y db 0
scr_width db 0
scr_high db 0
scr_forward db 0
data ends
os32_code segment use32 public
assume cs:os32_code,ds:data
;para ah=5 up,6:down al:lines, bh: attr
;ch:y,cl,x dh:yy,dl,xx
ScrollScreen proc near
mov scr_lines,al
mov scr_attr,bh
mov scr_x,cl
mov scr_y,ch
sub dl,cl
; inc dl ; need +1
mov scr_width,dl
sub dh,ch
; inc dh
mov scr_high,dh
mov scr_forward,ah
xor eax,eax
mov edx,eax
mov al,scr_y
cmp scr_forward,6
je isUpNotNeedAdd
add al,scr_high
isUpNotNeedAdd:
mov edx,160
mul edx
xor edx,edx
mov dl,scr_x
sal edx,1
add eax,edx ;eax offset
mov edx,ScreenBufBase
add eax,edx
mov esi,eax
mov edi,eax
cmp scr_forward,6
je isUp
sub esi,160
jmp beginScroll
isUp:
add esi,160
beginScroll:
mov ebx,esi
mov edx,edi
xor ecx,ecx
mov cl,scr_lines
scrLoop2:
call ScrollWindow
loop scrLoop2
ret
ScrollScreen endp
;para ebx,edx:offset
ScrollWindow proc near
push ebx
push ecx
push edx
xor ecx,ecx
mov cl,scr_high
scrLoop1:
mov esi,ebx
mov edi,edx
call ScrollLine
cmp scr_forward,6
jne isDownLine
add ebx,160
add edx,160
jmp continueScroll
isDownLine:
sub ebx,160
sub edx,160
continueScroll:
loop scrLoop1
mov esi,ebx
mov edi,edx
call FillBlank
pop edx
pop ecx
pop ebx
ret
ScrollWindow endp
;para esi:sour,edi:dest
ScrollLine proc near
push ecx
push esi
push edi
xor ecx,ecx
mov cl,scr_width
scrLoop:
mov ax,es:[esi]
mov es:[edi],ax
inc esi
inc esi
inc edi
inc edi
loop scrLoop
pop edi
pop esi
pop ecx
ret
ScrollLine endp
; para esi,edi:offset,
FillBlank proc near
push ecx
push edi
xor ecx,ecx
mov cl,scr_width
mov al,32
mov ah,scr_attr
cld
rep stosw
pop edi
pop ecx
ret
FillBlank endp
TTYPutChar proc near
cmp al,0dh
je put_CR
cmp al,0ah
je put_LF
cmp al,8
je put_BS
cmp al,7
je put_BEEP
push eax
call LastCur
call GotoXY
cmp dh,0
jne doing
cmp dl,0
jne doing
mov ah,7
jmp done
doing:
call BIOSGetCharAndAttrib
done:
mov biostmpttycolor,ah
call NextCur
pop eax
mov ah,biostmpttycolor
call BIOSPutCharAndAttrib
call NextCur
jmp exit_put
put_CR:
call GetXY
mov dl,0
call GotoXY
jmp exit_put
put_LF:
call GetXY
inc dh
call GotoXY
jmp exit_put
put_BS:
call LastCur
call GotoXY
mov al,32
call BIOSPutCharAndNotPutAttrib
jmp exit_put
put_BEEP:
beep
jmp exit_put
exit_put:
ret
TTYPutChar endp
NextCur proc near
call GetXY
inc dl
cmp dl,80
jae next_check ;>=
call GotoXY
ret
next_check:
mov dl,0
inc dh
cmp dh,25
jae need_scroll
call GotoXY
ret
need_scroll:
mov dh,24
call GotoXY
mov ah,6
mov al,1
mov bh,7
mov cx,0
mov dh,24
mov dl,79
call ScrollScreen ; up a line
ret
NextCur endp
LastCur proc near
call GetXY
cmp dl,0
je need_back
dec dl
ret
need_back:
cmp dh,0
je need_back2
dec dh
mov dl,79
ret
need_back2:
mov dl,0
ret
LastCur endp
os32_code ends
code segment use16 public
assume cs:code,ds:data
SetGraphMode proc near
mov ah,0
mov al,12h ;or other mode
int 10h
ret
SetGraphMode endp
SetTextMode proc near
mov ah,0
mov al,3
int 10h
ret
SetTextMode endp
code ends
3、D27.INC
; d27.inc
; for data
;
;
NULLSel equ 0
OS32CodeSel equ 8h
OS32DataSel equ 10h
OS16CodeSel equ 18h
OS16DataSel equ 20h
TmpTSSSel equ 28h
KerTSSSel equ 30h
User32DataSel equ 38h
data segment use16 public
IDTpword label qword
dw 07ffh ;2k
IDTBase dd 0
GDTpword label qword
dw 07ffh ;2k
GDTBase dd 0
GdtBegin label dword
NullSelDesc dq 0
OS32CodeSelDesc dd 0
dd 0
OS32DataSelDesc dd 0
dd 0
OS16CodeSelDesc dd 0
dd 0
OS16DataSelDesc dd 0
dd 0
TmpTSSSelDesc dd 0
dd 0
KerTSSSelDesc dd 0
dd 0
User32DataSelDesc dd 0
dd 0
GDTEnd label dword
data ends
data segment use16 public
TmpTSSBegin label word
dd 0 ;back
dw offset os_stack_top,0,OS32DataSel,0 ;stk0
dq 0 ;stk1
dq 0 ;stk2
dd 0 ;cr3
dw offset start_32,0 ;eip
dw 02,0 ;eflags
dd 0 ;regs
dd 0
dd 0
dd 0
dw offset os_stack_top,0 ;esp
dd 0
dd 0
dd 0
dw OS32DataSel,0 ;es
dw OS32CodeSel,0 ;cs
dw OS32DataSel,0 ;ss
dw OS32DataSel,0 ;ds
dw OS32DataSel,0 ;fs
dw OS32DataSel,0 ;gs
dw 0,0 ;ldt
dw 0 ;dtb
dw offset TmpTSSEnd+2
db 0ffh
TmpTSSEnd label word
db 0ffh
data ends
data segment use16 public
KerTssBegin label word
dd 0 ;back
dw offset os_stack_top,0,OS32DataSel,0 ;stk0
dq 0 ;stk1
dq 0 ;stk2
dd 0 ;cr3
dw offset restart_32,0 ;eip
dw 02h,0 ;eflags
dd 0 ;regs
dd 0
dd 0
dd 0
dw offset os_stack_top,0 ;esp
dd 0
dd 0
dd 0
dw User32DataSel,0 ;es
dw OS32CodeSel,0 ;cs
dw OS32DataSel,0 ;ss
dw OS32DataSel,0 ;ds
dw OS32DataSel,0 ;fs
dw OS32DataSel,0 ;gs
dw 0,0 ;ldt
dw 0 ;dtb
dw $+2-(offset KerTSSBegin) ;bitmap offset
db 400h/8 dup(0)
db 0ffh
KerTSSEnd label word
db 0ffh ;end of I/O bitmap
data ends
4、P27.INC
;
; p27.inc for switch virtual page mangner
;
;
;
data segment use16 public
RealCodeSEG dw ?
RealDataSEG dw ?
Real32CodeSEG dw ?
NULLSEG dw ?
data ends
code segment use16 public
assume cs:code,ds:data
begin:
mov ax,data
mov ds,ax
mov RealDataSEG,ax
mov ax,code
mov RealCodeSEG,ax
mov ax,os32_code
mov Real32CodeSEG,ax
mov ax,NULL_seg
mov NULLSEG,ax
call SetHZCodeAddress
mov ax,Real32CodeSEG
mov es,ax
mov ax,0
mov bx,offset OS32CodeSelDesc
mov cx,0cf9ah ; code,32bits,4KM
mov dx,0ffffh
call LoadSel
mov ax,RealDataSEG
mov es,ax
mov ax,0
mov bx,offset OS32DataSelDesc
mov cx,0cf92h ; data,32bits,4KM
mov dx,0ffffh
call LoadSel
mov ax,RealCodeSEG
mov es,ax
mov ax,0
mov bx,offset OS16CodeSelDesc
mov cx,9ah ; code,16bits,64k
mov dx,0ffffh
call LoadSel
mov ax,RealDataSEG
mov es,ax
mov ax,0
mov bx,offset OS16DataSelDesc
mov cx,92h ; data,16bits,64k
mov dx,0ffffh
call LoadSel
mov ax,0
mov es,ax
mov ax,0
mov bx,offset User32DataSelDesc
mov cx,0cf92h
mov dx,0ffffh
call LoadSel
mov ax,data
mov es,ax
mov ax,offset TmpTSSBegin
mov bx,offset TmpTSSSelDesc
mov cx,4089h
mov dx, (offset TmpTSSEnd)-(offset TmpTSSBegin)
call LoadSel
mov ax,data
mov es,ax
mov ax,offset KerTSSBegin
mov bx,offset KerTSSSelDesc
mov cx,4089h
mov dx, (offset KerTSSEnd)-(offset KerTSSBegin)
call LoadSel
call PageProcess
mov ax,data
mov es,ax
mov ax,offset GDTBegin
call Get20BitsOffset
mov GDTBase,eax
mov ax,RealDataSEG
mov es,ax
mov ax,offset IDTBegin
call Get20BitsOffset
mov IDTBase,eax
jmp far ptr start_16
int 19h
code ends
code segment use16 public
assume cs:code,ds:data
; LoadSel put base and attrib to sel's desc
;
;
; para
; es: REAL_SEG
; ax: REAL_OFFSET
; bx: SEL's offset
; cx: SEG_ATTRIB
; dx: SEL's limit
LoadSel proc near
and eax,0ffffh ; only ax is offset
and ebx,0ffffh ; only bx is offset
xor esi,esi
mov si,es
sal esi,4
add eax,esi
mov word ptr [bx],dx ;limit: 0_64K
mov dword ptr [bx]+2,eax ;base: 0_23(16M)
mov word ptr [bx]+5,cx ;attrib: word
mov byte ptr [bx]+7,0
ret
LoadSel endp
; Get20BitsOffset let (SEG<<4)+OFFSET
;
;para
;es: SEG
;ax,offset
;ret
;eax: 20bitsoffset
Get20BitsOffset proc near
xor ebx,ebx
and eax,0ffffh
mov bx,es
sal ebx,4
add eax,ebx
ret
Get20BitsOffset endp
SetHZCodeAddress proc near
mov ax,1130h
mov bh,6
int 10h
mov ax,bp ;es:bp rom 8*16 ascii code
call Get20BitsOffset
mov TextCodeAddress,eax
mov ax,0
mov es,ax
mov bx,4f0h
mov eax,es:[bx]
mov HZCodeAddress,eax ;HZCodeAddress
add bx,4
mov eax,es:[bx] ;CodeAddress 192K size
shr eax,12
inc eax
sal eax,12
mov CodeAddress,eax ; in 4k size
mov VirtualPageAddress,eax
add eax,4096
mov TextBufAddress,eax
add eax,4096
mov VirtualPage2Address,eax ; expend memory
add eax,(64+32)*1024 ; from a0000 to b7fff
mov OS32CodeBase,eax ; Move up code32self
add eax,1024*64
mov NowCodeAddress,eax
ret
SetHZCodeAddress endp
PageProcess proc near
mov ax,ds
mov es,ax
mov ax,offset PageBuf
call Get20BitsOffset
shr eax,12 ;must in 4K size
shl eax,12
add eax,4096
mov PageDirBase,eax
add eax,4096
mov PageTableBase,eax
ret
PageProcess endp
code ends
data segment use16 public
OS32CodeBase dd ?
PageDirBase dd ?
PageTableBase dd ?
PageBuf db 12*1024 dup (?)
data ends
5、S27.INC
; s27.inc
; for macros and subfunctions
;
;
Beep macro
local delay0,delay1
push eax
push ecx
in al,61h
mov ah,al
or al,03h
nop
nop
nop
nop
nop
nop
nop
out 61h,al
mov eax,06fh
delay0: mov ecx,0ffffh
delay1: loop delay1
clc
sub eax,1
jnz delay0
mov al,ah
out 61h,al
pop ecx
pop eax
endm