additional svga chipset emulation (tseng, paradise) and small fixes for s3, vasyl
Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3075
This commit is contained in:
parent
2c95419294
commit
e0d88e1d11
17 changed files with 1512 additions and 226 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dosbox.h,v 1.31 2008-01-09 20:34:21 c2woody Exp $ */
|
||||
|
||||
#ifndef DOSBOX_DOSBOX_H
|
||||
#define DOSBOX_DOSBOX_H
|
||||
|
||||
|
@ -51,7 +53,9 @@ enum MachineType {
|
|||
enum SVGACards {
|
||||
SVGA_None,
|
||||
SVGA_S3Trio,
|
||||
SVGA_TsengET4K
|
||||
SVGA_TsengET4K,
|
||||
SVGA_TsengET3K,
|
||||
SVGA_ParadisePVGA1A
|
||||
};
|
||||
|
||||
extern SVGACards svgaCard;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga.h,v 1.37 2008-01-09 20:34:21 c2woody Exp $ */
|
||||
|
||||
#ifndef DOSBOX_VGA_H
|
||||
#define DOSBOX_VGA_H
|
||||
|
||||
|
@ -157,23 +159,7 @@ typedef struct {
|
|||
Bit8u mc[64][64];
|
||||
} VGA_HWCURSOR;
|
||||
|
||||
typedef union {
|
||||
Bit32u fullbank;
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
struct {
|
||||
Bit16u lowerbank;
|
||||
Bit16u bank;
|
||||
} b;
|
||||
#else
|
||||
struct {
|
||||
Bit16u bank;
|
||||
Bit16u lowerbank;
|
||||
} b;
|
||||
#endif
|
||||
} VGA_S3_BANK;
|
||||
|
||||
typedef struct {
|
||||
VGA_S3_BANK svga_bank;
|
||||
Bit8u reg_lock1;
|
||||
Bit8u reg_lock2;
|
||||
Bit8u reg_31;
|
||||
|
@ -330,6 +316,11 @@ typedef struct {
|
|||
typedef struct {
|
||||
Bitu readStart, writeStart;
|
||||
Bitu bankMask;
|
||||
Bitu bank_read_full;
|
||||
Bitu bank_write_full;
|
||||
Bit8u bank_read;
|
||||
Bit8u bank_write;
|
||||
Bitu bank_size;
|
||||
} VGA_SVGA;
|
||||
|
||||
typedef union {
|
||||
|
@ -423,15 +414,64 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3);
|
|||
void VGA_ActivateHardwareCursor(void);
|
||||
void VGA_KillDrawing(void);
|
||||
|
||||
/* S3 Functions */
|
||||
Bitu SVGA_S3_GetClock(void);
|
||||
void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen);
|
||||
Bitu SVGA_S3_ReadCRTC(Bitu reg,Bitu iolen);
|
||||
void SVGA_S3_WriteSEQ(Bitu reg,Bitu val,Bitu iolen);
|
||||
Bitu SVGA_S3_ReadSEQ(Bitu reg,Bitu iolen);
|
||||
|
||||
extern VGA_Type vga;
|
||||
|
||||
/* Support for modular SVGA implementation */
|
||||
/* Video mode extra data to be passed to FinishSetMode_SVGA().
|
||||
This structure will be in flux until all drivers (including S3)
|
||||
are properly separated. Right now it contains only three overflow
|
||||
fields in S3 format and relies on drivers re-interpreting those.
|
||||
For reference:
|
||||
ver_overflow:X|line_comp10|X|vretrace10|X|vbstart10|vdispend10|vtotal10
|
||||
hor_overflow:X|X|X|hretrace8|X|hblank8|hdispend8|htotal8
|
||||
offset is not currently used by drivers (useful only for S3 itself)
|
||||
It also contains basic int10 mode data - number, vtotal, htotal
|
||||
*/
|
||||
typedef struct {
|
||||
Bit8u ver_overflow;
|
||||
Bit8u hor_overflow;
|
||||
Bitu offset;
|
||||
Bitu modeNo;
|
||||
Bitu htotal;
|
||||
Bitu vtotal;
|
||||
} VGA_ModeExtraData;
|
||||
|
||||
// Vector function prototypes
|
||||
typedef void (*tWritePort)(Bitu reg,Bitu val,Bitu iolen);
|
||||
typedef Bitu (*tReadPort)(Bitu reg,Bitu iolen);
|
||||
typedef void (*tFinishSetMode)(Bitu crtc_base, VGA_ModeExtraData* modeData);
|
||||
typedef void (*tDetermineMode)();
|
||||
typedef void (*tSetClock)(Bitu which,Bitu target);
|
||||
typedef Bitu (*tGetClock)();
|
||||
typedef bool (*tHWCursorActive)();
|
||||
typedef bool (*tAcceptsMode)(Bitu modeNo);
|
||||
|
||||
struct SVGA_Driver {
|
||||
tWritePort write_p3d5;
|
||||
tReadPort read_p3d5;
|
||||
tWritePort write_p3c5;
|
||||
tReadPort read_p3c5;
|
||||
tWritePort write_p3c0;
|
||||
tReadPort read_p3c1;
|
||||
tWritePort write_p3cf;
|
||||
tReadPort read_p3cf;
|
||||
|
||||
tFinishSetMode set_video_mode;
|
||||
tDetermineMode determine_mode;
|
||||
tSetClock set_clock;
|
||||
tGetClock get_clock;
|
||||
tHWCursorActive hardware_cursor_active;
|
||||
tAcceptsMode accepts_mode;
|
||||
};
|
||||
|
||||
extern SVGA_Driver svga;
|
||||
|
||||
void SVGA_Setup_S3Trio(void);
|
||||
void SVGA_Setup_TsengET4K(void);
|
||||
void SVGA_Setup_TsengET3K(void);
|
||||
void SVGA_Setup_ParadisePVGA1A(void);
|
||||
void SVGA_Setup_Driver(void);
|
||||
|
||||
extern Bit32u ExpandTable[256];
|
||||
extern Bit32u FillTable[16];
|
||||
extern Bit32u CGA_2_Table[16];
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: dosbox.cpp,v 1.124 2007-12-13 12:38:13 qbix79 Exp $ */
|
||||
/* $Id: dosbox.cpp,v 1.125 2008-01-09 20:34:21 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
@ -269,13 +269,22 @@ static void DOSBOX_RealInit(Section * sec) {
|
|||
(strcasecmp(mtype,"svga")==0) || (strcasecmp(mtype,"svga_s3")==0)) {
|
||||
machine=MCH_VGA;
|
||||
svgaCard=SVGA_S3Trio;
|
||||
/* } else if ((strcasecmp(mtype,"vga_et4000")==0) || (strcasecmp(mtype,"svga_et4000")==0)) {
|
||||
} else if ((strcasecmp(mtype,"vga_et4000")==0) || (strcasecmp(mtype,"svga_et4000")==0)) {
|
||||
machine=MCH_VGA;
|
||||
svgaCard=SVGA_TsengET4K; */
|
||||
svgaCard=SVGA_TsengET4K;
|
||||
} else if ((strcasecmp(mtype,"vga_et3000")==0) || (strcasecmp(mtype,"svga_et3000")==0)) {
|
||||
machine=MCH_VGA;
|
||||
svgaCard=SVGA_TsengET3K;
|
||||
} else if ((strcasecmp(mtype,"vga_pvga1a")==0) || (strcasecmp(mtype,"svga_pvga1a")==0) ||
|
||||
(strcasecmp(mtype,"svga_paradise")==0)) {
|
||||
machine=MCH_VGA;
|
||||
svgaCard=SVGA_ParadisePVGA1A;
|
||||
} else if (strcasecmp(mtype,"vgaonly")==0) {
|
||||
machine=MCH_VGA;
|
||||
svgaCard=SVGA_None;
|
||||
} else LOG_MSG("DOSBOX:Unknown machine type %s",mtype);
|
||||
} else {
|
||||
LOG_MSG("DOSBOX:Unknown machine type %s",mtype);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ noinst_LIBRARIES = libhardware.a
|
|||
libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \
|
||||
memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \
|
||||
vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \
|
||||
vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp \
|
||||
vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \
|
||||
cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga.cpp,v 1.31 2007-12-10 22:11:13 c2woody Exp $ */
|
||||
/* $Id: vga.cpp,v 1.32 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
//#include "setup.h"
|
||||
|
@ -24,7 +24,10 @@
|
|||
#include "pic.h"
|
||||
#include "vga.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
VGA_Type vga;
|
||||
SVGA_Driver svga;
|
||||
|
||||
Bit32u CGA_2_Table[16];
|
||||
Bit32u CGA_4_Table[256];
|
||||
|
@ -48,6 +51,10 @@ void VGA_SetMode(VGAModes mode) {
|
|||
}
|
||||
|
||||
void VGA_DetermineMode(void) {
|
||||
if (svga.determine_mode) {
|
||||
svga.determine_mode();
|
||||
return;
|
||||
}
|
||||
/* Test for VGA output active or direct color modes */
|
||||
switch (vga.s3.misc_control_2 >> 4) {
|
||||
case 0:
|
||||
|
@ -84,6 +91,10 @@ void VGA_StartResize(void) {
|
|||
}
|
||||
|
||||
void VGA_SetClock(Bitu which,Bitu target) {
|
||||
if (svga.set_clock) {
|
||||
svga.set_clock(which, target);
|
||||
return;
|
||||
}
|
||||
struct{
|
||||
Bitu n,m;
|
||||
Bits err;
|
||||
|
@ -158,6 +169,7 @@ void VGA_Init(Section* sec) {
|
|||
vga.screenflip = 0;
|
||||
vga.draw.resizing=false;
|
||||
vga.mode=M_ERROR; //For first init
|
||||
SVGA_Setup_Driver();
|
||||
VGA_SetupMemory();
|
||||
VGA_SetupMisc();
|
||||
VGA_SetupDAC();
|
||||
|
@ -220,3 +232,22 @@ void VGA_Init(Section* sec) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SVGA_Setup_Driver(void) {
|
||||
memset(&svga, 0, sizeof(SVGA_Driver));
|
||||
|
||||
switch(svgaCard) {
|
||||
case SVGA_S3Trio:
|
||||
SVGA_Setup_S3Trio();
|
||||
break;
|
||||
case SVGA_TsengET4K:
|
||||
SVGA_Setup_TsengET4K();
|
||||
break;
|
||||
case SVGA_TsengET3K:
|
||||
SVGA_Setup_TsengET3K();
|
||||
break;
|
||||
case SVGA_ParadisePVGA1A:
|
||||
SVGA_Setup_ParadisePVGA1A();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_attr.cpp,v 1.27 2007-12-23 16:00:53 c2woody Exp $ */
|
||||
/* $Id: vga_attr.cpp,v 1.28 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
|
@ -177,6 +177,10 @@ void write_p3c0(Bitu port,Bitu val,Bitu iolen) {
|
|||
*/
|
||||
break;
|
||||
default:
|
||||
if (svga.write_p3c0) {
|
||||
svga.write_p3c0(attr(index), val, iolen);
|
||||
break;
|
||||
}
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Write to unkown Index %2X",attr(index));
|
||||
break;
|
||||
}
|
||||
|
@ -203,6 +207,8 @@ Bitu read_p3c1(Bitu port,Bitu iolen) {
|
|||
case 0x14: /* Color Select Register */
|
||||
return attr(color_select);
|
||||
default:
|
||||
if (svga.read_p3c1)
|
||||
return svga.read_p3c1(attr(index), iolen);
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:Read from unkown Index %2X",attr(index));
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_crtc.cpp,v 1.30 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
|
@ -330,12 +332,10 @@ void vga_write_p3d5(Bitu port,Bitu val,Bitu iolen) {
|
|||
*/
|
||||
break;
|
||||
default:
|
||||
switch (svgaCard) {
|
||||
case SVGA_S3Trio:
|
||||
SVGA_S3_WriteCRTC( crtc(index), val, iolen);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
if (svga.write_p3d5) {
|
||||
svga.write_p3d5(crtc(index), val, iolen);
|
||||
} else {
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Write to unknown index %X",crtc(index));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -395,10 +395,9 @@ Bitu vga_read_p3d5(Bitu port,Bitu iolen) {
|
|||
case 0x18: /* Line Compare Register */
|
||||
return crtc(line_compare);
|
||||
default:
|
||||
switch (svgaCard) {
|
||||
case SVGA_S3Trio:
|
||||
return SVGA_S3_ReadCRTC( crtc(index), iolen );
|
||||
default:
|
||||
if (svga.read_p3d5) {
|
||||
return svga.read_p3d5(crtc(index), iolen);
|
||||
} else {
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:Read from unknown index %X",crtc(index));
|
||||
return 0x0;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_draw.cpp,v 1.90 2007-12-19 21:12:22 c2woody Exp $ */
|
||||
/* $Id: vga_draw.cpp,v 1.91 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
@ -206,7 +206,11 @@ static Bit8u * VGA_Draw_Chain_Line(Bitu vidstart, Bitu line) {
|
|||
}
|
||||
|
||||
static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) {
|
||||
if(vga.s3.hgc.curmode & 0x1) {
|
||||
bool hwcursor_active=false;
|
||||
if (svga.hardware_cursor_active) {
|
||||
if (svga.hardware_cursor_active()) hwcursor_active=true;
|
||||
}
|
||||
if (hwcursor_active) {
|
||||
Bitu lineat = (vidstart-(vga.config.real_start<<2)) / vga.draw.width;
|
||||
if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
|
@ -266,7 +270,11 @@ static Bit8u * VGA_Draw_VGA_Line_HWMouse( Bitu vidstart, Bitu line) {
|
|||
}
|
||||
|
||||
static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) {
|
||||
if(vga.s3.hgc.curmode & 0x1) {
|
||||
bool hwcursor_active=false;
|
||||
if (svga.hardware_cursor_active) {
|
||||
if (svga.hardware_cursor_active()) hwcursor_active=true;
|
||||
}
|
||||
if (hwcursor_active) {
|
||||
Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 1) / vga.draw.width;
|
||||
if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
|
@ -329,7 +337,11 @@ static Bit8u * VGA_Draw_LIN16_Line_HWMouse(Bitu vidstart, Bitu line) {
|
|||
}
|
||||
|
||||
static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu line) {
|
||||
if(vga.s3.hgc.curmode & 0x1) {
|
||||
bool hwcursor_active=false;
|
||||
if (svga.hardware_cursor_active) {
|
||||
if (svga.hardware_cursor_active()) hwcursor_active=true;
|
||||
}
|
||||
if (hwcursor_active) {
|
||||
Bitu lineat = ((vidstart-(vga.config.real_start<<2)) >> 2) / vga.draw.width;
|
||||
if((lineat < vga.s3.hgc.originy) || (lineat > (vga.s3.hgc.originy + 63U))) {
|
||||
return &vga.mem.linear[ vidstart ];
|
||||
|
@ -881,7 +893,11 @@ void VGA_CheckScanLength(void) {
|
|||
}
|
||||
|
||||
void VGA_ActivateHardwareCursor(void) {
|
||||
if(vga.s3.hgc.curmode & 0x1) {
|
||||
bool hwcursor_active=false;
|
||||
if (svga.hardware_cursor_active) {
|
||||
if (svga.hardware_cursor_active()) hwcursor_active=true;
|
||||
}
|
||||
if (hwcursor_active) {
|
||||
switch(vga.mode) {
|
||||
case M_LIN32:
|
||||
VGA_DrawLine=VGA_Draw_LIN32_Line_HWMouse;
|
||||
|
@ -963,11 +979,9 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
if ( !vbend) vbend = vbstart + 0x3f + 1;
|
||||
else vbend = vbstart + vbend;
|
||||
|
||||
switch (svgaCard) {
|
||||
case SVGA_S3Trio:
|
||||
clock = SVGA_S3_GetClock();
|
||||
break;
|
||||
default:
|
||||
if (svga.get_clock) {
|
||||
clock = svga.get_clock();
|
||||
} else {
|
||||
switch ((vga.misc_output >> 2) & 3) {
|
||||
case 0:
|
||||
clock = 25175000;
|
||||
|
@ -976,7 +990,6 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
clock = 28322000;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Check for 8 for 9 character clock mode */
|
||||
|
@ -986,8 +999,6 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
htotal*=2;
|
||||
}
|
||||
vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0xf)+1;
|
||||
/* Check for dual transfer whatever thing,master clock/2 */
|
||||
if (vga.s3.pll.cmd & 0x10) clock/=2;
|
||||
|
||||
if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0;
|
||||
else vga.draw.double_scan=(vtotal==262);
|
||||
|
@ -1150,7 +1161,7 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
case M_LIN8:
|
||||
if (vga.crtc.mode_control & 0x8)
|
||||
width >>=1;
|
||||
else if(!(vga.s3.reg_3a&0x10)) {
|
||||
else if(svgaCard == SVGA_S3Trio && !(vga.s3.reg_3a&0x10)) {
|
||||
doublewidth=true;
|
||||
width >>=1;
|
||||
}
|
||||
|
@ -1166,7 +1177,7 @@ void VGA_SetupDrawing(Bitu val) {
|
|||
case M_LIN16:
|
||||
// 15/16 bpp modes double the horizontal values
|
||||
width<<=2;
|
||||
if ((vga.crtc.mode_control & 0x8) || (vga.s3.pll.cmd & 0x10))
|
||||
if ((vga.crtc.mode_control & 0x8) || (svgaCard == SVGA_S3Trio && (vga.s3.pll.cmd & 0x10)))
|
||||
doublewidth = true;
|
||||
/* Use HW mouse cursor drawer if enabled */
|
||||
VGA_ActivateHardwareCursor();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_gfx.cpp,v 1.18 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
#include "vga.h"
|
||||
|
@ -174,14 +176,16 @@ static void write_p3cf(Bitu port,Bitu val,Bitu iolen) {
|
|||
display memory.
|
||||
*/
|
||||
break;
|
||||
case 9: /* Unknown */
|
||||
/* Crystal Dreams seems to like to write tothis register very weird */
|
||||
if (!index9warned) {
|
||||
default:
|
||||
if (svga.write_p3cf) {
|
||||
svga.write_p3cf(gfx(index), val, iolen);
|
||||
break;
|
||||
}
|
||||
if (gfx(index) == 9 && !index9warned) {
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:3CF:Write %2X to illegal index 9",val);
|
||||
index9warned=true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:3CF:Write %2X to illegal index %2X",val,gfx(index));
|
||||
break;
|
||||
}
|
||||
|
@ -208,7 +212,10 @@ static Bitu read_p3cf(Bitu port,Bitu iolen) {
|
|||
case 8: /* Bit Mask Register */
|
||||
return gfx(bit_mask);
|
||||
default:
|
||||
if (svga.read_p3cf)
|
||||
return svga.read_p3cf(gfx(index), iolen);
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("Reading from illegal index %2X in port %4X",static_cast<Bit32u>(gfx(index)),port);
|
||||
break;
|
||||
}
|
||||
return 0; /* Compiler happy */
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_memory.cpp,v 1.45 2007-12-10 22:11:13 c2woody Exp $ */
|
||||
/* $Id: vga_memory.cpp,v 1.46 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -132,16 +132,19 @@ public:
|
|||
public:
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return readHandler(addr);
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8);
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8) |
|
||||
|
@ -187,17 +190,20 @@ public:
|
|||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_write_full;
|
||||
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;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
|
@ -206,16 +212,19 @@ public:
|
|||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return readHandler(addr);
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8);
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
(readHandler(addr+1) << 8) |
|
||||
|
@ -263,17 +272,20 @@ public:
|
|||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_write_full;
|
||||
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;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr << 3);
|
||||
writeHandler<true>(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler<true>(addr+1,(Bit8u)(val >> 8));
|
||||
|
@ -307,10 +319,12 @@ public:
|
|||
}
|
||||
Bitu readb(PhysPt addr ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return readHandler<Bit8u>( addr );
|
||||
}
|
||||
Bitu readw(PhysPt addr ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
if (GCC_UNLIKELY(addr & 1))
|
||||
return
|
||||
(readHandler<Bit8u>( addr+0 ) << 0 ) |
|
||||
|
@ -320,6 +334,7 @@ public:
|
|||
}
|
||||
Bitu readd(PhysPt addr ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_read_full;
|
||||
if (GCC_UNLIKELY(addr & 3))
|
||||
return
|
||||
(readHandler<Bit8u>( addr+0 ) << 0 ) |
|
||||
|
@ -331,12 +346,14 @@ public:
|
|||
}
|
||||
void writeb(PhysPt addr, Bitu val ) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr );
|
||||
writeHandler<Bit8u>( addr, val );
|
||||
writeCache<Bit8u>( addr, val );
|
||||
}
|
||||
void writew(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr );
|
||||
// MEM_CHANGED( addr + 1);
|
||||
if (GCC_UNLIKELY(addr & 1)) {
|
||||
|
@ -349,6 +366,7 @@ public:
|
|||
}
|
||||
void writed(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr );
|
||||
// MEM_CHANGED( addr + 3);
|
||||
if (GCC_UNLIKELY(addr & 3)) {
|
||||
|
@ -381,20 +399,20 @@ public:
|
|||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
addr += vga.svga.bank_write_full;
|
||||
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;
|
||||
addr += vga.svga.bank_write_full;
|
||||
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;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr << 2);
|
||||
writeHandler(addr+0,(Bit8u)(val >> 0));
|
||||
writeHandler(addr+1,(Bit8u)(val >> 8));
|
||||
|
@ -427,11 +445,11 @@ public:
|
|||
}
|
||||
HostPt GetHostReadPt(Bitu phys_page) {
|
||||
phys_page-=vgapages.base;
|
||||
return &vga.mem.linear[vga.s3.svga_bank.fullbank+phys_page*4096];
|
||||
return &vga.mem.linear[vga.svga.bank_read_full+phys_page*4096];
|
||||
}
|
||||
HostPt GetHostWritePt(Bitu phys_page) {
|
||||
phys_page-=vgapages.base;
|
||||
return &vga.mem.linear[vga.s3.svga_bank.fullbank+phys_page*4096];
|
||||
return &vga.mem.linear[vga.svga.bank_write_full+phys_page*4096];
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -442,34 +460,34 @@ public:
|
|||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return hostRead<Bit8u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return hostRead<Bit16u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
Bitu readd(PhysPt addr) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
addr += vga.svga.bank_read_full;
|
||||
return hostRead<Bit32u>( &vga.mem.linear[addr] );
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = PAGING_GetPhysicalAddress(addr) & 0xffff;
|
||||
addr += vga.s3.svga_bank.fullbank;
|
||||
addr += vga.svga.bank_write_full;
|
||||
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;
|
||||
addr += vga.svga.bank_write_full;
|
||||
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;
|
||||
addr += vga.svga.bank_write_full;
|
||||
MEM_CHANGED( addr );
|
||||
hostWrite<Bit32u>( &vga.mem.linear[addr], val );
|
||||
}
|
||||
|
@ -481,20 +499,20 @@ public:
|
|||
flags=PFLAG_NOCODE;
|
||||
}
|
||||
void writeb(PhysPt addr,Bitu val) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
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 = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
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 = vga.svga.bank_write_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (128*1024-1);
|
||||
MEM_CHANGED( addr << 3 );
|
||||
writeHandler<false>(addr+0,(Bit8u)(val >> 0));
|
||||
|
@ -503,19 +521,19 @@ public:
|
|||
writeHandler<false>(addr+3,(Bit8u)(val >> 24));
|
||||
}
|
||||
Bitu readb(PhysPt addr) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (128*1024-1);
|
||||
return readHandler(addr);
|
||||
}
|
||||
Bitu readw(PhysPt addr) {
|
||||
addr = vga.s3.svga_bank.fullbank + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
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 = vga.svga.bank_read_full + (PAGING_GetPhysicalAddress(addr) & 0xffff);
|
||||
addr &= (128*1024-1);
|
||||
return
|
||||
(readHandler(addr+0) << 0) |
|
||||
|
@ -687,6 +705,9 @@ void VGA_ChangedBank(void) {
|
|||
}
|
||||
|
||||
void VGA_SetupHandlers(void) {
|
||||
vga.svga.bank_read_full = vga.svga.bank_read*vga.svga.bank_size;
|
||||
vga.svga.bank_write_full = vga.svga.bank_write*vga.svga.bank_size;
|
||||
|
||||
PageHandler *newHandler;
|
||||
switch (machine) {
|
||||
case MCH_CGA:
|
||||
|
@ -803,7 +824,7 @@ void VGA_SetupHandlers(void) {
|
|||
MEM_ResetPageHandler( VGA_PAGE_B0, 8 );
|
||||
break;
|
||||
}
|
||||
if(vga.s3.ext_mem_ctrl & 0x10)
|
||||
if(svgaCard == SVGA_S3Trio && (vga.s3.ext_mem_ctrl & 0x10))
|
||||
MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio);
|
||||
range_done:
|
||||
PAGING_ClearTLB();
|
||||
|
@ -828,7 +849,10 @@ void VGA_SetupMemory() {
|
|||
#ifdef VGA_KEEP_CHANGES
|
||||
memset( &vga.changes, 0, sizeof( vga.changes ));
|
||||
#endif
|
||||
vga.s3.svga_bank.fullbank=0;
|
||||
vga.svga.bank_read = vga.svga.bank_write = 0;
|
||||
vga.svga.bank_read_full = vga.svga.bank_write_full = 0;
|
||||
vga.svga.bank_size = 0x10000; /* most common bank size is 64K */
|
||||
|
||||
if (machine==MCH_PCJR) {
|
||||
/* PCJr does not have dedicated graphics memory but uses
|
||||
conventional memory below 128k */
|
||||
|
|
223
src/hardware/vga_paradise.cpp
Normal file
223
src/hardware/vga_paradise.cpp
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_paradise.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "setup.h"
|
||||
#include "vga.h"
|
||||
#include "inout.h"
|
||||
#include "mem.h"
|
||||
|
||||
typedef struct {
|
||||
Bitu PR0A;
|
||||
Bitu PR0B;
|
||||
Bitu PR1;
|
||||
Bitu PR2;
|
||||
Bitu PR3;
|
||||
Bitu PR4;
|
||||
Bitu PR5;
|
||||
|
||||
inline bool locked() { return (PR5&7)!=5; }
|
||||
|
||||
Bitu clockFreq[4];
|
||||
Bitu biosMode;
|
||||
} SVGA_PVGA1A_DATA;
|
||||
|
||||
static SVGA_PVGA1A_DATA pvga1a = { 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
|
||||
static void bank_setup_pvga1a() {
|
||||
// Note: There is some inconsistency in available documentation. Most sources tell that PVGA1A used
|
||||
// only 7 bits of bank index (VGADOC and Ferraro agree on that) but also point that there are
|
||||
// implementations with 1M of RAM which is simply not possible with 7-bit banks. This implementation
|
||||
// assumes that the eighth bit was actually wired and could be used. This does not conflict with
|
||||
// anything and actually works in WHATVGA just fine.
|
||||
if (pvga1a.PR1 & 0x08) {
|
||||
// TODO: Dual bank function is not supported yet
|
||||
// TODO: Requirements are not compatible with vga_memory implementation.
|
||||
} else {
|
||||
// Single bank config is straightforward
|
||||
vga.svga.bank_read = vga.svga.bank_write = pvga1a.PR0A;
|
||||
vga.svga.bank_size = 4*1024;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
void write_p3cf_pvga1a(Bitu reg,Bitu val,Bitu iolen) {
|
||||
if (pvga1a.locked() && reg >= 0x09 && reg <= 0x0e)
|
||||
return;
|
||||
|
||||
switch (reg) {
|
||||
case 0x09:
|
||||
// Bank A, 4K granularity, not using bit 7
|
||||
// Maps to A800h-AFFFh if PR1 bit 3 set and 64k config B000h-BFFFh if 128k config. A000h-AFFFh otherwise.
|
||||
pvga1a.PR0A = val;
|
||||
bank_setup_pvga1a();
|
||||
break;
|
||||
case 0x0a:
|
||||
// Bank B, 4K granularity, not using bit 7
|
||||
// Maps to A000h-A7FFh if PR1 bit 3 set and 64k config, A000h-AFFFh if 128k
|
||||
pvga1a.PR0B = val;
|
||||
bank_setup_pvga1a();
|
||||
break;
|
||||
case 0x0b:
|
||||
// Memory size. We only allow to mess with bit 3 here (enable bank B) - this may break some detection schemes
|
||||
pvga1a.PR1 = (pvga1a.PR1 & ~0x08) | (val & 0x08);
|
||||
bank_setup_pvga1a();
|
||||
break;
|
||||
case 0x0c:
|
||||
// Video configuration
|
||||
// TODO: Figure out if there is anything worth implementing here.
|
||||
pvga1a.PR2 = val;
|
||||
break;
|
||||
case 0x0d:
|
||||
// CRT control. Bits 3-4 contain bits 16-17 of CRT start.
|
||||
// TODO: Implement bit 2 (CRT address doubling - this mechanism is present in other chipsets as well,
|
||||
// but not implemented in DosBox core)
|
||||
pvga1a.PR3 = val;
|
||||
vga.config.display_start = (vga.config.display_start & 0xffff) | ((val & 0x18)<<13);
|
||||
vga.config.cursor_start = (vga.config.cursor_start & 0xffff) | ((val & 0x18)<<13);
|
||||
break;
|
||||
case 0x0e:
|
||||
// Video control
|
||||
// TODO: Figure out if there is anything worth implementing here.
|
||||
pvga1a.PR4 = val;
|
||||
break;
|
||||
case 0x0f:
|
||||
// Enable extended registers
|
||||
pvga1a.PR5 = val;
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:GFX:PVGA1A:Write to illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu read_p3cf_pvga1a(Bitu reg,Bitu iolen) {
|
||||
if (pvga1a.locked() && reg >= 0x09 && reg <= 0x0e)
|
||||
return 0x0;
|
||||
|
||||
switch (reg) {
|
||||
case 0x09:
|
||||
return pvga1a.PR0A;
|
||||
case 0x0a:
|
||||
return pvga1a.PR0B;
|
||||
case 0x0b:
|
||||
return pvga1a.PR1;
|
||||
case 0x0c:
|
||||
return pvga1a.PR2;
|
||||
case 0x0d:
|
||||
return pvga1a.PR3;
|
||||
case 0x0e:
|
||||
return pvga1a.PR4;
|
||||
case 0x0f:
|
||||
return pvga1a.PR5;
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:GFX:PVGA1A:Read from illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
void FinishSetMode_PVGA1A(Bitu /*crtc_base*/, VGA_ModeExtraData* modeData) {
|
||||
pvga1a.biosMode = modeData->modeNo;
|
||||
|
||||
// Reset to single bank and set it to 0. May need to unlock first (DPaint locks on exit)
|
||||
IO_Write(0x3ce, 0x0f);
|
||||
Bitu oldlock = IO_Read(0x3cf);
|
||||
IO_Write(0x3cf, 0x05);
|
||||
IO_Write(0x3ce, 0x09);
|
||||
IO_Write(0x3cf, 0x00);
|
||||
IO_Write(0x3ce, 0x0a);
|
||||
IO_Write(0x3cf, 0x00);
|
||||
IO_Write(0x3ce, 0x0b);
|
||||
Bit8u val = IO_Read(0x3cf);
|
||||
IO_Write(0x3cf, val & ~0x08);
|
||||
IO_Write(0x3ce, 0x0c);
|
||||
IO_Write(0x3cf, 0x00);
|
||||
IO_Write(0x3ce, 0x0d);
|
||||
IO_Write(0x3cf, 0x00);
|
||||
IO_Write(0x3ce, 0x0e);
|
||||
IO_Write(0x3cf, 0x00);
|
||||
IO_Write(0x3ce, 0x0f);
|
||||
IO_Write(0x3cf, oldlock);
|
||||
|
||||
if (svga.determine_mode)
|
||||
svga.determine_mode();
|
||||
|
||||
if (vga.mode != M_VGA)
|
||||
vga.config.compatible_chain4 = false; // in process of verification
|
||||
else
|
||||
vga.config.compatible_chain4 = true;
|
||||
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
|
||||
void DetermineMode_PVGA1A() {
|
||||
// Close replica from the base implementation. It will stay here
|
||||
// until I figure a way to either distinguish M_VGA and M_LIN8 or
|
||||
// merge them.
|
||||
if (vga.attr.mode_control & 1) {
|
||||
if (vga.gfx.mode & 0x40) VGA_SetMode((pvga1a.biosMode<=0x13)?M_VGA:M_LIN8);
|
||||
else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4);
|
||||
else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2);
|
||||
else VGA_SetMode((pvga1a.biosMode<=0x13)?M_EGA:M_LIN4);
|
||||
} else {
|
||||
VGA_SetMode(M_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void SetClock_PVGA1A(Bitu which,Bitu target) {
|
||||
if (which < 4) {
|
||||
pvga1a.clockFreq[which]=1000*target;
|
||||
VGA_StartResize();
|
||||
}
|
||||
}
|
||||
|
||||
Bitu GetClock_PVGA1A() {
|
||||
return pvga1a.clockFreq[(vga.misc_output >> 2) & 3];
|
||||
}
|
||||
|
||||
void SVGA_Setup_ParadisePVGA1A(void) {
|
||||
svga.write_p3cf = &write_p3cf_pvga1a;
|
||||
svga.read_p3cf = &read_p3cf_pvga1a;
|
||||
|
||||
svga.set_video_mode = &FinishSetMode_PVGA1A;
|
||||
svga.determine_mode = &DetermineMode_PVGA1A;
|
||||
svga.set_clock = &SetClock_PVGA1A;
|
||||
svga.get_clock = &GetClock_PVGA1A;
|
||||
|
||||
VGA_SetClock(0,CLK_25);
|
||||
VGA_SetClock(1,CLK_28);
|
||||
VGA_SetClock(2,32400); // could not find documentation
|
||||
VGA_SetClock(3,35900);
|
||||
|
||||
// Set memory size at 512K (standard for PVGA1A)
|
||||
pvga1a.PR1 = 2<<6;
|
||||
|
||||
// Paradise ROM signature
|
||||
PhysPt rom_base=PhysMake(0xc000,0);
|
||||
phys_writeb(rom_base+0x007d,'V');
|
||||
phys_writeb(rom_base+0x007e,'G');
|
||||
phys_writeb(rom_base+0x007f,'A');
|
||||
phys_writeb(rom_base+0x0080,'=');
|
||||
|
||||
IO_Write(0x3cf, 0x05); // Enable!
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_s3.cpp,v 1.10 2007-12-27 10:57:51 c2woody Exp $ */
|
||||
/* $Id: vga_s3.cpp,v 1.11 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
|
@ -28,6 +28,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
|
|||
//TODO Base address
|
||||
vga.s3.reg_31 = val;
|
||||
vga.config.compatible_chain4 = !(val&0x08);
|
||||
vga.config.display_start = (vga.config.display_start&~0x30000)|((val&0x30)<<12);
|
||||
VGA_DetermineMode();
|
||||
VGA_SetupHandlers();
|
||||
break;
|
||||
|
@ -48,9 +49,10 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
|
|||
case 0x35: /* CR35 CRT Register Lock */
|
||||
if (vga.s3.reg_lock1 != 0x48) return; //Needed for uvconfig detection
|
||||
vga.s3.reg_35=val & 0xf0;
|
||||
if ((vga.s3.svga_bank.b.bank & 0xf) ^ (val & 0xf)) {
|
||||
vga.s3.svga_bank.b.bank&=0xf0;
|
||||
vga.s3.svga_bank.b.bank|=val & 0xf;
|
||||
if ((vga.svga.bank_read & 0xf) ^ (val & 0xf)) {
|
||||
vga.svga.bank_read&=0xf0;
|
||||
vga.svga.bank_read|=val & 0xf;
|
||||
vga.svga.bank_write = vga.svga.bank_read;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
break;
|
||||
|
@ -138,12 +140,12 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
|
|||
break;
|
||||
case 0x51: /* Extended System Control 2 */
|
||||
vga.s3.reg_51=val & 0xc0; //Only store bits 6,7
|
||||
//TODO Display start
|
||||
vga.config.display_start&=0xFCFFFF;
|
||||
vga.config.display_start|=(val & 3) << 16;
|
||||
if ((vga.s3.svga_bank.b.bank&0xcf) ^ ((val&0xc)<<2)) {
|
||||
vga.s3.svga_bank.b.bank&=0xcf;
|
||||
vga.s3.svga_bank.b.bank|=(val&0xc)<<2;
|
||||
vga.config.display_start&=0xF3FFFF;
|
||||
vga.config.display_start|=(val & 3) << 18;
|
||||
if ((vga.svga.bank_read&0x30) ^ ((val&0xc)<<2)) {
|
||||
vga.svga.bank_read&=0xcf;
|
||||
vga.svga.bank_read|=(val&0xc)<<2;
|
||||
vga.svga.bank_write = vga.svga.bank_read;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
if (((val & 0x30) ^ (vga.config.scan_len >> 4)) & 0x30) {
|
||||
|
@ -310,7 +312,8 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
|
|||
}
|
||||
break;
|
||||
case 0x6a: /* Extended System Control 4 */
|
||||
vga.s3.svga_bank.b.bank=val & 0x3f;
|
||||
vga.svga.bank_read=val & 0x3f;
|
||||
vga.svga.bank_write = vga.svga.bank_read;
|
||||
VGA_SetupHandlers();
|
||||
break;
|
||||
case 0x6b: // BIOS scratchpad: LFB adress
|
||||
|
@ -340,7 +343,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) {
|
|||
//TODO mix in bits from baseaddress;
|
||||
return vga.s3.reg_31;
|
||||
case 0x35: /* CR35 CRT Register Lock */
|
||||
return vga.s3.reg_35|(vga.s3.svga_bank.b.bank & 0xf);
|
||||
return vga.s3.reg_35|(vga.svga.bank_read & 0xf);
|
||||
case 0x36: /* CR36 Reset State Read 1 */
|
||||
return 0x92; /* PCI version */
|
||||
//2 Mb PCI and some bios settings
|
||||
|
@ -349,7 +352,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) {
|
|||
case 0x38: /* CR38 Register Lock 1 */
|
||||
return vga.s3.reg_lock1;
|
||||
case 0x39: /* CR39 Register Lock 2 */
|
||||
return vga.s3.reg_lock2;
|
||||
return vga.s3.reg_lock2;
|
||||
case 0x3a:
|
||||
return vga.s3.reg_3a;
|
||||
case 0x40: /* CR40 system config */
|
||||
|
@ -376,7 +379,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) {
|
|||
return vga.s3.reg_50;
|
||||
case 0x51: /* Extended System Control 2 */
|
||||
return ((vga.config.display_start >> 16) & 3 ) |
|
||||
((vga.s3.svga_bank.b.bank & 0x30) >> 2) |
|
||||
((vga.svga.bank_read & 0x30) >> 2) |
|
||||
((vga.config.scan_len & 0x300) >> 4) |
|
||||
vga.s3.reg_51;
|
||||
case 0x52: // CR52 Extended BIOS flags 1
|
||||
|
@ -400,7 +403,7 @@ Bitu SVGA_S3_ReadCRTC( Bitu reg, Bitu iolen) {
|
|||
case 0x69: /* Extended System Control 3 */
|
||||
return (Bit8u)((vga.config.display_start & 0x1f0000)>>16);
|
||||
case 0x6a: /* Extended System Control 4 */
|
||||
return (Bit8u)(vga.s3.svga_bank.b.bank & 0x3f);
|
||||
return (Bit8u)(vga.svga.bank_read & 0x3f);
|
||||
case 0x6b: // BIOS scatchpad: LFB address
|
||||
return vga.s3.reg_6b;
|
||||
default:
|
||||
|
@ -471,6 +474,27 @@ Bitu SVGA_S3_GetClock(void) {
|
|||
clock = 28322000;
|
||||
else
|
||||
clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r);
|
||||
/* Check for dual transfer, master clock/2 */
|
||||
if (vga.s3.pll.cmd & 0x10) clock/=2;
|
||||
return clock;
|
||||
}
|
||||
|
||||
bool SVGA_S3_HWCursorActive(void) {
|
||||
return (vga.s3.hgc.curmode & 0x1) != 0;
|
||||
}
|
||||
|
||||
void SVGA_Setup_S3Trio(void) {
|
||||
svga.write_p3d5 = &SVGA_S3_WriteCRTC;
|
||||
svga.read_p3d5 = &SVGA_S3_ReadCRTC;
|
||||
svga.write_p3c5 = &SVGA_S3_WriteSEQ;
|
||||
svga.read_p3c5 = &SVGA_S3_ReadSEQ;
|
||||
svga.write_p3c0 = 0; /* no S3-specific functionality */
|
||||
svga.read_p3c1 = 0; /* no S3-specific functionality */
|
||||
|
||||
svga.set_video_mode = 0; /* implemented in core */
|
||||
svga.determine_mode = 0; /* implemented in core */
|
||||
svga.set_clock = 0; /* implemented in core */
|
||||
svga.get_clock = &SVGA_S3_GetClock;
|
||||
svga.hardware_cursor_active = &SVGA_S3_HWCursorActive;
|
||||
svga.accepts_mode = 0; /* don't filter modes */
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_seq.cpp,v 1.21 2007-12-23 16:00:53 c2woody Exp $ */
|
||||
/* $Id: vga_seq.cpp,v 1.22 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "inout.h"
|
||||
|
@ -109,13 +109,12 @@ void write_p3c5(Bitu port,Bitu val,Bitu iolen) {
|
|||
}
|
||||
break;
|
||||
default:
|
||||
switch (svgaCard) {
|
||||
case SVGA_S3Trio:
|
||||
SVGA_S3_WriteSEQ( seq(index), val, iolen );
|
||||
break;
|
||||
default:
|
||||
if (svga.write_p3c5) {
|
||||
svga.write_p3c5(seq(index), val, iolen);
|
||||
} else {
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:Write to illegal index %2X",seq(index));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,11 +136,11 @@ Bitu read_p3c5(Bitu port,Bitu iolen) {
|
|||
break;
|
||||
case 4: /* Memory Mode */
|
||||
return seq(memory_mode);
|
||||
break;
|
||||
default:
|
||||
switch (svgaCard) {
|
||||
case SVGA_S3Trio:
|
||||
return SVGA_S3_ReadSEQ( seq(index), iolen );
|
||||
}
|
||||
if (svga.read_p3c5)
|
||||
return svga.read_p3c5(seq(index), iolen);
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
785
src/hardware/vga_tseng.cpp
Normal file
785
src/hardware/vga_tseng.cpp
Normal file
|
@ -0,0 +1,785 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: vga_tseng.cpp,v 1.1 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "setup.h"
|
||||
#include "vga.h"
|
||||
#include "inout.h"
|
||||
#include "mem.h"
|
||||
|
||||
// Tseng ET4K data
|
||||
typedef struct {
|
||||
Bit8u extensionsEnabled;
|
||||
|
||||
// Stored exact values of some registers. Documentation only specifies some bits but hardware checks may
|
||||
// expect other bits to be preserved.
|
||||
Bitu store_3d4_31;
|
||||
Bitu store_3d4_32;
|
||||
Bitu store_3d4_33;
|
||||
Bitu store_3d4_34;
|
||||
Bitu store_3d4_35;
|
||||
Bitu store_3d4_36;
|
||||
Bitu store_3d4_37;
|
||||
Bitu store_3d4_3f;
|
||||
|
||||
Bitu store_3c0_16;
|
||||
Bitu store_3c0_17;
|
||||
|
||||
Bitu store_3c4_06;
|
||||
Bitu store_3c4_07;
|
||||
|
||||
Bitu clockFreq[16];
|
||||
Bitu biosMode;
|
||||
} SVGA_ET4K_DATA;
|
||||
|
||||
static SVGA_ET4K_DATA et4k = { 1, 0, /* the rest are 0s */ };
|
||||
|
||||
#define STORE_ET4K(port, index) \
|
||||
case 0x##index: \
|
||||
et4k.store_##port##_##index = val; \
|
||||
break;
|
||||
|
||||
#define RESTORE_ET4K(port, index) \
|
||||
case 0x##index: \
|
||||
return et4k.store_##port##_##index;
|
||||
|
||||
// Tseng ET4K implementation
|
||||
void write_p3d5_et4k(Bitu reg,Bitu val,Bitu iolen) {
|
||||
if(!et4k.extensionsEnabled && reg!=0x33)
|
||||
return;
|
||||
|
||||
switch(reg) {
|
||||
/*
|
||||
3d4h index 31h (R/W): General Purpose
|
||||
bit 0-3 Scratch pad
|
||||
6-7 Clock Select bits 3-4. Bits 0-1 are in 3C2h/3CCh bits 2-3.
|
||||
*/
|
||||
STORE_ET4K(3d4, 31);
|
||||
|
||||
// 3d4h index 32h - RAS/CAS Configuration (R/W)
|
||||
// No effect on emulation. Should not be written by software.
|
||||
STORE_ET4K(3d4, 32);
|
||||
|
||||
case 0x33:
|
||||
// 3d4 index 33h (R/W): Extended start Address
|
||||
// 0-1 Display Start Address bits 16-17
|
||||
// 2-3 Cursor start address bits 16-17
|
||||
// Used by standard Tseng ID scheme
|
||||
et4k.store_3d4_33 = val;
|
||||
vga.config.display_start = (vga.config.display_start & 0xffff) | ((val & 0x03)<<16);
|
||||
vga.config.cursor_start = (vga.config.cursor_start & 0xffff) | ((val & 0x0c)<<14);
|
||||
break;
|
||||
|
||||
/*
|
||||
3d4h index 34h (R/W): 6845 Compatibility Control Register
|
||||
bit 0 Enable CS0 (alternate clock timing)
|
||||
1 Clock Select bit 2. Bits 0-1 in 3C2h bits 2-3, bits 3-4 are in 3d4h
|
||||
index 31h bits 6-7
|
||||
2 Tristate ET4000 bus and color outputs if set
|
||||
3 Video Subsystem Enable Register at 46E8h if set, at 3C3h if clear.
|
||||
4 Enable Translation ROM for reading CRTC and MISCOUT if set
|
||||
5 Enable Translation ROM for writing CRTC and MISCOUT if set
|
||||
6 Enable double scan in AT&T compatibility mode if set
|
||||
7 Enable 6845 compatibility if set
|
||||
*/
|
||||
// TODO: Bit 6 may have effect on emulation
|
||||
STORE_ET4K(3d4, 34);
|
||||
|
||||
case 0x35:
|
||||
/*
|
||||
3d4h index 35h (R/W): Overflow High
|
||||
bit 0 Vertical Blank Start Bit 10 (3d4h index 15h).
|
||||
1 Vertical Total Bit 10 (3d4h index 6).
|
||||
2 Vertical Display End Bit 10 (3d4h index 12h).
|
||||
3 Vertical Sync Start Bit 10 (3d4h index 10h).
|
||||
4 Line Compare Bit 10 (3d4h index 18h).
|
||||
5 Gen-Lock Enabled if set (External sync)
|
||||
6 (4000) Read/Modify/Write Enabled if set. Currently not implemented.
|
||||
7 Vertical interlace if set. The Vertical timing registers are
|
||||
programmed as if the mode was non-interlaced!!
|
||||
*/
|
||||
et4k.store_3d4_35 = val;
|
||||
vga.config.line_compare = (vga.config.line_compare & 0x3ff) | ((val&0x10)<<6);
|
||||
// Abusing s3 ex_ver_overflow field. This is to be cleaned up later.
|
||||
{
|
||||
Bit8u s3val =
|
||||
((val & 0x01) << 2) | // vbstart
|
||||
((val & 0x02) >> 1) | // vtotal
|
||||
((val & 0x04) >> 1) | // vdispend
|
||||
((val & 0x08) << 1) | // vsyncstart (?)
|
||||
((val & 0x10) << 2); // linecomp
|
||||
if ((s3val ^ vga.s3.ex_ver_overflow) & 0x3) {
|
||||
vga.s3.ex_ver_overflow=s3val;
|
||||
VGA_StartResize();
|
||||
} else vga.s3.ex_ver_overflow=s3val;
|
||||
}
|
||||
break;
|
||||
|
||||
// 3d4h index 36h - Video System Configuration 1 (R/W)
|
||||
// VGADOC provides a lot of info on this register, Ferraro has significantly less detail.
|
||||
// This is unlikely to be used by any games. Bit 4 switches chipset into linear mode -
|
||||
// that may be useful in some cases if there is any software actually using it.
|
||||
// TODO (not near future): support linear addressing
|
||||
STORE_ET4K(3d4, 36);
|
||||
|
||||
// 3d4h index 37 - Video System Configuration 2 (R/W)
|
||||
// Bits 0,1, and 3 provides information about memory size:
|
||||
// 0-1 Bus width (1: 8 bit, 2: 16 bit, 3: 32 bit)
|
||||
// 3 Size of RAM chips (0: 64Kx, 1: 256Kx)
|
||||
// Other bits have no effect on emulation.
|
||||
case 0x37:
|
||||
if (val != et4k.store_3d4_37) {
|
||||
et4k.store_3d4_37 = val;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x3f:
|
||||
/*
|
||||
3d4h index 3Fh (R/W):
|
||||
bit 0 Bit 8 of the Horizontal Total (3d4h index 0)
|
||||
2 Bit 8 of the Horizontal Blank Start (3d4h index 3)
|
||||
4 Bit 8 of the Horizontal Retrace Start (3d4h index 4)
|
||||
7 Bit 8 of the CRTC offset register (3d4h index 13h).
|
||||
*/
|
||||
// The only unimplemented one is bit 7
|
||||
et4k.store_3d4_3f = val;
|
||||
// Abusing s3 ex_hor_overflow field which very similar. This is
|
||||
// to be cleaned up later
|
||||
if ((val ^ vga.s3.ex_hor_overflow) & 3) {
|
||||
vga.s3.ex_hor_overflow=(val&0x15);
|
||||
VGA_StartResize();
|
||||
} else vga.s3.ex_hor_overflow=(val&0x15);
|
||||
break;
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET4K:Write to illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu read_p3d5_et4k(Bitu reg,Bitu iolen) {
|
||||
if (!et4k.extensionsEnabled && reg!=0x33)
|
||||
return 0x0;
|
||||
switch(reg) {
|
||||
RESTORE_ET4K(3d4, 31);
|
||||
RESTORE_ET4K(3d4, 32);
|
||||
RESTORE_ET4K(3d4, 33);
|
||||
RESTORE_ET4K(3d4, 34);
|
||||
RESTORE_ET4K(3d4, 35);
|
||||
RESTORE_ET4K(3d4, 36);
|
||||
RESTORE_ET4K(3d4, 37);
|
||||
RESTORE_ET4K(3d4, 3f);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET4K:Read from illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
void write_p3c5_et4k(Bitu reg,Bitu val,Bitu iolen) {
|
||||
switch(reg) {
|
||||
/*
|
||||
3C4h index 6 (R/W): TS State Control
|
||||
bit 1-2 Font Width Select in dots/character
|
||||
If 3C4h index 4 bit 0 clear:
|
||||
0: 9 dots, 1: 10 dots, 2: 12 dots, 3: 6 dots
|
||||
If 3C4h index 5 bit 0 set:
|
||||
0: 8 dots, 1: 11 dots, 2: 7 dots, 3: 16 dots
|
||||
Only valid if 3d4h index 34h bit 3 set.
|
||||
*/
|
||||
// TODO: Figure out if this has any practical use
|
||||
STORE_ET4K(3c4, 06);
|
||||
// 3C4h index 7 (R/W): TS Auxiliary Mode
|
||||
// Unlikely to be used by games (things like ROM enable/disable and emulation of VGA vs EGA)
|
||||
STORE_ET4K(3c4, 07);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET4K:Write to illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu read_p3c5_et4k(Bitu reg,Bitu iolen) {
|
||||
switch(reg) {
|
||||
RESTORE_ET4K(3c4, 06);
|
||||
RESTORE_ET4K(3c4, 07);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET4K:Read from illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
/*
|
||||
3CDh (R/W): Segment Select
|
||||
bit 0-3 64k Write bank number (0..15)
|
||||
4-7 64k Read bank number (0..15)
|
||||
*/
|
||||
void write_p3cd_et4k(Bitu port,Bitu val,Bitu iolen) {
|
||||
vga.svga.bank_write = val & 0x0f;
|
||||
vga.svga.bank_read = (val>>4) & 0x0f;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
|
||||
Bitu read_p3cd_et4k(Bitu port,Bitu iolen) {
|
||||
return (vga.svga.bank_read<<4)|vga.svga.bank_write;
|
||||
}
|
||||
|
||||
void write_p3c0_et4k(Bitu reg,Bitu val,Bitu iolen) {
|
||||
switch(reg) {
|
||||
// 3c0 index 16h: ATC Miscellaneous
|
||||
// VGADOC provides a lot of information, Ferarro documents only two bits
|
||||
// and even those incompletely. The register is used as part of identification
|
||||
// scheme.
|
||||
// Unlikely to be used by any games but double timing may be useful.
|
||||
// TODO: Figure out if this has any practical use
|
||||
STORE_ET4K(3c0, 16);
|
||||
/*
|
||||
3C0h index 17h (R/W): Miscellaneous 1
|
||||
bit 7 If set protects the internal palette ram and redefines the attribute
|
||||
bits as follows:
|
||||
Monochrome:
|
||||
bit 0-2 Select font 0-7
|
||||
3 If set selects blinking
|
||||
4 If set selects underline
|
||||
5 If set prevents the character from being displayed
|
||||
6 If set displays the character at half intensity
|
||||
7 If set selects reverse video
|
||||
Color:
|
||||
bit 0-1 Selects font 0-3
|
||||
2 Foreground Blue
|
||||
3 Foreground Green
|
||||
4 Foreground Red
|
||||
5 Background Blue
|
||||
6 Background Green
|
||||
7 Background Red
|
||||
*/
|
||||
// TODO: Figure out if this has any practical use
|
||||
STORE_ET4K(3c0, 17);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET4K:Write to illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu read_p3c1_et4k(Bitu reg,Bitu iolen) {
|
||||
switch(reg) {
|
||||
RESTORE_ET4K(3c0, 16);
|
||||
RESTORE_ET4K(3c0, 17);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET4K:Read from illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
/*
|
||||
These ports are used but have little if any effect on emulation:
|
||||
3BFh (R/W): Hercules Compatibility Mode
|
||||
3CBh (R/W): PEL Address/Data Wd
|
||||
3CEh index 0Dh (R/W): Microsequencer Mode
|
||||
3CEh index 0Eh (R/W): Microsequencer Reset
|
||||
3d8h (R/W): Display Mode Control
|
||||
3DEh (W); AT&T Mode Control Register
|
||||
*/
|
||||
|
||||
static Bitu get_clock_index_et4k() {
|
||||
// Ignoring bit 4, using "only" 16 frequencies. Looks like most implementations had only that
|
||||
return ((vga.misc_output>>2)&3) | ((et4k.store_3d4_34<<1)&4) | ((et4k.store_3d4_31>>3)&8);
|
||||
}
|
||||
|
||||
static void set_clock_index_et4k(Bitu index) {
|
||||
// Shortwiring register reads/writes for simplicity
|
||||
IO_Write(0x3c2, (vga.misc_output&~0x0c)|((index&3)<<2));
|
||||
et4k.store_3d4_34 = (et4k.store_3d4_34&~0x02)|((index&4)>>1);
|
||||
et4k.store_3d4_31 = (et4k.store_3d4_31&~0xc0)|((index&8)<<3); // (index&0x18) if 32 clock frequencies are to be supported
|
||||
}
|
||||
|
||||
void FinishSetMode_ET4K(Bitu crtc_base, VGA_ModeExtraData* modeData) {
|
||||
et4k.biosMode = modeData->modeNo;
|
||||
|
||||
IO_Write(0x3cd, 0x00); // both banks to 0
|
||||
|
||||
// Reinterpret hor_overflow. Curiously, three bits out of four are
|
||||
// in the same places. Input has hdispend (not supported), output
|
||||
// has CRTC offset (also not supported)
|
||||
Bit8u et4k_hor_overflow =
|
||||
(modeData->hor_overflow & 0x01) |
|
||||
(modeData->hor_overflow & 0x04) |
|
||||
(modeData->hor_overflow & 0x10);
|
||||
IO_Write(crtc_base,0x3f);IO_Write(crtc_base+1,et4k_hor_overflow);
|
||||
|
||||
// Reinterpret ver_overflow
|
||||
Bit8u et4k_ver_overflow =
|
||||
((modeData->ver_overflow & 0x01) << 1) | // vtotal10
|
||||
((modeData->ver_overflow & 0x02) << 1) | // vdispend10
|
||||
((modeData->ver_overflow & 0x04) >> 2) | // vbstart10
|
||||
((modeData->ver_overflow & 0x10) >> 1) | // vretrace10 (tseng has vsync start?)
|
||||
((modeData->ver_overflow & 0x40) >> 2); // line_compare
|
||||
IO_Write(crtc_base,0x35);IO_Write(crtc_base+1,et4k_ver_overflow);
|
||||
|
||||
// Clear remaining ext CRTC registers
|
||||
IO_Write(crtc_base,0x31);IO_Write(crtc_base+1,0);
|
||||
IO_Write(crtc_base,0x32);IO_Write(crtc_base+1,0);
|
||||
IO_Write(crtc_base,0x33);IO_Write(crtc_base+1,0);
|
||||
IO_Write(crtc_base,0x34);IO_Write(crtc_base+1,0);
|
||||
IO_Write(crtc_base,0x36);IO_Write(crtc_base+1,0);
|
||||
IO_Write(crtc_base,0x37);IO_Write(crtc_base+1,0x0f); // 1M video ram (0x0e for 512K, 0x0d for 256K)
|
||||
// Clear ext SEQ
|
||||
IO_Write(0x3c4,0x06);IO_Write(0x3c5,0);
|
||||
IO_Write(0x3c4,0x07);IO_Write(0x3c5,0);
|
||||
// Clear ext ATTR
|
||||
IO_Write(0x3c0,0x16);IO_Write(0x3c0,0);
|
||||
IO_Write(0x3c0,0x17);IO_Write(0x3c0,0);
|
||||
|
||||
// Select SVGA clock to get close to 60Hz (not particularly clean implementation)
|
||||
if (modeData->modeNo > 0x13) {
|
||||
Bitu target = modeData->vtotal*8*modeData->htotal*60;
|
||||
Bitu best = 1;
|
||||
Bits dist = 100000000;
|
||||
for (Bitu i=0; i<16; i++) {
|
||||
if (abs(target-et4k.clockFreq[i]) < dist) {
|
||||
best = i;
|
||||
dist = abs(target-et4k.clockFreq[i]);
|
||||
}
|
||||
}
|
||||
set_clock_index_et4k(best);
|
||||
}
|
||||
|
||||
if(svga.determine_mode)
|
||||
svga.determine_mode();
|
||||
|
||||
// Verified (on real hardware and in a few games): Tseng ET4000 used chain4 implementation
|
||||
// different from standard VGA. It was also not limited to 64K in regular mode 13h.
|
||||
vga.config.compatible_chain4 = false;
|
||||
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
|
||||
void DetermineMode_ET4K() {
|
||||
// Close replica from the base implementation. It will stay here
|
||||
// until I figure a way to either distinguish M_VGA and M_LIN8 or
|
||||
// merge them.
|
||||
if (vga.attr.mode_control & 1) {
|
||||
if (vga.gfx.mode & 0x40) VGA_SetMode((et4k.biosMode<=0x13)?M_VGA:M_LIN8); // Ugly...
|
||||
else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4);
|
||||
else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2);
|
||||
else VGA_SetMode((et4k.biosMode<=0x13)?M_EGA:M_LIN4);
|
||||
} else {
|
||||
VGA_SetMode(M_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void SetClock_ET4K(Bitu which,Bitu target) {
|
||||
et4k.clockFreq[which]=1000*target;
|
||||
VGA_StartResize();
|
||||
}
|
||||
|
||||
Bitu GetClock_ET4K() {
|
||||
return et4k.clockFreq[get_clock_index_et4k()];
|
||||
}
|
||||
|
||||
bool AcceptsMode_ET4K(Bitu mode) {
|
||||
return mode != 0x3d;
|
||||
}
|
||||
|
||||
void SVGA_Setup_TsengET4K(void) {
|
||||
svga.write_p3d5 = &write_p3d5_et4k;
|
||||
svga.read_p3d5 = &read_p3d5_et4k;
|
||||
svga.write_p3c5 = &write_p3c5_et4k;
|
||||
svga.read_p3c5 = &read_p3c5_et4k;
|
||||
svga.write_p3c0 = &write_p3c0_et4k;
|
||||
svga.read_p3c1 = &read_p3c1_et4k;
|
||||
|
||||
svga.set_video_mode = &FinishSetMode_ET4K;
|
||||
svga.determine_mode = &DetermineMode_ET4K;
|
||||
svga.set_clock = &SetClock_ET4K;
|
||||
svga.get_clock = &GetClock_ET4K;
|
||||
svga.accepts_mode = &AcceptsMode_ET4K;
|
||||
|
||||
// From the depths of X86Config, probably inexact
|
||||
VGA_SetClock(0,CLK_25);
|
||||
VGA_SetClock(1,CLK_28);
|
||||
VGA_SetClock(2,32400);
|
||||
VGA_SetClock(3,35900);
|
||||
VGA_SetClock(4,39900);
|
||||
VGA_SetClock(5,44700);
|
||||
VGA_SetClock(6,31400);
|
||||
VGA_SetClock(7,37500);
|
||||
VGA_SetClock(8,50000);
|
||||
VGA_SetClock(9,56500);
|
||||
VGA_SetClock(10,64900);
|
||||
VGA_SetClock(11,71900);
|
||||
VGA_SetClock(12,79900);
|
||||
VGA_SetClock(13,89600);
|
||||
VGA_SetClock(14,62800);
|
||||
VGA_SetClock(15,74800);
|
||||
|
||||
IO_RegisterReadHandler(0x3cd,read_p3cd_et4k,IO_MB);
|
||||
IO_RegisterWriteHandler(0x3cd,write_p3cd_et4k,IO_MB);
|
||||
|
||||
// Tseng ROM signature
|
||||
PhysPt rom_base=PhysMake(0xc000,0);
|
||||
phys_writeb(rom_base+0x0075,' ');
|
||||
phys_writeb(rom_base+0x0076,'T');
|
||||
phys_writeb(rom_base+0x0077,'s');
|
||||
phys_writeb(rom_base+0x0078,'e');
|
||||
phys_writeb(rom_base+0x0079,'n');
|
||||
phys_writeb(rom_base+0x007a,'g');
|
||||
phys_writeb(rom_base+0x007b,' ');
|
||||
}
|
||||
|
||||
|
||||
// Tseng ET3K implementation
|
||||
typedef struct {
|
||||
// Stored exact values of some registers. Documentation only specifies some bits but hardware checks may
|
||||
// expect other bits to be preserved.
|
||||
Bitu store_3d4_1b;
|
||||
Bitu store_3d4_1c;
|
||||
Bitu store_3d4_1d;
|
||||
Bitu store_3d4_1e;
|
||||
Bitu store_3d4_1f;
|
||||
Bitu store_3d4_20;
|
||||
Bitu store_3d4_21;
|
||||
Bitu store_3d4_23; // note that 22 is missing
|
||||
Bitu store_3d4_24;
|
||||
Bitu store_3d4_25;
|
||||
|
||||
Bitu store_3c0_16;
|
||||
Bitu store_3c0_17;
|
||||
|
||||
Bitu store_3c4_06;
|
||||
Bitu store_3c4_07;
|
||||
|
||||
Bitu clockFreq[8];
|
||||
Bitu biosMode;
|
||||
} SVGA_ET3K_DATA;
|
||||
|
||||
static SVGA_ET3K_DATA et3k = { 0 /* and the rest are 0s as well */ };
|
||||
|
||||
#define STORE_ET3K(port, index) \
|
||||
case 0x##index: \
|
||||
et3k.store_##port##_##index = val; \
|
||||
break;
|
||||
|
||||
#define RESTORE_ET3K(port, index) \
|
||||
case 0x##index: \
|
||||
return et3k.store_##port##_##index;
|
||||
|
||||
|
||||
void write_p3d5_et3k(Bitu reg,Bitu val,Bitu iolen) {
|
||||
switch(reg) {
|
||||
// 3d4 index 1bh-21h: Hardware zoom control registers
|
||||
// I am not sure if there was a piece of software that used these.
|
||||
// Not implemented and will probably stay this way.
|
||||
STORE_ET3K(3d4, 1b);
|
||||
STORE_ET3K(3d4, 1c);
|
||||
STORE_ET3K(3d4, 1d);
|
||||
STORE_ET3K(3d4, 1e);
|
||||
STORE_ET3K(3d4, 1f);
|
||||
STORE_ET3K(3d4, 20);
|
||||
STORE_ET3K(3d4, 21);
|
||||
|
||||
case 0x23:
|
||||
/*
|
||||
3d4h index 23h (R/W): Extended start ET3000
|
||||
bit 0 Cursor start address bit 16
|
||||
1 Display start address bit 16
|
||||
2 Zoom start address bit 16
|
||||
7 If set memory address 8 is output on the MBSL pin (allowing access to
|
||||
1MB), if clear the blanking signal is output.
|
||||
*/
|
||||
// Only bits 1 and 2 are supported. Bit 2 is related to hardware zoom, bit 7 is too obscure to be useful
|
||||
et3k.store_3d4_23 = val;
|
||||
vga.config.display_start = (vga.config.display_start & 0xffff) | ((val & 0x02)<<15);
|
||||
vga.config.cursor_start = (vga.config.cursor_start & 0xffff) | ((val & 0x01)<<16);
|
||||
break;
|
||||
|
||||
|
||||
/*
|
||||
3d4h index 24h (R/W): Compatibility Control
|
||||
bit 0 Enable Clock Translate if set
|
||||
1 Clock Select bit 2. Bits 0-1 are in 3C2h/3CCh.
|
||||
2 Enable tri-state for all output pins if set
|
||||
3 Enable input A8 of 1MB DRAMs from the INTL output if set
|
||||
4 Reserved
|
||||
5 Enable external ROM CRTC translation if set
|
||||
6 Enable Double Scan and Underline Attribute if set
|
||||
7 Enable 6845 compatibility if set.
|
||||
*/
|
||||
// TODO: Some of these may be worth implementing.
|
||||
STORE_ET3K(3d4, 24);
|
||||
|
||||
|
||||
case 0x25:
|
||||
/*
|
||||
3d4h index 25h (R/W): Overflow High
|
||||
bit 0 Vertical Blank Start bit 10
|
||||
1 Vertical Total Start bit 10
|
||||
2 Vertical Display End bit 10
|
||||
3 Vertical Sync Start bit 10
|
||||
4 Line Compare bit 10
|
||||
5-6 Reserved
|
||||
7 Vertical Interlace if set
|
||||
*/
|
||||
et3k.store_3d4_25 = val;
|
||||
vga.config.line_compare = (vga.config.line_compare & 0x3ff) | ((val&0x10)<<6);
|
||||
// Abusing s3 ex_ver_overflow field. This is to be cleaned up later.
|
||||
{
|
||||
Bit8u s3val =
|
||||
((val & 0x01) << 2) | // vbstart
|
||||
((val & 0x02) >> 1) | // vtotal
|
||||
((val & 0x04) >> 1) | // vdispend
|
||||
((val & 0x08) << 1) | // vsyncstart (?)
|
||||
((val & 0x10) << 2); // linecomp
|
||||
if ((s3val ^ vga.s3.ex_ver_overflow) & 0x3) {
|
||||
vga.s3.ex_ver_overflow=s3val;
|
||||
VGA_StartResize();
|
||||
} else vga.s3.ex_ver_overflow=s3val;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET3K:Write to illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu read_p3d5_et3k(Bitu reg,Bitu iolen) {
|
||||
switch(reg) {
|
||||
RESTORE_ET3K(3d4, 1b);
|
||||
RESTORE_ET3K(3d4, 1c);
|
||||
RESTORE_ET3K(3d4, 1d);
|
||||
RESTORE_ET3K(3d4, 1e);
|
||||
RESTORE_ET3K(3d4, 1f);
|
||||
RESTORE_ET3K(3d4, 20);
|
||||
RESTORE_ET3K(3d4, 21);
|
||||
RESTORE_ET3K(3d4, 23);
|
||||
RESTORE_ET3K(3d4, 24);
|
||||
RESTORE_ET3K(3d4, 25);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:CRTC:ET3K:Read from illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
void write_p3c5_et3k(Bitu reg,Bitu val,Bitu iolen) {
|
||||
switch(reg) {
|
||||
// Both registers deal mostly with hardware zoom which is not implemented. Other bits
|
||||
// seem to be useless for emulation with the exception of index 7 bit 4 (font select)
|
||||
STORE_ET3K(3c4, 06);
|
||||
STORE_ET3K(3c4, 07);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET3K:Write to illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu read_p3c5_et3k(Bitu reg,Bitu iolen) {
|
||||
switch(reg) {
|
||||
RESTORE_ET3K(3c4, 06);
|
||||
RESTORE_ET3K(3c4, 07);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:SEQ:ET3K:Read from illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
/*
|
||||
3CDh (R/W): Segment Select
|
||||
bit 0-2 64k Write bank number
|
||||
3-5 64k Read bank number
|
||||
6-7 Segment Configuration.
|
||||
0 128K segments
|
||||
1 64K segments
|
||||
2 1M linear memory
|
||||
NOTES: 1M linear memory is not supported
|
||||
*/
|
||||
void write_p3cd_et3k(Bitu port,Bitu val,Bitu iolen) {
|
||||
vga.svga.bank_write = val & 0x07;
|
||||
vga.svga.bank_read = (val>>3) & 0x07;
|
||||
vga.svga.bank_size = (val&0x40)?64*1024:128*1024;
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
|
||||
Bitu read_p3cd_et3k(Bitu port,Bitu iolen) {
|
||||
return (vga.svga.bank_read<<3)|vga.svga.bank_write|((vga.svga.bank_size==128*1024)?0:0x40);
|
||||
}
|
||||
|
||||
void write_p3c0_et3k(Bitu reg,Bitu val,Bitu iolen) {
|
||||
// See ET4K notes.
|
||||
switch(reg) {
|
||||
STORE_ET3K(3c0, 16);
|
||||
STORE_ET3K(3c0, 17);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET3K:Write to illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Bitu read_p3c1_et3k(Bitu reg,Bitu iolen) {
|
||||
switch(reg) {
|
||||
RESTORE_ET3K(3c0, 16);
|
||||
RESTORE_ET3K(3c0, 17);
|
||||
default:
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)("VGA:ATTR:ET3K:Read from illegal index %2X", reg);
|
||||
break;
|
||||
}
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
/*
|
||||
These ports are used but have little if any effect on emulation:
|
||||
3B8h (W): Display Mode Control Register
|
||||
3BFh (R/W): Hercules Compatibility Mode
|
||||
3CBh (R/W): PEL Address/Data Wd
|
||||
3CEh index 0Dh (R/W): Microsequencer Mode
|
||||
3CEh index 0Eh (R/W): Microsequencer Reset
|
||||
3d8h (R/W): Display Mode Control
|
||||
3D9h (W): Color Select Register
|
||||
3dAh (W): Feature Control Register
|
||||
3DEh (W); AT&T Mode Control Register
|
||||
*/
|
||||
|
||||
static Bitu get_clock_index_et3k() {
|
||||
return ((vga.misc_output>>2)&3) | ((et3k.store_3d4_24<<1)&4);
|
||||
}
|
||||
|
||||
static void set_clock_index_et3k(Bitu index) {
|
||||
// Shortwiring register reads/writes for simplicity
|
||||
IO_Write(0x3c2, (vga.misc_output&~0x0c)|((index&3)<<2));
|
||||
et3k.store_3d4_24 = (et3k.store_3d4_24&~0x02)|((index&4)>>1);
|
||||
}
|
||||
|
||||
void FinishSetMode_ET3K(Bitu crtc_base, VGA_ModeExtraData* modeData) {
|
||||
et3k.biosMode = modeData->modeNo;
|
||||
|
||||
IO_Write(0x3cd, 0x40); // both banks to 0, 64K bank size
|
||||
|
||||
// Tseng ET3K does not have horizontal overflow bits
|
||||
// Reinterpret ver_overflow
|
||||
Bit8u et4k_ver_overflow =
|
||||
((modeData->ver_overflow & 0x01) << 1) | // vtotal10
|
||||
((modeData->ver_overflow & 0x02) << 1) | // vdispend10
|
||||
((modeData->ver_overflow & 0x04) >> 2) | // vbstart10
|
||||
((modeData->ver_overflow & 0x10) >> 1) | // vretrace10 (tseng has vsync start?)
|
||||
((modeData->ver_overflow & 0x40) >> 2); // line_compare
|
||||
IO_Write(crtc_base,0x25);IO_Write(crtc_base+1,et4k_ver_overflow);
|
||||
|
||||
// Clear remaining ext CRTC registers
|
||||
for (Bitu i=0x16; i<=0x21; i++)
|
||||
IO_Write(crtc_base,i);IO_Write(crtc_base+1,0);
|
||||
IO_Write(crtc_base,0x23);IO_Write(crtc_base+1,0);
|
||||
IO_Write(crtc_base,0x24);IO_Write(crtc_base+1,0);
|
||||
// Clear ext SEQ
|
||||
IO_Write(0x3c4,0x06);IO_Write(0x3c5,0);
|
||||
IO_Write(0x3c4,0x07);IO_Write(0x3c5,0x40); // 0 in this register breaks WHATVGA
|
||||
// Clear ext ATTR
|
||||
IO_Write(0x3c0,0x16);IO_Write(0x3c0,0);
|
||||
IO_Write(0x3c0,0x17);IO_Write(0x3c0,0);
|
||||
|
||||
// Select SVGA clock to get close to 60Hz (not particularly clean implementation)
|
||||
if (modeData->modeNo > 0x13) {
|
||||
Bitu target = modeData->vtotal*8*modeData->htotal*60;
|
||||
Bitu best = 1;
|
||||
Bits dist = 100000000;
|
||||
for (Bitu i=0; i<8; i++) {
|
||||
if (abs(target-et3k.clockFreq[i]) < dist) {
|
||||
best = i;
|
||||
dist = abs(target-et3k.clockFreq[i]);
|
||||
}
|
||||
}
|
||||
set_clock_index_et3k(best);
|
||||
}
|
||||
|
||||
if (svga.determine_mode)
|
||||
svga.determine_mode();
|
||||
|
||||
// Verified on functioning (at last!) hardware: Tseng ET3000 is the same as ET4000 when
|
||||
// it comes to chain4 architecture
|
||||
vga.config.compatible_chain4 = false;
|
||||
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
|
||||
void DetermineMode_ET3K() {
|
||||
// Close replica from the base implementation. It will stay here
|
||||
// until I figure a way to either distinguish M_VGA and M_LIN8 or
|
||||
// merge them.
|
||||
if (vga.attr.mode_control & 1) {
|
||||
if (vga.gfx.mode & 0x40) VGA_SetMode((et3k.biosMode<=0x13)?M_VGA:M_LIN8); // Ugly...
|
||||
else if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4);
|
||||
else if ((vga.gfx.miscellaneous & 0x0c)==0x0c) VGA_SetMode(M_CGA2);
|
||||
else VGA_SetMode((et3k.biosMode<=0x13)?M_EGA:M_LIN4);
|
||||
} else {
|
||||
VGA_SetMode(M_TEXT);
|
||||
}
|
||||
}
|
||||
|
||||
void SetClock_ET3K(Bitu which,Bitu target) {
|
||||
et3k.clockFreq[which]=1000*target;
|
||||
VGA_StartResize();
|
||||
}
|
||||
|
||||
Bitu GetClock_ET3K() {
|
||||
return et3k.clockFreq[get_clock_index_et3k()];
|
||||
}
|
||||
|
||||
bool AcceptsMode_ET3K(Bitu mode) {
|
||||
return mode <= 0x37 && mode != 0x2f;
|
||||
}
|
||||
|
||||
void SVGA_Setup_TsengET3K(void) {
|
||||
svga.write_p3d5 = &write_p3d5_et3k;
|
||||
svga.read_p3d5 = &read_p3d5_et3k;
|
||||
svga.write_p3c5 = &write_p3c5_et3k;
|
||||
svga.read_p3c5 = &read_p3c5_et3k;
|
||||
svga.write_p3c0 = &write_p3c0_et3k;
|
||||
svga.read_p3c1 = &read_p3c1_et3k;
|
||||
|
||||
svga.set_video_mode = &FinishSetMode_ET3K;
|
||||
svga.determine_mode = &DetermineMode_ET3K;
|
||||
svga.set_clock = &SetClock_ET3K;
|
||||
svga.get_clock = &GetClock_ET3K;
|
||||
svga.accepts_mode = &AcceptsMode_ET3K;
|
||||
|
||||
VGA_SetClock(0,CLK_25);
|
||||
VGA_SetClock(1,CLK_28);
|
||||
VGA_SetClock(2,32400);
|
||||
VGA_SetClock(3,35900);
|
||||
VGA_SetClock(4,39900);
|
||||
VGA_SetClock(5,44700);
|
||||
VGA_SetClock(6,31400);
|
||||
VGA_SetClock(7,37500);
|
||||
|
||||
IO_RegisterReadHandler(0x3cd,read_p3cd_et3k,IO_MB);
|
||||
IO_RegisterWriteHandler(0x3cd,write_p3cd_et3k,IO_MB);
|
||||
|
||||
// Tseng ROM signature
|
||||
PhysPt rom_base=PhysMake(0xc000,0);
|
||||
phys_writeb(rom_base+0x0075,' ');
|
||||
phys_writeb(rom_base+0x0076,'T');
|
||||
phys_writeb(rom_base+0x0077,'s');
|
||||
phys_writeb(rom_base+0x0078,'e');
|
||||
phys_writeb(rom_base+0x0079,'n');
|
||||
phys_writeb(rom_base+0x007a,'g');
|
||||
phys_writeb(rom_base+0x007b,' ');
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,6 +16,8 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: int10.cpp,v 1.48 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include "dosbox.h"
|
||||
#include "mem.h"
|
||||
#include "callback.h"
|
||||
|
@ -480,7 +482,7 @@ graphics_chars:
|
|||
}
|
||||
break;
|
||||
case 0x4f: /* VESA Calls */
|
||||
if ((!IS_VGA_ARCH) || (svgaCard==SVGA_None)) break;
|
||||
if ((!IS_VGA_ARCH) || (svgaCard!=SVGA_S3Trio)) break;
|
||||
switch (reg_al) {
|
||||
case 0x00: /* Get SVGA Information */
|
||||
reg_al=0x4f;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2002-2007 The DOSBox Team
|
||||
* Copyright (C) 2002-2008 The DOSBox Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
@ -16,7 +16,7 @@
|
|||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/* $Id: int10_modes.cpp,v 1.73 2007-12-27 10:57:51 c2woody Exp $ */
|
||||
/* $Id: int10_modes.cpp,v 1.74 2008-01-09 20:34:51 c2woody Exp $ */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -124,6 +124,79 @@ VideoModeBlock ModeList_VGA[]={
|
|||
{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 },
|
||||
};
|
||||
|
||||
VideoModeBlock ModeList_VGA_Tseng[]={
|
||||
/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */
|
||||
{ 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK },
|
||||
{ 0x001 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK },
|
||||
{ 0x002 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 },
|
||||
{ 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 },
|
||||
{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
|
||||
{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
|
||||
{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
|
||||
{ 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 },
|
||||
|
||||
{ 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE },
|
||||
{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE },
|
||||
{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/
|
||||
{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },
|
||||
{ 0x011 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */
|
||||
{ 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },
|
||||
{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 },
|
||||
|
||||
{ 0x018 ,M_TEXT ,1056 ,688, 132,44, 8, 8, 1 ,0xB0000 ,0x4000, 192, 800, 132, 704, 0 },
|
||||
{ 0x019 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1 ,0xB0000 ,0x2000, 192, 449, 132, 400, 0 },
|
||||
{ 0x01A ,M_TEXT ,1056 ,400, 132,28, 8, 16,1 ,0xB0000 ,0x2000, 192, 449, 132, 448, 0 },
|
||||
{ 0x022 ,M_TEXT ,1056 ,688, 132,44, 8, 8, 1 ,0xB8000 ,0x4000, 192, 800, 132, 704, 0 },
|
||||
{ 0x023 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1 ,0xB8000 ,0x2000, 192, 449, 132, 400, 0 },
|
||||
{ 0x024 ,M_TEXT ,1056 ,400, 132,28, 8, 16,1 ,0xB8000 ,0x2000, 192, 449, 132, 448, 0 },
|
||||
{ 0x025 ,M_LIN4 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 , 0 },
|
||||
{ 0x029 ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0xA000, 128 ,663 ,100,600 , 0 },
|
||||
{ 0x02D ,M_LIN8 ,640 ,350 ,80 ,21 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,350 , 0 },
|
||||
{ 0x02E ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 },
|
||||
{ 0x02F ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 },/* ET4000 only */
|
||||
{ 0x030 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 , 0 },
|
||||
{ 0x036 ,M_LIN4 ,960 , 720,120,45 ,8 ,16 ,1 ,0xA0000 ,0xA000, 120 ,800 ,120,720 , 0 },/* STB only */
|
||||
{ 0x037 ,M_LIN4 ,1024, 768,128,48 ,8 ,16 ,1 ,0xA0000 ,0xA000, 128 ,800 ,128,768 , 0 },
|
||||
{ 0x038 ,M_LIN8 ,1024 ,768,128,48 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,800 ,128,768 , 0 },/* ET4000 only */
|
||||
{ 0x03D ,M_LIN4 ,1280,1024,160,64 ,8 ,16 ,1 ,0xA0000 ,0xA000, 160 ,1152,160,1024, 0 },/* newer ET4000 */
|
||||
{ 0x03E ,M_LIN4 ,1280, 960,160,60 ,8 ,16 ,1 ,0xA0000 ,0xA000, 160 ,1024,160,960 , 0 },/* Definicon only */
|
||||
{ 0x06A ,M_LIN4 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0xA000, 128 ,663 ,100,600 , 0 },/* newer ET4000 */
|
||||
|
||||
{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 },
|
||||
};
|
||||
|
||||
VideoModeBlock ModeList_VGA_Paradise[]={
|
||||
/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */
|
||||
{ 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK },
|
||||
{ 0x001 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK },
|
||||
{ 0x002 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 },
|
||||
{ 0x003 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 },
|
||||
{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
|
||||
{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
|
||||
{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,1 ,0xB8000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
|
||||
{ 0x007 ,M_TEXT ,720 ,400 ,80 ,25 ,9 ,16 ,8 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 },
|
||||
|
||||
{ 0x00D ,M_EGA ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE },
|
||||
{ 0x00E ,M_EGA ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE },
|
||||
{ 0x00F ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },/*was EGA_2*/
|
||||
{ 0x010 ,M_EGA ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 },
|
||||
{ 0x011 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },/*was EGA_2 */
|
||||
{ 0x012 ,M_EGA ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 },
|
||||
{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x2000 ,100 ,449 ,80 ,400 ,0 },
|
||||
|
||||
{ 0x054 ,M_TEXT ,1056 ,688, 132,43, 8, 9, 1, 0xB0000, 0x4000, 192, 720, 132,688, 0 },
|
||||
{ 0x055 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1, 0xB0000, 0x2000, 192, 449, 132,400, 0 },
|
||||
{ 0x056 ,M_TEXT ,1056 ,688, 132,43, 8, 9, 1, 0xB0000, 0x4000, 192, 720, 132,688, 0 },
|
||||
{ 0x057 ,M_TEXT ,1056 ,400, 132,25, 8, 16,1, 0xB0000, 0x2000, 192, 449, 132,400, 0 },
|
||||
{ 0x058 ,M_LIN4 ,800 , 600, 100,37, 8, 16,1, 0xA0000, 0xA000, 128 ,663 ,100,600, 0 },
|
||||
{ 0x05D ,M_LIN4 ,1024, 768, 128,48 ,8, 16,1, 0xA0000, 0x10000,128 ,800 ,128,768 ,0 }, // documented only on C00 upwards
|
||||
{ 0x05E ,M_LIN8 ,640 , 400, 80 ,25, 8, 16,1, 0xA0000, 0x10000,100 ,449 ,80 ,400, 0 },
|
||||
{ 0x05F ,M_LIN8 ,640 , 480, 80 ,30, 8, 16,1, 0xA0000, 0x10000,100 ,525 ,80 ,480, 0 },
|
||||
|
||||
{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 },
|
||||
};
|
||||
|
||||
|
||||
VideoModeBlock ModeList_EGA[]={
|
||||
/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */
|
||||
{ 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,366 ,40 ,350 ,_EGA_HALF_CLOCK },
|
||||
|
@ -510,9 +583,29 @@ bool INT10_SetVideoMode(Bitu mode) {
|
|||
Bit8u modeset_ctl,video_ctl,vga_switches;
|
||||
|
||||
if (IS_VGA_ARCH) {
|
||||
if (!SetCurMode(ModeList_VGA,mode)){
|
||||
LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode);
|
||||
return false;
|
||||
if (svga.accepts_mode) {
|
||||
if (!svga.accepts_mode(mode)) return false;
|
||||
}
|
||||
|
||||
switch(svgaCard) {
|
||||
case SVGA_TsengET4K:
|
||||
case SVGA_TsengET3K:
|
||||
if (!SetCurMode(ModeList_VGA_Tseng,mode)){
|
||||
LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case SVGA_ParadisePVGA1A:
|
||||
if (!SetCurMode(ModeList_VGA_Paradise,mode)){
|
||||
LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode);
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (!SetCurMode(ModeList_VGA,mode)){
|
||||
LOG(LOG_INT10,LOG_ERROR)("VGA:Trying to set illegal mode %X",mode);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!SetCurMode(ModeList_EGA,mode)){
|
||||
|
@ -534,7 +627,7 @@ bool INT10_SetVideoMode(Bitu mode) {
|
|||
else crtc_base=0x3d4;
|
||||
|
||||
// Disable MMIO here so we can read / write memory
|
||||
if (IS_VGA_ARCH) IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0);
|
||||
if (IS_VGA_ARCH && svgaCard == SVGA_S3Trio) IO_Write(crtc_base,0x53);IO_Write(crtc_base+1,0x0);
|
||||
|
||||
/* Setup MISC Output Register */
|
||||
Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1);
|
||||
|
@ -744,10 +837,14 @@ bool INT10_SetVideoMode(Bitu mode) {
|
|||
|
||||
/* OverFlow */
|
||||
IO_Write(crtc_base,0x07);IO_Write(crtc_base+1,overflow);
|
||||
/* Extended Horizontal Overflow */
|
||||
IO_Write(crtc_base,0x5d);IO_Write(crtc_base+1,hor_overflow);
|
||||
/* Extended Vertical Overflow */
|
||||
IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow);
|
||||
|
||||
if (svgaCard == SVGA_S3Trio) {
|
||||
/* Extended Horizontal Overflow */
|
||||
IO_Write(crtc_base,0x5d);IO_Write(crtc_base+1,hor_overflow);
|
||||
/* Extended Vertical Overflow */
|
||||
IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow);
|
||||
}
|
||||
|
||||
/* Offset Register */
|
||||
Bitu offset;
|
||||
switch (CurMode->type) {
|
||||
|
@ -766,15 +863,18 @@ bool INT10_SetVideoMode(Bitu mode) {
|
|||
}
|
||||
IO_Write(crtc_base,0x13);
|
||||
IO_Write(crtc_base + 1,offset & 0xff);
|
||||
/* Extended System Control 2 Register */
|
||||
/* This register actually has more bits but only use the extended offset ones */
|
||||
IO_Write(crtc_base,0x51);
|
||||
IO_Write(crtc_base + 1,(offset & 0x300) >> 4);
|
||||
/* Clear remaining bits of the display start */
|
||||
IO_Write(crtc_base,0x69);
|
||||
IO_Write(crtc_base + 1,0);
|
||||
/* Extended Vertical Overflow */
|
||||
IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow);
|
||||
|
||||
if (svgaCard == SVGA_S3Trio) {
|
||||
/* Extended System Control 2 Register */
|
||||
/* This register actually has more bits but only use the extended offset ones */
|
||||
IO_Write(crtc_base,0x51);
|
||||
IO_Write(crtc_base + 1,(offset & 0x300) >> 4);
|
||||
/* Clear remaining bits of the display start */
|
||||
IO_Write(crtc_base,0x69);
|
||||
IO_Write(crtc_base + 1,0);
|
||||
/* Extended Vertical Overflow */
|
||||
IO_Write(crtc_base,0x5e);IO_Write(crtc_base+1,ver_overflow);
|
||||
}
|
||||
|
||||
/* Mode Control */
|
||||
Bit8u mode_control=0;
|
||||
|
@ -815,32 +915,36 @@ bool INT10_SetVideoMode(Bitu mode) {
|
|||
/* Renable write protection */
|
||||
IO_Write(crtc_base,0x11);
|
||||
IO_Write(crtc_base+1,IO_Read(crtc_base+1)|0x80);
|
||||
/* Setup the correct clock */
|
||||
if (CurMode->mode>=0x100) {
|
||||
misc_output|=0xef; //Select clock 3
|
||||
Bitu clock=CurMode->vtotal*8*CurMode->htotal*70;
|
||||
VGA_SetClock(3,clock/1000);
|
||||
|
||||
if (svgaCard == SVGA_S3Trio) {
|
||||
/* Setup the correct clock */
|
||||
if (CurMode->mode>=0x100) {
|
||||
misc_output|=0xef; //Select clock 3
|
||||
Bitu clock=CurMode->vtotal*8*CurMode->htotal*70;
|
||||
VGA_SetClock(3,clock/1000);
|
||||
}
|
||||
Bit8u misc_control_2;
|
||||
/* Setup Pixel format */
|
||||
switch (CurMode->type) {
|
||||
case M_LIN8:
|
||||
misc_control_2=0x00;
|
||||
break;
|
||||
case M_LIN15:
|
||||
misc_control_2=0x30;
|
||||
break;
|
||||
case M_LIN16:
|
||||
misc_control_2=0x50;
|
||||
break;
|
||||
case M_LIN32:
|
||||
misc_control_2=0xd0;
|
||||
break;
|
||||
default:
|
||||
misc_control_2=0x0;
|
||||
break;
|
||||
}
|
||||
IO_WriteB(crtc_base,0x67);IO_WriteB(crtc_base+1,misc_control_2);
|
||||
}
|
||||
Bit8u misc_control_2;
|
||||
/* Setup Pixel format */
|
||||
switch (CurMode->type) {
|
||||
case M_LIN8:
|
||||
misc_control_2=0x00;
|
||||
break;
|
||||
case M_LIN15:
|
||||
misc_control_2=0x30;
|
||||
break;
|
||||
case M_LIN16:
|
||||
misc_control_2=0x50;
|
||||
break;
|
||||
case M_LIN32:
|
||||
misc_control_2=0xd0;
|
||||
break;
|
||||
default:
|
||||
misc_control_2=0x0;
|
||||
break;
|
||||
}
|
||||
IO_WriteB(crtc_base,0x67);IO_WriteB(crtc_base+1,misc_control_2);
|
||||
|
||||
/* Write Misc Output */
|
||||
IO_Write(0x3c2,misc_output);
|
||||
/* Program Graphics controller */
|
||||
|
@ -1073,78 +1177,90 @@ dac_text16:
|
|||
}
|
||||
// disabled, has to be set in bios.cpp exclusively
|
||||
// real_writeb(BIOSMEM_SEG,BIOSMEM_INITIAL_MODE,feature);
|
||||
/* Setup the CPU Window */
|
||||
IO_Write(crtc_base,0x6a);
|
||||
IO_Write(crtc_base+1,0);
|
||||
/* Setup the linear frame buffer */
|
||||
IO_Write(crtc_base,0x59);
|
||||
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24));
|
||||
IO_Write(crtc_base,0x5a);
|
||||
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16));
|
||||
IO_Write(crtc_base,0x6b); // BIOS scratchpad
|
||||
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24));
|
||||
|
||||
/* Setup some remaining S3 registers */
|
||||
IO_Write(crtc_base,0x41); // BIOS scratchpad
|
||||
IO_Write(crtc_base+1,0x88);
|
||||
IO_Write(crtc_base,0x52); // extended BIOS scratchpad
|
||||
IO_Write(crtc_base+1,0x80);
|
||||
|
||||
IO_Write(0x3c4,0x15);
|
||||
IO_Write(0x3c5,0x03);
|
||||
if (svgaCard == SVGA_S3Trio) {
|
||||
/* Setup the CPU Window */
|
||||
IO_Write(crtc_base,0x6a);
|
||||
IO_Write(crtc_base+1,0);
|
||||
/* Setup the linear frame buffer */
|
||||
IO_Write(crtc_base,0x59);
|
||||
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24));
|
||||
IO_Write(crtc_base,0x5a);
|
||||
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 16));
|
||||
IO_Write(crtc_base,0x6b); // BIOS scratchpad
|
||||
IO_Write(crtc_base+1,(Bit8u)(S3_LFB_BASE >> 24));
|
||||
|
||||
/* Setup some remaining S3 registers */
|
||||
IO_Write(crtc_base,0x41); // BIOS scratchpad
|
||||
IO_Write(crtc_base+1,0x88);
|
||||
IO_Write(crtc_base,0x52); // extended BIOS scratchpad
|
||||
IO_Write(crtc_base+1,0x80);
|
||||
|
||||
// Accellerator setup
|
||||
Bitu reg_50=0;
|
||||
switch (CurMode->type) {
|
||||
case M_LIN15:
|
||||
case M_LIN16: reg_50|=0x10; break;
|
||||
case M_LIN32: reg_50|=0x30; break;
|
||||
}
|
||||
switch(CurMode->swidth)
|
||||
{
|
||||
case 640: reg_50|=0x40; break;
|
||||
case 800: reg_50|=0x80; break;
|
||||
case 1024: break;
|
||||
case 1152: reg_50|=0x01; break;
|
||||
case 1280: reg_50|=0xc1; break;
|
||||
}
|
||||
IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50);
|
||||
IO_Write(0x3c4,0x15);
|
||||
IO_Write(0x3c5,0x03);
|
||||
|
||||
Bitu reg_31, reg_3a;
|
||||
switch (CurMode->type) {
|
||||
// Accellerator setup
|
||||
Bitu reg_50=0;
|
||||
switch (CurMode->type) {
|
||||
case M_LIN15:
|
||||
case M_LIN16: reg_50|=0x10; break;
|
||||
case M_LIN32: reg_50|=0x30; break;
|
||||
}
|
||||
switch(CurMode->swidth) {
|
||||
case 640: reg_50|=0x40; break;
|
||||
case 800: reg_50|=0x80; break;
|
||||
case 1024: break;
|
||||
case 1152: reg_50|=0x01; break;
|
||||
case 1280: reg_50|=0xc1; break;
|
||||
}
|
||||
IO_WriteB(crtc_base,0x50); IO_WriteB(crtc_base+1,reg_50);
|
||||
|
||||
Bitu reg_31, reg_3a;
|
||||
switch (CurMode->type) {
|
||||
case M_LIN15:
|
||||
case M_LIN16:
|
||||
case M_LIN32:
|
||||
reg_3a=0x15;
|
||||
break;
|
||||
case M_LIN8:
|
||||
// S3VBE20 does it this way. The other double pixel bit does not
|
||||
// seem to have an effect on the Trio64.
|
||||
if(CurMode->special&_VGA_PIXEL_DOUBLE) reg_3a=0x5;
|
||||
else reg_3a=0x15;
|
||||
break;
|
||||
default:
|
||||
reg_3a=5;
|
||||
break;
|
||||
};
|
||||
|
||||
switch (CurMode->type) {
|
||||
case M_LIN4: // <- Theres a discrepance with real hardware on this
|
||||
case M_LIN8:
|
||||
case M_LIN15:
|
||||
case M_LIN16:
|
||||
case M_LIN32:
|
||||
reg_3a=0x15;
|
||||
break;
|
||||
case M_LIN8:
|
||||
// S3VBE20 does it this way. The other double pixel bit does not
|
||||
// seem to have an effect on the Trio64.
|
||||
if(CurMode->special&_VGA_PIXEL_DOUBLE) reg_3a=0x5;
|
||||
else reg_3a=0x15;
|
||||
reg_31 = 9;
|
||||
break;
|
||||
default:
|
||||
reg_3a=5;
|
||||
};
|
||||
|
||||
switch (CurMode->type) {
|
||||
case M_LIN4: // <- Theres a discrepance with real hardware on this
|
||||
case M_LIN8:
|
||||
case M_LIN15:
|
||||
case M_LIN16:
|
||||
case M_LIN32:
|
||||
reg_31 = 9;
|
||||
break;
|
||||
default:
|
||||
reg_31 = 5;
|
||||
break;
|
||||
}
|
||||
IO_Write(crtc_base,0x3a);IO_Write(crtc_base+1,reg_3a);
|
||||
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
|
||||
reg_31 = 5;
|
||||
break;
|
||||
}
|
||||
IO_Write(crtc_base,0x3a);IO_Write(crtc_base+1,reg_3a);
|
||||
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,0x38);IO_Write(crtc_base+1,0x48); //Register lock 1
|
||||
IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2
|
||||
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
|
||||
} else if (svga.set_video_mode) {
|
||||
VGA_ModeExtraData modeData;
|
||||
modeData.ver_overflow = ver_overflow;
|
||||
modeData.hor_overflow = hor_overflow;
|
||||
modeData.offset = offset;
|
||||
modeData.modeNo = CurMode->mode;
|
||||
modeData.htotal = CurMode->htotal;
|
||||
modeData.vtotal = CurMode->vtotal;
|
||||
svga.set_video_mode(crtc_base, &modeData);
|
||||
}
|
||||
|
||||
FinishSetMode(clearmem);
|
||||
/* Load text mode font */
|
||||
|
|
|
@ -513,12 +513,18 @@
|
|||
<File
|
||||
RelativePath="..\src\hardware\vga_other.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\hardware\vga_paradise.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\hardware\vga_s3.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\hardware\vga_seq.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\hardware\vga_tseng.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\src\hardware\vga_xga.cpp">
|
||||
</File>
|
||||
|
|
Loading…
Add table
Reference in a new issue