src/mess/drivers/mz2500.c
| r9031 | r9032 | |
| 5 | 5 | driver by Angelo Salese |
| 6 | 6 | |
| 7 | 7 | TODO: |
| 8 | | - Kanji text is cutted in half when font_size is 1 / interlace is disabled, different data used? (check Back to the Future); |
| 8 | - Kanji text is cutted in half when font_size is 1 / interlace is disabled, different ROM used? (check Back to the Future); |
| 9 | 9 | - Find real CRTC registers |
| 10 | 10 | - Some games doesn't set proper registers if you have interlace enabled, is there any real reason? |
| 11 | 11 | - Implement external ROM hook-up; |
| 12 | 12 | - FDC loading without the IPLPRO doesn't work at all, why? |
| 13 | 13 | - reverse / blanking tvram attributes; |
| 14 | - there's a soft reset PCG init bug now (try for example Eiyuu Densetsu Saga then Excite Bike); |
| 14 | 15 | - clean-ups! ^^' |
| 15 | 16 | |
| 16 | 17 | per-game/program specific TODO: |
| 17 | 18 | - Basic: vertical scrolling returns wrap-around that shouldn't wrap; |
| 18 | | - Basic: loading has an alignment bug with the bitmap |
| 19 | - Dust Box vol. n: they all dies after pressing a key on the 256 color CG layer shows up; |
| 20 | - Dust Box vol. n: three items returns "purple" text, presumably HW failures; |
| 21 | - Dust Box vol. 4: window effect transition is bugged; |
| 19 | 22 | - LayDock: hangs by reading the FDC status and expecting it to become 0x81; |
| 20 | | - Mappy: TVRAM layer is double x sized than it should be; |
| 21 | | - Marchen Veil I: dies with garbage on screen; |
| 22 | 23 | - Moon Child: needs mixed 3+3bpp tvram supported; |
| 23 | 24 | - Moon Child: appears to be a network / system link game, obviously doesn't work with current MAME / MESS framework; |
| 24 | | - Mugen no Shinzou: returns an HW error if you attempt to start a play; |
| 25 | - Mugen no Shinzou: returns an HW error if you attempt to start a play, it seems to be a fdc writing issue; |
| 25 | 26 | - Mugen no Shinzou II - The Prince of Darkness: dies on IPLPRO loading, presumably a wd17xx core bug; |
| 26 | 27 | - Multiplan: random hangs/crashes after you set the RTC, sometimes it loads properly; |
| 27 | 28 | - Murder Club: has lots of CG artifacts; |
| 28 | 29 | - Penguin Kun Wars: has a bug with window effects ("Push space or trigger" msg on the bottom"), needs investigation; |
| 29 | 30 | - Relics: doesn't boot, sets fdc register 0xdc bit 2 to 1 |
| 30 | | - Sound Gal Music Editor: dies with bad code, another wd17xx core bug; |
| 31 | - Sound Gal Music Editor: wants a "master disk", that apparently isn't available; |
| 32 | - Super MZ Demo: priority doesn't work properly on the "face" item; |
| 31 | 33 | - Telephone Soft: shows garbage with the CG layer; |
| 32 | 34 | - The Tower of Druaga: has a small priority/layer clearance bug at the digital / analog screen select; |
| 33 | 35 | - Xevious: has issues with the window effects, it should actually be applied on TV layer and not CG. |
| 34 | | - Ys 3: has garbage on top / bottom (note: you have to load both disks at start-up otherwise it refuses to run) |
| 36 | - Ys 3: has garbage on top / bottom (note: you have to load both disks at start-up otherwise it refuses to run), same issue as the Basic one; |
| 35 | 37 | - Yukar K2 (normal version): moans about something, DFJustin: "please put the system disk back to normal", disk write-protected? |
| 36 | 38 | |
| 37 | 39 | memory map: |
| r9031 | r9032 | |
| 82 | 84 | static UINT8 text_reg[0x100], text_reg_index; |
| 83 | 85 | static UINT8 text_col_size, text_font_reg; |
| 84 | 86 | static UINT8 pal_select; |
| 85 | | static UINT8 wid_40; |
| 86 | 87 | static UINT16 cg_vs,cg_ve,cg_hs,cg_he; //CG window parameters |
| 87 | 88 | static UINT8 cg_latch[4]; |
| 88 | 89 | static UINT8 cg_reg_index; |
| r9031 | r9032 | |
| 90 | 91 | static UINT8 clut16[0x10]; |
| 91 | 92 | static UINT16 clut256[0x100]; |
| 92 | 93 | static UINT8 cg_mask; |
| 94 | static int scr_x_size,scr_y_size; |
| 93 | 95 | |
| 94 | 96 | static VIDEO_START( mz2500 ) |
| 95 | 97 | { |
| r9031 | r9032 | |
| 151 | 153 | int tile_bank = vram[0x70000+count+0x1000] & 0x3f; |
| 152 | 154 | int gfx_sel = (attr & 0x38) | (vram[0x70000+count+0x1000] & 0xc0); |
| 153 | 155 | int color = attr & 7; |
| 156 | int inv_col = (attr & 0x40) >> 6; |
| 154 | 157 | |
| 155 | 158 | if(gfx_sel & 8) // Xevious, PCG 8 colors have priority above kanji roms |
| 156 | 159 | gfx_data = memory_region(machine,"pcg"); |
| r9031 | r9032 | |
| 187 | 190 | pen_bit[2] = ((gfx_data[tile*8+yi+0x0800]>>(7-xi)) & 1) ? 1 : 0; //B |
| 188 | 191 | |
| 189 | 192 | pen = (pen_bit[0]|pen_bit[1]|pen_bit[2]); |
| 193 | |
| 194 | if(inv_col) { pen ^= 7; } |
| 190 | 195 | } |
| 191 | 196 | else |
| 192 | 197 | { |
| 193 | | pen = ((gfx_data[tile*8+yi+((gfx_sel & 0x30)<<7)]>>(7-xi)) & 1) ? color : 0; |
| 198 | pen = (((gfx_data[tile*8+yi+((gfx_sel & 0x30)<<7)]>>(7-xi)) & 1) ^ inv_col) ? color : 0; |
| 194 | 199 | } |
| 195 | 200 | |
| 196 | | if(attr & 0x40) |
| 197 | | pen ^= 0x7; |
| 198 | | |
| 199 | 201 | if(pen) |
| 200 | 202 | { |
| 201 | 203 | if((y*8+yi-s_y) >= 0 && (y*8+yi-s_y) < 200*y_step) |
| r9031 | r9032 | |
| 233 | 235 | int gfx_sel = (attr & 0x38) | (vram[0x70000+count+0x1000] & 0xc0); |
| 234 | 236 | //int gfx_num; |
| 235 | 237 | int color = attr & 7; |
| 238 | int inv_col = (attr & 0x40) >> 6; |
| 236 | 239 | |
| 237 | 240 | if(gfx_sel & 8) // Xevious, PCG 8 colors have priority above kanji roms |
| 238 | 241 | gfx_data = memory_region(machine,"pcg"); |
| r9031 | r9032 | |
| 269 | 272 | pen_bit[2] = ((gfx_data[tile*8+yi+0x0800]>>(7-xi)) & 1) ? 1 : 0; //B |
| 270 | 273 | |
| 271 | 274 | pen = (pen_bit[0]|pen_bit[1]|pen_bit[2]); |
| 275 | |
| 276 | if(inv_col) { pen ^= 7; } |
| 272 | 277 | } |
| 273 | 278 | else |
| 274 | | pen = ((gfx_data[tile*8+yi+((gfx_sel & 0x30)<<7)]>>(7-xi)) & 1) ? color : 0; |
| 279 | pen = (((gfx_data[tile*8+yi+((gfx_sel & 0x30)<<7)]>>(7-xi)) & 1) ^ inv_col) ? color : 0; |
| 275 | 280 | |
| 276 | | if(attr & 0x40) |
| 277 | | pen ^= 0x7; |
| 278 | | |
| 279 | 281 | if(pen) |
| 280 | 282 | { |
| 281 | | if(wid_40) // 640 x 200 with 40 x 25, double x size |
| 282 | | { |
| 283 | | if((y*8+yi-s_y) >= 0 && (y*8+yi-s_y) < 200*y_step) |
| 284 | | mz2500_draw_pixel(machine,bitmap,x*8+xi,y*8+yi-s_y,pen+(pal_select ? 0x000 : 0x18),1,0); |
| 285 | | } |
| 286 | | else |
| 287 | | { |
| 288 | | if((y*8+yi-s_y) >= 0 && (y*8+yi-s_y) < 200*y_step) |
| 289 | | mz2500_draw_pixel(machine,bitmap,x*8+xi,y*8+yi-s_y,pen+(pal_select ? 0x000 : 0x18),0,0); |
| 290 | | } |
| 283 | if((y*8+yi-s_y) >= 0 && (y*8+yi-s_y) < 200*y_step) |
| 284 | mz2500_draw_pixel(machine,bitmap,x*8+xi,y*8+yi-s_y,pen+(pal_select ? 0x000 : 0x18),scr_x_size == 640,0); |
| 291 | 285 | } |
| 292 | 286 | } |
| 293 | 287 | } |
| r9031 | r9032 | |
| 384 | 378 | for(pen_i=0;pen_i<4;pen_i++) |
| 385 | 379 | pen |= pen_bit[pen_i]; |
| 386 | 380 | |
| 387 | | if(cg_interlace == 2) |
| 388 | | { |
| 389 | | if(pri == ((clut16[pen] & 0x10) >> 4)) |
| 390 | | mz2500_draw_pixel(machine,bitmap,res_x,res_y,(clut16[pen] & 0x0f)+0x10,0,1); |
| 391 | | |
| 392 | | } |
| 393 | | else |
| 394 | | { |
| 395 | | if(pri == ((clut16[pen] & 0x10) >> 4)) |
| 396 | | mz2500_draw_pixel(machine,bitmap,res_x,res_y,(clut16[pen] & 0x0f)+0x10,0,0); |
| 397 | | } |
| 381 | if(pri == ((clut16[pen] & 0x10) >> 4)) |
| 382 | mz2500_draw_pixel(machine,bitmap,res_x,res_y,(clut16[pen] & 0x0f)+0x10,(x_size == 320 && scr_x_size == 640),cg_interlace == 2); |
| 398 | 383 | } |
| 399 | 384 | count++; |
| 400 | 385 | count&=((base_mask<<8) | 0xff); |
| r9031 | r9032 | |
| 442 | 427 | for(pen_i=0;pen_i<8;pen_i++) |
| 443 | 428 | pen |= pen_bit[pen_i]; |
| 444 | 429 | |
| 445 | | if(cg_interlace == 2) |
| 446 | | { |
| 447 | | if(pri == ((clut256[pen] & 0x100) >> 8)) |
| 448 | | mz2500_draw_pixel(machine,bitmap,res_x,res_y,(clut256[pen] & 0xff)+0x100,0,1); |
| 449 | | } |
| 450 | | else |
| 451 | | { |
| 452 | | if(pri == ((clut256[pen] & 0x100) >> 8)) |
| 453 | | mz2500_draw_pixel(machine,bitmap,res_x,res_y,(clut256[pen] & 0xff)+0x100,0,0); |
| 454 | | } |
| 430 | if(pri == ((clut256[pen] & 0x100) >> 8)) |
| 431 | mz2500_draw_pixel(machine,bitmap,res_x,res_y,(clut256[pen] & 0xff)+0x100,scr_x_size == 640,cg_interlace == 2); |
| 455 | 432 | } |
| 456 | 433 | count++; |
| 457 | 434 | } |
| r9031 | r9032 | |
| 533 | 510 | return 0; |
| 534 | 511 | } |
| 535 | 512 | |
| 513 | static void mz2500_reconfigure_screen(running_machine *machine) |
| 514 | { |
| 515 | rectangle visarea; |
| 516 | |
| 517 | if((cg_reg[0x0e] & 0x1f) == 0x17 || (cg_reg[0x0e] & 0x1f) == 0x03 || text_col_size) |
| 518 | scr_x_size = 640; |
| 519 | else |
| 520 | scr_x_size = 320; |
| 521 | |
| 522 | if((cg_reg[0x0e] & 0x1f) == 0x03) |
| 523 | scr_y_size = 400; |
| 524 | else |
| 525 | scr_y_size = 200 * ((text_font_reg) ? 1 : 2); |
| 526 | |
| 527 | visarea.min_x = 0; |
| 528 | visarea.min_y = 0; |
| 529 | visarea.max_x = scr_x_size - 1; |
| 530 | visarea.max_y = scr_y_size - 1; |
| 531 | |
| 532 | //popmessage("%d %d %d %d %02x",vs,ve,hs,he,cg_reg[0x0e]); |
| 533 | |
| 534 | machine->primary_screen->configure(720, 480, visarea, machine->primary_screen->frame_period().attoseconds); |
| 535 | } |
| 536 | |
| 536 | 537 | static UINT8 mz2500_cg_latch_compare(void) |
| 537 | 538 | { |
| 538 | 539 | UINT8 compare_val = cg_reg[0x07] & 0xf; |
| r9031 | r9032 | |
| 931 | 932 | case 3: |
| 932 | 933 | /* Font size reg */ |
| 933 | 934 | text_font_reg = data & 1; |
| 935 | mz2500_reconfigure_screen(space->machine); |
| 934 | 936 | break; |
| 935 | 937 | } |
| 936 | 938 | } |
| r9031 | r9032 | |
| 1182 | 1184 | } |
| 1183 | 1185 | } |
| 1184 | 1186 | |
| 1185 | | { |
| 1186 | | rectangle visarea; |
| 1187 | | static int x_size,y_size; |
| 1187 | cg_vs = (cg_reg[0x08]) | ((cg_reg[0x09]<<8) & 1); |
| 1188 | cg_ve = (cg_reg[0x0a]) | ((cg_reg[0x0b]<<8) & 1); |
| 1189 | cg_hs = (cg_reg[0x0c] & 0x7f)*8; |
| 1190 | cg_he = (cg_reg[0x0d] & 0x7f)*8; |
| 1188 | 1191 | |
| 1189 | | /* TODO: not convinced about this arrangement ... */ |
| 1190 | | x_size = ((cg_reg[0x0e] & 0x1f) == 0x17 || (cg_reg[0x0e] & 0x1f) == 0x03) ? 640 : 320; |
| 1191 | | y_size = ((cg_reg[0x0e] & 0x1f) == 0x03) ? 400 : 200*((text_font_reg) ? 1 : 2); //enables interlace? |
| 1192 | | |
| 1193 | | visarea.min_x = 0; |
| 1194 | | visarea.min_y = 0; |
| 1195 | | visarea.max_x = x_size - 1; |
| 1196 | | visarea.max_y = y_size - 1; |
| 1197 | | |
| 1198 | | wid_40 = (x_size == 640); |
| 1199 | | |
| 1200 | | cg_vs = (cg_reg[0x08]) | ((cg_reg[0x09]<<8) & 1); |
| 1201 | | cg_ve = (cg_reg[0x0a]) | ((cg_reg[0x0b]<<8) & 1); |
| 1202 | | cg_hs = (cg_reg[0x0c] & 0x7f)*8; |
| 1203 | | cg_he = (cg_reg[0x0d] & 0x7f)*8; |
| 1204 | | |
| 1205 | | //popmessage("%d %d %d %d %02x",vs,ve,hs,he,cg_reg[0x0e]); |
| 1206 | | |
| 1207 | | space->machine->primary_screen->configure(720, 480, visarea, space->machine->primary_screen->frame_period().attoseconds); //TODO |
| 1192 | { |
| 1193 | mz2500_reconfigure_screen(space->machine); |
| 1208 | 1194 | } |
| 1209 | 1195 | |
| 1210 | 1196 | if(cg_reg_index & 0x80) //enable auto-inc |
| r9031 | r9032 | |
| 1413 | 1399 | PORT_BIT(0x80,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("BREAK") //PORT_CODE(KEYCODE_ESC) |
| 1414 | 1400 | |
| 1415 | 1401 | PORT_START("KEY4") |
| 1416 | | PORT_BIT(0x01,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("/") PORT_CODE(KEYCODE_SLASH) |
| 1402 | PORT_BIT(0x01,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("/") //PORT_CODE(KEYCODE_SLASH) |
| 1417 | 1403 | PORT_BIT(0x02,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') |
| 1418 | 1404 | PORT_BIT(0x04,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') |
| 1419 | 1405 | PORT_BIT(0x08,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') |
| r9031 | r9032 | |
| 1467 | 1453 | PORT_BIT(0x02,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') |
| 1468 | 1454 | PORT_BIT(0x04,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME(":") |
| 1469 | 1455 | PORT_BIT(0x08,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME(";") |
| 1470 | | PORT_BIT(0x10,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("-") |
| 1456 | PORT_BIT(0x10,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("-") PORT_CODE(KEYCODE_MINUS) |
| 1471 | 1457 | PORT_BIT(0x20,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("@") |
| 1472 | 1458 | PORT_BIT(0x40,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("[") |
| 1473 | 1459 | PORT_BIT(0x80,IP_ACTIVE_LOW,IPT_UNUSED) |
| r9031 | r9032 | |
| 1477 | 1463 | PORT_BIT(0x02,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("COPY") |
| 1478 | 1464 | PORT_BIT(0x04,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("CLR") |
| 1479 | 1465 | PORT_BIT(0x08,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("INST") |
| 1480 | | PORT_BIT(0x10,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("BS") |
| 1466 | PORT_BIT(0x10,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) |
| 1481 | 1467 | PORT_BIT(0x20,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("ESC") |
| 1482 | 1468 | PORT_BIT(0x40,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("* (PAD)") PORT_CODE(KEYCODE_ASTERISK) |
| 1483 | 1469 | PORT_BIT(0x80,IP_ACTIVE_LOW,IPT_KEYBOARD) PORT_NAME("/ (PAD)") PORT_CODE(KEYCODE_SLASH_PAD) |
| r9031 | r9032 | |
| 1713 | 1699 | |
| 1714 | 1700 | static WRITE8_DEVICE_HANDLER( mz2500_pio1_porta_w ) |
| 1715 | 1701 | { |
| 1702 | static UINT8 prev_col_val; |
| 1716 | 1703 | // printf("%02x\n",data); |
| 1717 | | text_col_size = (data & 0x20) ? 1 : 0; |
| 1704 | |
| 1705 | if(prev_col_val != ((data & 0x20) >> 5)) |
| 1706 | { |
| 1707 | text_col_size = ((data & 0x20) >> 5); |
| 1708 | prev_col_val = text_col_size; |
| 1709 | mz2500_reconfigure_screen(device->machine); |
| 1710 | } |
| 1718 | 1711 | key_mux = data & 0x1f; |
| 1719 | 1712 | } |
| 1720 | 1713 | |
| r9031 | r9032 | |
| 1897 | 1890 | /* video hardware */ |
| 1898 | 1891 | MDRV_SCREEN_ADD("screen", RASTER) |
| 1899 | 1892 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 1900 | | //MDRV_SCREEN_RAW_PARAMS(XTAL_17_73447MHz/2, 568, 0, 320, 312, 0, 200) |
| 1901 | | MDRV_SCREEN_RAW_PARAMS(XTAL_17_73447MHz, 640+108, 0, 320, 480, 0, 200) //TODO: fix this |
| 1893 | MDRV_SCREEN_RAW_PARAMS(XTAL_21_4772MHz, 640+108, 0, 320, 480, 0, 200) //unknown clock / divider |
| 1902 | 1894 | MDRV_PALETTE_LENGTH(0x200) |
| 1903 | 1895 | MDRV_PALETTE_INIT(mz2500) |
| 1904 | 1896 | |
| r9031 | r9032 | |
| 1909 | 1901 | |
| 1910 | 1902 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| 1911 | 1903 | |
| 1912 | | MDRV_SOUND_ADD("ym", YM2203, 6000000/4) //unknown clock / divider |
| 1904 | MDRV_SOUND_ADD("ym", YM2203, 2000000) //unknown clock / divider |
| 1913 | 1905 | MDRV_SOUND_CONFIG(ym2203_interface_1) |
| 1914 | | MDRV_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.60) |
| 1906 | MDRV_SOUND_ROUTE(0, "mono", 0.25) |
| 1907 | MDRV_SOUND_ROUTE(1, "mono", 0.25) |
| 1908 | MDRV_SOUND_ROUTE(2, "mono", 0.50) |
| 1909 | MDRV_SOUND_ROUTE(3, "mono", 0.50) |
| 1915 | 1910 | |
| 1916 | 1911 | MDRV_PIT8253_ADD("pit", mz2500_pit8253_intf) |
| 1917 | 1912 | MACHINE_CONFIG_END |
| r9031 | r9032 | |
| 1951 | 1946 | |
| 1952 | 1947 | /* Driver */ |
| 1953 | 1948 | |
| 1954 | | COMP( 1985, mz2500, 0, 0, mz2500, mz2500, 0, "Sharp", "MZ-2500", GAME_NOT_WORKING | GAME_NO_SOUND) |
| 1949 | COMP( 1985, mz2500, 0, 0, mz2500, mz2500, 0, "Sharp", "MZ-2500", 0 ) |