ecm

Düsseldorf, Germany, 31.01.2025, 23:21 |
What is the meaning of Local vs Global Enable/Disable A20 (How-tos) |
I added the basics for HMA support to the MS-DOS based lDOS. Only used for the msdos-based DOSCODE segment or explicit users of the 2F.4A interface yet. During this I also had to add support for working with A20, enabling it when entering the DOS and disabling on exec branching into a new process. (21.4B05 support not yet added.)
I found that the FreeDOS kernel uses functions 05h and 06h to enable and disable A20: https://github.com/FDOS/kernel/blob/5de2eb1aa01b0129b046cf06338453a233c6597b/kernel/kernel.asm#L1235
These functions are called Local Enable A20 and Local Disable A20: https://fd.lod.bz/rbil/interrup/memory/2f4310.html#table-02753
Previously I used the 03h and 04h Global Enable A20 and Global Disable A20. But I found that these didn't work as intended sometimes (cannot reproduce it right now).
So I first changed to 05h and 06h, but at least once my test program showed A20 on initially the first time I ran it, where I expected A20 off. Calling both global disable and local disable fixed this.
I'm using (so far, only) 03h Global Enable A20 in init.asm to relocate DOSCODE: https://hg.pushbx.org/ecm/msdos4/file/ff139b58d0cd/src/BIOS/init.asm#l3661
In entry.asm I'm using 05h Local Enable on entry into DOS now, but both Local and Global Disable: https://hg.pushbx.org/ecm/msdos4/rev/ff139b58d0cd
What is the exact meaning of "Local" and "Global"?
Here's a test program I created, it tries to disable A20 (either with XMS or int 15h) and reports the status 4 times: https://pushbx.org/ecm/test/20250131/a20test.asm It also uses both Global and Local Disable for now.
; Public Domain
cpu 8086
org 256
start:
int3
before:
call test
mov dx, msg.offbefore
je .off
.on:
mov dx, msg.onbefore
.off:
mov ah, 09h
int 21h
after:
call test
mov dx, msg.offafter
je .off
.on:
mov dx, msg.onafter
.off:
mov ah, 09h
int 21h
switchoff:
mov ax, 4300h
int 2Fh
cmp al, 80h
jne noxms
mov dx, msg.tryingxms
mov ah, 09h
int 21h
mov ax, 4310h
int 2Fh
push es
push bx
mov bp, sp
mov ah, 04h
call far [bp]
mov ah, 06h
call far [bp]
jmp end
noxms:
mov dx, msg.tryingrombios
mov ah, 09h
int 21h
mov ax, 2400h
int 15h
end:
testfirst:
call test
mov dx, msg.off
je .off
.on:
mov dx, msg.on
.off:
mov ah, 09h
int 21h
testagain:
call test
mov dx, msg.offagain
je .off
.on:
mov dx, msg.onagain
.off:
mov ah, 09h
int 21h
mov ax, 4C00h
int 21h
test:
les di, [cs:high]
lds si, [cs:low]
mov cx, 16
repe cmpsw
push cs
pop ds
retn
align 2
high: dd 0FFFF_0010h
low: dd 0
msg:
.offbefore:
.off: db "A20 was off. ",36
.onbefore:
.on: db "A20 was on. ",36
.offafter:
.offagain: db "After int 21h A20 is off.",13,10,36
.onafter:
.onagain: db "After int 21h A20 is on.",13,10,36
.tryingxms: db "XMS detected, trying to disable A20 on XMS.",13,10,36
.tryingrombios: db "XMS not detected, trying to disable A20 using ROM-BIOS.",13,10,36
--- l |
ecm

Düsseldorf, Germany, 31.01.2025, 23:40
@ ecm
|
What is the meaning of Local vs Global Enable/Disable A20 |
The specifications says: https://www.phatcode.net/res/219/files/xms20.txt
Global Enable A20 (Function 03h):
---------------------------------
ARGS: AH = 03h
RETS: AX = 0001h if the A20 line is enabled, 0000h otherwise
ERRS: BL = 80h if the function is not implemented
BL = 81h if a VDISK device is detected
BL = 82h if an A20 error occurs
This function attempts to enable the A20 line. It should only be used
by programs which have control of the HMA. The A20 line should be turned
off via Function 04h (Global Disable A20) before a program releases control
of the system.
NOTE: On many machines, toggling the A20 line is a relatively slow
operation.
Global Disable A20 (Function 04h):
----------------------------------
ARGS: AH = 04h
RETS: AX = 0001h if the A20 line is disabled, 0000h otherwise
ERRS: BL = 80h if the function is not implemented
BL = 81h if a VDISK device is detected
BL = 82h if an A20 error occurs
BL = 94h if the A20 line is still enabled
This function attempts to disable the A20 line. It should only be used
by programs which have control of the HMA. The A20 line should be disabled
before a program releases control of the system.
NOTE: On many machines, toggling the A20 line is a relatively slow
operation.
Local Enable A20 (Function 05h):
--------------------------------
ARGS: AH = 05h
RETS: AX = 0001h if the A20 line is enabled, 0000h otherwise
ERRS: BL = 80h if the function is not implemented
BL = 81h if a VDISK device is detected
BL = 82h if an A20 error occurs
This function attempts to enable the A20 line. It should only be used
by programs which need direct access to extended memory. Programs which use
this function should call Function 06h (Local Disable A20) before releasing
control of the system.
NOTE: On many machines, toggling the A20 line is a relatively slow
operation.
Local Disable A20 (Function 06h):
---------------------------------
ARGS: AH = 06h
RETS: AX = 0001h if the function succeeds, 0000h otherwise
ERRS: BL = 80h if the function is not implemented
BL = 81h if a VDISK device is detected
BL = 82h if an A20 error occurs
BL = 94h if the A20 line is still enabled
This function cancels a previous call to Function 05h (Local Enable
A20). It should only be used by programs which need direct access to
extended memory. Previous calls to Function 05h must be canceled before
releasing control of the system.
NOTE: On many machines, toggling the A20 line is a relatively slow
operation. --- l |
tom

Germany (West), 01.02.2025, 01:18 (edited by tom, 01.02.2025, 01:37)
@ ecm
|
What is the meaning of Local vs Global Enable/Disable A20 |
From memory, so be careful:
Global enable/disable unconditionally sets the A20 line
Local enable/disable increments/decrements a counter. only if the counter
switches between 0 and !=0 the A20 line is changed.
So if LocalEnable() is called 10 times, LocalDisable() must also be called
10 times before the actual A20 status changes back to disabled.
However, I may be totally wrong
Fortunately, the source to MS HIMEM is (and always was) publicly available,
and can be regarded as the definition of these functions.
FD HIMEM is supposed to mimic it precisely (which is not certain).
So you can look it up yourself without relying on unprecise descriptions.
[Edited to add]However I am not aware of a guideline how these functions are to
be used, for what purpose. If someone knows, please report. |