mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-25 18:11:50 +01:00
sync to dosbox 3635
This commit is contained in:
parent
2b06327229
commit
ce09efba36
@ -1,5 +1,5 @@
|
||||
dnl Init.
|
||||
AC_INIT(dosbox,0.74)
|
||||
AC_INIT(dosbox,SVN)
|
||||
AC_PREREQ(2.50)
|
||||
AC_CONFIG_SRCDIR(README)
|
||||
|
||||
|
@ -156,8 +156,9 @@ public:
|
||||
public:
|
||||
CFileInfo(void) {
|
||||
orgname[0] = shortname[0] = 0;
|
||||
nextEntry = shortNr = 0;
|
||||
isDir = false;
|
||||
id = MAX_OPENDIRS;
|
||||
nextEntry = shortNr = 0;
|
||||
}
|
||||
~CFileInfo(void) {
|
||||
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
|
||||
@ -167,6 +168,7 @@ public:
|
||||
char orgname [CROSS_LEN];
|
||||
char shortname [DOS_NAMELENGTH_ASCII];
|
||||
bool isDir;
|
||||
Bit16u id;
|
||||
Bitu nextEntry;
|
||||
Bitu shortNr;
|
||||
// contents
|
||||
@ -175,6 +177,8 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
void ClearFileInfo(CFileInfo *dir);
|
||||
void DeleteFileInfo(CFileInfo *dir);
|
||||
|
||||
bool RemoveTrailingDot (char* shortname);
|
||||
Bits GetLongName (CFileInfo* info, char* shortname);
|
||||
@ -203,7 +207,6 @@ private:
|
||||
Bit16u srchNr;
|
||||
CFileInfo* dirSearch [MAX_OPENDIRS];
|
||||
char dirSearchName [MAX_OPENDIRS];
|
||||
bool free [MAX_OPENDIRS];
|
||||
CFileInfo* dirFindFirst [MAX_OPENDIRS];
|
||||
Bit16u nextFreeFindFirst;
|
||||
|
||||
|
@ -114,7 +114,7 @@ typedef struct {
|
||||
typedef enum {
|
||||
PART,
|
||||
LINE,
|
||||
//EGALINE
|
||||
EGALINE
|
||||
} Drawmode;
|
||||
|
||||
typedef struct {
|
||||
@ -157,6 +157,8 @@ typedef struct {
|
||||
Bit8u font[64*1024];
|
||||
Bit8u * font_tables[2];
|
||||
Bitu blinking;
|
||||
bool blink;
|
||||
bool char9dot;
|
||||
struct {
|
||||
Bitu address;
|
||||
Bit8u sline,eline;
|
||||
|
@ -351,12 +351,16 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
|
||||
phys_writew(physAddress+0x02,(Bit16u)callback); //The immediate word
|
||||
physAddress+=4;
|
||||
}
|
||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
||||
phys_writew(physAddress+0x01,(Bit16u)0x0eb4); // mov ah, 0x0e
|
||||
phys_writew(physAddress+0x03,(Bit16u)0x10cd); // int 10
|
||||
phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax
|
||||
phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction
|
||||
return (use_cb?0x0b:0x07);
|
||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
||||
phys_writeb(physAddress+0x01,(Bit8u)0x53); // push bx
|
||||
phys_writew(physAddress+0x02,(Bit16u)0x0eb4); // mov ah, 0x0e
|
||||
phys_writeb(physAddress+0x04,(Bit8u)0xbb); // mov bx,
|
||||
phys_writew(physAddress+0x05,(Bit16u)0x0007); // 0x0007
|
||||
phys_writew(physAddress+0x07,(Bit16u)0x10cd); // int 10
|
||||
phys_writeb(physAddress+0x09,(Bit8u)0x5b); // pop bx
|
||||
phys_writeb(physAddress+0x0a,(Bit8u)0x58); // pop ax
|
||||
phys_writeb(physAddress+0x0b,(Bit8u)0xcf); //An IRET Instruction
|
||||
return (use_cb?0x10:0x0c);
|
||||
case CB_HOOKABLE:
|
||||
phys_writeb(physAddress+0x00,(Bit8u)0xEB); //jump near
|
||||
phys_writeb(physAddress+0x01,(Bit8u)0x03); //offset
|
||||
@ -456,7 +460,7 @@ Bitu CALLBACK_Setup(Bitu callback,CallBack_Handler handler,Bitu type,PhysPt addr
|
||||
}
|
||||
|
||||
void CALLBACK_RemoveSetup(Bitu callback) {
|
||||
for (Bitu i = 0;i < 16;i++) {
|
||||
for (Bitu i = 0;i < CB_SIZE;i++) {
|
||||
phys_writeb(CALLBACK_PhysPointer(callback)+i ,(Bit8u) 0x00);
|
||||
}
|
||||
}
|
||||
|
@ -31,6 +31,11 @@ typedef struct SMSF {
|
||||
unsigned char fr;
|
||||
} TMSF;
|
||||
|
||||
typedef struct SCtrl {
|
||||
Bit8u out[4]; // output channel
|
||||
Bit8u vol[4]; // channel volume
|
||||
} TCtrl;
|
||||
|
||||
extern int CDROM_GetMountType(char* path, int force);
|
||||
|
||||
class CDROM_Interface
|
||||
@ -52,6 +57,7 @@ public:
|
||||
virtual bool PlayAudioSector (unsigned long start,unsigned long len) = 0;
|
||||
virtual bool PauseAudio (bool resume) = 0;
|
||||
virtual bool StopAudio (void) = 0;
|
||||
virtual void ChannelControl (TCtrl ctrl) = 0;
|
||||
|
||||
virtual bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num) = 0;
|
||||
|
||||
@ -76,6 +82,7 @@ public:
|
||||
virtual bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||
virtual bool PauseAudio (bool resume);
|
||||
virtual bool StopAudio (void);
|
||||
virtual void ChannelControl (TCtrl ctrl) { return; };
|
||||
virtual bool ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return false; };
|
||||
virtual bool LoadUnloadMedia (bool unload);
|
||||
|
||||
@ -101,6 +108,7 @@ public:
|
||||
bool PlayAudioSector (unsigned long /*start*/,unsigned long /*len*/) { return true; };
|
||||
bool PauseAudio (bool /*resume*/) { return true; };
|
||||
bool StopAudio (void) { return true; };
|
||||
void ChannelControl (TCtrl ctrl) { return; };
|
||||
bool ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return true; };
|
||||
bool LoadUnloadMedia (bool /*unload*/) { return true; };
|
||||
};
|
||||
@ -166,6 +174,7 @@ public:
|
||||
bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||
bool PauseAudio (bool resume);
|
||||
bool StopAudio (void);
|
||||
void ChannelControl (TCtrl ctrl);
|
||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
bool LoadUnloadMedia (bool unload);
|
||||
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||
@ -188,6 +197,8 @@ static struct imagePlayer {
|
||||
int targetFrame;
|
||||
bool isPlaying;
|
||||
bool isPaused;
|
||||
bool ctrlUsed;
|
||||
TCtrl ctrlData;
|
||||
} player;
|
||||
|
||||
void ClearTracks();
|
||||
@ -234,6 +245,7 @@ public:
|
||||
bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||
bool PauseAudio (bool resume);
|
||||
bool StopAudio (void);
|
||||
void ChannelControl (TCtrl ctrl) { return; };
|
||||
|
||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
|
||||
@ -284,6 +296,7 @@ public:
|
||||
bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||
bool PauseAudio (bool resume);
|
||||
bool StopAudio (void);
|
||||
void ChannelControl (TCtrl ctrl);
|
||||
|
||||
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||
@ -338,6 +351,8 @@ private:
|
||||
int targetFrame;
|
||||
bool isPlaying;
|
||||
bool isPaused;
|
||||
bool ctrlUsed;
|
||||
TCtrl ctrlData;
|
||||
} player;
|
||||
|
||||
};
|
||||
|
@ -131,7 +131,7 @@ int CDROM_Interface_Image::AudioFile::getLength()
|
||||
int CDROM_Interface_Image::refCount = 0;
|
||||
CDROM_Interface_Image* CDROM_Interface_Image::images[26];
|
||||
CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = {
|
||||
NULL, NULL, NULL, {0}, 0, 0, 0, false, false };
|
||||
NULL, NULL, NULL, {0}, 0, 0, 0, false, false, false, {0} };
|
||||
|
||||
|
||||
CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit)
|
||||
@ -259,6 +259,12 @@ bool CDROM_Interface_Image::StopAudio(void)
|
||||
return true;
|
||||
}
|
||||
|
||||
void CDROM_Interface_Image::ChannelControl(TCtrl ctrl)
|
||||
{
|
||||
player.ctrlUsed = (ctrl.out[0]!=0 || ctrl.out[1]!=1 || ctrl.vol[0]<0xfe || ctrl.vol[1]<0xfe);
|
||||
player.ctrlData = ctrl;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
||||
{
|
||||
int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||
@ -336,6 +342,16 @@ void CDROM_Interface_Image::CDAudioCallBack(Bitu len)
|
||||
}
|
||||
}
|
||||
SDL_mutexV(player.mutex);
|
||||
if (player.ctrlUsed) {
|
||||
Bit16s sample0,sample1;
|
||||
Bit16s * samples=(Bit16s *)&player.buffer;
|
||||
for (Bitu pos=0;pos<len/4;pos++) {
|
||||
sample0=samples[pos*2+player.ctrlData.out[0]];
|
||||
sample1=samples[pos*2+player.ctrlData.out[1]];
|
||||
samples[pos*2+0]=(Bit16s)(sample0*player.ctrlData.vol[0]/255.0);
|
||||
samples[pos*2+1]=(Bit16s)(sample1*player.ctrlData.vol[1]/255.0);
|
||||
}
|
||||
}
|
||||
#if defined(WORDS_BIGENDIAN)
|
||||
player.channel->AddSamples_s16_nonnative(len/4,(Bit16s *)player.buffer);
|
||||
#else
|
||||
|
@ -175,7 +175,7 @@ bool CDROM_Interface_Ioctl::mci_CDPosition(int *position) {
|
||||
|
||||
|
||||
CDROM_Interface_Ioctl::dxPlayer CDROM_Interface_Ioctl::player = {
|
||||
NULL, NULL, NULL, 0, 0, 0, 0, 0, false, false };
|
||||
NULL, NULL, NULL, {0}, 0, 0, 0, false, false, false, {0} };
|
||||
|
||||
CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(cdioctl_cdatype ioctl_cda) {
|
||||
pathname[0] = 0;
|
||||
@ -462,6 +462,12 @@ bool CDROM_Interface_Ioctl::StopAudio(void) {
|
||||
return bStat>0;
|
||||
}
|
||||
|
||||
void CDROM_Interface_Ioctl::ChannelControl(TCtrl ctrl)
|
||||
{
|
||||
player.ctrlUsed = (ctrl.out[0]!=0 || ctrl.out[1]!=1 || ctrl.vol[0]<0xfe || ctrl.vol[1]<0xfe);
|
||||
player.ctrlData = ctrl;
|
||||
}
|
||||
|
||||
bool CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) {
|
||||
BOOL bStat;
|
||||
DWORD byteCount;
|
||||
@ -553,6 +559,16 @@ void CDROM_Interface_Ioctl::dx_CDAudioCallBack(Bitu len) {
|
||||
}
|
||||
}
|
||||
SDL_mutexV(player.mutex);
|
||||
if (player.ctrlUsed) {
|
||||
Bit16s sample0,sample1;
|
||||
Bit16s * samples=(Bit16s *)&player.buffer;
|
||||
for (Bitu pos=0;pos<len/4;pos++) {
|
||||
sample0=samples[pos*2+player.ctrlData.out[0]];
|
||||
sample1=samples[pos*2+player.ctrlData.out[1]];
|
||||
samples[pos*2+0]=(Bit16s)(sample0*player.ctrlData.vol[0]/255.0);
|
||||
samples[pos*2+1]=(Bit16s)(sample1*player.ctrlData.vol[1]/255.0);
|
||||
}
|
||||
}
|
||||
player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer);
|
||||
memmove(player.buffer, &player.buffer[len], player.bufLen - len);
|
||||
player.bufLen -= len;
|
||||
|
@ -227,10 +227,13 @@ static Bitu DOS_21Handler(void) {
|
||||
break;
|
||||
case 0x0c: /* Flush Buffer and read STDIN call */
|
||||
{
|
||||
/* flush STDIN-buffer */
|
||||
Bit8u c;Bit16u n;
|
||||
while (DOS_GetSTDINStatus()) {
|
||||
n=1; DOS_ReadFile(STDIN,&c,&n);
|
||||
/* flush buffer if STDIN is CON */
|
||||
Bit8u handle=RealHandle(STDIN);
|
||||
if (handle!=0xFF && Files[handle] && Files[handle]->IsName("CON")) {
|
||||
Bit8u c;Bit16u n;
|
||||
while (DOS_GetSTDINStatus()) {
|
||||
n=1; DOS_ReadFile(STDIN,&c,&n);
|
||||
}
|
||||
}
|
||||
switch (reg_al) {
|
||||
case 0x1:
|
||||
|
@ -203,6 +203,13 @@ bool DOS_GetCurrentDir(Bit8u drive,char * const buffer) {
|
||||
|
||||
bool DOS_ChangeDir(char const * const dir) {
|
||||
Bit8u drive;char fulldir[DOS_PATHLENGTH];
|
||||
const char * testdir=dir;
|
||||
if (strlen(testdir) && testdir[1]==':') testdir+=2;
|
||||
size_t len=strlen(testdir);
|
||||
if (!len || (len>1 && testdir[len-1]=='\\')) {
|
||||
DOS_SetError(DOSERR_PATH_NOT_FOUND);
|
||||
return false;
|
||||
}
|
||||
if (!DOS_MakeName(dir,fulldir,&drive)) return false;
|
||||
|
||||
if (Drives[drive]->TestDir(fulldir)) {
|
||||
|
@ -436,7 +436,7 @@ void DOS_SetupMemory(void) {
|
||||
if (machine==MCH_TANDY) {
|
||||
/* memory up to 608k available, the rest (to 640k) is used by
|
||||
the tandy graphics system's variable mapping of 0xb800 */
|
||||
mcb.SetSize(0x97FF - DOS_MEM_START - mcb_sizes);
|
||||
mcb.SetSize(0x9BFF - DOS_MEM_START - mcb_sizes);
|
||||
} else if (machine==MCH_PCJR) {
|
||||
/* memory from 128k to 640k is available */
|
||||
mcb_devicedummy.SetPt((Bit16u)0x2000);
|
||||
|
@ -152,6 +152,7 @@ private:
|
||||
bool locked; // drive locked ?
|
||||
bool lastResult; // last operation success ?
|
||||
Bit32u volumeSize; // for media change
|
||||
TCtrl audioCtrl; // audio channel control
|
||||
} TDriveInfo;
|
||||
|
||||
Bit16u defaultBufSeg;
|
||||
@ -160,6 +161,9 @@ private:
|
||||
|
||||
public:
|
||||
Bit16u rootDriverHeaderSeg;
|
||||
|
||||
bool ChannelControl (Bit8u subUnit, TCtrl ctrl);
|
||||
bool GetChannelControl (Bit8u subUnit, TCtrl& ctrl);
|
||||
};
|
||||
|
||||
CMscdex::CMscdex(void) {
|
||||
@ -368,25 +372,34 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
|
||||
devHeader.SetInterrupt(off+5);
|
||||
}
|
||||
|
||||
subUnit = (Bit8u)numDrives;
|
||||
// Set drive
|
||||
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
|
||||
devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1);
|
||||
|
||||
if (dinfo[0].drive-1==_drive) {
|
||||
CDROM_Interface *_cdrom = cdrom[numDrives];
|
||||
CDROM_Interface_Image *_cdimg = CDROM_Interface_Image::images[numDrives];
|
||||
for (Bit16u i=GetNumDrives(); i>0; i--) {
|
||||
dinfo[i] = dinfo[i-1];
|
||||
cdrom[i] = cdrom[i-1];
|
||||
CDROM_Interface_Image::images[i] = CDROM_Interface_Image::images[i-1];
|
||||
}
|
||||
cdrom[0] = _cdrom;
|
||||
CDROM_Interface_Image::images[0] = _cdimg;
|
||||
dinfo[0].drive = (Bit8u)_drive;
|
||||
dinfo[0].physDrive = (Bit8u)toupper(physicalPath[0]);
|
||||
subUnit = 0;
|
||||
} else {
|
||||
dinfo[numDrives].drive = (Bit8u)_drive;
|
||||
dinfo[numDrives].physDrive = (Bit8u)toupper(physicalPath[0]);
|
||||
subUnit = (Bit8u)numDrives;
|
||||
}
|
||||
numDrives++;
|
||||
// init channel control
|
||||
for (Bit8u chan=0;chan<4;chan++) {
|
||||
dinfo[subUnit].audioCtrl.out[chan]=chan;
|
||||
dinfo[subUnit].audioCtrl.vol[chan]=0xff;
|
||||
}
|
||||
// stop audio
|
||||
StopAudio(subUnit);
|
||||
return result;
|
||||
@ -459,7 +472,7 @@ bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length)
|
||||
if (subUnit>=numDrives) return false;
|
||||
// If value from last stop is used, this is meant as a resume
|
||||
// better start using resume command
|
||||
if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart)) {
|
||||
if (dinfo[subUnit].audioPaused && (sector==dinfo[subUnit].audioStart) && (dinfo[subUnit].audioEnd!=0)) {
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(true);
|
||||
} else
|
||||
dinfo[subUnit].lastResult = cdrom[subUnit]->PlayAudioSector(sector,length);
|
||||
@ -665,6 +678,7 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
||||
char entryName[256];
|
||||
bool foundComplete = false;
|
||||
bool foundName;
|
||||
bool nextPart = true;
|
||||
char* useName = 0;
|
||||
Bitu entryLength,nameLength;
|
||||
// clear error
|
||||
@ -695,14 +709,15 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
||||
if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false;
|
||||
// Get string part
|
||||
foundName = false;
|
||||
if (searchPos) {
|
||||
useName = searchPos;
|
||||
searchPos = strchr(searchPos,'\\');
|
||||
if (nextPart) {
|
||||
if (searchPos) {
|
||||
useName = searchPos;
|
||||
searchPos = strchr(searchPos,'\\');
|
||||
}
|
||||
if (searchPos) { *searchPos = 0; searchPos++; }
|
||||
else foundComplete = true;
|
||||
}
|
||||
|
||||
if (searchPos) { *searchPos = 0; searchPos++; }
|
||||
else foundComplete = true;
|
||||
|
||||
do {
|
||||
entryLength = mem_readb(defBuffer+index);
|
||||
if (entryLength==0) break;
|
||||
@ -759,10 +774,12 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
||||
// change directory
|
||||
dirEntrySector = mem_readd(defBuffer+index+2);
|
||||
dirSize = mem_readd(defBuffer+index+10);
|
||||
nextPart = true;
|
||||
} else {
|
||||
// continue search in next sector
|
||||
dirSize -= 2048;
|
||||
dirEntrySector++;
|
||||
nextPart = false;
|
||||
}
|
||||
};
|
||||
error = 2; // file not found
|
||||
@ -796,6 +813,7 @@ Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit)
|
||||
(dinfo[subUnit].locked << 1) | // Drive is locked ?
|
||||
(1<<2) | // raw + cooked sectors
|
||||
(1<<4) | // Can read sudio
|
||||
(1<<8) | // Can control audio
|
||||
(1<<9) | // Red book & HSG
|
||||
((!media) << 11); // Drive is empty ?
|
||||
return status;
|
||||
@ -860,6 +878,22 @@ void CMscdex::InitNewMedia(Bit8u subUnit) {
|
||||
}
|
||||
}
|
||||
|
||||
bool CMscdex::ChannelControl(Bit8u subUnit, TCtrl ctrl) {
|
||||
if (subUnit>=numDrives) return false;
|
||||
// adjust strange channel mapping
|
||||
if (ctrl.out[0]>1) ctrl.out[0]=0;
|
||||
if (ctrl.out[1]>1) ctrl.out[1]=1;
|
||||
dinfo[subUnit].audioCtrl=ctrl;
|
||||
cdrom[subUnit]->ChannelControl(ctrl);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMscdex::GetChannelControl(Bit8u subUnit, TCtrl& ctrl) {
|
||||
if (subUnit>=numDrives) return false;
|
||||
ctrl=dinfo[subUnit].audioCtrl;
|
||||
return true;
|
||||
}
|
||||
|
||||
static CMscdex* mscdex = 0;
|
||||
static PhysPt curReqheaderPtr = 0;
|
||||
|
||||
@ -889,6 +923,14 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) {
|
||||
return 0x03; // invalid function
|
||||
}
|
||||
}break;
|
||||
case 0x04 : /* Audio Channel control */
|
||||
TCtrl ctrl;
|
||||
if (!mscdex->GetChannelControl(drive_unit,ctrl)) return 0x01;
|
||||
for (Bit8u chan=0;chan<4;chan++) {
|
||||
mem_writeb(buffer+chan*2+1,ctrl.out[chan]);
|
||||
mem_writeb(buffer+chan*2+2,ctrl.vol[chan]);
|
||||
}
|
||||
break;
|
||||
case 0x06 : /* Get Device status */
|
||||
mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit));
|
||||
break;
|
||||
@ -980,7 +1022,13 @@ static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) {
|
||||
if (!mscdex->LoadUnloadMedia(drive_unit,true)) return 0x02;
|
||||
break;
|
||||
case 0x03: //Audio Channel control
|
||||
MSCDEX_LOG("MSCDEX: Audio Channel Control used. Not handled. Faking succes!");
|
||||
TCtrl ctrl;
|
||||
for (Bit8u chan=0;chan<4;chan++) {
|
||||
ctrl.out[chan]=mem_readb(buffer+chan*2+1);
|
||||
ctrl.vol[chan]=mem_readb(buffer+chan*2+2);
|
||||
}
|
||||
if (!mscdex->ChannelControl(drive_unit,ctrl)) return 0x01;
|
||||
break;
|
||||
case 0x01 : // (un)Lock door
|
||||
// do nothing -> report as success
|
||||
break;
|
||||
|
@ -67,7 +67,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) {
|
||||
srchNr = 0;
|
||||
label[0] = 0;
|
||||
nextFreeFindFirst = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; dirFindFirst[i] = 0; };
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; dirFindFirst[i] = 0; };
|
||||
SetDirSort(DIRALPHABETICAL);
|
||||
updatelabel = true;
|
||||
}
|
||||
@ -78,7 +78,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) {
|
||||
srchNr = 0;
|
||||
label[0] = 0;
|
||||
nextFreeFindFirst = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; free[i] = true; dirFindFirst[i] = 0; };
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { dirSearch[i] = 0; dirFindFirst[i] = 0; };
|
||||
SetDirSort(DIRALPHABETICAL);
|
||||
SetBaseDir(path);
|
||||
updatelabel = true;
|
||||
@ -86,11 +86,11 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) {
|
||||
|
||||
DOS_Drive_Cache::~DOS_Drive_Cache(void) {
|
||||
Clear();
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { delete dirFindFirst[i]; dirFindFirst[i]=0; };
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) { DeleteFileInfo(dirFindFirst[i]); dirFindFirst[i]=0; };
|
||||
}
|
||||
|
||||
void DOS_Drive_Cache::Clear(void) {
|
||||
delete dirBase; dirBase = 0;
|
||||
DeleteFileInfo(dirBase); dirBase = 0;
|
||||
nextFreeFindFirst = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) dirSearch[i] = 0;
|
||||
}
|
||||
@ -101,7 +101,6 @@ void DOS_Drive_Cache::EmptyCache(void) {
|
||||
dirBase = new CFileInfo;
|
||||
save_dir = 0;
|
||||
srchNr = 0;
|
||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) free[i] = true;
|
||||
SetBaseDir(basePath);
|
||||
}
|
||||
|
||||
@ -117,8 +116,16 @@ void DOS_Drive_Cache::SetLabel(const char* vname,bool cdrom,bool allowupdate) {
|
||||
}
|
||||
|
||||
Bit16u DOS_Drive_Cache::GetFreeID(CFileInfo* dir) {
|
||||
for (Bit16u i=0; i<MAX_OPENDIRS; i++) if (free[i] || (dir==dirSearch[i])) return i;
|
||||
if (dir->id != MAX_OPENDIRS)
|
||||
return dir->id;
|
||||
for (Bit16u i=0; i<MAX_OPENDIRS; i++) {
|
||||
if (!dirSearch[i]) {
|
||||
dir->id = i;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
LOG(LOG_FILES,LOG_NORMAL)("DIRCACHE: Too many open directories!");
|
||||
dir->id=0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -264,7 +271,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) {
|
||||
// delete file objects...
|
||||
for(Bit32u i=0; i<dir->fileList.size(); i++) {
|
||||
if (dirSearch[srchNr]==dir->fileList[i]) dirSearch[srchNr] = 0;
|
||||
delete dir->fileList[i]; dir->fileList[i] = 0;
|
||||
DeleteFileInfo(dir->fileList[i]); dir->fileList[i] = 0;
|
||||
}
|
||||
// clear lists
|
||||
dir->fileList.clear();
|
||||
@ -526,7 +533,10 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
|
||||
strcpy(buffer,dirPath);
|
||||
ReadDir(id,result);
|
||||
strcpy(dirPath,buffer);
|
||||
free[id] = true;
|
||||
if (dirSearch[id]) {
|
||||
dirSearch[id]->id = MAX_OPENDIRS;
|
||||
dirSearch[id] = 0;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
@ -556,7 +566,10 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
|
||||
strcpy(buffer,dirPath);
|
||||
ReadDir(id,result);
|
||||
strcpy(dirPath,buffer);
|
||||
free[id] = true;
|
||||
if (dirSearch[id]) {
|
||||
dirSearch[id]->id = MAX_OPENDIRS;
|
||||
dirSearch[id] = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
@ -600,9 +613,12 @@ bool DOS_Drive_Cache::OpenDir(CFileInfo* dir, const char* expand, Bit16u& id) {
|
||||
// Reset it..
|
||||
close_directory(dirp);
|
||||
strcpy(dirPath,expandcopy);
|
||||
free[id] = false;
|
||||
return true;
|
||||
}
|
||||
if (dirSearch[id]) {
|
||||
dirSearch[id]->id = MAX_OPENDIRS;
|
||||
dirSearch[id] = 0;
|
||||
}
|
||||
};
|
||||
return false;
|
||||
}
|
||||
@ -661,7 +677,10 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) {
|
||||
// Try to open directory
|
||||
dir_information* dirp = open_directory(dirPath);
|
||||
if (!dirp) {
|
||||
free[id] = true;
|
||||
if (dirSearch[id]) {
|
||||
dirSearch[id]->id = MAX_OPENDIRS;
|
||||
dirSearch[id] = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// Read complete directory
|
||||
@ -688,7 +707,10 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) {
|
||||
};*/
|
||||
};
|
||||
if (SetResult(dirSearch[id], result, dirSearch[id]->nextEntry)) return true;
|
||||
free[id] = true;
|
||||
if (dirSearch[id]) {
|
||||
dirSearch[id]->id = MAX_OPENDIRS;
|
||||
dirSearch[id] = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -732,7 +754,7 @@ bool DOS_Drive_Cache::FindFirst(char* path, Bit16u& id) {
|
||||
this->nextFreeFindFirst = 1; //the next free one after this search
|
||||
for(Bitu n=0; n<MAX_OPENDIRS;n++) {
|
||||
// Clear and reuse slot
|
||||
delete dirFindFirst[n];
|
||||
DeleteFileInfo(dirFindFirst[n]);
|
||||
dirFindFirst[n]=0;
|
||||
}
|
||||
|
||||
@ -767,8 +789,25 @@ bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result) {
|
||||
}
|
||||
if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) {
|
||||
// free slot
|
||||
delete dirFindFirst[id]; dirFindFirst[id] = 0;
|
||||
DeleteFileInfo(dirFindFirst[id]); dirFindFirst[id] = 0;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void DOS_Drive_Cache::ClearFileInfo(CFileInfo *dir) {
|
||||
for(Bit32u i=0; i<dir->fileList.size(); i++) {
|
||||
if (CFileInfo *info = dir->fileList[i])
|
||||
ClearFileInfo(info);
|
||||
}
|
||||
if (dir->id != MAX_OPENDIRS) {
|
||||
dirSearch[dir->id] = 0;
|
||||
dir->id = MAX_OPENDIRS;
|
||||
}
|
||||
}
|
||||
|
||||
void DOS_Drive_Cache::DeleteFileInfo(CFileInfo *dir) {
|
||||
if (dir)
|
||||
ClearFileInfo(dir);
|
||||
delete dir;
|
||||
}
|
||||
|
@ -289,7 +289,7 @@ bool isoDrive::FindNext(DOS_DTA &dta) {
|
||||
else findAttr |= DOS_ATTR_ARCHIVE;
|
||||
if (IS_HIDDEN(de.fileFlags)) findAttr |= DOS_ATTR_HIDDEN;
|
||||
|
||||
if (!(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern)
|
||||
if (!IS_ASSOC(de.fileFlags) && !(isRoot && de.ident[0]=='.') && WildFileCmp((char*)de.ident, pattern)
|
||||
&& !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) {
|
||||
|
||||
/* file is okay, setup everything to be copied in DTA Block */
|
||||
@ -541,7 +541,7 @@ bool isoDrive :: lookup(isoDirEntry *de, const char *path) {
|
||||
// look for the current path element
|
||||
int dirIterator = GetDirIterator(de);
|
||||
while (!found && GetNextDirEntry(dirIterator, de)) {
|
||||
if (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH)) {
|
||||
if (!IS_ASSOC(de->fileFlags) && (0 == strncasecmp((char*) de->ident, name, ISO_MAX_FILENAME_LENGTH))) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@ public:
|
||||
Bit16u GetInformation(void);
|
||||
bool UpdateDateTimeFromHost(void);
|
||||
void FlagReadOnlyMedium(void);
|
||||
void Flush(void);
|
||||
private:
|
||||
FILE * fhandle;
|
||||
bool read_only_medium;
|
||||
@ -95,6 +96,22 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
|
||||
CROSS_FILENAME(newname);
|
||||
dirCache.ExpandName(newname);
|
||||
|
||||
//Flush the buffer of handles for the same file. (Betrayal in Antara)
|
||||
Bit8u i,drive=DOS_DRIVES;
|
||||
localFile *lfp;
|
||||
for (i=0;i<DOS_DRIVES;i++) {
|
||||
if (Drives[i]==this) {
|
||||
drive=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i=0;i<DOS_FILES;i++) {
|
||||
if (Files[i] && Files[i]->IsOpen() && Files[i]->GetDrive()==drive && Files[i]->IsName(name)) {
|
||||
lfp=dynamic_cast<localFile*>(Files[i]);
|
||||
if (lfp) lfp->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
FILE * hand=fopen(newname,type);
|
||||
// Bit32u err=errno;
|
||||
if (!hand) {
|
||||
@ -541,6 +558,13 @@ bool localFile::UpdateDateTimeFromHost(void) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void localFile::Flush(void) {
|
||||
if (last_action==WRITE) {
|
||||
fseek(fhandle,ftell(fhandle),SEEK_SET);
|
||||
last_action=NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ********************************************
|
||||
// CDROM DRIVE
|
||||
|
@ -298,11 +298,13 @@ struct isoDirEntry {
|
||||
#endif
|
||||
|
||||
#define ISO_FRAMESIZE 2048
|
||||
#define ISO_ASSOCIATED 4
|
||||
#define ISO_DIRECTORY 2
|
||||
#define ISO_HIDDEN 1
|
||||
#define ISO_MAX_FILENAME_LENGTH 37
|
||||
#define ISO_MAXPATHNAME 256
|
||||
#define ISO_FIRST_VD 16
|
||||
#define IS_ASSOC(fileFlags) (fileFlags & ISO_ASSOCIATED)
|
||||
#define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY)
|
||||
#define IS_HIDDEN(fileFlags) (fileFlags & ISO_HIDDEN)
|
||||
#define ISO_MAX_HASH_TABLE_SIZE 100
|
||||
|
@ -504,6 +504,8 @@ static void GenerateDMASound(Bitu size) {
|
||||
sb.dma.left-=read;
|
||||
if (!sb.dma.left) {
|
||||
PIC_RemoveEvents(END_DMA_Event);
|
||||
if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16);
|
||||
else SB_RaiseIRQ(SB_IRQ_8);
|
||||
if (!sb.dma.autoinit) {
|
||||
LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended");
|
||||
sb.mode=MODE_NONE;
|
||||
@ -515,8 +517,6 @@ static void GenerateDMASound(Bitu size) {
|
||||
sb.mode=MODE_NONE;
|
||||
}
|
||||
}
|
||||
if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16);
|
||||
else SB_RaiseIRQ(SB_IRQ_8);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1345,7 +1345,8 @@ static Bit8u CTMIXER_Read(void) {
|
||||
return ret;
|
||||
case 0x82: /* IRQ Status */
|
||||
return (sb.irq.pending_8bit ? 0x1 : 0) |
|
||||
(sb.irq.pending_16bit ? 0x2 : 0);
|
||||
(sb.irq.pending_16bit ? 0x2 : 0) |
|
||||
((sb.type == SBT_16) ? 0x20 : 0);
|
||||
default:
|
||||
if ( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */
|
||||
(sb.type == SBT_16 && sb.mixer.index >= 0x3b && sb.mixer.index <= 0x47)) /* New SB16 registers */
|
||||
|
@ -76,26 +76,33 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
|
||||
10h and 14h.
|
||||
*/
|
||||
break;
|
||||
case 0x10: /* Mode Control Register */
|
||||
case 0x10: { /* Mode Control Register */
|
||||
if (!IS_VGA_ARCH) val&=0x1f; // not really correct, but should do it
|
||||
if ((attr(mode_control) ^ val) & 0x80) {
|
||||
attr(mode_control)^=0x80;
|
||||
for (Bit8u i=0;i<0x10;i++) {
|
||||
Bitu difference = attr(mode_control)^val;
|
||||
attr(mode_control)=(Bit8u)val;
|
||||
|
||||
if (difference & 0x80) {
|
||||
for (Bit8u i=0;i<0x10;i++)
|
||||
VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
|
||||
}
|
||||
if (difference & 0x08)
|
||||
VGA_SetBlinking(val & 0x8);
|
||||
|
||||
if (difference & 0x41)
|
||||
VGA_DetermineMode();
|
||||
|
||||
if (difference & 0x04) {
|
||||
// recompute the panning value
|
||||
if(vga.mode==M_TEXT) {
|
||||
Bit8u pan_reg = attr(horizontal_pel_panning);
|
||||
if (pan_reg > 7)
|
||||
vga.config.pel_panning=0;
|
||||
else if (val&0x4) // 9-dot wide characters
|
||||
vga.config.pel_panning=(Bit8u)(pan_reg+1);
|
||||
else // 8-dot characters
|
||||
vga.config.pel_panning=(Bit8u)pan_reg;
|
||||
}
|
||||
}
|
||||
if ((attr(mode_control) ^ val) & 0x08) {
|
||||
VGA_SetBlinking(val & 0x8);
|
||||
}
|
||||
if ((attr(mode_control) ^ val) & 0x04) {
|
||||
attr(mode_control)=(Bit8u)val;
|
||||
VGA_DetermineMode();
|
||||
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) VGA_StartResize();
|
||||
} else {
|
||||
attr(mode_control)=(Bit8u)val;
|
||||
VGA_DetermineMode();
|
||||
}
|
||||
|
||||
/*
|
||||
0 Graphics mode if set, Alphanumeric mode else.
|
||||
1 Monochrome mode if set, color mode else.
|
||||
@ -113,6 +120,7 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
|
||||
used.
|
||||
*/
|
||||
break;
|
||||
}
|
||||
case 0x11: /* Overscan Color Register */
|
||||
attr(overscan_color)=(Bit8u)val;
|
||||
/* 0-5 Color of screen border. Color is defined as in the palette registers. */
|
||||
@ -134,9 +142,12 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
|
||||
attr(horizontal_pel_panning)=val & 0xF;
|
||||
switch (vga.mode) {
|
||||
case M_TEXT:
|
||||
if ((val==0x7) && (svgaCard==SVGA_None)) vga.config.pel_panning=7;
|
||||
if (val>0x7) vga.config.pel_panning=0;
|
||||
else vga.config.pel_panning=(Bit8u)(val+1);
|
||||
if (val > 7)
|
||||
vga.config.pel_panning=0;
|
||||
else if (vga.attr.mode_control&0x4) // 9-dot wide characters
|
||||
vga.config.pel_panning=(Bit8u)(val+1);
|
||||
else // 8-dot characters
|
||||
vga.config.pel_panning=(Bit8u)val;
|
||||
break;
|
||||
case M_VGA:
|
||||
case M_LIN8:
|
||||
@ -146,6 +157,9 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
|
||||
default:
|
||||
vga.config.pel_panning=(val & 0x7);
|
||||
}
|
||||
if (machine==MCH_EGA)
|
||||
// On the EGA panning can be programmed for every scanline:
|
||||
vga.draw.panning = vga.config.pel_panning;
|
||||
/*
|
||||
0-3 Indicates number of pixels to shift the display left
|
||||
Value 9bit textmode 256color mode Other modes
|
||||
|
@ -155,7 +155,7 @@ static Bit8u * VGA_Draw_Changes_Line(Bitu vidstart, Bitu line) {
|
||||
for (; start <= end;start++) {
|
||||
if ( map[start] & checkMask ) {
|
||||
Bitu offset = vidstart & vga.draw.linear_mask;
|
||||
if(vga.draw.linear_mask-offset < vga.draw.line_length)
|
||||
if (vga.draw.linear_mask-offset < vga.draw.line_length)
|
||||
memcpy(vga.draw.linear_base+vga.draw.linear_mask+1, vga.draw.linear_base, vga.draw.line_length);
|
||||
Bit8u *ret = &vga.draw.linear_base[ offset ];
|
||||
#if !defined(C_UNALIGNED_MEMORY)
|
||||
@ -197,14 +197,6 @@ static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu /*line*/) {
|
||||
temps[i]=vga.dac.xlat16[ret[i]];
|
||||
}
|
||||
return TempLine;
|
||||
/*
|
||||
#if !defined(C_UNALIGNED_MEMORY)
|
||||
if (GCC_UNLIKELY( ((Bitu)ret) & (sizeof(Bitu)-1)) ) {
|
||||
memcpy( TempLine, ret, vga.draw.line_length );
|
||||
return TempLine;
|
||||
}
|
||||
#endif
|
||||
return ret;*/
|
||||
}
|
||||
|
||||
//Test version, might as well keep it
|
||||
@ -446,167 +438,121 @@ static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) {
|
||||
skip_cursor:
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
static Bit8u * VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) {
|
||||
Bits font_addr;
|
||||
Bit16u * draw=(Bit16u *)TempLine;
|
||||
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
|
||||
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
|
||||
Bitu chr=vidmem[cx*2];
|
||||
Bitu col=vidmem[cx*2+1];
|
||||
Bitu font=vga.draw.font_tables[(col >> 3)&1][chr*32+line];
|
||||
Bit32u mask1=TXT_Font_Table[font>>4] & FontMask[col >> 7];
|
||||
Bit32u mask2=TXT_Font_Table[font&0xf] & FontMask[col >> 7];
|
||||
Bit32u fg=TXT_FG_Table[col&0xf];
|
||||
Bit32u bg=TXT_BG_Table[col>>4];
|
||||
|
||||
mask1=(fg&mask1) | (bg&~mask1);
|
||||
mask2=(fg&mask2) | (bg&~mask2);
|
||||
|
||||
for(int i = 0; i < 4; i++) {
|
||||
*draw++ = vga.dac.xlat16[(mask1>>8*i)&0xff];
|
||||
}
|
||||
for(int i = 0; i < 4; i++) {
|
||||
*draw++ = vga.dac.xlat16[(mask2>>8*i)&0xff];
|
||||
}
|
||||
}
|
||||
if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor;
|
||||
font_addr = (vga.draw.cursor.address-vidstart) >> 1;
|
||||
if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) {
|
||||
if (line<vga.draw.cursor.sline) goto skip_cursor;
|
||||
if (line>vga.draw.cursor.eline) goto skip_cursor;
|
||||
draw=(Bit16u *)&TempLine[font_addr*16];
|
||||
Bit8u att=(Bit8u)(TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf]&0xff);
|
||||
for(int i = 0; i < 8; i++) {
|
||||
*draw++ = vga.dac.xlat16[att];
|
||||
}
|
||||
}
|
||||
skip_cursor:
|
||||
return TempLine;
|
||||
}
|
||||
|
||||
/*
|
||||
static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) {
|
||||
Bits font_addr;
|
||||
Bit8u * draw=(Bit8u *)TempLine;
|
||||
bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line;
|
||||
Bit8u pel_pan=(Bit8u)vga.draw.panning;
|
||||
if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0;
|
||||
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
|
||||
Bit8u chr=vidmem[0];
|
||||
Bit8u col=vidmem[1];
|
||||
Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
|
||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
||||
Bit8u fg=col&0xf;
|
||||
Bit8u bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
||||
Bitu draw_blocks=vga.draw.blocks;
|
||||
draw_blocks++;
|
||||
for (Bitu cx=1;cx<draw_blocks;cx++) {
|
||||
if (pel_pan) {
|
||||
chr=vidmem[cx*2];
|
||||
col=vidmem[cx*2+1];
|
||||
if (underline && ((col&0x07) == 0x01)) font|=0xff>>(8-pel_pan);
|
||||
else font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan);
|
||||
fg=col&0xf;
|
||||
bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
||||
// combined 8/9-dot wide text mode 8bpp line drawing function
|
||||
static Bit8u* VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) {
|
||||
// keep it aligned:
|
||||
Bit8u* draw = ((Bit8u*)TempLine) + 16 - vga.draw.panning;
|
||||
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs
|
||||
Bitu blocks = vga.draw.blocks;
|
||||
if (vga.draw.panning) blocks++; // if the text is panned part of an
|
||||
// additional character becomes visible
|
||||
while (blocks--) { // for each character in the line
|
||||
Bitu chr = *vidmem++;
|
||||
Bitu attr = *vidmem++;
|
||||
// the font pattern
|
||||
Bitu font = vga.draw.font_tables[(attr >> 3)&1][(chr<<5)+line];
|
||||
|
||||
Bitu background = attr >> 4;
|
||||
// if blinking is enabled bit7 is not mapped to attributes
|
||||
if (vga.draw.blinking) background &= ~0x8;
|
||||
// choose foreground color if blinking not set for this cell or blink on
|
||||
Bitu foreground = (vga.draw.blink || (!(attr&0x80)))?
|
||||
(attr&0xf):background;
|
||||
// underline: all foreground [freevga: 0x77, previous 0x7]
|
||||
if (GCC_UNLIKELY(((attr&0x77) == 0x01) &&
|
||||
(vga.crtc.underline_location&0x1f)==line))
|
||||
background = foreground;
|
||||
if (vga.draw.char9dot) {
|
||||
font <<=1; // 9 pixels
|
||||
// extend to the 9th pixel if needed
|
||||
if ((font&0x2) && (vga.attr.mode_control&0x04) &&
|
||||
(chr>=0xc0) && (chr<=0xdf)) font |= 1;
|
||||
for (Bitu n = 0; n < 9; n++) {
|
||||
*draw++ = (font&0x100)? foreground:background;
|
||||
font <<= 1;
|
||||
}
|
||||
} else {
|
||||
chr=vidmem[(cx-1)*2];
|
||||
col=vidmem[(cx-1)*2+1];
|
||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
||||
else font=vga.draw.font_tables[(col >> 3)&1][chr*32+line];
|
||||
fg=col&0xf;
|
||||
bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
||||
}
|
||||
if (FontMask[col>>7]==0) font=0;
|
||||
*draw++=(font&0x80)?fg:bg; *draw++=(font&0x40)?fg:bg;
|
||||
*draw++=(font&0x20)?fg:bg; *draw++=(font&0x10)?fg:bg;
|
||||
*draw++=(font&0x08)?fg:bg; *draw++=(font&0x04)?fg:bg;
|
||||
*draw++=(font&0x02)?fg:bg;
|
||||
Bit8u last=(font&0x01)?fg:bg;
|
||||
*draw++=last;
|
||||
*draw++=((vga.attr.mode_control&0x04) && ((chr<0xc0) || (chr>0xdf))) ? bg : last;
|
||||
if (pel_pan) {
|
||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
||||
else font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
|
||||
for (Bitu n = 0; n < 8; n++) {
|
||||
*draw++ = (font&0x80)? foreground:background;
|
||||
font <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor;
|
||||
font_addr = (vga.draw.cursor.address-vidstart) >> 1;
|
||||
if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) {
|
||||
if (line<vga.draw.cursor.sline) goto skip_cursor;
|
||||
if (line>vga.draw.cursor.eline) goto skip_cursor;
|
||||
draw=&TempLine[font_addr*9];
|
||||
Bit8u fg=vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf;
|
||||
*draw++=fg; *draw++=fg; *draw++=fg; *draw++=fg;
|
||||
*draw++=fg; *draw++=fg; *draw++=fg; *draw++=fg;
|
||||
// draw the text mode cursor if needed
|
||||
if ((vga.draw.cursor.count&0x8) && (line >= vga.draw.cursor.sline) &&
|
||||
(line <= vga.draw.cursor.eline) && vga.draw.cursor.enabled) {
|
||||
// the adress of the attribute that makes up the cell the cursor is in
|
||||
Bits attr_addr = (vga.draw.cursor.address-vidstart) >> 1;
|
||||
if (attr_addr >= 0 && attr_addr < (Bits)vga.draw.blocks) {
|
||||
Bitu index = attr_addr * (vga.draw.char9dot? 9:8);
|
||||
draw = (Bit8u*)(&TempLine[index]) + 16 - vga.draw.panning;
|
||||
|
||||
Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf;
|
||||
for (Bitu i = 0; i < 8; i++) {
|
||||
*draw++ = foreground;
|
||||
}
|
||||
}
|
||||
}
|
||||
skip_cursor:
|
||||
return TempLine;
|
||||
return TempLine+16;
|
||||
}
|
||||
*/
|
||||
|
||||
static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) {
|
||||
Bits font_addr;
|
||||
Bit16u * draw=(Bit16u *)TempLine;
|
||||
bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line;
|
||||
Bit8u pel_pan=(Bit8u)vga.draw.panning;
|
||||
if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0;
|
||||
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
|
||||
Bit8u chr=vidmem[0];
|
||||
Bit8u col=vidmem[1];
|
||||
Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
|
||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
||||
Bit8u fg=col&0xf;
|
||||
Bit8u bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
||||
Bitu draw_blocks=vga.draw.blocks;
|
||||
draw_blocks++;
|
||||
for (Bitu cx=1;cx<draw_blocks;cx++) {
|
||||
if (pel_pan) {
|
||||
chr=vidmem[cx*2];
|
||||
col=vidmem[cx*2+1];
|
||||
if (underline && ((col&0x07) == 0x01)) font|=0xff>>(8-pel_pan);
|
||||
else font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan);
|
||||
fg=col&0xf;
|
||||
bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
||||
// combined 8/9-dot wide text mode 16bpp line drawing function
|
||||
static Bit8u* VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) {
|
||||
// keep it aligned:
|
||||
Bit16u* draw = ((Bit16u*)TempLine) + 16 - vga.draw.panning;
|
||||
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs
|
||||
Bitu blocks = vga.draw.blocks;
|
||||
if (vga.draw.panning) blocks++; // if the text is panned part of an
|
||||
// additional character becomes visible
|
||||
while (blocks--) { // for each character in the line
|
||||
Bitu chr = *vidmem++;
|
||||
Bitu attr = *vidmem++;
|
||||
// the font pattern
|
||||
Bitu font = vga.draw.font_tables[(attr >> 3)&1][(chr<<5)+line];
|
||||
|
||||
Bitu background = attr >> 4;
|
||||
// if blinking is enabled bit7 is not mapped to attributes
|
||||
if (vga.draw.blinking) background &= ~0x8;
|
||||
// choose foreground color if blinking not set for this cell or blink on
|
||||
Bitu foreground = (vga.draw.blink || (!(attr&0x80)))?
|
||||
(attr&0xf):background;
|
||||
// underline: all foreground [freevga: 0x77, previous 0x7]
|
||||
if (GCC_UNLIKELY(((attr&0x77) == 0x01) &&
|
||||
(vga.crtc.underline_location&0x1f)==line))
|
||||
background = foreground;
|
||||
if (vga.draw.char9dot) {
|
||||
font <<=1; // 9 pixels
|
||||
// extend to the 9th pixel if needed
|
||||
if ((font&0x2) && (vga.attr.mode_control&0x04) &&
|
||||
(chr>=0xc0) && (chr<=0xdf)) font |= 1;
|
||||
for (Bitu n = 0; n < 9; n++) {
|
||||
*draw++ = vga.dac.xlat16[(font&0x100)? foreground:background];
|
||||
font <<= 1;
|
||||
}
|
||||
} else {
|
||||
chr=vidmem[(cx-1)*2];
|
||||
col=vidmem[(cx-1)*2+1];
|
||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
||||
else font=vga.draw.font_tables[(col >> 3)&1][chr*32+line];
|
||||
fg=col&0xf;
|
||||
bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
||||
}
|
||||
if (FontMask[col>>7]==0) font=0;
|
||||
Bit8u mask=0x80;
|
||||
for (int i = 0; i < 7; i++) {
|
||||
*draw++=vga.dac.xlat16[font&mask?fg:bg];
|
||||
mask>>=1;
|
||||
}
|
||||
Bit16u lastval=vga.dac.xlat16[font&mask?fg:bg];
|
||||
*draw++=lastval;
|
||||
*draw++=(((vga.attr.mode_control&0x04) && ((chr<0xc0) || (chr>0xdf))) &&
|
||||
!(underline && ((col&0x07) == 0x01))) ?
|
||||
(vga.dac.xlat16[bg]) : lastval;
|
||||
if (pel_pan) {
|
||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
||||
else font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
|
||||
for (Bitu n = 0; n < 8; n++) {
|
||||
*draw++ = vga.dac.xlat16[(font&0x80)? foreground:background];
|
||||
font <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor;
|
||||
font_addr = (vga.draw.cursor.address-vidstart) >> 1;
|
||||
if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) {
|
||||
if (line<vga.draw.cursor.sline) goto skip_cursor;
|
||||
if (line>vga.draw.cursor.eline) goto skip_cursor;
|
||||
draw=(Bit16u*)&TempLine[font_addr*18];
|
||||
Bit8u fg=vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
*draw++ = vga.dac.xlat16[fg];
|
||||
// draw the text mode cursor if needed
|
||||
if ((vga.draw.cursor.count&0x8) && (line >= vga.draw.cursor.sline) &&
|
||||
(line <= vga.draw.cursor.eline) && vga.draw.cursor.enabled) {
|
||||
// the adress of the attribute that makes up the cell the cursor is in
|
||||
Bits attr_addr = (vga.draw.cursor.address-vidstart) >> 1;
|
||||
if (attr_addr >= 0 && attr_addr < (Bits)vga.draw.blocks) {
|
||||
Bitu index = attr_addr * (vga.draw.char9dot? 18:16);
|
||||
draw = (Bit16u*)(&TempLine[index]) + 16 - vga.draw.panning;
|
||||
|
||||
Bitu foreground = vga.tandy.draw_base[vga.draw.cursor.address+1] & 0xf;
|
||||
for (Bitu i = 0; i < 8; i++) {
|
||||
*draw++ = vga.dac.xlat16[foreground];
|
||||
}
|
||||
}
|
||||
//if(underline && ((col&0x07) == 0x01))
|
||||
// *draw = vga.dac.xlat16[fg];
|
||||
}
|
||||
skip_cursor:
|
||||
return TempLine;
|
||||
return TempLine+32;
|
||||
}
|
||||
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
@ -628,14 +574,17 @@ static INLINE void VGA_ChangesEnd(void ) {
|
||||
|
||||
|
||||
static void VGA_ProcessSplit() {
|
||||
// On the EGA the address is always reset to 0.
|
||||
if ((vga.attr.mode_control&0x20) || (machine==MCH_EGA)) {
|
||||
if (vga.attr.mode_control&0x20) {
|
||||
vga.draw.address=0;
|
||||
// reset panning to 0 here so we don't have to check for
|
||||
// it in the character draw functions. It will be set back
|
||||
// to its proper value in v-retrace
|
||||
vga.draw.panning=0;
|
||||
} else {
|
||||
// In text mode only the characters are shifted by panning, not the address;
|
||||
// this is done in the text line draw function.
|
||||
vga.draw.address = vga.draw.byte_panning_shift*vga.draw.bytes_skip;
|
||||
if (!(vga.mode==M_TEXT)) vga.draw.address += vga.draw.panning;
|
||||
if ((vga.mode!=M_TEXT)&&(machine!=MCH_EGA)) vga.draw.address += vga.draw.panning;
|
||||
}
|
||||
vga.draw.address_line=0;
|
||||
}
|
||||
@ -662,6 +611,29 @@ static void VGA_DrawSingleLine(Bitu /*blah*/) {
|
||||
} else RENDER_EndUpdate(false);
|
||||
}
|
||||
|
||||
static void VGA_DrawEGASingleLine(Bitu /*blah*/) {
|
||||
if (GCC_UNLIKELY(vga.attr.disabled)) {
|
||||
memset(TempLine, 0, sizeof(TempLine));
|
||||
RENDER_DrawLine(TempLine);
|
||||
} else {
|
||||
Bitu address = vga.draw.address;
|
||||
if (vga.mode!=M_TEXT) address += vga.draw.panning;
|
||||
Bit8u * data=VGA_DrawLine(address, vga.draw.address_line );
|
||||
RENDER_DrawLine(data);
|
||||
}
|
||||
|
||||
vga.draw.address_line++;
|
||||
if (vga.draw.address_line>=vga.draw.address_line_total) {
|
||||
vga.draw.address_line=0;
|
||||
vga.draw.address+=vga.draw.address_add;
|
||||
}
|
||||
vga.draw.lines_done++;
|
||||
if (vga.draw.split_line==vga.draw.lines_done) VGA_ProcessSplit();
|
||||
if (vga.draw.lines_done < vga.draw.lines_total) {
|
||||
PIC_AddEvent(VGA_DrawEGASingleLine,(float)vga.draw.delay.htotal);
|
||||
} else RENDER_EndUpdate(false);
|
||||
}
|
||||
|
||||
static void VGA_DrawPart(Bitu lines) {
|
||||
while (lines--) {
|
||||
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
|
||||
@ -771,7 +743,6 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
||||
VGA_DisplayStartLatch(0);
|
||||
break;
|
||||
case MCH_VGA:
|
||||
case MCH_EGA:
|
||||
PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrstart);
|
||||
PIC_AddEvent(VGA_PanningLatch, (float)vga.draw.delay.vrend);
|
||||
// EGA: 82c435 datasheet: interrupt happens at display end
|
||||
@ -779,6 +750,10 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
||||
// add a little amount of time to make sure the last drawpart has already fired
|
||||
PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005));
|
||||
break;
|
||||
case MCH_EGA:
|
||||
PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrend);
|
||||
PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005));
|
||||
break;
|
||||
default:
|
||||
E_Exit("This new machine needs implementation in VGA_VerticalTimer too.");
|
||||
break;
|
||||
@ -798,7 +773,11 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
||||
vga.draw.address = vga.config.real_start;
|
||||
vga.draw.byte_panning_shift = 0;
|
||||
// go figure...
|
||||
if (machine==MCH_EGA) vga.draw.split_line*=2;
|
||||
if (machine==MCH_EGA) {
|
||||
if (vga.draw.doubleheight) // Spacepigs EGA Megademo
|
||||
vga.draw.split_line*=2;
|
||||
vga.draw.split_line++; // EGA adds one buggy scanline
|
||||
}
|
||||
// if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled);
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
bool startaddr_changed=false;
|
||||
@ -811,13 +790,13 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
||||
vga.draw.byte_panning_shift = 8;
|
||||
vga.draw.address += vga.draw.bytes_skip;
|
||||
vga.draw.address *= vga.draw.byte_panning_shift;
|
||||
vga.draw.address += vga.draw.panning;
|
||||
if (machine!=MCH_EGA) vga.draw.address += vga.draw.panning;
|
||||
#ifdef VGA_KEEP_CHANGES
|
||||
startaddr_changed=true;
|
||||
#endif
|
||||
break;
|
||||
case M_VGA:
|
||||
if(vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) {
|
||||
if (vga.config.compatible_chain4 && (vga.crtc.underline_location & 0x40)) {
|
||||
vga.draw.linear_base = vga.fastmem;
|
||||
vga.draw.linear_mask = 0xffff;
|
||||
} else {
|
||||
@ -851,6 +830,10 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
||||
/* check for blinking and blinking change delay */
|
||||
FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ?
|
||||
0 : 0xffffffff;
|
||||
/* if blinking is enabled, 'blink' will toggle between true
|
||||
* and false. Otherwise it's true */
|
||||
vga.draw.blink = ((vga.draw.blinking & (vga.draw.cursor.count >> 4))
|
||||
|| !vga.draw.blinking) ? true:false;
|
||||
break;
|
||||
case M_HERC_GFX:
|
||||
break;
|
||||
@ -889,16 +872,19 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
||||
PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines);
|
||||
break;
|
||||
case LINE:
|
||||
case EGALINE:
|
||||
if (GCC_UNLIKELY(vga.draw.lines_done < vga.draw.lines_total)) {
|
||||
LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d",
|
||||
vga.draw.lines_total-vga.draw.lines_done);
|
||||
PIC_RemoveEvents(VGA_DrawSingleLine);
|
||||
if (vga.draw.mode==EGALINE) PIC_RemoveEvents(VGA_DrawEGASingleLine);
|
||||
else PIC_RemoveEvents(VGA_DrawSingleLine);
|
||||
RENDER_EndUpdate(true);
|
||||
}
|
||||
vga.draw.lines_done = 0;
|
||||
PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip));
|
||||
if (vga.draw.mode==EGALINE)
|
||||
PIC_AddEvent(VGA_DrawEGASingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip));
|
||||
else PIC_AddEvent(VGA_DrawSingleLine,(float)(vga.draw.delay.htotal/4.0 + draw_skip));
|
||||
break;
|
||||
//case EGALINE:
|
||||
}
|
||||
}
|
||||
|
||||
@ -982,6 +968,10 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
case MCH_PCJR:
|
||||
vga.draw.mode = LINE;
|
||||
break;
|
||||
case MCH_EGA:
|
||||
// Note: The Paradise SVGA uses the same panning mechanism as EGA
|
||||
vga.draw.mode = EGALINE;
|
||||
break;
|
||||
case MCH_VGA:
|
||||
if (svgaCard==SVGA_None) {
|
||||
vga.draw.mode = LINE;
|
||||
@ -1077,13 +1067,13 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
htotal*=2;
|
||||
}
|
||||
vga.draw.address_line_total=(vga.crtc.maximum_scan_line&0x1f)+1;
|
||||
if(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) {
|
||||
if (IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA)) {
|
||||
// vgaonly; can't use with CGA because these use address_line for their
|
||||
// own purposes.
|
||||
// Set the low resolution modes to have as many lines as are scanned -
|
||||
// Quite a few demos change the max_scanline register at display time
|
||||
// to get SFX: Majic12 show, Magic circle, Copper, GBU, Party91
|
||||
if( vga.crtc.maximum_scan_line&0x80) vga.draw.address_line_total*=2;
|
||||
if ( vga.crtc.maximum_scan_line&0x80) vga.draw.address_line_total*=2;
|
||||
vga.draw.double_scan=false;
|
||||
}
|
||||
else if (IS_VGA_ARCH) vga.draw.double_scan=(vga.crtc.maximum_scan_line&0x80)>0;
|
||||
@ -1155,10 +1145,10 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
|
||||
// on blanking wrap to 0, the first line is not blanked
|
||||
// this is used by the S3 BIOS and other S3 drivers in some SVGA modes
|
||||
if((vbend&0x7f)==1) vblank_skip = 0;
|
||||
if ((vbend&0x7f)==1) vblank_skip = 0;
|
||||
|
||||
// it might also cut some lines off the bottom
|
||||
if(vbstart < vdend) {
|
||||
if (vbstart < vdend) {
|
||||
vdend = vbstart;
|
||||
}
|
||||
LOG(LOG_VGA,LOG_WARN)("Blanking wrap to line %d", vblank_skip);
|
||||
@ -1167,7 +1157,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
vblank_skip = vbend;
|
||||
LOG(LOG_VGA,LOG_WARN)("Upper %d lines of the screen blanked", vblank_skip);
|
||||
} else if (vbstart < vdend) {
|
||||
if(vbend < vdend) {
|
||||
if (vbend < vdend) {
|
||||
// the game wants a black bar somewhere on the screen
|
||||
LOG(LOG_VGA,LOG_WARN)("Unsupported blanking: line %d-%d",vbstart,vbend);
|
||||
} else {
|
||||
@ -1266,7 +1256,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
case M_LIN8:
|
||||
if (vga.crtc.mode_control & 0x8)
|
||||
width >>=1;
|
||||
else if(svgaCard == SVGA_S3Trio && !(vga.s3.reg_3a&0x10)) {
|
||||
else if (svgaCard == SVGA_S3Trio && !(vga.s3.reg_3a&0x10)) {
|
||||
doublewidth=true;
|
||||
width >>=1;
|
||||
}
|
||||
@ -1300,6 +1290,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
vga.draw.blocks = width;
|
||||
width<<=3;
|
||||
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) {
|
||||
// This would also be required for EGA in Spacepigs Megademo
|
||||
bpp=16;
|
||||
VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line;
|
||||
} else VGA_DrawLine=VGA_Draw_Linear_Line;
|
||||
@ -1329,17 +1320,22 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
aspect_ratio=1.0;
|
||||
vga.draw.blocks=width;
|
||||
doublewidth=(vga.seq.clocking_mode & 0x8) > 0;
|
||||
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None) && !(vga.seq.clocking_mode&0x01)) {
|
||||
width*=9; /* 9 bit wide text font */
|
||||
VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line_9;
|
||||
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) {
|
||||
// vgaonly: allow 9-pixel wide fonts
|
||||
if (vga.seq.clocking_mode&0x01) {
|
||||
vga.draw.char9dot = false;
|
||||
width*=8;
|
||||
} else {
|
||||
vga.draw.char9dot = true;
|
||||
width*=9;
|
||||
}
|
||||
VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line;
|
||||
bpp=16;
|
||||
// VGA_DrawLine=VGA_TEXT_Draw_Line_9;
|
||||
} else {
|
||||
width<<=3; /* 8 bit wide text font */
|
||||
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) {
|
||||
VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line;
|
||||
bpp=16;
|
||||
} else VGA_DrawLine=VGA_TEXT_Draw_Line;
|
||||
// not vgaonly: force 8-pixel wide fonts
|
||||
width*=8; // 8 bit wide text font
|
||||
vga.draw.char9dot = false;
|
||||
VGA_DrawLine=VGA_TEXT_Draw_Line;
|
||||
}
|
||||
break;
|
||||
case M_HERC_GFX:
|
||||
@ -1417,7 +1413,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
}
|
||||
vga.draw.vblank_skip = vblank_skip;
|
||||
|
||||
if(!(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA))) {
|
||||
if (!(IS_VGA_ARCH && (svgaCard==SVGA_None) && (vga.mode==M_EGA || vga.mode==M_VGA))) {
|
||||
//Only check for extra double height in vga modes
|
||||
//(line multiplying by address_line_total)
|
||||
if (!doubleheight && (vga.mode<M_TEXT) && !(vga.draw.address_line_total & 1)) {
|
||||
@ -1442,8 +1438,10 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
}
|
||||
// LOG_MSG("ht %d vt %d ratio %f", htotal, vtotal, aspect_ratio );
|
||||
|
||||
bool fps_changed = false;
|
||||
// need to change the vertical timing?
|
||||
if (fabs(vga.draw.delay.vtotal - 1000.0 / fps) > 0.0001) {
|
||||
fps_changed = true;
|
||||
vga.draw.delay.vtotal = 1000.0 / fps;
|
||||
VGA_KillDrawing();
|
||||
PIC_RemoveEvents(VGA_Other_VertInterrupt);
|
||||
@ -1470,7 +1468,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
(vga.draw.doublewidth != doublewidth) ||
|
||||
(vga.draw.doubleheight != doubleheight) ||
|
||||
(fabs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) ||
|
||||
(vga.draw.bpp != bpp)) {
|
||||
(vga.draw.bpp != bpp) || fps_changed) {
|
||||
|
||||
VGA_KillDrawing();
|
||||
|
||||
@ -1494,6 +1492,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
||||
void VGA_KillDrawing(void) {
|
||||
PIC_RemoveEvents(VGA_DrawPart);
|
||||
PIC_RemoveEvents(VGA_DrawSingleLine);
|
||||
PIC_RemoveEvents(VGA_DrawEGASingleLine);
|
||||
vga.draw.parts_left = 0;
|
||||
vga.draw.lines_done = ~0;
|
||||
RENDER_EndUpdate(true);
|
||||
|
@ -516,7 +516,12 @@ static void write_hercules(Bitu port,Bitu val,Bitu /*iolen*/) {
|
||||
break;
|
||||
}
|
||||
case 0x3bf:
|
||||
vga.herc.enable_bits=(Bit8u)val;
|
||||
if ( vga.herc.enable_bits ^ val) {
|
||||
vga.herc.enable_bits=val;
|
||||
// Bit 1 enables the upper 32k of video memory,
|
||||
// so update the handlers
|
||||
VGA_SetupHandlers();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -869,7 +869,7 @@ public:
|
||||
if (IS_TANDY_ARCH) {
|
||||
/* reduce reported memory size for the Tandy (32k graphics memory
|
||||
at the end of the conventional 640k) */
|
||||
if (machine==MCH_TANDY) mem_writew(BIOS_MEMORY_SIZE,608);
|
||||
if (machine==MCH_TANDY) mem_writew(BIOS_MEMORY_SIZE,624);
|
||||
else mem_writew(BIOS_MEMORY_SIZE,640);
|
||||
mem_writew(BIOS_TRUE_MEMORY_SIZE,640);
|
||||
} else mem_writew(BIOS_MEMORY_SIZE,640);
|
||||
|
@ -138,8 +138,7 @@ static Bitu INT10_Handler(void) {
|
||||
reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
||||
break;
|
||||
case 0x10: /* Palette functions */
|
||||
if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x02))) break;
|
||||
//TODO: subfunction 0x03 for ega
|
||||
if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x03))) break;
|
||||
switch (reg_al) {
|
||||
case 0x00: /* SET SINGLE PALETTE REGISTER */
|
||||
INT10_SetSinglePaletteRegister(reg_bl,reg_bh);
|
||||
@ -302,13 +301,8 @@ graphics_chars:
|
||||
break;
|
||||
}
|
||||
if ((reg_bh<=7) || (svgaCard==SVGA_TsengET4K)) {
|
||||
if (machine==MCH_EGA) {
|
||||
reg_cx=0x0e;
|
||||
reg_dl=0x18;
|
||||
} else {
|
||||
reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
||||
reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
|
||||
}
|
||||
reg_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
||||
reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
@ -66,9 +66,21 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu
|
||||
Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
|
||||
IO_Write(base,0x9);
|
||||
IO_Write(base+1,(IO_Read(base+1) & 0xe0)|(height-1));
|
||||
//Vertical display end bios says, but should stay the same?
|
||||
// Vertical display end bios says, but should stay the same?
|
||||
// Not on EGA.
|
||||
Bitu rows = CurMode->sheight/height;
|
||||
if (machine==MCH_EGA) {
|
||||
Bitu displayend = rows*height - 1;
|
||||
IO_Write(base,0x12);
|
||||
IO_Write(base+1,(Bit8u)(displayend & 0xff));
|
||||
IO_Write(base,0x7);
|
||||
// Note: IBM EGA registers can't be read
|
||||
Bitu v_overflow = IO_Read(base+1) & ~0x2;
|
||||
if (displayend & 0x100) v_overflow |= 0x2;
|
||||
IO_Write(base+1,(Bit8u)v_overflow);
|
||||
}
|
||||
//Rows setting in bios segment
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1);
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,rows-1);
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit8u)height);
|
||||
//TODO Reprogram cursor size?
|
||||
}
|
||||
|
@ -96,25 +96,42 @@ void INT10_SetAllPaletteRegisters(PhysPt data) {
|
||||
}
|
||||
|
||||
void INT10_ToggleBlinkingBit(Bit8u state) {
|
||||
Bit8u value;
|
||||
// state&=0x01;
|
||||
if ((state>1) && (svgaCard==SVGA_S3Trio)) return;
|
||||
ResetACTL();
|
||||
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,0x10);
|
||||
value=IO_Read(VGAREG_ACTL_READ_DATA);
|
||||
if (state<=1) {
|
||||
value&=0xf7;
|
||||
value|=state<<3;
|
||||
}
|
||||
if(IS_VGA_ARCH) {
|
||||
Bit8u value;
|
||||
// state&=0x01;
|
||||
if ((state>1) && (svgaCard==SVGA_S3Trio)) return;
|
||||
ResetACTL();
|
||||
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,0x10);
|
||||
value=IO_Read(VGAREG_ACTL_READ_DATA);
|
||||
if (state<=1) {
|
||||
value&=0xf7;
|
||||
value|=state<<3;
|
||||
}
|
||||
|
||||
ResetACTL();
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,0x10);
|
||||
IO_Write(VGAREG_ACTL_WRITE_DATA,value);
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette
|
||||
ResetACTL();
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,0x10);
|
||||
IO_Write(VGAREG_ACTL_WRITE_DATA,value);
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,32); //Enable output and protect palette
|
||||
|
||||
if (state<=1) {
|
||||
Bit8u msrval=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR)&0xdf;
|
||||
if (state<=1) {
|
||||
Bit8u msrval=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR)&0xdf;
|
||||
if (state) msrval|=0x20;
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,msrval);
|
||||
}
|
||||
} else { // EGA
|
||||
// Usually it reads this from the mode list in ROM
|
||||
if (CurMode->type!=M_TEXT) return;
|
||||
|
||||
Bit8u value = (CurMode->cwidth==9)? 0x4:0x0;
|
||||
if (state) value |= 0x8;
|
||||
|
||||
ResetACTL();
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,0x10);
|
||||
IO_Write(VGAREG_ACTL_WRITE_DATA,value);
|
||||
IO_Write(VGAREG_ACTL_ADDRESS,0x20);
|
||||
|
||||
Bit8u msrval=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR)& ~0x20;
|
||||
if (state) msrval|=0x20;
|
||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,msrval);
|
||||
}
|
||||
|
@ -490,7 +490,7 @@ void SHELL_Init() {
|
||||
MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n");
|
||||
MSG_Add("SHELL_CMD_COPY_FAILURE","Copy failure : %s.\n");
|
||||
MSG_Add("SHELL_CMD_COPY_SUCCESS"," %d File(s) copied.\n");
|
||||
MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Removing drive not supported. Doing nothing.\n");
|
||||
MSG_Add("SHELL_CMD_SUBST_NO_REMOVE","Unable to remove, drive not in use.\n");
|
||||
MSG_Add("SHELL_CMD_SUBST_FAILURE","SUBST failed. You either made an error in your commandline or the target drive is already used.\nIt's only possible to use SUBST on Local drives");
|
||||
|
||||
#ifdef HW_RVL
|
||||
|
@ -945,17 +945,22 @@ void DOS_Shell::CMD_SUBST (char * args) {
|
||||
CommandLine command(0,args);
|
||||
|
||||
if (command.GetCount() != 2) throw 0 ;
|
||||
command.FindCommand(2,arg);
|
||||
if((arg=="/D" ) || (arg=="/d")) throw 1; //No removal (one day)
|
||||
|
||||
command.FindCommand(1,arg);
|
||||
if( (arg.size()>1) && arg[1] !=':') throw(0);
|
||||
temp_str[0]=(char)toupper(args[0]);
|
||||
command.FindCommand(2,arg);
|
||||
if((arg=="/D") || (arg=="/d")) {
|
||||
if(!Drives[temp_str[0]-'A'] ) throw 1; //targetdrive not in use
|
||||
strcat(mountstring,"-u ");
|
||||
strcat(mountstring,temp_str);
|
||||
this->ParseLine(mountstring);
|
||||
return;
|
||||
}
|
||||
if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use
|
||||
strcat(mountstring,temp_str);
|
||||
strcat(mountstring," ");
|
||||
|
||||
command.FindCommand(2,arg);
|
||||
Bit8u drive;char fulldir[DOS_PATHLENGTH];
|
||||
if (!DOS_MakeName(const_cast<char*>(arg.c_str()),fulldir,&drive)) throw 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user