CeDOS - kernel/drivers/graphics.s

kernel/drivers/graphics.s (view raw)

.section .text.realmode
.global realmode_int10h
.code32
realmode_int10h:
    push %ebp
    mov %esp, %ebp

    pushf
    cli
    
    pusha

    # preserve protected mode IDT
    sidtl (pmode_IDT)

    mov %esp, %eax
    mov %eax, %esi

    mov %ebp, %eax
    mov %eax, %edi

    # setup real mode stack
    mov $0xF000, %eax
    mov %eax, %esp
    mov %eax, %ebp

    push %esi
    push %edi

    mov +16(%edi), %eax
    push %eax
    mov +12(%edi), %eax
    push %eax
    mov +8(%edi), %eax
    push %eax

    push %ebp
    mov %esp, %ebp

    # disable paging
    mov %cr3, %eax
    push %eax

    mov %cr0, %eax
    and $0x3FFFFFFD, %eax
    mov %eax, %cr0

    xor %eax, %eax
    mov %eax, %cr3

    # switch to 16 bit protected mode
    ljmp $0x8, $pmode16

.code16
pmode16:
    # setup segments
    movw $0x10, %ax
    movw %ax, %ss
    movw %ax, %ds
    movw %ax, %es
    movw %ax, %fs

    # load real mode interrupt descriptor table
    lidt (realmode_IDT)

    # switch to real mode
    mov %cr0, %eax
    and $0xFFFFFFFE, %eax
    mov %eax, %cr0

    ljmp $0, $realmode
realmode:
    # setup segments
    movw $0x0000, %ax
    movw %ax, %ss
    movw %ax, %ds
    movw %ax, %es
    movw %ax, %fs

    sti

    # load arguments
    movw +4(%bp), %ax
    movw +8(%bp), %bx
    movw +12(%bp), %cx

    int $0x10

    cli

    lidtl (pmode_IDT)

    mov %cr0, %eax
    or $0x00000001, %eax
    mov %eax, %cr0

    ljmp $0x18, $pmode32

.code32
pmode32:
    # set data segments
    movw $0x20, %ax
    movw %ax, %ss
    movw %ax, %ds
    movw %ax, %es
    movw %ax, %fs

    # restore paging
    pop %eax
    mov %eax, %cr3

    mov %cr0, %eax
    or $0x80000010, %eax
    mov %eax, %cr0

    # clean up argument buffer
    pop %ebp
    add $12, %esp

    # restore original stack
    pop %ebp
    pop %eax
    mov %eax, %esp

    popa
    popf
    
    # return
    pop %ebp
    ret


realmode_IDT:
  .word 0x3FF
  .int 0

pmode_IDT:
  .word 0
  .int 0