diff --git a/src/emu/video/pc_vga.c b/src/emu/video/pc_vga.c index d5ac9bdd246..bbea822201d 100644 --- a/src/emu/video/pc_vga.c +++ b/src/emu/video/pc_vga.c @@ -162,6 +162,8 @@ static struct { UINT8 bank_r,bank_w; UINT8 rgb8_en; + UINT8 rgb15_en; + UINT8 id; }svga; #define REG(x) vga.crtc.data[x] @@ -198,6 +200,12 @@ static struct #define TEXT_COPY_9COLUMN(ch) (((ch & 0xe0) == 0xc0)&&(vga.attribute.data[0x10]&4)) +// Special values for SVGA Trident - Mode Vesa 110h +#define TLINES (LINES) +#define TGA_COLUMNS (EGA_COLUMNS) +#define TGA_START_ADDRESS (vga.crtc.start_addr<<2) +#define TGA_LINE_LENGTH (vga.crtc.offset<<3) + /*************************************************************************** @@ -522,6 +530,43 @@ static void svga_vh_rgb8(running_machine &machine, bitmap_rgb32 &bitmap, const r } } +static void svga_vh_rgb15(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + #define MV(x) (vga.memory[x]+(vga.memory[x+1]<<8)) + #define IV 0xff000000 + int height = vga.crtc.maximum_scan_line * (vga.crtc.scan_doubling + 1); + int xi; + int yi; + int xm; + + int pos, line, column, c, addr, curr_addr; + + UINT32 *bitmapline; + UINT16 mask_comp; + + /* line compare is screen sensitive */ + mask_comp = 0xff | (TLINES & 0x300); + curr_addr = 0; + yi=0; + for (addr = TGA_START_ADDRESS, line=0; line500) return; + bitmapline = &bitmap.pix32(line); + addr %= vga.svga_intf.vram_size; + for (pos=addr, c=0, column=0; column vga.svga_intf.vram_size) + return; + for(xi=0,xm=0;xi<8;xi++,xm+=2) + { + if(!machine.primary_screen->visible_area().contains(c+xi, line + yi)) + continue; + bitmapline[c+xi] = IV|(MV(pos+xm)&0x7c00)<<9 |(MV(pos+xm)&0x3e0)<<6|(MV(pos+xm)&0x1f)<<3; + } + } + } +} + enum { SCREEN_OFF = 0, @@ -531,6 +576,7 @@ enum CGA_MODE, MONO_MODE, RGB8_MODE, + RGB15_MODE, SVGA_HACK }; @@ -577,6 +623,10 @@ static UINT8 pc_vga_choosevideomode(running_machine &machine) { return RGB8_MODE; } + else if (svga.rgb15_en&0x30) + { + return RGB15_MODE; + } else if (!GRAPHIC_MODE) { //proc = vga_vh_text; @@ -632,6 +682,7 @@ SCREEN_UPDATE_RGB32( pc_video ) case CGA_MODE: vga_vh_cga (screen.machine(), bitmap, cliprect); break; case MONO_MODE: vga_vh_mono(screen.machine(), bitmap, cliprect); break; case RGB8_MODE: svga_vh_rgb8(screen.machine(), bitmap, cliprect); break; + case RGB15_MODE: svga_vh_rgb15(screen.machine(), bitmap, cliprect); break; case SVGA_HACK: vga.svga_intf.choosevideomode(screen.machine(), bitmap, cliprect, vga.sequencer.data, vga.crtc.data, vga.gc.data, &w, &h); break; } @@ -1719,3 +1770,180 @@ WRITE8_HANDLER( tseng_mem_w ) else vga_mem_w(space,offset,data); } + +/****************************************** + +Trident implementation + +******************************************/ + +void pc_svga_trident_io_init(running_machine &machine, address_space *mem_space, offs_t mem_offset, address_space *io_space, offs_t port_offset) +{ + int buswidth; + UINT64 mask = 0; + + buswidth = machine.firstcpu->memory().space_config(AS_PROGRAM)->m_databus_width; + switch(buswidth) + { + case 8: + mask = 0; + break; + + case 16: + mask = 0xffff; + break; + + case 32: + mask = 0xffffffff; + break; + + case 64: + mask = -1; + break; + + default: + fatalerror("VGA: Bus width %d not supported", buswidth); + break; + } + io_space->install_legacy_readwrite_handler(port_offset + 0x3b0, port_offset + 0x3bf, FUNC(vga_port_03b0_r), FUNC(vga_port_03b0_w), mask); + io_space->install_legacy_readwrite_handler(port_offset + 0x3c0, port_offset + 0x3cf, FUNC(trident_03c0_r), FUNC(trident_03c0_w), mask); + io_space->install_legacy_readwrite_handler(port_offset + 0x3d0, port_offset + 0x3df, FUNC(trident_03d0_r), FUNC(trident_03d0_w), mask); + + mem_space->install_legacy_readwrite_handler(mem_offset + 0x00000, mem_offset + 0x1ffff, FUNC(trident_mem_r), FUNC(trident_mem_w), mask); + + // D3h = TGUI9660XGi + svga.id = 0xd3; // TODO: hardcoded for California Chase +} + +static UINT8 trident_seq_reg_read(running_machine &machine, UINT8 index) +{ + UINT8 res; + + res = 0xff; + + if(index <= 0x04) + res = vga.sequencer.data[index]; + else + { + switch(index) + { + case 0x0d: + res = svga.rgb15_en; + break; + } + } + + return res; +} + +static void trident_seq_reg_write(running_machine &machine, UINT8 index, UINT8 data) +{ + if(index <= 0x04) + { + vga.sequencer.data[vga.sequencer.index] = data; + seq_reg_write(machine,vga.sequencer.index,data); + recompute_params(machine); + } + else + { + switch(index) + { + case 0x0d: + svga.rgb15_en = data & 0x30; // TODO: doesn't match documentation + break; + } + } +} + + +READ8_HANDLER(trident_03c0_r) +{ + UINT8 res; + + switch(offset) + { + case 0x05: + res = trident_seq_reg_read(space->machine(),vga.sequencer.index); + break; + default: + res = vga_port_03c0_r(space,offset); + break; + } + + return res; +} + +WRITE8_HANDLER(trident_03c0_w) +{ + switch(offset) + { + case 0x05: + trident_seq_reg_write(space->machine(),vga.sequencer.index,data); + break; + default: + vga_port_03c0_w(space,offset,data); + break; + } +} + + +READ8_HANDLER(trident_03d0_r) +{ + UINT8 res = 0xff; + + if (CRTC_PORT_ADDR == 0x3d0) + { + switch(offset) + { + case 8: + res = svga.bank_w & 0x1f; // TODO: a lot more complex than this + break; + default: + res = vga_port_03d0_r(space,offset); + break; + } + } + + return res; +} + +WRITE8_HANDLER(trident_03d0_w) +{ + if (CRTC_PORT_ADDR == 0x3d0) + { + switch(offset) + { + case 8: + svga.bank_w = data & 0x1f; // TODO: a lot more complex than this + break; + default: + vga_port_03d0_w(space,offset,data); + break; + } + } +} + +READ8_HANDLER( trident_mem_r ) +{ + if (svga.rgb15_en & 0x30) + { + int data; + if(svga.bank_w>0x09) return 0; + data=vga.memory[offset + (svga.bank_w*0x10000)]; + return data; + } + + return vga_mem_r(space,offset); +} + +WRITE8_HANDLER( trident_mem_w ) +{ + if (svga.rgb15_en & 0x30) + { + if (svga.bank_w>0x09)return; + vga.memory[offset + (svga.bank_w*0x10000)]= data; + return; + } + + vga_mem_w(space,offset,data); +} diff --git a/src/emu/video/pc_vga.h b/src/emu/video/pc_vga.h index 08f22c64185..a13c0d2f3d2 100644 --- a/src/emu/video/pc_vga.h +++ b/src/emu/video/pc_vga.h @@ -25,6 +25,7 @@ struct pc_svga_interface void pc_vga_init(running_machine &machine, read8_space_func read_dipswitch, const struct pc_svga_interface *svga_intf); void pc_vga_io_init(running_machine &machine, address_space *mem_space, offs_t mem_offset, address_space *io_space, offs_t port_offset); +void pc_svga_trident_io_init(running_machine &machine, address_space *mem_space, offs_t mem_offset, address_space *io_space, offs_t port_offset); void pc_vga_reset(running_machine &machine); void *pc_vga_memory(void); size_t pc_vga_memory_size(void); @@ -47,6 +48,12 @@ WRITE8_HANDLER(tseng_et4k_03d0_w); READ8_HANDLER(tseng_mem_r); WRITE8_HANDLER(tseng_mem_w); +READ8_HANDLER(trident_03c0_r); +WRITE8_HANDLER(trident_03c0_w); +READ8_HANDLER(trident_03d0_r); +WRITE8_HANDLER(trident_03d0_w); +READ8_HANDLER(trident_mem_r); +WRITE8_HANDLER(trident_mem_w); /* pega notes (paradise) diff --git a/src/mame/drivers/calchase.c b/src/mame/drivers/calchase.c index dcafdbe3c26..4c7b93ca935 100644 --- a/src/mame/drivers/calchase.c +++ b/src/mame/drivers/calchase.c @@ -739,7 +739,7 @@ static DRIVER_INIT( calchase ) state->m_bios_ram = auto_alloc_array(machine, UINT32, 0x20000/4); pc_vga_init(machine, vga_setting, NULL); - pc_vga_io_init(machine, machine.device("maincpu")->memory().space(AS_PROGRAM), 0xa0000, machine.device("maincpu")->memory().space(AS_IO), 0x0000); + pc_svga_trident_io_init(machine, machine.device("maincpu")->memory().space(AS_PROGRAM), 0xa0000, machine.device("maincpu")->memory().space(AS_IO), 0x0000); init_pc_common(machine, PCCOMMON_KEYBOARD_AT, calchase_set_keyb_int);