📄 asm.s
字号:
#define cmd_DC_ni CB_DC_HD15 | CB_DC_NIEN#undef DEBUG#ifdef DEBUG#include "debug.h"#endif cmpb $0, %cs:(atapi_dev_count - int13_handler) jz no_cdrom /* no cdrom */ cmpb %cs:(min_cdrom_id - int13_handler), %dl jb not_cdrom_drv /* not cdrom drive */ cmpb %cs:(max_cdrom_id - int13_handler), %dl jbe edd30_for_cdromnot_cdrom_drv:// cmpb $0, %cs:(emu_disk_type - int13_handler)// je not_emu_drv// cmpb %cs:(edd30_cdemu_spec - int13_handler + 2), %dl #; struc_cdemu_spec.emu_drvid// je cdemu_int13hnot_emu_drv:no_cdrom:/****************************************************************************/ pushw %si /* BP-2: old SI */ /* set %si to the drive map */ movw $(hooked_drive_map - int13_handler), %si /* find the drive number from the drive map */ subw $DRIVE_MAP_SLOT_SIZE, %sp1: addw $DRIVE_MAP_SLOT_SIZE, %sp lodsl %cs:(%si), %eax pushl %eax /* BP-6: FROM, TO, Hmax, Smax */ lodsl %cs:(%si), %eax pushl %eax /* BP-10: TO_C, TO_H, TO_S */ lodsl %cs:(%si), %eax pushl %eax /* BP-14: StartLBA_Lo */ lodsl %cs:(%si), %eax pushl %eax /* BP-18: StartLBA_Hi */ lodsl %cs:(%si), %eax pushl %eax /* BP-22: S_count_Lo */ lodsl %cs:(%si), %eax pushl %eax /* BP-26: S_count_Hi */ movl -6(%bp), %eax /* FROM, TO, Hmax, Smax */ /* check if this is the end */ testl %eax, %eax jnz 3f /* not end, continue */ movl -14(%bp), %eax /* StartLBA_Lo */ testl %eax, %eax jnz 3f /* not end, continue */ movl -22(%bp), %eax /* S_count_Lo */ testl %eax, %eax jnz 3f /* not end, continue */ movb %dl, %al /* FROM */ movb %dl, %ah /* TO */ movw %ax, -6(%bp) jmp 2f /* map whole drive to itself signals the end */3: /* Now this is a valid drive map slot */ movw -6(%bp), %ax /* AL=FROM, AH=TO */ cmpb %al, %dl /* check if this matches the drive number */ jne 1b /* no, continue to check the next map */ /* yes, found the map corresponding to drive DL */#; movw -4(%bp), %ax /* AL=Hmax, AH=Smax */#; andb $0xC1, %ah /* clear bit 5 - bit 1 */ testb $0x80, -7(%bp) /* TO_S */ jnz 1f /* non-zero StartLBA signals emulation */ movl -14(%bp), %eax /* StartLBA_Lo */ testl %eax, %eax jnz drive_emulation /* S_count being not 1 signals emulation */ movl -22(%bp), %eax /* S_count_Lo */ shrl $1, %eax jnz drive_emulation /* now StartLBA=0 and sector count=1(for whole disk) */ /* if sectors per track > 1, this is force geometry screw. */ movw -4(%bp), %ax /* AL=Hmax, AH=Smax */ testb $62, %ah /* Sectors > 1 means force geom, this -- */ jnz drive_emulation /* -- also leads to drive emulation */ /* ignore geom and directly map a whole drive */ 1: /* bit 7 of the TO_S is for in-situ primary partition(alter MBR) */ /* bits of AH: * 7 bit set means readonly/fakewrite * 6 bit set means disable LBA * 5 - 1 bits already cleared(=0) * 0 bit cleared means disable CHS * So, if AH!=1, it is a restricted disk access; * and if AH=1, it is a normal disk access. */ cmpb $1, %ah je 1f// testb $0x3F, %ah// jz 3f// testb $0xC0, %ah// jz 1f//3: call restricted_map1: /* map a whole drive, normal access */ /* but if --in-situ was used, we should avoid writing the MBR! */ testb $0x80, -7(%bp) /* TO_S */ jz 1f /* not in-situ, allow write */ testb $0x40, -7(%bp) /* TO_S. bit 6 here means safe-boot */ jz 1f /* unsafe-boot, allow write */ movw 2(%bp), %ax /* restore AX */ cmpb $0x03, %ah /* is it CHS write? */ jne 3f /* check if it is a write to MBR, i.e., C/H/S=0/0/1 */ cmpw $0x0001, %cx /* C=0, S=1 */ jne 1f cmpb $0x00, %dh /* H=0 */ jne 1f /* deny the write and end the int 13 call */ call readonly_fakewrite /* NO RETURN!! */3: cmpb $0x43, %ah /* is it LBA write? */ jne 1f /* no, continue the normal access */ /* check if it is a write to MBR, i.e., LBA=0 */ xorl %eax, %eax cmpl %eax, 12(%si) /* write to LBA_hi32bits=0? */ jne 1f cmpl %eax, 8(%si) /* write to LBA_lo32bits=0? */ jne 1f /* deny the write and end the int 13 call */ call readonly_fakewrite /* NO RETURN!! */1: movw -6(%bp), %ax /* AL=FROM, AH=TO */ movb %ah, %dl /* Let DL access TO instead of FROM */2: /* might map to itself, i.e., actually not mapped */ movw -2(%bp), %si /* restore SI */#if 0 pushw 10(%bp) /* pushfw, simulate the interrupt call */ movl 2(%bp), %eax /* restore EAX */ movw (%bp), %bp /* restore BP */ /* pushfw, lcall, simulate the interrupt call */ lcall %cs:*(ROM_int13 - int13_handler) pushw %ax /* save AX */ pushfw /* save flags returned by int13 */ popw %ax#else pushw 10(%bp) /* pushfw, simulate the interrupt call */ movl 2(%bp), %eax /* restore EAX */ movw (%bp), %bp /* restore BP */ call backup_int13 popfw int $0x13 pushw %ax /* save AX */ pushfw /* save flags returned by int13 */ call restore_int13 popfw pushfw popw %ax /* AX=flags returned by int13 */#endif movw %sp, %bp /* set new BP */ /* BP+38: old Flags */ /* BP+36: return CS */ /* BP+34: return IP */ /* BP+30: old EAX */ /* BP+28: old BP */ /* BP+26: old SI */ /* BP+22: FROM, TO, Hmax, Smax */ /* BP+18: TO_C, TO_H, TO_S */ /* BP+14: StartLBA_Lo */ /* BP+10: StartLBA_Hi */ /* BP+ 6: S_count_Lo */ /* BP+ 2: S_count_Hi */ /* BP+ 0: new AX returned from int 13 */#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; leaw 28(%bp), %bp // it is addw $28, %bp but won't touch flags /* BP+10: old Flags */ /* BP+ 8: return CS */ /* BP+ 6: return IP */ /* BP+ 2: old EAX */ /* BP+ 0: old BP */ /* BP- 2: old SI */ /* BP- 6: FROM, TO, Hmax, Smax */ /* BP-10: TO_C, TO_H, TO_S */ /* BP-14: StartLBA_Lo */ /* BP-18: StartLBA_Hi */ /* BP-22: S_count_Lo */ /* BP-26: S_count_Hi */ /* BP-28: new AX returned from int 13 */#;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; movw %ax, 10(%bp) /* update the flags in the stack */ /* check if should restore(reversely map) the drive number */ jc 1f /* restore DL on error */ movw 2(%bp), %ax /* lower word of the saved EAX */ /* alter MBR after read */ testb $0x80, -7(%bp) jz 3f cmpb $0x02, %ah je alter_mbr cmpb $0x42, %ah je alter_mbr3: cmpb $0x08, %ah /* int13 AH=08h, read drive parameters */ jne 2f /* DL==number of drives, should not restore */ pushw %ds xorw %ax, %ax movw %ax, %ds movw -6(%bp), %ax /* AL=FROM, AH=TO */ testb %al, %al /* hard drive? */ movb 0x475, %dl /* DL=number of hard drives */ js 3f /* yes, jump */ //movw $0x10, %bx /* for floppy, refer to function 0x48 */ movb 0x410, %al rorb $1, %al cbw shlb $1, %al shrb $6, %al incw %ax andb %ah, %al movb %al, %dl /* DL=number of floppy drives */ //lesw 0x0078, %di /* point to int 1E floppy parameters */3: popw %ds jmp 3f2: //cmpb $0x15, %ah /* int13 AH=15h, read drive type */ //je 3f /* CX:DX==total sectors, should not restore */ //jne 1f xorb $0x15, %ah /* int13 AH=15h, read drive type */ /* CF=0 for now. if ZF=1, then AH was 0x15, and it is "equal" * for the jxx class of instructions. if ZF=0, then AH was not 0x15, * and it is "above" for the jxx class of instructions. */1: movw -6(%bp), %ax /* get the drive mapping */ /* should not simply use "jne 2f" here because ZF is unknown when * error occurred for the above int13 call */ jc 2f /* "below" means error occurred for int13 */ ja 2f /* "above" means it is not int13 AH=15h */ /* "equal" means int13 AH=15h */ testb %al, %al /* the FROM drive is harddrive? */ js 3f /* yes, do not restore DL */ /* restore DL for floppy int13 AH=15h call */2: /* try to restore DL if possible */ cmpb %al, %ah /* check if the mapping was performed */ je 3f /* not performed, so need not restore DL */ cmpb %dl, %ah jne 3f /* DL changed by int13, so do not restore */ movb %al, %dl /* restore DL back to the FROM drive */3: /* return */ movl 2(%bp), %eax /* restore the original EAX */ popw %ax /* update the int13 status in AX */ movw (%bp), %bp /* restore the original BP */ addw $32, %sp iretalter_mbr: call modify_in_situ movw -6(%bp), %ax /* get the drive mapping */ jmp 2b/****************************************************************************/restricted_map: movw 2(%bp), %ax /* lower word of the saved EAX */ /* CHS read functions */ cmpb $0x02, %ah /* read sectors */ je 2f cmpb $0x04, %ah /* verify sectors, also a read operation */ je 2f cmpb $0x0a, %ah /* read long sectors */ je 2f cmpb $0x0c, %ah /* seek to cylinder */ je 2f cmpb $0x21, %ah /* PS/1 and newer PS/2 - read multiple disk sectors */ jne 1f2: movb -3(%bp), %ah /* AH=Smax */ testb $63, %ah /* check if Sectors=0, i.e., disable CHS */ jz error_01_disable ret1: /* CHS write functions */ cmpb $0x03, %ah /* CHS write sectors */ je 2f cmpb $0x05, %ah /* PC/XT/AT/EISA format tracks */ je 2f cmpb $0x06, %ah /* PC/XT format tracks with bad sectors */ je 2f cmpb $0x07, %ah /* PC/XT format multiple cylinders */ je 2f cmpb $0x0b, %ah /* PC/XT/AT/EISA write sectors with ECC */ je 2f cmpb $0x0f, %ah /* PC/XT/PS/1 write sector buffer */ je 2f cmpb $0x22, %ah /* PS/1 and newer PS/2 - write multiple disk sectors */ jne 1f2: movb -3(%bp), %ah /* AH=Smax */ testb $63, %ah /* check if Sectors=0, i.e., disable CHS */ jz error_01_disable testb $0x80, %ah /* readonly access? */ jnz readonly_fakewrite ret1: /* LBA read functions */ cmpb $0x41, %ah /* Extensions - INSTALLATION CHECK */ je 2f cmpb $0x42, %ah /* Extensions - EXTENDED READ */ je 2f cmpb $0x44, %ah /* Extensions - verify sectors */ je 2f cmpb $0x45, %ah /* Extensions - LOCK/UNLOCK DRIVE */ je 2f cmpb $0x46, %ah /* Extensions - EJECT MEDIA */ je 2f cmpb $0x47, %ah /* Extensions - EXTENDED SEEK */ je 2f cmpb $0x48, %ah /* Extensions - GET DRIVE PARAMETERS */ je 2f cmpb $0x49, %ah /* Extensions - detect media change */ je 2f cmpb $0x4a, %ah /* Bootable CDROM - INITIATE DISK EMULATION */ je 2f cmpb $0x4b, %ah /* Bootable CDROM - TERMINATE DISK EMULATION */ je 2f cmpb $0x4c, %ah /* Bootable CDROM - INITIATE DISK EMULATION AND BOOT */ je 2f cmpb $0x4d, %ah /* Bootable CDROM - RETURN BOOT CATALOG */ je 2f cmpb $0x4e, %ah /* Extensions v2.1 - SET HARDWARE CONFIGURATION */ jne 1f2: movb -3(%bp), %ah /* AH=Smax */ testb $64, %ah /* disable LBA? */ jnz error_01_disable ret1: /* LBA write functions */ cmpb $0x43, %ah /* Extensions - EXTENDED WRITE */ jne 1f2: movb -3(%bp), %ah /* AH=Smax */ testb $64, %ah /* disable LBA? */ jnz error_01_disable testb $0x80, %ah /* readonly access? */ jnz readonly_fakewrite1: /* no restrictions, return and continue */ reterror_01_disable: /* function not supported, or the input CHS is invalid */ addw $26, %sp /* adjust SP */ popw %si popw %bp popl %eaxerror_01_disable2: movb $0x01, %ah /* signal invalid function call */ stc /* signal error */ lret $2 /* far return discard the original flags */readonly_fakewrite: addw $26, %sp /* adjust SP */ popw %si #;testb $1, -22(%bp) /* lowest bit of S_count_Lo */ testb $0x40, -7(%bp) /* bit 6 of TO_S */ popw %bp popl %eax jnz 1f /* read only */ movb $0x03, %ah /* signal write protection */ stc /* signal error */ lret $2 /* far return discard the original flags */1: /* fake write */ xorb %ah, %ah /* signal write succeeded */ /*clc*/ /* signal success, CF already cleared by XOR */ lret $2 /* far return discard the original flags *//****************************************************************************/drive_emulation: movw -4(%bp), %ax /* AL=Hmax, AH=Smax */ testb $63, %ah /* disable CHS? */ jz 2f /* yes, call restricted map */ testb $0xc0, %ah /* readonly or disable LBA? */ jz 1f2: call restricted_map1: movw 2(%bp), %ax /* get original AX */ testb %ah, %ah /* reset disk system, always succeed */ jnz 1f clc jmp int13_return/****************************************************************************/1: cmpb $0x01, %ah /* get status of last operation, always succeed */ jnz 1f xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x04, %ah /* verify sectors, always succeed */ jnz 1f xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x09, %ah /* INITIALIZE CONTROLLER WITH DRIVE PARAMETERS */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x0c, %ah /* SEEK TO CYLINDER */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x0d, %ah /* reset hard disks */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x10, %ah /* check if drive ready */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x11, %ah /* recalibrate drive */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x14, %ah /* CONTROLLER INTERNAL DIAGNOSTIC */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x05, %ah /* format track */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ /* CH=cylinder number (bits 8,9 in high bits of CL) * CL=high bits of cylinder number (bits 7,6) * DH=head number * DL=drive number */ xorb %ah, %ah /* do nothing but return success */ clc jmp int13_return/****************************************************************************/1: cmpb $0x08, %ah /* get drive parameters */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ pushw %ds xorw %ax, %ax movw %ax, %ds testb %dl, %dl /* hard drive? */ movb 0x475, %dl /* DL=number of hard drives */ js 2f /* yes, jump */ movw $0x10, %bx /* for floppy, refer to function 0x48 */ movb 0x410, %al rorb $1, %al cbw shlb $1, %al shrb $6, %al incw %ax andb %ah, %al xchgw %ax, %dx /* DL=number of floppy drives */ lesw 0x0078, %di /* point to int1E floppy parameters */2: popw %ds movw -4(%bp), %ax /* AL=Hmax, AH=Smax */ movb %al, %dh /* max head number */ andb $63, %ah movb %ah, %cl /* max sector number */ ///* simply use 1024 cylinders, hope this would work well */ //orw $0xffc0, %cx /* max cylinder number=1023 */ /* max cylinder number */ pushl %edx pushl %ecx movzbl %dh, %eax movzbl %cl, %ecx incl %eax mull %ecx /* EDX=0, EAX=sectors per cylinder */ xchgl %eax, %ecx movl -22(%bp), %eax /* S_count_Lo */ #;andb $0xfe, %al decl %eax //xorl %edx, %edx divl %ecx /* EAX=max cylinder number */ popl %ecx popl %edx movb %al, %ch /* low 8 bits of cylinder */ shlb $6, %ah /* high 2 bits of cylinder */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -