; ; (c) tkraj 2010 ; .286p ; program is started in real mode from DOS ; processor is switched into privileged mode ; program is running in 16-bit privileged mode ; processor is switched into real mode ; int21h (ah=4ch) is used for return into DOS ; PLACE MACRO dest_seg,src_seg,length mov ax,src_seg mov ds,ax mov ax,dest_seg mov es,ax mov cx,length xor si,si xor di,di rep movsb ENDM ; ; PM_TO_RM MACRO db 0fh, 20h, 0c0h ; mov eax, cr0 db 66h ; 32bit operand prefix db 25h dd 7ffffffeh ; and eax, 7ffffffeh db 0fh, 22h, 0c0h ; mov cr0, eax ENDM ; ; pjmp MACRO selector,offset db 0eah dw offset dw selector ENDM ; ; pcall MACRO selector,offset db 9ah dw offset dw selector ENDM ; ; seg_desc struc limit15_0 dw ? base15_0 dw ? base23_16 db ? acc_rights db 0 reserved1 dw 0 seg_desc ends ; ; ; *** GDT AT ADDRESS 051000h *** ; GDT segment ; Selector: null_desc seg_desc <0,0,0,0,0> ; 00h vga_desc seg_desc <0ffffh,8000h,0bh,10010010b,>; 08h disp_desc seg_desc <0ffffh,2000h,05h,10011000b,>; 10h stack1_desc seg_desc <0000h,3000h,05h,10010110b,>; 18h data1_desc seg_desc <0ffffh,4000h,05h,10010010b,>; 20h task1_desc seg_desc <0ffffh,5000h,05h,10011000b,>; 28h end_gdt: GDT ends ; ; ; *** DISP AT ADDRESS 052000h *** ; DISP segment assume cs:DISP,ds:DATA1 DISPVGA proc far ; offset of text in SI ; char CR ends text start2: mov di,line ; position on screen again2: mov al,[si] cmp al,0dh ; test on CR je test21 mov es:[di],al add di,2 ; skip attribute byte inc si jmp again2 test21: add line,160 ; new line ret end2: DISPVGA endp DISP ends ; ; ; *** DATA1 AT ADDRESS 054000h *** ; ; DATA1 segment assume ds:DATA1 off_ret dw ? ; offset of label return seg_ret dw ? ; segment of label return line dw 0 clear db " ",0dh text1 db "PRIVILEGED MODE",0dh text2 db "Task1 started.",0dh text3 db "Task1 finished.",0dh text4 db "REAL MODE, RETURN INTO DOS", 0dh end4 db ? DATA1 ends ; ; ; *** TASK1 AT ADDRESS 055000h *** ; TASK1 segment assume cs:TASK1 start5: cli mov ax,18h mov ss,ax mov sp,1000h ; init of the SP mov ax,08h mov es,ax ; init of the vga segment mov ax,20h mov ds,ax ; init of the data1 segment mov cx,25 again51: mov si,offset clear pcall 10h,0h loop again51 ; clear of the display mov line,320 ; cursor at line 2 mov si,offset text1 pcall 10h,0h mov si,offset text2 pcall 10h,0h mov si,offset text3 pcall 10h,0h switch_to_real_mode: cli PM_TO_RM ; mov eax, cr0 ; and eax, 7ffffffeh ; mov cr0, eax ; paging off, PE=0 ; xor eax, eax ; mov cr3, eax ; empty TLB ; ; IN REAL MODE NOW jmp real ; empty instruction queue real: mov ax, 5000h mov ss, ax mov sp, 4000h ; address 54000h retf ; jump on label return end5: TASK1 ends ; ; ; ; *** INITIALIZATION OF PRIVILEGED MODE *** ; ini_dat segment gdt_desc seg_desc <03ffh,1000h,05h,,> idt_desc seg_desc <03ffh,0000h,00h,,> ini_dat ends ; ; ini_cod segment assume cs:ini_cod,ds:ini_dat start: PLACE 5100h,GDT,(end_gdt-null_desc) PLACE 5200h,DISP,(end2-start2) PLACE 5400h,DATA1,(end4-off_ret) PLACE 5500h,TASK1,(end5-start5) mov ax, 5000h mov ds,ax ; base for 50000H mov si, 4000h mov word ptr [si], OFFSET return ; OFFSET into 54000H push cs pop ax mov word ptr [si+2], ax ; CS into 54002H cli mov ax,ini_dat mov ds,ax lgdt gdt_desc smsw ax or ax, 1 lmsw ax ; PE=1 ; ; *** PRIVILEGED MODE *** ; jmp priv1 ; empty queue priv1: pjmp 0028H,0000H ; start of TASK1 ; *** REAL MODE reached by retf *** return: mov ax, 5400h ; base of DATA1 segment mov ds, ax mov si, offset text4 call DISPVGA ; DISPVGA called in real mode mov ah, 4ch int 21h ; return into DOS ini_cod ends ; ; end start