📄 grub-0.97-patch4-emulation
字号:
+ movl %es:4(%di), %eax /* BaseAddrHigh */+ testl %eax, %eax+ jnz 4f+ movl %es:16(%di), %eax /* Type */+ decl %eax /* 1=usable memory, available to the operating system */+ jnz 4f+ /* set %si to the drive map */+ movw $(hooked_drive_map - int13_handler), %si+ movw $(DRIVE_MAP_SIZE), %cx+6:+ cmpb $0xff, %cs:1(%si)+ jne 5f+ movl %cs:4(%si), %ebx /* start_sector */+ shll $9, %ebx+ movl %es:4(%di), %eax /* BaseAddrHigh */+ testl %eax, %eax+ jnz 5f+ cmpl %es:(%di), %ebx /* BaseAddrLow */+ jb 5f+ movl %es:12(%di), %eax /* LengthHigh */+ testl %eax, %eax+ jnz 7f+ movl %es:8(%di), %eax /* LengthLow */+ addl %es:(%di), %eax+ jc 7f+ cmpl %eax, %ebx+ jnb 5f+7:+ subl %es:(%di), %ebx /* new length */+ movl %ebx, %es:8(%di) /* LengthLow */+ xorl %ebx, %ebx+ movl %ebx, %es:12(%di) /* LengthHigh */+ //jmp 4f++5:+ /* try next slot */+ addw $12, %si+ loop 6b+ //memory block length update done+4:+ popal+ clc+ lret $2++2:+ movb $0x86, %ah /* function not supported */+3:+ stc+ lret $2+1:+ cmpw $0xe801, %ax //cmpl $0x0000e801, %eax+ je 1f+ cmpw $0xe881, %ax //cmpl $0x0000e881, %eax+ je 1f+ cmpw $0xda88, %ax+ je 1f+ cmpb $0x8a, %ah+ je 1f+ cmpb $0x88, %ah+ je 1f+ ljmp %cs:*(ROM_int15 - int13_handler)+1:++ pushal++ /* find minimum mem ever used in the drive map slots */++ movl $-1, %eax /* 0xffffffff */+ movl %eax, %cs:(minimum_mem_in_map - int13_handler)+ /* set %si to the drive map */+ movw $(hooked_drive_map - int13_handler), %si+ movw $(DRIVE_MAP_SIZE), %cx+6:+ cmpb $0xff, %cs:1(%si)+ jne 5f+ movl %cs:4(%si), %ebx /* start_sector */+ shll $9, %ebx+ cmpl %ebx, %cs:(minimum_mem_in_map - int13_handler)+ jbe 5f+ movl %ebx, %cs:(minimum_mem_in_map - int13_handler)+5:+ /* try next slot */+ addw $12, %si+ loop 6b++ cmpl %eax, %cs:(minimum_mem_in_map - int13_handler)++ popal+ jne 1f+ ljmp %cs:*(ROM_int15 - int13_handler)++1:+ cmpw $0xe801, %ax //cmpl $0x0000e801, %eax+ jne 1f++ /* Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS */++ //movw $0x3c00, %ax /* 1-16M mem in K (0x3c00KB = 15MB) */+ //movw $0x0300, %bx /* mem above 16M in 64K blocks */+4:+ pushfw+ pushl %eax+ movl %cs:(minimum_mem_in_map - int13_handler), %eax+ cmpl $0x1000000, %eax /* 16M */+ ja 2f+ /* mem is no more than 16M */+ subl $0x0100000, %eax+ jnc 3f+ xorl %eax, %eax+3:+ shrl $10, %eax /* AX=1-16M mem in K */+ popw %bx+ pushw %ax+ xorw %bx, %bx+ jmp 5f+2:+ /* mem is more than 16M */+ popw %bx+ pushw $0x3c00 /* 0x3c00KB = 15MB */+ subl $0x1000000, %eax+ shrl $16, %eax /* AX=mem above 16M in 64K blocks */+ xchgw %ax, %bx+5:+ popl %eax+ popfw+ movw %ax, %cx+ movw %bx, %dx+ jnc 5f+ movzwl %ax, %eax+ movzwl %bx, %ebx+ movzwl %cx, %ecx+ movzwl %dx, %edx+5:+ clc+ lret $2++1:+ cmpw $0xe881, %ax //cmpl $0x0000e881, %eax+ jne 1f++ /* Phoenix BIOS v4.0 - GET MEMORY SIZE FOR >64M CONFIGURATIONS (32-bit) */++ //movl $0x3c00, %eax /* 1-16M mem in K (0x3c00 = 15MB) */+ //movl $0x0300, %ebx /* mem above 16M in 64K blocks */++ stc+ jmp 4b+1:+ cmpw $0xda88, %ax+ jne 1f++ /* AMI PCI BIOS - GET EXTENDED MEMORY SIZE */++ //AX = DA88h++ //Return:+ //CF clear (successful)+ //AX = 0000h+ //CL:BX = extended memory size in KBytes++ /* 63M = 3f00000 Bytes = 0xfc00 K */+ //movw $0xfc00, %bx++ pushl %eax+ movl %cs:(minimum_mem_in_map - int13_handler), %eax+ subl $0x0100000, %eax+ jnc 3f+ xorl %eax, %eax+3:+ shrl $10, %eax /* EAX=extened mem in K */+ xchgw %ax, %bx+ shrl $16, %eax+ movb %al, %cl+ popl %eax+ xorw %ax, %ax+ clc+ lret $2++1:+ cmpb $0x8a, %ah+ jne 1f++ /* Phoenix BIOS v4.0 - GET BIG MEMORY SIZE */++ //AH = 8Ah++ //Return:+ //DX:AX = extended memory size in K + //movw $0xfc00, %ax++ pushl %eax+ movl %cs:(minimum_mem_in_map - int13_handler), %eax+ subl $0x0100000, %eax+ jnc 3f+ xorl %eax, %eax+3:+ shrl $10, %eax /* EAX=extened mem in K */+ popw %dx+ pushw %ax+ shrl $16, %eax+ xchgw %ax, %dx+ popl %eax+ clc+ lret $2++1:+ cmpb $0x88, %ah+ jne 1f++ /* SYSTEM - GET EXTENDED MEMORY SIZE (286+) */++ //AH = 88h++ //Return:+ //CF clear on success(Not all BIOSes correctly return the carry flag)+ //AX = number of contiguous KB starting at absolute address 100000h+ //CF set on error+ //AH = status+ // 80h invalid command (PC,PCjr)+ // 86h unsupported function (XT,PS30)+ //movw $0xfc00, %ax++ pushl %eax+ movl %cs:(minimum_mem_in_map - int13_handler), %eax+ subl $0x0100000, %eax+ jnc 3f+ xorl %eax, %eax+3:+ shrl $10, %eax /* EAX=extened mem in K */+ cmpl $0x0000fc00, %eax+ jbe 3f+ movw $0xfc00, %ax+3:+ addw $2, %sp+ pushw %ax+ popl %eax+ clc+ lret $2++1:+ ljmp %cs:*(ROM_int15 - int13_handler)++#include "a20.inc"++// Input:+// dl=0 - Disable A20+// dl=1 - Eanble A20+++int13_enable_a20:+ movw $0x2400,%ax+ addb %dl, %al+ stc+ pushfw+ lcall %cs:*(ROM_int15 - int13_handler)+ jnc int13_a20_gloop2ret+ + call int13_a20_gloop1++ movb $KC_CMD_WOUT, %al+ outb $K_CMD++int13_a20_gloopint1:+ inb $K_STATUS+ andb $K_IBUF_FUL, %al+ jnz int13_a20_gloopint1++ movb $KB_OUTPUT_MASK, %al+ + orb %dl, %dl+ jz int13_a20_gdoit+ orb $KB_A20_ENABLE, %al++int13_a20_gdoit:+ outb $K_RDWR++ call int13_a20_gloop1++ /* output a dummy command (USB keyboard hack) */+ movb $0xff, %al+ outb $K_CMD+ call int13_a20_gloop1+ + jmp int13_a20_gloop2ret++int13_a20_gloop1:+ inb $K_STATUS+ andb $K_IBUF_FUL, %al+ jnz int13_a20_gloop1++int13_a20_gloop2:+ inb $K_STATUS+ andb $K_OBUF_FUL, %al+ jz int13_a20_gloop2ret+ inb $K_RDWR+ jmp int13_a20_gloop2++int13_a20_gloop2ret:+ ret+++__reg_select_dev:+#; ax = dev+#; simple version of the select dev+ addb $0x0A, %al #; AL= 0x0A or 0x0B+ shlb $4, %al #; AL= 0xA0 or 0xB0+ movw reg_addr - int13_handler + (6 * 2), %dx #; CB_DH = drive select+ outb %al, %dx++ call delay400ns+ ret+++reg_select_dev:+#; input: ax = bx = dev+#; set_timeout first+// movw %ax, %bx+ cmpb $2, (reg_dev_info - int13_handler)(%bx) # REG_CONFIG_TYPE_ATA+ jb __reg_select_dev # not ATA++ /* The device is ATA */++// pushw %bx++ call reg_poll_busy # change AL, DX++#if 0+ orw %ax, %ax+ jnz 1f # return if,{or ax,ax},nz+#else+ ja 1f # timeout, failure+#endif++ movw %bx, %ax+ call __reg_select_dev # change AL, DX++#ifndef USE_ATA+ call reg_poll_busy # change AL, DX+#if 0+ jmp 1f+#else+#if 0+ orw %ax, %ax+ jz 1f+#else+ jna 1f+#endif+#endif+#else //; USE_ATA+3:+ movw reg_addr - int13_handler + (7 * 2), %dx #; CB_STAT+ inb %dx, %al++ cmpb $2, (reg_dev_info - int13_handler)(%bx) # REG_CONFIG_TYPE_ATA+ jne 4f+ andb $(CB_STAT_BSY | CB_STAT_RDY | CB_STAT_SKC), %al+ # return if,{cmp al,CB_STAT_RDY|CB_STAT_SKC},e+ cmpb $(CB_STAT_RDY | CB_STAT_SKC), %al+ je 1f+ jmp 3b+4:+ # return if,{test al,CB_STAT_BSY},z+ testb $CB_STAT_BSY, %al+ jz 1f+ jmp 3b+#endif //; USE_ATA+++ call __reg_select_dev+1:+// popw %bx+ ret+++select_atapi:+ cmpw atapi_cur_dev - int13_handler, %ax # device serial number+ jne select_atapi_force+ //clc #; CF already cleared+ ret+++select_atapi_force:+#; input: ax = device serial number+#; return: cf =0 success, cf =1 failed+ pushaw+ pushw %es++ pushw %cs+ popw %es++ cmpw atapi_dev_count - int13_handler, %ax+ cmc+ jb 2f++ movw %ax, atapi_cur_dev - int13_handler # device serial number++ movw $atapi_dev_base - int13_handler, %si # array of ATAPI reg pointer and dev+ shlw $2, %ax # each element of array has 4 bytes+ addw %ax, %si+ movw (%si), %bx # BX is the reg pointer of the current device++ call reg_setup_base_addr # fill the 10-word reg_addr area+ # change no registers++ movw 2(%si), %bx # BX is the dev number of the current device+ movw %bx, %ax++ call set_timeout # set timeout for reg_select_dev+ # change no registers++ call reg_select_dev #; reg_select_dev++ addb $0x0A, %bl #; BL= 0x0A or 0x0B+ shlb $4, %bl #; BL= 0xA0 or 0xB0+ movb %bl, reg_cur_dev - int13_handler++ clc+2:+ pop %es+ popaw+ ret+++read_atapi:+#;input: es:di -> buffer, cx = sector count, edx = lba address+#;return: cf =0 success, cx = number of bytes actually read+ pushaw+ orw %cx, %cx+ jz 3f++1:+ pushw %cx+ pushl %edx++ call clear_atapi_buffer+ movb $0x28, atapi_cmd_buffer - int13_handler++ bswapl %edx+ movl %edx, atapi_cmd_buffer - int13_handler + 2+ movb $1, atapi_cmd_buffer - int13_handler + 8++ # invoke reg_packet,byte, 0, es, di, REG_ATAPI_MAX_BYTES+ pushw $0x8000 #; REG_ATAPI_MAX_BYTES+ pushw %di+ pushw %es+ pushw $0+ call reg_packet+ addw $8, %sp++ orw %ax, %ax+ jnz 2f+ cmpw $0x800, %cx #; CDSECTOR_SIZE+ jne 2f+ popl %edx+ incl %edx+ addw %cx, %di+ popw %cx+ loop 1b++ clc+ jmp 4f++2:+ popl %edx+ popw %cx++3:+ stc+4:+ popaw+ ret+++read_bios_time:+#; return EAX as the long time+ pushw %ds+ xorw %ax, %ax+ movw %ax, %ds+ movl 0x46c, %eax+ popw %ds+ ret+++edd30_read_cdrom:+#;return cf=0 success, cf=1 fail, ah = fail code+#;will change all registers, including ES!!++ call test_atapi_ready+ movb $0xAA, %ah # error code if CF=1+ jc 4f++ movw %ds, %ax # save DS++ movw -18(%bp), %ds # get DS for the disk address packet+ movw 2(%si), %cx # struc_int13ext.blk_count+ movw 4(%si), %di # struc_int13ext.buf_addr_off+ movw 6(%si), %bx # struc_int13ext.buf_addr_seg+ movl 8(%si), %edx # struc_int13ext.blk_num_low1+ cmpb $16, (%si) # valid packet size is 16++ movw %ax, %ds # restore DS++ setne %ah # AH=1 for invalid function call+ stc # error out if ...+ jne 4f # ... invalid packet size++ movw %bx, %es # ES changed!!++ call read_atapi++ movb $0x0C, %ah # error code if CF=1+4:+// /* debug print AX and FLAGS */+// pushfw+// pushw %ax+// pushw $read_cdrom_ah_flags - int13_handler # the format string+// call realmode_printf+// popw %ax+// popw %ax+// popfw+ ret++//read_cdrom_ah_flags:+// .ascii "edd30_read_cdrom: AX=%X, FLAGS=%X\r\n\0"+++reg_reset:+#; call after reg_probe_exist+ pushaw++#; mov_ax 0+#; call __reg_select_dev++#if 0+ /* The ATA software reset mechanism, SRST, (bit 2 in the Device Control+ * Register) cannot be used for ATAPI Device, because resets issued by+ * the ATAPI driver would also reset any attached hard disk and vice+ * versa. To solve this, ATAPI defines an ATAPI Soft Reset command+ * using a reserved ATA opcode which could be decoded by the interface+ * controller hardware.+ */++ movb $cmd_DC, %al+ orb $0x04, %al #; CB_DC_SRST = soft reset++ movw reg_addr - int13_handler + (8 * 2), %dx #; CB_DC+ outb %al, %dx++ call delay400ns+#endif++#if 0+ movb $0x08, %al #; ATAPI Soft Reset+ movw reg_addr - int13_handler + (7 * 2), %dx #; CB_CMD+ outb %al, %dx++ call delay400ns+#endif++#if 1+ /* set features (0xEF to command port) */+ /* set transfer mode (0x03 in feature register) */+ /* mode value in Sector Count register (0 for PIO default mode) */++ movb $0, %al #; PIO default transfer mode+ movw reg_addr - int13_handler + (2 * 2), %dx #; CB_SC = interrupt reason register+ outb %al, %dx++ call delay400ns++ mov
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -