📄 asm.s
字号:
orb %ah, %cl //movb $0x08, %dl /* drives=8(HDs=8 as well as FDs=8) */ xorw %ax, %ax clc jmp int13_return/****************************************************************************/1: cmpb $0x15, %ah /* get disk type */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ testb %dl, %dl /* hard drive? */ js 2f /* yes, jump */ movb $0x02, %ah /* floppy (or other removable drive) with change-line support */ clc jmp int13_return2: movb $0x03, %ah /* hard disk */ /* CX:DX=total number of sectors */ movw -22(%bp), %dx /* lo word of S_count_Lo */ movw -20(%bp), %cx /* hi word of S_count_Lo */ #;andb $0xfe, %dl /* clear bit 0 */ clc jmp int13_return/****************************************************************************/1: cmpb $0x16, %ah jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ xorb %ah, %ah /* AH=0 means disk not changed */ /* clc */ /* signal success, CF already cleared by XOR */ jmp int13_return/****************************************************************************/1: cmpb $0x17, %ah /* set floppy type for format */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ movb $0x03, %al /* 1.44M drive, 1.44M floppy */ xorb %ah, %ah /* clc */ /* signal success, CF already cleared by XOR */ jmp int13_return/****************************************************************************/1: cmpb $0x18, %ah /* set media type for format */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */ testb %dl, %dl /* hard drive? */ js error_01_invalid pushw %ax xorw %ax, %ax movw %ax, %es movw $0x0078, %di movl %es:(%di), %eax movw %ax, %di shrl $0x10, %eax movw %ax, %es popw %ax xorb %ah, %ah /* clc */ /* signal success, CF already cleared by XOR */ jmp int13_return/****************************************************************************/1: /* Now AH is neither 0 nor 1 */ testb $0xfc, %ah /* CHS read/write sectors */ jnz 1f /* so AH is either 2(for read) or 3(for write) */ testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jnz error_01_invalid /* CDROM */#if 1 cmpw $0x0301, %ax /* is it write 1 sector? */ jne 2f cmpw $0x0001, %cx /* write to cylinder 0, sector 1? */ jne 2f cmpb $0x01, %dh /* write to head 0 or 1? */ ja 2f /* cmpw $0xaa55, %es:0x1fe(%bx) je 2f */ testb %dl, %dl js 3f /* protect hard disk head 0 and 1 */ testb %dh, %dh /* write to floppy head 0? */ jne 2f /* no, write permitted */3: #;movb -22(%bp), %ah /* lowest byte of S_count_Lo */ movb -7(%bp), %ah /* TO_S, bit 6 for fake write */ testb $0x40, %ah /* fake write here means safeboot */ jz 2f /* unsafe boot allows the write */ /* disable the write */ addw $24, %sp /* adjust SP */ popw %si popw %bp popl %eax xorb %ah, %ah /* signal write succeeded, this is a fake */ /* clc */ /* signal success, CF already cleared by XOR */ lret $2 /* far return discard the original flags */ #else /* debug only. locate windows 98 unidentified write to floppy */ pushaw movw 8(%bp), %ax movw %ax, %ds movw 6(%bp), %si subw $0x0400, %si movw %bx, %di movw $0x0400, %cx cld repz movsw movw %si, %ax movw %di, %bx subw $4, %di stosw movw %bx, %ax stosw popaw movb $4, %al/*3:*/ /*hlt*/ /* invalid write to floppy, halt the machine */ /*jmp 3b*/#endif2: cmpb $0x7F, %al /* check if sectors exceed 127 */ ja error_01_invalid testb %al, %al /* read 0 sectors not allowed */ jz error_01_invalid testb $63, %cl /* beginning sector number 0 is invalid */ jz error_01_invalid movb -3(%bp), %ah /* AH=Smax */ andb $63, %ah pushw %cx andb $63, %cl cmpb %ah, %cl /* CL should not > max sector number */ popw %cx ja error_01_invalid movb -4(%bp), %ah /* AH=Hmax */ cmpb %ah, %dh /* DH should not > max head number */ ja error_01_invalid pushw %ds pushw %cs popw %ds /* DS=CS */ movw $(EBIOS_disk_address_packet - int13_handler), %si movw $0x0010, (%si) /* Disk Address Packet length */ movb %al, 2(%si) /* number of sectors to transfer */ movw %bx, 4(%si) /* offset */ movw %es, 6(%si) /* segment */ xorl %eax, %eax /* EAX=0 */ movb %ah, 3(%si) /* sectors_hi_reserved */ movl %eax, 12(%si) /* zero out hi 32 bits */ movb %ch, %al /* cylinder number lo 8 bits */ movb %cl, %ah /* CL holds higher 2 bits */ shrb $6, %ah /* AH lower holds the 2 bits */ /* EAX=cylinder number, <1024 */ pushl %ebx /* save EBX */ xorl %ebx, %ebx /* EBX=0 */ movb -4(%bp), %bl /* BL=Hmax */ incw %bx /* EBX=total heads, <=256 */ pushl %edx mull %ebx /* EDX=0, EAX=tracks before this cylinder */ popl %edx xorw %bx, %bx /* EBX=0 */ movb %dh, %bl /* EBX=head number */ addl %ebx, %eax /* EAX=tracks before this head */ movb -3(%bp), %bl /* Max sector number */ andb $63, %bl /* EBX=sectors per track */ pushl %edx mull %ebx /* EDX=0, EAX=sectors before this head */ popl %edx movb %cl, %bl /* sector number */ andb $63, %bl decb %bl addl %ebx, %eax /* EAX=lo 32 bits of logical sector number */ movl %eax, 8(%si) popl %ebx /* restore EBX */disk_address_packet_ready: /* start-sector-number(LBA) in DAP is still for FROM_DRIVE */ call bound_check testb $0xfe, %ah /* allow all or part of sectors to tranfer */ stc jnz 3f /* no sectors to transfer, skip */ /* adjust start-sector-number(LBA) to access TO_DRIVE */ movl -14(%bp), %eax /* StartLBA_Lo */ addl %eax, 8(%si) adcl $0, 12(%si) /* set drive number(TO_DRIVE) and function number(EBIOS) */ movb -5(%bp), %dl /* DL=TO_DRIVE */ movb 3(%bp), %ah /* 0x02=read, 0x03=write */ orb $0x40, %ah /* 0x42=EXT_read, 0x43=EXT_write */ call real_int13_service /* restore original start-sector-number(in the DAP) */ pushfw pushl %eax movl -14(%bp), %eax /* StartLBA_Lo */ subl %eax, 8(%si) sbbl $0, 12(%si) popl %eax popfw jc 2f /* on error we needn't use the bound check result */ call modify_boot_sectors popfw /* use bound check info */ pushfw /* dummy push, for the following dummy pop */ jnc 4f movb $0x04, %ah /* sector not found */2: popfw /* dummy pop */ stc pushfw4: movb 2(%si), %al /* number of sectors transferred */ /* write back sectors transferred to original DAP for LBA access */ testb $0x40, 3(%bp) /* original AH */ jz 4f /* not an LBA call */ movw -2(%bp), %si /* original SI */ popfw popw %ds pushw %ds pushfw /* DS:SI -> original DAP */ movb %al, 2(%si)4: /* It is not safe to use POPW %DS for running in protected mode */ popfw /* dummy pop, skip the pushed flags */ movb -6(%bp), %dl /* restore DL(=FROM_DRIVE) */3: popw %ds jmp int13_return/****************************************************************************/1: cmpb $0x41, %ah /* EBIOS installation check */ jnz 1f cmpw $0x55aa, %bx jnz error_01_invalid// testb %dl, %dl// jns error_01_invalid movw $0xaa55, %bx movb $0x21, %ah /* major version 2.1(EDD-1.1) */ movw $0x01, %cx /* support functions 42h,43h,44h,47h,48h */ clc jmp int13_return/****************************************************************************/1: cmpb $0x42, %ah /* EBIOS read sectors */ jz 2f cmpb $0x43, %ah /* EBIOS write sectors */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jz 2f /* CDROM */ movb $0x03, %ah /* write protection */ stc /* error */ jmp int13_return2: movw -2(%bp), %si /* get old SI, disk address packet */ movl (%si), %eax /* packet length, sectors, etc. */ testb %ah, %ah jnz error_01_invalid testb $0xf0, %al jz error_01_invalid shrl $16, %eax testw $0xff80, %ax jnz error_01_invalid testb %al, %al jz error_01_invalid#if 1 /* copy disk address packet to EBIOS_disk_address_packet */ pushw %es pushw %cx pushw %di movw %cs, %ax movw %ax, %es /* ES=CS */ movw $(EBIOS_disk_address_packet - int13_handler), %di movw $8, %cx /* will copy only 16 bytes! */ cld repz movsw popw %di popw %cx popw %es /* set DS:SI */ pushw %ds movw %cs, %ax movw %ax, %ds /* DS=CS */ movw $(EBIOS_disk_address_packet - int13_handler), %si testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jz 2f shlb $2, 2(%si) movl 8(%si), %eax shldl $2, %eax, 12(%si) shll $2, 8(%si)2: jmp disk_address_packet_ready#else call bound_check testb $0xfe, %ah /* allow all or part of sectors to tranfer */ stc jnz int13_return /* no sectors to transfer, skip */ movl -14(%bp), %eax /* StartLBA_Lo */ addl %eax, 8(%si) adcl $0, 12(%si) movb -5(%bp), %dl /* DL=TO_DRIVE */ movb 3(%bp), %ah /* 0x42=read, 0x43=write */ orb $0x40, %ah /* 0x42=EXT_read, 0x43=EXT_write */ call real_int13_service jc 2f /* on error need not use the bound check */// call modify_boot_sectors popfw /* use bound check info */ pushfw /* dummy push, for the following dummy pop */ jnc 3f movb $0x04, %ah /* sector not found */2: popfw /* dummy pop */ stc pushfw3: pushl %eax movl -14(%bp), %eax /* StartLBA_Lo */ subl %eax, 8(%si) sbbl $0, 12(%si) popl %eax call modify_boot_sectors movb -6(%bp), %dl /* restore DL(=FROM_DRIVE) */ popfw /* pop the pushed Flags by bound_check */ jmp int13_return#endif/****************************************************************************/1: cmpb $0x44, %ah /* EBIOS verify sectors */ jnz 1f xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x47, %ah /* EBIOS seek */ jnz 1f xorb %ah, %ah clc jmp int13_return/****************************************************************************/1: cmpb $0x48, %ah /* EBIOS GET DRIVE PARAMETERS */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jz 2f /* normal disks */ /* CDROM */ movw -2(%bp), %si /* get old SI, extended drive parameter table */ cmpw $26, (%si) jb error_01_invalid movw $26, (%si) /* buffer length */ movw $0x00, 2(%si) # no flags movw $0x800, 24(%si) # bytes per sect=2048 xorl %eax, %eax decw %ax movl %eax, 4(%si) # cylinders=0xFFFF movb $0, %ah movl %eax, 8(%si) # heads=0xFF movb $15, %al movl %eax, 12(%si) # sectors per track=15 movl %eax, 20(%si) # total sectors hi dword=0 xorw %ax, %ax # CF cleared decl %eax # EAX=0xFFFFFFFF movl %eax, 16(%si) # total sectors lo dword # CF is cleared xorw %ax, %ax /* success, CF cleared */ jmp int13_return2: movw -2(%bp), %si /* get old SI, extended drive parameter table */ movw $26, (%si) /* buffer length */ movw $2, 2(%si) /* info */ xorl %eax, %eax movl %eax, 8(%si) /* total heads */ movl %eax, 12(%si) /* sectors per track */ movl %eax, 16(%si) /* total sectors */ movl %eax, 20(%si) /* hi 32 bits of total sectors */ pushl %ebx xorl %ebx, %ebx movw -4(%bp), %ax /* AL=Hmax, AH=Smax */ andb $63, %ah movb %ah, 12(%si) /* sectors per track */ movb %ah, %bl xorb %ah, %ah incw %ax /* total heads=Hmax+1 */ movw %ax, 8(%si) /* total heads */ pushl %edx mulw %bx /* DX:AX=product, DX=0 */ movw %ax, %bx /* BX=sectors per cylinder */ movl -22(%bp), %eax /* S_count_Lo */ #;andb $0xfe, %al movl %eax, 16(%si) /* total sectors */ xorl %edx, %edx /* EDX:EAX=64bit total sectors */ testw %bx, %bx jz 2f divl %ebx /* EAX=quotient, EDX=residue */2: testl %edx, %edx popl %edx popl %ebx jz 2f incl %eax2: movl %eax, 4(%si) /* total cylinders */ movw $512, 24(%si) /* bytes per sector */ xorb %ah, %ah /*clc*/ /* signal success, CF already cleared by XOR */ jmp int13_return/****************************************************************************/1: cmpw $0x4B01, %ax /* CDROM GET DISK EMULATION STATUS */ jnz 1f testw $0x2000, -10(%bp) /* TO_C bit 13=FROM has 2048-byte cdrom sector */ jz error_01_invalid /* normal disks have no 0x4B01 function */ /* CDROM */ pushw %es pushw %di movw -2(%bp), %di /* old SI, specification packet */ pushw %ds popw %es movw $0x0013, %ax /* packet size=13h, boot type=0 (no-emu) */ cld stosw movb %dl, %al /* drive=DL, controller=0 */ stosw pushl %cs:lba_cd_boot - int13_handler popw %ax stosw popw %ax stosw /* LBA for no-emu image */ xorw %ax, %ax stosw /* device specification */ stosw /* user buffer segment */ stosw /* load segment */ movb $4, %al stosw /* sector count=4 */ /* CHS makes no sense for no-emu */ popw %di popw %es xorb %ah, %ah /* success, CF cleared */ jmp int13_return/****************************************************************************/1:/****************************************************************************/error_01_invalid: movb $0x01, %ah /* unsupported function call */ stc /* signal error */int13_return: pushw %ax /* save status */ //pushfw //popw %ax lahf /* Load Flags into AH */ movb 10(%bp), %al shrw $1, %ax rolb $1, %al movb %al, 10(%bp) /* update flags in the stack */ movw -2(%bp), %si /* restore the original SI */ movl 2(%bp), %eax /* restore the original EAX */ movw (%bp), %bp /* restore the original BP */ popw %ax /* restore status */ addw $32, %sp /* adjust SP */ iret/****************************************************************************/bound_check: /* * check if the request exceeds the boundary of the emulated disk. * * input: DS:SI * output: AH=0 no restrictions, all sectors transferred * AH=1 sectors transferred, but not all * AH=4 error exit immediately, no sectors transferred * * if S_count=StartLBA=0, then no restrictions * else if 8(%si)>=S_count then error * else if 8(%si)+2(%si)<=S_count then no restrictions * else let 2(%si)=S_count-8(%si),call original int13,signal error * */ movl -14(%bp), %eax /* StartLBA_Lo */ testl %eax, %eax jnz 2f movl -22(%bp), %eax /* S_count_Lo */ shrl $1, %eax jnz 2f clc /* map whole drive, signal no restrictions */ popw %ax /* pop return IP */ pushfw #; push additional Flags!! pushw %ax /* push return IP */ xorb %ah, %ah /* no restrictions, all sectors transferred */ ret2: movl 12(%si), %eax /* hi 32-bit of the requested StartLBA */ testl %eax, %eax jnz 3f /* non-zero is considered `too big' */ movl -22(%bp), %eax /* S_count_Lo */ #;andb $0xfe, %al cmpl %eax, 8(%si) /* lo 32-bit of the requested StartLBA */ jb 2f3: /* all sectors exceed the bound, exit immediately */ #; Return WITHOUT additional Flags pushed!! movb $4, %ah xorb %al, %al /* no sectors transferred */ movb %al, 2(%si) /* SI+2 retrieve sectors transferred */ stc ret2: subl 8(%si), %eax pushl %ebx xorl %ebx, %ebx movw 2(%si), %bx cmpl %eax, %ebx popl %ebx ja 2f clc /* signal no restrictions */ popw %ax /* pop return IP */ pushfw #; push additional Flags!! pushw %ax /* push return IP */ xorb %ah, %ah /* no restrictions, all sectors transferred */ ret2: movb %al, 2
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -