mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-26 02:21:49 +01:00
sync to dosbox 3635
This commit is contained in:
parent
2b06327229
commit
ce09efba36
@ -1,5 +1,5 @@
|
|||||||
dnl Init.
|
dnl Init.
|
||||||
AC_INIT(dosbox,0.74)
|
AC_INIT(dosbox,SVN)
|
||||||
AC_PREREQ(2.50)
|
AC_PREREQ(2.50)
|
||||||
AC_CONFIG_SRCDIR(README)
|
AC_CONFIG_SRCDIR(README)
|
||||||
|
|
||||||
|
@ -156,8 +156,9 @@ public:
|
|||||||
public:
|
public:
|
||||||
CFileInfo(void) {
|
CFileInfo(void) {
|
||||||
orgname[0] = shortname[0] = 0;
|
orgname[0] = shortname[0] = 0;
|
||||||
nextEntry = shortNr = 0;
|
|
||||||
isDir = false;
|
isDir = false;
|
||||||
|
id = MAX_OPENDIRS;
|
||||||
|
nextEntry = shortNr = 0;
|
||||||
}
|
}
|
||||||
~CFileInfo(void) {
|
~CFileInfo(void) {
|
||||||
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
|
for (Bit32u i=0; i<fileList.size(); i++) delete fileList[i];
|
||||||
@ -167,6 +168,7 @@ public:
|
|||||||
char orgname [CROSS_LEN];
|
char orgname [CROSS_LEN];
|
||||||
char shortname [DOS_NAMELENGTH_ASCII];
|
char shortname [DOS_NAMELENGTH_ASCII];
|
||||||
bool isDir;
|
bool isDir;
|
||||||
|
Bit16u id;
|
||||||
Bitu nextEntry;
|
Bitu nextEntry;
|
||||||
Bitu shortNr;
|
Bitu shortNr;
|
||||||
// contents
|
// contents
|
||||||
@ -175,6 +177,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void ClearFileInfo(CFileInfo *dir);
|
||||||
|
void DeleteFileInfo(CFileInfo *dir);
|
||||||
|
|
||||||
bool RemoveTrailingDot (char* shortname);
|
bool RemoveTrailingDot (char* shortname);
|
||||||
Bits GetLongName (CFileInfo* info, char* shortname);
|
Bits GetLongName (CFileInfo* info, char* shortname);
|
||||||
@ -203,7 +207,6 @@ private:
|
|||||||
Bit16u srchNr;
|
Bit16u srchNr;
|
||||||
CFileInfo* dirSearch [MAX_OPENDIRS];
|
CFileInfo* dirSearch [MAX_OPENDIRS];
|
||||||
char dirSearchName [MAX_OPENDIRS];
|
char dirSearchName [MAX_OPENDIRS];
|
||||||
bool free [MAX_OPENDIRS];
|
|
||||||
CFileInfo* dirFindFirst [MAX_OPENDIRS];
|
CFileInfo* dirFindFirst [MAX_OPENDIRS];
|
||||||
Bit16u nextFreeFindFirst;
|
Bit16u nextFreeFindFirst;
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ typedef struct {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
PART,
|
PART,
|
||||||
LINE,
|
LINE,
|
||||||
//EGALINE
|
EGALINE
|
||||||
} Drawmode;
|
} Drawmode;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -157,6 +157,8 @@ typedef struct {
|
|||||||
Bit8u font[64*1024];
|
Bit8u font[64*1024];
|
||||||
Bit8u * font_tables[2];
|
Bit8u * font_tables[2];
|
||||||
Bitu blinking;
|
Bitu blinking;
|
||||||
|
bool blink;
|
||||||
|
bool char9dot;
|
||||||
struct {
|
struct {
|
||||||
Bitu address;
|
Bitu address;
|
||||||
Bit8u sline,eline;
|
Bit8u sline,eline;
|
||||||
|
@ -352,11 +352,15 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
|
|||||||
physAddress+=4;
|
physAddress+=4;
|
||||||
}
|
}
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
phys_writeb(physAddress+0x00,(Bit8u)0x50); // push ax
|
||||||
phys_writew(physAddress+0x01,(Bit16u)0x0eb4); // mov ah, 0x0e
|
phys_writeb(physAddress+0x01,(Bit8u)0x53); // push bx
|
||||||
phys_writew(physAddress+0x03,(Bit16u)0x10cd); // int 10
|
phys_writew(physAddress+0x02,(Bit16u)0x0eb4); // mov ah, 0x0e
|
||||||
phys_writeb(physAddress+0x05,(Bit8u)0x58); // pop ax
|
phys_writeb(physAddress+0x04,(Bit8u)0xbb); // mov bx,
|
||||||
phys_writeb(physAddress+0x06,(Bit8u)0xcf); //An IRET Instruction
|
phys_writew(physAddress+0x05,(Bit16u)0x0007); // 0x0007
|
||||||
return (use_cb?0x0b:0x07);
|
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:
|
case CB_HOOKABLE:
|
||||||
phys_writeb(physAddress+0x00,(Bit8u)0xEB); //jump near
|
phys_writeb(physAddress+0x00,(Bit8u)0xEB); //jump near
|
||||||
phys_writeb(physAddress+0x01,(Bit8u)0x03); //offset
|
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) {
|
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);
|
phys_writeb(CALLBACK_PhysPointer(callback)+i ,(Bit8u) 0x00);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,11 @@ typedef struct SMSF {
|
|||||||
unsigned char fr;
|
unsigned char fr;
|
||||||
} TMSF;
|
} TMSF;
|
||||||
|
|
||||||
|
typedef struct SCtrl {
|
||||||
|
Bit8u out[4]; // output channel
|
||||||
|
Bit8u vol[4]; // channel volume
|
||||||
|
} TCtrl;
|
||||||
|
|
||||||
extern int CDROM_GetMountType(char* path, int force);
|
extern int CDROM_GetMountType(char* path, int force);
|
||||||
|
|
||||||
class CDROM_Interface
|
class CDROM_Interface
|
||||||
@ -52,6 +57,7 @@ public:
|
|||||||
virtual bool PlayAudioSector (unsigned long start,unsigned long len) = 0;
|
virtual bool PlayAudioSector (unsigned long start,unsigned long len) = 0;
|
||||||
virtual bool PauseAudio (bool resume) = 0;
|
virtual bool PauseAudio (bool resume) = 0;
|
||||||
virtual bool StopAudio (void) = 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;
|
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 PlayAudioSector (unsigned long start,unsigned long len);
|
||||||
virtual bool PauseAudio (bool resume);
|
virtual bool PauseAudio (bool resume);
|
||||||
virtual bool StopAudio (void);
|
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 ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return false; };
|
||||||
virtual bool LoadUnloadMedia (bool unload);
|
virtual bool LoadUnloadMedia (bool unload);
|
||||||
|
|
||||||
@ -101,6 +108,7 @@ public:
|
|||||||
bool PlayAudioSector (unsigned long /*start*/,unsigned long /*len*/) { return true; };
|
bool PlayAudioSector (unsigned long /*start*/,unsigned long /*len*/) { return true; };
|
||||||
bool PauseAudio (bool /*resume*/) { return true; };
|
bool PauseAudio (bool /*resume*/) { return true; };
|
||||||
bool StopAudio (void) { 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 ReadSectors (PhysPt /*buffer*/, bool /*raw*/, unsigned long /*sector*/, unsigned long /*num*/) { return true; };
|
||||||
bool LoadUnloadMedia (bool /*unload*/) { return true; };
|
bool LoadUnloadMedia (bool /*unload*/) { return true; };
|
||||||
};
|
};
|
||||||
@ -166,6 +174,7 @@ public:
|
|||||||
bool PlayAudioSector (unsigned long start,unsigned long len);
|
bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||||
bool PauseAudio (bool resume);
|
bool PauseAudio (bool resume);
|
||||||
bool StopAudio (void);
|
bool StopAudio (void);
|
||||||
|
void ChannelControl (TCtrl ctrl);
|
||||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||||
bool LoadUnloadMedia (bool unload);
|
bool LoadUnloadMedia (bool unload);
|
||||||
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||||
@ -188,6 +197,8 @@ static struct imagePlayer {
|
|||||||
int targetFrame;
|
int targetFrame;
|
||||||
bool isPlaying;
|
bool isPlaying;
|
||||||
bool isPaused;
|
bool isPaused;
|
||||||
|
bool ctrlUsed;
|
||||||
|
TCtrl ctrlData;
|
||||||
} player;
|
} player;
|
||||||
|
|
||||||
void ClearTracks();
|
void ClearTracks();
|
||||||
@ -234,6 +245,7 @@ public:
|
|||||||
bool PlayAudioSector (unsigned long start,unsigned long len);
|
bool PlayAudioSector (unsigned long start,unsigned long len);
|
||||||
bool PauseAudio (bool resume);
|
bool PauseAudio (bool resume);
|
||||||
bool StopAudio (void);
|
bool StopAudio (void);
|
||||||
|
void ChannelControl (TCtrl ctrl) { return; };
|
||||||
|
|
||||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
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 PlayAudioSector (unsigned long start,unsigned long len);
|
||||||
bool PauseAudio (bool resume);
|
bool PauseAudio (bool resume);
|
||||||
bool StopAudio (void);
|
bool StopAudio (void);
|
||||||
|
void ChannelControl (TCtrl ctrl);
|
||||||
|
|
||||||
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
bool ReadSector (Bit8u *buffer, bool raw, unsigned long sector);
|
||||||
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
bool ReadSectors (PhysPt buffer, bool raw, unsigned long sector, unsigned long num);
|
||||||
@ -338,6 +351,8 @@ private:
|
|||||||
int targetFrame;
|
int targetFrame;
|
||||||
bool isPlaying;
|
bool isPlaying;
|
||||||
bool isPaused;
|
bool isPaused;
|
||||||
|
bool ctrlUsed;
|
||||||
|
TCtrl ctrlData;
|
||||||
} player;
|
} player;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -131,7 +131,7 @@ int CDROM_Interface_Image::AudioFile::getLength()
|
|||||||
int CDROM_Interface_Image::refCount = 0;
|
int CDROM_Interface_Image::refCount = 0;
|
||||||
CDROM_Interface_Image* CDROM_Interface_Image::images[26];
|
CDROM_Interface_Image* CDROM_Interface_Image::images[26];
|
||||||
CDROM_Interface_Image::imagePlayer CDROM_Interface_Image::player = {
|
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)
|
CDROM_Interface_Image::CDROM_Interface_Image(Bit8u subUnit)
|
||||||
@ -259,6 +259,12 @@ bool CDROM_Interface_Image::StopAudio(void)
|
|||||||
return true;
|
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)
|
bool CDROM_Interface_Image::ReadSectors(PhysPt buffer, bool raw, unsigned long sector, unsigned long num)
|
||||||
{
|
{
|
||||||
int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
int sectorSize = raw ? RAW_SECTOR_SIZE : COOKED_SECTOR_SIZE;
|
||||||
@ -336,6 +342,16 @@ void CDROM_Interface_Image::CDAudioCallBack(Bitu len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_mutexV(player.mutex);
|
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)
|
#if defined(WORDS_BIGENDIAN)
|
||||||
player.channel->AddSamples_s16_nonnative(len/4,(Bit16s *)player.buffer);
|
player.channel->AddSamples_s16_nonnative(len/4,(Bit16s *)player.buffer);
|
||||||
#else
|
#else
|
||||||
|
@ -175,7 +175,7 @@ bool CDROM_Interface_Ioctl::mci_CDPosition(int *position) {
|
|||||||
|
|
||||||
|
|
||||||
CDROM_Interface_Ioctl::dxPlayer CDROM_Interface_Ioctl::player = {
|
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) {
|
CDROM_Interface_Ioctl::CDROM_Interface_Ioctl(cdioctl_cdatype ioctl_cda) {
|
||||||
pathname[0] = 0;
|
pathname[0] = 0;
|
||||||
@ -462,6 +462,12 @@ bool CDROM_Interface_Ioctl::StopAudio(void) {
|
|||||||
return bStat>0;
|
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 CDROM_Interface_Ioctl::LoadUnloadMedia(bool unload) {
|
||||||
BOOL bStat;
|
BOOL bStat;
|
||||||
DWORD byteCount;
|
DWORD byteCount;
|
||||||
@ -553,6 +559,16 @@ void CDROM_Interface_Ioctl::dx_CDAudioCallBack(Bitu len) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SDL_mutexV(player.mutex);
|
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);
|
player.channel->AddSamples_s16(len/4,(Bit16s *)player.buffer);
|
||||||
memmove(player.buffer, &player.buffer[len], player.bufLen - len);
|
memmove(player.buffer, &player.buffer[len], player.bufLen - len);
|
||||||
player.bufLen -= len;
|
player.bufLen -= len;
|
||||||
|
@ -227,11 +227,14 @@ static Bitu DOS_21Handler(void) {
|
|||||||
break;
|
break;
|
||||||
case 0x0c: /* Flush Buffer and read STDIN call */
|
case 0x0c: /* Flush Buffer and read STDIN call */
|
||||||
{
|
{
|
||||||
/* flush STDIN-buffer */
|
/* flush buffer if STDIN is CON */
|
||||||
|
Bit8u handle=RealHandle(STDIN);
|
||||||
|
if (handle!=0xFF && Files[handle] && Files[handle]->IsName("CON")) {
|
||||||
Bit8u c;Bit16u n;
|
Bit8u c;Bit16u n;
|
||||||
while (DOS_GetSTDINStatus()) {
|
while (DOS_GetSTDINStatus()) {
|
||||||
n=1; DOS_ReadFile(STDIN,&c,&n);
|
n=1; DOS_ReadFile(STDIN,&c,&n);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
switch (reg_al) {
|
switch (reg_al) {
|
||||||
case 0x1:
|
case 0x1:
|
||||||
case 0x6:
|
case 0x6:
|
||||||
|
@ -203,6 +203,13 @@ bool DOS_GetCurrentDir(Bit8u drive,char * const buffer) {
|
|||||||
|
|
||||||
bool DOS_ChangeDir(char const * const dir) {
|
bool DOS_ChangeDir(char const * const dir) {
|
||||||
Bit8u drive;char fulldir[DOS_PATHLENGTH];
|
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 (!DOS_MakeName(dir,fulldir,&drive)) return false;
|
||||||
|
|
||||||
if (Drives[drive]->TestDir(fulldir)) {
|
if (Drives[drive]->TestDir(fulldir)) {
|
||||||
|
@ -436,7 +436,7 @@ void DOS_SetupMemory(void) {
|
|||||||
if (machine==MCH_TANDY) {
|
if (machine==MCH_TANDY) {
|
||||||
/* memory up to 608k available, the rest (to 640k) is used by
|
/* memory up to 608k available, the rest (to 640k) is used by
|
||||||
the tandy graphics system's variable mapping of 0xb800 */
|
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) {
|
} else if (machine==MCH_PCJR) {
|
||||||
/* memory from 128k to 640k is available */
|
/* memory from 128k to 640k is available */
|
||||||
mcb_devicedummy.SetPt((Bit16u)0x2000);
|
mcb_devicedummy.SetPt((Bit16u)0x2000);
|
||||||
|
@ -152,6 +152,7 @@ private:
|
|||||||
bool locked; // drive locked ?
|
bool locked; // drive locked ?
|
||||||
bool lastResult; // last operation success ?
|
bool lastResult; // last operation success ?
|
||||||
Bit32u volumeSize; // for media change
|
Bit32u volumeSize; // for media change
|
||||||
|
TCtrl audioCtrl; // audio channel control
|
||||||
} TDriveInfo;
|
} TDriveInfo;
|
||||||
|
|
||||||
Bit16u defaultBufSeg;
|
Bit16u defaultBufSeg;
|
||||||
@ -160,6 +161,9 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
Bit16u rootDriverHeaderSeg;
|
Bit16u rootDriverHeaderSeg;
|
||||||
|
|
||||||
|
bool ChannelControl (Bit8u subUnit, TCtrl ctrl);
|
||||||
|
bool GetChannelControl (Bit8u subUnit, TCtrl& ctrl);
|
||||||
};
|
};
|
||||||
|
|
||||||
CMscdex::CMscdex(void) {
|
CMscdex::CMscdex(void) {
|
||||||
@ -368,25 +372,34 @@ int CMscdex::AddDrive(Bit16u _drive, char* physicalPath, Bit8u& subUnit)
|
|||||||
devHeader.SetInterrupt(off+5);
|
devHeader.SetInterrupt(off+5);
|
||||||
}
|
}
|
||||||
|
|
||||||
subUnit = (Bit8u)numDrives;
|
|
||||||
// Set drive
|
// Set drive
|
||||||
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
|
DOS_DeviceHeader devHeader(PhysMake(rootDriverHeaderSeg,0));
|
||||||
devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1);
|
devHeader.SetNumSubUnits(devHeader.GetNumSubUnits()+1);
|
||||||
|
|
||||||
if (dinfo[0].drive-1==_drive) {
|
if (dinfo[0].drive-1==_drive) {
|
||||||
CDROM_Interface *_cdrom = cdrom[numDrives];
|
CDROM_Interface *_cdrom = cdrom[numDrives];
|
||||||
|
CDROM_Interface_Image *_cdimg = CDROM_Interface_Image::images[numDrives];
|
||||||
for (Bit16u i=GetNumDrives(); i>0; i--) {
|
for (Bit16u i=GetNumDrives(); i>0; i--) {
|
||||||
dinfo[i] = dinfo[i-1];
|
dinfo[i] = dinfo[i-1];
|
||||||
cdrom[i] = cdrom[i-1];
|
cdrom[i] = cdrom[i-1];
|
||||||
|
CDROM_Interface_Image::images[i] = CDROM_Interface_Image::images[i-1];
|
||||||
}
|
}
|
||||||
cdrom[0] = _cdrom;
|
cdrom[0] = _cdrom;
|
||||||
|
CDROM_Interface_Image::images[0] = _cdimg;
|
||||||
dinfo[0].drive = (Bit8u)_drive;
|
dinfo[0].drive = (Bit8u)_drive;
|
||||||
dinfo[0].physDrive = (Bit8u)toupper(physicalPath[0]);
|
dinfo[0].physDrive = (Bit8u)toupper(physicalPath[0]);
|
||||||
|
subUnit = 0;
|
||||||
} else {
|
} else {
|
||||||
dinfo[numDrives].drive = (Bit8u)_drive;
|
dinfo[numDrives].drive = (Bit8u)_drive;
|
||||||
dinfo[numDrives].physDrive = (Bit8u)toupper(physicalPath[0]);
|
dinfo[numDrives].physDrive = (Bit8u)toupper(physicalPath[0]);
|
||||||
|
subUnit = (Bit8u)numDrives;
|
||||||
}
|
}
|
||||||
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
|
// stop audio
|
||||||
StopAudio(subUnit);
|
StopAudio(subUnit);
|
||||||
return result;
|
return result;
|
||||||
@ -459,7 +472,7 @@ bool CMscdex::PlayAudioSector(Bit8u subUnit, Bit32u sector, Bit32u length)
|
|||||||
if (subUnit>=numDrives) return false;
|
if (subUnit>=numDrives) return false;
|
||||||
// If value from last stop is used, this is meant as a resume
|
// If value from last stop is used, this is meant as a resume
|
||||||
// better start using resume command
|
// 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);
|
dinfo[subUnit].lastResult = cdrom[subUnit]->PauseAudio(true);
|
||||||
} else
|
} else
|
||||||
dinfo[subUnit].lastResult = cdrom[subUnit]->PlayAudioSector(sector,length);
|
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];
|
char entryName[256];
|
||||||
bool foundComplete = false;
|
bool foundComplete = false;
|
||||||
bool foundName;
|
bool foundName;
|
||||||
|
bool nextPart = true;
|
||||||
char* useName = 0;
|
char* useName = 0;
|
||||||
Bitu entryLength,nameLength;
|
Bitu entryLength,nameLength;
|
||||||
// clear error
|
// clear error
|
||||||
@ -695,13 +709,14 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||||||
if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false;
|
if (!ReadSectors(GetSubUnit(drive),false,dirEntrySector,1,defBuffer)) return false;
|
||||||
// Get string part
|
// Get string part
|
||||||
foundName = false;
|
foundName = false;
|
||||||
|
if (nextPart) {
|
||||||
if (searchPos) {
|
if (searchPos) {
|
||||||
useName = searchPos;
|
useName = searchPos;
|
||||||
searchPos = strchr(searchPos,'\\');
|
searchPos = strchr(searchPos,'\\');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchPos) { *searchPos = 0; searchPos++; }
|
if (searchPos) { *searchPos = 0; searchPos++; }
|
||||||
else foundComplete = true;
|
else foundComplete = true;
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
entryLength = mem_readb(defBuffer+index);
|
entryLength = mem_readb(defBuffer+index);
|
||||||
@ -759,10 +774,12 @@ bool CMscdex::GetDirectoryEntry(Bit16u drive, bool copyFlag, PhysPt pathname, Ph
|
|||||||
// change directory
|
// change directory
|
||||||
dirEntrySector = mem_readd(defBuffer+index+2);
|
dirEntrySector = mem_readd(defBuffer+index+2);
|
||||||
dirSize = mem_readd(defBuffer+index+10);
|
dirSize = mem_readd(defBuffer+index+10);
|
||||||
|
nextPart = true;
|
||||||
} else {
|
} else {
|
||||||
// continue search in next sector
|
// continue search in next sector
|
||||||
dirSize -= 2048;
|
dirSize -= 2048;
|
||||||
dirEntrySector++;
|
dirEntrySector++;
|
||||||
|
nextPart = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
error = 2; // file not found
|
error = 2; // file not found
|
||||||
@ -796,6 +813,7 @@ Bit32u CMscdex::GetDeviceStatus(Bit8u subUnit)
|
|||||||
(dinfo[subUnit].locked << 1) | // Drive is locked ?
|
(dinfo[subUnit].locked << 1) | // Drive is locked ?
|
||||||
(1<<2) | // raw + cooked sectors
|
(1<<2) | // raw + cooked sectors
|
||||||
(1<<4) | // Can read sudio
|
(1<<4) | // Can read sudio
|
||||||
|
(1<<8) | // Can control audio
|
||||||
(1<<9) | // Red book & HSG
|
(1<<9) | // Red book & HSG
|
||||||
((!media) << 11); // Drive is empty ?
|
((!media) << 11); // Drive is empty ?
|
||||||
return status;
|
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 CMscdex* mscdex = 0;
|
||||||
static PhysPt curReqheaderPtr = 0;
|
static PhysPt curReqheaderPtr = 0;
|
||||||
|
|
||||||
@ -889,6 +923,14 @@ static Bit16u MSCDEX_IOCTL_Input(PhysPt buffer,Bit8u drive_unit) {
|
|||||||
return 0x03; // invalid function
|
return 0x03; // invalid function
|
||||||
}
|
}
|
||||||
}break;
|
}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 */
|
case 0x06 : /* Get Device status */
|
||||||
mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit));
|
mem_writed(buffer+1,mscdex->GetDeviceStatus(drive_unit));
|
||||||
break;
|
break;
|
||||||
@ -980,7 +1022,13 @@ static Bit16u MSCDEX_IOCTL_Optput(PhysPt buffer,Bit8u drive_unit) {
|
|||||||
if (!mscdex->LoadUnloadMedia(drive_unit,true)) return 0x02;
|
if (!mscdex->LoadUnloadMedia(drive_unit,true)) return 0x02;
|
||||||
break;
|
break;
|
||||||
case 0x03: //Audio Channel control
|
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
|
case 0x01 : // (un)Lock door
|
||||||
// do nothing -> report as success
|
// do nothing -> report as success
|
||||||
break;
|
break;
|
||||||
|
@ -67,7 +67,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(void) {
|
|||||||
srchNr = 0;
|
srchNr = 0;
|
||||||
label[0] = 0;
|
label[0] = 0;
|
||||||
nextFreeFindFirst = 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);
|
SetDirSort(DIRALPHABETICAL);
|
||||||
updatelabel = true;
|
updatelabel = true;
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) {
|
|||||||
srchNr = 0;
|
srchNr = 0;
|
||||||
label[0] = 0;
|
label[0] = 0;
|
||||||
nextFreeFindFirst = 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);
|
SetDirSort(DIRALPHABETICAL);
|
||||||
SetBaseDir(path);
|
SetBaseDir(path);
|
||||||
updatelabel = true;
|
updatelabel = true;
|
||||||
@ -86,11 +86,11 @@ DOS_Drive_Cache::DOS_Drive_Cache(const char* path) {
|
|||||||
|
|
||||||
DOS_Drive_Cache::~DOS_Drive_Cache(void) {
|
DOS_Drive_Cache::~DOS_Drive_Cache(void) {
|
||||||
Clear();
|
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) {
|
void DOS_Drive_Cache::Clear(void) {
|
||||||
delete dirBase; dirBase = 0;
|
DeleteFileInfo(dirBase); dirBase = 0;
|
||||||
nextFreeFindFirst = 0;
|
nextFreeFindFirst = 0;
|
||||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) dirSearch[i] = 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;
|
dirBase = new CFileInfo;
|
||||||
save_dir = 0;
|
save_dir = 0;
|
||||||
srchNr = 0;
|
srchNr = 0;
|
||||||
for (Bit32u i=0; i<MAX_OPENDIRS; i++) free[i] = true;
|
|
||||||
SetBaseDir(basePath);
|
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) {
|
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!");
|
LOG(LOG_FILES,LOG_NORMAL)("DIRCACHE: Too many open directories!");
|
||||||
|
dir->id=0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,7 +271,7 @@ void DOS_Drive_Cache::CacheOut(const char* path, bool ignoreLastDir) {
|
|||||||
// delete file objects...
|
// delete file objects...
|
||||||
for(Bit32u i=0; i<dir->fileList.size(); i++) {
|
for(Bit32u i=0; i<dir->fileList.size(); i++) {
|
||||||
if (dirSearch[srchNr]==dir->fileList[i]) dirSearch[srchNr] = 0;
|
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
|
// clear lists
|
||||||
dir->fileList.clear();
|
dir->fileList.clear();
|
||||||
@ -526,7 +533,10 @@ DOS_Drive_Cache::CFileInfo* DOS_Drive_Cache::FindDirInfo(const char* path, char*
|
|||||||
strcpy(buffer,dirPath);
|
strcpy(buffer,dirPath);
|
||||||
ReadDir(id,result);
|
ReadDir(id,result);
|
||||||
strcpy(dirPath,buffer);
|
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);
|
strcpy(buffer,dirPath);
|
||||||
ReadDir(id,result);
|
ReadDir(id,result);
|
||||||
strcpy(dirPath,buffer);
|
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..
|
// Reset it..
|
||||||
close_directory(dirp);
|
close_directory(dirp);
|
||||||
strcpy(dirPath,expandcopy);
|
strcpy(dirPath,expandcopy);
|
||||||
free[id] = false;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
if (dirSearch[id]) {
|
||||||
|
dirSearch[id]->id = MAX_OPENDIRS;
|
||||||
|
dirSearch[id] = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -661,7 +677,10 @@ bool DOS_Drive_Cache::ReadDir(Bit16u id, char* &result) {
|
|||||||
// Try to open directory
|
// Try to open directory
|
||||||
dir_information* dirp = open_directory(dirPath);
|
dir_information* dirp = open_directory(dirPath);
|
||||||
if (!dirp) {
|
if (!dirp) {
|
||||||
free[id] = true;
|
if (dirSearch[id]) {
|
||||||
|
dirSearch[id]->id = MAX_OPENDIRS;
|
||||||
|
dirSearch[id] = 0;
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Read complete directory
|
// 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;
|
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;
|
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
|
this->nextFreeFindFirst = 1; //the next free one after this search
|
||||||
for(Bitu n=0; n<MAX_OPENDIRS;n++) {
|
for(Bitu n=0; n<MAX_OPENDIRS;n++) {
|
||||||
// Clear and reuse slot
|
// Clear and reuse slot
|
||||||
delete dirFindFirst[n];
|
DeleteFileInfo(dirFindFirst[n]);
|
||||||
dirFindFirst[n]=0;
|
dirFindFirst[n]=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -767,8 +789,25 @@ bool DOS_Drive_Cache::FindNext(Bit16u id, char* &result) {
|
|||||||
}
|
}
|
||||||
if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) {
|
if (!SetResult(dirFindFirst[id], result, dirFindFirst[id]->nextEntry)) {
|
||||||
// free slot
|
// free slot
|
||||||
delete dirFindFirst[id]; dirFindFirst[id] = 0;
|
DeleteFileInfo(dirFindFirst[id]); dirFindFirst[id] = 0;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
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;
|
else findAttr |= DOS_ATTR_ARCHIVE;
|
||||||
if (IS_HIDDEN(de.fileFlags)) findAttr |= DOS_ATTR_HIDDEN;
|
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))) {
|
&& !(~attr & findAttr & (DOS_ATTR_DIRECTORY | DOS_ATTR_HIDDEN | DOS_ATTR_SYSTEM))) {
|
||||||
|
|
||||||
/* file is okay, setup everything to be copied in DTA Block */
|
/* 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
|
// look for the current path element
|
||||||
int dirIterator = GetDirIterator(de);
|
int dirIterator = GetDirIterator(de);
|
||||||
while (!found && GetNextDirEntry(dirIterator, 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;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,7 @@ public:
|
|||||||
Bit16u GetInformation(void);
|
Bit16u GetInformation(void);
|
||||||
bool UpdateDateTimeFromHost(void);
|
bool UpdateDateTimeFromHost(void);
|
||||||
void FlagReadOnlyMedium(void);
|
void FlagReadOnlyMedium(void);
|
||||||
|
void Flush(void);
|
||||||
private:
|
private:
|
||||||
FILE * fhandle;
|
FILE * fhandle;
|
||||||
bool read_only_medium;
|
bool read_only_medium;
|
||||||
@ -95,6 +96,22 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
|
|||||||
CROSS_FILENAME(newname);
|
CROSS_FILENAME(newname);
|
||||||
dirCache.ExpandName(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);
|
FILE * hand=fopen(newname,type);
|
||||||
// Bit32u err=errno;
|
// Bit32u err=errno;
|
||||||
if (!hand) {
|
if (!hand) {
|
||||||
@ -541,6 +558,13 @@ bool localFile::UpdateDateTimeFromHost(void) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void localFile::Flush(void) {
|
||||||
|
if (last_action==WRITE) {
|
||||||
|
fseek(fhandle,ftell(fhandle),SEEK_SET);
|
||||||
|
last_action=NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ********************************************
|
// ********************************************
|
||||||
// CDROM DRIVE
|
// CDROM DRIVE
|
||||||
|
@ -298,11 +298,13 @@ struct isoDirEntry {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ISO_FRAMESIZE 2048
|
#define ISO_FRAMESIZE 2048
|
||||||
|
#define ISO_ASSOCIATED 4
|
||||||
#define ISO_DIRECTORY 2
|
#define ISO_DIRECTORY 2
|
||||||
#define ISO_HIDDEN 1
|
#define ISO_HIDDEN 1
|
||||||
#define ISO_MAX_FILENAME_LENGTH 37
|
#define ISO_MAX_FILENAME_LENGTH 37
|
||||||
#define ISO_MAXPATHNAME 256
|
#define ISO_MAXPATHNAME 256
|
||||||
#define ISO_FIRST_VD 16
|
#define ISO_FIRST_VD 16
|
||||||
|
#define IS_ASSOC(fileFlags) (fileFlags & ISO_ASSOCIATED)
|
||||||
#define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY)
|
#define IS_DIR(fileFlags) (fileFlags & ISO_DIRECTORY)
|
||||||
#define IS_HIDDEN(fileFlags) (fileFlags & ISO_HIDDEN)
|
#define IS_HIDDEN(fileFlags) (fileFlags & ISO_HIDDEN)
|
||||||
#define ISO_MAX_HASH_TABLE_SIZE 100
|
#define ISO_MAX_HASH_TABLE_SIZE 100
|
||||||
|
@ -504,6 +504,8 @@ static void GenerateDMASound(Bitu size) {
|
|||||||
sb.dma.left-=read;
|
sb.dma.left-=read;
|
||||||
if (!sb.dma.left) {
|
if (!sb.dma.left) {
|
||||||
PIC_RemoveEvents(END_DMA_Event);
|
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) {
|
if (!sb.dma.autoinit) {
|
||||||
LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended");
|
LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended");
|
||||||
sb.mode=MODE_NONE;
|
sb.mode=MODE_NONE;
|
||||||
@ -515,8 +517,6 @@ static void GenerateDMASound(Bitu size) {
|
|||||||
sb.mode=MODE_NONE;
|
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;
|
return ret;
|
||||||
case 0x82: /* IRQ Status */
|
case 0x82: /* IRQ Status */
|
||||||
return (sb.irq.pending_8bit ? 0x1 : 0) |
|
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:
|
default:
|
||||||
if ( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */
|
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 */
|
(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.
|
10h and 14h.
|
||||||
*/
|
*/
|
||||||
break;
|
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 (!IS_VGA_ARCH) val&=0x1f; // not really correct, but should do it
|
||||||
if ((attr(mode_control) ^ val) & 0x80) {
|
Bitu difference = attr(mode_control)^val;
|
||||||
attr(mode_control)^=0x80;
|
attr(mode_control)=(Bit8u)val;
|
||||||
for (Bit8u i=0;i<0x10;i++) {
|
|
||||||
|
if (difference & 0x80) {
|
||||||
|
for (Bit8u i=0;i<0x10;i++)
|
||||||
VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
|
VGA_ATTR_SetPalette(i,vga.attr.palette[i]);
|
||||||
}
|
}
|
||||||
}
|
if (difference & 0x08)
|
||||||
if ((attr(mode_control) ^ val) & 0x08) {
|
|
||||||
VGA_SetBlinking(val & 0x8);
|
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
0 Graphics mode if set, Alphanumeric mode else.
|
0 Graphics mode if set, Alphanumeric mode else.
|
||||||
1 Monochrome mode if set, color mode else.
|
1 Monochrome mode if set, color mode else.
|
||||||
@ -113,6 +120,7 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
|
|||||||
used.
|
used.
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case 0x11: /* Overscan Color Register */
|
case 0x11: /* Overscan Color Register */
|
||||||
attr(overscan_color)=(Bit8u)val;
|
attr(overscan_color)=(Bit8u)val;
|
||||||
/* 0-5 Color of screen border. Color is defined as in the palette registers. */
|
/* 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;
|
attr(horizontal_pel_panning)=val & 0xF;
|
||||||
switch (vga.mode) {
|
switch (vga.mode) {
|
||||||
case M_TEXT:
|
case M_TEXT:
|
||||||
if ((val==0x7) && (svgaCard==SVGA_None)) vga.config.pel_panning=7;
|
if (val > 7)
|
||||||
if (val>0x7) vga.config.pel_panning=0;
|
vga.config.pel_panning=0;
|
||||||
else vga.config.pel_panning=(Bit8u)(val+1);
|
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;
|
break;
|
||||||
case M_VGA:
|
case M_VGA:
|
||||||
case M_LIN8:
|
case M_LIN8:
|
||||||
@ -146,6 +157,9 @@ void write_p3c0(Bitu /*port*/,Bitu val,Bitu iolen) {
|
|||||||
default:
|
default:
|
||||||
vga.config.pel_panning=(val & 0x7);
|
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
|
0-3 Indicates number of pixels to shift the display left
|
||||||
Value 9bit textmode 256color mode Other modes
|
Value 9bit textmode 256color mode Other modes
|
||||||
|
@ -197,14 +197,6 @@ static Bit8u * VGA_Draw_Xlat16_Linear_Line(Bitu vidstart, Bitu /*line*/) {
|
|||||||
temps[i]=vga.dac.xlat16[ret[i]];
|
temps[i]=vga.dac.xlat16[ret[i]];
|
||||||
}
|
}
|
||||||
return TempLine;
|
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
|
//Test version, might as well keep it
|
||||||
@ -446,167 +438,121 @@ static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) {
|
|||||||
skip_cursor:
|
skip_cursor:
|
||||||
return TempLine;
|
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) {
|
// combined 8/9-dot wide text mode 8bpp line drawing function
|
||||||
Bits font_addr;
|
static Bit8u* VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) {
|
||||||
Bit8u * draw=(Bit8u *)TempLine;
|
// keep it aligned:
|
||||||
bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line;
|
Bit8u* draw = ((Bit8u*)TempLine) + 16 - vga.draw.panning;
|
||||||
Bit8u pel_pan=(Bit8u)vga.draw.panning;
|
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart); // pointer to chars+attribs
|
||||||
if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0;
|
Bitu blocks = vga.draw.blocks;
|
||||||
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
|
if (vga.draw.panning) blocks++; // if the text is panned part of an
|
||||||
Bit8u chr=vidmem[0];
|
// additional character becomes visible
|
||||||
Bit8u col=vidmem[1];
|
while (blocks--) { // for each character in the line
|
||||||
Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
|
Bitu chr = *vidmem++;
|
||||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
Bitu attr = *vidmem++;
|
||||||
Bit8u fg=col&0xf;
|
// the font pattern
|
||||||
Bit8u bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
Bitu font = vga.draw.font_tables[(attr >> 3)&1][(chr<<5)+line];
|
||||||
Bitu draw_blocks=vga.draw.blocks;
|
|
||||||
draw_blocks++;
|
Bitu background = attr >> 4;
|
||||||
for (Bitu cx=1;cx<draw_blocks;cx++) {
|
// if blinking is enabled bit7 is not mapped to attributes
|
||||||
if (pel_pan) {
|
if (vga.draw.blinking) background &= ~0x8;
|
||||||
chr=vidmem[cx*2];
|
// choose foreground color if blinking not set for this cell or blink on
|
||||||
col=vidmem[cx*2+1];
|
Bitu foreground = (vga.draw.blink || (!(attr&0x80)))?
|
||||||
if (underline && ((col&0x07) == 0x01)) font|=0xff>>(8-pel_pan);
|
(attr&0xf):background;
|
||||||
else font|=vga.draw.font_tables[(col >> 3)&1][chr*32+line]>>(8-pel_pan);
|
// underline: all foreground [freevga: 0x77, previous 0x7]
|
||||||
fg=col&0xf;
|
if (GCC_UNLIKELY(((attr&0x77) == 0x01) &&
|
||||||
bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
(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 {
|
} else {
|
||||||
chr=vidmem[(cx-1)*2];
|
for (Bitu n = 0; n < 8; n++) {
|
||||||
col=vidmem[(cx-1)*2+1];
|
*draw++ = (font&0x80)? foreground:background;
|
||||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
font <<= 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
skip_cursor:
|
// draw the text mode cursor if needed
|
||||||
return TempLine;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return TempLine+16;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
// 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];
|
||||||
|
|
||||||
static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) {
|
Bitu background = attr >> 4;
|
||||||
Bits font_addr;
|
// if blinking is enabled bit7 is not mapped to attributes
|
||||||
Bit16u * draw=(Bit16u *)TempLine;
|
if (vga.draw.blinking) background &= ~0x8;
|
||||||
bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line;
|
// choose foreground color if blinking not set for this cell or blink on
|
||||||
Bit8u pel_pan=(Bit8u)vga.draw.panning;
|
Bitu foreground = (vga.draw.blink || (!(attr&0x80)))?
|
||||||
if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0;
|
(attr&0xf):background;
|
||||||
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
|
// underline: all foreground [freevga: 0x77, previous 0x7]
|
||||||
Bit8u chr=vidmem[0];
|
if (GCC_UNLIKELY(((attr&0x77) == 0x01) &&
|
||||||
Bit8u col=vidmem[1];
|
(vga.crtc.underline_location&0x1f)==line))
|
||||||
Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
|
background = foreground;
|
||||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
if (vga.draw.char9dot) {
|
||||||
Bit8u fg=col&0xf;
|
font <<=1; // 9 pixels
|
||||||
Bit8u bg=(Bit8u)(TXT_BG_Table[col>>4]&0xff);
|
// extend to the 9th pixel if needed
|
||||||
Bitu draw_blocks=vga.draw.blocks;
|
if ((font&0x2) && (vga.attr.mode_control&0x04) &&
|
||||||
draw_blocks++;
|
(chr>=0xc0) && (chr<=0xdf)) font |= 1;
|
||||||
for (Bitu cx=1;cx<draw_blocks;cx++) {
|
for (Bitu n = 0; n < 9; n++) {
|
||||||
if (pel_pan) {
|
*draw++ = vga.dac.xlat16[(font&0x100)? foreground:background];
|
||||||
chr=vidmem[cx*2];
|
font <<= 1;
|
||||||
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);
|
|
||||||
} else {
|
} else {
|
||||||
chr=vidmem[(cx-1)*2];
|
for (Bitu n = 0; n < 8; n++) {
|
||||||
col=vidmem[(cx-1)*2+1];
|
*draw++ = vga.dac.xlat16[(font&0x80)? foreground:background];
|
||||||
if (underline && ((col&0x07) == 0x01)) font=0xff;
|
font <<= 1;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
//if(underline && ((col&0x07) == 0x01))
|
// draw the text mode cursor if needed
|
||||||
// *draw = vga.dac.xlat16[fg];
|
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];
|
||||||
}
|
}
|
||||||
skip_cursor:
|
}
|
||||||
return TempLine;
|
}
|
||||||
|
return TempLine+32;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VGA_KEEP_CHANGES
|
#ifdef VGA_KEEP_CHANGES
|
||||||
@ -628,14 +574,17 @@ static INLINE void VGA_ChangesEnd(void ) {
|
|||||||
|
|
||||||
|
|
||||||
static void VGA_ProcessSplit() {
|
static void VGA_ProcessSplit() {
|
||||||
// On the EGA the address is always reset to 0.
|
if (vga.attr.mode_control&0x20) {
|
||||||
if ((vga.attr.mode_control&0x20) || (machine==MCH_EGA)) {
|
|
||||||
vga.draw.address=0;
|
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 {
|
} else {
|
||||||
// In text mode only the characters are shifted by panning, not the address;
|
// In text mode only the characters are shifted by panning, not the address;
|
||||||
// this is done in the text line draw function.
|
// this is done in the text line draw function.
|
||||||
vga.draw.address = vga.draw.byte_panning_shift*vga.draw.bytes_skip;
|
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;
|
vga.draw.address_line=0;
|
||||||
}
|
}
|
||||||
@ -662,6 +611,29 @@ static void VGA_DrawSingleLine(Bitu /*blah*/) {
|
|||||||
} else RENDER_EndUpdate(false);
|
} 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) {
|
static void VGA_DrawPart(Bitu lines) {
|
||||||
while (lines--) {
|
while (lines--) {
|
||||||
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
|
Bit8u * data=VGA_DrawLine( vga.draw.address, vga.draw.address_line );
|
||||||
@ -771,7 +743,6 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
|||||||
VGA_DisplayStartLatch(0);
|
VGA_DisplayStartLatch(0);
|
||||||
break;
|
break;
|
||||||
case MCH_VGA:
|
case MCH_VGA:
|
||||||
case MCH_EGA:
|
|
||||||
PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrstart);
|
PIC_AddEvent(VGA_DisplayStartLatch, (float)vga.draw.delay.vrstart);
|
||||||
PIC_AddEvent(VGA_PanningLatch, (float)vga.draw.delay.vrend);
|
PIC_AddEvent(VGA_PanningLatch, (float)vga.draw.delay.vrend);
|
||||||
// EGA: 82c435 datasheet: interrupt happens at display end
|
// 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
|
// 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));
|
PIC_AddEvent(VGA_VertInterrupt,(float)(vga.draw.delay.vdend + 0.005));
|
||||||
break;
|
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:
|
default:
|
||||||
E_Exit("This new machine needs implementation in VGA_VerticalTimer too.");
|
E_Exit("This new machine needs implementation in VGA_VerticalTimer too.");
|
||||||
break;
|
break;
|
||||||
@ -798,7 +773,11 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
|||||||
vga.draw.address = vga.config.real_start;
|
vga.draw.address = vga.config.real_start;
|
||||||
vga.draw.byte_panning_shift = 0;
|
vga.draw.byte_panning_shift = 0;
|
||||||
// go figure...
|
// 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);
|
// if (machine==MCH_EGA) vga.draw.split_line = ((((vga.config.line_compare&0x5ff)+1)*2-1)/vga.draw.lines_scaled);
|
||||||
#ifdef VGA_KEEP_CHANGES
|
#ifdef VGA_KEEP_CHANGES
|
||||||
bool startaddr_changed=false;
|
bool startaddr_changed=false;
|
||||||
@ -811,7 +790,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
|||||||
vga.draw.byte_panning_shift = 8;
|
vga.draw.byte_panning_shift = 8;
|
||||||
vga.draw.address += vga.draw.bytes_skip;
|
vga.draw.address += vga.draw.bytes_skip;
|
||||||
vga.draw.address *= vga.draw.byte_panning_shift;
|
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
|
#ifdef VGA_KEEP_CHANGES
|
||||||
startaddr_changed=true;
|
startaddr_changed=true;
|
||||||
#endif
|
#endif
|
||||||
@ -851,6 +830,10 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
|
|||||||
/* check for blinking and blinking change delay */
|
/* check for blinking and blinking change delay */
|
||||||
FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ?
|
FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ?
|
||||||
0 : 0xffffffff;
|
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;
|
break;
|
||||||
case M_HERC_GFX:
|
case M_HERC_GFX:
|
||||||
break;
|
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);
|
PIC_AddEvent(VGA_DrawPart,(float)vga.draw.delay.parts + draw_skip,vga.draw.parts_lines);
|
||||||
break;
|
break;
|
||||||
case LINE:
|
case LINE:
|
||||||
|
case EGALINE:
|
||||||
if (GCC_UNLIKELY(vga.draw.lines_done < vga.draw.lines_total)) {
|
if (GCC_UNLIKELY(vga.draw.lines_done < vga.draw.lines_total)) {
|
||||||
LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d",
|
LOG(LOG_VGAMISC,LOG_NORMAL)( "Lines left: %d",
|
||||||
vga.draw.lines_total-vga.draw.lines_done);
|
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);
|
RENDER_EndUpdate(true);
|
||||||
}
|
}
|
||||||
vga.draw.lines_done = 0;
|
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;
|
break;
|
||||||
//case EGALINE:
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -982,6 +968,10 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
|||||||
case MCH_PCJR:
|
case MCH_PCJR:
|
||||||
vga.draw.mode = LINE;
|
vga.draw.mode = LINE;
|
||||||
break;
|
break;
|
||||||
|
case MCH_EGA:
|
||||||
|
// Note: The Paradise SVGA uses the same panning mechanism as EGA
|
||||||
|
vga.draw.mode = EGALINE;
|
||||||
|
break;
|
||||||
case MCH_VGA:
|
case MCH_VGA:
|
||||||
if (svgaCard==SVGA_None) {
|
if (svgaCard==SVGA_None) {
|
||||||
vga.draw.mode = LINE;
|
vga.draw.mode = LINE;
|
||||||
@ -1300,6 +1290,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
|||||||
vga.draw.blocks = width;
|
vga.draw.blocks = width;
|
||||||
width<<=3;
|
width<<=3;
|
||||||
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) {
|
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) {
|
||||||
|
// This would also be required for EGA in Spacepigs Megademo
|
||||||
bpp=16;
|
bpp=16;
|
||||||
VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line;
|
VGA_DrawLine = VGA_Draw_Xlat16_Linear_Line;
|
||||||
} else VGA_DrawLine=VGA_Draw_Linear_Line;
|
} else VGA_DrawLine=VGA_Draw_Linear_Line;
|
||||||
@ -1329,17 +1320,22 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
|||||||
aspect_ratio=1.0;
|
aspect_ratio=1.0;
|
||||||
vga.draw.blocks=width;
|
vga.draw.blocks=width;
|
||||||
doublewidth=(vga.seq.clocking_mode & 0x8) > 0;
|
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;
|
|
||||||
bpp=16;
|
|
||||||
// VGA_DrawLine=VGA_TEXT_Draw_Line_9;
|
|
||||||
} else {
|
|
||||||
width<<=3; /* 8 bit wide text font */
|
|
||||||
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) {
|
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;
|
VGA_DrawLine=VGA_TEXT_Xlat16_Draw_Line;
|
||||||
bpp=16;
|
bpp=16;
|
||||||
} else VGA_DrawLine=VGA_TEXT_Draw_Line;
|
} else {
|
||||||
|
// 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;
|
break;
|
||||||
case M_HERC_GFX:
|
case M_HERC_GFX:
|
||||||
@ -1442,8 +1438,10 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
|||||||
}
|
}
|
||||||
// LOG_MSG("ht %d vt %d ratio %f", htotal, vtotal, aspect_ratio );
|
// LOG_MSG("ht %d vt %d ratio %f", htotal, vtotal, aspect_ratio );
|
||||||
|
|
||||||
|
bool fps_changed = false;
|
||||||
// need to change the vertical timing?
|
// need to change the vertical timing?
|
||||||
if (fabs(vga.draw.delay.vtotal - 1000.0 / fps) > 0.0001) {
|
if (fabs(vga.draw.delay.vtotal - 1000.0 / fps) > 0.0001) {
|
||||||
|
fps_changed = true;
|
||||||
vga.draw.delay.vtotal = 1000.0 / fps;
|
vga.draw.delay.vtotal = 1000.0 / fps;
|
||||||
VGA_KillDrawing();
|
VGA_KillDrawing();
|
||||||
PIC_RemoveEvents(VGA_Other_VertInterrupt);
|
PIC_RemoveEvents(VGA_Other_VertInterrupt);
|
||||||
@ -1470,7 +1468,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
|||||||
(vga.draw.doublewidth != doublewidth) ||
|
(vga.draw.doublewidth != doublewidth) ||
|
||||||
(vga.draw.doubleheight != doubleheight) ||
|
(vga.draw.doubleheight != doubleheight) ||
|
||||||
(fabs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) ||
|
(fabs(aspect_ratio - vga.draw.aspect_ratio) > 0.0001) ||
|
||||||
(vga.draw.bpp != bpp)) {
|
(vga.draw.bpp != bpp) || fps_changed) {
|
||||||
|
|
||||||
VGA_KillDrawing();
|
VGA_KillDrawing();
|
||||||
|
|
||||||
@ -1494,6 +1492,7 @@ void VGA_SetupDrawing(Bitu /*val*/) {
|
|||||||
void VGA_KillDrawing(void) {
|
void VGA_KillDrawing(void) {
|
||||||
PIC_RemoveEvents(VGA_DrawPart);
|
PIC_RemoveEvents(VGA_DrawPart);
|
||||||
PIC_RemoveEvents(VGA_DrawSingleLine);
|
PIC_RemoveEvents(VGA_DrawSingleLine);
|
||||||
|
PIC_RemoveEvents(VGA_DrawEGASingleLine);
|
||||||
vga.draw.parts_left = 0;
|
vga.draw.parts_left = 0;
|
||||||
vga.draw.lines_done = ~0;
|
vga.draw.lines_done = ~0;
|
||||||
RENDER_EndUpdate(true);
|
RENDER_EndUpdate(true);
|
||||||
|
@ -516,7 +516,12 @@ static void write_hercules(Bitu port,Bitu val,Bitu /*iolen*/) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x3bf:
|
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;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -869,7 +869,7 @@ public:
|
|||||||
if (IS_TANDY_ARCH) {
|
if (IS_TANDY_ARCH) {
|
||||||
/* reduce reported memory size for the Tandy (32k graphics memory
|
/* reduce reported memory size for the Tandy (32k graphics memory
|
||||||
at the end of the conventional 640k) */
|
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);
|
else mem_writew(BIOS_MEMORY_SIZE,640);
|
||||||
mem_writew(BIOS_TRUE_MEMORY_SIZE,640);
|
mem_writew(BIOS_TRUE_MEMORY_SIZE,640);
|
||||||
} else mem_writew(BIOS_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);
|
reg_ah=(Bit8u)real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
|
||||||
break;
|
break;
|
||||||
case 0x10: /* Palette functions */
|
case 0x10: /* Palette functions */
|
||||||
if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x02))) break;
|
if ((machine==MCH_CGA) || ((!IS_VGA_ARCH) && (reg_al>0x03))) break;
|
||||||
//TODO: subfunction 0x03 for ega
|
|
||||||
switch (reg_al) {
|
switch (reg_al) {
|
||||||
case 0x00: /* SET SINGLE PALETTE REGISTER */
|
case 0x00: /* SET SINGLE PALETTE REGISTER */
|
||||||
INT10_SetSinglePaletteRegister(reg_bl,reg_bh);
|
INT10_SetSinglePaletteRegister(reg_bl,reg_bh);
|
||||||
@ -302,14 +301,9 @@ graphics_chars:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((reg_bh<=7) || (svgaCard==SVGA_TsengET4K)) {
|
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_cx=real_readw(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
|
||||||
reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
|
reg_dl=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG(LOG_INT10,LOG_ERROR)("Function 11:Unsupported character generator call %2X",reg_al);
|
LOG(LOG_INT10,LOG_ERROR)("Function 11:Unsupported character generator call %2X",reg_al);
|
||||||
|
@ -67,8 +67,20 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu
|
|||||||
IO_Write(base,0x9);
|
IO_Write(base,0x9);
|
||||||
IO_Write(base+1,(IO_Read(base+1) & 0xe0)|(height-1));
|
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
|
//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);
|
real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit8u)height);
|
||||||
//TODO Reprogram cursor size?
|
//TODO Reprogram cursor size?
|
||||||
}
|
}
|
||||||
|
@ -96,6 +96,7 @@ void INT10_SetAllPaletteRegisters(PhysPt data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void INT10_ToggleBlinkingBit(Bit8u state) {
|
void INT10_ToggleBlinkingBit(Bit8u state) {
|
||||||
|
if(IS_VGA_ARCH) {
|
||||||
Bit8u value;
|
Bit8u value;
|
||||||
// state&=0x01;
|
// state&=0x01;
|
||||||
if ((state>1) && (svgaCard==SVGA_S3Trio)) return;
|
if ((state>1) && (svgaCard==SVGA_S3Trio)) return;
|
||||||
@ -118,6 +119,22 @@ void INT10_ToggleBlinkingBit(Bit8u state) {
|
|||||||
if (state) msrval|=0x20;
|
if (state) msrval|=0x20;
|
||||||
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,msrval);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) {
|
void INT10_GetSinglePaletteRegister(Bit8u reg,Bit8u * val) {
|
||||||
|
@ -490,7 +490,7 @@ void SHELL_Init() {
|
|||||||
MSG_Add("SHELL_CMD_PAUSE_HELP","Waits for 1 keystroke to continue.\n");
|
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_FAILURE","Copy failure : %s.\n");
|
||||||
MSG_Add("SHELL_CMD_COPY_SUCCESS"," %d File(s) copied.\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");
|
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
|
#ifdef HW_RVL
|
||||||
|
@ -945,17 +945,22 @@ void DOS_Shell::CMD_SUBST (char * args) {
|
|||||||
CommandLine command(0,args);
|
CommandLine command(0,args);
|
||||||
|
|
||||||
if (command.GetCount() != 2) throw 0 ;
|
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);
|
command.FindCommand(1,arg);
|
||||||
if( (arg.size()>1) && arg[1] !=':') throw(0);
|
if( (arg.size()>1) && arg[1] !=':') throw(0);
|
||||||
temp_str[0]=(char)toupper(args[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
|
if(Drives[temp_str[0]-'A'] ) throw 0; //targetdrive in use
|
||||||
strcat(mountstring,temp_str);
|
strcat(mountstring,temp_str);
|
||||||
strcat(mountstring," ");
|
strcat(mountstring," ");
|
||||||
|
|
||||||
command.FindCommand(2,arg);
|
|
||||||
Bit8u drive;char fulldir[DOS_PATHLENGTH];
|
Bit8u drive;char fulldir[DOS_PATHLENGTH];
|
||||||
if (!DOS_MakeName(const_cast<char*>(arg.c_str()),fulldir,&drive)) throw 0;
|
if (!DOS_MakeName(const_cast<char*>(arg.c_str()),fulldir,&drive)) throw 0;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user