mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-25 18:11:50 +01:00
sync to dosbox r3778
This commit is contained in:
parent
033d4e91e4
commit
ccd97a1f39
106
README
106
README
@ -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.
|
||||
|
@ -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
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
};
|
||||
|
||||
void updateDPT(void);
|
||||
void incrementFDD(void);
|
||||
|
||||
#define MAX_HDD_IMAGES 2
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <assert.h>
|
||||
#include <sstream>
|
||||
#include <stddef.h>
|
||||
#include "dosbox.h"
|
||||
#include "cpu.h"
|
||||
#ifdef HW_RVL
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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) */
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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?
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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 */
|
||||
{
|
||||
|
@ -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++) {
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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));
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include "dosbox.h"
|
||||
#include "callback.h"
|
||||
#include "mem.h"
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user