Page 2 of 2

Posted: Thu Oct 18, 2007 10:01 am
by Combuster
would you mind putting

Code: Select all

...
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