trunk/src/lib/formats/flopimg.c
r17496 | r17497 | |
2303 | 2303 | } |
2304 | 2304 | } |
2305 | 2305 | |
| 2306 | |
| 2307 | void floppy_image_format_t::extract_sectors_from_bitstream_fm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size) |
| 2308 | { |
| 2309 | memset(sectors, 0, 256*sizeof(desc_xs)); |
| 2310 | |
| 2311 | // Don't bother if it's just too small |
| 2312 | if(track_size < 100) |
| 2313 | return; |
| 2314 | |
| 2315 | // Start by detecting all id and data blocks |
| 2316 | |
| 2317 | // If 100 is not enough, that track is too funky to be worth |
| 2318 | // bothering anyway |
| 2319 | |
| 2320 | int idblk[100], dblk[100]; |
| 2321 | int idblk_count = 0, dblk_count = 0; |
| 2322 | |
| 2323 | // Precharge the shift register to detect over-the-index stuff |
| 2324 | UINT16 shift_reg = 0; |
| 2325 | for(int i=0; i<16; i++) |
| 2326 | if(sbit_r(bitstream, track_size-16+i)) |
| 2327 | shift_reg |= 0x8000 >> i; |
| 2328 | |
| 2329 | // Scan the bitstream for sync marks and follow them to check for |
| 2330 | // blocks |
| 2331 | for(int i=0; i<track_size; i++) { |
| 2332 | shift_reg = (shift_reg << 1) | sbit_r(bitstream, i); |
| 2333 | if(shift_reg == 0xf77a) { |
| 2334 | //index mark |
| 2335 | UINT16 header; |
| 2336 | int pos = i+1; |
| 2337 | do { |
| 2338 | header = 0; |
| 2339 | for(int j=0; j<16; j++) |
| 2340 | if(sbit_rp(bitstream, pos, track_size)) |
| 2341 | header |= 0x8000 >> j; |
| 2342 | // Accept strings of sync marks as long and they're not wrapping |
| 2343 | |
| 2344 | // Wrapping ones have already been take into account |
| 2345 | // thanks to the precharging |
| 2346 | |
| 2347 | // fe |
| 2348 | if(header == 0xf57e) { // address mark |
| 2349 | if(idblk_count < 100) |
| 2350 | idblk[idblk_count++] = pos; |
| 2351 | i = pos-1; |
| 2352 | } |
| 2353 | // fb |
| 2354 | if(header == 0xf56f ) { // data mark |
| 2355 | if(dblk_count < 100) |
| 2356 | dblk[dblk_count++] = pos; |
| 2357 | i = pos-1; |
| 2358 | } |
| 2359 | } while(header != 0xf77a); |
| 2360 | } |
| 2361 | } |
| 2362 | |
| 2363 | // Then extract the sectors |
| 2364 | int sectdata_pos = 0; |
| 2365 | for(int i=0; i<idblk_count; i++) { |
| 2366 | int pos = idblk[i]; |
| 2367 | UINT8 track = sbyte_mfm_r(bitstream, pos, track_size); |
| 2368 | UINT8 head = sbyte_mfm_r(bitstream, pos, track_size); |
| 2369 | UINT8 sector = sbyte_mfm_r(bitstream, pos, track_size); |
| 2370 | UINT8 size = sbyte_mfm_r(bitstream, pos, track_size); |
| 2371 | if(size >= 8) |
| 2372 | continue; |
| 2373 | int ssize = 128 << size; |
| 2374 | |
| 2375 | // If we don't have enough space for a sector's data, skip it |
| 2376 | if(ssize + sectdata_pos > sectdata_size) |
| 2377 | continue; |
| 2378 | |
| 2379 | // Start of IDAM and DAM are supposed to be exactly 384 cells |
| 2380 | // apart. Of course the hardware is tolerant. Accept +/- 128 |
| 2381 | // cells of shift. |
| 2382 | |
| 2383 | int d_index; |
| 2384 | for(d_index = 0; d_index < dblk_count; d_index++) { |
| 2385 | int delta = dblk[d_index] - idblk[i]; |
| 2386 | if(delta >= 384-128 && delta <= 384+128) |
| 2387 | break; |
| 2388 | } |
| 2389 | if(d_index == dblk_count) |
| 2390 | continue; |
| 2391 | |
| 2392 | pos = dblk[d_index]; |
| 2393 | |
| 2394 | sectors[sector].track = track; |
| 2395 | sectors[sector].head = head; |
| 2396 | sectors[sector].size = ssize; |
| 2397 | sectors[sector].data = sectdata + sectdata_pos; |
| 2398 | for(int j=0; j<ssize; j++) |
| 2399 | sectdata[sectdata_pos++] = sbyte_mfm_r(bitstream, pos, track_size); |
| 2400 | } |
| 2401 | } |
| 2402 | |
| 2403 | void floppy_image_format_t::get_geometry_fm_pc(floppy_image *image, int cell_size, int &track_count, int &head_count, int §or_count) |
| 2404 | { |
| 2405 | image->get_actual_geometry(track_count, head_count); |
| 2406 | |
| 2407 | if(!track_count) { |
| 2408 | sector_count = 0; |
| 2409 | return; |
| 2410 | } |
| 2411 | |
| 2412 | UINT8 bitstream[500000/8]; |
| 2413 | UINT8 sectdata[50000]; |
| 2414 | desc_xs sectors[256]; |
| 2415 | int track_size; |
| 2416 | |
| 2417 | // Extract an arbitrary track to get an idea of the number of |
| 2418 | // sectors |
| 2419 | |
| 2420 | // 20 was rarely used for protections, not near the start like |
| 2421 | // 0-10, not near the end like 70+, no special effects on sync |
| 2422 | // like 33 |
| 2423 | |
| 2424 | generate_bitstream_from_track(track_count > 20 ? 20 : 0, 0, cell_size, bitstream, track_size, image); |
| 2425 | extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectdata, sizeof(sectdata)); |
| 2426 | |
| 2427 | for(sector_count = 44; sector_count > 0 && !sectors[sector_count].data; sector_count--); |
| 2428 | } |
| 2429 | |
| 2430 | |
| 2431 | void floppy_image_format_t::get_track_data_fm_pc(int track, int head, floppy_image *image, int cell_size, int sector_size, int sector_count, UINT8 *sectdata) |
| 2432 | { |
| 2433 | UINT8 bitstream[500000/8]; |
| 2434 | UINT8 sectbuf[50000]; |
| 2435 | desc_xs sectors[256]; |
| 2436 | int track_size; |
| 2437 | |
| 2438 | generate_bitstream_from_track(track, head, cell_size, bitstream, track_size, image); |
| 2439 | extract_sectors_from_bitstream_fm_pc(bitstream, track_size, sectors, sectbuf, sizeof(sectbuf)); |
| 2440 | for(int sector=1; sector <= sector_count; sector++) { |
| 2441 | UINT8 *sd = sectdata + (sector-1)*sector_size; |
| 2442 | if(sectors[sector].data && sectors[sector].track == track && sectors[sector].head == head) { |
| 2443 | int asize = sectors[sector].size; |
| 2444 | if(asize > sector_size) |
| 2445 | asize = sector_size; |
| 2446 | memcpy(sd, sectors[sector].data, asize); |
| 2447 | if(asize < sector_size) |
| 2448 | memset(sd+asize, 0, sector_size-asize); |
| 2449 | } else |
| 2450 | memset(sd, 0, sector_size); |
| 2451 | } |
| 2452 | } |
| | No newline at end of file |
trunk/src/lib/formats/flopimg.h
r17496 | r17497 | |
481 | 481 | |
482 | 482 | //! PC-type sectors with MFM encoding, sector size can go from 128 bytes to 16K. |
483 | 483 | void extract_sectors_from_bitstream_mfm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size); |
| 484 | //! PC-type sectors with FM encoding |
| 485 | void extract_sectors_from_bitstream_fm_pc(const UINT8 *bitstream, int track_size, desc_xs *sectors, UINT8 *sectdata, int sectdata_size); |
484 | 486 | |
485 | 487 | |
486 | 488 | //! @brief Get a geometry (including sectors) from an image. |
487 | 489 | |
488 | 490 | //! PC-type sectors with MFM encoding |
489 | 491 | void get_geometry_mfm_pc(floppy_image *image, int cell_size, int &track_count, int &head_count, int §or_count); |
| 492 | //! PC-type sectors with FM encoding |
| 493 | void get_geometry_fm_pc(floppy_image *image, int cell_size, int &track_count, int &head_count, int §or_count); |
490 | 494 | |
491 | 495 | |
492 | 496 | //! Regenerate the data for a full track. |
493 | 497 | //! PC-type sectors with MFM encoding and fixed-size. |
494 | 498 | void get_track_data_mfm_pc(int track, int head, floppy_image *image, int cell_size, int sector_size, int sector_count, UINT8 *sectdata); |
495 | 499 | |
| 500 | //! Regenerate the data for a full track. |
| 501 | //! PC-type sectors with FM encoding and fixed-size. |
| 502 | void get_track_data_fm_pc(int track, int head, floppy_image *image, int cell_size, int sector_size, int sector_count, UINT8 *sectdata); |
| 503 | |
496 | 504 | //! Look up a bit in a level-type stream. |
497 | 505 | bool bit_r(const UINT32 *buffer, int offset); |
498 | 506 | //! Look up multiple bits |