trunk/src/emu/machine/idectrl.c
| r23601 | r23602 | |
| 107 | 107 | { |
| 108 | 108 | } |
| 109 | 109 | |
| 110 | enum |
| 111 | { |
| 112 | TID_NULL, |
| 113 | TID_DELAYED_INTERRUPT, |
| 114 | TID_DELAYED_INTERRUPT_BUFFER_READY, |
| 115 | TID_RESET_CALLBACK, |
| 116 | TID_SECURITY_ERROR_DONE, |
| 117 | TID_READ_SECTOR_DONE_CALLBACK, |
| 118 | TID_WRITE_SECTOR_DONE_CALLBACK |
| 119 | }; |
| 110 | 120 | |
| 121 | void ide_controller_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) |
| 122 | { |
| 123 | switch(id) |
| 124 | { |
| 125 | case TID_DELAYED_INTERRUPT: |
| 126 | status &= ~IDE_STATUS_BUSY; |
| 127 | set_irq(ASSERT_LINE); |
| 128 | break; |
| 111 | 129 | |
| 112 | | /*************************************************************************** |
| 113 | | DELAYED INTERRUPT HANDLING |
| 114 | | ***************************************************************************/ |
| 130 | case TID_DELAYED_INTERRUPT_BUFFER_READY: |
| 131 | status &= ~IDE_STATUS_BUSY; |
| 132 | status |= IDE_STATUS_BUFFER_READY; |
| 133 | set_irq(ASSERT_LINE); |
| 134 | break; |
| 115 | 135 | |
| 116 | | static TIMER_CALLBACK( delayed_interrupt ) |
| 117 | | { |
| 118 | | ide_controller_device *ide = (ide_controller_device *)ptr; |
| 119 | | ide->status &= ~IDE_STATUS_BUSY; |
| 120 | | ide->set_irq(ASSERT_LINE); |
| 121 | | } |
| 136 | case TID_RESET_CALLBACK: |
| 137 | reset(); |
| 138 | break; |
| 122 | 139 | |
| 140 | case TID_SECURITY_ERROR_DONE: |
| 141 | /* clear error state */ |
| 142 | status &= ~IDE_STATUS_ERROR; |
| 143 | status |= IDE_STATUS_DRIVE_READY; |
| 144 | break; |
| 123 | 145 | |
| 124 | | static TIMER_CALLBACK( delayed_interrupt_buffer_ready ) |
| 125 | | { |
| 126 | | ide_controller_device *ide = (ide_controller_device *)ptr; |
| 127 | | ide->status &= ~IDE_STATUS_BUSY; |
| 128 | | ide->status |= IDE_STATUS_BUFFER_READY; |
| 129 | | ide->set_irq(ASSERT_LINE); |
| 146 | case TID_READ_SECTOR_DONE_CALLBACK: |
| 147 | read_sector_done(); |
| 148 | break; |
| 149 | |
| 150 | case TID_WRITE_SECTOR_DONE_CALLBACK: |
| 151 | write_sector_done(); |
| 152 | break; |
| 153 | } |
| 130 | 154 | } |
| 131 | 155 | |
| 132 | 156 | |
| r23601 | r23602 | |
| 138 | 162 | |
| 139 | 163 | /* set a timer */ |
| 140 | 164 | if (buffer_ready) |
| 141 | | machine().scheduler().timer_set(time, FUNC(delayed_interrupt_buffer_ready), 0, this); |
| 165 | timer_set(time, TID_DELAYED_INTERRUPT_BUFFER_READY); |
| 142 | 166 | else |
| 143 | | machine().scheduler().timer_set(time, FUNC(delayed_interrupt), 0, this); |
| 167 | timer_set(time, TID_DELAYED_INTERRUPT); |
| 144 | 168 | } |
| 145 | 169 | |
| 146 | 170 | |
| r23601 | r23602 | |
| 173 | 197 | } |
| 174 | 198 | |
| 175 | 199 | |
| 176 | | static TIMER_CALLBACK( reset_callback ) |
| 177 | | { |
| 178 | | reinterpret_cast<device_t *>(ptr)->reset(); |
| 179 | | } |
| 180 | 200 | |
| 181 | | |
| 182 | | |
| 183 | 201 | /************************************* |
| 184 | 202 | * |
| 185 | 203 | * Advance to the next sector |
| r23601 | r23602 | |
| 230 | 248 | * |
| 231 | 249 | *************************************/ |
| 232 | 250 | |
| 233 | | static TIMER_CALLBACK( security_error_done ) |
| 234 | | { |
| 235 | | ide_controller_device *ide = (ide_controller_device *)ptr; |
| 236 | | |
| 237 | | /* clear error state */ |
| 238 | | ide->status &= ~IDE_STATUS_ERROR; |
| 239 | | ide->status |= IDE_STATUS_DRIVE_READY; |
| 240 | | } |
| 241 | | |
| 242 | 251 | void ide_controller_device::security_error() |
| 243 | 252 | { |
| 244 | 253 | /* set error state */ |
| r23601 | r23602 | |
| 246 | 255 | status &= ~IDE_STATUS_DRIVE_READY; |
| 247 | 256 | |
| 248 | 257 | /* just set a timer and mark ourselves error */ |
| 249 | | machine().scheduler().timer_set(TIME_SECURITY_ERROR, FUNC(security_error_done), 0, this); |
| 258 | timer_set(TIME_SECURITY_ERROR, TID_SECURITY_ERROR_DONE); |
| 250 | 259 | } |
| 251 | 260 | |
| 252 | 261 | |
| r23601 | r23602 | |
| 350 | 359 | } |
| 351 | 360 | |
| 352 | 361 | |
| 353 | | static TIMER_CALLBACK( read_sector_done_callback ) |
| 354 | | { |
| 355 | | ide_controller_device *ide = (ide_controller_device *)ptr; |
| 356 | | |
| 357 | | ide->read_sector_done(); |
| 358 | | } |
| 359 | | |
| 360 | | |
| 361 | 362 | void ide_controller_device::read_first_sector() |
| 362 | 363 | { |
| 363 | 364 | ide_device_interface *dev = slot[cur_drive]->dev(); |
| r23601 | r23602 | |
| 376 | 377 | seek_time = TIME_SEEK_MULTISECTOR; |
| 377 | 378 | |
| 378 | 379 | dev->cur_lba = new_lba; |
| 379 | | machine().scheduler().timer_set(seek_time, FUNC(read_sector_done_callback), 0, this); |
| 380 | timer_set(seek_time, TID_READ_SECTOR_DONE_CALLBACK); |
| 380 | 381 | } |
| 381 | 382 | else |
| 382 | | machine().scheduler().timer_set(TIME_PER_SECTOR, FUNC(read_sector_done_callback), 0, this); |
| 383 | timer_set(TIME_PER_SECTOR, TID_READ_SECTOR_DONE_CALLBACK); |
| 383 | 384 | } |
| 384 | 385 | |
| 385 | 386 | |
| r23601 | r23602 | |
| 395 | 396 | read_sector_done(); |
| 396 | 397 | else |
| 397 | 398 | /* just set a timer */ |
| 398 | | machine().scheduler().timer_set(attotime::from_usec(1), FUNC(read_sector_done_callback), 0, this); |
| 399 | timer_set(attotime::from_usec(1), TID_READ_SECTOR_DONE_CALLBACK); |
| 399 | 400 | } |
| 400 | 401 | else |
| 401 | 402 | /* just set a timer */ |
| 402 | | machine().scheduler().timer_set(TIME_PER_SECTOR, FUNC(read_sector_done_callback), 0, this); |
| 403 | timer_set(TIME_PER_SECTOR, TID_READ_SECTOR_DONE_CALLBACK); |
| 403 | 404 | } |
| 404 | 405 | |
| 405 | 406 | |
| r23601 | r23602 | |
| 410 | 411 | * |
| 411 | 412 | *************************************/ |
| 412 | 413 | |
| 413 | | static TIMER_CALLBACK( write_sector_done_callback ); |
| 414 | | |
| 415 | 414 | void ide_controller_device::continue_write() |
| 416 | 415 | { |
| 417 | 416 | /* reset the totals */ |
| r23601 | r23602 | |
| 431 | 430 | else |
| 432 | 431 | { |
| 433 | 432 | /* set a timer to do the write */ |
| 434 | | machine().scheduler().timer_set(TIME_PER_SECTOR, FUNC(write_sector_done_callback), 0, this); |
| 433 | timer_set(TIME_PER_SECTOR, TID_WRITE_SECTOR_DONE_CALLBACK); |
| 435 | 434 | } |
| 436 | 435 | } |
| 437 | 436 | else |
| 438 | 437 | { |
| 439 | 438 | /* set a timer to do the write */ |
| 440 | | machine().scheduler().timer_set(TIME_PER_SECTOR, FUNC(write_sector_done_callback), 0, this); |
| 439 | timer_set(TIME_PER_SECTOR, TID_WRITE_SECTOR_DONE_CALLBACK); |
| 441 | 440 | } |
| 442 | 441 | } |
| 443 | 442 | |
| r23601 | r23602 | |
| 569 | 568 | } |
| 570 | 569 | |
| 571 | 570 | |
| 572 | | static TIMER_CALLBACK( write_sector_done_callback ) |
| 573 | | { |
| 574 | | ide_controller_device *ide = (ide_controller_device *)ptr; |
| 575 | | ide->write_sector_done(); |
| 576 | | } |
| 577 | 571 | |
| 578 | | |
| 579 | | |
| 580 | 572 | /************************************* |
| 581 | 573 | * |
| 582 | 574 | * Handle IDE commands |
| r23601 | r23602 | |
| 1330 | 1322 | slot[1] = owner()->subdevice<ide_slot_device>("drive_1"); |
| 1331 | 1323 | |
| 1332 | 1324 | /* create a timer for timing status */ |
| 1333 | | last_status_timer = machine().scheduler().timer_alloc(FUNC_NULL); |
| 1334 | | reset_timer = machine().scheduler().timer_alloc(FUNC(reset_callback), this); |
| 1325 | last_status_timer = timer_alloc(TID_NULL); |
| 1326 | reset_timer = timer_alloc(TID_RESET_CALLBACK); |
| 1335 | 1327 | |
| 1336 | 1328 | /* register ide states */ |
| 1337 | 1329 | save_item(NAME(adapter_control)); |