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 ,V86_INTX_CODE_SEL,0EE00H,0> ;TYPE=386 INTERRUPT DPL=3 P=1
ENDM
V86IDT08 IDT_DESC ;ok
REPT 4
IDT_DESC ,V86_INTX_CODE_SEL,0EE00H,0> ;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