Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the board
Thread view  Mix view  Order
ecm

Homepage E-mail

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

Homepage E-mail

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

Homepage

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.

Back to the board
Thread view  Mix view  Order
22208 Postings in 2050 Threads, 396 registered users, 25 users online (1 registered, 24 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum