Hello, I've tried to modify and read A20 line status, but next code seems incapable to do it. I've changed this code using 92h port (A20 Fast Gate) and goes perfectly. Anyone has an idea for what it doesn't work?. I'm sorry for my spanish comments around the code, I can translate them if it can be useful. Thank you in advance.
; ----------------------------------------------------------------------------
; - TITULO : Activa la línea A20 vía controladora teclado COM-NASM -
; ----- -----
; - AUTOR : Alfonso Víctor Caballero Hurtado -
; ----- -----
; - VERSION : 1.0 -
; ----------------------------------------------------------------------------
COM8042 EQU 64h
DAT8042 EQU 60h
Accion EQU 0DFh ; 0DFh para activar linea A20
; 0DDh para desactivar línea A20
[org 100h]
[section .text]
CALL CambiA20
JC $_Fallo
CALL EstadoA20
JC $_Fallo
MOV DX, A20MSG1 ; Suponemos A20 activa
JNZ $_Fin ; si lo está, saltamos a imprimirlo
MOV DX, A20MSG2 ; Mensaje A20 no activa
JMP $_Fin
$_Fallo:
MOV DX, A20MSG3
$_Fin:
MOV AH, 9
INT 21h
MOV AX, 4C00h ; Servicio 4Ch, mensaje 0
INT 21h ; volvemos AL DOS
CambiA20:
; Propósito: Modifica el estado de la línea A20
; entrada : Ninguna
; salida : ZF = 1 activa, ZF = 0 no activa
; STC: hubo fallo, CLC: todo bien
; Destruye : AX
CLI ; Desactiva interrupciones
CALL Bufer8042 ; ¿Búfer entrada 8042 vacío?
JNZ $_FalloC ; salimos si no lo está
MOV AL, 0D1h ; orden de escritura al puerto
OUT COM8042, AL ; Enviar el comando al 8042
CALL Bufer8042 ; ¿Búfer entrada 8042 vacío?
JNZ $_FalloC ; salimos si no lo está
MOV AL, Accion ; Activamos/Desactivamos línea A20
OUT DAT8042, AL
CALL Bufer8042 ; ¿Búfer entrada 8042 vacío?
STI ; Restauramos interrupciones
CLC ; Todo bien
JMP $_FinC
$_FalloC:
STC
$_FinC:
RET
EstadoA20:
; Propósito: Lee el estado de la línea A20
; entrada : Ninguna
; salida : ZF = 1 activa, ZF = 0 no activa
; STC: hubo fallo, CLC: todo bien
; Destruye : AX
CLI ; Desactiva interrupciones
CALL Bufer8042 ; ¿Búfer entrada 8042 vacío?
JNZ $_FalloV ; salimos si no lo está
MOV AL, 0D0h ; si lo está, escribe puerto salida
OUT COM8042, AL ; Enviar el comando al 8042
CALL Bufer8042 ; ¿Búfer entrada 8042 vacío?
JNZ $_FalloV ; salimos si no lo está
IN AL, DAT8042
CALL Bufer8042 ; ¿Búfer entrada 8042 vacío?
STI ; Restauramos interrupciones
AND AL, 2
CLC ; Todo bien
JMP $_FinV
$_FalloV:
STC
$_FinV:
RET
Bufer8042:
; Propósito: Nos aseguramos de que el búfer de entrada del 8042 está vacío
; entrada : Ninguna
; salida : ZF = 1 si AL = 0, ZF = 0 si AL <> 0
; Destruye : AX, CX
PUSH AX
XOR CX, CX ; Esperamos 65536 ciclos
$_BuclEspera:
IN AL, COM8042 ; Lee el estado del 8042
AND AL, 02 ; Comprueba búfer entrada lleno
LOOPNZ $_BuclEspera ; Sale si CX = 0 ó AL = 0
POP AX
RET
[section .data]
A20MSG1 DB "Linea A20 activa$"
A20MSG2 DB "Linea A20 no activa$"
A20MSG3 DB "El buffer del teclado no esta vacio$"
; Salida por pantalla:
; C:\Trabajo\AOE\Codigos\Cap12>A20CN1
; Linea A20 activa