summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mem.asm75
1 files changed, 75 insertions, 0 deletions
diff --git a/mem.asm b/mem.asm
new file mode 100644
index 0000000..c99660e
--- /dev/null
+++ b/mem.asm
@@ -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