; ===========================================================================
; L2PLL.ASM - Copyright (c) 1998 ATI Technologies Inc. All rights reserved
;
; Low level support functions to convert a logical address to a physical one.
;
; Compiling:
;   wasm -3pr -mf l2pll.asm
; ===========================================================================

.MODEL FLAT,C

.DATA

gdtlimit    dw  0
gdtbase     dd  0

.CODE
.386p

; ---------------------------------------------------------------------------
; GETDS
;
; Function returns value of DS segment register.
;
; Inputs : none
;
; Outputs: AX - value of DS segment register
; ---------------------------------------------------------------------------
            public  Getds_

Getds_  proc    near

            ; put DS value into AX
            xor     eax, eax
            mov     ax, ds

            ret

Getds_  endp

; ---------------------------------------------------------------------------
; GETLIN
;
; Function returns the linear address from the GDT/LDT based on DS segment
; value
;
; Inputs : AX  = DS segment value with attribute bits included
;
; Outputs: EAX = corresponding linear address from GDT or LDT
; ---------------------------------------------------------------------------
            public  Getlin_

Getlin_ proc    near

            ; save used registers
            push    ebx
            push    ecx
            push    edi

            ; check if segment descriptor is in GDT or LDT (bit 2)
            mov     bx, ax
            and     bx, 4
            jnz     @F

            ; read GDTR to get GDT base address
            sgdt    gdtlimit
            mov     ebx, gdtbase
            jmp     gl1
@@:
            ; read LDTR to get LDT base address
            sldt    gdtlimit
            mov     ebx, gdtbase
gl1:
            ; strip off segment attribute bits
            and     eax, 0fff8h

            ; get index to GDT/LDT entry by adding GDT/LDT base and segment
            add     eax, ebx

            ; read GDT/LDT entry and extract linear address
            mov     edi, eax
            mov     eax, [edi]
            mov     ebx, [edi+4]

            ; extract linear address
            shr     eax, 10h
            mov     ecx, ebx
            shr     ecx, 10h
            and     ecx, 0ff00h
            and     ebx, 0ffh
            add     ebx, ecx
            shl     ebx, 10h
            add     eax, ebx

            ; restore used registers
            pop     edi
            pop     ecx
            pop     ebx

            ret

Getlin_ endp

; ---------------------------------------------------------------------------
; GETPD
;
; Function returns page directory physical address from CR3 register
;
; Inputs : none
;
; Outputs: EAX - page directory physical address
; ---------------------------------------------------------------------------
            public  Getpd_

Getpd_  proc    near

            ; put CR3 value into EAX
            mov     eax, cr3
            and     eax, 0fffff000h ; strip off status bits

            ret

Getpd_  endp

; ---------------------------------------------------------------------------
; GETCR0
;
; Function returns value of CR0 register (indicates if paging is turned on)
;
; Inputs : none
;
; Outputs: EAX - value of CR0 register
; ---------------------------------------------------------------------------
            public  Getcr0_

Getcr0_ proc    near

            ; put CR0 value into AX
            mov     eax, cr0

            ret

Getcr0_ endp

            end

