int rawDiskWrite( BVRef bvr, unsigned int secno, void *buffer, unsigned int len ) { int secs; unsigned char *cbuf = (unsigned char *)buffer; unsigned int copy_len; int rc; if ((len & (BPS-1)) != 0) { error("raw disk write not sector aligned"); return -1; } secno += bvr->part_boff; cache_valid = FALSE; while (len > 0) { secs = len / BPS; if (secs > N_CACHE_SECS) secs = N_CACHE_SECS; copy_len = secs * BPS; bcopy( cbuf, trackbuf, copy_len ); //printf("rdr: ebioswrite(%d, %d, %d)\n", bvr->biosdev, secno, secs); if ((rc = ebioswrite(bvr->biosdev, secno, secs)) != 0) { error(" EBIOS write error: %s\n", bios_error(rc), rc); error(" Block %d Sectors %d\n", secno, secs); return rc; } len -= copy_len; cbuf += copy_len; secno += secs; spinActivityIndicator(); } return 0; }
int rawDiskRead( BVRef bvr, unsigned int secno, void *buffer, unsigned int len ) { int secs; unsigned char *cbuf = (unsigned char *)buffer; unsigned int copy_len; int rc; if ((len & (BPS-1)) != 0) { error("raw disk read not sector aligned"); return -1; } secno += bvr->part_boff; cache_valid = FALSE; while (len > 0) { secs = len / BPS; if (secs > N_CACHE_SECS) secs = N_CACHE_SECS; copy_len = secs * BPS; //printf("rdr: ebiosread(%d, %d, %d)\n", bvr->biosdev, secno, secs); if ((rc = ebiosread(bvr->biosdev, secno, secs)) != 0) { /* Ignore corrected ECC errors */ if (rc != ECC_CORRECTED_ERR) { error(" EBIOS read error: %s\n", bios_error(rc), rc); error(" Block %d Sectors %d\n", secno, secs); return rc; } } bcopy( trackbuf, cbuf, copy_len ); len -= copy_len; cbuf += copy_len; secno += secs; spinActivityIndicator(); } return 0; }
static int Biosread(int biosdev, unsigned long long secno) { static int xbiosdev; static unsigned int xsec, xnsecs; struct driveInfo di; int rc = -1; int tries = 0; int bps, divisor; if (getDriveInfo(biosdev, &di) < 0) { return -1; } // Is biosdev in El Torito no emulation mode (think bootable CD's here)? if (di.no_emulation) { bps = 2048; // Yes. Assume 2K block size since the BIOS may lie about the geometry. } else { bps = di.di.params.phys_nbps; if (bps == 0) { return -1; } } divisor = bps / BPS; // _DISK_DEBUG_DUMP("Biosread dev %x sec %d bps %d\n", biosdev, secno, bps); // Use ebiosread() when supported, otherwise revert to biosread(). if ((biosdev >= kBIOSDevTypeHardDrive) && (di.uses_ebios & EBIOS_FIXED_DISK_ACCESS)) { if (cache_valid && (biosdev == xbiosdev) && (secno >= xsec) && ((unsigned int)secno < (xsec + xnsecs))) { biosbuf = trackbuf + (BPS * (secno - xsec)); return 0; } xnsecs = N_CACHE_SECS; xsec = (secno / divisor) * divisor; cache_valid = false; while ((rc = ebiosread(biosdev, secno / divisor, xnsecs / divisor)) && (++tries < 5)) { if (rc == ECC_CORRECTED_ERR) { rc = 0; // Ignore corrected ECC errors. break; } error(" EBIOS read error: %s\n", bios_error(rc), rc); error(" Block 0x%x Sectors %d\n", secno, xnsecs); _DISK_DEBUG_SLEEP(1); } } #if LEGACY_BIOS_READ_SUPPORT else { static int xcyl, xhead; /* spc = spt * heads */ int spc = (di.di.params.phys_spt * di.di.params.phys_heads); int cyl = secno / spc; int head = (secno % spc) / di.di.params.phys_spt; int sec = secno % di.di.params.phys_spt; if (cache_valid && (biosdev == xbiosdev) && (cyl == xcyl) && (head == xhead) && ((unsigned int)sec >= xsec) && ((unsigned int)sec < (xsec + xnsecs))) { // this sector is in trackbuf cache. biosbuf = trackbuf + (BPS * (sec - xsec)); return 0; } // Cache up to a track worth of sectors, but do not cross a track boundary. xcyl = cyl; xhead = head; xsec = sec; xnsecs = ((unsigned int)(sec + N_CACHE_SECS) > di.di.params.phys_spt) ? (di.di.params.phys_spt - sec) : N_CACHE_SECS; cache_valid = false; while ((rc = biosread(biosdev, cyl, head, sec, xnsecs)) && (++tries < 5)) { if (rc == ECC_CORRECTED_ERR) { rc = 0; // Ignore corrected ECC errors. break; } error(" BIOS read error: %s\n", bios_error(rc), rc); error(" Block %d, Cyl %d Head %d Sector %d\n", secno, cyl, head, sec); _DISK_DEBUG_SLEEP(1); } } #endif // LEGACY_BIOS_READ_SUPPORT if (rc == 0) // BIOS reported success, mark sector cache as valid. { cache_valid = true; } biosbuf = trackbuf + (secno % divisor) * BPS; xbiosdev = biosdev; return rc; }
static int Biosread( int biosdev, unsigned int secno ) { static int xbiosdev, xcyl, xhead; static unsigned int xsec, xnsecs; struct driveInfo di; int rc = -1; int cyl, head, sec; int tries = 0; int bps, divisor; if (getDriveInfo(biosdev, &di) < 0) { return -1; } if (di.no_emulation) { /* Always assume 2k block size; BIOS may lie about geometry */ bps = 2048; } else { bps = di.di.params.phys_nbps; if (bps == 0) { return -1; } } divisor = bps / BPS; DEBUG_DISK(("Biosread dev %x sec %d bps %d\n", biosdev, secno, bps)); // To read the disk sectors, use EBIOS if we can. Otherwise, // revert to the standard BIOS calls. if ((biosdev >= kBIOSDevTypeHardDrive) && (di.uses_ebios & EBIOS_FIXED_DISK_ACCESS)) { if (cache_valid && (biosdev == xbiosdev) && (secno >= xsec) && ((unsigned int)secno < (xsec + xnsecs))) { biosbuf = trackbuf + (BPS * (secno - xsec)); return 0; } xnsecs = N_CACHE_SECS; xsec = (secno / divisor) * divisor; cache_valid = FALSE; while ((rc = ebiosread(biosdev, secno / divisor, xnsecs / divisor)) && (++tries < 5)) { if (rc == ECC_CORRECTED_ERR) { /* Ignore corrected ECC errors */ rc = 0; break; } error(" EBIOS read error: %s\n", bios_error(rc), rc); error(" Block %d Sectors %d\n", secno, xnsecs); sleep(1); } } else { /* spc = spt * heads */ int spc = (di.di.params.phys_spt * di.di.params.phys_heads); cyl = secno / spc; head = (secno % spc) / di.di.params.phys_spt; sec = secno % di.di.params.phys_spt; if (cache_valid && (biosdev == xbiosdev) && (cyl == xcyl) && (head == xhead) && ((unsigned int)sec >= xsec) && ((unsigned int)sec < (xsec + xnsecs))) { // this sector is in trackbuf cache biosbuf = trackbuf + (BPS * (sec - xsec)); return 0; } // Cache up to a track worth of sectors, but do not cross a // track boundary. xcyl = cyl; xhead = head; xsec = sec; xnsecs = ((unsigned int)(sec + N_CACHE_SECS) > di.di.params.phys_spt) ? (di.di.params.phys_spt - sec) : N_CACHE_SECS; cache_valid = FALSE; while ((rc = biosread(biosdev, cyl, head, sec, xnsecs)) && (++tries < 5)) { if (rc == ECC_CORRECTED_ERR) { /* Ignore corrected ECC errors */ rc = 0; break; } error(" BIOS read error: %s\n", bios_error(rc), rc); error(" Block %d, Cyl %d Head %d Sector %d\n", secno, cyl, head, sec); sleep(1); } } // If the BIOS reported success, mark the sector cache as valid. if (rc == 0) { cache_valid = TRUE; } biosbuf = trackbuf + (secno % divisor) * BPS; xbiosdev = biosdev; spinActivityIndicator(); return rc; }
static int bios_check(int flag) { int i, err, count = 0, check_max = DEBUG_BIOS; char *fname; if (!flag) ui_popup_reset(); video_copy_rect(show_frame, draw_frame, &full_rect, &full_rect); video_flip_screen(1); for (i = 0; i < BIOS_MAX; i++) bios_exist[i] = 0; #ifdef ADHOC if (flag == 2) { neogeo_bios = -1; check_max = ASIA_AES; } #endif for (i = 0; i <= check_max; i++) { if (file_open(bios_zip, NULL, bios_crc[i], NULL) >= 0) { count++; bios_exist[i] = 1; file_close(); } } if (count == 0) { if (!flag) ui_popup(TEXT(BIOS_NOT_FOUND)); else fatalerror(TEXT(BIOS_NOT_FOUND)); return 0; } fname = (char *)sfix_name; if ((err = file_open(bios_zip, NULL, sfix_crc, fname)) >= 0) { file_close(); } else { bios_error(sfix_name, err, flag); return 0; } fname = (char *)lorom_name; if ((err = file_open(bios_zip, NULL, lorom_crc, fname)) >= 0) { file_close(); } else { bios_error(lorom_name, err, flag); return 0; } return 1; }