trunk/src/mess/drivers/ng_aes.c
| r19019 | r19020 | |
| 42 | 42 | { |
| 43 | 43 | cdrom_file *cd; |
| 44 | 44 | const cdrom_toc *toc; |
| 45 | | UINT32 current_frame; |
| 46 | 45 | }; |
| 47 | 46 | |
| 48 | 47 | static neocd_t neocd; |
| r19019 | r19020 | |
| 54 | 53 | NEOGEO_BANK_AUDIO_CPU_CART_BANK0, NEOGEO_BANK_AUDIO_CPU_CART_BANK1, NEOGEO_BANK_AUDIO_CPU_CART_BANK2, NEOGEO_BANK_AUDIO_CPU_CART_BANK3 |
| 55 | 54 | }; |
| 56 | 55 | |
| 57 | | // CD-ROM / DMA control registers |
| 58 | | struct neocd_ctrl_t |
| 59 | 56 | |
| 60 | | { |
| 61 | | UINT8 area_sel; |
| 62 | | UINT8 pcm_bank_sel; |
| 63 | | UINT8 spr_bank_sel; |
| 64 | | UINT32 addr_source; // target if in fill mode |
| 65 | | UINT32 addr_target; |
| 66 | | UINT16 fill_word; |
| 67 | | UINT32 word_count; |
| 68 | | UINT16 dma_mode[10]; |
| 69 | | }; |
| 70 | | |
| 71 | 57 | #define CD_FRAMES_MINUTE (60 * 75) |
| 72 | 58 | #define CD_FRAMES_SECOND ( 75) |
| 73 | 59 | #define CD_FRAMES_PREGAP ( 2 * 75) |
| r19019 | r19020 | |
| 274 | 260 | */ |
| 275 | 261 | } |
| 276 | 262 | |
| 277 | | static void SekSetIRQLine(const INT32 line, const INT32 status) |
| 278 | | { |
| 279 | 263 | |
| 280 | | } |
| 281 | | |
| 282 | | |
| 283 | 264 | class ng_aes_state : public neogeo_state |
| 284 | 265 | { |
| 285 | 266 | public: |
| r19019 | r19020 | |
| 344 | 325 | |
| 345 | 326 | DECLARE_CUSTOM_INPUT_MEMBER(get_memcard_status); |
| 346 | 327 | |
| 347 | | TIMER_CALLBACK_MEMBER(display_position_interrupt_callback); |
| 348 | | TIMER_CALLBACK_MEMBER(display_position_vblank_callback); |
| 349 | | TIMER_CALLBACK_MEMBER(vblank_interrupt_callback); |
| 350 | | |
| 351 | 328 | // neoCD |
| 352 | 329 | TIMER_DEVICE_CALLBACK_MEMBER( neocd_access_timer_callback ); |
| 353 | | neocd_ctrl_t m_neocd_ctrl; |
| 354 | 330 | INT32 nIRQAcknowledge; |
| 355 | 331 | UINT16 nff0002; |
| 356 | 332 | UINT16 nff0016; |
| r19019 | r19020 | |
| 411 | 387 | UINT8 NeoCDCommsread(); |
| 412 | 388 | void NeoCDCommsReset(); |
| 413 | 389 | void NeoCDDoDMA(); |
| 414 | | UINT8 neogeoReadByteCDROM(UINT32 sekAddress); |
| 415 | 390 | UINT16 neogeoReadWordCDROM(UINT32 sekAddress); |
| 416 | | void neogeoWriteByteCDROM(UINT32 sekAddress, UINT8 byteValue); |
| 417 | 391 | void neogeoWriteWordCDROM(UINT32 sekAddress, UINT16 wordValue); |
| 418 | | UINT8 neogeoReadByteTransfer(UINT32 sekAddress); |
| 419 | | UINT16 neogeoReadWordTransfer(UINT32 sekAddress); |
| 420 | | void neogeoWriteByteTransfer(UINT32 sekAddress, UINT8 byteValue); |
| 421 | | void neogeoWriteWordTransfer(UINT32 sekAddress, UINT16 wordValue); |
| 392 | UINT8 neogeoReadTransfer(UINT32 sekAddress, int is_byte_transfer); |
| 393 | void neogeoWriteTransfer(UINT32 sekAddress, UINT8 byteValue, int is_byte_transfer); |
| 422 | 394 | void NeoIRQUpdate(UINT16 wordValue); |
| 423 | 395 | void SekWriteWord(UINT32 a, UINT16 d); |
| 424 | 396 | void SekWriteByte(UINT32 a, UINT8 d); |
| r19019 | r19020 | |
| 487 | 459 | //static void set_output_data(running_machine &machine, UINT8 data); |
| 488 | 460 | |
| 489 | 461 | |
| 490 | | /************************************* |
| 491 | | * |
| 492 | | * Main CPU interrupt generation |
| 493 | | * |
| 494 | | *************************************/ |
| 495 | 462 | |
| 496 | | #define IRQ2CTRL_ENABLE (0x10) |
| 497 | | #define IRQ2CTRL_LOAD_RELATIVE (0x20) |
| 498 | | #define IRQ2CTRL_AUTOLOAD_VBLANK (0x40) |
| 499 | | #define IRQ2CTRL_AUTOLOAD_REPEAT (0x80) |
| 500 | | |
| 501 | | |
| 502 | | static void adjust_display_position_interrupt_timer( running_machine &machine ) |
| 503 | | { |
| 504 | | neogeo_state *state = machine.driver_data<neogeo_state>(); |
| 505 | | |
| 506 | | if ((state->m_display_counter + 1) != 0) |
| 507 | | { |
| 508 | | attotime period = (attotime::from_hz(NEOGEO_PIXEL_CLOCK) * (state->m_display_counter + 1)); |
| 509 | | if (LOG_VIDEO_SYSTEM) logerror("adjust_display_position_interrupt_timer current y: %02x current x: %02x target y: %x target x: %x\n", machine.primary_screen->vpos(), machine.primary_screen->hpos(), (state->m_display_counter + 1) / NEOGEO_HTOTAL, (state->m_display_counter + 1) % NEOGEO_HTOTAL); |
| 510 | | |
| 511 | | state->m_display_position_interrupt_timer->adjust(period); |
| 512 | | } |
| 513 | | } |
| 514 | | |
| 515 | | static void update_interrupts( running_machine &machine ) |
| 516 | | { |
| 517 | | neogeo_state *state = machine.driver_data<neogeo_state>(); |
| 518 | | |
| 519 | | if(strcmp((char*)machine.system().name,"aes") != 0) |
| 520 | | { // raster and vblank IRQs are swapped on the NeoCD. |
| 521 | | machine.device("maincpu")->execute().set_input_line(2, state->m_vblank_interrupt_pending ? ASSERT_LINE : CLEAR_LINE); |
| 522 | | machine.device("maincpu")->execute().set_input_line(1, state->m_display_position_interrupt_pending ? ASSERT_LINE : CLEAR_LINE); |
| 523 | | machine.device("maincpu")->execute().set_input_line(3, state->m_irq3_pending ? ASSERT_LINE : CLEAR_LINE); |
| 524 | | } |
| 525 | | else |
| 526 | | { |
| 527 | | machine.device("maincpu")->execute().set_input_line(1, state->m_vblank_interrupt_pending ? ASSERT_LINE : CLEAR_LINE); |
| 528 | | machine.device("maincpu")->execute().set_input_line(2, state->m_display_position_interrupt_pending ? ASSERT_LINE : CLEAR_LINE); |
| 529 | | machine.device("maincpu")->execute().set_input_line(3, state->m_irq3_pending ? ASSERT_LINE : CLEAR_LINE); |
| 530 | | } |
| 531 | | } |
| 532 | | |
| 533 | | |
| 534 | | TIMER_CALLBACK_MEMBER(ng_aes_state::display_position_interrupt_callback) |
| 535 | | { |
| 536 | | |
| 537 | | if (LOG_VIDEO_SYSTEM) logerror("--- Scanline @ %d,%d\n", machine().primary_screen->vpos(), machine().primary_screen->hpos()); |
| 538 | | |
| 539 | | if (m_display_position_interrupt_control & IRQ2CTRL_ENABLE) |
| 540 | | { |
| 541 | | if (LOG_VIDEO_SYSTEM) logerror("*** Scanline interrupt (IRQ2) *** y: %02x x: %02x\n", machine().primary_screen->vpos(), machine().primary_screen->hpos()); |
| 542 | | m_display_position_interrupt_pending = 1; |
| 543 | | |
| 544 | | update_interrupts(machine()); |
| 545 | | } |
| 546 | | |
| 547 | | if (m_display_position_interrupt_control & IRQ2CTRL_AUTOLOAD_REPEAT) |
| 548 | | { |
| 549 | | if (LOG_VIDEO_SYSTEM) logerror("AUTOLOAD_REPEAT "); |
| 550 | | adjust_display_position_interrupt_timer(machine()); |
| 551 | | } |
| 552 | | } |
| 553 | | |
| 554 | | |
| 555 | | TIMER_CALLBACK_MEMBER(ng_aes_state::display_position_vblank_callback) |
| 556 | | { |
| 557 | | |
| 558 | | if (m_display_position_interrupt_control & IRQ2CTRL_AUTOLOAD_VBLANK) |
| 559 | | { |
| 560 | | if (LOG_VIDEO_SYSTEM) logerror("AUTOLOAD_VBLANK "); |
| 561 | | adjust_display_position_interrupt_timer(machine()); |
| 562 | | } |
| 563 | | |
| 564 | | /* set timer for next screen */ |
| 565 | | m_display_position_vblank_timer->adjust(machine().primary_screen->time_until_pos(NEOGEO_VBSTART, NEOGEO_VBLANK_RELOAD_HPOS)); |
| 566 | | } |
| 567 | | |
| 568 | | |
| 569 | | TIMER_CALLBACK_MEMBER(ng_aes_state::vblank_interrupt_callback) |
| 570 | | { |
| 571 | | |
| 572 | | if (LOG_VIDEO_SYSTEM) logerror("+++ VBLANK @ %d,%d\n", machine().primary_screen->vpos(), machine().primary_screen->hpos()); |
| 573 | | |
| 574 | | /* add a timer tick to the pd4990a */ |
| 575 | | upd4990a_addretrace(m_upd4990a); |
| 576 | | |
| 577 | | m_vblank_interrupt_pending = 1; |
| 578 | | |
| 579 | | update_interrupts(machine()); |
| 580 | | |
| 581 | | /* set timer for next screen */ |
| 582 | | m_vblank_interrupt_timer->adjust(machine().primary_screen->time_until_pos(NEOGEO_VBSTART, 0)); |
| 583 | | } |
| 584 | | |
| 585 | | |
| 586 | | static void create_interrupt_timers( running_machine &machine ) |
| 587 | | { |
| 588 | | ng_aes_state *state = machine.driver_data<ng_aes_state>(); |
| 589 | | state->m_display_position_interrupt_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(ng_aes_state::display_position_interrupt_callback),state)); |
| 590 | | state->m_display_position_vblank_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(ng_aes_state::display_position_vblank_callback),state)); |
| 591 | | state->m_vblank_interrupt_timer = machine.scheduler().timer_alloc(timer_expired_delegate(FUNC(ng_aes_state::vblank_interrupt_callback),state)); |
| 592 | | } |
| 593 | | |
| 594 | | |
| 595 | | static void start_interrupt_timers( running_machine &machine ) |
| 596 | | { |
| 597 | | neogeo_state *state = machine.driver_data<neogeo_state>(); |
| 598 | | state->m_vblank_interrupt_timer->adjust(machine.primary_screen->time_until_pos(NEOGEO_VBSTART, 0)); |
| 599 | | state->m_display_position_vblank_timer->adjust(machine.primary_screen->time_until_pos(NEOGEO_VBSTART, NEOGEO_VBLANK_RELOAD_HPOS)); |
| 600 | | } |
| 601 | | |
| 602 | | |
| 603 | | |
| 604 | 463 | /************************************* |
| 605 | 464 | * |
| 606 | 465 | * Audio CPU interrupt generation |
| r19019 | r19020 | |
| 1131 | 990 | |
| 1132 | 991 | |
| 1133 | 992 | |
| 1134 | | UINT8 ng_aes_state::neogeoReadByteTransfer(UINT32 sekAddress) |
| 993 | UINT8 ng_aes_state::neogeoReadTransfer(UINT32 sekAddress, int is_byte_transfer) |
| 1135 | 994 | { |
| 1136 | 995 | // if ((sekAddress & 0x0FFFFF) < 16) |
| 1137 | 996 | // printf(PRINT_NORMAL, _T(" - NGCD port 0x%06X read (byte, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| r19019 | r19020 | |
| 1157 | 1016 | return ~0; |
| 1158 | 1017 | } |
| 1159 | 1018 | |
| 1160 | | UINT16 ng_aes_state::neogeoReadWordTransfer(UINT32 sekAddress) |
| 1161 | | { |
| 1162 | | // if ((sekAddress & 0x0FFFFF) < 16) |
| 1163 | | // bprintf(PRINT_NORMAL, _T(" - Transfer: 0x%06X read (word, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| 1164 | 1019 | |
| 1165 | | switch (nActiveTransferArea) { |
| 1166 | | case 0: // Sprites |
| 1167 | | return *((UINT16*)(NeoSpriteRAM + nSpriteTransferBank + (sekAddress & 0xFFFFF))); |
| 1168 | | break; |
| 1169 | | case 1: // ADPCM |
| 1170 | | return 0xFF00 | YM2610ADPCMAROM[nNeoActiveSlot][nADPCMTransferBank + ((sekAddress & 0x0FFFFF) >> 1)]; |
| 1171 | | break; |
| 1172 | | case 4: // Z80 |
| 1173 | | if ((sekAddress & 0xfffff) >= 0x20000) break; |
| 1174 | | return 0xFF00 | NeoZ80ROMActive[(sekAddress & 0x1FFFF) >> 1]; |
| 1175 | | break; |
| 1176 | | case 5: // Text |
| 1177 | | return 0xFF00 | NeoTextRAM[(sekAddress & 0x3FFFF) >> 1]; |
| 1178 | | break; |
| 1179 | | } |
| 1180 | | |
| 1181 | | return ~0; |
| 1182 | | } |
| 1183 | | |
| 1184 | | void ng_aes_state::neogeoWriteByteTransfer(UINT32 sekAddress, UINT8 byteValue) |
| 1020 | void ng_aes_state::neogeoWriteTransfer(UINT32 sekAddress, UINT8 byteValue, int is_byte_transfer) |
| 1185 | 1021 | { |
| 1186 | 1022 | // if ((sekAddress & 0x0FFFFF) < 16) |
| 1187 | 1023 | // bprintf(PRINT_NORMAL, _T(" - Transfer: 0x%06X -> 0x%02X (PC: 0x%06X)\n"), sekAddress, byteValue, SekGetPC(-1)); |
| r19019 | r19020 | |
| 1191 | 1027 | } |
| 1192 | 1028 | int address; |
| 1193 | 1029 | |
| 1030 | // why, is our DMA broken? |
| 1194 | 1031 | sekAddress ^= 1; |
| 1195 | 1032 | |
| 1196 | 1033 | switch (nActiveTransferArea) { |
| r19019 | r19020 | |
| 1210 | 1047 | break; |
| 1211 | 1048 | case 4: // Z80 |
| 1212 | 1049 | if ((sekAddress & 0xfffff) >= 0x20000) break; |
| 1050 | |
| 1051 | if (!is_byte_transfer) |
| 1052 | { |
| 1053 | if (((sekAddress & 0xfffff) >= 0x20000) || nNeoCDZ80ProgWriteWordCancelHack) break; |
| 1054 | if (sekAddress == 0xe1fdf2) nNeoCDZ80ProgWriteWordCancelHack = 1; |
| 1055 | } |
| 1056 | |
| 1213 | 1057 | NeoZ80ROMActive[(sekAddress & 0x1FFFF) >> 1] = byteValue; |
| 1214 | 1058 | break; |
| 1215 | 1059 | case 5: // Text |
| r19019 | r19020 | |
| 1219 | 1063 | } |
| 1220 | 1064 | } |
| 1221 | 1065 | |
| 1222 | | void ng_aes_state::neogeoWriteWordTransfer(UINT32 sekAddress, UINT16 wordValue) |
| 1223 | | { |
| 1224 | | // if ((sekAddress & 0x0FFFFF) < 16) |
| 1225 | | // bprintf(PRINT_NORMAL, _T(" - Transfer: 0x%06X -> 0x%04X (PC: 0x%06X)\n"), sekAddress, wordValue, SekGetPC(-1)); |
| 1226 | 1066 | |
| 1227 | | if (!nTransferWriteEnable) { |
| 1228 | | // return; |
| 1229 | | } |
| 1230 | | //int address; |
| 1231 | 1067 | |
| 1232 | | switch (nActiveTransferArea) { |
| 1233 | | case 0: // Sprites |
| 1234 | | neogeoWriteByteTransfer(sekAddress+0, wordValue>>8); |
| 1235 | | neogeoWriteByteTransfer(sekAddress+1, wordValue&0xff); |
| 1068 | UINT16 ng_aes_state::neogeoReadWordCDROM(UINT32 sekAddress) |
| 1069 | { |
| 1070 | // bprintf(PRINT_NORMAL, _T(" - CDROM: 0x%06X read (word, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| 1236 | 1071 | |
| 1237 | | //address = (nSpriteTransferBank + (sekAddress & 0x0FFFFF)); |
| 1238 | | //NeoSpriteRAM[(address+0)] = (wordValue&0x00ff)>>0; |
| 1239 | | //NeoSpriteRAM[address+1] = (wordValue&0xff00)>>8; |
| 1240 | | // *((UINT16*)(NeoSpriteRAM + nSpriteTransferBank + (sekAddress & 0xFFFFF))) = wordValue; |
| 1241 | | // NeoCDOBJBankUpdate[nSpriteTransferBank >> 20] = true; |
| 1242 | | break; |
| 1243 | | case 1: // ADPCM |
| 1244 | | YM2610ADPCMAROM[nNeoActiveSlot][nADPCMTransferBank + ((sekAddress & 0x0FFFFF) >> 1)] = wordValue; |
| 1245 | | break; |
| 1246 | | case 4: // Z80 |
| 1247 | | // The games that write here, seem to write crap, however the BIOS writes the Z80 code here, and not in the byte area |
| 1248 | | // So basically, we are allowing writes to here, until the BIOS has finished writing the program, then not allowing any further writes |
| 1249 | | if (((sekAddress & 0xfffff) >= 0x20000) || nNeoCDZ80ProgWriteWordCancelHack) break; |
| 1250 | | if (sekAddress == 0xe1fdf2) nNeoCDZ80ProgWriteWordCancelHack = 1; |
| 1251 | | NeoZ80ROMActive[(sekAddress & 0x1FFFF) >> 1] = wordValue; |
| 1252 | | break; |
| 1253 | | case 5: // Text |
| 1254 | | NeoTextRAM[(sekAddress & 0x3FFFF) >> 1] = wordValue; |
| 1255 | | // NeoUpdateTextOne((sekAddress & 0x3FFFF) >> 1, wordValue); |
| 1256 | | break; |
| 1257 | | } |
| 1258 | | } |
| 1259 | 1072 | |
| 1260 | | |
| 1261 | | UINT8 ng_aes_state::neogeoReadByteCDROM(UINT32 sekAddress) |
| 1262 | | { |
| 1263 | | // bprintf(PRINT_NORMAL, _T(" - CDROM: 0x%06X read (byte, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| 1264 | | |
| 1265 | 1073 | switch (sekAddress & 0xFFFF) { |
| 1266 | 1074 | |
| 1267 | | case 0x0017: |
| 1075 | case 0x0016: |
| 1268 | 1076 | return nff0016; |
| 1269 | 1077 | |
| 1270 | 1078 | // LC8951 registers |
| 1271 | | case 0x0101: |
| 1079 | case 0x0100: |
| 1272 | 1080 | // bprintf(PRINT_NORMAL, _T(" - LC8951 register read (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1273 | 1081 | return nLC8951Register; |
| 1274 | | case 0x0103: { |
| 1082 | case 0x0102: { |
| 1275 | 1083 | // bprintf(PRINT_NORMAL, _T(" - LC8951 register 0x%X read (PC: 0x%06X)\n"), nLC8951Register, SekGetPC(-1)); |
| 1276 | 1084 | |
| 1277 | 1085 | INT32 reg = LC8951RegistersR[nLC8951Register]; |
| r19019 | r19020 | |
| 1292 | 1100 | } |
| 1293 | 1101 | |
| 1294 | 1102 | // CD mechanism communication |
| 1295 | | case 0x0161: |
| 1296 | | return NeoCDCommsread(); |
| 1103 | case 0x0160: |
| 1104 | return NeoCDCommsread(); |
| 1297 | 1105 | |
| 1298 | | default: { |
| 1299 | | // bprintf(PRINT_NORMAL, _T(" - NGCD port 0x%06X read (byte, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| 1300 | | } |
| 1106 | case 0x011C: // region |
| 1107 | return ~((0x10 | (NeoSystem & 3)) << 8); |
| 1301 | 1108 | } |
| 1302 | 1109 | |
| 1110 | |
| 1111 | // bprintf(PRINT_NORMAL, _T(" - NGCD port 0x%06X read (word, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| 1112 | |
| 1303 | 1113 | return ~0; |
| 1304 | 1114 | } |
| 1305 | 1115 | |
| 1306 | | UINT16 ng_aes_state::neogeoReadWordCDROM(UINT32 sekAddress) |
| 1116 | |
| 1117 | void ng_aes_state::neogeoWriteWordCDROM(UINT32 sekAddress, UINT16 wordValue) |
| 1307 | 1118 | { |
| 1308 | | // bprintf(PRINT_NORMAL, _T(" - CDROM: 0x%06X read (word, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| 1119 | // bprintf(PRINT_NORMAL, _T(" - NGCD port 0x%06X -> 0x%04X (PC: 0x%06X)\n"), sekAddress, wordValue, SekGetPC(-1)); |
| 1120 | int byteValue = wordValue & 0xff; |
| 1309 | 1121 | |
| 1310 | | #if 1 |
| 1311 | | switch (sekAddress & 0xFFFF) { |
| 1312 | | case 0x011C: |
| 1313 | | return ~((0x10 | (NeoSystem & 3)) << 8); |
| 1314 | | } |
| 1315 | | #endif |
| 1122 | switch (sekAddress & 0xFFFE) { |
| 1123 | case 0x0002: |
| 1124 | // bprintf(PRINT_IMPORTANT, _T(" - NGCD Interrupt mask -> 0x%04X (PC: 0x%06X)\n"), wordValue, SekGetPC(-1)); |
| 1125 | nff0002 = wordValue; |
| 1316 | 1126 | |
| 1317 | | // bprintf(PRINT_NORMAL, _T(" - NGCD port 0x%06X read (word, PC: 0x%06X)\n"), sekAddress, SekGetPC(-1)); |
| 1127 | // LC8951RegistersR[1] |= 0x20; |
| 1318 | 1128 | |
| 1319 | | return ~0; |
| 1320 | | } |
| 1129 | //if (nff0002 & 0x0500) |
| 1130 | // nNeoCDCyclesIRQPeriod = (INT32)(12000000.0 * nBurnCPUSpeedAdjust / (256.0 * 75.0)); |
| 1131 | //else |
| 1132 | // nNeoCDCyclesIRQPeriod = (INT32)(12000000.0 * nBurnCPUSpeedAdjust / (256.0 * 75.0)); |
| 1321 | 1133 | |
| 1322 | | void ng_aes_state::neogeoWriteByteCDROM(UINT32 sekAddress, UINT8 byteValue) |
| 1323 | | { |
| 1324 | | // bprintf(PRINT_NORMAL, _T(" - Neo Geo CD: 0x%06X -> 0x%02X (PC: 0x%06X)\n"), sekAddress, byteValue, SekGetPC(-1)); |
| 1134 | break; |
| 1325 | 1135 | |
| 1326 | | switch (sekAddress & 0xFFFF) { |
| 1327 | | case 0x000F: |
| 1328 | | NeoCDIRQUpdate(byteValue); |
| 1136 | case 0x000E: |
| 1137 | NeoCDIRQUpdate(wordValue); // irqack |
| 1329 | 1138 | break; |
| 1330 | 1139 | |
| 1331 | | case 0x0017: |
| 1140 | case 0x0016: |
| 1332 | 1141 | nff0016 = byteValue; |
| 1333 | 1142 | break; |
| 1334 | 1143 | |
| 1335 | | case 0x0061: |
| 1144 | // DMA controller |
| 1145 | case 0x0060: |
| 1336 | 1146 | if (byteValue & 0x40) { |
| 1337 | 1147 | NeoCDDoDMA(); |
| 1338 | 1148 | } |
| 1339 | 1149 | break; |
| 1340 | 1150 | |
| 1151 | |
| 1152 | case 0x0064: |
| 1153 | NeoCDDMAAddress1 &= 0x0000FFFF; |
| 1154 | NeoCDDMAAddress1 |= wordValue << 16; |
| 1155 | break; |
| 1156 | case 0x0066: |
| 1157 | NeoCDDMAAddress1 &= 0xFFFF0000; |
| 1158 | NeoCDDMAAddress1 |= wordValue; |
| 1159 | break; |
| 1160 | case 0x0068: |
| 1161 | NeoCDDMAAddress2 &= 0x0000FFFF; |
| 1162 | NeoCDDMAAddress2 |= wordValue << 16; |
| 1163 | break; |
| 1164 | case 0x006A: |
| 1165 | NeoCDDMAAddress2 &= 0xFFFF0000; |
| 1166 | NeoCDDMAAddress2 |= wordValue; |
| 1167 | break; |
| 1168 | case 0x006C: |
| 1169 | NeoCDDMAValue1 = wordValue; |
| 1170 | break; |
| 1171 | case 0x006E: |
| 1172 | NeoCDDMAValue2 = wordValue; |
| 1173 | break; |
| 1174 | case 0x0070: |
| 1175 | NeoCDDMACount &= 0x0000FFFF; |
| 1176 | NeoCDDMACount |= wordValue << 16; |
| 1177 | break; |
| 1178 | case 0x0072: |
| 1179 | NeoCDDMACount &= 0xFFFF0000; |
| 1180 | NeoCDDMACount |= wordValue; |
| 1181 | break; |
| 1182 | |
| 1183 | case 0x007E: |
| 1184 | NeoCDDMAMode = wordValue; |
| 1185 | // bprintf(PRINT_NORMAL, _T(" - DMA controller 0x%2X -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0xFF, wordValue, SekGetPC(-1)); |
| 1186 | break; |
| 1187 | |
| 1188 | // upload DMA controller program |
| 1189 | |
| 1190 | case 0x0080: |
| 1191 | case 0x0082: |
| 1192 | case 0x0084: |
| 1193 | case 0x0086: |
| 1194 | case 0x0088: |
| 1195 | case 0x008A: |
| 1196 | case 0x008C: |
| 1197 | case 0x008E: |
| 1198 | // bprintf(PRINT_NORMAL, _T(" - DMA controller program[%02i] -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0x0F, wordValue, SekGetPC(-1)); |
| 1199 | break; |
| 1200 | |
| 1341 | 1201 | // LC8951 registers |
| 1342 | | case 0x0101: |
| 1202 | case 0x0100: |
| 1343 | 1203 | nLC8951Register = byteValue & 0x0F; |
| 1344 | 1204 | // bprintf(PRINT_NORMAL, _T(" - LC8951 register -> 0x%02X (PC: 0x%06X)\n"), nLC8951Register, SekGetPC(-1)); |
| 1345 | 1205 | break; |
| 1346 | | case 0x0103: |
| 1206 | case 0x0102: |
| 1347 | 1207 | // bprintf(PRINT_NORMAL, _T(" - LC8951 register 0x%X -> 0x%02X (PC: 0x%06X)\n"), nLC8951Register, byteValue, SekGetPC(-1)); |
| 1348 | 1208 | switch (nLC8951Register) { |
| 1349 | 1209 | case 3: // DBCH |
| r19019 | r19020 | |
| 1374 | 1234 | nLC8951Register = (nLC8951Register + 1) & 0x0F; |
| 1375 | 1235 | break; |
| 1376 | 1236 | |
| 1377 | | case 0x0105: |
| 1237 | case 0x0104: |
| 1378 | 1238 | // bprintf(PRINT_NORMAL, _T(" - NGCD 0xE00000 area -> 0x%02X (PC: 0x%06X)\n"), byteValue, SekGetPC(-1)); |
| 1379 | 1239 | nActiveTransferArea = byteValue; |
| 1380 | 1240 | break; |
| 1381 | 1241 | |
| 1382 | | case 0x0121: |
| 1242 | case 0x0120: |
| 1383 | 1243 | // bprintf(PRINT_NORMAL, _T(" - NGCD OBJ BUSREQ -> 1 (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1384 | 1244 | NeoSetSpriteSlot(1); |
| 1385 | 1245 | memset(NeoCDOBJBankUpdate, 0, sizeof(NeoCDOBJBankUpdate)); |
| 1386 | 1246 | break; |
| 1387 | | case 0x0123: |
| 1247 | case 0x0122: |
| 1388 | 1248 | // bprintf(PRINT_NORMAL, _T(" - NGCD PCM BUSREQ -> 1 (PC: 0x%06X) %x\n"), SekGetPC(-1), byteValue); |
| 1389 | 1249 | break; |
| 1390 | | case 0x0127: |
| 1250 | case 0x0126: |
| 1391 | 1251 | // bprintf(PRINT_NORMAL, _T(" - NGCD Z80 BUSREQ -> 1 (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1392 | 1252 | curr_space->machine().scheduler().synchronize(); |
| 1393 | | curr_space->machine().device("audiocpu")->execute().set_input_line(INPUT_LINE_RESET, ASSERT_LINE); |
| 1253 | curr_space->machine().device("audiocpu")->execute().set_input_line(INPUT_LINE_HALT, ASSERT_LINE); |
| 1394 | 1254 | |
| 1395 | 1255 | break; |
| 1396 | | case 0x0129: |
| 1256 | case 0x0128: |
| 1397 | 1257 | // bprintf(PRINT_NORMAL, _T(" - NGCD FIX BUSREQ -> 1 (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1398 | 1258 | NeoSetTextSlot(1); |
| 1399 | 1259 | break; |
| 1400 | 1260 | |
| 1401 | | case 0x0141: |
| 1261 | case 0x0140: |
| 1402 | 1262 | // bprintf(PRINT_NORMAL, _T(" - NGCD OBJ BUSREQ -> 0 (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1403 | 1263 | video_reset(); |
| 1404 | 1264 | break; |
| 1405 | | case 0x0143: |
| 1265 | case 0x0142: |
| 1406 | 1266 | // bprintf(PRINT_NORMAL, _T(" - NGCD PCM BUSREQ -> 0 (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1407 | 1267 | break; |
| 1408 | | case 0x0147: |
| 1268 | case 0x0146: |
| 1409 | 1269 | // bprintf(PRINT_NORMAL, _T(" - NGCD Z80 BUSREQ -> 0 (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1410 | 1270 | curr_space->machine().scheduler().synchronize(); |
| 1411 | | curr_space->machine().device("audiocpu")->execute().set_input_line(INPUT_LINE_RESET, CLEAR_LINE); |
| 1271 | curr_space->machine().device("audiocpu")->execute().set_input_line(INPUT_LINE_HALT, CLEAR_LINE); |
| 1412 | 1272 | break; |
| 1413 | | case 0x0149: |
| 1273 | case 0x0148: |
| 1414 | 1274 | // bprintf(PRINT_NORMAL, _T(" - NGCD FIX BUSREQ -> 0 (PC: 0x%06X)\n"), SekGetPC(-1)); |
| 1415 | 1275 | video_reset(); |
| 1416 | 1276 | break; |
| 1417 | 1277 | |
| 1418 | 1278 | // CD mechanism communication |
| 1419 | | case 0x0163: |
| 1279 | case 0x0162: |
| 1420 | 1280 | NeoCDCommsWrite(byteValue); |
| 1421 | 1281 | break; |
| 1422 | | case 0x0165: |
| 1282 | case 0x0164: |
| 1423 | 1283 | NeoCDCommsControl(byteValue & 1, byteValue & 2); |
| 1424 | 1284 | break; |
| 1425 | 1285 | |
| 1426 | | case 0x016D: |
| 1286 | case 0x016c: |
| 1427 | 1287 | // bprintf(PRINT_ERROR, _T(" - NGCD port 0x%06X -> 0x%02X (PC: 0x%06X)\n"), sekAddress, byteValue, SekGetPC(-1)); |
| 1428 | 1288 | |
| 1429 | 1289 | MapVectorTable(!(byteValue == 0xFF)); |
| r19019 | r19020 | |
| 1432 | 1292 | //bRunPause = 1; |
| 1433 | 1293 | break; |
| 1434 | 1294 | |
| 1435 | | case 0x016F: |
| 1295 | case 0x016e: |
| 1436 | 1296 | // bprintf(PRINT_IMPORTANT, _T(" - NGCD 0xE00000 area write access %s (0x%02X, PC: 0x%06X)\n"), byteValue ? _T("enabled") : _T("disabled"), byteValue, SekGetPC(-1)); |
| 1437 | 1297 | |
| 1438 | 1298 | nTransferWriteEnable = byteValue; |
| 1439 | 1299 | break; |
| 1440 | 1300 | |
| 1441 | | case 0x0181: { |
| 1301 | case 0x0180: { |
| 1442 | 1302 | static UINT8 clara = 0; |
| 1443 | 1303 | if (!byteValue && clara) { |
| 1444 | 1304 | // bprintf(PRINT_IMPORTANT, _T(" - NGCD CD communication reset (PC: 0x%06X)\n"), SekGetPC(-1)); |
| r19019 | r19020 | |
| 1447 | 1307 | clara = byteValue; |
| 1448 | 1308 | break; |
| 1449 | 1309 | } |
| 1450 | | case 0x0183: { |
| 1310 | case 0x0182: { |
| 1451 | 1311 | static UINT8 clara = 0; |
| 1452 | 1312 | if (!byteValue && clara) { |
| 1453 | 1313 | // bprintf(PRINT_IMPORTANT, _T(" - NGCD Z80 reset (PC: 0x%06X)\n"), SekGetPC(-1)); |
| r19019 | r19020 | |
| 1456 | 1316 | clara = byteValue; |
| 1457 | 1317 | break; |
| 1458 | 1318 | } |
| 1459 | | case 0x01A1: |
| 1319 | case 0x01A0: |
| 1460 | 1320 | nSpriteTransferBank = (byteValue & 3) << 20; |
| 1461 | 1321 | break; |
| 1462 | | case 0x01A3: |
| 1322 | case 0x01A2: |
| 1463 | 1323 | nADPCMTransferBank = (byteValue & 1) << 19; |
| 1464 | 1324 | break; |
| 1465 | 1325 | |
| 1466 | | default: { |
| 1467 | | // bprintf(PRINT_NORMAL, _T(" - NGCD port 0x%06X -> 0x%02X (PC: 0x%06X)\n"), sekAddress, byteValue, SekGetPC(-1)); |
| 1468 | | } |
| 1469 | | } |
| 1470 | | } |
| 1471 | 1326 | |
| 1472 | | void ng_aes_state::neogeoWriteWordCDROM(UINT32 sekAddress, UINT16 wordValue) |
| 1473 | | { |
| 1474 | | // bprintf(PRINT_NORMAL, _T(" - NGCD port 0x%06X -> 0x%04X (PC: 0x%06X)\n"), sekAddress, wordValue, SekGetPC(-1)); |
| 1475 | | |
| 1476 | | switch (sekAddress & 0xFFFE) { |
| 1477 | | case 0x0002: |
| 1478 | | // bprintf(PRINT_IMPORTANT, _T(" - NGCD Interrupt mask -> 0x%04X (PC: 0x%06X)\n"), wordValue, SekGetPC(-1)); |
| 1479 | | nff0002 = wordValue; |
| 1480 | | |
| 1481 | | // LC8951RegistersR[1] |= 0x20; |
| 1482 | | |
| 1483 | | //if (nff0002 & 0x0500) |
| 1484 | | // nNeoCDCyclesIRQPeriod = (INT32)(12000000.0 * nBurnCPUSpeedAdjust / (256.0 * 75.0)); |
| 1485 | | //else |
| 1486 | | // nNeoCDCyclesIRQPeriod = (INT32)(12000000.0 * nBurnCPUSpeedAdjust / (256.0 * 75.0)); |
| 1487 | | |
| 1488 | | break; |
| 1489 | | |
| 1490 | | case 0x000E: |
| 1491 | | NeoCDIRQUpdate(wordValue); // irqack |
| 1492 | | break; |
| 1493 | | |
| 1494 | | // DMA controller |
| 1495 | | |
| 1496 | | case 0x0064: |
| 1497 | | NeoCDDMAAddress1 &= 0x0000FFFF; |
| 1498 | | NeoCDDMAAddress1 |= wordValue << 16; |
| 1499 | | break; |
| 1500 | | case 0x0066: |
| 1501 | | NeoCDDMAAddress1 &= 0xFFFF0000; |
| 1502 | | NeoCDDMAAddress1 |= wordValue; |
| 1503 | | break; |
| 1504 | | case 0x0068: |
| 1505 | | NeoCDDMAAddress2 &= 0x0000FFFF; |
| 1506 | | NeoCDDMAAddress2 |= wordValue << 16; |
| 1507 | | break; |
| 1508 | | case 0x006A: |
| 1509 | | NeoCDDMAAddress2 &= 0xFFFF0000; |
| 1510 | | NeoCDDMAAddress2 |= wordValue; |
| 1511 | | break; |
| 1512 | | case 0x006C: |
| 1513 | | NeoCDDMAValue1 = wordValue; |
| 1514 | | break; |
| 1515 | | case 0x006E: |
| 1516 | | NeoCDDMAValue2 = wordValue; |
| 1517 | | break; |
| 1518 | | case 0x0070: |
| 1519 | | NeoCDDMACount &= 0x0000FFFF; |
| 1520 | | NeoCDDMACount |= wordValue << 16; |
| 1521 | | break; |
| 1522 | | case 0x0072: |
| 1523 | | NeoCDDMACount &= 0xFFFF0000; |
| 1524 | | NeoCDDMACount |= wordValue; |
| 1525 | | break; |
| 1526 | | |
| 1527 | | case 0x007E: |
| 1528 | | NeoCDDMAMode = wordValue; |
| 1529 | | // bprintf(PRINT_NORMAL, _T(" - DMA controller 0x%2X -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0xFF, wordValue, SekGetPC(-1)); |
| 1530 | | break; |
| 1531 | | |
| 1532 | | // upload DMA controller program |
| 1533 | | |
| 1534 | | case 0x0080: |
| 1535 | | case 0x0082: |
| 1536 | | case 0x0084: |
| 1537 | | case 0x0086: |
| 1538 | | case 0x0088: |
| 1539 | | case 0x008A: |
| 1540 | | case 0x008C: |
| 1541 | | case 0x008E: |
| 1542 | | // bprintf(PRINT_NORMAL, _T(" - DMA controller program[%02i] -> 0x%04X (PC: 0x%06X)\n"), sekAddress & 0x0F, wordValue, SekGetPC(-1)); |
| 1543 | | break; |
| 1544 | | |
| 1545 | 1327 | default: { |
| 1546 | 1328 | // bprintf(PRINT_NORMAL, _T(" - NGCD port 0x%06X -> 0x%04X (PC: 0x%06X)\n"), sekAddress, wordValue, SekGetPC(-1)); |
| 1547 | 1329 | } |
| r19019 | r19020 | |
| 2206 | 1988 | |
| 2207 | 1989 | READ16_MEMBER(ng_aes_state::neocd_control_r) |
| 2208 | 1990 | { |
| 2209 | | if (mem_mask == 0xffff) |
| 2210 | | { |
| 2211 | | return neogeoReadWordCDROM(0xff0000+ (offset*2)); |
| 2212 | | } |
| 2213 | | else if (mem_mask ==0xff00) |
| 2214 | | { |
| 2215 | | return neogeoReadByteCDROM(0xff0000+ (offset*2)) << 8; |
| 2216 | | } |
| 2217 | | else if (mem_mask ==0x00ff) |
| 2218 | | { |
| 2219 | | return neogeoReadByteCDROM(0xff0000+ (offset*2)+1) & 0xff; |
| 2220 | | } |
| 2221 | | |
| 2222 | | return 0x0000; |
| 2223 | | |
| 1991 | return neogeoReadWordCDROM(0xff0000+ (offset*2)); |
| 2224 | 1992 | } |
| 2225 | 1993 | |
| 2226 | 1994 | |
| 2227 | 1995 | WRITE16_MEMBER(ng_aes_state::neocd_control_w) |
| 2228 | 1996 | { |
| 2229 | | if (mem_mask == 0xffff) |
| 2230 | | { |
| 2231 | | neogeoWriteWordCDROM(0xff0000+ (offset*2), data); |
| 2232 | | } |
| 2233 | | else if (mem_mask ==0xff00) |
| 2234 | | { |
| 2235 | | neogeoWriteByteCDROM(0xff0000+ (offset*2), data>>8); |
| 2236 | | } |
| 2237 | | else if (mem_mask ==0x00ff) |
| 2238 | | { |
| 2239 | | neogeoWriteByteCDROM(0xff0000+ (offset*2)+1, data&0xff); |
| 2240 | | } |
| 1997 | neogeoWriteWordCDROM(0xff0000+ (offset*2), data); |
| 2241 | 1998 | } |
| 2242 | 1999 | |
| 2243 | 2000 | |
| r19019 | r19020 | |
| 2251 | 2008 | |
| 2252 | 2009 | READ16_MEMBER(ng_aes_state::neocd_transfer_r) |
| 2253 | 2010 | { |
| 2254 | | if (mem_mask == 0xffff) |
| 2011 | int is_byte_transfer = 0; |
| 2012 | if (mem_mask != 0xffff) is_byte_transfer = 1; |
| 2013 | |
| 2014 | UINT16 ret = 0x0000; |
| 2015 | |
| 2016 | |
| 2017 | |
| 2018 | if (mem_mask & 0x00ff) |
| 2255 | 2019 | { |
| 2256 | | return neogeoReadWordTransfer(0xe00000+ (offset*2)); |
| 2020 | ret |= neogeoReadTransfer(0xe00000+ (offset*2)+1, is_byte_transfer) & 0xff; |
| 2257 | 2021 | } |
| 2258 | | else if (mem_mask ==0xff00) |
| 2022 | if (mem_mask & 0xff00) |
| 2259 | 2023 | { |
| 2260 | | return neogeoReadByteTransfer(0xe00000+ (offset*2)) << 8; |
| 2024 | ret |= neogeoReadTransfer(0xe00000+ (offset*2), is_byte_transfer) << 8; |
| 2261 | 2025 | } |
| 2262 | | else if (mem_mask ==0x00ff) |
| 2263 | | { |
| 2264 | | return neogeoReadByteTransfer(0xe00000+ (offset*2)+1) & 0xff; |
| 2265 | | } |
| 2266 | 2026 | |
| 2027 | return ret; |
| 2267 | 2028 | |
| 2268 | | return 0x0000; |
| 2269 | | |
| 2270 | 2029 | } |
| 2271 | 2030 | |
| 2272 | 2031 | WRITE16_MEMBER(ng_aes_state::neocd_transfer_w) |
| 2273 | 2032 | { |
| 2274 | | if (mem_mask == 0xffff) |
| 2033 | int is_byte_transfer = 0; |
| 2034 | if (mem_mask != 0xffff) is_byte_transfer = 1; |
| 2035 | |
| 2036 | |
| 2037 | if (mem_mask & 0xff00) |
| 2275 | 2038 | { |
| 2276 | | neogeoWriteWordTransfer(0xe00000+ (offset*2), data); |
| 2039 | neogeoWriteTransfer(0xe00000+ (offset*2), data>>8, is_byte_transfer); |
| 2277 | 2040 | } |
| 2278 | | else if (mem_mask ==0xff00) |
| 2041 | |
| 2042 | if (mem_mask & 0x00ff) |
| 2279 | 2043 | { |
| 2280 | | neogeoWriteByteTransfer(0xe00000+ (offset*2), data>>8); |
| 2044 | neogeoWriteTransfer(0xe00000+ (offset*2)+1, data&0xff, is_byte_transfer); |
| 2281 | 2045 | } |
| 2282 | | else if (mem_mask ==0x00ff) |
| 2283 | | { |
| 2284 | | neogeoWriteByteTransfer(0xe00000+ (offset*2)+1, data&0xff); |
| 2285 | | } |
| 2286 | 2046 | |
| 2047 | |
| 2287 | 2048 | } |
| 2288 | 2049 | |
| 2289 | 2050 | /* |
| r19019 | r19020 | |
| 2396 | 2157 | /* set the initial audio CPU ROM banks */ |
| 2397 | 2158 | audio_cpu_banking_init(machine); |
| 2398 | 2159 | |
| 2399 | | create_interrupt_timers(machine); |
| 2160 | state->create_interrupt_timers(machine); |
| 2400 | 2161 | |
| 2162 | /* irq levels for MVS / AES */ |
| 2163 | state->m_vblank_level = 1; |
| 2164 | state->m_raster_level = 2; |
| 2165 | |
| 2401 | 2166 | /* start with an IRQ3 - but NOT on a reset */ |
| 2402 | 2167 | state->m_irq3_pending = 1; |
| 2403 | 2168 | |
| r19019 | r19020 | |
| 2449 | 2214 | |
| 2450 | 2215 | common_machine_start(machine()); |
| 2451 | 2216 | |
| 2217 | /* irq levels for NEOCD (swapped compared to MVS / AES) */ |
| 2218 | m_vblank_level = 2; |
| 2219 | m_raster_level = 1; |
| 2220 | |
| 2221 | |
| 2452 | 2222 | /* initialize the memcard data structure */ |
| 2453 | 2223 | /* NeoCD doesn't have memcard slots, rather, it has a larger internal memory which works the same */ |
| 2454 | 2224 | m_memcard_data = auto_alloc_array_clear(machine(), UINT8, 0x2000); |
| r19019 | r19020 | |
| 2968 | 2738 | |
| 2969 | 2739 | |
| 2970 | 2740 | |
| 2971 | | int nVBLankIRQ = 2; |
| 2972 | | int nScanlineIRQ = 1; |
| 2973 | | |
| 2974 | | void ng_aes_state::NeoIRQUpdate(UINT16 wordValue) |
| 2975 | | { |
| 2976 | | nIRQAcknowledge |= (wordValue & 7); |
| 2977 | | |
| 2978 | | // bprintf(PRINT_NORMAL, _T(" - IRQ Ack -> %02X (at line %3i).\n"), nIRQAcknowledge, SekCurrentScanline()); |
| 2979 | | |
| 2980 | | if ((nIRQAcknowledge & 7) == 7) { |
| 2981 | | SekSetIRQLine(7, SEK_IRQSTATUS_NONE); |
| 2982 | | } else { |
| 2983 | | if ((nIRQAcknowledge & 1) == 0) { |
| 2984 | | SekSetIRQLine(3, SEK_IRQSTATUS_ACK); |
| 2985 | | } |
| 2986 | | if ((nIRQAcknowledge & 2) == 0) { |
| 2987 | | SekSetIRQLine(nScanlineIRQ, SEK_IRQSTATUS_ACK); |
| 2988 | | } |
| 2989 | | if ((nIRQAcknowledge & 4) == 0) { |
| 2990 | | SekSetIRQLine(nVBLankIRQ, SEK_IRQSTATUS_ACK); |
| 2991 | | } |
| 2992 | | } |
| 2993 | | } |
| 2994 | | |
| 2995 | | |
| 2996 | 2741 | /* NeoCD uses custom vectors on IRQ4 to handle various events from the CDC */ |
| 2997 | 2742 | |
| 2998 | 2743 | static IRQ_CALLBACK(neocd_int_callback) |
| 2999 | 2744 | { |
| 3000 | 2745 | ng_aes_state *state = device->machine().driver_data<ng_aes_state>(); |
| 3001 | 2746 | |
| 3002 | | // this is how FBA seems to be setup, but surely this would cause the custom |
| 3003 | | // interrupt levels to end up being used for the regular interrupts too in cases? |
| 3004 | | if (state->nNeoCDIRQVectorAck) { |
| 3005 | | state->nNeoCDIRQVectorAck = 0; |
| 3006 | | return state->nNeoCDIRQVector; |
| 2747 | if (irqline==4) |
| 2748 | { |
| 2749 | if (state->nNeoCDIRQVectorAck) { |
| 2750 | state->nNeoCDIRQVectorAck = 0; |
| 2751 | return state->nNeoCDIRQVector; |
| 2752 | } |
| 3007 | 2753 | } |
| 3008 | 2754 | |
| 3009 | 2755 | return (0x60+irqline*4)/4; |
| r19019 | r19020 | |
| 3011 | 2757 | |
| 3012 | 2758 | void ng_aes_state::NeoCDIRQUpdate(UINT8 byteValue) |
| 3013 | 2759 | { |
| 2760 | // do we also need to check the regular interrupts like FBA? |
| 2761 | |
| 3014 | 2762 | nIRQAcknowledge |= (byteValue & 0x38); |
| 3015 | 2763 | |
| 3016 | | // bprintf(PRINT_NORMAL, _T(" - IRQ Ack -> %02X (CD, at line %3i).\n"), nIRQAcknowledge, SekCurrentScanline()); |
| 3017 | | |
| 3018 | | if ((nIRQAcknowledge & 0x3F) == 0x3F) { |
| 3019 | | SekSetIRQLine(7, SEK_IRQSTATUS_NONE); |
| 3020 | | } else { |
| 3021 | | if ((nIRQAcknowledge & 0x07) != 7) { |
| 3022 | | NeoIRQUpdate(0); |
| 3023 | | return; |
| 3024 | | } |
| 3025 | | if ((nIRQAcknowledge & 0x08) == 0) { |
| 3026 | | nNeoCDIRQVector = 0x17; |
| 3027 | | nNeoCDIRQVectorAck = 1; |
| 3028 | | m_maincpu->set_input_line(4, HOLD_LINE); |
| 3029 | | return; |
| 3030 | | } |
| 3031 | | if ((nIRQAcknowledge & 0x10) == 0) { |
| 3032 | | nNeoCDIRQVector = 0x16; |
| 3033 | | nNeoCDIRQVectorAck = 1; |
| 3034 | | m_maincpu->set_input_line(4, HOLD_LINE); |
| 3035 | | return; |
| 3036 | | } |
| 3037 | | if ((nIRQAcknowledge & 0x20) == 0) { |
| 3038 | | nNeoCDIRQVector = 0x15; |
| 3039 | | nNeoCDIRQVectorAck = 1; |
| 3040 | | m_maincpu->set_input_line(4, HOLD_LINE); |
| 3041 | | return; |
| 3042 | | } |
| 2764 | if ((nIRQAcknowledge & 0x08) == 0) { |
| 2765 | nNeoCDIRQVector = 0x17; |
| 2766 | nNeoCDIRQVectorAck = 1; |
| 2767 | m_maincpu->set_input_line(4, HOLD_LINE); |
| 2768 | return; |
| 3043 | 2769 | } |
| 2770 | if ((nIRQAcknowledge & 0x10) == 0) { |
| 2771 | nNeoCDIRQVector = 0x16; |
| 2772 | nNeoCDIRQVectorAck = 1; |
| 2773 | m_maincpu->set_input_line(4, HOLD_LINE); |
| 2774 | return; |
| 2775 | } |
| 2776 | if ((nIRQAcknowledge & 0x20) == 0) { |
| 2777 | nNeoCDIRQVector = 0x15; |
| 2778 | nNeoCDIRQVectorAck = 1; |
| 2779 | m_maincpu->set_input_line(4, HOLD_LINE); |
| 2780 | return; |
| 2781 | } |
| 3044 | 2782 | } |
| 3045 | 2783 | |
| 3046 | 2784 | TIMER_DEVICE_CALLBACK_MEMBER( ng_aes_state::neocd_access_timer_callback ) |