trunk/src/emu/bus/ieee488/c8050fdc.c
| r245709 | r245710 | |
| 13 | 13 | |
| 14 | 14 | TODO: |
| 15 | 15 | |
| 16 | | - write mode |
| 17 | 16 | - write protect |
| 18 | | - separate read/write methods |
| 19 | 17 | |
| 20 | 18 | */ |
| 21 | 19 | |
| r245709 | r245710 | |
| 28 | 26 | //************************************************************************** |
| 29 | 27 | |
| 30 | 28 | #define LOG 0 |
| 29 | #define LOG_MORE 0 |
| 30 | #define LOG_BITS 0 |
| 31 | 31 | |
| 32 | 32 | #define GCR_DECODE(_e, _i) \ |
| 33 | 33 | ((BIT(_e, 6) << 7) | (BIT(_i, 7) << 6) | (_e & 0x33) | (BIT(_e, 2) << 3) | (_i & 0x04)) |
| r245709 | r245710 | |
| 74 | 74 | //------------------------------------------------- |
| 75 | 75 | |
| 76 | 76 | c8050_fdc_t::c8050_fdc_t(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 77 | | device_t(mconfig, C8050_FDC, "C8050 FDC", tag, owner, clock, "c8050fdc", __FILE__), |
| 77 | device_t(mconfig, C8050_FDC, "Commodore 8050 FDC", tag, owner, clock, "c8050fdc", __FILE__), |
| 78 | 78 | m_write_sync(*this), |
| 79 | 79 | m_write_ready(*this), |
| 80 | 80 | m_write_brdy(*this), |
| r245709 | r245710 | |
| 89 | 89 | m_ds(0), |
| 90 | 90 | m_drv_sel(0), |
| 91 | 91 | m_mode_sel(0), |
| 92 | | m_rw_sel(0) |
| 92 | m_rw_sel(1) |
| 93 | 93 | { |
| 94 | 94 | cur_live.tm = attotime::never; |
| 95 | 95 | cur_live.state = IDLE; |
| r245709 | r245710 | |
| 210 | 210 | { |
| 211 | 211 | live_sync(); |
| 212 | 212 | m_ds = cur_live.ds = ds; |
| 213 | | pll_reset(cur_live.tm, attotime::from_hz(clock() / (16 - m_ds))); |
| 213 | pll_reset(cur_live.tm); |
| 214 | if (LOG) logerror("%s %s DS %u\n", machine().time().as_string(), machine().describe_context(), ds); |
| 214 | 215 | checkpoint(); |
| 215 | 216 | live_run(); |
| 216 | 217 | } |
| r245709 | r245710 | |
| 240 | 241 | cur_live.rw_sel = m_rw_sel; |
| 241 | 242 | cur_live.pi = m_pi; |
| 242 | 243 | |
| 243 | | pll_reset(cur_live.tm, attotime::from_hz(clock() / (16 - m_ds))); |
| 244 | pll_reset(cur_live.tm); |
| 244 | 245 | checkpoint_live = cur_live; |
| 245 | 246 | pll_save_checkpoint(); |
| 246 | 247 | |
| 247 | 248 | live_run(); |
| 248 | 249 | } |
| 249 | 250 | |
| 250 | | void c8050_fdc_t::pll_reset(const attotime &when, const attotime &clock) |
| 251 | void c8050_fdc_t::pll_reset(const attotime &when) |
| 251 | 252 | { |
| 252 | 253 | cur_pll.reset(when); |
| 253 | | cur_pll.set_clock(clock); |
| 254 | cur_pll.set_clock(attotime::from_hz(clock() / (16 - m_ds))); |
| 254 | 255 | } |
| 255 | 256 | |
| 256 | 257 | void c8050_fdc_t::pll_start_writing(const attotime &tm) |
| 257 | 258 | { |
| 258 | 259 | cur_pll.start_writing(tm); |
| 260 | pll_reset(cur_live.tm); |
| 259 | 261 | } |
| 260 | 262 | |
| 261 | 263 | void c8050_fdc_t::pll_commit(floppy_image_device *floppy, const attotime &tm) |
| r245709 | r245710 | |
| 266 | 268 | void c8050_fdc_t::pll_stop_writing(floppy_image_device *floppy, const attotime &tm) |
| 267 | 269 | { |
| 268 | 270 | cur_pll.stop_writing(floppy, tm); |
| 271 | pll_reset(cur_live.tm); |
| 269 | 272 | } |
| 270 | 273 | |
| 271 | 274 | void c8050_fdc_t::pll_save_checkpoint() |
| r245709 | r245710 | |
| 285 | 288 | |
| 286 | 289 | bool c8050_fdc_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit) |
| 287 | 290 | { |
| 288 | | return cur_pll.write_next_bit_prev_cell(bit, tm, floppy, limit); |
| 291 | return cur_pll.write_next_bit(bit, tm, floppy, limit); |
| 289 | 292 | } |
| 290 | 293 | |
| 291 | 294 | void c8050_fdc_t::checkpoint() |
| r245709 | r245710 | |
| 366 | 369 | return; |
| 367 | 370 | |
| 368 | 371 | // read bit |
| 369 | | int bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); |
| 370 | | if(bit < 0) |
| 371 | | return; |
| 372 | int bit = 0; |
| 373 | if (cur_live.rw_sel) { |
| 374 | bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); |
| 375 | if(bit < 0) |
| 376 | return; |
| 377 | } |
| 372 | 378 | |
| 379 | // write bit |
| 380 | int write_bit = BIT(cur_live.shift_reg_write, 9); |
| 381 | if (!cur_live.rw_sel) { // TODO WPS |
| 382 | /* |
| 383 | write precompensation |
| 384 | |
| 385 | UA5.A = UM6.Qc |
| 386 | UA5.B = !(!(!BRDY && UM6.Qa) && !(BRDY && E7)) |
| 387 | UA5.C0 = UA4.Qb = bit clock delayed 333ns |
| 388 | UA5.C1 = UA4.Qa = bit clock delayed 166ns |
| 389 | UA5.C2 = UA4.Qc = bit clock delayed 499ns |
| 390 | UA5.C3 = UA5.Qb = bit clock delayed 333ns |
| 391 | |
| 392 | DATA OUT = !(!BITCLK || !(UA5.Y && !(WRITE_ENABLE && !UM6.Qb))) |
| 393 | */ |
| 394 | if (pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit)) |
| 395 | return; |
| 396 | } |
| 397 | |
| 398 | // clock read shift register |
| 373 | 399 | cur_live.shift_reg <<= 1; |
| 374 | 400 | cur_live.shift_reg |= bit; |
| 375 | 401 | cur_live.shift_reg &= 0x3ff; |
| r245709 | r245710 | |
| 378 | 404 | int sync = !((cur_live.shift_reg == 0x3ff) && cur_live.rw_sel); |
| 379 | 405 | |
| 380 | 406 | // bit counter |
| 381 | | if (cur_live.rw_sel) { |
| 382 | | if (!sync) { |
| 383 | | cur_live.bit_counter = 0; |
| 384 | | } else if (cur_live.sync) { |
| 385 | | cur_live.bit_counter++; |
| 386 | | if (cur_live.bit_counter == 10) { |
| 387 | | cur_live.bit_counter = 0; |
| 388 | | } |
| 389 | | } |
| 390 | | } else { |
| 407 | if (!sync) { |
| 408 | cur_live.bit_counter = 0; |
| 409 | } else if (cur_live.sync) { |
| 391 | 410 | cur_live.bit_counter++; |
| 392 | 411 | if (cur_live.bit_counter == 10) { |
| 393 | 412 | cur_live.bit_counter = 0; |
| r245709 | r245710 | |
| 403 | 422 | |
| 404 | 423 | cur_live.e = m_gcr_rom->base()[cur_live.i]; |
| 405 | 424 | |
| 406 | | if (LOG) logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e); |
| 407 | | |
| 408 | 425 | // byte ready |
| 409 | 426 | int ready = !(cur_live.bit_counter == 9); // 74190 _RC, should be triggered on the falling edge of the clock |
| 410 | 427 | int brdy = ready; // 74190 TC |
| r245709 | r245710 | |
| 412 | 429 | // GCR error |
| 413 | 430 | int error = !(ready || BIT(cur_live.e, 3)); |
| 414 | 431 | |
| 415 | | // write bit |
| 416 | | if (!cur_live.rw_sel) { // TODO WPS |
| 417 | | int write_bit = BIT(cur_live.shift_reg_write, 9); |
| 418 | | if (LOG) logerror("%s writing bit %u sr %03x\n",cur_live.tm.as_string(),write_bit,cur_live.shift_reg_write); |
| 419 | | pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit); |
| 432 | if (LOG_BITS) { |
| 433 | if (cur_live.rw_sel) { |
| 434 | logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e); |
| 435 | } else { |
| 436 | logerror("%s cyl %u writing bit %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),write_bit,cur_live.bit_counter,cur_live.shift_reg_write,cur_live.i,cur_live.e); |
| 437 | } |
| 420 | 438 | } |
| 421 | 439 | |
| 422 | 440 | if (!ready) { |
| 423 | 441 | // load write shift register |
| 424 | 442 | cur_live.shift_reg_write = GCR_ENCODE(cur_live.e, cur_live.i); |
| 425 | 443 | |
| 426 | | if (LOG) logerror("%s load write shift register %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write); |
| 444 | if (LOG_BITS) logerror("%s load write shift register %03x\n",cur_live.tm.as_string(),cur_live.shift_reg_write); |
| 427 | 445 | } else { |
| 428 | 446 | // clock write shift register |
| 429 | 447 | cur_live.shift_reg_write <<= 1; |
| r245709 | r245710 | |
| 431 | 449 | } |
| 432 | 450 | |
| 433 | 451 | if (ready != cur_live.ready) { |
| 434 | | if (LOG) logerror("%s READY %u : %02x\n", cur_live.tm.as_string(),ready,GCR_DECODE(cur_live.e, cur_live.i)); |
| 452 | if (cur_live.rw_sel && !ready) |
| 453 | if (LOG) logerror("%s READY %u : %02x\n", cur_live.tm.as_string(),ready,GCR_DECODE(cur_live.e, cur_live.i)); |
| 435 | 454 | cur_live.ready = ready; |
| 436 | 455 | syncpoint = true; |
| 437 | 456 | } |
| 438 | 457 | |
| 439 | 458 | if (brdy != cur_live.brdy) { |
| 440 | | if (LOG) logerror("%s BRDY %u\n", cur_live.tm.as_string(), brdy); |
| 459 | if (LOG_MORE) logerror("%s BRDY %u\n", cur_live.tm.as_string(), brdy); |
| 441 | 460 | cur_live.brdy = brdy; |
| 442 | 461 | syncpoint = true; |
| 443 | 462 | } |
| r245709 | r245710 | |
| 449 | 468 | } |
| 450 | 469 | |
| 451 | 470 | if (error != cur_live.error) { |
| 452 | | if (LOG) logerror("%s ERROR %u\n", cur_live.tm.as_string(), error); |
| 471 | if (LOG_MORE) logerror("%s ERROR %u\n", cur_live.tm.as_string(), error); |
| 453 | 472 | cur_live.error = error; |
| 454 | 473 | syncpoint = true; |
| 455 | 474 | } |
| r245709 | r245710 | |
| 462 | 481 | } |
| 463 | 482 | |
| 464 | 483 | case RUNNING_SYNCPOINT: { |
| 465 | | if (LOG) { |
| 466 | | if (!cur_live.sync) logerror("%s SYNC\n",cur_live.tm.as_string()); |
| 467 | | if (!cur_live.ready && cur_live.bit_counter == 9) logerror("%s DATA %02x\n",cur_live.tm.as_string(),GCR_DECODE(cur_live.e,cur_live.i)); |
| 468 | | } |
| 469 | 484 | m_write_ready(cur_live.ready); |
| 470 | 485 | m_write_brdy(cur_live.brdy); |
| 471 | 486 | m_write_sync(cur_live.sync); |
| r245709 | r245710 | |
| 484 | 499 | UINT8 e = checkpoint_live.e; |
| 485 | 500 | offs_t i = checkpoint_live.i; |
| 486 | 501 | |
| 487 | | UINT8 data = GCR_DECODE(e, i); |
| 488 | | |
| 489 | | if (LOG)logerror("%s %s VIA reads data %02x (%03x)\n", machine().time().as_string(), machine().describe_context(), data, checkpoint_live.shift_reg); |
| 490 | | |
| 491 | | return data; |
| 502 | return GCR_DECODE(e, i); |
| 492 | 503 | } |
| 493 | 504 | |
| 494 | 505 | WRITE8_MEMBER( c8050_fdc_t::write ) |
| 495 | 506 | { |
| 507 | if (LOG) logerror("%s %s PI %02x\n", machine().time().as_string(), machine().describe_context(), data); |
| 508 | |
| 496 | 509 | if (m_pi != data) |
| 497 | 510 | { |
| 498 | 511 | live_sync(); |
| 499 | 512 | m_pi = cur_live.pi = data; |
| 500 | 513 | checkpoint(); |
| 501 | | if (LOG) logerror("%s %s PI %02x\n", machine().time().as_string(), machine().describe_context(), data); |
| 502 | 514 | live_run(); |
| 503 | 515 | } |
| 504 | 516 | } |
| r245709 | r245710 | |
| 548 | 560 | checkpoint(); |
| 549 | 561 | if (LOG) logerror("%s %s RW SEL %u\n", machine().time().as_string(), machine().describe_context(), state); |
| 550 | 562 | if (m_rw_sel) { |
| 551 | | pll_stop_writing(get_floppy(), machine().time()); |
| 563 | pll_stop_writing(get_floppy(), cur_live.tm); |
| 552 | 564 | } else { |
| 553 | | pll_start_writing(machine().time()); |
| 565 | pll_start_writing(cur_live.tm); |
| 554 | 566 | } |
| 555 | 567 | live_run(); |
| 556 | 568 | } |
| r245709 | r245710 | |
| 616 | 628 | |
| 617 | 629 | WRITE_LINE_MEMBER( c8050_fdc_t::pull_sync_w ) |
| 618 | 630 | { |
| 619 | | if (LOG) logerror("%s %s PULL SYNC %u\n", machine().time().as_string(), machine().describe_context(), state); |
| 631 | if (LOG_MORE) logerror("%s %s PULL SYNC %u\n", machine().time().as_string(), machine().describe_context(), state); |
| 620 | 632 | } |
trunk/src/mess/machine/victor9k_fdc.c
| r245709 | r245710 | |
| 54 | 54 | #define LOG 0 |
| 55 | 55 | #define LOG_VIA 0 |
| 56 | 56 | #define LOG_SCP 0 |
| 57 | #define LOG_BITS 0 |
| 57 | 58 | |
| 58 | 59 | #define I8048_TAG "5d" |
| 59 | 60 | #define M6522_4_TAG "1f" |
| r245709 | r245710 | |
| 1069 | 1070 | cur_live.wrsync = m_wrsync; |
| 1070 | 1071 | cur_live.erase = m_erase; |
| 1071 | 1072 | |
| 1072 | | pll_reset(cur_live.tm, attotime::from_nsec(2130)); |
| 1073 | pll_reset(cur_live.tm); |
| 1073 | 1074 | checkpoint_live = cur_live; |
| 1074 | 1075 | pll_save_checkpoint(); |
| 1075 | 1076 | |
| 1076 | 1077 | live_run(); |
| 1077 | 1078 | } |
| 1078 | 1079 | |
| 1079 | | void victor_9000_fdc_t::pll_reset(const attotime &when, const attotime &clock) |
| 1080 | void victor_9000_fdc_t::pll_reset(const attotime &when) |
| 1080 | 1081 | { |
| 1081 | 1082 | cur_pll.reset(when); |
| 1082 | | cur_pll.set_clock(clock); |
| 1083 | cur_pll.set_clock(attotime::from_nsec(2130)); |
| 1083 | 1084 | } |
| 1084 | 1085 | |
| 1085 | 1086 | void victor_9000_fdc_t::pll_start_writing(const attotime &tm) |
| 1086 | 1087 | { |
| 1087 | 1088 | cur_pll.start_writing(tm); |
| 1089 | pll_reset(cur_live.tm); |
| 1088 | 1090 | } |
| 1089 | 1091 | |
| 1090 | 1092 | void victor_9000_fdc_t::pll_commit(floppy_image_device *floppy, const attotime &tm) |
| r245709 | r245710 | |
| 1095 | 1097 | void victor_9000_fdc_t::pll_stop_writing(floppy_image_device *floppy, const attotime &tm) |
| 1096 | 1098 | { |
| 1097 | 1099 | cur_pll.stop_writing(floppy, tm); |
| 1100 | pll_reset(cur_live.tm); |
| 1098 | 1101 | } |
| 1099 | 1102 | |
| 1100 | 1103 | void victor_9000_fdc_t::pll_save_checkpoint() |
| r245709 | r245710 | |
| 1114 | 1117 | |
| 1115 | 1118 | bool victor_9000_fdc_t::pll_write_next_bit(bool bit, attotime &tm, floppy_image_device *floppy, const attotime &limit) |
| 1116 | 1119 | { |
| 1117 | | return cur_pll.write_next_bit_prev_cell(bit, tm, floppy, limit); |
| 1120 | return cur_pll.write_next_bit(bit, tm, floppy, limit); |
| 1118 | 1121 | } |
| 1119 | 1122 | |
| 1120 | 1123 | void victor_9000_fdc_t::checkpoint() |
| r245709 | r245710 | |
| 1197 | 1200 | return; |
| 1198 | 1201 | |
| 1199 | 1202 | // read bit |
| 1200 | | int bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); |
| 1201 | | if(bit < 0) |
| 1202 | | return; |
| 1203 | int bit = 0; |
| 1204 | if (cur_live.drw) { |
| 1205 | bit = pll_get_next_bit(cur_live.tm, get_floppy(), limit); |
| 1206 | if(bit < 0) |
| 1207 | return; |
| 1208 | } |
| 1203 | 1209 | |
| 1210 | // write bit |
| 1211 | int write_bit = 0; |
| 1212 | if (!cur_live.drw) { // TODO WPS |
| 1213 | write_bit = BIT(cur_live.shift_reg_write, 9); |
| 1214 | if (pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit)) |
| 1215 | return; |
| 1216 | } |
| 1217 | |
| 1218 | // clock read shift register |
| 1204 | 1219 | cur_live.shift_reg <<= 1; |
| 1205 | 1220 | cur_live.shift_reg |= bit; |
| 1206 | 1221 | cur_live.shift_reg &= 0x3ff; |
| r245709 | r245710 | |
| 1261 | 1276 | // GCR error |
| 1262 | 1277 | int gcr_err = !(brdy || BIT(cur_live.e, 3)); |
| 1263 | 1278 | |
| 1264 | | // write bit |
| 1265 | | if (!cur_live.drw) { // TODO WPS |
| 1266 | | int write_bit = BIT(cur_live.shift_reg_write, 9); |
| 1267 | | if (LOG) logerror("%s writing bit %u sr %03x\n",cur_live.tm.as_string(),write_bit,cur_live.shift_reg_write); |
| 1268 | | pll_write_next_bit(write_bit, cur_live.tm, get_floppy(), limit); |
| 1279 | if (LOG_BITS) { |
| 1280 | if (cur_live.drw) { |
| 1281 | logerror("%s cyl %u bit %u sync %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),bit,sync,cur_live.bit_counter,cur_live.shift_reg,cur_live.i,cur_live.e); |
| 1282 | } else { |
| 1283 | logerror("%s cyl %u writing bit %u bc %u sr %03x i %03x e %02x\n",cur_live.tm.as_string(),get_floppy()->get_cyl(),write_bit,cur_live.bit_counter,cur_live.shift_reg_write,cur_live.i,cur_live.e); |
| 1284 | } |
| 1269 | 1285 | } |
| 1270 | 1286 | |
| 1271 | 1287 | if (!brdy) { |