История[]
При проектировании микропроцессора 80286 инженеры Intel допустили ошибку, позволившую из реального режима обращаться к части памяти за пределами младшего мегабайта — так называемой области верхней памяти (HMA). Чтобы компенсировать эту ошибку и гарантировать совместимость со старыми программами, в состав компьютера пришлось включить специальную схему, блокирующую 20-й разряд шины адреса (или все старшие разряды, начиная с 20-го — это зависит от особенностей чипсета) — Gate A20 (вентиль или шлюз линии A20). При использовании старых программ реального режима этот вентиль может быть закрыт, что обеспечит присутствие на линии A20 логического нуля, а при работе новых программ, поддерживающих защищённый режим, этот вентиль должен быть обязательно открыт.
Способы управления вентилем линии A20[]
Имеется два способа для разрешения или запрета вентиля линии A20. Один из них основан на использовании контроллера интерфейса PS/2 (часто неправильно называемого контроллером клавиатуры), другой — порта 92h.
Использование контроллера интерфейса PS/2[]
Контроллер интерфейса PS/2, помимо прочих своих функций, управляет также состоянием вентиля линии A20. Эта возможность обеспечивается тем, что контроллер, помимо линий ввода-вывода, связанных с интерфейсами PS/2 клавиатуры и мыши, имеет ещё несколько свободных «ног», одна из которых, а именно разряд 1 порта 2, и используется для управления вентилем линии A20: когда на ней находится 1, вентиль открыт, когда 0 — закрыт.
Для разрешения вентиля, т.е. для обеспечения нормального функционирования адресной линии A20, можно воспользоваться такой последовательностью команд:
call WaitForEmpty ; Ожидание готовности контроллера jnz @F ; Переход, если ошибка mov al, 0D1h ; Команда выдачи данных в порт 2 контроллера out 64h, al call WaitForEmpty ; Ожидание готовности контроллера jnz @F ; Переход, если ошибка mov al, 0DFh ; Данные для порта 2 out 60h, al call WaitForEmpty ; Ожидание готовности контроллера @@: ... ; Подпрограмма ожидания готовности контроллера PS/2 к приёму очередного байта ; Если за разумное время контроллер не перешёл в состояние готовности, ; возвращается признак ошибки: сброшенный флаг ZF WaitForEmpty: push cx mov cx, 0FFFFh ; Счётчик ожидания готовности @@: in al, 64h ; Чтение состояния контроллера test al, 02h ; Входной буфер пуст? loopnz @B ; Если не пуст, продолжаем ждать pop cx ret
Запрет вентиля A20 выполняется аналогичным образом, только вместо константы 0DFh в порт 2 необходимо вывести константу 0DDh.
Использование порта 92h[]
Порт 92h на ранних компьютерах, оснащённых вентилем A20, отсутствовал, поэтому достаточно долгое время главным способом разрешения или запрещения вентиля оставались описанные выше манипуляции с контроллером интерфейса PS/2. Однако необходимая последовательность команд для этого достаточно длинна, а её выполнение занимает приличное время, поскольку контроллер намного медленнее центрального процессора ПК. Кроме того, некоторые современные системные платы уже не имеют контроллера PS/2, поскольку этот интерфейс считается устаревшим. Поэтому в настоящее время рациональнее переключать состояние линии A20 вторым способом, часто называемым быстрым и основанным на использовании порта 92h, присутствующего во всех современных чипсетах. За вентиль линии A20 отвечает 1-й разряд порта; остальные разряды изменять нельзя.
Разрешение вентиля A20 через порт 92h выполняется следующим образом:
in al, 92h or al, 02h out 92h, al
Запрещение вентиля выполняется аналогичным образом, только команду or al, 02h
надо заменить на and al, 0FDh
.
Заметим, что между командами in
и out
теоретически может потребоваться введение задержки.