trunk/src/mess/drivers/gba.c
| r20536 | r20537 | |
| 82 | 82 | } |
| 83 | 83 | } |
| 84 | 84 | |
| 85 | | static void dma_exec(running_machine &machine, FPTR ch); |
| 86 | | |
| 87 | | static void gba_request_irq(running_machine &machine, UINT32 int_type) |
| 85 | void gba_state::request_irq(UINT32 int_type) |
| 88 | 86 | { |
| 89 | | gba_state *state = machine.driver_data<gba_state>(); |
| 90 | | |
| 91 | 87 | // set flag for later recovery |
| 92 | | state->m_IF |= int_type; |
| 88 | m_IF |= int_type; |
| 93 | 89 | |
| 94 | 90 | // is this specific interrupt enabled? |
| 95 | | int_type &= state->m_IE; |
| 91 | int_type &= m_IE; |
| 96 | 92 | if (int_type != 0) |
| 97 | 93 | { |
| 98 | 94 | // master enable? |
| 99 | | if (state->m_IME & 1) |
| 95 | if (m_IME & 1) |
| 100 | 96 | { |
| 101 | | machine.device("maincpu")->execute().set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); |
| 102 | | machine.device("maincpu")->execute().set_input_line(ARM7_IRQ_LINE, CLEAR_LINE); |
| 97 | m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE); |
| 98 | m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE); |
| 103 | 99 | } |
| 104 | 100 | } |
| 105 | 101 | } |
| r20536 | r20537 | |
| 121 | 117 | // IRQ |
| 122 | 118 | if (ctrl & 0x4000) |
| 123 | 119 | { |
| 124 | | gba_request_irq(machine(), ch_int[ch]); |
| 120 | request_irq(ch_int[ch]); |
| 125 | 121 | } |
| 126 | 122 | |
| 127 | 123 | // if we're supposed to repeat, don't clear "active" and then the next vbl/hbl will retrigger us |
| r20536 | r20537 | |
| 147 | 143 | } |
| 148 | 144 | } |
| 149 | 145 | |
| 150 | | static void dma_exec(running_machine &machine, FPTR ch) |
| 146 | void gba_state::dma_exec(FPTR ch) |
| 151 | 147 | { |
| 152 | | int i, cnt; |
| 153 | | int ctrl; |
| 154 | | int srcadd, dstadd; |
| 155 | | UINT32 src, dst; |
| 156 | | address_space &space = machine.device("maincpu")->memory().space(AS_PROGRAM); |
| 157 | | gba_state *state = machine.driver_data<gba_state>(); |
| 148 | address_space &space = ((device_t*)m_maincpu)->memory().space(AS_PROGRAM); |
| 149 | UINT32 src = m_dma_src[ch]; |
| 150 | UINT32 dst = m_dma_dst[ch]; |
| 151 | int ctrl = m_dma_regs[(ch*3)+2] >> 16; |
| 152 | int srcadd = m_dma_srcadd[ch]; |
| 153 | int dstadd = m_dma_dstadd[ch]; |
| 158 | 154 | |
| 159 | | src = state->m_dma_src[ch]; |
| 160 | | dst = state->m_dma_dst[ch]; |
| 161 | | ctrl = state->m_dma_regs[(ch*3)+2] >> 16; |
| 162 | | srcadd = state->m_dma_srcadd[ch]; |
| 163 | | dstadd = state->m_dma_dstadd[ch]; |
| 164 | | |
| 165 | | cnt = state->m_dma_cnt[ch]; |
| 155 | int cnt = m_dma_cnt[ch]; |
| 166 | 156 | if (!cnt) |
| 167 | 157 | { |
| 168 | 158 | if (ch == 3) |
| r20536 | r20537 | |
| 198 | 188 | // printf("DMA exec: ch %d from %08x to %08x, mode %04x, count %04x (PC %x) (%s)\n", (int)ch, src, dst, ctrl, cnt, activecpu_get_pc(), ((ctrl>>10) & 1) ? "32" : "16"); |
| 199 | 189 | } |
| 200 | 190 | |
| 201 | | for (i = 0; i < cnt; i++) |
| 191 | for (int i = 0; i < cnt; i++) |
| 202 | 192 | { |
| 203 | 193 | if ((ctrl>>10) & 1) |
| 204 | 194 | { |
| r20536 | r20537 | |
| 272 | 262 | } |
| 273 | 263 | } |
| 274 | 264 | |
| 275 | | state->m_dma_src[ch] = src; |
| 276 | | state->m_dma_dst[ch] = dst; |
| 265 | m_dma_src[ch] = src; |
| 266 | m_dma_dst[ch] = dst; |
| 277 | 267 | |
| 278 | | // printf("settng DMA timer %d for %d cycs (tmr %x)\n", ch, cnt, (UINT32)state->m_dma_timer[ch]); |
| 279 | | // state->m_dma_timer[ch]->adjust(ATTOTIME_IN_CYCLES(0, cnt), ch); |
| 280 | | state->dma_complete(NULL, ch); |
| 268 | // printf("settng DMA timer %d for %d cycs (tmr %x)\n", ch, cnt, (UINT32)m_dma_timer[ch]); |
| 269 | // m_dma_timer[ch]->adjust(ATTOTIME_IN_CYCLES(0, cnt), ch); |
| 270 | dma_complete(NULL, ch); |
| 281 | 271 | } |
| 282 | 272 | |
| 283 | | static void audio_tick(running_machine &machine, int ref) |
| 273 | void gba_state::audio_tick(int ref) |
| 284 | 274 | { |
| 285 | | gba_state *state = machine.driver_data<gba_state>(); |
| 286 | | |
| 287 | | if (!(state->m_SOUNDCNT_X & 0x80)) |
| 275 | if (!(m_SOUNDCNT_X & 0x80)) |
| 288 | 276 | { |
| 289 | 277 | return; |
| 290 | 278 | } |
| 291 | 279 | |
| 292 | 280 | if (!ref) |
| 293 | 281 | { |
| 294 | | if (state->m_fifo_a_ptr != state->m_fifo_a_in) |
| 282 | if (m_fifo_a_ptr != m_fifo_a_in) |
| 295 | 283 | { |
| 296 | | if (state->m_fifo_a_ptr == 17) |
| 284 | if (m_fifo_a_ptr == 17) |
| 297 | 285 | { |
| 298 | | state->m_fifo_a_ptr = 0; |
| 286 | m_fifo_a_ptr = 0; |
| 299 | 287 | } |
| 300 | 288 | |
| 301 | | if (state->m_SOUNDCNT_H & 0x200) |
| 289 | if (m_SOUNDCNT_H & 0x200) |
| 302 | 290 | { |
| 303 | | dac_device *dac = machine.device<dac_device>("direct_a_left"); |
| 304 | | |
| 305 | | dac->write_signed8(state->m_fifo_a[state->m_fifo_a_ptr]^0x80); |
| 291 | m_ladac->write_signed8(m_fifo_a[m_fifo_a_ptr]^0x80); |
| 306 | 292 | } |
| 307 | | if (state->m_SOUNDCNT_H & 0x100) |
| 293 | if (m_SOUNDCNT_H & 0x100) |
| 308 | 294 | { |
| 309 | | dac_device *dac = machine.device<dac_device>("direct_a_right"); |
| 310 | | |
| 311 | | dac->write_signed8(state->m_fifo_a[state->m_fifo_a_ptr]^0x80); |
| 295 | m_radac->write_signed8(m_fifo_a[m_fifo_a_ptr]^0x80); |
| 312 | 296 | } |
| 313 | | state->m_fifo_a_ptr++; |
| 297 | m_fifo_a_ptr++; |
| 314 | 298 | } |
| 315 | 299 | |
| 316 | 300 | // fifo empty? |
| 317 | | if (state->m_fifo_a_ptr == state->m_fifo_a_in) |
| 301 | if (m_fifo_a_ptr == m_fifo_a_in) |
| 318 | 302 | { |
| 319 | 303 | // is a DMA set up to feed us? |
| 320 | | if ((state->m_dma_regs[(1*3)+1] == 0x40000a0) && ((state->m_dma_regs[(1*3)+2] & 0x30000000) == 0x30000000)) |
| 304 | if ((m_dma_regs[(1*3)+1] == 0x40000a0) && ((m_dma_regs[(1*3)+2] & 0x30000000) == 0x30000000)) |
| 321 | 305 | { |
| 322 | 306 | // channel 1 it is |
| 323 | | dma_exec(machine, 1); |
| 307 | dma_exec(1); |
| 324 | 308 | } |
| 325 | | if ((state->m_dma_regs[(2*3)+1] == 0x40000a0) && ((state->m_dma_regs[(2*3)+2] & 0x30000000) == 0x30000000)) |
| 309 | if ((m_dma_regs[(2*3)+1] == 0x40000a0) && ((m_dma_regs[(2*3)+2] & 0x30000000) == 0x30000000)) |
| 326 | 310 | { |
| 327 | 311 | // channel 2 it is |
| 328 | | dma_exec(machine, 2); |
| 312 | dma_exec(2); |
| 329 | 313 | } |
| 330 | 314 | } |
| 331 | 315 | } |
| 332 | 316 | else |
| 333 | 317 | { |
| 334 | | if (state->m_fifo_b_ptr != state->m_fifo_b_in) |
| 318 | if (m_fifo_b_ptr != m_fifo_b_in) |
| 335 | 319 | { |
| 336 | | if (state->m_fifo_b_ptr == 17) |
| 320 | if (m_fifo_b_ptr == 17) |
| 337 | 321 | { |
| 338 | | state->m_fifo_b_ptr = 0; |
| 322 | m_fifo_b_ptr = 0; |
| 339 | 323 | } |
| 340 | 324 | |
| 341 | | if (state->m_SOUNDCNT_H & 0x2000) |
| 325 | if (m_SOUNDCNT_H & 0x2000) |
| 342 | 326 | { |
| 343 | | dac_device *dac = machine.device<dac_device>("direct_b_left"); |
| 344 | | |
| 345 | | dac->write_signed8(state->m_fifo_b[state->m_fifo_b_ptr]^0x80); |
| 327 | m_lbdac->write_signed8(m_fifo_b[m_fifo_b_ptr]^0x80); |
| 346 | 328 | } |
| 347 | | if (state->m_SOUNDCNT_H & 0x1000) |
| 329 | if (m_SOUNDCNT_H & 0x1000) |
| 348 | 330 | { |
| 349 | | dac_device *dac = machine.device<dac_device>("direct_b_right"); |
| 350 | | |
| 351 | | dac->write_signed8(state->m_fifo_b[state->m_fifo_b_ptr]^0x80); |
| 331 | m_rbdac->write_signed8(m_fifo_b[m_fifo_b_ptr]^0x80); |
| 352 | 332 | } |
| 353 | | state->m_fifo_b_ptr++; |
| 333 | m_fifo_b_ptr++; |
| 354 | 334 | } |
| 355 | 335 | |
| 356 | | if (state->m_fifo_b_ptr == state->m_fifo_b_in) |
| 336 | if (m_fifo_b_ptr == m_fifo_b_in) |
| 357 | 337 | { |
| 358 | 338 | // is a DMA set up to feed us? |
| 359 | | if ((state->m_dma_regs[(1*3)+1] == 0x40000a4) && ((state->m_dma_regs[(1*3)+2] & 0x30000000) == 0x30000000)) |
| 339 | if ((m_dma_regs[(1*3)+1] == 0x40000a4) && ((m_dma_regs[(1*3)+2] & 0x30000000) == 0x30000000)) |
| 360 | 340 | { |
| 361 | 341 | // channel 1 it is |
| 362 | | dma_exec(machine, 1); |
| 342 | dma_exec(1); |
| 363 | 343 | } |
| 364 | | if ((state->m_dma_regs[(2*3)+1] == 0x40000a4) && ((state->m_dma_regs[(2*3)+2] & 0x30000000) == 0x30000000)) |
| 344 | if ((m_dma_regs[(2*3)+1] == 0x40000a4) && ((m_dma_regs[(2*3)+2] & 0x30000000) == 0x30000000)) |
| 365 | 345 | { |
| 366 | 346 | // channel 2 it is |
| 367 | | dma_exec(machine, 2); |
| 347 | dma_exec(2); |
| 368 | 348 | } |
| 369 | 349 | } |
| 370 | 350 | } |
| r20536 | r20537 | |
| 399 | 379 | { |
| 400 | 380 | if ((m_SOUNDCNT_H & 0x400) == 0) |
| 401 | 381 | { |
| 402 | | audio_tick(machine(), 0); |
| 382 | audio_tick(0); |
| 403 | 383 | } |
| 404 | 384 | |
| 405 | 385 | if ((m_SOUNDCNT_H & 0x4000) == 0) |
| 406 | 386 | { |
| 407 | | audio_tick(machine(), 1); |
| 387 | audio_tick(1); |
| 408 | 388 | } |
| 409 | 389 | } |
| 410 | 390 | |
| r20536 | r20537 | |
| 412 | 392 | { |
| 413 | 393 | if ((m_SOUNDCNT_H & 0x400) == 0x400) |
| 414 | 394 | { |
| 415 | | audio_tick(machine(), 0); |
| 395 | audio_tick(0); |
| 416 | 396 | } |
| 417 | 397 | |
| 418 | 398 | if ((m_SOUNDCNT_H & 0x4000) == 0x4000) |
| 419 | 399 | { |
| 420 | | audio_tick(machine(), 1); |
| 400 | audio_tick(1); |
| 421 | 401 | } |
| 422 | 402 | } |
| 423 | 403 | |
| r20536 | r20537 | |
| 433 | 413 | m_timer_regs[1] |= m_timer_reload[1]; |
| 434 | 414 | if( ( m_timer_regs[1] & 0x400000 ) && ( m_IME != 0 ) ) |
| 435 | 415 | { |
| 436 | | gba_request_irq( machine(), tmr_ints[1] ); |
| 416 | request_irq(tmr_ints[1]); |
| 437 | 417 | } |
| 438 | 418 | if( ( m_timer_regs[2] & 0x40000 ) ) |
| 439 | 419 | { |
| r20536 | r20537 | |
| 443 | 423 | m_timer_regs[2] |= m_timer_reload[2]; |
| 444 | 424 | if( ( m_timer_regs[2] & 0x400000 ) && ( m_IME != 0 ) ) |
| 445 | 425 | { |
| 446 | | gba_request_irq( machine(), tmr_ints[2] ); |
| 426 | request_irq(tmr_ints[2]); |
| 447 | 427 | } |
| 448 | 428 | if( ( m_timer_regs[3] & 0x40000 ) ) |
| 449 | 429 | { |
| r20536 | r20537 | |
| 453 | 433 | m_timer_regs[3] |= m_timer_reload[3]; |
| 454 | 434 | if( ( m_timer_regs[3] & 0x400000 ) && ( m_IME != 0 ) ) |
| 455 | 435 | { |
| 456 | | gba_request_irq( machine(), tmr_ints[3] ); |
| 436 | request_irq(tmr_ints[3]); |
| 457 | 437 | } |
| 458 | 438 | } |
| 459 | 439 | } |
| r20536 | r20537 | |
| 471 | 451 | m_timer_regs[2] |= m_timer_reload[2]; |
| 472 | 452 | if( ( m_timer_regs[2] & 0x400000 ) && ( m_IME != 0 ) ) |
| 473 | 453 | { |
| 474 | | gba_request_irq( machine(), tmr_ints[2] ); |
| 454 | request_irq(tmr_ints[2]); |
| 475 | 455 | } |
| 476 | 456 | if( ( m_timer_regs[3] & 0x40000 ) ) |
| 477 | 457 | { |
| r20536 | r20537 | |
| 481 | 461 | m_timer_regs[3] |= m_timer_reload[3]; |
| 482 | 462 | if( ( m_timer_regs[3] & 0x400000 ) && ( m_IME != 0 ) ) |
| 483 | 463 | { |
| 484 | | gba_request_irq( machine(), tmr_ints[3] ); |
| 464 | request_irq(tmr_ints[3]); |
| 485 | 465 | } |
| 486 | 466 | } |
| 487 | 467 | } |
| r20536 | r20537 | |
| 497 | 477 | m_timer_regs[3] |= m_timer_reload[3]; |
| 498 | 478 | if( ( m_timer_regs[3] & 0x400000 ) && ( m_IME != 0 ) ) |
| 499 | 479 | { |
| 500 | | gba_request_irq( machine(), tmr_ints[3] ); |
| 480 | request_irq(tmr_ints[3]); |
| 501 | 481 | } |
| 502 | 482 | } |
| 503 | 483 | } |
| r20536 | r20537 | |
| 507 | 487 | // are we supposed to IRQ? |
| 508 | 488 | if ((m_timer_regs[tmr] & 0x400000) && (m_IME != 0)) |
| 509 | 489 | { |
| 510 | | gba_request_irq(machine(), tmr_ints[tmr]); |
| 490 | request_irq(tmr_ints[tmr]); |
| 511 | 491 | } |
| 512 | 492 | } |
| 513 | 493 | |
| 514 | 494 | TIMER_CALLBACK_MEMBER(gba_state::handle_irq) |
| 515 | 495 | { |
| 516 | | gba_request_irq(machine(), m_IF); |
| 496 | request_irq(m_IF); |
| 517 | 497 | |
| 518 | 498 | m_irq_timer->adjust(attotime::never); |
| 519 | 499 | } |
| r20536 | r20537 | |
| 521 | 501 | READ32_MEMBER(gba_state::gba_io_r) |
| 522 | 502 | { |
| 523 | 503 | UINT32 retval = 0; |
| 524 | | device_t *gb_device = machine().device("custom"); |
| 525 | 504 | |
| 526 | 505 | switch( offset ) |
| 527 | 506 | { |
| r20536 | r20537 | |
| 769 | 748 | } |
| 770 | 749 | break; |
| 771 | 750 | case 0x0060/4: |
| 772 | | retval = gb_sound_r(gb_device, space, 0) | gb_sound_r(gb_device, space, 1)<<16 | gb_sound_r(gb_device, space, 2)<<24; |
| 751 | retval = gb_sound_r(m_gbsound, space, 0) | gb_sound_r(m_gbsound, space, 1)<<16 | gb_sound_r(m_gbsound, space, 2)<<24; |
| 773 | 752 | break; |
| 774 | 753 | case 0x0064/4: |
| 775 | | retval = gb_sound_r(gb_device, space, 3) | gb_sound_r(gb_device, space, 4)<<8; |
| 754 | retval = gb_sound_r(m_gbsound, space, 3) | gb_sound_r(m_gbsound, space, 4)<<8; |
| 776 | 755 | break; |
| 777 | 756 | case 0x0068/4: |
| 778 | | retval = gb_sound_r(gb_device, space, 6) | gb_sound_r(gb_device, space, 7)<<8; |
| 757 | retval = gb_sound_r(m_gbsound, space, 6) | gb_sound_r(m_gbsound, space, 7)<<8; |
| 779 | 758 | break; |
| 780 | 759 | case 0x006c/4: |
| 781 | | retval = gb_sound_r(gb_device, space, 8) | gb_sound_r(gb_device, space, 9)<<8; |
| 760 | retval = gb_sound_r(m_gbsound, space, 8) | gb_sound_r(m_gbsound, space, 9)<<8; |
| 782 | 761 | break; |
| 783 | 762 | case 0x0070/4: |
| 784 | | retval = gb_sound_r(gb_device, space, 0xa) | gb_sound_r(gb_device, space, 0xb)<<16 | gb_sound_r(gb_device, space, 0xc)<<24; |
| 763 | retval = gb_sound_r(m_gbsound, space, 0xa) | gb_sound_r(m_gbsound, space, 0xb)<<16 | gb_sound_r(m_gbsound, space, 0xc)<<24; |
| 785 | 764 | break; |
| 786 | 765 | case 0x0074/4: |
| 787 | | retval = gb_sound_r(gb_device, space, 0xd) | gb_sound_r(gb_device, space, 0xe)<<8; |
| 766 | retval = gb_sound_r(m_gbsound, space, 0xd) | gb_sound_r(m_gbsound, space, 0xe)<<8; |
| 788 | 767 | break; |
| 789 | 768 | case 0x0078/4: |
| 790 | | retval = gb_sound_r(gb_device, space, 0x10) | gb_sound_r(gb_device, space, 0x11)<<8; |
| 769 | retval = gb_sound_r(m_gbsound, space, 0x10) | gb_sound_r(m_gbsound, space, 0x11)<<8; |
| 791 | 770 | break; |
| 792 | 771 | case 0x007c/4: |
| 793 | | retval = gb_sound_r(gb_device, space, 0x12) | gb_sound_r(gb_device, space, 0x13)<<8; |
| 772 | retval = gb_sound_r(m_gbsound, space, 0x12) | gb_sound_r(m_gbsound, space, 0x13)<<8; |
| 794 | 773 | break; |
| 795 | 774 | case 0x0080/4: |
| 796 | | retval = gb_sound_r(gb_device, space, 0x14) | gb_sound_r(gb_device, space, 0x15)<<8; |
| 775 | retval = gb_sound_r(m_gbsound, space, 0x14) | gb_sound_r(m_gbsound, space, 0x15)<<8; |
| 797 | 776 | if( (mem_mask) & 0xffff0000 ) |
| 798 | 777 | { |
| 799 | 778 | verboselog(machine(), 2, "GBA IO Register Read: SOUNDCNT_H (%08x) = %04x\n", 0x04000000 + ( offset << 2 ) + 2, m_SOUNDCNT_H ); |
| r20536 | r20537 | |
| 801 | 780 | } |
| 802 | 781 | break; |
| 803 | 782 | case 0x0084/4: |
| 804 | | retval = gb_sound_r(gb_device, space, 0x16); |
| 783 | retval = gb_sound_r(m_gbsound, space, 0x16); |
| 805 | 784 | break; |
| 806 | 785 | case 0x0088/4: |
| 807 | 786 | if( (mem_mask) & 0x0000ffff ) |
| r20536 | r20537 | |
| 815 | 794 | } |
| 816 | 795 | break; |
| 817 | 796 | case 0x0090/4: |
| 818 | | retval = gb_wave_r(gb_device, space, 0) | gb_wave_r(gb_device, space, 1)<<8 | gb_wave_r(gb_device, space, 2)<<16 | gb_wave_r(gb_device, space, 3)<<24; |
| 797 | retval = gb_wave_r(m_gbsound, space, 0) | gb_wave_r(m_gbsound, space, 1)<<8 | gb_wave_r(m_gbsound, space, 2)<<16 | gb_wave_r(m_gbsound, space, 3)<<24; |
| 819 | 798 | break; |
| 820 | 799 | case 0x0094/4: |
| 821 | | retval = gb_wave_r(gb_device, space, 4) | gb_wave_r(gb_device, space, 5)<<8 | gb_wave_r(gb_device, space, 6)<<16 | gb_wave_r(gb_device, space, 7)<<24; |
| 800 | retval = gb_wave_r(m_gbsound, space, 4) | gb_wave_r(m_gbsound, space, 5)<<8 | gb_wave_r(m_gbsound, space, 6)<<16 | gb_wave_r(m_gbsound, space, 7)<<24; |
| 822 | 801 | break; |
| 823 | 802 | case 0x0098/4: |
| 824 | | retval = gb_wave_r(gb_device, space, 8) | gb_wave_r(gb_device, space, 9)<<8 | gb_wave_r(gb_device, space, 10)<<16 | gb_wave_r(gb_device, space, 11)<<24; |
| 803 | retval = gb_wave_r(m_gbsound, space, 8) | gb_wave_r(m_gbsound, space, 9)<<8 | gb_wave_r(m_gbsound, space, 10)<<16 | gb_wave_r(m_gbsound, space, 11)<<24; |
| 825 | 804 | break; |
| 826 | 805 | case 0x009c/4: |
| 827 | | retval = gb_wave_r(gb_device, space, 12) | gb_wave_r(gb_device, space, 13)<<8 | gb_wave_r(gb_device, space, 14)<<16 | gb_wave_r(gb_device, space, 15)<<24; |
| 806 | retval = gb_wave_r(m_gbsound, space, 12) | gb_wave_r(m_gbsound, space, 13)<<8 | gb_wave_r(m_gbsound, space, 14)<<16 | gb_wave_r(m_gbsound, space, 15)<<24; |
| 828 | 807 | break; |
| 829 | 808 | case 0x00a0/4: |
| 830 | 809 | case 0x00a4/4: |
| r20536 | r20537 | |
| 1050 | 1029 | |
| 1051 | 1030 | WRITE32_MEMBER(gba_state::gba_io_w) |
| 1052 | 1031 | { |
| 1053 | | device_t *gb_device = machine().device("custom"); |
| 1054 | 1032 | switch( offset ) |
| 1055 | 1033 | { |
| 1056 | 1034 | case 0x0000/4: |
| r20536 | r20537 | |
| 1345 | 1323 | case 0x0060/4: |
| 1346 | 1324 | if( (mem_mask) & 0x000000ff ) // SOUNDCNTL |
| 1347 | 1325 | { |
| 1348 | | gb_sound_w(gb_device, space, 0, data); |
| 1326 | gb_sound_w(m_gbsound, space, 0, data); |
| 1349 | 1327 | } |
| 1350 | 1328 | if( (mem_mask) & 0x00ff0000 ) |
| 1351 | 1329 | { |
| 1352 | | gb_sound_w(gb_device, space, 1, data>>16); // SOUND1CNT_H |
| 1330 | gb_sound_w(m_gbsound, space, 1, data>>16); // SOUND1CNT_H |
| 1353 | 1331 | } |
| 1354 | 1332 | if( (mem_mask) & 0xff000000 ) |
| 1355 | 1333 | { |
| 1356 | | gb_sound_w(gb_device, space, 2, data>>24); |
| 1334 | gb_sound_w(m_gbsound, space, 2, data>>24); |
| 1357 | 1335 | } |
| 1358 | 1336 | break; |
| 1359 | 1337 | case 0x0064/4: |
| 1360 | 1338 | if( (mem_mask) & 0x000000ff ) // SOUNDCNTL |
| 1361 | 1339 | { |
| 1362 | | gb_sound_w(gb_device, space, 3, data); |
| 1340 | gb_sound_w(m_gbsound, space, 3, data); |
| 1363 | 1341 | } |
| 1364 | 1342 | if( (mem_mask) & 0x0000ff00 ) |
| 1365 | 1343 | { |
| 1366 | | gb_sound_w(gb_device, space, 4, data>>8); // SOUND1CNT_H |
| 1344 | gb_sound_w(m_gbsound, space, 4, data>>8); // SOUND1CNT_H |
| 1367 | 1345 | } |
| 1368 | 1346 | break; |
| 1369 | 1347 | case 0x0068/4: |
| 1370 | 1348 | if( (mem_mask) & 0x000000ff ) |
| 1371 | 1349 | { |
| 1372 | | gb_sound_w(gb_device, space, 6, data); |
| 1350 | gb_sound_w(m_gbsound, space, 6, data); |
| 1373 | 1351 | } |
| 1374 | 1352 | if( (mem_mask) & 0x0000ff00 ) |
| 1375 | 1353 | { |
| 1376 | | gb_sound_w(gb_device, space, 7, data>>8); |
| 1354 | gb_sound_w(m_gbsound, space, 7, data>>8); |
| 1377 | 1355 | } |
| 1378 | 1356 | break; |
| 1379 | 1357 | case 0x006c/4: |
| 1380 | 1358 | if( (mem_mask) & 0x000000ff ) |
| 1381 | 1359 | { |
| 1382 | | gb_sound_w(gb_device, space, 8, data); |
| 1360 | gb_sound_w(m_gbsound, space, 8, data); |
| 1383 | 1361 | } |
| 1384 | 1362 | if( (mem_mask) & 0x0000ff00 ) |
| 1385 | 1363 | { |
| 1386 | | gb_sound_w(gb_device, space, 9, data>>8); |
| 1364 | gb_sound_w(m_gbsound, space, 9, data>>8); |
| 1387 | 1365 | } |
| 1388 | 1366 | break; |
| 1389 | 1367 | case 0x0070/4: //SND3CNTL and H |
| 1390 | 1368 | if( (mem_mask) & 0x000000ff ) // SOUNDCNTL |
| 1391 | 1369 | { |
| 1392 | | gb_sound_w(gb_device, space, 0xa, data); |
| 1370 | gb_sound_w(m_gbsound, space, 0xa, data); |
| 1393 | 1371 | } |
| 1394 | 1372 | if( (mem_mask) & 0x00ff0000 ) |
| 1395 | 1373 | { |
| 1396 | | gb_sound_w(gb_device, space, 0xb, data>>16); // SOUND1CNT_H |
| 1374 | gb_sound_w(m_gbsound, space, 0xb, data>>16); // SOUND1CNT_H |
| 1397 | 1375 | } |
| 1398 | 1376 | if( (mem_mask) & 0xff000000 ) |
| 1399 | 1377 | { |
| 1400 | | gb_sound_w(gb_device, space, 0xc, data>>24); |
| 1378 | gb_sound_w(m_gbsound, space, 0xc, data>>24); |
| 1401 | 1379 | } |
| 1402 | 1380 | break; |
| 1403 | 1381 | case 0x0074/4: |
| 1404 | 1382 | if( (mem_mask) & 0x000000ff ) |
| 1405 | 1383 | { |
| 1406 | | gb_sound_w(gb_device, space, 0xd, data); |
| 1384 | gb_sound_w(m_gbsound, space, 0xd, data); |
| 1407 | 1385 | } |
| 1408 | 1386 | if( (mem_mask) & 0x0000ff00 ) |
| 1409 | 1387 | { |
| 1410 | | gb_sound_w(gb_device, space, 0xe, data>>8); |
| 1388 | gb_sound_w(m_gbsound, space, 0xe, data>>8); |
| 1411 | 1389 | } |
| 1412 | 1390 | break; |
| 1413 | 1391 | case 0x0078/4: |
| 1414 | 1392 | if( (mem_mask) & 0x000000ff ) |
| 1415 | 1393 | { |
| 1416 | | gb_sound_w(gb_device, space, 0x10, data); |
| 1394 | gb_sound_w(m_gbsound, space, 0x10, data); |
| 1417 | 1395 | } |
| 1418 | 1396 | if( (mem_mask) & 0x0000ff00 ) |
| 1419 | 1397 | { |
| 1420 | | gb_sound_w(gb_device, space, 0x11, data>>8); |
| 1398 | gb_sound_w(m_gbsound, space, 0x11, data>>8); |
| 1421 | 1399 | } |
| 1422 | 1400 | break; |
| 1423 | 1401 | case 0x007c/4: |
| 1424 | 1402 | if( (mem_mask) & 0x000000ff ) |
| 1425 | 1403 | { |
| 1426 | | gb_sound_w(gb_device, space, 0x12, data); |
| 1404 | gb_sound_w(m_gbsound, space, 0x12, data); |
| 1427 | 1405 | } |
| 1428 | 1406 | if( (mem_mask) & 0x0000ff00 ) |
| 1429 | 1407 | { |
| 1430 | | gb_sound_w(gb_device, space, 0x13, data>>8); |
| 1408 | gb_sound_w(m_gbsound, space, 0x13, data>>8); |
| 1431 | 1409 | } |
| 1432 | 1410 | break; |
| 1433 | 1411 | case 0x0080/4: |
| 1434 | 1412 | if( (mem_mask) & 0x000000ff ) |
| 1435 | 1413 | { |
| 1436 | | gb_sound_w(gb_device, space, 0x14, data); |
| 1414 | gb_sound_w(m_gbsound, space, 0x14, data); |
| 1437 | 1415 | } |
| 1438 | 1416 | if( (mem_mask) & 0x0000ff00 ) |
| 1439 | 1417 | { |
| 1440 | | gb_sound_w(gb_device, space, 0x15, data>>8); |
| 1418 | gb_sound_w(m_gbsound, space, 0x15, data>>8); |
| 1441 | 1419 | } |
| 1442 | 1420 | |
| 1443 | 1421 | if ((mem_mask) & 0xffff0000) |
| r20536 | r20537 | |
| 1448 | 1426 | // DAC A reset? |
| 1449 | 1427 | if (data & 0x0800) |
| 1450 | 1428 | { |
| 1451 | | dac_device *gb_a_l = machine().device<dac_device>("direct_a_left"); |
| 1452 | | dac_device *gb_a_r = machine().device<dac_device>("direct_a_right"); |
| 1453 | | |
| 1454 | 1429 | m_fifo_a_ptr = 17; |
| 1455 | 1430 | m_fifo_a_in = 17; |
| 1456 | | gb_a_l->write_signed8(0x80); |
| 1457 | | gb_a_r->write_signed8(0x80); |
| 1431 | m_ladac->write_signed8(0x80); |
| 1432 | m_radac->write_signed8(0x80); |
| 1458 | 1433 | } |
| 1459 | 1434 | |
| 1460 | 1435 | // DAC B reset? |
| 1461 | 1436 | if (data & 0x8000) |
| 1462 | 1437 | { |
| 1463 | | dac_device *gb_b_l = machine().device<dac_device>("direct_b_left"); |
| 1464 | | dac_device *gb_b_r = machine().device<dac_device>("direct_b_right"); |
| 1465 | | |
| 1466 | 1438 | m_fifo_b_ptr = 17; |
| 1467 | 1439 | m_fifo_b_in = 17; |
| 1468 | | gb_b_l->write_signed8(0x80); |
| 1469 | | gb_b_r->write_signed8(0x80); |
| 1440 | m_lbdac->write_signed8(0x80); |
| 1441 | m_rbdac->write_signed8(0x80); |
| 1470 | 1442 | } |
| 1471 | 1443 | } |
| 1472 | 1444 | break; |
| 1473 | 1445 | case 0x0084/4: |
| 1474 | 1446 | if( (mem_mask) & 0x000000ff ) |
| 1475 | 1447 | { |
| 1476 | | dac_device *gb_a_l = machine().device<dac_device>("direct_a_left"); |
| 1477 | | dac_device *gb_a_r = machine().device<dac_device>("direct_a_right"); |
| 1478 | | dac_device *gb_b_l = machine().device<dac_device>("direct_b_left"); |
| 1479 | | dac_device *gb_b_r = machine().device<dac_device>("direct_b_right"); |
| 1480 | | |
| 1481 | | gb_sound_w(gb_device, space, 0x16, data); |
| 1448 | gb_sound_w(m_gbsound, space, 0x16, data); |
| 1482 | 1449 | if ((data & 0x80) && !(m_SOUNDCNT_X & 0x80)) |
| 1483 | 1450 | { |
| 1484 | 1451 | m_fifo_a_ptr = m_fifo_a_in = 17; |
| 1485 | 1452 | m_fifo_b_ptr = m_fifo_b_in = 17; |
| 1486 | | gb_a_l->write_signed8(0x80); |
| 1487 | | gb_a_r->write_signed8(0x80); |
| 1488 | | gb_b_l->write_signed8(0x80); |
| 1489 | | gb_b_r->write_signed8(0x80); |
| 1453 | m_ladac->write_signed8(0x80); |
| 1454 | m_radac->write_signed8(0x80); |
| 1455 | m_lbdac->write_signed8(0x80); |
| 1456 | m_rbdac->write_signed8(0x80); |
| 1490 | 1457 | } |
| 1491 | 1458 | m_SOUNDCNT_X = data; |
| 1492 | 1459 | } |
| r20536 | r20537 | |
| 1505 | 1472 | case 0x0090/4: |
| 1506 | 1473 | if( (mem_mask) & 0x000000ff ) |
| 1507 | 1474 | { |
| 1508 | | gb_wave_w(gb_device, space, 0, data); |
| 1475 | gb_wave_w(m_gbsound, space, 0, data); |
| 1509 | 1476 | } |
| 1510 | 1477 | if( (mem_mask) & 0x0000ff00 ) |
| 1511 | 1478 | { |
| 1512 | | gb_wave_w(gb_device, space, 1, data>>8); |
| 1479 | gb_wave_w(m_gbsound, space, 1, data>>8); |
| 1513 | 1480 | } |
| 1514 | 1481 | if( (mem_mask) & 0x00ff0000 ) |
| 1515 | 1482 | { |
| 1516 | | gb_wave_w(gb_device, space, 2, data>>16); |
| 1483 | gb_wave_w(m_gbsound, space, 2, data>>16); |
| 1517 | 1484 | } |
| 1518 | 1485 | if( (mem_mask) & 0xff000000 ) |
| 1519 | 1486 | { |
| 1520 | | gb_wave_w(gb_device, space, 3, data>>24); |
| 1487 | gb_wave_w(m_gbsound, space, 3, data>>24); |
| 1521 | 1488 | } |
| 1522 | 1489 | break; |
| 1523 | 1490 | case 0x0094/4: |
| 1524 | 1491 | if( (mem_mask) & 0x000000ff ) |
| 1525 | 1492 | { |
| 1526 | | gb_wave_w(gb_device, space, 4, data); |
| 1493 | gb_wave_w(m_gbsound, space, 4, data); |
| 1527 | 1494 | } |
| 1528 | 1495 | if( (mem_mask) & 0x0000ff00 ) |
| 1529 | 1496 | { |
| 1530 | | gb_wave_w(gb_device, space, 5, data>>8); |
| 1497 | gb_wave_w(m_gbsound, space, 5, data>>8); |
| 1531 | 1498 | } |
| 1532 | 1499 | if( (mem_mask) & 0x00ff0000 ) |
| 1533 | 1500 | { |
| 1534 | | gb_wave_w(gb_device, space, 6, data>>16); |
| 1501 | gb_wave_w(m_gbsound, space, 6, data>>16); |
| 1535 | 1502 | } |
| 1536 | 1503 | if( (mem_mask) & 0xff000000 ) |
| 1537 | 1504 | { |
| 1538 | | gb_wave_w(gb_device, space, 7, data>>24); |
| 1505 | gb_wave_w(m_gbsound, space, 7, data>>24); |
| 1539 | 1506 | } |
| 1540 | 1507 | break; |
| 1541 | 1508 | case 0x0098/4: |
| 1542 | 1509 | if( (mem_mask) & 0x000000ff ) |
| 1543 | 1510 | { |
| 1544 | | gb_wave_w(gb_device, space, 8, data); |
| 1511 | gb_wave_w(m_gbsound, space, 8, data); |
| 1545 | 1512 | } |
| 1546 | 1513 | if( (mem_mask) & 0x0000ff00 ) |
| 1547 | 1514 | { |
| 1548 | | gb_wave_w(gb_device, space, 9, data>>8); |
| 1515 | gb_wave_w(m_gbsound, space, 9, data>>8); |
| 1549 | 1516 | } |
| 1550 | 1517 | if( (mem_mask) & 0x00ff0000 ) |
| 1551 | 1518 | { |
| 1552 | | gb_wave_w(gb_device, space, 0xa, data>>16); |
| 1519 | gb_wave_w(m_gbsound, space, 0xa, data>>16); |
| 1553 | 1520 | } |
| 1554 | 1521 | if( (mem_mask) & 0xff000000 ) |
| 1555 | 1522 | { |
| 1556 | | gb_wave_w(gb_device, space, 0xb, data>>24); |
| 1523 | gb_wave_w(m_gbsound, space, 0xb, data>>24); |
| 1557 | 1524 | } |
| 1558 | 1525 | break; |
| 1559 | 1526 | case 0x009c/4: |
| 1560 | 1527 | if( (mem_mask) & 0x000000ff ) |
| 1561 | 1528 | { |
| 1562 | | gb_wave_w(gb_device, space, 0xc, data); |
| 1529 | gb_wave_w(m_gbsound, space, 0xc, data); |
| 1563 | 1530 | } |
| 1564 | 1531 | if( (mem_mask) & 0x0000ff00 ) |
| 1565 | 1532 | { |
| 1566 | | gb_wave_w(gb_device, space, 0xd, data>>8); |
| 1533 | gb_wave_w(m_gbsound, space, 0xd, data>>8); |
| 1567 | 1534 | } |
| 1568 | 1535 | if( (mem_mask) & 0x00ff0000 ) |
| 1569 | 1536 | { |
| 1570 | | gb_wave_w(gb_device, space, 0xe, data>>16); |
| 1537 | gb_wave_w(m_gbsound, space, 0xe, data>>16); |
| 1571 | 1538 | } |
| 1572 | 1539 | if( (mem_mask) & 0xff000000 ) |
| 1573 | 1540 | { |
| 1574 | | gb_wave_w(gb_device, space, 0xf, data>>24); |
| 1541 | gb_wave_w(m_gbsound, space, 0xf, data>>24); |
| 1575 | 1542 | } |
| 1576 | 1543 | break; |
| 1577 | 1544 | case 0x00a0/4: |
| r20536 | r20537 | |
| 1642 | 1609 | // immediate start |
| 1643 | 1610 | if ((ctrl & 0x3000) == 0) |
| 1644 | 1611 | { |
| 1645 | | dma_exec(machine(), ch); |
| 1612 | dma_exec(ch); |
| 1646 | 1613 | return; |
| 1647 | 1614 | } |
| 1648 | 1615 | } |
| r20536 | r20537 | |
| 1743 | 1710 | // request interrupt ? |
| 1744 | 1711 | if (data & 0x4000) |
| 1745 | 1712 | { |
| 1746 | | gba_request_irq( machine(), INT_SIO); |
| 1713 | request_irq(INT_SIO); |
| 1747 | 1714 | } |
| 1748 | 1715 | } |
| 1749 | 1716 | } |
| r20536 | r20537 | |
| 1829 | 1796 | #if 0 |
| 1830 | 1797 | if (m_IE & m_IF) |
| 1831 | 1798 | { |
| 1832 | | gba_request_irq(machine(), m_IF); |
| 1799 | request_irq(m_IF); |
| 1833 | 1800 | } |
| 1834 | 1801 | #endif |
| 1835 | 1802 | } |
| r20536 | r20537 | |
| 1841 | 1808 | // if we still have interrupts, yank the IRQ line again |
| 1842 | 1809 | if (m_IF) |
| 1843 | 1810 | { |
| 1844 | | m_irq_timer->adjust(machine().device<cpu_device>("maincpu")->clocks_to_attotime(120)); |
| 1811 | m_irq_timer->adjust(m_maincpu->clocks_to_attotime(120)); |
| 1845 | 1812 | } |
| 1846 | 1813 | } |
| 1847 | 1814 | break; |
| r20536 | r20537 | |
| 1884 | 1851 | m_HALTCNT = data & 0x000000ff; |
| 1885 | 1852 | |
| 1886 | 1853 | // either way, wait for an IRQ |
| 1887 | | machine().device("maincpu")->execute().spin_until_interrupt(); |
| 1854 | m_maincpu->spin_until_interrupt(); |
| 1888 | 1855 | } |
| 1889 | 1856 | } |
| 1890 | 1857 | if( (mem_mask) & 0xffff0000 ) |
| r20536 | r20537 | |
| 1952 | 1919 | |
| 1953 | 1920 | READ32_MEMBER(gba_state::gba_10000000_r) |
| 1954 | 1921 | { |
| 1955 | | UINT32 data, cpsr, pc; |
| 1956 | | cpu_device *cpu = downcast<cpu_device *>(machine().device( "maincpu")); |
| 1957 | | pc = cpu->state_int( ARM7_PC); |
| 1958 | | cpsr = cpu->state_int( ARM7_CPSR); |
| 1922 | UINT32 data; |
| 1923 | UINT32 pc = m_maincpu->state_int( ARM7_PC); |
| 1924 | UINT32 cpsr = m_maincpu->state_int( ARM7_CPSR); |
| 1959 | 1925 | if (T_IS_SET( cpsr)) |
| 1960 | 1926 | { |
| 1961 | 1927 | data = space.read_dword( pc + 8); |
| r20536 | r20537 | |
| 2012 | 1978 | m_DISPSTAT |= DISPSTAT_HBL; |
| 2013 | 1979 | if ((m_DISPSTAT & DISPSTAT_HBL_IRQ_EN ) != 0) |
| 2014 | 1980 | { |
| 2015 | | gba_request_irq(machine(), INT_HBL); |
| 1981 | request_irq(INT_HBL); |
| 2016 | 1982 | } |
| 2017 | 1983 | |
| 2018 | 1984 | for (ch = 0; ch < 4; ch++) |
| r20536 | r20537 | |
| 2022 | 1988 | // HBL-triggered DMA? |
| 2023 | 1989 | if ((ctrl & 0x8000) && ((ctrl & 0x3000) == 0x2000)) |
| 2024 | 1990 | { |
| 2025 | | dma_exec(machine(), ch); |
| 1991 | dma_exec(ch); |
| 2026 | 1992 | } |
| 2027 | 1993 | } |
| 2028 | 1994 | |
| r20536 | r20537 | |
| 2054 | 2020 | m_DISPSTAT |= DISPSTAT_VCNT; |
| 2055 | 2021 | if (m_DISPSTAT & DISPSTAT_VCNT_IRQ_EN) |
| 2056 | 2022 | { |
| 2057 | | gba_request_irq(machine(), INT_VCNT); |
| 2023 | request_irq(INT_VCNT); |
| 2058 | 2024 | } |
| 2059 | 2025 | } |
| 2060 | 2026 | |
| r20536 | r20537 | |
| 2087 | 2053 | |
| 2088 | 2054 | if (m_DISPSTAT & DISPSTAT_VBL_IRQ_EN) |
| 2089 | 2055 | { |
| 2090 | | gba_request_irq(machine(), INT_VBL); |
| 2056 | request_irq(INT_VBL); |
| 2091 | 2057 | } |
| 2092 | 2058 | |
| 2093 | 2059 | for (ch = 0; ch < 4; ch++) |
| r20536 | r20537 | |
| 2097 | 2063 | // VBL-triggered DMA? |
| 2098 | 2064 | if ((ctrl & 0x8000) && ((ctrl & 0x3000) == 0x1000)) |
| 2099 | 2065 | { |
| 2100 | | dma_exec(machine(), ch); |
| 2066 | dma_exec(ch); |
| 2101 | 2067 | } |
| 2102 | 2068 | } |
| 2103 | 2069 | } |
| r20536 | r20537 | |
| 2108 | 2074 | |
| 2109 | 2075 | void gba_state::machine_reset() |
| 2110 | 2076 | { |
| 2111 | | dac_device *gb_a_l = machine().device<dac_device>("direct_a_left"); |
| 2112 | | dac_device *gb_a_r = machine().device<dac_device>("direct_a_right"); |
| 2113 | | dac_device *gb_b_l = machine().device<dac_device>("direct_b_left"); |
| 2114 | | dac_device *gb_b_r = machine().device<dac_device>("direct_b_right"); |
| 2115 | | |
| 2116 | 2077 | //memset(this, 0, sizeof(this)); |
| 2117 | 2078 | m_SOUNDBIAS = 0x0200; |
| 2118 | 2079 | m_eeprom_state = EEP_IDLE; |
| r20536 | r20537 | |
| 2146 | 2107 | m_fifo_a_in = m_fifo_b_in = 17; |
| 2147 | 2108 | |
| 2148 | 2109 | // and clear the DACs |
| 2149 | | gb_a_l->write_signed8(0x80); |
| 2150 | | gb_a_r->write_signed8(0x80); |
| 2151 | | gb_b_l->write_signed8(0x80); |
| 2152 | | gb_b_r->write_signed8(0x80); |
| 2110 | m_ladac->write_signed8(0x80); |
| 2111 | m_radac->write_signed8(0x80); |
| 2112 | m_lbdac->write_signed8(0x80); |
| 2113 | m_rbdac->write_signed8(0x80); |
| 2153 | 2114 | |
| 2154 | 2115 | if (m_flash_battery_load != 0) |
| 2155 | 2116 | { |
| r20536 | r20537 | |
| 2381 | 2342 | |
| 2382 | 2343 | if (m_eeprom_bits == 0) |
| 2383 | 2344 | { |
| 2384 | | mame_printf_verbose("%08x: EEPROM: %02x to %x\n", machine().device("maincpu")->safe_pc(), m_eep_data, m_eeprom_addr ); |
| 2345 | mame_printf_verbose("%08x: EEPROM: %02x to %x\n", space.device().safe_pc(), m_eep_data, m_eeprom_addr ); |
| 2385 | 2346 | if (m_eeprom_addr >= sizeof( m_gba_eeprom)) |
| 2386 | 2347 | { |
| 2387 | 2348 | fatalerror( "eeprom: invalid address (%x)\n", m_eeprom_addr); |
| r20536 | r20537 | |
| 3192 | 3153 | |
| 3193 | 3154 | DRIVER_INIT_MEMBER(gba_state,gbadv) |
| 3194 | 3155 | { |
| 3195 | | machine().device("maincpu")->memory().space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(gba_state::gba_direct), this)); |
| 3156 | ((device_t*)m_maincpu)->memory().space(AS_PROGRAM).set_direct_update_handler(direct_update_delegate(FUNC(gba_state::gba_direct), this)); |
| 3196 | 3157 | } |
| 3197 | 3158 | |
| 3198 | 3159 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ |