+a20_i8042_wait
+ in al, 64h
+ test al, 2
+ jnz a20_i8042_wait
+ ret
+
+a20_i8042_wait2
+ in al, 64h
+ test al, 1
+ jnz a20_i8042_wait2
+ ret
+
+enable_a20
+ mov ax, 2401h
+ int 15h
+ call check_a20
+ cmp ax, 1
+ jne .fail
+.success
+ ret
+.fail
+ cli ; disable interrupts
+
+ call a20_i8042_wait
+ mov al, 0ADh ; disable 1st PS/2 port
+ out 64h, al
+
+ call a20_i8042_wait
+ mov al, 0D0h ; read controller output port
+ out 64h, al
+
+ call a20_i8042_wait2
+ in al, 60h ; do the actual read
+ push ax ; save the register
+
+ call a20_i8042_wait
+ mov al, 0D1h ; write byte to output port
+ out 64h, al
+
+ call a20_i8042_wait
+ pop ax ; restore the register
+ or al, 2 ; toggle A20 bit
+ out 60h, al
+
+ call a20_i8042_wait
+ mov al, 0AEh ; reenable 1st PS/2 port
+ out 64h, al
+
+ call a20_i8042_wait
+ sti ; enable interrupts
+ ret
+
+ call check_a20
+ cmp ax, 1
+ jne .fail2
+ ret
+.fail2
+ mov si, A20_FAIL
+ call print
+ jmp $
+
+A20_FAIL db "A20 enable fail, not booting!", 0