Author Topic: A20 line controlling  (Read 18560 times)

Alfonso V

  • Guest
A20 line controlling
« on: July 08, 2006, 02:21:28 PM »
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

nobody

  • Guest
Re: A20 line controlling
« Reply #1 on: July 10, 2006, 10:49:52 AM »
Hi Alfonso,

Dos isn't booting for me lately, so the only way I could test your program was to convert it to a bootsector. Reported "no activa".

Where you send the 0D1h command to COM8042, I changed it to DAT8042. Reports "activa"!

Are we *still* messing with a20??? A phrase - "a20 - a pain from the past" came into my mind. Googling on that gets some good hits.

There's some code from Chris Giese that might help:

http://my.execpc.com/~geezer/osd/boot/a20.asm

Best,
Frank

Alfonso V

  • Guest
Re: A20 line controlling
« Reply #2 on: July 10, 2006, 04:10:43 PM »
Hello, Frank, we meet again!

Theorically we must anunciate first to port 64h wich command we are going to use against port 60h. So, first we put value D1h on 64h port, annuncing it that we want write on 60h port, or D0h value on 64h port for read from 60h port.

If we write DFh to 60h port, A20 line will be switched on; DDh will switch off it.

So this program *should* activate A20 line because Accion EQU 0DFh , nevertheless its result is "Linea A20 no activa", the same as Accion EQU 0DDh.

The program, instead, goes fine using A20 Fast Gate, for example...

I'll read carefully a20.asm code, maybe it has any light.

Thank you for your help, Frank

Cheers!

nobody

  • Guest
Re: A20 line controlling
« Reply #3 on: July 11, 2006, 01:04:31 AM »
Keep in mind that port 92h takes precedence.
That is, if its bit is 1, then memory is flat
no matter what -- only if its bit is 0, does
the KBC actually control A20M.