trunk/src/mame/drivers/twinkle.c
r17551 | r17552 | |
231 | 231 | #include "cpu/m68000/m68000.h" |
232 | 232 | #include "video/psx.h" |
233 | 233 | #include "includes/psx.h" |
234 | | #include "machine/am53cf96.h" |
| 234 | #include "machine/scsibus.h" |
235 | 235 | #include "machine/scsicd.h" |
| 236 | #include "machine/am53cf96.h" |
236 | 237 | #include "machine/rtc65271.h" |
237 | 238 | #include "machine/i2cmem.h" |
238 | 239 | #include "machine/idectrl.h" |
r17551 | r17552 | |
244 | 245 | { |
245 | 246 | public: |
246 | 247 | twinkle_state(const machine_config &mconfig, device_type type, const char *tag) |
247 | | : psx_state(mconfig, type, tag) { } |
| 248 | : psx_state(mconfig, type, tag), |
| 249 | m_am53cf96(*this, "scsi:am53cf96"){ } |
248 | 250 | |
| 251 | required_device<am53cf96_device> m_am53cf96; |
| 252 | |
249 | 253 | UINT16 m_spu_ctrl; // SPU board control register |
250 | 254 | UINT8 m_spu_shared[0x400]; // SPU/PSX shared dual-ported RAM |
251 | 255 | UINT32 m_unknown; |
r17551 | r17552 | |
627 | 631 | static ADDRESS_MAP_START( main_map, AS_PROGRAM, 32, twinkle_state ) |
628 | 632 | AM_RANGE(0x00000000, 0x003fffff) AM_RAM AM_SHARE("share1") /* ram */ |
629 | 633 | AM_RANGE(0x1f000000, 0x1f0007ff) AM_READWRITE(shared_psx_r, shared_psx_w) |
630 | | AM_RANGE(0x1f200000, 0x1f20001f) AM_DEVREADWRITE8("am53cf96", am53cf96_device, read, write, 0x00ff00ff) |
| 634 | AM_RANGE(0x1f200000, 0x1f20001f) AM_DEVREADWRITE8("scsi:am53cf96", am53cf96_device, read, write, 0x00ff00ff) |
631 | 635 | AM_RANGE(0x1f20a01c, 0x1f20a01f) AM_WRITENOP /* scsi? */ |
632 | 636 | AM_RANGE(0x1f210400, 0x1f2107ff) AM_READNOP |
633 | 637 | AM_RANGE(0x1f218000, 0x1f218003) AM_WRITE(watchdog_reset32_w) /* LTC1232 */ |
r17551 | r17552 | |
768 | 772 | static void scsi_dma_read( twinkle_state *state, UINT32 n_address, INT32 n_size ) |
769 | 773 | { |
770 | 774 | UINT32 *p_n_psxram = state->m_p_n_psxram; |
771 | | am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96"); |
772 | 775 | |
773 | 776 | int i; |
774 | 777 | int n_this; |
r17551 | r17552 | |
786 | 789 | if( n_this < 2048 / 4 ) |
787 | 790 | { |
788 | 791 | /* non-READ commands */ |
789 | | am53cf96->dma_read_data( n_this * 4, state->m_sector_buffer ); |
| 792 | state->m_am53cf96->dma_read_data( n_this * 4, state->m_sector_buffer ); |
790 | 793 | } |
791 | 794 | else |
792 | 795 | { |
793 | 796 | /* assume normal 2048 byte data for now */ |
794 | | am53cf96->dma_read_data( 2048, state->m_sector_buffer ); |
| 797 | state->m_am53cf96->dma_read_data( 2048, state->m_sector_buffer ); |
795 | 798 | n_this = 2048 / 4; |
796 | 799 | } |
797 | 800 | n_size -= n_this; |
r17551 | r17552 | |
814 | 817 | static void scsi_dma_write( twinkle_state *state, UINT32 n_address, INT32 n_size ) |
815 | 818 | { |
816 | 819 | UINT32 *p_n_psxram = state->m_p_n_psxram; |
817 | | am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96"); |
818 | 820 | |
819 | 821 | int i; |
820 | 822 | int n_this; |
r17551 | r17552 | |
843 | 845 | n_this--; |
844 | 846 | } |
845 | 847 | |
846 | | am53cf96->dma_write_data( n_this * 4, state->m_sector_buffer ); |
| 848 | state->m_am53cf96->dma_write_data( n_this * 4, state->m_sector_buffer ); |
847 | 849 | } |
848 | 850 | } |
849 | 851 | |
r17551 | r17552 | |
852 | 854 | psx_irq_set(machine, 0x400); |
853 | 855 | } |
854 | 856 | |
855 | | static const SCSIConfigTable dev_table = |
| 857 | static const SCSIBus_interface scsibus_intf = |
856 | 858 | { |
857 | | 1, /* 1 SCSI device */ |
858 | | { |
859 | | { "cdrom0" } |
860 | | } |
861 | 859 | }; |
862 | 860 | |
863 | | static const struct AM53CF96interface scsi_intf = |
| 861 | static const struct AM53CF96interface am53cf96_intf = |
864 | 862 | { |
865 | | &dev_table, /* SCSI device table */ |
866 | 863 | &scsi_irq, /* command completion IRQ */ |
867 | 864 | }; |
868 | 865 | |
r17551 | r17552 | |
881 | 878 | { |
882 | 879 | /* also hook up CDDA audio to the CD-ROM drive */ |
883 | 880 | void *cdrom; |
884 | | scsidev_device *scsidev = machine.device<scsidev_device>("cdrom0"); |
| 881 | scsidev_device *scsidev = machine.device<scsidev_device>("scsi:cdrom"); |
885 | 882 | scsidev->GetDevice( &cdrom ); |
886 | 883 | cdda_set_cdrom(machine.device("cdda"), cdrom); |
887 | 884 | } |
r17551 | r17552 | |
920 | 917 | MCFG_MACHINE_RESET( twinkle ) |
921 | 918 | MCFG_I2CMEM_ADD("security",i2cmem_interface) |
922 | 919 | |
923 | | MCFG_AM53CF96_ADD("am53cf96", scsi_intf); |
| 920 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 921 | MCFG_SCSIDEV_ADD("scsi:cdrom", SCSICD, SCSI_ID_4) |
| 922 | MCFG_AM53CF96_ADD("scsi:am53cf96", am53cf96_intf) |
924 | 923 | |
925 | | MCFG_SCSIDEV_ADD("cdrom0", SCSICD, SCSI_ID_4) |
926 | | |
927 | 924 | MCFG_IDE_CONTROLLER_ADD("ide", ide_interrupt, ide_devices, "hdd", NULL, true) |
928 | 925 | MCFG_RTC65271_ADD("rtc", twinkle_rtc) |
929 | 926 | |
r17551 | r17552 | |
1016 | 1013 | ROM_START( bmiidx ) |
1017 | 1014 | TWINKLE_BIOS |
1018 | 1015 | |
1019 | | DISK_REGION( "cdrom0" ) // program |
| 1016 | DISK_REGION( "scsi:cdrom" ) // program |
1020 | 1017 | DISK_IMAGE_READONLY("863jaa01", 0, BAD_DUMP SHA1(aee12de1dc5dd44e5bf7b62133ed695b80999390) ) |
1021 | 1018 | |
1022 | 1019 | DISK_REGION( "cdrom1" ) // video CD |
r17551 | r17552 | |
1032 | 1029 | ROM_REGION( 0x100, "security", 0 ) |
1033 | 1030 | ROM_LOAD( "985j.pd", 0x000000, 0x000100, BAD_DUMP CRC(a35143a9) SHA1(1c0feeab60d9dc50dc4b9a2f3dac73ca619e74b0) ) |
1034 | 1031 | |
1035 | | DISK_REGION( "cdrom0" ) |
| 1032 | DISK_REGION( "scsi:cdrom" ) |
1036 | 1033 | DISK_IMAGE_READONLY( "985jaa01", 0, BAD_DUMP SHA1(0b783f11317f64552ebf3323459139529e7f315f) ) |
1037 | 1034 | |
1038 | 1035 | DISK_REGION( "cdrom1" ) // video CD |
r17551 | r17552 | |
1048 | 1045 | ROM_REGION( 0x100, "security", 0 ) |
1049 | 1046 | ROM_LOAD( "992j.pd", 0x000000, 0x000100, BAD_DUMP CRC(51f24913) SHA1(574b555e3d0c234011198d218d7ae5e95091acb1) ) |
1050 | 1047 | |
1051 | | DISK_REGION( "cdrom0" ) |
| 1048 | DISK_REGION( "scsi:cdrom" ) |
1052 | 1049 | DISK_IMAGE_READONLY( "992jaa01", 0, BAD_DUMP SHA1(7e5389735dff379bb286ba3744edf59b7dfcc74b) ) |
1053 | 1050 | |
1054 | 1051 | DISK_REGION( "cdrom1" ) // video CD |
r17551 | r17552 | |
1064 | 1061 | ROM_REGION( 0x100, "security", 0 ) |
1065 | 1062 | ROM_LOAD( "a03j.pd", 0x000000, 0x000100, CRC(8860cfb6) SHA1(85a5b27f24d4baa7960e692b91c0cf3dc5388e72) ) |
1066 | 1063 | |
1067 | | DISK_REGION( "cdrom0" ) |
| 1064 | DISK_REGION( "scsi:cdrom" ) |
1068 | 1065 | DISK_IMAGE_READONLY( "a03jaa01", 0, BAD_DUMP SHA1(2a587b5524bac6f03d26b55247a0acd22aad6c3a) ) |
1069 | 1066 | |
1070 | 1067 | DISK_REGION( "cdrom1" ) // video CD |
r17551 | r17552 | |
1080 | 1077 | ROM_REGION( 0x100, "security", 0 ) |
1081 | 1078 | ROM_LOAD( "b4uj.pd", 0x000000, 0x000100, BAD_DUMP CRC(0ab15633) SHA1(df004ff41f35b16089f69808ccf53a5e5cc13ac3) ) |
1082 | 1079 | |
1083 | | DISK_REGION( "cdrom0" ) |
| 1080 | DISK_REGION( "scsi:cdrom" ) |
1084 | 1081 | DISK_IMAGE_READONLY( "b4ujaa01", 0, BAD_DUMP SHA1(d8f5d56b8728bea761dc4cdbc04851094d276bd6) ) |
1085 | 1082 | |
1086 | 1083 | DISK_REGION( "cdrom1" ) // DVD |
r17551 | r17552 | |
1096 | 1093 | ROM_REGION( 0x100, "security", 0 ) |
1097 | 1094 | ROM_LOAD( "b44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(5baf4761) SHA1(aa7e07eb2cada03b85bdf11ac6a3de65f4253eef) ) |
1098 | 1095 | |
1099 | | DISK_REGION( "cdrom0" ) |
| 1096 | DISK_REGION( "scsi:cdrom" ) |
1100 | 1097 | DISK_IMAGE_READONLY( "b44jaa01", 0, BAD_DUMP SHA1(a21610f3dc090e39e125d063442ed877fa056146) ) |
1101 | 1098 | |
1102 | 1099 | DISK_REGION( "cdrom1" ) // DVD |
r17551 | r17552 | |
1112 | 1109 | ROM_REGION( 0x100, "security", 0 ) |
1113 | 1110 | ROM_LOAD( "c44j.pd", 0x000000, 0x000100, BAD_DUMP CRC(04c22349) SHA1(d1cb78911cb1ca660d393a81ed3ed07b24c51525) ) |
1114 | 1111 | |
1115 | | DISK_REGION( "cdrom0" ) |
| 1112 | DISK_REGION( "scsi:cdrom" ) |
1116 | 1113 | DISK_IMAGE_READONLY( "c44jaa01", 0, BAD_DUMP SHA1(8b544c81bc56b19e4aa1649e68824811d6d51ce5) ) |
1117 | 1114 | |
1118 | 1115 | DISK_REGION( "cdrom1" ) // DVD |
r17551 | r17552 | |
1128 | 1125 | ROM_REGION( 0x100, "security", 0 ) |
1129 | 1126 | ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) ) |
1130 | 1127 | |
1131 | | DISK_REGION( "cdrom0" ) |
| 1128 | DISK_REGION( "scsi:cdrom" ) |
1132 | 1129 | DISK_IMAGE_READONLY( "896jaabm", 0, BAD_DUMP SHA1(af008e5bcf18da4e9aea752a712c843e37a74be5) ) |
1133 | 1130 | |
1134 | 1131 | DISK_REGION( "cdrom1" ) // video CD |
r17551 | r17552 | |
1144 | 1141 | ROM_REGION( 0x100, "security", 0 ) |
1145 | 1142 | ROM_LOAD( "984j.pd", 0x000000, 0x000100, BAD_DUMP CRC(213843e5) SHA1(5571db155a60fa4087dd996af48e8e27fc1c518c) ) |
1146 | 1143 | |
1147 | | DISK_REGION( "cdrom0" ) |
| 1144 | DISK_REGION( "scsi:cdrom" ) |
1148 | 1145 | DISK_IMAGE_READONLY( "984a01bm", 0, BAD_DUMP SHA1(d9b7d74a72a76e4e9cf7725e0fb8dafcc1c87187) ) |
1149 | 1146 | |
1150 | 1147 | DISK_REGION( "cdrom1" ) // video CD |
r17551 | r17552 | |
1160 | 1157 | ROM_REGION( 0x100, "security", 0 ) |
1161 | 1158 | ROM_LOAD( "896j.pd", 0x000000, 0x000100, BAD_DUMP CRC(1e5caf37) SHA1(75b378662b651cb322e41564d3bae68cc9edadc5) ) |
1162 | 1159 | |
1163 | | DISK_REGION( "cdrom0" ) |
| 1160 | DISK_REGION( "scsi:cdrom" ) |
1164 | 1161 | DISK_IMAGE_READONLY( "896jabbm", 0, BAD_DUMP SHA1(117ae4c876207bbaf9e8fe0fdf5bb161155c1bdb) ) |
1165 | 1162 | |
1166 | 1163 | DISK_REGION( "cdrom1" ) // video CD |
trunk/src/mame/drivers/cps3.c
r17551 | r17552 | |
388 | 388 | #include "machine/intelfsh.h" |
389 | 389 | #include "machine/nvram.h" |
390 | 390 | #include "includes/cps3.h" |
391 | | #include "machine/wd33c93.h" |
| 391 | #include "machine/scsibus.h" |
392 | 392 | #include "machine/scsicd.h" |
| 393 | #include "machine/wd33c93.h" |
393 | 394 | |
394 | 395 | #define MASTER_CLOCK 42954500 |
395 | 396 | |
r17551 | r17552 | |
2167 | 2168 | AM_RANGE(0x05100000, 0x05100003) AM_WRITE(cps3_irq12_ack_w ) |
2168 | 2169 | AM_RANGE(0x05110000, 0x05110003) AM_WRITE(cps3_irq10_ack_w ) |
2169 | 2170 | |
2170 | | AM_RANGE(0x05140000, 0x05140003) AM_DEVREADWRITE8("wd33c93", wd33c93_device, read, write, 0x00ff00ff ) |
| 2171 | AM_RANGE(0x05140000, 0x05140003) AM_DEVREADWRITE8("scsi:wd33c93", wd33c93_device, read, write, 0x00ff00ff ) |
2171 | 2172 | |
2172 | 2173 | AM_RANGE(0x06000000, 0x067fffff) AM_READWRITE(cps3_flash1_r, cps3_flash1_w ) /* Flash ROMs simm 1 */ |
2173 | 2174 | AM_RANGE(0x06800000, 0x06ffffff) AM_READWRITE(cps3_flash2_r, cps3_flash2_w ) /* Flash ROMs simm 2 */ |
r17551 | r17552 | |
2261 | 2262 | //static sh2_cpu_core sh2cp_conf_slave = { 1, NULL }; |
2262 | 2263 | |
2263 | 2264 | |
2264 | | static const SCSIConfigTable dev_table = |
| 2265 | static const SCSIBus_interface scsibus_intf = |
2265 | 2266 | { |
2266 | | 1, /* 1 SCSI device */ |
2267 | | { |
2268 | | { ":cdrom" } |
2269 | | } |
2270 | 2267 | }; |
2271 | 2268 | |
2272 | | static const struct WD33C93interface scsi_intf = |
| 2269 | static const struct WD33C93interface wd33c93_intf = |
2273 | 2270 | { |
2274 | | &dev_table, /* SCSI device table */ |
2275 | 2271 | NULL /* command completion IRQ */ |
2276 | 2272 | }; |
2277 | 2273 | |
r17551 | r17552 | |
2509 | 2505 | MCFG_CPU_PERIODIC_INT(cps3_other_interrupt,80) /* ?source? */ |
2510 | 2506 | MCFG_CPU_CONFIG(sh2_conf_cps3) |
2511 | 2507 | |
2512 | | MCFG_WD33C93_ADD("wd33c93", scsi_intf); |
2513 | | MCFG_SCSIDEV_ADD("cdrom", SCSICD, SCSI_ID_1) |
| 2508 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 2509 | MCFG_SCSIDEV_ADD("scsi:cdrom", SCSICD, SCSI_ID_1) |
| 2510 | MCFG_WD33C93_ADD("scsi:wd33c93", wd33c93_intf) |
2514 | 2511 | |
2515 | 2512 | /* video hardware */ |
2516 | 2513 | MCFG_SCREEN_ADD("screen", RASTER) |
r17551 | r17552 | |
2615 | 2612 | ROM_REGION( 0x200000, "simm5.1", 0 ) ROMX_LOAD( "redearth-simm5.1", 0x00000, 0x200000, CRC(9b8cb56b) SHA1(2ff1081dc99bb7c2f1e036f4c112137c96b83d23), flags ) \ |
2616 | 2613 | |
2617 | 2614 | #define REDEARTH_961121_CDROM \ |
2618 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-wzd-5", 0, BAD_DUMP SHA1(e5676752b08283dc4a98c3d7b759e8aa6dcd0679) ) \ |
| 2615 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-wzd-5", 0, BAD_DUMP SHA1(e5676752b08283dc4a98c3d7b759e8aa6dcd0679) ) \ |
2619 | 2616 | |
2620 | 2617 | #define REDEARTH_961023_FLASH( flags ) \ |
2621 | 2618 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "redearth(__961023)-simm1.0", 0x00000, 0x200000, CRC(65bac346) SHA1(6f4ba0c2cae91a37fc97bea5fc8a50aaf6ca6513), flags ) \ |
r17551 | r17552 | |
2642 | 2639 | ROM_REGION( 0x200000, "simm5.1", 0 ) ROMX_LOAD( "redearth-simm5.1", 0x00000, 0x200000, CRC(9b8cb56b) SHA1(2ff1081dc99bb7c2f1e036f4c112137c96b83d23), flags ) \ |
2643 | 2640 | |
2644 | 2641 | #define REDEARTH_961023_CDROM \ |
2645 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-wzd-3", 0, SHA1(a6ff67093db6bc80ee5fc46e4300e0177b213a52) ) \ |
| 2642 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-wzd-3", 0, SHA1(a6ff67093db6bc80ee5fc46e4300e0177b213a52) ) \ |
2646 | 2643 | |
2647 | 2644 | #define SFIII_970204_FLASH( flags ) \ |
2648 | 2645 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "sfiii-simm1.0", 0x00000, 0x200000, CRC(cfc9e45a) SHA1(5d9061f76680642e730373e3ac29b24926dc5c0c), flags ) \ |
r17551 | r17552 | |
2669 | 2666 | ROM_REGION( 0x200000, "simm5.1", 0 ) ROMX_LOAD( "sfiii-simm5.1", 0x00000, 0x200000, CRC(c6f1c066) SHA1(00de492dd1ef7aef05027a8c501c296b6602e917), flags ) \ |
2670 | 2667 | |
2671 | 2668 | #define SFIII_970204_CDROM \ |
2672 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-sf3-3", 0, BAD_DUMP SHA1(606e62cc5f46275e366e7dbb412dbaeb7e54cd0c) ) \ |
| 2669 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-sf3-3", 0, BAD_DUMP SHA1(606e62cc5f46275e366e7dbb412dbaeb7e54cd0c) ) \ |
2673 | 2670 | |
2674 | 2671 | #define SFIII2_970930_FLASH( flags ) \ |
2675 | 2672 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "sfiii2-simm1.0", 0x00000, 0x200000, CRC(2d666f0b) SHA1(68de034b3a3aeaf4b26122a84ad48b0b763e4122), flags ) \ |
r17551 | r17552 | |
2706 | 2703 | ROM_REGION( 0x200000, "simm5.7", 0 ) ROMX_LOAD( "sfiii2-simm5.7", 0x00000, 0x200000, CRC(93ffa199) SHA1(33ec2379f30c6fdf47ba72c1d0cad8bdd02f17df), flags ) \ |
2707 | 2704 | |
2708 | 2705 | #define SFIII2_970930_CDROM \ |
2709 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-3ga000", 0, BAD_DUMP SHA1(4e162885b0b3265a56e0265037bcf247e820f027) ) \ |
| 2706 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-3ga000", 0, BAD_DUMP SHA1(4e162885b0b3265a56e0265037bcf247e820f027) ) \ |
2710 | 2707 | |
2711 | 2708 | #define JOJO_990128_FLASH( flags ) \ |
2712 | 2709 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "jojo(__990128)-simm1.0", 0x00000, 0x200000, CRC(9516948b) SHA1(4d7e6c1eb7d1bebff2a5069bcd186070a9105474), flags ) \ |
r17551 | r17552 | |
2737 | 2734 | ROM_REGION( 0x200000, "simm5.1", 0 ) ROMX_LOAD( "jojo-simm5.1", 0x00000, 0x200000, CRC(734fd162) SHA1(16cdfac74d18a6c2216afb1ce6afbd7f15297c32), flags ) \ |
2738 | 2735 | |
2739 | 2736 | #define JOJO_990128_CDROM \ |
2740 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-jjk-3", 0, SHA1(dc6e74b5e02e13f62cb8c4e234dd6061501e49c1) ) \ |
| 2737 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-jjk-3", 0, SHA1(dc6e74b5e02e13f62cb8c4e234dd6061501e49c1) ) \ |
2741 | 2738 | |
2742 | 2739 | #define JOJO_990108_FLASH( flags ) \ |
2743 | 2740 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "jojo(__990108)-simm1.0", 0x00000, 0x200000, CRC(cfbc38d6) SHA1(c33e3a51fe8ab54e0912a1d6e662fe1ade73cee7), flags ) \ |
r17551 | r17552 | |
2768 | 2765 | ROM_REGION( 0x200000, "simm5.1", 0 ) ROMX_LOAD( "jojo-simm5.1", 0x00000, 0x200000, CRC(734fd162) SHA1(16cdfac74d18a6c2216afb1ce6afbd7f15297c32), flags ) \ |
2769 | 2766 | |
2770 | 2767 | #define JOJO_990108_CDROM \ |
2771 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-jjk-2", 0, BAD_DUMP SHA1(0f5c09171409213e191a607ee89ca3a91fe9c96a) ) \ |
| 2768 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-jjk-2", 0, BAD_DUMP SHA1(0f5c09171409213e191a607ee89ca3a91fe9c96a) ) \ |
2772 | 2769 | |
2773 | 2770 | #define JOJO_981202_FLASH( flags ) \ |
2774 | 2771 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "jojo(__981202)-simm1.0", 0x00000, 0x200000, CRC(e06ba886) SHA1(4defd5e8e1e6d0c439fed8a6454e89a59e24ea4c), flags ) \ |
r17551 | r17552 | |
2799 | 2796 | ROM_REGION( 0x200000, "simm5.1", 0 ) ROMX_LOAD( "jojo-simm5.1", 0x00000, 0x200000, CRC(734fd162) SHA1(16cdfac74d18a6c2216afb1ce6afbd7f15297c32), flags ) \ |
2800 | 2797 | |
2801 | 2798 | #define JOJO_981202_CDROM \ |
2802 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-jjk000", 0, BAD_DUMP SHA1(09869f6d8c032b527e02d815749dc8fab1289e86) ) \ |
| 2799 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-jjk000", 0, BAD_DUMP SHA1(09869f6d8c032b527e02d815749dc8fab1289e86) ) \ |
2803 | 2800 | |
2804 | 2801 | #define SFIII3_990608_FLASH( flags ) \ |
2805 | 2802 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "sfiii3(__990608)-simm1.0", 0x00000, 0x200000, CRC(11dfd3cd) SHA1(dba1f77c46e80317e3279298411154dfb6db2309), flags ) \ |
r17551 | r17552 | |
2844 | 2841 | ROM_REGION( 0x200000, "simm6.7", 0 ) ROMX_LOAD( "sfiii3-simm6.7", 0x00000, 0x200000, CRC(cc5f4187) SHA1(248ddace21ed4736a56e92f77cc6ad219d7fef0b), flags ) \ |
2845 | 2842 | |
2846 | 2843 | #define SFIII3_990608_CDROM \ |
2847 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-33s-2", 0, BAD_DUMP SHA1(41b0e246db91cbfc3f8f0f62d981734feb4b4ab5) ) \ |
| 2844 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-33s-2", 0, BAD_DUMP SHA1(41b0e246db91cbfc3f8f0f62d981734feb4b4ab5) ) \ |
2848 | 2845 | |
2849 | 2846 | #define SFIII3_990512_FLASH( flags ) \ |
2850 | 2847 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "sfiii3(__990512)-simm1.0", 0x00000, 0x200000, CRC(66e66235) SHA1(0a98038721d176458d4f85dbd76c5edb93a65322), flags ) \ |
r17551 | r17552 | |
2889 | 2886 | ROM_REGION( 0x200000, "simm6.7", 0 ) ROMX_LOAD( "sfiii3-simm6.7", 0x00000, 0x200000, CRC(cc5f4187) SHA1(248ddace21ed4736a56e92f77cc6ad219d7fef0b), flags ) \ |
2890 | 2887 | |
2891 | 2888 | #define SFIII3_990512_CDROM \ |
2892 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-33s-1", 0, BAD_DUMP SHA1(2f4a9006a31903114f9f9dc09465ae253e565c51) ) \ |
| 2889 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-33s-1", 0, BAD_DUMP SHA1(2f4a9006a31903114f9f9dc09465ae253e565c51) ) \ |
2893 | 2890 | |
2894 | 2891 | #define JOJOBA_990927_FLASH( flags ) \ |
2895 | 2892 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "jojoba(__990927)-simm1.0", 0x00000, 0x200000, CRC(adcd8377) SHA1(f1aacbe061e3bcade5cca34435c3f86aec5f1499), flags ) \ |
r17551 | r17552 | |
2926 | 2923 | ROM_REGION( 0x200000, "simm5.7", 0 ) ROMX_LOAD( "jojoba-simm5.7", 0x00000, 0x200000, CRC(8c8be520) SHA1(c461f3f76a83592b36b29afb316679a7c8972404), flags ) \ |
2927 | 2924 | |
2928 | 2925 | #define JOJOBA_990927_CDROM \ |
2929 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-jjm-1", 0, SHA1(8628d3fa555fbd5f4121082e925c1834b76c5e65) ) \ |
| 2926 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-jjm-1", 0, SHA1(8628d3fa555fbd5f4121082e925c1834b76c5e65) ) \ |
2930 | 2927 | |
2931 | 2928 | #define JOJOBA_990913_FLASH( flags ) \ |
2932 | 2929 | ROM_REGION( 0x200000, "simm1.0", 0 ) ROMX_LOAD( "jojoba(__990913)-simm1.0", 0x00000, 0x200000, CRC(76976231) SHA1(90adde7e5983ec6a4e02789d5cefe9e85c9c52d5), flags ) \ |
r17551 | r17552 | |
2963 | 2960 | ROM_REGION( 0x200000, "simm5.7", 0 ) ROMX_LOAD( "jojoba-simm5.7", 0x00000, 0x200000, CRC(8c8be520) SHA1(c461f3f76a83592b36b29afb316679a7c8972404), flags ) \ |
2964 | 2961 | |
2965 | 2962 | #define JOJOBA_990913_CDROM \ |
2966 | | DISK_REGION( "cdrom" ) DISK_IMAGE_READONLY( "cap-jjm-0", 0, BAD_DUMP SHA1(0678a0baeb853dcff1d230c14f0873cc9f143d7b) ) \ |
| 2963 | DISK_REGION( "scsi:cdrom" ) DISK_IMAGE_READONLY( "cap-jjm-0", 0, BAD_DUMP SHA1(0678a0baeb853dcff1d230c14f0873cc9f143d7b) ) \ |
2967 | 2964 | |
2968 | 2965 | |
2969 | 2966 | /* CD sets - use CD BIOS roms */ |
trunk/src/mame/drivers/konamigv.c
r17551 | r17552 | |
125 | 125 | #include "includes/psx.h" |
126 | 126 | #include "machine/eeprom.h" |
127 | 127 | #include "machine/intelfsh.h" |
128 | | #include "machine/am53cf96.h" |
| 128 | #include "machine/scsibus.h" |
129 | 129 | #include "machine/scsicd.h" |
| 130 | #include "machine/am53cf96.h" |
130 | 131 | #include "sound/spu.h" |
131 | 132 | #include "sound/cdda.h" |
132 | 133 | |
r17551 | r17552 | |
134 | 135 | { |
135 | 136 | public: |
136 | 137 | konamigv_state(const machine_config &mconfig, device_type type, const char *tag) |
137 | | : psx_state(mconfig, type, tag) { } |
| 138 | : psx_state(mconfig, type, tag), |
| 139 | m_am53cf96(*this, "scsi:am53cf96"){ } |
138 | 140 | |
| 141 | required_device<am53cf96_device> m_am53cf96; |
| 142 | |
139 | 143 | UINT32 m_flash_address; |
140 | 144 | |
141 | 145 | UINT16 m_trackball_prev[ 2 ]; |
r17551 | r17552 | |
190 | 194 | |
191 | 195 | static ADDRESS_MAP_START( konamigv_map, AS_PROGRAM, 32, konamigv_state ) |
192 | 196 | AM_RANGE(0x00000000, 0x001fffff) AM_RAM AM_SHARE("share1") /* ram */ |
193 | | AM_RANGE(0x1f000000, 0x1f00001f) AM_DEVREADWRITE8("am53cf96", am53cf96_device, read, write, 0x00ff00ff) |
| 197 | AM_RANGE(0x1f000000, 0x1f00001f) AM_DEVREADWRITE8("scsi:am53cf96", am53cf96_device, read, write, 0x00ff00ff) |
194 | 198 | AM_RANGE(0x1f100000, 0x1f100003) AM_READ_PORT("P1") |
195 | 199 | AM_RANGE(0x1f100004, 0x1f100007) AM_READ_PORT("P2") |
196 | 200 | AM_RANGE(0x1f100008, 0x1f10000b) AM_READ_PORT("P3_P4") |
r17551 | r17552 | |
209 | 213 | |
210 | 214 | static void scsi_dma_read( konamigv_state *state, UINT32 n_address, INT32 n_size ) |
211 | 215 | { |
212 | | am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96"); |
213 | | |
214 | 216 | UINT32 *p_n_psxram = state->m_p_n_psxram; |
215 | 217 | UINT8 *sector_buffer = state->m_sector_buffer; |
216 | 218 | int i; |
r17551 | r17552 | |
229 | 231 | if( n_this < 2048 / 4 ) |
230 | 232 | { |
231 | 233 | /* non-READ commands */ |
232 | | am53cf96->dma_read_data( n_this * 4, sector_buffer ); |
| 234 | state->m_am53cf96->dma_read_data( n_this * 4, sector_buffer ); |
233 | 235 | } |
234 | 236 | else |
235 | 237 | { |
236 | 238 | /* assume normal 2048 byte data for now */ |
237 | | am53cf96->dma_read_data( 2048, sector_buffer ); |
| 239 | state->m_am53cf96->dma_read_data( 2048, sector_buffer ); |
238 | 240 | n_this = 2048 / 4; |
239 | 241 | } |
240 | 242 | n_size -= n_this; |
r17551 | r17552 | |
256 | 258 | |
257 | 259 | static void scsi_dma_write( konamigv_state *state, UINT32 n_address, INT32 n_size ) |
258 | 260 | { |
259 | | am53cf96_device *am53cf96 = state->machine().device<am53cf96_device>("am53cf96"); |
260 | | |
261 | 261 | UINT32 *p_n_psxram = state->m_p_n_psxram; |
262 | 262 | UINT8 *sector_buffer = state->m_sector_buffer; |
263 | 263 | int i; |
r17551 | r17552 | |
287 | 287 | n_this--; |
288 | 288 | } |
289 | 289 | |
290 | | am53cf96->dma_write_data( n_this * 4, sector_buffer ); |
| 290 | state->m_am53cf96->dma_write_data( n_this * 4, sector_buffer ); |
291 | 291 | } |
292 | 292 | } |
293 | 293 | |
r17551 | r17552 | |
296 | 296 | psx_irq_set(machine, 0x400); |
297 | 297 | } |
298 | 298 | |
299 | | static const SCSIConfigTable dev_table = |
| 299 | static const SCSIBus_interface scsibus_intf = |
300 | 300 | { |
301 | | 1, /* 1 SCSI device */ |
302 | | { |
303 | | { ":cdrom", } |
304 | | } |
305 | 301 | }; |
306 | 302 | |
307 | | static const struct AM53CF96interface scsi_intf = |
| 303 | static const struct AM53CF96interface am53cf96_intf = |
308 | 304 | { |
309 | | &dev_table, /* SCSI device table */ |
310 | 305 | &scsi_irq, /* command completion IRQ */ |
311 | 306 | }; |
312 | 307 | |
r17551 | r17552 | |
331 | 326 | { |
332 | 327 | /* also hook up CDDA audio to the CD-ROM drive */ |
333 | 328 | void *cdrom; |
334 | | scsidev_device *scsidev = machine.device<scsidev_device>("cdrom"); |
| 329 | scsidev_device *scsidev = machine.device<scsidev_device>("scsi:cdrom"); |
335 | 330 | scsidev->GetDevice( &cdrom ); |
336 | 331 | cdda_set_cdrom(machine.device("cdda"), cdrom); |
337 | 332 | } |
r17551 | r17552 | |
357 | 352 | |
358 | 353 | MCFG_EEPROM_93C46_ADD("eeprom") |
359 | 354 | |
360 | | MCFG_AM53CF96_ADD("am53cf96", scsi_intf); |
| 355 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 356 | MCFG_SCSIDEV_ADD("scsi:cdrom", SCSICD, SCSI_ID_4) |
| 357 | MCFG_AM53CF96_ADD("scsi:am53cf96", am53cf96_intf) |
361 | 358 | |
362 | | MCFG_SCSIDEV_ADD("cdrom", SCSICD, SCSI_ID_4) |
363 | | |
364 | 359 | /* video hardware */ |
365 | 360 | MCFG_PSXGPU_ADD( "maincpu", "gpu", CXD8514Q, 0x100000, XTAL_53_693175MHz ) |
366 | 361 | |
r17551 | r17552 | |
779 | 774 | |
780 | 775 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
781 | 776 | ROM_LOAD( "susume.25c", 0x000000, 0x000080, CRC(52f17df7) SHA1(b8ad7787b0692713439d7d9bebfa0c801c806006) ) |
782 | | DISK_REGION( "cdrom" ) |
| 777 | DISK_REGION( "scsi:cdrom" ) |
783 | 778 | DISK_IMAGE_READONLY( "gv027j1", 0, BAD_DUMP SHA1(e7e6749ac65de7771eb8fed7d5eefaec3f902255) ) |
784 | 779 | ROM_END |
785 | 780 | |
r17551 | r17552 | |
789 | 784 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
790 | 785 | ROM_LOAD( "hyperath.25c", 0x000000, 0x000080, CRC(20a8c435) SHA1(a0f203a999757fba68b391c525ac4b9684a57ba9) ) |
791 | 786 | |
792 | | DISK_REGION( "cdrom" ) |
| 787 | DISK_REGION( "scsi:cdrom" ) |
793 | 788 | DISK_IMAGE_READONLY( "hyperath", 0, BAD_DUMP SHA1(694ef6200c61d3052316100cd9251b495eab88a1) ) |
794 | 789 | ROM_END |
795 | 790 | |
r17551 | r17552 | |
799 | 794 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
800 | 795 | ROM_LOAD( "pbball96.25c", 0x000000, 0x000080, CRC(405a7fc9) SHA1(e2d978f49748ba3c4a425188abcd3d272ec23907) ) |
801 | 796 | |
802 | | DISK_REGION( "cdrom" ) |
| 797 | DISK_REGION( "scsi:cdrom" ) |
803 | 798 | DISK_IMAGE_READONLY( "pbball96", 0, BAD_DUMP SHA1(ebd0ea18ff9ce300ea1e30d66a739a96acfb0621) ) |
804 | 799 | ROM_END |
805 | 800 | |
r17551 | r17552 | |
809 | 804 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
810 | 805 | ROM_LOAD( "weddingr.25c", 0x000000, 0x000080, CRC(b90509a0) SHA1(41510a0ceded81dcb26a70eba97636d38d3742c3) ) |
811 | 806 | |
812 | | DISK_REGION( "cdrom" ) |
| 807 | DISK_REGION( "scsi:cdrom" ) |
813 | 808 | DISK_IMAGE_READONLY( "weddingr", 0, BAD_DUMP SHA1(4e7122b191747ab7220fe4ce1b4483d62ab579af) ) |
814 | 809 | ROM_END |
815 | 810 | |
r17551 | r17552 | |
819 | 814 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
820 | 815 | ROM_LOAD( "simpbowl.25c", 0x000000, 0x000080, CRC(2c61050c) SHA1(16ae7f81cbe841c429c5c7326cf83e87db1782bf) ) |
821 | 816 | |
822 | | DISK_REGION( "cdrom" ) |
| 817 | DISK_REGION( "scsi:cdrom" ) |
823 | 818 | DISK_IMAGE_READONLY( "simpbowl", 0, BAD_DUMP SHA1(72b32a863e6891ad3bfc1fdfe9cb90a2bd334d71) ) |
824 | 819 | ROM_END |
825 | 820 | |
r17551 | r17552 | |
829 | 824 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
830 | 825 | ROM_LOAD( "btchmp.25c", 0x000000, 0x000080, CRC(6d02ea54) SHA1(d3babf481fd89db3aec17f589d0d3d999a2aa6e1) ) |
831 | 826 | |
832 | | DISK_REGION( "cdrom" ) |
| 827 | DISK_REGION( "scsi:cdrom" ) |
833 | 828 | DISK_IMAGE_READONLY( "btchamp", 0, BAD_DUMP SHA1(c9c858e9034826e1a12c3c003dd068a49a3577e1) ) |
834 | 829 | ROM_END |
835 | 830 | |
r17551 | r17552 | |
839 | 834 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
840 | 835 | ROM_LOAD( "kdeadeye.25c", 0x000000, 0x000080, CRC(3935d2df) SHA1(cbb855c475269077803c380dbc3621e522efe51e) ) |
841 | 836 | |
842 | | DISK_REGION( "cdrom" ) |
| 837 | DISK_REGION( "scsi:cdrom" ) |
843 | 838 | DISK_IMAGE_READONLY( "kdeadeye", 0, BAD_DUMP SHA1(3c737c51717925be724dcb93d30769649029b8ce) ) |
844 | 839 | ROM_END |
845 | 840 | |
r17551 | r17552 | |
849 | 844 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
850 | 845 | ROM_LOAD( "nagano98.25c", 0x000000, 0x000080, CRC(b64b7451) SHA1(a77a37e0cc580934d1e7e05d523bae0acd2c1480) ) |
851 | 846 | |
852 | | DISK_REGION( "cdrom" ) |
| 847 | DISK_REGION( "scsi:cdrom" ) |
853 | 848 | DISK_IMAGE_READONLY( "nagano98", 0, BAD_DUMP SHA1(1be7bd4531f249ff2233dd40a206c8d60054a8c6) ) |
854 | 849 | ROM_END |
855 | 850 | |
r17551 | r17552 | |
859 | 854 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
860 | 855 | ROM_LOAD( "720ja.25c", 0x000000, 0x000080, CRC(34c473ba) SHA1(768225b04a293bdbc114a092d14dee28d52044e9) ) |
861 | 856 | |
862 | | DISK_REGION( "cdrom" ) |
| 857 | DISK_REGION( "scsi:cdrom" ) |
863 | 858 | DISK_IMAGE_READONLY( "720jaa01", 0, SHA1(437160996551ef4dfca43899d1d14beca62eb4c9) ) |
864 | 859 | ROM_END |
865 | 860 | |
r17551 | r17552 | |
869 | 864 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
870 | 865 | ROM_LOAD( "tokimosh.25c", 0x000000, 0x000080, CRC(e57b833f) SHA1(f18a0974a6be69dc179706643aab837ff61c2738) ) |
871 | 866 | |
872 | | DISK_REGION( "cdrom" ) |
| 867 | DISK_REGION( "scsi:cdrom" ) |
873 | 868 | DISK_IMAGE_READONLY( "755jaa01", 0, BAD_DUMP SHA1(4af080f9650e34d1ddb91bb763469d5fb3c754bd) ) |
874 | 869 | ROM_END |
875 | 870 | |
r17551 | r17552 | |
879 | 874 | ROM_REGION16_BE( 0x0000080, "eeprom", 0 ) /* default eeprom */ |
880 | 875 | ROM_LOAD( "tokimosp.25c", 0x000000, 0x000080, CRC(af4cdd87) SHA1(97041e287e4c80066043967450779b81b62b2b8e) ) |
881 | 876 | |
882 | | DISK_REGION( "cdrom" ) |
| 877 | DISK_REGION( "scsi:cdrom" ) |
883 | 878 | DISK_IMAGE_READONLY( "756jab01", 0, BAD_DUMP SHA1(7bd974d908ae5a7bfa8d30db185ab01ac38dff28) ) |
884 | 879 | ROM_END |
885 | 880 | |
trunk/src/emu/machine/scsibus.c
r0 | r17552 | |
| 1 | /* |
| 2 | SCSIBus.c |
| 3 | |
| 4 | Implementation of a raw SCSI/SASI bus for machines that don't use a SCSI |
| 5 | controler chip such as the RM Nimbus, which implements it as a bunch of |
| 6 | 74LS series chips. |
| 7 | |
| 8 | */ |
| 9 | |
| 10 | #include "emu.h" |
| 11 | #include "machine/scsidev.h" |
| 12 | #include "machine/scsibus.h" |
| 13 | #include "debugger.h" |
| 14 | #include "debug/debugcpu.h" |
| 15 | #include "debug/debugcon.h" |
| 16 | |
| 17 | /* |
| 18 | LOGLEVEL |
| 19 | 0 no logging, |
| 20 | 1 just commands |
| 21 | 2 1 + data |
| 22 | 3 2 + line changes |
| 23 | */ |
| 24 | |
| 25 | #define LOGLEVEL 0 |
| 26 | |
| 27 | #define LOG(level,...) if(LOGLEVEL>=level) logerror(__VA_ARGS__) |
| 28 | |
| 29 | static const char *const linenames[] = |
| 30 | { |
| 31 | "select", "busy", "request", "acknoledge", "C/D", "I/O", "message", "reset" |
| 32 | }; |
| 33 | |
| 34 | static const char *const phasenames[] = |
| 35 | { |
| 36 | "data out", "data in", "command", "status", "none", "none", "message out", "message in", "bus free","select" |
| 37 | }; |
| 38 | |
| 39 | void scsibus_device::dump_bytes(UINT8 *buff, int count) |
| 40 | { |
| 41 | int byteno; |
| 42 | |
| 43 | for(byteno=0; byteno<count; byteno++) |
| 44 | { |
| 45 | logerror("%02X ",buff[byteno]); |
| 46 | } |
| 47 | } |
| 48 | |
| 49 | void scsibus_device::dump_command_bytes() |
| 50 | { |
| 51 | logerror("sending command 0x%02X to ScsiID %d\n",command[0],last_id); |
| 52 | dump_bytes(command,cmd_idx); |
| 53 | logerror("\n\n"); |
| 54 | } |
| 55 | |
| 56 | void scsibus_device::dump_data_bytes(int count) |
| 57 | { |
| 58 | logerror("Data buffer[0..%d]\n",count); |
| 59 | dump_bytes(buffer,count); |
| 60 | logerror("\n\n"); |
| 61 | } |
| 62 | |
| 63 | void scsibus_device::scsibus_read_data() |
| 64 | { |
| 65 | data_last = (bytes_left >= sectorbytes) ? sectorbytes : bytes_left; |
| 66 | |
| 67 | LOG(2,"SCSIBUS:scsibus_read_data bytes_left=%04X, data_last=%04X, xfer_count=%04X\n",bytes_left,data_last,xfer_count); |
| 68 | |
| 69 | if (data_last > 0) |
| 70 | { |
| 71 | devices[last_id]->ReadData(buffer, data_last); |
| 72 | bytes_left-=data_last; |
| 73 | data_idx=0; |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | void scsibus_device::scsibus_write_data() |
| 78 | { |
| 79 | if(bytes_left >= sectorbytes) |
| 80 | { |
| 81 | devices[last_id]->WriteData(buffer, sectorbytes); |
| 82 | |
| 83 | bytes_left-=sectorbytes; |
| 84 | data_idx=0; |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | /* SCSI Bus read/write */ |
| 89 | |
| 90 | UINT8 scsibus_device::scsi_data_r() |
| 91 | { |
| 92 | UINT8 result = 0; |
| 93 | |
| 94 | switch (phase) |
| 95 | { |
| 96 | case SCSI_PHASE_DATAIN: |
| 97 | result=buffer[data_idx++]; |
| 98 | |
| 99 | // check to see if we have reached the end of the block buffer |
| 100 | // and that there is more data to read from the scsi disk |
| 101 | if((data_idx==sectorbytes) && (bytes_left>0) && IS_READ_COMMAND()) |
| 102 | { |
| 103 | scsibus_read_data(); |
| 104 | } |
| 105 | break; |
| 106 | |
| 107 | case SCSI_PHASE_STATUS: |
| 108 | result=status; // return command status |
| 109 | break; |
| 110 | |
| 111 | case SCSI_PHASE_MESSAGE_IN: |
| 112 | result=0; // no errors for the time being ! |
| 113 | break; |
| 114 | } |
| 115 | |
| 116 | LOG(2,"scsi_data_r : %02x phase=%s, data_idx=%d, cmd_idx=%d\n",result,phasenames[phase],data_idx,cmd_idx); |
| 117 | return result; |
| 118 | } |
| 119 | |
| 120 | READ8_MEMBER( scsibus_device::scsi_data_r ) |
| 121 | { |
| 122 | return scsi_data_r(); |
| 123 | } |
| 124 | |
| 125 | void scsibus_device::scsi_data_w( UINT8 data ) |
| 126 | { |
| 127 | switch (phase) |
| 128 | { |
| 129 | // Note this assumes we only have one initiator and therefore |
| 130 | // only one line active. |
| 131 | case SCSI_PHASE_BUS_FREE: |
| 132 | last_id=scsibus_driveno(data); |
| 133 | break; |
| 134 | |
| 135 | case SCSI_PHASE_COMMAND: |
| 136 | command[cmd_idx++]=data; |
| 137 | break; |
| 138 | |
| 139 | case SCSI_PHASE_DATAOUT: |
| 140 | |
| 141 | //LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",xfer_count,bytes_left,data_idx); |
| 142 | |
| 143 | if(IS_COMMAND(SCSI_CMD_FORMAT_UNIT)) |
| 144 | { |
| 145 | // Only store the first 4 bytes of the bad block list (the header) |
| 146 | //if(data_idx<4) |
| 147 | buffer[data_idx++]=data; |
| 148 | dump_data_bytes(4); |
| 149 | //else |
| 150 | // data_idx++; |
| 151 | |
| 152 | // If we have the first byte, then cancel the dataout timout |
| 153 | if(data_idx==1) |
| 154 | dataout_timer->adjust(attotime::never); |
| 155 | |
| 156 | // When we have the first 3 bytes, calculate how many more are in the |
| 157 | // bad block list. |
| 158 | if(data_idx==3) |
| 159 | { |
| 160 | xfer_count+=((buffer[2]<<8)+buffer[3]); |
| 161 | data_last=xfer_count; |
| 162 | LOG(1,"format_unit reading an extra %d bytes\n",xfer_count-4); |
| 163 | dump_data_bytes(4); |
| 164 | } |
| 165 | } |
| 166 | else |
| 167 | { |
| 168 | buffer[data_idx++]=data; |
| 169 | } |
| 170 | |
| 171 | // If the data buffer is full, and we are writing blocks flush it to the SCSI disk |
| 172 | if((data_idx == sectorbytes) && IS_WRITE_COMMAND()) |
| 173 | scsibus_write_data(); |
| 174 | break; |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | WRITE8_MEMBER( scsibus_device::scsi_data_w ) |
| 179 | { |
| 180 | scsi_data_w( data ); |
| 181 | } |
| 182 | |
| 183 | /* Get/Set lines */ |
| 184 | |
| 185 | UINT8 scsibus_device::get_scsi_line(UINT8 lineno) |
| 186 | { |
| 187 | UINT8 result=0; |
| 188 | |
| 189 | switch (lineno) |
| 190 | { |
| 191 | case SCSI_LINE_SEL: result=(linestate & (1<<SCSI_LINE_SEL)) >> SCSI_LINE_SEL; break; |
| 192 | case SCSI_LINE_BSY: result=(linestate & (1<<SCSI_LINE_BSY)) >> SCSI_LINE_BSY; break; |
| 193 | case SCSI_LINE_REQ: result=(linestate & (1<<SCSI_LINE_REQ)) >> SCSI_LINE_REQ; break; |
| 194 | case SCSI_LINE_ACK: result=(linestate & (1<<SCSI_LINE_ACK)) >> SCSI_LINE_ACK; break; |
| 195 | case SCSI_LINE_CD: result=(linestate & (1<<SCSI_LINE_CD )) >> SCSI_LINE_CD; break; |
| 196 | case SCSI_LINE_IO: result=(linestate & (1<<SCSI_LINE_IO )) >> SCSI_LINE_IO; break; |
| 197 | case SCSI_LINE_MSG: result=(linestate & (1<<SCSI_LINE_MSG)) >> SCSI_LINE_MSG; break; |
| 198 | case SCSI_LINE_RESET: result=(linestate & (1<<SCSI_LINE_RESET)) >> SCSI_LINE_RESET; break; |
| 199 | } |
| 200 | |
| 201 | LOG(3,"get_scsi_line(%s)=%d\n",linenames[lineno],result); |
| 202 | |
| 203 | return result; |
| 204 | } |
| 205 | |
| 206 | READ_LINE_MEMBER( scsibus_device::scsi_bsy_r ) { return get_scsi_line(SCSI_LINE_BSY); } |
| 207 | READ_LINE_MEMBER( scsibus_device::scsi_sel_r ) { return get_scsi_line(SCSI_LINE_SEL); } |
| 208 | READ_LINE_MEMBER( scsibus_device::scsi_cd_r ) { return get_scsi_line(SCSI_LINE_CD); } |
| 209 | READ_LINE_MEMBER( scsibus_device::scsi_io_r ) { return get_scsi_line(SCSI_LINE_IO); } |
| 210 | READ_LINE_MEMBER( scsibus_device::scsi_msg_r ) { return get_scsi_line(SCSI_LINE_MSG); } |
| 211 | READ_LINE_MEMBER( scsibus_device::scsi_req_r ) { return get_scsi_line(SCSI_LINE_REQ); } |
| 212 | READ_LINE_MEMBER( scsibus_device::scsi_ack_r ) { return get_scsi_line(SCSI_LINE_ACK); } |
| 213 | READ_LINE_MEMBER( scsibus_device::scsi_rst_r ) { return get_scsi_line(SCSI_LINE_RESET); } |
| 214 | |
| 215 | void scsibus_device::set_scsi_line(UINT8 line, UINT8 state) |
| 216 | { |
| 217 | UINT8 changed; |
| 218 | |
| 219 | changed = ((linestate & (1<<line)) != (state << line)); |
| 220 | |
| 221 | LOG(3,"set_scsi_line(%s,%d), changed=%d, linestate=%02X\n",linenames[line],state,changed,linestate); |
| 222 | |
| 223 | if(changed) |
| 224 | { |
| 225 | if (line==SCSI_LINE_ACK) |
| 226 | set_scsi_line_ack(state); |
| 227 | else |
| 228 | set_scsi_line_now(line,state); |
| 229 | } |
| 230 | } |
| 231 | |
| 232 | WRITE_LINE_MEMBER( scsibus_device::scsi_bsy_w ) { set_scsi_line(SCSI_LINE_BSY, state); } |
| 233 | WRITE_LINE_MEMBER( scsibus_device::scsi_sel_w ) { set_scsi_line(SCSI_LINE_SEL, state); } |
| 234 | WRITE_LINE_MEMBER( scsibus_device::scsi_cd_w ) { set_scsi_line(SCSI_LINE_CD, state); } |
| 235 | WRITE_LINE_MEMBER( scsibus_device::scsi_io_w ) { set_scsi_line(SCSI_LINE_IO, state); } |
| 236 | WRITE_LINE_MEMBER( scsibus_device::scsi_msg_w ) { set_scsi_line(SCSI_LINE_MSG, state); } |
| 237 | WRITE_LINE_MEMBER( scsibus_device::scsi_req_w ) { set_scsi_line(SCSI_LINE_REQ, state); } |
| 238 | WRITE_LINE_MEMBER( scsibus_device::scsi_ack_w ) { set_scsi_line(SCSI_LINE_ACK, state); } |
| 239 | WRITE_LINE_MEMBER( scsibus_device::scsi_rst_w ) { set_scsi_line(SCSI_LINE_RESET, state); } |
| 240 | |
| 241 | void scsibus_device::set_scsi_line_now(UINT8 line, UINT8 state) |
| 242 | { |
| 243 | if(state) |
| 244 | linestate |= (1<<line); |
| 245 | else |
| 246 | linestate &= ~(1<<line); |
| 247 | |
| 248 | scsi_in_line_changed(line,state); |
| 249 | } |
| 250 | |
| 251 | void scsibus_device::set_scsi_line_ack(UINT8 state) |
| 252 | { |
| 253 | ack_timer->adjust(attotime::from_nsec(ACK_DELAY_NS),state); |
| 254 | } |
| 255 | |
| 256 | void scsibus_device::scsibus_exec_command() |
| 257 | { |
| 258 | int command_local = 0; |
| 259 | int newphase; |
| 260 | |
| 261 | if(LOGLEVEL) |
| 262 | dump_command_bytes(); |
| 263 | |
| 264 | //is_linked=command[cmd_idx-1] & 0x01; |
| 265 | is_linked=0; |
| 266 | |
| 267 | // Assume command will succeed, if not set sytatus below. |
| 268 | if (command[0]!=SCSI_CMD_REQUEST_SENSE) |
| 269 | SET_STATUS_SENSE(SCSI_STATUS_OK,SCSI_SENSE_NO_SENSE); |
| 270 | |
| 271 | // Check for locally executed commands, and if found execute them |
| 272 | switch (command[0]) |
| 273 | { |
| 274 | // Test ready |
| 275 | case SCSI_CMD_TEST_READY: |
| 276 | LOG(1,"SCSIBUS: test_ready\n"); |
| 277 | command_local=1; |
| 278 | xfer_count=0; |
| 279 | data_last=xfer_count; |
| 280 | bytes_left=0; |
| 281 | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 282 | break; |
| 283 | |
| 284 | // Recalibrate drive |
| 285 | case SCSI_CMD_RECALIBRATE: |
| 286 | LOG(1,"SCSIBUS: Recalibrate drive\n"); |
| 287 | command_local=1; |
| 288 | xfer_count=0; |
| 289 | data_last=xfer_count; |
| 290 | bytes_left=0; |
| 291 | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 292 | break; |
| 293 | |
| 294 | // Request sense, return previous error codes |
| 295 | case SCSI_CMD_REQUEST_SENSE: |
| 296 | LOG(1,"SCSIBUS: request_sense\n"); |
| 297 | command_local=1; |
| 298 | xfer_count=SCSI_SENSE_SIZE; |
| 299 | data_last=xfer_count; |
| 300 | bytes_left=0; |
| 301 | buffer[0]=sense; |
| 302 | buffer[1]=0x00; |
| 303 | buffer[2]=0x00; |
| 304 | buffer[3]=0x00; |
| 305 | SET_STATUS_SENSE(SCSI_STATUS_OK,SCSI_SENSE_NO_SENSE); |
| 306 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 307 | break; |
| 308 | |
| 309 | // Format unit |
| 310 | case SCSI_CMD_FORMAT_UNIT: |
| 311 | LOG(1,"SCSIBUS: format unit command[1]=%02X & 0x10\n",(command[1] & 0x10)); |
| 312 | command_local=1; |
| 313 | if((command[1] & 0x10)==0x10) |
| 314 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 315 | else |
| 316 | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 317 | |
| 318 | xfer_count=4; |
| 319 | data_last=xfer_count; |
| 320 | bytes_left=0; |
| 321 | dataout_timer->adjust(attotime::from_seconds(FORMAT_UNIT_TIMEOUT)); |
| 322 | break; |
| 323 | |
| 324 | // Check track format Xebec |
| 325 | case SCSI_CMD_CHECK_TRACK_FORMAT: |
| 326 | LOG(1,"SCSIBUS: check track format\n"); |
| 327 | command_local=1; |
| 328 | xfer_count=0; |
| 329 | data_last=xfer_count; |
| 330 | bytes_left=0; |
| 331 | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 332 | break; |
| 333 | |
| 334 | // Setup drive parameters Xebec |
| 335 | case SCSI_CMD_INIT_DRIVE_PARAMS: |
| 336 | LOG(1,"SCSIBUS: init_drive_params: Xebec S1410\n"); |
| 337 | command_local=1; |
| 338 | xfer_count=XEBEC_PARAMS_SIZE; |
| 339 | data_last=xfer_count; |
| 340 | bytes_left=0; |
| 341 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 342 | break; |
| 343 | |
| 344 | // Format bad track Xebec |
| 345 | case SCSI_CMD_FORMAT_ALT_TRACK: |
| 346 | LOG(1,"SCSIBUS: format_alt_track: Xebec S1410\n"); |
| 347 | command_local=1; |
| 348 | xfer_count=XEBEC_ALT_TRACK_SIZE; |
| 349 | data_last=xfer_count; |
| 350 | bytes_left=0; |
| 351 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 352 | break; |
| 353 | |
| 354 | // Write buffer Xebec S1410 specific |
| 355 | case SCSI_CMD_WRITE_SEC_BUFFER: |
| 356 | LOG(1,"SCSIBUS: write_sector_buffer: Xebec S1410\n"); |
| 357 | command_local=1; |
| 358 | xfer_count=XEBEC_SECTOR_BUFFER_SIZE; |
| 359 | data_last=xfer_count; |
| 360 | bytes_left=0; |
| 361 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 362 | break; |
| 363 | |
| 364 | // Read buffer Xebec S1410 specific |
| 365 | case SCSI_CMD_READ_SEC_BUFFER: |
| 366 | LOG(1,"SCSIBUS: read_sector_buffer: Xebec S1410\n"); |
| 367 | command_local=1; |
| 368 | xfer_count=XEBEC_SECTOR_BUFFER_SIZE; |
| 369 | data_last=xfer_count; |
| 370 | bytes_left=0; |
| 371 | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
| 372 | break; |
| 373 | |
| 374 | // Write buffer, Adaptec ACB40x0 specific |
| 375 | case SCSI_CMD_WRITE_DATA_BUFFER: |
| 376 | LOG(1,"SCSIBUS: write_buffer: Adaptec ACB40x0\n"); |
| 377 | command_local=1; |
| 378 | xfer_count=ADAPTEC_DATA_BUFFER_SIZE; |
| 379 | data_last=xfer_count; |
| 380 | bytes_left=0; |
| 381 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 382 | break; |
| 383 | |
| 384 | // Read buffer, Adaptec ACB40x0 specific |
| 385 | case SCSI_CMD_READ_DATA_BUFFER: |
| 386 | LOG(1,"SCSIBUS: read_data_buffer: Adaptec ACB40x0\n"); |
| 387 | command_local=1; |
| 388 | xfer_count=ADAPTEC_DATA_BUFFER_SIZE; |
| 389 | data_last=xfer_count; |
| 390 | bytes_left=0; |
| 391 | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
| 392 | break; |
| 393 | |
| 394 | // Send diagnostic info |
| 395 | case SCSI_CMD_SEND_DIAGNOSTIC: |
| 396 | LOG(1,"SCSIBUS: send_diagnostic\n"); |
| 397 | command_local=1; |
| 398 | xfer_count=(command[3]<<8)+command[4]; |
| 399 | data_last=xfer_count; |
| 400 | bytes_left=0; |
| 401 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 402 | break; |
| 403 | |
| 404 | case SCSI_CMD_SEARCH_DATA_EQUAL: |
| 405 | LOG(1,"SCSIBUS: Search_data_equal ACB40x0\n"); |
| 406 | command_local=1; |
| 407 | xfer_count=0; |
| 408 | data_last=xfer_count; |
| 409 | bytes_left=0; |
| 410 | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 411 | break; |
| 412 | |
| 413 | case SCSI_CMD_READ_DEFECT: |
| 414 | LOG(1,"SCSIBUS: read defect list\n"); |
| 415 | command_local=1; |
| 416 | |
| 417 | buffer[0] = 0x00; |
| 418 | buffer[1] = command[2]; |
| 419 | buffer[3] = 0x00; // defect list len msb |
| 420 | buffer[4] = 0x00; // defect list len lsb |
| 421 | |
| 422 | xfer_count=4; |
| 423 | data_last=xfer_count; |
| 424 | bytes_left=0; |
| 425 | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
| 426 | break; |
| 427 | |
| 428 | // write buffer |
| 429 | case SCSI_CMD_BUFFER_WRITE: |
| 430 | LOG(1,"SCSIBUS: write_buffer\n"); |
| 431 | command_local=1; |
| 432 | xfer_count=(command[7]<<8)+command[8]; |
| 433 | data_last=xfer_count; |
| 434 | bytes_left=0; |
| 435 | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
| 436 | break; |
| 437 | |
| 438 | // read buffer |
| 439 | case SCSI_CMD_BUFFER_READ: |
| 440 | LOG(1,"SCSIBUS: read_buffer\n"); |
| 441 | command_local=1; |
| 442 | xfer_count=(command[7]<<8)+command[8]; |
| 443 | data_last=xfer_count; |
| 444 | bytes_left=0; |
| 445 | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
| 446 | break; |
| 447 | |
| 448 | // Xebec S1410 |
| 449 | case SCSI_CMD_RAM_DIAGS: |
| 450 | case SCSI_CMD_DRIVE_DIAGS: |
| 451 | case SCSI_CMD_CONTROLER_DIAGS: |
| 452 | LOG(1,"SCSIBUS: Xebec RAM, disk or Controler diags [%02X]\n",command[0]); |
| 453 | command_local=1; |
| 454 | xfer_count=0; |
| 455 | data_last=xfer_count; |
| 456 | bytes_left=0; |
| 457 | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 458 | break; |
| 459 | |
| 460 | // Commodore D9060/9090 |
| 461 | case SCSI_CMD_PHYSICAL_DEVICE_ID: |
| 462 | LOG(1,"SCSIBUS: physical device ID\n"); |
| 463 | command_local=1; |
| 464 | xfer_count=0; |
| 465 | data_last=xfer_count; |
| 466 | bytes_left=0; |
| 467 | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
| 468 | break; |
| 469 | } |
| 470 | |
| 471 | |
| 472 | // Check for locally executed command, if not then pass it on |
| 473 | // to the disk driver |
| 474 | if(!command_local) |
| 475 | { |
| 476 | devices[last_id]->SetCommand(command, cmd_idx); |
| 477 | devices[last_id]->ExecCommand(&xfer_count); |
| 478 | bytes_left=xfer_count; |
| 479 | data_last=xfer_count; |
| 480 | data_idx=0; |
| 481 | } |
| 482 | |
| 483 | devices[last_id]->GetPhase(&newphase); |
| 484 | |
| 485 | scsi_change_phase(newphase); |
| 486 | |
| 487 | LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",xfer_count,bytes_left,data_idx); |
| 488 | |
| 489 | // This is correct as we need to read from disk for commands other than just read data |
| 490 | if ((phase == SCSI_PHASE_DATAIN) && (!command_local)) |
| 491 | scsibus_read_data(); |
| 492 | } |
| 493 | |
| 494 | int scsibus_device::datain_done() |
| 495 | { |
| 496 | int result=0; |
| 497 | |
| 498 | // Read data commands |
| 499 | if(IS_READ_COMMAND() && (data_idx == data_last) && (bytes_left == 0)) |
| 500 | result=1; |
| 501 | else if (data_idx==data_last) |
| 502 | result=1; |
| 503 | |
| 504 | return result; |
| 505 | } |
| 506 | |
| 507 | int scsibus_device::dataout_done() |
| 508 | { |
| 509 | int result=0; |
| 510 | |
| 511 | // Write data commands |
| 512 | if(IS_WRITE_COMMAND() && (data_idx == 0) && (bytes_left == 0)) |
| 513 | result=1; |
| 514 | else if (data_idx==data_last) |
| 515 | result=1; |
| 516 | |
| 517 | return result; |
| 518 | } |
| 519 | |
| 520 | void scsibus_device::check_process_dataout() |
| 521 | { |
| 522 | int capacity=0; |
| 523 | int tracks; |
| 524 | adaptec_sense_t *sense; |
| 525 | |
| 526 | LOG(1,"SCSIBUS:check_process_dataout cmd=%02X\n",command[0]); |
| 527 | |
| 528 | switch (command[0]) |
| 529 | { |
| 530 | case SCSI_CMD_INIT_DRIVE_PARAMS: |
| 531 | tracks=((buffer[0]<<8)+buffer[1]); |
| 532 | capacity=(tracks * buffer[2]) * 17; |
| 533 | LOG(1,"Tracks=%d, Heads=%d\n",tracks,buffer[2]); |
| 534 | LOG(1,"Setting disk capacity to %d blocks\n",capacity); |
| 535 | //debugger_break(device->machine()); |
| 536 | break; |
| 537 | |
| 538 | case SCSI_CMD_MODE_SELECT: |
| 539 | sense=(adaptec_sense_t *)buffer; |
| 540 | tracks=(sense->cylinder_count[0]<<8)+sense->cylinder_count[1]; |
| 541 | capacity=(tracks * sense->head_count * 17); |
| 542 | LOG(1,"Tracks=%d, Heads=%d sec/track=%d\n",tracks,sense->head_count,sense->sectors_per_track); |
| 543 | LOG(1,"Setting disk capacity to %d blocks\n",capacity); |
| 544 | dump_data_bytes(0x16); |
| 545 | //debugger_break(device->machine()); |
| 546 | break; |
| 547 | } |
| 548 | } |
| 549 | |
| 550 | |
| 551 | void scsibus_device::scsi_in_line_changed(UINT8 line, UINT8 state) |
| 552 | { |
| 553 | void *hdfile; |
| 554 | |
| 555 | // Reset aborts and returns to bus free |
| 556 | if((line==SCSI_LINE_RESET) && (state==0)) |
| 557 | { |
| 558 | scsi_change_phase(SCSI_PHASE_BUS_FREE); |
| 559 | cmd_idx=0; |
| 560 | data_idx=0; |
| 561 | is_linked=0; |
| 562 | |
| 563 | return; |
| 564 | } |
| 565 | |
| 566 | switch (phase) |
| 567 | { |
| 568 | case SCSI_PHASE_BUS_FREE: |
| 569 | if((line==SCSI_LINE_SEL) && (devices[last_id]!=NULL)) |
| 570 | { |
| 571 | // Check to see if device had image file mounted, if not, do not set busy, |
| 572 | // and stay busfree. |
| 573 | devices[last_id]->GetDevice(&hdfile); |
| 574 | if(hdfile!=(void *)NULL) |
| 575 | { |
| 576 | if(state==0) |
| 577 | sel_timer->adjust(attotime::from_nsec(BSY_DELAY_NS)); |
| 578 | else |
| 579 | scsi_change_phase(SCSI_PHASE_COMMAND); |
| 580 | } |
| 581 | } |
| 582 | break; |
| 583 | |
| 584 | case SCSI_PHASE_COMMAND: |
| 585 | if(line==SCSI_LINE_ACK) |
| 586 | { |
| 587 | if(state) |
| 588 | { |
| 589 | // If the command is ready go and execute it |
| 590 | if(cmd_idx==get_scsi_cmd_len(command[0])) |
| 591 | { |
| 592 | scsibus_exec_command(); |
| 593 | } |
| 594 | else |
| 595 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 596 | } |
| 597 | else |
| 598 | scsi_out_line_change(SCSI_LINE_REQ,1); |
| 599 | } |
| 600 | break; |
| 601 | |
| 602 | case SCSI_PHASE_DATAIN: |
| 603 | if(line==SCSI_LINE_ACK) |
| 604 | { |
| 605 | if(state) |
| 606 | { |
| 607 | if(datain_done()) |
| 608 | scsi_change_phase(SCSI_PHASE_STATUS); |
| 609 | else |
| 610 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 611 | } |
| 612 | else |
| 613 | scsi_out_line_change(SCSI_LINE_REQ,1); |
| 614 | } |
| 615 | break; |
| 616 | |
| 617 | case SCSI_PHASE_DATAOUT: |
| 618 | if(line==SCSI_LINE_ACK) |
| 619 | { |
| 620 | if(state) |
| 621 | { |
| 622 | if(dataout_done()) |
| 623 | { |
| 624 | check_process_dataout(); |
| 625 | scsi_change_phase(SCSI_PHASE_STATUS); |
| 626 | } |
| 627 | else |
| 628 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 629 | } |
| 630 | else |
| 631 | scsi_out_line_change(SCSI_LINE_REQ,1); |
| 632 | } |
| 633 | break; |
| 634 | |
| 635 | case SCSI_PHASE_STATUS: |
| 636 | if(line==SCSI_LINE_ACK) |
| 637 | { |
| 638 | if(state) |
| 639 | { |
| 640 | if(cmd_idx > 0) |
| 641 | { |
| 642 | scsi_change_phase(SCSI_PHASE_MESSAGE_IN); |
| 643 | } |
| 644 | else |
| 645 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 646 | } |
| 647 | else |
| 648 | { |
| 649 | cmd_idx++; |
| 650 | scsi_out_line_change(SCSI_LINE_REQ,1); |
| 651 | } |
| 652 | } |
| 653 | break; |
| 654 | |
| 655 | case SCSI_PHASE_MESSAGE_IN: |
| 656 | if(line==SCSI_LINE_ACK) |
| 657 | { |
| 658 | if(state) |
| 659 | { |
| 660 | if(cmd_idx > 0) |
| 661 | { |
| 662 | if(is_linked) |
| 663 | scsi_change_phase(SCSI_PHASE_COMMAND); |
| 664 | else |
| 665 | scsi_change_phase(SCSI_PHASE_BUS_FREE); |
| 666 | } |
| 667 | else |
| 668 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 669 | } |
| 670 | else |
| 671 | { |
| 672 | cmd_idx++; |
| 673 | scsi_out_line_change(SCSI_LINE_REQ,1); |
| 674 | } |
| 675 | } |
| 676 | break; |
| 677 | } |
| 678 | } |
| 679 | |
| 680 | void scsibus_device::scsi_out_line_change(UINT8 line, UINT8 state) |
| 681 | { |
| 682 | if(line==SCSI_LINE_REQ) |
| 683 | scsi_out_line_req(state); |
| 684 | else |
| 685 | scsi_out_line_change_now(line,state); |
| 686 | } |
| 687 | |
| 688 | void scsibus_device::scsi_out_line_change_now(UINT8 line, UINT8 state) |
| 689 | { |
| 690 | if(state) |
| 691 | linestate |= (1<<line); |
| 692 | else |
| 693 | linestate &= ~(1<<line); |
| 694 | |
| 695 | LOG(3,"scsi_out_line_change(%s,%d)\n",linenames[line],state); |
| 696 | |
| 697 | if(line_change_cb!=NULL) |
| 698 | line_change_cb(this, line,state); |
| 699 | |
| 700 | switch (line) |
| 701 | { |
| 702 | case SCSI_LINE_BSY: out_bsy_func(state); break; |
| 703 | case SCSI_LINE_SEL: out_sel_func(state); break; |
| 704 | case SCSI_LINE_CD: out_cd_func(state); break; |
| 705 | case SCSI_LINE_IO: out_io_func(state); break; |
| 706 | case SCSI_LINE_MSG: out_msg_func(state); break; |
| 707 | case SCSI_LINE_REQ: out_req_func(state); break; |
| 708 | case SCSI_LINE_RESET: out_rst_func(state); break; |
| 709 | } |
| 710 | } |
| 711 | |
| 712 | void scsibus_device::scsi_out_line_req(UINT8 state) |
| 713 | { |
| 714 | req_timer->adjust(attotime::from_nsec(REQ_DELAY_NS),state); |
| 715 | } |
| 716 | |
| 717 | void scsibus_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) |
| 718 | { |
| 719 | switch( tid ) |
| 720 | { |
| 721 | case 0: |
| 722 | scsi_out_line_change_now(SCSI_LINE_REQ, param); |
| 723 | break; |
| 724 | |
| 725 | case 1: |
| 726 | set_scsi_line_now(SCSI_LINE_ACK, param); |
| 727 | break; |
| 728 | |
| 729 | case 2: |
| 730 | scsi_out_line_change_now(SCSI_LINE_BSY, param); |
| 731 | break; |
| 732 | |
| 733 | case 3: |
| 734 | // Some drives, notably the ST225N and ST125N, accept fromat unit commands |
| 735 | // with flags set indicating that bad block data should be transfered but |
| 736 | // don't then implemnt a data in phase, this timeout it to catch these ! |
| 737 | if(IS_COMMAND(SCSI_CMD_FORMAT_UNIT) && (data_idx==0)) |
| 738 | scsi_change_phase(SCSI_PHASE_STATUS); |
| 739 | break; |
| 740 | } |
| 741 | } |
| 742 | |
| 743 | void scsibus_device::scsi_change_phase(UINT8 newphase) |
| 744 | { |
| 745 | LOG(1,"scsi_change_phase() from=%s, to=%s\n",phasenames[phase],phasenames[newphase]); |
| 746 | |
| 747 | phase=newphase; |
| 748 | cmd_idx=0; |
| 749 | data_idx=0; |
| 750 | |
| 751 | switch(phase) |
| 752 | { |
| 753 | case SCSI_PHASE_BUS_FREE: |
| 754 | scsi_out_line_change(SCSI_LINE_CD,1); |
| 755 | scsi_out_line_change(SCSI_LINE_IO,1); |
| 756 | scsi_out_line_change(SCSI_LINE_MSG,1); |
| 757 | scsi_out_line_change(SCSI_LINE_REQ,1); |
| 758 | scsi_out_line_change(SCSI_LINE_BSY,1); |
| 759 | LOG(1,"SCSIBUS: done\n\n"); |
| 760 | //if (IS_COMMAND(SCSI_CMD_READ_CAPACITY)) |
| 761 | // debugger_break(device->machine()); |
| 762 | break; |
| 763 | |
| 764 | case SCSI_PHASE_COMMAND: |
| 765 | scsi_out_line_change(SCSI_LINE_CD,0); |
| 766 | scsi_out_line_change(SCSI_LINE_IO,1); |
| 767 | scsi_out_line_change(SCSI_LINE_MSG,1); |
| 768 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 769 | LOG(1,"\nSCSIBUS: Command begin\n"); |
| 770 | break; |
| 771 | |
| 772 | case SCSI_PHASE_DATAOUT: |
| 773 | scsi_out_line_change(SCSI_LINE_CD,1); |
| 774 | scsi_out_line_change(SCSI_LINE_IO,1); |
| 775 | scsi_out_line_change(SCSI_LINE_MSG,1); |
| 776 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 777 | break; |
| 778 | |
| 779 | case SCSI_PHASE_DATAIN: |
| 780 | scsi_out_line_change(SCSI_LINE_CD,1); |
| 781 | scsi_out_line_change(SCSI_LINE_IO,0); |
| 782 | scsi_out_line_change(SCSI_LINE_MSG,1); |
| 783 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 784 | break; |
| 785 | |
| 786 | case SCSI_PHASE_STATUS: |
| 787 | scsi_out_line_change(SCSI_LINE_CD,0); |
| 788 | scsi_out_line_change(SCSI_LINE_IO,0); |
| 789 | scsi_out_line_change(SCSI_LINE_MSG,1); |
| 790 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 791 | break; |
| 792 | |
| 793 | case SCSI_PHASE_MESSAGE_OUT: |
| 794 | scsi_out_line_change(SCSI_LINE_CD,0); |
| 795 | scsi_out_line_change(SCSI_LINE_IO,1); |
| 796 | scsi_out_line_change(SCSI_LINE_MSG,0); |
| 797 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 798 | break; |
| 799 | |
| 800 | case SCSI_PHASE_MESSAGE_IN: |
| 801 | scsi_out_line_change(SCSI_LINE_CD,0); |
| 802 | scsi_out_line_change(SCSI_LINE_IO,0); |
| 803 | scsi_out_line_change(SCSI_LINE_MSG,0); |
| 804 | scsi_out_line_change(SCSI_LINE_REQ,0); |
| 805 | break; |
| 806 | } |
| 807 | } |
| 808 | |
| 809 | UINT8 scsibus_device::scsibus_driveno(UINT8 drivesel) |
| 810 | { |
| 811 | switch (drivesel) |
| 812 | { |
| 813 | case 0x01: return 0; |
| 814 | case 0x02: return 1; |
| 815 | case 0x04: return 2; |
| 816 | case 0x08: return 3; |
| 817 | case 0x10: return 4; |
| 818 | case 0x20: return 5; |
| 819 | case 0x40: return 6; |
| 820 | case 0x80: return 7; |
| 821 | default: return 0; |
| 822 | } |
| 823 | } |
| 824 | |
| 825 | // get the length of a SCSI command based on it's command byte type |
| 826 | int scsibus_device::get_scsi_cmd_len(int cbyte) |
| 827 | { |
| 828 | int group; |
| 829 | |
| 830 | group = (cbyte>>5) & 7; |
| 831 | |
| 832 | if (group == 0 || group == 3 || group == 6 || group == 7) return 6; |
| 833 | if (group == 1 || group == 2) return 10; |
| 834 | if (group == 5) return 12; |
| 835 | |
| 836 | fatalerror("scsibus: Unknown SCSI command group %d, command byte=%02X", group,cbyte); |
| 837 | |
| 838 | return 6; |
| 839 | } |
| 840 | |
| 841 | void scsibus_device::init_scsibus(int _sectorbytes) |
| 842 | { |
| 843 | sectorbytes = _sectorbytes; |
| 844 | } |
| 845 | |
| 846 | scsibus_device::scsibus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
| 847 | : device_t(mconfig, SCSIBUS, "SCSI bus", tag, owner, clock) |
| 848 | { |
| 849 | } |
| 850 | |
| 851 | void scsibus_device::device_config_complete() |
| 852 | { |
| 853 | // inherit a copy of the static data |
| 854 | const SCSIBus_interface *intf = reinterpret_cast<const SCSIBus_interface *>(static_config()); |
| 855 | if (intf != NULL) |
| 856 | { |
| 857 | *static_cast<SCSIBus_interface *>(this) = *intf; |
| 858 | } |
| 859 | } |
| 860 | |
| 861 | void scsibus_device::device_start() |
| 862 | { |
| 863 | memset(devices, 0, sizeof(devices)); |
| 864 | |
| 865 | out_bsy_func.resolve(_out_bsy_func, *this); |
| 866 | out_sel_func.resolve(_out_sel_func, *this); |
| 867 | out_cd_func.resolve(_out_cd_func, *this); |
| 868 | out_io_func.resolve(_out_io_func, *this); |
| 869 | out_msg_func.resolve(_out_msg_func, *this); |
| 870 | out_req_func.resolve(_out_req_func, *this); |
| 871 | out_rst_func.resolve(_out_rst_func, *this); |
| 872 | |
| 873 | // All lines start high - inactive |
| 874 | linestate=0xFF; |
| 875 | |
| 876 | // Start with bus free |
| 877 | phase=SCSI_PHASE_BUS_FREE; |
| 878 | |
| 879 | // Setup req/ack/sel timers |
| 880 | req_timer=timer_alloc(0); |
| 881 | ack_timer=timer_alloc(1); |
| 882 | sel_timer=timer_alloc(2); |
| 883 | dataout_timer=timer_alloc(3); |
| 884 | |
| 885 | for( device_t *device = first_subdevice(); device != NULL; device = device->next() ) |
| 886 | { |
| 887 | scsidev_device *scsidev = dynamic_cast<scsidev_device *>(device); |
| 888 | if( scsidev != NULL ) |
| 889 | { |
| 890 | devices[scsidev->GetDeviceID()] = scsidev; |
| 891 | } |
| 892 | } |
| 893 | } |
| 894 | |
| 895 | const device_type SCSIBUS = &device_creator<scsibus_device>; |
trunk/src/emu/machine/scsibus.h
r0 | r17552 | |
| 1 | /* |
| 2 | SCSIBus.h |
| 3 | |
| 4 | Implementation of a raw SCSI/SASI bus for machines that don't use a SCSI |
| 5 | controler chip such as the RM Nimbus, which implements it as a bunch of |
| 6 | 74LS series chips. |
| 7 | |
| 8 | */ |
| 9 | |
| 10 | #ifndef _SCSIBUS_H_ |
| 11 | #define _SCSIBUS_H_ |
| 12 | |
| 13 | #include "machine/scsidev.h" |
| 14 | |
| 15 | |
| 16 | /*************************************************************************** |
| 17 | INTERFACE |
| 18 | ***************************************************************************/ |
| 19 | |
| 20 | typedef struct _SCSIBus_interface SCSIBus_interface; |
| 21 | struct _SCSIBus_interface |
| 22 | { |
| 23 | void (*line_change_cb)(device_t *, UINT8 line, UINT8 state); |
| 24 | |
| 25 | devcb_write_line _out_bsy_func; |
| 26 | devcb_write_line _out_sel_func; |
| 27 | devcb_write_line _out_cd_func; |
| 28 | devcb_write_line _out_io_func; |
| 29 | devcb_write_line _out_msg_func; |
| 30 | devcb_write_line _out_req_func; |
| 31 | devcb_write_line _out_rst_func; |
| 32 | }; |
| 33 | |
| 34 | /*************************************************************************** |
| 35 | MACROS |
| 36 | ***************************************************************************/ |
| 37 | |
| 38 | #define MCFG_SCSIBUS_ADD(_tag, _intrf) \ |
| 39 | MCFG_DEVICE_ADD(_tag, SCSIBUS, 0) \ |
| 40 | MCFG_DEVICE_CONFIG(_intrf) |
| 41 | |
| 42 | |
| 43 | /*************************************************************************** |
| 44 | CONSTANTS |
| 45 | ***************************************************************************/ |
| 46 | |
| 47 | #define SCSI_LINE_SEL 0 |
| 48 | #define SCSI_LINE_BSY 1 |
| 49 | #define SCSI_LINE_REQ 2 |
| 50 | #define SCSI_LINE_ACK 3 |
| 51 | #define SCSI_LINE_CD 4 |
| 52 | #define SCSI_LINE_IO 5 |
| 53 | #define SCSI_LINE_MSG 6 |
| 54 | #define SCSI_LINE_RESET 7 |
| 55 | |
| 56 | // Perhaps thse should be in scsi.h ? |
| 57 | #define SCSI_PHASE_BUS_FREE 8 |
| 58 | #define SCSI_PHASE_SELECT 9 |
| 59 | |
| 60 | #define REQ_DELAY_NS 90 |
| 61 | #define ACK_DELAY_NS 90 |
| 62 | #define BSY_DELAY_NS 50 |
| 63 | |
| 64 | #define CMD_BUF_SIZE 32 |
| 65 | #define ADAPTEC_BUF_SIZE 1024 |
| 66 | |
| 67 | #define SCSI_CMD_TEST_READY 0x00 |
| 68 | #define SCSI_CMD_RECALIBRATE 0x01 |
| 69 | #define SCSI_CMD_REQUEST_SENSE 0x03 |
| 70 | #define SCSI_CMD_FORMAT_UNIT 0x04 |
| 71 | #define SCSI_CMD_CHECK_TRACK_FORMAT 0x05 |
| 72 | #define SCSI_CMD_INIT_DRIVE_PARAMS 0x0C |
| 73 | #define SCSI_CMD_FORMAT_ALT_TRACK 0x0E |
| 74 | #define SCSI_CMD_WRITE_SEC_BUFFER 0x0F |
| 75 | #define SCSI_CMD_READ_SEC_BUFFER 0x10 |
| 76 | #define SCSI_COMMAND_INQUIRY 0x12 |
| 77 | #define SCSI_CMD_WRITE_DATA_BUFFER 0x13 |
| 78 | #define SCSI_CMD_READ_DATA_BUFFER 0x14 |
| 79 | #define SCSI_CMD_MODE_SELECT 0x15 |
| 80 | #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D |
| 81 | #define SCSI_CMD_READ_CAPACITY 0x25 |
| 82 | #define SCSI_CMD_SEARCH_DATA_EQUAL 0x31 |
| 83 | #define SCSI_CMD_READ_DEFECT 0x37 |
| 84 | #define SCSI_CMD_BUFFER_WRITE 0x3B |
| 85 | #define SCSI_CMD_BUFFER_READ 0x3C |
| 86 | |
| 87 | // Xebec SASI |
| 88 | #define SCSI_CMD_RAM_DIAGS 0xE0 |
| 89 | #define SCSI_CMD_DRIVE_DIAGS 0xE3 |
| 90 | #define SCSI_CMD_CONTROLER_DIAGS 0xE4 |
| 91 | |
| 92 | // Commodore D9060/9090 SASI |
| 93 | #define SCSI_CMD_PHYSICAL_DEVICE_ID 0xc0 |
| 94 | |
| 95 | #define RW_BUFFER_HEAD_BYTES 0x04 |
| 96 | |
| 97 | #define ADAPTEC_DATA_BUFFER_SIZE 0x0400 |
| 98 | #define XEBEC_SECTOR_BUFFER_SIZE 0x0200 |
| 99 | |
| 100 | #define XEBEC_PARAMS_SIZE 0x08 |
| 101 | #define XEBEC_ALT_TRACK_SIZE 0x03 |
| 102 | |
| 103 | #define IS_COMMAND(cmd) (command[0]==cmd) |
| 104 | #define IS_READ_COMMAND() ((command[0]==0x08) || (command[0]==0x28) || (command[0]==0xa8)) |
| 105 | #define IS_WRITE_COMMAND() ((command[0]==0x0a) || (command[0]==0x2a)) |
| 106 | #define SET_STATUS_SENSE(stat,sen) { status=(stat); sense=(sen); } |
| 107 | |
| 108 | #define FORMAT_UNIT_TIMEOUT 5 |
| 109 | |
| 110 | // |
| 111 | // Status / Sense data taken from Adaptec ACB40x0 documentation. |
| 112 | // |
| 113 | |
| 114 | #define SCSI_STATUS_OK 0x00 |
| 115 | #define SCSI_STATUS_CHECK 0x02 |
| 116 | #define SCSI_STATUS_EQUAL 0x04 |
| 117 | #define SCSI_STATUS_BUSY 0x08 |
| 118 | |
| 119 | #define SCSI_SENSE_ADDR_VALID 0x80 |
| 120 | #define SCSI_SENSE_NO_SENSE 0x00 |
| 121 | #define SCSI_SENSE_NO_INDEX 0x01 |
| 122 | #define SCSI_SENSE_SEEK_NOT_COMP 0x02 |
| 123 | #define SCSI_SENSE_WRITE_FAULT 0x03 |
| 124 | #define SCSI_SENSE_DRIVE_NOT_READY 0x04 |
| 125 | #define SCSI_SENSE_NO_TRACK0 0x06 |
| 126 | #define SCSI_SENSE_ID_CRC_ERROR 0x10 |
| 127 | #define SCSI_SENSE_UNCORRECTABLE 0x11 |
| 128 | #define SCSI_SENSE_ADDRESS_NF 0x12 |
| 129 | #define SCSI_SENSE_RECORD_NOT_FOUND 0x14 |
| 130 | #define SCSI_SENSE_SEEK_ERROR 0x15 |
| 131 | #define SCSI_SENSE_DATA_CHECK_RETRY 0x18 |
| 132 | #define SCSI_SENSE_ECC_VERIFY 0x19 |
| 133 | #define SCSI_SENSE_INTERLEAVE_ERROR 0x1A |
| 134 | #define SCSI_SENSE_UNFORMATTED 0x1C |
| 135 | #define SCSI_SENSE_ILLEGAL_COMMAND 0x20 |
| 136 | #define SCSI_SENSE_ILLEGAL_ADDRESS 0x21 |
| 137 | #define SCSI_SENSE_VOLUME_OVERFLOW 0x23 |
| 138 | #define SCSI_SENSE_BAD_ARGUMENT 0x24 |
| 139 | #define SCSI_SENSE_INVALID_LUN 0x25 |
| 140 | #define SCSI_SENSE_CART_CHANGED 0x28 |
| 141 | #define SCSI_SENSE_ERROR_OVERFLOW 0x2C |
| 142 | |
| 143 | #define SCSI_SENSE_SIZE 4 |
| 144 | |
| 145 | typedef struct |
| 146 | { |
| 147 | // parameter list |
| 148 | UINT8 reserved1[3]; |
| 149 | UINT8 length; |
| 150 | |
| 151 | // descriptor list |
| 152 | UINT8 density; |
| 153 | UINT8 reserved2[4]; |
| 154 | UINT8 block_size[3]; |
| 155 | |
| 156 | // drive parameter list |
| 157 | UINT8 format_code; |
| 158 | UINT8 cylinder_count[2]; |
| 159 | UINT8 head_count; |
| 160 | UINT8 reduced_write[2]; |
| 161 | UINT8 write_precomp[2]; |
| 162 | UINT8 landing_zone; |
| 163 | UINT8 step_pulse_code; |
| 164 | UINT8 bit_flags; |
| 165 | UINT8 sectors_per_track; |
| 166 | } adaptec_sense_t; |
| 167 | |
| 168 | class scsibus_device : public device_t, |
| 169 | public SCSIBus_interface |
| 170 | { |
| 171 | public: |
| 172 | // construction/destruction |
| 173 | scsibus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 174 | /* SCSI Bus read/write */ |
| 175 | |
| 176 | UINT8 scsi_data_r(); |
| 177 | void scsi_data_w( UINT8 data ); |
| 178 | DECLARE_READ8_MEMBER( scsi_data_r ); |
| 179 | DECLARE_WRITE8_MEMBER( scsi_data_w ); |
| 180 | |
| 181 | /* Get/Set lines */ |
| 182 | |
| 183 | UINT8 get_scsi_line(UINT8 lineno); |
| 184 | void set_scsi_line(UINT8 line, UINT8 state); |
| 185 | |
| 186 | DECLARE_READ_LINE_MEMBER( scsi_bsy_r ); |
| 187 | DECLARE_READ_LINE_MEMBER( scsi_sel_r ); |
| 188 | DECLARE_READ_LINE_MEMBER( scsi_cd_r ); |
| 189 | DECLARE_READ_LINE_MEMBER( scsi_io_r ); |
| 190 | DECLARE_READ_LINE_MEMBER( scsi_msg_r ); |
| 191 | DECLARE_READ_LINE_MEMBER( scsi_req_r ); |
| 192 | DECLARE_READ_LINE_MEMBER( scsi_ack_r ); |
| 193 | DECLARE_READ_LINE_MEMBER( scsi_rst_r ); |
| 194 | |
| 195 | DECLARE_WRITE_LINE_MEMBER( scsi_bsy_w ); |
| 196 | DECLARE_WRITE_LINE_MEMBER( scsi_sel_w ); |
| 197 | DECLARE_WRITE_LINE_MEMBER( scsi_cd_w ); |
| 198 | DECLARE_WRITE_LINE_MEMBER( scsi_io_w ); |
| 199 | DECLARE_WRITE_LINE_MEMBER( scsi_msg_w ); |
| 200 | DECLARE_WRITE_LINE_MEMBER( scsi_req_w ); |
| 201 | DECLARE_WRITE_LINE_MEMBER( scsi_ack_w ); |
| 202 | DECLARE_WRITE_LINE_MEMBER( scsi_rst_w ); |
| 203 | |
| 204 | /* Initialisation at machine reset time */ |
| 205 | void init_scsibus(int sectorbytes); |
| 206 | |
| 207 | protected: |
| 208 | // device-level overrides |
| 209 | virtual void device_config_complete(); |
| 210 | virtual void device_start(); |
| 211 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 212 | |
| 213 | private: |
| 214 | int get_scsi_cmd_len(int cbyte); |
| 215 | UINT8 scsibus_driveno(UINT8 drivesel); |
| 216 | void scsi_change_phase(UINT8 newphase); |
| 217 | void set_scsi_line_now(UINT8 line, UINT8 state); |
| 218 | void set_scsi_line_ack(UINT8 state); |
| 219 | void scsi_in_line_changed(UINT8 line, UINT8 state); |
| 220 | void scsi_out_line_change(UINT8 line, UINT8 state); |
| 221 | void scsi_out_line_change_now(UINT8 line, UINT8 state); |
| 222 | void scsi_out_line_req(UINT8 state); |
| 223 | void scsibus_read_data(); |
| 224 | void scsibus_write_data(); |
| 225 | int datain_done(); |
| 226 | int dataout_done(); |
| 227 | void scsibus_exec_command(); |
| 228 | void check_process_dataout(); |
| 229 | void dump_command_bytes(); |
| 230 | void dump_data_bytes(int count); |
| 231 | void dump_bytes(UINT8 *buff, int count); |
| 232 | |
| 233 | scsidev_device *devices[8]; |
| 234 | |
| 235 | devcb_resolved_write_line out_bsy_func; |
| 236 | devcb_resolved_write_line out_sel_func; |
| 237 | devcb_resolved_write_line out_cd_func; |
| 238 | devcb_resolved_write_line out_io_func; |
| 239 | devcb_resolved_write_line out_msg_func; |
| 240 | devcb_resolved_write_line out_req_func; |
| 241 | devcb_resolved_write_line out_rst_func; |
| 242 | |
| 243 | UINT8 linestate; |
| 244 | UINT8 last_id; |
| 245 | UINT8 phase; |
| 246 | |
| 247 | UINT8 command[CMD_BUF_SIZE]; |
| 248 | UINT8 cmd_idx; |
| 249 | UINT8 is_linked; |
| 250 | |
| 251 | UINT8 status; |
| 252 | UINT8 sense; |
| 253 | |
| 254 | UINT8 buffer[ADAPTEC_BUF_SIZE]; |
| 255 | UINT16 data_idx; |
| 256 | int xfer_count; |
| 257 | int bytes_left; |
| 258 | int data_last; |
| 259 | int sectorbytes; |
| 260 | |
| 261 | emu_timer *req_timer; |
| 262 | emu_timer *ack_timer; |
| 263 | emu_timer *sel_timer; |
| 264 | emu_timer *dataout_timer; |
| 265 | }; |
| 266 | |
| 267 | // device type definition |
| 268 | extern const device_type SCSIBUS; |
| 269 | |
| 270 | #endif |
trunk/src/mess/machine/scsibus.c
r17551 | r17552 | |
1 | | /* |
2 | | SCSIBus.c |
3 | | |
4 | | Implementation of a raw SCSI/SASI bus for machines that don't use a SCSI |
5 | | controler chip such as the RM Nimbus, which implements it as a bunch of |
6 | | 74LS series chips. |
7 | | |
8 | | */ |
9 | | |
10 | | #include "emu.h" |
11 | | #include "machine/scsi.h" |
12 | | #include "machine/scsidev.h" |
13 | | #include "machine/scsibus.h" |
14 | | #include "debugger.h" |
15 | | #include "debug/debugcpu.h" |
16 | | #include "debug/debugcon.h" |
17 | | |
18 | | /* |
19 | | LOGLEVEL |
20 | | 0 no logging, |
21 | | 1 just commands |
22 | | 2 1 + data |
23 | | 3 2 + line changes |
24 | | */ |
25 | | |
26 | | #define LOGLEVEL 0 |
27 | | |
28 | | #define LOG(level,...) if(LOGLEVEL>=level) logerror(__VA_ARGS__) |
29 | | |
30 | | static const char *const linenames[] = |
31 | | { |
32 | | "select", "busy", "request", "acknoledge", "C/D", "I/O", "message", "reset" |
33 | | }; |
34 | | |
35 | | static const char *const phasenames[] = |
36 | | { |
37 | | "data out", "data in", "command", "status", "none", "none", "message out", "message in", "bus free","select" |
38 | | }; |
39 | | |
40 | | void scsibus_device::dump_bytes(UINT8 *buff, int count) |
41 | | { |
42 | | int byteno; |
43 | | |
44 | | for(byteno=0; byteno<count; byteno++) |
45 | | { |
46 | | logerror("%02X ",buff[byteno]); |
47 | | } |
48 | | } |
49 | | |
50 | | void scsibus_device::dump_command_bytes() |
51 | | { |
52 | | logerror("sending command 0x%02X to ScsiID %d\n",command[0],last_id); |
53 | | dump_bytes(command,cmd_idx); |
54 | | logerror("\n\n"); |
55 | | } |
56 | | |
57 | | void scsibus_device::dump_data_bytes(int count) |
58 | | { |
59 | | logerror("Data buffer[0..%d]\n",count); |
60 | | dump_bytes(buffer,count); |
61 | | logerror("\n\n"); |
62 | | } |
63 | | |
64 | | void scsibus_device::scsibus_read_data() |
65 | | { |
66 | | data_last = (bytes_left >= sectorbytes) ? sectorbytes : bytes_left; |
67 | | |
68 | | LOG(2,"SCSIBUS:scsibus_read_data bytes_left=%04X, data_last=%04X, xfer_count=%04X\n",bytes_left,data_last,xfer_count); |
69 | | |
70 | | if (data_last > 0) |
71 | | { |
72 | | devices[last_id]->ReadData(buffer, data_last); |
73 | | bytes_left-=data_last; |
74 | | data_idx=0; |
75 | | } |
76 | | } |
77 | | |
78 | | void scsibus_device::scsibus_write_data() |
79 | | { |
80 | | if(bytes_left >= sectorbytes) |
81 | | { |
82 | | devices[last_id]->WriteData(buffer, sectorbytes); |
83 | | |
84 | | bytes_left-=sectorbytes; |
85 | | data_idx=0; |
86 | | } |
87 | | } |
88 | | |
89 | | /* SCSI Bus read/write */ |
90 | | |
91 | | UINT8 scsibus_device::scsi_data_r() |
92 | | { |
93 | | UINT8 result = 0; |
94 | | |
95 | | switch (phase) |
96 | | { |
97 | | case SCSI_PHASE_DATAIN: |
98 | | result=buffer[data_idx++]; |
99 | | |
100 | | // check to see if we have reached the end of the block buffer |
101 | | // and that there is more data to read from the scsi disk |
102 | | if((data_idx==sectorbytes) && (bytes_left>0) && IS_READ_COMMAND()) |
103 | | { |
104 | | scsibus_read_data(); |
105 | | } |
106 | | break; |
107 | | |
108 | | case SCSI_PHASE_STATUS: |
109 | | result=status; // return command status |
110 | | break; |
111 | | |
112 | | case SCSI_PHASE_MESSAGE_IN: |
113 | | result=0; // no errors for the time being ! |
114 | | break; |
115 | | } |
116 | | |
117 | | LOG(2,"scsi_data_r : %02x phase=%s, data_idx=%d, cmd_idx=%d\n",result,phasenames[phase],data_idx,cmd_idx); |
118 | | return result; |
119 | | } |
120 | | |
121 | | READ8_MEMBER( scsibus_device::scsi_data_r ) |
122 | | { |
123 | | return scsi_data_r(); |
124 | | } |
125 | | |
126 | | void scsibus_device::scsi_data_w( UINT8 data ) |
127 | | { |
128 | | switch (phase) |
129 | | { |
130 | | // Note this assumes we only have one initiator and therefore |
131 | | // only one line active. |
132 | | case SCSI_PHASE_BUS_FREE: |
133 | | last_id=scsibus_driveno(data); |
134 | | break; |
135 | | |
136 | | case SCSI_PHASE_COMMAND: |
137 | | command[cmd_idx++]=data; |
138 | | break; |
139 | | |
140 | | case SCSI_PHASE_DATAOUT: |
141 | | |
142 | | //LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",xfer_count,bytes_left,data_idx); |
143 | | |
144 | | if(IS_COMMAND(SCSI_CMD_FORMAT_UNIT)) |
145 | | { |
146 | | // Only store the first 4 bytes of the bad block list (the header) |
147 | | //if(data_idx<4) |
148 | | buffer[data_idx++]=data; |
149 | | dump_data_bytes(4); |
150 | | //else |
151 | | // data_idx++; |
152 | | |
153 | | // If we have the first byte, then cancel the dataout timout |
154 | | if(data_idx==1) |
155 | | dataout_timer->adjust(attotime::never); |
156 | | |
157 | | // When we have the first 3 bytes, calculate how many more are in the |
158 | | // bad block list. |
159 | | if(data_idx==3) |
160 | | { |
161 | | xfer_count+=((buffer[2]<<8)+buffer[3]); |
162 | | data_last=xfer_count; |
163 | | LOG(1,"format_unit reading an extra %d bytes\n",xfer_count-4); |
164 | | dump_data_bytes(4); |
165 | | } |
166 | | } |
167 | | else |
168 | | { |
169 | | buffer[data_idx++]=data; |
170 | | } |
171 | | |
172 | | // If the data buffer is full, and we are writing blocks flush it to the SCSI disk |
173 | | if((data_idx == sectorbytes) && IS_WRITE_COMMAND()) |
174 | | scsibus_write_data(); |
175 | | break; |
176 | | } |
177 | | } |
178 | | |
179 | | WRITE8_MEMBER( scsibus_device::scsi_data_w ) |
180 | | { |
181 | | scsi_data_w( data ); |
182 | | } |
183 | | |
184 | | /* Get/Set lines */ |
185 | | |
186 | | UINT8 scsibus_device::get_scsi_line(UINT8 lineno) |
187 | | { |
188 | | UINT8 result=0; |
189 | | |
190 | | switch (lineno) |
191 | | { |
192 | | case SCSI_LINE_SEL: result=(linestate & (1<<SCSI_LINE_SEL)) >> SCSI_LINE_SEL; break; |
193 | | case SCSI_LINE_BSY: result=(linestate & (1<<SCSI_LINE_BSY)) >> SCSI_LINE_BSY; break; |
194 | | case SCSI_LINE_REQ: result=(linestate & (1<<SCSI_LINE_REQ)) >> SCSI_LINE_REQ; break; |
195 | | case SCSI_LINE_ACK: result=(linestate & (1<<SCSI_LINE_ACK)) >> SCSI_LINE_ACK; break; |
196 | | case SCSI_LINE_CD: result=(linestate & (1<<SCSI_LINE_CD )) >> SCSI_LINE_CD; break; |
197 | | case SCSI_LINE_IO: result=(linestate & (1<<SCSI_LINE_IO )) >> SCSI_LINE_IO; break; |
198 | | case SCSI_LINE_MSG: result=(linestate & (1<<SCSI_LINE_MSG)) >> SCSI_LINE_MSG; break; |
199 | | case SCSI_LINE_RESET: result=(linestate & (1<<SCSI_LINE_RESET)) >> SCSI_LINE_RESET; break; |
200 | | } |
201 | | |
202 | | LOG(3,"get_scsi_line(%s)=%d\n",linenames[lineno],result); |
203 | | |
204 | | return result; |
205 | | } |
206 | | |
207 | | READ_LINE_MEMBER( scsibus_device::scsi_bsy_r ) { return get_scsi_line(SCSI_LINE_BSY); } |
208 | | READ_LINE_MEMBER( scsibus_device::scsi_sel_r ) { return get_scsi_line(SCSI_LINE_SEL); } |
209 | | READ_LINE_MEMBER( scsibus_device::scsi_cd_r ) { return get_scsi_line(SCSI_LINE_CD); } |
210 | | READ_LINE_MEMBER( scsibus_device::scsi_io_r ) { return get_scsi_line(SCSI_LINE_IO); } |
211 | | READ_LINE_MEMBER( scsibus_device::scsi_msg_r ) { return get_scsi_line(SCSI_LINE_MSG); } |
212 | | READ_LINE_MEMBER( scsibus_device::scsi_req_r ) { return get_scsi_line(SCSI_LINE_REQ); } |
213 | | READ_LINE_MEMBER( scsibus_device::scsi_ack_r ) { return get_scsi_line(SCSI_LINE_ACK); } |
214 | | READ_LINE_MEMBER( scsibus_device::scsi_rst_r ) { return get_scsi_line(SCSI_LINE_RESET); } |
215 | | |
216 | | void scsibus_device::set_scsi_line(UINT8 line, UINT8 state) |
217 | | { |
218 | | UINT8 changed; |
219 | | |
220 | | changed = ((linestate & (1<<line)) != (state << line)); |
221 | | |
222 | | LOG(3,"set_scsi_line(%s,%d), changed=%d, linestate=%02X\n",linenames[line],state,changed,linestate); |
223 | | |
224 | | if(changed) |
225 | | { |
226 | | if (line==SCSI_LINE_ACK) |
227 | | set_scsi_line_ack(state); |
228 | | else |
229 | | set_scsi_line_now(line,state); |
230 | | } |
231 | | } |
232 | | |
233 | | WRITE_LINE_MEMBER( scsibus_device::scsi_bsy_w ) { set_scsi_line(SCSI_LINE_BSY, state); } |
234 | | WRITE_LINE_MEMBER( scsibus_device::scsi_sel_w ) { set_scsi_line(SCSI_LINE_SEL, state); } |
235 | | WRITE_LINE_MEMBER( scsibus_device::scsi_cd_w ) { set_scsi_line(SCSI_LINE_CD, state); } |
236 | | WRITE_LINE_MEMBER( scsibus_device::scsi_io_w ) { set_scsi_line(SCSI_LINE_IO, state); } |
237 | | WRITE_LINE_MEMBER( scsibus_device::scsi_msg_w ) { set_scsi_line(SCSI_LINE_MSG, state); } |
238 | | WRITE_LINE_MEMBER( scsibus_device::scsi_req_w ) { set_scsi_line(SCSI_LINE_REQ, state); } |
239 | | WRITE_LINE_MEMBER( scsibus_device::scsi_ack_w ) { set_scsi_line(SCSI_LINE_ACK, state); } |
240 | | WRITE_LINE_MEMBER( scsibus_device::scsi_rst_w ) { set_scsi_line(SCSI_LINE_RESET, state); } |
241 | | |
242 | | void scsibus_device::set_scsi_line_now(UINT8 line, UINT8 state) |
243 | | { |
244 | | if(state) |
245 | | linestate |= (1<<line); |
246 | | else |
247 | | linestate &= ~(1<<line); |
248 | | |
249 | | scsi_in_line_changed(line,state); |
250 | | } |
251 | | |
252 | | void scsibus_device::set_scsi_line_ack(UINT8 state) |
253 | | { |
254 | | ack_timer->adjust(attotime::from_nsec(ACK_DELAY_NS),state); |
255 | | } |
256 | | |
257 | | void scsibus_device::scsibus_exec_command() |
258 | | { |
259 | | int command_local = 0; |
260 | | int newphase; |
261 | | |
262 | | if(LOGLEVEL) |
263 | | dump_command_bytes(); |
264 | | |
265 | | //is_linked=command[cmd_idx-1] & 0x01; |
266 | | is_linked=0; |
267 | | |
268 | | // Assume command will succeed, if not set sytatus below. |
269 | | if (command[0]!=SCSI_CMD_REQUEST_SENSE) |
270 | | SET_STATUS_SENSE(SCSI_STATUS_OK,SCSI_SENSE_NO_SENSE); |
271 | | |
272 | | // Check for locally executed commands, and if found execute them |
273 | | switch (command[0]) |
274 | | { |
275 | | // Test ready |
276 | | case SCSI_CMD_TEST_READY: |
277 | | LOG(1,"SCSIBUS: test_ready\n"); |
278 | | command_local=1; |
279 | | xfer_count=0; |
280 | | data_last=xfer_count; |
281 | | bytes_left=0; |
282 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
283 | | break; |
284 | | |
285 | | // Recalibrate drive |
286 | | case SCSI_CMD_RECALIBRATE: |
287 | | LOG(1,"SCSIBUS: Recalibrate drive\n"); |
288 | | command_local=1; |
289 | | xfer_count=0; |
290 | | data_last=xfer_count; |
291 | | bytes_left=0; |
292 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
293 | | break; |
294 | | |
295 | | // Request sense, return previous error codes |
296 | | case SCSI_CMD_REQUEST_SENSE: |
297 | | LOG(1,"SCSIBUS: request_sense\n"); |
298 | | command_local=1; |
299 | | xfer_count=SCSI_SENSE_SIZE; |
300 | | data_last=xfer_count; |
301 | | bytes_left=0; |
302 | | buffer[0]=sense; |
303 | | buffer[1]=0x00; |
304 | | buffer[2]=0x00; |
305 | | buffer[3]=0x00; |
306 | | SET_STATUS_SENSE(SCSI_STATUS_OK,SCSI_SENSE_NO_SENSE); |
307 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
308 | | break; |
309 | | |
310 | | // Format unit |
311 | | case SCSI_CMD_FORMAT_UNIT: |
312 | | LOG(1,"SCSIBUS: format unit command[1]=%02X & 0x10\n",(command[1] & 0x10)); |
313 | | command_local=1; |
314 | | if((command[1] & 0x10)==0x10) |
315 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
316 | | else |
317 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
318 | | |
319 | | xfer_count=4; |
320 | | data_last=xfer_count; |
321 | | bytes_left=0; |
322 | | dataout_timer->adjust(attotime::from_seconds(FORMAT_UNIT_TIMEOUT)); |
323 | | break; |
324 | | |
325 | | // Check track format Xebec |
326 | | case SCSI_CMD_CHECK_TRACK_FORMAT: |
327 | | LOG(1,"SCSIBUS: check track format\n"); |
328 | | command_local=1; |
329 | | xfer_count=0; |
330 | | data_last=xfer_count; |
331 | | bytes_left=0; |
332 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
333 | | break; |
334 | | |
335 | | // Setup drive parameters Xebec |
336 | | case SCSI_CMD_INIT_DRIVE_PARAMS: |
337 | | LOG(1,"SCSIBUS: init_drive_params: Xebec S1410\n"); |
338 | | command_local=1; |
339 | | xfer_count=XEBEC_PARAMS_SIZE; |
340 | | data_last=xfer_count; |
341 | | bytes_left=0; |
342 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
343 | | break; |
344 | | |
345 | | // Format bad track Xebec |
346 | | case SCSI_CMD_FORMAT_ALT_TRACK: |
347 | | LOG(1,"SCSIBUS: format_alt_track: Xebec S1410\n"); |
348 | | command_local=1; |
349 | | xfer_count=XEBEC_ALT_TRACK_SIZE; |
350 | | data_last=xfer_count; |
351 | | bytes_left=0; |
352 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
353 | | break; |
354 | | |
355 | | // Write buffer Xebec S1410 specific |
356 | | case SCSI_CMD_WRITE_SEC_BUFFER: |
357 | | LOG(1,"SCSIBUS: write_sector_buffer: Xebec S1410\n"); |
358 | | command_local=1; |
359 | | xfer_count=XEBEC_SECTOR_BUFFER_SIZE; |
360 | | data_last=xfer_count; |
361 | | bytes_left=0; |
362 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
363 | | break; |
364 | | |
365 | | // Read buffer Xebec S1410 specific |
366 | | case SCSI_CMD_READ_SEC_BUFFER: |
367 | | LOG(1,"SCSIBUS: read_sector_buffer: Xebec S1410\n"); |
368 | | command_local=1; |
369 | | xfer_count=XEBEC_SECTOR_BUFFER_SIZE; |
370 | | data_last=xfer_count; |
371 | | bytes_left=0; |
372 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
373 | | break; |
374 | | |
375 | | // Write buffer, Adaptec ACB40x0 specific |
376 | | case SCSI_CMD_WRITE_DATA_BUFFER: |
377 | | LOG(1,"SCSIBUS: write_buffer: Adaptec ACB40x0\n"); |
378 | | command_local=1; |
379 | | xfer_count=ADAPTEC_DATA_BUFFER_SIZE; |
380 | | data_last=xfer_count; |
381 | | bytes_left=0; |
382 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
383 | | break; |
384 | | |
385 | | // Read buffer, Adaptec ACB40x0 specific |
386 | | case SCSI_CMD_READ_DATA_BUFFER: |
387 | | LOG(1,"SCSIBUS: read_data_buffer: Adaptec ACB40x0\n"); |
388 | | command_local=1; |
389 | | xfer_count=ADAPTEC_DATA_BUFFER_SIZE; |
390 | | data_last=xfer_count; |
391 | | bytes_left=0; |
392 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
393 | | break; |
394 | | |
395 | | // Send diagnostic info |
396 | | case SCSI_CMD_SEND_DIAGNOSTIC: |
397 | | LOG(1,"SCSIBUS: send_diagnostic\n"); |
398 | | command_local=1; |
399 | | xfer_count=(command[3]<<8)+command[4]; |
400 | | data_last=xfer_count; |
401 | | bytes_left=0; |
402 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
403 | | break; |
404 | | |
405 | | case SCSI_CMD_SEARCH_DATA_EQUAL: |
406 | | LOG(1,"SCSIBUS: Search_data_equal ACB40x0\n"); |
407 | | command_local=1; |
408 | | xfer_count=0; |
409 | | data_last=xfer_count; |
410 | | bytes_left=0; |
411 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
412 | | break; |
413 | | |
414 | | case SCSI_CMD_READ_DEFECT: |
415 | | LOG(1,"SCSIBUS: read defect list\n"); |
416 | | command_local=1; |
417 | | |
418 | | buffer[0] = 0x00; |
419 | | buffer[1] = command[2]; |
420 | | buffer[3] = 0x00; // defect list len msb |
421 | | buffer[4] = 0x00; // defect list len lsb |
422 | | |
423 | | xfer_count=4; |
424 | | data_last=xfer_count; |
425 | | bytes_left=0; |
426 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
427 | | break; |
428 | | |
429 | | // write buffer |
430 | | case SCSI_CMD_BUFFER_WRITE: |
431 | | LOG(1,"SCSIBUS: write_buffer\n"); |
432 | | command_local=1; |
433 | | xfer_count=(command[7]<<8)+command[8]; |
434 | | data_last=xfer_count; |
435 | | bytes_left=0; |
436 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAOUT); |
437 | | break; |
438 | | |
439 | | // read buffer |
440 | | case SCSI_CMD_BUFFER_READ: |
441 | | LOG(1,"SCSIBUS: read_buffer\n"); |
442 | | command_local=1; |
443 | | xfer_count=(command[7]<<8)+command[8]; |
444 | | data_last=xfer_count; |
445 | | bytes_left=0; |
446 | | devices[last_id]->SetPhase(SCSI_PHASE_DATAIN); |
447 | | break; |
448 | | |
449 | | // Xebec S1410 |
450 | | case SCSI_CMD_RAM_DIAGS: |
451 | | case SCSI_CMD_DRIVE_DIAGS: |
452 | | case SCSI_CMD_CONTROLER_DIAGS: |
453 | | LOG(1,"SCSIBUS: Xebec RAM, disk or Controler diags [%02X]\n",command[0]); |
454 | | command_local=1; |
455 | | xfer_count=0; |
456 | | data_last=xfer_count; |
457 | | bytes_left=0; |
458 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
459 | | break; |
460 | | |
461 | | // Commodore D9060/9090 |
462 | | case SCSI_CMD_PHYSICAL_DEVICE_ID: |
463 | | LOG(1,"SCSIBUS: physical device ID\n"); |
464 | | command_local=1; |
465 | | xfer_count=0; |
466 | | data_last=xfer_count; |
467 | | bytes_left=0; |
468 | | devices[last_id]->SetPhase(SCSI_PHASE_STATUS); |
469 | | break; |
470 | | } |
471 | | |
472 | | |
473 | | // Check for locally executed command, if not then pass it on |
474 | | // to the disk driver |
475 | | if(!command_local) |
476 | | { |
477 | | devices[last_id]->SetCommand(command, cmd_idx); |
478 | | devices[last_id]->ExecCommand(&xfer_count); |
479 | | bytes_left=xfer_count; |
480 | | data_last=xfer_count; |
481 | | data_idx=0; |
482 | | } |
483 | | |
484 | | devices[last_id]->GetPhase(&newphase); |
485 | | |
486 | | scsi_change_phase(newphase); |
487 | | |
488 | | LOG(1,"SCSIBUS:xfer_count=%02X, bytes_left=%02X data_idx=%02X\n",xfer_count,bytes_left,data_idx); |
489 | | |
490 | | // This is correct as we need to read from disk for commands other than just read data |
491 | | if ((phase == SCSI_PHASE_DATAIN) && (!command_local)) |
492 | | scsibus_read_data(); |
493 | | } |
494 | | |
495 | | int scsibus_device::datain_done() |
496 | | { |
497 | | int result=0; |
498 | | |
499 | | // Read data commands |
500 | | if(IS_READ_COMMAND() && (data_idx == data_last) && (bytes_left == 0)) |
501 | | result=1; |
502 | | else if (data_idx==data_last) |
503 | | result=1; |
504 | | |
505 | | return result; |
506 | | } |
507 | | |
508 | | int scsibus_device::dataout_done() |
509 | | { |
510 | | int result=0; |
511 | | |
512 | | // Write data commands |
513 | | if(IS_WRITE_COMMAND() && (data_idx == 0) && (bytes_left == 0)) |
514 | | result=1; |
515 | | else if (data_idx==data_last) |
516 | | result=1; |
517 | | |
518 | | return result; |
519 | | } |
520 | | |
521 | | void scsibus_device::check_process_dataout() |
522 | | { |
523 | | int capacity=0; |
524 | | int tracks; |
525 | | adaptec_sense_t *sense; |
526 | | |
527 | | LOG(1,"SCSIBUS:check_process_dataout cmd=%02X\n",command[0]); |
528 | | |
529 | | switch (command[0]) |
530 | | { |
531 | | case SCSI_CMD_INIT_DRIVE_PARAMS: |
532 | | tracks=((buffer[0]<<8)+buffer[1]); |
533 | | capacity=(tracks * buffer[2]) * 17; |
534 | | LOG(1,"Tracks=%d, Heads=%d\n",tracks,buffer[2]); |
535 | | LOG(1,"Setting disk capacity to %d blocks\n",capacity); |
536 | | //debugger_break(device->machine()); |
537 | | break; |
538 | | |
539 | | case SCSI_CMD_MODE_SELECT: |
540 | | sense=(adaptec_sense_t *)buffer; |
541 | | tracks=(sense->cylinder_count[0]<<8)+sense->cylinder_count[1]; |
542 | | capacity=(tracks * sense->head_count * 17); |
543 | | LOG(1,"Tracks=%d, Heads=%d sec/track=%d\n",tracks,sense->head_count,sense->sectors_per_track); |
544 | | LOG(1,"Setting disk capacity to %d blocks\n",capacity); |
545 | | dump_data_bytes(0x16); |
546 | | //debugger_break(device->machine()); |
547 | | break; |
548 | | } |
549 | | } |
550 | | |
551 | | |
552 | | void scsibus_device::scsi_in_line_changed(UINT8 line, UINT8 state) |
553 | | { |
554 | | void *hdfile; |
555 | | |
556 | | // Reset aborts and returns to bus free |
557 | | if((line==SCSI_LINE_RESET) && (state==0)) |
558 | | { |
559 | | scsi_change_phase(SCSI_PHASE_BUS_FREE); |
560 | | cmd_idx=0; |
561 | | data_idx=0; |
562 | | is_linked=0; |
563 | | |
564 | | return; |
565 | | } |
566 | | |
567 | | switch (phase) |
568 | | { |
569 | | case SCSI_PHASE_BUS_FREE: |
570 | | if((line==SCSI_LINE_SEL) && (devices[last_id]!=NULL)) |
571 | | { |
572 | | // Check to see if device had image file mounted, if not, do not set busy, |
573 | | // and stay busfree. |
574 | | devices[last_id]->GetDevice(&hdfile); |
575 | | if(hdfile!=(void *)NULL) |
576 | | { |
577 | | if(state==0) |
578 | | sel_timer->adjust(attotime::from_nsec(BSY_DELAY_NS)); |
579 | | else |
580 | | scsi_change_phase(SCSI_PHASE_COMMAND); |
581 | | } |
582 | | } |
583 | | break; |
584 | | |
585 | | case SCSI_PHASE_COMMAND: |
586 | | if(line==SCSI_LINE_ACK) |
587 | | { |
588 | | if(state) |
589 | | { |
590 | | // If the command is ready go and execute it |
591 | | if(cmd_idx==get_scsi_cmd_len(command[0])) |
592 | | { |
593 | | scsibus_exec_command(); |
594 | | } |
595 | | else |
596 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
597 | | } |
598 | | else |
599 | | scsi_out_line_change(SCSI_LINE_REQ,1); |
600 | | } |
601 | | break; |
602 | | |
603 | | case SCSI_PHASE_DATAIN: |
604 | | if(line==SCSI_LINE_ACK) |
605 | | { |
606 | | if(state) |
607 | | { |
608 | | if(datain_done()) |
609 | | scsi_change_phase(SCSI_PHASE_STATUS); |
610 | | else |
611 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
612 | | } |
613 | | else |
614 | | scsi_out_line_change(SCSI_LINE_REQ,1); |
615 | | } |
616 | | break; |
617 | | |
618 | | case SCSI_PHASE_DATAOUT: |
619 | | if(line==SCSI_LINE_ACK) |
620 | | { |
621 | | if(state) |
622 | | { |
623 | | if(dataout_done()) |
624 | | { |
625 | | check_process_dataout(); |
626 | | scsi_change_phase(SCSI_PHASE_STATUS); |
627 | | } |
628 | | else |
629 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
630 | | } |
631 | | else |
632 | | scsi_out_line_change(SCSI_LINE_REQ,1); |
633 | | } |
634 | | break; |
635 | | |
636 | | case SCSI_PHASE_STATUS: |
637 | | if(line==SCSI_LINE_ACK) |
638 | | { |
639 | | if(state) |
640 | | { |
641 | | if(cmd_idx > 0) |
642 | | { |
643 | | scsi_change_phase(SCSI_PHASE_MESSAGE_IN); |
644 | | } |
645 | | else |
646 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
647 | | } |
648 | | else |
649 | | { |
650 | | cmd_idx++; |
651 | | scsi_out_line_change(SCSI_LINE_REQ,1); |
652 | | } |
653 | | } |
654 | | break; |
655 | | |
656 | | case SCSI_PHASE_MESSAGE_IN: |
657 | | if(line==SCSI_LINE_ACK) |
658 | | { |
659 | | if(state) |
660 | | { |
661 | | if(cmd_idx > 0) |
662 | | { |
663 | | if(is_linked) |
664 | | scsi_change_phase(SCSI_PHASE_COMMAND); |
665 | | else |
666 | | scsi_change_phase(SCSI_PHASE_BUS_FREE); |
667 | | } |
668 | | else |
669 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
670 | | } |
671 | | else |
672 | | { |
673 | | cmd_idx++; |
674 | | scsi_out_line_change(SCSI_LINE_REQ,1); |
675 | | } |
676 | | } |
677 | | break; |
678 | | } |
679 | | } |
680 | | |
681 | | void scsibus_device::scsi_out_line_change(UINT8 line, UINT8 state) |
682 | | { |
683 | | if(line==SCSI_LINE_REQ) |
684 | | scsi_out_line_req(state); |
685 | | else |
686 | | scsi_out_line_change_now(line,state); |
687 | | } |
688 | | |
689 | | void scsibus_device::scsi_out_line_change_now(UINT8 line, UINT8 state) |
690 | | { |
691 | | if(state) |
692 | | linestate |= (1<<line); |
693 | | else |
694 | | linestate &= ~(1<<line); |
695 | | |
696 | | LOG(3,"scsi_out_line_change(%s,%d)\n",linenames[line],state); |
697 | | |
698 | | if(line_change_cb!=NULL) |
699 | | line_change_cb(this, line,state); |
700 | | |
701 | | switch (line) |
702 | | { |
703 | | case SCSI_LINE_BSY: out_bsy_func(state); break; |
704 | | case SCSI_LINE_SEL: out_sel_func(state); break; |
705 | | case SCSI_LINE_CD: out_cd_func(state); break; |
706 | | case SCSI_LINE_IO: out_io_func(state); break; |
707 | | case SCSI_LINE_MSG: out_msg_func(state); break; |
708 | | case SCSI_LINE_REQ: out_req_func(state); break; |
709 | | case SCSI_LINE_RESET: out_rst_func(state); break; |
710 | | } |
711 | | } |
712 | | |
713 | | void scsibus_device::scsi_out_line_req(UINT8 state) |
714 | | { |
715 | | req_timer->adjust(attotime::from_nsec(REQ_DELAY_NS),state); |
716 | | } |
717 | | |
718 | | void scsibus_device::device_timer(emu_timer &timer, device_timer_id tid, int param, void *ptr) |
719 | | { |
720 | | switch( tid ) |
721 | | { |
722 | | case 0: |
723 | | scsi_out_line_change_now(SCSI_LINE_REQ, param); |
724 | | break; |
725 | | |
726 | | case 1: |
727 | | set_scsi_line_now(SCSI_LINE_ACK, param); |
728 | | break; |
729 | | |
730 | | case 2: |
731 | | scsi_out_line_change_now(SCSI_LINE_BSY, param); |
732 | | break; |
733 | | |
734 | | case 3: |
735 | | // Some drives, notably the ST225N and ST125N, accept fromat unit commands |
736 | | // with flags set indicating that bad block data should be transfered but |
737 | | // don't then implemnt a data in phase, this timeout it to catch these ! |
738 | | if(IS_COMMAND(SCSI_CMD_FORMAT_UNIT) && (data_idx==0)) |
739 | | scsi_change_phase(SCSI_PHASE_STATUS); |
740 | | break; |
741 | | } |
742 | | } |
743 | | |
744 | | void scsibus_device::scsi_change_phase(UINT8 newphase) |
745 | | { |
746 | | LOG(1,"scsi_change_phase() from=%s, to=%s\n",phasenames[phase],phasenames[newphase]); |
747 | | |
748 | | phase=newphase; |
749 | | cmd_idx=0; |
750 | | data_idx=0; |
751 | | |
752 | | switch(phase) |
753 | | { |
754 | | case SCSI_PHASE_BUS_FREE: |
755 | | scsi_out_line_change(SCSI_LINE_CD,1); |
756 | | scsi_out_line_change(SCSI_LINE_IO,1); |
757 | | scsi_out_line_change(SCSI_LINE_MSG,1); |
758 | | scsi_out_line_change(SCSI_LINE_REQ,1); |
759 | | scsi_out_line_change(SCSI_LINE_BSY,1); |
760 | | LOG(1,"SCSIBUS: done\n\n"); |
761 | | //if (IS_COMMAND(SCSI_CMD_READ_CAPACITY)) |
762 | | // debugger_break(device->machine()); |
763 | | break; |
764 | | |
765 | | case SCSI_PHASE_COMMAND: |
766 | | scsi_out_line_change(SCSI_LINE_CD,0); |
767 | | scsi_out_line_change(SCSI_LINE_IO,1); |
768 | | scsi_out_line_change(SCSI_LINE_MSG,1); |
769 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
770 | | LOG(1,"\nSCSIBUS: Command begin\n"); |
771 | | break; |
772 | | |
773 | | case SCSI_PHASE_DATAOUT: |
774 | | scsi_out_line_change(SCSI_LINE_CD,1); |
775 | | scsi_out_line_change(SCSI_LINE_IO,1); |
776 | | scsi_out_line_change(SCSI_LINE_MSG,1); |
777 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
778 | | break; |
779 | | |
780 | | case SCSI_PHASE_DATAIN: |
781 | | scsi_out_line_change(SCSI_LINE_CD,1); |
782 | | scsi_out_line_change(SCSI_LINE_IO,0); |
783 | | scsi_out_line_change(SCSI_LINE_MSG,1); |
784 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
785 | | break; |
786 | | |
787 | | case SCSI_PHASE_STATUS: |
788 | | scsi_out_line_change(SCSI_LINE_CD,0); |
789 | | scsi_out_line_change(SCSI_LINE_IO,0); |
790 | | scsi_out_line_change(SCSI_LINE_MSG,1); |
791 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
792 | | break; |
793 | | |
794 | | case SCSI_PHASE_MESSAGE_OUT: |
795 | | scsi_out_line_change(SCSI_LINE_CD,0); |
796 | | scsi_out_line_change(SCSI_LINE_IO,1); |
797 | | scsi_out_line_change(SCSI_LINE_MSG,0); |
798 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
799 | | break; |
800 | | |
801 | | case SCSI_PHASE_MESSAGE_IN: |
802 | | scsi_out_line_change(SCSI_LINE_CD,0); |
803 | | scsi_out_line_change(SCSI_LINE_IO,0); |
804 | | scsi_out_line_change(SCSI_LINE_MSG,0); |
805 | | scsi_out_line_change(SCSI_LINE_REQ,0); |
806 | | break; |
807 | | } |
808 | | } |
809 | | |
810 | | UINT8 scsibus_device::scsibus_driveno(UINT8 drivesel) |
811 | | { |
812 | | switch (drivesel) |
813 | | { |
814 | | case 0x01: return 0; |
815 | | case 0x02: return 1; |
816 | | case 0x04: return 2; |
817 | | case 0x08: return 3; |
818 | | case 0x10: return 4; |
819 | | case 0x20: return 5; |
820 | | case 0x40: return 6; |
821 | | case 0x80: return 7; |
822 | | default: return 0; |
823 | | } |
824 | | } |
825 | | |
826 | | // get the length of a SCSI command based on it's command byte type |
827 | | int scsibus_device::get_scsi_cmd_len(int cbyte) |
828 | | { |
829 | | int group; |
830 | | |
831 | | group = (cbyte>>5) & 7; |
832 | | |
833 | | if (group == 0 || group == 3 || group == 6 || group == 7) return 6; |
834 | | if (group == 1 || group == 2) return 10; |
835 | | if (group == 5) return 12; |
836 | | |
837 | | fatalerror("scsibus: Unknown SCSI command group %d, command byte=%02X", group,cbyte); |
838 | | |
839 | | return 6; |
840 | | } |
841 | | |
842 | | void scsibus_device::init_scsibus(int _sectorbytes) |
843 | | { |
844 | | sectorbytes = _sectorbytes; |
845 | | } |
846 | | |
847 | | scsibus_device::scsibus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) |
848 | | : device_t(mconfig, SCSIBUS, "SCSI bus", tag, owner, clock) |
849 | | { |
850 | | } |
851 | | |
852 | | void scsibus_device::device_config_complete() |
853 | | { |
854 | | // inherit a copy of the static data |
855 | | const SCSIBus_interface *intf = reinterpret_cast<const SCSIBus_interface *>(static_config()); |
856 | | if (intf != NULL) |
857 | | { |
858 | | *static_cast<SCSIBus_interface *>(this) = *intf; |
859 | | } |
860 | | } |
861 | | |
862 | | void scsibus_device::device_start() |
863 | | { |
864 | | memset(devices, 0, sizeof(devices)); |
865 | | |
866 | | out_bsy_func.resolve(_out_bsy_func, *this); |
867 | | out_sel_func.resolve(_out_sel_func, *this); |
868 | | out_cd_func.resolve(_out_cd_func, *this); |
869 | | out_io_func.resolve(_out_io_func, *this); |
870 | | out_msg_func.resolve(_out_msg_func, *this); |
871 | | out_req_func.resolve(_out_req_func, *this); |
872 | | out_rst_func.resolve(_out_rst_func, *this); |
873 | | |
874 | | // All lines start high - inactive |
875 | | linestate=0xFF; |
876 | | |
877 | | // Start with bus free |
878 | | phase=SCSI_PHASE_BUS_FREE; |
879 | | |
880 | | // Setup req/ack/sel timers |
881 | | req_timer=timer_alloc(0); |
882 | | ack_timer=timer_alloc(1); |
883 | | sel_timer=timer_alloc(2); |
884 | | dataout_timer=timer_alloc(3); |
885 | | |
886 | | for( device_t *device = first_subdevice(); device != NULL; device = device->next() ) |
887 | | { |
888 | | scsidev_device *scsidev = downcast<scsidev_device *>(device); |
889 | | devices[scsidev->GetDeviceID()] = scsidev; |
890 | | } |
891 | | } |
892 | | |
893 | | const device_type SCSIBUS = &device_creator<scsibus_device>; |
trunk/src/mess/machine/scsibus.h
r17551 | r17552 | |
1 | | /* |
2 | | SCSIBus.h |
3 | | |
4 | | Implementation of a raw SCSI/SASI bus for machines that don't use a SCSI |
5 | | controler chip such as the RM Nimbus, which implements it as a bunch of |
6 | | 74LS series chips. |
7 | | |
8 | | */ |
9 | | |
10 | | #ifndef _SCSIBUS_H_ |
11 | | #define _SCSIBUS_H_ |
12 | | |
13 | | #include "machine/scsi.h" |
14 | | #include "machine/scsidev.h" |
15 | | |
16 | | |
17 | | /*************************************************************************** |
18 | | INTERFACE |
19 | | ***************************************************************************/ |
20 | | |
21 | | typedef struct _SCSIBus_interface SCSIBus_interface; |
22 | | struct _SCSIBus_interface |
23 | | { |
24 | | void (*line_change_cb)(device_t *, UINT8 line, UINT8 state); |
25 | | |
26 | | devcb_write_line _out_bsy_func; |
27 | | devcb_write_line _out_sel_func; |
28 | | devcb_write_line _out_cd_func; |
29 | | devcb_write_line _out_io_func; |
30 | | devcb_write_line _out_msg_func; |
31 | | devcb_write_line _out_req_func; |
32 | | devcb_write_line _out_rst_func; |
33 | | }; |
34 | | |
35 | | /*************************************************************************** |
36 | | MACROS |
37 | | ***************************************************************************/ |
38 | | |
39 | | #define MCFG_SCSIBUS_ADD(_tag, _intrf) \ |
40 | | MCFG_DEVICE_ADD(_tag, SCSIBUS, 0) \ |
41 | | MCFG_DEVICE_CONFIG(_intrf) |
42 | | |
43 | | |
44 | | /*************************************************************************** |
45 | | CONSTANTS |
46 | | ***************************************************************************/ |
47 | | |
48 | | #define SCSI_LINE_SEL 0 |
49 | | #define SCSI_LINE_BSY 1 |
50 | | #define SCSI_LINE_REQ 2 |
51 | | #define SCSI_LINE_ACK 3 |
52 | | #define SCSI_LINE_CD 4 |
53 | | #define SCSI_LINE_IO 5 |
54 | | #define SCSI_LINE_MSG 6 |
55 | | #define SCSI_LINE_RESET 7 |
56 | | |
57 | | // Perhaps thse should be in scsi.h ? |
58 | | #define SCSI_PHASE_BUS_FREE 8 |
59 | | #define SCSI_PHASE_SELECT 9 |
60 | | |
61 | | #define REQ_DELAY_NS 90 |
62 | | #define ACK_DELAY_NS 90 |
63 | | #define BSY_DELAY_NS 50 |
64 | | |
65 | | #define CMD_BUF_SIZE 32 |
66 | | #define ADAPTEC_BUF_SIZE 1024 |
67 | | |
68 | | #define SCSI_CMD_TEST_READY 0x00 |
69 | | #define SCSI_CMD_RECALIBRATE 0x01 |
70 | | #define SCSI_CMD_REQUEST_SENSE 0x03 |
71 | | #define SCSI_CMD_FORMAT_UNIT 0x04 |
72 | | #define SCSI_CMD_CHECK_TRACK_FORMAT 0x05 |
73 | | #define SCSI_CMD_INIT_DRIVE_PARAMS 0x0C |
74 | | #define SCSI_CMD_FORMAT_ALT_TRACK 0x0E |
75 | | #define SCSI_CMD_WRITE_SEC_BUFFER 0x0F |
76 | | #define SCSI_CMD_READ_SEC_BUFFER 0x10 |
77 | | #define SCSI_COMMAND_INQUIRY 0x12 |
78 | | #define SCSI_CMD_WRITE_DATA_BUFFER 0x13 |
79 | | #define SCSI_CMD_READ_DATA_BUFFER 0x14 |
80 | | #define SCSI_CMD_MODE_SELECT 0x15 |
81 | | #define SCSI_CMD_SEND_DIAGNOSTIC 0x1D |
82 | | #define SCSI_CMD_READ_CAPACITY 0x25 |
83 | | #define SCSI_CMD_SEARCH_DATA_EQUAL 0x31 |
84 | | #define SCSI_CMD_READ_DEFECT 0x37 |
85 | | #define SCSI_CMD_BUFFER_WRITE 0x3B |
86 | | #define SCSI_CMD_BUFFER_READ 0x3C |
87 | | |
88 | | // Xebec SASI |
89 | | #define SCSI_CMD_RAM_DIAGS 0xE0 |
90 | | #define SCSI_CMD_DRIVE_DIAGS 0xE3 |
91 | | #define SCSI_CMD_CONTROLER_DIAGS 0xE4 |
92 | | |
93 | | // Commodore D9060/9090 SASI |
94 | | #define SCSI_CMD_PHYSICAL_DEVICE_ID 0xc0 |
95 | | |
96 | | #define RW_BUFFER_HEAD_BYTES 0x04 |
97 | | |
98 | | #define ADAPTEC_DATA_BUFFER_SIZE 0x0400 |
99 | | #define XEBEC_SECTOR_BUFFER_SIZE 0x0200 |
100 | | |
101 | | #define XEBEC_PARAMS_SIZE 0x08 |
102 | | #define XEBEC_ALT_TRACK_SIZE 0x03 |
103 | | |
104 | | #define IS_COMMAND(cmd) (command[0]==cmd) |
105 | | #define IS_READ_COMMAND() ((command[0]==0x08) || (command[0]==0x28) || (command[0]==0xa8)) |
106 | | #define IS_WRITE_COMMAND() ((command[0]==0x0a) || (command[0]==0x2a)) |
107 | | #define SET_STATUS_SENSE(stat,sen) { status=(stat); sense=(sen); } |
108 | | |
109 | | #define FORMAT_UNIT_TIMEOUT 5 |
110 | | |
111 | | // |
112 | | // Status / Sense data taken from Adaptec ACB40x0 documentation. |
113 | | // |
114 | | |
115 | | #define SCSI_STATUS_OK 0x00 |
116 | | #define SCSI_STATUS_CHECK 0x02 |
117 | | #define SCSI_STATUS_EQUAL 0x04 |
118 | | #define SCSI_STATUS_BUSY 0x08 |
119 | | |
120 | | #define SCSI_SENSE_ADDR_VALID 0x80 |
121 | | #define SCSI_SENSE_NO_SENSE 0x00 |
122 | | #define SCSI_SENSE_NO_INDEX 0x01 |
123 | | #define SCSI_SENSE_SEEK_NOT_COMP 0x02 |
124 | | #define SCSI_SENSE_WRITE_FAULT 0x03 |
125 | | #define SCSI_SENSE_DRIVE_NOT_READY 0x04 |
126 | | #define SCSI_SENSE_NO_TRACK0 0x06 |
127 | | #define SCSI_SENSE_ID_CRC_ERROR 0x10 |
128 | | #define SCSI_SENSE_UNCORRECTABLE 0x11 |
129 | | #define SCSI_SENSE_ADDRESS_NF 0x12 |
130 | | #define SCSI_SENSE_RECORD_NOT_FOUND 0x14 |
131 | | #define SCSI_SENSE_SEEK_ERROR 0x15 |
132 | | #define SCSI_SENSE_DATA_CHECK_RETRY 0x18 |
133 | | #define SCSI_SENSE_ECC_VERIFY 0x19 |
134 | | #define SCSI_SENSE_INTERLEAVE_ERROR 0x1A |
135 | | #define SCSI_SENSE_UNFORMATTED 0x1C |
136 | | #define SCSI_SENSE_ILLEGAL_COMMAND 0x20 |
137 | | #define SCSI_SENSE_ILLEGAL_ADDRESS 0x21 |
138 | | #define SCSI_SENSE_VOLUME_OVERFLOW 0x23 |
139 | | #define SCSI_SENSE_BAD_ARGUMENT 0x24 |
140 | | #define SCSI_SENSE_INVALID_LUN 0x25 |
141 | | #define SCSI_SENSE_CART_CHANGED 0x28 |
142 | | #define SCSI_SENSE_ERROR_OVERFLOW 0x2C |
143 | | |
144 | | #define SCSI_SENSE_SIZE 4 |
145 | | |
146 | | typedef struct |
147 | | { |
148 | | // parameter list |
149 | | UINT8 reserved1[3]; |
150 | | UINT8 length; |
151 | | |
152 | | // descriptor list |
153 | | UINT8 density; |
154 | | UINT8 reserved2[4]; |
155 | | UINT8 block_size[3]; |
156 | | |
157 | | // drive parameter list |
158 | | UINT8 format_code; |
159 | | UINT8 cylinder_count[2]; |
160 | | UINT8 head_count; |
161 | | UINT8 reduced_write[2]; |
162 | | UINT8 write_precomp[2]; |
163 | | UINT8 landing_zone; |
164 | | UINT8 step_pulse_code; |
165 | | UINT8 bit_flags; |
166 | | UINT8 sectors_per_track; |
167 | | } adaptec_sense_t; |
168 | | |
169 | | class scsibus_device : public device_t, |
170 | | public SCSIBus_interface |
171 | | { |
172 | | public: |
173 | | // construction/destruction |
174 | | scsibus_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
175 | | /* SCSI Bus read/write */ |
176 | | |
177 | | UINT8 scsi_data_r(); |
178 | | void scsi_data_w( UINT8 data ); |
179 | | DECLARE_READ8_MEMBER( scsi_data_r ); |
180 | | DECLARE_WRITE8_MEMBER( scsi_data_w ); |
181 | | |
182 | | /* Get/Set lines */ |
183 | | |
184 | | UINT8 get_scsi_line(UINT8 lineno); |
185 | | void set_scsi_line(UINT8 line, UINT8 state); |
186 | | |
187 | | DECLARE_READ_LINE_MEMBER( scsi_bsy_r ); |
188 | | DECLARE_READ_LINE_MEMBER( scsi_sel_r ); |
189 | | DECLARE_READ_LINE_MEMBER( scsi_cd_r ); |
190 | | DECLARE_READ_LINE_MEMBER( scsi_io_r ); |
191 | | DECLARE_READ_LINE_MEMBER( scsi_msg_r ); |
192 | | DECLARE_READ_LINE_MEMBER( scsi_req_r ); |
193 | | DECLARE_READ_LINE_MEMBER( scsi_ack_r ); |
194 | | DECLARE_READ_LINE_MEMBER( scsi_rst_r ); |
195 | | |
196 | | DECLARE_WRITE_LINE_MEMBER( scsi_bsy_w ); |
197 | | DECLARE_WRITE_LINE_MEMBER( scsi_sel_w ); |
198 | | DECLARE_WRITE_LINE_MEMBER( scsi_cd_w ); |
199 | | DECLARE_WRITE_LINE_MEMBER( scsi_io_w ); |
200 | | DECLARE_WRITE_LINE_MEMBER( scsi_msg_w ); |
201 | | DECLARE_WRITE_LINE_MEMBER( scsi_req_w ); |
202 | | DECLARE_WRITE_LINE_MEMBER( scsi_ack_w ); |
203 | | DECLARE_WRITE_LINE_MEMBER( scsi_rst_w ); |
204 | | |
205 | | /* Initialisation at machine reset time */ |
206 | | void init_scsibus(int sectorbytes); |
207 | | |
208 | | protected: |
209 | | // device-level overrides |
210 | | virtual void device_config_complete(); |
211 | | virtual void device_start(); |
212 | | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
213 | | |
214 | | private: |
215 | | int get_scsi_cmd_len(int cbyte); |
216 | | UINT8 scsibus_driveno(UINT8 drivesel); |
217 | | void scsi_change_phase(UINT8 newphase); |
218 | | void set_scsi_line_now(UINT8 line, UINT8 state); |
219 | | void set_scsi_line_ack(UINT8 state); |
220 | | void scsi_in_line_changed(UINT8 line, UINT8 state); |
221 | | void scsi_out_line_change(UINT8 line, UINT8 state); |
222 | | void scsi_out_line_change_now(UINT8 line, UINT8 state); |
223 | | void scsi_out_line_req(UINT8 state); |
224 | | void scsibus_read_data(); |
225 | | void scsibus_write_data(); |
226 | | int datain_done(); |
227 | | int dataout_done(); |
228 | | void scsibus_exec_command(); |
229 | | void check_process_dataout(); |
230 | | void dump_command_bytes(); |
231 | | void dump_data_bytes(int count); |
232 | | void dump_bytes(UINT8 *buff, int count); |
233 | | |
234 | | scsidev_device *devices[8]; |
235 | | |
236 | | devcb_resolved_write_line out_bsy_func; |
237 | | devcb_resolved_write_line out_sel_func; |
238 | | devcb_resolved_write_line out_cd_func; |
239 | | devcb_resolved_write_line out_io_func; |
240 | | devcb_resolved_write_line out_msg_func; |
241 | | devcb_resolved_write_line out_req_func; |
242 | | devcb_resolved_write_line out_rst_func; |
243 | | |
244 | | UINT8 linestate; |
245 | | UINT8 last_id; |
246 | | UINT8 phase; |
247 | | |
248 | | UINT8 command[CMD_BUF_SIZE]; |
249 | | UINT8 cmd_idx; |
250 | | UINT8 is_linked; |
251 | | |
252 | | UINT8 status; |
253 | | UINT8 sense; |
254 | | |
255 | | UINT8 buffer[ADAPTEC_BUF_SIZE]; |
256 | | UINT16 data_idx; |
257 | | int xfer_count; |
258 | | int bytes_left; |
259 | | int data_last; |
260 | | int sectorbytes; |
261 | | |
262 | | emu_timer *req_timer; |
263 | | emu_timer *ack_timer; |
264 | | emu_timer *sel_timer; |
265 | | emu_timer *dataout_timer; |
266 | | }; |
267 | | |
268 | | // device type definition |
269 | | extern const device_type SCSIBUS; |
270 | | |
271 | | #endif |
trunk/src/mess/drivers/mac.c
r17551 | r17552 | |
45 | 45 | #include "machine/ncr5380.h" |
46 | 46 | #include "machine/applefdc.h" |
47 | 47 | #include "devices/sonydriv.h" |
48 | | #include "imagedev/harddriv.h" |
49 | 48 | #include "formats/ap_dsk35.h" |
50 | 49 | #include "machine/ram.h" |
| 50 | #include "machine/scsibus.h" |
51 | 51 | #include "machine/scsihd.h" |
52 | | #include "imagedev/chd_cd.h" |
53 | 52 | #include "sound/asc.h" |
54 | 53 | #include "sound/awacs.h" |
55 | 54 | #include "sound/cdda.h" |
r17551 | r17552 | |
814 | 813 | sony_read_status |
815 | 814 | }; |
816 | 815 | |
817 | | static const SCSIConfigTable dev_table = |
| 816 | static const SCSIBus_interface scsibus_intf = |
818 | 817 | { |
819 | | 2, /* 2 SCSI devices */ |
820 | | { |
821 | | { "harddisk1" }, |
822 | | { "harddisk2" } |
823 | | } |
824 | 818 | }; |
825 | 819 | |
826 | 820 | static const struct NCR5380interface macplus_5380intf = |
827 | 821 | { |
828 | | &dev_table, // SCSI device table |
829 | 822 | mac_scsi_irq // IRQ (unconnected on the Mac Plus) |
830 | 823 | }; |
831 | 824 | |
832 | 825 | static const struct NCR539Xinterface mac_539x_intf = |
833 | 826 | { |
834 | | &dev_table, // SCSI device table |
835 | 827 | DEVCB_DRIVER_LINE_MEMBER(mac_state, irq_539x_1_w), |
836 | 828 | DEVCB_DRIVER_LINE_MEMBER(mac_state, drq_539x_1_w) |
837 | 829 | }; |
r17551 | r17552 | |
939 | 931 | MCFG_CPU_MODIFY( "maincpu" ) |
940 | 932 | MCFG_CPU_PROGRAM_MAP(macplus_map) |
941 | 933 | |
942 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 934 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 935 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 936 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 937 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
943 | 938 | |
944 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
945 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
946 | | |
947 | 939 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_MODIFY(mac_floppy_interface) |
948 | 940 | |
949 | 941 | /* internal ram */ |
r17551 | r17552 | |
998 | 990 | MCFG_NVRAM_HANDLER(mac) |
999 | 991 | |
1000 | 992 | /* devices */ |
1001 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 993 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 994 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 995 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 996 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
1002 | 997 | |
1003 | 998 | MCFG_IWM_ADD("fdc", mac_iwm_interface) |
1004 | 999 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_interface) |
r17551 | r17552 | |
1006 | 1001 | MCFG_SCC8530_ADD("scc", C7M, line_cb_t(FUNC(mac_state::set_scc_interrupt), static_cast<mac_state *>(owner))) |
1007 | 1002 | MCFG_VIA6522_ADD("via6522_0", 783360, mac_via6522_intf) |
1008 | 1003 | |
1009 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1010 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1011 | | |
1012 | 1004 | /* internal ram */ |
1013 | 1005 | MCFG_RAM_ADD(RAM_TAG) |
1014 | 1006 | MCFG_RAM_DEFAULT_SIZE("1M") |
r17551 | r17552 | |
1044 | 1036 | MCFG_NUBUS_SLOT_ADD("nubus","nbd", mac_nubus_cards, NULL, NULL) |
1045 | 1037 | MCFG_NUBUS_SLOT_ADD("nubus","nbe", mac_nubus_cards, NULL, NULL) |
1046 | 1038 | |
1047 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 1039 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 1040 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 1041 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 1042 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
1048 | 1043 | |
1049 | 1044 | MCFG_IWM_ADD("fdc", mac_iwm_interface) |
1050 | 1045 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_interface) |
r17551 | r17552 | |
1054 | 1049 | MCFG_VIA6522_ADD("via6522_0", C7M/10, mac_via6522_adb_intf) |
1055 | 1050 | MCFG_VIA6522_ADD("via6522_1", C7M/10, mac_via6522_2_intf) |
1056 | 1051 | |
1057 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1058 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1059 | | |
1060 | 1052 | /* internal ram */ |
1061 | 1053 | MCFG_RAM_ADD(RAM_TAG) |
1062 | 1054 | MCFG_RAM_DEFAULT_SIZE("2M") |
r17551 | r17552 | |
1096 | 1088 | MCFG_NUBUS_SLOT_ADD("nubus","nbd", mac_nubus_cards, NULL, NULL) |
1097 | 1089 | MCFG_NUBUS_SLOT_ADD("nubus","nbe", mac_nubus_cards, NULL, NULL) |
1098 | 1090 | |
1099 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 1091 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 1092 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 1093 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 1094 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
1100 | 1095 | |
1101 | 1096 | MCFG_IWM_ADD("fdc", mac_iwm_interface) |
1102 | 1097 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_interface) |
r17551 | r17552 | |
1105 | 1100 | |
1106 | 1101 | MCFG_VIA6522_ADD("via6522_0", C7M/10, mac_via6522_adb_intf) |
1107 | 1102 | |
1108 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1109 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1110 | | |
1111 | 1103 | /* internal ram */ |
1112 | 1104 | MCFG_RAM_ADD(RAM_TAG) |
1113 | 1105 | MCFG_RAM_DEFAULT_SIZE("4M") |
r17551 | r17552 | |
1294 | 1286 | MCFG_NVRAM_HANDLER(mac) |
1295 | 1287 | |
1296 | 1288 | /* devices */ |
1297 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 1289 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 1290 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 1291 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 1292 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
1298 | 1293 | |
1299 | 1294 | MCFG_SWIM_ADD("fdc", mac_iwm_interface) |
1300 | 1295 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_interface) |
r17551 | r17552 | |
1304 | 1299 | MCFG_VIA6522_ADD("via6522_0", 783360, mac_via6522_adb_intf) |
1305 | 1300 | MCFG_VIA6522_ADD("via6522_1", 783360, mac_via6522_2_intf) |
1306 | 1301 | |
1307 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1308 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1309 | | |
1310 | 1302 | /* internal ram */ |
1311 | 1303 | MCFG_RAM_ADD(RAM_TAG) |
1312 | 1304 | MCFG_RAM_DEFAULT_SIZE("2M") |
r17551 | r17552 | |
1345 | 1337 | MCFG_NVRAM_HANDLER(mac) |
1346 | 1338 | |
1347 | 1339 | /* devices */ |
1348 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 1340 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 1341 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 1342 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 1343 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
1349 | 1344 | |
1350 | 1345 | MCFG_SWIM_ADD("fdc", mac_iwm_interface) |
1351 | 1346 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_interface) |
r17551 | r17552 | |
1355 | 1350 | MCFG_VIA6522_ADD("via6522_0", 783360, mac_via6522_adb_intf) |
1356 | 1351 | MCFG_VIA6522_ADD("via6522_1", 783360, mac_via6522_2_intf) |
1357 | 1352 | |
1358 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1359 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1360 | | |
1361 | 1353 | /* internal ram */ |
1362 | 1354 | MCFG_RAM_ADD(RAM_TAG) |
1363 | 1355 | MCFG_RAM_DEFAULT_SIZE("2M") |
r17551 | r17552 | |
1416 | 1408 | MCFG_NVRAM_HANDLER(mac) |
1417 | 1409 | |
1418 | 1410 | /* devices */ |
1419 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 1411 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 1412 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 1413 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 1414 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
1420 | 1415 | |
1421 | 1416 | MCFG_SWIM_ADD("fdc", mac_iwm_interface) |
1422 | 1417 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_interface) |
r17551 | r17552 | |
1426 | 1421 | MCFG_VIA6522_ADD("via6522_0", 783360, mac_via6522_adb_intf) |
1427 | 1422 | MCFG_VIA6522_ADD("via6522_1", 783360, mac_via6522_2_intf) |
1428 | 1423 | |
1429 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1430 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1431 | | |
1432 | 1424 | /* internal ram */ |
1433 | 1425 | MCFG_RAM_ADD(RAM_TAG) |
1434 | 1426 | MCFG_RAM_DEFAULT_SIZE("4M") |
r17551 | r17552 | |
1587 | 1579 | MCFG_NVRAM_HANDLER(mac) |
1588 | 1580 | |
1589 | 1581 | /* devices */ |
1590 | | MCFG_NCR5380_ADD("ncr5380", C7M, macplus_5380intf) |
| 1582 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 1583 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 1584 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
| 1585 | MCFG_NCR5380_ADD("scsi:ncr5380", C7M, macplus_5380intf) |
1591 | 1586 | |
1592 | 1587 | MCFG_IWM_ADD("fdc", mac_iwm_interface) |
1593 | 1588 | MCFG_LEGACY_FLOPPY_SONY_2_DRIVES_ADD(mac_floppy_interface) |
r17551 | r17552 | |
1597 | 1592 | MCFG_VIA6522_ADD("via6522_0", 783360, mac_via6522_adb_intf) |
1598 | 1593 | MCFG_VIA6522_ADD("via6522_1", 783360, mac_via6522_2_intf) |
1599 | 1594 | |
1600 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1601 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1602 | | |
1603 | 1595 | /* internal ram */ |
1604 | 1596 | MCFG_RAM_ADD(RAM_TAG) |
1605 | 1597 | MCFG_RAM_DEFAULT_SIZE("8M") |
r17551 | r17552 | |
1647 | 1639 | MCFG_VIA6522_ADD("via6522_0", C7M/10, mac_via6522_adb_intf) |
1648 | 1640 | MCFG_VIA6522_ADD("via6522_1", C7M/10, mac_via6522_2_intf) |
1649 | 1641 | |
| 1642 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 1643 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_6) |
| 1644 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_5) |
1650 | 1645 | MCFG_NCR539X_ADD(MAC_539X_1_TAG, C7M, mac_539x_intf) |
1651 | 1646 | |
1652 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_6) |
1653 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_5) |
1654 | | |
1655 | 1647 | /* internal ram */ |
1656 | 1648 | MCFG_RAM_ADD(RAM_TAG) |
1657 | 1649 | MCFG_RAM_DEFAULT_SIZE("4M") |
trunk/src/mess/drivers/x68k.c
r17551 | r17552 | |
128 | 128 | #include "machine/hd63450.h" |
129 | 129 | #include "machine/rp5c15.h" |
130 | 130 | #include "machine/mb89352.h" |
131 | | #include "machine/scsi.h" |
132 | 131 | #include "imagedev/flopdrv.h" |
133 | 132 | #include "formats/basicdsk.h" |
134 | 133 | #include "formats/dim_dsk.h" |
135 | | #include "imagedev/harddriv.h" |
136 | 134 | #include "machine/x68k_hdc.h" |
137 | 135 | #include "includes/x68k.h" |
138 | 136 | #include "machine/ram.h" |
r17551 | r17552 | |
140 | 138 | #include "machine/x68kexp.h" |
141 | 139 | #include "machine/x68k_neptunex.h" |
142 | 140 | #include "machine/x68k_scsiext.h" |
| 141 | #include "machine/scsibus.h" |
143 | 142 | #include "machine/scsihd.h" |
144 | 143 | #include "x68000.lh" |
145 | 144 | |
r17551 | r17552 | |
2018 | 2017 | AM_RANGE(0xe92002, 0xe92003) AM_DEVREADWRITE8_LEGACY("okim6258", okim6258_status_r, okim6258_data_w, 0x00ff) |
2019 | 2018 | AM_RANGE(0xe94000, 0xe95fff) AM_READWRITE_LEGACY(x68k_fdc_r, x68k_fdc_w) |
2020 | 2019 | // AM_RANGE(0xe96000, 0xe9601f) AM_DEVREADWRITE_LEGACY("x68k_hdc",x68k_hdc_r, x68k_hdc_w) |
2021 | | AM_RANGE(0xe96020, 0xe9603f) AM_DEVREADWRITE8("mb89352_int",mb89352_device,mb89352_r,mb89352_w,0x00ff) |
| 2020 | AM_RANGE(0xe96020, 0xe9603f) AM_DEVREADWRITE8("scsi:mb89352",mb89352_device,mb89352_r,mb89352_w,0x00ff) |
2022 | 2021 | AM_RANGE(0xe98000, 0xe99fff) AM_READWRITE_LEGACY(x68k_scc_r, x68k_scc_w) |
2023 | 2022 | AM_RANGE(0xe9a000, 0xe9bfff) AM_READWRITE_LEGACY(x68k_ppi_r, x68k_ppi_w) |
2024 | 2023 | AM_RANGE(0xe9c000, 0xe9dfff) AM_READWRITE_LEGACY(x68k_ioc_r, x68k_ioc_w) |
r17551 | r17552 | |
2056 | 2055 | AM_RANGE(0xe92000, 0xe92003) AM_DEVREADWRITE8_LEGACY("okim6258", okim6258_status_r, x68030_adpcm_w, 0x00ff00ff) |
2057 | 2056 | AM_RANGE(0xe94000, 0xe95fff) AM_READWRITE16_LEGACY(x68k_fdc_r, x68k_fdc_w,0xffffffff) |
2058 | 2057 | // AM_RANGE(0xe96000, 0xe9601f) AM_DEVREADWRITE16_LEGACY("x68k_hdc",x68k_hdc_r, x68k_hdc_w,0xffffffff) |
2059 | | AM_RANGE(0xe96020, 0xe9603f) AM_DEVREADWRITE8("mb89352_int",mb89352_device,mb89352_r,mb89352_w,0x00ff00ff) |
| 2058 | AM_RANGE(0xe96020, 0xe9603f) AM_DEVREADWRITE8("scsi:mb89352",mb89352_device,mb89352_r,mb89352_w,0x00ff00ff) |
2060 | 2059 | AM_RANGE(0xe98000, 0xe99fff) AM_READWRITE16_LEGACY(x68k_scc_r, x68k_scc_w,0xffffffff) |
2061 | 2060 | AM_RANGE(0xe9a000, 0xe9bfff) AM_READWRITE16_LEGACY(x68k_ppi_r, x68k_ppi_w,0xffffffff) |
2062 | 2061 | AM_RANGE(0xe9c000, 0xe9dfff) AM_READWRITE16_LEGACY(x68k_ioc_r, x68k_ioc_w,0xffffffff) |
r17551 | r17552 | |
2529 | 2528 | NULL |
2530 | 2529 | }; |
2531 | 2530 | |
2532 | | static const SCSIConfigTable x68k_scsi_devtable = |
| 2531 | static const SCSIBus_interface scsibus_intf = |
2533 | 2532 | { |
2534 | | 7, /* 7 SCSI devices */ |
2535 | | { |
2536 | | { "harddisk0" }, |
2537 | | { "harddisk1" }, |
2538 | | { "harddisk2" }, |
2539 | | { "harddisk3" }, |
2540 | | { "harddisk4" }, |
2541 | | { "harddisk5" }, |
2542 | | { "harddisk6" }, |
2543 | | } |
2544 | 2533 | }; |
2545 | 2534 | |
2546 | 2535 | static const mb89352_interface x68k_scsi_intf = |
2547 | 2536 | { |
2548 | | &x68k_scsi_devtable, |
2549 | 2537 | DEVCB_LINE(x68k_scsi_irq), |
2550 | 2538 | DEVCB_LINE(x68k_scsi_drq) |
2551 | 2539 | }; |
r17551 | r17552 | |
2833 | 2821 | MCFG_CPU_MODIFY("maincpu") |
2834 | 2822 | MCFG_CPU_PROGRAM_MAP(x68kxvi_map) |
2835 | 2823 | |
2836 | | MCFG_MB89352A_ADD("mb89352_int",x68k_scsi_intf) |
2837 | | MCFG_SCSIDEV_ADD("harddisk0", SCSIHD, SCSI_ID_0) |
2838 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_1) |
2839 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_2) |
2840 | | MCFG_SCSIDEV_ADD("harddisk3", SCSIHD, SCSI_ID_3) |
2841 | | MCFG_SCSIDEV_ADD("harddisk4", SCSIHD, SCSI_ID_4) |
2842 | | MCFG_SCSIDEV_ADD("harddisk5", SCSIHD, SCSI_ID_5) |
2843 | | MCFG_SCSIDEV_ADD("harddisk6", SCSIHD, SCSI_ID_6) |
| 2824 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 2825 | MCFG_SCSIDEV_ADD("scsi:harddisk0", SCSIHD, SCSI_ID_0) |
| 2826 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_1) |
| 2827 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_2) |
| 2828 | MCFG_SCSIDEV_ADD("scsi:harddisk3", SCSIHD, SCSI_ID_3) |
| 2829 | MCFG_SCSIDEV_ADD("scsi:harddisk4", SCSIHD, SCSI_ID_4) |
| 2830 | MCFG_SCSIDEV_ADD("scsi:harddisk5", SCSIHD, SCSI_ID_5) |
| 2831 | MCFG_SCSIDEV_ADD("scsi:harddisk6", SCSIHD, SCSI_ID_6) |
| 2832 | MCFG_MB89352A_ADD("scsi:mb89352",x68k_scsi_intf) |
2844 | 2833 | MACHINE_CONFIG_END |
2845 | 2834 | |
2846 | 2835 | static MACHINE_CONFIG_START( x68kxvi, x68k_state ) |
r17551 | r17552 | |
2853 | 2842 | MCFG_CPU_CLOCK(16000000) /* 16 MHz */ |
2854 | 2843 | MCFG_CPU_PROGRAM_MAP(x68kxvi_map) |
2855 | 2844 | |
2856 | | MCFG_MB89352A_ADD("mb89352_int",x68k_scsi_intf) |
2857 | | MCFG_SCSIDEV_ADD("harddisk0", SCSIHD, SCSI_ID_0) |
2858 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_1) |
2859 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_2) |
2860 | | MCFG_SCSIDEV_ADD("harddisk3", SCSIHD, SCSI_ID_3) |
2861 | | MCFG_SCSIDEV_ADD("harddisk4", SCSIHD, SCSI_ID_4) |
2862 | | MCFG_SCSIDEV_ADD("harddisk5", SCSIHD, SCSI_ID_5) |
2863 | | MCFG_SCSIDEV_ADD("harddisk6", SCSIHD, SCSI_ID_6) |
| 2845 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 2846 | MCFG_SCSIDEV_ADD("scsi:harddisk0", SCSIHD, SCSI_ID_0) |
| 2847 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_1) |
| 2848 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_2) |
| 2849 | MCFG_SCSIDEV_ADD("scsi:harddisk3", SCSIHD, SCSI_ID_3) |
| 2850 | MCFG_SCSIDEV_ADD("scsi:harddisk4", SCSIHD, SCSI_ID_4) |
| 2851 | MCFG_SCSIDEV_ADD("scsi:harddisk5", SCSIHD, SCSI_ID_5) |
| 2852 | MCFG_SCSIDEV_ADD("scsi:harddisk6", SCSIHD, SCSI_ID_6) |
| 2853 | MCFG_MB89352A_ADD("scsi:mb89352",x68k_scsi_intf) |
2864 | 2854 | MACHINE_CONFIG_END |
2865 | 2855 | |
2866 | 2856 | static MACHINE_CONFIG_START( x68030, x68k_state ) |
r17551 | r17552 | |
2874 | 2864 | |
2875 | 2865 | MCFG_NVRAM_ADD_0FILL("nvram32") |
2876 | 2866 | |
2877 | | MCFG_MB89352A_ADD("mb89352_int",x68k_scsi_intf) |
2878 | | MCFG_SCSIDEV_ADD("harddisk0", SCSIHD, SCSI_ID_0) |
2879 | | MCFG_SCSIDEV_ADD("harddisk1", SCSIHD, SCSI_ID_1) |
2880 | | MCFG_SCSIDEV_ADD("harddisk2", SCSIHD, SCSI_ID_2) |
2881 | | MCFG_SCSIDEV_ADD("harddisk3", SCSIHD, SCSI_ID_3) |
2882 | | MCFG_SCSIDEV_ADD("harddisk4", SCSIHD, SCSI_ID_4) |
2883 | | MCFG_SCSIDEV_ADD("harddisk5", SCSIHD, SCSI_ID_5) |
2884 | | MCFG_SCSIDEV_ADD("harddisk6", SCSIHD, SCSI_ID_6) |
| 2867 | MCFG_SCSIBUS_ADD("scsi", scsibus_intf) |
| 2868 | MCFG_SCSIDEV_ADD("scsi:harddisk0", SCSIHD, SCSI_ID_0) |
| 2869 | MCFG_SCSIDEV_ADD("scsi:harddisk1", SCSIHD, SCSI_ID_1) |
| 2870 | MCFG_SCSIDEV_ADD("scsi:harddisk2", SCSIHD, SCSI_ID_2) |
| 2871 | MCFG_SCSIDEV_ADD("scsi:harddisk3", SCSIHD, SCSI_ID_3) |
| 2872 | MCFG_SCSIDEV_ADD("scsi:harddisk4", SCSIHD, SCSI_ID_4) |
| 2873 | MCFG_SCSIDEV_ADD("scsi:harddisk5", SCSIHD, SCSI_ID_5) |
| 2874 | MCFG_SCSIDEV_ADD("scsi:harddisk6", SCSIHD, SCSI_ID_6) |
| 2875 | MCFG_MB89352A_ADD("scsi:mb89352",x68k_scsi_intf) |
2885 | 2876 | MACHINE_CONFIG_END |
2886 | 2877 | |
2887 | 2878 | ROM_START( x68000 ) |