294 lines
7.4 KiB
NASM
Executable File
294 lines
7.4 KiB
NASM
Executable File
; <20> ¡®â áâ㤥⠣à㯯ë 2084/3
|
||
; Œ ª ४® €â®
|
||
; ¯® ªãàáã –‚Œ
|
||
|
||
; <20>à®£à ¬¬ , ¯à®¨§¢®¤¨â ¯¥à¥å®¤ ¢ Protrcted Mode,
|
||
; ¯¥à¥¯à®£à ¬¨àã¥â ª®â஫«¥à ¯à¥àë¢ ¨© ¨ ¯à®¨§¢®¤¨â
|
||
; ¯¥à¥å¢ â ¯à¥àë¢ ¨ï ®â ª« ¢¨ âãàë.
|
||
|
||
; Œ ªà®á ¯à¥®¡à §®¢ ¨ï á¬¥é¥¨ï ¨§ 32-å ¡¨â®£® ᥣ¬¥â ¢ 16-¡¨âãî ¯¥à¥¬¥ãî
|
||
so equ small offset
|
||
|
||
.386p
|
||
|
||
; ‘¥£¬¥â Real Mode, 16 ¡¨â
|
||
RM_seg segment para public "CODE" use16
|
||
assume cs: RM_seg, ds: PM_seg, ss: Stack_seg
|
||
start:
|
||
; Žç¨áâ¨âì íªà
|
||
mov ax, 3
|
||
int 10h
|
||
; <20>®¤£®â®¢¨âì ᥣ¬¥âë¥ à¥£¨áâàë
|
||
push PM_seg
|
||
pop ds
|
||
; <20>஢¥à¨âì ०¨¬ (PM ¨«¨ ¥â)
|
||
mov eax, cr0
|
||
test al, 1
|
||
jz no_V86
|
||
; …᫨ 㦥 ¢ PM - á®®¡é¨âì ®¡ ®è¨¡ª¥ ¨ ¢ë©â¨
|
||
mov dx, so v86_msg
|
||
err_exit:
|
||
mov ah, 9
|
||
int 21h
|
||
mov ah, 4Ch
|
||
int 21h
|
||
; <20>஢¥à¨âì ¯à¨áãâá⢨¥ Windows
|
||
no_V86:
|
||
mov ax, 1600h
|
||
int 2Fh
|
||
test al, al
|
||
jz no_Windows
|
||
; …᫨ ¯®¤ Wondows - á®®¡é¨âì ¨ ¢ë©â¨
|
||
mov dx, so win_msg
|
||
jmp short err_exit
|
||
; *****************************************
|
||
; ‚ᥠ¢¯®à浪¥, ç âì ¢ë¯®«¥¨¥ ¯à®£à ¬¬ë
|
||
no_Windows:
|
||
; ‚ëç¨á«¨âì ¡ §ë ¤«ï ¢á¥å ¨á¯®«ì§ã¥¬ëå ¤¥áªà¨¯â®à®¢ ᥣ¬¥â®¢
|
||
xor eax, eax
|
||
mov ax, RM_seg ; <20> §®© 16bitCS ¡ã¤¥â RM_seg
|
||
shl eax, 4
|
||
mov word ptr GDT_16bitCS+2, ax ; ¡¨âë 15-0
|
||
shr eax, 16
|
||
mov byte ptr GDT_16bitCS+4, al ; ¡¨âë 23-16
|
||
mov ax, PM_seg
|
||
shl eax, 4
|
||
mov word ptr GDT_32bitCS+2, ax ; <20> §®© ¢á¥å 32bit* ¡ã¤¥â
|
||
mov word ptr GDT_32bitSS+2, ax ; PM_seg
|
||
mov word ptr GDT_32bitDS+2, ax
|
||
shr eax, 16
|
||
mov byte ptr GDT_32bitCS+4, al
|
||
mov byte ptr GDT_32bitSS+4, al
|
||
mov byte ptr GDT_32bitDS+4, al
|
||
; ‚ëç¨á«¨âì «¨¥©ë© ¤à¥á GDT
|
||
xor eax, eax
|
||
mov ax, PM_seg
|
||
shl eax, 4
|
||
push eax
|
||
add eax, offset GDT
|
||
mov dword ptr gdtr+2, eax
|
||
; ‡ £à㧨âì GDT
|
||
lgdt fword ptr gdtr
|
||
; ‚ëç¨á«¨âì «¨¥©ë© ¤à¥á IDT
|
||
pop eax
|
||
add eax, offset IDT
|
||
mov dword ptr idtr+2, eax
|
||
; ‡ £à㧨âì IDT
|
||
lidt fword ptr idtr
|
||
; ’.ª. ᮡ¨à ¥¬áï à ¡®â âì á 32-å ¡¨â®© ¯ ¬ïâìî - ®âªàëâì A20
|
||
in al, 70h
|
||
or al, 2
|
||
out 92h, al
|
||
; Žâª«îç¨âì ¯à¥àë¢ ¨ï
|
||
cli
|
||
; Žâª«îç¨âì ¥¬ ᪨àã¥¬ë¥ ¯à¥àë¢ ¨ï (NMI)
|
||
in al, 70h
|
||
or al, 80h
|
||
out 70h, al
|
||
; <20>¥à¥©â¨ ¢ § é¨é¥ë© ०¨¬
|
||
mov eax, cr0
|
||
or al, 1
|
||
mov cr0, eax
|
||
; ‡ £à㧨âì SEL_32bitCS ¢ CS
|
||
db 66h ; <20>à¥ä¨ªá ¯à¥®¡à §®¢ ¨ï à §à冷áâ¨
|
||
db 0EAh ; „ «ì¨© ¯¥à¥å®¤
|
||
dd offset PM_entry
|
||
dw Sel_32bitCS
|
||
RM_return:
|
||
; <20>¥à¥©â¨ ¢ Real Mode
|
||
mov eax, cr0
|
||
and al, 0FEh
|
||
mov cr0, eax
|
||
; ‘¡à®á¨âì ®ç¥à¥¤ì ¨ § £à㧨âì CS ॠ«ìë¬ ç¨á«®¬
|
||
db 0EAh
|
||
dw $+4
|
||
dw RM_seg
|
||
; “áâ ®¢¨âì ॣ¨áâàë ¤«ï à ¡®âë ¢ ॠ«ì®¬ ०¨¬¥
|
||
mov ax, PM_seg
|
||
mov ds, ax
|
||
mov es, ax
|
||
mov ax, Stack_seg
|
||
mov bx, stack_l
|
||
mov ss, ax
|
||
mov sp, bx
|
||
; ‡ £à㧨âì IDTR ¤«ï RM
|
||
mov ax, PM_seg
|
||
mov ds, ax
|
||
lidt fword ptr idtr_real
|
||
; <20> §à¥è¨âì NMI
|
||
in al, 70h
|
||
and al, 07Fh
|
||
out 70h, al
|
||
; <20> §à¥è¨âì ¯à¥àë¢ ¨ï
|
||
sti
|
||
; ¨ ¢ë©â¨
|
||
mov ah, 4Ch
|
||
int 21h
|
||
RM_seg ends
|
||
|
||
; 32-å ¡¨âë© á¥£¬¥â
|
||
PM_seg segment para "CODE" use32
|
||
assume cs: PM_seg
|
||
; ’ ¡«¨æ GDT ¨ IDT ¤.¡. ¢ë஢¥ë, ¯®í⮬ã à §¬¥é îâáï ¢ ç «¥ ᥣ¬¥â
|
||
GDT label byte
|
||
db 8 dup(0)
|
||
; 32-x ¡¨âë© 4-å ƒ¡ ᥣ¬¥â á ¡ §®© =0
|
||
GTD_flatDS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0
|
||
; 16-¨ ¡¨âë© 64-å Š¡ ᥣ¬¥â ª®¤ á ¡ §®© RM_seg
|
||
GDT_16bitCS db 0FFh,0FFh,0,0,0,10011010b,0,0
|
||
; 32-x ¡¨âë© 4-å ƒ¡ ᥣ¬¥â ª®¤ á ¡ §®© PM_seg
|
||
GDT_32bitCS db 0FFh,0FFh,0,0,0,10011010b,11001111b,0
|
||
; 32-x ¡¨âë© 4-å ƒ¡ ᥣ¬¥â ¤ ëå á ¡ §®© PM_seg
|
||
GDT_32bitDS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0
|
||
; 32-x ¡¨âë© 4-å ƒ¡ ᥣ¬¥â ¤ ëå á ¡ §®© Stack_seg
|
||
GDT_32bitSS db 0FFh,0FFh,0,0,0,10010010b,11001111b,0
|
||
gdt_size = $-GDT
|
||
gdtr dw gdt_size-1 ; <20>।¥« GDT
|
||
dd ? ; ‹¨¥©ë© ¤à¥á GDT
|
||
; <20> §¢ ¨ï ᥫ¥ªâ®à®¢
|
||
SEL_flatDS equ 001000b
|
||
SEL_16bitCS equ 010000b
|
||
SEL_32bitCS equ 011000b
|
||
SEL_32bitDS equ 100000b
|
||
SEL_32bitSS equ 101000b
|
||
|
||
; ’ ¡«¨æ ¤¥áªà¨¯â®à®¢ ¯à¥àë¢ ¨© IDT
|
||
IDT label byte
|
||
; ‚ᥠ¤¥áªà¨¯â®àë ¨¬¥îâ ⨯ 0Eh - 32-å ¡¨âë© è«î§ ¯à¥àë¢ ¨ï
|
||
; INT 00-07
|
||
dw 8 dup(so int_handler, SEL_32bitCS, 8E00h,0)
|
||
; INT 08(irq0)
|
||
dw so irq0_7_handler,SEL_32bitCS,8E00h,0
|
||
; INT 09(irq1)
|
||
dw so irq1_handler,SEL_32bitCS,8E00h,0
|
||
; INT 0Ah-0Fh (IRQ2-IRQ8)
|
||
dw 6 dup(so irq0_7_handler,SEL_32bitCS,8E00h,0)
|
||
; INT 10h-6Fh
|
||
dw 97 dup(so int_handler,SEL_32bitCS,8E00h,0)
|
||
; INT 70h-78h (IRQ8-IRQ15)
|
||
dw 8 dup(so irq8_15_handler,SEL_32bitCS,8E00h,0)
|
||
; INT 79h-FFh
|
||
dw 135 dup(so int_handler,SEL_32bitCS,8E00h,0)
|
||
idt_size = $-IDT
|
||
idtr dw idt_size-1 ; <20>।¥« IDT
|
||
dd ? ; ‹¨¥©ë© ¤à¥á ç « IDT
|
||
; ‘®¤¥à¦¨¬®¥ ॣ¨áâà IDTR ¢ ॠ«ì®¬ ०¨¬¥
|
||
idtr_real dw 3FFh,0,0
|
||
|
||
; ‘®®¡é¥¨ï ®¡ ®è¨¡ª å ¯à¨ áâ àâ¥
|
||
v86_msg db "<22>à®æ¥áá®à ¢ ०¨¬¥ v86 - ¥«ì§ï ¯¥à¥ª«îç¨âìáï ¢ PM$"
|
||
win_msg db "<22>à®£à ¬¬ ¬®¦¥â ¡ âì § ¯ãé¥ ¨§ ¯®¤ Windows$"
|
||
|
||
; ’ ¡«¨æ ¤«ï ¯¥à¥¢®¤ OE ᪠-ª®¤®¢ ¢ ASCII
|
||
scan2ascii db 0,1Bh,'1','2','3','4','5','6','7','8','9','0','-','=',8
|
||
screen_addr dd 0 ; ’¥ªãé ï ¯®§¨æ¨ï íªà ¥
|
||
|
||
; ’®çª ¢å®¤ ¢ 32-å ¡¨âë© § é¨é¥ë© ०¨¬
|
||
PM_entry:
|
||
; “áâ ®¢¨âì 32-å ¡¨âë© á⥪ ¨ ¤à㣨¥ ॣ¨áâàë
|
||
mov ax, SEL_flatDS
|
||
mov ds, ax
|
||
mov es, ax
|
||
mov ax, SEL_32bitSS
|
||
mov ebx, stack_l
|
||
mov ss, ax
|
||
mov esp, ebx
|
||
; <20> §à¥è¨âì ¯à¥àë¢ ¨ï
|
||
sti
|
||
; ¨ ¢®©â¨ ¢ ¢¥çë© æ¨ª«
|
||
jmp short $
|
||
|
||
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
;! Ž¡à ¡®â稪¨ ¯à¥àë¢ ¨© !
|
||
;! Œ®£¨¥ ¥ ª®à४âë - ¥«ì§ï ¤®¯ã᪠âì ®è¨¡®ª !
|
||
;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
||
; Ž¡à ¡®â稪 ®¡ë箣® ¯à¥àë¢ ¨ï
|
||
int_handler:
|
||
iretd
|
||
; Ž¡à ¡®â稪 ¯¯ à ⮣® ¯à¥àë¢ ¨ï IRQ0-IRQ7
|
||
irq0_7_handler:
|
||
push eax
|
||
mov al, 20h
|
||
out 20h, al
|
||
pop eax
|
||
iretd
|
||
; Ž¡à ¡®â稪 ¯¯ à ⮣® ¯à¥àë¢ ¨ï IRQ8-IRQ15
|
||
irq8_15_handler:
|
||
push eax
|
||
mov al, 20h
|
||
out 0A1h, al
|
||
pop eax
|
||
iretd
|
||
; Ž¡à ¡®â稪 IRQ1 - ¯à¥àë¢ ¨¥ ®â ª« ¢¨ âãàë
|
||
irq1_handler:
|
||
push eax ; <20>â® ¯¯ à ⮥ ¯à¥àë¢ ¨¥ -
|
||
push ebx ; á®åà ¨âì ॣ¨áâàë
|
||
push es
|
||
push ds
|
||
in al, 60h ; <20>à®ç¨â âì ᪠-ª®¤ ¦ ⮩ ª« ¢¨è¨
|
||
cmp al, 0Eh ; …᫨ ® ¡®«ìè¥, 祬 ®¡á«ã¦¨¢ ¥¬ë©
|
||
ja skip_translate ; ¬¨, - ¥ ®¡à ¡ âë¢ âì
|
||
cmp al, 1 ; …᫨ íâ® ESC,
|
||
je esc_pressed ; ¢ë©â¨ ¢ ॠ«ìë© à¥¦¨¬
|
||
mov bx, SEL_32bitDS ; ˆ ç¥:
|
||
mov ds, bx ; DS:EBX - â ¡«¨æ ¤«ï ¯¥à¥¢®¤
|
||
mov ebx, offset scan2ascii ; ᪠-ª®¤ ¢ ASCII
|
||
xlatb ; <20>८¡à §®¢ âì
|
||
mov bx, SEL_flatDS
|
||
mov es, bx ; ES:EBX - ¤à¥á ⥪ã饩
|
||
mov ebx, screen_addr ; <20>®§¨æ¨¨ íªà ¥
|
||
cmp al, 8 ; …᫨ ¦ â BkSpace
|
||
je bs_pressed ; ᮮ⢥âáâ¢ãî騩 ®¡à ¡®â稪
|
||
mov es:[ebx+0B8000h], al ; ¨ ç¥ ¯®á« âì ᨬ¢®« íªà
|
||
add dword ptr screen_addr, 2; “¢¥«¨ç¨âì ¤à¥á ¯®§¨æ¨¨ 2
|
||
jmp short skip_translate
|
||
bs_pressed: ; <20> ¦ â BkSpace:
|
||
mov al,' ' ; ‚뢥á⨠¯à®¡¥«
|
||
sub ebx, 2 ; ¢ ¯®§¨æ¨¨ ¯à¥¤ë¤ã饣® ᨬ¢®«
|
||
mov es:[ebx+0B8000h], al
|
||
mov screen_addr, ebx ; ¨ á®åà ¨âì ¤à¥á ¯¥à¥¤ë¤ ᨬ¢®« ,
|
||
; ª ª ⥪ã騩
|
||
skip_translate:
|
||
; <20> §à¥è¨âì à ¡®âã ª« ¢¨ âãàë
|
||
in al, 61h
|
||
or al, 80h
|
||
out 61h, al
|
||
; <20>®á« âì EOI ª®â஫«¥àã ¯à¥àë¢ ¨©
|
||
mov al, 20h
|
||
out 20h, al
|
||
; ‚®ááâ ®¢¨âì ॣ¨áâàë ¨ ¢ë©â¨
|
||
pop ds
|
||
pop es
|
||
pop ebx
|
||
pop eax
|
||
iretd
|
||
|
||
; *******************
|
||
; <20> ¦ â ESC
|
||
esc_pressed:
|
||
; <20> §à¥è¨âì à ¡®âã ª« ¢¨ âãàë, ¯®á« âì EOI ¨ ¢®ááâ ®¢¨âì ॣ¨áâàë
|
||
in al, 61h
|
||
or al, 80h
|
||
out 61h, al
|
||
mov al, 20h
|
||
out 20h, al
|
||
pop ds
|
||
pop es
|
||
pop ebx
|
||
pop eax
|
||
; ‚¥àãâìáï ¢ ॠ«ìë© à¥¦¨¬
|
||
cli
|
||
db 0EAh
|
||
dd offset RM_return
|
||
dw SEL_16bitCS
|
||
PM_seg ends
|
||
|
||
; ‘¥£¬¥â á⥪ , ¨á¯®«ì§ã¥âáï ª ª 16-¡¨âë© ¢ 16-¡¨â®© ç á⨠¯à®£à ¬¬ë ¨ ª ª
|
||
; 32-å ¡¨âë© (ç¥à¥§ ᥫ¥ªâ®à SEL_32bitSS) ¢ 32-å ¡¨â®© ç áâ¨
|
||
Stack_seg segment para stack "STACK"
|
||
stack_start db 100h dup(?)
|
||
stack_l = $-stack_start ; „«¨ á⥪ ¤«ï ¨¨æ¨ «¨§ 樨 ESP
|
||
Stack_seg ends
|
||
end start
|