branches/alto2/src/emu/cpu/alto2/a2drive.c
| r26100 | r26101 | |
| 20 | 20 | #define GUARD_ZONE_BITS (16*32) |
| 21 | 21 | |
| 22 | 22 | /** @brief write a bit into an array of UINT32 */ |
| 23 | | #define WRBIT(bits,dst,bit) do { \ |
| 24 | | if (bit) { \ |
| 25 | | bits[(dst)/32] |= 1 << ((dst) % 32); \ |
| 26 | | } else { \ |
| 27 | | bits[(dst)/32] &= ~(1 << ((dst) % 32)); \ |
| 28 | | } \ |
| 29 | | } while (0) |
| 23 | static inline size_t WRBIT(UINT32* bits, size_t dst, int bit) |
| 24 | { |
| 25 | if (bit) { |
| 26 | bits[(dst)/32] |= 1 << ((dst) % 32); |
| 27 | } else { |
| 28 | bits[(dst)/32] &= ~(1 << ((dst) % 32)); |
| 29 | } |
| 30 | return ++dst; |
| 31 | } |
| 30 | 32 | |
| 31 | 33 | /** @brief read a bit from an array of UINT32 */ |
| 32 | | #define RDBIT(bits,src) ((bits[(src)/32] >> ((src) % 32)) & 1) |
| 34 | static inline size_t RDBIT(UINT32* bits, size_t src, int& bit) |
| 35 | { |
| 36 | bit = (bits[src/32] >> (src % 32)) & 1; |
| 37 | return ++src; |
| 38 | } |
| 33 | 39 | |
| 34 | 40 | /** |
| 35 | 41 | * @brief calculate the sector from the logical block address |
| r26100 | r26101 | |
| 70 | 76 | */ |
| 71 | 77 | static int cksum(UINT8 *src, size_t size, int start) |
| 72 | 78 | { |
| 73 | | size_t offs; |
| 74 | 79 | int sum = start; |
| 75 | | int word; |
| 76 | | |
| 77 | 80 | /* compute XOR of all words */ |
| 78 | | for (offs = 0; offs < size; offs += 2) { |
| 79 | | word = src[size - 2 - offs] + 256 * src[size - 2 - offs + 1]; |
| 81 | for (size_t offs = 0; offs < size; offs += 2) { |
| 82 | int word = src[size - 2 - offs] + 256 * src[size - 2 - offs + 1]; |
| 80 | 83 | sum ^= word; |
| 81 | 84 | } |
| 82 | 85 | return sum; |
| r26100 | r26101 | |
| 92 | 95 | */ |
| 93 | 96 | static size_t expand_zeroes(UINT32 *bits, size_t dst, size_t size) |
| 94 | 97 | { |
| 95 | | size_t offs; |
| 96 | | |
| 97 | | for (offs = 0; offs < 32 * size; offs += 2) { |
| 98 | | WRBIT(bits, dst, 1); // write the clock bit |
| 99 | | dst++; |
| 100 | | WRBIT(bits, dst, 0); // write the 0 data bit |
| 101 | | dst++; |
| 98 | for (size_t offs = 0; offs < 32 * size; offs += 2) { |
| 99 | dst = WRBIT(bits, dst, 1); // write the clock bit |
| 100 | dst = WRBIT(bits, dst, 0); // write the 0 data bit |
| 102 | 101 | } |
| 103 | | |
| 104 | 102 | return dst; |
| 105 | 103 | } |
| 106 | 104 | |
| r26100 | r26101 | |
| 114 | 112 | */ |
| 115 | 113 | static size_t expand_sync(UINT32 *bits, size_t dst, size_t size) |
| 116 | 114 | { |
| 117 | | size_t offs; |
| 118 | | |
| 119 | | for (offs = 0; offs < 32 * size - 2; offs += 2) { |
| 120 | | WRBIT(bits, dst, 1); // write the clock bit |
| 121 | | dst++; |
| 122 | | WRBIT(bits, dst, 0); // write the 0 data bit |
| 123 | | dst++; |
| 115 | for (size_t offs = 0; offs < 32 * size - 2; offs += 2) { |
| 116 | dst = WRBIT(bits, dst, 1); // write the clock bit |
| 117 | dst = WRBIT(bits, dst, 0); // write the 0 data bit |
| 124 | 118 | } |
| 125 | | WRBIT(bits, dst, 1); // write the final clock bit |
| 126 | | dst++; |
| 127 | | WRBIT(bits, dst, 1); // write the 1 data bit |
| 128 | | dst++; |
| 119 | dst = WRBIT(bits, dst, 1); // write the final clock bit |
| 120 | dst = WRBIT(bits, dst, 1); // write the 1 data bit |
| 129 | 121 | return dst; |
| 130 | 122 | } |
| 131 | 123 | |
| r26100 | r26101 | |
| 140 | 132 | */ |
| 141 | 133 | static size_t expand_record(UINT32 *bits, size_t dst, UINT8 *field, size_t size) |
| 142 | 134 | { |
| 143 | | size_t offs, bit; |
| 144 | | |
| 145 | | for (offs = 0; offs < size; offs += 2) { |
| 135 | for (size_t offs = 0; offs < size; offs += 2) { |
| 146 | 136 | int word = field[size - 2 - offs] + 256 * field[size - 2 - offs + 1]; |
| 147 | | for (bit = 0; bit < 16; bit++) { |
| 148 | | WRBIT(bits, dst, 1); // write the clock bit |
| 149 | | dst++; |
| 150 | | WRBIT(bits, dst, (word >> 15) & 1); // write the data bit |
| 151 | | dst++; |
| 137 | for (size_t bit = 0; bit < 16; bit++) { |
| 138 | dst = WRBIT(bits, dst, 1); // write the clock bit |
| 139 | dst = WRBIT(bits, dst, (word >> 15) & 1); // write the data bit |
| 152 | 140 | word <<= 1; |
| 153 | 141 | } |
| 154 | 142 | } |
| r26100 | r26101 | |
| 166 | 154 | */ |
| 167 | 155 | static size_t expand_cksum(UINT32 *bits, size_t dst, UINT8 *field, size_t size) |
| 168 | 156 | { |
| 169 | | size_t bit; |
| 170 | 157 | int word = cksum(field, size, 0521); |
| 171 | | |
| 172 | | for (bit = 0; bit < 32; bit += 2) { |
| 173 | | /* write the clock bit */ |
| 174 | | WRBIT(bits, dst, 1); |
| 175 | | dst++; |
| 176 | | /* write the data bit */ |
| 177 | | WRBIT(bits, dst, (word >> 15) & 1); |
| 178 | | dst++; |
| 158 | for (size_t bit = 0; bit < 32; bit += 2) { |
| 159 | dst = WRBIT(bits, dst, 1); // write the clock bit |
| 160 | dst = WRBIT(bits, dst, (word >> 15) & 1); // write the data bit |
| 179 | 161 | word <<= 1; |
| 180 | 162 | } |
| 181 | 163 | return dst; |
| r26100 | r26101 | |
| 320 | 302 | */ |
| 321 | 303 | size_t alto2_cpu_device::squeeze_sync(UINT32 *bits, size_t src, size_t size) |
| 322 | 304 | { |
| 323 | | size_t offs, bitcount; |
| 324 | 305 | UINT32 accu = 0; |
| 325 | | |
| 326 | 306 | /* hunt for the first 0x0001 word */ |
| 327 | | for (bitcount = 0, offs = 0; offs < size; /* */) { |
| 307 | for (size_t bitcount = 0, offs = 0; offs < size; /* */) { |
| 328 | 308 | /* |
| 329 | 309 | * accumulate clock and data bits until we are |
| 330 | 310 | * on the clock bit boundary |
| 331 | 311 | */ |
| 332 | | accu = (accu << 1) | RDBIT(bits,src); |
| 333 | | src++; |
| 312 | int bit; |
| 313 | src = RDBIT(bits,src,bit); |
| 314 | accu = (accu << 1) | bit; |
| 334 | 315 | /* |
| 335 | 316 | * look for 15 alternating clocks and 0-bits |
| 336 | 317 | * and the 16th clock with a 1-bit |
| r26100 | r26101 | |
| 348 | 329 | } |
| 349 | 330 | |
| 350 | 331 | /** |
| 351 | | * @brief find a 0 bit sequence in an array of clock and data bits |
| 332 | * @brief find a 16 x 0 bits sequence in an array of clock and data bits |
| 352 | 333 | * |
| 353 | 334 | * @param bits pointer to the sector's bits |
| 354 | 335 | * @param src source offset into bits (bit number) |
| r26100 | r26101 | |
| 357 | 338 | */ |
| 358 | 339 | size_t alto2_cpu_device::squeeze_unsync(UINT32 *bits, size_t src, size_t size) |
| 359 | 340 | { |
| 360 | | size_t offs, bitcount; |
| 361 | 341 | UINT32 accu = 0; |
| 362 | | |
| 363 | | /* hunt for the first 0x0000 word */ |
| 364 | | for (bitcount = 0, offs = 0; offs < size; /* */) { |
| 342 | /* hunt for the first 0 word (16 x 0 bits) */ |
| 343 | for (size_t bitcount = 0, offs = 0; offs < size; /* */) { |
| 365 | 344 | /* |
| 366 | 345 | * accumulate clock and data bits until we are |
| 367 | 346 | * on the clock bit boundary |
| 368 | 347 | */ |
| 369 | | accu = (accu << 1) | RDBIT(bits,src); |
| 370 | | src++; |
| 348 | int bit; |
| 349 | src = RDBIT(bits,src,bit); |
| 350 | accu = (accu << 1) | bit; |
| 371 | 351 | /* |
| 372 | | * look for 15 alternating clocks and 0-bits |
| 373 | | * and the 16th clock with a 1-bit |
| 352 | * look for 16 alternating clocks and 0 data bits |
| 374 | 353 | */ |
| 375 | 354 | if (accu == 0xaaaaaaaa) |
| 376 | 355 | return src; |
| r26100 | r26101 | |
| 395 | 374 | */ |
| 396 | 375 | size_t alto2_cpu_device::squeeze_record(UINT32 *bits, size_t src, UINT8 *field, size_t size) |
| 397 | 376 | { |
| 398 | | size_t offs, bitcount; |
| 399 | 377 | UINT32 accu = 0; |
| 400 | | |
| 401 | | |
| 402 | | for (bitcount = 0, offs = 0; offs < size; /* */) { |
| 403 | | /* skip clock */ |
| 404 | | src++; |
| 405 | | /* get data bit */ |
| 406 | | accu = (accu << 1) | RDBIT(bits,src); |
| 407 | | src++; |
| 378 | for (size_t bitcount = 0, offs = 0; offs < size; /* */) { |
| 379 | int bit; |
| 380 | src = RDBIT(bits,src,bit); // skip clock |
| 381 | assert(bit == 1); |
| 382 | src = RDBIT(bits,src,bit); // get data bit |
| 383 | accu = (accu << 1) | bit; |
| 408 | 384 | bitcount += 2; |
| 409 | 385 | if (bitcount == 32) { |
| 410 | 386 | /* collected a word */ |
| r26100 | r26101 | |
| 427 | 403 | */ |
| 428 | 404 | size_t alto2_cpu_device::squeeze_cksum(UINT32 *bits, size_t src, int *cksum) |
| 429 | 405 | { |
| 430 | | size_t bitcount; |
| 431 | 406 | UINT32 accu = 0; |
| 432 | 407 | |
| 433 | | |
| 434 | | for (bitcount = 0; bitcount < 32; bitcount += 2) { |
| 435 | | /* skip clock */ |
| 436 | | src++; |
| 437 | | /* get data bit */ |
| 438 | | accu = (accu << 1) | RDBIT(bits,src); |
| 439 | | src++; |
| 408 | for (size_t bitcount = 0; bitcount < 32; bitcount += 2) { |
| 409 | int bit; |
| 410 | src = RDBIT(bits,src,bit); // skip clock |
| 411 | assert(bit == 1); |
| 412 | src = RDBIT(bits,src,bit); // get data bit |
| 413 | accu = (accu << 1) | bit; |
| 440 | 414 | } |
| 441 | 415 | |
| 442 | 416 | /* set the cksum to the extracted word */ |
| r26100 | r26101 | |
| 1073 | 1047 | if (-1 == d->rdfirst) |
| 1074 | 1048 | d->rdfirst = index; |
| 1075 | 1049 | |
| 1076 | | bit = RDBIT(bits,index); |
| 1050 | RDBIT(bits,index,bit); |
| 1077 | 1051 | LOG((LOG_DRIVE,7," read #%d %d/%d/%d bit #%d:%d\n", unit, d->cylinder, d->head, d->sector, index, bit)); |
| 1078 | 1052 | d->rdlast = index; |
| 1079 | 1053 | return bit; |
| r26100 | r26101 | |
| 1123 | 1097 | if (index & 1) { |
| 1124 | 1098 | clk = 0; |
| 1125 | 1099 | } else { |
| 1126 | | clk = RDBIT(bits,index); |
| 1100 | RDBIT(bits,index,clk); |
| 1127 | 1101 | } |
| 1128 | | |
| 1129 | 1102 | LOG((LOG_DRIVE,7, " read #%d %d/%d/%d clk #%d:%d\n", unit, d->cylinder, d->head, d->sector, index, clk)); |
| 1130 | | |
| 1131 | 1103 | d->rdlast = index; |
| 1132 | 1104 | return clk ^ 1; |
| 1133 | 1105 | } |
| r26100 | r26101 | |
| 1144 | 1116 | { |
| 1145 | 1117 | diablo_drive_t *d = m_drive[unit]; |
| 1146 | 1118 | UINT32 *bits; |
| 1147 | | UINT32 accu; |
| 1148 | 1119 | |
| 1149 | 1120 | if (unit < 0 || unit > 1) |
| 1150 | 1121 | return 0; |
| r26100 | r26101 | |
| 1167 | 1138 | return 0; |
| 1168 | 1139 | } |
| 1169 | 1140 | |
| 1170 | | accu = 0; |
| 1141 | UINT32 accu = 0; |
| 1171 | 1142 | while (offs < 400 * 32) { |
| 1172 | | accu = (accu << 1) | RDBIT(bits,offs); |
| 1173 | | offs++; |
| 1143 | int bit; |
| 1144 | offs = RDBIT(bits,offs,bit); |
| 1145 | accu = (accu << 1) | bit; |
| 1174 | 1146 | if (accu == 0xaaaaaaab) |
| 1175 | 1147 | break; |
| 1176 | 1148 | } |
| r26100 | r26101 | |
| 1213 | 1185 | return 0177777; |
| 1214 | 1186 | } |
| 1215 | 1187 | |
| 1216 | | for (i = 0, clks = 0, word = 0; i < 16; i++, offs += 2) { |
| 1217 | | clks = (clks << 1) | RDBIT(bits,offs); |
| 1218 | | word = (word << 1) | RDBIT(bits,offs+1); |
| 1188 | for (i = 0, clks = 0, word = 0; i < 16; i++) { |
| 1189 | int bit; |
| 1190 | offs = RDBIT(bits,offs,bit); |
| 1191 | clks = (clks << 1) | bit; |
| 1192 | offs = RDBIT(bits,offs,bit); |
| 1193 | word = (word << 1) | bit; |
| 1219 | 1194 | } |
| 1220 | 1195 | |
| 1221 | 1196 | return word; |
| r26100 | r26101 | |
| 1358 | 1333 | if (unit == DRIVE_MAX) |
| 1359 | 1334 | return -1; |
| 1360 | 1335 | |
| 1361 | | d = reinterpret_cast<diablo_drive_t *>(m_drive[unit]); |
| 1336 | d = m_drive[unit]; |
| 1362 | 1337 | |
| 1363 | 1338 | snprintf(d->basename, sizeof(d->basename), "%s", basename); |
| 1364 | 1339 | |
| r26100 | r26101 | |
| 1485 | 1460 | 267 * 2, sizeof(diablo_sector_t)); |
| 1486 | 1461 | |
| 1487 | 1462 | for (i = 0; i < DIABLO_DRIVE_MAX; i++) { |
| 1488 | | // FIXME: use MAME resource system(?) |
| 1489 | 1463 | diablo_drive_t *d = reinterpret_cast<diablo_drive_t *>(auto_alloc_clear(machine(), diablo_drive_t)); |
| 1490 | 1464 | m_drive[i] = d; |
| 1491 | 1465 | |