Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
JulienDarc wrote:I don't understand why we touch ds:si because it is not directly used in the cmp.
If modifying the data at 0x00000500 (or 0x0000:0x0500 in real mode) causes the data at address 0x00100500 (or 0xFFFF:0x0510 in real mode) to change, then A20 is disabled.
Cheers,
Brendan
Last edited by Candy on Thu Mar 26, 2015 4:28 am, edited 1 time in total.
Reason:Minor offset bug
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
JulienDarc wrote:I don't understand why we touch ds:si because it is not directly used in the cmp.
If modifying the data at 0x00000500 (or 0x0000:0x0500 in real mode) causes the data at address 0x00100500 (or 0xFFFF:0x0510 in real mode) to change, then A20 is disabled.
Cheers,
Brendan
But it responded not truly the question why there is no compare instruction for the content of DS:SI.
JulienDarc wrote:I don't understand why we touch ds:si because it is not directly used in the cmp.
If modifying the data at 0x00000500 (or 0x0000:0x0500 in real mode) causes the data at address 0x00100500 (or 0xFFFF:0x0510 in real mode) to change, then A20 is disabled.
Cheers,
Brendan
But it responded not truly the question why there is no compare instruction for the content of DS:SI.
Dirk
Read up on what A20 does - if A20 is off, writing to 0x100500 will actually write to 0x500, and reading 0x100500 will read from 0x500. That means, if you write to 0x100500, then write to 0x500, and then read 0x100500 it should give you the first value (that you wrote to 0x100500). If that works, A20 is enabled. If it does not, all writes got sent to 0x500 instead and you can now detect it.
Candy wrote:Read up on what A20 does - if A20 is off, writing to 0x100500 will actually write to 0x500, and reading 0x100500 will read from 0x500. That means, if you write to 0x100500, then write to 0x500, and then read 0x100500 it should give you the first value (that you wrote to 0x100500). If that works, A20 is enabled. If it does not, all writes got sent to 0x500 instead and you can now detect it.
pushf
pushw ds
pushw es
pushw di
pushw si
cli
xorw %ax, %ax # ax = 0
movw %ax, %es
not %ax # ax = 0xFFFF
movw %ax, %ds
movw $(0x500), %di
movw $(0x510), %si
movb $(0x00), %es:di
movb $(0xFF), %ds:si
cmpb $(0xFF), %es:di
movw $0, ax
je check_a20__exit
movw $1, ax
sti
check_a20__exit:
pop si
pop di
pop es
pop ds
popf
ret
?
My readings "tell" me that there is a wrap around when a20 is disabled.
So the byte located at 0x0000:0x0500 should be written with the value 0xff when a20 is disabled and 0x00 when a20 is enabled (and 0xffff:0x0510 has its byte 0xff written).
The code above seems to do just that, too. Am I wrong ?
that code is basically identical to the original except:
your code doesn't save/restore the previous contents of those memory locations, if whatever was in them was important, it is now lost...
also:
your code has a serious bug in that it disables but does not restore interrupts...
if the wraparound happens, interrupts are left disabled (bug)
if wraparound does not happen interrupts are enabled even if they were disabled before the code ran (very very dangerous bug that can cause instant triple-fault or random/unexpected code execution)
oops... your right, i didn't see that there at the end, just the (pointless) sti earlier (saw the STI and assumed there wasn't a popf since sti is unnecessary otherwise)