src/mess/machine/ncr5380.c
| r9036 | r9037 | |
| 3 | 3 | * |
| 4 | 4 | * NCR 5380 SCSI controller, as seen in many 680x0 Macs, |
| 5 | 5 | * official Apple add-on cards for the Apple II series, |
| 6 | | * and probably some PC cards as well. |
| 6 | * and probably some PC and Amiga cards as well. |
| 7 | 7 | * |
| 8 | | * Preliminary emulation by R. Belmont. |
| 8 | * Emulation by R. Belmont. |
| 9 | 9 | * |
| 10 | 10 | * References: |
| 11 | 11 | * Zilog 5380 manual |
| 12 | | * "Inside Macintosh: Devices" (online at http://www.manolium.org/dev/techsupport/insidemac/Devices/Devices-2.html ) |
| 12 | * "Inside Macintosh: Devices" (formerly online at http://www.manolium.org/dev/techsupport/insidemac/Devices/Devices-2.html ) |
| 13 | 13 | * |
| 14 | 14 | * NOTES: |
| 15 | 15 | * This implementation is tied closely to the drivers found in the Mac Plus ROM and the routines in Mac |
| 16 | | * System 6.0.3 that it patches out the ROM traps with. While attempts have been made to |
| 16 | * System 6 and 7 that it patches out the ROM traps with. While attempts have been made to |
| 17 | 17 | * have the behavior work according to the manual and not the specific Apple driver code, |
| 18 | 18 | * there are almost certainly areas where that is true. In particular, IRQs are not implemented |
| 19 | 19 | * as they are unused on the Mac Plus. |
| r9036 | r9037 | |
| 22 | 22 | |
| 23 | 23 | #include "emu.h" |
| 24 | 24 | #include "ncr5380.h" |
| 25 | #include "machine/devhelpr.h" |
| 25 | 26 | |
| 26 | 27 | #define VERBOSE (0) |
| 27 | 28 | |
| r9036 | r9037 | |
| 49 | 50 | "DMA initiator rec" |
| 50 | 51 | }; |
| 51 | 52 | |
| 52 | | static SCSIInstance *devices[8]; // SCSI IDs 0-7 |
| 53 | | static const struct NCR5380interface *intf; |
| 54 | | |
| 55 | | static UINT8 n5380_Registers[8]; |
| 56 | | static UINT8 last_id; |
| 57 | | static UINT8 n5380_Command[32]; |
| 58 | | static INT32 cmd_ptr, d_ptr, d_limit, next_req_flag; |
| 59 | | static UINT8 n5380_Data[512]; |
| 60 | | |
| 61 | 53 | // get the length of a SCSI command based on it's command byte type |
| 62 | 54 | static int get_cmd_len(int cbyte) |
| 63 | 55 | { |
| r9036 | r9037 | |
| 74 | 66 | return 6; |
| 75 | 67 | } |
| 76 | 68 | |
| 77 | | WRITE8_HANDLER(ncr5380_w) |
| 69 | //************************************************************************** |
| 70 | // DEVICE CONFIGURATION |
| 71 | //************************************************************************** |
| 72 | |
| 73 | ncr5380_device_config::ncr5380_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 74 | : device_config(mconfig, static_alloc_device_config, "5380 SCSI", tag, owner, clock) |
| 78 | 75 | { |
| 76 | } |
| 77 | |
| 78 | device_config *ncr5380_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 79 | { |
| 80 | return global_alloc(ncr5380_device_config(mconfig, tag, owner, clock)); |
| 81 | } |
| 82 | |
| 83 | device_t *ncr5380_device_config::alloc_device(running_machine &machine) const |
| 84 | { |
| 85 | return auto_alloc(&machine, ncr5380_device(machine, *this)); |
| 86 | } |
| 87 | |
| 88 | //------------------------------------------------- |
| 89 | // device_config_complete - perform any |
| 90 | // operations now that the configuration is |
| 91 | // complete |
| 92 | //------------------------------------------------- |
| 93 | |
| 94 | void ncr5380_device_config::device_config_complete() |
| 95 | { |
| 96 | // inherit a copy of the static data |
| 97 | const NCR5380interface *intf = reinterpret_cast<const NCR5380interface *>(static_config()); |
| 98 | if (intf != NULL) |
| 99 | *static_cast<NCR5380interface *>(this) = *intf; |
| 100 | |
| 101 | // or initialize to defaults if none provided |
| 102 | else |
| 103 | { |
| 104 | scsidevs = NULL; |
| 105 | irq_callback = NULL; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | //************************************************************************** |
| 110 | // LIVE DEVICE |
| 111 | //************************************************************************** |
| 112 | |
| 113 | const device_type NCR5380 = ncr5380_device_config::static_alloc_device_config; |
| 114 | |
| 115 | //------------------------------------------------- |
| 116 | // ncr5380_device - constructor/destructor |
| 117 | //------------------------------------------------- |
| 118 | |
| 119 | ncr5380_device::ncr5380_device(running_machine &_machine, const ncr5380_device_config &config) |
| 120 | : device_t(_machine, config), |
| 121 | m_config(config) |
| 122 | { |
| 123 | } |
| 124 | |
| 125 | //------------------------------------------------- |
| 126 | // device_start - device-specific startup |
| 127 | //------------------------------------------------- |
| 128 | |
| 129 | void ncr5380_device::device_start() |
| 130 | { |
| 131 | int i; |
| 132 | |
| 133 | memset(m_5380_Registers, 0, sizeof(m_5380_Registers)); |
| 134 | memset(m_5380_Data, 0, sizeof(m_5380_Data)); |
| 135 | memset(m_scsi_devices, 0, sizeof(m_scsi_devices)); |
| 136 | |
| 137 | m_next_req_flag = 0; |
| 138 | |
| 139 | // try to open the devices |
| 140 | for (i = 0; i < m_config.scsidevs->devs_present; i++) |
| 141 | { |
| 142 | SCSIAllocInstance( machine, |
| 143 | m_config.scsidevs->devices[i].scsiClass, |
| 144 | &m_scsi_devices[m_config.scsidevs->devices[i].scsiID], |
| 145 | m_config.scsidevs->devices[i].diskregion ); |
| 146 | } |
| 147 | |
| 148 | state_save_register_device_item_array(this, 0, m_5380_Registers); |
| 149 | state_save_register_device_item_array(this, 0, m_5380_Command); |
| 150 | state_save_register_device_item_array(this, 0, m_5380_Data); |
| 151 | state_save_register_device_item(this, 0, m_last_id); |
| 152 | state_save_register_device_item(this, 0, m_cmd_ptr); |
| 153 | state_save_register_device_item(this, 0, m_d_ptr); |
| 154 | state_save_register_device_item(this, 0, m_d_limit); |
| 155 | state_save_register_device_item(this, 0, m_next_req_flag); |
| 156 | } |
| 157 | |
| 158 | //------------------------------------------------- |
| 159 | // device_reset - device-specific reset |
| 160 | //------------------------------------------------- |
| 161 | |
| 162 | void ncr5380_device::device_reset() |
| 163 | { |
| 164 | memset(m_5380_Registers, 0, sizeof(m_5380_Registers)); |
| 165 | memset(m_5380_Data, 0, sizeof(m_5380_Data)); |
| 166 | memset(m_scsi_devices, 0, sizeof(m_scsi_devices)); |
| 167 | |
| 168 | m_next_req_flag = 0; |
| 169 | m_cmd_ptr = 0; |
| 170 | m_d_ptr = 0; |
| 171 | m_d_limit = 0; |
| 172 | m_last_id = 0; |
| 173 | } |
| 174 | |
| 175 | //------------------------------------------------- |
| 176 | // device_stop - device-specific stop/shutdown |
| 177 | //------------------------------------------------- |
| 178 | void ncr5380_device::device_stop() |
| 179 | { |
| 180 | int i; |
| 181 | |
| 182 | // clean up the devices |
| 183 | for (i = 0; i < m_config.scsidevs->devs_present; i++) |
| 184 | { |
| 185 | SCSIDeleteInstance( m_scsi_devices[m_config.scsidevs->devices[i].scsiID] ); |
| 186 | } |
| 187 | } |
| 188 | |
| 189 | //------------------------------------------------- |
| 190 | // Public API |
| 191 | //------------------------------------------------- |
| 192 | READ8_DEVICE_HANDLER_TRAMPOLINE(ncr5380, ncr5380_read_reg) |
| 193 | { |
| 79 | 194 | int reg = offset & 7; |
| 195 | UINT8 rv = 0; |
| 80 | 196 | |
| 197 | switch( reg ) |
| 198 | { |
| 199 | case R5380_CURDATA: |
| 200 | case R5380_INPUTDATA: |
| 201 | rv = m_5380_Registers[reg]; |
| 202 | |
| 203 | // if we're in the data transfer phase or DMA, readback device data instead |
| 204 | if (((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x04) || (m_5380_Registers[R5380_BUSSTATUS] & 0x40)) |
| 205 | { |
| 206 | rv = m_5380_Data[m_d_ptr]; |
| 207 | |
| 208 | // if the limit's less than 512, only read "limit" bytes |
| 209 | if (m_d_limit < 512) |
| 210 | { |
| 211 | if (m_d_ptr < (m_d_limit-1)) |
| 212 | { |
| 213 | m_d_ptr++; |
| 214 | } |
| 215 | else |
| 216 | { |
| 217 | m_next_req_flag = 1; |
| 218 | } |
| 219 | } |
| 220 | else |
| 221 | { |
| 222 | if (m_d_ptr < 511) |
| 223 | { |
| 224 | m_d_ptr++; |
| 225 | } |
| 226 | else |
| 227 | { |
| 228 | m_d_limit -= 512; |
| 229 | m_d_ptr = 0; |
| 230 | |
| 231 | m_next_req_flag = 1; |
| 232 | |
| 233 | // don't issue a "false" read |
| 234 | if (m_d_limit > 0) |
| 235 | { |
| 236 | ncr5380_read_data((m_d_limit < 512) ? m_d_limit : 512, m_5380_Data); |
| 237 | } |
| 238 | else |
| 239 | { |
| 240 | // if this is DMA, signal DMA end |
| 241 | if (m_5380_Registers[R5380_BUSSTATUS] & 0x40) |
| 242 | { |
| 243 | m_5380_Registers[R5380_BUSSTATUS] |= 0x80; |
| 244 | } |
| 245 | |
| 246 | // drop /REQ |
| 247 | m_5380_Registers[R5380_BUSSTATUS] &= ~0x20; |
| 248 | |
| 249 | // clear phase match |
| 250 | m_5380_Registers[R5380_BUSANDSTAT] &= ~0x08; |
| 251 | } |
| 252 | } |
| 253 | } |
| 254 | |
| 255 | } |
| 256 | break; |
| 257 | |
| 258 | default: |
| 259 | rv = m_5380_Registers[reg]; |
| 260 | |
| 261 | // temporarily drop /REQ |
| 262 | if ((reg == R5380_BUSSTATUS) && (m_next_req_flag)) |
| 263 | { |
| 264 | rv &= ~0x20; |
| 265 | m_next_req_flag = 0; |
| 266 | } |
| 267 | break; |
| 268 | } |
| 269 | |
| 81 | 270 | if (VERBOSE) |
| 82 | | logerror("NCR5380: %02x to %s (reg %d) [PC=%x]\n", data, wnames[reg], reg, cpu_get_pc(space->machine->firstcpu)); |
| 271 | logerror("NCR5380: read %s (reg %d) = %02x [PC=%x]\n", rnames[reg], reg, rv, cpu_get_pc(machine->firstcpu)); |
| 83 | 272 | |
| 273 | return rv; |
| 274 | } |
| 275 | |
| 276 | WRITE8_DEVICE_HANDLER_TRAMPOLINE(ncr5380, ncr5380_write_reg) |
| 277 | { |
| 278 | int reg = offset & 7; |
| 279 | |
| 280 | if (VERBOSE) |
| 281 | logerror("NCR5380: %02x to %s (reg %d) [PC=%x]\n", data, wnames[reg], reg, cpu_get_pc(machine->firstcpu)); |
| 282 | |
| 84 | 283 | switch( reg ) |
| 85 | 284 | { |
| 86 | 285 | case R5380_OUTDATA: |
| 87 | 286 | // if we're in the command phase, collect the command bytes |
| 88 | | if ((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08) |
| 287 | if ((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08) |
| 89 | 288 | { |
| 90 | | n5380_Command[cmd_ptr++] = data; |
| 289 | m_5380_Command[m_cmd_ptr++] = data; |
| 91 | 290 | } |
| 92 | 291 | |
| 93 | 292 | // if we're in the select phase, this is the target id |
| 94 | | if (n5380_Registers[R5380_INICOMMAND] == 0x04) |
| 293 | if (m_5380_Registers[R5380_INICOMMAND] == 0x04) |
| 95 | 294 | { |
| 96 | 295 | data &= 0x7f; // clear the high bit |
| 97 | 296 | if (data == 0x40) |
| 98 | 297 | { |
| 99 | | last_id = 6; |
| 298 | m_last_id = 6; |
| 100 | 299 | } |
| 101 | 300 | else if (data == 0x20) |
| 102 | 301 | { |
| 103 | | last_id = 5; |
| 302 | m_last_id = 5; |
| 104 | 303 | } |
| 105 | 304 | else if (data == 0x10) |
| 106 | 305 | { |
| 107 | | last_id = 4; |
| 306 | m_last_id = 4; |
| 108 | 307 | } |
| 109 | 308 | else if (data == 0x08) |
| 110 | 309 | { |
| 111 | | last_id = 3; |
| 310 | m_last_id = 3; |
| 112 | 311 | } |
| 113 | 312 | else if (data == 0x04) |
| 114 | 313 | { |
| 115 | | last_id = 2; |
| 314 | m_last_id = 2; |
| 116 | 315 | } |
| 117 | 316 | else if (data == 0x02) |
| 118 | 317 | { |
| 119 | | last_id = 1; |
| 318 | m_last_id = 1; |
| 120 | 319 | } |
| 121 | 320 | else if (data == 0x01) |
| 122 | 321 | { |
| 123 | | last_id = 0; |
| 322 | m_last_id = 0; |
| 124 | 323 | } |
| 125 | 324 | } |
| 126 | 325 | |
| 127 | 326 | // if this is a write, accumulate accordingly |
| 128 | | if (((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x00) && (n5380_Registers[R5380_INICOMMAND] == 1)) |
| 327 | if (((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x00) && (m_5380_Registers[R5380_INICOMMAND] == 1)) |
| 129 | 328 | { |
| 130 | | n5380_Data[d_ptr] = data; |
| 329 | m_5380_Data[m_d_ptr] = data; |
| 131 | 330 | |
| 132 | 331 | // if we've hit a sector, flush |
| 133 | | if (d_ptr == 511) |
| 332 | if (m_d_ptr == 511) |
| 134 | 333 | { |
| 135 | | ncr5380_write_data(512, &n5380_Data[0]); |
| 334 | ncr5380_write_data(512, &m_5380_Data[0]); |
| 136 | 335 | |
| 137 | | d_limit -= 512; |
| 138 | | d_ptr = 0; |
| 336 | m_d_limit -= 512; |
| 337 | m_d_ptr = 0; |
| 139 | 338 | |
| 140 | 339 | // no more data? set DMA END flag |
| 141 | | if (d_limit <= 0) |
| 340 | if (m_d_limit <= 0) |
| 142 | 341 | { |
| 143 | | n5380_Registers[R5380_BUSANDSTAT] = 0xc8; |
| 342 | m_5380_Registers[R5380_BUSANDSTAT] = 0xc8; |
| 144 | 343 | } |
| 145 | 344 | } |
| 146 | 345 | else |
| 147 | 346 | { |
| 148 | | d_ptr++; |
| 347 | m_d_ptr++; |
| 149 | 348 | } |
| 150 | 349 | |
| 151 | 350 | // make sure we don't upset the status readback |
| r9036 | r9037 | |
| 157 | 356 | if (data == 0) // dropping the bus |
| 158 | 357 | { |
| 159 | 358 | // make sure it's not busy |
| 160 | | n5380_Registers[R5380_BUSSTATUS] &= ~0x40; |
| 359 | m_5380_Registers[R5380_BUSSTATUS] &= ~0x40; |
| 161 | 360 | |
| 162 | 361 | // are we in the command phase? |
| 163 | | if ((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08) |
| 362 | if ((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08) |
| 164 | 363 | { |
| 165 | 364 | // is the current command complete? |
| 166 | | if (get_cmd_len(n5380_Command[0]) == cmd_ptr) |
| 365 | if (get_cmd_len(m_5380_Command[0]) == m_cmd_ptr) |
| 167 | 366 | { |
| 168 | 367 | if (VERBOSE) |
| 169 | | logerror("NCR5380: Command (to ID %d): %x %x %x %x %x %x %x %x %x %x (PC %x)\n", last_id, n5380_Command[0], n5380_Command[1], n5380_Command[2], n5380_Command[3], n5380_Command[4], n5380_Command[5], n5380_Command[6], n5380_Command[7], n5380_Command[8], n5380_Command[9], cpu_get_pc(space->cpu)); |
| 368 | logerror("NCR5380: Command (to ID %d): %x %x %x %x %x %x %x %x %x %x (PC %x)\n", m_last_id, m_5380_Command[0], m_5380_Command[1], m_5380_Command[2], m_5380_Command[3], m_5380_Command[4], m_5380_Command[5], m_5380_Command[6], m_5380_Command[7], m_5380_Command[8], m_5380_Command[9], cpu_get_pc(machine->firstcpu)); |
| 170 | 369 | |
| 171 | | SCSISetCommand(devices[last_id], &n5380_Command[0], 16); |
| 172 | | SCSIExecCommand(devices[last_id], &d_limit); |
| 370 | SCSISetCommand(m_scsi_devices[m_last_id], &m_5380_Command[0], 16); |
| 371 | SCSIExecCommand(m_scsi_devices[m_last_id], &m_d_limit); |
| 173 | 372 | |
| 174 | 373 | if (VERBOSE) |
| 175 | | logerror("NCR5380: Command returned %d bytes\n", d_limit); |
| 374 | logerror("NCR5380: Command returned %d bytes\n", m_d_limit); |
| 176 | 375 | |
| 177 | | d_ptr = 0; |
| 376 | m_d_ptr = 0; |
| 178 | 377 | |
| 179 | 378 | // is data available? |
| 180 | | if (d_limit > 0) |
| 379 | if (m_d_limit > 0) |
| 181 | 380 | { |
| 182 | 381 | // make sure for transfers under 512 bytes that we always pad with a zero |
| 183 | | if (d_limit < 512) |
| 382 | if (m_d_limit < 512) |
| 184 | 383 | { |
| 185 | | n5380_Data[d_limit] = 0; |
| 384 | m_5380_Data[m_d_limit] = 0; |
| 186 | 385 | } |
| 187 | 386 | |
| 188 | 387 | // read back the amount available, or 512 bytes, whichever is smaller |
| 189 | | ncr5380_read_data((d_limit < 512) ? d_limit : 512, n5380_Data); |
| 388 | ncr5380_read_data((m_d_limit < 512) ? m_d_limit : 512, m_5380_Data); |
| 190 | 389 | |
| 191 | 390 | // raise REQ to indicate data is available |
| 192 | | n5380_Registers[R5380_BUSSTATUS] |= 0x20; |
| 391 | m_5380_Registers[R5380_BUSSTATUS] |= 0x20; |
| 193 | 392 | } |
| 194 | 393 | } |
| 195 | 394 | } |
| r9036 | r9037 | |
| 201 | 400 | // if the device exists, make the bus busy. |
| 202 | 401 | // otherwise don't. |
| 203 | 402 | |
| 204 | | if (devices[last_id]) |
| 403 | if (m_scsi_devices[m_last_id]) |
| 205 | 404 | { |
| 206 | 405 | if (VERBOSE) |
| 207 | | logerror("NCR5380: Giving the bus for ID %d\n", last_id); |
| 208 | | n5380_Registers[R5380_BUSSTATUS] |= 0x40; |
| 406 | logerror("NCR5380: Giving the bus for ID %d\n", m_last_id); |
| 407 | m_5380_Registers[R5380_BUSSTATUS] |= 0x40; |
| 209 | 408 | } |
| 210 | 409 | else |
| 211 | 410 | { |
| 212 | 411 | if (VERBOSE) |
| 213 | | logerror("NCR5380: Rejecting the bus for ID %d\n", last_id); |
| 214 | | n5380_Registers[R5380_BUSSTATUS] &= ~0x40; |
| 412 | logerror("NCR5380: Rejecting the bus for ID %d\n", m_last_id); |
| 413 | m_5380_Registers[R5380_BUSSTATUS] &= ~0x40; |
| 215 | 414 | } |
| 216 | 415 | } |
| 217 | 416 | |
| 218 | 417 | if (data == 1) // data bus (prelude to command?) |
| 219 | 418 | { |
| 220 | 419 | // raise REQ |
| 221 | | n5380_Registers[R5380_BUSSTATUS] |= 0x20; |
| 420 | m_5380_Registers[R5380_BUSSTATUS] |= 0x20; |
| 222 | 421 | } |
| 223 | 422 | |
| 224 | 423 | if (data & 0x10) // ACK drops REQ |
| 225 | 424 | { |
| 226 | 425 | // drop REQ |
| 227 | | n5380_Registers[R5380_BUSSTATUS] &= ~0x20; |
| 426 | m_5380_Registers[R5380_BUSSTATUS] &= ~0x20; |
| 228 | 427 | } |
| 229 | 428 | break; |
| 230 | 429 | |
| r9036 | r9037 | |
| 232 | 431 | if (data == 2) // DMA |
| 233 | 432 | { |
| 234 | 433 | // put us in DMA mode |
| 235 | | n5380_Registers[R5380_BUSANDSTAT] |= 0x40; |
| 434 | m_5380_Registers[R5380_BUSANDSTAT] |= 0x40; |
| 236 | 435 | } |
| 237 | 436 | |
| 238 | 437 | if (data == 1) // arbitrate? |
| 239 | 438 | { |
| 240 | | n5380_Registers[R5380_INICOMMAND] |= 0x40; // set arbitration in progress |
| 241 | | n5380_Registers[R5380_INICOMMAND] &= ~0x20; // clear "lost arbitration" |
| 439 | m_5380_Registers[R5380_INICOMMAND] |= 0x40; // set arbitration in progress |
| 440 | m_5380_Registers[R5380_INICOMMAND] &= ~0x20; // clear "lost arbitration" |
| 242 | 441 | } |
| 243 | 442 | |
| 244 | 443 | if (data == 0) |
| 245 | 444 | { |
| 246 | 445 | // drop DMA mode |
| 247 | | n5380_Registers[R5380_BUSANDSTAT] &= ~0x40; |
| 446 | m_5380_Registers[R5380_BUSANDSTAT] &= ~0x40; |
| 248 | 447 | } |
| 249 | 448 | break; |
| 250 | 449 | |
| 251 | 450 | case R5380_TARGETCMD: |
| 252 | 451 | // sync the bus phase with what was just written |
| 253 | | n5380_Registers[R5380_BUSSTATUS] &= ~0x1c; |
| 254 | | n5380_Registers[R5380_BUSSTATUS] |= (data & 7)<<2; |
| 452 | m_5380_Registers[R5380_BUSSTATUS] &= ~0x1c; |
| 453 | m_5380_Registers[R5380_BUSSTATUS] |= (data & 7)<<2; |
| 255 | 454 | |
| 256 | 455 | // and set the "phase match" flag |
| 257 | | n5380_Registers[R5380_BUSANDSTAT] |= 0x08; |
| 456 | m_5380_Registers[R5380_BUSANDSTAT] |= 0x08; |
| 258 | 457 | |
| 259 | 458 | // and set /REQ |
| 260 | | n5380_Registers[R5380_BUSSTATUS] |= 0x20; |
| 459 | m_5380_Registers[R5380_BUSSTATUS] |= 0x20; |
| 261 | 460 | |
| 262 | 461 | // if we're entering the command phase, start accumulating the data |
| 263 | | if ((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08) |
| 462 | if ((m_5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x08) |
| 264 | 463 | { |
| 265 | | cmd_ptr = 0; |
| 464 | m_cmd_ptr = 0; |
| 266 | 465 | } |
| 267 | 466 | break; |
| 268 | 467 | |
| r9036 | r9037 | |
| 270 | 469 | break; |
| 271 | 470 | } |
| 272 | 471 | |
| 273 | | n5380_Registers[reg] = data; |
| 472 | m_5380_Registers[reg] = data; |
| 274 | 473 | |
| 275 | 474 | // note: busandstat overlaps startdma, so we need to do this here! |
| 276 | 475 | if (reg == R5380_STARTDMA) |
| 277 | 476 | { |
| 278 | | n5380_Registers[R5380_BUSANDSTAT] = 0x48; |
| 477 | m_5380_Registers[R5380_BUSANDSTAT] = 0x48; |
| 279 | 478 | } |
| 280 | 479 | } |
| 281 | 480 | |
| 282 | | READ8_HANDLER(ncr5380_r) |
| 283 | | { |
| 284 | | int reg = offset & 7; |
| 285 | | UINT8 rv = 0; |
| 286 | 481 | |
| 287 | | switch( reg ) |
| 288 | | { |
| 289 | | case R5380_CURDATA: |
| 290 | | case R5380_INPUTDATA: |
| 291 | | rv = n5380_Registers[reg]; |
| 292 | | |
| 293 | | // if we're in the data transfer phase or DMA, readback device data instead |
| 294 | | if (((n5380_Registers[R5380_BUSSTATUS] & 0x1c) == 0x04) || (n5380_Registers[R5380_BUSSTATUS] & 0x40)) |
| 295 | | { |
| 296 | | rv = n5380_Data[d_ptr]; |
| 297 | | |
| 298 | | // if the limit's less than 512, only read "limit" bytes |
| 299 | | if (d_limit < 512) |
| 300 | | { |
| 301 | | if (d_ptr < (d_limit-1)) |
| 302 | | { |
| 303 | | d_ptr++; |
| 304 | | } |
| 305 | | else |
| 306 | | { |
| 307 | | next_req_flag = 1; |
| 308 | | } |
| 309 | | } |
| 310 | | else |
| 311 | | { |
| 312 | | if (d_ptr < 511) |
| 313 | | { |
| 314 | | d_ptr++; |
| 315 | | } |
| 316 | | else |
| 317 | | { |
| 318 | | d_limit -= 512; |
| 319 | | d_ptr = 0; |
| 320 | | |
| 321 | | next_req_flag = 1; |
| 322 | | |
| 323 | | // don't issue a "false" read |
| 324 | | if (d_limit > 0) |
| 325 | | { |
| 326 | | ncr5380_read_data((d_limit < 512) ? d_limit : 512, n5380_Data); |
| 327 | | } |
| 328 | | else |
| 329 | | { |
| 330 | | // if this is DMA, signal DMA end |
| 331 | | if (n5380_Registers[R5380_BUSSTATUS] & 0x40) |
| 332 | | { |
| 333 | | n5380_Registers[R5380_BUSSTATUS] |= 0x80; |
| 334 | | } |
| 335 | | |
| 336 | | // drop /REQ |
| 337 | | n5380_Registers[R5380_BUSSTATUS] &= ~0x20; |
| 338 | | |
| 339 | | // clear phase match |
| 340 | | n5380_Registers[R5380_BUSANDSTAT] &= ~0x08; |
| 341 | | } |
| 342 | | } |
| 343 | | } |
| 344 | | |
| 345 | | } |
| 346 | | break; |
| 347 | | |
| 348 | | default: |
| 349 | | rv = n5380_Registers[reg]; |
| 350 | | |
| 351 | | // temporarily drop /REQ |
| 352 | | if ((reg == R5380_BUSSTATUS) && (next_req_flag)) |
| 353 | | { |
| 354 | | rv &= ~0x20; |
| 355 | | next_req_flag = 0; |
| 356 | | } |
| 357 | | break; |
| 358 | | } |
| 359 | | |
| 360 | | if (VERBOSE) |
| 361 | | logerror("NCR5380: read %s (reg %d) = %02x [PC=%x]\n", rnames[reg], reg, rv, cpu_get_pc(space->machine->firstcpu)); |
| 362 | | |
| 363 | | return rv; |
| 364 | | } |
| 365 | | |
| 366 | | void ncr5380_init( running_machine *machine, const struct NCR5380interface *interface ) |
| 482 | void ncr5380_device::ncr5380_read_data(int bytes, UINT8 *pData) |
| 367 | 483 | { |
| 368 | | // save interface pointer for later |
| 369 | | intf = interface; |
| 370 | | |
| 371 | | memset(n5380_Registers, 0, sizeof(n5380_Registers)); |
| 372 | | memset(n5380_Data, 0, sizeof(n5380_Data)); |
| 373 | | memset(devices, 0, sizeof(devices)); |
| 374 | | |
| 375 | | next_req_flag = 0; |
| 376 | | state_save_register_item_array(machine, "ncr5380", NULL, 0, n5380_Registers); |
| 377 | | state_save_register_item_array(machine, "ncr5380", NULL, 0, n5380_Command); |
| 378 | | state_save_register_item_array(machine, "ncr5380", NULL, 0, n5380_Data); |
| 379 | | state_save_register_item(machine, "ncr5380", NULL, 0, last_id); |
| 380 | | state_save_register_item(machine, "ncr5380", NULL, 0, cmd_ptr); |
| 381 | | state_save_register_item(machine, "ncr5380", NULL, 0, d_ptr); |
| 382 | | state_save_register_item(machine, "ncr5380", NULL, 0, d_limit); |
| 383 | | state_save_register_item(machine, "ncr5380", NULL, 0, next_req_flag); |
| 384 | | } |
| 385 | | |
| 386 | | void ncr5380_scan_devices( running_machine *machine ) |
| 387 | | { |
| 388 | | int i; |
| 389 | | |
| 390 | | // try to open the devices |
| 391 | | for (i = 0; i < intf->scsidevs->devs_present; i++) |
| 484 | if (m_scsi_devices[m_last_id]) |
| 392 | 485 | { |
| 393 | | // if a device wasn't already allocated |
| 394 | | if (!devices[intf->scsidevs->devices[i].scsiID]) |
| 395 | | { |
| 396 | | SCSIAllocInstance( machine, |
| 397 | | intf->scsidevs->devices[i].scsiClass, |
| 398 | | &devices[intf->scsidevs->devices[i].scsiID], |
| 399 | | intf->scsidevs->devices[i].diskregion ); |
| 400 | | } |
| 401 | | } |
| 402 | | } |
| 403 | | |
| 404 | | void ncr5380_exit( const struct NCR5380interface *interface ) |
| 405 | | { |
| 406 | | int i; |
| 407 | | |
| 408 | | // clean up the devices |
| 409 | | for (i = 0; i < interface->scsidevs->devs_present; i++) |
| 410 | | { |
| 411 | | SCSIDeleteInstance( devices[interface->scsidevs->devices[i].scsiID] ); |
| 412 | | } |
| 413 | | } |
| 414 | | |
| 415 | | void ncr5380_read_data(int bytes, UINT8 *pData) |
| 416 | | { |
| 417 | | if (devices[last_id]) |
| 418 | | { |
| 419 | 486 | if (VERBOSE) |
| 420 | 487 | logerror("NCR5380: issuing read for %d bytes\n", bytes); |
| 421 | | SCSIReadData(devices[last_id], pData, bytes); |
| 488 | SCSIReadData(m_scsi_devices[m_last_id], pData, bytes); |
| 422 | 489 | } |
| 423 | 490 | else |
| 424 | 491 | { |
| 425 | | logerror("ncr5380: read unknown device SCSI ID %d\n", last_id); |
| 492 | logerror("ncr5380: read unknown device SCSI ID %d\n", m_last_id); |
| 426 | 493 | } |
| 427 | 494 | } |
| 428 | 495 | |
| 429 | | void ncr5380_write_data(int bytes, UINT8 *pData) |
| 430 | | { |
| 431 | | if (devices[last_id]) |
| 432 | | { |
| 433 | | SCSIWriteData(devices[last_id], pData, bytes); |
| 434 | | } |
| 435 | | else |
| 436 | | { |
| 437 | | logerror("ncr5380: write to unknown device SCSI ID %d\n", last_id); |
| 438 | | } |
| 439 | | } |
| 440 | 496 | |
| 441 | | void *ncr5380_get_device(int id) |
| 497 | void ncr5380_device::ncr5380_write_data(int bytes, UINT8 *pData) |
| 442 | 498 | { |
| 443 | | void *ret; |
| 444 | | |
| 445 | | if (devices[id]) |
| 499 | if (m_scsi_devices[m_last_id]) |
| 446 | 500 | { |
| 447 | | logerror("ncr5380: fetching dev pointer for SCSI ID %d\n", id); |
| 448 | | SCSIGetDevice(devices[id], &ret); |
| 449 | | |
| 450 | | return ret; |
| 501 | SCSIWriteData(m_scsi_devices[m_last_id], pData, bytes); |
| 451 | 502 | } |
| 452 | | |
| 453 | | return NULL; |
| 454 | | } |
| 455 | | |
| 456 | | #if USE_5380_DEVICE |
| 457 | | //************************************************************************** |
| 458 | | // DEVICE CONFIGURATION |
| 459 | | //************************************************************************** |
| 460 | | |
| 461 | | ncr5380_device_config::ncr5380_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 462 | | : device_config(mconfig, static_alloc_device_config, "5380 SCSI", tag, owner, clock) |
| 463 | | { |
| 464 | | } |
| 465 | | |
| 466 | | device_config *ncr5380_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock) |
| 467 | | { |
| 468 | | return global_alloc(ncr5380_device_config(mconfig, tag, owner, clock)); |
| 469 | | } |
| 470 | | |
| 471 | | device_t *ncr5380_device_config::alloc_device(running_machine &machine) const |
| 472 | | { |
| 473 | | return auto_alloc(&machine, ncr5380_device(machine, *this)); |
| 474 | | } |
| 475 | | |
| 476 | | //------------------------------------------------- |
| 477 | | // device_config_complete - perform any |
| 478 | | // operations now that the configuration is |
| 479 | | // complete |
| 480 | | //------------------------------------------------- |
| 481 | | |
| 482 | | void ncr5380_device_config::device_config_complete() |
| 483 | | { |
| 484 | | // inherit a copy of the static data |
| 485 | | const NCR5380interface *intf = reinterpret_cast<const NCR5380interface *>(static_config()); |
| 486 | | if (intf != NULL) |
| 487 | | *static_cast<NCR5380interface *>(this) = *intf; |
| 488 | | |
| 489 | | // or initialize to defaults if none provided |
| 490 | 503 | else |
| 491 | 504 | { |
| 492 | | scsidevs = NULL; |
| 493 | | irq_callback = NULL; |
| 505 | logerror("ncr5380: write to unknown device SCSI ID %d\n", m_last_id); |
| 494 | 506 | } |
| 495 | 507 | } |
| 496 | 508 | |
| 497 | | //************************************************************************** |
| 498 | | // LIVE DEVICE |
| 499 | | //************************************************************************** |
| 500 | | |
| 501 | | const device_type NCR5380 = ncr5380_device_config::static_alloc_device_config; |
| 502 | | |
| 503 | | //------------------------------------------------- |
| 504 | | // via6522_device - constructor |
| 505 | | //------------------------------------------------- |
| 506 | | |
| 507 | | ncr5380_device::ncr5380_device(running_machine &_machine, const ncr5380_device_config &config) |
| 508 | | : device_t(_machine, config), |
| 509 | | m_config(config) |
| 509 | void ncr5380_device::ncr5380_scan_devices() |
| 510 | 510 | { |
| 511 | | } |
| 512 | | |
| 513 | | //------------------------------------------------- |
| 514 | | // device_start - device-specific startup |
| 515 | | //------------------------------------------------- |
| 516 | | |
| 517 | | void ncr5380_device::device_start() |
| 518 | | { |
| 519 | 511 | int i; |
| 520 | 512 | |
| 521 | | memset(m_5380_Registers, 0, sizeof(m_5380_Registers)); |
| 522 | | memset(m_5380_Data, 0, sizeof(m_5380_Data)); |
| 523 | | memset(m_scsi_devices, 0, sizeof(m_scsi_devices)); |
| 524 | | |
| 525 | | m_next_req_flag = 0; |
| 526 | | |
| 527 | 513 | // try to open the devices |
| 528 | 514 | for (i = 0; i < m_config.scsidevs->devs_present; i++) |
| 529 | 515 | { |
| 530 | | SCSIAllocInstance( machine, |
| 531 | | m_config.scsidevs->devices[i].scsiClass, |
| 532 | | &m_scsi_devices[m_config.scsidevs->devices[i].scsiID], |
| 533 | | m_config.scsidevs->devices[i].diskregion ); |
| 516 | // if a device wasn't already allocated |
| 517 | if (!m_scsi_devices[m_config.scsidevs->devices[i].scsiID]) |
| 518 | { |
| 519 | SCSIAllocInstance( machine, |
| 520 | m_config.scsidevs->devices[i].scsiClass, |
| 521 | &m_scsi_devices[m_config.scsidevs->devices[i].scsiID], |
| 522 | m_config.scsidevs->devices[i].diskregion ); |
| 523 | } |
| 534 | 524 | } |
| 535 | | |
| 536 | | state_save_register_device_item_array(this, 0, m_5380_Registers); |
| 537 | | state_save_register_device_item_array(this, 0, m_Command); |
| 538 | | state_save_register_device_item_array(this, 0, m_5380_Data); |
| 539 | | state_save_register_device_item(this, 0, m_last_id); |
| 540 | | state_save_register_device_item(this, 0, m_cmd_ptr); |
| 541 | | state_save_register_device_item(this, 0, m_d_ptr); |
| 542 | | state_save_register_device_item(this, 0, m_d_limit); |
| 543 | | state_save_register_device_item(this, 0, m_next_req_flag); |
| 544 | 525 | } |
| 545 | 526 | |
| 546 | | //------------------------------------------------- |
| 547 | | // device_reset - device-specific reset |
| 548 | | //------------------------------------------------- |
| 549 | | |
| 550 | | void ncr5380_device::device_reset() |
| 527 | void ncr5380_read_data(running_device *dev, UINT8 bytes, UINT8 *pData) |
| 551 | 528 | { |
| 552 | | memset(m_5380_Registers, 0, sizeof(m_5380_Registers)); |
| 553 | | memset(m_5380_Data, 0, sizeof(m_5380_Data)); |
| 554 | | memset(m_scsi_devices, 0, sizeof(m_scsi_devices)); |
| 555 | | |
| 556 | | m_next_req_flag = 0; |
| 557 | | m_cmd_ptr = 0; |
| 558 | | m_d_ptr = 0; |
| 559 | | m_d_limit = 0; |
| 560 | | m_last_id = 0; |
| 529 | return downcast<ncr5380_device*>(dev)->ncr5380_read_data(bytes, pData); |
| 561 | 530 | } |
| 562 | 531 | |
| 563 | | UINT8 ncr5380_device::read(UINT8 offset) |
| 532 | void ncr5380_write_data(running_device *dev, UINT8 bytes, UINT8 *pData) |
| 564 | 533 | { |
| 565 | | return 0; |
| 534 | downcast<ncr5380_device*>(dev)->ncr5380_write_data(bytes, pData); |
| 566 | 535 | } |
| 567 | 536 | |
| 568 | | void ncr5380_device::write(UINT8 offset, UINT8 data) |
| 537 | void ncr5380_scan_devices(running_device *dev) |
| 569 | 538 | { |
| 539 | downcast<ncr5380_device*>(dev)->ncr5380_scan_devices(); |
| 570 | 540 | } |
| 571 | 541 | |
| 572 | | void ncr5380_device::read_data(int bytes, UINT8 *pData) |
| 573 | | { |
| 574 | | } |
| 575 | | |
| 576 | | void ncr5380_device::write_data(int bytes, UINT8 *pData) |
| 577 | | { |
| 578 | | } |
| 579 | | |
| 580 | | void *ncr5380_device::get_scsi_device(int id) |
| 581 | | { |
| 582 | | return NULL; |
| 583 | | } |
| 584 | | #endif |
src/mess/machine/mac.c
| r9036 | r9037 | |
| 911 | 911 | READ16_HANDLER ( macplus_scsi_r ) |
| 912 | 912 | { |
| 913 | 913 | int reg = (offset>>3) & 0xf; |
| 914 | running_device *ncr = space->machine->device("ncr5380"); |
| 914 | 915 | |
| 915 | 916 | // logerror("macplus_scsi_r: offset %x mask %x\n", offset, mem_mask); |
| 916 | 917 | |
| r9036 | r9037 | |
| 919 | 920 | reg = R5380_CURDATA_DTACK; |
| 920 | 921 | } |
| 921 | 922 | |
| 922 | | return ncr5380_r(space, reg)<<8; |
| 923 | return ncr5380_read_reg(ncr, reg)<<8; |
| 923 | 924 | } |
| 924 | 925 | |
| 925 | 926 | READ32_HANDLER (macii_scsi_drq_r) |
| 926 | 927 | { |
| 928 | running_device *ncr = space->machine->device("ncr5380"); |
| 929 | |
| 927 | 930 | switch (mem_mask) |
| 928 | 931 | { |
| 929 | 932 | case 0xff000000: |
| 930 | | return ncr5380_r(space, R5380_CURDATA_DTACK)<<24; |
| 933 | return ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<24; |
| 931 | 934 | |
| 932 | 935 | case 0xffff0000: |
| 933 | | return (ncr5380_r(space, R5380_CURDATA_DTACK)<<24) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<16); |
| 936 | return (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<24) | (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<16); |
| 934 | 937 | |
| 935 | 938 | case 0xffffffff: |
| 936 | | return (ncr5380_r(space, R5380_CURDATA_DTACK)<<24) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<16) | (ncr5380_r(space, R5380_CURDATA_DTACK)<<8) | ncr5380_r(space, R5380_CURDATA_DTACK); |
| 939 | return (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<24) | (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<16) | (ncr5380_read_reg(ncr, R5380_CURDATA_DTACK)<<8) | ncr5380_read_reg(ncr, R5380_CURDATA_DTACK); |
| 937 | 940 | |
| 938 | 941 | default: |
| 939 | 942 | logerror("macii_scsi_drq_r: unknown mem_mask %08x\n", mem_mask); |
| r9036 | r9037 | |
| 944 | 947 | |
| 945 | 948 | WRITE32_HANDLER (macii_scsi_drq_w) |
| 946 | 949 | { |
| 950 | running_device *ncr = space->machine->device("ncr5380"); |
| 951 | |
| 947 | 952 | switch (mem_mask) |
| 948 | 953 | { |
| 949 | 954 | case 0xff000000: |
| 950 | | ncr5380_w(space, R5380_OUTDATA_DTACK, data>>24); |
| 955 | ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>24); |
| 951 | 956 | break; |
| 952 | 957 | |
| 953 | 958 | case 0xffff0000: |
| 954 | | ncr5380_w(space, R5380_OUTDATA_DTACK, data>>24); |
| 955 | | ncr5380_w(space, R5380_OUTDATA_DTACK, data>>16); |
| 959 | ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>24); |
| 960 | ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>16); |
| 956 | 961 | break; |
| 957 | 962 | |
| 958 | 963 | case 0xffffffff: |
| 959 | | ncr5380_w(space, R5380_OUTDATA_DTACK, data>>24); |
| 960 | | ncr5380_w(space, R5380_OUTDATA_DTACK, data>>16); |
| 961 | | ncr5380_w(space, R5380_OUTDATA_DTACK, data>>8); |
| 962 | | ncr5380_w(space, R5380_OUTDATA_DTACK, data&0xff); |
| 964 | ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>24); |
| 965 | ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>16); |
| 966 | ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data>>8); |
| 967 | ncr5380_write_reg(ncr, R5380_OUTDATA_DTACK, data&0xff); |
| 963 | 968 | break; |
| 964 | 969 | |
| 965 | 970 | default: |
| r9036 | r9037 | |
| 971 | 976 | WRITE16_HANDLER ( macplus_scsi_w ) |
| 972 | 977 | { |
| 973 | 978 | int reg = (offset>>3) & 0xf; |
| 979 | running_device *ncr = space->machine->device("ncr5380"); |
| 974 | 980 | |
| 975 | 981 | // logerror("macplus_scsi_w: data %x offset %x mask %x\n", data, offset, mem_mask); |
| 976 | 982 | |
| r9036 | r9037 | |
| 979 | 985 | reg = R5380_OUTDATA_DTACK; |
| 980 | 986 | } |
| 981 | 987 | |
| 982 | | ncr5380_w(space, reg, data); |
| 988 | ncr5380_write_reg(ncr, reg, data); |
| 983 | 989 | } |
| 984 | 990 | |
| 985 | 991 | WRITE16_HANDLER ( macii_scsi_w ) |
| 986 | 992 | { |
| 987 | 993 | int reg = (offset>>3) & 0xf; |
| 994 | running_device *ncr = space->machine->device("ncr5380"); |
| 988 | 995 | |
| 989 | 996 | // logerror("macplus_scsi_w: data %x offset %x mask %x (PC=%x)\n", data, offset, mem_mask, cpu_get_pc(space->cpu)); |
| 990 | 997 | |
| r9036 | r9037 | |
| 993 | 1000 | reg = R5380_OUTDATA_DTACK; |
| 994 | 1001 | } |
| 995 | 1002 | |
| 996 | | ncr5380_w(space, reg, data>>8); |
| 1003 | ncr5380_write_reg(ncr, reg, data>>8); |
| 997 | 1004 | } |
| 998 | 1005 | |
| 999 | | static void mac_scsi_irq(running_machine *machine, int state) |
| 1006 | void mac_scsi_irq(running_machine *machine, int state) |
| 1000 | 1007 | { |
| 1001 | 1008 | mac_state *mac = machine->driver_data<mac_state>(); |
| 1002 | 1009 | |
| r9036 | r9037 | |
| 2748 | 2755 | * Main |
| 2749 | 2756 | * *************************************************************************/ |
| 2750 | 2757 | |
| 2751 | | static const SCSIConfigTable dev_table = |
| 2752 | | { |
| 2753 | | 2, /* 2 SCSI devices */ |
| 2754 | | { |
| 2755 | | { SCSI_ID_6, "harddisk1", SCSI_DEVICE_HARDDISK }, /* SCSI ID 6, using disk1, and it's a harddisk */ |
| 2756 | | { SCSI_ID_5, "harddisk2", SCSI_DEVICE_HARDDISK } /* SCSI ID 5, using disk2, and it's a harddisk */ |
| 2757 | | } |
| 2758 | | }; |
| 2759 | | |
| 2760 | | static const struct NCR5380interface macplus_5380intf = |
| 2761 | | { |
| 2762 | | &dev_table, // SCSI device table |
| 2763 | | mac_scsi_irq // IRQ (unconnected on the Mac Plus) |
| 2764 | | }; |
| 2765 | | |
| 2766 | | static void macscsi_exit(running_machine &machine) |
| 2767 | | { |
| 2768 | | ncr5380_exit(&macplus_5380intf); |
| 2769 | | } |
| 2770 | | |
| 2771 | 2758 | MACHINE_START( mac ) |
| 2772 | 2759 | { |
| 2773 | 2760 | mac_state *mac = machine->driver_data<mac_state>(); |
| r9036 | r9037 | |
| 2816 | 2803 | |
| 2817 | 2804 | if (mac->mac_model >= MODEL_MAC_PLUS) |
| 2818 | 2805 | { |
| 2819 | | ncr5380_scan_devices(machine); |
| 2806 | ncr5380_scan_devices(machine->device("ncr5380")); |
| 2820 | 2807 | } |
| 2821 | 2808 | |
| 2822 | 2809 | if ((mac->mac_model == MODEL_MAC_SE) || (mac->mac_model == MODEL_MAC_CLASSIC)) |
| r9036 | r9037 | |
| 2952 | 2939 | mac_driver_init(machine, MODEL_MAC_512KE); |
| 2953 | 2940 | } |
| 2954 | 2941 | |
| 2955 | | MACHINE_START( macscsi ) |
| 2956 | | { |
| 2957 | | MACHINE_START_CALL(mac); |
| 2958 | | |
| 2959 | | ncr5380_init(machine, &macplus_5380intf); |
| 2960 | | machine->add_notifier(MACHINE_NOTIFY_EXIT, macscsi_exit); |
| 2961 | | } |
| 2962 | | |
| 2963 | 2942 | DRIVER_INIT(macplus) |
| 2964 | 2943 | { |
| 2965 | 2944 | // UINT32 *ROM = (UINT32 *)memory_region(machine, "bootrom"); |