src/lib/formats/ap2_dsk.c
| r15078 | r15079 | |
| 581 | 581 | return size == expected_size; |
| 582 | 582 | } |
| 583 | 583 | |
| 584 | // following is placeholder, is completely wrong. |
| 584 | 585 | const floppy_image_format_t::desc_e a2_16sect_format::mac_gcr[] = { |
| 585 | 586 | { SECTOR_LOOP_START, 0, -1 }, |
| 586 | 587 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| r15078 | r15079 | |
| 703 | 704 | int ts; |
| 704 | 705 | //fprintf(stderr,"DEBUG: a2_16sect_format::save() about to generate bitstream from physical track %d (logical %d)...", track, track/2); |
| 705 | 706 | //~332 samples per cell, times 3+8+3 (14) for address mark, 24 for sync, 3+343+3 (349) for data mark, 24 for sync is around 743, near 776 expected |
| 706 | | generate_bitstream_from_track(track, head, 200000000/(3104*nsect*3), buf, ts, image); // 3104 needs tweaking, *3 is 3x multiread from a dfi disk |
| 707 | generate_bitstream_from_track(track, head, 200000000/((3004*nsect*6)/2), buf, ts, image); // 3104 needs tweaking |
| 707 | 708 | //fprintf(stderr,"done.\n"); |
| 708 | 709 | int pos = 0; |
| 709 | 710 | int wrap = 0; |
| r15078 | r15079 | |
| 860 | 861 | //printf("\n"); |
| 861 | 862 | } |
| 862 | 863 | // display a little table of which sectors decoded ok |
| 864 | int total_good = 0; |
| 863 | 865 | for (int j = 0; j < 35; j++) { |
| 864 | 866 | printf("T%2d: ",j); |
| 865 | 867 | for (int i = 0; i < 16; i++) { |
| r15078 | r15079 | |
| 868 | 870 | if (visualgrid[i][j] & ADDRFOUND) printf("a"); else printf(" "); |
| 869 | 871 | if (visualgrid[i][j] & ADDRGOOD) printf("A"); else printf(" "); |
| 870 | 872 | if (visualgrid[i][j] & DATAFOUND) printf("d"); else printf(" "); |
| 871 | | if (visualgrid[i][j] & DATAGOOD) printf("D"); else printf(" "); |
| 873 | if (visualgrid[i][j] & DATAGOOD) { printf("D"); total_good++; } else printf(" "); |
| 872 | 874 | if (visualgrid[i][j] & DATAPOST) printf("."); else printf(" "); |
| 873 | 875 | } |
| 874 | 876 | } |
| 875 | 877 | printf("\n"); |
| 876 | 878 | } |
| 879 | printf("Total Good Sectors: %d\n", total_good); |
| 877 | 880 | |
| 878 | 881 | return true; |
| 879 | 882 | } |
| 880 | 883 | |
| 881 | 884 | const floppy_format_type FLOPPY_A216S_FORMAT = &floppy_image_format_creator<a2_16sect_format>; |
| 885 | /* RWTS18 format |
| 886 | * Developed by Roland Gustafsson (http://www.acts.org/roland/index.html) |
| 887 | for Br0derbund Software around 1986 |
| 888 | This format works as follows: |
| 889 | * Track 0, in its entirety, is a normal 16-sector track, nothing special. |
| 890 | (some disks may lack a normal sector 0 on this track, more info needed) |
| 891 | * Tracks 1 thru 34 are in the special "RWTS18" track format: |
| 892 | The format consists of six "large" sectors with 768 bytes each. |
| 893 | Each of those large sectors has a title-specific sync byte and contains |
| 894 | three "virtual" small sectors of 256 bytes, in an order like follows: |
| 895 | BigSector Contains |
| 896 | 0: 0, 6, 12 |
| 897 | 1: 1, 7, 13 |
| 898 | 2: 2, 8, 14 |
| 899 | 3: 3, 9, 15 |
| 900 | 4: 4, 10, 16 |
| 901 | 5: 5, 11, 17 |
| 902 | The sector format is: (all gcr6) |
| 903 | D5 9D <track> <sector> <checksum> AA FF FF <titlespecific sync> <0x400 nybbles which represent 768 bytes> <data checksum> D6 |
| 904 | Title-specific sync bytes are: |
| 905 | Airheart: D4 |
| 906 | Toy Shop: unknown |
| 907 | Carmen USA: unknown (not all released versions used RWTS18) |
| 908 | Wings of Fury: 96 |
| 909 | Prince of Persia: unknown |
| 910 | And several others. |
| 911 | */ |
| 912 | a2_rwts18_format::a2_rwts18_format() : floppy_image_format_t() |
| 913 | { |
| 914 | } |
| 915 | |
| 916 | const char *a2_rwts18_format::name() const |
| 917 | { |
| 918 | return "a2_rwts18"; |
| 919 | } |
| 920 | |
| 921 | const char *a2_rwts18_format::description() const |
| 922 | { |
| 923 | return "Apple II RWTS18-type Image"; |
| 924 | } |
| 925 | |
| 926 | const char *a2_rwts18_format::extensions() const |
| 927 | { |
| 928 | return "rti"; |
| 929 | } |
| 930 | |
| 931 | bool a2_rwts18_format::supports_save() const |
| 932 | { |
| 933 | return true; |
| 934 | } |
| 935 | |
| 936 | int a2_rwts18_format::identify(io_generic *io, UINT32 form_factor) |
| 937 | { |
| 938 | int size = io_generic_size(io); |
| 939 | int expected_size = 35 * 16 * 256; |
| 940 | return size == expected_size; |
| 941 | } |
| 942 | |
| 943 | // following is placeholder, is completely wrong. |
| 944 | const floppy_image_format_t::desc_e a2_rwts18_format::mac_gcr[] = { |
| 945 | { SECTOR_LOOP_START, 0, -1 }, |
| 946 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 947 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 948 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 949 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 950 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 951 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 952 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 953 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 954 | { RAWBITS, 0xd5aa96, 24 }, |
| 955 | { CRC_MACHEAD_START, 0 }, |
| 956 | { TRACK_ID_GCR6 }, |
| 957 | { SECTOR_ID_GCR6 }, |
| 958 | { TRACK_HEAD_ID_GCR6 }, |
| 959 | { SECTOR_INFO_GCR6 }, |
| 960 | { CRC_END, 0 }, |
| 961 | { CRC, 0 }, |
| 962 | { RAWBITS, 0xdeaaff, 24 }, |
| 963 | { RAWBITS, 0xff3fcf, 24 }, { RAWBITS, 0xf3fcff, 24 }, |
| 964 | { RAWBITS, 0xd5aaad, 24 }, |
| 965 | { SECTOR_ID_GCR6 }, |
| 966 | { SECTOR_DATA_MAC, -1 }, |
| 967 | { RAWBITS, 0xdeaaff, 24 }, |
| 968 | { RAWBITS, 0xff, 8 }, |
| 969 | { SECTOR_LOOP_END }, |
| 970 | { END }, |
| 971 | }; |
| 972 | |
| 973 | |
| 974 | bool a2_rwts18_format::load(io_generic *io, UINT32 form_factor, floppy_image *image) |
| 975 | { |
| 976 | /* TODO: rewrite me properly |
| 977 | UINT8 sector_data[(256)*16]; |
| 978 | memset(sector_data, 0, sizeof(sector_data)); |
| 979 | |
| 980 | desc_s sectors[16]; |
| 981 | int format = 0; |
| 982 | int pos_data = 0; |
| 983 | |
| 984 | int head_count = 1; |
| 985 | |
| 986 | for(int track=0; track < 35; track++) { |
| 987 | for(int head=0; head < head_count; head++) { |
| 988 | for(int si=0; si<16; si++) { |
| 989 | UINT8 *data = sector_data + (256)*si; |
| 990 | sectors[si].data = data; |
| 991 | sectors[si].size = 256; |
| 992 | sectors[si].sector_id = si; |
| 993 | sectors[si].sector_info = format; |
| 994 | io_generic_read(io, data, pos_data, 256); |
| 995 | pos_data += 256; |
| 996 | } |
| 997 | generate_track(mac_gcr, track, head, sectors, 16, 3104*16, image); |
| 998 | } |
| 999 | } |
| 1000 | return true;*/ |
| 1001 | return false; // I hope that throws an error... |
| 1002 | } |
| 1003 | |
| 1004 | UINT8 a2_rwts18_format::gb(const UINT8 *buf, int ts, int &pos, int &wrap) |
| 1005 | { |
| 1006 | UINT8 v = 0; |
| 1007 | int w1 = wrap; |
| 1008 | while(wrap != w1+2 && !(v & 0x80)) { |
| 1009 | v = v << 1 | ((buf[pos >> 3] >> (7-(pos & 7))) & 1); |
| 1010 | pos++; |
| 1011 | if(pos == ts) { |
| 1012 | pos = 0; |
| 1013 | wrap++; |
| 1014 | } |
| 1015 | } |
| 1016 | return v; |
| 1017 | } |
| 1018 | |
| 1019 | void a2_rwts18_format::update_chk(const UINT8 *data, int size, UINT32 &chk) |
| 1020 | { |
| 1021 | } |
| 1022 | |
| 1023 | bool a2_rwts18_format::save(io_generic *io, floppy_image *image) |
| 1024 | { |
| 1025 | int g_tracks, g_heads; |
| 1026 | int visualgrid[18][35]; // visualizer grid, cleared/initialized below |
| 1027 | // lenient addr check: if unset, only accept an addr mark if the checksum was good |
| 1028 | // if set, accept an addr mark if the track and sector values are both sane |
| 1029 | #undef LENIENT_ADDR_CHECK |
| 1030 | // if set, use the old, not as robust logic for choosing which copy of a decoded sector to write |
| 1031 | // to the resulting image if the sector has a bad checksum and/or postamble |
| 1032 | #undef USE_OLD_BEST_SECTOR_PRIORITY |
| 1033 | // select a sector order for resulting file: 0 = logical, 1 = dos3.3, 2 = prodos |
| 1034 | #define SECTOR_ORDER 1 |
| 1035 | // nothing found |
| 1036 | #define NOTFOUND 0 |
| 1037 | // address mark was found |
| 1038 | #define ADDRFOUND 1 |
| 1039 | // address checksum is good |
| 1040 | #define ADDRGOOD 2 |
| 1041 | // data mark was found (requires addrfound and sane values) |
| 1042 | #define DATAFOUND 4 |
| 1043 | // data checksum is good |
| 1044 | #define DATAGOOD 8 |
| 1045 | // data postamble is good |
| 1046 | #define DATAPOST 16 |
| 1047 | for (int i = 0; i < 18; i++) { |
| 1048 | for (int j = 0; j < 35; j++) { |
| 1049 | visualgrid[i][j] = 0; |
| 1050 | } |
| 1051 | } |
| 1052 | image->get_actual_geometry(g_tracks, g_heads); |
| 1053 | |
| 1054 | int head = 0; |
| 1055 | |
| 1056 | int pos_data = 0; |
| 1057 | |
| 1058 | // for track 0 ONLY: |
| 1059 | UINT8 sectdata[(768)*6]; |
| 1060 | memset(sectdata, 0, sizeof(sectdata)); |
| 1061 | int nsect = 18; |
| 1062 | UINT8 buf[130000]; // originally 13000, multiread dfi disks need larger |
| 1063 | int ts; |
| 1064 | //fprintf(stderr,"DEBUG: a2_rwts18_format::save() about to generate bitstream from physical track %d (logical %d)...", track, track/2); |
| 1065 | //~332 samples per cell, times 3+8+3 (14) for address mark, 24 for sync, 3+343+3 (349) for data mark, 24 for sync is around 743, near 776 expected |
| 1066 | generate_bitstream_from_track(0, head, 200000000/((3004*nsect*6)/2), buf, ts, image); // 3104 needs tweaking |
| 1067 | //fprintf(stderr,"done.\n"); |
| 1068 | int pos = 0; |
| 1069 | int wrap = 0; |
| 1070 | int hb = 0; |
| 1071 | int dosver = 0; // apple dos version; 0 = >=3.3, 1 = <3.3 |
| 1072 | for(;;) { |
| 1073 | UINT8 v = gb(buf, ts, pos, wrap); |
| 1074 | if(v == 0xff) |
| 1075 | hb = 1; |
| 1076 | else if(hb == 1 && v == 0xd5) |
| 1077 | hb = 2; |
| 1078 | else if(hb == 2 && v == 0xaa) |
| 1079 | hb = 3; |
| 1080 | else if(hb == 3 && ((v == 0x96) || (v == 0xab))) { // 0x96 = dos 3.3/16sec, 0xab = dos 3.21 and below/13sec |
| 1081 | hb = 4; |
| 1082 | if (v == 0xab) dosver = 1; |
| 1083 | } |
| 1084 | else |
| 1085 | hb = 0; |
| 1086 | |
| 1087 | if(hb == 4) { |
| 1088 | UINT8 h[11]; |
| 1089 | for(int i=0; i<11; i++) |
| 1090 | h[i] = gb(buf, ts, pos, wrap); |
| 1091 | //UINT8 v2 = gcr6bw_tb[h[2]]; |
| 1092 | UINT8 vl = gcr4_decode(h[0],h[1]); |
| 1093 | UINT8 tr = gcr4_decode(h[2],h[3]); |
| 1094 | UINT8 se = gcr4_decode(h[4],h[5]); |
| 1095 | UINT8 chk = gcr4_decode(h[6],h[7]); |
| 1096 | UINT32 post = (h[8]<<16)|(h[9]<<8)|h[10]; |
| 1097 | printf("Address Mark:\tVolume %d, Track %d, Sector %2d, Checksum %02X: %s, Postamble %03X: %s\n", vl, tr, se, chk, (chk ^ vl ^ tr ^ se)==0?"OK":"BAD", post, (post&0xFFFF00)==0xDEAA00?"OK":"BAD"); |
| 1098 | // sanity check |
| 1099 | if (tr == 0 && se < nsect) { |
| 1100 | visualgrid[se][0] |= ADDRFOUND; |
| 1101 | visualgrid[se][0] |= ((chk ^ vl ^ tr ^ se)==0)?ADDRGOOD:0; |
| 1102 | #ifdef LENIENT_ADDR_CHECK |
| 1103 | // if ((visualgrid[se][0] & ADDRFOUND) == ADDRFOUND) { |
| 1104 | #else |
| 1105 | if ((visualgrid[se][0] & ADDRGOOD) == ADDRGOOD) { |
| 1106 | #endif |
| 1107 | int opos = pos; |
| 1108 | int owrap = wrap; |
| 1109 | hb = 0; |
| 1110 | for(int i=0; i<20 && hb != 4; i++) { |
| 1111 | v = gb(buf, ts, pos, wrap); |
| 1112 | if(v == 0xff) |
| 1113 | hb = 1; |
| 1114 | else if(hb == 1 && v == 0xd5) |
| 1115 | hb = 2; |
| 1116 | else if(hb == 2 && v == 0xaa) |
| 1117 | hb = 3; |
| 1118 | else if(hb == 3 && v == 0xad) |
| 1119 | hb = 4; |
| 1120 | else |
| 1121 | hb = 0; |
| 1122 | } |
| 1123 | if((hb == 4)&&(dosver == 0)) { |
| 1124 | visualgrid[se][0] |= DATAFOUND; |
| 1125 | int sector_translate[16] = { |
| 1126 | #if SECTOR_ORDER == 0 |
| 1127 | // logical order (0-15) |
| 1128 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
| 1129 | 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F |
| 1130 | #elif SECTOR_ORDER == 1 |
| 1131 | // DOS order (*.do) |
| 1132 | 0x00, 0x07, 0x0E, 0x06, 0x0D, 0x05, 0x0C, 0x04, |
| 1133 | 0x0B, 0x03, 0x0A, 0x02, 0x09, 0x01, 0x08, 0x0F |
| 1134 | #elif SECTOR_ORDER == 2 |
| 1135 | // prodos order (*.po) |
| 1136 | 0x00, 0x08, 0x01, 0x09, 0x02, 0x0A, 0x03, 0x0B, |
| 1137 | 0x04, 0x0C, 0x05, 0x0D, 0x06, 0x0E, 0x07, 0x0F |
| 1138 | #endif |
| 1139 | }; |
| 1140 | UINT8 *dest = sectdata+(256)*sector_translate[se]; |
| 1141 | UINT8 data[0x157]; |
| 1142 | UINT32 dpost = 0; |
| 1143 | UINT8 c = 0; |
| 1144 | // first read in sector and decode to 6bit form |
| 1145 | for(int i=0; i<0x156; i++) { |
| 1146 | data[i] = gcr6bw_tb[gb(buf, ts, pos, wrap)] ^ c; |
| 1147 | c = data[i]; |
| 1148 | // printf("%02x ", c); |
| 1149 | // if (((i&0xf)+1)==0x10) printf("\n"); |
| 1150 | } |
| 1151 | // read the checksum byte |
| 1152 | data[0x156] = gcr6bw_tb[gb(buf,ts,pos,wrap)]; |
| 1153 | // now read the postamble bytes |
| 1154 | for(int i=0; i<3; i++) { |
| 1155 | dpost <<= 8; |
| 1156 | dpost |= gb(buf, ts, pos, wrap); |
| 1157 | } |
| 1158 | // next combine in the upper 2 bits of each byte |
| 1159 | UINT8 bit_swap[4] = { 0, 2, 1, 3 }; |
| 1160 | for(int i=0; i<0x56; i++) |
| 1161 | data[i+0x056] = data[i+0x056]<<2 | bit_swap[data[i]&3]; |
| 1162 | for(int i=0; i<0x56; i++) |
| 1163 | data[i+0x0ac] = data[i+0x0ac]<<2 | bit_swap[(data[i]>>2)&3]; |
| 1164 | for(int i=0; i<0x54; i++) |
| 1165 | data[i+0x102] = data[i+0x102]<<2 | bit_swap[(data[i]>>4)&3]; |
| 1166 | // now decode it into 256 bytes |
| 1167 | // but only write it if the bitfield of the track shows datagood is NOT set. |
| 1168 | // if it is set we don't want to overwrite a guaranteed good read with a bad one |
| 1169 | // if past read had a bad checksum or bad postamble... |
| 1170 | #ifndef USE_OLD_BEST_SECTOR_PRIORITY |
| 1171 | if (((visualgrid[se][0]&DATAGOOD)==0)||((visualgrid[se][0]&DATAPOST)==0)) { |
| 1172 | // if the current read is good, and postamble is good, write it in, no matter what. |
| 1173 | // if the current read is good and the current postamble is bad, write it in unless the postamble was good before |
| 1174 | // if the current read is bad and the current postamble is good and the previous read had neither good, write it in |
| 1175 | // if the current read isn't good and neither is the postamble but nothing better |
| 1176 | // has been written before, write it anyway. |
| 1177 | if ( ((data[0x156] == c) && (dpost&0xFFFF00)==0xDEAA00) || |
| 1178 | (((data[0x156] == c) && (dpost&0xFFFF00)!=0xDEAA00) && ((visualgrid[se][0]&DATAPOST)==0)) || |
| 1179 | (((data[0x156] != c) && (dpost&0xFFFF00)==0xDEAA00) && (((visualgrid[se][0]&DATAGOOD)==0)&&(visualgrid[se][0]&DATAPOST)==0)) || |
| 1180 | (((data[0x156] != c) && (dpost&0xFFFF00)!=0xDEAA00) && (((visualgrid[se][0]&DATAGOOD)==0)&&(visualgrid[se][0]&DATAPOST)==0)) |
| 1181 | ) { |
| 1182 | for(int i=0x56; i<0x156; i++) { |
| 1183 | UINT8 dv = data[i]; |
| 1184 | *dest++ = dv; |
| 1185 | } |
| 1186 | } |
| 1187 | } |
| 1188 | #else |
| 1189 | if ((visualgrid[se][0]&DATAGOOD)==0) { |
| 1190 | for(int i=0x56; i<0x156; i++) { |
| 1191 | UINT8 dv = data[i]; |
| 1192 | *dest++ = dv; |
| 1193 | } |
| 1194 | } |
| 1195 | #endif |
| 1196 | // do some checking |
| 1197 | if ((data[0x156] != c) || (dpost&0xFFFF00)!=0xDEAA00) |
| 1198 | fprintf(stderr,"Data Mark:\tChecksum xpctd %d found %d: %s, Postamble %03X: %s\n", data[0x156], c, (data[0x156]==c)?"OK":"BAD", dpost, (dpost&0xFFFF00)==0xDEAA00?"OK":"BAD"); |
| 1199 | if (data[0x156] == c) visualgrid[se][0] |= DATAGOOD; |
| 1200 | if ((dpost&0xFFFF00)==0xDEAA00) visualgrid[se][0] |= DATAPOST; |
| 1201 | } else if ((hb == 4)&&(dosver == 1)) { |
| 1202 | fprintf(stderr,"ERROR: We don't handle dos sectors below 3.3 yet!\n"); |
| 1203 | } else { |
| 1204 | pos = opos; |
| 1205 | wrap = owrap; |
| 1206 | } |
| 1207 | } |
| 1208 | } |
| 1209 | hb = 0; |
| 1210 | } |
| 1211 | if(wrap) |
| 1212 | break; |
| 1213 | } |
| 1214 | for(int i=0; i<nsect; i++) { |
| 1215 | //if(nsect>0) printf("t%d,", track); |
| 1216 | UINT8 *data = sectdata + (256)*i; |
| 1217 | io_generic_write(io, data, pos_data, 256); |
| 1218 | pos_data += 256; |
| 1219 | } |
| 1220 | |
| 1221 | // for the rest of the tracks |
| 1222 | for(int track=2; track < 70; track+=2) { |
| 1223 | UINT8 sectdata[(768)*6]; |
| 1224 | memset(sectdata, 0, sizeof(sectdata)); |
| 1225 | int nsect = 18; |
| 1226 | UINT8 buf[130000]; // originally 13000, multiread dfi disks need larger |
| 1227 | int ts; |
| 1228 | //fprintf(stderr,"DEBUG: a2_rwts18_format::save() about to generate bitstream from physical track %d (logical %d)...", track, track/2); |
| 1229 | //~332 samples per cell, times 3+8+3 (14) for address mark, 24 for sync, 3+343+3 (349) for data mark, 24 for sync is around 743, near 776 expected |
| 1230 | generate_bitstream_from_track(track, head, 200000000/((3004*nsect*6)/2), buf, ts, image); // 3104 needs tweaking |
| 1231 | //fprintf(stderr,"done.\n"); |
| 1232 | int pos = 0; |
| 1233 | int wrap = 0; |
| 1234 | int hb = 0; |
| 1235 | for(;;) { |
| 1236 | UINT8 v = gb(buf, ts, pos, wrap); |
| 1237 | if(v == 0xff) |
| 1238 | hb = 1; |
| 1239 | else if(hb == 1 && v == 0xd5) |
| 1240 | hb = 2; |
| 1241 | else if(hb == 2 && v == 0x9d) |
| 1242 | hb = 3; |
| 1243 | else |
| 1244 | hb = 0; |
| 1245 | |
| 1246 | if(hb == 3) { |
| 1247 | UINT8 h[11]; |
| 1248 | for(int i=0; i<7; i++) |
| 1249 | h[i] = gb(buf, ts, pos, wrap); |
| 1250 | UINT8 tr = gcr6bw_tb[h[0]]; |
| 1251 | UINT8 se = gcr6bw_tb[h[1]]; |
| 1252 | UINT8 chk = gcr6bw_tb[h[2]]; |
| 1253 | UINT32 post = (h[3]<<16)|(h[4]<<8)|h[5]; |
| 1254 | printf("RWTS18 AM:\t Track %d, Sector %2d, Checksum %02X: %s, Postamble %03X: %s\n", tr, se, chk, (chk ^ tr ^ se)==0?"OK":"BAD", post, post==0xAAFFFF?"OK":"BAD"); |
| 1255 | // sanity check |
| 1256 | if (tr == track/2 && se < nsect) { |
| 1257 | visualgrid[se][track/2] |= ADDRFOUND; |
| 1258 | visualgrid[se][track/2] |= ((chk ^ tr ^ se)==0)?ADDRGOOD:0; |
| 1259 | #ifdef LENIENT_ADDR_CHECK |
| 1260 | // if ((visualgrid[se][track/2] & ADDRFOUND) == ADDRFOUND) { |
| 1261 | #else |
| 1262 | if ((visualgrid[se][track/2] & ADDRGOOD) == ADDRGOOD) { |
| 1263 | #endif |
| 1264 | //int opos = pos; |
| 1265 | //int owrap = wrap; |
| 1266 | // RWTS18 doesn't have a true data mark, its part of the address header |
| 1267 | // The next byte however is unique per title |
| 1268 | v = gb(buf, ts, pos, wrap); |
| 1269 | printf("Data mark header per-title byte = 0x%2x\n", v); |
| 1270 | |
| 1271 | visualgrid[se][track/2] |= DATAFOUND; |
| 1272 | //UINT8 *dest = sectdata+(768)*se; |
| 1273 | UINT8 data[0x401]; |
| 1274 | UINT32 dpost = 0; |
| 1275 | UINT8 c = 0; |
| 1276 | // first read in the ENTIRE sector and decode to 6bit form |
| 1277 | for(int i=0; i<0x400; i++) { |
| 1278 | data[i] = gcr6bw_tb[gb(buf, ts, pos, wrap)] ^ c; |
| 1279 | c = data[i]; |
| 1280 | printf("%02x ", c); |
| 1281 | if (((i&0xf)+1)==0x10) printf("\n"); |
| 1282 | } |
| 1283 | // read the checksum byte |
| 1284 | data[0x400] = gcr6bw_tb[gb(buf,ts,pos,wrap)]; |
| 1285 | // now read the postamble byte |
| 1286 | for(int i=0; i<1; i++) { |
| 1287 | dpost <<= 8; |
| 1288 | dpost |= gb(buf, ts, pos, wrap); |
| 1289 | } |
| 1290 | printf("Data Postamble was 0x%02x\n", dpost); |
| 1291 | /* |
| 1292 | // next combine in the upper 2 bits of each byte |
| 1293 | UINT8 bit_swap[4] = { 0, 2, 1, 3 }; |
| 1294 | for(int i=0; i<0x56; i++) |
| 1295 | data[i+0x056] = data[i+0x056]<<2 | bit_swap[data[i]&3]; |
| 1296 | for(int i=0; i<0x56; i++) |
| 1297 | data[i+0x0ac] = data[i+0x0ac]<<2 | bit_swap[(data[i]>>2)&3]; |
| 1298 | for(int i=0; i<0x54; i++) |
| 1299 | data[i+0x102] = data[i+0x102]<<2 | bit_swap[(data[i]>>4)&3]; |
| 1300 | // now decode it into 256 bytes |
| 1301 | // but only write it if the bitfield of the track shows datagood is NOT set. |
| 1302 | // if it is set we don't want to overwrite a guaranteed good read with a bad one |
| 1303 | // if past read had a bad checksum or bad postamble... |
| 1304 | #ifndef USE_OLD_BEST_SECTOR_PRIORITY |
| 1305 | if (((visualgrid[se][track/2]&DATAGOOD)==0)||((visualgrid[se][track/2]&DATAPOST)==0)) { |
| 1306 | // if the current read is good, and postamble is good, write it in, no matter what. |
| 1307 | // if the current read is good and the current postamble is bad, write it in unless the postamble was good before |
| 1308 | // if the current read is bad and the current postamble is good and the previous read had neither good, write it in |
| 1309 | // if the current read isn't good and neither is the postamble but nothing better |
| 1310 | // has been written before, write it anyway. |
| 1311 | if ( ((data[0x156] == c) && (dpost&0xFFFF00)==0xDEAA00) || |
| 1312 | (((data[0x156] == c) && (dpost&0xFFFF00)!=0xDEAA00) && ((visualgrid[se][track/2]&DATAPOST)==0)) || |
| 1313 | (((data[0x156] != c) && (dpost&0xFFFF00)==0xDEAA00) && (((visualgrid[se][track/2]&DATAGOOD)==0)&&(visualgrid[se][track/2]&DATAPOST)==0)) || |
| 1314 | (((data[0x156] != c) && (dpost&0xFFFF00)!=0xDEAA00) && (((visualgrid[se][track/2]&DATAGOOD)==0)&&(visualgrid[se][track/2]&DATAPOST)==0)) |
| 1315 | ) { |
| 1316 | for(int i=0x56; i<0x156; i++) { |
| 1317 | UINT8 dv = data[i]; |
| 1318 | *dest++ = dv; |
| 1319 | } |
| 1320 | } |
| 1321 | } |
| 1322 | #else |
| 1323 | if ((visualgrid[se][track/2]&DATAGOOD)==0) { |
| 1324 | for(int i=0x56; i<0x156; i++) { |
| 1325 | UINT8 dv = data[i]; |
| 1326 | *dest++ = dv; |
| 1327 | } |
| 1328 | } |
| 1329 | #endif |
| 1330 | // do some checking |
| 1331 | if ((data[0x156] != c) || (dpost&0xFFFF00)!=0xDEAA00) |
| 1332 | fprintf(stderr,"Data Mark:\tChecksum xpctd %d found %d: %s, Postamble %03X: %s\n", data[0x156], c, (data[0x156]==c)?"OK":"BAD", dpost, (dpost&0xFFFF00)==0xDEAA00?"OK":"BAD"); |
| 1333 | if (data[0x156] == c) visualgrid[se][track/2] |= DATAGOOD; |
| 1334 | if ((dpost&0xFFFF00)==0xDEAA00) visualgrid[se][track/2] |= DATAPOST; |
| 1335 | } else if ((hb == 4)&&(dosver == 1)) { |
| 1336 | fprintf(stderr,"ERROR: We don't handle dos sectors below 3.3 yet!\n"); |
| 1337 | } else { |
| 1338 | pos = opos; |
| 1339 | wrap = owrap; |
| 1340 | }*/ |
| 1341 | } |
| 1342 | } |
| 1343 | hb = 0; |
| 1344 | } |
| 1345 | if(wrap) |
| 1346 | break; |
| 1347 | } |
| 1348 | for(int i=0; i<nsect; i++) { |
| 1349 | //if(nsect>0) printf("t%d,", track); |
| 1350 | UINT8 *data = sectdata + (256)*i; |
| 1351 | io_generic_write(io, data, pos_data, 256); |
| 1352 | pos_data += 256; |
| 1353 | } |
| 1354 | //printf("\n"); |
| 1355 | } |
| 1356 | // display a little table of which sectors decoded ok |
| 1357 | int total_good = 0; |
| 1358 | for (int j = 0; j < 35; j++) { |
| 1359 | printf("T%2d: ",j); |
| 1360 | for (int i = 0; i < 16; i++) { |
| 1361 | if (visualgrid[i][j] == NOTFOUND) printf("-NF- "); |
| 1362 | else { |
| 1363 | if (visualgrid[i][j] & ADDRFOUND) printf("a"); else printf(" "); |
| 1364 | if (visualgrid[i][j] & ADDRGOOD) printf("A"); else printf(" "); |
| 1365 | if (visualgrid[i][j] & DATAFOUND) printf("d"); else printf(" "); |
| 1366 | if (visualgrid[i][j] & DATAGOOD) { printf("D"); total_good++; } else printf(" "); |
| 1367 | if (visualgrid[i][j] & DATAPOST) printf("."); else printf(" "); |
| 1368 | } |
| 1369 | } |
| 1370 | printf("\n"); |
| 1371 | } |
| 1372 | printf("Total Good Sectors: %d\n", total_good); |
| 1373 | |
| 1374 | return true; |
| 1375 | } |
| 1376 | |
| 1377 | const floppy_format_type FLOPPY_RWTS18_FORMAT = &floppy_image_format_creator<a2_rwts18_format>; |
| | No newline at end of file |