trunk/src/mess/drivers/pc9801.c
| r19396 | r19397 | |
| 33 | 33 | - Microsoft Windows 1.0 MSDOS.SYS error (can be bypassed by loading MS-DOS first) |
| 34 | 34 | \- these two happens due of a fail in sense drive status command, ready line (bit 5) |
| 35 | 35 | |
| 36 | | - Dokkin Minako Sensei! |
| 36 | - Dokkin Minako Sensei |
| 37 | 37 | |
| 38 | | |
| 39 | 38 | List of per-game TODO: |
| 40 | 39 | - 4D Boxing: tries to format User Disk; |
| 40 | - 4D Driving: accesses some undefined ports (guess that it accesses the low part of them with word opcodes ...) |
| 41 | 41 | - Absolutely Mahjong: Epson splash screen doesn't appear at all, why? |
| 42 | - Brandish 2: has some annoying strips at the main menu, also no selection seems to work; |
| 42 | 43 | - Dragon Buster: missing bitplanes for the PCG, slight issue with window masking; |
| 43 | 44 | - Far Side Moon: doesn't detect neither mouse nor sound board; |
| 44 | 45 | - First Queen: has broken text display; |
| r19396 | r19397 | |
| 349 | 350 | UINT8 r[16],g[16],b[16]; |
| 350 | 351 | }m_analog16; |
| 351 | 352 | struct { |
| 353 | UINT8 pal_entry; |
| 354 | UINT8 r[0x100],g[0x100],b[0x100]; |
| 355 | }m_analog256; |
| 356 | struct { |
| 352 | 357 | UINT8 mode; |
| 353 | 358 | UINT8 tile[4], tile_index; |
| 354 | 359 | }m_grcg; |
| 355 | 360 | |
| 356 | 361 | /* PC9821 specific */ |
| 357 | | UINT8 m_analog256,m_analog256e; |
| 358 | 362 | UINT8 m_sdip[24], m_sdip_bank; |
| 359 | 363 | UINT8 *m_ide_rom; |
| 360 | 364 | UINT8 *m_ide_ram; |
| r19396 | r19397 | |
| 558 | 562 | #define MEMSW_REG 6 |
| 559 | 563 | #define DISPLAY_REG 7 |
| 560 | 564 | |
| 561 | | #define ANALOG_16 0 |
| 565 | #define ANALOG_16_MODE 0 |
| 566 | #define ANALOG_256_MODE 0x10 |
| 562 | 567 | |
| 563 | 568 | void pc9801_state::video_start() |
| 564 | 569 | { |
| r19396 | r19397 | |
| 599 | 604 | return; |
| 600 | 605 | |
| 601 | 606 | interlace_on = state->m_video_ff[INTERLACE_REG]; |
| 602 | | colors16_mode = (state->m_ex_video_ff[0]) ? 16 : 8; |
| 607 | colors16_mode = (state->m_ex_video_ff[ANALOG_16_MODE]) ? 16 : 8; |
| 603 | 608 | |
| 604 | | for(xi=0;xi<8;xi++) |
| 609 | if(state->m_ex_video_ff[ANALOG_256_MODE]) |
| 605 | 610 | { |
| 606 | | res_x = x + xi; |
| 607 | | res_y = y; |
| 611 | for(xi=0;xi<8;xi++) |
| 612 | { |
| 613 | res_x = x + xi; |
| 614 | res_y = y; |
| 608 | 615 | |
| 609 | | pen = ((state->m_video_ram_2[(address & 0x7fff) + (0x08000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 1 : 0; |
| 610 | | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x10000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 2 : 0; |
| 611 | | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x18000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 4 : 0; |
| 612 | | if(state->m_ex_video_ff[0]) |
| 613 | | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 8 : 0; |
| 616 | if(!device->machine().primary_screen->visible_area().contains(res_x, res_y*2+0)) |
| 617 | return; |
| 614 | 618 | |
| 615 | | if(interlace_on) |
| 616 | | { |
| 617 | | if(device->machine().primary_screen->visible_area().contains(res_x, res_y*2+0)) |
| 618 | | bitmap.pix32(res_y*2+0, res_x) = palette[pen + colors16_mode]; |
| 619 | pen = state->m_ext_gvram[(address*8+xi)+(state->m_vram_disp*0x40000)]; |
| 620 | |
| 621 | bitmap.pix32(res_y*2+0, res_x) = palette[pen + 0x20]; |
| 619 | 622 | if(device->machine().primary_screen->visible_area().contains(res_x, res_y*2+1)) |
| 620 | | bitmap.pix32(res_y*2+1, res_x) = palette[pen + colors16_mode]; |
| 623 | bitmap.pix32(res_y*2+1, res_x) = palette[pen + 0x20]; |
| 621 | 624 | } |
| 622 | | else |
| 623 | | bitmap.pix32(res_y, res_x) = palette[pen + colors16_mode]; |
| 624 | 625 | } |
| 626 | else |
| 627 | { |
| 628 | for(xi=0;xi<8;xi++) |
| 629 | { |
| 630 | res_x = x + xi; |
| 631 | res_y = y; |
| 632 | |
| 633 | pen = ((state->m_video_ram_2[(address & 0x7fff) + (0x08000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 1 : 0; |
| 634 | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x10000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 2 : 0; |
| 635 | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0x18000) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 4 : 0; |
| 636 | if(state->m_ex_video_ff[ANALOG_16_MODE]) |
| 637 | pen|= ((state->m_video_ram_2[(address & 0x7fff) + (0) + (state->m_vram_disp*0x20000)] >> (7-xi)) & 1) ? 8 : 0; |
| 638 | |
| 639 | if(interlace_on) |
| 640 | { |
| 641 | if(device->machine().primary_screen->visible_area().contains(res_x, res_y*2+0)) |
| 642 | bitmap.pix32(res_y*2+0, res_x) = palette[pen + colors16_mode]; |
| 643 | if(device->machine().primary_screen->visible_area().contains(res_x, res_y*2+1)) |
| 644 | bitmap.pix32(res_y*2+1, res_x) = palette[pen + colors16_mode]; |
| 645 | } |
| 646 | else |
| 647 | bitmap.pix32(res_y, res_x) = palette[pen + colors16_mode]; |
| 648 | } |
| 649 | } |
| 625 | 650 | } |
| 626 | 651 | |
| 627 | 652 | static UPD7220_DRAW_TEXT_LINE( hgdc_draw_text ) |
| r19396 | r19397 | |
| 1126 | 1151 | case 0x00: |
| 1127 | 1152 | case 0x02: |
| 1128 | 1153 | return m_hgdc2->read(space, (offset & 2) >> 1); |
| 1129 | | /* bitmap palette clut read */ |
| 1154 | /* TODO: double check these two */ |
| 1130 | 1155 | case 0x04: |
| 1131 | 1156 | return m_vram_disp & 1; |
| 1132 | 1157 | case 0x06: |
| 1133 | 1158 | return m_vram_bank & 1; |
| 1159 | /* bitmap palette clut read */ |
| 1134 | 1160 | case 0x08: |
| 1135 | 1161 | case 0x0a: |
| 1136 | 1162 | case 0x0c: |
| r19396 | r19397 | |
| 1174 | 1200 | case 0x02: |
| 1175 | 1201 | m_hgdc2->write(space, (offset & 2) >> 1,data); |
| 1176 | 1202 | return; |
| 1177 | | case 0x04: m_vram_disp = data & 1; return; |
| 1203 | case 0x04: |
| 1204 | m_vram_disp = data & 1; |
| 1205 | return; |
| 1178 | 1206 | case 0x06: |
| 1179 | 1207 | m_vram_bank = data & 1; |
| 1180 | | //m_hgdc2->bank_w(space, 0,(data & 1) << 2); //TODO: check me |
| 1181 | 1208 | return; |
| 1182 | 1209 | /* bitmap palette clut write */ |
| 1183 | 1210 | case 0x08: |
| r19396 | r19397 | |
| 1804 | 1831 | |
| 1805 | 1832 | WRITE8_MEMBER(pc9801_state::pc9801rs_video_ff_w) |
| 1806 | 1833 | { |
| 1807 | | |
| 1808 | 1834 | if(offset == 2) |
| 1809 | 1835 | { |
| 1810 | | m_ex_video_ff[(data & 0xfe) >> 1] = data & 1; |
| 1836 | if((data & 0xf0) == 0) /* disable any PC-9821 specific HW regs */ |
| 1837 | m_ex_video_ff[(data & 0xfe) >> 1] = data & 1; |
| 1811 | 1838 | |
| 1812 | 1839 | if(0) |
| 1813 | 1840 | { |
| r19396 | r19397 | |
| 1833 | 1860 | WRITE8_MEMBER(pc9801_state::pc9801rs_a0_w) |
| 1834 | 1861 | { |
| 1835 | 1862 | |
| 1836 | | if((offset & 1) == 0 && offset & 8 && m_ex_video_ff[ANALOG_16]) |
| 1863 | if((offset & 1) == 0 && offset & 8 && m_ex_video_ff[ANALOG_16_MODE]) |
| 1837 | 1864 | { |
| 1838 | 1865 | switch(offset) |
| 1839 | 1866 | { |
| r19396 | r19397 | |
| 1876 | 1903 | AM_RANGE(0x0020, 0x0027) AM_READWRITE8(pc9801_20_r, pc9801_20_w, 0xffffffff) // RTC / DMA registers (LS244) |
| 1877 | 1904 | AM_RANGE(0x0030, 0x0037) AM_READWRITE8(pc9801rs_30_r, pc9801_30_w, 0xffffffff) //i8251 RS232c / i8255 system port |
| 1878 | 1905 | AM_RANGE(0x0040, 0x0047) AM_READWRITE8(pc9801_40_r, pc9801_40_w, 0xffffffff) //i8255 printer port / i8251 keyboard |
| 1906 | AM_RANGE(0x005c, 0x005f) AM_WRITENOP // time-stamp? |
| 1879 | 1907 | AM_RANGE(0x0060, 0x0063) AM_READWRITE8(pc9801_60_r, pc9801_60_w, 0xffffffff) //upd7220 character ports / <undefined> |
| 1880 | 1908 | AM_RANGE(0x0064, 0x0067) AM_WRITE8(pc9801_vrtc_mask_w, 0xffffffff) |
| 1881 | 1909 | AM_RANGE(0x0068, 0x006b) AM_WRITE8(pc9801rs_video_ff_w,0xffffffff) //mode FF / <undefined> |
| r19396 | r19397 | |
| 1935 | 1963 | AM_RANGE(0x0020, 0x0027) AM_READWRITE8(pc9801_20_r, pc9801_20_w, 0xffff) // RTC / DMA registers (LS244) |
| 1936 | 1964 | AM_RANGE(0x0030, 0x0037) AM_READWRITE8(pc9801rs_30_r, pc9801_30_w, 0xffff) //i8251 RS232c / i8255 system port |
| 1937 | 1965 | AM_RANGE(0x0040, 0x0047) AM_READWRITE8(pc9801_40_r, pc9801_40_w, 0xffff) //i8255 printer port / i8251 keyboard |
| 1966 | AM_RANGE(0x005c, 0x005f) AM_WRITENOP // time-stamp? |
| 1938 | 1967 | AM_RANGE(0x0060, 0x0063) AM_READWRITE8(pc9801_60_r, pc9801_60_w, 0xffff) //upd7220 character ports / <undefined> |
| 1939 | 1968 | AM_RANGE(0x0064, 0x0067) AM_WRITE8(pc9801_vrtc_mask_w, 0xffff) |
| 1940 | 1969 | AM_RANGE(0x0068, 0x006b) AM_WRITE8(pc9801rs_video_ff_w,0xffff) //mode FF / <undefined> |
| r19396 | r19397 | |
| 1961 | 1990 | READ8_MEMBER(pc9801_state::pc9821_ide_r) { return m_ide_rom[offset]; } |
| 1962 | 1991 | READ8_MEMBER(pc9801_state::pc9821_unkrom_r) { return m_unk_rom[offset]; } |
| 1963 | 1992 | |
| 1964 | | READ8_MEMBER(pc9801_state::pc9821_vram256_r) { return m_vram256[offset]; } |
| 1965 | | WRITE8_MEMBER(pc9801_state::pc9821_vram256_w) { m_vram256[offset] = data; } |
| 1993 | READ8_MEMBER(pc9801_state::pc9821_vram256_r) |
| 1994 | { |
| 1995 | if(m_ex_video_ff[ANALOG_256_MODE]) |
| 1996 | return m_vram256[offset]; |
| 1966 | 1997 | |
| 1998 | return m_pc9801rs_grcg_r(offset & 0x7fff,0); |
| 1999 | } |
| 2000 | |
| 2001 | WRITE8_MEMBER(pc9801_state::pc9821_vram256_w) |
| 2002 | { |
| 2003 | if(m_ex_video_ff[ANALOG_256_MODE]) |
| 2004 | { |
| 2005 | m_vram256[offset] = data; |
| 2006 | return; |
| 2007 | } |
| 2008 | |
| 2009 | m_pc9801rs_grcg_w(offset & 0x7fff,0,data); |
| 2010 | } |
| 2011 | |
| 1967 | 2012 | /* Note: not hooking this up causes "MEMORY ERROR" at POST */ |
| 1968 | 2013 | READ8_MEMBER(pc9801_state::pc9821_ideram_r) { return m_ide_ram[offset]; } |
| 1969 | 2014 | WRITE8_MEMBER(pc9801_state::pc9821_ideram_w) { m_ide_ram[offset] = data; } |
| r19396 | r19397 | |
| 2032 | 2077 | { |
| 2033 | 2078 | if(offset == 2) |
| 2034 | 2079 | { |
| 2035 | | switch(data & 0xf8) // pc-9821 specific extended registers |
| 2036 | | { |
| 2037 | | case 0x20: m_analog256 = data & 1; return; |
| 2038 | | case 0x68: m_analog256e = data & 1; return; |
| 2039 | | } // intentional fall-through |
| 2080 | m_ex_video_ff[(data & 0xfe) >> 1] = data & 1; |
| 2081 | |
| 2082 | //if((data & 0xfe) == 0x20) |
| 2083 | // printf("%02x\n",data & 1); |
| 2040 | 2084 | } |
| 2041 | 2085 | |
| 2086 | /* Intentional fall-through */ |
| 2042 | 2087 | pc9801rs_video_ff_w(space,offset,data); |
| 2043 | 2088 | } |
| 2044 | 2089 | |
| r19396 | r19397 | |
| 2046 | 2091 | { |
| 2047 | 2092 | if((offset & 1) == 0 && offset & 8) |
| 2048 | 2093 | { |
| 2049 | | if(m_analog256) |
| 2094 | if(m_ex_video_ff[ANALOG_256_MODE]) |
| 2050 | 2095 | { |
| 2051 | 2096 | printf("256 color mode [%02x] R\n",offset); |
| 2052 | 2097 | return 0; |
| 2053 | 2098 | } |
| 2054 | | else if(m_ex_video_ff[ANALOG_16]) //16 color mode, readback possible there |
| 2099 | else if(m_ex_video_ff[ANALOG_16_MODE]) //16 color mode, readback possible there |
| 2055 | 2100 | { |
| 2056 | 2101 | UINT8 res = 0; |
| 2057 | 2102 | |
| r19396 | r19397 | |
| 2073 | 2118 | WRITE8_MEMBER(pc9801_state::pc9821_a0_w) |
| 2074 | 2119 | { |
| 2075 | 2120 | |
| 2076 | | if((offset & 1) == 0 && offset & 8 && m_analog256) |
| 2121 | if((offset & 1) == 0 && offset & 8 && m_ex_video_ff[ANALOG_256_MODE]) |
| 2077 | 2122 | { |
| 2078 | | printf("256 color mode [%02x] %02x W\n",offset,data); |
| 2123 | switch(offset) |
| 2124 | { |
| 2125 | case 0x08: m_analog256.pal_entry = data & 0xff; break; |
| 2126 | case 0x0a: m_analog256.g[m_analog256.pal_entry] = data & 0xff; break; |
| 2127 | case 0x0c: m_analog256.r[m_analog256.pal_entry] = data & 0xff; break; |
| 2128 | case 0x0e: m_analog256.b[m_analog256.pal_entry] = data & 0xff; break; |
| 2129 | } |
| 2130 | |
| 2131 | palette_set_color_rgb(machine(), (m_analog256.pal_entry)+0x20, |
| 2132 | m_analog256.r[m_analog256.pal_entry], |
| 2133 | m_analog256.g[m_analog256.pal_entry], |
| 2134 | m_analog256.b[m_analog256.pal_entry]); |
| 2079 | 2135 | return; |
| 2080 | 2136 | } |
| 2081 | 2137 | |