sync to dosbox r3778

This commit is contained in:
dborth 2012-02-09 02:35:43 +00:00
parent 033d4e91e4
commit ccd97a1f39
63 changed files with 1043 additions and 393 deletions

106
README
View File

@ -220,11 +220,11 @@ CD-ROM: My CD-ROM doesn't work.
To enable SDL-support (does not include low-level CD access!):
- mount d f:\ -t cdrom -usecd 0 -noioctl
To enable ioctl access using digital audio extraction for CD audio
(windows-only, useful for Vista):
(Windows-only, useful for Vista):
- mount d f:\ -t cdrom -ioctl_dx
To enable ioctl access using MCI for CD audio (windows-only):
To enable ioctl access using MCI for CD audio (Windows-only):
- mount d f:\ -t cdrom -ioctl_mci
To force ioctl-only access (windows-only):
To force ioctl-only access (Windows-only):
- mount d f:\ -t cdrom -ioctl_dio
To enable low-level aspi-support (win98 with aspi-layer installed):
- mount d f:\ -t cdrom -aspi
@ -265,7 +265,7 @@ SOUND: There is no sound.
Be sure that the sound is correctly configured in the game. This might be
done during the installation or with a setup/setsound utility that
accompanies the game. First see if an autodetection option is provided. If
there is none try selecting Soundblaster or Soundblaster 16 with the default
there is none try selecting SoundBlaster or SoundBlaster 16 with the default
settings being "address=220 irq=7 dma=1" (sometimes highdma=5). You might
also want to select Sound Canvas/SCC/MPU-401/General MIDI/Wave Blaster
at "address=330 IRQ=2" as music device.
@ -275,8 +275,8 @@ SOUND: There is no sound.
configuration and use some lower fixed cycles value (like cycles=2000). Also
assure that your host operating sound does provide sound.
In certain cases it might be useful to use a different emulated sound device
like a soundblaster pro (sbtype=sbpro1 in the DOSBox configuration file) or
the gravis ultrasound (gus=true).
like a SoundBlaster Pro (sbtype=sbpro1 in the DOSBox configuration file) or
the Gravis Ultrasound (gus=true).
SOUND: What sound hardware does DOSBox presently emulate?
@ -286,21 +286,21 @@ SOUND: What sound hardware does DOSBox presently emulate?
digital sound output through the internal speaker.
- Creative CMS/Gameblaster
The is the first card released by Creative Labs(R). The default
configuration places it on address 220. It is disabled as default.
configuration places it on address 220. It is disabled by default.
- Tandy 3 voice
The emulation of this sound hardware is complete with the exception of
the noise channel. The noise channel is not very well documented and as
such is only a best guess as to the sound's accuracy. It is disabled as
default.
- Tandy DAC
Some games may require turning off sound blaster emulation (sbtype=none)
for better tandy DAC sound support. Don't forget to set the sbtype back to
sb16 if you don't use tandy sound.
Some games may require turning off SoundBlaster emulation (sbtype=none)
for better Tandy DAC sound support. Don't forget to set the sbtype back to
sb16 if you don't use Tandy sound.
- Adlib
This emulation is almost perfect and includes the Adlib's ability to
almost play digitized sound. Placed at address 220 (also on 388).
- SoundBlaster 16 / SoundBlaster Pro I & II / SoundBlaster I & II
By default DOSBox provides Soundblaster 16 level 16-bit stereo sound.
By default DOSBox provides SoundBlaster 16 level 16-bit stereo sound.
You can select a different SoundBlaster version in the configuration of
DOSBox. AWE32 music is not emulated as you can use MPU-401 instead
(see below).
@ -311,14 +311,14 @@ SOUND: What sound hardware does DOSBox presently emulate?
The emulation of this hardware is nearly complete, though the MIDI
capabilities have been left out, since an MPU-401 has been emulated
in other code. For Gravis music you also have to install Gravis drivers
inside DOSBox. It is disabled as default.
inside DOSBox. It is disabled by default.
- MPU-401
A MIDI passthrough interface is also emulated. This method of sound
output will only work when used with external device/emulator.
Every Windows XP/Vista/7 and MAC OS has got a default emulator compatible
with: Sound Canvas/SCC/General Standard/General MIDI/Wave Blaster.
A different device/emulator is needed for Roland LAPC/CM-32L/MT-32
compatibility.
Every Windows XP/Vista/7 and Mac OS X has got a default emulator
compatible with: Sound Canvas/SCC/General Standard/General MIDI/Wave
Blaster. A different device/emulator is needed for
Roland LAPC/CM-32L/MT-32 compatibility.
SOUND: The sound stutters or sounds stretched/weird.
@ -387,7 +387,7 @@ CRASH: The game/application does not run at all/crashes!
Look at Section 11: "Troubleshooting".
CRASH: DOSBox crashes on startup!.
CRASH: DOSBox crashes on startup!
Look at Section 11: "Troubleshooting".
@ -429,7 +429,7 @@ See Section 13: "The configuration (options) file".
To be able to use Command Line Parameters:
(Windows) open cmd.exe or command.com or edit the shortcut to dosbox.exe
(Linux) use console
(MAC OS X) start terminal.app and navigate to:
(Mac OS X) start terminal.app and navigate to:
/applications/dosbox.app/contents/macos/dosbox
The options are valid for all operating systems unless noted in the option
@ -482,15 +482,15 @@ dosbox -erasemapper
-machine machinetype
Setup DOSBox to emulate a specific type of machine. Valid choices are:
hercules, cga, ega, pcjr, tandy, svga_s3 (default) as well as
the additional svga chipsets listed in the DOSBox configuration file.
svga_s3 enables vesa emulation as well.
For some special vga effects the machinetype vgaonly can be used,
note that this disables svga capabilities and might be slower due to the
the additional SVGA chipsets listed in the DOSBox configuration file.
svga_s3 enables VESA emulation as well.
For some special VGA effects the machinetype vgaonly can be used,
note that this disables SVGA capabilities and might be slower due to the
higher emulation precision.
The machinetype affects the video card and the available sound cards.
-noconsole (Windows Only)
Start DOSBox without showing DOSBox Status Window (console).
Start DOSBox without showing the DOSBox status window (console).
Output will be redirected to stdout.txt and stderr.txt
-startmapper
@ -630,7 +630,7 @@ MOUNT -u "Emulated Drive letter"
Forces use of the SDL CD-ROM layer. Valid on all systems.
-usecd number
Valid on all systems, under windows the -noioctl switch has to be
Valid on all systems, under Windows the -noioctl switch has to be
present to make use of the -usecd switch.
Enables to select the drive that should be used by SDL. Use this if
the wrong or no CD-ROM drive is mounted while using the SDL CD-ROM
@ -882,10 +882,19 @@ LOADFIX -f
loadfix -f
RESCAN
RESCAN [Drive:] [-All]
Make DOSBox reread the directory structure. Useful if you changed something
on a mounted drive outside of DOSBox. (CTRL - F4 does this as well!)
Drive:
Drive to refresh.
-All
Refresh all drives.
if both a Drive: and -All are missing, then the current drive will be
refreshed.
MIXER
Makes DOSBox display its current volume settings.
@ -1170,8 +1179,8 @@ CTRL-F11 Slow down emulation (Decrease DOSBox Cycles).
CTRL-F12 Speed up emulation (Increase DOSBox Cycles)*.
ALT-F12 Unlock speed (turbo button/fast forward)**.
CTRL-ALT-HOME Restart DOSBox.
F11, ALT-F11 (machine=cga) change tint in NTSC output modes***
F11 (machine=hercules) cycle through amber, green, white colouring***
F11, ALT-F11 (machine=cga) change tint in NTSC output modes***.
F11 (machine=hercules) cycle through amber, green, white colouring***.
*NOTE: Once you increase your DOSBox cycles beyond your computer CPU resources,
it will produce the same effect as slowing down the emulation.
@ -1187,13 +1196,14 @@ F11 (machine=hercules) cycle through amber, green, white colouring***
These are the default keybindings. They can be changed in the keymapper
(see Section 7: "KeyMapper").
In MAC OS you can try using cmd(applekey) together with Ctrl if the key doesn't
work eg. cmd-ctrl-F1, but some keys may still need remapping (in Linux too).
In Mac OS X you can try using cmd(applekey) together with Ctrl (and/or ) Fn,
if the key doesn't work i.e. fn-cmd-ctrl-F1, but some keys may still need
remapping (in Linux too).
Saved/recorded files can be found in:
(Windows) "Start/WinLogo Menu"->"All Programs"->DOSBox-0.74->Extras
(Linux) ~/.dosbox/capture
(MAC OS X) "~/Library/Preferences/capture"
(Mac OS X) "~/Library/Preferences/capture"
This can be changed in the DOSBox configuration file.
@ -1231,7 +1241,7 @@ connected, or with a different joystick setting, your new setting will not work
properly, or not work at all, until you reset DOSBox's mapperfile.
If controller is working properly outside DOSBox, but doesn't calibrate properly
inside DOSBox, try different 'timed' setting in DOSBox's configuration file.
inside DOSBox, try a different 'timed' setting in DOSBox's configuration file.
@ -1239,8 +1249,8 @@ inside DOSBox, try different 'timed' setting in DOSBox's configuration file.
7. KeyMapper:
=============
You start the DOSBox mapper either with CTRL-F1 (see Section 5: "Special Keys")
or -startmapper (see Section 3: "Command Line Parameters").
Start the DOSBox mapper either with CTRL-F1 (see Section 5: "Special Keys") or
-startmapper (see Section 3: "Command Line Parameters").
You are presented with a virtual keyboard and a virtual joystick.
These virtual devices correspond to the keys and events DOSBox will
@ -1296,7 +1306,7 @@ Q3. If you try it out in DOSBox, you will notice that pressing X makes ZX
mapped key X. Click "Del".
Examples about remapping the joystick:
Examples of remapping the joystick:
You have a joystick attached, it is working fine under DOSBox and you
want to play some keyboard-only game with the joystick (it is assumed
that the game is controlled by the arrows on the keyboard):
@ -1318,7 +1328,7 @@ Examples about remapping the joystick:
If you want to remap anything to your d-pad/hat you will have to change
'joysticktype=auto' to 'joysticktype=fcs' in configuration file. Maybe this
will be improved in the next dosbox version.
will be improved in the next DOSBox version.
If you change the default mapping, you can save your changes by clicking on
@ -1333,12 +1343,12 @@ your mapperfile, if it is present in the DOSBox configuration file.
===================
To switch to a different keyboard layout, either the entry "keyboardlayout"
in the [dos] section of the DOSBox configuration file can be used, or the
internal DOSBox program keyb.com (Section 4: "Internal Programs"). Both accept
in the [dos] section of the DOSBox configuration file or the internal DOSBox
program keyb.com (Section 4: "Internal Programs") can be used. Both accept
DOS conforming language codes (see below), but only by using keyb.com a
custom codepage can be specified.
The default keyboardlayout=auto currently works under windows only. The language
The default keyboardlayout=auto currently works under Windows only. The language
is chosen according to the OS language, but the keyboard layout is not detected.
Layout switching
@ -1411,7 +1421,7 @@ of the nullmodem connection. These are all parameters:
* port: - TCP port number. Default: 23
* rxdelay: - how long (milliseconds) to delay received data if the
interface is not ready. Increase this value if you encounter
overrun errors in the DOSBox Status Window. Default: 100
overrun errors in the DOSBox status window. Default: 100
* txdelay: - how long to gather data before sending a packet. Default: 12
(reduces Network overhead)
* server: - This nullmodem will be a client connecting to the specified
@ -1517,7 +1527,7 @@ Example:
====================
General tip:
Check messages in DOSBox Status Window. See Section 12: "DOSBox Status Window".
Check messages in the DOSBox status window. See Section 12: "DOSBox Status Window".
DOSBox crashes right after starting it:
- use different values for the output= entry in your DOSBox
@ -1563,14 +1573,14 @@ The game exits to the DOSBox prompt with some error message:
12. DOSBox Status Window:
=========================
DOSBox's Staus window contains many useful information about your currant
configuration, your actions in DOSBox, errors that happened and more.
Whenever you have any problem with DOSBox check these messages.
DOSBox's status window contains useful information about your current
configuration, your actions in DOSBox, errors which occurred and more.
Check these messages in case you encounter any problems with DOSBox.
To start DOSBox Status Window:
(Windows) Status Window is being started together with main DOSBox window.
(Linux) You may have to start DOSBox from a console to see Status Window.
(MAC OS X) Right click on DOSBox.app, choose "Show Package Contents"->
To display the DOSBox status window:
(Windows) The status window is being started together with main DOSBox window.
(Linux) You may have to start DOSBox from a console to see the status window.
(Mac OS X) Right click on DOSBox.app, choose "Show Package Contents"->
->enter "Contents"->enter "MacOS"->run "DOSBox"
@ -1583,7 +1593,7 @@ The configuration file is automatically created the first time you run DOSBox.
The file can be found in:
(Windows) "Start/WinLogo Menu"->"All Programs"->DOSBox-0.74->Options
(Linux) ~/.dosbox/dosbox-0.74.conf
(MAC OS X) "~/Library/Preferences/DOSBox 0.74 Preferences"
(Mac OS X) "~/Library/Preferences/DOSBox 0.74 Preferences"
The file is divided into several sections. Each section starts with a
[section name] line. The settings are the property=value lines where value can
be altered to customize DOSBox.

View File

@ -205,7 +205,7 @@ which is located on the local filesystem. Not a mounted drive in
.RS
.TP
.B \-securemode
.RB Switches dosbox " to a more secure mode. In this mode the"
.RB "Switches " dosbox " to a more secure mode. In this mode the"
.RI "internal commands " MOUNT ", " IMGMOUNT " and " BOOT " won\'t work."
It\'s not possible
either to create a new configfile or languagefile in this mode.
@ -216,7 +216,7 @@ either to create a new configfile or languagefile in this mode.
The configuration file controls various settings of
.BR dosbox ": The amount of emulated memory,"
the emulated soundcards and many
.RI "more things. It futher allows acces to " AUTOEXEC.BAT .
.RI "more things. It further allows access to " AUTOEXEC.BAT .
.LP
The language file controls all visible output of the internal commands and
the internal dos.
@ -242,11 +242,21 @@ The amount of memory to eat up (in kb). Example \-32, \-64 or \-128
Frees all memory eaten up by loadfix.
.RE
.TP
.B RESCAN
.B RESCAN [\-All] [Drive:]
.LP
.RB "Make " dosbox " reread the directory structure. Useful if you changed
.RB "something on a mounted drive outside " dosbox ".(CTRL\-F4 does"
this as well!)
.RS
.TP
.B \-All
.R Reread directory structure for all drives.
.TP
.B Drive:
.RB "Reread directory structure for drive " Drive:
.RE
.LP
.RB "If both " \-All " and " Drive: " are missing, then the current drive is used.
.TP
.B IMGMOUNT
.LP
@ -335,7 +345,7 @@ gets saved/recorded !
capacity, it will produce the same effect as slowing down the emulation.
This maximum will vary from computer to computer, there is no standard.
.SH "SYSTEM REQUIREMENTS"
Fast machine. My guess would be pentium\-2 400+ to get decent emulation
Fast machine. My guess would be Pentium\-2 400+ to get decent emulation
of games written for an 286 machine.
For protected mode games a 1 Ghz machine is recommended and don't expect
them to run fast though!! Be sure to read the next section on how to speed

View File

@ -69,6 +69,7 @@ public:
};
void updateDPT(void);
void incrementFDD(void);
#define MAX_HDD_IMAGES 2

View File

@ -30,7 +30,7 @@ extern CallBack_Handler CallBack_Handlers[];
enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,
CB_IRQ0,CB_IRQ1,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_IRQ6_PCJR,CB_MOUSE,
CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET,
CB_INT21 };
CB_INT21,CB_INT13 };
#define CB_MAX 128
#define CB_SIZE 32

View File

@ -61,16 +61,17 @@ public:
PCI_Device* GetSubdevice(Bits subfct);
Bit16u NumSubdevices(void) {
if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return PCI_MAX_PCIFUNCTIONS-1;
return num_subdevices;
if (num_subdevices>PCI_MAX_PCIFUNCTIONS-1) return (Bit16u)(PCI_MAX_PCIFUNCTIONS-1);
return (Bit16u)num_subdevices;
}
Bits GetNextSubdeviceNumber(void) {
if (num_subdevices>=PCI_MAX_PCIFUNCTIONS-1) return -1;
return num_subdevices+1;
return (Bits)num_subdevices+1;
}
virtual Bits ParseReadRegister(Bit8u regnum)=0;
virtual bool OverrideReadRegister(Bit8u regnum, Bit8u* rval, Bit8u* rval_mask)=0;
virtual Bits ParseWriteRegister(Bit8u regnum,Bit8u value)=0;
virtual bool InitializeRegisters(Bit8u registers[256])=0;

View File

@ -50,6 +50,7 @@ public:
bool FindCommand(unsigned int which,std::string & value);
bool FindStringBegin(char const * const begin,std::string & value, bool remove=false);
bool FindStringRemain(char const * const name,std::string & value);
bool FindStringRemainBegin(char const * const name,std::string & value);
bool GetStringRemain(std::string & value);
int GetParameterFromList(const char* const params[], std::vector<std::string> & output);
void FillVector(std::vector<std::string> & vector);

View File

@ -166,6 +166,7 @@ typedef struct {
} cursor;
Drawmode mode;
bool vret_triggered;
bool vga_override;
} VGA_Draw;
typedef struct {
@ -448,6 +449,8 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3);
void VGA_ActivateHardwareCursor(void);
void VGA_KillDrawing(void);
void VGA_SetOverride(bool vga_override);
extern VGA_Type vga;
/* Support for modular SVGA implementation */

View File

@ -433,7 +433,18 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
phys_writeb(physAddress+0x09,(Bit8u)0x59); // pop cx
phys_writeb(physAddress+0x0A,(Bit8u)0xCF); //An IRET Instruction
return (use_cb?15:11);
case CB_INT13:
phys_writeb(physAddress+0x00,(Bit8u)0xFB); //STI
if (use_cb) {
phys_writeb(physAddress+0x01,(Bit8u)0xFE); //GRP 4
phys_writeb(physAddress+0x02,(Bit8u)0x38); //Extra Callback instruction
phys_writew(physAddress+0x03,(Bit16u)callback); //The immediate word
physAddress+=4;
}
phys_writeb(physAddress+0x01,(Bit8u)0xCF); //An IRET Instruction
phys_writew(physAddress+0x02,(Bit16u)0x0ECD); // int 0e
phys_writeb(physAddress+0x04,(Bit8u)0xCF); //An IRET Instruction
return (use_cb?9:5);
default:
E_Exit("CALLBACK:Setup:Illegal type %d",type);
}

View File

@ -247,8 +247,8 @@ static void dyn_restoreregister(DynReg * src_reg, DynReg * dst_reg) {
{ \
__asm__ volatile ( \
"fnsave %0 \n" \
: "=m" (dyn_dh_fpu.state[0]) \
: \
: "m" (dyn_dh_fpu.state[0]) \
: "memory" \
); \
dyn_dh_fpu.state_used=false; \
@ -303,7 +303,10 @@ run_block:
}
#endif
if (!GETFLAG(TF)) {
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
if (GETFLAG(IF) && PIC_IRQCheck) {
if (dyn_dh_fpu.state_used) DH_FPU_SAVE_REINIT
return CBRET_NONE;
}
goto restart_core;
}
cpudecoder=CPU_Core_Dyn_X86_Trap_Run;
@ -450,8 +453,8 @@ void CPU_Core_Dyn_X86_Init(void) {
"finit \n"
"fsave %0 \n"
"fstcw %1 \n"
: "=m" (dyn_dh_fpu.state[0]), "=m" (dyn_dh_fpu.host_cw)
:
: "m" (dyn_dh_fpu.state[0]), "m" (dyn_dh_fpu.host_cw)
: "memory"
);
#endif
@ -468,8 +471,62 @@ void CPU_Core_Dyn_X86_Cache_Close(void) {
cache_close();
}
void CPU_Core_Dyn_X86_Cache_Reset(void) {
cache_reset();
}
void CPU_Core_Dyn_X86_SetFPUMode(bool dh_fpu) {
dyn_dh_fpu.dh_fpu_enabled=dh_fpu;
}
Bit32u fpu_state[32];
void CPU_Core_Dyn_X86_SaveDHFPUState(void) {
if (dyn_dh_fpu.dh_fpu_enabled) {
if (dyn_dh_fpu.state_used!=0) {
#if defined (_MSC_VER)
__asm {
__asm fsave fpu_state[0]
__asm finit
}
#else
__asm__ volatile (
"fsave %0 \n"
"finit \n"
: "=m" (fpu_state[0])
:
: "memory"
);
#endif
}
}
}
void CPU_Core_Dyn_X86_RestoreDHFPUState(void) {
if (dyn_dh_fpu.dh_fpu_enabled) {
if (dyn_dh_fpu.state_used!=0) {
#if defined (_MSC_VER)
__asm {
__asm frstor fpu_state[0]
}
#else
__asm__ volatile (
"frstor %0 \n"
:
: "m" (fpu_state[0])
:
);
#endif
}
}
}
#else
void CPU_Core_Dyn_X86_SaveDHFPUState(void) {
}
void CPU_Core_Dyn_X86_RestoreDHFPUState(void) {
}
#endif

View File

@ -569,3 +569,75 @@ static void cache_close(void) {
cache_code_link_blocks = NULL;
cache_initialized = false; */
}
static void cache_reset(void) {
if (cache_initialized) {
for (;;) {
if (cache.used_pages) {
CodePageHandler * cpage=cache.used_pages;
CodePageHandler * npage=cache.used_pages->next;
cpage->ClearRelease();
delete cpage;
cache.used_pages=npage;
} else break;
}
if (cache_blocks == NULL) {
cache_blocks=(CacheBlock*)malloc(CACHE_BLOCKS*sizeof(CacheBlock));
if(!cache_blocks) E_Exit("Allocating cache_blocks has failed");
}
memset(cache_blocks,0,sizeof(CacheBlock)*CACHE_BLOCKS);
cache.block.free=&cache_blocks[0];
for (Bits i=0;i<CACHE_BLOCKS-1;i++) {
cache_blocks[i].link[0].to=(CacheBlock *)1;
cache_blocks[i].link[1].to=(CacheBlock *)1;
cache_blocks[i].cache.next=&cache_blocks[i+1];
}
if (cache_code_start_ptr==NULL) {
#if defined (WIN32)
cache_code_start_ptr=(Bit8u*)VirtualAlloc(0,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP,
MEM_COMMIT,PAGE_EXECUTE_READWRITE);
if (!cache_code_start_ptr)
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#else
cache_code_start_ptr=(Bit8u*)malloc(CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP-1+PAGESIZE_TEMP);
#endif
if (!cache_code_start_ptr) E_Exit("Allocating dynamic core cache memory failed");
cache_code=(Bit8u*)(((int)cache_code_start_ptr + PAGESIZE_TEMP-1) & ~(PAGESIZE_TEMP-1)); //MEM LEAK. store old pointer if you want to free it.
cache_code_link_blocks=cache_code;
cache_code+=PAGESIZE_TEMP;
#if (C_HAVE_MPROTECT)
if(mprotect(cache_code_link_blocks,CACHE_TOTAL+CACHE_MAXSIZE+PAGESIZE_TEMP,PROT_WRITE|PROT_READ|PROT_EXEC))
LOG_MSG("Setting excute permission on the code cache has failed!");
#endif
}
CacheBlock * block=cache_getblock();
cache.block.first=block;
cache.block.active=block;
block->cache.start=&cache_code[0];
block->cache.size=CACHE_TOTAL;
block->cache.next=0; //Last block in the list
/* Setup the default blocks for block linkage returns */
cache.pos=&cache_code_link_blocks[0];
link_blocks[0].cache.start=cache.pos;
gen_return(BR_Link1);
cache.pos=&cache_code_link_blocks[32];
link_blocks[1].cache.start=cache.pos;
gen_return(BR_Link2);
cache.free_pages=0;
cache.last_page=0;
cache.used_pages=0;
/* Setup the code pages */
for (Bitu i=0;i<CACHE_PAGES;i++) {
CodePageHandler * newpage=new CodePageHandler();
newpage->next=cache.free_pages;
cache.free_pages=newpage;
}
}
}

View File

@ -2677,7 +2677,7 @@ restart_prefix:
goto illegalopcode;
}
}
// link to next block because the maximal number of opcodes has been reached
// link to next block because the maximum number of opcodes has been reached
dyn_set_eip_end();
dyn_reduce_cycles();
dyn_save_critical_regs();

View File

@ -246,7 +246,7 @@ run_block:
// the block was exited due to a non-predictable control flow
// modifying instruction (like ret) or some nontrivial cpu state
// changing instruction (for example switch to/from pmode),
// or the maximal number of instructions to translate was reached
// or the maximum number of instructions to translate was reached
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif

View File

@ -53,7 +53,7 @@ public:
CacheBlockDynRec * to; // this block can transfer control to the to-block
CacheBlockDynRec * next;
CacheBlockDynRec * from; // the from-block can transfer control to this block
} link[2]; // maximal two links (conditional jumps)
} link[2]; // maximum two links (conditional jumps)
CacheBlockDynRec * crossblock;
};

View File

@ -26,7 +26,7 @@
/*
The function CreateCacheBlock translates the instruction stream
until either an unhandled instruction is found, the maximal
until either an unhandled instruction is found, the maximum
number of translated instructions is reached or some critical
instruction is encountered.
*/
@ -586,7 +586,7 @@ restart_prefix:
goto illegalopcode;
}
}
// link to next block because the maximal number of opcodes has been reached
// link to next block because the maximum number of opcodes has been reached
dyn_set_eip_end();
dyn_reduce_cycles();
gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlockDynRec,cache.start));

View File

@ -502,7 +502,7 @@ l_M_Ed:
continue;
case D_RDTSC: {
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) goto illegalopcode;
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double)CPU_CycleMax);
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double)(CPU_CycleAutoAdjust?70000:CPU_CycleMax));
reg_edx=(Bit32u)(tsc>>32);
reg_eax=(Bit32u)(tsc&0xffffffff);
break;

View File

@ -228,7 +228,8 @@
CASE_0F_B(0x31) /* RDTSC */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_PENTIUMSLOW) goto illegal_opcode;
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double)CPU_CycleMax);
/* Use a fixed number when in auto cycles mode as else the reported value changes constantly */
Bit64s tsc=(Bit64s)(PIC_FullIndex()*(double) (CPU_CycleAutoAdjust?70000:CPU_CycleMax));
reg_edx=(Bit32u)(tsc>>32);
reg_eax=(Bit32u)(tsc&0xffffffff);
}

View File

@ -19,6 +19,7 @@
#include <assert.h>
#include <sstream>
#include <stddef.h>
#include "dosbox.h"
#include "cpu.h"
#ifdef HW_RVL

View File

@ -849,7 +849,7 @@ void PAGING_SetDirBase(Bitu cr3) {
}
void PAGING_Enable(bool enabled) {
/* If paging is disable we work from a default paging table */
/* If paging is disabled, we work from a default paging table */
if (paging.enabled==enabled) return;
paging.enabled=enabled;
if (enabled) {

View File

@ -402,7 +402,7 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate)
CBreakpoint* bp;
for(i=BPoints.begin(); i != BPoints.end(); i++) {
bp = (*i);
// Do not activate, when bp is an actual adress
// Do not activate, when bp is an actual address
if (activate && (bp->GetType()==BKPNT_PHYSICAL) && (bp->GetLocation()==adr)) {
// Do not activate :)
continue;
@ -412,7 +412,7 @@ void CBreakpoint::ActivateBreakpoints(PhysPt adr, bool activate)
};
bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off)
// Checks if breakpoint is valid an should stop execution
// Checks if breakpoint is valid and should stop execution
{
if ((ignoreAddressOnce!=0) && (GetAddress(seg,off)==ignoreAddressOnce)) {
ignoreAddressOnce = 0;
@ -476,7 +476,7 @@ bool CBreakpoint::CheckBreakpoint(Bitu seg, Bitu off)
};
bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue)
// Checks if interrupt breakpoint is valid an should stop execution
// Checks if interrupt breakpoint is valid and should stop execution
{
if ((ignoreAddressOnce!=0) && (adr==ignoreAddressOnce)) {
ignoreAddressOnce = 0;
@ -491,7 +491,7 @@ bool CBreakpoint::CheckIntBreakpoint(PhysPt adr, Bit8u intNr, Bit16u ahValue)
bp = (*i);
if ((bp->GetType()==BKPNT_INTERRUPT) && bp->IsActive() && (bp->GetIntNr()==intNr)) {
if ((bp->GetValue()==BPINT_ALL) || (bp->GetValue()==ahValue)) {
// Ignoie it once ?
// Ignore it once ?
if (ignoreOnce==bp) {
ignoreOnce=0;
bp->Activate(true);
@ -681,7 +681,7 @@ static void DrawData(void) {
Bit32u address;
/* Data win */
for (int y=0; y<8; y++) {
// Adress
// Address
if (add<0x10000) mvwprintw (dbg.win_data,1+y,0,"%04X:%04X ",dataSeg,add);
else mvwprintw (dbg.win_data,1+y,0,"%04X:%08X ",dataSeg,add);
for (int x=0; x<16; x++) {
@ -1402,7 +1402,7 @@ char* AnalyzeInstruction(char* inst, bool saveSelector) {
// Variable found ?
CDebugVar* var = CDebugVar::FindVar(address);
if (var) {
// Replace occurance
// Replace occurence
char* pos1 = strchr(inst,'[');
char* pos2 = strchr(inst,']');
if (pos1 && pos2) {
@ -2424,7 +2424,7 @@ void DEBUG_HeavyWriteLogInstruction(void) {
out << hex << noshowbase << setfill('0') << uppercase;
Bit32u startLog = logCount;
do {
// Write Intructions
// Write Instructions
TLogInst & inst = logInst[startLog];
out << setw(4) << inst.s_cs << ":" << setw(8) << inst.eip << " "
<< inst.dline << " " << inst.res << " EAX:" << setw(8)<< inst.eax

View File

@ -283,8 +283,10 @@ static char const *second[] = {
0, 0, 0, 0,
0, 0, 0, 0,
/* 3 */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, "rdtsc", 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
/* 4 */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
@ -947,7 +949,9 @@ static void percent(char type, char subtype)
break;
case '2': /* old [pop cs]! now indexes */
ua_str(second[getbyte()]); /* instructions in 386/486 */
c = getbyte();
wordop = c & 1;
ua_str(second[c]); /* instructions in 386/486 */
break;
case 'g': /* modrm group `subtype' (0--7) */

View File

@ -161,7 +161,7 @@ static void DrawBars(void) {
static void MakeSubWindows(void) {
/* The Std output win should go in bottem */
/* The Std output win should go at the bottom */
/* Make all the subwindows */
int win_main_maxy, win_main_maxx; getmaxyx(dbg.win_main,win_main_maxy,win_main_maxx);
int outy=1; //Match values with above

View File

@ -37,7 +37,7 @@ public:
private:
Bit8u readcache;
Bit8u lastwrite;
struct ansi { /* should create a constructor which fills them with the appriorate values */
struct ansi { /* should create a constructor, which would fill them with the appropriate values */
bool esc;
bool sci;
bool enabled;
@ -128,7 +128,7 @@ bool device_CON::Write(Bit8u * data,Bit16u * size) {
count++;
continue;
} else {
/* Some sort of "hack" now that \n doesn't set col to 0 (int10_char.cpp old chessgame) */
/* Some sort of "hack" now that '\n' doesn't set col to 0 (int10_char.cpp old chessgame) */
if((data[count] == '\n') && (lastwrite != '\r')) INT10_TeletypeOutputAttr('\r',ansi.attr,ansi.enabled);
/* pass attribute only if ansi is enabled */
INT10_TeletypeOutputAttr(data[count],ansi.attr,ansi.enabled);

View File

@ -220,6 +220,7 @@ static Bitu DOS_21Handler(void) {
Bit8u free=mem_readb(data);
Bit8u read=0;Bit8u c;Bit16u n=1;
if (!free) break;
free--;
for(;;) {
DOS_ReadFile(STDIN,&c,&n);
if (c == 8) { // Backspace
@ -232,7 +233,7 @@ static Bitu DOS_21Handler(void) {
}
continue;
}
if (read >= free) { // Keyboard buffer full
if (read == free && c != 13) { // Keyboard buffer full
Bit8u bell = 7;
DOS_WriteFile(STDOUT, &bell, &n);
continue;

View File

@ -97,6 +97,7 @@ DOS_File::DOS_File(const DOS_File& orig) {
attr=orig.attr;
refCtr=orig.refCtr;
open=orig.open;
hdrive=orig.hdrive;
name=0;
if(orig.name) {
name=new char [strlen(orig.name) + 1];strcpy(name,orig.name);
@ -110,6 +111,7 @@ DOS_File & DOS_File::operator= (const DOS_File & orig) {
attr=orig.attr;
refCtr=orig.refCtr;
open=orig.open;
hdrive=orig.hdrive;
if(name) {
delete [] name; name=0;
}

View File

@ -93,8 +93,13 @@ void DOS_UpdatePSPName(void) {
DOS_MCB mcb(dos.psp()-1);
static char name[9];
mcb.GetFileName(name);
name[8] = 0;
if (!strlen(name)) strcpy(name,"DOSBOX");
RunningProgram=name;
for(Bitu i = 0;i < 8;i++) { //Don't put garbage in the title bar. Mac OS X doesn't like it
if (name[i] == 0) break;
if ( !isprint(*reinterpret_cast<unsigned char*>(&name[i])) ) name[i] = '?';
}
RunningProgram = name;
GFX_SetTitle(-1,-1,false);
}

View File

@ -299,7 +299,7 @@ bool DOS_Rename(char const * const oldname,char const * const newname) {
}
if (Drives[drivenew]->Rename(fullold,fullnew)) return true;
/* If it still fails. which error should we give ? PATH NOT FOUND or EACCESS */
/* If it still fails, which error should we give ? PATH NOT FOUND or EACCESS */
LOG(LOG_FILES,LOG_NORMAL)("Rename fails for %s to %s, no proper errorcode returned.",oldname,newname);
DOS_SetError(DOSERR_FILE_NOT_FOUND);
return false;
@ -924,7 +924,10 @@ bool DOS_FCBCreate(Bit16u seg,Bit16u offset) {
DOS_FCB fcb(seg,offset);
char shortname[DOS_FCBNAME];Bit16u handle;
fcb.GetName(shortname);
if (!DOS_CreateFile(shortname,DOS_ATTR_ARCHIVE,&handle)) return false;
Bit8u attr = DOS_ATTR_ARCHIVE;
fcb.GetAttr(attr);
if (!attr) attr = DOS_ATTR_ARCHIVE; //Better safe than sorry
if (!DOS_CreateFile(shortname,attr,&handle)) return false;
fcb.FileOpen((Bit8u)handle);
return true;
}
@ -1164,10 +1167,11 @@ bool DOS_FCBDeleteFile(Bit16u seg,Bit16u offset){
* stored. This can not be the tempdta as that one is used by fcbfindfirst
*/
RealPt old_dta=dos.dta();dos.dta(dos.tables.tempdta_fcbdelete);
DOS_FCB fcb(RealSeg(dos.dta()),RealOff(dos.dta()));
RealPt new_dta=dos.dta();
bool nextfile = false;
bool return_value = false;
nextfile = DOS_FCBFindFirst(seg,offset);
DOS_FCB fcb(RealSeg(new_dta),RealOff(new_dta));
while(nextfile) {
char shortname[DOS_FCBNAME] = { 0 };
fcb.GetName(shortname);

View File

@ -40,7 +40,7 @@ bool DOS_IOCTL(void) {
} else if (reg_al<0x12) { /* those use a diskdrive except 0x0b */
if (reg_al!=0x0b) {
drive=reg_bl;if (!drive) drive = DOS_GetDefaultDrive();else drive--;
if( !(( drive < DOS_DRIVES ) && Drives[drive]) ) {
if( (drive >= 2) && !(( drive < DOS_DRIVES ) && Drives[drive]) ) {
DOS_SetError(DOSERR_INVALID_DRIVE);
return false;
}
@ -133,7 +133,7 @@ bool DOS_IOCTL(void) {
}
return true;
case 0x09: /* Check if block device remote */
if (Drives[drive]->isRemote()) {
if ((drive >= 2) && Drives[drive]->isRemote()) {
reg_dx=0x1000; // device is remote
// undocumented bits always clear
} else {
@ -151,7 +151,7 @@ bool DOS_IOCTL(void) {
return true;
case 0x0D: /* Generic block device request */
{
if (Drives[drive]->isRemovable()) {
if ((drive < 2) || Drives[drive]->isRemovable()) {
DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID);
return false;
}
@ -202,11 +202,14 @@ bool DOS_IOCTL(void) {
return true;
}
case 0x0E: /* Get Logical Drive Map */
if (Drives[drive]->isRemovable()) {
if (drive < 2) {
if (Drives[drive]) reg_al=drive+1;
else reg_al=1;
} else if (Drives[drive]->isRemovable()) {
DOS_SetError(DOSERR_FUNCTION_NUMBER_INVALID);
return false;
}
reg_al = 0; /* Only 1 logical drive assigned */
} else reg_al=0; /* Only 1 logical drive assigned */
reg_ah=0x07;
return true;
default:
LOG(LOG_DOSMISC,LOG_ERROR)("DOS:IOCTL Call %2X unhandled",reg_al);

View File

@ -48,6 +48,7 @@ Bitu DEBUG_EnableDebugger(void);
#endif
void MSCDEX_SetCDInterface(int intNr, int forceCD);
static Bitu ZDRIVE_NUM = 25;
#ifdef HW_RVL
// Mounts a folder as a harddrive before starting the shell
@ -121,23 +122,51 @@ int MountDOSBoxDir(char DriveLetter, const char *path) {
class MOUNT : public Program {
public:
void Run(void)
{
void ListMounts(void) {
char name[DOS_NAMELENGTH_ASCII];Bit32u size;Bit16u date;Bit16u time;Bit8u attr;
/* Command uses dta so set it to our internal dta */
RealPt save_dta = dos.dta();
dos.dta(dos.tables.tempdta);
DOS_DTA dta(dos.dta());
WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1"));
WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),"Drive","Type","Label");
for(int p = 0;p < 8;p++) WriteOut("----------");
for (int d = 0;d < DOS_DRIVES;d++) {
if (!Drives[d]) continue;
char root[4] = {'A'+d,':','\\',0};
bool ret = DOS_FindFirst(root,DOS_ATTR_VOLUME);
if (ret) {
dta.GetResult(name,size,date,time,attr);
DOS_FindNext(); //Mark entry as invalid
} else name[0] = 0;
/* Change 8.3 to 11.0 */
char* dot = strchr(name,'.');
if(dot && (dot - name == 8) ) {
name[8] = name[9];name[9] = name[10];name[10] = name[11];name[11] = 0;
}
root[1] = 0; //This way, the format string can be reused.
WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_FORMAT"),root, Drives[d]->GetInfo(),name);
}
dos.dta(save_dta);
}
void Run(void) {
DOS_Drive * newdrive;char drive;
std::string label;
std::string umount;
std::string newz;
//Hack To allow long commandlines
ChangeToLongCmd();
/* Parse the command line */
/* if the command line is empty show current mounts */
if (!cmd->GetCount()) {
WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_1"));
for (int d=0;d<DOS_DRIVES;d++) {
if (Drives[d]) {
WriteOut(MSG_Get("PROGRAM_MOUNT_STATUS_2"),d+'A',Drives[d]->GetInfo());
}
}
ListMounts();
return;
}
@ -152,12 +181,12 @@ public:
if (cmd->FindString("-u",umount,false)) {
umount[0] = toupper(umount[0]);
int i_drive = umount[0]-'A';
if(i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) {
if (i_drive < DOS_DRIVES && i_drive >= 0 && Drives[i_drive]) {
switch (DriveManager::UnmountDrive(i_drive)) {
case 0:
Drives[i_drive] = 0;
if(i_drive == DOS_GetDefaultDrive())
DOS_SetDrive(toupper('Z') - 'A');
DOS_SetDrive(ZDRIVE_NUM);
WriteOut(MSG_Get("PROGRAM_MOUNT_UMOUNT_SUCCESS"),umount[0]);
break;
case 1:
@ -172,8 +201,46 @@ public:
}
return;
}
// Show list of cdroms
/* Check for moving Z: */
/* Only allowing moving it once. It is merely a convenience added for the wine team */
if (ZDRIVE_NUM == 25 && cmd->FindString("-z", newz,false)) {
newz[0] = toupper(newz[0]);
int i_newz = newz[0] - 'A';
if (i_newz >= 0 && i_newz < DOS_DRIVES-1 && !Drives[i_newz]) {
ZDRIVE_NUM = i_newz;
/* remap drives */
Drives[i_newz] = Drives[25];
Drives[25] = 0;
DOS_Shell *fs = static_cast<DOS_Shell *>(first_shell); //dynamic ?
/* Update environment */
std::string line = "";
char ppp[2] = {newz[0],0};
std::string tempenv = ppp; tempenv += ":\\";
if (fs->GetEnvStr("PATH",line)){
std::string::size_type idx = line.find('=');
std::string value = line.substr(idx +1 , std::string::npos);
while ( (idx = value.find("Z:\\")) != std::string::npos ||
(idx = value.find("z:\\")) != std::string::npos )
value.replace(idx,3,tempenv);
line = value;
}
if (!line.size()) line = tempenv;
fs->SetEnv("PATH",line.c_str());
tempenv += "COMMAND.COM";
fs->SetEnv("COMSPEC",tempenv.c_str());
/* Update batch file if running from Z: (very likely: autoexec) */
if(fs->bf) {
std::string &name = fs->bf->filename;
if(name.length() >2 && name[0] == 'Z' && name[1] == ':') name[0] = newz[0];
}
/* Change the active drive */
if (DOS_GetDefaultDrive() == 25) DOS_SetDrive(i_newz);
}
return;
}
/* Show list of cdroms */
if (cmd->FindExist("-cd",false)) {
int num = SDL_CDNumDrives();
WriteOut(MSG_Get("PROGRAM_MOUNT_CDROMS_FOUND"),num);
@ -393,6 +460,7 @@ public:
label = drive; label += "_FLOPPY";
newdrive->dirCache.SetLabel(label.c_str(),iscdrom,true);
}
if(type == "floppy") incrementFDD();
return;
showusage:
#if defined (WIN32) || defined(OS2)
@ -982,11 +1050,29 @@ public:
void RESCAN::Run(void)
{
// Get current drive
bool all = false;
Bit8u drive = DOS_GetDefaultDrive();
if (Drives[drive]) {
Drives[drive]->EmptyCache();
if(cmd->FindCommand(1,temp_line)) {
//-A -All /A /All
if(temp_line.size() >= 2 && (temp_line[0] == '-' ||temp_line[0] =='/')&& (temp_line[1] == 'a' || temp_line[1] =='A') ) all = true;
else if(temp_line.size() == 2 && temp_line[1] == ':') {
lowcase(temp_line);
drive = temp_line[0] - 'a';
}
}
// Get current drive
if (all) {
for(Bitu i =0; i<DOS_DRIVES;i++) {
if (Drives[i]) Drives[i]->EmptyCache();
}
WriteOut(MSG_Get("PROGRAM_RESCAN_SUCCESS"));
} else {
if (drive < DOS_DRIVES && Drives[drive]) {
Drives[drive]->EmptyCache();
WriteOut(MSG_Get("PROGRAM_RESCAN_SUCCESS"));
}
}
}
@ -1423,8 +1509,9 @@ void DOS_SetupPrograms(void) {
/*Add Messages */
MSG_Add("PROGRAM_MOUNT_CDROMS_FOUND","CDROMs found: %d\n");
MSG_Add("PROGRAM_MOUNT_STATUS_FORMAT","%-5s %-58s %-12s\n");
MSG_Add("PROGRAM_MOUNT_STATUS_2","Drive %c is mounted as %s\n");
MSG_Add("PROGRAM_MOUNT_STATUS_1","Current mounted drives are:\n");
MSG_Add("PROGRAM_MOUNT_STATUS_1","The currently mounted drives are:\n");
MSG_Add("PROGRAM_MOUNT_ERROR_1","Directory %s doesn't exist.\n");
MSG_Add("PROGRAM_MOUNT_ERROR_2","%s isn't a directory\n");
MSG_Add("PROGRAM_MOUNT_ILL_TYPE","Illegal type %s\n");

View File

@ -192,7 +192,7 @@ char* DOS_Drive_Cache::GetExpandName(const char* path) {
if((len > 1) && (work[len-1] == CROSS_FILESPLIT )) {
#endif
#ifndef HW_RVL
work[len-1] = 0; // Remove trailing slashes except when in root
work[len-1] = 0; // Remove trailing slashes except when in root
#endif
}
}
@ -378,6 +378,60 @@ bool DOS_Drive_Cache::RemoveTrailingDot(char* shortname) {
return false;
}
#define WINE_DRIVE_SUPPORT 1
#if WINE_DRIVE_SUPPORT
//Changes to interact with WINE by supporting their namemangling.
//The code is rather slow, because orglist is unordered, so it needs to be avoided if possible.
//Hence the tests in GetLongFileName
// From the Wine project
static Bits wine_hash_short_file_name( char* name, char* buffer )
{
static const char hash_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345";
static const char invalid_chars[] = { '*','?','<','>','|','"','+','=',',',';','[',']',' ','\345','~','.',0 };
char* p;
char* ext;
char* end = name + strlen(name);
char* dst;
unsigned short hash;
int i;
// Compute the hash code of the file name
for (p = name, hash = 0xbeef; p < end - 1; p++)
hash = (hash<<3) ^ (hash>>5) ^ tolower(*p) ^ (tolower(p[1]) << 8);
hash = (hash<<3) ^ (hash>>5) ^ tolower(*p); // Last character
// Find last dot for start of the extension
for (p = name + 1, ext = NULL; p < end - 1; p++) if (*p == '.') ext = p;
// Copy first 4 chars, replacing invalid chars with '_'
for (i = 4, p = name, dst = buffer; i > 0; i--, p++)
{
if (p == end || p == ext) break;
*dst++ = (*p < 0 || strchr( invalid_chars, *p ) != NULL) ? '_' : toupper(*p);
}
// Pad to 5 chars with '~'
while (i-- >= 0) *dst++ = '~';
// Insert hash code converted to 3 ASCII chars
*dst++ = hash_chars[(hash >> 10) & 0x1f];
*dst++ = hash_chars[(hash >> 5) & 0x1f];
*dst++ = hash_chars[hash & 0x1f];
// Copy the first 3 chars of the extension (if any)
if (ext)
{
*dst++ = '.';
for (i = 3, ext++; (i > 0) && ext < end; i--, ext++)
*dst++ = (*ext < 0 || strchr( invalid_chars, *ext ) != NULL) ? '_' : toupper(*ext);
}
return dst - buffer;
}
#endif
Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) {
std::vector<CFileInfo*>::size_type filelist_size = curDir->fileList.size();
if (GCC_UNLIKELY(filelist_size<=0)) return -1;
@ -398,6 +452,21 @@ Bits DOS_Drive_Cache::GetLongName(CFileInfo* curDir, char* shortName) {
return mid;
};
}
#ifdef WINE_DRIVE_SUPPORT
if (strlen(shortName) < 8 || shortName[4] != '~' || shortName[5] == '.' || shortName[6] == '.' || shortName[7] == '.') return -1; // not available
// else it's most likely a Wine style short name ABCD~###, # = not dot (length at least 8)
// The above test is rather strict as the following loop can be really slow if filelist_size is large.
char buff[CROSS_LEN];
for (Bitu i = 0; i < filelist_size; i++) {
res = wine_hash_short_file_name(curDir->fileList[i]->orgname,buff);
buff[res] = 0;
if (!strcmp(shortName,buff)) {
// Found
strcpy(shortName,curDir->fileList[i]->orgname);
return (Bits)i;
}
}
#endif
// not available
return -1;
}

View File

@ -101,7 +101,7 @@ bool Virtual_File::Read(Bit8u * data,Bit16u * size) {
}
bool Virtual_File::Write(Bit8u * data,Bit16u * size){
/* Not really writeable */
/* Not really writable */
return false;
}

View File

@ -506,6 +506,7 @@ void DOSBOX_Init(void) {
Pstring = secprop->Add_string("midiconfig",Property::Changeable::WhenIdle,"");
Pstring->Set_help("Special configuration options for the device driver. This is usually the id of the device you want to use.\n"
" or in the case of coreaudio, you can specify a soundfont here.\n"
" When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.\n"
" In that case, add 'delaysysex', for example: midiconfig=2 delaysysex\n"
" See the README/Manual for more details.");
@ -733,8 +734,8 @@ void DOSBOX_Init(void) {
"You can put your MOUNT lines here.\n"
);
MSG_Add("CONFIGFILE_INTRO",
"# This is the configurationfile for DOSBox %s. (Please use the latest version of DOSBox)\n"
"# Lines starting with a # are commentlines and are ignored by DOSBox.\n"
"# This is the configuration file for DOSBox %s. (Please use the latest version of DOSBox)\n"
"# Lines starting with a # are comment lines and are ignored by DOSBox.\n"
"# They are used to (briefly) document the effect of each option.\n");
MSG_Add("CONFIG_SUGGESTED_VALUES", "Possible values");

View File

@ -32,6 +32,7 @@ class MidiHandler_coreaudio : public MidiHandler {
private:
AUGraph m_auGraph;
AudioUnit m_synth;
const char *soundfont;
public:
MidiHandler_coreaudio() : m_auGraph(0), m_synth(0) {}
const char * GetName(void) { return "coreaudio"; }
@ -71,6 +72,22 @@ public:
// Get the music device from the graph.
RequireNoErr(AUGraphGetNodeInfo(m_auGraph, synthNode, NULL, NULL, NULL, &m_synth));
// Optionally load a soundfont
if (conf && conf[0]) {
soundfont = conf;
FSRef soundfontRef;
RequireNoErr(FSPathMakeRef((const UInt8*)soundfont, &soundfontRef, NULL));
RequireNoErr(AudioUnitSetProperty(
m_synth,
kMusicDeviceProperty_SoundBankFSRef,
kAudioUnitScope_Global,
0,
&soundfontRef,
sizeof(soundfontRef)
));
LOG_MSG("MIDI:coreaudio: loaded soundfont: %s",soundfont);
}
// Finally: Start the graph!
RequireNoErr(AUGraphStart(m_auGraph));

View File

@ -2107,7 +2107,7 @@ static void CreateDefaultBinds(void) {
}
void MAPPER_AddHandler(MAPPER_Handler * handler,MapKeys key,Bitu mods,char const * const eventname,char const * const buttonname) {
//Check if it allready exists=> if so return.
//Check if it already exists=> if so return.
for(CHandlerEventVector_it it=handlergroup.begin();it!=handlergroup.end();it++)
if(strcmp((*it)->buttonname,buttonname) == 0) return;

View File

@ -174,6 +174,8 @@ struct SDL_Block {
} window;
Bit8u bpp;
bool fullscreen;
bool lazy_fullscreen;
bool lazy_fullscreen_req;
bool doublebuf;
SCREEN_TYPES type;
SCREEN_TYPES want_type;
@ -247,6 +249,12 @@ void GFX_SetTitle(Bit32s cycles,Bits frameskip,bool paused){
SDL_WM_SetCaption(title,VERSION);
}
static void KillSwitch(bool pressed) {
if (!pressed)
return;
throw 1;
}
static void PauseDOSBox(bool pressed) {
if (!pressed)
return;
@ -263,15 +271,22 @@ static void PauseDOSBox(bool pressed) {
SDL_WaitEvent(&event); // since we're not polling, cpu usage drops to 0.
switch (event.type) {
case SDL_QUIT: throw(0); break;
case SDL_QUIT: KillSwitch(true); break;
case SDL_KEYDOWN: // Must use Pause/Break Key to resume.
case SDL_KEYUP:
if(event.key.keysym.sym==SDLK_PAUSE) {
if(event.key.keysym.sym == SDLK_PAUSE) {
paused=false;
paused = false;
GFX_SetTitle(-1,-1,false);
break;
}
#if defined (MACOSX)
if (event.key.keysym.sym == SDLK_q && (event.key.keysym.mod == KMOD_RMETA || event.key.keysym.mod == KMOD_LMETA) ) {
/* On macs, all aps exit when pressing cmd-q */
KillSwitch(true);
break;
}
#endif
}
}
}
@ -356,6 +371,16 @@ void GFX_ResetScreen(void) {
CPU_Reset_AutoAdjust();
}
void GFX_ForceFullscreenExit(void) {
if (sdl.desktop.lazy_fullscreen) {
// sdl.desktop.lazy_fullscreen_req=true;
LOG_MSG("GFX LF: invalid screen change");
} else {
sdl.desktop.fullscreen=false;
GFX_ResetScreen();
}
}
static int int_log2 (int val) {
int log = 0;
while ((val >>= 1) != 0)
@ -408,6 +433,16 @@ static SDL_Surface * GFX_SetupSurfaceScaled(Bit32u sdl_flags, Bit32u bpp) {
}
}
void GFX_TearDown(void) {
if (sdl.updating)
GFX_EndUpdate( 0 );
if (sdl.blit.surface) {
SDL_FreeSurface(sdl.blit.surface);
sdl.blit.surface=0;
}
}
Bitu GFX_SetSize(Bitu width,Bitu height,Bitu flags,double scalex,double scaley,GFX_CallBack_t callback) {
if (sdl.updating)
GFX_EndUpdate( 0 );
@ -673,6 +708,18 @@ void GFX_CaptureMouse(void) {
mouselocked=sdl.mouse.locked;
}
void GFX_UpdateSDLCaptureState(void) {
if (sdl.mouse.locked) {
SDL_WM_GrabInput(SDL_GRAB_ON);
SDL_ShowCursor(SDL_DISABLE);
} else {
SDL_WM_GrabInput(SDL_GRAB_OFF);
if (sdl.mouse.autoenable || !sdl.mouse.autolock) SDL_ShowCursor(SDL_ENABLE);
}
CPU_Reset_AutoAdjust();
GFX_SetTitle(-1,-1,false);
}
bool mouselocked; //Global variable for mapper
static void CaptureMouse(bool pressed) {
if (!pressed)
@ -680,12 +727,40 @@ static void CaptureMouse(bool pressed) {
GFX_CaptureMouse();
}
#if defined (WIN32)
STICKYKEYS stick_keys = {sizeof(STICKYKEYS), 0};
void sticky_keys(bool restore){
static bool inited = false;
if (!inited){
inited = true;
SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &stick_keys, 0);
}
if (restore) {
SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &stick_keys, 0);
return;
}
//Get current sticky keys layout:
STICKYKEYS s = {sizeof(STICKYKEYS), 0};
SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), &s, 0);
if ( !(s.dwFlags & SKF_STICKYKEYSON)) { //Not on already
s.dwFlags &= ~SKF_HOTKEYACTIVE;
SystemParametersInfo(SPI_SETSTICKYKEYS, sizeof(STICKYKEYS), &s, 0);
}
}
#endif
void GFX_SwitchFullScreen(void) {
sdl.desktop.fullscreen=!sdl.desktop.fullscreen;
if (sdl.desktop.fullscreen) {
if (!sdl.mouse.locked) GFX_CaptureMouse();
#if defined (WIN32)
sticky_keys(false); //disable sticky keys in fullscreen mode
#endif
} else {
if (sdl.mouse.locked) GFX_CaptureMouse();
#if defined (WIN32)
sticky_keys(true); //restore sticky keys to default state in windowed mode.
#endif
}
GFX_ResetScreen();
}
@ -693,7 +768,32 @@ void GFX_SwitchFullScreen(void) {
static void SwitchFullScreen(bool pressed) {
if (!pressed)
return;
GFX_SwitchFullScreen();
if (sdl.desktop.lazy_fullscreen) {
// sdl.desktop.lazy_fullscreen_req=true;
LOG_MSG("GFX LF: fullscreen switching not supported");
} else {
GFX_SwitchFullScreen();
}
}
void GFX_SwitchLazyFullscreen(bool lazy) {
sdl.desktop.lazy_fullscreen=lazy;
sdl.desktop.lazy_fullscreen_req=false;
}
void GFX_SwitchFullscreenNoReset(void) {
sdl.desktop.fullscreen=!sdl.desktop.fullscreen;
}
bool GFX_LazyFullscreenRequested(void) {
if (sdl.desktop.lazy_fullscreen) return sdl.desktop.lazy_fullscreen_req;
return false;
}
void GFX_RestoreMode(void) {
GFX_SetSize(sdl.draw.width,sdl.draw.height,sdl.draw.flags,sdl.draw.scalex,sdl.draw.scaley,sdl.draw.callback);
GFX_UpdateSDLCaptureState();
}
@ -907,11 +1007,6 @@ static void GUI_ShutDown(Section * /*sec*/) {
if (sdl.desktop.fullscreen) GFX_SwitchFullScreen();
}
static void KillSwitch(bool pressed) {
if (!pressed)
return;
throw 1;
}
static void SetPriority(PRIORITY_LEVELS level) {
@ -1010,6 +1105,9 @@ static void GUI_StartUp(Section * sec) {
SDL_WM_SetIcon(logos,NULL);
#endif
sdl.desktop.lazy_fullscreen=false;
sdl.desktop.lazy_fullscreen_req=false;
sdl.desktop.fullscreen=section->Get_bool("fullscreen");
sdl.wait_on_error=section->Get_bool("waitonerror");
@ -1186,7 +1284,7 @@ static void GUI_StartUp(Section * sec) {
//#endif
/* Please leave the Splash screen stuff in working order in DOSBox. We spend a lot of time making DOSBox. */
/*
#ifndef HW_RVL
SDL_Surface* splash_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 640, 400, 32, rmask, gmask, bmask, 0);
if (splash_surf) {
SDL_FillRect(splash_surf, NULL, SDL_MapRGB(splash_surf->format, 0, 0, 0));
@ -1246,7 +1344,7 @@ static void GUI_StartUp(Section * sec) {
delete [] tmpbufp;
}
*/
#endif
/* Get some Event handlers */
MAPPER_AddHandler(KillSwitch,MK_f9,MMOD1,"shutdown","ShutDown");
MAPPER_AddHandler(CaptureMouse,MK_f10,MMOD1,"capmouse","Cap Mouse");
@ -1327,6 +1425,10 @@ void GFX_LosingFocus(void) {
MAPPER_LosingFocus();
}
bool GFX_IsFullscreen(void) {
return sdl.desktop.fullscreen;
}
void GFX_Events() {
#ifdef HW_RVL
// check for home button
@ -1363,8 +1465,7 @@ void GFX_Events() {
#ifdef WIN32
if (sdl.desktop.fullscreen) {
VGA_KillDrawing();
sdl.desktop.fullscreen=false;
GFX_ResetScreen();
GFX_ForceFullscreenExit();
}
#endif
GFX_CaptureMouse();
@ -1446,6 +1547,15 @@ void GFX_Events() {
if (event.key.keysym.sym==SDLK_RALT) sdl.raltstate = event.key.type;
if (((event.key.keysym.sym==SDLK_TAB)) &&
((sdl.laltstate==SDL_KEYDOWN) || (sdl.raltstate==SDL_KEYDOWN))) break;
#endif
#if defined (MACOSX)
case SDL_KEYDOWN:
case SDL_KEYUP:
/* On macs CMD-Q is the default key to close an application */
if (event.key.keysym.sym == SDLK_q && (event.key.keysym.mod == KMOD_RMETA || event.key.keysym.mod == KMOD_LMETA) ) {
KillSwitch(true);
break;
}
#endif
default:
void MAPPER_CheckEvent(SDL_Event * event);
@ -1755,7 +1865,7 @@ int main(int argc, char* argv[]) {
if(control->cmdline->FindExist("-resetconf")) eraseconfigfile();
if(control->cmdline->FindExist("-erasemapper")) erasemapperfile();
if(control->cmdline->FindExist("-resetmapper")) erasemapperfile();
/* Can't disable the console with debugger enabled */
#if defined(WIN32) && !(C_DEBUG)
if (control->cmdline->FindExist("-noconsole")) {
@ -1933,7 +2043,7 @@ int main(int argc, char* argv[]) {
Section_prop * sdl_sec=static_cast<Section_prop *>(control->GetSection("sdl"));
if (control->cmdline->FindExist("-fullscreen") || sdl_sec->Get_bool("fullscreen")) {
if(!sdl.desktop.fullscreen) { //only switch if not allready in fullscreen
if(!sdl.desktop.fullscreen) { //only switch if not already in fullscreen
GFX_SwitchFullScreen();
}
}
@ -1957,6 +2067,9 @@ int main(int argc, char* argv[]) {
control->StartUp();
/* Shutdown everything */
} catch (char * error) {
#if defined (WIN32)
sticky_keys(true);
#endif
GFX_ShowMsg("Exit to error: %s",error);
fflush(NULL);
if(sdl.wait_on_error) {
@ -1975,11 +2088,17 @@ int main(int argc, char* argv[]) {
;//nothing pressed killswitch
}
catch(...){
#if defined (WIN32)
sticky_keys(true);
#endif
//Force visible mouse to end user. Somehow this sometimes doesn't happen
SDL_WM_GrabInput(SDL_GRAB_OFF);
SDL_ShowCursor(SDL_ENABLE);
throw;//dunno what happened. rethrow for sdl to catch
}
#if defined (WIN32)
sticky_keys(true); //Might not be needed if the shutdown function switches to windowed mode, but it doesn't hurt
#endif
//Force visible mouse to end user. Somehow this sometimes doesn't happen
SDL_WM_GrabInput(SDL_GRAB_OFF);
SDL_ShowCursor(SDL_ENABLE);

View File

@ -323,7 +323,7 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags,
/* Open the actual file */
FILE * fp=OpenCaptureFile("Screenshot",".png");
if (!fp) goto skip_shot;
/* First try to alloacte the png structures */
/* First try to allocate the png structures */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL,NULL, NULL);
if (!png_ptr) goto skip_shot;
info_ptr = png_create_info_struct(png_ptr);
@ -359,7 +359,23 @@ void CAPTURE_AddImage(Bitu width, Bitu height, Bitu bpp, Bitu pitch, Bitu flags,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
}
#ifdef PNG_TEXT_SUPPORTED
int fields = 1;
png_text text[1];
const char* text_s = "DOSBox " VERSION;
size_t strl = strlen(text_s);
char* ptext_s = new char[strl + 1];
strcpy(ptext_s, text_s);
char software[9] = { 'S','o','f','t','w','a','r','e',0};
text[0].compression = PNG_TEXT_COMPRESSION_NONE;
text[0].key = software;
text[0].text = ptext_s;
png_set_text(png_ptr, info_ptr, text, fields);
#endif
png_write_info(png_ptr, info_ptr);
#ifdef PNG_TEXT_SUPPORTED
delete [] ptext_s;
#endif
for (i=0;i<height;i++) {
void *rowPointer;
void *srcLine;

View File

@ -347,15 +347,18 @@ void KEYBOARD_AddKey(KBD_KEYS keytype,bool pressed) {
}
/* Add the actual key in the keyboard queue */
if (pressed) {
if (keyb.repeat.key==keytype) keyb.repeat.wait=keyb.repeat.rate;
else keyb.repeat.wait=keyb.repeat.pause;
keyb.repeat.key=keytype;
if (keyb.repeat.key == keytype) keyb.repeat.wait = keyb.repeat.rate;
else keyb.repeat.wait = keyb.repeat.pause;
keyb.repeat.key = keytype;
} else {
keyb.repeat.key=KBD_NONE;
keyb.repeat.wait=0;
ret+=128;
if (keyb.repeat.key == keytype) {
/* repeated key being released */
keyb.repeat.key = KBD_NONE;
keyb.repeat.wait = 0;
}
ret += 128;
}
if (extend) KEYBOARD_AddBuffer(0xe0);
if (extend) KEYBOARD_AddBuffer(0xe0);
KEYBOARD_AddBuffer(ret);
}

View File

@ -601,7 +601,7 @@ MixerChannel* MixerObject::Install(MIXER_Handler handler,Bitu freq,const char *
installed = true;
return MIXER_AddChannel(handler,freq,name);
} else {
E_Exit("allready added mixer channel.");
E_Exit("already added mixer channel.");
return 0; //Compiler happy
}
}

View File

@ -131,6 +131,12 @@ static Bit8u read_pci_register(PCI_Device* dev,Bit8u regnum) {
if ((parsed_regnum>=0) && (parsed_regnum<256))
return pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][parsed_regnum];
Bit8u newval, mask;
if (dev->OverrideReadRegister(regnum, &newval, &mask)) {
Bit8u oldval=pci_cfg_data[dev->PCIId()][dev->PCISubfunction()][regnum] & (~mask);
return oldval | (newval & mask);
}
return 0xff;
}

View File

@ -871,6 +871,11 @@ static void DSP_DoCommand(void) {
case 0x76: /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */
DSP_PrepareDMA_Old(DSP_DMA_3,false,false);
break;
case 0x7d: /* Auto Init 4-bit ADPCM Reference */
DSP_SB2_ABOVE;
sb.adpcm.haveref=true;
DSP_PrepareDMA_Old(DSP_DMA_4,true,false);
break;
case 0x17: /* 017h : Single Cycle 2-bit ADPCM Reference*/
sb.adpcm.haveref=true;
case 0x16: /* 074h : Single Cycle 2-bit ADPCM */
@ -996,7 +1001,7 @@ static void DSP_DoCommand(void) {
DSP_SB2_ABOVE;
LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented MIDI UART command %2X",sb.dsp.cmd);
break;
case 0x7d: case 0x7f: case 0x1f:
case 0x7f: case 0x1f:
DSP_SB2_ABOVE;
LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented auto-init DMA ADPCM command %2X",sb.dsp.cmd);
break;
@ -1158,10 +1163,15 @@ static void CTMIXER_Write(Bit8u val) {
break;
case 0x08: /* CDA Volume (SB2 Only) */
SETPROVOL(sb.mixer.cda,(val&0xf)|(val<<4));
CTMIXER_UpdateVolumes();
break;
case 0x0a: /* Mic Level (SBPRO) or DAC Volume (SB2): 2-bit, 3-bit on SB16 */
if (sb.type==SBT_2) sb.mixer.dac[0]=sb.mixer.dac[1]=((val & 0x6) << 2)|3;
else sb.mixer.mic=((val & 0x7) << 2)|(sb.type==SBT_16?1:3);
if (sb.type==SBT_2) {
sb.mixer.dac[0]=sb.mixer.dac[1]=((val & 0x6) << 2)|3;
CTMIXER_UpdateVolumes();
} else {
sb.mixer.mic=((val & 0x7) << 2)|(sb.type==SBT_16?1:3);
}
break;
case 0x0e: /* Output/Stereo Select */
sb.mixer.stereo=(val & 0x2) > 0;
@ -1179,6 +1189,7 @@ static void CTMIXER_Write(Bit8u val) {
break;
case 0x28: /* CD Audio Volume (SBPRO) */
SETPROVOL(sb.mixer.cda,val);
CTMIXER_UpdateVolumes();
break;
case 0x2e: /* Line-in Volume (SBPRO) */
SETPROVOL(sb.mixer.lin,val);

View File

@ -197,7 +197,7 @@ int SERIAL_getextchar(COMPORT port) {
char chRead;
int retval = 0;
// receive a byte; TODO communicate faliure
// receive a byte; TODO communicate failure
if (ReadFile (port->porthandle, &chRead, 1, &dwRead, NULL)) {
if (dwRead) {
// check for errors
@ -580,7 +580,7 @@ int SERIAL_getextchar(COMPORT port) {
char chRead;
int retval = 0;
// receive a byte; TODO communicate faliure
// receive a byte; TODO communicate failure
if (DosRead(port->porthandle, &chRead, 1, &dwRead) == NO_ERROR) {
if (dwRead) {
// check for errors; will OS/2 clear the error on reading its data?

View File

@ -52,87 +52,59 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
// 1) when it is client connect to the server not immediately but
// as soon as a modem-aware application is started (DTR is switched on).
// 2) only receive data when DTR is on.
if(getBituSubstring("usedtr:", &bool_temp, cmd)) {
if(bool_temp==1) {
if (getBituSubstring("usedtr:", &bool_temp, cmd)) {
if (bool_temp==1) {
dtrrespect=true;
transparent=true;
DTR_delta=false; // connect immediately when DTR is already 1
}
}
// transparent: don't add additional handshake control.
if(getBituSubstring("transparent:", &bool_temp, cmd)) {
if(bool_temp==1) transparent=true;
if (getBituSubstring("transparent:", &bool_temp, cmd)) {
if (bool_temp==1) transparent=true;
else transparent=false;
}
// telnet: interpret telnet commands.
if(getBituSubstring("telnet:", &bool_temp, cmd)) {
if(bool_temp==1) {
if (getBituSubstring("telnet:", &bool_temp, cmd)) {
if (bool_temp==1) {
transparent=true;
telnet=true;
}
}
// rxdelay: How many milliseconds to wait before causing an
// overflow when the application is unresponsive.
if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) {
if(!(rx_retry_max<=10000)) {
if (getBituSubstring("rxdelay:", &rx_retry_max, cmd)) {
if (!(rx_retry_max<=10000)) {
rx_retry_max=50;
}
}
// txdelay: How many milliseconds to wait before sending data.
// This reduces network overhead quite a lot.
if(getBituSubstring("txdelay:", &tx_gather, cmd)) {
if(!(tx_gather<=500)) {
if (getBituSubstring("txdelay:", &tx_gather, cmd)) {
if (!(tx_gather<=500)) {
tx_gather=12;
}
}
// port is for both server and client
if(getBituSubstring("port:", &temptcpport, cmd)) {
if(!(temptcpport>0&&temptcpport<65536)) {
if (getBituSubstring("port:", &temptcpport, cmd)) {
if (!(temptcpport>0&&temptcpport<65536)) {
temptcpport=23;
}
}
// socket inheritance
if(getBituSubstring("inhsocket:", &bool_temp, cmd)) {
// socket inheritance (client-alike)
if (getBituSubstring("inhsocket:", &bool_temp, cmd)) {
#ifdef NATIVESOCKETS
if(Netwrapper_GetCapabilities()&NETWRAPPER_TCP_NATIVESOCKET) {
if(bool_temp==1) {
if (Netwrapper_GetCapabilities()&NETWRAPPER_TCP_NATIVESOCKET) {
if (bool_temp==1) {
int sock;
if (control->cmdline->FindInt("-socket",sock,true)) {
dtrrespect=false;
transparent=true;
// custom connect
Bit8u peernamebuf[16];
LOG_MSG("inheritance port: %d",sock);
clientsocket = new TCPClientSocket(sock);
if(!clientsocket->isopen) {
LOG_MSG("Serial%d: Connection failed.",COMNUMBER);
#if SERIAL_DEBUG
log_ser(dbg_aux,"Nullmodem: Connection failed.");
#endif
delete clientsocket;
clientsocket=0;
LOG_MSG("Inheritance socket handle: %d",sock);
if (!ClientConnect(new TCPClientSocket(sock)))
return;
}
clientsocket->SetSendBufferSize(256);
clientsocket->GetRemoteAddressString(peernamebuf);
// transmit the line status
if(!transparent) setRTSDTR(getRTS(), getDTR());
LOG_MSG("Serial%d: Connected to %s",COMNUMBER,peernamebuf);
#if SERIAL_DEBUG
log_ser(dbg_aux,"Nullmodem: Connected to %s",peernamebuf);
#endif
setEvent(SERIAL_POLLING_EVENT, 1);
CSerial::Init_Registers ();
InstallationSuccessful = true;
setCTS(true);
setDSR(true);
setRI (false);
setCD (true);
return;
} else {
LOG_MSG("Serial%d: -socket start parameter missing.",COMNUMBER);
LOG_MSG("Serial%d: -socket parameter missing.",COMNUMBER);
return;
}
}
@ -144,47 +116,44 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
#else
LOG_MSG("Serial%d: socket inheritance not available.", COMNUMBER);
#endif
}
std::string tmpstring;
if(cmd->FindStringBegin("server:",tmpstring,false)) {
// we are a client
const char* hostnamechar=tmpstring.c_str();
size_t hostlen=strlen(hostnamechar)+1;
if(hostlen>sizeof(hostnamebuffer)) {
hostlen=sizeof(hostnamebuffer);
hostnamebuffer[sizeof(hostnamebuffer)-1]=0;
}
memcpy(hostnamebuffer,hostnamechar,hostlen);
clientport=(Bit16u)temptcpport;
if(dtrrespect) {
// we connect as soon as DTR is switched on
setEvent(SERIAL_NULLMODEM_DTR_EVENT, 50);
LOG_MSG("Serial%d: Waiting for DTR...",COMNUMBER);
} else ClientConnect();
} else {
// we are a server
serverport = (Bit16u)temptcpport;
serversocket = new TCPServerSocket(serverport);
if(!serversocket->isopen) return;
LOG_MSG("Serial%d: Nullmodem server waiting for connection on port %d...",
COMNUMBER,serverport);
setEvent(SERIAL_SERVER_POLLING_EVENT, 50);
// normal server/client
std::string tmpstring;
if (cmd->FindStringBegin("server:",tmpstring,false)) {
// we are a client
const char* hostnamechar=tmpstring.c_str();
size_t hostlen=strlen(hostnamechar)+1;
if (hostlen>sizeof(hostnamebuffer)) {
hostlen=sizeof(hostnamebuffer);
hostnamebuffer[sizeof(hostnamebuffer)-1]=0;
}
memcpy(hostnamebuffer,hostnamechar,hostlen);
clientport=(Bit16u)temptcpport;
if (dtrrespect) {
// we connect as soon as DTR is switched on
setEvent(SERIAL_NULLMODEM_DTR_EVENT, 50);
LOG_MSG("Serial%d: Waiting for DTR...",COMNUMBER);
} else if (!ClientConnect(
new TCPClientSocket((char*)hostnamebuffer,(Bit16u)clientport)))
return;
} else {
// we are a server
serverport = (Bit16u)temptcpport;
if (!ServerListen()) return;
}
}
// ....
CSerial::Init_Registers ();
CSerial::Init_Registers();
InstallationSuccessful = true;
setCTS(dtrrespect||transparent);
setDSR(dtrrespect||transparent);
setRI (false);
setCD (dtrrespect);
setRI(false);
setCD(clientsocket > 0); // CD on if connection established
}
CNullModem::~CNullModem () {
if(serversocket) delete serversocket;
if(clientsocket) delete clientsocket;
CNullModem::~CNullModem() {
if (serversocket) delete serversocket;
if (clientsocket) delete clientsocket;
// remove events
for(Bit16u i = SERIAL_BASE_EVENT_COUNT+1;
i <= SERIAL_NULLMODEM_EVENT_COUNT; i++) {
@ -193,9 +162,8 @@ CNullModem::~CNullModem () {
}
void CNullModem::WriteChar(Bit8u data) {
if(clientsocket)clientsocket->SendByteBuffered(data);
if(!tx_block) {
if (clientsocket)clientsocket->SendByteBuffered(data);
if (!tx_block) {
//LOG_MSG("setevreduct");
setEvent(SERIAL_TX_REDUCTION, (float)tx_gather);
tx_block=true;
@ -203,37 +171,75 @@ void CNullModem::WriteChar(Bit8u data) {
}
Bits CNullModem::readChar() {
Bits rxchar = clientsocket->GetcharNonBlock();
if(telnet && rxchar>=0) return TelnetEmulation((Bit8u)rxchar);
else if(rxchar==0xff && !transparent) {// escape char
if (telnet && rxchar>=0) return TelnetEmulation((Bit8u)rxchar);
else if (rxchar==0xff && !transparent) {// escape char
// get the next char
Bits rxchar = clientsocket->GetcharNonBlock();
if(rxchar==0xff) return rxchar; // 0xff 0xff -> 0xff was meant
if (rxchar==0xff) return rxchar; // 0xff 0xff -> 0xff was meant
rxchar&0x1? setCTS(true) : setCTS(false);
rxchar&0x2? setDSR(true) : setDSR(false);
if(rxchar&0x4) receiveByteEx(0x0,0x10);
if (rxchar&0x4) receiveByteEx(0x0,0x10);
return -1; // no "payload" received
} else return rxchar;
}
void CNullModem::ClientConnect(){
bool CNullModem::ClientConnect(TCPClientSocket* newsocket) {
Bit8u peernamebuf[16];
clientsocket = new TCPClientSocket((char*)hostnamebuffer,
(Bit16u)clientport);
if(!clientsocket->isopen) {
LOG_MSG("Serial%d: Connection failed.",idnumber+1);
clientsocket = newsocket;
if (!clientsocket->isopen) {
LOG_MSG("Serial%d: Connection failed.",COMNUMBER);
delete clientsocket;
clientsocket=0;
return;
setCD(false);
return false;
}
clientsocket->SetSendBufferSize(256);
clientsocket->GetRemoteAddressString(peernamebuf);
// transmit the line status
if(!transparent) setRTSDTR(getRTS(), getDTR());
if (!transparent) setRTSDTR(getRTS(), getDTR());
rx_state=N_RX_IDLE;
LOG_MSG("Serial%d: Connected to %s",idnumber+1,peernamebuf);
LOG_MSG("Serial%d: Connected to %s",COMNUMBER,peernamebuf);
setEvent(SERIAL_POLLING_EVENT, 1);
setCD(true);
return true;
}
bool CNullModem::ServerListen() {
// Start the server listen port.
serversocket = new TCPServerSocket(serverport);
if (!serversocket->isopen) return false;
LOG_MSG("Serial%d: Nullmodem server waiting for connection on port %d...",
COMNUMBER,serverport);
setEvent(SERIAL_SERVER_POLLING_EVENT, 50);
setCD(false);
return true;
}
bool CNullModem::ServerConnect() {
// check if a connection is available.
clientsocket=serversocket->Accept();
if (!clientsocket) return false;
Bit8u peeripbuf[16];
clientsocket->GetRemoteAddressString(peeripbuf);
LOG_MSG("Serial%d: A client (%s) has connected.",COMNUMBER,peeripbuf);
#if SERIAL_DEBUG
log_ser(dbg_aux,"Nullmodem: A client (%s) has connected.", peeripbuf);
#endif
clientsocket->SetSendBufferSize(256);
rx_state=N_RX_IDLE;
setEvent(SERIAL_POLLING_EVENT, 1);
// we don't accept further connections
delete serversocket;
serversocket=0;
// transmit the line status
setRTSDTR(getRTS(), getDTR());
if (transparent) setCD(true);
return true;
}
void CNullModem::Disconnect() {
@ -245,11 +251,16 @@ void CNullModem::Disconnect() {
clientsocket=0;
setDSR(false);
setCTS(false);
if(serverport) {
setCD(false);
if (serverport) {
serversocket = new TCPServerSocket(serverport);
if(serversocket->isopen)
if (serversocket->isopen)
setEvent(SERIAL_SERVER_POLLING_EVENT, 50);
else delete serversocket;
} else if (dtrrespect) {
setEvent(SERIAL_NULLMODEM_DTR_EVENT,50);
DTR_delta = getDTR(); // try to reconnect the next time DTR is set
}
}
@ -264,8 +275,8 @@ void CNullModem::handleUpperEvent(Bit16u type) {
updateMSR();
switch(rx_state) {
case N_RX_IDLE:
if(CanReceiveByte()) {
if(doReceive()) {
if (CanReceiveByte()) {
if (doReceive()) {
// a byte was received
rx_state=N_RX_WAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
@ -281,13 +292,13 @@ void CNullModem::handleUpperEvent(Bit16u type) {
break;
case N_RX_BLOCKED:
// one timeout tick
if(!CanReceiveByte()) {
if (!CanReceiveByte()) {
rx_retry++;
if(rx_retry>=rx_retry_max) {
if (rx_retry>=rx_retry_max) {
// it has timed out:
rx_retry=0;
removeEvent(SERIAL_RX_EVENT);
if(doReceive()) {
if (doReceive()) {
// read away everything
while(doReceive());
rx_state=N_RX_WAIT;
@ -304,7 +315,7 @@ void CNullModem::handleUpperEvent(Bit16u type) {
// good: we can receive again
removeEvent(SERIAL_RX_EVENT);
rx_retry=0;
if(doReceive()) {
if (doReceive()) {
rx_state=N_RX_FASTWAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.65f);
} else {
@ -329,11 +340,11 @@ void CNullModem::handleUpperEvent(Bit16u type) {
case N_RX_BLOCKED: // try to receive
case N_RX_WAIT:
case N_RX_FASTWAIT:
if(CanReceiveByte()) {
if (CanReceiveByte()) {
// just works or unblocked
if(doReceive()) {
if (doReceive()) {
rx_retry=0; // not waiting anymore
if(rx_state==N_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
if (rx_state==N_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
else {
// maybe unblocked
rx_state=N_RX_FASTWAIT;
@ -347,7 +358,7 @@ void CNullModem::handleUpperEvent(Bit16u type) {
} else {
// blocking now or still blocked
#if SERIAL_DEBUG
if(rx_state==N_RX_BLOCKED)
if (rx_state==N_RX_BLOCKED)
log_ser(dbg_aux,"Nullmodem: rx still blocked (retry=%d)",rx_retry);
else log_ser(dbg_aux,"Nullmodem: block on continued rx (retry=%d).",rx_retry);
#endif
@ -361,8 +372,8 @@ void CNullModem::handleUpperEvent(Bit16u type) {
}
case SERIAL_TX_EVENT: {
// Maybe echo cirquit works a bit better this way
if(rx_state==N_RX_IDLE && CanReceiveByte() && clientsocket) {
if(doReceive()) {
if (rx_state==N_RX_IDLE && CanReceiveByte() && clientsocket) {
if (doReceive()) {
// a byte was received
rx_state=N_RX_WAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
@ -380,25 +391,7 @@ void CNullModem::handleUpperEvent(Bit16u type) {
case SERIAL_SERVER_POLLING_EVENT: {
// As long as nothing is connected to our server poll the
// connection.
clientsocket=serversocket->Accept();
if(clientsocket) {
Bit8u peeripbuf[16];
clientsocket->GetRemoteAddressString(peeripbuf);
LOG_MSG("Serial%d: A client (%s) has connected.",COMNUMBER,peeripbuf);
#if SERIAL_DEBUG
log_ser(dbg_aux,"Nullmodem: A client (%s) has connected.", peeripbuf);
#endif// new socket found...
clientsocket->SetSendBufferSize(256);
rx_state=N_RX_IDLE;
setEvent(SERIAL_POLLING_EVENT, 1);
// we don't accept further connections
delete serversocket;
serversocket=0;
// transmit the line status
setRTSDTR(getRTS(), getDTR());
} else {
if (!ServerConnect()) {
// continue looking
setEvent(SERIAL_SERVER_POLLING_EVENT, 50);
}
@ -406,13 +399,19 @@ void CNullModem::handleUpperEvent(Bit16u type) {
}
case SERIAL_TX_REDUCTION: {
// Flush the data in the transmitting buffer.
if(clientsocket) clientsocket->FlushBuffer();
if (clientsocket) clientsocket->FlushBuffer();
tx_block=false;
break;
}
case SERIAL_NULLMODEM_DTR_EVENT: {
if(getDTR()) ClientConnect();
else setEvent(SERIAL_NULLMODEM_DTR_EVENT,50);
if ((!DTR_delta) && getDTR()) {
// DTR went positive. Try to connect.
if (ClientConnect(new TCPClientSocket((char*)hostnamebuffer,
(Bit16u)clientport)))
break; // no more DTR wait event when connected
}
DTR_delta = getDTR();
setEvent(SERIAL_NULLMODEM_DTR_EVENT,50);
break;
}
}
@ -432,11 +431,11 @@ void CNullModem::updateMSR () {
bool CNullModem::doReceive () {
Bits rxchar = readChar();
if(rxchar>=0) {
if (rxchar>=0) {
receiveByteEx((Bit8u)rxchar,0);
return true;
}
else if(rxchar==-2) {
else if (rxchar==-2) {
Disconnect();
}
return false;
@ -444,7 +443,7 @@ bool CNullModem::doReceive () {
void CNullModem::transmitByte (Bit8u val, bool first) {
// transmit it later in THR_Event
if(first) setEvent(SERIAL_THR_EVENT, bytetime/8);
if (first) setEvent(SERIAL_THR_EVENT, bytetime/8);
else setEvent(SERIAL_TX_EVENT, bytetime);
// disable 0xff escaping when transparent mode is enabled
@ -455,73 +454,73 @@ void CNullModem::transmitByte (Bit8u val, bool first) {
Bits CNullModem::TelnetEmulation(Bit8u data) {
Bit8u response[3];
if(telClient.inIAC) {
if(telClient.recCommand) {
if((data != 0) && (data != 1) && (data != 3)) {
if (telClient.inIAC) {
if (telClient.recCommand) {
if ((data != 0) && (data != 1) && (data != 3)) {
LOG_MSG("Serial%d: Unrecognized telnet option %d",COMNUMBER, data);
if(telClient.command>250) {
if (telClient.command>250) {
/* Reject anything we don't recognize */
response[0]=0xff;
response[1]=252;
response[2]=data; /* We won't do crap! */
if(clientsocket) clientsocket->SendArray(response, 3);
if (clientsocket) clientsocket->SendArray(response, 3);
}
}
switch(telClient.command) {
case 251: /* Will */
if(data == 0) telClient.binary[TEL_SERVER] = true;
if(data == 1) telClient.echo[TEL_SERVER] = true;
if(data == 3) telClient.supressGA[TEL_SERVER] = true;
if (data == 0) telClient.binary[TEL_SERVER] = true;
if (data == 1) telClient.echo[TEL_SERVER] = true;
if (data == 3) telClient.supressGA[TEL_SERVER] = true;
break;
case 252: /* Won't */
if(data == 0) telClient.binary[TEL_SERVER] = false;
if(data == 1) telClient.echo[TEL_SERVER] = false;
if(data == 3) telClient.supressGA[TEL_SERVER] = false;
if (data == 0) telClient.binary[TEL_SERVER] = false;
if (data == 1) telClient.echo[TEL_SERVER] = false;
if (data == 3) telClient.supressGA[TEL_SERVER] = false;
break;
case 253: /* Do */
if(data == 0) {
if (data == 0) {
telClient.binary[TEL_CLIENT] = true;
response[0]=0xff;
response[1]=251;
response[2]=0; /* Will do binary transfer */
if(clientsocket) clientsocket->SendArray(response, 3);
if (clientsocket) clientsocket->SendArray(response, 3);
}
if(data == 1) {
if (data == 1) {
telClient.echo[TEL_CLIENT] = false;
response[0]=0xff;
response[1]=252;
response[2]=1; /* Won't echo (too lazy) */
if(clientsocket) clientsocket->SendArray(response, 3);
if (clientsocket) clientsocket->SendArray(response, 3);
}
if(data == 3) {
if (data == 3) {
telClient.supressGA[TEL_CLIENT] = true;
response[0]=0xff;
response[1]=251;
response[2]=3; /* Will Suppress GA */
if(clientsocket) clientsocket->SendArray(response, 3);
if (clientsocket) clientsocket->SendArray(response, 3);
}
break;
case 254: /* Don't */
if(data == 0) {
if (data == 0) {
telClient.binary[TEL_CLIENT] = false;
response[0]=0xff;
response[1]=252;
response[2]=0; /* Won't do binary transfer */
if(clientsocket) clientsocket->SendArray(response, 3);
if (clientsocket) clientsocket->SendArray(response, 3);
}
if(data == 1) {
if (data == 1) {
telClient.echo[TEL_CLIENT] = false;
response[0]=0xff;
response[1]=252;
response[2]=1; /* Won't echo (fine by me) */
if(clientsocket) clientsocket->SendArray(response, 3);
if (clientsocket) clientsocket->SendArray(response, 3);
}
if(data == 3) {
if (data == 3) {
telClient.supressGA[TEL_CLIENT] = true;
response[0]=0xff;
response[1]=251;
response[2]=3; /* Will Suppress GA (too lazy) */
if(clientsocket) clientsocket->SendArray(response, 3);
if (clientsocket) clientsocket->SendArray(response, 3);
}
break;
default:
@ -532,7 +531,7 @@ Bits CNullModem::TelnetEmulation(Bit8u data) {
telClient.recCommand = false;
return -1; //continue;
} else {
if(data==249) {
if (data==249) {
/* Go Ahead received */
telClient.inIAC = false;
return -1; //continue;
@ -540,7 +539,7 @@ Bits CNullModem::TelnetEmulation(Bit8u data) {
telClient.command = data;
telClient.recCommand = true;
if((telClient.binary[TEL_SERVER]) && (data == 0xff)) {
if ((telClient.binary[TEL_SERVER]) && (data == 0xff)) {
/* Binary data with value of 255 */
telClient.inIAC = false;
telClient.recCommand = false;
@ -548,7 +547,7 @@ Bits CNullModem::TelnetEmulation(Bit8u data) {
}
}
} else {
if(data == 0xff) {
if (data == 0xff) {
telClient.inIAC = true;
return -1;
}
@ -570,14 +569,14 @@ void CNullModem::setBreak (bool /*value*/) {
/* updateModemControlLines(mcr) sets DTR and RTS. **/
/*****************************************************************************/
void CNullModem::setRTSDTR(bool xrts, bool xdtr) {
if(!transparent) {
if (!transparent) {
Bit8u control[2];
control[0]=0xff;
control[1]=0x0;
if(xrts) control[1]|=1;
if(xdtr) control[1]|=2;
if(LCR&LCR_BREAK_MASK) control[1]|=4;
if(clientsocket) clientsocket->SendArray(control, 2);
if (xrts) control[1]|=1;
if (xdtr) control[1]|=2;
if (LCR&LCR_BREAK_MASK) control[1]|=4;
if (clientsocket) clientsocket->SendArray(control, 2);
}
}
void CNullModem::setRTS(bool val) {

View File

@ -35,16 +35,8 @@
class CNullModem : public CSerial {
public:
TCPServerSocket* serversocket;
TCPClientSocket* clientsocket;
CNullModem(Bitu id, CommandLine* cmd);
~CNullModem();
bool receiveblock; // It's not a block of data it rather blocks
Bit16u serverport; // we are a server if this is nonzero
Bit16u clientport;
Bit8u hostnamebuffer[128]; // the name passed to us by the user
void updatePortConfig(Bit16u divider, Bit8u lcr);
void updateMSR();
@ -56,6 +48,16 @@ public:
void setDTR(bool val);
void handleUpperEvent(Bit16u type);
private:
TCPServerSocket* serversocket;
TCPClientSocket* clientsocket;
bool receiveblock; // It's not a block of data it rather blocks
Bit16u serverport; // we are a server if this is nonzero
Bit16u clientport;
Bit8u hostnamebuffer[128]; // the name passed to us by the user
Bitu rx_state;
#define N_RX_IDLE 0
#define N_RX_WAIT 1
@ -64,11 +66,17 @@ public:
#define N_RX_DISC 4
bool doReceive();
void ClientConnect();
bool ClientConnect(TCPClientSocket* newsocket);
bool ServerListen();
bool ServerConnect();
void Disconnect();
Bits readChar();
void WriteChar(Bit8u data);
bool DTR_delta; // with dtrrespect, we try to establish a connection
// whenever DTR switches to 1. This variable is
// used to remember the old state.
bool tx_block; // true while the SERIAL_TX_REDUCTION event
// is pending

View File

@ -223,7 +223,8 @@ void CSerial::changeLineProperties() {
else bitlen = (1000.0f/115200.0f)*(float)baud_divider;
bytetime=bitlen*(float)(1+5+1); // startbit + minimum length + stopbit
bytetime+= bitlen*(float)(LCR&0x3); // databits
if(LCR&0x4) bytetime+=bitlen; // stopbit
if(LCR&0x4) bytetime+=bitlen; // 2nd stopbit
if(LCR&0x8) bytetime+=bitlen; // parity
#if SERIAL_DEBUG
const char* const dbgtext[]={"none","odd","none","even","none","mark","none","space"};

View File

@ -77,20 +77,20 @@ static Bitu temp[643]={0};
static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) {
const Bit8u *base = vga.tandy.draw_base + ((line & vga.tandy.line_mask) << vga.tandy.line_shift);
const Bit8u *reader = base + vidstart;
#define CGA16_READER(OFF) (base[(vidstart +(OFF))& (8*1024 -1)])
Bit32u * draw=(Bit32u *)TempLine;
//Generate a temporary bitline to calculate the avarage
//over bit-2 bit-1 bit bit+1.
//Combine this number with the current colour to get
//an unigue index in the pallete. Or it with bit 7 as they are stored
//an unique index in the pallette. Or it with bit 7 as they are stored
//in the upperpart to keep them from interfering the regular cga stuff
for(Bitu x = 0; x < 640; x++)
temp[x+2] = (( reader[(x>>3)] >> (7-(x&7)) )&1) << 4;
temp[x+2] = (( CGA16_READER(x>>3)>> (7-(x&7)) )&1) << 4;
//shift 4 as that is for the index.
Bitu i = 0,temp1,temp2,temp3,temp4;
for (Bitu x=0;x<vga.draw.blocks;x++) {
Bitu val1 = *reader++;
Bitu val1 = CGA16_READER(x);
Bitu val2 = val1&0xf;
val1 >>= 4;
@ -113,6 +113,7 @@ static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart, Bitu line) {
((temp4|val2) <<24);
}
return TempLine;
#undef CGA16_READER
}
static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart, Bitu line) {
@ -824,7 +825,7 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
break;
}
//Check if we can actually render, else skip the rest (frameskip)
if (!RENDER_StartUpdate())
if (vga.draw.vga_override || !RENDER_StartUpdate())
return;
vga.draw.address_line = vga.config.hlines_skip;
@ -1556,7 +1557,9 @@ void VGA_SetupDrawing(Bitu /*val*/) {
LOG(LOG_VGA,LOG_NORMAL)("%s width, %s height aspect %f",
doublewidth ? "double":"normal",doubleheight ? "double":"normal",aspect_ratio);
#endif
RENDER_SetSize(width,height,bpp,(float)fps,aspect_ratio,doublewidth,doubleheight);
if (!vga.draw.vga_override)
RENDER_SetSize(width, height, bpp, (float)fps, aspect_ratio,
doublewidth, doubleheight);
}
}
@ -1566,5 +1569,19 @@ void VGA_KillDrawing(void) {
PIC_RemoveEvents(VGA_DrawEGASingleLine);
vga.draw.parts_left = 0;
vga.draw.lines_done = ~0;
RENDER_EndUpdate(true);
if (!vga.draw.vga_override) RENDER_EndUpdate(true);
}
void VGA_SetOverride(bool vga_override) {
if (vga.draw.vga_override!=vga_override) {
if (vga_override) {
VGA_KillDrawing();
vga.draw.vga_override=true;
} else {
vga.draw.vga_override=false;
vga.draw.width=0; // change it so the output window gets updated
VGA_SetupDrawing(0);
}
}
}

View File

@ -700,6 +700,7 @@ public:
// |PFLAG_NOCODE;
}
HostPt GetHostReadPt(Bitu phys_page) {
// Odd banks are limited to 16kB and repeated
if (vga.tandy.mem_bank & 1)
phys_page&=0x03;
else
@ -719,9 +720,9 @@ public:
}
HostPt GetHostReadPt(Bitu phys_page) {
phys_page-=0xb8;
//test for a unaliged bank, then replicate 2x16kb
if (vga.tandy.mem_bank & 1)
phys_page&=0x03;
// The 16kB map area is repeated in the 32kB range
// On CGA CPU A14 is not decoded so it repeats there too
phys_page&=0x03;
return vga.tandy.mem_base + (phys_page * 4096);
}
HostPt GetHostWritePt(Bitu phys_page) {

View File

@ -83,7 +83,9 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
vga.draw.cursor.eline = (Bit8u)(val&0x1f);
break;
case 0x0C: /* Start Address High Register */
vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8);
// Bit 12 (depending on video mode) and 13 are actually masked too,
// but so far no need to implement it.
vga.config.display_start=(vga.config.display_start & 0x00FF) | ((val&0x3F) << 8);
break;
case 0x0D: /* Start Address Low Register */
vga.config.display_start=(vga.config.display_start & 0xFF00) | val;
@ -491,10 +493,18 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) {
write_tandy_reg((Bit8u)val);
break;
case 0x3df:
// CRT/processor page register
// See the comments on the PCJr version of this register.
// A difference to it is:
// Bit 3-5: Processor page CPU_PG
// The remapped range is 32kB instead of 16. Therefore CPU_PG bit 0
// appears to be ORed with CPU A14 (to preserve some sort of
// backwards compatibility?), resulting in odd pages being mapped
// as 2x16kB. Implemeted in vga_memory.cpp Tandy handler.
vga.tandy.line_mask = (Bit8u)(val >> 6);
vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
if(vga.tandy.line_mask==3) vga.tandy.draw_bank &= ~1; // LSB unused in 32k modes
vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
vga.tandy.mem_bank = (val >> 3) & 7;
TandyCheckLineMask();
VGA_SetupHandlers();
break;
@ -514,9 +524,38 @@ static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) {
vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop;
break;
case 0x3df:
// CRT/processor page register
// Bit 0-2: CRT page PG0-2
// In one- and two bank modes, bit 0-2 select the 16kB memory
// area of system RAM that is displayed on the screen.
// In 4-banked modes, bit 1-2 select the 32kB memory area.
// Bit 2 only has effect when the PCJR upgrade to 128k is installed.
// Bit 3-5: Processor page CPU_PG
// Selects the 16kB area of system RAM that is mapped to
// the B8000h IBM PC video memory window. Since A14-A16 of the
// processor are unconditionally replaced with these bits when
// B8000h is accessed, the 16kB area is mapped to the 32kB
// range twice in a row. (Scuba Venture writes across the boundary)
// Bit 6-7: Video Address mode
// 0: CRTC addresses A0-12 directly, accessing 8k characters
// (+8k attributes). Used in text modes (one bank).
// PG0-2 in effect. 16k range.
// 1: CRTC A12 is replaced with CRTC RA0 (see max_scanline).
// This results in the even/odd scanline two bank system.
// PG0-2 in effect. 16k range.
// 2: Documented as unused. CRTC addresses A0-12, PG0 is replaced
// with RA1. Looks like nonsense.
// PG1-2 in effect. 32k range which cannot be used completely.
// 3: CRTC A12 is replaced with CRTC RA0, PG0 is replaced with
// CRTC RA1. This results in the 4-bank mode.
// PG1-2 in effect. 32k range.
vga.tandy.line_mask = (Bit8u)(val >> 6);
vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7);
vga.tandy.mem_bank = (val >> 3) & 7;
vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024];
vga.tandy.mem_base = &MemBase[vga.tandy.mem_bank * 16 * 1024];
TandyCheckLineMask();
@ -674,6 +713,9 @@ void VGA_SetupOther(void) {
write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 );
IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB);
IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB);
// additional CRTC access documented
IO_RegisterWriteHandler(0x3d0,write_crtc_index_other,IO_MB);
IO_RegisterWriteHandler(0x3d1,write_crtc_data_other,IO_MB);
}
if (machine==MCH_HERC) {
Bitu base=0x3b0;

View File

@ -341,7 +341,7 @@ void SVGA_S3_WriteCRTC(Bitu reg,Bitu val,Bitu iolen) {
vga.svga.bank_write = vga.svga.bank_read;
VGA_SetupHandlers();
break;
case 0x6b: // BIOS scratchpad: LFB adress
case 0x6b: // BIOS scratchpad: LFB address
vga.s3.reg_6b=(Bit8u)val;
break;
default:

View File

@ -38,7 +38,6 @@
#include <ogc/lwp_watchdog.h>
#endif
/* if mem_systems 0 then size_extended is reported as the real size else
* zero is reported. ems and xms can increase or decrease the other_memsystems
* counter using the BIOS_ZeroExtendedSize call */
@ -850,6 +849,7 @@ static Bitu INT15_Handler(void) {
CALLBACK_Idle();
}
CALLBACK_SCF(false);
break;
}
case 0x87: /* Copy extended memory */
{

View File

@ -85,13 +85,26 @@ void updateDPT(void) {
}
}
void incrementFDD(void) {
Bit16u equipment=mem_readw(BIOS_CONFIGURATION);
if(equipment&1) {
Bitu numofdisks = (equipment>>6)&3;
numofdisks++;
if(numofdisks > 1) numofdisks=1;//max 2 floppies at the moment
equipment&=~0x00C0;
equipment|=(numofdisks<<6);
} else equipment|=1;
mem_writew(BIOS_CONFIGURATION,equipment);
CMOS_SetRegister(0x14, (Bit8u)(equipment&0xff));
}
void swapInDisks(void) {
bool allNull = true;
Bits diskcount = 0;
Bits swapPos = swapPosition;
int i;
/* Check to make sure there's atleast one setup image */
/* Check to make sure that there is at least one setup image */
for(i=0;i<MAX_SWAPPABLE_DISKS;i++) {
if(diskSwap[i]!=NULL) {
allNull = false;
@ -219,16 +232,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard
if(!founddisk) {
active = false;
} else {
Bit16u equipment=mem_readw(BIOS_CONFIGURATION);
if(equipment&1) {
Bitu numofdisks = (equipment>>6)&3;
numofdisks++;
if(numofdisks > 1) numofdisks=1;//max 2 floppies at the moment
equipment&=~0x00C0;
equipment|=(numofdisks<<6);
} else equipment|=1;
mem_writew(BIOS_CONFIGURATION,equipment);
CMOS_SetRegister(0x14, (Bit8u)(equipment&0xff));
incrementFDD();
}
}
}
@ -329,12 +333,14 @@ static Bitu INT13_DiskHandler(void) {
if ((machine==MCH_CGA) || (machine==MCH_PCJR)) {
/* those bioses call floppy drive reset for invalid drive values */
if (((imageDiskList[0]) && (imageDiskList[0]->active)) || ((imageDiskList[1]) && (imageDiskList[1]->active))) {
if (reg_dl<0x80) reg_ip++;
last_status = 0x00;
CALLBACK_SCF(false);
}
}
return CBRET_NONE;
}
if (reg_dl<0x80) reg_ip++;
last_status = 0x00;
CALLBACK_SCF(false);
}
@ -496,7 +502,7 @@ static Bitu INT13_DiskHandler(void) {
void BIOS_SetupDisks(void) {
/* TODO Start the time correctly */
call_int13=CALLBACK_Allocate();
CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_IRET,"Int 13 Bios disk");
CALLBACK_Setup(call_int13,&INT13_DiskHandler,CB_INT13,"Int 13 Bios disk");
RealSetVec(0x13,CALLBACK_RealPointer(call_int13));
int i;
for(i=0;i<4;i++) {

View File

@ -382,7 +382,7 @@ static Bitu IRQ1_Handler(void) {
add_key(scan_to_scanascii[scancode].normal+0x5000);
} else if (flags1 &0x04) {
add_key((scan_to_scanascii[scancode].control&0xff00)|0xe0);
} else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) {
} else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) { //Due to |0xe0 results are identical.
add_key((scan_to_scanascii[scancode].shift&0xff00)|0xe0);
} else add_key((scan_to_scanascii[scancode].normal&0xff00)|0xe0);
break;
@ -393,7 +393,7 @@ static Bitu IRQ1_Handler(void) {
mem_writeb(BIOS_KEYBOARD_TOKEN,token);
} else if (flags1 &0x04) {
add_key(scan_to_scanascii[scancode].control);
} else if( ((flags1 &0x3) != 0) || ((flags1 &0x20) != 0) ) {
} else if( ((flags1 &0x3) != 0) ^ ((flags1 &0x20) != 0) ) { //Xor shift and numlock (both means off)
add_key(scan_to_scanascii[scancode].shift);
} else add_key(scan_to_scanascii[scancode].normal);
break;
@ -546,7 +546,7 @@ static Bitu INT16_Handler(void) {
reg_ax=temp;
}
break;
case 0x02: /* GET SHIFT FlAGS */
case 0x02: /* GET SHIFT FLAGS */
reg_al=mem_readb(BIOS_KEYBOARD_FLAGS1);
break;
case 0x03: /* SET TYPEMATIC RATE AND DELAY */
@ -594,7 +594,7 @@ static void InitBiosSegment(void) {
mem_writew(BIOS_KEYBOARD_BUFFER_HEAD,0x1e);
mem_writew(BIOS_KEYBOARD_BUFFER_TAIL,0x1e);
Bit8u flag1 = 0;
Bit8u leds = 16; /* Ack recieved */
Bit8u leds = 16; /* Ack received */
#if SDL_VERSION_ATLEAST(1, 2, 14)
//Nothing, mapper handles all.

View File

@ -489,7 +489,7 @@ static Bit8u EMM_PartialPageMapping(void) {
mem_writew(data,segment);data+=2;
MEM_BlockWrite(data,&emm_mappings[page],sizeof(EMM_Mapping));
data+=sizeof(EMM_Mapping);
} else if (((segment>=EMM_PAGEFRAME-0x1000) && (segment<EMM_PAGEFRAME)) || ((segment>=0xa000) && (segment<0xb000))) {
} else if ((ems_type==1) || (ems_type==3) || ((segment>=EMM_PAGEFRAME-0x1000) && (segment<EMM_PAGEFRAME)) || ((segment>=0xa000) && (segment<0xb000))) {
mem_writew(data,segment);data+=2;
MEM_BlockWrite(data,&emm_segmentmappings[segment>>10],sizeof(EMM_Mapping));
data+=sizeof(EMM_Mapping);
@ -506,7 +506,7 @@ static Bit8u EMM_PartialPageMapping(void) {
if ((segment>=EMM_PAGEFRAME) && (segment<EMM_PAGEFRAME+0x1000)) {
Bit16u page = (segment-EMM_PAGEFRAME) / (EMM_PAGE_SIZE>>4);
MEM_BlockRead(data,&emm_mappings[page],sizeof(EMM_Mapping));
} else if (((segment>=EMM_PAGEFRAME-0x1000) && (segment<EMM_PAGEFRAME)) || ((segment>=0xa000) && (segment<0xb000))) {
} else if ((ems_type==1) || (ems_type==3) || ((segment>=EMM_PAGEFRAME-0x1000) && (segment<EMM_PAGEFRAME)) || ((segment>=0xa000) && (segment<0xb000))) {
MEM_BlockRead(data,&emm_segmentmappings[segment>>10],sizeof(EMM_Mapping));
} else {
return EMM_ILL_PHYS;
@ -1079,7 +1079,7 @@ static Bitu V86_Monitor() {
reg_esp+=6; // skip ip of CALL and error code of EXCEPTION 0x0d
/* Get adress of faulting instruction */
/* Get address of faulting instruction */
Bit16u v86_cs=mem_readw(SegPhys(ss)+((reg_esp+4) & cpu.stack.mask));
Bit16u v86_ip=mem_readw(SegPhys(ss)+((reg_esp+0) & cpu.stack.mask));
Bit8u v86_opcode=mem_readb((v86_cs<<4)+v86_ip);

View File

@ -375,7 +375,7 @@ graphics_chars:
reg_al=0x12;
break;
}
case 0x32: /* Video adressing */
case 0x32: /* Video addressing */
if (!IS_VGA_ARCH) break;
LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl);
if (svgaCard==SVGA_TsengET4K) reg_al&=1;

View File

@ -49,7 +49,7 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu
PhysPt ftwhere=PhysMake(0xa000,map_offset[map & 0x7]+(Bit16u)(offset*32));
IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x4); //Enable plane 2
IO_Write(0x3ce,0x6);Bitu old_6=IO_Read(0x3cf);
IO_Write(0x3cf,0x0); //Disable odd/even and a0000 adressing
IO_Write(0x3cf,0x0); //Disable odd/even and a0000 addressing
for (Bitu i=0;i<count;i++) {
MEM_BlockCopy(ftwhere,font,height);
ftwhere+=32;
@ -57,7 +57,7 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu
}
IO_Write(0x3c4,0x2);IO_Write(0x3c5,0x3); //Enable textmode planes (0,1)
IO_Write(0x3ce,0x6);
if (IS_VGA_ARCH) IO_Write(0x3cf,(Bit8u)old_6); //odd/even and b8000 adressing
if (IS_VGA_ARCH) IO_Write(0x3cf,(Bit8u)old_6); //odd/even and b8000 addressing
else IO_Write(0x3cf,0x0e);
/* Reload tables and registers with new values based on this height */
if (reload) {
@ -154,7 +154,7 @@ void INT10_SetupRomMemory(void) {
int10.rom.video_dcc_table=RealMake(0xC000,int10.rom.used);
phys_writeb(rom_base+int10.rom.used++,0x10); // number of entries
phys_writeb(rom_base+int10.rom.used++,1); // version number
phys_writeb(rom_base+int10.rom.used++,8); // maximal display code
phys_writeb(rom_base+int10.rom.used++,8); // maximum display code
phys_writeb(rom_base+int10.rom.used++,0); // reserved
// display combination codes
phys_writew(rom_base+int10.rom.used,0x0000); int10.rom.used+=2;

View File

@ -405,7 +405,7 @@ static void FinishSetMode(bool clearmem) {
case M_LIN15:
case M_LIN16:
case M_LIN32:
/* Hack we just acess the memory directly */
/* Hack we just access the memory directly */
memset(vga.mem.linear,0,vga.vmemsize);
memset(vga.fastmem, 0, vga.vmemsize<<1);
}

View File

@ -321,7 +321,7 @@ void INT10_SetBackgroundBorder(Bit8u val) {
}
else if (IS_EGAVGA_ARCH) {
val = ((val << 1) & 0x10) | (val & 0x7);
/* Aways set the overscan color */
/* Always set the overscan color */
INT10_SetSinglePaletteRegister( 0x11, val );
/* Don't set any extra colors when in text mode */
if (CurMode->mode <= 3)

View File

@ -50,8 +50,8 @@ struct button_event {
#define QUEUE_SIZE 32
#define MOUSE_BUTTONS 3
#define MOUSE_IRQ 12
#define POS_X ((Bit16s)(mouse.x) & mouse.granMask)
#define POS_Y (Bit16s)(mouse.y)
#define POS_X (static_cast<Bit16s>(mouse.x) & mouse.gran_x)
#define POS_Y (static_cast<Bit16s>(mouse.y) & mouse.gran_y)
#define CURSORX 16
#define CURSORY 16
@ -125,7 +125,7 @@ static struct {
bool timer_in_progress;
bool in_UIR;
Bit8u mode;
Bit16s granMask;
Bit16s gran_x,gran_y;
} mouse;
bool Mouse_SetPS2State(bool use) {
@ -255,6 +255,7 @@ void DrawCursorText() {
// Save Background
mouse.backposx = POS_X>>3;
mouse.backposy = POS_Y>>3;
if (mouse.mode < 2) mouse.backposx >>= 1;
//use current page (CV program)
Bit8u page = real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE);
@ -582,43 +583,48 @@ static void Mouse_ResetHardware(void){
//Does way to much. Many things should be moved to mouse reset one day
void Mouse_NewVideoMode(void) {
mouse.inhibit_draw=false;
mouse.inhibit_draw = false;
/* Get the correct resolution from the current video mode */
Bit8u mode=mem_readb(BIOS_VIDEO_MODE);
Bit8u mode = mem_readb(BIOS_VIDEO_MODE);
if(mode == mouse.mode) {LOG(LOG_MOUSE,LOG_NORMAL)("New video is the same as the old"); /*return;*/}
mouse.gran_x = (Bit16s)0xffff;
mouse.gran_y = (Bit16s)0xffff;
switch (mode) {
case 0x00:
case 0x01:
case 0x02:
case 0x03: {
Bitu rows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
if ((rows==0) || (rows>250)) rows=25-1;
mouse.max_y=8*(rows+1)-1;
case 0x03:
case 0x07: {
mouse.gran_x = (mode<2)?0xfff0:0xfff8;
mouse.gran_y = (Bit16s)0xfff8;
Bitu rows = real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS);
if ((rows == 0) || (rows > 250)) rows = 25 - 1;
mouse.max_y = 8*(rows+1) - 1;
break;
}
case 0x04:
case 0x05:
case 0x06:
case 0x07:
case 0x08:
case 0x09:
case 0x0a:
case 0x0d:
case 0x0e:
case 0x13:
mouse.max_y=199;
if (mode == 0x0d || mode == 0x13) mouse.gran_x = (Bit16s)0xfffe;
mouse.max_y = 199;
break;
case 0x0f:
case 0x10:
mouse.max_y=349;
mouse.max_y = 349;
break;
case 0x11:
case 0x12:
mouse.max_y=479;
mouse.max_y = 479;
break;
default:
LOG(LOG_MOUSE,LOG_ERROR)("Unhandled videomode %X on reset",mode);
mouse.inhibit_draw=true;
mouse.inhibit_draw = true;
return;
}
mouse.mode = mode;
@ -626,7 +632,6 @@ void Mouse_NewVideoMode(void) {
mouse.max_x = 639;
mouse.min_x = 0;
mouse.min_y = 0;
mouse.granMask = (mode == 0x0d || mode == 0x13) ? 0xfffe : 0xffff;
mouse.events = 0;
mouse.timer_in_progress = false;
@ -1007,7 +1012,7 @@ static Bitu INT74_Handler(void) {
} else if (useps2callback) {
CPU_Push16(RealSeg(CALLBACK_RealPointer(int74_ret_callback)));
CPU_Push16(RealOff(CALLBACK_RealPointer(int74_ret_callback)));
DoPS2Callback(mouse.event_queue[mouse.events].buttons, POS_X, POS_Y);
DoPS2Callback(mouse.event_queue[mouse.events].buttons, static_cast<Bit16s>(mouse.x), static_cast<Bit16s>(mouse.y));
} else {
SegSet16(cs, RealSeg(CALLBACK_RealPointer(int74_ret_callback)));
reg_ip = RealOff(CALLBACK_RealPointer(int74_ret_callback));

View File

@ -19,6 +19,7 @@
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include "dosbox.h"
#include "callback.h"
#include "mem.h"

View File

@ -98,7 +98,7 @@ static void LoadMessageFile(const char * fname) {
strcpy(name,linein+1);
/* End of string marker */
} else if (linein[0]=='.') {
/* Replace/Add the string to the internal langaugefile */
/* Replace/Add the string to the internal languagefile */
/* Remove last newline (marker is \n.\n) */
size_t ll = strlen(string);
if(ll && string[ll - 1] == '\n') string[ll - 1] = 0; //Second if should not be needed, but better be safe.

View File

@ -128,6 +128,7 @@ void Program::ChangeToLongCmd() {
full_arguments.assign(""); //Clear so it gets even more save
}
static char last_written_character = 0;//For 0xA to OxD 0xA expansion
void Program::WriteOut(const char * format,...) {
char buf[2048];
va_list msg;
@ -139,10 +140,10 @@ void Program::WriteOut(const char * format,...) {
Bit16u size = (Bit16u)strlen(buf);
for(Bit16u i = 0; i < size;i++) {
Bit8u out;Bit16u s=1;
if (buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) {
if (buf[i] == 0xA && last_written_character != 0xD) {
out = 0xD;DOS_WriteFile(STDOUT,&out,&s);
}
out = buf[i];
last_written_character = out = buf[i];
DOS_WriteFile(STDOUT,&out,&s);
}
@ -154,10 +155,10 @@ void Program::WriteOut_NoParsing(const char * format) {
char const* buf = format;
for(Bit16u i = 0; i < size;i++) {
Bit8u out;Bit16u s=1;
if (buf[i] == 0xA && i > 0 && buf[i-1] !=0xD) {
if (buf[i] == 0xA && last_written_character != 0xD) {
out = 0xD;DOS_WriteFile(STDOUT,&out,&s);
}
out = buf[i];
last_written_character = out = buf[i];
DOS_WriteFile(STDOUT,&out,&s);
}

View File

@ -955,6 +955,39 @@ bool CommandLine::FindStringRemain(char const * const name,std::string & value)
return true;
}
/* Only used for parsing command.com /C
* Allowing /C dir and /Cdir
* Restoring quotes back into the commands so command /C mount d "/tmp/a b" works as intended
*/
bool CommandLine::FindStringRemainBegin(char const * const name,std::string & value) {
cmd_it it;value="";
if (!FindEntry(name,it)) {
size_t len = strlen(name);
for (it=cmds.begin();it!=cmds.end();it++) {
if (strncasecmp(name,(*it).c_str(),len)==0) {
std::string temp = ((*it).c_str() + len);
//Restore quotes for correct parsing in later stages
if(temp.find(" ") != std::string::npos)
value = std::string("\"") + temp + std::string("\"");
else
value = temp;
break;
}
}
if( it == cmds.end()) return false;
}
it++;
for (;it!=cmds.end();it++) {
value += " ";
std::string temp = (*it);
if(temp.find(" ") != std::string::npos)
value += std::string("\"") + temp + std::string("\"");
else
value += temp;
}
return true;
}
bool CommandLine::GetStringRemain(std::string & value) {
if(!cmds.size()) return false;

View File

@ -52,14 +52,14 @@ typedef std::list<std::string>::iterator auto_it;
void VFILE_Remove(const char *name);
void AutoexecObject::Install(const std::string &in) {
if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf.c_str());
if(GCC_UNLIKELY(installed)) E_Exit("autoexec: already created %s",buf.c_str());
installed = true;
buf = in;
autoexec_strings.push_back(buf);
this->CreateAutoexec();
//autoexec.bat is normally created AUTOEXEC_Init.
//But if we are allready running (first_shell)
//But if we are already running (first_shell)
//we have to update the envirionment to display changes
if(first_shell) {
@ -80,7 +80,7 @@ void AutoexecObject::Install(const std::string &in) {
}
void AutoexecObject::InstallBefore(const std::string &in) {
if(GCC_UNLIKELY(installed)) E_Exit("autoexec: allready created %s",buf.c_str());
if(GCC_UNLIKELY(installed)) E_Exit("autoexec: already created %s",buf.c_str());
installed = true;
buf = in;
autoexec_strings.push_front(buf);
@ -288,7 +288,7 @@ void DOS_Shell::RunInternal(void)
void DOS_Shell::Run(void) {
char input_line[CMD_MAXLINE] = {0};
std::string line;
if (cmd->FindStringRemain("/C",line)) {
if (cmd->FindStringRemainBegin("/C",line)) {
strcpy(input_line,line.c_str());
char* sep = strpbrk(input_line,"\r\n"); //GTA installer
if (sep) *sep = 0;

View File

@ -123,11 +123,12 @@ void DOS_Shell::DoCommand(char * line) {
char cmd_buffer[CMD_MAXLINE];
char * cmd_write=cmd_buffer;
while (*line) {
if (*line==32) break;
if (*line=='/') break;
if (*line=='\t') break;
if (*line=='=') break;
if ((*line=='.') ||(*line =='\\')) { //allow stuff like cd.. and dir.exe cd\kees
if (*line == 32) break;
if (*line == '/') break;
if (*line == '\t') break;
if (*line == '=') break;
// if (*line == ':') break; //This breaks drive switching as that is handled at a later stage.
if ((*line == '.') ||(*line == '\\')) { //allow stuff like cd.. and dir.exe cd\kees
*cmd_write=0;
Bit32u cmd_index=0;
while (cmd_list[cmd_index].name) {
@ -287,7 +288,7 @@ void DOS_Shell::CMD_ECHO(char * args){
args++;//skip first character. either a slash or dot or space
size_t len = strlen(args); //TODO check input of else ook nodig is.
if(len && args[len - 1] == '\r') {
LOG(LOG_MISC,LOG_WARN)("Hu ? carriage return allready present. Is this possible?");
LOG(LOG_MISC,LOG_WARN)("Hu ? carriage return already present. Is this possible?");
WriteOut("%s\n",args);
} else WriteOut("%s\r\n",args);
}
@ -573,6 +574,7 @@ void DOS_Shell::CMD_COPY(char * args) {
while(ScanCMDBool(args,"A")) ;
ScanCMDBool(args,"Y");
ScanCMDBool(args,"-Y");
ScanCMDBool(args,"V");
char * rem=ScanCMDRemain(args);
if (rem) {

View File

@ -56,7 +56,7 @@ void DOS_Shell::InputCommand(char * line) {
Bit16u dummy;
DOS_CloseFile(input_handle);
DOS_OpenFile("con",2,&dummy);
LOG(LOG_MISC,LOG_ERROR)("Reopening the input handle.This is a bug!");
LOG(LOG_MISC,LOG_ERROR)("Reopening the input handle. This is a bug!");
}
if (!n) {
size=0; //Kill the while loop
@ -174,6 +174,24 @@ void DOS_Shell::InputCommand(char * line) {
size++;
}
break;
case 15: /* Shift-Tab */
if (l_completion.size()) {
if (it_completion == l_completion.begin()) it_completion = l_completion.end ();
it_completion--;
if (it_completion->length()) {
for (;str_index > completion_index; str_index--) {
// removes all characters
outc(8); outc(' '); outc(8);
}
strcpy(&line[completion_index], it_completion->c_str());
len = (Bit16u)it_completion->length();
str_len = str_index = completion_index + len;
size = CMD_MAXLINE - str_index - 2;
DOS_WriteFile(STDOUT, (Bit8u *)it_completion->c_str(), &len);
}
}
default:
break;
}
@ -281,7 +299,7 @@ void DOS_Shell::InputCommand(char * line) {
}
res=DOS_FindNext();
}
/* Add excutable list to front of completion list. */
/* Add executable list to front of completion list. */
std::copy(executable.begin(),executable.end(),std::front_inserter(l_completion));
it_completion = l_completion.begin();
dos.dta(save_dta);