From 829b301e470332cb77b16d39befe9b5fa3758067 Mon Sep 17 00:00:00 2001 From: Angelo Salese Date: Thu, 26 Jan 2012 19:11:41 +0000 Subject: [PATCH] Major overhaul of VGA memory handlers, added monochrome emulation and fixed text banking while at it [Angelo Salese]" --- src/emu/video/pc_vga.c | 262 +++++++++++++++++------------------------ 1 file changed, 108 insertions(+), 154 deletions(-) diff --git a/src/emu/video/pc_vga.c b/src/emu/video/pc_vga.c index ade621754be..32e8dc6fba0 100644 --- a/src/emu/video/pc_vga.c +++ b/src/emu/video/pc_vga.c @@ -68,6 +68,7 @@ static struct { UINT8 index; UINT8 *data; + UINT8 map_mask; } sequencer; /* An empty comment at the start of the line indicates that register is currently unused */ @@ -167,18 +168,18 @@ static struct #define GRAPHIC_MODE (vga.gc.data[6]&1) /* else textmodus */ #define EGA_COLUMNS (vga.crtc.data[1]+1) -#define EGA_START_ADDRESS ((vga.crtc.data[0xd]|(vga.crtc.data[0xc]<<8))<<2) -#define EGA_LINE_LENGTH (vga.crtc.data[0x13]<<3) +#define EGA_START_ADDRESS ((vga.crtc.data[0xd]|(vga.crtc.data[0xc]<<8))) +#define EGA_LINE_LENGTH (vga.crtc.offset<<1) -#define VGA_COLUMNS (EGA_COLUMNS>>1) -#define VGA_START_ADDRESS (EGA_START_ADDRESS) -#define VGA_LINE_LENGTH (EGA_LINE_LENGTH<<2) +#define VGA_COLUMNS (vga.crtc.data[1]+1) +#define VGA_START_ADDRESS (vga.crtc.start_addr<<3) +#define VGA_LINE_LENGTH (vga.crtc.offset<<3) #define CHAR_WIDTH ((vga.sequencer.data[1]&1)?8:9) #define TEXT_COLUMNS (vga.crtc.data[1]+1) -#define TEXT_START_ADDRESS (EGA_START_ADDRESS) -#define TEXT_LINE_LENGTH (EGA_LINE_LENGTH>>2) +#define TEXT_START_ADDRESS (vga.crtc.start_addr<<3) +#define TEXT_LINE_LENGTH (vga.crtc.offset<<1) #define TEXT_COPY_9COLUMN(ch) ((ch>=192)&&(ch<=223)&&(vga.attribute.data[0x10]&4)) @@ -215,7 +216,7 @@ static void vga_vh_text(running_machine &machine, bitmap_rgb32 &bitmap, const re { UINT8 ch, attr; UINT8 bits; - UINT8 *font; + UINT32 font_base; UINT32 *bitmapline; int width=CHAR_WIDTH, height=CRTC_CHAR_HEIGHT; int pos, line, column, mask, w, h, addr; @@ -235,16 +236,16 @@ static void vga_vh_text(running_machine &machine, bitmap_rgb32 &bitmap, const re { for (pos = addr, column=0; column>=1) { @@ -295,20 +296,20 @@ static void vga_vh_ega(running_machine &machine, bitmap_rgb32 &bitmap, const re pen_t pen; for (addr=EGA_START_ADDRESS, pos=0, line=0; line= 0; i--) { @@ -341,6 +342,7 @@ static void vga_vh_vga(running_machine &machine, bitmap_rgb32 &bitmap, const rec mask_comp = 0x0ff | (LINES & 0x300); curr_addr = 0; + #if 0 if(vga.sequencer.data[4] & 0x08) { for (addr = VGA_START_ADDRESS, line=0; line> 1) * width/8); - for(x=0;x<640;x+=8) + for(x=0;x> (xi)) & 1]; + pen = vga.pens[(vga.memory[addr] >> (7-xi)) & 1]; + if(!machine.primary_screen->visible_area().contains(x+xi, y * height + yi)) + continue; bitmapline[x+xi] = pen; } } - //popmessage("%02x %02x %02x %02x %02x %02x %02x %02x",vga.memory[0],vga.memory[1],vga.memory[2],vga.memory[3],vga.memory[4],vga.memory[5],vga.memory[6],vga.memory[7]); - addr++; } } @@ -577,40 +582,6 @@ INLINE UINT8 rotate_right(UINT8 val, UINT8 rot) return (val >> rot) | (val << (8 - rot)); } - -INLINE WRITE8_HANDLER(vga_dirty_w) -{ - vga.memory[offset] = data; -} - -static READ8_HANDLER(vga_cga_r) -{ - int data; - data=vga.memory[offset]; - - return data; -} - -static WRITE8_HANDLER(vga_cga_w) -{ - vga.memory[offset] = data; -} - - - -static READ8_HANDLER(vga_text_r) -{ - int data; - data=vga.memory[((offset&~1)<<1)|(offset&1)]; - - return data; -} - -static WRITE8_HANDLER(vga_text_w) -{ - vga_dirty_w(space, ((offset&~1)<<1)|(offset&1),data); -} - INLINE UINT8 ega_bitplane_to_packed(UINT8 *latch, int number) { return color_bitplane_to_packed[0][number][latch[0]] @@ -619,30 +590,6 @@ INLINE UINT8 ega_bitplane_to_packed(UINT8 *latch, int number) |color_bitplane_to_packed[3][number][latch[3]]; } -static READ8_HANDLER(vga_ega_r) -{ - int data; - vga.gc.latch[0]=vga.memory[(offset<<2)]; - vga.gc.latch[1]=vga.memory[(offset<<2)+1]; - vga.gc.latch[2]=vga.memory[(offset<<2)+2]; - vga.gc.latch[3]=vga.memory[(offset<<2)+3]; - if (vga.gc.data[5]&8) { - data=0; - if (!(ega_bitplane_to_packed(vga.gc.latch, 0)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=1; - if (!(ega_bitplane_to_packed(vga.gc.latch, 1)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=2; - if (!(ega_bitplane_to_packed(vga.gc.latch, 2)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=4; - if (!(ega_bitplane_to_packed(vga.gc.latch, 3)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=8; - if (!(ega_bitplane_to_packed(vga.gc.latch, 4)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x10; - if (!(ega_bitplane_to_packed(vga.gc.latch, 5)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x20; - if (!(ega_bitplane_to_packed(vga.gc.latch, 6)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x40; - if (!(ega_bitplane_to_packed(vga.gc.latch, 7)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x80; - } else { - data=vga.gc.latch[vga.gc.data[4]&3]; - } - - return data; -} - INLINE UINT8 vga_latch_helper(UINT8 cpu, UINT8 latch, UINT8 mask) { switch (vga.gc.data[3] & 0x18) @@ -690,32 +637,6 @@ INLINE UINT8 vga_latch_write(int offs, UINT8 data) return 0; /* must not be reached, suppress compiler warning */ } -static WRITE8_HANDLER(vga_ega_w) -{ - if (vga.sequencer.data[2]&1) - vga_dirty_w(space, offset<<2, vga_latch_write(0,data)); - if (vga.sequencer.data[2]&2) - vga_dirty_w(space, (offset<<2)+1, vga_latch_write(1,data)); - if (vga.sequencer.data[2]&4) - vga_dirty_w(space, (offset<<2)+2, vga_latch_write(2,data)); - if (vga.sequencer.data[2]&8) - vga_dirty_w(space, (offset<<2)+3, vga_latch_write(3,data)); - if ((offset==0xffff)&&(data==0)) vga.log=1; -} - -static READ8_HANDLER(vga_vga_r) -{ - int data; - data=vga.memory[((offset&~3)<<2)|(offset&3)]; - - return data; -} - -static WRITE8_HANDLER(vga_vga_w) -{ - vga_dirty_w(space, ((offset&~3)<<2)|(offset&3),data); -} - #if 0 static UINT8 crtc_reg_read(UINT8 index) { @@ -892,6 +813,21 @@ static void crtc_reg_write(running_machine &machine, UINT8 index, UINT8 data) } } +#include "debugger.h" + +static void seq_reg_write(running_machine &machine, UINT8 index, UINT8 data) +{ + switch(index) + { + case 0x02: + vga.sequencer.map_mask = data & 0xf; + break; + case 0x03: + //vga.sequencer.char_map_sel = data & 0x03; + break; + } +} + static READ8_HANDLER(vga_crtc_r) { UINT8 data = 0xff; @@ -1158,8 +1094,10 @@ WRITE8_HANDLER(vga_port_03c0_w) if (vga.sequencer.index < vga.svga_intf.seq_regcount) { vga.sequencer.data[vga.sequencer.index] = data; - recompute_params(space->machine()); } + + seq_reg_write(space->machine(),vga.sequencer.index,data); + recompute_params(space->machine()); break; case 6: vga.dac.mask=data; @@ -1267,61 +1205,77 @@ void pc_vga_reset(running_machine &machine) READ8_HANDLER(vga_mem_r) { - read8_space_func read_handler; - if (vga.sequencer.data[4]&8) + switch((vga.gc.data[6] >> 2) & 0x03) { - read_handler = vga_vga_r; + case 0: break; + case 1: offset &= 0x0ffff; break; + case 2: offset -= 0x10000; offset &= 0x07fff; break; + case 3: offset -= 0x18000; offset &= 0x07fff; break; } - else if (vga.sequencer.data[4] & 4) + + if(vga.sequencer.data[4] & 4) { - read_handler = vga_ega_r; - } - else if (vga.gc.data[5]&0x20) - { - read_handler = vga_cga_r; + int data; + vga.gc.latch[0]=vga.memory[(offset)]; + vga.gc.latch[1]=vga.memory[(offset)+0x20000]; + vga.gc.latch[2]=vga.memory[(offset)+0x40000]; + vga.gc.latch[3]=vga.memory[(offset)+0x60000]; + if (vga.gc.data[5]&8) { + data=0; + if (!(ega_bitplane_to_packed(vga.gc.latch, 0)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=1; + if (!(ega_bitplane_to_packed(vga.gc.latch, 1)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=2; + if (!(ega_bitplane_to_packed(vga.gc.latch, 2)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=4; + if (!(ega_bitplane_to_packed(vga.gc.latch, 3)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=8; + if (!(ega_bitplane_to_packed(vga.gc.latch, 4)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x10; + if (!(ega_bitplane_to_packed(vga.gc.latch, 5)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x20; + if (!(ega_bitplane_to_packed(vga.gc.latch, 6)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x40; + if (!(ega_bitplane_to_packed(vga.gc.latch, 7)^(vga.gc.data[2]&0xf&~vga.gc.data[7]))) data|=0x80; + } else { + data=vga.gc.latch[vga.gc.data[4]&3]; + } + + return data; } else { - read_handler = vga_text_r; - } - switch((vga.gc.data[6] >> 2) & 0x03) - { - case 0: return vga.memory[offset & 0x1ffff]; - case 1: return read_handler(space,(offset - 0x00000) & 0x0ffff); - case 2: return read_handler(space,(offset - 0x10000) & 0x0ffff); - case 3: return read_handler(space,(offset - 0x18000) & 0x0ffff); + // TODO: Guesswork, probably not right + UINT8 i,data; + + data = 0; + //printf("%08x\n",offset); + + for(i=0;i<4;i++) + { + if(vga.sequencer.map_mask & 1 << i) + data |= vga.memory[offset+i*0x20000]; + } + + return data; } + return 0; } WRITE8_HANDLER(vga_mem_w) { - write8_space_func write_handler; - - if (vga.sequencer.data[4]&8) - { - write_handler = vga_vga_w; - } - else if (vga.sequencer.data[4] & 4) - { - write_handler = vga_ega_w; - } - else if (vga.gc.data[5]&0x20) - { - write_handler = vga_cga_w; - } - else - { - write_handler = vga_text_w; - } switch((vga.gc.data[6] >> 2) & 0x03) { - case 0: vga.memory[offset & 0x1ffff] = data; break; - case 1: write_handler(space,(offset - 0x00000) & 0x0ffff,data); break; - case 2: write_handler(space,(offset - 0x10000) & 0x0ffff,data); break; - case 3: write_handler(space,(offset - 0x18000) & 0x0ffff,data); break; + case 0: break; + case 1: offset &= 0x0ffff; break; + case 2: offset -= 0x10000; offset &= 0x07fff; break; + case 3: offset -= 0x18000; offset &= 0x07fff; break; } + { + UINT8 i; + + for(i=0;i<4;i++) + { + if(vga.sequencer.map_mask & 1 << i) + vga.memory[offset+i*0x20000] = (vga.sequencer.data[4] & 4) ? vga_latch_write(i,data) : data; + } + return; + } } void pc_vga_init(running_machine &machine, read8_space_func read_dipswitch, const struct pc_svga_interface *svga_intf) @@ -1353,7 +1307,7 @@ void pc_vga_init(running_machine &machine, read8_space_func read_dipswitch, cons } else { - vga.svga_intf.vram_size = 0x40000; + vga.svga_intf.vram_size = 0x80000; vga.svga_intf.seq_regcount = 0x05; vga.svga_intf.gc_regcount = 0x09; vga.svga_intf.crtc_regcount = 0x19;