//This only boots to primary IDE, unit 0 asm { #define BOOT_ADDRESS 0x040000 #define BLK_SIZE 0x200 #define LT_XSUM 0xA5CF3796 #define BOOT_HIGH_LOC ((0xA0000-2*BLK_SIZE)>>4) #define BOOT_CODE_FLOPPY 1 #define BOOT_CODE_HARDDRIVE 2 #define BOOT_CODE_CDROM 3 #define BOOT_CODE_RAM 4 #define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/ #define WIN_DEV_RESET 0x08 #define WIN_READ_NATIVE_MAX 0xF8 #define WIN_SET_MAX 0xF9 #define ERR_STAT 0x01 #define INDEX_STAT 0x02 #define ECC_STAT 0x04 /* Corrected error */ #define DRQ_STAT 0x08 #define SEEK_STAT 0x10 #define WRERR_STAT 0x20 #define READY_STAT 0x40 #define BUSY_STAT 0x80 #define BAD_R_STAT (BUSY_STAT | ERR_STAT) #define BAD_W_STAT (BAD_R_STAT | WRERR_STAT) #define BAD_STAT (BAD_R_STAT | DRQ_STAT) #define DRIVE_READY (READY_STAT | SEEK_STAT) #define DATA_READY (DRQ_STAT) #define IDE_BASE0 0x1F0 #define IDE_BASE1 0x3F6 #define IDE_DATA_REG (IDE_BASE0+0) #define IDE_FEATURE_REG (IDE_BASE0+1) #define IDE_NSECTOR_REG (IDE_BASE0+2) #define IDE_SECTOR_REG (IDE_BASE0+3) #define IDE_LCYL_REG (IDE_BASE0+4) #define IDE_HCYL_REG (IDE_BASE0+5) #define IDE_SELECT_REG (IDE_BASE0+6) #define IDE_STATUS (IDE_BASE0+7) #define IDE_CMD (IDE_BASE0+7) #define IDE_CONTROL_REG (IDE_BASE1+0) USE16 BHD2_START:: DU1 32 DUP(0); BHD2_CODE:: CLI CLD MOV AX,BOOT_HIGH_LOC MOV SS,AX MOV ES,AX MOV SP,2*BLK_SIZE CALL U2 GET_IP GET_IP: POP BX SUB BX,GET_IP SHR BX,4 MOV AX,CS //COPY HIGH ADD AX,BX MOV DS,AX MOV CX,BLK_SIZE XOR SI,SI XOR DI,DI REP_MOVSB DU1 0xEA; DU2 BHD2_HISTART,BOOT_HIGH_LOC; BHD2_WAIT_BUSY: MOV DX,IDE_STATUS IN AL,DX AND AL,BUSY_STAT JNZ BHD2_WAIT_BUSY RET BHD2_ATA_CMD: PUSH AX MOV DX,IDE_FEATURE_REG XOR AL,AL OUT DX,AL POP AX MOV DX,IDE_CMD OUT DX,AL RET BHD2_SELECT: MOV DX,IDE_SELECT_REG MOV AL,0xE0 //Unit 0 OUT DX,AL RET BHD2_BLK:: DU4 ?; BHD2_HISTART: //Init Drive CALL BHD2_SELECT MOV AL,WIN_DEV_RESET CALL BHD2_ATA_CMD CALL BHD2_WAIT_BUSY CALL BHD2_SELECT MOV AL,WIN_READ_NATIVE_MAX CALL BHD2_ATA_CMD CALL BHD2_WAIT_BUSY MOV DX,IDE_CONTROL_REG MOV AL,8 OUT DX,AL MOV DX,IDE_SECTOR_REG XOR AL,AL OUT DX,AL MOV DX,IDE_NSECTOR_REG OUT DX,AL MOV DX,IDE_LCYL_REG OUT DX,AL MOV DX,IDE_HCYL_REG OUT DX,AL MOV DX,IDE_SELECT_REG OR AL,0xEF //Unit 0 OUT DX,AL MOV AL,WIN_SET_MAX CALL BHD2_ATA_CMD CALL BHD2_WAIT_BUSY BHD2_RESTART:: MOV CX,512 //Gets patched MOV AX,BOOT_ADDRESS/16 MOV ES,AX @@1: XOR DI,DI PUSH CX //READ BLK MOV DX,IDE_CONTROL_REG MOV AL,8 OUT DX,AL MOV DX,IDE_SECTOR_REG MOV AL,U1 [BHD2_BLK] OUT DX,AL MOV DX,IDE_NSECTOR_REG MOV AL,1 //Blk Cnt OUT DX,AL MOV DX,IDE_LCYL_REG MOV AL,U1 [BHD2_BLK+1] OUT DX,AL MOV DX,IDE_HCYL_REG MOV AL,U1 [BHD2_BLK+2] OUT DX,AL MOV DX,IDE_SELECT_REG MOV AL,U1 [BHD2_BLK+3] OR AL,0xE0 //Unit 0 OUT DX,AL MOV AL,WIN_MULTREAD CALL BHD2_ATA_CMD MOV DX,IDE_STATUS @@10: IN AL,DX AND AL,DATA_READY JZ @@10 MOV CX,BLK_SIZE/2 MOV DX,IDE_DATA_REG REP_INSW CALL BHD2_WAIT_BUSY POP CX INC U4 [BHD2_BLK] MOV AX,ES ADD AX,BLK_SIZE/16 MOV ES,AX LOOP @@1 MOV EBX,BOOT_CODE_HARDDRIVE DU1 0xEA; BHD2_JMP_START:: DU2 0,BOOT_ADDRESS/16; BHD2_END:: END }