Subversion Repositories pentevo

Rev

Blame | Last modification | View Log | Download | RSS feed | ?url?

  1. #include "std.h"
  2.  
  3. #include "emul.h"
  4. #include "vars.h"
  5.  
  6. #include "util.h"
  7.  
  8. //#define DUMP_HDD_IO 1
  9.  
  10. const unsigned MAX_DEVICES = MAX_PHYS_HD_DRIVES+2*MAX_PHYS_CD_DRIVES;
  11.  
  12. PHYS_DEVICE phys[MAX_DEVICES];
  13. unsigned n_phys = 0;
  14.  
  15. /*
  16. // this function is untested
  17. void ATA_DEVICE::exec_mode_select()
  18. {
  19.    intrq = 1;
  20.    command_ok();
  21.  
  22.    struct {
  23.       SCSI_PASS_THROUGH_DIRECT p;
  24.       unsigned char sense[0x40];
  25.    } srb = { 0 }, dst;
  26.  
  27.    srb.p.Length = sizeof(SCSI_PASS_THROUGH_DIRECT);
  28.    *(CDB*)&srb.p.Cdb = cdb;
  29.    srb.p.CdbLength = sizeof(CDB);
  30.    srb.p.DataIn = SCSI_IOCTL_DATA_OUT;
  31.    srb.p.TimeOutValue = 10;
  32.    srb.p.DataBuffer = transbf;
  33.    srb.p.DataTransferLength = transcount;
  34.    srb.p.SenseInfoLength = sizeof(srb.sense);
  35.    srb.p.SenseInfoOffset = sizeof(SCSI_PASS_THROUGH_DIRECT);
  36.  
  37.    DWORD outsize;
  38.    int r = DeviceIoControl(hDevice, IOCTL_SCSI_PASS_THROUGH_DIRECT,
  39.                            &srb.p, sizeof(srb.p),
  40.                            &dst, sizeof(dst),
  41.                            &outsize, 0);
  42.  
  43.    if (!r) return;
  44.    if (senselen = dst.p.SenseInfoLength) memcpy(sense, dst.sense, senselen);
  45.    return;
  46. }
  47. */
  48.  
  49. void init_hdd_cd()
  50. {
  51.    memset(&phys, 0, sizeof phys);
  52.    if (conf.ide_skip_real)
  53.        return;
  54.  
  55.    n_phys = 0;
  56.    n_phys = ATA_PASSER::identify(phys + n_phys, MAX_DEVICES - n_phys);
  57.    n_phys += ATAPI_PASSER::identify(phys + n_phys, MAX_DEVICES - n_phys);
  58.  
  59.    if (!n_phys)
  60.        errmsg("HDD/CD emulator can't access physical drives");
  61. }
  62.  
  63. static void delstr_spaces(char *dst, char *src)
  64. {
  65.    for (; *src; src++)
  66.       if (*src != ' ') *dst++ = *src;
  67.    *dst = 0;
  68. }
  69.  
  70. unsigned find_hdd_device(char *name)
  71. {
  72.    char s2[512];
  73.    delstr_spaces(s2, name);
  74. //   if(temp.win9x)
  75.    for (unsigned drive = 0; drive < n_phys; drive++)
  76.    {
  77.       char s1[512];
  78.       delstr_spaces(s1, phys[drive].viewname);
  79.       if (!stricmp(s1,s2))
  80.           return drive;
  81.    }
  82.    return -1U;
  83. }
  84.  
  85. void ATA_DEVICE::configure(IDE_CONFIG *cfg)
  86. {
  87.    atapi_p.close(); ata_p.close();
  88.  
  89.    c = cfg->c; h = cfg->h; s = cfg->s; lba = cfg->lba; readonly = cfg->readonly;
  90.  
  91.    memset(&reg, 0, sizeof(reg)); // ╬ўш∙рхь ЁхушёЄЁ√
  92.    command_ok(); // ╤сЁрё√трхь ёюёЄю эшх ш яючшЎш■ яхЁхфрўш фрээ√ї
  93.  
  94.    phys_dev = -1U;
  95.    if (!*cfg->image)
  96.        return;
  97.  
  98.    PHYS_DEVICE filedev, *dev;
  99.    phys_dev = find_hdd_device(cfg->image);
  100.    if (phys_dev == -1U)
  101.    {
  102.       if (cfg->image[0] == '<')
  103.       {
  104.           errmsg("no physical device %s", cfg->image);
  105.           *cfg->image = 0;
  106.           return;
  107.       }
  108.       strcpy(filedev.filename, cfg->image);
  109.       filedev.type = cfg->cd ? ATA_FILECD : ATA_FILEHDD;
  110.       dev = &filedev;
  111.    }
  112.    else
  113.    {
  114.       dev = &phys[phys_dev];
  115.       if (dev->type == ATA_NTHDD)
  116.       {
  117.          // read geometry from id sector
  118.          c = *(unsigned short*)(phys[phys_dev].idsector+2);
  119.          h = *(unsigned short*)(phys[phys_dev].idsector+6);
  120.          s = *(unsigned short*)(phys[phys_dev].idsector+12);
  121.          lba = *(unsigned*)(phys[phys_dev].idsector+0x78); // lba28
  122.          if(*((u16*)(phys[phys_dev].idsector+83*2)) & (1<<10))
  123.          {
  124.              lba = *(u64*)(phys[phys_dev].idsector+100*2); // lba48
  125.          }
  126.          if (!lba)
  127.              lba = c*h*s;
  128.       }
  129.    }
  130.    DWORD errcode = ERROR_DEVICE_NOT_AVAILABLE;
  131.    if (dev->type == ATA_NTHDD || dev->type == ATA_FILEHDD)
  132.    {
  133.        dev->usage = ATA_OP_USE;
  134.        errcode = ata_p.open(dev);
  135.        atapi = 0;
  136.    }
  137.  
  138.    if (dev->type == ATA_SPTI_CD || dev->type == ATA_ASPI_CD || dev->type == ATA_FILECD)
  139.    {
  140.        dev->usage = ATA_OP_USE;
  141.        errcode = atapi_p.open(dev);
  142.        atapi = 1;
  143.    }
  144.  
  145.    if (errcode == NO_ERROR)
  146.        return;
  147.    errmsg("failed to open %s", cfg->image);
  148.    err_win32(errcode);
  149.    *cfg->image = 0;
  150. }
  151.  
  152. void ATA_PORT::reset()
  153. {
  154.    dev[0].reset(ATA_DEVICE::RESET_HARD);
  155.    dev[1].reset(ATA_DEVICE::RESET_HARD);
  156. }
  157.  
  158. unsigned char ATA_PORT::read(unsigned n_reg)
  159. {
  160.    u8 val1 = dev[0].read(n_reg);
  161.    u8 val2 = dev[1].read(n_reg);
  162.  
  163.    unsigned devs = 0;
  164.    devs |= (dev[0].loaded() ? 1 : 0);
  165.    devs |= (dev[1].loaded() ? 2 : 0);
  166.  
  167.    u8 val = 0xFF;
  168.    switch(devs)
  169.    {
  170.    case 1: val = val1; break;
  171.    case 2: val = val2; break;
  172.    case 3: val = dev[0].selected() ? val1 : val2; break;
  173.    }
  174.  
  175. #ifdef DUMP_HDD_IO
  176.    printf("R%X:%02X ", n_reg, val);
  177. #endif
  178.    return val;
  179. }
  180.  
  181. unsigned ATA_PORT::read_data()
  182. {
  183. #ifdef DUMP_HDD_IO
  184.    unsigned val = dev[0].read_data() & dev[1].read_data();
  185.    printf("r%04X ", val & 0xFFFF);
  186.    return val;
  187. #endif
  188.    return dev[0].read_data() & dev[1].read_data();
  189. }
  190.  
  191. void ATA_PORT::write(unsigned n_reg, unsigned char data)
  192. {
  193. #ifdef DUMP_HDD_IO
  194.    printf("R%X=%02X ", n_reg, data);
  195. #endif
  196.    dev[0].write(n_reg, data);
  197.    dev[1].write(n_reg, data);
  198. }
  199.  
  200. void ATA_PORT::write_data(unsigned data)
  201. {
  202. #ifdef DUMP_HDD_IO
  203.    printf("w%04X ", data & 0xFFFF);
  204. #endif
  205.    dev[0].write_data(data);
  206.    dev[1].write_data(data);
  207. }
  208.  
  209. unsigned char ATA_PORT::read_intrq()
  210. {
  211. #ifdef DUMP_HDD_IO
  212. unsigned char i = dev[0].read_intrq() & dev[1].read_intrq(); printf("i%d ", !!i); return i;
  213. #endif
  214.    return dev[0].read_intrq() & dev[1].read_intrq();
  215. }
  216.  
  217. void ATA_DEVICE::reset_signature(RESET_TYPE mode)
  218. {
  219.    reg.count = reg.sec = 1;
  220.    reg.err = 1;
  221.    reg.cyl = atapi ? 0xEB14 : 0;
  222.    reg.devhead |= 0x50;
  223.    reg.devhead &= (atapi && mode == RESET_SOFT) ? 0x10 : 0;
  224.    reg.status = (mode == RESET_SOFT || !atapi) ? STATUS_DRDY | STATUS_DSC : 0;
  225. }
  226.  
  227. void ATA_DEVICE::reset(RESET_TYPE mode)
  228. {
  229.    reg.control = 0; // clear SRST
  230.    intrq = 0;
  231.    regs_sel = 0;
  232.  
  233.    command_ok();
  234.    reset_signature(mode);
  235. }
  236.  
  237. void ATA_DEVICE::command_ok()
  238. {
  239.    state = S_IDLE;
  240.    transptr = -1U;
  241.    reg.err = 0;
  242.    reg.status = STATUS_DRDY | STATUS_DSC;
  243. }
  244.  
  245. unsigned char ATA_DEVICE::read_intrq()
  246. {
  247.    if (!loaded() || ((reg.devhead ^ device_id) & 0x10) || (reg.control & CONTROL_nIEN)) return 0xFF;
  248.    return intrq? 0xFF : 0x00;
  249. }
  250.  
  251. unsigned char ATA_DEVICE::read(unsigned n_reg)
  252. {
  253.    if (!loaded())
  254.        return 0xFF;
  255.  
  256. /*
  257.    if ((reg.devhead ^ device_id) & 0x10)
  258.    {
  259.        return 0xFF;
  260.    }
  261. */
  262.  
  263.    if (n_reg == 7)
  264.        intrq = 0;
  265.    if (n_reg == 8)
  266.        n_reg = 7; // read alt.status -> read status
  267.  
  268.    if ((n_reg == 7) && ((reg.devhead ^ device_id) & 0x10))
  269.    {
  270.        return 0;
  271.    }
  272.  
  273.    if (n_reg == 7 || (reg.status & STATUS_BSY))
  274.    {
  275. //         printf("state=%d\n",state); //Alone Coder
  276.            return reg.status;
  277.    } // BSY=1 or read status
  278.    // BSY = 0
  279.    //// if (reg.status & STATUS_DRQ) return 0xFF;    // DRQ.  ATA-5: registers should not be queried while DRQ=1, but programs do this!
  280.  
  281.    update_regs();
  282.    // DRQ = 0
  283.    unsigned sel = regs_sel;
  284.    if(lba > 0xFFFFFFFULL)
  285.    { // lba48
  286.        sel ^= (reg.control & CONTROL_HOB) ? 1 : 0;
  287.    }
  288.  
  289.    return *regs_r[sel][n_reg];
  290. }
  291.  
  292. unsigned ATA_DEVICE::read_data()
  293. {
  294.    if (!loaded())
  295.        return 0xFFFFFFFF;
  296.    if ((reg.devhead ^ device_id) & 0x10)
  297.        return 0xFFFFFFFF;
  298.    if (/* (reg.status & (STATUS_DRQ | STATUS_BSY)) != STATUS_DRQ ||*/ transptr >= transcount)
  299.        return 0xFFFFFFFF;
  300.  
  301.    // DRQ=1, BSY=0, data present
  302.    unsigned result = *(unsigned*)(transbf + transptr*2);
  303.    transptr++;
  304. //   printf(__FUNCTION__" data=0x%04X\n", result & 0xFFFF);
  305.  
  306.    if (transptr < transcount)
  307.        return result;
  308.    // look to state, prepare next block
  309.    if (state == S_READ_ID || state == S_READ_ATAPI)
  310.        command_ok();
  311.    if (state == S_READ_SECTORS)
  312.    {
  313. //       __debugbreak();
  314. //       printf("dev=%d, cnt=%d\n", device_id, reg.count);
  315.        if(!--reg.count)
  316.            command_ok();
  317.        else
  318.        {
  319.            next_sector();
  320.            read_sectors();
  321.        }
  322.    }
  323.  
  324.    return result;
  325. }
  326.  
  327. char ATA_DEVICE::exec_ata_cmd(unsigned char cmd)
  328. {
  329. //   printf(__FUNCTION__" cmd=%02X\n", cmd);
  330.    // EXECUTE DEVICE DIAGNOSTIC for both ATA and ATAPI
  331.    if (cmd == 0x90)
  332.    {
  333.        reset_signature(RESET_SOFT);
  334.        return 1;
  335.    }
  336.  
  337.    if (atapi)
  338.        return 0;
  339.  
  340.    // INITIALIZE DEVICE PARAMETERS
  341.    if (cmd == 0x91)
  342.    {
  343.      // pos = (reg.cyl * h + (reg.devhead & 0x0F)) * s + reg.sec - 1;
  344.      h = (reg.devhead & 0xF) + 1;
  345.      s = reg.count;
  346.      if(s == 0)
  347.      {
  348.           reg.status = STATUS_DRDY | STATUS_DF | STATUS_DSC | STATUS_ERR;
  349.           return 1;
  350.      }
  351.  
  352.      c = unsigned(lba / s / h);
  353.  
  354.      reg.status = STATUS_DRDY | STATUS_DSC;
  355.      return 1;
  356.    }
  357.  
  358.    if ((cmd & 0xFE) == 0x20) // ATA-3 (mandatory), read sectors (20-w-retr/21-wo-retr)
  359.    { // cmd #21 obsolette, rqd for is-dos
  360. //       printf(__FUNCTION__" sec_cnt=%d\n", reg.count);
  361. //       __debugbreak();
  362.        read_sectors();
  363.        return 1;
  364.    }
  365.  
  366.    if ((cmd == 0x24) && (lba > 0xFFFFFFFULL)) // ATA-6 read sectors ext (lba48)
  367.    {
  368.        read_sectors();
  369.        return 1;
  370.    }
  371.  
  372.  
  373.    if((cmd & 0xFE) == 0x40) // ATA-3 (mandatory),  verify sectors
  374.    { //rqd for is-dos
  375.        verify_sectors();
  376.        return 1;
  377.    }
  378.  
  379.    if ((cmd == 0x42) && (lba > 0xFFFFFFFULL)) // ATA-6 verify sectors ext (lba48)
  380.    {
  381.        verify_sectors();
  382.        return 1;
  383.    }
  384.  
  385.    if ((cmd & 0xFE) == 0x30 && !readonly) // ATA-3 (mandatory), write sectors (30-w-retr,31-wo-retr)
  386.    {
  387.       if (seek())
  388.       {
  389.           state = S_WRITE_SECTORS;
  390.           reg.status = STATUS_DRQ | STATUS_DSC;
  391.           transptr = 0;
  392.           transcount = 0x100;
  393.       }
  394.       return 1;
  395.    }
  396.  
  397.    if ((cmd == 0x34) && (lba > 0xFFFFFFFULL) && !readonly) // ATA-6 write sectors ext (lba48)
  398.    {
  399.       if (seek())
  400.       {
  401.           state = S_WRITE_SECTORS;
  402.           reg.status = STATUS_DRQ | STATUS_DSC;
  403.           transptr = 0;
  404.           transcount = 0x100;
  405.       }
  406.       return 1;
  407.    }
  408.  
  409.    if(cmd == 0x50) // format track (фрээр  ЁхрышчрЎш  - эшўхую эх фхырхЄ)
  410.    {
  411.       reg.sec = 1;
  412.       if (seek())
  413.       {
  414.           state = S_FORMAT_TRACK;
  415.           reg.status = STATUS_DRQ | STATUS_DSC;
  416.           transptr = 0;
  417.           transcount = 0x100;
  418.       }
  419.       return 1;
  420.    }
  421.  
  422.    if (cmd == 0xEC)
  423.    {
  424.        prepare_id();
  425.        return 1;
  426.    }
  427.  
  428.    if (cmd == 0xE7)
  429.    { // FLUSH CACHE
  430.       if (ata_p.flush())
  431.       {
  432.           command_ok();
  433.           intrq = 1;
  434.       }
  435.       else
  436.           reg.status = STATUS_DRDY | STATUS_DF | STATUS_DSC | STATUS_ERR; // 0x71
  437.       return 1;
  438.    }
  439.  
  440.    if (cmd == 0x10)
  441.    {
  442.       recalibrate();
  443.       command_ok();
  444.       intrq = 1;
  445.       return 1;
  446.    }
  447.  
  448.    if (cmd == 0x70)
  449.    { // seek
  450.       if (!seek())
  451.           return 1;
  452.       command_ok();
  453.       intrq = 1;
  454.       return 1;
  455.    }
  456.  
  457.    printf("*** unknown ata cmd %02X ***\n", cmd);
  458.  
  459.    return 0;
  460. }
  461.  
  462. char ATA_DEVICE::exec_atapi_cmd(unsigned char cmd)
  463. {
  464.    if (!atapi)
  465.        return 0;
  466.  
  467.    // soft reset
  468.    if (cmd == 0x08)
  469.    {
  470.        reset(RESET_SOFT);
  471.        return 1;
  472.    }
  473.    if (cmd == 0xA1) // IDENTIFY PACKET DEVICE
  474.    {
  475.        prepare_id();
  476.        return 1;
  477.    }
  478.  
  479.    if (cmd == 0xA0)
  480.    { // packet
  481.       state = S_RECV_PACKET;
  482.       reg.status = STATUS_DRQ;
  483.       reg.intreason = INT_COD;
  484.       transptr = 0;
  485.       transcount = 6;
  486.       return 1;
  487.    }
  488.  
  489.    if (cmd == 0xEC)
  490.    {
  491.        reg.count = 1;
  492.        reg.sec = 1;
  493.        reg.cyl = 0xEB14;
  494.  
  495.        reg.status = STATUS_DSC | STATUS_DRDY | STATUS_ERR;
  496.        reg.err = ERR_ABRT;
  497.        state = S_IDLE;
  498.        intrq = 1;
  499.        return 1;
  500.    }
  501.  
  502.    printf("*** unknown atapi cmd %02X ***\n", cmd);
  503.    // "command aborted" with ATAPI signature
  504.    reg.count = 1;
  505.    reg.sec = 1;
  506.    reg.cyl = 0xEB14;
  507.    return 0;
  508. }
  509.  
  510. void ATA_DEVICE::write(unsigned n_reg, unsigned char data)
  511. {
  512. //   printf("dev=%d, reg=%d, data=%02X\n", device_id, n_reg, data);
  513.    if (!loaded())
  514.        return;
  515.  
  516.    reg.control &= ~CONTROL_HOB;
  517.  
  518.    if (n_reg == 1)
  519.    {
  520.        reg.feat = data;
  521.        return;
  522.    }
  523.  
  524.    if (n_reg != 7) // ═х ЁхушёЄЁ ъюьрэф
  525.    {
  526.       *regs_w[regs_sel][n_reg] = data;
  527.       regs_sel ^= (lba > 0xFFFFFFFULL) ? 1 : 0;
  528.  
  529.       update_cur();
  530.  
  531.       if (reg.control & CONTROL_SRST)
  532.       {
  533. //          printf("dev=%d, reset\n", device_id);
  534.           reset(RESET_SRST);
  535.       }
  536.       return;
  537.    }
  538.  
  539.    // execute command!
  540.    if (((reg.devhead ^ device_id) & 0x10) && data != 0x90)
  541.        return;
  542.    if (!(reg.status & STATUS_DRDY) && !atapi)
  543.    {
  544.        printf("warning: hdd not ready cmd = %02X (ignored)\n", data);
  545.        return;
  546.    }
  547.  
  548.    reg.err = 0; intrq = 0;
  549.  
  550. //{printf(" [");for (int q=1;q<9;q++) printf("-%02X",regs[q]);printf("]\n");}
  551.    if (exec_atapi_cmd(data))
  552.        return;
  553.    if (exec_ata_cmd(data))
  554.        return;
  555.    reg.status = STATUS_DSC | STATUS_DRDY | STATUS_ERR;
  556.    reg.err = ERR_ABRT;
  557.    state = S_IDLE; intrq = 1;
  558. }
  559.  
  560. void ATA_DEVICE::write_data(unsigned data)
  561. {
  562.    if (!loaded()) return;
  563.    if ((reg.devhead ^ device_id) & 0x10)
  564.        return;
  565.    if (/* (reg.status & (STATUS_DRQ | STATUS_BSY)) != STATUS_DRQ ||*/ transptr >= transcount)
  566.        return;
  567.    *(unsigned short*)(transbf + transptr*2) = (unsigned short)data; transptr++;
  568.    if (transptr < transcount)
  569.        return;
  570.    // look to state, prepare next block
  571.    if (state == S_WRITE_SECTORS)
  572.    {
  573.        write_sectors();
  574.        return;
  575.    }
  576.  
  577.    if (state == S_FORMAT_TRACK)
  578.    {
  579.        format_track();
  580.        return;
  581.    }
  582.  
  583.    if (state == S_RECV_PACKET)
  584.    {
  585.        handle_atapi_packet();
  586.        return;
  587.    }
  588. /*   if (state == S_MODE_SELECT) { exec_mode_select(); return; } */
  589. }
  590.  
  591. char ATA_DEVICE::seek()
  592. {
  593.    u64 pos;
  594.    if (reg.devhead & 0x40)
  595.    {
  596.       pos = lba_cur;
  597.       if (lba_cur >= lba)
  598.       {
  599. //          printf("seek error: lba %I64u:%I64u\n", lba, pos);
  600.  
  601.           seek_err:
  602.           reg.status = STATUS_DRDY | STATUS_DF | STATUS_ERR;
  603.           reg.err = ERR_IDNF | ERR_ABRT;
  604.           intrq = 1;
  605.           return 0;
  606.       }
  607. //      printf("lba %I64u:%I64u\n", lba, pos);
  608.    }
  609.    else
  610.    {
  611.       if (c_cur >= c || h_cur >= h || s_cur > s || s_cur == 0)
  612.       {
  613. //          printf("seek error: chs %4d/%02d/%02d\n", c_cur,  h_cur, s_cur);
  614.           goto seek_err;
  615.       }
  616.       pos = (c_cur * h + h_cur) * s + s_cur - 1;
  617. //      printf("chs %4d/%02d/%02d: %I64u\n", c_cur,  h_cur, s_cur, pos);
  618.    }
  619. //printf("[seek %I64u]", pos << 9);
  620.    if (!ata_p.seek(pos))
  621.    {
  622.       reg.status = STATUS_DRDY | STATUS_DF | STATUS_ERR;
  623.       reg.err = ERR_IDNF | ERR_ABRT;
  624.       intrq = 1;
  625.       return 0;
  626.    }
  627.    return 1;
  628. }
  629.  
  630. void ATA_DEVICE::format_track()
  631. {
  632.    intrq = 1;
  633.    if(!seek())
  634.        return;
  635.  
  636.    command_ok();
  637.    return;
  638. }
  639.  
  640. void ATA_DEVICE::write_sectors()
  641. {
  642.    intrq = 1;
  643. //printf(" [write] ");
  644.    if(!seek())
  645.        return;
  646.  
  647.    if (!ata_p.write_sector(transbf))
  648.    {
  649.       reg.status = STATUS_DRDY | STATUS_DSC | STATUS_ERR;
  650.       reg.err = ERR_UNC;
  651.       state = S_IDLE;
  652.       return;
  653.    }
  654.  
  655.    if (!--reg.count)
  656.    {
  657.        command_ok();
  658.        return;
  659.    }
  660.    next_sector();
  661.  
  662.    transptr = 0; transcount = 0x100;
  663.    state = S_WRITE_SECTORS;
  664.    reg.err = 0;
  665.    reg.status = STATUS_DRQ | STATUS_DSC;
  666. }
  667.  
  668. void ATA_DEVICE::read_sectors()
  669. {
  670. //   __debugbreak();
  671.    intrq = 1;
  672.    if (!seek())
  673.       return;
  674.  
  675.    if (!ata_p.read_sector(transbf))
  676.    {
  677.       reg.status = STATUS_DRDY | STATUS_DSC | STATUS_ERR;
  678.       reg.err = ERR_UNC | ERR_IDNF;
  679.       state = S_IDLE;
  680.       return;
  681.    }
  682.    transptr = 0;
  683.    transcount = 0x100;
  684.    state = S_READ_SECTORS;
  685.    reg.err = 0;
  686.    reg.status = STATUS_DRDY | STATUS_DRQ | STATUS_DSC;
  687.  
  688. /*
  689.    if(reg.devhead & 0x40)
  690.        printf("dev=%d lba=%d\n", device_id, *(unsigned*)(regs+3) & 0x0FFFFFFF);
  691.    else
  692.        printf("dev=%d c/h/s=%d/%d/%d\n", device_id, reg.cyl, (reg.devhead & 0xF), reg.sec);
  693. */
  694. }
  695.  
  696. void ATA_DEVICE::verify_sectors()
  697. {
  698.    intrq = 1;
  699. //   __debugbreak();
  700.  
  701.    do
  702.    {
  703.        --n_cur;
  704. /*
  705.        if(reg.devhead & 0x40)
  706.            printf("lba=%d\n", *(unsigned*)(regs+3) & 0x0FFFFFFF);
  707.        else
  708.            printf("c/h/s=%d/%d/%d\n", reg.cyl, (reg.devhead & 0xF), reg.sec);
  709. */
  710.        if (!seek())
  711.            return;
  712. /*
  713.        u8 Buf[512];
  714.        if (!ata_p.read_sector(Buf))
  715.        {
  716.           reg.status = STATUS_DRDY | STATUS_DF | STATUS_CORR | STATUS_DSC | STATUS_ERR;
  717.           reg.err = ERR_UNC | ERR_IDNF | ERR_ABRT | ERR_AMNF;
  718.           state = S_IDLE;
  719.           return;
  720.        }
  721. */
  722.        if(n_cur)
  723.            next_sector();
  724.    }while(n_cur);
  725.    command_ok();
  726. }
  727.  
  728. void ATA_DEVICE::next_sector()
  729. {
  730.    if (reg.devhead & 0x40)
  731.    { // LBA
  732.       lba_cur++;
  733.       return;
  734.    }
  735.    // need to recalc CHS for every sector, coz ATA registers
  736.    // should contain current position on failure
  737.    if (s_cur < s)
  738.    {
  739.        s_cur++;
  740.        return;
  741.    }
  742.    s_cur = 1;
  743.  
  744.    if (++h_cur < h)
  745.    {
  746.        return;
  747.    }
  748.    h_cur = 0;
  749.    c_cur++;
  750. }
  751.  
  752. void ATA_DEVICE::recalibrate()
  753. {
  754.    lba_cur = 0;
  755.    c_cur = 0;
  756.    h_cur = 0;
  757.    s_cur = 1;
  758.  
  759.    reg.cyl = 0;
  760.    reg.devhead &= 0xF0;
  761.  
  762.    if (reg.devhead & 0x40) // LBA
  763.    {
  764.       reg.sec = 0;
  765.       return;
  766.    }
  767.  
  768.    reg.sec = 1;
  769. }
  770.  
  771. #define TOC_DATA_TRACK          0x04
  772.  
  773. // [vv] ╨рсюЄр ё Їрщыюь - юсЁрчюь фшёър эряЁ ьє■
  774. void ATA_DEVICE::handle_atapi_packet_emulate()
  775. {
  776. //    printf("%s\n", __FUNCTION__);
  777.     memcpy(&atapi_p.cdb, transbf, 12);
  778.  
  779.     switch(atapi_p.cdb.CDB12.OperationCode)
  780.     {
  781.     case SCSIOP_TEST_UNIT_READY:; // 6
  782.           command_ok();
  783.           return;
  784.  
  785.     case SCSIOP_READ:; // 10
  786.     {
  787.       unsigned cnt = (u32(atapi_p.cdb.CDB10.TransferBlocksMsb) << 8) | atapi_p.cdb.CDB10.TransferBlocksLsb;
  788.       unsigned pos = (u32(atapi_p.cdb.CDB10.LogicalBlockByte0) << 24) |
  789.                      (u32(atapi_p.cdb.CDB10.LogicalBlockByte1) << 16) |
  790.                      (u32(atapi_p.cdb.CDB10.LogicalBlockByte2) << 8) |
  791.                      atapi_p.cdb.CDB10.LogicalBlockByte3;
  792.  
  793.       if(cnt * 2048 > sizeof(transbf))
  794.       {
  795.           reg.status = STATUS_DRDY | STATUS_DSC | STATUS_ERR;
  796.           reg.err = ERR_UNC | ERR_IDNF;
  797.           state = S_IDLE;
  798.           return;
  799.       }
  800.  
  801.       for(unsigned i = 0; i < cnt; i++, pos++)
  802.       {
  803.           if (!atapi_p.seek(pos))
  804.           {
  805.              reg.status = STATUS_DRDY | STATUS_DSC | STATUS_ERR;
  806.              reg.err = ERR_UNC | ERR_IDNF;
  807.              state = S_IDLE;
  808.              return;
  809.           }
  810.  
  811.           if (!atapi_p.read_sector(transbf + i * 2048))
  812.           {
  813.              reg.status = STATUS_DRDY | STATUS_DSC | STATUS_ERR;
  814.              reg.err = ERR_UNC | ERR_IDNF;
  815.              state = S_IDLE;
  816.              return;
  817.           }
  818.       }
  819.       intrq = 1;
  820.       reg.atapi_count = u16(cnt * 2048);
  821.       reg.intreason = INT_IO;
  822.       reg.status = STATUS_DRQ;
  823.       transcount = (cnt * 2048)/2;
  824.       transptr = 0;
  825.       state = S_READ_ATAPI;
  826.       return;
  827.     }
  828.  
  829.     case SCSIOP_READ_TOC:; // 10
  830.     {
  831.       static const u8 TOC_DATA[] =
  832.       {
  833.         0, 4+8*2 - 2, 1, 0xAA,
  834.         0, TOC_DATA_TRACK, 1, 0, 0, 0, 0, 0,
  835.         0, TOC_DATA_TRACK, 0xAA, 0, 0, 0, 0, 0,
  836.       };
  837.       unsigned len = sizeof(TOC_DATA);
  838.       memcpy(transbf, TOC_DATA, len);
  839.       reg.atapi_count = u16(len);
  840.       reg.intreason = INT_IO;
  841.       reg.status = STATUS_DRQ;
  842.       transcount = (len + 1)/2;
  843.       transptr = 0;
  844.       state = S_READ_ATAPI;
  845.       return;
  846.     }
  847.     case SCSIOP_START_STOP_UNIT:; // 10
  848.           command_ok();
  849.           return;
  850.  
  851.     case SCSIOP_SET_CD_SPEED:; // 12
  852.           command_ok();
  853.           return;
  854.     }
  855.  
  856.     printf("*** unknown scsi cmd %02X ***\n", atapi_p.cdb.CDB12.OperationCode);
  857.  
  858.     reg.err = 0;
  859.     state = S_IDLE;
  860.     reg.status = STATUS_DSC | STATUS_ERR | STATUS_DRDY;
  861. }
  862.  
  863. void ATA_DEVICE::handle_atapi_packet()
  864. {
  865. #if defined(DUMP_HDD_IO)
  866.    {
  867.        printf(" [packet");
  868.        for (int i = 0; i < 12; i++)
  869.            printf("-%02X", transbf[i]);
  870.        printf("]\n");
  871.    }
  872. #endif
  873.    if(phys_dev == -1U)
  874.        return handle_atapi_packet_emulate();
  875.  
  876.    memcpy(&atapi_p.cdb, transbf, 12);
  877.  
  878.    intrq = 1;
  879.  
  880.    if (atapi_p.cdb.MODE_SELECT10.OperationCode == 0x55)
  881.    { // MODE SELECT requires additional data from host
  882.  
  883.       state = S_MODE_SELECT;
  884.       reg.status = STATUS_DRQ;
  885.       reg.intreason = 0;
  886.       transptr = 0;
  887.       transcount = atapi_p.cdb.MODE_SELECT10.ParameterListLength[0]*0x100 + atapi_p.cdb.MODE_SELECT10.ParameterListLength[1];
  888.       return;
  889.    }
  890.  
  891.    if (atapi_p.cdb.CDB6READWRITE.OperationCode == 0x03 && atapi_p.senselen)
  892.    { // REQ.SENSE - read cached
  893.       memcpy(transbf, atapi_p.sense, atapi_p.senselen);
  894.       atapi_p.passed_length = atapi_p.senselen; atapi_p.senselen = 0; // next time read from device
  895.       goto ok;
  896.    }
  897.  
  898.    if (atapi_p.pass_through(transbf, sizeof transbf))
  899.    {
  900.       if (atapi_p.senselen)
  901.       {
  902.           reg.err = u8(atapi_p.sense[2] << 4);
  903.           goto err;
  904.       } // err = sense key //win9x hangs on drq after atapi packet when emulator does goto err (see walkaround in SEND_ASPI_CMD)
  905.     ok:
  906.       if (!atapi_p.cdb.CDB6READWRITE.OperationCode)
  907.           atapi_p.passed_length = 0; // bugfix in cdrom driver: TEST UNIT READY has no data
  908.       if (!atapi_p.passed_length /* || atapi_p.passed_length == sizeof transbf */ )
  909.       {
  910.           command_ok();
  911.           return;
  912.       }
  913.       reg.atapi_count = u16(atapi_p.passed_length);
  914.       reg.intreason = INT_IO;
  915.       reg.status = STATUS_DRQ;
  916.       transcount = (atapi_p.passed_length+1)/2;
  917.           //printf("transcount=%d\n",transcount); //32768 in win9x
  918.       transptr = 0;
  919.       state = S_READ_ATAPI;
  920.    }
  921.    else
  922.    { // bus error
  923.       reg.err = 0;
  924.     err:
  925.       state = S_IDLE;
  926.       reg.status = STATUS_DSC | STATUS_ERR | STATUS_DRDY;
  927.    }
  928. }
  929.  
  930. void ATA_DEVICE::prepare_id()
  931. {
  932.    if (phys_dev == -1U)
  933.    {
  934.       memset(transbf, 0, 512);
  935.       make_ata_string(transbf+54, 20, "UNREAL SPECCY HARD DRIVE IMAGE");
  936.       make_ata_string(transbf+20, 10, "0000");
  937.       make_ata_string(transbf+46,  4, VERS_STRING);
  938.       *(unsigned short*)transbf = 0x045A;
  939.       ((unsigned short*)transbf)[1] = (unsigned short)c;
  940.       ((unsigned short*)transbf)[3] = (unsigned short)h;
  941.       ((unsigned short*)transbf)[6] = (unsigned short)s;
  942.       *(unsigned*)(transbf+60*2) = (lba > 0xFFFFFFFULL) ? 0xFFFFFFF : unsigned(lba); // lba28
  943.       ((unsigned short*)transbf)[20] = 3; // a dual ported multi-sector buffer capable of simultaneous transfers with a read caching capability
  944.       ((unsigned short*)transbf)[21] = 512; // cache size=256k
  945.       ((unsigned short*)transbf)[22] = 4; // ECC bytes
  946.       ((unsigned short*)transbf)[49] = 0x200; // LBA supported
  947.       ((unsigned short*)transbf)[80] = 0x3E; // support specifications up to ATA-5
  948.       ((unsigned short*)transbf)[81] = 0x13; // ATA/ATAPI-5 T13 1321D revision 3
  949.       ((unsigned short*)transbf)[82] = 0x60; // supported look-ahead and write cache
  950.  
  951.       if(lba > 0xFFFFFFFULL)
  952.       {
  953.           ((unsigned short*)transbf)[83] = 0x400; // lba48 supported
  954.           ((unsigned short*)transbf)[86] = 0x400; // lba48 supported
  955.           *(u64*)(transbf+100*2) = lba; // lba48
  956.       }
  957.  
  958.       // make checksum
  959.       transbf[510] = 0xA5;
  960.       unsigned char cs = 0;
  961.       for (unsigned i = 0; i < 511; i++)
  962.           cs += transbf[i];
  963.       transbf[511] = 0-cs;
  964.    }
  965.    else
  966.    { // copy as is...
  967.       memcpy(transbf, phys[phys_dev].idsector, 512);
  968.    }
  969.  
  970.    state = S_READ_ID;
  971.    transptr = 0;
  972.    transcount = 0x100;
  973.    intrq = 1;
  974.    reg.status = STATUS_DRDY | STATUS_DRQ | STATUS_DSC;
  975.    reg.err = 0;
  976. }
  977.  
  978. void ATA_DEVICE::update_regs()
  979. {
  980.    if(reg.devhead & 0x40)
  981.    { // lba
  982.        if(lba > 0xFFFFFFFULL)
  983.        { // lba48
  984.            reg.lba0 = lba_cur & 0xFF;
  985.            reg.lba1 = (lba_cur >> 8) & 0xFF;
  986.            reg.lba2 = (lba_cur >> 16) & 0xFF;
  987.            reg.lba4 = (lba_cur >> 24) & 0xFF;
  988.            reg.lba5 = (lba_cur >> 32) & 0xFF;
  989.            reg.lba6 = (lba_cur >> 40) & 0xFF;
  990.        }
  991.        else
  992.        { // lba28
  993.            reg.lba0 = lba_cur & 0xFF;
  994.            reg.lba1 = (lba_cur >> 8) & 0xFF;
  995.            reg.lba2 = (lba_cur >> 16) & 0xFF;
  996.            reg.lba3 &= ~0xF;
  997.            reg.lba3 |= (lba_cur >> 24) & 0xF;
  998.        }
  999.    }
  1000.    else
  1001.    { // chs
  1002.        reg.cyl = u16(c_cur);
  1003.        reg.devhead &= ~0xF;
  1004.        reg.devhead |= h_cur & 0xF;
  1005.        reg.sec = u8(s_cur);
  1006.    }
  1007. }
  1008.  
  1009. void ATA_DEVICE::update_cur()
  1010. {
  1011.    n_cur = reg.count;
  1012.    if(lba > 0xFFFFFFFULL)
  1013.    { // lba48
  1014.        lba_cur = reg.lba0 | (u64(reg.lba1) << 8) | (u64(reg.lba2) << 16) | (u64(reg.lba4) << 24) | (u64(reg.lba5) << 32) | (u64(reg.lba6) << 40);
  1015.        n_cur |= unsigned(reg.count1 << 8);
  1016.    }
  1017.    else
  1018.    { // lba28
  1019.        lba_cur = reg.lba0 | (u64(reg.lba1) << 8) | (u64(reg.lba2) << 16) | (u64(reg.lba3 & 0xF) << 24);
  1020.    }
  1021.  
  1022.    c_cur = reg.cyl;
  1023.    h_cur = reg.devhead & 0xF;
  1024.    s_cur = reg.sec;
  1025. }
  1026.