trunk/src/mess/drivers/pc9801.c
| r19303 | r19304 | |
| 10 | 10 | - boot is too slow right now, might be due of the floppy / HDD devices |
| 11 | 11 | - investigate on POR bit |
| 12 | 12 | - Write a PC80S31K device (also used on PC-8801 and PC-88VA, it's the FDC + Z80 sub-system); |
| 13 | - Check for mouse support |
| 14 | - .FDI support, should be a standard raw image, but then it mis-match with the Western file format ... |
| 15 | - kanji support; |
| 13 | 16 | |
| 14 | 17 | TODO (PC-9801RS): |
| 15 | 18 | - floppy disk hook-up; |
| r19303 | r19304 | |
| 28 | 31 | - Dies on ARTIC check; |
| 29 | 32 | - Presumably one ROM is undumped? |
| 30 | 33 | |
| 34 | floppy issues TODO (certain fail, even with a stock F version) |
| 35 | - AdventureLand: "disk offline" error |
| 36 | - Dokkin Minako Sensei! |
| 37 | - Microsoft Windows 1.0 MSDOS.SYS error (can be bypassed by loading MS-DOS first) |
| 38 | |
| 39 | List of per-game TODO: |
| 40 | - Dragon Buster: has lots of gfx artifacts; |
| 41 | - Far Side Moon: doesn't detect neither mouse nor sound board; |
| 42 | - First Queen: has broken text display; |
| 43 | - Flappy Plus: keyboard is unresponsive; |
| 44 | - Jan Borg Suzume: error text isn't shown; |
| 45 | - Jangou 2: floppy fails to load after the title screen; |
| 46 | - Lovely Horror: Doesn't show kanji, tries to read it thru the 0xa9 port; |
| 47 | - Okuman Chouja 2: needs 16 colors support; |
| 48 | - Quarth: should do a split screen effect, it doesn't hence there are broken gfxs |
| 49 | - Quarth: uploads a PCG charset |
| 50 | - Uchiyama Aki no Chou Bangai: half size gfxs, can't start (needs mouse)? |
| 51 | - Xenon 2 - Megablast: copyright isn't shown at device select; |
| 52 | |
| 31 | 53 | ======================================================================================== |
| 32 | 54 | |
| 33 | 55 | This series features a huge number of models released between 1982 and 1997. They |
| r19303 | r19304 | |
| 324 | 346 | UINT8 pal_entry; |
| 325 | 347 | UINT8 r[16],g[16],b[16]; |
| 326 | 348 | }m_analog16; |
| 349 | UINT8 m_support_16_colors; |
| 327 | 350 | |
| 328 | 351 | /* PC9821 specific */ |
| 329 | 352 | UINT8 m_analog256,m_analog256e; |
| r19303 | r19304 | |
| 366 | 389 | DECLARE_WRITE8_MEMBER(pc9801_tvram_w); |
| 367 | 390 | DECLARE_READ8_MEMBER(pc9801_gvram_r); |
| 368 | 391 | DECLARE_WRITE8_MEMBER(pc9801_gvram_w); |
| 392 | // DECLARE_READ8_MEMBER(pc9801rs_gvram_r); |
| 393 | DECLARE_WRITE8_MEMBER(pc9801rs_gvram_w); |
| 369 | 394 | DECLARE_READ8_MEMBER(pc9801_opn_r); |
| 370 | 395 | DECLARE_WRITE8_MEMBER(pc9801_opn_w); |
| 371 | 396 | DECLARE_READ8_MEMBER(pc9801rs_wram_r); |
| r19303 | r19304 | |
| 537 | 562 | int res_x,res_y; |
| 538 | 563 | UINT8 pen; |
| 539 | 564 | UINT8 interlace_on; |
| 565 | UINT8 colors16_mode; |
| 540 | 566 | |
| 541 | 567 | if(state->m_video_ff[DISPLAY_REG] == 0) //screen is off |
| 542 | 568 | return; |
| 543 | 569 | |
| 544 | 570 | interlace_on = state->m_video_ff[INTERLACE_REG]; |
| 571 | colors16_mode = (state->m_ex_video_ff[0] && state->m_support_16_colors) ? 16 : 8; |
| 545 | 572 | |
| 546 | 573 | for(xi=0;xi<8;xi++) |
| 547 | 574 | { |
| r19303 | r19304 | |
| 551 | 578 | pen = ((state->m_video_ram_2[(address & 0x7fff) + (0x08000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 1 : 0; |
| 552 | 579 | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x10000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 2 : 0; |
| 553 | 580 | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x18000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 4 : 0; |
| 581 | if(state->m_ex_video_ff[0]) |
| 582 | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 8 : 0; |
| 554 | 583 | |
| 555 | 584 | if(interlace_on) |
| 556 | 585 | { |
| 557 | 586 | if(res_y*2+0 < 400) |
| 558 | | bitmap.pix16(res_y*2+0, res_x) = pen + 8; |
| 587 | bitmap.pix16(res_y*2+0, res_x) = pen + colors16_mode; |
| 559 | 588 | if(res_y*2+1 < 400) |
| 560 | | bitmap.pix16(res_y*2+1, res_x) = pen + 8; |
| 589 | bitmap.pix16(res_y*2+1, res_x) = pen + colors16_mode; |
| 561 | 590 | } |
| 562 | 591 | else |
| 563 | | bitmap.pix16(res_y, res_x) = pen + 8; |
| 592 | bitmap.pix16(res_y, res_x) = pen + colors16_mode; |
| 564 | 593 | } |
| 565 | 594 | } |
| 566 | 595 | |
| r19303 | r19304 | |
| 1116 | 1145 | switch((offset & 0xe) + 1) |
| 1117 | 1146 | { |
| 1118 | 1147 | case 0x01: |
| 1119 | | m_font_addr = (data << 8) | (m_font_addr & 0xff); |
| 1148 | m_font_addr = (data & 0xff) | (m_font_addr & 0xff00); |
| 1120 | 1149 | return; |
| 1121 | 1150 | case 0x03: |
| 1122 | | m_font_addr = (data & 0xff) | (m_font_addr & 0xff00); |
| 1151 | m_font_addr = (data << 8) | (m_font_addr & 0xff); |
| 1123 | 1152 | return; |
| 1124 | 1153 | case 0x05: |
| 1154 | //printf("%02x\n",data); |
| 1125 | 1155 | m_font_line = data & 0x1f; |
| 1126 | 1156 | m_font_lr = data & 0x20 ? 0x000 : 0x800; |
| 1127 | 1157 | return; |
| 1128 | 1158 | case 0x09: //cg window font write |
| 1129 | 1159 | { |
| 1160 | //printf("W\n"); |
| 1130 | 1161 | m_pcg_ram[((m_font_addr & 0x7f7f) << 4) | m_font_lr | m_font_line] = data; |
| 1131 | 1162 | return; |
| 1132 | 1163 | } |
| r19303 | r19304 | |
| 1291 | 1322 | m_video_ram_2[offset+0x08000+m_vram_bank*0x20000] = data; |
| 1292 | 1323 | } |
| 1293 | 1324 | |
| 1325 | WRITE8_MEMBER(pc9801_state::pc9801rs_gvram_w) |
| 1326 | { |
| 1327 | m_video_ram_2[offset+0+m_vram_bank*0x20000] = data; |
| 1328 | } |
| 1329 | |
| 1330 | |
| 1294 | 1331 | READ8_MEMBER(pc9801_state::pc9801_opn_r) |
| 1295 | 1332 | { |
| 1296 | 1333 | if((offset & 1) == 0) |
| r19303 | r19304 | |
| 1461 | 1498 | else if(offset >= 0x000a0000 && offset <= 0x000a3fff) { pc9801_tvram_w(space,offset-0xa0000,data); } |
| 1462 | 1499 | else if(offset >= 0x000a4000 && offset <= 0x000a4fff) { pc9801rs_knjram_w(space,offset & 0xfff,data); } |
| 1463 | 1500 | else if(offset >= 0x000a8000 && offset <= 0x000bffff) { pc9801_gvram_w(space,offset-0xa8000,data); } |
| 1464 | | else if(offset >= 0x00100000 && offset <= 0x00100000+m_ram_size-1) { pc9801rs_ex_wram_w(space,offset-0x00100000,data); } |
| 1501 | else if(offset >= 0x000e0000 && offset <= 0x000e7fff) { pc9801rs_gvram_w(space,offset & 0x7fff,data); } |
| 1502 | else if(offset >= 0x00100000 && offset <= 0x00100000+m_ram_size-1) { pc9801rs_ex_wram_w(space,offset-0x00100000,data); } |
| 1465 | 1503 | //else |
| 1466 | 1504 | // printf("%08x %08x\n",offset,data); |
| 1467 | 1505 | } |
| r19303 | r19304 | |
| 1652 | 1690 | AM_RANGE(0x0064, 0x0067) AM_WRITE8(pc9801_vrtc_mask_w, 0xffffffff) |
| 1653 | 1691 | AM_RANGE(0x0068, 0x006b) AM_WRITE8(pc9801rs_video_ff_w,0xffffffff) //mode FF / <undefined> |
| 1654 | 1692 | AM_RANGE(0x0070, 0x007b) AM_READWRITE8(pc9801_70_r, pc9801_70_w, 0xffffffff) //display registers "GRCG" / i8253 pit |
| 1693 | AM_RANGE(0x0080, 0x0083) AM_READWRITE8(pc9801_sasi_r, pc9801_sasi_w, 0xffffffff) //HDD SASI interface / <undefined> |
| 1655 | 1694 | AM_RANGE(0x0090, 0x0097) AM_READWRITE8(pc9801rs_2hd_r, pc9801rs_2hd_w, 0xffffffff) |
| 1656 | 1695 | AM_RANGE(0x00a0, 0x00af) AM_READWRITE8(pc9801_a0_r, pc9801rs_a0_w, 0xffffffff) //upd7220 bitmap ports / display registers |
| 1657 | 1696 | AM_RANGE(0x00bc, 0x00bf) AM_READWRITE8(pc9810rs_fdc_ctrl_r,pc9810rs_fdc_ctrl_w,0xffffffff) |
| 1658 | 1697 | AM_RANGE(0x00c8, 0x00cf) AM_READWRITE8(pc9801rs_2hd_r, pc9801rs_2hd_w, 0xffffffff) |
| 1659 | 1698 | AM_RANGE(0x00f0, 0x00ff) AM_READWRITE8(pc9801rs_f0_r, pc9801rs_f0_w, 0xffffffff) |
| 1699 | AM_RANGE(0x0188, 0x018b) AM_READWRITE8(pc9801_opn_r, pc9801_opn_w, 0xffffffff) //ym2203 opn / <undefined> |
| 1660 | 1700 | AM_RANGE(0x0438, 0x043b) AM_READWRITE8(pc9801rs_access_ctrl_r,pc9801rs_access_ctrl_w,0xffffffff) |
| 1661 | 1701 | AM_RANGE(0x043c, 0x043f) AM_WRITE8(pc9801rs_bank_w, 0xffffffff) //ROM/RAM bank |
| 1662 | 1702 | ADDRESS_MAP_END |
| r19303 | r19304 | |
| 1713 | 1753 | AM_RANGE(0x00bc, 0x00bf) AM_READWRITE8(pc9810rs_fdc_ctrl_r,pc9810rs_fdc_ctrl_w,0xffff) |
| 1714 | 1754 | AM_RANGE(0x00c8, 0x00cf) AM_READWRITE8(pc9801rs_2hd_r, pc9801rs_2hd_w, 0xffff) |
| 1715 | 1755 | AM_RANGE(0x00f0, 0x00ff) AM_READWRITE8(pc9801rs_f0_r, pc9801rs_f0_w, 0xffff) |
| 1756 | AM_RANGE(0x0188, 0x018b) AM_READWRITE8(pc9801_opn_r, pc9801_opn_w, 0xffff) //ym2203 opn / <undefined> |
| 1716 | 1757 | AM_RANGE(0x0438, 0x043b) AM_READWRITE8(pc9801rs_access_ctrl_r,pc9801rs_access_ctrl_w,0xffff) |
| 1717 | 1758 | AM_RANGE(0x043c, 0x043f) AM_WRITE8(pc9801rs_bank_w, 0xffff) //ROM/RAM bank |
| 1718 | 1759 | |
| r19303 | r19304 | |
| 1988 | 2029 | AM_RANGE(0x00c8, 0x00cf) AM_READWRITE8(pc9801rs_2hd_r, pc9801rs_2hd_w, 0xffffffff) |
| 1989 | 2030 | // AM_RANGE(0x00d8, 0x00df) AMD98 (sound?) board |
| 1990 | 2031 | AM_RANGE(0x00f0, 0x00ff) AM_READWRITE8(pc9801rs_f0_r, pc9801rs_f0_w, 0xffffffff) |
| 1991 | | // AM_RANGE(0x0188, 0x018b) YM2203 OPN board / <undefined> |
| 2032 | AM_RANGE(0x0188, 0x018b) AM_READWRITE8(pc9801_opn_r, pc9801_opn_w, 0xffffffff) //ym2203 opn / <undefined> |
| 1992 | 2033 | // AM_RANGE(0x018c, 0x018f) YM2203 OPN extended ports / <undefined> |
| 1993 | 2034 | // AM_RANGE(0x0430, 0x0430) IDE bank register |
| 1994 | 2035 | // AM_RANGE(0x0432, 0x0432) IDE bank register (mirror) |
| r19303 | r19304 | |
| 2724 | 2765 | |
| 2725 | 2766 | void pc9801_state::pc9801rs_fdc_drq(bool state) |
| 2726 | 2767 | { |
| 2727 | | printf("DRQ %d\n",state); |
| 2768 | // printf("DRQ %d\n",state); |
| 2728 | 2769 | |
| 2729 | 2770 | if(m_fdc_ctrl & 1) |
| 2730 | 2771 | m_dmac->dreq2_w(state ^ 1); |
| r19303 | r19304 | |
| 2783 | 2824 | m_ipl_rom = memregion("ipl")->base(); |
| 2784 | 2825 | m_pcg_ram = auto_alloc_array(machine(), UINT8, 0x80000); |
| 2785 | 2826 | |
| 2827 | m_support_16_colors = 0; |
| 2786 | 2828 | state_save_register_global_pointer(machine(), m_pcg_ram, 0x80000); |
| 2787 | 2829 | } |
| 2788 | 2830 | |
| r19303 | r19304 | |
| 2826 | 2868 | state_save_register_global_pointer(machine(), m_work_ram, 0xa0000); |
| 2827 | 2869 | state_save_register_global_pointer(machine(), m_ext_work_ram, 0x700000); |
| 2828 | 2870 | |
| 2871 | m_support_16_colors = 1; |
| 2872 | |
| 2829 | 2873 | upd765a_device *fdc; |
| 2830 | 2874 | fdc = machine().device<upd765a_device>(":upd765_2hd"); |
| 2831 | 2875 | fdc->setup_intrq_cb(upd765a_device::line_cb(FUNC(pc9801_state::pc9801rs_fdc_irq), this)); |
| r19303 | r19304 | |
| 2939 | 2983 | { |
| 2940 | 2984 | // pc9801_state *state = device->machine().driver_data<pc9801_state>(); |
| 2941 | 2985 | |
| 2986 | /* TODO: seems to die very often */ |
| 2942 | 2987 | pic8259_ir4_w(device->machine().device("pic8259_slave"), irq); |
| 2943 | 2988 | } |
| 2944 | 2989 | |
| r19303 | r19304 | |
| 3084 | 3129 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 3085 | 3130 | |
| 3086 | 3131 | MCFG_SOUND_ADD("opn", YM2203, 4000000) // unknown clock / divider |
| 3132 | MCFG_SOUND_CONFIG(pc98_ym2203_intf) |
| 3087 | 3133 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |
| 3088 | 3134 | |
| 3089 | 3135 | MCFG_SOUND_ADD(BEEPER_TAG, BEEP, 0) |
| r19303 | r19304 | |
| 3145 | 3191 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 3146 | 3192 | |
| 3147 | 3193 | MCFG_SOUND_ADD("opn", YM2203, 4000000) // unknown clock / divider |
| 3194 | MCFG_SOUND_CONFIG(pc98_ym2203_intf) |
| 3148 | 3195 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.50) |
| 3149 | 3196 | |
| 3150 | 3197 | MCFG_SOUND_ADD(BEEPER_TAG, BEEP, 0) |