↑ Back to main site.

EPOS

Experimental Protected-mode Operating System

access_bios.asm
;
; EPOS
; http://www.atanaslaskov.com/epos/
;
; FILE:         access_bios.asm
; DESCRIPTION:  BIOS access and some real-mode data types and routines.
;
; BSD LICENSE
; Copyright (c) 2006, Atanas Laskov
; All rights reserved.
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions are met:
;   1. Redistributions of source code must retain the above copyright notice,
;   this list of conditions and the following disclaimer.
;   2. Redistributions in binary form must reproduce the above copyright notice,
;   this list of conditions and the following disclaimer in the documentation
;   and/or other materials provided with the distribution.
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
; DISCLAIMED. IN NO EVENT SHALL ATANAS LASKOV BE LIABLE FOR ANY
; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;
BITS 32

extern SEL_GDT_CODE
extern SEL_GDT_DATA
extern SEL_GDT_LINEAR
extern SEL_GDT_CODE16
extern SEL_GDT_DATA16

REAL_MODE_IP dw ENTER_RM
REAL_MODE_CS dw 60h

STACK_PTR:  dw 0
            dw 0

extern _IDTR
IDTR_R: dw 0FFFFh        ; Real-mode interrupt descriptor table limit
        dd 0             ; Linear physical address of real-mode IDT

RM_REGS:                    ; Some space to store the registers
RM_REGS_AX: dw  0E00h + '&' ;ax
RM_REGS_BX: dw  ' '         ;bx
RM_REGS_CX: dw  0           ;cx
RM_REGS_DX: dw  0           ;dx
RM_REGS_SI: dw  0           ;si
RM_REGS_DI: dw  0           ;di
RM_REGS_BP: dw  0           ;bp
RM_REGS_DS: dw  0           ;ds
RM_REGS_ES: dw  0           ;es
RM_REGS_NI: db  10h         ;nint
dw 0
dw 0

; -----------------------  Get a pointer to real-mode registers
;
global _access_getprmregs
_access_getprmregs:
    mov eax, RM_REGS
ret

; -----------------------  Access bios
;
global _access_bios
_access_bios:
push eax
push ebx
push ecx
push edx
push esi
push edi
push ebp
mov eax, esp
mov [STACK_PTR], eax
mov esp, 0

; Enter real-mode; BIOS doesn't like PM
;
mov eax, cr0
push eax
cli
jmp SEL_GDT_CODE16:ENTER_16
BITS 16
ENTER_16:

; All segment registers must be valid for RM
; before clearing the Protected-mode (PM) flag
;
mov ax, SEL_GDT_DATA16
mov ss, ax
mov ds, ax

mov eax, 0
mov cr0, eax

;mov eax, cr0
;and al, 0xFE
;mov cr0, eax

; Ops! CS is still selector
jmp far [REAL_MODE_IP]


; ES and DS are still selectors
ENTER_RM:
mov ax, 60h
mov ds, ax
mov es, ax
mov ax, 50h
mov ss, ax

lidt [IDTR_R]

mov ax, 0B800h
mov es, ax
mov [es:78*2], byte 'R'

; Now we are in Real-mode. Call the BIOS service
;
mov al, [RM_REGS_NI]
mov [CS:INT_NUMBER], al

mov ax, [CS:RM_REGS_ES]
mov es, ax
mov ax, [CS:RM_REGS_DS]
mov ds, ax

mov ax, [CS:RM_REGS_AX]
mov bx, [CS:RM_REGS_BX]
mov cx, [CS:RM_REGS_CX]
mov dx, [CS:RM_REGS_DX]
mov si, [CS:RM_REGS_SI]
mov di, [CS:RM_REGS_DI]
mov bp, [CS:RM_REGS_BP]
sti

;mov ah, 0Eh
;mov al, '%'
;mov bl, ' '
;int 10h

db 0CDh     ; int x
INT_NUMBER: db 10h
cli

mov [RM_REGS_ES], es
mov [RM_REGS_DS], dx

mov [CS:RM_REGS_AX], ax
mov [CS:RM_REGS_BX], bx
mov [CS:RM_REGS_CX], cx
mov [CS:RM_REGS_DX], dx
mov [CS:RM_REGS_SI], si
mov [CS:RM_REGS_DI], di
mov [CS:RM_REGS_BP], bp

; Return to protected-mode
;
mov eax, cr0
or al, 1
mov cr0, eax

jmp SEL_GDT_CODE:ENTER_32_
BITS 32
ENTER_32_:

mov ax, SEL_GDT_DATA
mov ds, ax
mov es, ax
mov fs, ax

mov ax, SEL_GDT_LINEAR
mov gs, ax

mov ax, SEL_GDT_DATA
mov ss, ax
nop
pop eax
mov cr0, eax
lidt [cs:_IDTR]

mov eax, [STACK_PTR]
mov esp, eax
pop ebp
pop edi
pop esi
pop edx
pop ecx
pop ebx
pop eax
ret