diff options
Diffstat (limited to 'mem.asm')
-rw-r--r-- | mem.asm | 75 |
1 files changed, 75 insertions, 0 deletions
@@ -0,0 +1,75 @@ +%ifndef __MEM_ASM +%define __MEM_ASM + +check_a20: + pushf ; preserve flags + push ds ; data segment + push es ; extra segment + push di ; destination index + push si ; source index + + cli ; disable interrupts + + xor ax, ax ; zero out ax + mov es, ax ; zero out extra segment + + not ax ; flip all bits in ax + mov ds, ax + + mov di, 0x0500 ; destination address + mov si, 0x0510 ; source address + + mov al, byte [es:di] ; copy byte from destination (FFFF:0500) + push ax + + mov al, byte [ds:si] ; copy byte from source (FFFF:0510) + push ax + + mov byte [es:di], 0x00 ; set es:di to 0 + mov byte [ds:si], 0xFF ; set es:si to 255 + + cmp byte [es:di], 0xFF ; did it wrap around? + + pop ax + mov byte [ds:si], al + + pop ax + mov byte [es:di], al + + mov ax, 0 + je check_a20__exit + + mov ax, 1 + +check_a20__exit: + sti ; enable interrupts + pop si ; restore registers + pop di + pop es + pop ds + popf ; restore flags + + ret + + +enable_a20: ; fast A20 + cli ; disble interrupts + call check_a20 ; is A20 already enabled? + cmp al, 1 + je .no_a20 + + in al, 0x92 ; enable A20 + test al, 2 + jnz .return + or al, 2 + and al, 0xFE + out 0x92, al + jmp .return +.no_a20: + stc ; set carry on failure +.return: + sti ; enable interrupts + clc ; clear carry + ret + +%endif |