1
0
Fork 0

Support for setting linear frame buffer base.

New way of setting up vga read/write handler or frame buffer.
No longer use HostPt memory for certain video modes.


Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1122
This commit is contained in:
Sjoerd van der Berg 2003-07-14 08:39:40 +00:00
parent 74676d9bb7
commit 4d26f08a37
5 changed files with 76 additions and 62 deletions

View file

@ -48,6 +48,10 @@ enum VGAModes {
#define MH_SETRESET 0x0002;
#define MH_BITMASK 0x0004;
typedef Bit8u VGA_ReadHandler(PhysPt off);
typedef void VGA_WriteHandler(PhysPt off,Bit8u val);
typedef struct {
bool attrindex;
} VGA_Internal;
@ -78,7 +82,10 @@ typedef struct {
Bit8u bytes_skip;
/* Specific stuff memory write/read handling */
PhysPt mem_base;
VGA_ReadHandler * readhandler;
VGA_WriteHandler * writehandler;
Bit8u read_mode;
Bit8u write_mode;
Bit8u read_map_select;
@ -128,6 +135,7 @@ typedef struct {
Bit8u reg_55;
Bit8u ex_hor_overflow;
Bit8u ex_ver_overflow;
Bit16u la_window;
struct {
Bit8u r;
Bit8u n;
@ -262,13 +270,15 @@ typedef struct {
VGA_Memory mem;
} VGA_Type;
/* Functions for different resolutions */
void VGA_SetMode(VGAModes mode);
void VGA_SetupHandlers(void);
void VGA_StartResize(void);
void VGA_SetupDrawing(void);
/* Some support functions */
/* Some DAC/Attribute functions */
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal);
void VGA_ATTR_SetPalette(Bit8u index,Bit8u val);
@ -285,6 +295,7 @@ void VGA_SetupSEQ(void);
void VGA_SetClock(Bitu which,Bitu target);
void VGA_DACSetEntirePalette(void);
void VGA_StartRetrace(void);
void VGA_StartUpdateLFB(void);
extern VGA_Type vga;

View file

@ -422,6 +422,14 @@ void write_p3d5(Bit32u port,Bit8u val) {
7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs,
if clear 7MCLKs
*/
case 0x59: /* Linear Address Window Position Low */
vga.s3.la_window=(vga.s3.la_window&0xff00) | val;
VGA_StartUpdateLFB();
break;
case 0x5a: /* Linear Address Window Position High */
vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8);
VGA_StartUpdateLFB();
break;
case 0x5D: /* Extended Horizontal Overflow */
if ((val & vga.s3.ex_hor_overflow) ^ 3) {
vga.s3.ex_hor_overflow=val;

View file

@ -26,8 +26,8 @@
//TODO Make the full draw like the vga really does from video memory.
static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) {
Bit8u * reader=HostMake(0xB800,0);
Bit8u * flip=HostMake(0xB800,8*1024);
Bit8u * reader=&vga.mem.linear[0];
Bit8u * flip=&vga.mem.linear[8*1024];
Bit8u * draw;
for (Bitu y=0;y<vga.draw.height;y++) {
Bit8u * tempread;
@ -55,8 +55,8 @@ static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) {
}
static void VGA_CGA4_Draw(Bit8u * bitdata,Bitu pitch) {
Bit8u * reader=HostMake(0xB800,vga.config.display_start*2);
Bit8u * flip=HostMake(0xB800,8*1024);
Bit8u * reader=&vga.mem.linear[0];
Bit8u * flip=&vga.mem.linear[8*1024];
Bit8u * draw;
for (Bitu y=0;y<vga.draw.height;y++) {
Bit8u * tempread;
@ -99,7 +99,7 @@ static void VGA_TANDY16_Draw(Bit8u * bitdata,Bitu pitch) {
void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) {
Bit8u * reader=HostMake(0xb800,start);
Bit8u * reader=&vga.mem.linear[0];
Bit8u * draw_start=bitdata;
/* Todo Blinking and high intensity colors */
Bitu next_charline=vga.draw.font_height*vga.draw.width;
@ -177,7 +177,7 @@ void VGA_TEXT_Draw(Bit8u * bitdata,Bitu start,Bitu panning,Bitu rows) {
Bitu row=cur_start / (vga.config.scan_len*2);
Bitu col=cur_start % (vga.config.scan_len*2);
Bit32u att=*HostMake(0xb800,vga.config.cursor_start*2+1)&0xf;
Bit32u att=vga.mem.linear[vga.config.cursor_start*2+1]&0xf;
att=(att << 8) | att;
att=(att << 16) | att;

View file

@ -139,19 +139,7 @@ void write_p3cf(Bit32u port,Bit8u val) {
break;
case 6: /* Miscellaneous Register */
gfx(miscellaneous)=val;
switch ((val >> 2) & 3) {
case 0:
case 1:
vga.config.mem_base=0xa0000;
break;
case 2:
vga.config.mem_base=0xb0000;
break;
case 3:
vga.config.mem_base=0xb8000;
break;
}
if (vga.mode==M_TEXT16) VGA_SetupHandlers();
VGA_SetupHandlers();
/*
0 Indicates Graphics Mode if set, Alphanumeric mode else.
1 Enables Odd/Even mode if set.

View file

@ -24,10 +24,10 @@
#include "dosbox.h"
#include "mem.h"
#include "vga.h"
#include "paging.h"
#include "pic.h"
static Bit8u VGA_NormalReadHandler(PhysPt start) {
start-=0xa0000;
vga.latch.d=vga.mem.latched[start].d;
switch (vga.config.read_mode) {
case 0:
@ -56,7 +56,6 @@ INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) {
return 0;
}
INLINE static Bit32u ModeOperation(Bit8u val) {
Bit32u full;
switch (vga.config.write_mode) {
@ -84,26 +83,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) {
return full;
}
static Bit8u VGA_CGA_4_ReadHandler(PhysPt start) {
return vga.mem.linear[start-0xb8000];
}
static void VGA_CGA_4_WriteHandler(PhysPt start,Bit8u val) {
start-=0xb8000;
vga.mem.linear[start]=val;
Bitu off;
if (start>0x2000) off=320*(((start-0x2000)/80)*2+1)+((start-0x2000) % 80)*4;
else off=320*(((start)/80)*2)+(start % 80)*4;
Bit32u * draw=(Bit32u *)&vga.mem.linear[512*1024+off];
/* TODO Could also use a Bit32u lookup table for this */
*draw=CGA_4_Table[val];
draw=(Bit32u *)&vga.mem.linear[512*1024+off+0x4000*4];
*draw=CGA_4_Table[val];
}
static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) {
start-=0xa0000;
val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate));
Bit32u data=ModeOperation(val);
/* Update video memory and the pixel buffer */
@ -135,7 +115,6 @@ static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) {
}
static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) {
start-=0xa0000;
Bit32u data=ModeOperation(val);
// Bit32u data=ExpandTable[val];
VGA_Latch pixels;
@ -147,7 +126,6 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) {
}
static void VGA_TEXT16_Write(PhysPt start,Bit8u val) {
start-=vga.config.mem_base;
/* Check for page 2 being enabled for writing */
if (vga.seq.map_mask & 0x4) {
vga.draw.font[start]=val;
@ -156,53 +134,82 @@ static void VGA_TEXT16_Write(PhysPt start,Bit8u val) {
}
static Bit8u VGA_TEXT16_Read(PhysPt start) {
start-=vga.config.mem_base;
return vga.draw.font[start];
}
void VGA_SetupHandlers(void) {
/* Sets up the correct memory handler from the vga.mode setting */
MEM_ClearPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x20000));
HostPt where;
switch (vga.mode) {
case M_LIN8:
MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]);
where=&vga.mem.linear[vga.s3.bank*64*1024];
break;
case M_VGA:
if (vga.config.chained) {
MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]);
where=&vga.mem.linear[vga.s3.bank*64*1024];
} else {
MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),
&VGA_NormalReadHandler,&VGA_GFX_256U_WriteHandler);
vga.config.readhandler=&VGA_NormalReadHandler,
vga.config.writehandler=&VGA_GFX_256U_WriteHandler;
where=0;
}
break;
case M_EGA16:
MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),
&VGA_NormalReadHandler,&VGA_GFX_16_WriteHandler);
vga.config.readhandler=&VGA_NormalReadHandler,
vga.config.writehandler=&VGA_GFX_16_WriteHandler;
where=0;
break;
case M_TEXT16:
/* Check if we're not in odd/even mode */
if (vga.gfx.miscellaneous & 0x2) break;
MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&VGA_TEXT16_Read,&VGA_TEXT16_Write);
//Could also do it using 0xb8000, let's double map
MEM_SetupPageHandlers(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&VGA_TEXT16_Read,&VGA_TEXT16_Write);
if (vga.gfx.miscellaneous & 0x2) {
where=&vga.mem.linear[0];
} else {
vga.config.readhandler=&VGA_TEXT16_Read;
vga.config.writehandler=&VGA_TEXT16_Write;
where=0;
}
break;
case M_TANDY16:
MEM_SetupMapping(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&vga.mem.linear[vga.tandy.mem_bank << 14]);
where=&vga.mem.linear[vga.tandy.mem_bank << 14];
break;
case M_CGA4:
case M_CGA2:
where=&vga.mem.linear[0];
break;
default:
LOG_MSG("Unhandled vga mode %X",vga.mode);
}
VGA_RANGES range;
switch ((vga.gfx.miscellaneous >> 2) & 3) {
case 0:
case 1:
range=VGA_RANGE_A000;
break;
case 2:
range=VGA_RANGE_B000;
break;
case 3:
range=VGA_RANGE_B800;
break;
}
MEM_SetupVGA(range,where);
}
bool lfb_update;
static void VGA_DoUpdateLFB(void) {
lfb_update=false;
MEM_SetLFB(vga.s3.la_window << 4,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]);
}
void VGA_StartUpdateLFB(void) {
if (!lfb_update) {
lfb_update=true;
PIC_AddEvent(VGA_DoUpdateLFB,2000); //2 milliseconds later
}
}
void VGA_SetupMemory() {
memset((void *)&vga.mem,0,512*1024*4);
/* Map linear frame buffer at 32 mb */
MEM_SetupMapping(PAGE_COUNT(32*1024*1024),PAGE_COUNT(2*1024*1024),&vga.mem);
/* Setup linear window to some initial value */
vga.s3.la_window=0xc000;
VGA_DoUpdateLFB();
}