Fixed vram size, nw

This commit is contained in:
Angelo Salese 2012-02-08 20:58:50 +00:00
parent 4c300d9e9f
commit 6ddfcbaf12

View File

@ -18,10 +18,9 @@
TODO: TODO:
- modernize - modernize
- add emulated mc6845 hook-up - fix video update, still need to get that choosevideomode() out of it.
- fix video update.
- rewrite video drawing functions (they are horrible) - rewrite video drawing functions (they are horrible)
- add VESA etc. - add per-gfx card VESA functions;
- (and many more ...) - (and many more ...)
per-game issues: per-game issues:
@ -146,6 +145,7 @@ static struct
{ {
UINT8 index, data[0x15]; int state; UINT8 index, data[0x15]; int state;
UINT8 prot_bit; UINT8 prot_bit;
UINT8 pel_shift;
} attribute; } attribute;
@ -171,6 +171,7 @@ static struct
UINT8 rgb8_en; UINT8 rgb8_en;
UINT8 rgb15_en; UINT8 rgb15_en;
UINT8 rgb16_en; UINT8 rgb16_en;
UINT8 rgb32_en;
UINT8 id; UINT8 id;
}svga; }svga;
@ -186,6 +187,7 @@ static struct
UINT8 ext_misc_ctrl_2; UINT8 ext_misc_ctrl_2;
UINT8 crt_reg_lock; UINT8 crt_reg_lock;
UINT8 reg_lock1; UINT8 reg_lock1;
UINT8 reg_lock2;
}s3; }s3;
#define REG(x) vga.crtc.data[x] #define REG(x) vga.crtc.data[x]
@ -277,7 +279,7 @@ static void vga_vh_text(running_machine &machine, bitmap_rgb32 &bitmap, const re
{ {
ch = vga.memory[(pos<<1) + 0]; ch = vga.memory[(pos<<1) + 0];
attr = vga.memory[(pos<<1) + 1]; attr = vga.memory[(pos<<1) + 1];
font_base = 0x40000+(ch<<5); font_base = 0x20000+(ch<<5);
font_base += ((attr & 8) ? vga.sequencer.char_sel.B : vga.sequencer.char_sel.A)*0x2000; font_base += ((attr & 8) ? vga.sequencer.char_sel.B : vga.sequencer.char_sel.A)*0x2000;
blink_en = (vga.attribute.data[0x10]&8&&machine.primary_screen->frame_number() & 0x20) ? attr & 0x80 : 0; blink_en = (vga.attribute.data[0x10]&8&&machine.primary_screen->frame_number() & 0x20) ? attr & 0x80 : 0;
@ -338,6 +340,7 @@ static void vga_vh_ega(running_machine &machine, bitmap_rgb32 &bitmap, const re
UINT32 *bitmapline; UINT32 *bitmapline;
pen_t pen; pen_t pen;
/**/
for (addr=EGA_START_ADDRESS, pos=0, line=0; line<LINES; for (addr=EGA_START_ADDRESS, pos=0, line=0; line<LINES;
line += height, addr += EGA_LINE_LENGTH) line += height, addr += EGA_LINE_LENGTH)
{ {
@ -350,9 +353,9 @@ static void vga_vh_ega(running_machine &machine, bitmap_rgb32 &bitmap, const re
int data[4]; int data[4];
data[0]=vga.memory[(pos & 0xffff)]; data[0]=vga.memory[(pos & 0xffff)];
data[1]=vga.memory[(pos & 0xffff)+0x20000]<<1; data[1]=vga.memory[(pos & 0xffff)+0x10000]<<1;
data[2]=vga.memory[(pos & 0xffff)+0x40000]<<2; data[2]=vga.memory[(pos & 0xffff)+0x20000]<<2;
data[3]=vga.memory[(pos & 0xffff)+0x60000]<<3; data[3]=vga.memory[(pos & 0xffff)+0x30000]<<3;
for (i = 7; i >= 0; i--) for (i = 7; i >= 0; i--)
{ {
@ -382,7 +385,7 @@ static void vga_vh_vga(running_machine &machine, bitmap_rgb32 &bitmap, const rec
int xi; int xi;
/* line compare is screen sensitive */ /* line compare is screen sensitive */
mask_comp = 0x0ff | (LINES & 0x300); mask_comp = 0x3ff; //| (LINES & 0x300);
curr_addr = 0; curr_addr = 0;
if(!(vga.sequencer.data[4] & 0x08)) if(!(vga.sequencer.data[4] & 0x08))
@ -396,7 +399,6 @@ static void vga_vh_vga(running_machine &machine, bitmap_rgb32 &bitmap, const rec
if((line + yi) == (vga.crtc.line_compare & mask_comp)) if((line + yi) == (vga.crtc.line_compare & mask_comp))
curr_addr = 0; curr_addr = 0;
bitmapline = &bitmap.pix32(line + yi); bitmapline = &bitmap.pix32(line + yi);
addr %= vga.svga_intf.vram_size;
for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=8, pos++) for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=8, pos++)
{ {
if(pos > 0x80000/4) if(pos > 0x80000/4)
@ -406,7 +408,7 @@ static void vga_vh_vga(running_machine &machine, bitmap_rgb32 &bitmap, const rec
{ {
if(!machine.primary_screen->visible_area().contains(c+xi, line + yi)) if(!machine.primary_screen->visible_area().contains(c+xi, line + yi))
continue; continue;
bitmapline[c+xi] = machine.pens[vga.memory[pos+((xi >> 1)*0x20000)]]; bitmapline[c+xi] = machine.pens[vga.memory[(pos & 0xffff)+((xi >> 1)*0x10000)]];
} }
} }
} }
@ -423,7 +425,7 @@ static void vga_vh_vga(running_machine &machine, bitmap_rgb32 &bitmap, const rec
if((line + yi) == (vga.crtc.line_compare & mask_comp)) if((line + yi) == (vga.crtc.line_compare & mask_comp))
curr_addr = 0; curr_addr = 0;
bitmapline = &bitmap.pix32(line + yi); bitmapline = &bitmap.pix32(line + yi);
addr %= vga.svga_intf.vram_size; //addr %= 0x80000;
for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=0x10, pos+=0x8) for (pos=curr_addr, c=0, column=0; column<VGA_COLUMNS; column++, c+=0x10, pos+=0x8)
{ {
if(pos + 0x08 > 0x80000) if(pos + 0x08 > 0x80000)
@ -433,7 +435,7 @@ static void vga_vh_vga(running_machine &machine, bitmap_rgb32 &bitmap, const rec
{ {
if(!machine.primary_screen->visible_area().contains(c+xi, line + yi)) if(!machine.primary_screen->visible_area().contains(c+xi, line + yi))
continue; continue;
bitmapline[c+xi] = machine.pens[vga.memory[pos+(xi >> 1)]]; bitmapline[c+xi] = machine.pens[vga.memory[(pos+(xi >> 1)) & 0xffff]];
} }
} }
} }
@ -565,7 +567,6 @@ static void svga_vh_rgb15(running_machine &machine, bitmap_rgb32 &bitmap, const
int xi; int xi;
int yi; int yi;
int xm; int xm;
int pos, line, column, c, addr, curr_addr; int pos, line, column, c, addr, curr_addr;
UINT32 *bitmapline; UINT32 *bitmapline;
@ -610,7 +611,6 @@ static void svga_vh_rgb16(running_machine &machine, bitmap_rgb32 &bitmap, const
int xi; int xi;
int yi; int yi;
int xm; int xm;
int pos, line, column, c, addr, curr_addr; int pos, line, column, c, addr, curr_addr;
UINT32 *bitmapline; UINT32 *bitmapline;
@ -647,6 +647,46 @@ static void svga_vh_rgb16(running_machine &machine, bitmap_rgb32 &bitmap, const
} }
} }
static void svga_vh_rgb32(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
#define MD(x) (vga.memory[x]+(vga.memory[x+1]<<8)+(vga.memory[x+2]<<16))
#define ID 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; line<TLINES; line+=height, addr+=(vga.crtc.offset * 4), curr_addr+=(vga.crtc.offset * 4))
{
bitmapline = &bitmap.pix32(line);
addr %= vga.svga_intf.vram_size;
for (pos=addr, c=0, column=0; column<TGA_COLUMNS; column++, c+=8, pos+=0x20)
{
if(pos + 0x20 > 0x100000)
return;
for(xi=0,xm=0;xi<8;xi++,xm+=4)
{
int r,g,b;
if(!machine.primary_screen->visible_area().contains(c+xi, line + yi))
continue;
r = (MD(pos+xm)&0xff0000)>>16;
g = (MD(pos+xm)&0x00ff00)>>8;
b = (MD(pos+xm)&0x0000ff)>>0;
bitmapline[c+xi] = IV|(r<<16)|(g<<8)|(b<<0);
}
}
}
}
enum enum
{ {
@ -659,6 +699,7 @@ enum
RGB8_MODE, RGB8_MODE,
RGB15_MODE, RGB15_MODE,
RGB16_MODE, RGB16_MODE,
RGB32_MODE,
SVGA_HACK SVGA_HACK
}; };
@ -701,6 +742,10 @@ static UINT8 pc_vga_choosevideomode(running_machine &machine)
{ {
return SVGA_HACK; return SVGA_HACK;
} }
else if (svga.rgb32_en)
{
return RGB32_MODE;
}
else if (svga.rgb16_en) else if (svga.rgb16_en)
{ {
return RGB16_MODE; return RGB16_MODE;
@ -757,19 +802,21 @@ SCREEN_UPDATE_RGB32( pc_video )
cur_mode = pc_vga_choosevideomode(screen.machine()); cur_mode = pc_vga_choosevideomode(screen.machine());
//popmessage("%02x",cur_mode); //popmessage("%02x %02x",cur_mode,vga.attribute.data[0x13]);
//popmessage("%d",vga.attribute.pel_shift);
switch(cur_mode) switch(cur_mode)
{ {
case SCREEN_OFF: bitmap.fill(get_black_pen(screen.machine()), cliprect);break; case SCREEN_OFF: bitmap.fill (get_black_pen(screen.machine()), cliprect);break;
case TEXT_MODE: vga_vh_text(screen.machine(), bitmap, cliprect); break; case TEXT_MODE: vga_vh_text (screen.machine(), bitmap, cliprect); break;
case VGA_MODE: vga_vh_vga (screen.machine(), bitmap, cliprect); break; case VGA_MODE: vga_vh_vga (screen.machine(), bitmap, cliprect); break;
case EGA_MODE: vga_vh_ega (screen.machine(), bitmap, cliprect); break; case EGA_MODE: vga_vh_ega (screen.machine(), bitmap, cliprect); break;
case CGA_MODE: vga_vh_cga (screen.machine(), bitmap, cliprect); break; case CGA_MODE: vga_vh_cga (screen.machine(), bitmap, cliprect); break;
case MONO_MODE: vga_vh_mono(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 RGB8_MODE: svga_vh_rgb8 (screen.machine(), bitmap, cliprect); break;
case RGB15_MODE: svga_vh_rgb15(screen.machine(), bitmap, cliprect); break; case RGB15_MODE: svga_vh_rgb15(screen.machine(), bitmap, cliprect); break;
case RGB16_MODE: svga_vh_rgb16(screen.machine(), bitmap, cliprect); break; case RGB16_MODE: svga_vh_rgb16(screen.machine(), bitmap, cliprect); break;
case RGB32_MODE: svga_vh_rgb32(screen.machine(), bitmap, cliprect); break;
case SVGA_HACK: vga.svga_intf.choosevideomode(screen.machine(), bitmap, cliprect, vga.sequencer.data, vga.crtc.data, &w, &h); break; case SVGA_HACK: vga.svga_intf.choosevideomode(screen.machine(), bitmap, cliprect, vga.sequencer.data, vga.crtc.data, &w, &h); break;
} }
@ -880,8 +927,8 @@ static void recompute_params(running_machine &machine)
static void crtc_reg_write(running_machine &machine, UINT8 index, UINT8 data) static void crtc_reg_write(running_machine &machine, UINT8 index, UINT8 data)
{ {
/* Doom does this */ /* Doom does this */
// if(vga.crtc.protect_enable && index <= 0x07) // if(vga.crtc.protect_enable && index <= 0x07)
// printf("write to protected address %02x\n",index); // printf("write to protected address %02x\n",index);
switch(index) switch(index)
{ {
@ -1179,8 +1226,8 @@ READ8_HANDLER( vga_port_03c0_r )
data = vga.attribute.index; data = vga.attribute.index;
break; break;
case 1: case 1:
if( vga.attribute.index & 0x20) // protection bit if(vga.attribute.index&0x20)
data = vga.attribute.index; data = vga.attribute.index; // TODO: open bus
else if ((vga.attribute.index&0x1f)<sizeof(vga.attribute.data)) else if ((vga.attribute.index&0x1f)<sizeof(vga.attribute.data))
data=vga.attribute.data[vga.attribute.index&0x1f]; data=vga.attribute.data[vga.attribute.index&0x1f];
break; break;
@ -1304,6 +1351,7 @@ static void attribute_reg_write(UINT8 index, UINT8 data)
{ {
if((index & 0x30) == 0) if((index & 0x30) == 0)
{ {
//if(vga.sequencer.data[1]&0x20) // ok?
vga.attribute.data[index & 0x1f] = data & 0x3f; vga.attribute.data[index & 0x1f] = data & 0x3f;
} }
else else
@ -1314,7 +1362,7 @@ static void attribute_reg_write(UINT8 index, UINT8 data)
case 0x10: vga.attribute.data[0x10] = data; break; case 0x10: vga.attribute.data[0x10] = data; break;
case 0x11: vga.attribute.data[0x11] = data; break; case 0x11: vga.attribute.data[0x11] = data; break;
case 0x12: vga.attribute.data[0x12] = data; break; case 0x12: vga.attribute.data[0x12] = data; break;
case 0x13: vga.attribute.data[0x13] = data; break; case 0x13: vga.attribute.pel_shift = vga.attribute.data[0x13] = data; break;
case 0x14: vga.attribute.data[0x14] = data; break; case 0x14: vga.attribute.data[0x14] = data; break;
} }
} }
@ -1505,9 +1553,9 @@ READ8_HANDLER(vga_mem_r)
if (!space->debugger_access()) if (!space->debugger_access())
{ {
vga.gc.latch[0]=vga.memory[(offset)]; vga.gc.latch[0]=vga.memory[(offset)];
vga.gc.latch[1]=vga.memory[(offset)+0x20000]; vga.gc.latch[1]=vga.memory[(offset)+0x10000];
vga.gc.latch[2]=vga.memory[(offset)+0x40000]; vga.gc.latch[2]=vga.memory[(offset)+0x20000];
vga.gc.latch[3]=vga.memory[(offset)+0x60000]; vga.gc.latch[3]=vga.memory[(offset)+0x30000];
} }
if (vga.gc.read_mode) if (vga.gc.read_mode)
@ -1545,7 +1593,7 @@ READ8_HANDLER(vga_mem_r)
for(i=0;i<4;i++) for(i=0;i<4;i++)
{ {
if(vga.sequencer.map_mask & 1 << i) if(vga.sequencer.map_mask & 1 << i)
data |= vga.memory[offset+i*0x20000]; data |= vga.memory[offset+i*0x10000];
} }
return data; return data;
@ -1586,7 +1634,7 @@ WRITE8_HANDLER(vga_mem_w)
for(i=0;i<4;i++) for(i=0;i<4;i++)
{ {
if(vga.sequencer.map_mask & 1 << i) if(vga.sequencer.map_mask & 1 << i)
vga.memory[offset+i*0x20000] = (vga.sequencer.data[4] & 4) ? vga_latch_write(i,data) : data; vga.memory[offset+i*0x10000] = (vga.sequencer.data[4] & 4) ? vga_latch_write(i,data) : data;
} }
return; return;
} }
@ -2137,6 +2185,9 @@ static UINT8 s3_crtc_reg_read(running_machine &machine, UINT8 index)
case 0x38: case 0x38:
res = s3.reg_lock1; res = s3.reg_lock1;
break; break;
case 0x39:
res = s3.reg_lock2;
break;
case 0x42: // CR42 Mode Control case 0x42: // CR42 Mode Control
res = 0x0d; // hardcode to non-interlace res = 0x0d; // hardcode to non-interlace
break; break;
@ -2164,9 +2215,12 @@ static void s3_define_video_mode(void)
svga.rgb8_en = 0; svga.rgb8_en = 0;
svga.rgb15_en = 0; svga.rgb15_en = 0;
svga.rgb16_en = 0; svga.rgb16_en = 0;
svga.rgb32_en = 0;
switch((s3.ext_misc_ctrl_2) >> 4) switch((s3.ext_misc_ctrl_2) >> 4)
{ {
case 5: svga.rgb16_en = 1; break; case 0x03: svga.rgb15_en = 1; break;
case 0x05: svga.rgb16_en = 1; break;
case 0x0d: svga.rgb32_en = 1; break;
default: fatalerror("TODO: s3 video mode not implemented %02x",((s3.ext_misc_ctrl_2) >> 4)); break; default: fatalerror("TODO: s3 video mode not implemented %02x",((s3.ext_misc_ctrl_2) >> 4)); break;
} }
} }
@ -2174,6 +2228,8 @@ static void s3_define_video_mode(void)
{ {
svga.rgb8_en = (s3.memory_config & 8) >> 3; svga.rgb8_en = (s3.memory_config & 8) >> 3;
svga.rgb15_en = 0; svga.rgb15_en = 0;
svga.rgb16_en = 0;
svga.rgb32_en = 0;
} }
} }
@ -2202,6 +2258,10 @@ static void s3_crtc_reg_write(running_machine &machine, UINT8 index, UINT8 data)
case 0x38: case 0x38:
s3.reg_lock1 = data; s3.reg_lock1 = data;
break; break;
case 0x39:
/* TODO: reg lock mechanism */
s3.reg_lock2 = data;
break;
case 0x51: case 0x51:
vga.crtc.start_addr &= ~0xc0000; vga.crtc.start_addr &= ~0xc0000;
vga.crtc.start_addr |= ((data & 0x3) << 18); vga.crtc.start_addr |= ((data & 0x3) << 18);
@ -2275,7 +2335,7 @@ WRITE8_HANDLER(s3_port_9ae8_w)
READ8_HANDLER( s3_mem_r ) READ8_HANDLER( s3_mem_r )
{ {
if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en) if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb32_en)
{ {
int data; int data;
if(offset & 0x10000) if(offset & 0x10000)
@ -2300,7 +2360,7 @@ READ8_HANDLER( s3_mem_r )
WRITE8_HANDLER( s3_mem_w ) WRITE8_HANDLER( s3_mem_w )
{ {
if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en) if (svga.rgb8_en || svga.rgb15_en || svga.rgb16_en || svga.rgb32_en)
{ {
//printf("%08x %02x (%02x %02x) %02X\n",offset,data,vga.sequencer.map_mask,svga.bank_w,(vga.sequencer.data[4] & 0x08)); //printf("%08x %02x (%02x %02x) %02X\n",offset,data,vga.sequencer.map_mask,svga.bank_w,(vga.sequencer.data[4] & 0x08));
if(offset & 0x10000) if(offset & 0x10000)