| 974 | } |
| 975 | |
| 976 | static void do_process_rw_command (struct ide_hdf *ide) |
| 977 | { |
| 978 | unsigned int cyl, head, sec, nsec, nsec_total; |
| 979 | uae_u64 lba; |
| 980 | bool last = true; |
| 981 | |
| 982 | ide->data_offset = 0; |
| 983 | |
| 984 | if (ide->direction > 1) { |
| 985 | // FORMAT TRACK? |
| 986 | // Don't write anything |
| 987 | goto end; |
| 988 | } |
| 989 | |
| 990 | nsec = get_nsec (ide); |
| 991 | get_lbachs (ide, &lba, &cyl, &head, &sec); |
| 992 | if (IDE_LOG > 1) |
| 993 | write_log(_T("IDE%d off=%d, nsec=%d (%d) %s\n"), ide->num, (uae_u32)lba, nsec, ide->multiple_mode, getidemode(ide)); |
| 994 | if (nsec > ide->max_lba - lba) { |
| 995 | nsec = (unsigned int)(ide->max_lba - lba); |
| 996 | if (IDE_LOG > 1) |
| 997 | write_log (_T("IDE%d nsec changed to %d\n"), ide->num, nsec); |
| 998 | } |
| 999 | if (nsec <= 0) { |
| 1000 | ide_data_ready (ide); |
| 1001 | ide_fail_err (ide, IDE_ERR_IDNF); |
| 1002 | return; |
| 1003 | } |
| 1004 | nsec_total = nsec; |
| 1005 | ide_grow_buffer(ide, nsec_total * ide->blocksize); |
| 1006 | |
| 1007 | if (nsec > ide->data_multi) |
| 1008 | nsec = ide->data_multi; |
| 1009 | |
| 1010 | if (ide->buffer_offset == 0) { |
| 1011 | // store initial lba and number of sectors to transfer |
| 1012 | ide->start_lba = lba; |
| 1013 | ide->start_nsec = nsec_total; |
| 1014 | } |
| 1015 | |
| 1016 | if (ide->direction) { |
| 1017 | if (IDE_LOG > 1) |
| 1018 | write_log (_T("IDE%d write, %d/%d bytes, buffer offset %d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset); |
| 1019 | } else { |
| 1020 | if (ide->buffer_offset == 0) { |
| 1021 | hdf_read(&ide->hdhfd.hfd, ide->secbuf, ide->start_lba * ide->blocksize, ide->start_nsec * ide->blocksize); |
| 1022 | if (IDE_LOG > 1) |
| 1023 | write_log(_T("IDE%d initial read, %d bytes\n"), ide->num, nsec_total * ide->blocksize); |
| 1024 | } |
| 1025 | if (IDE_LOG > 1) |
| 1026 | write_log (_T("IDE%d read, read %d/%d bytes, buffer offset=%d\n"), ide->num, nsec * ide->blocksize, nsec_total * ide->blocksize, ide->buffer_offset); |
| 1027 | } |
| 1028 | ide->intdrq = true; |
| 1029 | last = dec_nsec (ide, nsec) == 0; |
| 1030 | // ATA-2 spec says CHS/LBA does only need to be updated if error condition |
| 1031 | if (ide->ata_level != 2 || !last) { |
| 1032 | put_lbachs (ide, lba, cyl, head, sec, last ? nsec - 1 : nsec); |
| 1033 | } |
no test coverage detected