Організація роботи мiкропроцесора в захищеному режимi, страница 19

        port[$71]:=byte_shut;                                         { яка мiстить байт вiдключення; }

{ код Ah байта вiдключення забезпечує при скиданнi МП }

                                             { перехiд згiдно з адресою в ячейках 40h:67h и 40h:69h;  }

                                              {  код 5 байта вiдключення крiм цього здiйснює також }

                                                                            { iнiцiалiзацiю контролера переривань }

       end; {save_ret_real}

    procedure not_int;         { Заборона апаратних переривань: }

       begin

        asm cli end;                                                                                                { маскуємих }       port[$70]:=$80;                 { i немаскуємих }

      end; {not_int}

    procedure en_int;                                                      { Дозвiл апаратних переривань: }

      begin

        asm sti end;                { маскуємих }

        port[$70]:=$d;                        { i немаскуємих }

        mem[$40:$17]:=0     { Скидання стану управляючих клавiш }

      end; {en_int}

    procedure set_unr(base,limit:longint;kseg);

      begin                        { Установка режиму "Unreal" }

{----------------------------------Формування таблицi GDT---------------------------------------}

        init_gdt(0,0,0,0,0);                                                                         { нуль-дескриптор }

        init_gdt(1,limit,base,$92,$80);  { дескриптор сегмента }

        init_gdtr;                                               { Створення даних i завантаження GDTR }

        not_int; {Заборона маскуємих i немаскуємих переривань }

{--------------------------------Перехiд в захищенчй режим---------------------------------------}

        asm                      

            db $0f,$20,0c0h                     { MOV EAX,CR0 }

            db 66h,0dh                              { OR EAX,1 }

            dd 1h

            db $0f,22h,0c0h                     { MOV CR0,EAX }

{--------------------Завантаження селектору заданого сегмента (kseg)----------------------}

            mov ax,8

            cmp kseg,0

            jnz @3

            db 8eh,0c0h                             { MOV ES,AX }

            jmp @k

        @3: cmp kseg,3

            jnz @4

            db 8eh,0d8h                             { MOV DS,AX }

            jmp @k

        @4: cmp kseg,4

            jnz @5

            db 8eh,0e0h                           { MOV FS,AX }

            jmp @k

         @5:db 8eh,0e8h                            { MOV GS,AX }

{----------------------------------Повернення в реальний режим---------------------------------}

         @k:db $0f,$20,0c0h                     { MOV EAX,CR0  }

            db 66h,25h                      { AND EAX,FFFFFFFEh }

            dd 0fffffffeh

            db $0f,22h,0c0h                     { MOV CR0,EAX  }

          end;

          en_int

      end; {set_unr}

    procedure pic(mode:byte);                           { Програмування ведучого i  ведомого }

{ контролерів переривань для роботи в  реальному  (mode = 0) }

                { i  захищеному (mode = 1) режимах }

      var  k1,k2:byte;

      begin

        if mode=0 then begin

          k1:=8;

          k2:=$70

        end else begin

          k1:=$20;

          k2:=$28

        end;

        port[$20]:=$11;                                                                                { 1-й ПКП: ICW1 }

        port[$21]:=k1;                                                                                  { 1-й ПКП: ICW2 }

        port[$21]:=4;                                                                                    { 1-й ПКП: ICW3 }

        port[$21]:=1;                                                                                    { 1-й ПКП: ICW4 }

        port[$a0]:=$11;                                                                                { 2-й ПКП: ICW1 }