Fixes to hercules emulation, better detection and bank switching
Fixes to tandy emulation, 640x200x16 mode and different sizes bank. EGA/VGA memory changes detection for faster rendering added Renderer does initial pass to check for needing to lock buffer Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@2781
This commit is contained in:
parent
667c756775
commit
5660ee1856
16 changed files with 1132 additions and 565 deletions
|
@ -21,6 +21,10 @@
|
|||
|
||||
#include "../src/gui/render_scalers.h"
|
||||
|
||||
#define RENDER_SKIP_CACHE 16
|
||||
//Enable this for scalers to support 0 input for empty lines
|
||||
//#define RENDER_NULL_INPUT
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
Bit8u red;
|
||||
|
@ -40,7 +44,7 @@ typedef struct {
|
|||
|
||||
typedef struct {
|
||||
struct {
|
||||
Bitu width;
|
||||
Bitu width, start;
|
||||
Bitu height;
|
||||
Bitu bpp;
|
||||
bool dblw,dblh;
|
||||
|
@ -50,6 +54,8 @@ typedef struct {
|
|||
struct {
|
||||
Bitu count;
|
||||
Bitu max;
|
||||
Bitu index;
|
||||
Bit8u hadSkip[RENDER_SKIP_CACHE];
|
||||
} frameskip;
|
||||
struct {
|
||||
Bitu size;
|
||||
|
@ -71,13 +77,14 @@ typedef struct {
|
|||
bool updating;
|
||||
bool active;
|
||||
bool aspect;
|
||||
bool fullFrame;
|
||||
} Render_t;
|
||||
|
||||
extern Render_t render;
|
||||
extern ScalerLineHandler_t RENDER_DrawLine;
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh);
|
||||
bool RENDER_StartUpdate(void);
|
||||
void RENDER_EndUpdate( bool fullUpdate );
|
||||
void RENDER_EndUpdate( );
|
||||
void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue);
|
||||
|
||||
|
||||
|
|
|
@ -23,8 +23,18 @@
|
|||
#include "dosbox.h"
|
||||
#endif
|
||||
|
||||
//Don't enable keeping changes and mapping lfb probably...
|
||||
#define VGA_LFB_MAPPED
|
||||
//#define VGA_KEEP_CHANGES
|
||||
#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;
|
||||
|
||||
|
||||
enum VGAModes {
|
||||
M_CGA2, M_CGA4,
|
||||
M_EGA, M_VGA,
|
||||
|
@ -70,6 +80,7 @@ typedef struct {
|
|||
Bit8u pel_panning; /* Amount of pixels to skip when starting horizontal line */
|
||||
Bit8u hlines_skip;
|
||||
Bit8u bytes_skip;
|
||||
Bit8u addr_shift;
|
||||
|
||||
/* Specific stuff memory write/read handling */
|
||||
|
||||
|
@ -97,6 +108,10 @@ typedef struct {
|
|||
Bitu blocks;
|
||||
Bitu panning;
|
||||
Bitu address;
|
||||
Bit8u *linear_base;
|
||||
Bitu linear_mask;
|
||||
Bitu address_mask;
|
||||
Bitu address_last;
|
||||
Bitu address_add;
|
||||
Bitu address_line_total;
|
||||
Bitu address_line;
|
||||
|
@ -108,13 +123,14 @@ typedef struct {
|
|||
Bitu parts_lines;
|
||||
Bitu parts_left;
|
||||
struct {
|
||||
float vtotal;
|
||||
float vstart;
|
||||
float vend;
|
||||
float htotal;
|
||||
float hstart;
|
||||
float hend;
|
||||
float parts;
|
||||
double framestart;
|
||||
double vrstart, vrend; // V-retrace
|
||||
double hrstart, hrend; // H-retrace
|
||||
double hblkstart, hblkend; // H-blanking
|
||||
double vblkstart, vblkend; // V-Blanking
|
||||
double vdend, vtotal;
|
||||
double hdend, htotal;
|
||||
double parts;
|
||||
} delay;
|
||||
bool double_scan;
|
||||
bool doublewidth,doubleheight;
|
||||
|
@ -194,31 +210,36 @@ typedef struct {
|
|||
Bit8u htotal;
|
||||
Bit8u hdend;
|
||||
Bit8u hsyncp;
|
||||
Bit8u hsyncw;
|
||||
Bit8u syncw;
|
||||
Bit8u vtotal;
|
||||
Bit8u vdend;
|
||||
Bit8u vadjust;
|
||||
Bit8u vsyncp;
|
||||
Bit8u vsyncw;
|
||||
Bit8u max_scanline;
|
||||
Bit8u lpen_low, lpen_high;
|
||||
Bit8u cursor_start;
|
||||
Bit8u cursor_end;
|
||||
} VGA_OTHER;
|
||||
|
||||
typedef struct {
|
||||
Bit8u pcjr_flipflop;
|
||||
Bit8u mode_control;
|
||||
Bit8u color_select;
|
||||
Bit8u mem_bank;
|
||||
Bit8u disp_bank;
|
||||
Bit8u reg_index;
|
||||
Bit8u gfx_control;
|
||||
Bit8u palette_mask;
|
||||
Bit8u extended_ram;
|
||||
Bit8u border_color;
|
||||
bool is_32k_mode;
|
||||
bool pcjr_flipflop;
|
||||
Bit8u line_mask, line_shift;
|
||||
Bit8u draw_bank, mem_bank;
|
||||
Bit8u *draw_base, *mem_base;
|
||||
Bitu addr_mask;
|
||||
} VGA_TANDY;
|
||||
|
||||
typedef struct {
|
||||
Bit8u index;
|
||||
|
||||
Bit8u reset;
|
||||
Bit8u clocking_mode;
|
||||
Bit8u map_mask;
|
||||
|
@ -281,11 +302,11 @@ typedef struct {
|
|||
Bit8u bit_mask;
|
||||
} VGA_Gfx;
|
||||
|
||||
struct RGBEntry {
|
||||
typedef struct {
|
||||
Bit8u red;
|
||||
Bit8u green;
|
||||
Bit8u blue;
|
||||
};
|
||||
} RGBEntry;
|
||||
|
||||
typedef struct {
|
||||
Bit8u bits; /* DAC bits, usually 6 or 8 */
|
||||
|
@ -298,16 +319,30 @@ typedef struct {
|
|||
RGBEntry rgb[0x100];
|
||||
} VGA_Dac;
|
||||
|
||||
union VGA_Latch {
|
||||
typedef struct {
|
||||
Bitu readStart, writeStart;
|
||||
Bitu bankMask;
|
||||
} VGA_SVGA;
|
||||
|
||||
typedef union {
|
||||
Bit32u d;
|
||||
Bit8u b[4];
|
||||
};
|
||||
} VGA_Latch;
|
||||
|
||||
union VGA_Memory {
|
||||
Bit8u linear[512*1024*4];
|
||||
Bit8u paged[512*1024][4];
|
||||
VGA_Latch latched[512*1024];
|
||||
};
|
||||
typedef struct {
|
||||
Bit8u linear[VGA_MEMORY];
|
||||
} VGA_Memory;
|
||||
|
||||
typedef struct {
|
||||
//Add a few more just to be safe
|
||||
Bit8u map[(VGA_MEMORY >> VGA_CHANGE_SHIFT) + 32];
|
||||
Bit8u checkMask, frame, writeMask;
|
||||
bool active;
|
||||
Bit32u lineWidth;
|
||||
Bit32u clearMask;
|
||||
Bit32u start, last;
|
||||
Bit32u lastAddress;
|
||||
} VGA_Changes;
|
||||
|
||||
typedef struct {
|
||||
Bit32u page;
|
||||
|
@ -316,8 +351,6 @@ typedef struct {
|
|||
PageHandler *handler;
|
||||
} VGA_LFB;
|
||||
|
||||
#define VGA_CHANGE_SHIFT 9
|
||||
typedef Bit8u VGA_Changed[(2*1024*1024) >> VGA_CHANGE_SHIFT];
|
||||
typedef struct {
|
||||
VGAModes mode; /* The mode the vga system is in */
|
||||
VGAModes lastmode;
|
||||
|
@ -333,13 +366,15 @@ typedef struct {
|
|||
VGA_Dac dac;
|
||||
VGA_Latch latch;
|
||||
VGA_S3 s3;
|
||||
VGA_SVGA svga;
|
||||
VGA_HERC herc;
|
||||
VGA_TANDY tandy;
|
||||
VGA_OTHER other;
|
||||
VGA_Memory mem;
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
VGA_Changes changes;
|
||||
#endif
|
||||
VGA_LFB lfb;
|
||||
VGA_Changed changed;
|
||||
Bit8u * gfxmem_start;
|
||||
} VGA_Type;
|
||||
|
||||
|
||||
|
@ -351,6 +386,7 @@ void VGA_SetupHandlers(void);
|
|||
void VGA_StartResize(void);
|
||||
void VGA_SetupDrawing(Bitu val);
|
||||
void VGA_CheckScanLength(void);
|
||||
void VGA_ChangedBank(void);
|
||||
|
||||
/* Some DAC/Attribute functions */
|
||||
void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: render.cpp,v 1.49 2007-01-08 19:45:39 qbix79 Exp $ */
|
||||
/* $Id: render.cpp,v 1.50 2007-01-24 16:29:09 harekiet Exp $ */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
|
@ -37,6 +37,8 @@
|
|||
Render_t render;
|
||||
ScalerLineHandler_t RENDER_DrawLine;
|
||||
|
||||
static void RENDER_CallBack( GFX_CallBackFunctions_t function );
|
||||
|
||||
static void Check_Palette(void) {
|
||||
/* Clean up any previous changed palette data */
|
||||
if (render.pal.changed) {
|
||||
|
@ -95,6 +97,30 @@ void RENDER_SetPal(Bit8u entry,Bit8u red,Bit8u green,Bit8u blue) {
|
|||
static void RENDER_EmptyLineHandler(const void * src) {
|
||||
}
|
||||
|
||||
static void RENDER_StartLineHandler(const void * s) {
|
||||
if (s) {
|
||||
const Bitu *src = (Bitu*)s;
|
||||
Bitu *cache = (Bitu*)(render.scale.cacheRead);
|
||||
for (Bits x=render.src.start;x>0;) {
|
||||
if (GCC_UNLIKELY(src[0] != cache[0])) {
|
||||
if (!GFX_StartUpdate( render.scale.outWrite, render.scale.outPitch )) {
|
||||
RENDER_DrawLine = RENDER_EmptyLineHandler;
|
||||
return;
|
||||
}
|
||||
render.scale.outWrite += render.scale.outPitch * Scaler_ChangedLines[0];
|
||||
RENDER_DrawLine = render.scale.lineHandler;
|
||||
RENDER_DrawLine( s );
|
||||
return;
|
||||
}
|
||||
x--; src++; cache++;
|
||||
}
|
||||
}
|
||||
render.scale.cacheRead += render.scale.cachePitch;
|
||||
Scaler_ChangedLines[0] += Scaler_Aspect[ render.scale.inLine ];
|
||||
render.scale.inLine++;
|
||||
render.scale.outLine++;
|
||||
}
|
||||
|
||||
static void RENDER_ClearCacheHandler(const void * src) {
|
||||
Bitu x, width;
|
||||
Bit32u *srcLine, *cacheLine;
|
||||
|
@ -119,33 +145,54 @@ bool RENDER_StartUpdate(void) {
|
|||
if (render.scale.inMode == scalerMode8) {
|
||||
Check_Palette();
|
||||
}
|
||||
if (GCC_UNLIKELY(!GFX_StartUpdate(render.scale.outWrite,render.scale.outPitch)))
|
||||
return false;
|
||||
render.scale.inLine = 0;
|
||||
render.scale.outLine = 0;
|
||||
render.scale.cacheRead = (Bit8u*)&scalerSourceCache;
|
||||
render.scale.outWrite = 0;
|
||||
render.scale.outPitch = 0;
|
||||
Scaler_ChangedLines[0] = 0;
|
||||
Scaler_ChangedLineIndex = 0;
|
||||
/* Clearing the cache will first process the line to make sure it's never the same */
|
||||
if (GCC_UNLIKELY( render.scale.clearCache) ) {
|
||||
// LOG_MSG("Clearing cache");
|
||||
//Will always have to update the screen with this one anyway, so let's update already
|
||||
if (GCC_UNLIKELY(!GFX_StartUpdate( render.scale.outWrite, render.scale.outPitch )))
|
||||
return false;
|
||||
render.fullFrame = true;
|
||||
render.scale.clearCache = false;
|
||||
RENDER_DrawLine = RENDER_ClearCacheHandler;
|
||||
} else {
|
||||
if (render.pal.changed)
|
||||
if (render.pal.changed) {
|
||||
/* Assume pal changes always do a full screen update anyway */
|
||||
if (GCC_UNLIKELY(!GFX_StartUpdate( render.scale.outWrite, render.scale.outPitch )))
|
||||
return false;
|
||||
RENDER_DrawLine = render.scale.linePalHandler;
|
||||
else
|
||||
RENDER_DrawLine = render.scale.lineHandler;
|
||||
render.fullFrame = true;
|
||||
} else {
|
||||
RENDER_DrawLine = RENDER_StartLineHandler;
|
||||
if (GCC_UNLIKELY(CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO)))
|
||||
render.fullFrame = true;
|
||||
else
|
||||
render.fullFrame = false;
|
||||
}
|
||||
}
|
||||
render.updating=true;
|
||||
render.updating = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void RENDER_EndUpdate( bool fullUpdate ) {
|
||||
if (!render.updating)
|
||||
static void RENDER_Halt( void ) {
|
||||
RENDER_DrawLine = RENDER_EmptyLineHandler;
|
||||
GFX_EndUpdate( 0 );
|
||||
render.updating=false;
|
||||
render.active=false;
|
||||
}
|
||||
|
||||
extern Bitu PIC_Ticks;
|
||||
void RENDER_EndUpdate( void ) {
|
||||
if (GCC_UNLIKELY(!render.updating))
|
||||
return;
|
||||
RENDER_DrawLine = RENDER_EmptyLineHandler;
|
||||
if (CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO)) {
|
||||
if (GCC_UNLIKELY(CaptureState & (CAPTURE_IMAGE|CAPTURE_VIDEO))) {
|
||||
Bitu pitch, flags;
|
||||
flags = 0;
|
||||
if (render.src.dblw != render.src.dblh) {
|
||||
|
@ -159,40 +206,46 @@ void RENDER_EndUpdate( bool fullUpdate ) {
|
|||
CAPTURE_AddImage( render.src.width, render.src.height, render.src.bpp, pitch,
|
||||
flags, fps, (Bit8u *)&scalerSourceCache, (Bit8u*)&render.pal.rgb );
|
||||
}
|
||||
GFX_EndUpdate( fullUpdate ? Scaler_ChangedLines : 0);
|
||||
if ( render.scale.outWrite ) {
|
||||
GFX_EndUpdate( Scaler_ChangedLines );
|
||||
render.frameskip.hadSkip[render.frameskip.index] = 0;
|
||||
} else {
|
||||
#if 0
|
||||
Bitu total = 0, i;
|
||||
render.frameskip.hadSkip[render.frameskip.index] = 1;
|
||||
for (i = 0;i<RENDER_SKIP_CACHE;i++)
|
||||
total += render.frameskip.hadSkip[i];
|
||||
LOG_MSG( "Skipped frame %d %d", PIC_Ticks, (total * 100) / RENDER_SKIP_CACHE );
|
||||
#endif
|
||||
}
|
||||
render.frameskip.index = (render.frameskip.index + 1) & (RENDER_SKIP_CACHE - 1);
|
||||
render.updating=false;
|
||||
}
|
||||
|
||||
static Bitu MakeAspectTable(Bitu height,double scaley,Bitu miny) {
|
||||
static Bitu MakeAspectTable(Bitu skip,Bitu height,double scaley,Bitu miny) {
|
||||
Bitu i;
|
||||
double lines=0;
|
||||
Bitu linesadded=0;
|
||||
for (Bitu i=0;i<height;i++) {
|
||||
lines+=scaley;
|
||||
if (lines>=miny) {
|
||||
Bitu templines=(Bitu)lines;
|
||||
lines-=templines;
|
||||
linesadded+=templines;
|
||||
Scaler_Aspect[1+i]=templines-miny;
|
||||
} else Scaler_Aspect[1+i]=0;
|
||||
for (i=0;i<skip;i++)
|
||||
Scaler_Aspect[i] = 0;
|
||||
|
||||
height += skip;
|
||||
for (i=skip;i<height;i++) {
|
||||
lines += scaley;
|
||||
if (lines >= miny) {
|
||||
Bitu templines = (Bitu)lines;
|
||||
lines -= templines;
|
||||
linesadded += templines;
|
||||
Scaler_Aspect[i] = templines;
|
||||
} else {
|
||||
Scaler_Aspect[i] = 0;
|
||||
}
|
||||
}
|
||||
return linesadded;
|
||||
}
|
||||
|
||||
void RENDER_CallBack( GFX_CallBackFunctions_t function ) {
|
||||
if (render.updating) {
|
||||
/* Still updating the current screen, shut it down correctly */
|
||||
RENDER_EndUpdate( false );
|
||||
}
|
||||
|
||||
if (function == GFX_CallBackStop)
|
||||
return;
|
||||
|
||||
if (function == GFX_CallBackRedraw) {
|
||||
//LOG_MSG("redraw");
|
||||
render.scale.clearCache = true;
|
||||
return;
|
||||
}
|
||||
|
||||
static void RENDER_Reset( void ) {
|
||||
Bitu width=render.src.width;
|
||||
Bitu height=render.src.height;
|
||||
bool dblw=render.src.dblw;
|
||||
|
@ -301,20 +354,24 @@ forcenormal:
|
|||
}
|
||||
switch (render.src.bpp) {
|
||||
case 8:
|
||||
render.src.start = ( render.src.width * 1) / sizeof(Bitu);
|
||||
if (gfx_flags & GFX_CAN_8)
|
||||
gfx_flags |= GFX_LOVE_8;
|
||||
else
|
||||
gfx_flags |= GFX_LOVE_32;
|
||||
break;
|
||||
case 15:
|
||||
render.src.start = ( render.src.width * 2) / sizeof(Bitu);
|
||||
gfx_flags |= GFX_LOVE_15;
|
||||
gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY;
|
||||
break;
|
||||
case 16:
|
||||
render.src.start = ( render.src.width * 2) / sizeof(Bitu);
|
||||
gfx_flags |= GFX_LOVE_16;
|
||||
gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY;
|
||||
break;
|
||||
case 32:
|
||||
render.src.start = ( render.src.width * 4) / sizeof(Bitu);
|
||||
gfx_flags |= GFX_LOVE_32;
|
||||
gfx_flags = (gfx_flags & ~GFX_CAN_8) | GFX_RGBONLY;
|
||||
break;
|
||||
|
@ -327,15 +384,16 @@ forcenormal:
|
|||
goto forcenormal;
|
||||
}
|
||||
width *= xscale;
|
||||
Bitu skip = complexBlock ? 1 : 0;
|
||||
if (gfx_flags & GFX_SCALING) {
|
||||
height = MakeAspectTable(render.src.height, yscale, yscale );
|
||||
height = MakeAspectTable(skip, render.src.height, yscale, yscale );
|
||||
} else {
|
||||
if ((gfx_flags & GFX_CAN_RANDOM) && gfx_scaleh > 1) {
|
||||
gfx_scaleh *= yscale;
|
||||
height = MakeAspectTable(render.src.height, gfx_scaleh, yscale );
|
||||
height = MakeAspectTable( skip, render.src.height, gfx_scaleh, yscale );
|
||||
} else {
|
||||
gfx_flags &= ~GFX_CAN_RANDOM; //Hardware surface when possible
|
||||
height = MakeAspectTable(render.src.height, yscale, yscale);
|
||||
height = MakeAspectTable( skip, render.src.height, yscale, yscale);
|
||||
}
|
||||
}
|
||||
/* Setup the scaler variables */
|
||||
|
@ -409,12 +467,26 @@ forcenormal:
|
|||
render.active=true;
|
||||
}
|
||||
|
||||
static void RENDER_CallBack( GFX_CallBackFunctions_t function ) {
|
||||
if (function == GFX_CallBackStop) {
|
||||
RENDER_Halt( );
|
||||
return;
|
||||
} else if (function == GFX_CallBackRedraw) {
|
||||
render.scale.clearCache = true;
|
||||
return;
|
||||
} else if ( function == GFX_CallBackReset) {
|
||||
GFX_EndUpdate( 0 );
|
||||
RENDER_Reset();
|
||||
} else {
|
||||
E_Exit("Unhandled GFX_CallBackReset %d", function );
|
||||
}
|
||||
}
|
||||
|
||||
void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool dblw,bool dblh) {
|
||||
RENDER_Halt( );
|
||||
if (!width || !height || width > SCALER_MAXWIDTH || height > SCALER_MAXHEIGHT) {
|
||||
render.active=false;
|
||||
return;
|
||||
}
|
||||
RENDER_EndUpdate( false );
|
||||
render.src.width=width;
|
||||
render.src.height=height;
|
||||
render.src.bpp=bpp;
|
||||
|
@ -422,7 +494,7 @@ void RENDER_SetSize(Bitu width,Bitu height,Bitu bpp,float fps,double ratio,bool
|
|||
render.src.dblh=dblh;
|
||||
render.src.fps=fps;
|
||||
render.src.ratio=ratio;
|
||||
RENDER_CallBack( GFX_CallBackReset );
|
||||
RENDER_Reset( );
|
||||
}
|
||||
|
||||
extern void GFX_SetTitle(Bit32s cycles, Bits frameskip,bool paused);
|
||||
|
@ -499,6 +571,7 @@ void RENDER_Init(Section * sec) {
|
|||
//If something changed that needs a ReInit
|
||||
if(running && (render.aspect != aspect || render.scale.op != scaleOp))
|
||||
RENDER_CallBack( GFX_CallBackReset );
|
||||
|
||||
if(!running) render.updating=true;
|
||||
running = true;
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ static void conc3d(SCALERNAME,SBPP,L)(void) {
|
|||
#else
|
||||
static void conc3d(SCALERNAME,SBPP,R)(void) {
|
||||
#endif
|
||||
//Skip the first one for multiline input scalers
|
||||
if (!render.scale.outLine) {
|
||||
render.scale.outLine++;
|
||||
return;
|
||||
|
@ -30,14 +31,9 @@ lastagain:
|
|||
#if defined(SCALERLINEAR)
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
#else
|
||||
Bitu scaleLines = SCALERHEIGHT + Scaler_Aspect[ render.scale.outLine ];
|
||||
Bitu scaleLines = Scaler_Aspect[ render.scale.outLine ];
|
||||
#endif
|
||||
render.scale.outWrite += render.scale.outPitch * scaleLines;
|
||||
if (!(Scaler_ChangedLineIndex & 1)) {
|
||||
Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines;
|
||||
} else {
|
||||
Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines;
|
||||
}
|
||||
ScalerAddLines( 0, scaleLines );
|
||||
if (++render.scale.outLine == render.scale.inHeight)
|
||||
goto lastagain;
|
||||
return;
|
||||
|
@ -141,25 +137,15 @@ lastagain:
|
|||
}
|
||||
#if defined(SCALERLINEAR)
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
render.scale.outWrite += render.scale.outPitch * scaleLines;
|
||||
#else
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
if ( Scaler_Aspect[ render.scale.outLine ] ) {
|
||||
scaleLines++;
|
||||
Bitu scaleLines = Scaler_Aspect[ render.scale.outLine ];
|
||||
if ( ((Bits)(scaleLines - SCALERHEIGHT)) > 0 ) {
|
||||
BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT,
|
||||
render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1),
|
||||
render.src.width * SCALERWIDTH * PSIZE);
|
||||
render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1);
|
||||
} else {
|
||||
render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT;
|
||||
}
|
||||
#endif
|
||||
/* Keep track of changed lines */
|
||||
if (Scaler_ChangedLineIndex & 1) {
|
||||
Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines;
|
||||
} else {
|
||||
Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines;
|
||||
}
|
||||
ScalerAddLines( 1, scaleLines );
|
||||
if (++render.scale.outLine == render.scale.inHeight)
|
||||
goto lastagain;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,16 @@ static INLINE void BituMove( void *_dst, const void * _src, Bitu size) {
|
|||
dst[x] = src[x];
|
||||
}
|
||||
|
||||
static INLINE void ScalerAddLines( Bitu changed, Bitu count ) {
|
||||
if ((Scaler_ChangedLineIndex & 1) == changed ) {
|
||||
Scaler_ChangedLines[Scaler_ChangedLineIndex] += count;
|
||||
} else {
|
||||
Scaler_ChangedLines[++Scaler_ChangedLineIndex] = count;
|
||||
}
|
||||
render.scale.outWrite += render.scale.outPitch * count;
|
||||
}
|
||||
|
||||
|
||||
#define BituMove2(_DST,_SRC,_SIZE) \
|
||||
{ \
|
||||
Bitu bsize=(_SIZE)/sizeof(Bitu); \
|
||||
|
|
|
@ -20,13 +20,25 @@
|
|||
static void conc4d(SCALERNAME,SBPP,DBPP,L)(const void *s) {
|
||||
#else
|
||||
static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) {
|
||||
#endif
|
||||
#ifdef RENDER_NULL_INPUT
|
||||
if (!s) {
|
||||
render.scale.cacheRead += render.scale.cachePitch;
|
||||
#if defined(SCALERLINEAR)
|
||||
Bitu skipLines = SCALERHEIGHT;
|
||||
#else
|
||||
Bitu skipLines = Scaler_Aspect[ render.scale.outLine++ ];
|
||||
#endif
|
||||
ScalerAddLines( 0, skipLines );
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/* Clear the complete line marker */
|
||||
Bitu hadChange;
|
||||
const SRCTYPE *src = (SRCTYPE*)s;
|
||||
SRCTYPE *cache = (SRCTYPE*)(render.scale.cacheRead);
|
||||
render.scale.cacheRead += render.scale.cachePitch;
|
||||
PTYPE * line0=(PTYPE *)(render.scale.outWrite);
|
||||
Bitu hadChange = 0;
|
||||
#if (SBPP == 9)
|
||||
for (Bits x=render.src.width;x>0;) {
|
||||
if (*(Bit32u const*)src == *(Bit32u*)cache && !(
|
||||
|
@ -90,26 +102,15 @@ static void conc4d(SCALERNAME,SBPP,DBPP,R)(const void *s) {
|
|||
}
|
||||
#if defined(SCALERLINEAR)
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
render.scale.outWrite += render.scale.outPitch * scaleLines;
|
||||
#else
|
||||
Bitu scaleLines = SCALERHEIGHT;
|
||||
if ( Scaler_Aspect[ render.scale.outLine++ ] ) {
|
||||
scaleLines++;
|
||||
if (hadChange)
|
||||
BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT,
|
||||
Bitu scaleLines = Scaler_Aspect[ render.scale.outLine++ ];
|
||||
if ( scaleLines - SCALERHEIGHT && hadChange ) {
|
||||
BituMove( render.scale.outWrite + render.scale.outPitch * SCALERHEIGHT,
|
||||
render.scale.outWrite + render.scale.outPitch * (SCALERHEIGHT-1),
|
||||
render.src.width * SCALERWIDTH * PSIZE);
|
||||
render.scale.outWrite += render.scale.outPitch * (SCALERHEIGHT + 1);
|
||||
} else {
|
||||
render.scale.outWrite += render.scale.outPitch * SCALERHEIGHT;
|
||||
}
|
||||
/* Keep track of changed lines */
|
||||
if ((Scaler_ChangedLineIndex & 1) == hadChange) {
|
||||
Scaler_ChangedLines[Scaler_ChangedLineIndex] += scaleLines;
|
||||
} else {
|
||||
Scaler_ChangedLines[++Scaler_ChangedLineIndex] = scaleLines;
|
||||
}
|
||||
#endif
|
||||
ScalerAddLines( hadChange, scaleLines );
|
||||
}
|
||||
|
||||
#if !defined(SCALERLINEAR)
|
||||
|
|
|
@ -153,6 +153,14 @@
|
|||
|
||||
|
||||
static void conc3d(Cache,SBPP,DBPP) (const void * s) {
|
||||
#ifdef RENDER_NULL_INPUT
|
||||
if (!s) {
|
||||
render.scale.cacheRead += render.scale.cachePitch;
|
||||
render.scale.inLine++;
|
||||
render.scale.complexHandler();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
const SRCTYPE * src = (SRCTYPE*)s;
|
||||
PTYPE *fc= &FC[render.scale.inLine+1][1];
|
||||
SRCTYPE *sc = (SRCTYPE*)(render.scale.cacheRead);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: sdlmain.cpp,v 1.126 2007-01-10 15:01:15 c2woody Exp $ */
|
||||
/* $Id: sdlmain.cpp,v 1.127 2007-01-24 16:29:09 harekiet Exp $ */
|
||||
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
|
@ -328,7 +328,8 @@ check_gotbpp:
|
|||
|
||||
void GFX_ResetScreen(void) {
|
||||
GFX_Stop();
|
||||
if (sdl.draw.callback) (sdl.draw.callback)( GFX_CallBackReset );
|
||||
if (sdl.draw.callback)
|
||||
(sdl.draw.callback)( GFX_CallBackReset );
|
||||
GFX_Start();
|
||||
}
|
||||
|
||||
|
@ -661,7 +662,8 @@ static void SwitchFullScreen(bool pressed) {
|
|||
|
||||
|
||||
bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) {
|
||||
if (!sdl.active || sdl.updating) return false;
|
||||
if (!sdl.active || sdl.updating)
|
||||
return false;
|
||||
switch (sdl.desktop.type) {
|
||||
case SCREEN_SURFACE:
|
||||
if (sdl.blit.surface) {
|
||||
|
@ -710,7 +712,8 @@ bool GFX_StartUpdate(Bit8u * & pixels,Bitu & pitch) {
|
|||
|
||||
void GFX_EndUpdate( const Bit16u *changedLines ) {
|
||||
int ret;
|
||||
if (!sdl.updating) return;
|
||||
if (!sdl.updating)
|
||||
return;
|
||||
sdl.updating=false;
|
||||
switch (sdl.desktop.type) {
|
||||
case SCREEN_SURFACE:
|
||||
|
@ -745,15 +748,11 @@ void GFX_EndUpdate( const Bit16u *changedLines ) {
|
|||
}
|
||||
if (rectCount)
|
||||
SDL_UpdateRects( sdl.surface, rectCount, sdl.updateRects );
|
||||
} else {
|
||||
SDL_Flip(sdl.surface);
|
||||
}
|
||||
break;
|
||||
#if (HAVE_DDRAW_H) && defined(WIN32)
|
||||
case SCREEN_SURFACE_DDRAW:
|
||||
if (SDL_MUSTLOCK(sdl.blit.surface)) {
|
||||
SDL_UnlockSurface(sdl.blit.surface);
|
||||
}
|
||||
SDL_UnlockSurface(sdl.blit.surface);
|
||||
ret=IDirectDrawSurface3_Blt(
|
||||
sdl.surface->hwdata->dd_writebuf,&sdl.blit.rect,
|
||||
sdl.blit.surface->hwdata->dd_surface,0,
|
||||
|
|
|
@ -64,7 +64,6 @@ void VGA_DetermineMode(void) {
|
|||
VGA_SetMode(M_LIN4);
|
||||
else
|
||||
VGA_SetMode(M_EGA);
|
||||
|
||||
}
|
||||
} else {
|
||||
VGA_SetMode(M_TEXT);
|
||||
|
|
|
@ -242,6 +242,13 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) {
|
|||
break;
|
||||
case 0x14: /* Underline Location Register */
|
||||
crtc(underline_location)=val;
|
||||
//Byte,word,dword mode
|
||||
if ( crtc(underline_location) & 0x20 )
|
||||
vga.config.addr_shift = 2;
|
||||
else if ( crtc( mode_control) & 0x40 )
|
||||
vga.config.addr_shift = 0;
|
||||
else
|
||||
vga.config.addr_shift = 1;
|
||||
/*
|
||||
0-4 Position of underline within Character cell.
|
||||
5 If set memory address is only changed every fourth character clock.
|
||||
|
@ -268,7 +275,24 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) {
|
|||
break;
|
||||
case 0x17: /* Mode Control Register */
|
||||
crtc(mode_control)=val;
|
||||
vga.tandy.line_mask = (~val) & 3;
|
||||
//Byte,word,dword mode
|
||||
if ( crtc(underline_location) & 0x20 )
|
||||
vga.config.addr_shift = 2;
|
||||
else if ( crtc( mode_control) & 0x40 )
|
||||
vga.config.addr_shift = 0;
|
||||
else
|
||||
vga.config.addr_shift = 1;
|
||||
|
||||
if ( vga.tandy.line_mask ) {
|
||||
vga.tandy.line_shift = 13;
|
||||
vga.tandy.addr_mask = (1 << 13) - 1;
|
||||
} else {
|
||||
vga.tandy.addr_mask = ~0;
|
||||
vga.tandy.line_shift = 0;
|
||||
}
|
||||
VGA_DetermineMode();
|
||||
//Should we really need to do a determinemode here?
|
||||
/*
|
||||
0 If clear use CGA compatible memory addressing system
|
||||
by substituting character row scan counter bit 0 for address bit 13,
|
||||
|
|
|
@ -27,46 +27,41 @@
|
|||
|
||||
#define VGA_PARTS 4
|
||||
|
||||
typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line);
|
||||
typedef void (* VGA_FrameStart_Handler)();
|
||||
typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart, Bitu line);
|
||||
|
||||
static VGA_Line_Handler VGA_DrawLine;
|
||||
static VGA_FrameStart_Handler VGA_FrameStart;
|
||||
static Bit8u TempLine[SCALER_MAXWIDTH * 4];
|
||||
|
||||
static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
line*=8*1024;Bit32u * draw=(Bit32u *)TempLine;
|
||||
for (Bitu x=vga.draw.blocks;x>0;x--) {
|
||||
Bitu val=vga.gfxmem_start[vidstart+line];
|
||||
vidstart++;
|
||||
if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing
|
||||
vidstart &= 0x1dfff;
|
||||
static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart, Bitu line) {
|
||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||
Bit32u *draw = (Bit32u *)TempLine;
|
||||
for (Bitu x=vga.draw.blocks;x>0;x--, vidstart++) {
|
||||
Bitu val = base[(vidstart & (8 * 1024 -1))];
|
||||
*draw++=CGA_2_Table[val >> 4];
|
||||
*draw++=CGA_2_Table[val & 0xf];
|
||||
}
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
line*=8*1024;Bit32u * draw=(Bit32u *)TempLine;
|
||||
static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart, Bitu line) {
|
||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||
Bit32u * draw=(Bit32u *)TempLine;
|
||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
||||
Bitu val=vga.gfxmem_start[vidstart+line];
|
||||
Bitu val = base[vidstart & vga.tandy.addr_mask];
|
||||
vidstart++;
|
||||
if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing
|
||||
vidstart &= 0x1dfff;
|
||||
*draw++=CGA_4_Table[val];
|
||||
}
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
line*=8*1024;Bit32u * draw=(Bit32u *)TempLine;
|
||||
static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart, Bitu line) {
|
||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||
Bit32u * draw=(Bit32u *)TempLine;
|
||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
||||
Bitu val1=vga.gfxmem_start[vidstart+line];
|
||||
Bitu val2=vga.gfxmem_start[vidstart+1+line];
|
||||
vidstart+=2;
|
||||
if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing
|
||||
vidstart &= 0x1dfff;
|
||||
Bitu val1 = base[vidstart & vga.tandy.addr_mask];
|
||||
++vidstart;
|
||||
Bitu val2 = base[vidstart & vga.tandy.addr_mask];
|
||||
++vidstart;
|
||||
*draw++=CGA_4_HiRes_Table[(val1>>4)|(val2&0xf0)];
|
||||
*draw++=CGA_4_HiRes_Table[(val1&0x0f)|((val2&0x0f)<<4)];
|
||||
}
|
||||
|
@ -75,8 +70,9 @@ static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
|||
|
||||
static Bitu temp[643]={0};
|
||||
|
||||
static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
const Bit8u * reader=&vga.mem.linear[vidstart + (line * 8 * 1024)];
|
||||
static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) {
|
||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||
const Bit8u *reader = base + vidstart;
|
||||
Bit32u * draw=(Bit32u *)TempLine;
|
||||
//Generate a temporary bitline to calculate the avarage
|
||||
//over bit-2 bit-1 bit bit+1.
|
||||
|
@ -114,17 +110,14 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
|||
return TempLine;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
line*=8*1024;Bit32u * draw=(Bit32u *)TempLine;
|
||||
static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) {
|
||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||
Bit32u * draw=(Bit32u *)TempLine;
|
||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
||||
if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing
|
||||
vidstart &= 0x19fff;
|
||||
Bitu val1=vga.gfxmem_start[vidstart+line];
|
||||
vidstart++;
|
||||
if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing
|
||||
vidstart &= 0x19fff;
|
||||
Bitu val2=vga.gfxmem_start[vidstart+line];
|
||||
vidstart++;
|
||||
Bitu val1 = base[vidstart & vga.tandy.addr_mask];
|
||||
++vidstart;
|
||||
Bitu val2 = base[vidstart & vga.tandy.addr_mask];
|
||||
++vidstart;
|
||||
*draw++=(val1 & 0x0f) << 8 |
|
||||
(val1 & 0xf0) >> 4 |
|
||||
(val2 & 0x0f) << 24 |
|
||||
|
@ -133,13 +126,12 @@ static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
|||
return TempLine;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
line*=8*1024;Bit32u * draw=(Bit32u *)TempLine;
|
||||
static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart, Bitu line) {
|
||||
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
|
||||
Bit32u * draw=(Bit32u *)TempLine;
|
||||
for (Bitu x=0;x<vga.draw.blocks;x++) {
|
||||
if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing
|
||||
vidstart &= 0x1dfff;
|
||||
Bitu val=vga.gfxmem_start[vidstart+line];
|
||||
vidstart++;
|
||||
Bitu val = base[vidstart & vga.tandy.addr_mask];
|
||||
++vidstart;
|
||||
*draw++=(val & 0xf0) >> 4 |
|
||||
(val & 0xf0) << 4 |
|
||||
(val & 0x0f) << 16 |
|
||||
|
@ -148,43 +140,48 @@ static Bit8u * VGA_Draw_4BPP_Line_Double(Bitu vidstart,Bitu panning,Bitu line) {
|
|||
return TempLine;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_LIN4_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[512*1024+vidstart*8+panning];
|
||||
}
|
||||
static Bit8u * VGA_Draw_EGA_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[512*1024+vidstart*8+panning];
|
||||
}
|
||||
static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[vidstart*4+panning];
|
||||
}
|
||||
static Bit8u * VGA_Draw_LIN16_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[vidstart*4+panning];
|
||||
}
|
||||
static Bit8u * VGA_Draw_LIN32_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[vidstart*4+panning];
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) {
|
||||
Bitu checkMask = vga.changes.checkMask;
|
||||
Bit8u *map = vga.changes.map;
|
||||
Bitu start = (vidstart >> VGA_CHANGE_SHIFT);
|
||||
Bitu end = ((vidstart + vga.changes.lineWidth ) >> VGA_CHANGE_SHIFT);
|
||||
for (; start <= end;start++) {
|
||||
if ( map[start] & checkMask ) {
|
||||
return &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ];
|
||||
}
|
||||
}
|
||||
// memset( TempLine, 0x30, vga.changes.lineWidth );
|
||||
// return TempLine;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_VGAChained_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
return &vga.mem.linear[512*1024+((vidstart*4+panning)&0xffff)];
|
||||
#endif
|
||||
|
||||
static Bit8u * VGA_Draw_Linear_Line(Bitu vidstart, Bitu line) {
|
||||
return &vga.draw.linear_base[ vidstart & vga.draw.linear_mask ];
|
||||
}
|
||||
|
||||
static void VGA_StartFrame_VGA() {
|
||||
if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40))
|
||||
VGA_DrawLine=VGA_Draw_VGAChained_Line;
|
||||
else
|
||||
VGA_DrawLine = VGA_Draw_VGA_Line;
|
||||
static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) {
|
||||
Bitu i = 0;
|
||||
for ( i = 0; i < vga.draw.width;i++ ) {
|
||||
Bitu addr = vidstart + i;
|
||||
TempLine[i] = vga.mem.linear[((addr&~3)<<2)+(addr&3)];
|
||||
}
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) {
|
||||
|
||||
static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) {
|
||||
if(vga.s3.hgc.curmode & 0x1) {
|
||||
Bitu lineat = 4 * vidstart / vga.draw.width;
|
||||
Bitu lineat = vidstart / vga.draw.width;
|
||||
if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
|
||||
return VGA_Draw_VGA_Line(vidstart, panning, line);
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
} else {
|
||||
memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), vga.draw.width);
|
||||
memcpy(TempLine, &vga.mem.linear[ vidstart ], vga.draw.width);
|
||||
/* Draw mouse cursor */
|
||||
Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy;
|
||||
if(moff>63) return VGA_Draw_VGA_Line(vidstart, panning, line);
|
||||
if(moff>63) return &vga.mem.linear[ vidstart ];
|
||||
if(moff<0) moff+=64;
|
||||
Bitu xat = vga.s3.hgc.originx;
|
||||
Bitu m, mapat;
|
||||
|
@ -231,20 +228,20 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line)
|
|||
}
|
||||
} else {
|
||||
/* HW Mouse not enabled, use the tried and true call */
|
||||
return VGA_Draw_VGA_Line(vidstart, panning, line);
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
}
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) {
|
||||
static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) {
|
||||
if(vga.s3.hgc.curmode & 0x1) {
|
||||
Bitu lineat = 2 * vidstart / vga.draw.width;
|
||||
Bitu lineat = (vidstart >> 1) / vga.draw.width;
|
||||
if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
|
||||
return VGA_Draw_LIN16_Line(vidstart, panning, line);
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
} else {
|
||||
memcpy(TempLine, VGA_Draw_LIN16_Line(vidstart, panning, line), 2*vga.draw.width);
|
||||
memcpy(TempLine, &vga.mem.linear[ vidstart ], 2*vga.draw.width);
|
||||
/* Draw mouse cursor */
|
||||
Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy;
|
||||
if(moff>63) return VGA_Draw_LIN16_Line(vidstart, panning, line);
|
||||
if(moff>63) return &vga.mem.linear[ vidstart ];
|
||||
if(moff<0) moff+=64;
|
||||
Bitu xat = 2*vga.s3.hgc.originx;
|
||||
Bitu m, mapat;
|
||||
|
@ -294,20 +291,20 @@ static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu lin
|
|||
}
|
||||
} else {
|
||||
/* HW Mouse not enabled, use the tried and true call */
|
||||
return VGA_Draw_LIN16_Line(vidstart, panning, line);
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
}
|
||||
}
|
||||
|
||||
static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu line) {
|
||||
static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) {
|
||||
if(vga.s3.hgc.curmode & 0x1) {
|
||||
Bitu lineat = vidstart / vga.draw.width;
|
||||
Bitu lineat = (vidstart >> 2) / vga.draw.width;
|
||||
if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
|
||||
return VGA_Draw_LIN32_Line(vidstart, panning, line);
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
} else {
|
||||
memcpy(TempLine, VGA_Draw_LIN32_Line(vidstart, panning, line), 4*vga.draw.width);
|
||||
memcpy(TempLine, &vga.mem.linear[ vidstart ], 4*vga.draw.width);
|
||||
/* Draw mouse cursor */
|
||||
Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy;
|
||||
if(moff>63) return VGA_Draw_LIN32_Line(vidstart, panning, line);
|
||||
if(moff>63) return &vga.mem.linear[ vidstart ];
|
||||
if(moff<0) moff+=64;
|
||||
Bitu xat = 4*vga.s3.hgc.originx;
|
||||
Bitu m, mapat;
|
||||
|
@ -363,15 +360,15 @@ static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu panning, Bitu lin
|
|||
}
|
||||
} else {
|
||||
/* HW Mouse not enabled, use the tried and true call */
|
||||
return VGA_Draw_LIN32_Line(vidstart, panning, line);
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
}
|
||||
}
|
||||
|
||||
static Bit32u FontMask[2]={0xffffffff,0x0};
|
||||
static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
||||
static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) {
|
||||
Bitu font_addr;
|
||||
Bit32u * draw=(Bit32u *)TempLine;
|
||||
Bit8u * vidmem=&vga.gfxmem_start[vidstart];
|
||||
const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
|
||||
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
|
||||
Bitu chr=vidmem[cx*2];
|
||||
Bitu col=vidmem[cx*2+1];
|
||||
|
@ -389,7 +386,7 @@ static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) {
|
|||
if (line<vga.draw.cursor.sline) goto skip_cursor;
|
||||
if (line>vga.draw.cursor.eline) goto skip_cursor;
|
||||
draw=(Bit32u *)&TempLine[font_addr*8];
|
||||
Bit32u att=TXT_FG_Table[vga.gfxmem_start[vga.draw.cursor.address+1]&0xf];
|
||||
Bit32u att=TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf];
|
||||
*draw++=att;*draw++=att;
|
||||
}
|
||||
skip_cursor:
|
||||
|
@ -397,7 +394,7 @@ skip_cursor:
|
|||
}
|
||||
|
||||
static void VGA_VerticalDisplayEnd(Bitu val) {
|
||||
vga.config.retrace=true;
|
||||
// vga.config.retrace=true;
|
||||
vga.config.real_start=vga.config.display_start & ((2*1024*1024)-1);
|
||||
}
|
||||
|
||||
|
@ -405,28 +402,55 @@ static void VGA_HorizontalTimer(void) {
|
|||
|
||||
}
|
||||
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
static INLINE void VGA_ChangesEnd(void ) {
|
||||
if ( vga.changes.active ) {
|
||||
// vga.changes.active = false;
|
||||
Bitu end = vga.draw.address >> VGA_CHANGE_SHIFT;
|
||||
Bitu total = 4 + end - vga.changes.start;
|
||||
Bit32u clearMask = vga.changes.clearMask;
|
||||
total >>= 2;
|
||||
Bit32u *clear = (Bit32u *)&vga.changes.map[ vga.changes.start & ~3 ];
|
||||
while ( total-- ) {
|
||||
clear[0] &= clearMask;
|
||||
clear++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void VGA_DrawPart(Bitu lines) {
|
||||
while (lines--) {
|
||||
vga.draw.lines_done++;
|
||||
Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line);
|
||||
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
|
||||
RENDER_DrawLine(data);
|
||||
vga.draw.address_line++;
|
||||
if (vga.draw.address_line>=vga.draw.address_line_total) {
|
||||
vga.draw.address_line=0;
|
||||
vga.draw.address+=vga.draw.address_add;
|
||||
}
|
||||
vga.draw.lines_done++;
|
||||
if (vga.draw.split_line==vga.draw.lines_done) {
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
VGA_ChangesEnd( );
|
||||
#endif
|
||||
vga.draw.address=0;
|
||||
if(vga.attr.mode_control&0x20)
|
||||
vga.draw.panning=0;
|
||||
if(!(vga.attr.mode_control&0x20))
|
||||
vga.draw.address += vga.draw.panning;
|
||||
vga.draw.address_line=0;
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (--vga.draw.parts_left) {
|
||||
PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,
|
||||
PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts,
|
||||
(vga.draw.parts_left!=1) ? vga.draw.parts_lines : (vga.draw.lines_total - vga.draw.lines_done));
|
||||
} else {
|
||||
RENDER_EndUpdate( true );
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
VGA_ChangesEnd();
|
||||
#endif
|
||||
RENDER_EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,26 +469,81 @@ void VGA_SetBlinking(Bitu enabled) {
|
|||
for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24);
|
||||
}
|
||||
|
||||
static void VGA_VerticalTimer(Bitu val) {
|
||||
if (VGA_FrameStart)
|
||||
VGA_FrameStart();
|
||||
vga.config.retrace=false;
|
||||
PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal);
|
||||
PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.delay.vend);
|
||||
bool bDoDraw = RENDER_StartUpdate();
|
||||
if (bDoDraw) {
|
||||
// if (RENDER_StartUpdate()) {
|
||||
vga.draw.parts_left=vga.draw.parts_total;
|
||||
vga.draw.lines_done=0;
|
||||
vga.draw.address=vga.config.real_start;
|
||||
vga.draw.address_line=vga.config.hlines_skip;
|
||||
vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled);
|
||||
vga.draw.panning=vga.config.pel_panning;
|
||||
// PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts,vga.draw.parts_lines);
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
static void INLINE VGA_ChangesStart( void ) {
|
||||
vga.changes.start = vga.draw.address >> VGA_CHANGE_SHIFT;
|
||||
vga.changes.last = vga.changes.start;
|
||||
if ( vga.changes.lastAddress != vga.draw.address ) {
|
||||
// LOG_MSG("Address");
|
||||
VGA_DrawLine = VGA_Draw_Linear_Line;
|
||||
vga.changes.lastAddress = vga.draw.address;
|
||||
} else if ( render.fullFrame ) {
|
||||
// LOG_MSG("Full Frame");
|
||||
VGA_DrawLine = VGA_Draw_Linear_Line;
|
||||
} else {
|
||||
// LOG_MSG("Changes");
|
||||
VGA_DrawLine = VGA_Draw_Changes_Line;
|
||||
}
|
||||
vga.changes.active = true;
|
||||
vga.changes.checkMask = vga.changes.writeMask;
|
||||
vga.changes.clearMask = ~( 0x01010101 << (vga.changes.frame & 7));
|
||||
vga.changes.frame++;
|
||||
vga.changes.writeMask = 1 << (vga.changes.frame & 7);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void VGA_VerticalTimer(Bitu val) {
|
||||
double error = vga.draw.delay.framestart;
|
||||
vga.draw.delay.framestart = PIC_FullIndex();
|
||||
error = vga.draw.delay.framestart - error - vga.draw.delay.vtotal;
|
||||
// if (abs(error) > 0.001 )
|
||||
// LOG_MSG("vgaerror: %f",error);
|
||||
PIC_AddEvent(VGA_VerticalTimer, (float)vga.draw.delay.vtotal );
|
||||
if ( GCC_UNLIKELY( vga.draw.parts_left )) {
|
||||
LOG_MSG( "parts left: %d", vga.draw.parts_left );
|
||||
PIC_RemoveEvents( &VGA_DrawPart );
|
||||
}
|
||||
//Check if we can actually render, else skip the rest
|
||||
if (!RENDER_StartUpdate())
|
||||
return;
|
||||
//TODO Maybe check for an active frame on parts_left and clear that first?
|
||||
vga.draw.parts_left=vga.draw.parts_total;
|
||||
vga.draw.lines_done=0;
|
||||
vga.draw.address=vga.config.display_start;
|
||||
vga.draw.address_line=vga.config.hlines_skip;
|
||||
vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled);
|
||||
switch (vga.mode) {
|
||||
case M_EGA:
|
||||
vga.draw.address *= 8;
|
||||
vga.draw.address += vga.config.pel_panning;
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
VGA_ChangesStart();
|
||||
#endif
|
||||
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_mask = 0xffff;
|
||||
VGA_DrawLine = VGA_Draw_Chain_Line;
|
||||
} else {
|
||||
vga.draw.linear_base = vga.mem.linear;
|
||||
vga.draw.linear_mask = VGA_MEMORY - 1;
|
||||
VGA_DrawLine = VGA_Draw_Linear_Line;
|
||||
}
|
||||
case M_LIN8:
|
||||
case M_LIN15:
|
||||
case M_LIN16:
|
||||
case M_LIN32:
|
||||
vga.draw.address *= 4;
|
||||
vga.draw.address += vga.config.pel_panning;
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
VGA_ChangesStart();
|
||||
#endif
|
||||
break;
|
||||
case M_TEXT:
|
||||
vga.draw.address=(vga.draw.address*2);
|
||||
vga.draw.address *= 2;
|
||||
vga.draw.panning = vga.config.pel_panning;
|
||||
case M_TANDY_TEXT:
|
||||
case M_HERC_TEXT:
|
||||
vga.draw.cursor.address=vga.config.cursor_start*2;
|
||||
|
@ -473,30 +552,32 @@ static void VGA_VerticalTimer(Bitu val) {
|
|||
FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ?
|
||||
0 : 0xffffffff;
|
||||
break;
|
||||
case M_CGA4:case M_CGA2:case M_CGA16:
|
||||
case M_TANDY2:case M_TANDY4:case M_TANDY16:
|
||||
case M_HERC_GFX:
|
||||
break;
|
||||
case M_CGA4:case M_CGA2:
|
||||
vga.draw.address=(vga.draw.address*2)&0x1fff;
|
||||
break;
|
||||
case M_CGA16:
|
||||
case M_TANDY2:case M_TANDY4:case M_TANDY16:
|
||||
vga.draw.address *= 2;
|
||||
break;
|
||||
}
|
||||
if (IS_TANDY_ARCH) {
|
||||
vga.draw.address+=vga.tandy.disp_bank << 14;
|
||||
vga.draw.cursor.address+=vga.tandy.disp_bank << 14;
|
||||
}
|
||||
if (bDoDraw)
|
||||
// VGA_DrawPart(vga.draw.parts_lines);
|
||||
PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts/2,vga.draw.parts_lines); //Else tearline in Tyrian and second reality
|
||||
VGA_DrawPart( vga.draw.parts_lines );
|
||||
// PIC_AddEvent(VGA_DrawPart,vga.draw.delay.parts/2,vga.draw.parts_lines); //Else tearline in Tyrian and second reality
|
||||
}
|
||||
|
||||
void VGA_CheckScanLength(void) {
|
||||
switch (vga.mode) {
|
||||
case M_EGA:
|
||||
case M_VGA:
|
||||
case M_LIN4:
|
||||
vga.draw.address_add=vga.config.scan_len*16;
|
||||
break;
|
||||
case M_VGA:
|
||||
case M_LIN8:
|
||||
case M_LIN15:
|
||||
case M_LIN16:
|
||||
case M_LIN32:
|
||||
vga.draw.address_add=vga.config.scan_len*2;
|
||||
vga.draw.address_add=vga.config.scan_len*8;
|
||||
break;
|
||||
case M_TEXT:
|
||||
vga.draw.address_add=vga.config.scan_len*4;
|
||||
|
@ -541,17 +622,7 @@ void VGA_ActivateHardwareCursor(void) {
|
|||
VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse;
|
||||
}
|
||||
} else {
|
||||
switch(vga.mode) {
|
||||
case M_LIN32:
|
||||
VGA_DrawLine=VGA_Draw_LIN32_Line;
|
||||
break;
|
||||
case M_LIN15:
|
||||
case M_LIN16:
|
||||
VGA_DrawLine=VGA_Draw_LIN16_Line;
|
||||
break;
|
||||
default:
|
||||
VGA_DrawLine=VGA_Draw_VGA_Line;
|
||||
}
|
||||
VGA_DrawLine=VGA_Draw_Linear_Line;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -563,24 +634,49 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
}
|
||||
/* Calculate the FPS for this screen */
|
||||
float fps;Bitu clock;
|
||||
Bitu htotal,hdispend,hbstart,hrstart;
|
||||
Bitu vtotal,vdispend,vbstart,vrstart;
|
||||
Bitu htotal, hdend, hbstart, hbend, hrstart, hrend;
|
||||
Bitu vtotal, vdend, vbstart, vbend, vrstart, vrend;
|
||||
if (machine==MCH_VGA) {
|
||||
htotal = 5 + vga.crtc.horizontal_total;
|
||||
hdend = 1 + vga.crtc.horizontal_display_end;
|
||||
hbstart = vga.crtc.start_horizontal_blanking;
|
||||
hbend = vga.crtc.end_horizontal_blanking&0x1F |
|
||||
((vga.crtc.end_horizontal_retrace&0x80)>>2);
|
||||
hbend = hbstart + ((hbend - hbstart) & 0x3F);
|
||||
hrstart = vga.crtc.start_horizontal_retrace;
|
||||
hrend = vga.crtc.end_horizontal_retrace & 0x1f;
|
||||
hrend = (hrend - hrstart) & 0x1f;
|
||||
if ( !hrend )
|
||||
hrend = hrstart + 0x1f + 1;
|
||||
else
|
||||
hrend = hrstart + hrend;
|
||||
|
||||
vtotal=2 + vga.crtc.vertical_total |
|
||||
((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4);
|
||||
htotal=5 + vga.crtc.horizontal_total;
|
||||
vdispend = 1 + (vga.crtc.vertical_display_end |
|
||||
((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) |
|
||||
vdend = 1 + (vga.crtc.vertical_display_end |
|
||||
((vga.crtc.overflow & 2)<<7) |
|
||||
((vga.crtc.overflow & 0x40) << 3) |
|
||||
((vga.s3.ex_ver_overflow & 0x2) << 9));
|
||||
hdispend = 1 + (vga.crtc.horizontal_display_end);
|
||||
hbstart = vga.crtc.start_horizontal_blanking;
|
||||
vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) |
|
||||
((vga.crtc.maximum_scan_line & 0x20) << 4) ;
|
||||
hrstart = vga.crtc.start_horizontal_retrace;
|
||||
vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6) |
|
||||
vrstart = vga.crtc.vertical_retrace_start +
|
||||
((vga.crtc.overflow & 0x04) << 6) |
|
||||
((vga.crtc.overflow & 0x80) << 2);
|
||||
if (hbstart<hdispend) hdispend=hbstart;
|
||||
if (vbstart<vdispend) vdispend=vbstart;
|
||||
vrend = vga.crtc.vertical_retrace_end & 0xF;
|
||||
vrend = ( vrend - vrstart)&0xF;
|
||||
if ( !vrend)
|
||||
vrend = vrstart + 0xf + 1;
|
||||
else
|
||||
vrend = vrstart + vrend;
|
||||
|
||||
vbstart = vga.crtc.start_vertical_blanking |
|
||||
((vga.crtc.overflow & 0x08) << 5) |
|
||||
((vga.crtc.maximum_scan_line & 0x20) << 4);
|
||||
vbend = vga.crtc.end_vertical_blanking & 0x3f;
|
||||
vbend = (vbend - vbstart) & 0x3f;
|
||||
if ( !vbend)
|
||||
vbend = vbstart + 0x3f + 1;
|
||||
else
|
||||
vbend = vbstart + vbend;
|
||||
|
||||
|
||||
switch (svgaCard) {
|
||||
case SVGA_S3Trio:
|
||||
|
@ -608,13 +704,24 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
if (vga.s3.pll.cmd & 0x10) clock/=2;
|
||||
vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0;
|
||||
} else {
|
||||
vga.draw.address_line_total=vga.other.max_scanline+1;
|
||||
htotal=vga.other.htotal+1;
|
||||
hdispend=vga.other.hdend;
|
||||
hrstart=vga.other.hsyncp;
|
||||
vtotal=vga.draw.address_line_total*(vga.other.vtotal+1)+vga.other.vadjust;
|
||||
vdispend=vga.draw.address_line_total*vga.other.vdend;
|
||||
vrstart=vga.draw.address_line_total*vga.other.vsyncp;
|
||||
htotal = vga.other.htotal + 1;
|
||||
hdend = vga.other.hdend;
|
||||
hbstart = hdend;
|
||||
hbend = htotal;
|
||||
hrstart = vga.other.hsyncp;
|
||||
hrend = hrstart + (vga.other.syncw & 0xf) ;
|
||||
|
||||
vga.draw.address_line_total = vga.other.max_scanline + 1;
|
||||
vtotal = vga.draw.address_line_total * (vga.other.vtotal+1)+vga.other.vadjust;
|
||||
vdend = vga.draw.address_line_total * vga.other.vdend;
|
||||
vrstart = vga.draw.address_line_total * vga.other.vsyncp;
|
||||
vrend = (vga.other.syncw >> 4);
|
||||
if (!vrend)
|
||||
vrend = vrstart + 0xf + 1;
|
||||
else
|
||||
vrend = vrstart + vrend;
|
||||
vbstart = vdend;
|
||||
vbend = vtotal;
|
||||
vga.draw.double_scan=false;
|
||||
switch (machine) {
|
||||
case MCH_CGA:
|
||||
|
@ -627,69 +734,92 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal);
|
||||
LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend);
|
||||
LOG(LOG_VGA,LOG_NORMAL)("h total %d end %d blank (%d/%d) retrace (%d/%d)",
|
||||
htotal, hdend, hbstart, hbend, hrstart, hrend );
|
||||
LOG(LOG_VGA,LOG_NORMAL)("v total %d end %d blank (%d/%d) retrace (%d/%d)",
|
||||
vtotal, vdend, vbstart, vbend, vrstart, vrend );
|
||||
|
||||
if (!htotal) return;
|
||||
if (!vtotal) return;
|
||||
|
||||
fps=(float)clock/(vtotal*htotal);
|
||||
float linetime=1000.0f/fps;
|
||||
vga.draw.parts_total=VGA_PARTS;
|
||||
vga.draw.delay.vtotal=linetime;
|
||||
linetime/=vtotal; //Really make it the line_delay
|
||||
vga.draw.delay.vend=linetime*vrstart;
|
||||
vga.draw.delay.parts=(linetime*vdispend)/vga.draw.parts_total;
|
||||
vga.draw.delay.htotal=linetime;
|
||||
vga.draw.delay.hend=(linetime/htotal)*hrstart;
|
||||
// The time a complete video frame takes
|
||||
vga.draw.delay.vtotal = (1000.0 * (double)(vtotal*htotal)) / (double)clock;
|
||||
// Horizontal total (that's how long a line takes with whistles and bells)
|
||||
vga.draw.delay.htotal = htotal*1000.0/clock; //in milliseconds
|
||||
// Start and End of horizontal blanking
|
||||
vga.draw.delay.hblkstart = hbstart*1000.0/clock; //in milliseconds
|
||||
vga.draw.delay.hblkend = hbend*1000.0/clock;
|
||||
vga.draw.delay.hrstart = 0;
|
||||
|
||||
// Start and End of vertical blanking
|
||||
vga.draw.delay.vblkstart = vbstart * vga.draw.delay.htotal;
|
||||
vga.draw.delay.vblkend = vbend * vga.draw.delay.htotal;
|
||||
// Start and End of vertical retrace pulse
|
||||
vga.draw.delay.vrstart = vrstart * vga.draw.delay.htotal;
|
||||
vga.draw.delay.vrend = vrend * vga.draw.delay.htotal;
|
||||
// Display end
|
||||
vga.draw.delay.vdend = vdend * vga.draw.delay.htotal;
|
||||
|
||||
/*
|
||||
// just curious
|
||||
LOG_MSG("H total %d, V Total %d",htotal,vtotal);
|
||||
LOG_MSG("H D End %d, V D End %d",hdispend,vdispend);
|
||||
LOG_MSG("vrstart: %d, vrend: %d\n",vrstart,vrend);
|
||||
LOG_MSG("htotal: %2.6f, vtotal: %2.6f,\n"\
|
||||
"hblkstart: %2.6f, hblkend: %2.6f,\n"\
|
||||
"vblkstart: %2.6f, vblkend: %2.6f,\n"\
|
||||
"vrstart: %2.6f, vrend: %2.6f,\n"\
|
||||
"vdispend: %2.6f",
|
||||
vga.draw.delay.htotal, vga.draw.delay.vtotal,
|
||||
vga.draw.delay.hblkstart, vga.draw.delay.hblkend,
|
||||
vga.draw.delay.vblkstart, vga.draw.delay.vblkend,
|
||||
vga.draw.delay.vrstart, vga.draw.delay.vrend,
|
||||
vga.draw.delay.vend);
|
||||
*/
|
||||
vga.draw.parts_total=VGA_PARTS;
|
||||
double correct_ratio=(100.0/525.0);
|
||||
double aspect_ratio=((double)htotal/((double)vtotal)/correct_ratio);
|
||||
|
||||
vga.draw.resizing=false;
|
||||
Bitu width=hdispend;
|
||||
Bitu height=vdispend;
|
||||
Bitu bpp=8;
|
||||
|
||||
//Check to prevent useless black areas
|
||||
if (hbstart<hdend) hdend=hbstart;
|
||||
if (vbstart<vdend) vdend=vbstart;
|
||||
|
||||
Bitu width=hdend;
|
||||
Bitu height=vdend;
|
||||
bool doubleheight=false;
|
||||
bool doublewidth=false;
|
||||
VGA_FrameStart = NULL;
|
||||
|
||||
//Set the bpp
|
||||
Bitu bpp;
|
||||
switch (vga.mode) {
|
||||
case M_LIN15:
|
||||
bpp = 15;
|
||||
break;
|
||||
case M_LIN16:
|
||||
bpp = 16;
|
||||
break;
|
||||
case M_LIN32:
|
||||
bpp = 32;
|
||||
break;
|
||||
default:
|
||||
bpp = 8;
|
||||
break;
|
||||
}
|
||||
vga.draw.linear_base = vga.mem.linear;
|
||||
vga.draw.linear_mask = VGA_MEMORY - 1;
|
||||
switch (vga.mode) {
|
||||
case M_VGA:
|
||||
doublewidth=true;
|
||||
width<<=2;
|
||||
// Proper line handler is selected at the beginning of the frame
|
||||
// VGA_DrawLine=VGA_Draw_VGAChained_Line;
|
||||
VGA_FrameStart=VGA_StartFrame_VGA;
|
||||
VGA_DrawLine = VGA_Draw_Linear_Line;
|
||||
break;
|
||||
case M_LIN8:
|
||||
width<<=3;
|
||||
if (vga.crtc.mode_control & 0x8) {
|
||||
doublewidth = true;
|
||||
width >>= 1;
|
||||
}
|
||||
/* Use HW mouse cursor drawer if enabled */
|
||||
VGA_ActivateHardwareCursor();
|
||||
break;
|
||||
case M_LIN15:
|
||||
bpp = 15;
|
||||
width<<=3;
|
||||
if (vga.crtc.mode_control & 0x8) {
|
||||
doublewidth = true;
|
||||
width >>= 1;
|
||||
}
|
||||
/* Use HW mouse cursor drawer if enabled */
|
||||
VGA_ActivateHardwareCursor();
|
||||
break;
|
||||
case M_LIN16:
|
||||
bpp = 16;
|
||||
width<<=3;
|
||||
if (vga.crtc.mode_control & 0x8) {
|
||||
doublewidth = true;
|
||||
width >>= 1;
|
||||
}
|
||||
/* Use HW mouse cursor drawer if enabled */
|
||||
VGA_ActivateHardwareCursor();
|
||||
break;
|
||||
case M_LIN32:
|
||||
bpp = 32;
|
||||
width<<=3;
|
||||
if (vga.crtc.mode_control & 0x8) {
|
||||
doublewidth = true;
|
||||
|
@ -702,13 +832,17 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
doublewidth=(vga.seq.clocking_mode & 0x8) > 0;
|
||||
vga.draw.blocks = width;
|
||||
width<<=3;
|
||||
VGA_DrawLine=VGA_Draw_LIN4_Line;
|
||||
VGA_DrawLine=VGA_Draw_Linear_Line;
|
||||
vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET;
|
||||
vga.draw.linear_mask = 1024 * 1024 - 1;
|
||||
break;
|
||||
case M_EGA:
|
||||
doublewidth=(vga.seq.clocking_mode & 0x8) > 0;
|
||||
vga.draw.blocks = width;
|
||||
width<<=3;
|
||||
VGA_DrawLine=VGA_Draw_EGA_Line;
|
||||
VGA_DrawLine=VGA_Draw_Linear_Line;
|
||||
vga.draw.linear_base = vga.mem.linear + VGA_CACHE_OFFSET;
|
||||
vga.draw.linear_mask = 512 * 1024 - 1;
|
||||
break;
|
||||
case M_CGA16:
|
||||
doubleheight=true;
|
||||
|
@ -758,18 +892,26 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
vga.draw.blocks=width * 2;
|
||||
width=vga.draw.blocks*4;
|
||||
if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) ||
|
||||
(machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) VGA_DrawLine=VGA_Draw_2BPPHiRes_Line;
|
||||
(machine==MCH_PCJR && (vga.tandy.mode_control==0x0b)))
|
||||
VGA_DrawLine=VGA_Draw_2BPPHiRes_Line;
|
||||
else VGA_DrawLine=VGA_Draw_2BPP_Line;
|
||||
break;
|
||||
case M_TANDY16:
|
||||
aspect_ratio=1.2;
|
||||
doubleheight=true;
|
||||
doublewidth=true;
|
||||
vga.draw.blocks=width*2;
|
||||
if (vga.tandy.mode_control & 0x1) {
|
||||
width=vga.draw.blocks*2;
|
||||
if ( vga.tandy.mode_control & 0x10 ) {
|
||||
doublewidth = false;
|
||||
vga.draw.blocks*=2;
|
||||
width=vga.draw.blocks*2;
|
||||
} else {
|
||||
doublewidth = true;
|
||||
width=vga.draw.blocks*2;
|
||||
}
|
||||
VGA_DrawLine=VGA_Draw_4BPP_Line;
|
||||
} else {
|
||||
doublewidth=true;
|
||||
width=vga.draw.blocks*4;
|
||||
VGA_DrawLine=VGA_Draw_4BPP_Line_Double;
|
||||
}
|
||||
|
@ -799,6 +941,13 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
}
|
||||
vga.draw.lines_total=height;
|
||||
vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total;
|
||||
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
vga.changes.active = false;
|
||||
vga.changes.lineWidth = width * ((bpp + 1) / 8);
|
||||
vga.changes.frame = 0;
|
||||
vga.changes.writeMask = 1;
|
||||
#endif
|
||||
if (( width != vga.draw.width) || (height != vga.draw.height) || (vga.mode != vga.lastmode)) {
|
||||
vga.lastmode = vga.mode;
|
||||
PIC_RemoveEvents(VGA_VerticalTimer);
|
||||
|
@ -816,7 +965,8 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio);
|
||||
#endif
|
||||
RENDER_SetSize(width,height,bpp,fps,aspect_ratio,doublewidth,doubleheight);
|
||||
PIC_AddEvent(VGA_VerticalTimer,vga.draw.delay.vtotal);
|
||||
vga.draw.delay.framestart = PIC_FullIndex();
|
||||
PIC_AddEvent( VGA_VerticalTimer , vga.draw.delay.vtotal );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,6 +25,37 @@
|
|||
#include "pic.h"
|
||||
#include "inout.h"
|
||||
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
#define MEM_CHANGED( _MEM ) vga.changes.map[ (_MEM) >> VGA_CHANGE_SHIFT ] |= vga.changes.writeMask;
|
||||
//#define MEM_CHANGED( _MEM ) vga.changes.map[ (_MEM) >> VGA_CHANGE_SHIFT ] = 1;
|
||||
#else
|
||||
#define MEM_CHANGED( _MEM )
|
||||
#endif
|
||||
|
||||
#define TANDY_VIDBASE(_X_) &MemBase[ 0x80000 + (_X_)]
|
||||
|
||||
template <class Size>
|
||||
static INLINE void hostWrite(HostPt off, Bitu val) {
|
||||
if ( sizeof( Size ) == 1)
|
||||
host_writeb( off, (Bit8u)val );
|
||||
else if ( sizeof( Size ) == 2)
|
||||
host_writew( off, (Bit16u)val );
|
||||
else if ( sizeof( Size ) == 4)
|
||||
host_writed( off, (Bit32u)val );
|
||||
}
|
||||
|
||||
template <class Size>
|
||||
static INLINE Bitu hostRead(HostPt off ) {
|
||||
if ( sizeof( Size ) == 1)
|
||||
return host_readb( off );
|
||||
else if ( sizeof( Size ) == 2)
|
||||
return host_readw( off );
|
||||
else if ( sizeof( Size ) == 4)
|
||||
return host_readd( off );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void VGA_MapMMIO(void);
|
||||
//Nice one from DosEmu
|
||||
INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) {
|
||||
|
@ -83,8 +114,7 @@ static struct {
|
|||
class VGA_UnchainedRead_Handler : public PageHandler {
|
||||
public:
|
||||
Bitu readHandler(PhysPt start) {
|
||||
start += vga.s3.svga_bank.fullbank;
|
||||
vga.latch.d=vga.mem.latched[start].d;
|
||||
vga.latch.d=((Bit32u*)vga.mem.linear)[start];
|
||||
switch (vga.config.read_mode) {
|
||||
case 0:
|
||||
return (vga.latch.b[vga.config.read_map_select]);
|
||||
|
@ -116,45 +146,20 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class VGA_Chained_ReadHandler : public PageHandler {
|
||||
class VGA_ChainedEGA_Handler : public PageHandler {
|
||||
public:
|
||||
Bitu readHandler(PhysPt addr) {
|
||||
if(vga.mode == M_VGA)
|
||||
return vga.mem.linear[((addr&~3)<<2)|(addr&3)];
|
||||
return vga.mem.linear[addr];
|
||||
}
|
||||
public:
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return readHandler(addr);
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8);
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8) |
|
||||
(readHandler(addr+2) << 16) |
|
||||
(readHandler(addr+3) << 24);
|
||||
}
|
||||
};
|
||||
|
||||
class VGA_ChainedEGA_Handler : public VGA_Chained_ReadHandler {
|
||||
public:
|
||||
void writeHandler(PhysPt start, Bit8u val) {
|
||||
Bit32u data=ModeOperation(val);
|
||||
/* Update video memory and the pixel buffer */
|
||||
VGA_Latch pixels;
|
||||
vga.mem.linear[start] = val;
|
||||
start >>= 2;
|
||||
pixels.d=vga.mem.latched[start].d;
|
||||
pixels.d=((Bit32u*)vga.mem.linear)[start];
|
||||
|
||||
Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)];
|
||||
Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)];
|
||||
|
||||
Bit32u colors0_3, colors4_7;
|
||||
VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f;
|
||||
|
@ -178,33 +183,55 @@ public:
|
|||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler(addr+2,(Bit8u)(val >> 16));
|
||||
writeHandler(addr+3,(Bit8u)(val >> 24));
|
||||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return readHandler(addr);
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8);
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8) |
|
||||
(readHandler(addr+2) << 16) |
|
||||
(readHandler(addr+3) << 24);
|
||||
}
|
||||
};
|
||||
|
||||
class VGA_UnchainedEGA_Handler : public VGA_UnchainedRead_Handler {
|
||||
public:
|
||||
template< bool wrapping>
|
||||
void writeHandler(PhysPt start, Bit8u val) {
|
||||
Bit32u data=ModeOperation(val);
|
||||
/* Update video memory and the pixel buffer */
|
||||
VGA_Latch pixels;
|
||||
pixels.d=vga.mem.latched[start].d;
|
||||
pixels.d=((Bit32u*)vga.mem.linear)[start];
|
||||
pixels.d&=vga.config.full_not_map_mask;
|
||||
pixels.d|=(data & vga.config.full_map_mask);
|
||||
vga.mem.latched[start].d=pixels.d;
|
||||
Bit8u * write_pixels=&vga.mem.linear[512*1024+(start<<3)];
|
||||
((Bit32u*)vga.mem.linear)[start]=pixels.d;
|
||||
Bit8u * write_pixels=&vga.mem.linear[VGA_CACHE_OFFSET+(start<<3)];
|
||||
|
||||
Bit32u colors0_3, colors4_7;
|
||||
VGA_Latch temp;temp.d=(pixels.d>>4) & 0x0f0f0f0f;
|
||||
|
@ -214,7 +241,6 @@ public:
|
|||
Expand16Table[2][temp.b[2]] |
|
||||
Expand16Table[3][temp.b[3]];
|
||||
*(Bit32u *)write_pixels=colors0_3;
|
||||
*(Bit32u *)(write_pixels+512*1024)=colors0_3;
|
||||
temp.d=pixels.d & 0x0f0f0f0f;
|
||||
colors4_7 =
|
||||
Expand16Table[0][temp.b[0]] |
|
||||
|
@ -222,7 +248,10 @@ public:
|
|||
Expand16Table[2][temp.b[2]] |
|
||||
Expand16Table[3][temp.b[3]];
|
||||
*(Bit32u *)(write_pixels+4)=colors4_7;
|
||||
*(Bit32u *)(write_pixels+512*1024+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() {
|
||||
|
@ -230,68 +259,147 @@ public:
|
|||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler<true>(addr+1,(Bit8u)(val >> 8));
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler(addr+2,(Bit8u)(val >> 16));
|
||||
writeHandler(addr+3,(Bit8u)(val >> 24));
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler<true>(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler<true>(addr+2,(Bit8u)(val >> 16));
|
||||
writeHandler<true>(addr+3,(Bit8u)(val >> 24));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class VGA_ChainedVGA_Handler : public VGA_Chained_ReadHandler {
|
||||
//Slighly unusual version, will directly write 8,16,32 bits values
|
||||
class VGA_ChainedVGA_Handler : public PageHandler {
|
||||
public:
|
||||
void writeHandler(PhysPt addr, Bitu val) {
|
||||
// No need to check for compatible chains here, this one is only enabled if that bit is set
|
||||
vga.mem.linear[((addr&~3)<<2)|(addr&3)] = val;
|
||||
// Linearized version for faster rendering
|
||||
vga.mem.linear[512*1024+addr] = val;
|
||||
if (addr >= 320) return;
|
||||
// And replicate the first line
|
||||
vga.mem.linear[512*1024+addr+64*1024] = val;
|
||||
}
|
||||
public:
|
||||
VGA_ChainedVGA_Handler() {
|
||||
flags=PFLAG_NOCODE;
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
template <class Size>
|
||||
static INLINE Bitu readHandler(PhysPt addr ) {
|
||||
return hostRead<Size>( &vga.mem.linear[((addr&~3)<<2)+(addr&3)] );
|
||||
}
|
||||
template <class Size>
|
||||
static INLINE void writeCache(PhysPt addr, Bitu val) {
|
||||
hostWrite<Size>( &vga.mem.linear[VGA_CACHE_OFFSET+addr], val );
|
||||
if (GCC_UNLIKELY(addr < 320)) {
|
||||
// And replicate the first line
|
||||
hostWrite<Size>( &vga.mem.linear[VGA_CACHE_OFFSET+addr+64*1024], val );
|
||||
}
|
||||
}
|
||||
template <class Size>
|
||||
static INLINE void writeHandler(PhysPt addr, Bitu val) {
|
||||
// No need to check for compatible chains here, this one is only enabled if that bit is set
|
||||
hostWrite<Size>( &vga.mem.linear[((addr&~3)<<2)+(addr&3)], val );
|
||||
}
|
||||
Bitu readb(PhysPt addr ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
return readHandler<Bit8u>( addr );
|
||||
}
|
||||
Bitu readw(PhysPt addr ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return readHandler<Bit16u>( addr );
|
||||
}
|
||||
Bitu readd(PhysPt addr ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
return readHandler<Bit32u>( addr );
|
||||
}
|
||||
bool readw_checked( PhysPt addr,Bitu *val ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
if ( addr & 1) {
|
||||
*val =
|
||||
(readHandler<Bit8u>( addr+0 ) << 0 ) |
|
||||
(readHandler<Bit8u>( addr+1 ) << 8 );
|
||||
} else {
|
||||
*val = readHandler<Bit16u>( addr );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool readd_checked( PhysPt addr,Bitu *val ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
if ( addr & 3) {
|
||||
*val =
|
||||
(readHandler<Bit8u>( addr+0 ) << 0 ) |
|
||||
(readHandler<Bit8u>( addr+1 ) << 8 ) |
|
||||
(readHandler<Bit8u>( addr+2 ) << 16 ) |
|
||||
(readHandler<Bit8u>( addr+3 ) << 24 );
|
||||
} else {
|
||||
*val = readHandler<Bit32u>( addr );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void writeb(PhysPt addr, Bitu val ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
MEM_CHANGED( addr );
|
||||
writeHandler<Bit8u>( addr, val );
|
||||
writeCache<Bit8u>( addr, val );
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
MEM_CHANGED( addr );
|
||||
writeHandler<Bit16u>( addr, val );
|
||||
writeCache<Bit16u>( addr, val );
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler(addr+2,(Bit8u)(val >> 16));
|
||||
writeHandler(addr+3,(Bit8u)(val >> 24));
|
||||
MEM_CHANGED( addr );
|
||||
writeHandler<Bit32u>( addr, val );
|
||||
writeCache<Bit32u>( addr, val );
|
||||
}
|
||||
bool writew_checked( PhysPt addr,Bitu val ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
if ( addr & 1 ) {
|
||||
MEM_CHANGED( addr );
|
||||
MEM_CHANGED( addr + 1);
|
||||
writeHandler<Bit8u>( addr+0, val >> 0 );
|
||||
writeHandler<Bit8u>( addr+1, val >> 8 );
|
||||
writeCache<Bit16u>( addr, val );
|
||||
} else {
|
||||
MEM_CHANGED( addr );
|
||||
writeHandler<Bit16u>( addr, val );
|
||||
writeCache<Bit16u>( addr, val );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool writed_checked( PhysPt addr,Bitu val ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
if ( addr & 3) {
|
||||
MEM_CHANGED( addr );
|
||||
MEM_CHANGED( addr + 3);
|
||||
writeHandler<Bit8u>( addr+0, val >> 0 );
|
||||
writeHandler<Bit8u>( addr+1, val >> 8 );
|
||||
writeHandler<Bit8u>( addr+2, val >> 16 );
|
||||
writeHandler<Bit8u>( addr+3, val >> 24 );
|
||||
writeCache<Bit32u>( addr, val );
|
||||
} else {
|
||||
MEM_CHANGED( addr );
|
||||
writeHandler<Bit32u>( addr, val );
|
||||
writeCache<Bit32u>( addr, val );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
class VGA_UnchainedVGA_Handler : public VGA_UnchainedRead_Handler {
|
||||
public:
|
||||
void writeHandler( PhysPt addr, Bit8u val ) {
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
Bit32u data=ModeOperation(val);
|
||||
VGA_Latch pixels;
|
||||
pixels.d=vga.mem.latched[addr].d;
|
||||
pixels.d=((Bit32u*)vga.mem.linear)[addr];
|
||||
pixels.d&=vga.config.full_not_map_mask;
|
||||
pixels.d|=(data & vga.config.full_map_mask);
|
||||
vga.mem.latched[addr].d=pixels.d;
|
||||
((Bit32u*)vga.mem.linear)[addr]=pixels.d;
|
||||
if(vga.config.compatible_chain4)
|
||||
vga.mem.latched[addr+64*1024].d=pixels.d;
|
||||
((Bit32u*)vga.mem.linear)[addr+64*1024]=pixels.d;
|
||||
}
|
||||
public:
|
||||
VGA_UnchainedVGA_Handler() {
|
||||
|
@ -299,15 +407,21 @@ public:
|
|||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
MEM_CHANGED( addr << 2 );
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
MEM_CHANGED( addr << 2);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
MEM_CHANGED( addr << 2);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler(addr+2,(Bit8u)(val >> 16));
|
||||
|
@ -332,9 +446,9 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class VGA_MAP_PageHandler : public PageHandler {
|
||||
class VGA_Map_Handler : public PageHandler {
|
||||
public:
|
||||
VGA_MAP_PageHandler() {
|
||||
VGA_Map_Handler() {
|
||||
flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE;
|
||||
}
|
||||
HostPt GetHostReadPt(Bitu phys_page) {
|
||||
|
@ -347,87 +461,88 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
class VGA_LIN4Linear_Handler : public VGA_UnchainedEGA_Handler {
|
||||
class VGA_Changes_Handler : public PageHandler {
|
||||
public:
|
||||
VGA_LIN4Linear_Handler() {
|
||||
flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE;
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler(addr+2,(Bit8u)(val >> 16));
|
||||
writeHandler(addr+3,(Bit8u)(val >> 24));
|
||||
VGA_Changes_Handler() {
|
||||
flags=PFLAG_NOCODE;
|
||||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1);
|
||||
return readHandler(addr);
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
return hostRead<Bit8u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1);
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8);
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
return hostRead<Bit16u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = (PAGING_GetPhysicalAddress(addr) - vga.lfb.addr) & (512*1024-1);
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8) |
|
||||
(readHandler(addr+2) << 16) |
|
||||
(readHandler(addr+3) << 24);
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
return hostRead<Bit32u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
MEM_CHANGED( addr );
|
||||
hostWrite<Bit8u>( &vga.mem.linear[addr], val );
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
MEM_CHANGED( addr );
|
||||
hostWrite<Bit16u>( &vga.mem.linear[addr], val );
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
MEM_CHANGED( addr );
|
||||
hostWrite<Bit32u>( &vga.mem.linear[addr], val );
|
||||
}
|
||||
};
|
||||
|
||||
class VGA_LIN4Banked_Handler : public VGA_UnchainedEGA_Handler {
|
||||
class VGA_LIN4_Handler : public VGA_UnchainedEGA_Handler {
|
||||
public:
|
||||
VGA_LIN4Banked_Handler() {
|
||||
VGA_LIN4_Handler() {
|
||||
flags=PFLAG_NOCODE;
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (512*1024-1);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
addr &= (128*1024-1);
|
||||
MEM_CHANGED( addr << 3 );
|
||||
writeHandler<false>(addr+0,(Bit8u)(val >> 0));
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (512*1024-1);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
addr &= (128*1024-1);
|
||||
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.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (512*1024-1);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler(addr+2,(Bit8u)(val >> 16));
|
||||
writeHandler(addr+3,(Bit8u)(val >> 24));
|
||||
addr &= (128*1024-1);
|
||||
MEM_CHANGED( addr << 3 );
|
||||
writeHandler<false>(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler<false>(addr+1,(Bit8u)(val >> 8));
|
||||
writeHandler<false>(addr+2,(Bit8u)(val >> 16));
|
||||
writeHandler<false>(addr+3,(Bit8u)(val >> 24));
|
||||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (512*1024-1);
|
||||
addr &= (128*1024-1);
|
||||
return readHandler(addr);
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (512*1024-1);
|
||||
addr &= (128*1024-1);
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8);
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (512*1024-1);
|
||||
addr &= (128*1024-1);
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8) |
|
||||
|
@ -444,31 +559,38 @@ public:
|
|||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
|
||||
return *(Bit8u*)(&vga.mem.linear[addr]);
|
||||
return hostRead<Bit8u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
|
||||
return *(Bit16u*)(&vga.mem.linear[addr]);
|
||||
return hostRead<Bit16u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
|
||||
return *(Bit32u*)(&vga.mem.linear[addr]);
|
||||
return hostRead<Bit32u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
|
||||
*(Bit8u*)(&vga.mem.linear[addr]) = val;
|
||||
vga.changed[addr >> VGA_CHANGE_SHIFT] = 1;
|
||||
hostWrite<Bit8u>( &vga.mem.linear[addr], val );
|
||||
MEM_CHANGED( addr );
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
|
||||
*(Bit16u*)(&vga.mem.linear[addr]) = val;
|
||||
vga.changed[addr >> VGA_CHANGE_SHIFT] = 1;
|
||||
hostWrite<Bit16u>( &vga.mem.linear[addr], val );
|
||||
MEM_CHANGED( addr );
|
||||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
|
||||
*(Bit32u*)(&vga.mem.linear[addr]) = val;
|
||||
vga.changed[addr >> VGA_CHANGE_SHIFT] = 1;
|
||||
hostWrite<Bit32u>( &vga.mem.linear[addr], val );
|
||||
MEM_CHANGED( addr );
|
||||
}
|
||||
bool writed_checked( PhysPt addr,Bitu val ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) - vga.lfb.addr;
|
||||
hostWrite<Bit32u>( &vga.mem.linear[addr], val );
|
||||
MEM_CHANGED( addr );
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class VGA_LFB_Handler : public PageHandler {
|
||||
|
@ -569,156 +691,207 @@ public:
|
|||
// |PFLAG_NOCODE;
|
||||
}
|
||||
HostPt GetHostReadPt(Bitu phys_page) {
|
||||
if (phys_page>=0xb8) {
|
||||
phys_page-=0xb8;
|
||||
return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)];
|
||||
} else {
|
||||
if (machine==MCH_TANDY) phys_page-=0x80;
|
||||
return &vga.mem.linear[phys_page * 4096];
|
||||
}
|
||||
if (vga.tandy.mem_bank & 1)
|
||||
phys_page&=0x03;
|
||||
else
|
||||
phys_page&=0x07;
|
||||
return vga.tandy.mem_base + (phys_page * 4096);
|
||||
}
|
||||
HostPt GetHostWritePt(Bitu phys_page) {
|
||||
return GetHostReadPt( phys_page );
|
||||
}
|
||||
};
|
||||
|
||||
class VGA_PCJR_PageHandler : public PageHandler {
|
||||
|
||||
class VGA_PCJR_Handler : public PageHandler {
|
||||
public:
|
||||
VGA_PCJR_PageHandler() {
|
||||
VGA_PCJR_Handler() {
|
||||
flags=PFLAG_READABLE|PFLAG_WRITEABLE;
|
||||
}
|
||||
HostPt GetHostReadPt(Bitu phys_page) {
|
||||
phys_page-=0xb8;
|
||||
if (!vga.tandy.is_32k_mode) phys_page&=0x03;
|
||||
return MemBase+(vga.tandy.mem_bank << 14)+(phys_page * 4096);
|
||||
//test for a unaliged bank, then replicate 2x16kb
|
||||
if (vga.tandy.mem_bank & 1)
|
||||
phys_page&=0x03;
|
||||
return vga.tandy.mem_base + (phys_page * 4096);
|
||||
}
|
||||
HostPt GetHostWritePt(Bitu phys_page) {
|
||||
return GetHostReadPt( phys_page );
|
||||
}
|
||||
};
|
||||
|
||||
class VGA_Empty_Handler : public PageHandler {
|
||||
public:
|
||||
VGA_Empty_Handler() {
|
||||
flags=PFLAG_NOCODE;
|
||||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
// LOG(LOG_VGA, LOG_NORMAL ) ( "Read from empty memory space at %x", addr );
|
||||
return 0xff;
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
// LOG(LOG_VGA, LOG_NORMAL ) ( "Write %x to empty memory space at %x", val, addr );
|
||||
}
|
||||
};
|
||||
|
||||
static struct vg {
|
||||
VGA_MAP_PageHandler map;
|
||||
VGA_Map_Handler map;
|
||||
VGA_Changes_Handler changes;
|
||||
VGA_TEXT_PageHandler text;
|
||||
VGA_TANDY_PageHandler tandy;
|
||||
VGA_ChainedEGA_Handler cega;
|
||||
VGA_ChainedVGA_Handler cvga;
|
||||
VGA_UnchainedEGA_Handler uega;
|
||||
VGA_UnchainedVGA_Handler uvga;
|
||||
VGA_PCJR_PageHandler hpcjr;
|
||||
VGA_LIN4Banked_Handler l4banked;
|
||||
VGA_LIN4Linear_Handler l4linear;
|
||||
VGA_PCJR_Handler pcjr;
|
||||
VGA_LIN4_Handler lin4;
|
||||
VGA_LFB_Handler lfb;
|
||||
VGA_LFBChanges_Handler lfbchanges;
|
||||
VGA_MMIO_Handler mmio;
|
||||
VGA_Empty_Handler empty;
|
||||
} vgaph;
|
||||
|
||||
void VGA_ChangedBank(void) {
|
||||
#ifndef VGA_LFB_MAPPED
|
||||
//If the mode is accurate than the correct mapper must have been installed already
|
||||
if ( vga.mode >= M_LIN4 && vga.mode <= M_LIN32 ) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
|
||||
void VGA_SetupHandlers(void) {
|
||||
PageHandler * range_handler;
|
||||
PageHandler *newHandler;
|
||||
switch (machine) {
|
||||
case MCH_CGA:
|
||||
range_handler=&vgaph.map;
|
||||
goto range_b800;
|
||||
case MCH_HERC:
|
||||
range_handler=&vgaph.map;
|
||||
if (vga.herc.mode_control&0x80) goto range_b800;
|
||||
else goto range_b000;
|
||||
case MCH_TANDY:
|
||||
range_handler=&vgaph.tandy;
|
||||
MEM_SetPageHandler(0x80,32,range_handler);
|
||||
goto range_b800;
|
||||
case MCH_PCJR:
|
||||
range_handler=&vgaph.hpcjr;
|
||||
MEM_SetPageHandler( VGA_PAGE_B8, 8, &vgaph.pcjr );
|
||||
goto range_done;
|
||||
case MCH_HERC:
|
||||
vgapages.base=VGA_PAGE_B0;
|
||||
if (vga.herc.enable_bits & 0x2) {
|
||||
vgapages.mask=0xffff;
|
||||
MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.map);
|
||||
} else {
|
||||
vgapages.mask=0x7fff;
|
||||
/* With hercules in 32kb mode it leaves a memory hole on 0xb800 */
|
||||
MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.map);
|
||||
MEM_SetPageHandler(VGA_PAGE_B8,8,&vgaph.empty);
|
||||
}
|
||||
goto range_done;
|
||||
case MCH_TANDY:
|
||||
/* Always map 0xa000 - 0xbfff, might overwrite 0xb800 */
|
||||
vgapages.base=VGA_PAGE_A0;
|
||||
vgapages.mask=0x1ffff;
|
||||
MEM_SetPageHandler(VGA_PAGE_A0, 32, &vgaph.map );
|
||||
if ( vga.tandy.extended_ram & 1 ) {
|
||||
//You seem to be able to also map different 64kb banks, but have to figure that out
|
||||
//This seems to work so far though
|
||||
vga.tandy.draw_base = vga.mem.linear;
|
||||
vga.tandy.mem_base = vga.mem.linear;
|
||||
} else {
|
||||
vga.tandy.draw_base = TANDY_VIDBASE( vga.tandy.draw_bank * 16 * 1024);
|
||||
vga.tandy.mem_base = TANDY_VIDBASE( vga.tandy.mem_bank * 16 * 1024);
|
||||
MEM_SetPageHandler( 0xb8, 8, &vgaph.tandy );
|
||||
}
|
||||
goto range_done;
|
||||
// MEM_SetPageHandler(vga.tandy.mem_bank<<2,vga.tandy.is_32k_mode ? 0x08 : 0x04,range_handler);
|
||||
goto range_b800;
|
||||
case MCH_VGA:
|
||||
break;
|
||||
default:
|
||||
LOG_MSG("Illegal machine type %d", machine );
|
||||
return;
|
||||
}
|
||||
|
||||
/* This should be vga only */
|
||||
switch (vga.mode) {
|
||||
case M_ERROR:
|
||||
return;
|
||||
case M_LIN4:
|
||||
range_handler=&vgaph.l4banked;
|
||||
newHandler = &vgaph.lin4;
|
||||
break;
|
||||
case M_LIN15:
|
||||
case M_LIN16:
|
||||
case M_LIN32:
|
||||
range_handler=&vgaph.map;
|
||||
#ifdef VGA_LFB_MAPPED
|
||||
newHandler = &vgaph.map;
|
||||
#else
|
||||
newHandler = &vgaph.changes;
|
||||
#endif
|
||||
break;
|
||||
case M_LIN8:
|
||||
case M_VGA:
|
||||
if (vga.config.chained) {
|
||||
if(vga.config.compatible_chain4)
|
||||
range_handler = &vgaph.cvga;
|
||||
else
|
||||
range_handler=&vgaph.map;
|
||||
newHandler = &vgaph.cvga;
|
||||
else
|
||||
#ifdef VGA_LFB_MAPPED
|
||||
newHandler = &vgaph.map;
|
||||
#else
|
||||
newHandler = &vgaph.changes;
|
||||
#endif
|
||||
} else {
|
||||
range_handler=&vgaph.uvga;
|
||||
newHandler = &vgaph.uvga;
|
||||
}
|
||||
break;
|
||||
case M_EGA:
|
||||
if (vga.config.chained)
|
||||
range_handler=&vgaph.cega;
|
||||
newHandler = &vgaph.cega;
|
||||
else
|
||||
range_handler=&vgaph.uega;
|
||||
newHandler = &vgaph.uega;
|
||||
break;
|
||||
case M_TEXT:
|
||||
/* Check if we're not in odd/even mode */
|
||||
if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.map;
|
||||
else range_handler=&vgaph.text;
|
||||
if (vga.gfx.miscellaneous & 0x2) newHandler = &vgaph.map;
|
||||
else newHandler = &vgaph.text;
|
||||
break;
|
||||
case M_CGA4:
|
||||
case M_CGA2:
|
||||
range_handler=&vgaph.map;
|
||||
newHandler = &vgaph.map;
|
||||
break;
|
||||
}
|
||||
switch ((vga.gfx.miscellaneous >> 2) & 3) {
|
||||
case 0:
|
||||
vgapages.base=VGA_PAGE_A0;
|
||||
vgapages.mask=0x1ffff;
|
||||
MEM_SetPageHandler(VGA_PAGE_A0,32,range_handler);
|
||||
vgapages.base = VGA_PAGE_A0;
|
||||
vgapages.mask = 0x1ffff;
|
||||
MEM_SetPageHandler(VGA_PAGE_A0, 32, newHandler );
|
||||
break;
|
||||
case 1:
|
||||
vgapages.base=VGA_PAGE_A0;
|
||||
vgapages.mask=0xffff;
|
||||
MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler);
|
||||
MEM_ResetPageHandler(VGA_PAGE_B0,16);
|
||||
vgapages.base = VGA_PAGE_A0;
|
||||
vgapages.mask = 0xffff;
|
||||
MEM_SetPageHandler( VGA_PAGE_A0, 16, newHandler );
|
||||
MEM_ResetPageHandler( VGA_PAGE_B0, 16);
|
||||
break;
|
||||
case 2:
|
||||
range_b000:
|
||||
vgapages.base=VGA_PAGE_B0;
|
||||
vgapages.mask=0x7fff;
|
||||
MEM_SetPageHandler(VGA_PAGE_B0,8,range_handler);
|
||||
MEM_ResetPageHandler(VGA_PAGE_A0,16);
|
||||
MEM_ResetPageHandler(VGA_PAGE_B8,8);
|
||||
vgapages.base = VGA_PAGE_B0;
|
||||
vgapages.mask = 0x7fff;
|
||||
MEM_SetPageHandler( VGA_PAGE_B0, 8, newHandler );
|
||||
MEM_ResetPageHandler( VGA_PAGE_A0, 16 );
|
||||
MEM_ResetPageHandler( VGA_PAGE_B8, 8 );
|
||||
break;
|
||||
case 3:
|
||||
range_b800:
|
||||
vgapages.base=VGA_PAGE_B8;
|
||||
vgapages.mask=0x7fff;
|
||||
MEM_SetPageHandler(VGA_PAGE_B8,8,range_handler);
|
||||
MEM_ResetPageHandler(VGA_PAGE_A0,16);
|
||||
MEM_ResetPageHandler(VGA_PAGE_B0,8);
|
||||
vgapages.base = VGA_PAGE_B8;
|
||||
vgapages.mask = 0x7fff;
|
||||
MEM_SetPageHandler( VGA_PAGE_B8, 8, newHandler );
|
||||
MEM_ResetPageHandler( VGA_PAGE_A0, 16 );
|
||||
MEM_ResetPageHandler( VGA_PAGE_B0, 8 );
|
||||
break;
|
||||
}
|
||||
|
||||
if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) /*&& (vga.mode == M_LIN8)*/)
|
||||
MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio);
|
||||
|
||||
range_done:
|
||||
PAGING_ClearTLB();
|
||||
}
|
||||
|
||||
void VGA_StartUpdateLFB(void) {
|
||||
vga.lfb.page = vga.s3.la_window << 4;
|
||||
vga.lfb.addr = vga.s3.la_window << 16;
|
||||
switch (vga.mode) {
|
||||
case M_LIN4:
|
||||
vga.lfb.handler = &vgaph.l4linear;
|
||||
break;
|
||||
default:
|
||||
vga.lfb.handler = &vgaph.lfbchanges;
|
||||
break;
|
||||
}
|
||||
#ifdef VGA_LFB_MAPPED
|
||||
vga.lfb.handler = &vgaph.lfb;
|
||||
#else
|
||||
vga.lfb.handler = &vgaph.lfbchanges;
|
||||
#endif
|
||||
MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096, vga.lfb.handler );
|
||||
}
|
||||
|
||||
|
@ -732,11 +905,14 @@ void VGA_UnmapMMIO(void) {
|
|||
|
||||
|
||||
void VGA_SetupMemory() {
|
||||
memset((void *)&vga.mem,0,512*1024*4);
|
||||
memset( &vga.mem, 0, VGA_MEMORY );
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
memset( &vga.changes, 0, sizeof( vga.changes ));
|
||||
#endif
|
||||
vga.s3.svga_bank.fullbank=0;
|
||||
if (machine==MCH_PCJR) {
|
||||
/* PCJr does not have dedicated graphics memory but uses
|
||||
conventional memory below 128k */
|
||||
vga.gfxmem_start=GetMemBase();
|
||||
} else vga.gfxmem_start=&vga.mem.linear[0];
|
||||
//TODO map?
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "inout.h"
|
||||
#include "pic.h"
|
||||
#include "vga.h"
|
||||
#include <math.h>
|
||||
|
||||
static Bit8u flip=0;
|
||||
|
||||
|
@ -31,24 +32,45 @@ Bitu vga_read_p3d5(Bitu port,Bitu iolen);
|
|||
static Bitu vga_read_p3da(Bitu port,Bitu iolen) {
|
||||
vga.internal.attrindex=false;
|
||||
vga.tandy.pcjr_flipflop=false;
|
||||
if (vga.config.retrace) {
|
||||
switch (machine) {
|
||||
case MCH_HERC:
|
||||
return 0x81;
|
||||
default:
|
||||
return 9;
|
||||
}
|
||||
}
|
||||
flip++;
|
||||
if (flip>20) flip=0;
|
||||
if (flip>10) return 1;
|
||||
return 0;
|
||||
/*
|
||||
0 Either Vertical or Horizontal Retrace active if set
|
||||
3 Vertical Retrace in progress if set
|
||||
*/
|
||||
}
|
||||
Bit8u retval=0;
|
||||
double timeInFrame = PIC_FullIndex()-vga.draw.delay.framestart;
|
||||
|
||||
vga.internal.attrindex=false;
|
||||
vga.tandy.pcjr_flipflop=false;
|
||||
|
||||
double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal);
|
||||
|
||||
switch (machine) {
|
||||
case MCH_HERC:
|
||||
// 3BAh (R): Status Register
|
||||
// bit 0 Horizontal sync
|
||||
// 3 Video signal
|
||||
// 7 Vertical sync
|
||||
if(timeInFrame >= vga.draw.delay.vrstart &&
|
||||
timeInFrame <= vga.draw.delay.vrend)
|
||||
retval |= 0x80;
|
||||
if(timeInLine >= vga.draw.delay.hrstart &&
|
||||
timeInLine <= vga.draw.delay.hrend)
|
||||
retval |= 1;
|
||||
retval |= 0x10; //Hercules ident
|
||||
break;
|
||||
default:
|
||||
// 3DAh (R): Status Register
|
||||
// bit 0 Horizontal or Vertical blanking
|
||||
// 3 Vertical sync
|
||||
|
||||
if(timeInFrame >= vga.draw.delay.vrstart &&
|
||||
timeInFrame <= vga.draw.delay.vrend)
|
||||
retval |= 8;
|
||||
if(timeInFrame >= vga.draw.delay.vblkstart &&
|
||||
timeInFrame <= vga.draw.delay.vblkend)
|
||||
retval |= 1;
|
||||
else if(timeInLine >= vga.draw.delay.hblkstart &&
|
||||
timeInLine <= vga.draw.delay.hblkend)
|
||||
retval |= 1;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void write_p3c2(Bitu port,Bitu val,Bitu iolen) {
|
||||
vga.misc_output=val;
|
||||
|
|
|
@ -16,13 +16,14 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_other.cpp,v 1.19 2007-01-08 19:45:40 qbix79 Exp $ */
|
||||
/* $Id: vga_other.cpp,v 1.20 2007-01-24 16:29:09 harekiet Exp $ */
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
#include "vga.h"
|
||||
#include "mem.h"
|
||||
#include "render.h"
|
||||
#include "mapper.h"
|
||||
|
||||
|
@ -47,8 +48,8 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) {
|
|||
case 0x02: //Horizontal sync position
|
||||
vga.other.hsyncp=val;
|
||||
break;
|
||||
case 0x03: //Horizontal sync width
|
||||
vga.other.hsyncw=val;
|
||||
case 0x03: //Horizontal and vertical sync width
|
||||
vga.other.syncw=val;
|
||||
break;
|
||||
case 0x04: //Vertical total
|
||||
if (vga.other.vtotal ^ val) VGA_StartResize();
|
||||
|
@ -70,10 +71,12 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) {
|
|||
vga.other.max_scanline=val;
|
||||
break;
|
||||
case 0x0A: /* Cursor Start Register */
|
||||
vga.other.cursor_start = val & 0x3f;
|
||||
vga.draw.cursor.sline = val&0x1f;
|
||||
vga.draw.cursor.enabled = ((val & 0x60) != 0x20);
|
||||
break;
|
||||
case 0x0B: /* Cursor End Register */
|
||||
vga.other.cursor_end = val&0x1f;
|
||||
vga.draw.cursor.eline = val&0x1f;
|
||||
break;
|
||||
case 0x0C: /* Start Address High Register */
|
||||
|
@ -90,6 +93,12 @@ static void write_crtc_data_other(Bitu port,Bitu val,Bitu iolen) {
|
|||
vga.config.cursor_start&=0xff00;
|
||||
vga.config.cursor_start|=val;
|
||||
break;
|
||||
case 0x10: /* Light Pen High */
|
||||
vga.other.lpen_high = val & 0x1f; //only 6 bits
|
||||
break;
|
||||
case 0x11: /* Light Pen Low */
|
||||
vga.other.lpen_low = val;
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Write %X to illegal index %x",val,vga.other.index);
|
||||
}
|
||||
|
@ -102,8 +111,8 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) {
|
|||
return vga.other.hdend;
|
||||
case 0x02: //Horizontal sync position
|
||||
return vga.other.hsyncp;
|
||||
case 0x03: //Horizontal sync width
|
||||
return vga.other.hsyncw;
|
||||
case 0x03: //Horizontal and vertical sync width
|
||||
return vga.other.syncw;
|
||||
case 0x04: //Vertical total
|
||||
return vga.other.vtotal;
|
||||
case 0x05: //Vertical display adjust
|
||||
|
@ -114,6 +123,10 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) {
|
|||
return vga.other.vsyncp;
|
||||
case 0x09: //Max scanline
|
||||
return vga.other.max_scanline;
|
||||
case 0x0A: /* Cursor Start Register */
|
||||
return vga.other.cursor_start;
|
||||
case 0x0B: /* Cursor End Register */
|
||||
return vga.other.cursor_end;
|
||||
case 0x0C: /* Start Address High Register */
|
||||
return vga.config.display_start >> 8;
|
||||
case 0x0D: /* Start Address Low Register */
|
||||
|
@ -122,10 +135,14 @@ static Bitu read_crtc_data_other(Bitu port,Bitu iolen) {
|
|||
return vga.config.cursor_start>>8;
|
||||
case 0x0F: /* Cursor Location Low Register */
|
||||
return vga.config.cursor_start;
|
||||
case 0x10: /* Light Pen High */
|
||||
return vga.other.lpen_high;
|
||||
case 0x11: /* Light Pen Low */
|
||||
return vga.other.lpen_low;
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("MC6845:Read from illegal index %x",vga.other.index);
|
||||
}
|
||||
return (Bitu)-1;
|
||||
return ~0;
|
||||
}
|
||||
|
||||
static double hue_offset = 0.0;
|
||||
|
@ -241,25 +258,16 @@ static void write_color_select(Bit8u val) {
|
|||
}
|
||||
}
|
||||
|
||||
static void write_mode_control(Bit8u val) {
|
||||
/* Check if someone changes the blinking/hi intensity bit */
|
||||
vga.tandy.mode_control=val;
|
||||
VGA_SetBlinking((val & 0x20));
|
||||
if (val & 0x2) {
|
||||
if (val & 0x10) {
|
||||
} else VGA_SetMode(M_CGA4);
|
||||
write_color_select(vga.tandy.color_select); //Setup the correct palette
|
||||
} else {
|
||||
VGA_SetMode(M_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
static void TANDY_FindMode(void) {
|
||||
if (vga.tandy.mode_control & 0x2) {
|
||||
if (vga.tandy.gfx_control & 0x10) VGA_SetMode(M_TANDY16);
|
||||
else if (vga.tandy.gfx_control & 0x08) VGA_SetMode(M_TANDY4);
|
||||
else if (vga.tandy.mode_control & 0x10) VGA_SetMode(M_TANDY2);
|
||||
else VGA_SetMode(M_TANDY4);
|
||||
if (vga.tandy.gfx_control & 0x10)
|
||||
VGA_SetMode(M_TANDY16);
|
||||
else if (vga.tandy.gfx_control & 0x08)
|
||||
VGA_SetMode(M_TANDY4);
|
||||
else if (vga.tandy.mode_control & 0x10)
|
||||
VGA_SetMode(M_TANDY2);
|
||||
else
|
||||
VGA_SetMode(M_TANDY4);
|
||||
write_color_select(vga.tandy.color_select);
|
||||
} else {
|
||||
VGA_SetMode(M_TANDY_TEXT);
|
||||
|
@ -284,6 +292,21 @@ static void PCJr_FindMode(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void TandyCheckLineMask(void ) {
|
||||
if ( vga.tandy.extended_ram & 1 ) {
|
||||
vga.tandy.line_mask = 0;
|
||||
} else if ( vga.tandy.mode_control & 0x2) {
|
||||
vga.tandy.line_mask |= 1;
|
||||
}
|
||||
if ( vga.tandy.line_mask ) {
|
||||
vga.tandy.line_shift = 13;
|
||||
vga.tandy.addr_mask = (1 << 13) - 1;
|
||||
} else {
|
||||
vga.tandy.addr_mask = ~0;
|
||||
vga.tandy.line_shift = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void write_tandy_reg(Bit8u val) {
|
||||
switch (vga.tandy.reg_index) {
|
||||
case 0x0:
|
||||
|
@ -291,7 +314,10 @@ static void write_tandy_reg(Bit8u val) {
|
|||
vga.tandy.mode_control=val;
|
||||
VGA_SetBlinking(val & 0x20);
|
||||
PCJr_FindMode();
|
||||
} else LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
|
||||
} else {
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index);
|
||||
}
|
||||
break;
|
||||
case 0x2: /* Border color */
|
||||
vga.tandy.border_color=val;
|
||||
break;
|
||||
|
@ -300,6 +326,19 @@ static void write_tandy_reg(Bit8u val) {
|
|||
if (machine==MCH_TANDY) TANDY_FindMode();
|
||||
else PCJr_FindMode();
|
||||
break;
|
||||
case 0x5: /* Extended ram page register */
|
||||
// Bit 0 enables extended ram
|
||||
// Bit 7 Switches clock, 0 -> cga 28.6 , 1 -> mono 32.5
|
||||
vga.tandy.extended_ram = val;
|
||||
//This is a bit of a hack to enable mapping video memory differently for highres mode
|
||||
TandyCheckLineMask();
|
||||
VGA_SetupHandlers();
|
||||
break;
|
||||
case 0x8: /* Monitor mode seletion */
|
||||
//Bit 1 select mode e, for 640x200x16, some double clocking thing?
|
||||
//Bit 4 select 350 line mode for hercules emulation
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to tandy monitor mode",val );
|
||||
break;
|
||||
/* palette colors */
|
||||
case 0x10: case 0x11: case 0x12: case 0x13:
|
||||
case 0x14: case 0x15: case 0x16: case 0x17:
|
||||
|
@ -340,6 +379,7 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) {
|
|||
switch (port) {
|
||||
case 0x3d8:
|
||||
vga.tandy.mode_control=val;
|
||||
TandyCheckLineMask();
|
||||
VGA_SetBlinking(val & 0x20);
|
||||
TANDY_FindMode();
|
||||
break;
|
||||
|
@ -349,13 +389,20 @@ static void write_tandy(Bitu port,Bitu val,Bitu iolen) {
|
|||
case 0x3da:
|
||||
vga.tandy.reg_index=val;
|
||||
break;
|
||||
// case 0x3db: //Clear lightpen latch
|
||||
break;
|
||||
// case 0x3dc: //Preset lightpen latch
|
||||
break;
|
||||
// case 0x3dd: //Extended ram page address register:
|
||||
break;
|
||||
case 0x3de:
|
||||
write_tandy_reg(val);
|
||||
break;
|
||||
case 0x3df:
|
||||
vga.tandy.is_32k_mode=(val & 0x80)==0x80;
|
||||
vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7);
|
||||
vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7);
|
||||
vga.tandy.line_mask = val >> 6;
|
||||
vga.tandy.draw_bank = val & 0x7;
|
||||
vga.tandy.mem_bank = (val >> 3) & 0x7;
|
||||
TandyCheckLineMask();
|
||||
VGA_SetupHandlers();
|
||||
break;
|
||||
}
|
||||
|
@ -372,9 +419,12 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) {
|
|||
vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop;
|
||||
break;
|
||||
case 0x3df:
|
||||
vga.tandy.is_32k_mode=(val & 0x80)==0x80;
|
||||
vga.tandy.disp_bank=val & (vga.tandy.is_32k_mode ? 0x6 : 0x7);
|
||||
vga.tandy.mem_bank=(val >> 3) & 0x7;
|
||||
vga.tandy.line_mask = val >> 6;
|
||||
vga.tandy.draw_bank = val & 0x7;
|
||||
vga.tandy.mem_bank = (val >> 3) & 0x7;
|
||||
vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024];
|
||||
vga.tandy.mem_base = &MemBase[vga.tandy.mem_bank * 16 * 1024];
|
||||
TandyCheckLineMask();
|
||||
VGA_SetupHandlers();
|
||||
break;
|
||||
}
|
||||
|
@ -383,7 +433,7 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) {
|
|||
static void write_hercules(Bitu port,Bitu val,Bitu iolen) {
|
||||
switch (port) {
|
||||
case 0x3b8:
|
||||
if (vga.herc.enable_bits & 1) {
|
||||
if (vga.herc.enable_bits & 1 ) {
|
||||
vga.herc.mode_control&=~0x2;
|
||||
vga.herc.mode_control|=(val&0x2);
|
||||
if (val & 0x2) {
|
||||
|
@ -394,11 +444,14 @@ static void write_hercules(Bitu port,Bitu val,Bitu iolen) {
|
|||
}
|
||||
if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) {
|
||||
vga.herc.mode_control^=0x80;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
vga.tandy.draw_base = &vga.mem.linear[(vga.herc.mode_control & 0x80 ) ? 32*1024 : 0];
|
||||
break;
|
||||
case 0x3bf:
|
||||
vga.herc.enable_bits=val;
|
||||
if ( vga.herc.enable_bits ^ val) {
|
||||
vga.herc.enable_bits=val;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -411,6 +464,14 @@ static Bitu read_hercules(Bitu port,Bitu iolen) {
|
|||
|
||||
void VGA_SetupOther(void) {
|
||||
Bitu i;
|
||||
memset( &vga.tandy, 0, sizeof( vga.tandy ));
|
||||
//Initialize values common for most machines, can be overwritten
|
||||
vga.tandy.draw_base = vga.mem.linear;
|
||||
vga.tandy.mem_base = vga.mem.linear;
|
||||
vga.tandy.addr_mask = 8*1024 - 1;
|
||||
vga.tandy.line_mask = 3;
|
||||
vga.tandy.line_shift = 13;
|
||||
|
||||
if (machine==MCH_CGA || IS_TANDY_ARCH) {
|
||||
extern Bit8u int10_font_08[256 * 8];
|
||||
for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8);
|
||||
|
@ -434,7 +495,7 @@ void VGA_SetupOther(void) {
|
|||
IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB);
|
||||
}
|
||||
if (machine==MCH_TANDY) {
|
||||
vga.tandy.is_32k_mode=false;
|
||||
write_tandy( 0x3df, 0x0, 0 );
|
||||
IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB);
|
||||
IO_RegisterWriteHandler(0x3d9,write_tandy,IO_MB);
|
||||
IO_RegisterWriteHandler(0x3de,write_tandy,IO_MB);
|
||||
|
@ -442,8 +503,8 @@ void VGA_SetupOther(void) {
|
|||
IO_RegisterWriteHandler(0x3da,write_tandy,IO_MB);
|
||||
}
|
||||
if (machine==MCH_PCJR) {
|
||||
vga.tandy.mem_bank=7;vga.tandy.disp_bank=7;
|
||||
vga.tandy.is_32k_mode=false;vga.tandy.pcjr_flipflop=false;
|
||||
//write_pcjr will setup base address
|
||||
write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 );
|
||||
IO_RegisterWriteHandler(0x3d9,write_pcjr,IO_MB);
|
||||
IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB);
|
||||
IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB);
|
||||
|
|
|
@ -195,6 +195,8 @@ static Bitu INT10_Handler(void) {
|
|||
}
|
||||
break;
|
||||
case 0x11: /* Character generator functions */
|
||||
if (machine<MCH_VGA)
|
||||
break;
|
||||
switch (reg_al) {
|
||||
/* Textmode calls */
|
||||
case 0x00: /* Load user font */
|
||||
|
@ -289,7 +291,8 @@ graphics_chars:
|
|||
}
|
||||
break;
|
||||
case 0x12: /* alternate function select */
|
||||
if (machine<MCH_VGA) break;
|
||||
if (machine<MCH_VGA)
|
||||
break;
|
||||
switch (reg_bl) {
|
||||
case 0x10: /* Get EGA Information */
|
||||
reg_bh=(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS)==0x3B4);
|
||||
|
|
|
@ -238,7 +238,7 @@ static void FinishSetMode(bool clearmem) {
|
|||
case M_CGA2:
|
||||
case M_TANDY16:
|
||||
for (i=0;i<16*1024;i++) {
|
||||
real_writew(0xb800,i*2,0x0000);
|
||||
real_writew( 0xb800,i*2,0x0000);
|
||||
}
|
||||
break;
|
||||
case M_TEXT:
|
||||
|
@ -307,7 +307,12 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
|
|||
}
|
||||
break;
|
||||
case MCH_HERC:
|
||||
if (mode!=7) return false;
|
||||
if (mode!=7) {
|
||||
//Just the text memory, most games seem to use any random mode to clear the screen
|
||||
for (i=0;i<16*1024;i++)
|
||||
real_writew(0xb000,i*2,0x0120);
|
||||
return false;
|
||||
}
|
||||
CurMode=&Hercules_Mode;
|
||||
break;
|
||||
}
|
||||
|
@ -373,8 +378,10 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
|
|||
case MCH_HERC:
|
||||
IO_WriteB(0x3bf,0x3); //Enable changing all bits
|
||||
IO_WriteB(0x3b8,0x8); //TEXT mode and non-blinking characters
|
||||
IO_WriteB(0x3bf,0x0); //Disable changing all bits
|
||||
VGA_DAC_CombineColor(1,0xf);
|
||||
IO_WriteB(0x3bf,0x0);
|
||||
VGA_DAC_CombineColor(0,0);
|
||||
for ( i = 1; i < 15;i++)
|
||||
VGA_DAC_CombineColor(i,0xf);
|
||||
break;
|
||||
case MCH_CGA:
|
||||
mode_control=mode_control_list[CurMode->mode];
|
||||
|
@ -400,6 +407,12 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
|
|||
default:
|
||||
IO_WriteB(0x3de,0x0);break;
|
||||
}
|
||||
//Clear extended mapping
|
||||
IO_WriteB(0x3da,0x5);
|
||||
IO_WriteB(0x3de,0x0);
|
||||
//Clear monitor mode
|
||||
IO_WriteB(0x3da,0x8);
|
||||
IO_WriteB(0x3de,0x0);
|
||||
crtpage=(CurMode->mode>=0x9) ? 0xf6 : 0x3f;
|
||||
IO_WriteB(0x3df,crtpage);
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CRTCPU_PAGE,crtpage);
|
||||
|
@ -974,7 +987,6 @@ dac_text16:
|
|||
}
|
||||
IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,reg_31); //Enable banked memory and 256k+ access
|
||||
IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing
|
||||
IO_Write(crtc_base,0x58);IO_Write(crtc_base+1,0x3); //Enable 8 mb of linear addressing
|
||||
|
||||
IO_Write(crtc_base,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1
|
||||
IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue