Page 2 of 2
Posted: Thu Oct 18, 2007 10:01 am
by Combuster
would you mind putting
tags around your code. That makes everything a whole lot easier to read.
DJGPP is based off a binutils/gcc toolchain. That means it comes with the gnu assembler (as.exe). It requires you to write programs in AT&T syntax or a poor imitation of intel syntax, which is a reason for people to not use it. If you want to assemble intel syntax code you should get a separate assembler like nasm or yasm.
Re: ATA disk returning status 0x0
Posted: Sat Oct 01, 2016 1:36 am
by ch3ll0v3k
I know its old topic. Bud.... Maybe this will be usefull for some one.
Code: Select all
#define ATA_CMD_IDENT 0xEC // Identify Device
// structure returned by ATA_CMD_IDENT, as per ANSI ATA2 rev.2f spec
typedef struct {
uint16_t config; // lots of obsolete bit flags
uint16_t cyls; // "physical" cyls
uint16_t reserved2; // reserved (word 2)
uint16_t heads; // "physical" heads
uint16_t track_bytes; // unformatted bytes per track
uint16_t sector_bytes; // unformatted bytes per sector
uint16_t sectors; // "physical" sectors per track
uint16_t vendor0; // vendor unique
uint16_t vendor1; // vendor unique
uint16_t vendor2; // vendor unique
uint8_t serial_no[20]; // 0 = not_specified
uint16_t buf_type; // +2
uint16_t buf_size; // 512 byte increments; 0 = not_specified
uint16_t ecc_bytes; // for r/w long cmds; 0 = not_specified
uint8_t fw_rev[8]; // 0 = not_specified
uint8_t model[40]; // 0 = not_specified
uint8_t max_multsect; // 0=not_implemented
uint8_t vendor3; // vendor unique
uint16_t dword_io; // 0=not_implemented; 1=implemented
uint8_t vendor4; // vendor unique
uint8_t capability; // bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsu
uint16_t reserved50; // reserved (word 50)
uint8_t vendor5; // vendor unique
uint8_t tPIO; // 0=slow, 1=medium, 2=fast
uint8_t vendor6; // vendor unique
uint8_t tDMA; // 0=slow, 1=medium, 2=fast
uint16_t field_valid; // bits 0:cur_ok 1:eide_ok
uint16_t cur_cyls; // logical cylinders
uint16_t cur_heads; // logical heads
uint16_t cur_sectors; // logical sectors per track
uint16_t cur_capacity0; // logical total sectors on drive
uint16_t cur_capacity1; // (2 words, misaligned int)
uint8_t multsect; // current multiple sector count
uint8_t multsect_valid; // when (bit0==1) multsect is ok
uint32_t lba_capacity; // total number of sectors
uint16_t dma_1word; // single-word dma info
uint16_t dma_mword; // multiple-word dma info
uint16_t eide_pio_modes; // bits 0:mode3 1:mode4
uint16_t eide_dma_min; // min mword dma cycle time (ns)
uint16_t eide_dma_time; // recommended mword dma cycle time (ns)
uint16_t eide_pio; // min cycle time (ns), no IORDY
uint16_t eide_pio_iordy; // min cycle time (ns), with IORDY
uint16_t words69_70[2]; // reserved words 69-70
uint16_t words71_74[4]; // reserved words 71-74
uint16_t queue_depth; // +2
uint16_t words76_79[4]; // reserved words 76-79
uint16_t major_rev_num; // +2
uint16_t minor_rev_num; // +2
uint16_t command_set_1; // bits 0:Smart 1:Security 2:Removable 3:PM
uint16_t command_set_2; // bits 14:Smart Enabled 13:0 zero 10:lba48 suppor
uint16_t cfsse; // command set-feature supported extensions
uint16_t cfs_enable_1; // command set-feature enabled
uint16_t cfs_enable_2; // command set-feature enabled
uint16_t csf_default; // command set-feature default
uint16_t dma_ultra; // +2
uint16_t word89; // reserved (word 89)
uint16_t word90; // reserved (word 90)
uint16_t CurAPMvalues; // current APM values
uint16_t word92; // reserved (word 92)
uint16_t hw_config; // hardware config
uint16_t words94_99[6]; // reserved words 94-99
uint16_t lba48_capacity[4]; // 4 16bit values containing lba 48 total number of sectors
uint16_t words104_125[22]; // reserved words 104-125
uint16_t last_lun; // reserved (word 126)
uint16_t word127; // reserved (word 127)
uint16_t dlf; // device lock function
// 15:9 reserved
// 8 security level 1:max 0:high
// 7:6 reserved
// 5 enhanced erase
// 4 expire
// 3 frozen
// 2 locked
// 1 en/disabled
// 0 capability
uint16_t csfo; // current set features options
// 15:4 reserved
// 3 auto reassign
// 2 reverting
// 1 read-look-ahead
// 0 write cache
uint16_t words130_155[26]; // reserved vendor words 130-155
uint16_t word156; // +2
uint16_t words157_159[3]; // reserved vendor words 157-159
uint16_t words160_162[3]; // reserved words 160-162
uint16_t cf_advanced_caps; // +2
uint16_t words164_255[92]; // reserved words 164-255
} __attribute__((packed)) hd_drive_id_t;
// ******************************************************************************
while ( inb(0x1f0 + 7) != 0x58) { // check if data is ready
__asm__ __volatile__ ("nop");
}
outb(0x1f0 + 6, 0xa0); /* masterselect 0xa0 master */
outb(0x1f0 + 7, 0xEC); /* ask for data */
while ( inb(0x1f0 + 7) != 0x58) { // check if data is ready
__asm__ __volatile__ ("nop");
}
uint16_t data[256];
for (i = 0; i<256; i++) { // Read the data
data[i] = inw(0x1f0);
}
printf("--------------------------------------------------------------\n");
hd_drive_id_t HD = *((hd_drive_id_t*) data);
printf("vendor[0-6]: [%d %d %d %d %d %d] \n", HD.vendor0, HD.vendor1, HD.vendor2, HD.vendor3, HD.vendor4, HD.vendor5, HD.vendor6 ); // [ATA_IDENT] bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsu
uint8_t cp = HD.capability;
printf("capability: [%s] \n", (cp == 3) ? "IORDYsu" : (cp == 2) ? "IORDYsw" : (cp == 1) ? "LBA" : "DMA" ); // bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsu
printf("model: [%s] \n", HD.model );
printf("serial_no: [%s] \n", HD.serial_no, HD.serial_no );
printf("tDMA: [%s] \n", (HD.tDMA == 2) ? "FAST" : (HD.tDMA == 1) ? "MED" : "SLOW" ); // 0=slow, 1=medium, 2=fast
printf("cur_cyls: [%d] [0x%x] \n", HD.cur_cyls, HD.cur_cyls ); // logical cylinders
printf("cur_heads: [%d] [0x%x] \n", HD.cur_heads, HD.cur_heads ); // logical heads
printf("cur_sectors: [%d] [0x%x] \n", HD.cur_sectors, HD.cur_sectors ); // logical sectors per track
printf("cur_capacity0: [%d] [0x%x] \n", HD.cur_capacity0, HD.cur_capacity0 ); // logical total sectors on drive