trunk/src/mess/machine/psxcd.c
r22512 | r22513 | |
125 | 125 | |
126 | 126 | void psxcd_device::device_reset() |
127 | 127 | { |
| 128 | next_read_event = -1; |
128 | 129 | stop_read(); |
129 | 130 | |
130 | 131 | for (int i = 0; i < MAX_PSXCD_TIMERS; i++) |
r22512 | r22513 | |
149 | 150 | m_regs.imr = 0x1f; |
150 | 151 | sechead = 0; |
151 | 152 | sectail = 0; |
152 | | next_read_event = -1; |
153 | 153 | m_mute = false; |
154 | 154 | m_dmaload = false; |
155 | 155 | curpos.w = 0; |
r22512 | r22513 | |
470 | 470 | start_read(); |
471 | 471 | } else |
472 | 472 | { |
473 | | send_result(intr_diskerror); |
| 473 | send_result(intr_diskerror, NULL, 0, 0x80); |
474 | 474 | } |
475 | 475 | } |
476 | 476 | |
r22512 | r22513 | |
609 | 609 | decimal_to_bcd(loc.b[F]) // aframe |
610 | 610 | }; |
611 | 611 | |
612 | | verboselog(machine(), 1, "psxcd: getlocp [%02x %02x %02x %02x %02x %02x %02x %02x]\n", |
613 | | data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); |
| 612 | verboselog(machine(), 1, "psxcd: getlocp [%02x %02x %02x %02x %02x %02x %02x %02x]\n", |
| 613 | data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); |
614 | 614 | |
615 | 615 | send_result(intr_complete,data,8); |
616 | 616 | } |
r22512 | r22513 | |
624 | 624 | { |
625 | 625 | unsigned char data[3]= |
626 | 626 | { |
627 | | status, |
628 | | decimal_to_bcd(1), |
629 | | decimal_to_bcd(cdrom_get_last_track(m_cdrom_handle)) |
| 627 | status, |
| 628 | decimal_to_bcd(1), |
| 629 | decimal_to_bcd(cdrom_get_last_track(m_cdrom_handle)) |
630 | 630 | }; |
631 | 631 | |
632 | 632 | send_result(intr_complete,data,3); |
633 | 633 | } |
634 | 634 | else |
635 | 635 | { |
636 | | status |= status_error; |
637 | | send_result(intr_diskerror); |
| 636 | send_result(intr_diskerror, NULL, 0, 0x80); |
638 | 637 | } |
639 | 638 | } |
640 | 639 | |
r22512 | r22513 | |
663 | 662 | } |
664 | 663 | else |
665 | 664 | { |
666 | | status |= status_error; |
667 | | send_result(intr_diskerror); |
| 665 | send_result(intr_diskerror, NULL, 0, 0x80); |
668 | 666 | } |
669 | 667 | } |
670 | 668 | |
r22512 | r22513 | |
688 | 686 | |
689 | 687 | void psxcd_device::cdcmd_test() |
690 | 688 | { |
691 | | verboselog(machine(), 1, "psxcd: test %08x\n",cmdbuf[0]); |
| 689 | verboselog(machine(), 1, "psxcd: test %02x\n", cmdbuf[0]); |
692 | 690 | |
693 | | static unsigned char data[4]= |
| 691 | switch(cmdbuf[0]) |
694 | 692 | { |
695 | | 0x95, |
696 | | 0x07, |
697 | | 0x06, |
698 | | 0xff |
699 | | }; |
| 693 | case 0x20: |
| 694 | static unsigned char data[4]= |
| 695 | { |
| 696 | 0x95, |
| 697 | 0x07, |
| 698 | 0x06, |
| 699 | 0xff |
| 700 | }; |
700 | 701 | |
701 | | send_result(intr_complete,data,4); |
| 702 | send_result(intr_complete,data,4); |
| 703 | break; |
| 704 | |
| 705 | default: |
| 706 | verboselog(machine(), 0, "psxcd: unimplemented test cmd %02x", cmdbuf[0]); |
| 707 | cmd_complete(prepare_result(intr_diskerror, NULL, 0, 0x10)); |
| 708 | break; |
| 709 | } |
702 | 710 | } |
703 | 711 | |
704 | 712 | void psxcd_device::cdcmd_id() |
r22512 | r22513 | |
707 | 715 | |
708 | 716 | if (!open) |
709 | 717 | { |
710 | | static unsigned char gamedata[8] = { 0x00, 0x00, 0x00, 0x00, 'S', 'C', 'E', 'A' }; |
711 | | static unsigned char audiodata[8] = { 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // drops into the audio CD player. 08 80 goes to the menu. |
| 718 | UINT8 cdid[8]; |
| 719 | int irq; |
| 720 | memset(cdid, '\0', 8); |
712 | 721 | |
| 722 | send_result(intr_complete); |
713 | 723 | if(cdrom_get_track_type(m_cdrom_handle, 0) == CD_TRACK_AUDIO) |
714 | 724 | { |
715 | | audiodata[0] = status | status_invalid; |
716 | | send_result(intr_acknowledge,audiodata,8); |
| 725 | irq = intr_diskerror; |
| 726 | cdid[0] = status | status_invalid; |
| 727 | cdid[1] = 0x90; |
717 | 728 | } |
718 | 729 | else |
719 | 730 | { |
720 | | gamedata[0] = status; |
721 | | send_result(intr_acknowledge,gamedata,8); |
| 731 | irq = intr_acknowledge; |
| 732 | cdid[0] = status; |
| 733 | cdid[4] = 'S'; |
| 734 | cdid[5] = 'C'; |
| 735 | cdid[6] = 'E'; |
| 736 | cdid[7] = 'A'; |
722 | 737 | } |
723 | | } else |
| 738 | send_result(irq,cdid,8,default_irq_delay*3); |
| 739 | } |
| 740 | else |
724 | 741 | { |
725 | | status |= status_error; |
726 | | send_result(intr_diskerror); |
| 742 | send_result(intr_diskerror, NULL, 0, 0x80); |
727 | 743 | } |
728 | 744 | } |
729 | 745 | |
r22512 | r22513 | |
739 | 755 | start_read(); |
740 | 756 | } else |
741 | 757 | { |
742 | | send_result(intr_diskerror); |
| 758 | send_result(intr_diskerror, NULL, 0, 0x80); |
743 | 759 | } |
744 | 760 | } |
745 | 761 | |
r22512 | r22513 | |
753 | 769 | verboselog(machine(), 1, "psxcd: readtoc\n"); |
754 | 770 | |
755 | 771 | send_result(intr_complete); |
| 772 | send_result(intr_acknowledge, NULL, 0, default_irq_delay*3); // ? |
756 | 773 | } |
757 | 774 | |
758 | 775 | void psxcd_device::cdcmd_unknown12() |
r22512 | r22513 | |
762 | 779 | if(cmdbuf[0] == 1) |
763 | 780 | send_result(intr_complete); |
764 | 781 | else |
765 | | { |
766 | | status |= status_error; |
767 | | send_result(intr_diskerror); |
768 | | } |
| 782 | send_result(intr_diskerror, NULL, 0, 0x40); |
769 | 783 | } |
770 | 784 | |
771 | 785 | void psxcd_device::cdcmd_illegal17() |
r22512 | r22513 | |
786 | 800 | void psxcd_device::illegalcmd(UINT8 cmd) |
787 | 801 | { |
788 | 802 | verboselog(machine(), 0, "psxcd: unimplemented cd command %02x\n", cmd); |
789 | | command_result *res=global_alloc(command_result); |
790 | | res->res=intr_diskerror; |
791 | | res->data[0]=status | status_error; |
792 | | res->data[1]=0x40; //invalid command |
793 | | res->sz=2; |
794 | | cmd_complete(res); |
| 803 | |
| 804 | send_result(intr_diskerror, NULL, 0, 0x40); |
795 | 805 | } |
796 | 806 | |
797 | 807 | void psxcd_device::cmd_complete(command_result *res) |
r22512 | r22513 | |
808 | 818 | else |
809 | 819 | { |
810 | 820 | res_queue = res; |
811 | | m_regs.ir = res_queue->res & m_regs.imr; // or should it not trigger a masked irq? |
812 | | if(m_regs.ir) |
| 821 | m_regs.ir = res_queue->res; |
| 822 | if(m_regs.ir & m_regs.imr) |
813 | 823 | m_irq_handler(1); |
814 | 824 | m_regs.sr |= 0x20; |
815 | 825 | } |
816 | 826 | res->next = NULL; |
817 | 827 | } |
818 | 828 | |
819 | | void psxcd_device::send_result(UINT8 res, UINT8 *data, int sz, int delay) |
| 829 | psxcd_device::command_result *psxcd_device::prepare_result(UINT8 res, UINT8 *data, int sz, UINT8 errcode) |
820 | 830 | { |
821 | 831 | command_result *cr=global_alloc(command_result); |
822 | 832 | |
r22512 | r22513 | |
828 | 838 | cr->sz=sz; |
829 | 839 | } else |
830 | 840 | { |
831 | | cr->data[0]=status; |
832 | | cr->sz=1; |
| 841 | if((res == intr_diskerror) && errcode) |
| 842 | { |
| 843 | cr->data[0] = status | status_error; |
| 844 | cr->data[1] = errcode; |
| 845 | cr->sz = 2; |
| 846 | } |
| 847 | else |
| 848 | { |
| 849 | cr->data[0]=status; |
| 850 | cr->sz=1; |
| 851 | } |
833 | 852 | } |
834 | 853 | status &= ~status_error; |
835 | 854 | |
| 855 | return cr; |
| 856 | } |
| 857 | |
| 858 | void psxcd_device::send_result(UINT8 res, UINT8 *data, int sz, int delay, UINT8 errcode) |
| 859 | { |
836 | 860 | // Avoid returning results after sector read results - |
837 | 861 | // delay the sector read slightly if necessary |
838 | 862 | |
r22512 | r22513 | |
843 | 867 | m_timers[next_read_event]->adjust(attotime::from_hz(hz), 0, attotime::never); |
844 | 868 | } |
845 | 869 | |
846 | | add_system_event(event_cmd_complete, delay, (void *)cr); |
| 870 | add_system_event(event_cmd_complete, delay, prepare_result(res, data, sz, errcode)); |
847 | 871 | } |
848 | 872 | |
849 | 873 | void psxcd_device::start_dma(UINT8 *mainram, UINT32 size) |
r22512 | r22513 | |
895 | 919 | } |
896 | 920 | else |
897 | 921 | { |
898 | | command_result *res=global_alloc(command_result); |
899 | | res->res=intr_dataready; |
900 | | res->data[0]=status; |
901 | | res->sz=1; |
902 | | cmd_complete(res); |
| 922 | cmd_complete(prepare_result(intr_dataready)); |
903 | 923 | sectail++; |
904 | 924 | sectail %= sector_buffer_size; |
905 | 925 | |
r22512 | r22513 | |
936 | 956 | { |
937 | 957 | verboselog(machine(), 1, "psxcd: autopause xa\n"); |
938 | 958 | |
939 | | command_result *res=global_alloc(command_result); |
940 | | res->res=intr_dataend; |
941 | | res->data[0]=status; |
942 | | res->sz=1; |
943 | | cmd_complete(res); |
| 959 | cmd_complete(prepare_result(intr_dataend)); |
944 | 960 | stop_read(); |
945 | 961 | } |
946 | 962 | } |
r22512 | r22513 | |
964 | 980 | if(!cdrom_read_data(m_cdrom_handle, sector, secbuf[sectail], CD_TRACK_RAW_DONTCARE)) |
965 | 981 | { |
966 | 982 | stop_read(); // assume we've reached the end |
967 | | command_result *res=global_alloc(command_result); |
968 | | res->res=intr_dataend; |
969 | | res->data[0]=status; |
970 | | res->sz=1; |
971 | | cmd_complete(res); |
| 983 | cmd_complete(prepare_result(intr_dataend)); |
972 | 984 | return; |
973 | 985 | } |
974 | 986 | } |
r22512 | r22513 | |
997 | 1009 | verboselog(machine(), 1, "psxcd: autopause cdda\n"); |
998 | 1010 | |
999 | 1011 | stop_read(); |
1000 | | command_result *res=global_alloc(command_result); |
1001 | | res->res=intr_dataend; |
1002 | | res->data[0]=status; |
1003 | | res->sz=1; |
1004 | | cmd_complete(res); |
| 1012 | cmd_complete(prepare_result(intr_dataend)); |
1005 | 1013 | return; |
1006 | 1014 | } |
1007 | 1015 | } |
r22512 | r22513 | |
1053 | 1061 | if(!(mode & mode_cdda) && (cdrom_get_track_type(m_cdrom_handle, cdrom_get_track(m_cdrom_handle, sector + 150)) == CD_TRACK_AUDIO)) |
1054 | 1062 | { |
1055 | 1063 | stop_read(); |
1056 | | command_result *res=global_alloc(command_result); |
1057 | | res->res=intr_diskerror; |
1058 | | res->data[0]=status | status_error; |
1059 | | res->data[1]=0x40; |
1060 | | res->sz=2; |
1061 | | cmd_complete(res); |
| 1064 | cmd_complete(prepare_result(intr_diskerror, NULL, 0, 0x40)); |
1062 | 1065 | return; |
1063 | 1066 | } |
1064 | 1067 | send_result(intr_complete); |