mirror of
https://github.com/FDOS/kernel.git
synced 2025-07-23 13:54:30 +02:00
kernel: optimise A20 check and enable/disable calls
Some assembly tricks: * SMC instead of checking the XMS driver address in the DOS DS stub, * SMC so that the address goes right into a `call far immediate` instruction, * use `repe cmpsw` to compare multiple words (saves space over the individual word compares), * near calls to far functions use push cs to build a far-call stack frame, * segments 0 and FFFFh generated by segment arithmetic instead of loading from memory, * common case (A20 already enabled) made to be the case where the conditional branch just falls through, which may be slightly better.
This commit is contained in:
parent
72edabfdb7
commit
d91c14723a
@ -317,6 +317,7 @@ extern struct RelocationTable DOSFAR ASM _HMARelocationTableStart[];
|
|||||||
extern struct RelocationTable DOSFAR ASM _HMARelocationTableEnd[];
|
extern struct RelocationTable DOSFAR ASM _HMARelocationTableEnd[];
|
||||||
|
|
||||||
extern void FAR *DOSFAR ASM XMSDriverAddress;
|
extern void FAR *DOSFAR ASM XMSDriverAddress;
|
||||||
|
extern UBYTE DOSFAR ASM XMS_Enable_Patch;
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
extern VOID ASMPASCAL _EnableA20(VOID) FAR;
|
extern VOID ASMPASCAL _EnableA20(VOID) FAR;
|
||||||
extern VOID ASMPASCAL _DisableA20(VOID) FAR;
|
extern VOID ASMPASCAL _DisableA20(VOID) FAR;
|
||||||
|
@ -179,6 +179,7 @@ int MoveKernelToHMA()
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
XMSDriverAddress = xms_addr;
|
XMSDriverAddress = xms_addr;
|
||||||
|
XMS_Enable_Patch = 0x90; /* must be set after XMSDriverAddress */
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* A) for debugging purpose, suppress this,
|
/* A) for debugging purpose, suppress this,
|
||||||
|
@ -1165,17 +1165,20 @@ __HMARelocationTableEnd:
|
|||||||
; will be only ever called, if HMA (DOS=HIGH) is enabled.
|
; will be only ever called, if HMA (DOS=HIGH) is enabled.
|
||||||
; for obvious reasons it should be located at the relocation table
|
; for obvious reasons it should be located at the relocation table
|
||||||
;
|
;
|
||||||
global _XMSDriverAddress
|
|
||||||
_XMSDriverAddress:
|
|
||||||
dw 0 ; XMS driver, if detected
|
|
||||||
dw 0
|
|
||||||
|
|
||||||
global _ENABLEA20
|
global _ENABLEA20
|
||||||
_ENABLEA20:
|
_ENABLEA20:
|
||||||
mov ah,5
|
mov ah,5
|
||||||
UsingXMSdriver:
|
UsingXMSdriver:
|
||||||
|
|
||||||
|
global _XMS_Enable_Patch
|
||||||
|
_XMS_Enable_Patch: ; SMC: patch to nop (90h) to enable use of XMS
|
||||||
|
retf
|
||||||
|
|
||||||
push bx
|
push bx
|
||||||
call far [cs:_XMSDriverAddress]
|
call 0:0 ; (immediate far address patched)
|
||||||
|
global _XMSDriverAddress
|
||||||
|
_XMSDriverAddress: equ $ - 4 ; XMS driver, if detected
|
||||||
pop bx
|
pop bx
|
||||||
retf
|
retf
|
||||||
|
|
||||||
@ -1184,8 +1187,6 @@ _DISABLEA20:
|
|||||||
mov ah,6
|
mov ah,6
|
||||||
jmp short UsingXMSdriver
|
jmp short UsingXMSdriver
|
||||||
|
|
||||||
dslowmem dw 0
|
|
||||||
eshighmem dw 0ffffh
|
|
||||||
|
|
||||||
global forceEnableA20
|
global forceEnableA20
|
||||||
forceEnableA20:
|
forceEnableA20:
|
||||||
@ -1193,67 +1194,55 @@ forceEnableA20:
|
|||||||
push ds
|
push ds
|
||||||
push es
|
push es
|
||||||
push ax
|
push ax
|
||||||
|
push si
|
||||||
forceEnableA20retry:
|
push di
|
||||||
mov ds, [cs:dslowmem]
|
push cx
|
||||||
mov es, [cs:eshighmem]
|
pushf
|
||||||
|
cld
|
||||||
mov ax, [ds:00000h]
|
|
||||||
cmp ax, [es:00010h]
|
|
||||||
jne forceEnableA20success
|
|
||||||
|
|
||||||
mov ax, [ds:00002h]
|
.retry:
|
||||||
cmp ax, [es:00012h]
|
xor si, si ; = 0000h
|
||||||
jne forceEnableA20success
|
mov ds, si ; => low memory (IVT)
|
||||||
|
dec si ; = FFFFh
|
||||||
|
mov es, si ; => HMA at offset 10h
|
||||||
|
inc si ; back to 0, -> IVT entry 0 and 1
|
||||||
|
mov di, 10h ; -> HMA, or wrapping around to 0:0
|
||||||
|
mov cx, 4
|
||||||
|
repe cmpsw ; compare up to 4 words
|
||||||
|
je .enable
|
||||||
|
|
||||||
mov ax, [ds:00004h]
|
.success:
|
||||||
cmp ax, [es:00014h]
|
popf
|
||||||
jne forceEnableA20success
|
pop cx
|
||||||
|
pop di
|
||||||
mov ax, [ds:00006h]
|
pop si
|
||||||
cmp ax, [es:00016h]
|
|
||||||
jne forceEnableA20success
|
|
||||||
|
|
||||||
;
|
|
||||||
; ok, we have to enable A20 )at least seems so
|
|
||||||
;
|
|
||||||
|
|
||||||
call DGROUP:_ENABLEA20
|
|
||||||
|
|
||||||
jmp short forceEnableA20retry
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
forceEnableA20success:
|
|
||||||
pop ax
|
pop ax
|
||||||
pop es
|
pop es
|
||||||
pop ds
|
pop ds
|
||||||
ret
|
retn
|
||||||
|
|
||||||
;
|
.enable:
|
||||||
|
; ok, we have to enable A20 (at least seems so)
|
||||||
|
push cs ; make far call stack frame
|
||||||
|
call _ENABLEA20
|
||||||
|
jmp short .retry
|
||||||
|
|
||||||
|
|
||||||
; global f*cking compatibility issues:
|
; global f*cking compatibility issues:
|
||||||
;
|
;
|
||||||
; very old brain dead software (PKLITE, copyright 1990)
|
; very old brain dead software (PKLITE, copyright 1990)
|
||||||
; forces us to execute with A20 disabled
|
; forces us to execute with A20 disabled
|
||||||
;
|
;
|
||||||
|
|
||||||
global _ExecUserDisableA20
|
global _ExecUserDisableA20
|
||||||
|
|
||||||
_ExecUserDisableA20:
|
_ExecUserDisableA20:
|
||||||
|
push ax
|
||||||
cmp word [cs:_XMSDriverAddress], byte 0
|
push cs ; make far call stack frame
|
||||||
jne NeedToDisable
|
call _DISABLEA20 ; (no-op if not in HMA, patched otherwise)
|
||||||
cmp word [cs:_XMSDriverAddress+2], byte 0
|
|
||||||
je noNeedToDisable
|
|
||||||
NeedToDisable:
|
|
||||||
push ax
|
|
||||||
call DGROUP:_DISABLEA20
|
|
||||||
pop ax
|
pop ax
|
||||||
noNeedToDisable:
|
iret
|
||||||
iret
|
|
||||||
|
|
||||||
|
|
||||||
;
|
|
||||||
; Default Int 24h handler -- always returns fail
|
; Default Int 24h handler -- always returns fail
|
||||||
; so we have not to relocate it (now)
|
; so we have not to relocate it (now)
|
||||||
;
|
;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user