src/mess/drivers/pc8801.c
| r10108 | r10109 | |
| 2 | 2 | |
| 3 | 3 | PC-8801 (c) 1981 NEC |
| 4 | 4 | |
| 5 | | preliminary driver by Angelo Salese, original MESS PC-88SR by ??? |
| 5 | preliminary driver by Angelo Salese, original MESS PC-88SR driver by ??? |
| 6 | 6 | |
| 7 | 7 | TODO: |
| 8 | | - used to do more, currently under rewriting stage. We are currently using plain PC-8801 as the base, will add differences for the |
| 9 | | later models at some point. |
| 10 | | - macros for the various rom / ram areas, it might require various attempts in order to finally get a reasonable arrangement ... |
| 11 | | - dipswitches are WRONG |
| 8 | - add differences between various models; |
| 12 | 9 | - implement proper i8214 routing, also add irq latch mechanism; |
| 13 | 10 | - implement proper upd3301 / i8257 support; |
| 14 | 11 | - below notes states that plain PC-8801 doesn't have a disk CPU, but the BIOS clearly checks the floppy ports. Wrong info? |
| 15 | | - joystick / mouse support; |
| 12 | - mouse support; |
| 16 | 13 | - cursor is 8 x 10, not 8 x 8 as current implementation. |
| 17 | | - text DMAC stuff isn't well documented; |
| 18 | | - CRTC really looks like to be a MCU; |
| 19 | 14 | - needs to support V1 / V2 properly; |
| 20 | 15 | - Add limits for extend work RAM; |
| 16 | - Later models have palette bugs with some games (Alphos, Tokyo Nampa Street), check out why; |
| 21 | 17 | - What happens to the palette contents when the analog/digital palette mode changes? |
| 18 | - dipswitches needs to be controlled; |
| 22 | 19 | |
| 23 | | list of games that crashes due of floppy issues: |
| 24 | | - Bokosuka Wars |
| 25 | | - Bouken Roman |
| 26 | | - Bruce Lee |
| 27 | | - Castle Excellent |
| 28 | | - Tobira wo Akete (in parent pc8801 only) |
| 29 | | |
| 30 | 20 | per-game specific TODO: |
| 31 | 21 | - 100 Yen disk(s): reads kanji ports; |
| 32 | | - 177: gameplay is too fast; |
| 22 | - 177: gameplay is too fast (parent pc8801 only); |
| 33 | 23 | - Acro Jet: hangs waiting for an irq; |
| 34 | 24 | - American Success: reads the light pen? |
| 35 | 25 | - Alpha (demo): crashes with "illegal function" msg; |
| 36 | | - Alphos: text VRAM garbage during gameplay; |
| 37 | 26 | - Balance of Power: attempt to use the SIO port for mouse polling, worked around for now; |
| 38 | | - Battle Entry: moans with a kanji msg then dies if you try to press either numpad 1 or 2 (what it basically asks by looking at the DASM) |
| 39 | | - Bersekers Front Gaiden 3: checks CPU speed port and polls the PCG stuff too; |
| 27 | - Balance of Power: moans with a JP msg; |
| 28 | - Battle Entry: moans with a JP msg then dies if you try to press either numpad 1 or 2 (asks if the user wants to use the sound board (yes 1 / no 2) |
| 40 | 29 | - Bishoujo Baseball Gakuen: checks ym2608 after intro screen; |
| 41 | 30 | - Blue Moon Story: moans with a kanji msg;. |
| 42 | 31 | - Bu U Ma: sets gfx compatibility mode on title screen (attr bit 4,N-BASIC), dunno how to draw with it ...; |
| 43 | | - Grobda: palette is ugly; |
| 44 | | - Wanderers from Ys: user data looks screwed? It loads with everything as maximum as per now ... |
| 45 | | - Xevious: game is too fast |
| 32 | - Grobda: palette is ugly (parent pc8801 only); |
| 33 | - Wanderers from Ys: user data disk looks screwed? It loads with everything as maximum as per now ... |
| 34 | - Wanderers from Ys: sound crashes at some point, presumably irq issue; |
| 35 | - Xevious: game is too fast (parent pc8801 only) |
| 46 | 36 | |
| 37 | list of games that crashes due of floppy issues: |
| 38 | - Bersekers Front Gaiden 3 |
| 39 | - Bokosuka Wars |
| 40 | - Bouken Roman |
| 41 | - Bruce Lee |
| 42 | - Castle Excellent |
| 43 | - Tobira wo Akete (random crashes in parent pc8801 only) |
| 44 | |
| 45 | games that needs to NOT have write-protect floppies (BTANBs): |
| 46 | - Tobira wo Akete (hangs at title screen) |
| 47 | |
| 48 | |
| 47 | 49 | Notes: |
| 48 | 50 | - BIOS disk ROM defines what kind of floppies you could load: |
| 49 | 51 | * with 0x0800 ROM size you can load 2d floppies only; |
| r10108 | r10109 | |
| 352 | 354 | UINT8 y_height; |
| 353 | 355 | UINT8 attr; |
| 354 | 356 | UINT8 reverse; |
| 355 | | UINT8 pal; |
| 356 | | UINT8 gfx_mode; |
| 357 | int pal; |
| 358 | //UINT8 gfx_mode; |
| 357 | 359 | |
| 358 | 360 | y_height = y_size == 20 ? 10 : 8; |
| 359 | 361 | |
| r10108 | r10109 | |
| 366 | 368 | if(text_color_flag) |
| 367 | 369 | { |
| 368 | 370 | pal = (attr & 0xe0) >> 5; |
| 369 | | gfx_mode = (attr & 0x10) >> 4; |
| 371 | //gfx_mode = (attr & 0x10) >> 4; |
| 370 | 372 | reverse = 0; |
| 373 | pal|=8; //text pal bank |
| 371 | 374 | } |
| 372 | 375 | else |
| 373 | 376 | { |
| 374 | | pal = 7; |
| 377 | pal = (txt_color) ? 7 : 0; |
| 375 | 378 | reverse = attr & 4; |
| 379 | pal|=8; //text pal bank |
| 376 | 380 | } |
| 377 | 381 | |
| 378 | | pal|=8; //text pal bank |
| 379 | | |
| 380 | 382 | for(yi=0;yi<8;yi++) |
| 381 | 383 | { |
| 382 | 384 | is_cursor = calc_cursor_pos(machine,x,y,yi); |
| r10108 | r10109 | |
| 419 | 421 | UINT8 y_height; |
| 420 | 422 | UINT8 attr; |
| 421 | 423 | UINT8 reverse; |
| 422 | | UINT8 pal; |
| 424 | int pal; |
| 423 | 425 | |
| 424 | 426 | y_height = y_size == 20 ? 10 : 8; |
| 425 | 427 | |
| r10108 | r10109 | |
| 435 | 437 | if(text_color_flag) |
| 436 | 438 | { |
| 437 | 439 | pal = (attr & 0xe0) >> 5; |
| 440 | //gfx_mode = (attr & 0x10) >> 4; |
| 438 | 441 | reverse = 0; |
| 442 | pal|=8; //text pal bank |
| 439 | 443 | } |
| 440 | 444 | else |
| 441 | 445 | { |
| 442 | | pal = 7; |
| 446 | pal = (txt_color) ? 7 : 0; |
| 443 | 447 | reverse = attr & 4; |
| 448 | pal|=8; //text pal bank |
| 444 | 449 | } |
| 445 | 450 | |
| 446 | | pal|=8; //text pal bank |
| 447 | | |
| 448 | | |
| 449 | 451 | for(yi=0;yi<8;yi++) |
| 450 | 452 | { |
| 451 | 453 | is_cursor = calc_cursor_pos(machine,x,y,yi); |
| r10108 | r10109 | |
| 491 | 493 | draw_bitmap_1bpp(screen->machine,bitmap); |
| 492 | 494 | } |
| 493 | 495 | |
| 496 | //popmessage("%02x %02x %02x %02x",layer_mask,dmac_mode,crtc.status,crtc.irq_mask); |
| 497 | |
| 494 | 498 | if(!(layer_mask & 1) && dmac_mode & 4 && crtc.status & 0x10 && crtc.irq_mask == 3) |
| 495 | 499 | { |
| 496 | 500 | static int y_size; |
| r10108 | r10109 | |
| 802 | 806 | static WRITE8_HANDLER( pc8801_ctrl_w ) |
| 803 | 807 | { |
| 804 | 808 | /* |
| 805 | | x--- ---- beeper (mirror?) |
| 809 | x--- ---- SING (buzzer mirror?) |
| 806 | 810 | -x-- ---- mouse latch (JOP1, routes on OPN sound port A) |
| 807 | 811 | --x- ---- beeper |
| 808 | 812 | --- |
| r10108 | r10109 | |
| 1012 | 1016 | switch(crtc.cmd) |
| 1013 | 1017 | { |
| 1014 | 1018 | case 0: // reset CRTC |
| 1015 | | crtc.status &= (~0x10 | ~0x04 | ~0x02); |
| 1019 | crtc.status &= (~0x16); |
| 1016 | 1020 | break; |
| 1017 | 1021 | case 1: // start display |
| 1018 | 1022 | crtc.status |= 0x10; |
| 1019 | 1023 | crtc.status &= (~0x08); |
| 1020 | 1024 | if(data & 1) |
| 1021 | 1025 | printf("CRTC reverse display ON\n"); |
| 1022 | | |
| 1023 | 1026 | break; |
| 1024 | 1027 | case 2: // set irq mask |
| 1025 | 1028 | crtc.irq_mask = data & 3; |
| r10108 | r10109 | |
| 1032 | 1035 | break; |
| 1033 | 1036 | case 5: // reset IRQ |
| 1034 | 1037 | case 6: // reset counters |
| 1035 | | crtc.status &= (~0x04 | ~0x02); |
| 1038 | crtc.status &= (~0x06); |
| 1036 | 1039 | break; |
| 1037 | 1040 | } |
| 1038 | 1041 | |
| r10108 | r10109 | |
| 1110 | 1113 | |
| 1111 | 1114 | txt_width = data & 1; |
| 1112 | 1115 | txt_color = data & 2; |
| 1116 | if((data & 2) == 0) |
| 1117 | printf("TEXT COLOR is black\n"); |
| 1113 | 1118 | } |
| 1114 | 1119 | |
| 1115 | 1120 | static UINT32 knj_addr[2]; |
| r10108 | r10109 | |
| 1172 | 1177 | AM_RANGE(0x34, 0x34) AM_WRITE(pc8801_alu_ctrl1_w) |
| 1173 | 1178 | AM_RANGE(0x35, 0x35) AM_WRITE(pc8801_alu_ctrl2_w) |
| 1174 | 1179 | AM_RANGE(0x40, 0x40) AM_READWRITE(pc8801_ctrl_r, pc8801_ctrl_w) |
| 1175 | | AM_RANGE(0x44, 0x45) AM_DEVREADWRITE("ym2203", ym2203_r,ym2203_w) |
| 1180 | AM_RANGE(0x44, 0x45) AM_DEVREADWRITE("opn", ym2203_r,ym2203_w) |
| 1176 | 1181 | // AM_RANGE(0x46, 0x47) AM_NOP /* OPNA extra port */ |
| 1177 | 1182 | AM_RANGE(0x50, 0x50) AM_READWRITE(pc8801_crtc_param_r, pc88_crtc_param_w) |
| 1178 | 1183 | AM_RANGE(0x51, 0x51) AM_READWRITE(pc8801_crtc_status_r, pc88_crtc_cmd_w) |
| r10108 | r10109 | |
| 1529 | 1534 | PORT_DIPSETTING( 0x80, "9600bps" ) |
| 1530 | 1535 | PORT_DIPSETTING( 0x90, "19200bps" ) |
| 1531 | 1536 | |
| 1532 | | PORT_START("OPNA") |
| 1537 | PORT_START("OPN_PA") |
| 1533 | 1538 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) |
| 1534 | 1539 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) |
| 1535 | 1540 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) |
| 1536 | 1541 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) |
| 1537 | 1542 | PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 1538 | 1543 | |
| 1539 | | PORT_START("OPNB") |
| 1544 | PORT_START("OPN_PB") |
| 1540 | 1545 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) |
| 1541 | 1546 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) |
| 1542 | 1547 | PORT_BIT( 0xfc, IP_ACTIVE_LOW, IPT_UNUSED ) |
| r10108 | r10109 | |
| 1614 | 1619 | } |
| 1615 | 1620 | |
| 1616 | 1621 | /* TODO: mouse routing (that's why I don't use DEVCB_INPUT_PORT here) */ |
| 1617 | | static READ8_DEVICE_HANDLER( opn_porta_r ) { return input_port_read(device->machine, "OPNA"); } |
| 1618 | | static READ8_DEVICE_HANDLER( opn_portb_r ) { return input_port_read(device->machine, "OPNB"); } |
| 1622 | static READ8_DEVICE_HANDLER( opn_porta_r ) { return input_port_read(device->machine, "OPN_PA"); } |
| 1623 | static READ8_DEVICE_HANDLER( opn_portb_r ) { return input_port_read(device->machine, "OPN_PB"); } |
| 1619 | 1624 | |
| 1620 | 1625 | static const ym2203_interface pc88_ym2203_intf = |
| 1621 | 1626 | { |
| r10108 | r10109 | |
| 1698 | 1703 | cpu_set_input_line_vector(machine->device("fdccpu"), 0, 0); |
| 1699 | 1704 | |
| 1700 | 1705 | { |
| 1706 | txt_color = 2; |
| 1707 | } |
| 1708 | |
| 1709 | { |
| 1701 | 1710 | int i; |
| 1702 | 1711 | |
| 1703 | 1712 | for(i=0;i<3;i++) |
| r10108 | r10109 | |
| 1805 | 1814 | |
| 1806 | 1815 | /* sound hardware */ |
| 1807 | 1816 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 1808 | | MCFG_SOUND_ADD("ym2203", YM2203, 4000000) //unknown clock |
| 1817 | MCFG_SOUND_ADD("opn", YM2203, 4000000) //unknown clock |
| 1809 | 1818 | MCFG_SOUND_CONFIG(pc88_ym2203_intf) |
| 1810 | 1819 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25) |
| 1811 | 1820 | |