src/mess/machine/mb89352.c
| r14681 | r14682 | |
| 165 | 165 | m_error_status = 0x00; |
| 166 | 166 | m_transfer_count = 0; |
| 167 | 167 | m_spc_status = 0x05; // presumably the data reg is empty to start with |
| 168 | | m_ints = 0x00; |
| 169 | 168 | |
| 170 | 169 | mb89352_rescan(); |
| 171 | 170 | } |
| r14681 | r14682 | |
| 236 | 235 | { |
| 237 | 236 | case SCSI_PHASE_BUS_FREE: |
| 238 | 237 | m_line_status = 0; |
| 239 | | if(m_int_enable != 0) |
| 240 | | m_irq_func(1); |
| 238 | m_spc_status &= ~SSTS_XFER_IN_PROGRESS; |
| 241 | 239 | break; |
| 242 | 240 | case SCSI_PHASE_COMMAND: |
| 243 | 241 | m_line_status |= MB89352_LINE_REQ; |
| r14681 | r14682 | |
| 329 | 327 | #define SERR_OFFSET 0x01*/ |
| 330 | 328 | return 0; |
| 331 | 329 | case 0x08: // PCTL - Phase Control |
| 332 | | return ((m_busfree_int_enable) ? 0x80 : 0x00); |
| 330 | return ((m_busfree_int_enable) ? (m_line_status & 0x07) | 0x80 : (m_line_status & 0x07)); |
| 333 | 331 | case 0x0a: // DREG - Data register (for data transfers) |
| 334 | 332 | if(m_spc_status | SSTS_XFER_IN_PROGRESS) |
| 335 | 333 | { |
| r14681 | r14682 | |
| 344 | 342 | m_spc_status &= ~SSTS_XFER_IN_PROGRESS; |
| 345 | 343 | m_spc_status |= SSTS_DREG_EMPTY; |
| 346 | 344 | m_ints |= INTS_COMMAND_COMPLETE; |
| 347 | | set_phase(SCSI_PHASE_STATUS); |
| 345 | if(m_int_enable != 0) |
| 346 | m_irq_func(1); |
| 347 | if(m_phase == SCSI_PHASE_MESSAGE_IN) |
| 348 | set_phase(SCSI_PHASE_BUS_FREE); |
| 349 | else if(m_phase == SCSI_PHASE_DATAIN) |
| 350 | set_phase(SCSI_PHASE_STATUS); |
| 348 | 351 | } |
| 349 | 352 | } |
| 350 | 353 | return m_data; |
| 351 | 354 | case 0x0b: // TEMP - Temporary |
| 355 | logerror("mb89352: read temporary register.\n"); |
| 352 | 356 | return m_temp; |
| 353 | 357 | case 0x0c: // TCH - Transfer Counter High |
| 354 | 358 | return (m_transfer_count & 0x00ff0000) >> 16; |
| r14681 | r14682 | |
| 377 | 381 | case 0x01: // SCTL - SPC Control |
| 378 | 382 | if(data & 0x80) // reset and disable |
| 379 | 383 | { |
| 380 | | m_ints |= INTS_RESET; |
| 381 | 384 | device_reset(); |
| 382 | 385 | logerror("mb89352: SCTL: Reset and disable.\n"); |
| 383 | 386 | } |
| r14681 | r14682 | |
| 397 | 400 | m_parity_enable = 0; |
| 398 | 401 | if(data & 0x04) |
| 399 | 402 | { |
| 400 | | m_resel_enable = 1; |
| 401 | | logerror("mb89352: SCTL: Reselection enabled.\n"); |
| 403 | m_sel_enable = 1; |
| 404 | logerror("mb89352: SCTL: Selection enabled.\n"); |
| 402 | 405 | } |
| 403 | 406 | else |
| 404 | | m_resel_enable = 0; |
| 407 | m_sel_enable = 0; |
| 405 | 408 | if(data & 0x02) |
| 406 | 409 | { |
| 407 | | m_sel_enable = 1; |
| 408 | | logerror("mb89352: SCTL: Selection enabled.\n"); |
| 410 | m_resel_enable = 1; |
| 411 | logerror("mb89352: SCTL: Reselection enabled.\n"); |
| 409 | 412 | } |
| 410 | 413 | else |
| 411 | | m_sel_enable = 0; |
| 414 | m_resel_enable = 0; |
| 412 | 415 | if(data & 0x01) |
| 413 | 416 | { |
| 414 | 417 | m_int_enable = 1; |
| r14681 | r14682 | |
| 421 | 424 | } |
| 422 | 425 | break; |
| 423 | 426 | case 0x02: // SCMD - Command |
| 424 | | /* From NetBSD source |
| 427 | /* From NetBSD/x68k source |
| 425 | 428 | #define SCMD_BUS_REL 0x00 |
| 426 | 429 | #define SCMD_SELECT 0x20 |
| 427 | 430 | #define SCMD_RST_ATN 0x40 |
| r14681 | r14682 | |
| 439 | 442 | m_line_status = 0; |
| 440 | 443 | m_spc_status &= ~SSTS_TARG_CONNECTED; |
| 441 | 444 | m_spc_status &= ~SSTS_INIT_CONNECTED; |
| 445 | m_spc_status &= ~SSTS_XFER_IN_PROGRESS; |
| 446 | set_phase(SCSI_PHASE_BUS_FREE); |
| 447 | if(m_busfree_int_enable) |
| 448 | { |
| 449 | if(m_int_enable != 0) |
| 450 | m_irq_func(1); |
| 451 | } |
| 442 | 452 | logerror("mb89352: SCMD: Bus free\n"); |
| 443 | 453 | break; |
| 444 | 454 | case 0x01: |
| r14681 | r14682 | |
| 458 | 468 | } |
| 459 | 469 | if(m_sel_enable != 0) |
| 460 | 470 | { |
| 461 | | m_ints |= INTS_SELECTION; |
| 471 | //m_ints |= INTS_SELECTION; |
| 462 | 472 | } |
| 463 | | set_phase(SCSI_PHASE_COMMAND); // straight to command phase, may need a delay betweem selection and command phases |
| 473 | set_phase(SCSI_PHASE_COMMAND); // straight to command phase, may need a delay between selection and command phases |
| 464 | 474 | m_line_status |= MB89352_LINE_SEL; |
| 465 | | if(m_int_enable != 0) |
| 466 | | m_irq_func(1); |
| 467 | 475 | m_line_status |= MB89352_LINE_BSY; |
| 468 | 476 | m_spc_status &= ~SSTS_TARG_CONNECTED; |
| 469 | 477 | m_spc_status |= SSTS_INIT_CONNECTED; |
| 470 | 478 | m_spc_status |= SSTS_SPC_BSY; |
| 471 | 479 | m_ints |= INTS_COMMAND_COMPLETE; |
| 480 | if(m_int_enable != 0) |
| 481 | m_irq_func(1); |
| 472 | 482 | logerror("mb89352: SCMD: Selection (SCSI ID%i)\n",m_target); |
| 473 | 483 | break; |
| 474 | 484 | case 0x02: // Reset ATN |
| r14681 | r14682 | |
| 484 | 494 | m_spc_status |= SSTS_XFER_IN_PROGRESS; |
| 485 | 495 | if(m_phase == SCSI_PHASE_DATAIN) // if we are reading data... |
| 486 | 496 | { |
| 487 | | m_spc_status &= ~SSTS_DREG_EMPTY; // DREG is no longer empty, but apparently it's not full either. |
| 497 | m_spc_status &= ~SSTS_DREG_EMPTY; // DREG is no longer empty |
| 488 | 498 | SCSIReadData(m_SCSIdevices[m_target],m_buffer,512); |
| 489 | 499 | } |
| 500 | if(m_phase == SCSI_PHASE_MESSAGE_IN) |
| 501 | { |
| 502 | m_spc_status &= ~SSTS_DREG_EMPTY; // DREG is no longer empty |
| 503 | m_data = 0; |
| 504 | m_temp = 0x00; |
| 505 | set_phase(SCSI_PHASE_BUS_FREE); |
| 506 | m_spc_status &= ~SSTS_XFER_IN_PROGRESS; |
| 507 | m_command_index = 0; |
| 508 | } |
| 490 | 509 | logerror("mb89352: SCMD: Start Transfer\n"); |
| 491 | 510 | break; |
| 492 | 511 | case 0x05: // Transfer pause |
| r14681 | r14682 | |
| 568 | 587 | logerror("mb89352: PCTL selection cancelled\n"); |
| 569 | 588 | } |
| 570 | 589 | // writing to the low 3 bits sets the phase |
| 571 | | m_phase = data & 0x07; |
| 572 | | m_line_status |= (data & 0x07); |
| 590 | if((m_phase & 0x07) != (data & 0x07)) |
| 591 | set_phase(data & 0x07); |
| 592 | m_busfree_int_enable = data & 0x80; |
| 573 | 593 | logerror("mb89352: PCTL write %02x\n",data); |
| 574 | 594 | break; |
| 575 | 595 | case 0x0a: // DREG - Data register |
| 596 | if(m_phase == SCSI_PHASE_COMMAND) |
| 597 | { |
| 598 | m_command[m_command_index++] = data; |
| 599 | if(m_command_index >= get_scsi_cmd_len(m_command[0])) |
| 600 | { |
| 601 | int x; |
| 602 | int phase; |
| 603 | // execute SCSI command |
| 604 | SCSISetCommand(m_SCSIdevices[m_target],m_command,m_command_index); |
| 605 | SCSIExecCommand(m_SCSIdevices[m_target],&m_result_length); |
| 606 | SCSIGetPhase(m_SCSIdevices[m_target],&phase); |
| 607 | if(m_command[0] == 1) // Rezero Unit - not implemented in SCSI code |
| 608 | set_phase(SCSI_PHASE_STATUS); |
| 609 | else |
| 610 | set_phase(phase); |
| 611 | logerror("Command executed: "); |
| 612 | for(x=0;x<m_command_index;x++) |
| 613 | logerror(" %02x",m_command[x]); |
| 614 | logerror("\n"); |
| 615 | } |
| 616 | return; |
| 617 | } |
| 576 | 618 | if(m_spc_status | SSTS_XFER_IN_PROGRESS) |
| 577 | 619 | { |
| 578 | 620 | m_buffer[m_transfer_index % 512] = data; |
| r14681 | r14682 | |
| 587 | 629 | m_spc_status &= ~SSTS_XFER_IN_PROGRESS; |
| 588 | 630 | m_spc_status |= SSTS_DREG_EMPTY; |
| 589 | 631 | m_ints |= INTS_COMMAND_COMPLETE; |
| 632 | if(m_int_enable != 0) |
| 633 | m_irq_func(1); |
| 590 | 634 | set_phase(SCSI_PHASE_STATUS); |
| 591 | 635 | } |
| 592 | 636 | } |