www.pudn.com > czxtsycx1.zip > G_INT81.ASM


.MODEL HUGE 
.386P 
include \tc\g\include\g_def.asm   ; 描述符结构、常量、宏定义,清单见程序1-1 
STACK       SEGMENT STACK PARA 'STACK' 
            DB 200 DUP(0) 
STACK       ENDS 
CODE        SEGMENT WORD PUBLIC 'CODE' 
            ASSUME CS:CODE,DS:DATA,SS:STACK 
G_INT21     PROC FAR 
START:       
            MOV AX,DATA 
            MOV DS,AX 
            CLI 
            MOV AX,STACK 
            MOV SS,AX 
            MOV SAVE_SS,AX 
            ;MOV SP,200 
            MOV SAVE_SP,SP 
            STI 
            MOV AH,0DFH 
            CALL OPEN_A20 
            ; save current GDTR & IDTR 
            SGDT FWORD PTR SAVE_GDT 
            SIDT FWORD PTR SAVE_IDT 
            ;*************************** setup interrupt desc 
            ;set idt_desc for IDT21 
            MOV DI,OFFSET IDT21 
            MOV AX,OFFSET GINT21H 
            MOV [DI].OFF_L,AX 
            ;set gdt_desc for cs 
            MOV DI,OFFSET GDT_CS 
            MOV AX,CS 
            MOV CX,10H 
            MUL CX 
            MOV [DI].BASE_L,AX 
            MOV [DI].BASE_M,DL 
            ;set gdt_desc for ds 
            MOV DI,OFFSET GDT_DS 
            MOV DX,0 
            MOV AX,DS 
            MOV CX,10H 
            MUL CX 
            MOV [DI].BASE_L,AX 
            MOV [DI].BASE_M,DL 
            MOV [DI].BASE_H,DH 
            ;set gdt_desc for ss 
            MOV DI,OFFSET GDT_SS 
            MOV AX,SS 
            MOV CX,10H 
            MUL CX 
            MOV [DI].BASE_L,AX 
            MOV [DI].BASE_M,DL 
            ;*********************************************** 
                                     ;setup idt 
            CLI 
            MOV AX,DS 
            MOV CX,10H 
            MUL CX 
            ADD AX,OFFSET IDT0 
                         ;DX:AX=32 address for IDT 
            ADC DX,0  
            MOV IDTLOAD,AX 
            MOV IDTLOAD+2,DX 
            MOV AX,OFFSET IDT_SIZE 
            SUB AX,OFFSET IDTSIZE 
            ADD AX,1 
            MOV IDTSIZE,AX 
            ;*********************************************** 
            MOV AX,DS 
            MOV CX,10H 
            MUL CX 
            ADD AX,OFFSET GDT_DEF  
                         ;DX:AX=32 address for GDT 
            ADC DX,0  
            MOV GDTLOAD,AX 
            MOV GDTLOAD+2,DX 
            MOV AX,OFFSET GDT_SIZE 
            SUB AX,OFFSET GDTSIZE 
            ADD AX,1 
            MOV GDTSIZE,AX 
TURN_TO_PROTECT_MODE: 
            cli 
            LGDT FWORD PTR GDTSIZE 
            LIDT FWORD PTR IDTSIZE 
            MOV EAX,00000001H 
            MOV CR0,EAX 
            JMP EDS_FLUSH         ;clear instructors 
EDS_FLUSH:  DB 0EAH 
            DW OFFSET VRAM_DISP 
            DW GDT_CS_SEL 
VRAM_DISP:   
            MOV AX,G_VRAM_SEL 
            MOV ES,AX 
            MOV AX,GDT_DS_SEL 
            MOV DS,AX 
            ;DS:DX string(ended by '$') addr 
            MOV AH,9 
            MOV CX,0810H ;08 row 10 column 
            MOV DX,OFFSET TEST_MSG 
            INT 21H 
 
COMEBACK_TO_TOS: 
            CLI 
            MOV EAX,CR0 
            AND AX,NOT PE_ON 
            MOV CR0,EAX 
            DB 0EAH 
            DW OFFSET REAL_MODE 
            DW CODE 
REAL_MODE:  MOV AH,0DDH 
            CALL CLOSE_A20 
            ; 
            MOV AX,DATA 
            MOV DS,AX 
            MOV SS,SAVE_SS 
            MOV SP,SAVE_SP 
            LGDT FWORD PTR SAVE_GDT 
            LIDT FWORD PTR SAVE_IDT 
            ; 
            sti 
            LEA DX,OK_MSG 
            MOV AH,9 
            INT 21H 
            MOV AH,4CH 
            INT 21H 
G_INT21     ENDP 
include     \tc\g\include\tos_used.asm 
include     \tc\g\include\a20.asm 
CODE        ENDS 
 
DATA        SEGMENT WORD PUBLIC 'DATA' 
t_string    DB 80 DUP(?) 
OK_MSG      DB 0DH,0AH,'Return to DOS, Bye!   $' 
TEST_MSG    DB 'This is a test string! $' 
SAVE_GDT    DW 4 DUP(0) 
SAVE_IDT    DW 4 DUP(0) 
SAVE_SS     DW 0 
SAVE_SP     DW 0 
 
IDTSIZE     DW 272 
IDTLOAD     DW 0,0 
IDT0        IDT_DESC <> 
IDT1        DW 128 DUP(0) ;01->20 32*4 
IDT21       IDT_DESC <0,GDT_CS_SEL,8E00H,0> 
                           ;P=1,DPL=0,TYPE=14 
IDT_SIZE    DW 272 
 
GDTSIZE     DW 0 
GDTLOAD     DW 0,0 
GDT_DEF     GDT_DESC <0,0,0,0,0,0> 
GDT_CS      GDT_DESC <0FFFFH,0,0,9AH,0,0> 
                           ;9AH=exec/read ,DPL=0 
GDT_DS      GDT_DESC <0FFFFH,0,0,92H,0,0> 
                           ;92H=P ,DPL=0,TYPE=2 
GDT_SS      GDT_DESC <0FFFFH,0,0,96H,0,0>    
                           ;96H=R/W ,DOWN 
G_VRAM      GDT_DESC <0FFFFH,08000H,0BH,92H,0,0> 
                           ;92H=P ,DPL=0,TYPE=2 
G_VRAM_SEL  = G_VRAM - GDT_DEF 
GDT_SIZE    DW 0 
; next no use 
real_sel      = $ 
ps_to_tos_sel = $ 
tos_code_sel  =$ 
DATA        ENDS 
            END START