1
0
Fork 0

add variable-size graphics memory, enable some more vga memory wrapping (vasyl)

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3077
This commit is contained in:
Sebastian Strohhäcker 2008-01-12 17:37:48 +00:00
parent 056302a6a5
commit 50917251f4
10 changed files with 285 additions and 76 deletions

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga.h,v 1.37 2008-01-09 20:34:21 c2woody Exp $ */
/* $Id: vga.h,v 1.38 2008-01-12 17:36:48 c2woody Exp $ */
#ifndef DOSBOX_VGA_H
#define DOSBOX_VGA_H
@ -31,9 +31,6 @@
#define VGA_MEMORY (2*1024*1024)
#define VGA_CHANGE_SHIFT 9
//Offset inside VGA_MEMORY that will be used for certain types of caching
#define VGA_CACHE_OFFSET (512*1024)
class PageHandler;
@ -164,6 +161,7 @@ typedef struct {
Bit8u reg_lock2;
Bit8u reg_31;
Bit8u reg_35;
Bit8u reg_36; // RAM size
Bit8u reg_3a; // 4/8/doublepixel bit in there
Bit8u reg_40; // 8415/A functionality register
Bit8u reg_41; // BIOS flags
@ -330,11 +328,12 @@ typedef union {
typedef struct {
Bit8u* linear;
Bit8u* linear_orgptr;
} VGA_Memory;
typedef struct {
//Add a few more just to be safe
Bit8u map[(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32];
Bit8u* map; /* allocated dynamically: [(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32] */
Bit8u checkMask, frame, writeMask;
bool active;
Bit32u clearMask;
@ -370,6 +369,10 @@ typedef struct {
VGA_TANDY tandy;
VGA_OTHER other;
VGA_Memory mem;
Bit32u vmemwrap; /* this is assumed to be power of 2 */
Bit8u* fastmem; /* memory for fast (usually 16-color) rendering, always twice as big as vmemsize */
Bit8u* fastmem_orgptr;
Bit32u vmemsize;
#ifdef VGA_KEEP_CHANGES
VGA_Changes changes;
#endif
@ -394,7 +397,7 @@ void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
/* The VGA Subfunction startups */
void VGA_SetupAttr(void);
void VGA_SetupMemory(void);
void VGA_SetupMemory(Section* sec);
void VGA_SetupDAC(void);
void VGA_SetupCRTC(void);
void VGA_SetupMisc(void);
@ -472,6 +475,9 @@ void SVGA_Setup_TsengET3K(void);
void SVGA_Setup_ParadisePVGA1A(void);
void SVGA_Setup_Driver(void);
// Amount of video memory required for a mode, implemented in int10_modes.cpp
Bitu VideoModeMemSize(Bitu mode);
extern Bit32u ExpandTable[256];
extern Bit32u FillTable[16];
extern Bit32u CGA_2_Table[16];

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga.cpp,v 1.32 2008-01-09 20:34:51 c2woody Exp $ */
/* $Id: vga.cpp,v 1.33 2008-01-12 17:37:48 c2woody Exp $ */
#include "dosbox.h"
//#include "setup.h"
@ -170,7 +170,7 @@ void VGA_Init(Section* sec) {
vga.draw.resizing=false;
vga.mode=M_ERROR; //For first init
SVGA_Setup_Driver();
VGA_SetupMemory();
VGA_SetupMemory(sec);
VGA_SetupMisc();
VGA_SetupDAC();
VGA_SetupGFX();
@ -249,5 +249,8 @@ void SVGA_Setup_Driver(void) {
case SVGA_ParadisePVGA1A:
SVGA_Setup_ParadisePVGA1A();
break;
default:
vga.vmemsize = vga.vmemwrap = 256*1024;
break;
}
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_draw.cpp,v 1.91 2008-01-09 20:34:51 c2woody Exp $ */
/* $Id: vga_draw.cpp,v 1.92 2008-01-12 17:37:48 c2woody Exp $ */
#include <string.h>
#include <math.h>
@ -150,7 +150,10 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) {
Bitu end = ((vidstart + vga.draw.line_length ) >> VGA_CHANGE_SHIFT);
for (; start <= end;start++) {
if ( map[start] & checkMask ) {
Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ];
Bitu offset = vidstart & vga.draw.linear_mask;
if(vga.draw.linear_mask-offset < vga.draw.line_length)
memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length);
Bit8u *ret = &vga.draw.linear_base[ offset ];
#if !defined(C_UNALIGNED_MEMORY)
if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) {
memcpy( TempLine, ret, vga.draw.line_length );
@ -168,7 +171,12 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) {
#endif
static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) {
Bit8u *ret = &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ];
// There is guaranteed extra memory past the wrap boundary. So, instead of using temporary
// storage just copy appropriate chunk from the beginning to the wrap boundary when needed.
Bitu offset = vidstart & vga.draw.linear_mask;
if (vga.draw.linear_mask-offset < vga.draw.line_length)
memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length);
Bit8u *ret = &vga.draw.linear_base[ offset ];
#if !defined(C_UNALIGNED_MEMORY)
if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) {
memcpy( TempLine, ret, vga.draw.line_length );
@ -598,7 +606,7 @@ skip_cursor:
static void VGA_VerticalDisplayEnd(Bitu val) {
// vga.config.retrace=true;
vga.config.real_start=vga.config.display_start & ((VGA_MEMORY)-1);
vga.config.real_start=vga.config.display_start & (vga.vmemwrap-1);
}
static void VGA_HorizontalTimer(void) {
@ -800,11 +808,11 @@ static void VGA_VerticalTimer(Bitu val) {
break;
case M_VGA:
if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) {
vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET;
vga.draw.linear_base = vga.fastmem;
vga.draw.linear_mask = 0xffff;
} else {
vga.draw.linear_base = vga.mem.linear;
vga.draw.linear_mask = VGA_MEMORY - 1;
vga.draw.linear_mask = vga.vmemwrap - 1;
}
case M_LIN8:
case M_LIN15:
@ -1148,7 +1156,7 @@ void VGA_SetupDrawing(Bitu val) {
break;
}
vga.draw.linear_base = vga.mem.linear;
vga.draw.linear_mask = VGA_MEMORY - 1;
vga.draw.linear_mask = vga.vmemwrap - 1;
switch (vga.mode) {
case M_VGA:
doublewidth=true;
@ -1187,8 +1195,8 @@ void VGA_SetupDrawing(Bitu val) {
vga.draw.blocks = width;
width<<=3;
VGA_DrawLine=VGA_Draw_Linear_Line;
vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET;
vga.draw.linear_mask = 1024 * 1024 - 1;
vga.draw.linear_base = vga.fastmem;
vga.draw.linear_mask = (vga.vmemwrap<<1) - 1;
break;
case M_EGA:
doublewidth=(vga.seq.clocking_mode & 0x8) > 0;
@ -1199,8 +1207,8 @@ void VGA_SetupDrawing(Bitu val) {
VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line;
} else VGA_DrawLine=VGA_Draw_Linear_Line;
vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET;
vga.draw.linear_mask = 512 * 1024 - 1;
vga.draw.linear_base = vga.fastmem;
vga.draw.linear_mask = (vga.vmemwrap<<1) - 1;
break;
case M_CGA16:
doubleheight=true;

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_memory.cpp,v 1.46 2008-01-09 20:34:51 c2woody Exp $ */
/* $Id: vga_memory.cpp,v 1.47 2008-01-12 17:37:48 c2woody Exp $ */
#include <stdlib.h>
#include <string.h>
@ -26,6 +26,27 @@
#include "paging.h"
#include "pic.h"
#include "inout.h"
#include "setup.h"
/* #ifndef C_VGARAM_CHECKED
#define C_VGARAM_CHECKED 1
#endif */
#if C_VGARAM_CHECKED
// Checked linear offset
#define CHECKED(v) ((v)&(vga.vmemwrap-1))
// Checked planar offset (latched access)
#define CHECKED2(v) ((v)&((vga.vmemwrap>>2)-1))
// Checked planar offset (latched access)
#else
#define CHECKED(v) (v)
#define CHECKED2(v) (v)
#endif
#define CHECKED3(v) ((v)&(vga.vmemwrap-1))
#define CHECKED4(v) ((v)&((vga.vmemwrap>>2)-1))
#ifdef VGA_KEEP_CHANGES
#define MEM_CHANGED( _MEM ) vga.changes.map[ (_MEM) >> VGA_CHANGE_SHIFT ] |= vga.changes.writeMask;
@ -133,11 +154,13 @@ public:
Bitu readb(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED2(addr);
return readHandler(addr);
}
Bitu readw(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED2(addr);
return
(readHandler(addr+0) << 0) |
(readHandler(addr+1) << 8);
@ -145,6 +168,7 @@ public:
Bitu readd(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED2(addr);
return
(readHandler(addr+0) << 0) |
(readHandler(addr+1) << 8) |
@ -166,7 +190,7 @@ public:
start >>= 2;
pixels.d=((Bit32u*)vga.mem.linear)[start];
Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)];
Bit8u * write_pixels=&vga.fastmem[start<<3];
Bit32u colors0_3, colors4_7;
VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f;
@ -191,12 +215,14 @@ public:
void writeb(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr << 3);
writeHandler(addr+0,(Bit8u)(val >> 0));
}
void writew(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr << 3);
writeHandler(addr+0,(Bit8u)(val >> 0));
writeHandler(addr+1,(Bit8u)(val >> 8));
@ -204,6 +230,7 @@ public:
void writed(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr << 3);
writeHandler(addr+0,(Bit8u)(val >> 0));
writeHandler(addr+1,(Bit8u)(val >> 8));
@ -213,11 +240,13 @@ public:
Bitu readb(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
return readHandler(addr);
}
Bitu readw(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
return
(readHandler(addr+0) << 0) |
(readHandler(addr+1) << 8);
@ -225,6 +254,7 @@ public:
Bitu readd(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
return
(readHandler(addr+0) << 0) |
(readHandler(addr+1) << 8) |
@ -244,7 +274,7 @@ public:
pixels.d&=vga.config.full_not_map_mask;
pixels.d|=(data & vga.config.full_map_mask);
((Bit32u*)vga.mem.linear)[start]=pixels.d;
Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)];
Bit8u * write_pixels=&vga.fastmem[start<<3];
Bit32u colors0_3, colors4_7;
VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f;
@ -261,10 +291,6 @@ public:
Expand16Table[2][temp.b[2]] |
Expand16Table[3][temp.b[3]];
*(Bit32u *)(write_pixels+4)=colors4_7;
if (wrapping && GCC_UNLIKELY( start < 512)) {
*(Bit32u *)(write_pixels+512*1024)=colors0_3;
*(Bit32u *)(write_pixels+512*1024+4)=colors4_7;
}
}
public:
VGA_UnchainedEGA_Handler() {
@ -273,12 +299,14 @@ public:
void writeb(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED2(addr);
MEM_CHANGED( addr << 3);
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
}
void writew(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED2(addr);
MEM_CHANGED( addr << 3);
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
writeHandler<true>(addr+1,(Bit8u)(val >> 8));
@ -286,6 +314,7 @@ public:
void writed(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED2(addr);
MEM_CHANGED( addr << 3);
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
writeHandler<true>(addr+1,(Bit8u)(val >> 8));
@ -306,10 +335,10 @@ public:
}
template <class Size>
static INLINE void writeCache(PhysPt addr, Bitu val) {
hostWrite<Size>( &vga.mem.linear[VGA_CACHE_OFFSET+addr], val );
hostWrite<Size>( &vga.fastmem[addr], val );
if (GCC_UNLIKELY(addr < 320)) {
// And replicate the first line
hostWrite<Size>( &vga.mem.linear[VGA_CACHE_OFFSET+addr+64*1024], val );
hostWrite<Size>( &vga.fastmem[addr+64*1024], val );
}
}
template <class Size>
@ -320,11 +349,13 @@ public:
Bitu readb(PhysPt addr ) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
return readHandler<Bit8u>( addr );
}
Bitu readw(PhysPt addr ) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
if (GCC_UNLIKELY(addr & 1))
return
(readHandler<Bit8u>( addr+0 ) << 0 ) |
@ -335,6 +366,7 @@ public:
Bitu readd(PhysPt addr ) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
if (GCC_UNLIKELY(addr & 3))
return
(readHandler<Bit8u>( addr+0 ) << 0 ) |
@ -347,6 +379,7 @@ public:
void writeb(PhysPt addr, Bitu val ) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr );
writeHandler<Bit8u>( addr, val );
writeCache<Bit8u>( addr, val );
@ -354,6 +387,7 @@ public:
void writew(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr );
// MEM_CHANGED( addr + 1);
if (GCC_UNLIKELY(addr & 1)) {
@ -367,6 +401,7 @@ public:
void writed(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr );
// MEM_CHANGED( addr + 3);
if (GCC_UNLIKELY(addr & 3)) {
@ -391,7 +426,7 @@ public:
pixels.d|=(data & vga.config.full_map_mask);
((Bit32u*)vga.mem.linear)[addr]=pixels.d;
if(vga.config.compatible_chain4)
((Bit32u*)vga.mem.linear)[addr+64*1024]=pixels.d;
((Bit32u*)vga.mem.linear)[CHECKED2(addr+64*1024)]=pixels.d;
}
public:
VGA_UnchainedVGA_Handler() {
@ -400,12 +435,14 @@ public:
void writeb(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED2(addr);
MEM_CHANGED( addr << 2 );
writeHandler(addr+0,(Bit8u)(val >> 0));
}
void writew(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED2(addr);
MEM_CHANGED( addr << 2);
writeHandler(addr+0,(Bit8u)(val >> 0));
writeHandler(addr+1,(Bit8u)(val >> 8));
@ -413,6 +450,7 @@ public:
void writed(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED2(addr);
MEM_CHANGED( addr << 2);
writeHandler(addr+0,(Bit8u)(val >> 0));
writeHandler(addr+1,(Bit8u)(val >> 8));
@ -445,11 +483,11 @@ public:
}
HostPt GetHostReadPt(Bitu phys_page) {
phys_page-=vgapages.base;
return &vga.mem.linear[vga.svga.bank_read_full+phys_page*4096];
return &vga.mem.linear[CHECKED3(vga.svga.bank_read_full+phys_page*4096)];
}
HostPt GetHostWritePt(Bitu phys_page) {
phys_page-=vgapages.base;
return &vga.mem.linear[vga.svga.bank_write_full+phys_page*4096];
return &vga.mem.linear[CHECKED3(vga.svga.bank_write_full+phys_page*4096)];
}
};
@ -461,33 +499,39 @@ public:
Bitu readb(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
return hostRead<Bit8u>( &vga.mem.linear[addr] );
}
Bitu readw(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
return hostRead<Bit16u>( &vga.mem.linear[addr] );
}
Bitu readd(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_read_full;
addr = CHECKED(addr);
return hostRead<Bit32u>( &vga.mem.linear[addr] );
}
void writeb(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr );
hostWrite<Bit8u>( &vga.mem.linear[addr], val );
}
void writew(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr );
hostWrite<Bit16u>( &vga.mem.linear[addr], val );
}
void writed(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
addr += vga.svga.bank_write_full;
addr = CHECKED(addr);
MEM_CHANGED( addr );
hostWrite<Bit32u>( &vga.mem.linear[addr], val );
}
@ -500,20 +544,20 @@ public:
}
void writeb(PhysPt addr,Bitu val) {
addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
addr &= (128*1024-1);
addr = CHECKED4(addr);
MEM_CHANGED( addr << 3 );
writeHandler<false>(addr+0,(Bit8u)(val >> 0));
}
void writew(PhysPt addr,Bitu val) {
addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
addr &= (128*1024-1);
addr = CHECKED4(addr);
MEM_CHANGED( addr << 3 );
writeHandler<false>(addr+0,(Bit8u)(val >> 0));
writeHandler<false>(addr+1,(Bit8u)(val >> 8));
}
void writed(PhysPt addr,Bitu val) {
addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
addr &= (128*1024-1);
addr = CHECKED4(addr);
MEM_CHANGED( addr << 3 );
writeHandler<false>(addr+0,(Bit8u)(val >> 0));
writeHandler<false>(addr+1,(Bit8u)(val >> 8));
@ -522,19 +566,19 @@ public:
}
Bitu readb(PhysPt addr) {
addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
addr &= (128*1024-1);
addr = CHECKED4(addr);
return readHandler(addr);
}
Bitu readw(PhysPt addr) {
addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
addr &= (128*1024-1);
addr = CHECKED4(addr);
return
(readHandler(addr+0) << 0) |
(readHandler(addr+1) << 8);
}
Bitu readd(PhysPt addr) {
addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
addr &= (128*1024-1);
addr = CHECKED4(addr);
return
(readHandler(addr+0) << 0) |
(readHandler(addr+1) << 8) |
@ -551,28 +595,34 @@ public:
}
Bitu readb(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
addr = CHECKED(addr);
return hostRead<Bit8u>( &vga.mem.linear[addr] );
}
Bitu readw(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
addr = CHECKED(addr);
return hostRead<Bit16u>( &vga.mem.linear[addr] );
}
Bitu readd(PhysPt addr) {
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
addr = CHECKED(addr);
return hostRead<Bit32u>( &vga.mem.linear[addr] );
}
void writeb(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
addr = CHECKED(addr);
hostWrite<Bit8u>( &vga.mem.linear[addr], val );
MEM_CHANGED( addr );
}
void writew(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
addr = CHECKED(addr);
hostWrite<Bit16u>( &vga.mem.linear[addr], val );
MEM_CHANGED( addr );
}
void writed(PhysPt addr,Bitu val) {
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
addr = CHECKED(addr);
hostWrite<Bit32u>( &vga.mem.linear[addr], val );
MEM_CHANGED( addr );
}
@ -585,7 +635,7 @@ public:
}
HostPt GetHostReadPt( Bitu phys_page ) {
phys_page -= vga.lfb.page;
return &vga.mem.linear[phys_page * 4096];
return &vga.mem.linear[CHECKED3(phys_page * 4096)];
}
HostPt GetHostWritePt( Bitu phys_page ) {
return GetHostReadPt( phys_page );
@ -838,21 +888,45 @@ void VGA_StartUpdateLFB(void) {
#else
vga.lfb.handler = &vgaph.lfbchanges;
#endif
MEM_SetLFB(vga.s3.la_window << 4 ,VGA_MEMORY/4096, vga.lfb.handler, &vgaph.mmio);
MEM_SetLFB(vga.s3.la_window << 4 ,vga.vmemsize/4096, vga.lfb.handler, &vgaph.mmio);
}
void VGA_SetupMemory() {
// allocate 16byte-aligned memory
vga.mem.linear = new Bit8u[VGA_MEMORY+16];
vga.mem.linear=(Bit8u*)(((Bitu)vga.mem.linear + 16-1) & ~(16-1));
memset( vga.mem.linear, 0, VGA_MEMORY );
static void VGA_Memory_ShutDown(Section * sec) {
delete[] vga.mem.linear_orgptr;
delete[] vga.fastmem_orgptr;
#ifdef VGA_KEEP_CHANGES
delete[] vga.changes.map;
#endif
}
void VGA_SetupMemory(Section* sec) {
vga.svga.bank_read = vga.svga.bank_write = 0;
vga.svga.bank_read_full = vga.svga.bank_write_full = 0;
// We reserve extra 2K for one scan line
vga.mem.linear_orgptr = new Bit8u[vga.vmemsize+2048+16];
vga.mem.linear=(Bit8u*)(((Bitu)vga.mem.linear_orgptr + 16-1) & ~(16-1));
memset(vga.mem.linear,0,vga.vmemsize);
vga.fastmem_orgptr = new Bit8u[(vga.vmemsize<<1)+4096+16];
vga.fastmem=(Bit8u*)(((Bitu)vga.fastmem_orgptr + 16-1) & ~(16-1));
// In most cases these values stay the same. Assumptions: vmemwrap is power of 2,
// vmemwrap <= vmemsize, fastmem implicitly has mem wrap twice as big
vga.vmemwrap = vga.vmemsize;
#ifdef VGA_KEEP_CHANGES
memset( &vga.changes, 0, sizeof( vga.changes ));
int changesMapSize = (vga.vmemsize >> VGA_CHANGE_SHIFT) + 32;
vga.changes.map = new Bit8u[changesMapSize];
memset(vga.changes.map, 0, changesMapSize);
#endif
vga.svga.bank_read = vga.svga.bank_write = 0;
vga.svga.bank_read_full = vga.svga.bank_write_full = 0;
vga.svga.bank_size = 0x10000; /* most common bank size is 64K */
sec->AddDestroyFunction(&VGA_Memory_ShutDown);
if (machine==MCH_PCJR) {
/* PCJr does not have dedicated graphics memory but uses
conventional memory below 128k */

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_paradise.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */
/* $Id: vga_paradise.cpp,v 1.2 2008-01-12 17:37:48 c2woody Exp $ */
#include "dosbox.h"
#include "setup.h"
@ -162,10 +162,13 @@ void FinishSetMode_PVGA1A(Bitu /*crtc_base*/, VGA_ModeExtraData* modeData) {
if (svga.determine_mode)
svga.determine_mode();
if (vga.mode != M_VGA)
vga.config.compatible_chain4 = false; // in process of verification
else
if(vga.mode != M_VGA) {
vga.config.compatible_chain4 = false;
vga.vmemwrap = vga.vmemsize;
} else {
vga.config.compatible_chain4 = true;
vga.vmemwrap = 256*1024;
}
VGA_SetupHandlers();
}
@ -195,6 +198,10 @@ Bitu GetClock_PVGA1A() {
return pvga1a.clockFreq[(vga.misc_output >> 2) & 3];
}
bool AcceptsMode_PVGA1A(Bitu mode) {
return VideoModeMemSize(mode) < vga.vmemsize;
}
void SVGA_Setup_ParadisePVGA1A(void) {
svga.write_p3cf = &write_p3cf_pvga1a;
svga.read_p3cf = &read_p3cf_pvga1a;
@ -203,14 +210,26 @@ void SVGA_Setup_ParadisePVGA1A(void) {
svga.determine_mode = &DetermineMode_PVGA1A;
svga.set_clock = &SetClock_PVGA1A;
svga.get_clock = &GetClock_PVGA1A;
svga.accepts_mode = &AcceptsMode_PVGA1A;
VGA_SetClock(0,CLK_25);
VGA_SetClock(1,CLK_28);
VGA_SetClock(2,32400); // could not find documentation
VGA_SetClock(3,35900);
// Set memory size at 512K (standard for PVGA1A)
pvga1a.PR1 = 2<<6;
// Adjust memory, default to 512K
if (vga.vmemsize == 0)
vga.vmemsize = 512*1024;
if (vga.vmemsize < 512*1024) {
vga.vmemsize = 256*1024;
pvga1a.PR1 = 1<<6;
} else if (vga.vmemsize > 512*1024) {
vga.vmemsize = 1024*1024;
pvga1a.PR1 = 3<<6;
} else {
pvga1a.PR1 = 2<<6;
}
// Paradise ROM signature
PhysPt rom_base=PhysMake(0xc000,0);

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_s3.cpp,v 1.11 2008-01-09 20:34:51 c2woody Exp $ */
/* $Id: vga_s3.cpp,v 1.12 2008-01-12 17:37:48 c2woody Exp $ */
#include "dosbox.h"
#include "inout.h"
@ -28,6 +28,8 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
//TODO Base address
vga.s3.reg_31 = val;
vga.config.compatible_chain4 = !(val&0x08);
if (vga.config.compatible_chain4) vga.vmemwrap = 256*1024;
else vga.vmemwrap = vga.vmemsize;
vga.config.display_start = (vga.config.display_start&~0x30000)|((val&0x30)<<12);
VGA_DetermineMode();
VGA_SetupHandlers();
@ -312,7 +314,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
}
break;
case 0x6a: /* Extended System Control 4 */
vga.svga.bank_read=val & 0x3f;
vga.svga.bank_read=val & 0x7f;
vga.svga.bank_write = vga.svga.bank_read;
VGA_SetupHandlers();
break;
@ -345,8 +347,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) {
case 0x35: /* CR35 CRT Register Lock */
return vga.s3.reg_35|(vga.svga.bank_read & 0xf);
case 0x36: /* CR36 Reset State Read 1 */
return 0x92; /* PCI version */
//2 Mb PCI and some bios settings
return vga.s3.reg_36;
case 0x37: /* Reset state read 2 */
return 0x2b;
case 0x38: /* CR38 Register Lock 1 */
@ -403,7 +404,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) {
case 0x69: /* Extended System Control 3 */
return (Bit8u)((vga.config.display_start & 0x1f0000)>>16);
case 0x6a: /* Extended System Control 4 */
return (Bit8u)(vga.svga.bank_read & 0x3f);
return (Bit8u)(vga.svga.bank_read & 0x7f);
case 0x6b: // BIOS scatchpad: LFB address
return vga.s3.reg_6b;
default:
@ -483,6 +484,10 @@ bool SVGA_S3_HWCursorActive(void) {
return (vga.s3.hgc.curmode & 0x1) != 0;
}
bool SVGA_S3_AcceptsMode(Bitu mode) {
return VideoModeMemSize(mode) < vga.vmemsize;
}
void SVGA_Setup_S3Trio(void) {
svga.write_p3d5 = &SVGA_S3_WriteCRTC;
svga.read_p3d5 = &SVGA_S3_ReadCRTC;
@ -496,5 +501,26 @@ void SVGA_Setup_S3Trio(void) {
svga.set_clock = 0; /* implemented in core */
svga.get_clock = &SVGA_S3_GetClock;
svga.hardware_cursor_active = &SVGA_S3_HWCursorActive;
svga.accepts_mode = 0; /* don't filter modes */
svga.accepts_mode = &SVGA_S3_AcceptsMode;
if (vga.vmemsize == 0)
vga.vmemsize = VGA_MEMORY; // the most common S3 configuration
// Set CRTC 36 to specify amount of VRAM and PCI
if (vga.vmemsize < 1024*1024) {
vga.vmemsize = 512*1024;
vga.s3.reg_36 = 0xf2;
} else if (vga.vmemsize < 2048*1024) {
vga.vmemsize = 1024*1024;
vga.s3.reg_36 = 0xd2;
} else if (vga.vmemsize < 3072*1024) {
vga.vmemsize = 2048*1024;
vga.s3.reg_36 = 0x92;
} else if (vga.vmemsize < 4096*1024) {
vga.vmemsize = 3072*1024;
vga.s3.reg_36 = 0x52;
} else { // Trio64 supported only up to 4M
vga.vmemsize = 4096*1024;
vga.s3.reg_36 = 0x12;
}
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_tseng.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */
/* $Id: vga_tseng.cpp,v 1.2 2008-01-12 17:37:48 c2woody Exp $ */
#include "dosbox.h"
#include "setup.h"
@ -147,6 +147,7 @@ void write_p3d5_et4k(Bitu reg,Bitu val,Bitu iolen) {
case 0x37:
if (val != et4k.store_3d4_37) {
et4k.store_3d4_37 = val;
vga.vmemwrap = ((64*1024)<<((val&8)>>2))<<((val&3)-1);
VGA_SetupHandlers();
}
break;
@ -340,7 +341,7 @@ void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) {
IO_Write(crtc_base,0x33);IO_Write(crtc_base+1,0);
IO_Write(crtc_base,0x34);IO_Write(crtc_base+1,0);
IO_Write(crtc_base,0x36);IO_Write(crtc_base+1,0);
IO_Write(crtc_base,0x37);IO_Write(crtc_base+1,0x0f); // 1M video ram (0x0e for 512K, 0x0d for 256K)
IO_Write(crtc_base,0x37);IO_Write(crtc_base+1,0x0c|(vga.vmemsize==1024*1024?3:vga.vmemsize==512*1024?2:1));
// Clear ext SEQ
IO_Write(0x3c4,0x06);IO_Write(0x3c5,0);
IO_Write(0x3c4,0x07);IO_Write(0x3c5,0);
@ -368,6 +369,7 @@ void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) {
// Verified (on real hardware and in a few games): Tseng ET4000 used chain4 implementation
// different from standard VGA. It was also not limited to 64K in regular mode 13h.
vga.config.compatible_chain4 = false;
vga.vmemwrap = vga.vmemsize;
VGA_SetupHandlers();
}
@ -396,7 +398,8 @@ Bitu GetClock_ET4K() {
}
bool AcceptsMode_ET4K(Bitu mode) {
return mode != 0x3d;
return VideoModeMemSize(mode) < vga.vmemsize;
// return mode != 0x3d;
}
void SVGA_Setup_TsengET4K(void) {
@ -434,6 +437,17 @@ void SVGA_Setup_TsengET4K(void) {
IO_RegisterReadHandler(0x3cd,read_p3cd_et4k,IO_MB);
IO_RegisterWriteHandler(0x3cd,write_p3cd_et4k,IO_MB);
// Default to 1M of VRAM
if (vga.vmemsize == 0)
vga.vmemsize = 1024*1024;
if (vga.vmemsize < 512*1024)
vga.vmemsize = 256*1024;
else if (vga.vmemsize < 1024*1024)
vga.vmemsize = 512*1024;
else
vga.vmemsize = 1024*1024;
// Tseng ROM signature
PhysPt rom_base=PhysMake(0xc000,0);
phys_writeb(rom_base+0x0075,' ');
@ -716,6 +730,7 @@ void FinishSetMode_ET3K(Bitu crtc_base, VGA_ModeExtraData* modeData) {
// Verified on functioning (at last!) hardware: Tseng ET3000 is the same as ET4000 when
// it comes to chain4 architecture
vga.config.compatible_chain4 = false;
vga.vmemwrap = vga.vmemsize;
VGA_SetupHandlers();
}
@ -744,7 +759,7 @@ Bitu GetClock_ET3K() {
}
bool AcceptsMode_ET3K(Bitu mode) {
return mode <= 0x37 && mode != 0x2f;
return mode <= 0x37 && mode != 0x2f && VideoModeMemSize(mode) < vga.vmemsize;
}
void SVGA_Setup_TsengET3K(void) {
@ -773,6 +788,8 @@ void SVGA_Setup_TsengET3K(void) {
IO_RegisterReadHandler(0x3cd,read_p3cd_et3k,IO_MB);
IO_RegisterWriteHandler(0x3cd,write_p3cd_et3k,IO_MB);
vga.vmemsize = 512*1024; // Cannot figure how this was supposed to work on the real card
// Tseng ROM signature
PhysPt rom_base=PhysMake(0xc000,0);
phys_writeb(rom_base+0x0075,' ');

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_xga.cpp,v 1.11 2008-01-10 20:36:03 c2woody Exp $ */
/* $Id: vga_xga.cpp,v 1.12 2008-01-12 17:37:48 c2woody Exp $ */
#include <string.h>
#include "dosbox.h"
@ -152,7 +152,7 @@ void XGA_DrawPoint(Bitu x, Bitu y, Bitu c) {
Bitu XGA_GetPoint(Bitu x, Bitu y) {
Bit32u memaddr = (y * XGA_SCREEN_WIDTH) + x;
if(VGA_MEMORY < memaddr) {
if(vga.vmemsize < memaddr) {
//LOG_MSG("getpoint mem over: x%d y%d",x,y);
return 0;
}

View file

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_modes.cpp,v 1.74 2008-01-09 20:34:51 c2woody Exp $ */
/* $Id: int10_modes.cpp,v 1.75 2008-01-12 17:37:48 c2woody Exp $ */
#include <string.h>
@ -368,7 +368,8 @@ static void FinishSetMode(bool clearmem) {
case M_LIN16:
case M_LIN32:
/* Hack we just acess the memory directly */
memset(vga.mem.linear,0,VGA_MEMORY);
memset(vga.mem.linear,0,vga.vmemsize);
memset(vga.fastmem, 0, vga.vmemsize<<1);
}
}
/* Setup the BIOS */
@ -1270,3 +1271,50 @@ dac_text16:
}
return true;
}
Bitu VideoModeMemSize(Bitu mode) {
if (!IS_VGA_ARCH)
return 0;
VideoModeBlock* modelist = NULL;
switch (svgaCard) {
case SVGA_TsengET4K:
case SVGA_TsengET3K:
modelist = ModeList_VGA_Tseng;
break;
case SVGA_ParadisePVGA1A:
modelist = ModeList_VGA_Paradise;
break;
default:
modelist = ModeList_VGA;
break;
}
VideoModeBlock* vmodeBlock = NULL;
Bitu i=0;
while (modelist[i].mode!=0xffff) {
if (modelist[i].mode==mode) {
vmodeBlock = &modelist[i];
break;
}
i++;
}
if (!vmodeBlock)
return 0;
switch(vmodeBlock->type) {
case M_LIN4:
return vmodeBlock->swidth*vmodeBlock->sheight/2;
case M_LIN8:
return vmodeBlock->swidth*vmodeBlock->sheight;
case M_LIN15: case M_LIN16:
return vmodeBlock->swidth*vmodeBlock->sheight*2;
case M_LIN32:
return vmodeBlock->swidth*vmodeBlock->sheight*4;
case M_TEXT:
return vmodeBlock->twidth*vmodeBlock->theight*2;
}
// Return 0 for all other types, those always fit in memory
return 0;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2007 The DOSBox Team
* Copyright (C) 2002-2008 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_vesa.cpp,v 1.30 2007-12-10 22:11:13 c2woody Exp $ */
/* $Id: int10_vesa.cpp,v 1.31 2008-01-12 17:37:48 c2woody Exp $ */
#include <string.h>
#include <stddef.h>
@ -115,7 +115,7 @@ Bit8u VESA_GetSVGAInformation(Bit16u seg,Bit16u off) {
}
mem_writed(buffer+0x0a,0x0); //Capabilities and flags
mem_writed(buffer+0x0e,int10.rom.vesa_modes); //VESA Mode list
mem_writew(buffer+0x12,Bit16u(VGA_MEMORY/(64*1024))); // memory size in 64kb blocks
mem_writew(buffer+0x12,(Bit16u)(vga.vmemsize/(64*1024))); // memory size in 64kb blocks
return 0x00;
}
@ -129,6 +129,9 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) {
mode&=0x3fff; // vbe2 compatible, ignore lfb and keep screen content bits
if (mode<0x100) return 0x01;
if (svga.accepts_mode) {
if (!svga.accepts_mode(mode)) return 0x01;
}
while (ModeList_VGA[i].mode!=0xffff) {
if (mode==ModeList_VGA[i].mode) goto foundit; else i++;
}
@ -145,12 +148,12 @@ foundit:
var_write(&minfo.MemoryModel,3); //ega planar mode
modeAttributes = 0x1b; // Color, graphics, no linear buffer
if(pageSize > 512*1024) { // this limitation is not on the real card
if(pageSize > vga.vmemsize/4) { // this limitation is not on the real card
var_write(&minfo.ModeAttributes, modeAttributes & ~0x1);
var_write(&minfo.NumberOfImagePages,0);
} else {
var_write(&minfo.ModeAttributes, modeAttributes);
Bitu pages = (512*1024 / pageSize)-1;
Bitu pages = ((vga.vmemsize/4) / pageSize)-1;
var_write(&minfo.NumberOfImagePages,pages);
}
break;
@ -227,13 +230,13 @@ foundit:
var_write(&minfo.WinAAttributes,0x7); // Exists/readable/writable
if(mblock->type != M_LIN4)
if(pageSize > VGA_MEMORY) {
if(pageSize > vga.vmemsize) {
// Mode not supported by current hardware configuration
var_write(&minfo.ModeAttributes, modeAttributes & ~0x1);
var_write(&minfo.NumberOfImagePages,0);
} else {
var_write(&minfo.ModeAttributes, modeAttributes);
Bitu pages = (VGA_MEMORY / pageSize)-1;
Bitu pages = (vga.vmemsize / pageSize)-1;
var_write(&minfo.NumberOfImagePages,pages);
}
@ -274,7 +277,7 @@ Bit8u VESA_GetSVGAMode(Bit16u & mode) {
Bit8u VESA_SetCPUWindow(Bit8u window,Bit8u address) {
if (window) return 0x1;
if ((address<32)) {
if (((Bit32u)(address)*64*1024<vga.vmemsize)) {
IO_Write(0x3d4,0x6a);
IO_Write(0x3d5,(Bit8u)address);
return 0x0;
@ -359,7 +362,7 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixe
case 0x03: /* Get maximum */
bytes=0x400*4;
pixels=bytes/bpp;
lines = VGA_MEMORY / bytes;
lines = (Bit16u)(vga.vmemsize / bytes);
return 0x00;
case 0x01: /* Get lengths */
break;
@ -375,12 +378,12 @@ Bit8u VESA_ScanLineLength(Bit8u subcall,Bit16u val, Bit16u & bytes,Bit16u & pixe
if(CurMode->type==M_LIN4) {
pixels=(vga.config.scan_len*16)/bpp;
bytes=vga.config.scan_len*2;
lines = Bit16u(VGA_MEMORY /( bytes*4));
lines = (Bit16u)(vga.vmemsize /( bytes*4));
}
else {
pixels=(vga.config.scan_len*8)/bpp;
bytes=vga.config.scan_len*8;
lines = Bit16u(VGA_MEMORY / bytes);
lines = (Bit16u)(vga.vmemsize / bytes);
}
VGA_StartResize();
return 0x0;
@ -465,7 +468,12 @@ void INT10_SetupVESA(void) {
int10.rom.vesa_modes=RealMake(0xc000,int10.rom.used);
//TODO Maybe add normal vga modes too, but only seems to complicate things
while (ModeList_VGA[i].mode!=0xffff) {
if (ModeList_VGA[i].mode>=0x100){
bool canuse_mode=false;
if (!svga.accepts_mode) canuse_mode=true;
else {
if (svga.accepts_mode(ModeList_VGA[i].mode)) canuse_mode=true;
}
if (ModeList_VGA[i].mode>=0x100 && canuse_mode) {
phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode);
int10.rom.used+=2;
}