trunk/src/mess/machine/rmnimbus.c
r22503 | r22504 | |
102 | 102 | |
103 | 103 | /* Debugging */ |
104 | 104 | |
105 | | #define DEBUG_SET(flags) ((state->m_debug_machine & (flags))==(flags)) |
| 105 | #define DEBUG_SET(flags) ((m_debug_machine & (flags))==(flags)) |
| 106 | #define DEBUG_SET_STATE(flags) ((state->m_debug_machine & (flags))==(flags)) |
106 | 107 | |
107 | 108 | #define DEBUG_NONE 0x0000000 |
108 | 109 | #define DMA_BREAK 0x0000001 |
r22503 | r22504 | |
152 | 153 | /* Sound */ |
153 | 154 | |
154 | 155 | |
155 | | static void drq_callback(running_machine &machine, int which); |
156 | | static void nimbus_recalculate_ints(running_machine &machine); |
157 | | |
158 | 156 | static void execute_debug_irq(running_machine &machine, int ref, int params, const char *param[]); |
159 | 157 | static void execute_debug_intmasks(running_machine &machine, int ref, int params, const char *param[]); |
160 | 158 | static void nimbus_debug(running_machine &machine, int ref, int params, const char *param[]); |
r22503 | r22504 | |
169 | 167 | static void decode_dssi_f_plonk_char(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag); |
170 | 168 | static void decode_dssi_f_rw_sectors(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag); |
171 | 169 | |
172 | | static void nimbus_bank_memory(running_machine &machine); |
173 | | static void memory_reset(running_machine &machine); |
174 | | static void fdc_reset(running_machine &machine); |
175 | | static void set_disk_int(running_machine &machine, int state); |
176 | | static void hdc_reset(running_machine &machine); |
177 | | static void hdc_ctrl_write(running_machine &machine, UINT8 data); |
178 | | static void hdc_post_rw(running_machine &machine); |
179 | | static void hdc_drq(running_machine &machine); |
180 | 170 | |
181 | | static void keyboard_reset(running_machine &machine); |
182 | 171 | |
183 | | |
184 | | static void pc8031_reset(running_machine &machine); |
185 | | static void iou_reset(running_machine &machine); |
186 | | static void rmni_sound_reset(running_machine &machine); |
187 | | |
188 | | static void mouse_js_reset(running_machine &machine); |
189 | | |
190 | | |
191 | | |
192 | 172 | /************************************* |
193 | 173 | * |
194 | 174 | * 80186 interrupt controller |
r22503 | r22504 | |
260 | 240 | } |
261 | 241 | |
262 | 242 | |
263 | | static void update_interrupt_state(running_machine &machine) |
| 243 | void rmnimbus_state::update_interrupt_state() |
264 | 244 | { |
265 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
266 | 245 | int new_vector = 0; |
267 | 246 | int Priority; |
268 | 247 | int IntNo; |
269 | 248 | |
270 | 249 | if (LOG_INTERRUPTS) |
271 | | logerror("update_interrupt_status: req=%04X stat=%04X serv=%04X priority_mask=%4X\n", state->m_i186.intr.request, state->m_i186.intr.status, state->m_i186.intr.in_service, state->m_i186.intr.priority_mask); |
| 250 | logerror("update_interrupt_status: req=%04X stat=%04X serv=%04X priority_mask=%4X\n", m_i186.intr.request, m_i186.intr.status, m_i186.intr.in_service, m_i186.intr.priority_mask); |
272 | 251 | |
273 | 252 | /* loop over priorities */ |
274 | | for (Priority = 0; Priority <= state->m_i186.intr.priority_mask; Priority++) |
| 253 | for (Priority = 0; Priority <= m_i186.intr.priority_mask; Priority++) |
275 | 254 | { |
276 | 255 | /* note: by checking 4 bits, we also verify that the mask is off */ |
277 | | if ((state->m_i186.intr.timer & 0x0F) == Priority) |
| 256 | if ((m_i186.intr.timer & 0x0F) == Priority) |
278 | 257 | { |
279 | 258 | /* if we're already servicing something at this level, don't generate anything new */ |
280 | | if (state->m_i186.intr.in_service & 0x01) |
| 259 | if (m_i186.intr.in_service & 0x01) |
281 | 260 | return; |
282 | 261 | |
283 | 262 | /* if there's something pending, generate an interrupt */ |
284 | | if (state->m_i186.intr.status & 0x07) |
| 263 | if (m_i186.intr.status & 0x07) |
285 | 264 | { |
286 | | if (state->m_i186.intr.status & 1) |
| 265 | if (m_i186.intr.status & 1) |
287 | 266 | new_vector = 0x08; |
288 | | else if (state->m_i186.intr.status & 2) |
| 267 | else if (m_i186.intr.status & 2) |
289 | 268 | new_vector = 0x12; |
290 | | else if (state->m_i186.intr.status & 4) |
| 269 | else if (m_i186.intr.status & 4) |
291 | 270 | new_vector = 0x13; |
292 | 271 | else |
293 | 272 | popmessage("Invalid timer interrupt!"); |
294 | 273 | |
295 | 274 | /* set the clear mask and generate the int */ |
296 | | state->m_i186.intr.ack_mask = 0x0001; |
| 275 | m_i186.intr.ack_mask = 0x0001; |
297 | 276 | goto generate_int; |
298 | 277 | } |
299 | 278 | } |
300 | 279 | |
301 | 280 | /* check DMA interrupts */ |
302 | 281 | for (IntNo = 0; IntNo < 2; IntNo++) |
303 | | if ((state->m_i186.intr.dma[IntNo] & 0x0F) == Priority) |
| 282 | if ((m_i186.intr.dma[IntNo] & 0x0F) == Priority) |
304 | 283 | { |
305 | 284 | /* if we're already servicing something at this level, don't generate anything new */ |
306 | | if (state->m_i186.intr.in_service & (0x04 << IntNo)) |
| 285 | if (m_i186.intr.in_service & (0x04 << IntNo)) |
307 | 286 | return; |
308 | 287 | |
309 | 288 | /* if there's something pending, generate an interrupt */ |
310 | | if (state->m_i186.intr.request & (0x04 << IntNo)) |
| 289 | if (m_i186.intr.request & (0x04 << IntNo)) |
311 | 290 | { |
312 | 291 | new_vector = 0x0a + IntNo; |
313 | 292 | |
314 | 293 | /* set the clear mask and generate the int */ |
315 | | state->m_i186.intr.ack_mask = 0x0004 << IntNo; |
| 294 | m_i186.intr.ack_mask = 0x0004 << IntNo; |
316 | 295 | goto generate_int; |
317 | 296 | } |
318 | 297 | } |
319 | 298 | |
320 | 299 | /* check external interrupts */ |
321 | 300 | for (IntNo = 0; IntNo < 4; IntNo++) |
322 | | if ((state->m_i186.intr.ext[IntNo] & 0x0F) == Priority) |
| 301 | if ((m_i186.intr.ext[IntNo] & 0x0F) == Priority) |
323 | 302 | { |
324 | 303 | if (LOG_INTERRUPTS) |
325 | 304 | logerror("Int%d priority=%d\n",IntNo,Priority); |
326 | 305 | |
327 | 306 | /* if we're already servicing something at this level, don't generate anything new */ |
328 | | if (state->m_i186.intr.in_service & (0x10 << IntNo)) |
| 307 | if (m_i186.intr.in_service & (0x10 << IntNo)) |
329 | 308 | return; |
330 | 309 | |
331 | 310 | /* if there's something pending, generate an interrupt */ |
332 | | if (state->m_i186.intr.request & (0x10 << IntNo)) |
| 311 | if (m_i186.intr.request & (0x10 << IntNo)) |
333 | 312 | { |
334 | 313 | /* otherwise, generate an interrupt for this request */ |
335 | 314 | new_vector = 0x0c + IntNo; |
336 | 315 | |
337 | 316 | /* set the clear mask and generate the int */ |
338 | | state->m_i186.intr.ack_mask = 0x0010 << IntNo; |
| 317 | m_i186.intr.ack_mask = 0x0010 << IntNo; |
339 | 318 | goto generate_int; |
340 | 319 | } |
341 | 320 | } |
r22503 | r22504 | |
344 | 323 | |
345 | 324 | generate_int: |
346 | 325 | /* generate the appropriate interrupt */ |
347 | | state->m_i186.intr.poll_status = 0x8000 | new_vector; |
348 | | if (!state->m_i186.intr.pending) |
349 | | machine.device(MAINCPU_TAG)->execute().set_input_line(0, ASSERT_LINE); |
350 | | state->m_i186.intr.pending = 1; |
351 | | machine.scheduler().trigger(CPU_RESUME_TRIGGER); |
| 326 | m_i186.intr.poll_status = 0x8000 | new_vector; |
| 327 | if (!m_i186.intr.pending) |
| 328 | m_maincpu->set_input_line(0, ASSERT_LINE); |
| 329 | m_i186.intr.pending = 1; |
| 330 | machine().scheduler().trigger(CPU_RESUME_TRIGGER); |
352 | 331 | if (LOG_OPTIMIZATION) logerror(" - trigger due to interrupt pending\n"); |
353 | | if (LOG_INTERRUPTS) logerror("(%f) **** Requesting interrupt vector %02X\n", machine.time().as_double(), new_vector); |
| 332 | if (LOG_INTERRUPTS) logerror("(%f) **** Requesting interrupt vector %02X\n", machine().time().as_double(), new_vector); |
354 | 333 | } |
355 | 334 | |
356 | 335 | |
357 | | static void handle_eoi(running_machine &machine,int data) |
| 336 | void rmnimbus_state::handle_eoi(int data) |
358 | 337 | { |
359 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
360 | 338 | int Priority; |
361 | 339 | int IntNo; |
362 | 340 | int handled=0; |
r22503 | r22504 | |
367 | 345 | /* turn off the appropriate in-service bit */ |
368 | 346 | switch (data & 0x1f) |
369 | 347 | { |
370 | | case 0x08: state->m_i186.intr.in_service &= ~0x01; break; |
371 | | case 0x12: state->m_i186.intr.in_service &= ~0x01; break; |
372 | | case 0x13: state->m_i186.intr.in_service &= ~0x01; break; |
373 | | case 0x0a: state->m_i186.intr.in_service &= ~0x04; break; |
374 | | case 0x0b: state->m_i186.intr.in_service &= ~0x08; break; |
375 | | case 0x0c: state->m_i186.intr.in_service &= ~0x10; break; |
376 | | case 0x0d: state->m_i186.intr.in_service &= ~0x20; break; |
377 | | case 0x0e: state->m_i186.intr.in_service &= ~0x40; break; |
378 | | case 0x0f: state->m_i186.intr.in_service &= ~0x80; break; |
379 | | default: logerror("%05X:ERROR - 80186 EOI with unknown vector %02X\n", machine.device(MAINCPU_TAG)->safe_pc(), data & 0x1f); |
| 348 | case 0x08: m_i186.intr.in_service &= ~0x01; break; |
| 349 | case 0x12: m_i186.intr.in_service &= ~0x01; break; |
| 350 | case 0x13: m_i186.intr.in_service &= ~0x01; break; |
| 351 | case 0x0a: m_i186.intr.in_service &= ~0x04; break; |
| 352 | case 0x0b: m_i186.intr.in_service &= ~0x08; break; |
| 353 | case 0x0c: m_i186.intr.in_service &= ~0x10; break; |
| 354 | case 0x0d: m_i186.intr.in_service &= ~0x20; break; |
| 355 | case 0x0e: m_i186.intr.in_service &= ~0x40; break; |
| 356 | case 0x0f: m_i186.intr.in_service &= ~0x80; break; |
| 357 | default: logerror("%05X:ERROR - 80186 EOI with unknown vector %02X\n", m_maincpu->pc(), data & 0x1f); |
380 | 358 | } |
381 | | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for vector %02X\n", machine.time().as_double(), data & 0x1f); |
| 359 | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for vector %02X\n", machine().time().as_double(), data & 0x1f); |
382 | 360 | } |
383 | 361 | |
384 | 362 | /* non-specific case */ |
r22503 | r22504 | |
388 | 366 | for (Priority = 0; ((Priority <= 7) && !handled); Priority++) |
389 | 367 | { |
390 | 368 | /* check for in-service timers */ |
391 | | if ((state->m_i186.intr.timer & 0x07) == Priority && (state->m_i186.intr.in_service & 0x01)) |
| 369 | if ((m_i186.intr.timer & 0x07) == Priority && (m_i186.intr.in_service & 0x01)) |
392 | 370 | { |
393 | | state->m_i186.intr.in_service &= ~0x01; |
394 | | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for timer\n", machine.time().as_double()); |
| 371 | m_i186.intr.in_service &= ~0x01; |
| 372 | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for timer\n", machine().time().as_double()); |
395 | 373 | handled=1; |
396 | 374 | } |
397 | 375 | |
398 | 376 | /* check for in-service DMA interrupts */ |
399 | 377 | for (IntNo = 0; ((IntNo < 2) && !handled) ; IntNo++) |
400 | | if ((state->m_i186.intr.dma[IntNo] & 0x07) == Priority && (state->m_i186.intr.in_service & (0x04 << IntNo))) |
| 378 | if ((m_i186.intr.dma[IntNo] & 0x07) == Priority && (m_i186.intr.in_service & (0x04 << IntNo))) |
401 | 379 | { |
402 | | state->m_i186.intr.in_service &= ~(0x04 << IntNo); |
403 | | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for DMA%d\n", machine.time().as_double(), IntNo); |
| 380 | m_i186.intr.in_service &= ~(0x04 << IntNo); |
| 381 | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for DMA%d\n", machine().time().as_double(), IntNo); |
404 | 382 | handled=1; |
405 | 383 | } |
406 | 384 | |
407 | 385 | /* check external interrupts */ |
408 | 386 | for (IntNo = 0; ((IntNo < 4) && !handled) ; IntNo++) |
409 | | if ((state->m_i186.intr.ext[IntNo] & 0x07) == Priority && (state->m_i186.intr.in_service & (0x10 << IntNo))) |
| 387 | if ((m_i186.intr.ext[IntNo] & 0x07) == Priority && (m_i186.intr.in_service & (0x10 << IntNo))) |
410 | 388 | { |
411 | | state->m_i186.intr.in_service &= ~(0x10 << IntNo); |
412 | | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for INT%d\n", machine.time().as_double(), IntNo); |
| 389 | m_i186.intr.in_service &= ~(0x10 << IntNo); |
| 390 | if (LOG_INTERRUPTS) logerror("(%f) **** Got EOI for INT%d\n", machine().time().as_double(), IntNo); |
413 | 391 | handled=1; |
414 | 392 | } |
415 | 393 | } |
416 | 394 | } |
417 | | nimbus_recalculate_ints(machine); |
| 395 | nimbus_recalculate_ints(); |
418 | 396 | } |
419 | 397 | |
420 | 398 | /* Trigger an external interupt, optionally supplying the vector to take */ |
421 | | static void external_int(running_machine &machine, UINT16 intno, UINT8 vector) |
| 399 | void rmnimbus_state::external_int(UINT16 intno, UINT8 vector) |
422 | 400 | { |
423 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
424 | 401 | if (LOG_INTERRUPTS_EXT) logerror("generating external int %02X, vector %02X\n",intno,vector); |
425 | 402 | |
426 | 403 | // Only 4 external ints |
r22503 | r22504 | |
434 | 411 | // int 0 & int 1 |
435 | 412 | if (intno<2) |
436 | 413 | { |
437 | | if(state->m_i186.intr.ext[intno] & EXTINT_CTRL_CASCADE) |
438 | | state->m_i186.intr.ext_vector[intno]=vector; |
| 414 | if(m_i186.intr.ext[intno] & EXTINT_CTRL_CASCADE) |
| 415 | m_i186.intr.ext_vector[intno]=vector; |
439 | 416 | } |
440 | 417 | |
441 | 418 | // Turn on the requested request bit and handle interrupt |
442 | | state->m_i186.intr.request |= (0x010 << intno); |
443 | | update_interrupt_state(machine); |
| 419 | m_i186.intr.request |= (0x010 << intno); |
| 420 | update_interrupt_state(); |
444 | 421 | } |
445 | 422 | |
446 | | static void nimbus_recalculate_ints(running_machine &machine) |
| 423 | void rmnimbus_state::nimbus_recalculate_ints() |
447 | 424 | { |
448 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
449 | | if((state->m_iou_reg092 & DISK_INT_ENABLE) && state->m_nimbus_drives.int_ff) |
| 425 | if((m_iou_reg092 & DISK_INT_ENABLE) && m_nimbus_drives.int_ff) |
450 | 426 | { |
451 | | state->m_nimbus_drives.int_ff=0; |
452 | | external_int(machine,0,EXTERNAL_INT_DISK); |
| 427 | m_nimbus_drives.int_ff=0; |
| 428 | external_int(0,EXTERNAL_INT_DISK); |
453 | 429 | } |
454 | 430 | } |
455 | 431 | |
r22503 | r22504 | |
473 | 449 | if (t->control & 0x2000) |
474 | 450 | { |
475 | 451 | m_i186.intr.status |= 0x01 << which; |
476 | | update_interrupt_state(machine()); |
| 452 | update_interrupt_state(); |
477 | 453 | if (LOG_TIMER) logerror(" Generating timer interrupt\n"); |
478 | 454 | } |
479 | 455 | |
r22503 | r22504 | |
489 | 465 | } |
490 | 466 | |
491 | 467 | |
492 | | static void internal_timer_sync(running_machine &machine, int which) |
| 468 | void rmnimbus_state::internal_timer_sync(int which) |
493 | 469 | { |
494 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
495 | | struct timer_state *t = &state->m_i186.timer[which]; |
| 470 | struct timer_state *t = &m_i186.timer[which]; |
496 | 471 | |
497 | 472 | /* if we have a timing timer running, adjust the count */ |
498 | 473 | if (t->time_timer_active) |
r22503 | r22504 | |
514 | 489 | } |
515 | 490 | |
516 | 491 | |
517 | | static void internal_timer_update(running_machine &machine, |
518 | | int which, |
519 | | int new_count, |
520 | | int new_maxA, |
521 | | int new_maxB, |
522 | | int new_control) |
| 492 | void rmnimbus_state::internal_timer_update(int which,int new_count,int new_maxA,int new_maxB,int new_control) |
523 | 493 | { |
524 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
525 | | struct timer_state *t = &state->m_i186.timer[which]; |
| 494 | struct timer_state *t = &m_i186.timer[which]; |
526 | 495 | int update_int_timer = 0; |
527 | 496 | |
528 | 497 | if (LOG_TIMER) |
r22503 | r22504 | |
533 | 502 | { |
534 | 503 | if (t->control & 0x8000) |
535 | 504 | { |
536 | | internal_timer_sync(machine, which); |
| 505 | internal_timer_sync(which); |
537 | 506 | update_int_timer = 1; |
538 | 507 | } |
539 | 508 | t->count = new_count; |
r22503 | r22504 | |
544 | 513 | { |
545 | 514 | if (t->control & 0x8000) |
546 | 515 | { |
547 | | internal_timer_sync(machine, which); |
| 516 | internal_timer_sync(which); |
548 | 517 | update_int_timer = 1; |
549 | 518 | } |
550 | 519 | t->maxA = new_maxA; |
r22503 | r22504 | |
559 | 528 | { |
560 | 529 | if (t->control & 0x8000) |
561 | 530 | { |
562 | | internal_timer_sync(machine, which); |
| 531 | internal_timer_sync(which); |
563 | 532 | update_int_timer = 1; |
564 | 533 | } |
565 | 534 | |
r22503 | r22504 | |
589 | 558 | diff = new_control ^ t->control; |
590 | 559 | if (diff & 0x001c) |
591 | 560 | logerror("%05X:ERROR! -unsupported timer mode %04X\n", |
592 | | machine.device(MAINCPU_TAG)->safe_pc(), new_control); |
| 561 | m_maincpu->pc(), new_control); |
593 | 562 | |
594 | 563 | /* if we have real changes, update things */ |
595 | 564 | if (diff != 0) |
r22503 | r22504 | |
598 | 567 | if ((diff & 0x8000) && !(new_control & 0x8000)) |
599 | 568 | { |
600 | 569 | /* compute the final count */ |
601 | | internal_timer_sync(machine, which); |
| 570 | internal_timer_sync(which); |
602 | 571 | |
603 | 572 | /* nuke the timer and force the interrupt timer to be recomputed */ |
604 | 573 | t->time_timer->adjust(attotime::never, which); |
r22503 | r22504 | |
618 | 587 | /* if something about the interrupt timer changed, force an update */ |
619 | 588 | if (!(diff & 0x8000) && (diff & 0x2000)) |
620 | 589 | { |
621 | | internal_timer_sync(machine, which); |
| 590 | internal_timer_sync(which); |
622 | 591 | update_int_timer = 1; |
623 | 592 | } |
624 | 593 | } |
r22503 | r22504 | |
668 | 637 | { |
669 | 638 | if (LOG_DMA>1) logerror("DMA%d timer callback - requesting interrupt: count = %04X, source = %04X\n", which, d->count, d->source); |
670 | 639 | m_i186.intr.request |= 0x04 << which; |
671 | | update_interrupt_state(machine()); |
| 640 | update_interrupt_state(); |
672 | 641 | } |
673 | 642 | } |
674 | 643 | |
675 | 644 | |
676 | | static void update_dma_control(running_machine &machine, int which, int new_control) |
| 645 | void rmnimbus_state::update_dma_control(int which, int new_control) |
677 | 646 | { |
678 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
679 | | struct dma_state *d = &state->m_i186.dma[which]; |
| 647 | struct dma_state *d = &m_i186.dma[which]; |
680 | 648 | int diff; |
681 | 649 | |
682 | 650 | /* handle the CHG bit */ |
r22503 | r22504 | |
688 | 656 | diff = new_control ^ d->control; |
689 | 657 | if ((LOG_DMA) && (diff & 0x6811)) |
690 | 658 | logerror("%05X:ERROR! - unsupported DMA mode %04X\n", |
691 | | machine.device(MAINCPU_TAG)->safe_pc(), new_control); |
| 659 | m_maincpu->pc(), new_control); |
692 | 660 | #if 0 |
693 | 661 | /* if we're going live, set a timer */ |
694 | 662 | if ((diff & 0x0002) && (new_control & 0x0002)) |
r22503 | r22504 | |
717 | 685 | |
718 | 686 | if (LOG_DMA) logerror("Initiated DMA %d - count = %04X, source = %04X, dest = %04X\n", which, d->count, d->source, d->dest); |
719 | 687 | if (DEBUG_SET(DMA_BREAK)) |
720 | | debugger_break(machine); |
| 688 | debugger_break(machine()); |
721 | 689 | |
722 | 690 | /* set the new control register */ |
723 | 691 | d->control = new_control; |
724 | 692 | } |
725 | 693 | |
726 | | static void drq_callback(running_machine &machine, int which) |
| 694 | void rmnimbus_state::drq_callback(int which) |
727 | 695 | { |
728 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
729 | | struct dma_state *dma = &state->m_i186.dma[which]; |
730 | | address_space &memory_space = machine.device(MAINCPU_TAG)->memory().space(AS_PROGRAM); |
731 | | address_space &io_space = machine.device(MAINCPU_TAG)->memory().space(AS_IO); |
| 696 | struct dma_state *dma = &m_i186.dma[which]; |
| 697 | address_space &memory_space = m_maincpu->space(AS_PROGRAM); |
| 698 | address_space &io_space = m_maincpu->space(AS_IO); |
732 | 699 | |
733 | 700 | UINT16 dma_word; |
734 | 701 | UINT8 dma_byte; |
r22503 | r22504 | |
740 | 707 | if(!(dma->control & ST_STOP)) |
741 | 708 | { |
742 | 709 | logerror("%05X:ERROR! - drq%d with dma channel stopped\n", |
743 | | machine.device(MAINCPU_TAG)->safe_pc(), which); |
| 710 | m_maincpu->pc(), which); |
744 | 711 | |
745 | 712 | return; |
746 | 713 | } |
r22503 | r22504 | |
789 | 756 | if((dma->control & INTERRUPT_ON_ZERO) && (dma->count==0)) |
790 | 757 | { |
791 | 758 | if (LOG_DMA>1) logerror("DMA%d - requesting interrupt: count = %04X, source = %04X\n", which, dma->count, dma->source); |
792 | | state->m_i186.intr.request |= 0x04 << which; |
793 | | update_interrupt_state(machine); |
| 759 | m_i186.intr.request |= 0x04 << which; |
| 760 | update_interrupt_state(); |
794 | 761 | } |
795 | 762 | } |
796 | 763 | |
r22503 | r22504 | |
798 | 765 | /* Name: rmnimbus */ |
799 | 766 | /* Desc: CPU - Initialize the 80186 CPU */ |
800 | 767 | /*-------------------------------------------------------------------------*/ |
801 | | static void nimbus_cpu_init(running_machine &machine) |
| 768 | void rmnimbus_state::nimbus_cpu_init() |
802 | 769 | { |
803 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
804 | 770 | logerror("Machine reset\n"); |
805 | 771 | |
806 | 772 | /* create timers here so they stick around */ |
807 | | state->m_i186.timer[0].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),state)); |
808 | | state->m_i186.timer[1].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),state)); |
809 | | state->m_i186.timer[2].int_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),state)); |
810 | | state->m_i186.timer[0].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); |
811 | | state->m_i186.timer[1].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); |
812 | | state->m_i186.timer[2].time_timer = machine.scheduler().timer_alloc(FUNC_NULL); |
813 | | state->m_i186.dma[0].finish_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::dma_timer_callback),state)); |
814 | | state->m_i186.dma[1].finish_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::dma_timer_callback),state)); |
| 773 | m_i186.timer[0].int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),this)); |
| 774 | m_i186.timer[1].int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),this)); |
| 775 | m_i186.timer[2].int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::internal_timer_int),this)); |
| 776 | m_i186.timer[0].time_timer = machine().scheduler().timer_alloc(FUNC_NULL); |
| 777 | m_i186.timer[1].time_timer = machine().scheduler().timer_alloc(FUNC_NULL); |
| 778 | m_i186.timer[2].time_timer = machine().scheduler().timer_alloc(FUNC_NULL); |
| 779 | m_i186.dma[0].finish_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::dma_timer_callback),this)); |
| 780 | m_i186.dma[1].finish_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::dma_timer_callback),this)); |
815 | 781 | } |
816 | 782 | |
817 | | static void nimbus_cpu_reset(running_machine &machine) |
| 783 | void rmnimbus_state::nimbus_cpu_reset() |
818 | 784 | { |
819 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
820 | 785 | /* reset the interrupt state */ |
821 | | state->m_i186.intr.priority_mask = 0x0007; |
822 | | state->m_i186.intr.timer = 0x000f; |
823 | | state->m_i186.intr.dma[0] = 0x000f; |
824 | | state->m_i186.intr.dma[1] = 0x000f; |
825 | | state->m_i186.intr.ext[0] = 0x000f; |
826 | | state->m_i186.intr.ext[1] = 0x000f; |
827 | | state->m_i186.intr.ext[2] = 0x000f; |
828 | | state->m_i186.intr.ext[3] = 0x000f; |
829 | | state->m_i186.intr.in_service = 0x0000; |
| 786 | m_i186.intr.priority_mask = 0x0007; |
| 787 | m_i186.intr.timer = 0x000f; |
| 788 | m_i186.intr.dma[0] = 0x000f; |
| 789 | m_i186.intr.dma[1] = 0x000f; |
| 790 | m_i186.intr.ext[0] = 0x000f; |
| 791 | m_i186.intr.ext[1] = 0x000f; |
| 792 | m_i186.intr.ext[2] = 0x000f; |
| 793 | m_i186.intr.ext[3] = 0x000f; |
| 794 | m_i186.intr.in_service = 0x0000; |
830 | 795 | |
831 | 796 | /* External vectors by default to internal int 0/1 vectors */ |
832 | | state->m_i186.intr.ext_vector[0] = 0x000C; |
833 | | state->m_i186.intr.ext_vector[1] = 0x000D; |
| 797 | m_i186.intr.ext_vector[0] = 0x000C; |
| 798 | m_i186.intr.ext_vector[1] = 0x000D; |
834 | 799 | |
835 | | state->m_i186.intr.pending = 0x0000; |
836 | | state->m_i186.intr.ack_mask = 0x0000; |
837 | | state->m_i186.intr.request = 0x0000; |
838 | | state->m_i186.intr.status = 0x0000; |
839 | | state->m_i186.intr.poll_status = 0x0000; |
| 800 | m_i186.intr.pending = 0x0000; |
| 801 | m_i186.intr.ack_mask = 0x0000; |
| 802 | m_i186.intr.request = 0x0000; |
| 803 | m_i186.intr.status = 0x0000; |
| 804 | m_i186.intr.poll_status = 0x0000; |
840 | 805 | |
841 | 806 | logerror("CPU reset done\n"); |
842 | 807 | } |
r22503 | r22504 | |
854 | 819 | case 0x12: |
855 | 820 | if (LOG_PORTS) logerror("%05X:read 80186 interrupt poll\n", space.device().safe_pc()); |
856 | 821 | if (m_i186.intr.poll_status & 0x8000) |
857 | | int_callback(*machine().device(MAINCPU_TAG), 0); |
| 822 | int_callback(*m_maincpu, 0); |
858 | 823 | return m_i186.intr.poll_status; |
859 | 824 | |
860 | 825 | case 0x13: |
r22503 | r22504 | |
925 | 890 | if (LOG_PORTS) logerror("%05X:read 80186 Timer %d count\n", space.device().safe_pc(), (offset - 0x28) / 4); |
926 | 891 | which = (offset - 0x28) / 4; |
927 | 892 | if (!(offset & 1)) |
928 | | internal_timer_sync(machine(), which); |
| 893 | internal_timer_sync(which); |
929 | 894 | return m_i186.timer[which].count; |
930 | 895 | |
931 | 896 | case 0x29: |
r22503 | r22504 | |
1025 | 990 | { |
1026 | 991 | case 0x11: |
1027 | 992 | if (LOG_PORTS) logerror("%05X:80186 EOI = %04X\n", space.device().safe_pc(), data16); |
1028 | | handle_eoi(machine(),0x8000); |
1029 | | update_interrupt_state(machine()); |
| 993 | handle_eoi(0x8000); |
| 994 | update_interrupt_state(); |
1030 | 995 | break; |
1031 | 996 | |
1032 | 997 | case 0x12: |
r22503 | r22504 | |
1046 | 1011 | m_i186.intr.ext[1] = (m_i186.intr.ext[1] & ~0x08) | ((data16 >> 2) & 0x08); |
1047 | 1012 | m_i186.intr.ext[2] = (m_i186.intr.ext[2] & ~0x08) | ((data16 >> 3) & 0x08); |
1048 | 1013 | m_i186.intr.ext[3] = (m_i186.intr.ext[3] & ~0x08) | ((data16 >> 4) & 0x08); |
1049 | | update_interrupt_state(machine()); |
| 1014 | update_interrupt_state(); |
1050 | 1015 | break; |
1051 | 1016 | |
1052 | 1017 | case 0x15: |
1053 | 1018 | if (LOG_PORTS) logerror("%05X:80186 interrupt priority mask = %04X\n", space.device().safe_pc(), data16); |
1054 | 1019 | m_i186.intr.priority_mask = data16 & 0x0007; |
1055 | | update_interrupt_state(machine()); |
| 1020 | update_interrupt_state(); |
1056 | 1021 | break; |
1057 | 1022 | |
1058 | 1023 | case 0x16: |
1059 | 1024 | if (LOG_PORTS) logerror("%05X:80186 interrupt in-service = %04X\n", space.device().safe_pc(), data16); |
1060 | 1025 | m_i186.intr.in_service = data16 & 0x00ff; |
1061 | | update_interrupt_state(machine()); |
| 1026 | update_interrupt_state(); |
1062 | 1027 | break; |
1063 | 1028 | |
1064 | 1029 | case 0x17: |
1065 | 1030 | if (LOG_PORTS) logerror("%05X:80186 interrupt request = %04X\n", space.device().safe_pc(), data16); |
1066 | 1031 | m_i186.intr.request = (m_i186.intr.request & ~0x00c0) | (data16 & 0x00c0); |
1067 | | update_interrupt_state(machine()); |
| 1032 | update_interrupt_state(); |
1068 | 1033 | break; |
1069 | 1034 | |
1070 | 1035 | case 0x18: |
1071 | 1036 | if (LOG_PORTS) logerror("%05X:WARNING - wrote to 80186 interrupt status = %04X\n", space.device().safe_pc(), data16); |
1072 | 1037 | m_i186.intr.status = (m_i186.intr.status & ~0x8007) | (data16 & 0x8007); |
1073 | | update_interrupt_state(machine()); |
| 1038 | update_interrupt_state(); |
1074 | 1039 | break; |
1075 | 1040 | |
1076 | 1041 | case 0x19: |
r22503 | r22504 | |
1113 | 1078 | case 0x30: |
1114 | 1079 | if (LOG_PORTS) logerror("%05X:80186 Timer %d count = %04X\n", space.device().safe_pc(), (offset - 0x28) / 4, data16); |
1115 | 1080 | which = (offset - 0x28) / 4; |
1116 | | internal_timer_update(machine(),which, data16, -1, -1, -1); |
| 1081 | internal_timer_update(which, data16, -1, -1, -1); |
1117 | 1082 | break; |
1118 | 1083 | |
1119 | 1084 | case 0x29: |
r22503 | r22504 | |
1121 | 1086 | case 0x31: |
1122 | 1087 | if (LOG_PORTS) logerror("%05X:80186 Timer %d max A = %04X\n", space.device().safe_pc(), (offset - 0x29) / 4, data16); |
1123 | 1088 | which = (offset - 0x29) / 4; |
1124 | | internal_timer_update(machine(),which, -1, data16, -1, -1); |
| 1089 | internal_timer_update(which, -1, data16, -1, -1); |
1125 | 1090 | break; |
1126 | 1091 | |
1127 | 1092 | case 0x2a: |
1128 | 1093 | case 0x2e: |
1129 | 1094 | if (LOG_PORTS) logerror("%05X:80186 Timer %d max B = %04X\n", space.device().safe_pc(), (offset - 0x2a) / 4, data16); |
1130 | 1095 | which = (offset - 0x2a) / 4; |
1131 | | internal_timer_update(machine(),which, -1, -1, data16, -1); |
| 1096 | internal_timer_update(which, -1, -1, data16, -1); |
1132 | 1097 | break; |
1133 | 1098 | |
1134 | 1099 | case 0x2b: |
r22503 | r22504 | |
1136 | 1101 | case 0x33: |
1137 | 1102 | if (LOG_PORTS) logerror("%05X:80186 Timer %d control = %04X\n", space.device().safe_pc(), (offset - 0x2b) / 4, data16); |
1138 | 1103 | which = (offset - 0x2b) / 4; |
1139 | | internal_timer_update(machine(),which, -1, -1, -1, data16); |
| 1104 | internal_timer_update(which, -1, -1, -1, data16); |
1140 | 1105 | break; |
1141 | 1106 | |
1142 | 1107 | case 0x50: |
r22503 | r22504 | |
1208 | 1173 | case 0x6d: |
1209 | 1174 | if (LOG_PORTS) logerror("%05X:80186 DMA%d control = %04X\n", space.device().safe_pc(), (offset - 0x65) / 8, data16); |
1210 | 1175 | which = (offset - 0x65) / 8; |
1211 | | update_dma_control(machine(), which, data16); |
| 1176 | update_dma_control(which, data16); |
1212 | 1177 | break; |
1213 | 1178 | |
1214 | 1179 | case 0x7f: |
r22503 | r22504 | |
1220 | 1185 | temp = (data16 & 0x0fff) << 8; |
1221 | 1186 | if (data16 & 0x1000) |
1222 | 1187 | { |
1223 | | machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM).install_read_handler(temp, temp + 0xff, read16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_r),this)); |
1224 | | machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM).install_write_handler(temp, temp + 0xff, write16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_w),this)); |
| 1188 | m_maincpu->space(AS_PROGRAM).install_read_handler(temp, temp + 0xff, read16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_r),this)); |
| 1189 | m_maincpu->space(AS_PROGRAM).install_write_handler(temp, temp + 0xff, write16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_w),this)); |
1225 | 1190 | } |
1226 | 1191 | else |
1227 | 1192 | { |
1228 | 1193 | temp &= 0xffff; |
1229 | | machine().device(MAINCPU_TAG)->memory().space(AS_IO).install_read_handler(temp, temp + 0xff, read16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_r),this)); |
1230 | | machine().device(MAINCPU_TAG)->memory().space(AS_IO).install_write_handler(temp, temp + 0xff, write16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_w),this)); |
| 1194 | m_maincpu->space(AS_IO).install_read_handler(temp, temp + 0xff, read16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_r),this)); |
| 1195 | m_maincpu->space(AS_IO).install_write_handler(temp, temp + 0xff, write16_delegate(FUNC(rmnimbus_state::nimbus_i186_internal_port_w),this)); |
1231 | 1196 | } |
1232 | 1197 | break; |
1233 | 1198 | |
r22503 | r22504 | |
1240 | 1205 | void rmnimbus_state::machine_reset() |
1241 | 1206 | { |
1242 | 1207 | /* CPU */ |
1243 | | nimbus_cpu_reset(machine()); |
1244 | | iou_reset(machine()); |
1245 | | fdc_reset(machine()); |
1246 | | hdc_reset(machine()); |
1247 | | keyboard_reset(machine()); |
1248 | | pc8031_reset(machine()); |
1249 | | rmni_sound_reset(machine()); |
1250 | | memory_reset(machine()); |
1251 | | mouse_js_reset(machine()); |
| 1208 | nimbus_cpu_reset(); |
| 1209 | iou_reset(); |
| 1210 | fdc_reset(); |
| 1211 | hdc_reset(); |
| 1212 | keyboard_reset(); |
| 1213 | pc8031_reset(); |
| 1214 | rmni_sound_reset(); |
| 1215 | memory_reset(); |
| 1216 | mouse_js_reset(); |
1252 | 1217 | } |
1253 | 1218 | |
1254 | 1219 | DRIVER_INIT_MEMBER(rmnimbus_state,nimbus) |
r22503 | r22504 | |
1258 | 1223 | void rmnimbus_state::machine_start() |
1259 | 1224 | { |
1260 | 1225 | /* init cpu */ |
1261 | | nimbus_cpu_init(machine()); |
| 1226 | nimbus_cpu_init(); |
1262 | 1227 | |
1263 | 1228 | m_keyboard.keyscan_timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::keyscan_callback),this)); |
1264 | 1229 | m_nimbus_mouse.m_mouse_timer=machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(rmnimbus_state::mouse_callback),this)); |
r22503 | r22504 | |
1271 | 1236 | debug_console_register_command(machine(), "nimbus_debug", CMDFLAG_NONE, 0, 0, 1, nimbus_debug); |
1272 | 1237 | |
1273 | 1238 | /* set up the instruction hook */ |
1274 | | machine().device(MAINCPU_TAG)->debug()->set_instruction_hook(instruction_hook); |
| 1239 | m_maincpu->debug()->set_instruction_hook(instruction_hook); |
1275 | 1240 | } |
1276 | 1241 | |
1277 | 1242 | m_debug_machine=DEBUG_NONE; |
r22503 | r22504 | |
1279 | 1244 | |
1280 | 1245 | static void execute_debug_irq(running_machine &machine, int ref, int params, const char *param[]) |
1281 | 1246 | { |
| 1247 | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
1282 | 1248 | int IntNo; |
1283 | 1249 | int Vector; |
1284 | 1250 | |
r22503 | r22504 | |
1288 | 1254 | sscanf(param[1],"%X",&Vector); |
1289 | 1255 | |
1290 | 1256 | debug_console_printf(machine,"triggering IRQ%d, Vector=%02X\n",IntNo,Vector); |
1291 | | external_int(machine,IntNo,Vector); |
| 1257 | state->external_int(IntNo,Vector); |
1292 | 1258 | } |
1293 | 1259 | else |
1294 | 1260 | { |
r22503 | r22504 | |
1341 | 1307 | |
1342 | 1308 | if ((addr_ptr !=NULL) && (addr_ptr[0]==0xCD)) |
1343 | 1309 | { |
1344 | | if(DEBUG_SET(DECODE_BIOS) && (addr_ptr[1]==0xF0)) |
| 1310 | if(DEBUG_SET_STATE(DECODE_BIOS) && (addr_ptr[1]==0xF0)) |
1345 | 1311 | { |
1346 | | if(DEBUG_SET(DECODE_BIOS_RAW)) |
| 1312 | if(DEBUG_SET_STATE(DECODE_BIOS_RAW)) |
1347 | 1313 | decode_subbios(&device,curpc,1); |
1348 | 1314 | else |
1349 | 1315 | decode_subbios(&device,curpc,0); |
1350 | 1316 | } |
1351 | 1317 | |
1352 | | if(DEBUG_SET(DECODE_DOS21) && (addr_ptr[1]==0x21)) |
| 1318 | if(DEBUG_SET_STATE(DECODE_DOS21) && (addr_ptr[1]==0x21)) |
1353 | 1319 | decode_dos21(&device,curpc); |
1354 | 1320 | } |
1355 | 1321 | |
r22503 | r22504 | |
1700 | 1666 | } |
1701 | 1667 | } |
1702 | 1668 | |
1703 | | static void *get_dssi_ptr(address_space &space, UINT16 ds, UINT16 si) |
| 1669 | void *rmnimbus_state::get_dssi_ptr(address_space &space, UINT16 ds, UINT16 si) |
1704 | 1670 | { |
1705 | 1671 | int addr; |
1706 | 1672 | |
r22503 | r22504 | |
1712 | 1678 | |
1713 | 1679 | static void decode_dssi_generic(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag) |
1714 | 1680 | { |
1715 | | address_space &space = device->machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM); |
| 1681 | rmnimbus_state *state = device->machine().driver_data<rmnimbus_state>(); |
| 1682 | address_space &space = state->m_maincpu->space(AS_PROGRAM); |
1716 | 1683 | UINT16 *params; |
1717 | 1684 | int count; |
1718 | 1685 | |
1719 | 1686 | if(raw_flag) |
1720 | 1687 | return; |
1721 | 1688 | |
1722 | | params=(UINT16 *)get_dssi_ptr(space,ds,si); |
| 1689 | params=(UINT16 *)state->get_dssi_ptr(space,ds,si); |
1723 | 1690 | |
1724 | 1691 | for(count=0; count<10; count++) |
1725 | 1692 | logerror("%04X ",params[count]); |
r22503 | r22504 | |
1730 | 1697 | |
1731 | 1698 | static void decode_dssi_f_fill_area(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag) |
1732 | 1699 | { |
1733 | | address_space &space = device->machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM); |
| 1700 | rmnimbus_state *state = device->machine().driver_data<rmnimbus_state>(); |
| 1701 | address_space &space = state->m_maincpu->space(AS_PROGRAM); |
1734 | 1702 | |
1735 | 1703 | UINT16 *addr_ptr; |
1736 | 1704 | t_area_params *area_params; |
1737 | 1705 | t_nimbus_brush *brush; |
1738 | 1706 | int cocount; |
1739 | 1707 | |
1740 | | area_params = (t_area_params *)get_dssi_ptr(space,ds,si); |
| 1708 | area_params = (t_area_params *)state->get_dssi_ptr(space,ds,si); |
1741 | 1709 | |
1742 | 1710 | if (!raw_flag) |
1743 | 1711 | OUTPUT_SEGOFS("SegBrush:OfsBrush",area_params->seg_brush,area_params->ofs_brush); |
r22503 | r22504 | |
1783 | 1751 | |
1784 | 1752 | static void decode_dssi_f_plot_character_string(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag) |
1785 | 1753 | { |
1786 | | address_space &space = device->machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM); |
| 1754 | rmnimbus_state *state = device->machine().driver_data<rmnimbus_state>(); |
| 1755 | address_space &space = state->m_maincpu->space(AS_PROGRAM); |
1787 | 1756 | |
1788 | 1757 | UINT8 *char_ptr; |
1789 | 1758 | t_plot_string_params *plot_string_params; |
r22503 | r22504 | |
1792 | 1761 | if(raw_flag) |
1793 | 1762 | return; |
1794 | 1763 | |
1795 | | plot_string_params=(t_plot_string_params *)get_dssi_ptr(space,ds,si); |
| 1764 | plot_string_params=(t_plot_string_params *)state->get_dssi_ptr(space,ds,si); |
1796 | 1765 | |
1797 | 1766 | OUTPUT_SEGOFS("SegFont:OfsFont",plot_string_params->seg_font,plot_string_params->ofs_font); |
1798 | 1767 | OUTPUT_SEGOFS("SegData:OfsData",plot_string_params->seg_data,plot_string_params->ofs_data); |
r22503 | r22504 | |
1812 | 1781 | |
1813 | 1782 | static void decode_dssi_f_set_new_clt(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag) |
1814 | 1783 | { |
1815 | | address_space &space = device->machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM); |
| 1784 | rmnimbus_state *state = device->machine().driver_data<rmnimbus_state>(); |
| 1785 | address_space &space = state->m_maincpu->space(AS_PROGRAM); |
1816 | 1786 | UINT16 *new_colours; |
1817 | 1787 | int colour; |
1818 | | new_colours=(UINT16 *)get_dssi_ptr(space,ds,si); |
| 1788 | new_colours=(UINT16 *)state->get_dssi_ptr(space,ds,si); |
1819 | 1789 | |
1820 | 1790 | if(raw_flag) |
1821 | 1791 | return; |
r22503 | r22504 | |
1829 | 1799 | |
1830 | 1800 | static void decode_dssi_f_plonk_char(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag) |
1831 | 1801 | { |
1832 | | address_space &space = device->machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM); |
| 1802 | rmnimbus_state *state = device->machine().driver_data<rmnimbus_state>(); |
| 1803 | address_space &space = state->m_maincpu->space(AS_PROGRAM); |
1833 | 1804 | UINT16 *params; |
1834 | | params=(UINT16 *)get_dssi_ptr(space,ds,si); |
| 1805 | params=(UINT16 *)state->get_dssi_ptr(space,ds,si); |
1835 | 1806 | |
1836 | 1807 | if(raw_flag) |
1837 | 1808 | return; |
r22503 | r22504 | |
1843 | 1814 | |
1844 | 1815 | static void decode_dssi_f_rw_sectors(device_t *device,UINT16 ds, UINT16 si, UINT8 raw_flag) |
1845 | 1816 | { |
1846 | | address_space &space = device->machine().device(MAINCPU_TAG)->memory().space(AS_PROGRAM); |
| 1817 | rmnimbus_state *state = device->machine().driver_data<rmnimbus_state>(); |
| 1818 | address_space &space = state->m_maincpu->space(AS_PROGRAM); |
1847 | 1819 | UINT16 *params; |
1848 | 1820 | int param_no; |
1849 | 1821 | |
1850 | 1822 | if(raw_flag) |
1851 | 1823 | return; |
1852 | 1824 | |
1853 | | params=(UINT16 *)get_dssi_ptr(space,ds,si); |
| 1825 | params=(UINT16 *)state->get_dssi_ptr(space,ds,si); |
1854 | 1826 | |
1855 | 1827 | for(param_no=0;param_no<16;param_no++) |
1856 | 1828 | logerror("%04X ",params[param_no]); |
r22503 | r22504 | |
1976 | 1948 | {{ 0, 512 }, { 512, 512 }, { 1024, 512 } } |
1977 | 1949 | }; |
1978 | 1950 | |
1979 | | static void nimbus_bank_memory(running_machine &machine) |
| 1951 | void rmnimbus_state::nimbus_bank_memory() |
1980 | 1952 | { |
1981 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
1982 | | address_space &space = machine.device( MAINCPU_TAG)->memory().space( AS_PROGRAM ); |
1983 | | int ramsize = machine.device<ram_device>(RAM_TAG)->size(); |
| 1953 | address_space &space = machine().device( MAINCPU_TAG)->memory().space( AS_PROGRAM ); |
| 1954 | int ramsize = machine().device<ram_device>(RAM_TAG)->size(); |
1984 | 1955 | int ramblock = 0; |
1985 | 1956 | int blockno; |
1986 | 1957 | char bank[10]; |
1987 | | UINT8 *ram = &machine.device<ram_device>(RAM_TAG)->pointer()[0]; |
| 1958 | UINT8 *ram = &machine().device<ram_device>(RAM_TAG)->pointer()[0]; |
1988 | 1959 | UINT8 *map_blocks[3]; |
1989 | 1960 | UINT8 *map_base; |
1990 | 1961 | int map_blockno; |
1991 | 1962 | int block_ofs; |
1992 | 1963 | |
1993 | | UINT8 ramsel = (state->m_mcu_reg080 & 0x1F); |
| 1964 | UINT8 ramsel = (m_mcu_reg080 & 0x1F); |
1994 | 1965 | |
1995 | 1966 | // Invalid ramsel, return. |
1996 | 1967 | if((ramsel & 0x07)!=0x07) |
r22503 | r22504 | |
2011 | 1982 | map_blocks[1] = (ramblocks[ramblock][1].blocksize==0) ? NULL : &ram[ramblocks[ramblock][1].blockbase*1024]; |
2012 | 1983 | map_blocks[2] = (ramblocks[ramblock][2].blocksize==0) ? NULL : &ram[ramblocks[ramblock][2].blockbase*1024]; |
2013 | 1984 | |
2014 | | //if(LOG_RAM) logerror("\n\nmcu_reg080=%02X, ramblock=%d, map_blocks[0]=%X, map_blocks[1]=%X, map_blocks[2]=%X\n",state->m_mcu_reg080,ramblock,(int)map_blocks[0],(int)map_blocks[1],(int)map_blocks[2]); |
| 1985 | //if(LOG_RAM) logerror("\n\nmcu_reg080=%02X, ramblock=%d, map_blocks[0]=%X, map_blocks[1]=%X, map_blocks[2]=%X\n",m_mcu_reg080,ramblock,(int)map_blocks[0],(int)map_blocks[1],(int)map_blocks[2]); |
2015 | 1986 | |
2016 | 1987 | for(blockno=0;blockno<8;blockno++) |
2017 | 1988 | { |
r22503 | r22504 | |
2035 | 2006 | { |
2036 | 2007 | map_base=(ramsel==0x07) ? map_blocks[map_blockno] : &map_blocks[map_blockno][block_ofs*1024]; |
2037 | 2008 | |
2038 | | state->membank(bank)->set_base(map_base); |
| 2009 | membank(bank)->set_base(map_base); |
2039 | 2010 | space.install_readwrite_bank(memmap[blockno].start, memmap[blockno].end, bank); |
2040 | 2011 | //if(LOG_RAM) logerror(", base=%X\n",(int)map_base); |
2041 | 2012 | } |
r22503 | r22504 | |
2056 | 2027 | { |
2057 | 2028 | m_mcu_reg080=data; |
2058 | 2029 | |
2059 | | nimbus_bank_memory(machine()); |
| 2030 | nimbus_bank_memory(); |
2060 | 2031 | } |
2061 | 2032 | |
2062 | | static void memory_reset(running_machine &machine) |
| 2033 | void rmnimbus_state::memory_reset() |
2063 | 2034 | { |
2064 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2065 | | state->m_mcu_reg080=0x07; |
2066 | | nimbus_bank_memory(machine); |
| 2035 | m_mcu_reg080=0x07; |
| 2036 | nimbus_bank_memory(); |
2067 | 2037 | } |
2068 | 2038 | |
2069 | 2039 | READ16_MEMBER(rmnimbus_state::nimbus_io_r) |
r22503 | r22504 | |
2097 | 2067 | |
2098 | 2068 | */ |
2099 | 2069 | |
2100 | | static void keyboard_reset(running_machine &machine) |
| 2070 | void rmnimbus_state::keyboard_reset() |
2101 | 2071 | { |
2102 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2103 | | memset(state->m_keyboard.keyrows,0xFF,NIMBUS_KEYROWS); |
| 2072 | memset(m_keyboard.keyrows,0xFF,NIMBUS_KEYROWS); |
2104 | 2073 | |
2105 | | // Setup timer to scan state->m_keyboard. |
2106 | | state->m_keyboard.keyscan_timer->adjust(attotime::zero, 0, attotime::from_hz(50)); |
| 2074 | // Setup timer to scan m_keyboard. |
| 2075 | m_keyboard.keyscan_timer->adjust(attotime::zero, 0, attotime::from_hz(50)); |
2107 | 2076 | } |
2108 | 2077 | |
2109 | | static void queue_scancode(running_machine &machine, UINT8 scancode) |
| 2078 | void rmnimbus_state::queue_scancode(UINT8 scancode) |
2110 | 2079 | { |
2111 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2112 | | state->m_keyboard.queue[state->m_keyboard.head] = scancode; |
2113 | | state->m_keyboard.head++; |
2114 | | state->m_keyboard.head %= ARRAY_LENGTH(state->m_keyboard.queue); |
| 2080 | m_keyboard.queue[m_keyboard.head] = scancode; |
| 2081 | m_keyboard.head++; |
| 2082 | m_keyboard.head %= ARRAY_LENGTH(m_keyboard.queue); |
2115 | 2083 | } |
2116 | 2084 | |
2117 | | static int keyboard_queue_read(running_machine &machine) |
| 2085 | int rmnimbus_state::keyboard_queue_read() |
2118 | 2086 | { |
2119 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2120 | 2087 | int data; |
2121 | | if (state->m_keyboard.tail == state->m_keyboard.head) |
| 2088 | if (m_keyboard.tail == m_keyboard.head) |
2122 | 2089 | return -1; |
2123 | 2090 | |
2124 | | data = state->m_keyboard.queue[state->m_keyboard.tail]; |
| 2091 | data = m_keyboard.queue[m_keyboard.tail]; |
2125 | 2092 | |
2126 | 2093 | if (LOG_KEYBOARD) |
2127 | 2094 | logerror("keyboard_queue_read(): Keyboard Read 0x%02x\n",data); |
2128 | 2095 | |
2129 | | state->m_keyboard.tail++; |
2130 | | state->m_keyboard.tail %= ARRAY_LENGTH(state->m_keyboard.queue); |
| 2096 | m_keyboard.tail++; |
| 2097 | m_keyboard.tail %= ARRAY_LENGTH(m_keyboard.queue); |
2131 | 2098 | return data; |
2132 | 2099 | } |
2133 | 2100 | |
2134 | | static void scan_keyboard(running_machine &machine) |
2135 | | |
| 2101 | void rmnimbus_state::scan_keyboard() |
2136 | 2102 | { |
2137 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2138 | 2103 | UINT8 keyrow; |
2139 | 2104 | UINT8 row; |
2140 | 2105 | UINT8 bitno; |
r22503 | r22504 | |
2147 | 2112 | |
2148 | 2113 | for(row=0;row<NIMBUS_KEYROWS;row++) |
2149 | 2114 | { |
2150 | | keyrow=machine.root_device().ioport(keynames[row])->read(); |
| 2115 | keyrow=machine().root_device().ioport(keynames[row])->read(); |
2151 | 2116 | |
2152 | 2117 | for(mask=0x80, bitno=7;mask>0;mask=mask>>1, bitno-=1) |
2153 | 2118 | { |
2154 | | if(!(keyrow & mask) && (state->m_keyboard.keyrows[row] & mask)) |
| 2119 | if(!(keyrow & mask) && (m_keyboard.keyrows[row] & mask)) |
2155 | 2120 | { |
2156 | 2121 | if (LOG_KEYBOARD) logerror("keypress %02X\n",(row<<3)+bitno); |
2157 | | queue_scancode(machine, (row<<3)+bitno); |
| 2122 | queue_scancode((row<<3)+bitno); |
2158 | 2123 | } |
2159 | 2124 | |
2160 | | if((keyrow & mask) && !(state->m_keyboard.keyrows[row] & mask)) |
| 2125 | if((keyrow & mask) && !(m_keyboard.keyrows[row] & mask)) |
2161 | 2126 | { |
2162 | 2127 | if (LOG_KEYBOARD) logerror("keyrelease %02X\n",0x80+(row<<3)+bitno); |
2163 | | queue_scancode(machine, 0x80+(row<<3)+bitno); |
| 2128 | queue_scancode(0x80+(row<<3)+bitno); |
2164 | 2129 | } |
2165 | 2130 | } |
2166 | 2131 | |
2167 | | state->m_keyboard.keyrows[row]=keyrow; |
| 2132 | m_keyboard.keyrows[row]=keyrow; |
2168 | 2133 | } |
2169 | 2134 | } |
2170 | 2135 | |
2171 | 2136 | TIMER_CALLBACK_MEMBER(rmnimbus_state::keyscan_callback) |
2172 | 2137 | { |
2173 | | scan_keyboard(machine()); |
| 2138 | scan_keyboard(); |
2174 | 2139 | } |
2175 | 2140 | |
2176 | 2141 | /* |
r22503 | r22504 | |
2192 | 2157 | m_sio_int_state=state; |
2193 | 2158 | |
2194 | 2159 | if(state) |
2195 | | external_int(machine(),0,EXTERNAL_INT_Z80SIO); |
| 2160 | external_int(0,EXTERNAL_INT_Z80SIO); |
2196 | 2161 | } |
2197 | 2162 | } |
2198 | 2163 | |
r22503 | r22504 | |
2213 | 2178 | { |
2214 | 2179 | if(offset==0) |
2215 | 2180 | { |
2216 | | return keyboard_queue_read(machine()); |
| 2181 | return keyboard_queue_read(); |
2217 | 2182 | } |
2218 | 2183 | else |
2219 | 2184 | return -1; |
r22503 | r22504 | |
2221 | 2186 | |
2222 | 2187 | /* Floppy disk */ |
2223 | 2188 | |
2224 | | static void fdc_reset(running_machine &machine) |
| 2189 | void rmnimbus_state::fdc_reset() |
2225 | 2190 | { |
2226 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2227 | | device_t *fdc = machine.device(FDC_TAG); |
| 2191 | device_t *fdc = machine().device(FDC_TAG); |
2228 | 2192 | |
2229 | | state->m_nimbus_drives.reg400=0; |
2230 | | state->m_nimbus_drives.reg410_in=0; |
2231 | | state->m_nimbus_drives.reg410_out=0; |
2232 | | state->m_nimbus_drives.int_ff=0; |
| 2193 | m_nimbus_drives.reg400=0; |
| 2194 | m_nimbus_drives.reg410_in=0; |
| 2195 | m_nimbus_drives.reg410_out=0; |
| 2196 | m_nimbus_drives.int_ff=0; |
2233 | 2197 | wd17xx_set_pause_time(fdc,FDC_PAUSE); |
2234 | 2198 | } |
2235 | 2199 | |
2236 | | static void set_disk_int(running_machine &machine, int state) |
| 2200 | void rmnimbus_state::set_disk_int(int state) |
2237 | 2201 | { |
2238 | | rmnimbus_state *drvstate = machine.driver_data<rmnimbus_state>(); |
2239 | 2202 | if(LOG_DISK) |
2240 | 2203 | logerror("nimbus_drives_intrq = %d\n",state); |
2241 | 2204 | |
2242 | | if(drvstate->m_iou_reg092 & DISK_INT_ENABLE) |
| 2205 | if(m_iou_reg092 & DISK_INT_ENABLE) |
2243 | 2206 | { |
2244 | | drvstate->m_nimbus_drives.int_ff=state; |
| 2207 | m_nimbus_drives.int_ff=state; |
2245 | 2208 | |
2246 | 2209 | if(state) |
2247 | | external_int(machine,0,EXTERNAL_INT_DISK); |
| 2210 | external_int(0,EXTERNAL_INT_DISK); |
2248 | 2211 | } |
2249 | 2212 | } |
2250 | 2213 | |
2251 | 2214 | WRITE_LINE_MEMBER(rmnimbus_state::nimbus_fdc_intrq_w) |
2252 | 2215 | { |
2253 | | set_disk_int(machine(),state); |
| 2216 | set_disk_int(state); |
2254 | 2217 | } |
2255 | 2218 | |
2256 | 2219 | WRITE_LINE_MEMBER(rmnimbus_state::nimbus_fdc_drq_w) |
r22503 | r22504 | |
2258 | 2221 | if(LOG_DISK) |
2259 | 2222 | logerror("nimbus_drives_drq_w(%d)\n", state); |
2260 | 2223 | |
2261 | | if(state && FDC_DRQ_ENABLED(this)) |
2262 | | drq_callback(machine(),1); |
| 2224 | if(state && FDC_DRQ_ENABLED()) |
| 2225 | drq_callback(1); |
2263 | 2226 | } |
2264 | 2227 | |
2265 | | static UINT8 fdc_driveno(UINT8 drivesel) |
| 2228 | UINT8 rmnimbus_state::fdc_driveno(UINT8 drivesel) |
2266 | 2229 | { |
2267 | 2230 | switch (drivesel) |
2268 | 2231 | { |
r22503 | r22504 | |
2297 | 2260 | device_t *fdc = machine().device(FDC_TAG); |
2298 | 2261 | |
2299 | 2262 | int pc=space.device().safe_pc(); |
2300 | | rmnimbus_state *state = machine().driver_data<rmnimbus_state>(); |
2301 | 2263 | device_t *drive = machine().device(nimbus_wd17xx_interface.floppy_drive_tags[FDC_DRIVE()]); |
2302 | 2264 | |
2303 | 2265 | switch(offset*2) |
r22503 | r22504 | |
2326 | 2288 | break; |
2327 | 2289 | case 0x18 : |
2328 | 2290 | result = m_scsibus->scsi_data_r(); |
2329 | | hdc_post_rw(machine()); |
| 2291 | hdc_post_rw(); |
2330 | 2292 | default: |
2331 | 2293 | break; |
2332 | 2294 | } |
r22503 | r22504 | |
2371 | 2333 | if((LOG_DISK_HDD) && (((offset*2)>=0x10) || (offset==0))) |
2372 | 2334 | logerror("Nimbus HDCW at %05X write of %02X to %04X\n",pc,data,(offset*2)+0x400); |
2373 | 2335 | |
2374 | | rmnimbus_state *state = machine().driver_data<rmnimbus_state>(); |
2375 | 2336 | switch(offset*2) |
2376 | 2337 | { |
2377 | 2338 | case 0x00 : |
r22503 | r22504 | |
2384 | 2345 | |
2385 | 2346 | // if we enable hdc drq with a pending condition, act on it |
2386 | 2347 | if((data & HDC_DRQ_MASK) && (~reg400_old & HDC_DRQ_MASK)) |
2387 | | hdc_drq(machine()); |
| 2348 | hdc_drq(); |
2388 | 2349 | |
2389 | 2350 | break; |
2390 | 2351 | case 0x08 : |
r22503 | r22504 | |
2400 | 2361 | wd17xx_data_w(fdc, space, 0, data); |
2401 | 2362 | break; |
2402 | 2363 | case 0x10 : |
2403 | | hdc_ctrl_write(machine(),data); |
| 2364 | hdc_ctrl_write(data); |
2404 | 2365 | break; |
2405 | 2366 | |
2406 | 2367 | case 0x18 : |
2407 | 2368 | m_scsibus->scsi_data_w(data); |
2408 | | hdc_post_rw(machine()); |
| 2369 | hdc_post_rw(); |
2409 | 2370 | break; |
2410 | 2371 | } |
2411 | 2372 | } |
2412 | 2373 | |
2413 | | static void hdc_reset(running_machine &machine) |
| 2374 | void rmnimbus_state::hdc_reset() |
2414 | 2375 | { |
2415 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2416 | 2376 | |
2417 | | state->m_nimbus_drives.reg410_in=0; |
2418 | | state->m_nimbus_drives.reg410_in |= (state->m_scsibus->scsi_req_r() ? 0 : HDC_REQ_MASK); |
2419 | | state->m_nimbus_drives.reg410_in |= (state->m_scsibus->scsi_cd_r() ? 0 : HDC_CD_MASK); |
2420 | | state->m_nimbus_drives.reg410_in |= (state->m_scsibus->scsi_io_r() ? 0 : HDC_IO_MASK); |
2421 | | state->m_nimbus_drives.reg410_in |= (state->m_scsibus->scsi_bsy_r() ? 0 : HDC_BSY_MASK); |
2422 | | state->m_nimbus_drives.reg410_in |= (state->m_scsibus->scsi_msg_r() ? 0 : HDC_MSG_MASK); |
| 2377 | m_nimbus_drives.reg410_in=0; |
| 2378 | m_nimbus_drives.reg410_in |= (m_scsibus->scsi_req_r() ? 0 : HDC_REQ_MASK); |
| 2379 | m_nimbus_drives.reg410_in |= (m_scsibus->scsi_cd_r() ? 0 : HDC_CD_MASK); |
| 2380 | m_nimbus_drives.reg410_in |= (m_scsibus->scsi_io_r() ? 0 : HDC_IO_MASK); |
| 2381 | m_nimbus_drives.reg410_in |= (m_scsibus->scsi_bsy_r() ? 0 : HDC_BSY_MASK); |
| 2382 | m_nimbus_drives.reg410_in |= (m_scsibus->scsi_msg_r() ? 0 : HDC_MSG_MASK); |
2423 | 2383 | |
2424 | | state->m_nimbus_drives.drq_ff=0; |
| 2384 | m_nimbus_drives.drq_ff=0; |
2425 | 2385 | } |
2426 | 2386 | |
2427 | | static void hdc_ctrl_write(running_machine &machine, UINT8 data) |
| 2387 | void rmnimbus_state::hdc_ctrl_write(UINT8 data) |
2428 | 2388 | { |
2429 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2430 | 2389 | |
2431 | 2390 | // If we enable the HDC interupt, and an interrupt is pending, go deal with it. |
2432 | | if(((data & HDC_IRQ_MASK) && (~state->m_nimbus_drives.reg410_out & HDC_IRQ_MASK)) && |
2433 | | ((~state->m_nimbus_drives.reg410_in & HDC_INT_TRIGGER)==HDC_INT_TRIGGER)) |
2434 | | set_disk_int(machine,1); |
| 2391 | if(((data & HDC_IRQ_MASK) && (~m_nimbus_drives.reg410_out & HDC_IRQ_MASK)) && |
| 2392 | ((~m_nimbus_drives.reg410_in & HDC_INT_TRIGGER)==HDC_INT_TRIGGER)) |
| 2393 | set_disk_int(1); |
2435 | 2394 | |
2436 | | state->m_nimbus_drives.reg410_out=data; |
| 2395 | m_nimbus_drives.reg410_out=data; |
2437 | 2396 | |
2438 | | state->m_scsibus->scsi_rst_w((data & HDC_RESET_MASK) ? 1 : 0); |
2439 | | state->m_scsibus->scsi_sel_w((data & HDC_SEL_MASK) ? 1 : 0); |
| 2397 | m_scsibus->scsi_rst_w((data & HDC_RESET_MASK) ? 1 : 0); |
| 2398 | m_scsibus->scsi_sel_w((data & HDC_SEL_MASK) ? 1 : 0); |
2440 | 2399 | } |
2441 | 2400 | |
2442 | | static void hdc_post_rw(running_machine &machine) |
| 2401 | void rmnimbus_state::hdc_post_rw() |
2443 | 2402 | { |
2444 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2445 | 2403 | |
2446 | | if((state->m_nimbus_drives.reg410_in & HDC_REQ_MASK)==0) |
2447 | | state->m_scsibus->scsi_ack_w(1); |
| 2404 | if((m_nimbus_drives.reg410_in & HDC_REQ_MASK)==0) |
| 2405 | m_scsibus->scsi_ack_w(1); |
2448 | 2406 | |
2449 | | state->m_nimbus_drives.drq_ff=0; |
| 2407 | m_nimbus_drives.drq_ff=0; |
2450 | 2408 | } |
2451 | 2409 | |
2452 | | static void hdc_drq(running_machine &machine) |
| 2410 | void rmnimbus_state::hdc_drq() |
2453 | 2411 | { |
2454 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2455 | | if(HDC_DRQ_ENABLED() && state->m_nimbus_drives.drq_ff) |
| 2412 | if(HDC_DRQ_ENABLED() && m_nimbus_drives.drq_ff) |
2456 | 2413 | { |
2457 | | drq_callback(machine,1); |
| 2414 | drq_callback(1); |
2458 | 2415 | } |
2459 | 2416 | } |
2460 | 2417 | |
r22503 | r22504 | |
2496 | 2453 | |
2497 | 2454 | |
2498 | 2455 | if(HDC_IRQ_ENABLED() && ((~m_nimbus_drives.reg410_in & HDC_INT_TRIGGER)==HDC_INT_TRIGGER)) |
2499 | | set_disk_int(machine(),1); |
| 2456 | set_disk_int(1); |
2500 | 2457 | else |
2501 | | set_disk_int(machine(),0); |
| 2458 | set_disk_int(0); |
2502 | 2459 | |
2503 | 2460 | switch( mask ) |
2504 | 2461 | { |
r22503 | r22504 | |
2508 | 2465 | if(((m_nimbus_drives.reg410_in & HDC_CD_MASK)==HDC_CD_MASK) && (last!=0)) |
2509 | 2466 | { |
2510 | 2467 | m_nimbus_drives.drq_ff=1; |
2511 | | hdc_drq(machine()); |
| 2468 | hdc_drq(); |
2512 | 2469 | } |
2513 | 2470 | } |
2514 | 2471 | else |
r22503 | r22504 | |
2528 | 2485 | |
2529 | 2486 | /* 8031/8051 Peripheral controler 80186 side */ |
2530 | 2487 | |
2531 | | static void pc8031_reset(running_machine &machine) |
| 2488 | void rmnimbus_state::pc8031_reset() |
2532 | 2489 | { |
2533 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2534 | | device_t *er59256 = machine.device(ER59256_TAG); |
| 2490 | device_t *er59256 = machine().device(ER59256_TAG); |
2535 | 2491 | |
2536 | 2492 | logerror("peripheral controler reset\n"); |
2537 | 2493 | |
2538 | | memset(&state->m_ipc_interface,0,sizeof(state->m_ipc_interface)); |
| 2494 | memset(&m_ipc_interface,0,sizeof(m_ipc_interface)); |
2539 | 2495 | |
2540 | 2496 | if(!er59256_data_loaded(er59256)) |
2541 | 2497 | er59256_preload_rom(er59256,def_config,ARRAY_LENGTH(def_config)); |
r22503 | r22504 | |
2543 | 2499 | |
2544 | 2500 | |
2545 | 2501 | #if 0 |
2546 | | static void ipc_dumpregs() |
| 2502 | void rmnimbus_state::ipc_dumpregs() |
2547 | 2503 | { |
2548 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2549 | 2504 | logerror("in_data=%02X, in_status=%02X, out_data=%02X, out_status=%02X\n", |
2550 | | state->m_ipc_interface.ipc_in, state->m_ipc_interface.status_in, |
2551 | | state->m_ipc_interface.ipc_out, state->m_ipc_interface.status_out); |
| 2505 | m_ipc_interface.ipc_in, m_ipc_interface.status_in, |
| 2506 | m_ipc_interface.ipc_out, m_ipc_interface.status_out); |
2552 | 2507 | |
2553 | 2508 | } |
2554 | 2509 | #endif |
r22503 | r22504 | |
2620 | 2575 | } |
2621 | 2576 | |
2622 | 2577 | if(((offset==2) || (offset==3)) && (m_iou_reg092 & PC8031_INT_ENABLE)) |
2623 | | external_int(machine(),0,EXTERNAL_INT_PC8031_8C); |
| 2578 | external_int(0,EXTERNAL_INT_PC8031_8C); |
2624 | 2579 | |
2625 | 2580 | if(LOG_PC8031) |
2626 | 2581 | logerror("8031: PCIOR %04X read of %04X returns %02X\n",pc,offset,result); |
r22503 | r22504 | |
2654 | 2609 | m_ipc_interface.status_out &= ~IPC_OUT_ADDR; |
2655 | 2610 | m_ipc_interface.status_in |= IPC_IN_READ_PEND; |
2656 | 2611 | if(m_iou_reg092 & PC8031_INT_ENABLE) |
2657 | | external_int(machine(),0,EXTERNAL_INT_PC8031_8F); |
| 2612 | external_int(0,EXTERNAL_INT_PC8031_8F); |
2658 | 2613 | break; |
2659 | 2614 | |
2660 | 2615 | case 0x03 : m_ipc_interface.ipc_out=data; |
r22503 | r22504 | |
2662 | 2617 | m_ipc_interface.status_out |= IPC_OUT_ADDR; |
2663 | 2618 | m_ipc_interface.status_in |= IPC_IN_READ_PEND; |
2664 | 2619 | if(m_iou_reg092 & PC8031_INT_ENABLE) |
2665 | | external_int(machine(),0,EXTERNAL_INT_PC8031_8E); |
| 2620 | external_int(0,EXTERNAL_INT_PC8031_8E); |
2666 | 2621 | break; |
2667 | 2622 | } |
2668 | 2623 | } |
r22503 | r22504 | |
2732 | 2687 | } |
2733 | 2688 | } |
2734 | 2689 | |
2735 | | static void iou_reset(running_machine &machine) |
| 2690 | void rmnimbus_state::iou_reset() |
2736 | 2691 | { |
2737 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2738 | | state->m_iou_reg092=0x00; |
| 2692 | m_iou_reg092=0x00; |
2739 | 2693 | } |
2740 | 2694 | |
2741 | 2695 | /* |
r22503 | r22504 | |
2752 | 2706 | |
2753 | 2707 | */ |
2754 | 2708 | |
2755 | | static void rmni_sound_reset(running_machine &machine) |
| 2709 | void rmnimbus_state::rmni_sound_reset() |
2756 | 2710 | { |
2757 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
2758 | | //device_t *ay8910 = machine.device(AY8910_TAG); |
2759 | | device_t *msm5205 = machine.device(MSM5205_TAG); |
| 2711 | //device_t *ay8910 = machine().device(AY8910_TAG); |
| 2712 | device_t *msm5205 = machine().device(MSM5205_TAG); |
2760 | 2713 | |
2761 | 2714 | //ay8910_reset_ym(ay8910); |
2762 | 2715 | msm5205_reset_w(msm5205, 1); |
2763 | 2716 | |
2764 | | state->m_last_playmode=MSM5205_S48_4B; |
2765 | | msm5205_playmode_w(msm5205,state->m_last_playmode); |
| 2717 | m_last_playmode=MSM5205_S48_4B; |
| 2718 | msm5205_playmode_w(msm5205,m_last_playmode); |
2766 | 2719 | |
2767 | | state->m_ay8910_a=0; |
| 2720 | m_ay8910_a=0; |
2768 | 2721 | } |
2769 | 2722 | |
2770 | 2723 | READ8_MEMBER(rmnimbus_state::nimbus_sound_ay8910_r) |
r22503 | r22504 | |
2819 | 2772 | { |
2820 | 2773 | rmnimbus_state *state = device->machine().driver_data<rmnimbus_state>(); |
2821 | 2774 | if(state->m_iou_reg092 & MSM5205_INT_ENABLE) |
2822 | | external_int(device->machine(),0,EXTERNAL_INT_MSM5205); |
| 2775 | state->external_int(0,EXTERNAL_INT_MSM5205); |
2823 | 2776 | } |
2824 | 2777 | |
2825 | 2778 | static const int MOUSE_XYA[3][4] = { { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 } }; |
r22503 | r22504 | |
2827 | 2780 | //static const int MOUSE_XYA[4] = { 1, 1, 0, 0 }; |
2828 | 2781 | //static const int MOUSE_XYB[4] = { 0, 1, 1, 0 }; |
2829 | 2782 | |
2830 | | static void mouse_js_reset(running_machine &machine) |
| 2783 | void rmnimbus_state::mouse_js_reset() |
2831 | 2784 | { |
2832 | | rmnimbus_state *drvstate = machine.driver_data<rmnimbus_state>(); |
2833 | | mouse_joy_state *state = &drvstate->m_nimbus_mouse; |
| 2785 | mouse_joy_state *state = &m_nimbus_mouse; |
2834 | 2786 | |
2835 | 2787 | state->m_mouse_px=0; |
2836 | 2788 | state->m_mouse_py=0; |
r22503 | r22504 | |
2851 | 2803 | { |
2852 | 2804 | UINT8 x = 0; |
2853 | 2805 | UINT8 y = 0; |
2854 | | // int pc=machine().device(MAINCPU_TAG)->safe_pc(); |
| 2806 | // int pc=m_maincpu->pc(); |
2855 | 2807 | |
2856 | 2808 | UINT8 intstate_x; |
2857 | 2809 | UINT8 intstate_y; |
r22503 | r22504 | |
2943 | 2895 | { |
2944 | 2896 | xint=mxa ? EXTERNAL_INT_MOUSE_XR : EXTERNAL_INT_MOUSE_XL; |
2945 | 2897 | |
2946 | | external_int(machine(),0,xint); |
| 2898 | external_int(0,xint); |
2947 | 2899 | |
2948 | 2900 | // logerror("Xint:%02X, mxb=%02X\n",xint,mxb); |
2949 | 2901 | } |
r22503 | r22504 | |
2953 | 2905 | { |
2954 | 2906 | yint=myb ? EXTERNAL_INT_MOUSE_YU : EXTERNAL_INT_MOUSE_YD; |
2955 | 2907 | |
2956 | | external_int(machine(),0,yint); |
| 2908 | external_int(0,yint); |
2957 | 2909 | // logerror("Yint:%02X, myb=%02X\n",yint,myb); |
2958 | 2910 | } |
2959 | 2911 | } |
r22503 | r22504 | |
2996 | 2948 | |
2997 | 2949 | */ |
2998 | 2950 | UINT8 result; |
2999 | | //int pc=machine().device(MAINCPU_TAG)->safe_pc(); |
| 2951 | //int pc=m_maincpu->_pc(); |
3000 | 2952 | mouse_joy_state *state = &m_nimbus_mouse; |
3001 | 2953 | |
3002 | 2954 | if (ioport("config")->read() & 0x01) |
r22503 | r22504 | |
3041 | 2993 | WRITE_LINE_MEMBER(rmnimbus_state::nimbus_via_irq_w) |
3042 | 2994 | { |
3043 | 2995 | if(state) |
3044 | | external_int(machine(),VIA_INT,0x00); |
| 2996 | external_int(VIA_INT,0x00); |
3045 | 2997 | } |
3046 | 2998 | |
3047 | 2999 | const via6522_interface nimbus_via = |
trunk/src/mess/video/rmnimbus.c
r22503 | r22504 | |
58 | 58 | #define reg02C 0x16 |
59 | 59 | #define reg02E 0x17 |
60 | 60 | |
61 | | #define FG_COLOUR (state->m_vidregs[reg024]&0x0F) |
62 | | #define BG_COLOUR ((state->m_vidregs[reg024]&0xF0)>>4) |
| 61 | #define FG_COLOUR (m_vidregs[reg024]&0x0F) |
| 62 | #define BG_COLOUR ((m_vidregs[reg024]&0xF0)>>4) |
63 | 63 | |
64 | | #define IS_80COL (state->m_vidregs[reg026]&MASK_4080) |
65 | | #define IS_XOR (state->m_vidregs[reg022]&XOR_MASK) |
| 64 | #define IS_80COL (m_vidregs[reg026]&MASK_4080) |
| 65 | #define IS_XOR (m_vidregs[reg022]&XOR_MASK) |
66 | 66 | |
67 | 67 | |
68 | 68 | |
r22503 | r22504 | |
71 | 71 | #define DEBUG_DB 0x02 |
72 | 72 | #define DEBUG_PIXEL 0x04 |
73 | 73 | |
74 | | #define DEBUG_SET(flags) ((state->m_debug_video & (flags))==(flags)) |
| 74 | #define DEBUG_SET(flags) ((m_debug_video & (flags))==(flags)) |
75 | 75 | |
76 | | static UINT8 get_pixel(rmnimbus_state *state, UINT16 x, UINT16 y); |
77 | | static UINT16 read_pixel_line(rmnimbus_state *state, UINT16 x, UINT16 y, UINT8 width); |
78 | | static UINT16 read_pixel_data(rmnimbus_state *state, UINT16 x, UINT16 y); |
79 | | static UINT16 read_reg_00A(rmnimbus_state *state); |
80 | | |
81 | | static void set_pixel(rmnimbus_state *state, UINT16 x, UINT16 y, UINT8 colour); |
82 | | static void write_pixel_line(rmnimbus_state *state, UINT16 x, UINT16 y, UINT16 data, UINT8 width); |
83 | | static void write_pixel_data(rmnimbus_state *state, UINT16 x, UINT16 y, UINT16 data); |
84 | | static void move_pixel_line(rmnimbus_state *state, UINT16 x, UINT16 y, UINT16 data, UINT8 width); |
85 | | static void write_reg_004(rmnimbus_state *state); |
86 | | static void write_reg_006(rmnimbus_state *state); |
87 | | static void write_reg_010(rmnimbus_state *state); |
88 | | static void write_reg_012(rmnimbus_state *state); |
89 | | static void write_reg_014(rmnimbus_state *state); |
90 | | static void write_reg_016(rmnimbus_state *state); |
91 | | static void write_reg_01A(rmnimbus_state *state); |
92 | | static void write_reg_01C(rmnimbus_state *state); |
93 | | static void write_reg_01E(rmnimbus_state *state); |
94 | | static void write_reg_026(rmnimbus_state *state); |
95 | | static void change_palette(running_machine &machine, UINT8 bank, UINT16 colours, UINT8 regno); |
96 | | |
97 | 76 | static void video_debug(running_machine &machine, int ref, int params, const char *param[]); |
98 | 77 | static void video_regdump(running_machine &machine, int ref, int params, const char *param[]); |
99 | 78 | |
r22503 | r22504 | |
103 | 82 | */ |
104 | 83 | |
105 | 84 | READ16_MEMBER(rmnimbus_state::nimbus_video_io_r) |
106 | | { |
107 | | rmnimbus_state *state = machine().driver_data<rmnimbus_state>(); |
| 85 | { |
108 | 86 | int pc=space.device().safe_pc(); |
109 | 87 | UINT16 result; |
110 | 88 | |
r22503 | r22504 | |
115 | 93 | case reg004 : result=m_vidregs[reg004]; break; |
116 | 94 | case reg006 : result=m_vidregs[reg006]; break; |
117 | 95 | case reg008 : result=m_vidregs[reg008]; break; |
118 | | case reg00A : result=read_reg_00A(state); break; |
| 96 | case reg00A : result=read_reg_00A(); break; |
119 | 97 | case reg00C : result=m_vidregs[reg00C]; break; |
120 | 98 | case reg00E : result=m_vidregs[reg00E]; break; |
121 | 99 | |
r22503 | r22504 | |
145 | 123 | return result; |
146 | 124 | } |
147 | 125 | |
148 | | static UINT8 get_pixel(rmnimbus_state *state, UINT16 x, UINT16 y) |
| 126 | UINT8 rmnimbus_state::get_pixel(UINT16 x, UINT16 y) |
149 | 127 | { |
150 | 128 | UINT8 result = 0; |
151 | 129 | |
152 | 130 | if((x<SCREEN_WIDTH_PIXELS) && (y<SCREEN_HEIGHT_LINES)) |
153 | 131 | { |
154 | 132 | if(IS_80COL) |
155 | | result=state->m_video_mem[x][y]; |
| 133 | result=m_video_mem[x][y]; |
156 | 134 | else |
157 | | result=state->m_video_mem[x*2][y]; |
| 135 | result=m_video_mem[x*2][y]; |
158 | 136 | } |
159 | 137 | |
160 | 138 | return result; |
161 | 139 | } |
162 | 140 | |
163 | | static UINT16 read_pixel_line(rmnimbus_state *state, UINT16 x, UINT16 y, UINT8 width) |
| 141 | UINT16 rmnimbus_state::read_pixel_line(UINT16 x, UINT16 y, UINT8 width) |
164 | 142 | { |
165 | 143 | UINT16 result = 0; |
166 | 144 | UINT16 mask; |
r22503 | r22504 | |
169 | 147 | UINT8 shifts; |
170 | 148 | |
171 | 149 | if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) |
172 | | logerror("read_pixel_line(x=%04X, y=%04X, width=%02X, bpp=%02X, pixel_mask=%02X)\n",x,y,width,state->m_bpp,state->m_pixel_mask); |
| 150 | logerror("read_pixel_line(x=%04X, y=%04X, width=%02X, bpp=%02X, pixel_mask=%02X)\n",x,y,width,m_bpp,m_pixel_mask); |
173 | 151 | |
174 | | shifts=width-state->m_bpp; |
| 152 | shifts=width-m_bpp; |
175 | 153 | |
176 | | for(mask=state->m_pixel_mask, pixel_x=(x*(width/state->m_bpp)); mask>0; mask=(mask>>state->m_bpp), pixel_x++) |
| 154 | for(mask=m_pixel_mask, pixel_x=(x*(width/m_bpp)); mask>0; mask=(mask>>m_bpp), pixel_x++) |
177 | 155 | { |
178 | | colour=get_pixel(state,pixel_x,y); |
| 156 | colour=get_pixel(pixel_x,y); |
179 | 157 | |
180 | | if(state->m_bpp==1) |
| 158 | if(m_bpp==1) |
181 | 159 | colour=((colour==FG_COLOUR) ? 1 : 0) << shifts; |
182 | 160 | else |
183 | 161 | colour=colour << shifts; |
184 | 162 | |
185 | 163 | result=(result & ~mask) | colour; |
186 | 164 | |
187 | | shifts-=state->m_bpp; |
| 165 | shifts-=m_bpp; |
188 | 166 | } |
189 | 167 | |
190 | 168 | return result; |
191 | 169 | } |
192 | 170 | |
193 | | static UINT16 read_pixel_data(rmnimbus_state *state, UINT16 x, UINT16 y) |
| 171 | UINT16 rmnimbus_state::read_pixel_data(UINT16 x, UINT16 y) |
194 | 172 | { |
195 | 173 | UINT16 result=0; |
196 | 174 | |
197 | 175 | if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) |
198 | | logerror("read_pixel_data(x=%04X, y=%04X), reg022=%04X\n",x,y,state->m_vidregs[reg022]); |
| 176 | logerror("read_pixel_data(x=%04X, y=%04X), reg022=%04X\n",x,y,m_vidregs[reg022]); |
199 | 177 | |
200 | 178 | if(IS_80COL) |
201 | 179 | { |
202 | | switch (state->m_vidregs[reg022] & WIDTH_MASK) |
| 180 | switch (m_vidregs[reg022] & WIDTH_MASK) |
203 | 181 | { |
204 | 182 | case 0x00 : break; |
205 | 183 | |
r22503 | r22504 | |
213 | 191 | |
214 | 192 | case 0x05 : break; |
215 | 193 | |
216 | | case 0x06 : state->m_bpp=2; state->m_pixel_mask=0xC000; |
217 | | result=read_pixel_line(state,x,y,16); |
| 194 | case 0x06 : m_bpp=2; m_pixel_mask=0xC000; |
| 195 | result=read_pixel_line(x,y,16); |
218 | 196 | break; |
219 | 197 | |
220 | 198 | case 0x07 : break; |
r22503 | r22504 | |
222 | 200 | } |
223 | 201 | else /* 40 Col */ |
224 | 202 | { |
225 | | switch (state->m_vidregs[reg022] & WIDTH_MASK) |
| 203 | switch (m_vidregs[reg022] & WIDTH_MASK) |
226 | 204 | { |
227 | 205 | case 0x00 : break; |
228 | 206 | |
r22503 | r22504 | |
236 | 214 | |
237 | 215 | case 0x05 : break; |
238 | 216 | |
239 | | case 0x06 : state->m_bpp=4; state->m_pixel_mask=0xF000; |
240 | | result=read_pixel_line(state,x,y,16); |
| 217 | case 0x06 : m_bpp=4; m_pixel_mask=0xF000; |
| 218 | result=read_pixel_line(x,y,16); |
241 | 219 | break; |
242 | 220 | |
243 | 221 | case 0x07 : break; |
r22503 | r22504 | |
247 | 225 | return result; |
248 | 226 | } |
249 | 227 | |
250 | | static UINT16 read_reg_00A(rmnimbus_state *state) |
| 228 | UINT16 rmnimbus_state::read_reg_00A() |
251 | 229 | { |
252 | | return read_pixel_data(state, ++state->m_vidregs[reg002],state->m_vidregs[reg00C]); |
| 230 | return read_pixel_data(++m_vidregs[reg002],m_vidregs[reg00C]); |
253 | 231 | } |
254 | 232 | |
255 | 233 | |
r22503 | r22504 | |
264 | 242 | */ |
265 | 243 | |
266 | 244 | WRITE16_MEMBER(rmnimbus_state::nimbus_video_io_w) |
267 | | { |
268 | | rmnimbus_state *state = machine().driver_data<rmnimbus_state>(); |
| 245 | { |
269 | 246 | int pc=space.device().safe_pc(); |
270 | 247 | |
271 | 248 | if(offset<reg028) |
r22503 | r22504 | |
281 | 258 | { |
282 | 259 | case reg000 : m_vidregs[reg000]=data; break; |
283 | 260 | case reg002 : m_vidregs[reg002]=data; break; |
284 | | case reg004 : m_vidregs[reg004]=data; write_reg_004(state); break; |
285 | | case reg006 : m_vidregs[reg006]=data; write_reg_006(state); break; |
| 261 | case reg004 : m_vidregs[reg004]=data; write_reg_004(); break; |
| 262 | case reg006 : m_vidregs[reg006]=data; write_reg_006(); break; |
286 | 263 | case reg008 : m_vidregs[reg008]=data; break; |
287 | 264 | case reg00A : m_vidregs[reg00A]=data; break; |
288 | 265 | case reg00C : m_vidregs[reg00C]=data; break; |
289 | 266 | case reg00E : m_vidregs[reg00E]=data; break; |
290 | 267 | |
291 | | case reg010 : m_vidregs[reg010]=data; write_reg_010(state); break; |
292 | | case reg012 : m_vidregs[reg012]=data; write_reg_012(state); break; |
293 | | case reg014 : m_vidregs[reg014]=data; write_reg_014(state); break; |
294 | | case reg016 : m_vidregs[reg016]=data; write_reg_016(state); break; |
| 268 | case reg010 : m_vidregs[reg010]=data; write_reg_010(); break; |
| 269 | case reg012 : m_vidregs[reg012]=data; write_reg_012(); break; |
| 270 | case reg014 : m_vidregs[reg014]=data; write_reg_014(); break; |
| 271 | case reg016 : m_vidregs[reg016]=data; write_reg_016(); break; |
295 | 272 | case reg018 : m_vidregs[reg018]=data; break; |
296 | | case reg01A : m_vidregs[reg01A]=data; write_reg_01A(state); break; |
297 | | case reg01C : m_vidregs[reg01C]=data; write_reg_01C(state);break; |
298 | | case reg01E : m_vidregs[reg01E]=data; write_reg_01E(state);break; |
| 273 | case reg01A : m_vidregs[reg01A]=data; write_reg_01A(); break; |
| 274 | case reg01C : m_vidregs[reg01C]=data; write_reg_01C();break; |
| 275 | case reg01E : m_vidregs[reg01E]=data; write_reg_01E();break; |
299 | 276 | |
300 | 277 | case reg020 : m_vidregs[reg020]=data; break; |
301 | 278 | case reg022 : m_vidregs[reg022]=data; break; |
302 | 279 | case reg024 : m_vidregs[reg024]=data; break; |
303 | | case reg026 : m_vidregs[reg026]=data; write_reg_026(state); break; |
304 | | case reg028 : change_palette(machine(),0,data,reg028); break; |
305 | | case reg02A : change_palette(machine(),1,data,reg02A); break; |
306 | | case reg02C : change_palette(machine(),2,data,reg02C); break; |
307 | | case reg02E : change_palette(machine(),3,data,reg02E); break; |
| 280 | case reg026 : m_vidregs[reg026]=data; write_reg_026(); break; |
| 281 | case reg028 : change_palette(0,data,reg028); break; |
| 282 | case reg02A : change_palette(1,data,reg02A); break; |
| 283 | case reg02C : change_palette(2,data,reg02C); break; |
| 284 | case reg02E : change_palette(3,data,reg02E); break; |
308 | 285 | |
309 | 286 | default : break; |
310 | 287 | } |
311 | 288 | } |
312 | 289 | |
313 | | static void set_pixel(rmnimbus_state *state, UINT16 x, UINT16 y, UINT8 colour) |
| 290 | void rmnimbus_state::set_pixel(UINT16 x, UINT16 y, UINT8 colour) |
314 | 291 | { |
315 | 292 | if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) |
316 | 293 | logerror("set_pixel(x=%04X, y=%04X, colour=%04X), IS_XOR=%02X\n",x,y,colour,IS_XOR); |
r22503 | r22504 | |
321 | 298 | if((x<SCREEN_WIDTH_PIXELS) && (y<SCREEN_HEIGHT_LINES)) |
322 | 299 | { |
323 | 300 | if(IS_XOR) |
324 | | state->m_video_mem[x][y]^=colour; |
| 301 | m_video_mem[x][y]^=colour; |
325 | 302 | else |
326 | | state->m_video_mem[x][y]=colour; |
| 303 | m_video_mem[x][y]=colour; |
327 | 304 | } |
328 | 305 | } |
329 | 306 | |
330 | | static void set_pixel40(rmnimbus_state *state, UINT16 x, UINT16 y, UINT8 colour) |
| 307 | void rmnimbus_state::set_pixel40( UINT16 x, UINT16 y, UINT8 colour) |
331 | 308 | { |
332 | | set_pixel(state, (x*2),y,colour); |
333 | | set_pixel(state, (x*2)+1,y,colour); |
| 309 | set_pixel((x*2),y,colour); |
| 310 | set_pixel((x*2)+1,y,colour); |
334 | 311 | } |
335 | 312 | |
336 | | static void write_pixel_line(rmnimbus_state *state, UINT16 x, UINT16 y, UINT16 data, UINT8 width) |
| 313 | void rmnimbus_state::write_pixel_line(UINT16 x, UINT16 y, UINT16 data, UINT8 width) |
337 | 314 | { |
338 | 315 | UINT16 mask; |
339 | 316 | UINT16 pixel_x; |
r22503 | r22504 | |
341 | 318 | UINT8 shifts; |
342 | 319 | |
343 | 320 | if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) |
344 | | logerror("write_pixel_line(x=%04X, y=%04X, data=%04X, width=%02X, bpp=%02X, pixel_mask=%02X)\n",x,y,data,width,state->m_bpp,state->m_pixel_mask); |
| 321 | logerror("write_pixel_line(x=%04X, y=%04X, data=%04X, width=%02X, bpp=%02X, pixel_mask=%02X)\n",x,y,data,width,m_bpp,m_pixel_mask); |
345 | 322 | |
346 | | shifts=width-state->m_bpp; |
| 323 | shifts=width-m_bpp; |
347 | 324 | |
348 | | for(mask=state->m_pixel_mask, pixel_x=(x*(width/state->m_bpp)); mask>0; mask=(mask>>state->m_bpp), pixel_x++) |
| 325 | for(mask=m_pixel_mask, pixel_x=(x*(width/m_bpp)); mask>0; mask=(mask>>m_bpp), pixel_x++) |
349 | 326 | { |
350 | | if(state->m_bpp==1) |
| 327 | if(m_bpp==1) |
351 | 328 | colour=(data & mask) ? FG_COLOUR : BG_COLOUR; |
352 | 329 | else |
353 | 330 | colour=(data & mask) >> shifts; |
354 | 331 | |
355 | | //logerror("write_pixel_line: data=%04X, mask=%04X, shifts=%02X, bpp=%02X colour=%02X\n",data,mask,shifts,state->m_bpp,colour); |
| 332 | //logerror("write_pixel_line: data=%04X, mask=%04X, shifts=%02X, bpp=%02X colour=%02X\n",data,mask,shifts,m_bpp,colour); |
356 | 333 | |
357 | 334 | if(IS_80COL) |
358 | | set_pixel(state,pixel_x,y,colour); |
| 335 | set_pixel(pixel_x,y,colour); |
359 | 336 | else |
360 | | set_pixel40(state,pixel_x,y,colour); |
| 337 | set_pixel40(pixel_x,y,colour); |
361 | 338 | |
362 | | shifts-=state->m_bpp; |
| 339 | shifts-=m_bpp; |
363 | 340 | } |
364 | 341 | } |
365 | 342 | |
366 | | static void move_pixel_line(rmnimbus_state *state, UINT16 x, UINT16 y, UINT16 data, UINT8 width) |
| 343 | void rmnimbus_state::move_pixel_line(UINT16 x, UINT16 y, UINT16 data, UINT8 width) |
367 | 344 | { |
368 | 345 | UINT16 pixelno; |
369 | 346 | UINT16 pixelx; |
r22503 | r22504 | |
376 | 353 | pixelx=(x*width)+pixelno; |
377 | 354 | if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) |
378 | 355 | logerror("pixelx=%04X\n",pixelx); |
379 | | state->m_video_mem[pixelx][state->m_vidregs[reg020]]=state->m_video_mem[pixelx][y]; |
| 356 | m_video_mem[pixelx][m_vidregs[reg020]]=m_video_mem[pixelx][y]; |
380 | 357 | } |
381 | 358 | } |
382 | 359 | |
r22503 | r22504 | |
407 | 384 | 1 pixels are xor'ed onto the screen |
408 | 385 | */ |
409 | 386 | |
410 | | static void write_pixel_data(rmnimbus_state *state, UINT16 x, UINT16 y, UINT16 data) |
| 387 | void rmnimbus_state::write_pixel_data(UINT16 x, UINT16 y, UINT16 data) |
411 | 388 | { |
412 | 389 | if(DEBUG_SET(DEBUG_TEXT | DEBUG_PIXEL)) |
413 | | logerror("write_pixel_data(x=%04X, y=%04X, data=%04X), reg022=%04X\n",x,y,data,state->m_vidregs[reg022]); |
| 390 | logerror("write_pixel_data(x=%04X, y=%04X, data=%04X), reg022=%04X\n",x,y,data,m_vidregs[reg022]); |
414 | 391 | |
415 | 392 | if(IS_80COL) |
416 | 393 | { |
417 | | switch (state->m_vidregs[reg022] & WIDTH_MASK) |
| 394 | switch (m_vidregs[reg022] & WIDTH_MASK) |
418 | 395 | { |
419 | | case 0x00 : state->m_bpp=1; state->m_pixel_mask=0x8000; |
420 | | write_pixel_line(state,x,y,data,16); |
| 396 | case 0x00 : m_bpp=1; m_pixel_mask=0x8000; |
| 397 | write_pixel_line(x,y,data,16); |
421 | 398 | break; |
422 | 399 | |
423 | | case 0x01 : state->m_bpp=1; state->m_pixel_mask=0x80; |
424 | | write_pixel_line(state,x,y,data,8); |
| 400 | case 0x01 : m_bpp=1; m_pixel_mask=0x80; |
| 401 | write_pixel_line(x,y,data,8); |
425 | 402 | break; |
426 | 403 | |
427 | | case 0x02 : state->m_bpp=1; state->m_pixel_mask=0x0080; |
428 | | write_pixel_line(state,x,y,data,8); |
| 404 | case 0x02 : m_bpp=1; m_pixel_mask=0x0080; |
| 405 | write_pixel_line(x,y,data,8); |
429 | 406 | break; |
430 | 407 | |
431 | | case 0x03 : state->m_bpp=1; |
432 | | set_pixel(state,x,y,FG_COLOUR); |
| 408 | case 0x03 : m_bpp=1; |
| 409 | set_pixel(x,y,FG_COLOUR); |
433 | 410 | break; |
434 | 411 | |
435 | | case 0x04 : state->m_bpp=2; state->m_pixel_mask=0xC0; |
436 | | write_pixel_line(state,x,y,((data & 0xFF) & ((data & 0xFF00)>>8)),8); |
| 412 | case 0x04 : m_bpp=2; m_pixel_mask=0xC0; |
| 413 | write_pixel_line(x,y,((data & 0xFF) & ((data & 0xFF00)>>8)),8); |
437 | 414 | break; |
438 | 415 | |
439 | | case 0x05 : move_pixel_line(state,x,y,data,16); |
| 416 | case 0x05 : move_pixel_line(x,y,data,16); |
440 | 417 | break; |
441 | 418 | |
442 | | case 0x06 : state->m_bpp=2; state->m_pixel_mask=0xC000; |
443 | | write_pixel_line(state,x,y,data,16); |
| 419 | case 0x06 : m_bpp=2; m_pixel_mask=0xC000; |
| 420 | write_pixel_line(x,y,data,16); |
444 | 421 | break; |
445 | 422 | |
446 | | case 0x07 : state->m_bpp=1; |
447 | | set_pixel(state,x,y,FG_COLOUR); |
| 423 | case 0x07 : m_bpp=1; |
| 424 | set_pixel(x,y,FG_COLOUR); |
448 | 425 | break; |
449 | 426 | } |
450 | 427 | } |
451 | 428 | else /* 40 Col */ |
452 | 429 | { |
453 | | switch (state->m_vidregs[reg022] & WIDTH_MASK) |
| 430 | switch (m_vidregs[reg022] & WIDTH_MASK) |
454 | 431 | { |
455 | | case 0x00 : state->m_bpp=1; state->m_pixel_mask=0x0080; |
456 | | write_pixel_line(state,x,y,data,8); |
| 432 | case 0x00 : m_bpp=1; m_pixel_mask=0x0080; |
| 433 | write_pixel_line(x,y,data,8); |
457 | 434 | break; |
458 | 435 | |
459 | | case 0x01 : state->m_bpp=2; state->m_pixel_mask=0xC0; |
460 | | write_pixel_line(state,x,y,data,8); |
| 436 | case 0x01 : m_bpp=2; m_pixel_mask=0xC0; |
| 437 | write_pixel_line(x,y,data,8); |
461 | 438 | break; |
462 | 439 | |
463 | | case 0x02 : state->m_bpp=1; state->m_pixel_mask=0x0080; |
464 | | set_pixel40(state,x,y,FG_COLOUR); |
| 440 | case 0x02 : m_bpp=1; m_pixel_mask=0x0080; |
| 441 | set_pixel40(x,y,FG_COLOUR); |
465 | 442 | break; |
466 | 443 | |
467 | | case 0x03 : state->m_bpp=1; |
468 | | set_pixel(state,x,y,FG_COLOUR); |
| 444 | case 0x03 : m_bpp=1; |
| 445 | set_pixel(x,y,FG_COLOUR); |
469 | 446 | break; |
470 | 447 | |
471 | | case 0x04 : state->m_bpp=4; state->m_pixel_mask=0xF0; |
472 | | write_pixel_line(state,x,y,((data & 0xFF) & ((data & 0xFF00)>>8)),8); |
| 448 | case 0x04 : m_bpp=4; m_pixel_mask=0xF0; |
| 449 | write_pixel_line(x,y,((data & 0xFF) & ((data & 0xFF00)>>8)),8); |
473 | 450 | break; |
474 | 451 | |
475 | | case 0x05 : move_pixel_line(state,x,y,data,16); |
| 452 | case 0x05 : move_pixel_line(x,y,data,16); |
476 | 453 | break; |
477 | 454 | |
478 | | case 0x06 : state->m_bpp=4; state->m_pixel_mask=0xF000; |
479 | | write_pixel_line(state,x,y,data,16); |
| 455 | case 0x06 : m_bpp=4; m_pixel_mask=0xF000; |
| 456 | write_pixel_line(x,y,data,16); |
480 | 457 | break; |
481 | 458 | |
482 | | case 0x07 : state->m_bpp=1; |
483 | | set_pixel(state,x,y,FG_COLOUR); |
| 459 | case 0x07 : m_bpp=1; |
| 460 | set_pixel(x,y,FG_COLOUR); |
484 | 461 | break; |
485 | 462 | } |
486 | 463 | } |
487 | 464 | } |
488 | 465 | |
489 | | static void write_reg_004(rmnimbus_state *state) |
| 466 | void rmnimbus_state::write_reg_004() |
490 | 467 | { |
491 | | state->m_vidregs[reg002]=0; |
492 | | state->m_vidregs[reg00C]++; |
| 468 | m_vidregs[reg002]=0; |
| 469 | m_vidregs[reg00C]++; |
493 | 470 | } |
494 | 471 | |
495 | | static void write_reg_006(rmnimbus_state *state) |
| 472 | void rmnimbus_state::write_reg_006() |
496 | 473 | { |
497 | | state->m_vidregs[reg00C]++; |
498 | | state->m_vidregs[reg002]=state->m_vidregs[reg006]; |
| 474 | m_vidregs[reg00C]++; |
| 475 | m_vidregs[reg002]=m_vidregs[reg006]; |
499 | 476 | } |
500 | 477 | |
501 | | static void write_reg_010(rmnimbus_state *state) |
| 478 | void rmnimbus_state::write_reg_010() |
502 | 479 | { |
503 | | write_pixel_data(state, state->m_vidregs[reg002],state->m_vidregs[reg00C],state->m_vidregs[reg010]); |
| 480 | write_pixel_data(m_vidregs[reg002],m_vidregs[reg00C],m_vidregs[reg010]); |
504 | 481 | } |
505 | 482 | |
506 | | static void write_reg_012(rmnimbus_state *state) |
| 483 | void rmnimbus_state::write_reg_012() |
507 | 484 | { |
508 | 485 | // I dunno if this is actually what is happening as the regs seem to be write only.... |
509 | 486 | // doing this however does seem to make some programs (worms from the welcom disk) |
510 | 487 | // work correctly. |
511 | | state->m_vidregs[reg002]=state->m_vidregs[reg012]; |
| 488 | m_vidregs[reg002]=m_vidregs[reg012]; |
512 | 489 | |
513 | | write_pixel_data(state, state->m_vidregs[reg012],state->m_vidregs[reg00C],FG_COLOUR); |
| 490 | write_pixel_data(m_vidregs[reg012],m_vidregs[reg00C],FG_COLOUR); |
514 | 491 | } |
515 | 492 | |
516 | | static void write_reg_014(rmnimbus_state *state) |
| 493 | void rmnimbus_state::write_reg_014() |
517 | 494 | { |
518 | | write_pixel_data(state, state->m_vidregs[reg002],state->m_vidregs[reg00C]++,state->m_vidregs[reg014]); |
| 495 | write_pixel_data(m_vidregs[reg002],m_vidregs[reg00C]++,m_vidregs[reg014]); |
519 | 496 | } |
520 | 497 | |
521 | | static void write_reg_016(rmnimbus_state *state) |
| 498 | void rmnimbus_state::write_reg_016() |
522 | 499 | { |
523 | | state->m_vidregs[reg002]=state->m_vidregs[reg016]; |
| 500 | m_vidregs[reg002]=m_vidregs[reg016]; |
524 | 501 | |
525 | | write_pixel_data(state, state->m_vidregs[reg002],state->m_vidregs[reg00C]++,FG_COLOUR); |
| 502 | write_pixel_data(m_vidregs[reg002],m_vidregs[reg00C]++,FG_COLOUR); |
526 | 503 | } |
527 | 504 | |
528 | 505 | |
529 | | static void write_reg_01A(rmnimbus_state *state) |
| 506 | void rmnimbus_state::write_reg_01A() |
530 | 507 | { |
531 | | write_pixel_data(state, ++state->m_vidregs[reg002],state->m_vidregs[reg00C],state->m_vidregs[reg01A]); |
| 508 | write_pixel_data(++m_vidregs[reg002],m_vidregs[reg00C],m_vidregs[reg01A]); |
532 | 509 | } |
533 | 510 | |
534 | | static void write_reg_01C(rmnimbus_state *state) |
| 511 | void rmnimbus_state::write_reg_01C() |
535 | 512 | { |
536 | 513 | // I dunno if this is actually what is happening as the regs seem to be write only.... |
537 | 514 | // doing this however does seem to make some programs (welcome from the welcom disk, |
538 | 515 | // and others using the standard RM box menus) work correctly. |
539 | | state->m_vidregs[reg00C]=state->m_vidregs[reg01C]; |
| 516 | m_vidregs[reg00C]=m_vidregs[reg01C]; |
540 | 517 | |
541 | | write_pixel_data(state, state->m_vidregs[reg002],state->m_vidregs[reg01C],FG_COLOUR); |
| 518 | write_pixel_data(m_vidregs[reg002],m_vidregs[reg01C],FG_COLOUR); |
542 | 519 | } |
543 | 520 | |
544 | | static void write_reg_01E(rmnimbus_state *state) |
| 521 | void rmnimbus_state::write_reg_01E() |
545 | 522 | { |
546 | | state->m_vidregs[reg00C]=state->m_vidregs[reg01E]; |
| 523 | m_vidregs[reg00C]=m_vidregs[reg01E]; |
547 | 524 | |
548 | | write_pixel_data(state, ++state->m_vidregs[reg002],state->m_vidregs[reg00C],FG_COLOUR); |
| 525 | write_pixel_data(++m_vidregs[reg002],m_vidregs[reg00C],FG_COLOUR); |
549 | 526 | } |
550 | 527 | |
551 | 528 | /* |
r22503 | r22504 | |
553 | 530 | bit 5 contains the 40/80 column (320/640 pixel) flag. |
554 | 531 | */ |
555 | 532 | |
556 | | static void write_reg_026(rmnimbus_state *state) |
| 533 | void rmnimbus_state::write_reg_026() |
557 | 534 | { |
558 | 535 | if(DEBUG_SET(DEBUG_TEXT)) |
559 | | logerror("reg 026 write, border_colour=%02X\n",state->m_vidregs[reg026] & 0x0F); |
| 536 | logerror("reg 026 write, border_colour=%02X\n",m_vidregs[reg026] & 0x0F); |
560 | 537 | } |
561 | 538 | |
562 | | static void change_palette(running_machine &machine, UINT8 bank, UINT16 colours, UINT8 regno) |
| 539 | void rmnimbus_state::change_palette(UINT8 bank, UINT16 colours, UINT8 regno) |
563 | 540 | { |
564 | | rmnimbus_state *state = machine.driver_data<rmnimbus_state>(); |
565 | 541 | UINT8 colourno; |
566 | 542 | UINT16 mask; |
567 | 543 | UINT8 shifts; |
r22503 | r22504 | |
570 | 546 | UINT8 first; |
571 | 547 | |
572 | 548 | // for the register's data has changed update it, and then update the pallette, else do nothing. |
573 | | if(state->m_vidregs[regno]!=colours) |
574 | | state->m_vidregs[regno]=colours; |
| 549 | if(m_vidregs[regno]!=colours) |
| 550 | m_vidregs[regno]=colours; |
575 | 551 | else |
576 | 552 | return; |
577 | 553 | |
r22503 | r22504 | |
586 | 562 | for(colourno=first; colourno<(first+colourmax); colourno++) |
587 | 563 | { |
588 | 564 | paletteidx=(colours & mask) >> shifts; |
589 | | palette_set_color_rgb(machine, colourno, nimbus_palette[paletteidx][RED], nimbus_palette[paletteidx][GREEN], nimbus_palette[paletteidx][BLUE]); |
| 565 | palette_set_color_rgb(machine(), colourno, nimbus_palette[paletteidx][RED], nimbus_palette[paletteidx][GREEN], nimbus_palette[paletteidx][BLUE]); |
590 | 566 | |
591 | 567 | if(DEBUG_SET(DEBUG_TEXT)) |
592 | 568 | logerror("set colourno[%02X](r,g,b)=(%02X,%02X,%02X), paletteidx=%02X\n",colourno, nimbus_palette[paletteidx][RED], nimbus_palette[paletteidx][GREEN], nimbus_palette[paletteidx][BLUE],paletteidx); |