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


;*************************************************v86 
;*************************************************v86 
V86CODESEG  SEGMENT PARA USE16   ;8086 code 
            ASSUME CS:V86CODESEG,DS:V86_DATASEG 
V86BEGIN    PROC FAR     
            cli 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            MOV AX,DS:V86_AX 
            MOV BX,DS:V86_BX 
            MOV CX,DS:V86_CX 
            MOV DX,DS:V86_DX 
            CMP DS:G_INT,10H 
            JE DOS_10H 
            CMP DS:G_INT,13H 
            JE DOS_13H 
            CMP DS:G_INT,16H 
            JE DOS_16H 
            CMP DS:G_INT,1AH 
            JE DOS_1AH 
            CMP DS:G_INT,21H 
            JE DOS_21H 
            JMP G_TO_COS 
DOS_10H: 
            ;G_DIRECT_BIOS_START  
            mov ax,0 
            mov ds,ax 
            mov di,64 ;10h 
            mov BX,ds:[di] 
            mov CX,ds:[di+2] 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            mov DS:g_ipcs,BX 
            mov DS:g_ipcs[2],CX 
            ; DO INT 10H 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            MOV AX,DS:V86_AX 
            MOV BX,DS:V86_BX 
            MOV CX,DS:V86_CX 
            MOV DX,DS:V86_DX 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs 
            ;G_DIRECT_BIOS_END 
 
            ;save out_information 
            PUSH AX 
            MOV AX,V86_DATASEG          
            MOV DS,AX 
            MOV DS:V86_BX_O,BX 
            MOV DS:V86_CX_O,CX 
            MOV DS:V86_DX_O,DX 
            POP AX 
            MOV DS:V86_AX_O,AX 
            JMP G_TO_COS 
DOS_13H: 
            ;G_DIRECT_BIOS_START  
            mov ax,0 
            mov ds,ax 
            mov di,76 ;13h 
            mov BX,ds:[di] 
            mov CX,ds:[di+2] 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            mov DS:g_ipcs,BX 
            mov DS:g_ipcs[2],CX 
            ; DO INT 13H 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            MOV ES,AX 
            MOV BX,OFFSET V86_BUFFER 
            MOV AX,DS:V86_AX 
            MOV CX,DS:V86_CX 
            MOV DX,DS:V86_DX 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs 
            ;G_DIRECT_BIOS_END 
            JMP G_TO_COS 
DOS_16H: 
            ;G_DIRECT_BIOS_START  
            mov ax,0 
            mov ds,ax 
            mov di,88 ;16h 
            mov BX,ds:[di] 
            mov CX,ds:[di+2] 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            mov DS:g_ipcs,BX 
            mov DS:g_ipcs[2],CX 
            ; DO INT 16H 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            MOV ES,AX 
            MOV BX,OFFSET V86_BUFFER 
            MOV AX,DS:V86_AX 
            MOV CX,DS:V86_CX 
            MOV DX,DS:V86_DX 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs 
            ;G_DIRECT_BIOS_END 
            MOV DS:V86_AX_O,AX 
            JMP G_TO_COS 
DOS_1AH: 
            ;G_DIRECT_BIOS_START  
            mov ax,0 
            mov ds,ax 
            mov di,104 ;1Ah    1AH*4=104 
            mov BX,ds:[di] 
            mov CX,ds:[di+2] 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            mov DS:g_ipcs,BX 
            mov DS:g_ipcs[2],CX 
            ; DO INT 1AH 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            MOV ES,AX 
            MOV BX,OFFSET V86_BUFFER 
            MOV AX,DS:V86_AX 
            MOV CX,DS:V86_CX 
            MOV DX,DS:V86_DX 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs 
            ;G_DIRECT_BIOS_END 
            MOV DS:V86_CX_O,CX 
            MOV DS:V86_DX_O,DX 
            JMP G_TO_COS 
 
DOS_21H: 
            CMP AH,09 
            JE  DOS_21H09 
            CMP AH,0AH 
            JE  DOS_21H0A 
            JMP DO_DOS_21H 
DOS_21H09: 
            ;MOV DX,OFFSET V86_BUFFER 
            ;jmp DO_DOS_21H  ; now use follow than using these 2 lines 
 
            ;G_DIRECT_BIOS_END   
            ;in :ds:dx addr for string ended by '$' 
            cli 
            mov ax,0 
            mov ds,ax 
            mov di,64 ;10h 
            mov BX,ds:[di] 
            mov CX,ds:[di+2] 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            mov DS:g_ipcs,BX 
            mov DS:g_ipcs[2],CX    ; bios_ADDRESS FOR INT 10H 
;JMP G_TO_COS 
            MOV AH,3H 
            MOV BH,0 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs ;READ CURSOR-->DH/DL:row/column 
            cli 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            MOV CX,DS:V86_CX 
            MOV ES,AX 
            MOV DS:V86_BP,BP 
            MOV BP,OFFSET V86_BUFFER 
            MOV AX,1301H 
            MOV BH,0 
            MOV BL,7h 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs ;dispay string 
            cli 
            MOV BP,DS:V86_BP 
            JMP G_TO_COS 
            ;G_DIRECT_BIOS_END 
 
DO_DOS_21H: 
            INT 21H 
            JMP G_TO_COS 
             
DOS_21H0A:                     ;NO 21H0A DIRECT CALL BIOS 0A 
            ;G_DIRECT_BIOS_START  
            mov ax,0 
            mov ds,ax 
            mov di,64 ;10h 
            mov BX,ds:[di] 
            mov CX,ds:[di+2] 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            mov DS:g_ipcs2,BX 
            mov DS:g_ipcs2[2],CX    ;ADDRESS FOR INT 10H 
 
            mov ax,0 
            mov ds,ax 
            mov di,88 ;16h 
            mov BX,ds:[di] 
            mov CX,ds:[di+2] 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            mov DS:g_ipcs,BX 
            mov DS:g_ipcs[2],CX      ;ADDRESS FOR INT 16 
            ; DO INT 16H 
            MOV AX,V86_DATASEG 
            MOV DS,AX 
            MOV SI,OFFSET V86_BUFFER 
            MOV AX,DS:V86_AX 
            MOV DL,AL        ;READ_COUNT 
            ADD SI,2 
DOS_21H0A_1:  
            CMP DL,0 
            JE  DOS_21H0A_2      ;buffer is full 
            XOR DI,DI 
            PUSH DI 
            MOV AH,10H 
            call dword ptr ds:g_ipcs 
            CMP AL,0DH            ;input_string='enter' 
            JE DOS_21H0A_2  
            CMP AL,08H 
            JE DOS_21H0A_08 
            CMP AL,0E0H 
            JE DOS_21H0A_08 
            MOV DS:[SI],AL           ;AL->V86_BUFFER 
            INC SI 
            MOV AH,9H 
            MOV BH,0 
            MOV BL,7                 ;41H RED_BACKGROUND 
            MOV CX,1 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs2 ;DISPLAY CHAR 
            PUSH DX 
            MOV AH,3H 
            MOV BH,0 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs2 ;READ CURSOR 
            INC DL 
            MOV AH,2 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs2 ;SET CURSOR 
            POP DX 
            DEC DL 
            JMP DOS_21H0A_1  
DOS_21H0A_08:  
            PUSH DX 
            MOV AH,3H 
            MOV BH,0 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs2 ;READ CURSOR 
            DEC DL 
            DEC SI 
            MOV AH,2 
            XOR DI,DI 
            PUSH DI 
            call dword ptr ds:g_ipcs2 ;SET CURSOR 
            POP DX 
            JMP DOS_21H0A_1  
 
DOS_21H0A_2_FULL:  
            MOV AL,0DH 
            DEC SI 
DOS_21H0A_2:  
            MOV DS:[SI],AL           ;AL='enter'->V86_BUFFER 
            MOV SI,OFFSET V86_BUFFER 
            INC SI 
            MOV AL,255 
            DEC DL 
            SUB AL,DL 
            MOV DS:[SI],AL 
            JMP G_TO_COS 
 
            ;8086 WIRTE "$" 
            mov di,130h 
qq0:        mov cx,0ffffh 
qq1:        mov ax,0b800h 
            mov es,ax 
            mov al,24h  ;"$" 
            mov ah,41H 
            mov es:1762,ax 
            dec cx 
            cmp cx,1 
            ja qq1 
            dec di 
            cmp di,1 
            ja qq0 
G_TO_COS:   cli 
            INT 0FFH 
V86BEGIN    ENDP 
V86CODESEG  ENDS 
 
V86IDTSEG   SEGMENT PARA USE16 
            REPT 8 
               IDT_DESC   ;TYPE=386 INTERRUPT DPL=3 P=1 
            ENDM 
V86IDT08    IDT_DESC   ;ok 
            REPT 4 
               IDT_DESC   ;TYPE=386 INTERRUPT DPL=3 P=1 
            ENDM 
            IDT_DESC   ;efTYPE=386 INTERRUPT DPL=3 P=1 
            REPT 241           ;256 - 14 
               IDT_DESC <0,V86_INTX_CODE_SEL,0EE00H,0>  ;TYPE=386 INTERRUPT DPL=3 P=1 
            ENDM 
            IDT_DESC   ;efTYPE=386 INTERRUPT DPL=3 P=1 
            ;IDT_DESC <0,TOS_TSS_SEL,0E500H,0>  ;TYPE=TASK DPL=3 P=1 error why? 
V86IDTLEN   = $ 
V86IDTSEG   ENDS 
 
V86_STACK0SEG SEGMENT PARA USE16      
              V86_STACK0LEN = 1024 
              DB V86_STACK0LEN DUP(0) 
V86_STACK0SEG ENDS 
 
V86_STACK3SEG SEGMENT PARA USE16      
              V86_STACK3LEN = 1024 
              DB V86_STACK3LEN DUP(0) 
V86_STACK3SEG ENDS 
 
V86_DATASEG   SEGMENT PARA USE16      
V86_AX        DW 0         
V86_BX        DW 0         
V86_CX        DW 1         
V86_DX        DW 0         
V86_SI        DW 0         
V86_DI        DW 0         
V86_BP        DW 0         
V86_EAX       DD 0         
V86_EBX       DD 0         
V86_ECX       DD 1         
V86_EDX       DD 0         
V86_SS        DW 0         
V86_CS        DW 0         
V86_DS        DW 0         
V86_ES        DW 0         
V86_FS        DW 0         
V86_AX_O      DW 0         
V86_BX_O      DW 0         
V86_CX_O      DW 0         
V86_DX_O      DW 0         
V86_SI_O      DW 0         
V86_DI_O      DW 0         
V86_EAX_O     DD 0         
V86_EBX_O     DD 0         
V86_ECX_O     DD 0         
V86_EDX_O     DD 0         
V86_SS_O      DW 0         
V86_CS_O      DW 0         
V86_DS_O      DW 0         
V86_ES_O      DW 0         
V86_FS_O      DW 0         
 
CURRENT_LDT  DW 0 
CURRENT_TR   DW 0 
 
COS_TIME        DB 30H,30H,':',30H,30H,':',30H,30H 
TIME_COUNT    DB 18           ;1 second and time pice 
g_ipcs        dw 0,0 
g_ipcs2       dw 0,0 
G_INT         DW 0 
V86_BUFFER    DB 4096 DUP('$'),0 
V86_BUF_LEN   DW 0 
G_MSG         DB '..... GENERAL PROTECT ERROR ...' 
G_MSGLEN      = $ - G_MSG 
V86_DATALEN   = $               
V86_DATASEG   ENDS 
 
PERR    EQU WORD PTR [BP+0] 
PIP     EQU WORD PTR [BP+4] 
PCS     EQU WORD PTR [BP+8] 
PFLAG   EQU WORD PTR [BP+12] 
PSP     EQU WORD PTR [BP+16] 
PSS     EQU WORD PTR [BP+20] 
PES     EQU WORD PTR [BP+24] 
PDS     EQU WORD PTR [BP+28] 
PFS     EQU WORD PTR [BP+32] 
PGS     EQU WORD PTR [BP+36] 
 
V86TSSSEG SEGMENT PARA USE16  
             DW 0,0;V_TOS_TSS_SEL,0              ;LINK 
             DW V86_STACK0LEN,0      ;0_STACK V86_STACK0LEN 
             DW V86_STACK0_SEL,0 
             DD 0              ;1_STACK 
             DW ?,0 
             DD 0              ;2_STACK 
             DW ?,0 
             DD G_PDT_ADDR ;CR3 
             DW V86BEGIN,0 ;EIP 
             DW 3000H,2    ;EFLAGS IOPL=3(12.13) should be 3000h 
                           ;EFLAGS VM=1(17) 
             DD 0 ;EAX 
             DD 0 ;ECX 
             DD 0 ;EDX 
             DD 0 ;EBX 
             DW V86_STACK3LEN,0 ;ESP V86_STACK3LEN 
             DD 0 ;EBP 
             DD 0 ;ESI 
             DD 0 ;EDI 
             DW 0B800H,0           ;ES 
             DW V86CODESEG,0       ;CS 
             DW V86_STACK3SEG,0    ;SS 
             DW V86_DATASEG,0      ;DS 
             DW V86CODESEG,0       ;FS 
             DW V86CODESEG,0       ;GS 
             DW V86LDT_sel,0 
             DW 0 
             DW $ + 2 
             DB 4000H/8 DUP(0)   
             DB 0FFH   ;I/O END 
V86TSSLEN = $  
V86TSSSEG  ENDS      
 
V86LDTSEG        SEGMENT PARA USE16 
V86LDT           LABEL BYTE 
V861M            GDT_DESC <0FFFFH,0,0,93H,0FH,0>  ;LIMIT=1M 
V861M_SEL        = (V861M - V86LDT) + 4 
 
V86_TOS_CODE    GDT_DESC <0FFFFH,3000H,42H,0FAH,0,0C0H> ;9AH=exec/read ,DPL=3 
V86_TOS_CODE_SEL = (V86_TOS_CODE - V86LDT) + 4 
 
USER_PX_LDT_INIT_BEGIN LABEL BYTE 
 
;V86_CODE         GDT_DESC <0FFFFH,V86CODESEG,0,9AH,0,0>  
;V86_CODE_SEL     = (V86_CODE - V86LDT) + 4  
V86_STACK0       GDT_DESC    ;96H=R/W ,DOWN 
V86_STACK0_SEL   = (V86_STACK0 - V86LDT) + 4 
V86_DATA         GDT_DESC    ;96H=R/W ,DOWN 
V86_DATA_SEL     = (V86_DATA -  V86LDT) + 4  
V86_INTX_CODE       GDT_DESC  ;9AH=exec/read ,DPL=0 
V86_INTX_CODE_SEL   = (V86_INTX_CODE - V86LDT) + 4 
V86_INT0D_CODE      GDT_DESC  ;9AH=exec/read ,DPL=0 
V86_INT0D_CODE_SEL  = (V86_INT0D_CODE - V86LDT) + 4 
USER_PX_LDT_INIT_COUNT  = ($ - USER_PX_LDT_INIT_BEGIN)/(SIZE GDT_DESC) 
 
V86_TO_COS          GAT_DESC <0 ,V_TOS_TSS_SEL,0,085H,0>  
V86_TO_COS_SEL      = (V86_TO_COS - V86LDT) +4 
V86LDTLEN  = $ - V86LDT 
V86LDTSEG ENDS 
 
V86_INTX_CODESEG SEGMENT PARA USE16 
        ASSUME  CS:V86_INTX_CODESEG 
V86_INTX_BEGIN: 
COUNT   = 0 
        REPT    256 
        IF COUNT EQ 21H 
           ENT21H LABEL BYTE 
        ENDIF 
        PUSH    BP 
        MOV     BP,COUNT 
        JMP     DO_INTX 
        COUNT = COUNT+1 
        ENDM 
 
DO_INTX: 
        PUSH    BP        ;interrupt number 
        MOV     BP,SP 
        PUSH    EAX 
        PUSH    EBX 
 
        MOV     AX,V861M_SEL 
        MOV     DS,AX 
        XOR     EAX,EAX 
        MOV     AX,PSP 
        SUB     AX,6  ;3*2 
        MOV     PSP,AX 
        XOR     EBX,EBX 
        MOV     BX,PSS 
        SHL     EBX,4 
        ADD     EBX,EAX 
        MOV     AX,PIP 
        MOV     [EBX],AX 
        MOV     AX,PCS 
        MOV     [BX+2],AX 
        MOV     AX,PFLAG 
        MOV     [EBX+4],AX 
 
        MOV     BX,[BP] 
        SHL     BX,2 
        MOV     AX,[BX] 
        MOV     PIP,AX 
        MOV     AX,[BX+2] 
        MOV     PCS,AX 
 
        POP     EBX 
        POP     EAX 
        POP     BP 
        POP     BP 
        IRETD 
;********************** 
V86INTFF_BEGIN:     
;;test             
;            MOV AX,G_VRAM_SEL 
;            MOV DS,AX 
;            MOV AL,48H  ;"H" 
;            MOV AH,41H 
;            MOV DS:1772,AX 
;;test 
            MOV EBP,ESP 
            SUB EBP,12 
            MOV ESP,EBP 
 
            MOV AX,V86_DATA_GDT_SEL 
            MOV DS,AX 
            MOV bx,WORD PTR DS:CURRENT_LDT       
            MOV WORD PTR DS:CURRENT_LDT,0   
            and bx,0ffc0h 
            mov ax,V_USER_PSLDT_SEL 
            and ax,0ffc0h 
            cmp ax,bx 
            JNE V86INTFF_BEGIN1 
            lldt WORD PTR DS:CURRENT_ldt 
V86INTFF_BEGIN1: 
            MOV bx,WORD PTR DS:CURRENT_TR        
            MOV WORD PTR DS:CURRENT_TR,0 
            and bx,0ffc0h 
            mov ax,V_USER_PSTSS_SEL 
            and ax,0ffc0h 
 
            cmp ax,bx 
            JNE V86INTFF_BEGIN2 
;jmp V86INTFF_BEGIN2            
            jmp V86INTFF_BEGIN11 
V86INTFF_BEGIN11:             
            DB 0EAH 
            DW FROM_V86 
            DW V_USER_PSTSS_SEL  ;ok 
 
V86INTFF_BEGIN2: 
            ;MOV AX,V_TOS_STACK_SEL 
            ;MOV SS,AX 
            jmp V86INTFF_BEGIN22 
V86INTFF_BEGIN22:             
            DB 0EAH 
            DW FROM_V86 
            DW V_TOS_TSS_SEL  ;ok 
 
V86_INTX_LEN = $ 
V86_INTX_CODESEG ENDS 
 
V86_INT0D_CODESEG SEGMENT PARA USE16 
        ASSUME  CS:V86_INT0D_CODESEG 
V86_INT0D_BEGIN: 
        MOV     AX,V86_DATA_SEL 
        MOV     DS,AX 
        MOV     SI,OFFSET G_MSG 
        MOV     AX,V86_VRAM_SEL 
        MOV     ES,AX 
        MOV     DI,0 
        MOV     AH,17H 
        MOV     CX,G_MSGLEN 
        CLD 
V86_INT0DNEXT: 
        LODSB 
        STOSW 
        LOOP V86_INT0DNEXT 
        ADD     ESP,4 
        MOV     AX,4C01H 
        DB      0EAH 
        DW      ENT21H 
        DW      V86_INTX_CODE_SEL 
V86_INT0D_LEN = $ 
V86_INT0D_CODESEG ENDS 
;*************************************************v86 
;*************************************************v86 
;test 
;  PUSH ES 
;  PUSH EAX 
;  push esi 
;  mov esi,1ffffffh 
;ghgh1: 
;  MOV AX,0B800H 
;  MOV ES,AX 
;  MOV AL,'V' 
;  MOV AH,41H   
;  MOV WORD PTR ES:[808],AX 
;  dec esi 
;  jnz ghgh1 
;  pop esi 
;  POP EAX 
;  POP ES 
;jmp G_TO_COS 
; test