// vim: ft=gas:et:sw=12:ts=12:sts=12 .include "src/mode.S" .global bios_write .code32 bios_write: push %ebp mov %esp, %ebp push %ebx mov 8+0(%ebp), %edx PROT16 REAL .bwloop: cmpb $0, (%edx) jz .bwreturn xor %bx, %bx mov $0x0E, %ah mov (%edx), %al push %edx int $0x10 pop %edx add $1, %edx jmp .bwloop .bwreturn: PROT PROT32 pop %ebx mov %ebp, %esp pop %ebp ret .global bios_getmap .code32 bios_getmap:push %ebp mov %esp, %ebp push %ebx push %edi mov 8+0(%ebp), %edi PROT16 REAL xor %ebx, %ebx _gmnext: movl $0, 20(%di) mov $0x534D4150, %edx // e820 magic number mov $24, %ecx mov $0xE820, %eax int $0x15 jc _gmdone test %ebx, %ebx jz _gmdone add $24, %di jmp _gmnext _gmdone: add $24, %di PROT PROT32 mov %edi, %eax pop %edi pop %ebx mov %ebp, %esp pop %ebp ret .global bios_func bios_func: push %ebp mov %esp, %ebp push %ebx push %ebp push %edi push %esi mov 8+0(%ebp), %eax mov 8+4(%ebp), %edi // The interrupt number is given as an immediate value to INT. // To support any interrupt number, we use self-modifying code. mov %al, _bf_int+1 mov 0(%edi), %eax mov 4(%edi), %ecx mov 8(%edi), %edx mov 12(%edi), %ebx mov 16(%edi), %ebp mov 20(%edi), %esi mov 24(%edi), %edi PROT16 REAL // This instruction will get written at runtime _bf_int: .byte 0xCD, 0 // INT imm8 push $0 pushf PROT PROT32 push %edi mov 8+4(%ebp), %edi mov %eax, 0(%edi) mov %ecx, 4(%edi) mov %edx, 8(%edi) mov %ebx, 12(%edi) mov %ebp, 16(%edi) mov %esi, 20(%edi) pop %eax mov %eax, 24(%edi) pop %eax pop %esi pop %edi pop %ebp pop %ebx mov %ebp, %esp pop %ebp ret