// 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 leave 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 leave ret .global bios_func bios_func: push %ebp mov %esp, %ebp push %ebx push %ebp push %edi push %esi // The interrupt number is given as an immediate value to INT. // To support any interrupt number, we use self-modifying code. mov 8+0(%ebp), %eax mov %al, _bf_int+1 PROT16 REAL mov 8+4(%ebp), %edi mov 0(%edi), %ax mov 2(%edi), %cx mov 4(%edi), %dx mov 6(%edi), %bx mov 8(%edi), %bp mov 10(%edi), %si mov 12(%edi), %di // This instruction will get written at runtime _bf_int: .byte 0xCD, 0 // INT imm8 push $0 pushf push %di mov 8+4(%ebp), %edi mov %ax, 0(%edi) mov %cx, 2(%edi) mov %dx, 4(%edi) mov %bx, 6(%edi) mov %bp, 8(%edi) mov %si, 10(%edi) pop %ax mov %ax, 12(%edi) PROT PROT32 pop %eax pop %esi pop %edi pop %ebp pop %ebx leave ret