trunk/src/lib/formats/td0_dsk.c
| r29485 | r29486 | |
| 823 | 823 | dynamic_buffer imagebuf(max_size); |
| 824 | 824 | UINT8 header[12]; |
| 825 | 825 | |
| 826 | | try |
| 826 | io_generic_read(io, header, 0, 12); |
| 827 | head_count = header[9]; |
| 828 | |
| 829 | if(header[0] == 't') |
| 827 | 830 | { |
| 828 | | io_generic_read(io, header, 0, 12); |
| 829 | | head_count = header[9]; |
| 831 | td0dsk_t disk_decode; |
| 830 | 832 | |
| 831 | | if(header[0] == 't') |
| 832 | | { |
| 833 | | td0dsk_t disk_decode; |
| 833 | disk_decode.floppy_file = io; |
| 834 | disk_decode.init_Decode(); |
| 835 | disk_decode.floppy_file_offset = 12; |
| 836 | disk_decode.Decode(imagebuf, max_size); |
| 837 | } |
| 838 | else |
| 839 | io_generic_read(io, imagebuf, 12, io_generic_size(io)); |
| 834 | 840 | |
| 835 | | disk_decode.floppy_file = io; |
| 836 | | disk_decode.init_Decode(); |
| 837 | | disk_decode.floppy_file_offset = 12; |
| 838 | | disk_decode.Decode(imagebuf, max_size); |
| 839 | | } |
| 840 | | else |
| 841 | | io_generic_read(io, imagebuf, 12, io_generic_size(io)); |
| 841 | if(header[7] & 0x80) |
| 842 | offset = 10 + imagebuf[2] + (imagebuf[3] << 8); |
| 842 | 843 | |
| 843 | | if(header[7] & 0x80) |
| 844 | | offset = 10 + imagebuf[2] + (imagebuf[3] << 8); |
| 844 | track_spt = imagebuf[offset]; |
| 845 | if(track_spt == 255) // Empty file? |
| 846 | return false; |
| 845 | 847 | |
| 846 | | track_spt = imagebuf[offset]; |
| 847 | | if(track_spt == 255) // Empty file? |
| 848 | | throw false; |
| 849 | | |
| 850 | | switch(header[6]) |
| 851 | | { |
| 852 | | case 2: |
| 853 | | if((imagebuf[offset + 2] & 0x7f) == 2) // ? |
| 854 | | { |
| 855 | | if(head_count == 2) |
| 856 | | image->set_variant(floppy_image::DSHD); |
| 857 | | else |
| 858 | | throw false; // single side hd? |
| 859 | | break; |
| 860 | | } |
| 861 | | /* no break; could be qd, won't know until tracks are counted */ |
| 862 | | case 1: |
| 848 | switch(header[6]) |
| 849 | { |
| 850 | case 2: |
| 851 | if((imagebuf[offset + 2] & 0x7f) == 2) // ? |
| 852 | { |
| 863 | 853 | if(head_count == 2) |
| 864 | | image->set_variant(floppy_image::DSDD); |
| 854 | image->set_variant(floppy_image::DSHD); |
| 865 | 855 | else |
| 866 | | image->set_variant(floppy_image::SSDD); |
| 856 | return false; // single side hd? |
| 867 | 857 | break; |
| 868 | | case 4: |
| 869 | | if((imagebuf[offset + 2] & 0x7f) == 2) // ? |
| 870 | | { |
| 871 | | if(head_count == 2) |
| 872 | | image->set_variant(floppy_image::DSHD); |
| 873 | | else |
| 874 | | throw false; // single side 3.5? |
| 875 | | break; |
| 876 | | } |
| 877 | | /* no break */ |
| 878 | | case 3: |
| 858 | } |
| 859 | /* no break; could be qd, won't know until tracks are counted */ |
| 860 | case 1: |
| 861 | if(head_count == 2) |
| 862 | image->set_variant(floppy_image::DSDD); |
| 863 | else |
| 864 | image->set_variant(floppy_image::SSDD); |
| 865 | break; |
| 866 | case 4: |
| 867 | if((imagebuf[offset + 2] & 0x7f) == 2) // ? |
| 868 | { |
| 879 | 869 | if(head_count == 2) |
| 880 | | { |
| 881 | | if(form_factor == floppy_image::FF_525) |
| 882 | | image->set_variant(floppy_image::DSQD); |
| 883 | | else |
| 884 | | image->set_variant(floppy_image::DSDD); |
| 885 | | } |
| 870 | image->set_variant(floppy_image::DSHD); |
| 886 | 871 | else |
| 887 | | { |
| 888 | | if(form_factor == floppy_image::FF_525) |
| 889 | | image->set_variant(floppy_image::SSQD); |
| 890 | | else |
| 891 | | throw false; // single side 3.5? |
| 892 | | } |
| 872 | return false; // single side 3.5? |
| 893 | 873 | break; |
| 894 | | } |
| 874 | } |
| 875 | /* no break */ |
| 876 | case 3: |
| 877 | if(head_count == 2) |
| 878 | { |
| 879 | if(form_factor == floppy_image::FF_525) |
| 880 | image->set_variant(floppy_image::DSQD); |
| 881 | else |
| 882 | image->set_variant(floppy_image::DSDD); |
| 883 | } |
| 884 | else |
| 885 | { |
| 886 | if(form_factor == floppy_image::FF_525) |
| 887 | image->set_variant(floppy_image::SSQD); |
| 888 | else |
| 889 | return false; // single side 3.5? |
| 890 | } |
| 891 | break; |
| 892 | } |
| 895 | 893 | |
| 896 | | static const int rates[3] = { 250000, 300000, 500000 }; |
| 897 | | int rate = (header[5] & 0x7f) >= 3 ? 500000 : rates[header[5] & 0x7f]; |
| 898 | | int rpm = form_factor == floppy_image::FF_8 || (form_factor == floppy_image::FF_525 && rate >= 300000) ? 360 : 300; |
| 899 | | int base_cell_count = rate*60/rpm; |
| 894 | static const int rates[3] = { 250000, 300000, 500000 }; |
| 895 | int rate = (header[5] & 0x7f) >= 3 ? 500000 : rates[header[5] & 0x7f]; |
| 896 | int rpm = form_factor == floppy_image::FF_8 || (form_factor == floppy_image::FF_525 && rate >= 300000) ? 360 : 300; |
| 897 | int base_cell_count = rate*60/rpm; |
| 900 | 898 | |
| 901 | | while(track_spt != 255) |
| 899 | while(track_spt != 255) |
| 900 | { |
| 901 | desc_pc_sector sects[256]; |
| 902 | UINT8 sect_data[65536]; |
| 903 | int sdatapos = 0; |
| 904 | int track = imagebuf[offset + 1]; |
| 905 | int head = imagebuf[offset + 2] & 1; |
| 906 | bool fm = (header[5] & 0x80) || (imagebuf[offset + 2] & 0x80); // ? |
| 907 | offset += 4; |
| 908 | for(int i = 0; i < track_spt; i++) |
| 902 | 909 | { |
| 903 | | desc_pc_sector sects[256]; |
| 904 | | UINT8 sect_data[65536]; |
| 905 | | int sdatapos = 0; |
| 906 | | int track = imagebuf[offset + 1]; |
| 907 | | int head = imagebuf[offset + 2] & 1; |
| 908 | | bool fm = (header[5] & 0x80) || (imagebuf[offset + 2] & 0x80); // ? |
| 909 | | offset += 4; |
| 910 | | for(int i = 0; i < track_spt; i++) |
| 911 | | { |
| 912 | | UINT8 *hs = &imagebuf[offset]; |
| 913 | | UINT16 size; |
| 914 | | offset += 6; |
| 910 | UINT8 *hs = &imagebuf[offset]; |
| 911 | UINT16 size; |
| 912 | offset += 6; |
| 915 | 913 | |
| 916 | | sects[i].track = hs[0]; |
| 917 | | sects[i].head = hs[1]; |
| 918 | | sects[i].sector = hs[2]; |
| 919 | | sects[i].size = hs[3]; |
| 920 | | sects[i].deleted = (hs[4] & 4) == 4; |
| 921 | | sects[i].bad_crc = (hs[4] & 2) == 2; |
| 914 | sects[i].track = hs[0]; |
| 915 | sects[i].head = hs[1]; |
| 916 | sects[i].sector = hs[2]; |
| 917 | sects[i].size = hs[3]; |
| 918 | sects[i].deleted = (hs[4] & 4) == 4; |
| 919 | sects[i].bad_crc = (hs[4] & 2) == 2; |
| 922 | 920 | |
| 923 | | if(hs[4] & 0x30) |
| 924 | | size = 0; |
| 925 | | else |
| 921 | if(hs[4] & 0x30) |
| 922 | size = 0; |
| 923 | else |
| 924 | { |
| 925 | offset += 3; |
| 926 | size = 128 << hs[3]; |
| 927 | int j, k; |
| 928 | switch(hs[8]) |
| 926 | 929 | { |
| 927 | | offset += 3; |
| 928 | | size = 128 << hs[3]; |
| 929 | | int j, k; |
| 930 | | switch(hs[8]) |
| 931 | | { |
| 932 | | default: |
| 933 | | throw false; |
| 934 | | case 0: |
| 935 | | memcpy(§_data[sdatapos], &imagebuf[offset], size); |
| 936 | | offset += size; |
| 937 | | break; |
| 938 | | case 1: |
| 939 | | offset += 4; |
| 940 | | k = (hs[9] + (hs[10] << 8)) * 2; |
| 941 | | k = (k <= size) ? k : size; |
| 942 | | for(j = 0; j < k; j += 2) |
| 930 | default: |
| 931 | return false; |
| 932 | case 0: |
| 933 | memcpy(§_data[sdatapos], &imagebuf[offset], size); |
| 934 | offset += size; |
| 935 | break; |
| 936 | case 1: |
| 937 | offset += 4; |
| 938 | k = (hs[9] + (hs[10] << 8)) * 2; |
| 939 | k = (k <= size) ? k : size; |
| 940 | for(j = 0; j < k; j += 2) |
| 941 | { |
| 942 | sect_data[sdatapos + j] = hs[11]; |
| 943 | sect_data[sdatapos + j + 1] = hs[12]; |
| 944 | } |
| 945 | if(k < size) |
| 946 | memset(§_data[sdatapos + k], '\0', size - k); |
| 947 | break; |
| 948 | case 2: |
| 949 | k = 0; |
| 950 | while(k < size) |
| 951 | { |
| 952 | UINT16 len = imagebuf[offset]; |
| 953 | UINT16 rep = imagebuf[offset + 1]; |
| 954 | offset += 2; |
| 955 | if(!len) |
| 943 | 956 | { |
| 944 | | sect_data[sdatapos + j] = hs[11]; |
| 945 | | sect_data[sdatapos + j + 1] = hs[12]; |
| 957 | memcpy(§_data[sdatapos + k], &imagebuf[offset], rep); |
| 958 | offset += rep; |
| 959 | k += rep; |
| 946 | 960 | } |
| 947 | | if(k < size) |
| 948 | | memset(§_data[sdatapos + k], '\0', size - k); |
| 949 | | break; |
| 950 | | case 2: |
| 951 | | k = 0; |
| 952 | | while(k < size) |
| 961 | else |
| 953 | 962 | { |
| 954 | | UINT16 len = imagebuf[offset]; |
| 955 | | UINT16 rep = imagebuf[offset + 1]; |
| 956 | | offset += 2; |
| 957 | | if(!len) |
| 958 | | { |
| 959 | | memcpy(§_data[sdatapos + k], &imagebuf[offset], rep); |
| 960 | | offset += rep; |
| 961 | | k += rep; |
| 962 | | } |
| 963 | | else |
| 964 | | { |
| 965 | | len = (1 << len); |
| 966 | | rep = len * rep; |
| 967 | | rep = ((rep + k) <= size) ? rep : (size - k); |
| 968 | | for(j = 0; j < rep; j += len) |
| 969 | | memcpy(§_data[sdatapos + j + k], &imagebuf[offset], len); |
| 970 | | k += rep; |
| 971 | | offset += len; |
| 972 | | } |
| 963 | len = (1 << len); |
| 964 | rep = len * rep; |
| 965 | rep = ((rep + k) <= size) ? rep : (size - k); |
| 966 | for(j = 0; j < rep; j += len) |
| 967 | memcpy(§_data[sdatapos + j + k], &imagebuf[offset], len); |
| 968 | k += rep; |
| 969 | offset += len; |
| 973 | 970 | } |
| 974 | | break; |
| 975 | | } |
| 971 | } |
| 972 | break; |
| 976 | 973 | } |
| 974 | } |
| 977 | 975 | |
| 978 | | sects[i].actual_size = size; |
| 976 | sects[i].actual_size = size; |
| 979 | 977 | |
| 980 | | if(size) |
| 981 | | { |
| 982 | | sects[i].data = §_data[sdatapos]; |
| 983 | | sdatapos += size; |
| 984 | | } |
| 985 | | else |
| 986 | | sects[i].data = NULL; |
| 978 | if(size) |
| 979 | { |
| 980 | sects[i].data = §_data[sdatapos]; |
| 981 | sdatapos += size; |
| 987 | 982 | } |
| 988 | | track_count = track; |
| 989 | | |
| 990 | | if(fm) |
| 991 | | build_pc_track_fm(track, head, image, base_cell_count, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size)); |
| 992 | 983 | else |
| 993 | | build_pc_track_mfm(track, head, image, base_cell_count*2, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size)); |
| 994 | | |
| 995 | | track_spt = imagebuf[offset]; |
| 984 | sects[i].data = NULL; |
| 996 | 985 | } |
| 997 | | if((track_count > 50) && (form_factor == floppy_image::FF_525)) // ? |
| 998 | | { |
| 999 | | if(image->get_variant() == floppy_image::DSDD) |
| 1000 | | image->set_variant(floppy_image::DSQD); |
| 1001 | | else if(image->get_variant() == floppy_image::SSDD) |
| 1002 | | image->set_variant(floppy_image::SSQD); |
| 1003 | | } |
| 1004 | | throw true; |
| 986 | track_count = track; |
| 987 | |
| 988 | if(fm) |
| 989 | build_pc_track_fm(track, head, image, base_cell_count, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size)); |
| 990 | else |
| 991 | build_pc_track_mfm(track, head, image, base_cell_count*2, track_spt, sects, calc_default_pc_gap3_size(form_factor, sects[0].actual_size)); |
| 992 | |
| 993 | track_spt = imagebuf[offset]; |
| 1005 | 994 | } |
| 1006 | | catch(bool ret) |
| 995 | if((track_count > 50) && (form_factor == floppy_image::FF_525)) // ? |
| 1007 | 996 | { |
| 1008 | | return ret; |
| 997 | if(image->get_variant() == floppy_image::DSDD) |
| 998 | image->set_variant(floppy_image::DSQD); |
| 999 | else if(image->get_variant() == floppy_image::SSDD) |
| 1000 | image->set_variant(floppy_image::SSQD); |
| 1009 | 1001 | } |
| 1010 | | return false; |
| 1002 | return true; |
| 1011 | 1003 | } |
| 1012 | 1004 | |
| 1013 | 1005 | |