sync with official

This commit is contained in:
dborth 2009-10-09 06:22:57 +00:00
parent d4f4b6ce52
commit f0f4e75fe3
75 changed files with 3928 additions and 2794 deletions

36
README
View File

@ -1,39 +1,5 @@
DOSBox Wii (Port of DOSBox v0.73)
http://code.google.com/p/dosbox-wii/
DOSBox v0.73
====
WII:
====
Report bugs at: http://code.google.com/p/dosbox-wii/issues/list
You can also view and download the source code from there.
To run homebrew applications, such as this one, on your Wii,
please see http://www.wiibrew.org/wiki/Main_Page
See the wiki for more information:
http://www.wiibrew.org/wiki/DOSBox_Wii
You currently need a USB keyboard to use DOSBox.
The Wii Remote can be used as a mouse by pointing and using the A
and B buttons. The Wii Remote, Nunchuk, Classic Controller and
Gamecube Controller can also be used as a joystick.
HOME will exit back to the homebrew channel, as will the RESET
button on the console.
The C: drive will automatically be mounted to sd:/DOSBox/ if loaded
from apps/dosbox-wii/. Otherwise, the directory the dol is loaded
from will be mounted as C, and sd:/DOSBox as D (if present).
The Z: driver is a virtual drive that is part of DOSBox.
Other drives can be mounted using the MOUNT command.
Prefix sd: for an SD card, and usb: for a USB drive.
The Wii's DVD drive and network folders can't be mounted at this time.
The configuration is loaded from the directory the dol is located in
(if present) and sd:/DOSBox/dosbox.conf otherwise
This file will be created automatically after you start DOSBox.
Please edit it with a text editor to choose settings appropriate
for each game.
=====
NOTE:

View File

@ -1,6 +1,12 @@
Some notes about porting DOSBox to systems with certain restrictions,
like handheld devices.
General:
- depending on where you start off with the port, assure that the
config.h entries are correct/exhausting, like GCC_ATTRIBUTE is
required (struct packing) but is undefined if you base the port
on msvc sources which have a special config.h
If memory is a constraint:
- in paging.h out-comment the USE_FULL_TLB define to enable special
TLB linking code that uses less memory

View File

@ -1,5 +1,5 @@
.\" Hey, EMACS: -*- nroff -*-
.TH DOSBOX 1 "Jul 01, 2007"
.TH DOSBOX 1 "May 27, 2009"
.\" Please adjust this date whenever revising the manpage.
.SH NAME
dosbox \- an x86/DOS emulator with sound/graphics
@ -18,7 +18,15 @@ dosbox \- an x86/DOS emulator with sound/graphics
.B [\-exit]
.BI "[\-machine " machinetype ]
.LP
.B dosbox -version
.B dosbox \-version
.LP
.BI "dosbox \-editconf" " program"
.LP
.BI "dosbox \-opencaptures" " program"
.LP
.B dosbox \-printconf
.LP
.B dosbox \-eraseconf
.SH DESCRIPTION
This manual page briefly documents
.BR "dosbox" ", an x86/DOS emulator."
@ -74,17 +82,31 @@ wish to execute on startup. Multiple
.RB "Start " dosbox " with the language specified in "
.IR langfile .
.TP
.B \-exit
.BR dosbox " will close itself when the DOS program specified by "file " ends."
.B "\-exit "
.BR "dosbox" " will close itself when the DOS program specified by "file " ends."
.TP
.BI \-machine " machinetype
.RB "Setup " dosbox " to emulate a specific type of machine."
.RI "Valid choices are: " "hercules, cga, pcjr, tandy, vga(default)".
.RI "Valid choices are: " "hercules, cga, tandy, pcjr, ega, vgaonly, svga_s3(default), svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe".
The machinetype has influence on both the videocard and the available
soundcards.
.TP
.B \-version
Output version information and exit. Useful for frontends.
.TP
.BI \-editconf " program"
.RI calls " program" " with as first parameter the configuration file."
.R You can specify this command more than once. In this case it will
.RI " move to second " program " if the first one fails to start."
.TP
.BI \-opencaptures " program"
.RI "calls " program " with as first paramater the location of the captures folder."
.TP
.B \-printconf
.R prints the location of the default configuration file.
.TP
.B \-eraseconf
.R removes the default configuration file.
.SH "INTERNAL COMMANDS"
.B dosbox
supports most of the DOS commands found in command.com. In addition, the
@ -243,11 +265,13 @@ Keyb can change the keyboardlayout and the codepage used inside dosbox.
.RE
.SH FILES
Configuration and language files use a format similar to Windows .ini files.
First ~/.dosboxrc (if present) will be loaded. If no
configfile is specified at the commandline, a file named
If no configfile is specified at the commandline, a file named
.BR dosbox.conf " (if present in the current directory) will be"
loaded automatically afterwards. If a configfile is specified at the commandline
that one will be used instead.
loaded automatically. If a configfile is specified at the commandline
that one will be used instead. If no configfile is specified or found
in the current directory
.RB " then dosbox will load one from " ~/.dosbox/ ". It will try to create "
one if there is none.
.SH "SPECIAL KEYS"
.TP 12m
.IP ALT\-ENTER

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: callback.h,v 1.25 2009/06/11 16:05:17 c2woody Exp $ */
/* $Id: callback.h,v 1.26 2009/08/23 17:24:54 c2woody Exp $ */
#ifndef DOSBOX_CALLBACK_H
#define DOSBOX_CALLBACK_H
@ -71,6 +71,7 @@ bool CALLBACK_Free(Bitu callback);
void CALLBACK_SCF(bool val);
void CALLBACK_SZF(bool val);
void CALLBACK_SIF(bool val);
extern Bitu call_priv_io;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dma.h,v 1.19 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dma.h,v 1.20 2009/07/24 09:56:14 c2woody Exp $ */
#ifndef DOSBOX_DMA_H
#define DOSBOX_DMA_H
@ -35,7 +35,7 @@ class DmaChannel {
public:
Bit32u pagebase;
Bit16u baseaddr;
Bit16u curraddr;
Bit32u curraddr;
Bit16u basecnt;
Bit16u currcnt;
Bit8u channum;
@ -114,4 +114,6 @@ DmaChannel * GetDMAChannel(Bit8u chan);
void CloseSecondDMAController(void);
bool SecondDMAControllerAvailable(void);
static Bit32u dma_wrapping = 0xffff;
#endif

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_inc.h,v 1.78 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dos_inc.h,v 1.82 2009/10/04 14:28:06 c2woody Exp $ */
#ifndef DOSBOX_DOS_INC_H
#define DOSBOX_DOS_INC_H
@ -86,7 +86,7 @@ enum { RETURN_EXIT=0,RETURN_CTRLC=1,RETURN_ABORT=2,RETURN_TSR=3};
#define DOS_SDA_OFS 0
#define DOS_CDS_SEG 0x108
#define DOS_FIRST_SHELL 0x118
#define DOS_MEM_START 0x158 //First Segment that DOS can use
#define DOS_MEM_START 0x16f //First Segment that DOS can use
#define DOS_PRIVATE_SEGMENT 0xc800
#define DOS_PRIVATE_SEGMENT_END 0xd000
@ -154,7 +154,7 @@ void DOS_SetupDevices(void);
bool DOS_NewPSP(Bit16u pspseg,Bit16u size);
bool DOS_ChildPSP(Bit16u pspseg,Bit16u size);
bool DOS_Execute(char * name,PhysPt block,Bit8u flags);
bool DOS_Terminate(bool tsr,Bit8u exitcode);
void DOS_Terminate(Bit16u pspseg,bool tsr,Bit8u exitcode);
/* Memory Handling Routines */
void DOS_SetupMemory(void);
@ -489,7 +489,7 @@ private:
class DOS_FCB: public MemStruct {
public:
DOS_FCB(Bit16u seg,Bit16u off);
DOS_FCB(Bit16u seg,Bit16u off,bool allow_extended=true);
void Create(bool _extended);
void SetName(Bit8u _drive,char * _fname,char * _ext);
void SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time);

View File

@ -16,16 +16,11 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: serialport.h,v 1.17 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: serialport.h,v 1.18 2009/09/25 23:40:48 h-a-l-9000 Exp $ */
#ifndef DOSBOX_SERIALPORT_H
#define DOSBOX_SERIALPORT_H
#define SERIAL_DEBUG 0
// Uncomment this for a lot of debug messages:
//#define LOG_UART
#ifndef DOSBOX_DOSBOX_H
#include "dosbox.h"
#endif
@ -42,12 +37,91 @@
#include "programs.h"
#endif
// set this to 1 for serial debugging in release mode
#define SERIAL_DBG_FORCED 0
#if (C_DEBUG || SERIAL_DBG_FORCED)
#define SERIAL_DEBUG 1
#endif
#if SERIAL_DEBUG
#include "hardware.h"
#endif
// Serial port interface
class MyFifo {
public:
MyFifo(Bitu maxsize_) {
maxsize=size=maxsize_;
pos=used=0;
data=new Bit8u[size];
}
~MyFifo() {
delete[] data;
}
INLINE Bitu getFree(void) {
return size-used;
}
bool isEmpty() {
return used==0;
}
bool isFull() {
return (size-used)==0;
}
INLINE Bitu getUsage(void) {
return used;
}
void setSize(Bitu newsize)
{
size=newsize;
pos=used=0;
}
void clear(void) {
pos=used=0;
data[0]=0;
}
bool addb(Bit8u _val) {
Bitu where=pos+used;
if (where>=size) where-=size;
if(used>=size) {
// overwrite last byte
if(where==0) where=size-1;
else where--;
data[where]=_val;
return false;
}
data[where]=_val;
used++;
return true;
}
Bit8u getb() {
if (!used) return data[pos];
Bitu where=pos;
if (++pos>=size) pos-=size;
used--;
return data[where];
}
Bit8u getTop() {
Bitu where=pos+used;
if (where>=size) where-=size;
if(used>=size) {
if(where==0) where=size-1;
else where--;
}
return data[where];
}
Bit8u probeByte() {
return data[pos];
}
private:
Bit8u * data;
Bitu maxsize,size,pos,used;
};
class CSerial {
public:
@ -58,7 +132,7 @@ public:
bool dbg_register;
bool dbg_interrupt;
bool dbg_aux;
void log_ser(bool active, char const* format,...);
#endif
static bool getBituSubstring(const char* name,Bitu* data, CommandLine* cmd);
@ -92,8 +166,9 @@ public:
#define SERIAL_RX_EVENT 4
#define SERIAL_POLLING_EVENT 5
#define SERIAL_THR_EVENT 6
#define SERIAL_RX_TIMEOUT_EVENT 7
#define SERIAL_BASE_EVENT_COUNT 6
#define SERIAL_BASE_EVENT_COUNT 7
#define COMNUMBER idnumber+1
@ -144,6 +219,7 @@ public:
// If a byte comes from loopback or prepherial, put it in here.
void receiveByte(Bit8u data);
void receiveByteEx(Bit8u data, Bit8u error);
// If an error was received, put it here (in LSR register format)
void receiveError(Bit8u errorword);
@ -177,7 +253,7 @@ private:
DOS_Device* mydosdevice;
// I used this spec: http://www.exar.com/products/st16c450v420.pdf
// I used this spec: st16c450v420.pdf
void ComputeInterrupts();
@ -191,23 +267,20 @@ private:
#define RX_PRIORITY 1 // a byte has been received
#define TX_PRIORITY 2 // tx buffer has become empty
#define MSR_PRIORITY 8 // CRS, DSR, RI, DCD change
#define TIMEOUT_PRIORITY 0x10
#define NONE_PRIORITY 0
Bit8u waiting_interrupts; // these are on, but maybe not enabled
// 16C450 (no FIFO)
// 16C550
// read/write name
Bit16u baud_divider;
Bit8u RHR; // r Receive Holding Register, also LSB of Divisor Latch (r/w)
#define RHR_OFFSET 0
// Data: whole byte
Bit8u THR; // w Transmit Holding Register
#define THR_OFFSET 0
// Data: whole byte
Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch
#define RHR_OFFSET 0 // r Receive Holding Register, also LSB of Divisor Latch (r/w)
// Data: whole byte
#define THR_OFFSET 0 // w Transmit Holding Register
// Data: whole byte
Bit8u IER; // r/w Interrupt Enable Register, also MSB of Divisor Latch
#define IER_OFFSET 1
bool irq_active;
@ -221,6 +294,7 @@ private:
#define ISR_OFFSET 2
#define ISR_CLEAR_VAL 0x1
#define ISR_FIFOTIMEOUT_VAL 0xc
#define ISR_ERROR_VAL 0x6
#define ISR_RX_VAL 0x4
#define ISR_TX_VAL 0x2
@ -292,6 +366,7 @@ private:
Bitu framingErrors;
Bitu parityErrors;
Bitu overrunErrors;
Bitu txOverrunErrors;
Bitu overrunIF0;
Bitu breakErrors;
@ -329,16 +404,28 @@ private:
void transmitLoopbackByte(Bit8u val, bool value);
// 16C550 (FIFO)
// TODO
public: // todo remove
MyFifo* rxfifo;
private:
MyFifo* txfifo;
MyFifo* errorfifo;
Bitu errors_in_fifo;
Bitu rx_interrupt_threshold;
Bitu fifosize;
Bit8u FCR;
bool sync_guardtime;
#define FIFO_STATUS_ACTIVE 0xc0 // FIFO is active AND works ;)
#define FIFO_ERROR 0x80
#define FCR_ACTIVATE 0x01
#define FCR_CLEAR_RX 0x02
#define FCR_CLEAR_TX 0x04
#define FCR_OFFSET 2
bool fifo_warn;
//Bit8u FCR; // FIFO Control Register
#define FIFO_FLOWCONTROL 0x20
};
extern CSerial* serialports[];
const Bit8u serial_defaultirq[4] = { 4, 3, 4, 3 };
const Bit16u serial_baseaddr[4] = {0x3f8,0x2f8,0x3e8,0x2e8};
const Bit8u serial_defaultirq[] = { 4, 3, 4, 3 };
const Bit16u serial_baseaddr[] = {0x3f8,0x2f8,0x3e8,0x2e8};
const char* const serial_comname[]={"COM1","COM2","COM3","COM4"};
// the COM devices
@ -358,4 +445,3 @@ private:
};
#endif

View File

@ -26,7 +26,9 @@
#pragma warning ( disable : 4290 )
#endif
#ifdef HW_RVL
#include <stdio.h>
#endif
#ifndef CH_LIST
#define CH_LIST
@ -52,11 +54,11 @@ public:
Hex():_hex(0) { };
bool operator==(Hex const& other) {return _hex == other._hex;}
operator int () const { return _hex; }
};
class Value {
/*
/*
* Multitype storage container that is aware of the currently stored type in it.
* Value st = "hello";
* Value in = 1;
@ -72,7 +74,7 @@ private:
public:
class WrongType { }; // Conversion error class
enum Etype { V_NONE, V_HEX, V_BOOL, V_INT, V_STRING, V_DOUBLE,V_CURRENT} type;
/* Constructors */
Value() :_string(0), type(V_NONE) { };
Value(Hex in) :_hex(in), type(V_HEX) { };
@ -84,7 +86,7 @@ public:
Value(Value const& in):_string(0) {plaincopy(in);}
~Value() { destroy();};
Value(std::string const& in,Etype _t) :_string(0),type(V_NONE) {SetValue(in,_t);}
/* Assigment operators */
Value& operator= (Hex in) throw(WrongType) { return copy(Value(in));}
Value& operator= (int in) throw(WrongType) { return copy(Value(in));}
@ -132,7 +134,7 @@ public:
virtual bool CheckValue(Value const& in, bool warn);
//Set interval value to in or default if in is invalid. force always sets the value.
void SetVal(Value const& in, bool forced,bool warn=true) {if(forced || CheckValue(in,warn)) value = in; else value = default_value;}
virtual ~Property(){ }
virtual ~Property(){ }
virtual const std::vector<Value>& GetValues() const;
Value::Etype Get_type(){return default_value.type;}
@ -147,12 +149,12 @@ protected:
class Prop_int:public Property {
public:
Prop_int(std::string const& _propname,Changeable::Value when, int _value)
:Property(_propname,when) {
:Property(_propname,when) {
default_value = value = _value;
min = max = -1;
}
Prop_int(std::string const& _propname,Changeable::Value when, int _min,int _max,int _value)
:Property(_propname,when) {
:Property(_propname,when) {
default_value = value = _value;
min = _min;
max = _max;
@ -178,7 +180,7 @@ public:
class Prop_bool:public Property {
public:
Prop_bool(std::string const& _propname, Changeable::Value when, bool _value)
:Property(_propname,when) {
:Property(_propname,when) {
default_value = value = _value;
}
void SetValue(std::string const& in);
@ -188,7 +190,7 @@ public:
class Prop_string:public Property{
public:
Prop_string(std::string const& _propname, Changeable::Value when, char const * const _value)
:Property(_propname,when) {
:Property(_propname,when) {
default_value = value = _value;
}
void SetValue(std::string const& in);
@ -199,7 +201,7 @@ class Prop_path:public Prop_string{
public:
std::string realpath;
Prop_path(std::string const& _propname, Changeable::Value when, char const * const _value)
:Prop_string(_propname,when,_value) {
:Prop_string(_propname,when,_value) {
default_value = value = _value;
realpath = _value;
}
@ -210,7 +212,7 @@ public:
class Prop_hex:public Property {
public:
Prop_hex(std::string const& _propname, Changeable::Value when, Hex _value)
:Property(_propname,when) {
:Property(_propname,when) {
default_value = value = _value;
}
void SetValue(std::string const& in);
@ -264,7 +266,7 @@ public:
Prop_path* Add_path(std::string const& _propname, Property::Changeable::Value when, char const * const _value=NULL);
Prop_bool* Add_bool(std::string const& _propname, Property::Changeable::Value when, bool _value=false);
Prop_hex* Add_hex(std::string const& _propname, Property::Changeable::Value when, Hex _value=0);
// void Add_double(char const * const _propname, double _value=0.0);
// void Add_double(char const * const _propname, double _value=0.0);
Prop_multival *Add_multi(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
Prop_multival_remain *Add_multiremain(std::string const& _propname, Property::Changeable::Value when,std::string const& sep);
@ -307,7 +309,7 @@ public:
virtual void SetValue(std::string const& input);
};
class Section_line: public Section{
public:
Section_line(std::string const& _sectionname):Section(_sectionname){}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell.h,v 1.27 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: shell.h,v 1.28 2009/07/03 19:36:57 qbix79 Exp $ */
#ifndef DOSBOX_SHELL_H
#define DOSBOX_SHELL_H
@ -55,6 +55,7 @@ public:
DOS_Shell * shell;
BatchFile * prev;
CommandLine * cmd;
std::string filename;
};
class AutoexecEditor;

View File

@ -1,8 +1,8 @@
!define VER_MAYOR 0
!define VER_MINOR 72
!define VER_MINOR 73
!define APP_NAME "DOSBox ${VER_MAYOR}.${VER_MINOR} Installer"
!define COMP_NAME "DOSBox Team"
!define COPYRIGHT "Copyright © 2002-2008 DOSBox Team"
!define COPYRIGHT "Copyright © 2002-2009 DOSBox Team"
!define DESCRIPTION "DOSBox Installer"
VIProductVersion "${VER_MAYOR}.${VER_MINOR}.0.0"
@ -32,10 +32,13 @@ LicenseText "DOSBox v${VER_MAYOR}.${VER_MINOR} License" "Next >"
; Else vista enables compatibility mode
RequestExecutionLevel admin
; Shortcuts in all users
ComponentText "Select components for DOSBox"
; The stuff to install
Section "!Core files" Core
SetShellVarContext all
; Set output path to the installation directory.
ClearErrors
SetOutPath $INSTDIR
@ -44,7 +47,6 @@ Section "!Core files" Core
; Put file there
CreateDirectory "$INSTDIR\capture"
CreateDirectory "$INSTDIR\zmbv"
File /oname=README.txt README
File /oname=COPYING.txt COPYING
@ -53,7 +55,6 @@ Section "!Core files" Core
File /oname=AUTHORS.txt AUTHORS
File /oname=INSTALL.txt INSTALL
File DOSBox.exe
File dosbox.conf
File SDL.dll
File SDL_net.dll
File /oname=zmbv\zmbv.dll zmbv.dll
@ -62,12 +63,14 @@ Section "!Core files" Core
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
CreateDirectory "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole -conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk" "$INSTDIR\DOSBox.exe" "-noconsole" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk" "$INSTDIR\README.txt"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk" "notepad.exe" "$INSTDIR\dosbox.conf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\capture"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Edit Configuration.lnk" "$INSTDIR\DOSBox.exe" "-editconf notepad.exe -editconf $\"%SystemRoot%\system32\notepad.exe$\" -editconf $\"%WINDIR%\notepad.exe$\""
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.lnk" "$INSTDIR\DOSBox.exe" "-eraseconf"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk" "$INSTDIR\DOSBox.exe" "-opencaptures explorer.exe"
CreateShortCut "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk" "$INSTDIR\zmbv\README.txt"
;change outpath so the working directory gets set to zmbv
SetOutPath "$INSTDIR\zmbv"
@ -97,8 +100,9 @@ end_section:
SectionEnd ; end the section
Section "Desktop Shortcut" SecDesktop
SetShellVarContext all
CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "-conf $\"$INSTDIR\dosbox.conf$\"" "$INSTDIR\DOSBox.exe" 0
CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.exe" "" "$INSTDIR\DOSBox.exe" 0
SectionEnd ; end the section
@ -106,6 +110,10 @@ CreateShortCut "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk" "$INSTDIR\DOSBox.
UninstallText "This will uninstall DOSBox v${VER_MAYOR}.${VER_MINOR}. Hit next to continue."
Section "Uninstall"
; Shortcuts in all users
SetShellVarContext all
Delete "$DESKTOP\DOSBox ${VER_MAYOR}.${VER_MINOR}.lnk"
; remove registry keys
; remove files
@ -116,7 +124,6 @@ Section "Uninstall"
Delete $INSTDIR\AUTHORS.txt
Delete $INSTDIR\INSTALL.txt
Delete $INSTDIR\DOSBox.exe
Delete $INSTDIR\dosbox.conf
Delete $INSTDIR\SDL.dll
Delete $INSTDIR\SDL_net.dll
Delete $INSTDIR\zmbv\zmbv.dll
@ -134,14 +141,15 @@ Section "Uninstall"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\README.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox (noconsole).lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\DOSBox.conf.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Edit Configuration.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration\Reset Configuration.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Capture folder.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Install movie codec.lnk"
Delete "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video\Video instructions.lnk"
; remove directories used.
RMDir "$INSTDIR\zmbv"
RMDir "$INSTDIR\capture"
RMDir "$INSTDIR"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Configuration"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}\Video"
RMDir "$SMPROGRAMS\DOSBox-${VER_MAYOR}.${VER_MINOR}"
SectionEnd

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: callback.cpp,v 1.41 2009/06/11 16:05:17 c2woody Exp $ */
/* $Id: callback.cpp,v 1.42 2009/08/23 17:24:54 c2woody Exp $ */
#include <stdlib.h>
#include <string.h>
@ -109,15 +109,24 @@ void CALLBACK_RunRealInt(Bit8u intnum) {
}
void CALLBACK_SZF(bool val) {
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFBF;
Bit16u newZF=(val==true) << 6;
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newZF));
Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4);
if (val) tempf |= FLAG_ZF;
else tempf &= ~FLAG_ZF;
mem_writew(SegPhys(ss)+reg_sp+4,tempf);
}
void CALLBACK_SCF(bool val) {
Bit16u tempf=mem_readw(SegPhys(ss)+reg_sp+4) & 0xFFFE;
Bit16u newCF=(val==true);
mem_writew(SegPhys(ss)+reg_sp+4,(tempf | newCF));
Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4);
if (val) tempf |= FLAG_CF;
else tempf &= ~FLAG_CF;
mem_writew(SegPhys(ss)+reg_sp+4,tempf);
}
void CALLBACK_SIF(bool val) {
Bit16u tempf = mem_readw(SegPhys(ss)+reg_sp+4);
if (val) tempf |= FLAG_IF;
else tempf &= ~FLAG_IF;
mem_writew(SegPhys(ss)+reg_sp+4,tempf);
}
void CALLBACK_SetDescription(Bitu nr, const char* descr) {

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: core_dyn_x86.cpp,v 1.35 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: core_dyn_x86.cpp,v 1.36 2009/07/20 17:55:52 c2woody Exp $ */
#include "dosbox.h"
@ -306,7 +306,10 @@ run_block:
return debugCallback;
}
#endif
if (!GETFLAG(TF)) goto restart_core;
if (!GETFLAG(TF)) {
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
goto restart_core;
}
cpudecoder=CPU_Core_Dyn_X86_Trap_Run;
if (!dyn_dh_fpu.state_used) return CBRET_NONE;
DH_FPU_SAVE_REINIT

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: cache.h,v 1.20 2009/07/12 20:13:05 c2woody Exp $ */
class CacheBlock {
public:
void Clear(void);
@ -88,6 +108,10 @@ public:
return is_current_block;
}
void writeb(PhysPt addr,Bitu val){
if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return;
if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) {
E_Exit("wb:non-readable code page found that is no ROM page");
}
addr&=4095;
if (host_readb(hostmem+addr)==(Bit8u)val) return;
host_writeb(hostmem+addr,val);
@ -104,6 +128,10 @@ public:
InvalidateRange(addr,addr);
}
void writew(PhysPt addr,Bitu val){
if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return;
if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) {
E_Exit("ww:non-readable code page found that is no ROM page");
}
addr&=4095;
if (host_readw(hostmem+addr)==(Bit16u)val) return;
host_writew(hostmem+addr,val);
@ -120,6 +148,10 @@ public:
InvalidateRange(addr,addr+1);
}
void writed(PhysPt addr,Bitu val){
if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return;
if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) {
E_Exit("wd:non-readable code page found that is no ROM page");
}
addr&=4095;
if (host_readd(hostmem+addr)==(Bit32u)val) return;
host_writed(hostmem+addr,val);
@ -136,6 +168,10 @@ public:
InvalidateRange(addr,addr+3);
}
bool writeb_checked(PhysPt addr,Bitu val) {
if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false;
if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) {
E_Exit("cb:non-readable code page found that is no ROM page");
}
addr&=4095;
if (host_readb(hostmem+addr)==(Bit8u)val) return false;
if (!*(Bit8u*)&write_map[addr]) {
@ -158,6 +194,10 @@ public:
return false;
}
bool writew_checked(PhysPt addr,Bitu val) {
if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false;
if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) {
E_Exit("cw:non-readable code page found that is no ROM page");
}
addr&=4095;
if (host_readw(hostmem+addr)==(Bit16u)val) return false;
if (!*(Bit16u*)&write_map[addr]) {
@ -180,6 +220,10 @@ public:
return false;
}
bool writed_checked(PhysPt addr,Bitu val) {
if (GCC_UNLIKELY(old_pagehandler->flags&PFLAG_HASROM)) return false;
if (GCC_UNLIKELY((old_pagehandler->flags&PFLAG_READABLE)!=PFLAG_READABLE)) {
E_Exit("cd:non-readable code page found that is no ROM page");
}
addr&=4095;
if (host_readd(hostmem+addr)==(Bit32u)val) return false;
if (!*(Bit32u*)&write_map[addr]) {

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: decoder.h,v 1.57 2009/03/29 17:32:20 qbix79 Exp $ */
/* $Id: decoder.h,v 1.58 2009/10/08 20:01:31 c2woody Exp $ */
#define X86_DYNFPU_DH_ENABLED
#define X86_INLINED_MEMACCESS
@ -187,13 +187,19 @@ static INLINE void decode_increase_wmapmask(Bitu size) {
static bool decode_fetchb_imm(Bitu & val) {
if (decode.page.index<4096) {
HostPt tlb_addr=get_tlb_read(decode.code);
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(1);
decode.code++;
decode.page.index++;
return true;
if (decode.page.invmap != NULL) {
if (decode.page.invmap[decode.page.index] == 0) {
val=(Bit32u)decode_fetchb();
return false;
}
HostPt tlb_addr=get_tlb_read(decode.code);
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(1);
decode.code++;
decode.page.index++;
return true;
}
}
}
val=(Bit32u)decode_fetchb();
@ -201,13 +207,21 @@ static bool decode_fetchb_imm(Bitu & val) {
}
static bool decode_fetchw_imm(Bitu & val) {
if (decode.page.index<4095) {
HostPt tlb_addr=get_tlb_read(decode.code);
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(2);
decode.code+=2;
decode.page.index+=2;
return true;
if (decode.page.invmap != NULL) {
if ((decode.page.invmap[decode.page.index] == 0) &&
(decode.page.invmap[decode.page.index + 1] == 0)
) {
val=decode_fetchw();
return false;
}
HostPt tlb_addr=get_tlb_read(decode.code);
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(2);
decode.code+=2;
decode.page.index+=2;
return true;
}
}
}
val=decode_fetchw();
@ -215,13 +229,23 @@ static bool decode_fetchw_imm(Bitu & val) {
}
static bool decode_fetchd_imm(Bitu & val) {
if (decode.page.index<4093) {
HostPt tlb_addr=get_tlb_read(decode.code);
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(4);
decode.code+=4;
decode.page.index+=4;
return true;
if (decode.page.invmap != NULL) {
if ((decode.page.invmap[decode.page.index] == 0) &&
(decode.page.invmap[decode.page.index + 1] == 0) &&
(decode.page.invmap[decode.page.index + 2] == 0) &&
(decode.page.invmap[decode.page.index + 3] == 0)
) {
val=decode_fetchd();
return false;
}
HostPt tlb_addr=get_tlb_read(decode.code);
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(4);
decode.code+=4;
decode.page.index+=4;
return true;
}
}
}
val=decode_fetchd();
@ -2649,8 +2673,13 @@ restart_prefix:
goto illegalopcode;
}
}
/* Normal exit because of max opcodes reached */
// link to next block because the maximal number of opcodes has been reached
dyn_set_eip_end();
dyn_reduce_cycles();
dyn_save_critical_regs();
gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start));
dyn_closeblock();
goto finish_block;
core_close_block:
dyn_reduce_cycles();
dyn_save_critical_regs();

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dyn_fpu.h,v 1.4 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dyn_fpu.h,v 1.5 2009/09/23 20:55:19 c2woody Exp $ */
#include "dosbox.h"
#if C_FPU
@ -593,6 +593,11 @@ static void dyn_fpu_esc7(){
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
switch (group){
case 0x00: /* FFREEP STi*/
dyn_fpu_top();
gen_call_function((void*)&FPU_FFREE,"%Ddr",DREG(EA));
gen_call_function((void*)&FPU_FPOP,"");
break;
case 0x01: /* FXCH STi*/
dyn_fpu_top();
gen_call_function((void*)&FPU_FXCH,"%Ddr%Ddr",DREG(TMPB),DREG(EA));

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dyn_fpu_dh.h,v 1.6 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dyn_fpu_dh.h,v 1.7 2009/09/23 20:55:19 c2woody Exp $ */
#include "dosbox.h"
#if C_FPU
@ -408,6 +408,10 @@ static void dh_fpu_esc7(){
Bitu sub=(decode.modrm.val & 7);
if (decode.modrm.val >= 0xc0) {
switch (group){
case 0x00: /* FFREEP STi*/
cache_addb(0xdf);
cache_addb(decode.modrm.val);
break;
case 0x01: /* FXCH STi*/
cache_addb(0xdf);
cache_addb(decode.modrm.val);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: core_dynrec.cpp,v 1.12 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: core_dynrec.cpp,v 1.15 2009/08/02 16:52:33 c2woody Exp $ */
#include "dosbox.h"
@ -51,6 +51,7 @@
#include "paging.h"
#include "inout.h"
#include "lazyflags.h"
#include "pic.h"
#define CACHE_MAXSIZE (4096*2)
#define CACHE_TOTAL (1024*1024*8)
@ -99,9 +100,9 @@
#define DRCD_SEG_PHYS(seg) (&Segs.phys[seg])
// access to an 8bit general register
#define DRCD_REG_BYTE(reg,idx) (&cpu_regs.regs[reg].byte[idx])
#define DRCD_REG_BYTE(reg,idx) (&cpu_regs.regs[reg].byte[idx?BH_INDEX:BL_INDEX])
// access to 16/32bit general registers
#define DRCD_REG_WORD(reg,dwrd) ((dwrd)?((void*)(&cpu_regs.regs[reg].dword)):((void*)(&cpu_regs.regs[reg].word)))
#define DRCD_REG_WORD(reg,dwrd) ((dwrd)?((void*)(&cpu_regs.regs[reg].dword[DW_INDEX])):((void*)(&cpu_regs.regs[reg].word[W_INDEX])))
enum BlockReturn {
@ -139,6 +140,7 @@ static struct {
#define X86_64 0x02
#define MIPSEL 0x03
#define ARMV4LE 0x04
#define POWERPC 0x04
#if C_TARGETCPU == X86_64
#include "core_dynrec/risc_x64.h"
@ -148,6 +150,8 @@ static struct {
#include "core_dynrec/risc_mipsel32.h"
#elif C_TARGETCPU == ARMV4LE
#include "core_dynrec/risc_armv4le.h"
#elif C_TARGETCPU == POWERPC
#include "core_dynrec/risc_ppc.h"
#endif
#include "core_dynrec/decoder.h"
@ -233,7 +237,10 @@ run_block:
#if C_HEAVY_DEBUG
if (DEBUG_HeavyIsBreakpoint()) return debugCallback;
#endif
if (!GETFLAG(TF)) break;
if (!GETFLAG(TF)) {
if (GETFLAG(IF) && PIC_IRQCheck) return CBRET_NONE;
break;
}
// trapflag is set, switch to the trap-aware decoder
cpudecoder=CPU_Core_Dynrec_Trap_Run;
return CBRET_NONE;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: decoder.h,v 1.6 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: decoder.h,v 1.7 2009/10/08 20:01:31 c2woody Exp $ */
#include "decoder_basic.h"
@ -574,8 +574,12 @@ restart_prefix:
goto illegalopcode;
}
}
// normal exit because the maximal number of opcodes has been reached
// link to next block because the maximal 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));
dyn_closeblock();
goto finish_block;
core_close_block:
dyn_reduce_cycles();
dyn_return(BR_Normal);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: decoder_basic.h,v 1.15 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: decoder_basic.h,v 1.16 2009/10/08 20:01:31 c2woody Exp $ */
/*
@ -290,16 +290,24 @@ static bool decode_fetchb_imm(Bitu & val) {
if (GCC_UNLIKELY(decode.page.index>=4096)) {
decode_advancepage();
}
HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(1);
decode.code++;
decode.page.index++;
return true;
if (decode.page.invmap != NULL) {
if (decode.page.invmap[decode.page.index] == 0) {
// position not yet modified
val=(Bit32u)decode_fetchb();
return false;
}
HostPt tlb_addr=get_tlb_read(decode.code);
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(1);
decode.code++;
decode.page.index++;
return true;
}
}
// not directly accessible, just fetch the value
// first time decoding or not directly accessible, just fetch the value
val=(Bit32u)decode_fetchb();
return false;
}
@ -308,17 +316,26 @@ static bool decode_fetchb_imm(Bitu & val) {
// otherwise val contains the current value read from the position
static bool decode_fetchw_imm(Bitu & val) {
if (decode.page.index<4095) {
HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(2);
decode.code+=2;
decode.page.index+=2;
return true;
if (decode.page.invmap != NULL) {
if ((decode.page.invmap[decode.page.index] == 0) &&
(decode.page.invmap[decode.page.index + 1] == 0)) {
// position not yet modified
val=decode_fetchw();
return false;
}
HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(2);
decode.code+=2;
decode.page.index+=2;
return true;
}
}
}
// not directly accessible, just fetch the value
// first time decoding or not directly accessible, just fetch the value
val=decode_fetchw();
return false;
}
@ -327,17 +344,28 @@ static bool decode_fetchw_imm(Bitu & val) {
// otherwise val contains the current value read from the position
static bool decode_fetchd_imm(Bitu & val) {
if (decode.page.index<4093) {
HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(4);
decode.code+=4;
decode.page.index+=4;
return true;
if (decode.page.invmap != NULL) {
if ((decode.page.invmap[decode.page.index] == 0) &&
(decode.page.invmap[decode.page.index + 1] == 0) &&
(decode.page.invmap[decode.page.index + 2] == 0) &&
(decode.page.invmap[decode.page.index + 3] == 0)) {
// position not yet modified
val=decode_fetchd();
return false;
}
HostPt tlb_addr=get_tlb_read(decode.code);
// see if position is directly accessible
if (tlb_addr) {
val=(Bitu)(tlb_addr+decode.code);
decode_increase_wmapmask(4);
decode.code+=4;
decode.page.index+=4;
return true;
}
}
}
// not directly accessible, just fetch the value
// first time decoding or not directly accessible, just fetch the value
val=decode_fetchd();
return false;
}

View File

@ -16,6 +16,8 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dyn_fpu.h,v 1.8 2009/09/23 20:55:19 c2woody Exp $ */
#include "dosbox.h"
#if C_FPU
@ -602,6 +604,11 @@ static void dyn_fpu_esc7(){
dyn_get_modrm();
if (decode.modrm.val >= 0xc0) {
switch (decode.modrm.reg){
case 0x00: /* FFREEP STi */
dyn_fpu_top();
gen_call_function_R((void*)&FPU_FFREE,FC_OP2);
gen_call_function_raw((void*)&FPU_FPOP);
break;
case 0x01: /* FXCH STi*/
dyn_fpu_top();
gen_call_function_RR((void*)&FPU_FXCH,FC_OP1,FC_OP2);

View File

@ -356,6 +356,63 @@
CASE_0F_W(0xaf) /* IMUL Gw,Ew */
RMGwEwOp3(DIMULW,*rmrw);
break;
CASE_0F_B(0xb0) /* cmpxchg Eb,Gb */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
FillFlags();
GetRMrb;
if (rm >= 0xc0 ) {
GetEArb;
if (reg_al == *earb) {
*earb=*rmrb;
SETFLAGBIT(ZF,1);
} else {
reg_al = *earb;
SETFLAGBIT(ZF,0);
}
} else {
GetEAa;
Bit8u val = LoadMb(eaa);
if (reg_al == val) {
SaveMb(eaa,*rmrb);
SETFLAGBIT(ZF,1);
} else {
SaveMb(eaa,val); // cmpxchg always issues a write
reg_al = val;
SETFLAGBIT(ZF,0);
}
}
break;
}
CASE_0F_W(0xb1) /* cmpxchg Ew,Gw */
{
if (CPU_ArchitectureType<CPU_ARCHTYPE_486OLDSLOW) goto illegal_opcode;
FillFlags();
GetRMrw;
if (rm >= 0xc0 ) {
GetEArw;
if(reg_ax == *earw) {
*earw = *rmrw;
SETFLAGBIT(ZF,1);
} else {
reg_ax = *earw;
SETFLAGBIT(ZF,0);
}
} else {
GetEAa;
Bit16u val = LoadMw(eaa);
if(reg_ax == val) {
SaveMw(eaa,*rmrw);
SETFLAGBIT(ZF,1);
} else {
SaveMw(eaa,val); // cmpxchg always issues a write
reg_ax = val;
SETFLAGBIT(ZF,0);
}
}
break;
}
CASE_0F_W(0xb2) /* LSS Ew */
{
GetRMrw;

View File

@ -256,7 +256,7 @@
SaveMd(eaa,*rmrd);
SETFLAGBIT(ZF,1);
} else {
SaveMd(eaa,val);
SaveMd(eaa,val); // cmpxchg always issues a write
reg_eax=val;
SETFLAGBIT(ZF,0);
}

View File

@ -23,14 +23,10 @@
#include "dosbox.h"
#include "cpu.h"
#ifdef HW_RVL
// memory.h doesn't exist for Wii
#else
#ifdef HW_DOL
// memory.h doesn't exist for Gamecube
#include "string.h"
#else
#include "memory.h"
#endif
#endif
#include "debug.h"
#include "mapper.h"
#include "setup.h"

View File

@ -398,6 +398,7 @@ static char const *fop_52[] = { "*fsubrp %GF,st" };
static char const *fop_53[] = { "*fsubp %GF,st" };
static char const *fop_54[] = { "*fdivrp %GF,st" };
static char const *fop_55[] = { "*fdivp %GF,st" };
static char const *fop_56[] = { "*ffreep %GF" };
static char const *fop_60[] = { "fstsw ax", 0, 0, 0, 0, 0, 0, 0 };
static char const **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means undefined */
@ -408,7 +409,7 @@ static char const **fspecial[] = { /* 0=use st(i), 1=undefined 0 in fop_* means
fop_32, fop_33, fop_34, fop_35, fop_36, fop_37, fop_38, fop_39,
fop_40, fop_41, fop_42, fop_43, fop_44, fop_45, f0, f0,
fop_48, fop_49, fop_50, fop_51, fop_52, fop_53, fop_54, fop_55,
f0, f0, f0, f0, fop_60, f0, f0, f0,
fop_56, f0, f0, f0, fop_60, f0, f0, f0,
};
static const char *floatops[] = { /* assumed " %EF" at end of each. mod != 3 only */

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos.cpp,v 1.117 2009/04/16 12:16:52 qbix79 Exp $ */
/* $Id: dos.cpp,v 1.120 2009/10/04 14:28:07 c2woody Exp $ */
#include <stdlib.h>
#include <string.h>
@ -70,6 +70,9 @@ static Bitu DOS_21Handler(void) {
char name1[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII];
char name2[DOSNAMEBUF+2+DOS_NAMELENGTH_ASCII];
switch (reg_ah) {
case 0x00: /* Terminate Program */
DOS_Terminate(mem_readw(SegPhys(ss)+reg_sp+2),false,0);
break;
case 0x01: /* Read character from STDIN, with echo */
{
Bit8u c;Bit16u n=1;
@ -83,6 +86,8 @@ static Bitu DOS_21Handler(void) {
{
Bit8u c=reg_dl;Bit16u n=1;
DOS_WriteFile(STDOUT,&c,&n);
//Not in the official specs, but happens nonetheless. (last written character)
reg_al = c;// reg_al=(c==9)?0x20:c; //Officially: tab to spaces
}
break;
case 0x03: /* Read character from STDAUX */
@ -115,7 +120,7 @@ static Bitu DOS_21Handler(void) {
switch (reg_dl) {
case 0xFF: /* Input */
{
//TODO Make this better according to standards
//TODO Make this better according to standards
if (!DOS_GetSTDINStatus()) {
reg_al=0;
CALLBACK_SZF(true);
@ -388,17 +393,17 @@ static Bitu DOS_21Handler(void) {
reg_cx=0x0000;
break;
case 0x31: /* Terminate and stay resident */
//TODO First get normal files executing
// Important: This service does not set the carry flag!
DOS_ResizeMemory(dos.psp(),&reg_dx);
DOS_Terminate(true,reg_al);
dos.return_mode=RETURN_TSR;
DOS_Terminate(dos.psp(),true,reg_al);
break;
case 0x1f: /* Get drive parameter block for default drive */
case 0x32: /* Get drive parameter block for specific drive */
{ /* Officially a dpb should be returned as well. The disk detection part is implemented */
Bitu drive=reg_dl;if(!drive || reg_ah==0x1f) drive = DOS_GetDefaultDrive();else drive--;
if(Drives[drive]) {
Bit8u drive=reg_dl;
if (!drive || reg_ah==0x1f) drive = DOS_GetDefaultDrive();
else drive--;
if (Drives[drive]) {
reg_al = 0x00;
SegSet16(ds,dos.tables.dpb);
reg_bx = drive;//Faking only the first entry (that is the driveletter)
@ -704,18 +709,9 @@ static Bitu DOS_21Handler(void) {
}
break;
//TODO Check for use of execution state AL=5
case 0x00:
reg_ax=0x4c00; /* Terminate Program */
case 0x4c: /* EXIT Terminate with return code */
{
if (DOS_Terminate(false,reg_al)) {
/* This can't ever return false normally */
} else {
reg_ax=dos.errorcode;
CALLBACK_SCF(true);
}
break;
}
DOS_Terminate(dos.psp(),false,reg_al);
break;
case 0x4d: /* Get Return code */
reg_al=dos.return_code;/* Officially read from SDA and clear when read */
reg_ah=dos.return_mode;
@ -813,6 +809,8 @@ static Bitu DOS_21Handler(void) {
break;
default:
LOG(LOG_DOSMISC,LOG_ERROR)("DOS:58:Not Supported Set//Get memory allocation call %X",reg_al);
reg_ax=1;
CALLBACK_SCF(true);
}
break;
case 0x59: /* Get Extended error information */
@ -945,7 +943,7 @@ static Bitu DOS_21Handler(void) {
{
int in = reg_dl;
int out = toupper(in);
reg_dl = out;
reg_dl = (Bit8u)out;
}
CALLBACK_SCF(false);
break;
@ -960,8 +958,8 @@ static Bitu DOS_21Handler(void) {
MEM_BlockRead(data,dos_copybuf,len);
dos_copybuf[len] = 0;
//No upcase as String(0x21) might be multiple asciz strings
for(Bitu count = 0; count < len;count++)
dos_copybuf[count] = toupper(*reinterpret_cast<unsigned char*>(dos_copybuf+count));
for (Bitu count = 0; count < len;count++)
dos_copybuf[count] = (Bit8u)toupper(*reinterpret_cast<unsigned char*>(dos_copybuf+count));
MEM_BlockWrite(data,dos_copybuf,len);
}
CALLBACK_SCF(false);
@ -1045,7 +1043,7 @@ static Bitu DOS_21Handler(void) {
static Bitu DOS_20Handler(void) {
reg_ax=0x4c00;
reg_ah=0x00;
DOS_21Handler();
return CBRET_NONE;
}
@ -1053,7 +1051,8 @@ static Bitu DOS_20Handler(void) {
static Bitu DOS_27Handler(void) {
// Terminate & stay resident
Bit16u para = (reg_dx/16)+((reg_dx % 16)>0);
if (DOS_ResizeMemory(dos.psp(),&para)) DOS_Terminate(true,0);
Bit16u psp = mem_readw(SegPhys(ss)+reg_sp+2);
if (DOS_ResizeMemory(psp,&para)) DOS_Terminate(psp,true,0);
return CBRET_NONE;
}
@ -1149,7 +1148,7 @@ public:
static DOS* test;
void DOS_ShutDown(Section* sec) {
void DOS_ShutDown(Section* /*sec*/) {
delete test;
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_classes.cpp,v 1.57 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dos_classes.cpp,v 1.58 2009/07/09 20:06:57 c2woody Exp $ */
#include <string.h>
#include <stdlib.h>
@ -32,14 +32,14 @@ void DOS_ParamBlock::Clear(void) {
}
void DOS_ParamBlock::LoadData(void) {
exec.envseg=sGet(sExec,envseg);
exec.envseg=(Bit16u)sGet(sExec,envseg);
exec.cmdtail=sGet(sExec,cmdtail);
exec.fcb1=sGet(sExec,fcb1);
exec.fcb2=sGet(sExec,fcb2);
exec.initsssp=sGet(sExec,initsssp);
exec.initcsip=sGet(sExec,initcsip);
overlay.loadseg=sGet(sOverlay,loadseg);
overlay.relocation=sGet(sOverlay,relocation);
overlay.loadseg=(Bit16u)sGet(sOverlay,loadseg);
overlay.relocation=(Bit16u)sGet(sOverlay,relocation);
}
void DOS_ParamBlock::SaveData(void) {
@ -143,7 +143,7 @@ void DOS_InfoBlock::SetDiskBufferHeadPt(Bit32u _dbheadpt) {
}
Bit16u DOS_InfoBlock::GetStartOfUMBChain(void) {
return sGet(sDIB,startOfUMBChain);
return (Bit16u)sGet(sDIB,startOfUMBChain);
}
void DOS_InfoBlock::SetStartOfUMBChain(Bit16u _umbstartseg) {
@ -151,7 +151,7 @@ void DOS_InfoBlock::SetStartOfUMBChain(Bit16u _umbstartseg) {
}
Bit8u DOS_InfoBlock::GetUMBChainState(void) {
return sGet(sDIB,chainingUMB);
return (Bit8u)sGet(sDIB,chainingUMB);
}
void DOS_InfoBlock::SetUMBChainState(Bit8u _umbchaining) {
@ -202,7 +202,7 @@ void DOS_PSP::MakeNew(Bit16u mem_size) {
/* Init file pointer and max_files */
sSave(sPSP,file_table,RealMake(seg,offsetof(sPSP,files)));
sSave(sPSP,max_files,20);
for (i=0;i<20;i++) SetFileHandle(i,0xff);
for (Bit16u ct=0;ct<20;ct++) SetFileHandle(ct,0xff);
/* User Stack pointer */
// if (prevpsp.GetSegment()!=0) sSave(sPSP,stack,prevpsp.GetStack());
@ -309,7 +309,7 @@ bool DOS_PSP::SetNumFiles(Bit16u fileNum) {
sSave(sPSP,file_table,data);
sSave(sPSP,max_files,fileNum);
Bit16u i;
for (i=0; i<20; i++) SetFileHandle(i,sGet(sPSP,files[i]));
for (i=0; i<20; i++) SetFileHandle(i,(Bit8u)sGet(sPSP,files[i]));
for (i=20; i<fileNum; i++) SetFileHandle(i,0xFF);
} else {
sSave(sPSP,max_files,fileNum);
@ -349,17 +349,17 @@ void DOS_DTA::SetResult(const char * _name,Bit32u _size,Bit16u _date,Bit16u _tim
void DOS_DTA::GetResult(char * _name,Bit32u & _size,Bit16u & _date,Bit16u & _time,Bit8u & _attr) {
MEM_BlockRead(pt+offsetof(sDTA,name),_name,DOS_NAMELENGTH_ASCII);
_size=sGet(sDTA,size);
_date=sGet(sDTA,date);
_time=sGet(sDTA,time);
_attr=sGet(sDTA,attr);
_date=(Bit16u)sGet(sDTA,date);
_time=(Bit16u)sGet(sDTA,time);
_attr=(Bit8u)sGet(sDTA,attr);
}
Bit8u DOS_DTA::GetSearchDrive(void) {
return sGet(sDTA,sdrive);
return (Bit8u)sGet(sDTA,sdrive);
}
void DOS_DTA::GetSearchParams(Bit8u & attr,char * pattern) {
attr=sGet(sDTA,sattr);
attr=(Bit8u)sGet(sDTA,sattr);
char temp[11];
MEM_BlockRead(pt+offsetof(sDTA,sname),temp,11);
memcpy(pattern,temp,8);
@ -369,13 +369,16 @@ void DOS_DTA::GetSearchParams(Bit8u & attr,char * pattern) {
}
DOS_FCB::DOS_FCB(Bit16u seg,Bit16u off) {
DOS_FCB::DOS_FCB(Bit16u seg,Bit16u off,bool allow_extended) {
SetPt(seg,off);
real_pt=pt;
if (sGet(sFCB,drive)==0xff) {
pt+=7;
extended=true;
} else extended=false;
extended=false;
if (allow_extended) {
if (sGet(sFCB,drive)==0xff) {
pt+=7;
extended=true;
}
}
}
bool DOS_FCB::Extended(void) {
@ -410,13 +413,13 @@ void DOS_FCB::SetSizeDateTime(Bit32u _size,Bit16u _date,Bit16u _time) {
void DOS_FCB::GetSizeDateTime(Bit32u & _size,Bit16u & _date,Bit16u & _time) {
_size=sGet(sFCB,filesize);
_date=sGet(sFCB,date);
_time=sGet(sFCB,time);
_date=(Bit16u)sGet(sFCB,date);
_time=(Bit16u)sGet(sFCB,time);
}
void DOS_FCB::GetRecord(Bit16u & _cur_block,Bit8u & _cur_rec) {
_cur_block=sGet(sFCB,cur_block);
_cur_rec=sGet(sFCB,cur_rec);
_cur_block=(Bit16u)sGet(sFCB,cur_block);
_cur_rec=(Bit8u)sGet(sFCB,cur_rec);
}
@ -426,8 +429,8 @@ void DOS_FCB::SetRecord(Bit16u _cur_block,Bit8u _cur_rec) {
}
void DOS_FCB::GetSeqData(Bit8u & _fhandle,Bit16u & _rec_size) {
_fhandle=sGet(sFCB,file_handle);
_rec_size=sGet(sFCB,rec_size);
_fhandle=(Bit8u)sGet(sFCB,file_handle);
_rec_size=(Bit16u)sGet(sFCB,rec_size);
}
@ -462,12 +465,12 @@ bool DOS_FCB::Valid() {
}
void DOS_FCB::FileClose(Bit8u & _fhandle) {
_fhandle=sGet(sFCB,file_handle);
_fhandle=(Bit8u)sGet(sFCB,file_handle);
sSave(sFCB,file_handle,0xff);
}
Bit8u DOS_FCB::GetDrive(void) {
Bit8u drive=sGet(sFCB,drive);
Bit8u drive=(Bit8u)sGet(sFCB,drive);
if (!drive) return DOS_GetDefaultDrive();
else return drive-1;
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_execute.cpp,v 1.67 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dos_execute.cpp,v 1.68 2009/10/04 14:28:07 c2woody Exp $ */
#include <string.h>
#include <ctype.h>
@ -104,15 +104,13 @@ void DOS_UpdatePSPName(void) {
GFX_SetTitle(-1,-1,false);
}
bool DOS_Terminate(bool tsr,Bit8u exitcode) {
void DOS_Terminate(Bit16u pspseg,bool tsr,Bit8u exitcode) {
dos.return_code=exitcode;
dos.return_mode=RETURN_EXIT;
dos.return_mode=(tsr)?RETURN_TSR:RETURN_EXIT;
Bit16u mempsp = dos.psp();
DOS_PSP curpsp(mempsp);
if (mempsp==curpsp.GetParent()) return true;
DOS_PSP curpsp(pspseg);
if (pspseg==curpsp.GetParent()) return;
/* Free Files owned by process */
if (!tsr) curpsp.CloseFiles();
@ -136,10 +134,10 @@ bool DOS_Terminate(bool tsr,Bit8u exitcode) {
interrupts enabled, test flags cleared */
mem_writew(SegPhys(ss)+reg_sp+4,0x7202);
// Free memory owned by process
if (!tsr) DOS_FreeProcessMemory(mempsp);
if (!tsr) DOS_FreeProcessMemory(pspseg);
DOS_UpdatePSPName();
if ((!(CPU_AutoDetermineMode>>CPU_AUTODETERMINE_SHIFT)) || (cpu.pmode)) return true;
if ((!(CPU_AutoDetermineMode>>CPU_AUTODETERMINE_SHIFT)) || (cpu.pmode)) return;
CPU_AutoDetermineMode>>=CPU_AUTODETERMINE_SHIFT;
if (CPU_AutoDetermineMode&CPU_AUTODETERMINE_CYCLES) {
@ -159,7 +157,7 @@ bool DOS_Terminate(bool tsr,Bit8u exitcode) {
}
#endif
return true;
return;
}
static bool MakeEnv(char * name,Bit16u * segment) {

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_files.cpp,v 1.111 2009/06/18 18:17:54 c2woody Exp $ */
/* $Id: dos_files.cpp,v 1.113 2009/08/31 18:03:08 qbix79 Exp $ */
#include <string.h>
#include <stdlib.h>
@ -188,7 +188,7 @@ bool DOS_MakeName(char const * const name,char * const fullname,Bit8u * drive) {
bool DOS_GetCurrentDir(Bit8u drive,char * const buffer) {
if (drive==0) drive=DOS_GetDefaultDrive();
else drive--;
if ((drive>DOS_DRIVES) || (!Drives[drive])) {
if ((drive>=DOS_DRIVES) || (!Drives[drive])) {
DOS_SetError(DOSERR_INVALID_DRIVE);
return false;
}
@ -665,7 +665,7 @@ bool DOS_Canonicalize(char const * const name,char * const big) {
bool DOS_GetFreeDiskSpace(Bit8u drive,Bit16u * bytes,Bit8u * sectors,Bit16u * clusters,Bit16u * free) {
if (drive==0) drive=DOS_GetDefaultDrive();
else drive--;
if ((drive>DOS_DRIVES) || (!Drives[drive])) {
if ((drive>=DOS_DRIVES) || (!Drives[drive])) {
DOS_SetError(DOSERR_INVALID_DRIVE);
return false;
}
@ -768,11 +768,17 @@ static bool isvalid(const char in){
#define PARSE_RET_BADDRIVE 0xff
Bit8u FCB_Parsename(Bit16u seg,Bit16u offset,Bit8u parser ,char *string, Bit8u *change) {
char * string_begin=string;Bit8u ret=0;
DOS_FCB fcb(seg,offset);
char * string_begin=string;
Bit8u ret=0;
if (!(parser & PARSE_DFLT_DRIVE)) {
// default drive forced, this intentionally invalidates an extended FCB
mem_writeb(PhysMake(seg,offset),0);
}
DOS_FCB fcb(seg,offset,false); // always a non-extended FCB
bool hasdrive,hasname,hasext,finished;
hasdrive=hasname=hasext=finished=false;
Bitu index=0;Bit8u fill=' ';
Bitu index=0;
Bit8u fill=' ';
/* First get the old data from the fcb */
#ifdef _MSC_VER
#pragma pack (1)

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_keyboard_layout.cpp,v 1.21 2009/04/01 18:30:41 c2woody Exp $ */
/* $Id: dos_keyboard_layout.cpp,v 1.22 2009/09/06 19:25:33 c2woody Exp $ */
#include "dosbox.h"
#include "bios.h"
@ -935,8 +935,7 @@ Bitu keyboard_layout::read_codepage_file(const char* codepage_file_name, Bit32s
// update font if necessary
if (font_changed && (CurMode->type==M_TEXT) && (IS_EGAVGA_ARCH)) {
if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16);
else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14);
INT10_ReloadFont();
}
INT10_SetupRomMemoryChecksum();

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_memory.cpp,v 1.44 2009/06/08 17:20:02 c2woody Exp $ */
/* $Id: dos_memory.cpp,v 1.45 2009/07/15 17:05:07 c2woody Exp $ */
#include "dosbox.h"
#include "mem.h"
@ -347,7 +347,7 @@ bool DOS_LinkUMBsToMemChain(Bit16u linkstate) {
Bit16u umb_start=dos_infoblock.GetStartOfUMBChain();
if (umb_start!=UMB_START_SEG) {
if (umb_start!=0xffff) LOG(LOG_DOSMISC,LOG_ERROR)("Corrupt UMB chain: %x",umb_start);
return true;
return false;
}
if ((linkstate&1)==(dos_infoblock.GetUMBChainState()&1)) return true;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dos_misc.cpp,v 1.23 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dos_misc.cpp,v 1.24 2009/09/25 20:51:21 qbix79 Exp $ */
#include "dosbox.h"
#include "callback.h"
@ -184,8 +184,7 @@ static bool DOS_MultiplexFunctions(void) {
else return false;
case 0x1680: /* RELEASE CURRENT VIRTUAL MACHINE TIME-SLICE */
//TODO Maybe do some idling but could screw up other systems :)
reg_al=0;
return true;
return true; //So no warning in the debugger anymore
case 0x1689: /* Kernel IDLE CALL */
case 0x168f: /* Close awareness crap */
/* Removing warning */

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_iso.cpp,v 1.26 2009/06/19 18:28:10 c2woody Exp $ */
/* $Id: drive_iso.cpp,v 1.27 2009/09/22 21:48:08 c2woody Exp $ */
#include <cctype>
#include <cstring>
@ -430,7 +430,11 @@ void isoDrive::FreeDirIterator(const int dirIterator) {
// if this was the last aquired iterator decrement nextFreeIterator
if ((dirIterator + 1) % MAX_OPENDIRS == nextFreeDirIterator) {
nextFreeDirIterator--;
if (nextFreeDirIterator>0) {
nextFreeDirIterator--;
} else {
nextFreeDirIterator = MAX_OPENDIRS-1;
}
}
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: drive_local.cpp,v 1.81 2009/06/18 18:17:54 c2woody Exp $ */
/* $Id: drive_local.cpp,v 1.82 2009/07/18 18:42:55 c2woody Exp $ */
#include <stdio.h>
#include <stdlib.h>
@ -83,7 +83,7 @@ bool localDrive::FileOpen(DOS_File * * file,char * name,Bit32u flags) {
const char* type;
switch (flags&0xf) {
case OPEN_READ:type="rb"; break;
case OPEN_WRITE:type="wb"; break;
case OPEN_WRITE:type="rb+"; break;
case OPEN_READWRITE:type="rb+"; break;
default:
DOS_SetError(DOSERR_ACCESS_CODE_INVALID);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: fpu.cpp,v 1.30 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: fpu.cpp,v 1.31 2009/09/16 18:01:53 qbix79 Exp $ */
#include "dosbox.h"
#if C_FPU
@ -594,6 +594,10 @@ void FPU_ESC7_Normal(Bitu rm) {
Bitu group=(rm >> 3) & 7;
Bitu sub=(rm & 7);
switch (group){
case 0x00: /* FFREEP STi*/
fpu.tags[STV(sub)]=TAG_Empty;
FPU_FPOP();
break;
case 0x01: /* FXCH STi*/
FPU_FXCH(TOP,STV(sub));
break;

File diff suppressed because it is too large Load Diff

View File

@ -349,12 +349,12 @@ static void conc3d(Cache,SBPP,DBPP) (const void * s) {
line0[0]=P; \
line0[1]=P & greenMask; \
line0[2]=P & blueMask; \
line1[0]=P & blueMask; \
line1[1]=P; \
line1[2]=P & redMask; \
line2[0]=P & redMask; \
line2[1]=P & greenMask; \
line2[2]=P;
line1[0]=P & greenMask; \
line1[1]=P & redMask; \
line1[2]=P; \
line2[0]=P; \
line2[1]=P & blueMask; \
line2[2]=P & redMask;
#include "render_simple.h"
#undef SCALERNAME
#undef SCALERWIDTH

View File

@ -111,12 +111,7 @@ static GUI::ScreenSDL *UI_Startup(GUI::ScreenSDL *screen) {
old_unicode = SDL_EnableUNICODE(1);
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);
#ifdef HW_RVL
// This won't work because the Masks are wrong for 16-bit.
screenshot = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, 0);
#else
screenshot = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, 0);
#endif
// create screenshot for fade effect
int rs = screenshot->format->Rshift, gs = screenshot->format->Gshift, bs = screenshot->format->Bshift, am = GUI::Color::AlphaMask;
@ -129,12 +124,7 @@ static GUI::ScreenSDL *UI_Startup(GUI::ScreenSDL *screen) {
}
}
#ifdef HW_RVL
// This won't work because the Masks are wrong for 16-bit.
background = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 16, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, GUI::Color::AlphaMask);
#else
background = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, 32, GUI::Color::RedMask, GUI::Color::GreenMask, GUI::Color::BlueMask, GUI::Color::AlphaMask);
#endif
// use a blurred and sepia-toned screenshot as menu background
for (int y = 0; y < h; y++) {
Bit32u *bg = (Bit32u*)(y*background->pitch + (char*)background->pixels);
@ -165,8 +155,7 @@ static GUI::ScreenSDL *UI_Startup(GUI::ScreenSDL *screen) {
SDL_Surface* sdlscreen = SDL_SetVideoMode(w, h, 16, SDL_SWSURFACE|(fs?SDL_FULLSCREEN:0));
#else
SDL_Surface* sdlscreen = SDL_SetVideoMode(w, h, 32, SDL_SWSURFACE|(fs?SDL_FULLSCREEN:0));
#endif
if (sdlscreen == NULL) E_Exit("Could not initialize video mode %ix%ix32 for UI: %s", w, h, SDL_GetError());
#endif if (sdlscreen == NULL) E_Exit("Could not initialize video mode %ix%ix32 for UI: %s", w, h, SDL_GetError());
// fade out
SDL_Event event;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: dma.cpp,v 1.40 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: dma.cpp,v 1.41 2009/07/24 09:56:14 c2woody Exp $ */
#include <string.h>
#include "dosbox.h"
@ -41,28 +41,40 @@ static void UpdateEMSMapping(void) {
}
/* read a block from physical memory */
static void DMA_BlockRead(PhysPt pt,void * data,Bitu size) {
static void DMA_BlockRead(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8u dma16) {
Bit8u * write=(Bit8u *) data;
for ( ; size ; size--, pt++) {
Bitu page = pt >> 12;
Bitu highpart_addr_page = spage>>12;
size <<= dma16;
offset <<= dma16;
Bit32u dma_wrap = ((0xffff<<dma16)+dma16) | dma_wrapping;
for ( ; size ; size--, offset++) {
if (offset>(dma_wrapping<<dma16)) E_Exit("DMA segbound wrapping (read)");
offset &= dma_wrap;
Bitu page = highpart_addr_page+(offset >> 12);
/* care for EMS pageframe etc. */
if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page];
else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page];
else if (page < LINK_START) page = paging.firstmb[page];
*write++=phys_readb(page*4096 + (pt & 4095));
*write++=phys_readb(page*4096 + (offset & 4095));
}
}
/* write a block into physical memory */
static void DMA_BlockWrite(PhysPt pt,void * data,Bitu size) {
static void DMA_BlockWrite(PhysPt spage,PhysPt offset,void * data,Bitu size,Bit8u dma16) {
Bit8u * read=(Bit8u *) data;
for ( ; size ; size--, pt++) {
Bitu page = pt >> 12;
Bitu highpart_addr_page = spage>>12;
size <<= dma16;
offset <<= dma16;
Bit32u dma_wrap = ((0xffff<<dma16)+dma16) | dma_wrapping;
for ( ; size ; size--, offset++) {
if (offset>(dma_wrapping<<dma16)) E_Exit("DMA segbound wrapping (write)");
offset &= dma_wrap;
Bitu page = highpart_addr_page+(offset >> 12);
/* care for EMS pageframe etc. */
if (page < EMM_PAGEFRAME4K) page = paging.firstmb[page];
else if (page < EMM_PAGEFRAME4K+0x10) page = ems_board_mapping[page];
else if (page < LINK_START) page = paging.firstmb[page];
phys_writeb(page*4096 + (pt & 4095), *read++);
phys_writeb(page*4096 + (offset & 4095), *read++);
}
}
@ -91,7 +103,7 @@ bool SecondDMAControllerAvailable(void) {
else return false;
}
static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) {
static void DMA_Write_Port(Bitu port,Bitu val,Bitu /*iolen*/) {
if (port<0x10) {
/* write to the first DMA controller (channels 0-3) */
DmaControllers[0]->WriteControllerReg(port,val,1);
@ -102,12 +114,12 @@ static void DMA_Write_Port(Bitu port,Bitu val,Bitu iolen) {
UpdateEMSMapping();
switch (port) {
/* write DMA page register */
case 0x81:GetDMAChannel(2)->SetPage(val);break;
case 0x82:GetDMAChannel(3)->SetPage(val);break;
case 0x83:GetDMAChannel(1)->SetPage(val);break;
case 0x89:GetDMAChannel(6)->SetPage(val);break;
case 0x8a:GetDMAChannel(7)->SetPage(val);break;
case 0x8b:GetDMAChannel(5)->SetPage(val);break;
case 0x81:GetDMAChannel(2)->SetPage((Bit8u)val);break;
case 0x82:GetDMAChannel(3)->SetPage((Bit8u)val);break;
case 0x83:GetDMAChannel(1)->SetPage((Bit8u)val);break;
case 0x89:GetDMAChannel(6)->SetPage((Bit8u)val);break;
case 0x8a:GetDMAChannel(7)->SetPage((Bit8u)val);break;
case 0x8b:GetDMAChannel(5)->SetPage((Bit8u)val);break;
}
}
}
@ -131,13 +143,13 @@ static Bitu DMA_Read_Port(Bitu port,Bitu iolen) {
return 0;
}
void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
DmaChannel * chan;Bitu i;
void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu /*len*/) {
DmaChannel * chan;
switch (reg) {
/* set base address of DMA transfer (1st byte low part, 2nd byte high part) */
case 0x0:case 0x2:case 0x4:case 0x6:
UpdateEMSMapping();
chan=GetChannel(reg >> 1);
chan=GetChannel((Bit8u)(reg >> 1));
flipflop=!flipflop;
if (flipflop) {
chan->baseaddr=(chan->baseaddr&0xff00)|val;
@ -150,7 +162,7 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
/* set DMA transfer count (1st byte low part, 2nd byte high part) */
case 0x1:case 0x3:case 0x5:case 0x7:
UpdateEMSMapping();
chan=GetChannel(reg >> 1);
chan=GetChannel((Bit8u)(reg >> 1));
flipflop=!flipflop;
if (flipflop) {
chan->basecnt=(chan->basecnt&0xff00)|val;
@ -181,8 +193,8 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
flipflop=false;
break;
case 0xd: /* Master Clear/Reset */
for (i=0;i<4;i++) {
chan=GetChannel(i);
for (Bit8u ct=0;ct<4;ct++) {
chan=GetChannel(ct);
chan->SetMask(true);
chan->tcount=false;
}
@ -190,15 +202,15 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
break;
case 0xe: /* Clear Mask register */
UpdateEMSMapping();
for (i=0;i<4;i++) {
chan=GetChannel(i);
for (Bit8u ct=0;ct<4;ct++) {
chan=GetChannel(ct);
chan->SetMask(false);
}
break;
case 0xf: /* Multiple Mask register */
UpdateEMSMapping();
for (i=0;i<4;i++) {
chan=GetChannel(i);
for (Bit8u ct=0;ct<4;ct++) {
chan=GetChannel(ct);
chan->SetMask(val & 1);
val>>=1;
}
@ -206,12 +218,12 @@ void DmaController::WriteControllerReg(Bitu reg,Bitu val,Bitu len) {
}
}
Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) {
DmaChannel * chan;Bitu i,ret;
Bitu DmaController::ReadControllerReg(Bitu reg,Bitu /*len*/) {
DmaChannel * chan;Bitu ret;
switch (reg) {
/* read base address of DMA transfer (1st byte low part, 2nd byte high part) */
case 0x0:case 0x2:case 0x4:case 0x6:
chan=GetChannel(reg >> 1);
chan=GetChannel((Bit8u)(reg >> 1));
flipflop=!flipflop;
if (flipflop) {
return chan->curraddr & 0xff;
@ -220,7 +232,7 @@ Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) {
}
/* read DMA transfer count (1st byte low part, 2nd byte high part) */
case 0x1:case 0x3:case 0x5:case 0x7:
chan=GetChannel(reg >> 1);
chan=GetChannel((Bit8u)(reg >> 1));
flipflop=!flipflop;
if (flipflop) {
return chan->currcnt & 0xff;
@ -229,12 +241,11 @@ Bitu DmaController::ReadControllerReg(Bitu reg,Bitu len) {
}
case 0x8: /* Status Register */
ret=0;
for (i=0;i<4;i++) {
chan=GetChannel(i);
if (chan->tcount) ret|=1 << i;
for (Bit8u ct=0;ct<4;ct++) {
chan=GetChannel(ct);
if (chan->tcount) ret|=1 << ct;
chan->tcount=false;
// if (chan->callback) ret|=1 << (i+4);
if (chan->request) ret|=1 << (4+i);
if (chan->request) ret|=1 << (4+ct);
}
return ret;
default:
@ -264,15 +275,16 @@ DmaChannel::DmaChannel(Bit8u num, bool dma16) {
Bitu DmaChannel::Read(Bitu want, Bit8u * buffer) {
Bitu done=0;
curraddr &= dma_wrapping;
again:
Bitu left=(currcnt+1);
if (want<left) {
DMA_BlockRead(pagebase+(curraddr << DMA16),buffer,want << DMA16);
DMA_BlockRead(pagebase,curraddr,buffer,want,DMA16);
done+=want;
curraddr+=want;
currcnt-=want;
} else {
DMA_BlockRead(pagebase+(curraddr << DMA16),buffer,left << DMA16);
DMA_BlockRead(pagebase,curraddr,buffer,want,DMA16);
buffer+=left << DMA16;
want-=left;
done+=left;
@ -295,15 +307,16 @@ again:
Bitu DmaChannel::Write(Bitu want, Bit8u * buffer) {
Bitu done=0;
curraddr &= dma_wrapping;
again:
Bitu left=(currcnt+1);
if (want<left) {
DMA_BlockWrite(pagebase+(curraddr << DMA16),buffer,want << DMA16);
DMA_BlockWrite(pagebase,curraddr,buffer,want,DMA16);
done+=want;
curraddr+=want;
currcnt-=want;
} else {
DMA_BlockWrite(pagebase+(curraddr << DMA16),buffer,left << DMA16);
DMA_BlockWrite(pagebase,curraddr,buffer,left,DMA16);
buffer+=left << DMA16;
want-=left;
done+=left;
@ -366,12 +379,17 @@ public:
}
};
void DMA_SetWrapping(Bitu wrap) {
dma_wrapping = wrap;
}
static DMA* test;
void DMA_Destroy(Section* sec){
void DMA_Destroy(Section* /*sec*/){
delete test;
}
void DMA_Init(Section* sec) {
DMA_SetWrapping(0xffff);
test = new DMA(sec);
sec->AddDestroyFunction(&DMA_Destroy);
Bitu i;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: gus.cpp,v 1.36 2009/04/27 17:11:26 qbix79 Exp $ */
/* $Id: gus.cpp,v 1.37 2009/09/03 16:03:01 c2woody Exp $ */
#include <string.h>
#include <iomanip>
@ -338,7 +338,9 @@ static void GUSReset(void) {
myGUS.timers[1].value = 0xff;
myGUS.timers[0].delay = 0.080f;
myGUS.timers[1].delay = 0.320f;
myGUS.ChangeIRQDMA = false;
myGUS.mixControl = 0x0b; // latches enabled by default LINEs disabled
// Stop all channels
int i;
for(i=0;i<32;i++) {
@ -633,11 +635,11 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) {
// LOG_MSG("Write gus port %x val %x",port,val);
switch(port - GUS_BASE) {
case 0x200:
myGUS.mixControl = val;
myGUS.mixControl = (Bit8u)val;
myGUS.ChangeIRQDMA = true;
return;
case 0x208:
adlib_commandreg = val;
adlib_commandreg = (Bit8u)val;
break;
case 0x209:
//TODO adlib_commandreg should be 4 for this to work else it should just latch the value
@ -684,21 +686,21 @@ static void write_gus(Bitu port,Bitu val,Bitu iolen) {
curchan = guschan[myGUS.gCurChannel];
break;
case 0x303:
myGUS.gRegSelect = val;
myGUS.gRegSelect = (Bit8u)val;
myGUS.gRegData = 0;
break;
case 0x304:
if (iolen==2) {
myGUS.gRegData=val;
myGUS.gRegData=(Bit16u)val;
ExecuteGlobRegister();
} else myGUS.gRegData = val;
} else myGUS.gRegData = (Bit16u)val;
break;
case 0x305:
myGUS.gRegData = (0x00ff & myGUS.gRegData) | val << 8;
myGUS.gRegData = (Bit16u)((0x00ff & myGUS.gRegData) | val << 8);
ExecuteGlobRegister();
break;
case 0x307:
if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = val;
if(myGUS.gDramAddr < sizeof(GUSRam)) GUSRam[myGUS.gDramAddr] = (Bit8u)val;
break;
default:
#if LOG_GUS

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: mixer.cpp,v 1.53 2009/04/28 21:48:24 harekiet Exp $ */
/* $Id: mixer.cpp,v 1.54 2009/09/05 11:10:04 qbix79 Exp $ */
/*
Remove the sdl code from here and have it handeld in the sdlmain.
@ -147,12 +147,8 @@ void MixerChannel::Mix(Bitu _needed) {
needed=_needed;
while (enabled && needed>done) {
Bitu todo=needed-done;
todo*=freq_add;
if (todo & MIXER_REMAIN) {
todo=(todo >> MIXER_SHIFT) + 1;
} else {
todo=(todo >> MIXER_SHIFT);
}
todo *= freq_add;
todo = (todo >> MIXER_SHIFT) + ((todo & MIXER_REMAIN)!=0);
handler(todo);
}
}

View File

@ -26,7 +26,9 @@
#include <math.h>
#ifdef HW_RVL
#include <string.h>
#endif
#include <stdlib.h> // rand()
#include "dosbox.h"
#include "opl.h"

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: sblaster.cpp,v 1.76 2009/06/10 17:44:59 c2woody Exp $ */
/* $Id: sblaster.cpp,v 1.77 2009/07/11 10:39:38 harekiet Exp $ */
#include <iomanip>
#include <sstream>
@ -938,7 +938,7 @@ static void DSP_DoCommand(void) {
DSP_FlushData();
switch (sb.type) {
case SBT_1:
DSP_AddData(0x1);DSP_AddData(0x1);break;
DSP_AddData(0x1);DSP_AddData(0x05);break;
case SBT_2:
DSP_AddData(0x2);DSP_AddData(0x1);break;
case SBT_PRO1:

View File

@ -2,9 +2,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libserial.a
libserial_a_SOURCES = directserial_win32.cpp directserial_win32.h \
serialdummy.cpp serialdummy.h serialport.cpp \
softmodem.cpp softmodem.h misc_util.cpp misc_util.h \
directserial_os2.h directserial_os2.cpp \
directserial_posix.h directserial_posix.cpp \
nullmodem.cpp nullmodem.h
libserial_a_SOURCES = directserial.cpp directserial.h \
libserial.cpp libserial.h \
serialdummy.cpp serialdummy.h serialport.cpp \
softmodem.cpp softmodem.h misc_util.cpp misc_util.h \
nullmodem.cpp nullmodem.h

View File

@ -0,0 +1,319 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: directserial.cpp,v 1.2 2009/09/26 09:15:19 h-a-l-9000 Exp $ */
#include "dosbox.h"
#if C_DIRECTSERIAL
#include "serialport.h"
#include "directserial.h"
#include "misc_util.h"
#include "pic.h"
#include "libserial.h"
/* This is a serial passthrough class. Its amazingly simple to */
/* write now that the serial ports themselves were abstracted out */
CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd)
:CSerial (id, cmd) {
InstallationSuccessful = false;
comport = 0;
rx_retry = 0;
rx_retry_max = 0;
std::string tmpstring;
if(!cmd->FindStringBegin("realport:",tmpstring,false)) return;
LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str());
if(!SERIAL_open(tmpstring.c_str(), &comport)) {
char errorbuffer[256];
SERIAL_getErrorString(errorbuffer, sizeof(errorbuffer));
LOG_MSG("Serial%d: Serial Port \"%s\" could not be opened.",
COMNUMBER, tmpstring.c_str());
LOG_MSG("%s",errorbuffer);
return;
}
#if SERIAL_DEBUG
dbgmsg_poll_block=false;
dbgmsg_rx_block=false;
#endif
// 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)) {
rx_retry_max=0;
}
}
CSerial::Init_Registers();
InstallationSuccessful = true;
rx_state = D_RX_IDLE;
setEvent(SERIAL_POLLING_EVENT, 1); // millisecond receive tick
}
CDirectSerial::~CDirectSerial () {
if(comport) SERIAL_close(comport);
// We do not use own events so we don't have to clear them.
}
// CanReceive: true:UART part has room left
// doReceive: true:there was really a byte to receive
// rx_retry is incremented in polling events
// in POLLING_EVENT: always add new polling event
// D_RX_IDLE + CanReceive + doReceive -> D_RX_WAIT , add RX_EVENT
// D_RX_IDLE + CanReceive + not doReceive -> D_RX_IDLE
// D_RX_IDLE + not CanReceive -> D_RX_BLOCKED, add RX_EVENT
// D_RX_BLOCKED + CanReceive + doReceive -> D_RX_FASTWAIT, rem RX_EVENT
// rx_retry=0 , add RX_EVENT
// D_RX_BLOCKED + CanReceive + !doReceive -> D_RX_IDLE, rem RX_EVENT
// rx_retry=0
// D_RX_BLOCKED + !CanReceive + doReceive + retry < max -> D_RX_BLOCKED, rx_retry++
// D_RX_BLOCKED + !CanReceive + doReceive + retry >=max -> rx_retry=0
// to be continued...
void CDirectSerial::handleUpperEvent(Bit16u type) {
switch(type) {
case SERIAL_POLLING_EVENT: {
setEvent(SERIAL_POLLING_EVENT, 1.0f);
// update Modem input line states
switch(rx_state) {
case D_RX_IDLE:
if(CanReceiveByte()) {
if(doReceive()) {
// a byte was received
rx_state=D_RX_WAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
} // else still idle
} else {
#if SERIAL_DEBUG
if(!dbgmsg_poll_block) {
log_ser(dbg_aux,"Directserial: block on polling.");
dbgmsg_poll_block=true;
}
#endif
rx_state=D_RX_BLOCKED;
// have both delays (1ms + bytetime)
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
}
break;
case D_RX_BLOCKED:
// one timeout tick
if(!CanReceiveByte()) {
rx_retry++;
if(rx_retry>=rx_retry_max) {
// it has timed out:
rx_retry=0;
removeEvent(SERIAL_RX_EVENT);
if(doReceive()) {
// read away everything
// this will set overrun errors
while(doReceive());
rx_state=D_RX_WAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
} else {
// much trouble about nothing
rx_state=D_RX_IDLE;
}
} // else wait further
} else {
// good: we can receive again
#if SERIAL_DEBUG
dbgmsg_poll_block=false;
dbgmsg_rx_block=false;
#endif
removeEvent(SERIAL_RX_EVENT);
rx_retry=0;
if(doReceive()) {
rx_state=D_RX_FASTWAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.65f);
} else {
// much trouble about nothing
rx_state=D_RX_IDLE;
}
}
break;
case D_RX_WAIT:
case D_RX_FASTWAIT:
break;
}
updateMSR();
break;
}
case SERIAL_RX_EVENT: {
switch(rx_state) {
case D_RX_IDLE:
LOG_MSG("internal error in directserial");
break;
case D_RX_BLOCKED: // try to receive
case D_RX_WAIT:
case D_RX_FASTWAIT:
if(CanReceiveByte()) {
// just works or unblocked
rx_retry=0; // not waiting anymore
if(doReceive()) {
if(rx_state==D_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
else {
// maybe unblocked
rx_state=D_RX_FASTWAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.65f);
}
} else {
// didn't receive anything
rx_state=D_RX_IDLE;
}
} else {
// blocking now or still blocked
#if SERIAL_DEBUG
if(rx_state==D_RX_BLOCKED) {
if(!dbgmsg_rx_block) {
log_ser(dbg_aux,"Directserial: rx still blocked (retry=%d)",rx_retry);
dbgmsg_rx_block=true;
}
}
else log_ser(dbg_aux,"Directserial: block on continued rx (retry=%d).",rx_retry);
#endif
setEvent(SERIAL_RX_EVENT, bytetime*0.65f);
rx_state=D_RX_BLOCKED;
}
break;
}
updateMSR();
break;
}
case SERIAL_TX_EVENT: {
// Maybe echo cirquit works a bit better this way
if(rx_state==D_RX_IDLE && CanReceiveByte()) {
if(doReceive()) {
// a byte was received
rx_state=D_RX_WAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
}
}
ByteTransmitted();
updateMSR();
break;
}
case SERIAL_THR_EVENT: {
ByteTransmitting();
setEvent(SERIAL_TX_EVENT,bytetime*1.1f);
break;
}
}
}
bool CDirectSerial::doReceive() {
int value = SERIAL_getextchar(comport);
if(value) {
receiveByteEx((Bit8u)(value&0xff),(Bit8u)((value&0xff00)>>8));
return true;
}
return false;
}
// updatePortConfig is called when emulated app changes the serial port
// parameters baudrate, stopbits, number of databits, parity.
void CDirectSerial::updatePortConfig (Bit16u divider, Bit8u lcr) {
Bit8u parity = 0;
switch ((lcr & 0x38)>>3) {
case 0x1: parity='o'; break;
case 0x3: parity='e'; break;
case 0x5: parity='m'; break;
case 0x7: parity='s'; break;
default: parity='n'; break;
}
Bit8u bytelength = (lcr & 0x3)+5;
// baudrate
Bitu baudrate;
if(divider==0) baudrate=115200;
else baudrate = 115200 / divider;
// stopbits
Bit8u stopbits;
if (lcr & 0x4) {
if (bytelength == 5) stopbits = SERIAL_15STOP;
else stopbits = SERIAL_2STOP;
} else stopbits = SERIAL_1STOP;
if(!SERIAL_setCommParameters(comport, baudrate, parity, stopbits, bytelength)) {
#if SERIAL_DEBUG
log_ser(dbg_aux,"Serial port settings not supported by host." );
#endif
LOG_MSG ("Serial%d: Desired serial mode not supported (%d,%d,%c,%d)",
COMNUMBER, baudrate,bytelength,parity,stopbits);
}
CDirectSerial::setRTSDTR(getRTS(), getDTR());
}
void CDirectSerial::updateMSR () {
int new_status = SERIAL_getmodemstatus(comport);
setCTS(new_status&SERIAL_CTS? true:false);
setDSR(new_status&SERIAL_DSR? true:false);
setRI(new_status&SERIAL_RI? true:false);
setCD(new_status&SERIAL_CD? true:false);
}
void CDirectSerial::transmitByte (Bit8u val, bool first) {
if(!SERIAL_sendchar(comport, val))
LOG_MSG("Serial%d: COM port error: write failed!", COMNUMBER);
if(first) setEvent(SERIAL_THR_EVENT, bytetime/8);
else setEvent(SERIAL_TX_EVENT, bytetime);
}
// setBreak(val) switches break on or off
void CDirectSerial::setBreak (bool value) {
SERIAL_setBREAK(comport,value);
}
// updateModemControlLines(mcr) sets DTR and RTS.
void CDirectSerial::setRTSDTR(bool rts, bool dtr) {
SERIAL_setRTS(comport,rts);
SERIAL_setDTR(comport,dtr);
}
void CDirectSerial::setRTS(bool val) {
SERIAL_setRTS(comport,val);
}
void CDirectSerial::setDTR(bool val) {
SERIAL_setDTR(comport,val);
}
#endif

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: directserial.h,v 1.2 2009/09/26 09:15:19 h-a-l-9000 Exp $ */
// include guard
#ifndef DOSBOX_DIRECTSERIAL_WIN32_H
#define DOSBOX_DIRECTSERIAL_WIN32_H
#include "dosbox.h"
#if C_DIRECTSERIAL
#define DIRECTSERIAL_AVAILIBLE
#include "serialport.h"
#include "libserial.h"
class CDirectSerial : public CSerial {
public:
CDirectSerial(Bitu id, CommandLine* cmd);
~CDirectSerial();
void updatePortConfig(Bit16u divider, Bit8u lcr);
void updateMSR();
void transmitByte(Bit8u val, bool first);
void setBreak(bool value);
void setRTSDTR(bool rts, bool dtr);
void setRTS(bool val);
void setDTR(bool val);
void handleUpperEvent(Bit16u type);
private:
COMPORT comport;
Bitu rx_state;
#define D_RX_IDLE 0
#define D_RX_WAIT 1
#define D_RX_BLOCKED 2
#define D_RX_FASTWAIT 3
Bitu rx_retry; // counter of retries (every millisecond)
Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing
// an overrun error.
bool doReceive();
#if SERIAL_DEBUG
bool dbgmsg_poll_block;
bool dbgmsg_rx_block;
#endif
};
#endif // C_DIRECTSERIAL
#endif // include guard

View File

@ -0,0 +1,706 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: libserial.cpp,v 1.2 2009/09/26 09:15:19 h-a-l-9000 Exp $ */
#include "libserial.h"
#include "config.h"
#ifdef WIN32
#include <windows.h>
#include <stdio.h>
struct _COMPORT {
HANDLE porthandle;
bool breakstatus;
DCB orig_dcb;
};
bool SERIAL_open(const char* portname, COMPORT* port) {
// allocate COMPORT structure
COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT));
if(cp == NULL) return false;
cp->breakstatus=false;
// open the port in NT object space (recommended by Microsoft)
// allows the user to open COM10+ and custom port names.
int len = strlen(portname);
if(len > 240) {
SetLastError(ERROR_BUFFER_OVERFLOW);
return false;
}
char extended_portname[256] = "\\\\.\\";
memcpy(extended_portname+4,portname,len+1);
cp->porthandle = CreateFile (extended_portname,
GENERIC_READ | GENERIC_WRITE, 0,
// must be opened with exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // must use OPEN_EXISTING
0, // non overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (cp->porthandle == INVALID_HANDLE_VALUE) goto cleanup_error;
cp->orig_dcb.DCBlength=sizeof(DCB);
if(!GetCommState(cp->porthandle, &cp->orig_dcb)) {
goto cleanup_error;
}
// configure the port for polling
DCB newdcb;
memcpy(&newdcb,&cp->orig_dcb,sizeof(DCB));
newdcb.fBinary=true;
newdcb.fParity=true;
newdcb.fOutxCtsFlow=false;
newdcb.fOutxDsrFlow=false;
newdcb.fDtrControl=DTR_CONTROL_DISABLE;
newdcb.fDsrSensitivity=false;
newdcb.fOutX=false;
newdcb.fInX=false;
newdcb.fErrorChar=0;
newdcb.fNull=false;
newdcb.fRtsControl=RTS_CONTROL_DISABLE;
newdcb.fAbortOnError=false;
if(!SetCommState(cp->porthandle, &newdcb)) {
goto cleanup_error;
}
// Configure timeouts to effectively use polling
COMMTIMEOUTS ct;
ct.ReadIntervalTimeout = MAXDWORD;
ct.ReadTotalTimeoutConstant = 0;
ct.ReadTotalTimeoutMultiplier = 0;
ct.WriteTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 0;
if(!SetCommTimeouts(cp->porthandle, &ct)) {
goto cleanup_error;
}
if(!ClearCommBreak(cp->porthandle)) {
// Bluetooth Bluesoleil seems to not implement it
//goto cleanup_error;
}
DWORD errors;
if(!ClearCommError(cp->porthandle, &errors, NULL)) {
goto cleanup_error;
}
*port = cp;
return true;
cleanup_error:
if (cp->porthandle != INVALID_HANDLE_VALUE) CloseHandle(cp->porthandle);
free(cp);
return false;
}
void SERIAL_close(COMPORT port) {
// restore original DCB, close handle, free the COMPORT struct
if (port->porthandle != INVALID_HANDLE_VALUE) {
SetCommState(port->porthandle, &port->orig_dcb);
CloseHandle(port->porthandle);
}
free(port);
}
void SERIAL_getErrorString(char* buffer, int length) {
int error = GetLastError();
if(length < 50) return;
memset(buffer,0,length);
// get the error message text from the operating system
LPVOID sysmessagebuffer;
FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &sysmessagebuffer,
0,NULL);
const char* err5text = "The specified port is already in use.\n";
const char* err2text = "The specified port does not exist.\n";
int sysmsg_offset = 0;
if(error == 5) {
sysmsg_offset = strlen(err5text);
memcpy(buffer,err5text,sysmsg_offset);
} else if(error == 2) {
sysmsg_offset = strlen(err2text);
memcpy(buffer,err2text,sysmsg_offset);
}
if((length - sysmsg_offset - strlen((const char*)sysmessagebuffer)) >= 0)
memcpy(buffer + sysmsg_offset, sysmessagebuffer,
strlen((const char*)sysmessagebuffer));
LocalFree(sysmessagebuffer);
}
void SERIAL_setDTR(COMPORT port, bool value) {
EscapeCommFunction(port->porthandle, value ? SETDTR:CLRDTR);
}
void SERIAL_setRTS(COMPORT port, bool value) {
EscapeCommFunction(port->porthandle, value ? SETRTS:CLRRTS);
}
void SERIAL_setBREAK(COMPORT port, bool value) {
EscapeCommFunction(port->porthandle, value ? SETBREAK:CLRBREAK);
port->breakstatus = value;
}
int SERIAL_getmodemstatus(COMPORT port) {
DWORD retval = 0;
GetCommModemStatus (port->porthandle, &retval);
return (int)retval;
}
bool SERIAL_sendchar(COMPORT port, char data) {
DWORD bytesWritten;
// mean bug: with break = 1, WriteFile will never return.
if(port->breakstatus) return true; // true or false?!
WriteFile (port->porthandle, &data, 1, &bytesWritten, NULL);
if(bytesWritten==1) return true;
else return false;
}
// 0-7 char data, higher=flags
int SERIAL_getextchar(COMPORT port) {
DWORD errors = 0; // errors from API
DWORD dwRead = 0; // Number of chars read
char chRead;
int retval = 0;
// receive a byte; TODO communicate faliure
if (ReadFile (port->porthandle, &chRead, 1, &dwRead, NULL)) {
if (dwRead) {
// check for errors
ClearCommError(port->porthandle, &errors, NULL);
// mask bits are identical
errors &= CE_BREAK|CE_FRAME|CE_RXPARITY|CE_OVERRUN;
retval |= (errors<<8);
retval |= (chRead & 0xff);
retval |= 0x10000;
}
}
return retval;
}
bool SERIAL_setCommParameters(COMPORT port,
int baudrate, char parity, int stopbits, int length) {
DCB dcb;
dcb.DCBlength=sizeof(dcb);
GetCommState(port->porthandle,&dcb);
// parity
switch (parity) {
case 'n': dcb.Parity = NOPARITY; break;
case 'o': dcb.Parity = ODDPARITY; break;
case 'e': dcb.Parity = EVENPARITY; break;
case 'm': dcb.Parity = MARKPARITY; break;
case 's': dcb.Parity = SPACEPARITY; break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
// stopbits
switch(stopbits) {
case SERIAL_1STOP: dcb.StopBits = ONESTOPBIT; break;
case SERIAL_2STOP: dcb.StopBits = TWOSTOPBITS; break;
case SERIAL_15STOP: dcb.StopBits = ONE5STOPBITS; break;
default:
SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
// byte length
if(length > 8 || length < 5) {
SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
dcb.ByteSize = length;
dcb.BaudRate = baudrate;
if (!SetCommState (port->porthandle, &dcb)) return false;
return true;
}
#endif
#if defined (LINUX) || defined (MACOSX)
#include <memory.h> // strlen
#include <malloc.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h> // sprinf
struct _COMPORT {
int porthandle;
bool breakstatus;
termios backup;
};
bool SERIAL_open(const char* portname, COMPORT* port) {
int result;
// allocate COMPORT structure
COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT));
if(cp == NULL) return false;
cp->breakstatus=false;
int len = strlen(portname);
if(len > 240) {
///////////////////////////////////SetLastError(ERROR_BUFFER_OVERFLOW);
return false;
}
char extended_portname[256] = "/dev/";
memcpy(extended_portname+5,portname,len);
cp->porthandle = open (extended_portname, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (cp->porthandle < 0) goto cleanup_error;
result = tcgetattr(cp->porthandle,&cp->backup);
if (result==-1) goto cleanup_error;
// get port settings
termios termInfo;
memcpy(&termInfo,&cp->backup,sizeof(termios));
// initialize the port
termInfo.c_cflag = CS8 | CREAD | CLOCAL; // noparity, 1 stopbit
termInfo.c_iflag = PARMRK | INPCK;
termInfo.c_oflag = 0;
termInfo.c_lflag = 0;
termInfo.c_cc[VMIN] = 0;
termInfo.c_cc[VTIME] = 0;
tcflush (cp->porthandle, TCIFLUSH);
tcsetattr (cp->porthandle, TCSANOW, &termInfo);
*port = cp;
return true;
cleanup_error:
if (cp->porthandle != 0) close(cp->porthandle);
free(cp);
return false;
}
void SERIAL_close(COMPORT port) {
// restore original termios, close handle, free the COMPORT struct
if (port->porthandle >= 0) {
tcsetattr(port->porthandle, TCSANOW, &port->backup);
close(port->porthandle);
}
free(port);
}
void SERIAL_getErrorString(char* buffer, int length) {
int error = errno;
if(length < 50) return;
memset(buffer,0,length);
// get the error message text from the operating system
// TODO (or not)
const char* err5text = "The specified port is already in use.\n";
const char* err2text = "The specified port does not exist.\n";
int sysmsg_offset = 0;
if(error == EBUSY) {
sysmsg_offset = strlen(err5text);
memcpy(buffer,err5text,sysmsg_offset);
} else if(error == 2) {
sysmsg_offset = strlen(err2text);
memcpy(buffer,err2text,sysmsg_offset);
}
sprintf(buffer + sysmsg_offset, "System error %d.",error);
}
int SERIAL_getmodemstatus(COMPORT port) {
long flags = 0;
ioctl (port->porthandle, TIOCMGET, &flags);
int retval = 0;
if (flags & TIOCM_CTS) retval |= SERIAL_CTS;
if (flags & TIOCM_DSR) retval |= SERIAL_DSR;
if (flags & TIOCM_RI) retval |= SERIAL_RI;
if (flags & TIOCM_CD) retval |= SERIAL_CD;
return retval;
}
bool SERIAL_sendchar(COMPORT port, char data) {
if(port->breakstatus) return true; // true or false?!; Does POSIX need this check?
int bytesWritten = write(port->porthandle, &data, 1);
if(bytesWritten==1) return true;
else return false;
}
int SERIAL_getextchar(COMPORT port) {
unsigned char chRead = 0;
int dwRead = 0;
unsigned char error = 0;
int retval = 0;
dwRead=read(port->porthandle,&chRead,1);
if (dwRead==1) {
if(chRead==0xff) // error escape
{
dwRead=read(port->porthandle,&chRead,1);
if(chRead==0x00) // an error
{
dwRead=read(port->porthandle,&chRead,1);
if(chRead==0x0) error=SERIAL_BREAK_ERR;
else error=SERIAL_FRAMING_ERR;
}
}
retval |= (error<<8);
retval |= chRead;
retval |= 0x10000;
}
return retval;
}
bool SERIAL_setCommParameters(COMPORT port,
int baudrate, char parity, int stopbits, int length) {
termios termInfo;
int result = tcgetattr(port->porthandle, &termInfo);
if (result==-1) return false;
termInfo.c_cflag = CREAD | CLOCAL;
// parity
// "works on many systems"
#define CMSPAR 010000000000
switch (parity) {
case 'n': break;
case 'o': termInfo.c_cflag |= (PARODD | PARENB); break;
case 'e': termInfo.c_cflag |= PARENB; break;
case 'm': termInfo.c_cflag |= (PARENB | CMSPAR | PARODD); break;
case 's': termInfo.c_cflag |= (PARENB | CMSPAR); break;
default:
return false;
}
// stopbits
switch(stopbits) {
case SERIAL_1STOP: break;
case SERIAL_2STOP:
case SERIAL_15STOP: termInfo.c_cflag |= CSTOPB; break;
default:
return false;
}
// byte length
if(length > 8 || length < 5) return false;
switch (length) {
case 5: termInfo.c_cflag |= CS5; break;
case 6: termInfo.c_cflag |= CS6; break;
case 7: termInfo.c_cflag |= CS7; break;
case 8: termInfo.c_cflag |= CS8; break;
}
// baudrate
int posix_baudrate=0;
switch(baudrate) {
case 115200: posix_baudrate = B115200; break;
case 57600: posix_baudrate = B57600; break;
case 38400: posix_baudrate = B38400; break;
case 19200: posix_baudrate = B19200; break;
case 9600: posix_baudrate = B9600; break;
case 4800: posix_baudrate = B4800; break;
case 2400: posix_baudrate = B2400; break;
case 1200: posix_baudrate = B1200; break;
case 600: posix_baudrate = B600; break;
case 300: posix_baudrate = B300; break;
case 110: posix_baudrate = B110; break;
default: return false;
}
cfsetospeed (&termInfo, posix_baudrate);
cfsetispeed (&termInfo, posix_baudrate);
int retval = tcsetattr(port->porthandle, TCSANOW, &termInfo);
if(retval==-1) return false;
return true;
}
void SERIAL_setBREAK(COMPORT port, bool value) {
ioctl(port->porthandle, value?TIOCSBRK:TIOCCBRK);
}
void SERIAL_setDTR(COMPORT port, bool value) {
long flag = TIOCM_DTR;
ioctl(port->porthandle, value?TIOCMBIS:TIOCMBIC, &flag);
}
void SERIAL_setRTS(COMPORT port, bool value) {
long flag = TIOCM_RTS;
ioctl(port->porthandle, value?TIOCMBIS:TIOCMBIC, &flag);
}
#endif
#ifdef OS2
// OS/2 related headers
#define INCL_DOSFILEMGR
#define INCL_DOSERRORS
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_DOSPROCESS
#include <os2.h>
struct _COMPORT {
HFILE porthandle;
bool breakstatus;
DCBINFO backup;
};
// TODO: THIS IS INCOMPLETE and UNTESTED.
bool SERIAL_open(const char* portname, COMPORT* port) {
// allocate COMPORT structure
COMPORT cp = (_COMPORT*)malloc(sizeof(_COMPORT));
if(cp == NULL) return false;
cp->porthandle=0;
cp->breakstatus=false;
ULONG ulAction = 0;
APIRET rc = DosOpen(portname, &cp->porthandle,
&ulAction, 0L, FILE_NORMAL, FILE_OPEN,
OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L);
if (rc != NO_ERROR) {
goto cleanup_error;
}
ULONG ulParmLen = sizeof(DCBINFO);
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO,
0, 0, 0, &cp->orig_dcb, ulParmLen, &ulParmLen);
if ( rc != NO_ERROR) {
goto cleanup_error;
}
// configure the port for polling
DCBINFO newdcb;
memcpy(&newdcb,&cp->orig_dcb,sizeof(DCBINFO));
newdcb.usWriteTimeout = 0;
newdcb.usReadTimeout = 0; //65535;
newdcb.fbCtlHndShake = dcb.fbFlowReplace = 0;
newdcb.fbTimeout = 6;
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO,
&newdcb, ulParmLen, &ulParmLen, 0, 0, 0);
if ( rc != NO_ERROR) {
goto cleanup_error;
}
USHORT errors = 0;
ulParmLen = sizeof(errors);
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR,
0, 0, 0, &errors, ulParmLen, &ulParmLen);
if ( rc != NO_ERROR) {
goto cleanup_error;
}
*port = cp;
return true;
cleanup_error:
// TODO error string - rc value
if (cp->porthandle != 0) CloseHandle(cp->porthandle);
free(cp);
return false;
}
void SERIAL_getErrorString(char* buffer, int length) {
sprintf(buffer, "TODO: error handling is not fun");
}
void SERIAL_close(COMPORT port) {
ULONG ulParmLen = sizeof(DCBINFO);
// restore original DCB, close handle, free the COMPORT struct
if (port->porthandle != 0) {
DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETDCBINFO,
&port->orig_dcb, ulParmLen, &ulParmLen, 0, 0, 0);
SetCmmState(port->porthandle, &port->orig_dcb);
DosClose (port->porthandle);
}
free(port);
}
bool SERIAL_sendchar(COMPORT port, char data) {
ULONG bytesWritten = 0;
if(port->breakstatus) return true; // does OS/2 need this?
APIRET rc = DosWrite(port->porthandle, &data, 1, &bytesWritten);
if (rc == NO_ERROR && bytesWritten > 0) return true;
else return false;
}
void SERIAL_setBREAK(COMPORT port, bool value) {
USHORT error;
ULONG ulParmLen = sizeof(error);
DosDevIOCtl(port->porthandle, IOCTL_ASYNC,
value? ASYNC_SETBREAKON:ASYNC_SETBREAKOFF,
0,0,0, &error, ulParmLen, &ulParmLen);
}
int SERIAL_getextchar(COMPORT port) {
ULONG dwRead = 0; // Number of chars read
char chRead;
int retval = 0;
// receive a byte; TODO communicate faliure
if (DosRead(port->porthandle, &chRead, 1, &dwRead) == NO_ERROR) {
if (dwRead) {
// check for errors; will OS/2 clear the error on reading its data?
// if yes then this is in wrong order
USHORT errors = 0, event = 0;
ULONG ulParmLen = sizeof(errors);
DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_GETCOMMEVENT,
0, 0, 0, &event, ulParmLen, &ulParmLen);
if (event & (64 + 128) ) { // Break (Bit 6) or Frame or Parity (Bit 7) error
Bit8u errreg = 0;
if (event & 64) retval |= SERIAL_BREAK_ERR;
if (event & 128) {
DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_GETCOMMERROR,
0, 0, 0, &errors, ulParmLen, &ulParmLen);
if (errors & 8) retval |= SERIAL_FRAMING_ERR;
if (errors & 4) retval |= SERIAL_PARITY_ERR;
}
}
retval |= (chRead & 0xff);
retval |= 0x10000;
}
}
return retval;
}
int SERIAL_getmodemstatus(COMPORT port) {
UCHAR dptr = 0;
ULONG ulParmLen = sizeof(dptr);
DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_GETMODEMINPUT,
0, 0, 0, &dptr, ulParmLen, &ulParmLen);
// bits are the same as return value
return (int)dptr;
}
void SERIAL_setDTR(COMPORT port, bool value) {
UCHAR masks[2];
ULONG ulParmLen = sizeof(masks);
if(value) {
masks[0]=0x01;
masks[1]=0xFF;
} else {
masks[0]=0x00;
masks[1]=0xFE;
}
DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETMODEMCTRL,
0,0,0, &masks, ulParmLen, &ulParmLen);
}
void SERIAL_setRTS(COMPORT port, bool value) {
UCHAR masks[2];
ULONG ulParmLen = sizeof(masks);
if(value) {
masks[0]=0x02;
masks[1]=0xFF;
} else {
masks[0]=0x00;
masks[1]=0xFD;
}
DosDevIOCtl(port->porthandle, IOCTL_ASYNC, ASYNC_SETMODEMCTRL,
0,0,0, &masks, ulParmLen, &ulParmLen);
}
bool SERIAL_setCommParameters(COMPORT port,
int baudrate, char parity, int stopbits, int length) {
// baud
struct {
ULONG baud;
BYTE fraction;
} setbaud;
setbaud.baud = baudrate;
setbaud.fraction = 0;
ULONG ulParmLen = sizeof(setbaud);
APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE,
&setbaud, ulParmLen, &ulParmLen, 0, 0, 0);
if (rc != NO_ERROR) {
return false;
}
struct {
UCHAR data;
UCHAR parity;
UCHAR stop;
} paramline;
// byte length
if(length > 8 || length < 5) {
// TODO SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
paramline.data = length;
// parity
switch (parity) {
case 'n': paramline.parity = 0; break;
case 'o': paramline.parity = 1; break;
case 'e': paramline.parity = 2; break;
case 'm': paramline.parity = 3; break;
case 's': paramline.parity = 4; break;
default:
// TODO SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
// stopbits
switch(stopbits) {
case SERIAL_1STOP: paramline.stop = 0; break;
case SERIAL_2STOP: paramline.stop = 2; break;
case SERIAL_15STOP: paramline.stop = 1; break;
default:
// TODO SetLastError(ERROR_INVALID_PARAMETER);
return false;
}
// set it
ulParmLen = sizeof(paramline);
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL,
&paramline, ulParmLen, &ulParmLen, 0, 0, 0);
if ( rc != NO_ERROR)
return false;
return true;
}
#endif

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: libserial.h,v 1.2 2009/09/26 09:15:19 h-a-l-9000 Exp $ */
typedef struct _COMPORT *COMPORT;
bool SERIAL_open(const char* portname, COMPORT* port);
void SERIAL_close(COMPORT port);
void SERIAL_getErrorString(char* buffer, int length);
#define SERIAL_1STOP 1
#define SERIAL_2STOP 2
#define SERIAL_15STOP 0
// parity: n, o, e, m, s
bool SERIAL_setCommParameters(COMPORT port,
int baudrate, char parity, int stopbits, int length);
void SERIAL_setDTR(COMPORT port, bool value);
void SERIAL_setRTS(COMPORT port, bool value);
void SERIAL_setBREAK(COMPORT port, bool value);
#define SERIAL_CTS 0x10
#define SERIAL_DSR 0x20
#define SERIAL_RI 0x40
#define SERIAL_CD 0x80
int SERIAL_getmodemstatus(COMPORT port);
bool SERIAL_setmodemcontrol(COMPORT port, int flags);
bool SERIAL_sendchar(COMPORT port, char data);
// 0-7 char data, higher=flags
#define SERIAL_BREAK_ERR 0x10
#define SERIAL_FRAMING_ERR 0x08
#define SERIAL_PARITY_ERR 0x04
#define SERIAL_OVERRUN_ERR 0x02
int SERIAL_getextchar(COMPORT port);

View File

@ -1,3 +1,24 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id $ */
#include "config.h"
#if C_MODEM
@ -161,7 +182,7 @@ bool TCPClientSocket::GetRemoteAddressString(Bit8u* buffer) {
bool TCPClientSocket::ReceiveArray(Bit8u* data, Bitu* size) {
if(SDLNet_CheckSockets(listensocketset,0))
{
Bitu retval = SDLNet_TCP_Recv(mysock, data, *size);
Bits retval = SDLNet_TCP_Recv(mysock, data, *size);
if(retval<1) {
isopen=false;
*size=0;

View File

@ -1,3 +1,23 @@
/*
* Copyright (C) 2002-2009 The DOSBox Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: misc_util.h,v 1.5 2009/09/25 23:40:47 h-a-l-9000 Exp $ */
#ifndef SDLNETWRAPPER_H
#define SDLNETWRAPPER_H

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: nullmodem.cpp,v 1.7 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: nullmodem.cpp,v 1.8 2009/09/25 23:40:47 h-a-l-9000 Exp $ */
#include "dosbox.h"
@ -36,7 +36,8 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
clientport = 0;
rx_retry = 0;
rx_retry_max = 100;
rx_retry_max = 20;
rx_state=N_RX_DISC;
tx_gather = 12;
@ -51,7 +52,7 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
// usedtr: The nullmodem will
// 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 transfer data when DTR is on.
// 2) only receive data when DTR is on.
if(getBituSubstring("usedtr:", &bool_temp, cmd)) {
if(bool_temp==1) {
dtrrespect=true;
@ -105,6 +106,9 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
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;
return;
@ -115,6 +119,9 @@ CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
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 ();
@ -204,7 +211,7 @@ Bits CNullModem::readChar() {
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) receiveError(0x10);
if(rxchar&0x4) receiveByteEx(0x0,0x10);
return -1; // no "payload" received
} else return rxchar;
}
@ -223,14 +230,16 @@ void CNullModem::ClientConnect(){
clientsocket->GetRemoteAddressString(peernamebuf);
// transmit the line status
if(!transparent) setRTSDTR(getRTS(), getDTR());
rx_state=N_RX_IDLE;
LOG_MSG("Serial%d: Connected to %s",idnumber+1,peernamebuf);
setEvent(SERIAL_POLLING_EVENT, 1);
}
void CNullModem::Disconnect() {
removeEvent(SERIAL_POLLING_EVENT);
removeEvent(SERIAL_RX_EVENT);
// it was disconnected; free the socket and restart the server socket
LOG_MSG("Serial%d: Disconnected.",idnumber+1);
LOG_MSG("Serial%d: Disconnected.",COMNUMBER);
delete clientsocket;
clientsocket=0;
setDSR(false);
@ -249,48 +258,115 @@ void CNullModem::handleUpperEvent(Bit16u type) {
case SERIAL_POLLING_EVENT: {
// periodically check if new data arrived, disconnect
// if required. Add it back.
if(!receiveblock && clientsocket) {
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max )
&&(!dtrrespect | (dtrrespect&& getDTR()) )) {
rx_retry=0;
Bits rxchar = readChar();
if(rxchar>=0) {
receiveblock=true;
setEvent(SERIAL_RX_EVENT, bytetime-0.01f);
receiveByte((Bit8u)rxchar);
setEvent(SERIAL_POLLING_EVENT, 1.0f);
// update Modem input line states
updateMSR();
switch(rx_state) {
case N_RX_IDLE:
if(CanReceiveByte()) {
if(doReceive()) {
// a byte was received
rx_state=N_RX_WAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
} // else still idle
} else {
#if SERIAL_DEBUG
log_ser(dbg_aux,"Nullmodem: block on polling.");
#endif
rx_state=N_RX_BLOCKED;
// have both delays (1ms + bytetime)
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
}
else if(rxchar==-2) Disconnect();
else setEvent(SERIAL_POLLING_EVENT, 1);
} else {
rx_retry++;
setEvent(SERIAL_POLLING_EVENT, 1);
}
}
break;
case N_RX_BLOCKED:
// one timeout tick
if(!CanReceiveByte()) {
rx_retry++;
if(rx_retry>=rx_retry_max) {
// it has timed out:
rx_retry=0;
removeEvent(SERIAL_RX_EVENT);
if(doReceive()) {
// read away everything
while(doReceive());
rx_state=N_RX_WAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
} else {
// much trouble about nothing
rx_state=N_RX_IDLE;
#if SERIAL_DEBUG
log_ser(dbg_aux,"Nullmodem: unblock due to no more data",rx_retry);
#endif
}
} // else wait further
} else {
// good: we can receive again
removeEvent(SERIAL_RX_EVENT);
rx_retry=0;
if(doReceive()) {
rx_state=N_RX_FASTWAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.65f);
} else {
// much trouble about nothing
rx_state=N_RX_IDLE;
}
}
break;
case N_RX_WAIT:
case N_RX_FASTWAIT:
break;
}
break;
}
case SERIAL_RX_EVENT: {
// receive time is up, try to receive another byte.
receiveblock=false;
if((!(LSR&LSR_RX_DATA_READY_MASK) || rx_retry>=rx_retry_max)
&&(!dtrrespect | (dtrrespect&& getDTR()) )
) {
rx_retry=0;
Bits rxchar = readChar();
if(rxchar>=0) {
receiveblock=true;
setEvent(SERIAL_RX_EVENT, bytetime-0.01f);
receiveByte((Bit8u)rxchar);
}
else if(rxchar==-2) Disconnect();
else setEvent(SERIAL_POLLING_EVENT, 1);
} else {
setEvent(SERIAL_POLLING_EVENT, 1);
rx_retry++;
switch(rx_state) {
case N_RX_IDLE:
LOG_MSG("internal error in nullmodem");
break;
case N_RX_BLOCKED: // try to receive
case N_RX_WAIT:
case N_RX_FASTWAIT:
if(CanReceiveByte()) {
// just works or unblocked
if(doReceive()) {
rx_retry=0; // not waiting anymore
if(rx_state==N_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f);
else {
// maybe unblocked
rx_state=N_RX_FASTWAIT;
setEvent(SERIAL_RX_EVENT, bytetime*0.65f);
}
} else {
// didn't receive anything
rx_retry=0;
rx_state=N_RX_IDLE;
}
} else {
// blocking now or still blocked
#if SERIAL_DEBUG
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
setEvent(SERIAL_RX_EVENT, bytetime*0.65f);
rx_state=N_RX_BLOCKED;
}
break;
}
break;
}
case SERIAL_TX_EVENT: {
// Maybe echo cirquit works a bit better this way
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);
}
}
ByteTransmitted();
break;
}
@ -301,15 +377,18 @@ void CNullModem::handleUpperEvent(Bit16u type) {
break;
}
case SERIAL_SERVER_POLLING_EVENT: {
// As long as nothing is connected to out server poll the
// 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.",idnumber+1,peeripbuf);
// new socket found...
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
@ -350,15 +429,23 @@ void CNullModem::updateMSR () {
}
bool CNullModem::doReceive () {
Bits rxchar = readChar();
if(rxchar>=0) {
receiveByteEx((Bit8u)rxchar,0);
return true;
}
else if(rxchar==-2) {
Disconnect();
}
return false;
}
void CNullModem::transmitByte (Bit8u val, bool first) {
// transmit it later in THR_Event
if(first) setEvent(SERIAL_THR_EVENT, bytetime/8);
else setEvent(SERIAL_TX_EVENT, bytetime);
// transmit it later in THR_Event
if(first) {
setEvent(SERIAL_THR_EVENT, bytetime/8);
} else {
//if(clientsocket) clientsocket->Putchar(val);
setEvent(SERIAL_TX_EVENT, bytetime);
}
// disable 0xff escaping when transparent mode is enabled
if (!transparent && (val==0xff)) WriteChar(0xff);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: nullmodem.h,v 1.3 2009/05/27 09:15:41 qbix79 Exp $ */
/* $Id: nullmodem.h,v 1.4 2009/09/25 23:40:47 h-a-l-9000 Exp $ */
// include guard
#ifndef DOSBOX_NULLMODEM_WIN32_H
@ -57,6 +57,14 @@ public:
void setDTR(bool val);
void handleUpperEvent(Bit16u type);
Bitu rx_state;
#define N_RX_IDLE 0
#define N_RX_WAIT 1
#define N_RX_BLOCKED 2
#define N_RX_FASTWAIT 3
#define N_RX_DISC 4
bool doReceive();
void ClientConnect();
void Disconnect();
Bits readChar();

File diff suppressed because it is too large Load Diff

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: softmodem.cpp,v 1.11 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: softmodem.cpp,v 1.12 2009/10/04 20:57:40 h-a-l-9000 Exp $ */
#include "dosbox.h"
@ -77,41 +77,47 @@ CSerialModem::~CSerialModem() {
}
void CSerialModem::handleUpperEvent(Bit16u type) {
switch(type)
{
case SERIAL_RX_EVENT:
{
break;
}
case MODEM_TX_EVENT:
{
if(tqueue->left()) {
tqueue->addb(waiting_tx_character);
if(tqueue->left() < 2) {
CSerial::setCTS(false);
}
} else {
static Bits lcount=0;
if (lcount<1000) {
lcount++;
LOG_MSG("MODEM: TX Buffer overflow!");
}
switch (type) {
case SERIAL_RX_EVENT: {
// check for bytes to be sent to port
if(CSerial::CanReceiveByte())
if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))) {
Bit8u rbyte = rqueue->getb();
//LOG_MSG("Modem: sending byte %2x back to UART3",rbyte);
CSerial::receiveByte(rbyte);
}
if(CSerial::CanReceiveByte()) setEvent(SERIAL_RX_EVENT, bytetime*0.98f);
break;
}
case MODEM_TX_EVENT: {
if (tqueue->left()) {
tqueue->addb(waiting_tx_character);
if (tqueue->left() < 2) {
CSerial::setCTS(false);
}
} else {
static Bits lcount=0;
if (lcount<1000) {
lcount++;
LOG_MSG("MODEM: TX Buffer overflow!");
}
ByteTransmitted();
break;
}
case SERIAL_POLLING_EVENT:
{
Timer2();
setEvent(SERIAL_POLLING_EVENT,1);
break;
ByteTransmitted();
break;
}
case SERIAL_POLLING_EVENT: {
if (rqueue->inuse()) {
removeEvent(SERIAL_RX_EVENT);
setEvent(SERIAL_RX_EVENT, (float)0.01);
}
Timer2();
setEvent(SERIAL_POLLING_EVENT,1);
break;
}
case MODEM_RING_EVENT:
{
break;
}
case MODEM_RING_EVENT: {
break;
}
}
}
@ -216,6 +222,12 @@ Bitu CSerialModem::ScanNumber(char * & scan) {
return ret;
}
char CSerialModem::GetChar(char * & scan) {
char ch = *scan;
scan++;
return ch;
}
void CSerialModem::Reset(){
EnterIdleState();
cmdpos = 0;
@ -300,227 +312,238 @@ void CSerialModem::DoCommand() {
cmdpos = 0; //Reset for next command
upcase(cmdbuf);
LOG_MSG("Command sent to modem: ->%s<-\n", cmdbuf);
/* Check for empty line, stops dialing and autoanswer */
if (!cmdbuf[0]) {
reg[0]=0; // autoanswer off
return;
// }
//else {
//MIXER_Enable(mhd.chan,false);
// dialing = false;
// SendRes(ResNOCARRIER);
// goto ret_none;
// }
}
/* AT command set interpretation */
/* Check for empty line, stops dialing and autoanswer */
if (!cmdbuf[0]) {
reg[0]=0; // autoanswer off
return;
}
//else {
//MIXER_Enable(mhd.chan,false);
// dialing = false;
// SendRes(ResNOCARRIER);
// goto ret_none;
//}
/* AT command set interpretation */
if ((cmdbuf[0] != 'A') || (cmdbuf[1] != 'T')) {
SendRes(ResERROR);
return;
}
if (strstr(cmdbuf,"NET0")) {
telnetmode = false;
SendRes(ResOK);
return;
}
else if (strstr(cmdbuf,"NET1")) {
telnetmode = true;
SendRes(ResOK);
return;
}
char * scanbuf;
scanbuf=&cmdbuf[2];
char chr;
Bitu num;
while (chr=*scanbuf++) {
switch (chr) {
case 'D': // Dial
{
char * foundstr=&scanbuf[0];
if (*foundstr=='T' || *foundstr=='P') foundstr++;
// Small protection against empty line and long string
if ((!foundstr[0]) || (strlen(foundstr)>100)) {
SendRes(ResERROR);
return;
}
char* helper;
// scan for and remove spaces; weird bug: with leading spaces in the string,
// SDLNet_ResolveHost will return no error but not work anyway (win)
while(foundstr[0]==' ') foundstr++;
helper=foundstr;
helper+=strlen(foundstr);
while(helper[0]==' ') {
helper[0]=0;
helper--;
}
if (strlen(foundstr) >= 12) {
// Check if supplied parameter only consists of digits
bool isNum = true;
for (Bitu i=0; i<strlen(foundstr); i++)
if (foundstr[i] < '0' || foundstr[i] > '9')
isNum = false;
if (isNum) {
// Parameter is a number with at least 12 digits => this cannot
// be a valid IP/name
// Transform by adding dots
char buffer[128];
Bitu j = 0;
for (Bitu i=0; i<strlen(foundstr); i++) {
buffer[j++] = foundstr[i];
// Add a dot after the third, sixth and ninth number
if (i == 2 || i == 5 || i == 8)
buffer[j++] = '.';
// If the string is longer than 12 digits,
// interpret the rest as port
if (i == 11 && strlen(foundstr)>12)
buffer[j++] = ':';
}
buffer[j] = 0;
foundstr = buffer;
}
}
Dial(foundstr);
return;
}
case 'I': //Some strings about firmware
switch (num=ScanNumber(scanbuf)) {
case 3:SendLine("DosBox Emulated Modem Firmware V1.00");break;
case 4:SendLine("Modem compiled for DosBox version " VERSION);break;
};break;
case 'E': //Echo on/off
switch (num=ScanNumber(scanbuf)) {
case 0:echo = false;break;
case 1:echo = true;break;
};break;
case 'V':
switch (num=ScanNumber(scanbuf)) {
case 0:numericresponse = true;break;
case 1:numericresponse = false;break;
};break;
case 'H': //Hang up
switch (num=ScanNumber(scanbuf)) {
case 0:
if (connected) {
SendRes(ResNOCARRIER);
EnterIdleState();
return;
}
//Else return ok
};break;
case 'O': //Return to data mode
switch (num=ScanNumber(scanbuf))
{
case 0:
if (clientsocket) {
commandmode = false;
return;
} else {
SendRes(ResERROR);
return;
}
};break;
case 'T': //Tone Dial
case 'P': //Pulse Dial
break;
case 'M': //Monitor
case 'L': //Volume
ScanNumber(scanbuf);
break;
case 'A': //Answer call
if (waitingclientsocket) {
AcceptIncomingCall();
} else {
SendRes(ResERROR);
return;
}
return;
case 'Z': //Reset and load profiles
{
// scan the number away, if any
ScanNumber(scanbuf);
if (clientsocket/*socket*/) SendRes(ResNOCARRIER);
Reset();
break;
}
case ' ': //Space just skip
break;
case 'Q': // Response options
{ // 0 = all on, 1 = all off,
// 2 = no ring and no connect/carrier in answermode
Bitu val = ScanNumber(scanbuf);
if(!(val>2)) {
doresponse=val;
break;
} else {
SendRes(ResERROR);
return;
}
}
case 'S': //Registers
{
Bitu index=ScanNumber(scanbuf);
if(index>=SREGS) {
SendRes(ResERROR);
return; //goto ret_none;
}
while(scanbuf[0]==' ') scanbuf++; // skip spaces
if(scanbuf[0]=='=') { // set register
scanbuf++;
while(scanbuf[0]==' ') scanbuf++; // skip spaces
Bitu val = ScanNumber(scanbuf);
reg[index]=val;
break;
}
else if(scanbuf[0]=='?') { // get register
SendNumber(reg[index]);
scanbuf++;
break;
}
//else LOG_MSG("print reg %d with %d",index,reg[index]);
}
break;
case '&':
{
if(scanbuf[0]!=0) {
char ch = scanbuf[0];
scanbuf++;
switch(ch) {
case 'K':
{
Bitu val = ScanNumber(scanbuf);
if(val<5) flowcontrol=val;
else {
SendRes(ResERROR);
return;
}
break;
}
default:
{
scanbuf++;
LOG_MSG("Modem: Unhandled command: &%c%d",ch,ScanNumber(scanbuf));
break;
}
}
} else {
SendRes(ResERROR);
return;
}
}
break;
default:
LOG_MSG("Modem: Unhandled command: %c%d",chr,ScanNumber(scanbuf));
}
}
if ((cmdbuf[0] != 'A') || (cmdbuf[1] != 'T')) {
SendRes(ResERROR);
return;
}
if (strstr(cmdbuf,"NET0")) {
telnetmode = false;
SendRes(ResOK);
return;
}
else if (strstr(cmdbuf,"NET1")) {
telnetmode = true;
SendRes(ResOK);
return;
}
char * scanbuf = &cmdbuf[2];
while (1) {
// LOG_MSG("loopstart ->%s<-",scanbuf);
char chr = GetChar(scanbuf);
switch (chr) {
case 'D': { // Dial
char * foundstr=&scanbuf[0];
if (*foundstr=='T' || *foundstr=='P') foundstr++;
// Small protection against empty line and long string
if ((!foundstr[0]) || (strlen(foundstr)>100)) {
SendRes(ResERROR);
return;
}
char* helper;
// scan for and remove spaces; weird bug: with leading spaces in the string,
// SDLNet_ResolveHost will return no error but not work anyway (win)
while(foundstr[0]==' ') foundstr++;
helper=foundstr;
helper+=strlen(foundstr);
while(helper[0]==' ') {
helper[0]=0;
helper--;
}
if (strlen(foundstr) >= 12) {
// Check if supplied parameter only consists of digits
bool isNum = true;
for (Bitu i=0; i<strlen(foundstr); i++)
if (foundstr[i] < '0' || foundstr[i] > '9') isNum = false;
if (isNum) {
// Parameter is a number with at least 12 digits => this cannot
// be a valid IP/name
// Transform by adding dots
char buffer[128];
Bitu j = 0;
for (Bitu i=0; i<strlen(foundstr); i++) {
buffer[j++] = foundstr[i];
// Add a dot after the third, sixth and ninth number
if (i == 2 || i == 5 || i == 8)
buffer[j++] = '.';
// If the string is longer than 12 digits,
// interpret the rest as port
if (i == 11 && strlen(foundstr)>12)
buffer[j++] = ':';
}
buffer[j] = 0;
foundstr = buffer;
}
}
Dial(foundstr);
return;
}
case 'I': // Some strings about firmware
switch (ScanNumber(scanbuf)) {
case 3: SendLine("DosBox Emulated Modem Firmware V1.00"); break;
case 4: SendLine("Modem compiled for DosBox version " VERSION); break;
}
break;
case 'E': // Echo on/off
switch (ScanNumber(scanbuf)) {
case 0: echo = false; break;
case 1: echo = true; break;
}
break;
case 'V':
switch (ScanNumber(scanbuf)) {
case 0: numericresponse = true; break;
case 1: numericresponse = false; break;
}
break;
case 'H': // Hang up
switch (ScanNumber(scanbuf)) {
case 0:
if (connected) {
SendRes(ResNOCARRIER);
EnterIdleState();
return;
}
// else return ok
}
break;
case 'O': // Return to data mode
switch (ScanNumber(scanbuf)) {
case 0:
if (clientsocket) {
commandmode = false;
return;
} else {
SendRes(ResERROR);
return;
}
}
break;
case 'T': // Tone Dial
case 'P': // Pulse Dial
break;
case 'M': // Monitor
case 'L': // Volume
ScanNumber(scanbuf);
break;
case 'A': // Answer call
if (waitingclientsocket) {
AcceptIncomingCall();
} else {
SendRes(ResERROR);
return;
}
return;
case 'Z': { // Reset and load profiles
// scan the number away, if any
ScanNumber(scanbuf);
if (clientsocket) SendRes(ResNOCARRIER);
Reset();
break;
}
case ' ': // skip space
break;
case 'Q': {
// Response options
// 0 = all on, 1 = all off,
// 2 = no ring and no connect/carrier in answermode
Bitu val = ScanNumber(scanbuf);
if(!(val>2)) {
doresponse=val;
break;
} else {
SendRes(ResERROR);
return;
}
}
case 'S': { // Registers
Bitu index=ScanNumber(scanbuf);
if(index>=SREGS) {
SendRes(ResERROR);
return; //goto ret_none;
}
while(scanbuf[0]==' ') scanbuf++; // skip spaces
if(scanbuf[0]=='=') { // set register
scanbuf++;
while(scanbuf[0]==' ') scanbuf++; // skip spaces
Bitu val = ScanNumber(scanbuf);
reg[index]=val;
break;
}
else if(scanbuf[0]=='?') { // get register
SendNumber(reg[index]);
scanbuf++;
break;
}
//else LOG_MSG("print reg %d with %d",index,reg[index]);
}
break;
case '&': { // & escaped commands
char cmdchar = GetChar(scanbuf);
switch(cmdchar) {
case 'K': {
Bitu val = ScanNumber(scanbuf);
if(val<5) flowcontrol=val;
else {
SendRes(ResERROR);
return;
}
break;
}
case '\0':
// end of string
SendRes(ResERROR);
return;
default:
LOG_MSG("Modem: Unhandled command: &%c%d",cmdchar,ScanNumber(scanbuf));
break;
}
break;
}
case '\\': { // \ escaped commands
char cmdchar = GetChar(scanbuf);
switch(cmdchar) {
case 'N':
// error correction stuff - not emulated
if (ScanNumber(scanbuf) > 5) {
SendRes(ResERROR);
return;
}
break;
case '\0':
// end of string
SendRes(ResERROR);
return;
default:
LOG_MSG("Modem: Unhandled command: \\%c%d",cmdchar, ScanNumber(scanbuf));
break;
}
break;
}
case '\0':
SendRes(ResOK);
return;
default:
LOG_MSG("Modem: Unhandled command: %c%d",chr,ScanNumber(scanbuf));
break;
}
}
}
void CSerialModem::TelnetEmulation(Bit8u * data, Bitu size) {
Bitu i;
@ -631,13 +654,6 @@ void CSerialModem::Timer2(void) {
Bit8u txval;
Bitu txbuffersize =0;
// check for bytes to be sent to port
if(CSerial::CanReceiveByte())
if(rqueue->inuse() && (CSerial::getRTS()||(flowcontrol!=3))) {
Bit8u rbyte = rqueue->getb();
//LOG_MSG("Modem: sending byte %2x back to UART3",rbyte);
CSerial::receiveByte(rbyte);
}
// Check for eventual break command
if (!commandmode) cmdpause++;
// Handle incoming data from serial port, read as much as available
@ -684,8 +700,10 @@ void CSerialModem::Timer2(void) {
if (clientsocket && sendbyte && txbuffersize) {
// down here it saves a lot of network traffic
clientsocket->SendArray(tmpbuf,txbuffersize);
//TODO error testing
if(!clientsocket->SendArray(tmpbuf,txbuffersize)) {
SendRes(ResNOCARRIER);
EnterIdleState();
}
}
// Handle incoming to the serial port
if(!commandmode && clientsocket && rqueue->left()) {
@ -695,7 +713,6 @@ void CSerialModem::Timer2(void) {
SendRes(ResNOCARRIER);
EnterIdleState();
} else if(usesize) {
// LOG_MSG("rcv:%d", result);
// Filter telnet commands
if(telnetmode) TelnetEmulation(tmpbuf, usesize);
else rqueue->adds(tmpbuf,usesize);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: softmodem.h,v 1.10 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: softmodem.h,v 1.12 2009/10/04 20:57:40 h-a-l-9000 Exp $ */
#ifndef DOSBOX_SERIALMODEM_H
#define DOSBOX_SERIALMODEM_H
@ -92,7 +92,7 @@ public:
static Bits lcount=0;
if (lcount<1000) {
lcount++;
LOG_MSG("MODEM: FIFO Overflow! (adds len %d)",_len);
LOG_MSG("MODEM: FIFO Overflow! (adds len %u)",_len);
}
return;
}
@ -102,7 +102,7 @@ public:
used+=_len;
while (_len--) {
if (where>=size) where-=size;
//LOG_MSG("+%x",*_str);
//LOG_MSG("+'%x'",*_str);
data[where++]=*_str++;
}
}
@ -172,6 +172,7 @@ public:
bool Dial(char * host);
void AcceptIncomingCall(void);
Bitu ScanNumber(char * & scan);
char GetChar(char * & scan);
void DoCommand();

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_draw.cpp,v 1.109 2009/06/29 18:43:33 c2woody Exp $ */
/* $Id: vga_draw.cpp,v 1.111 2009/09/10 17:44:57 h-a-l-9000 Exp $ */
#include <string.h>
#include <math.h>
@ -344,11 +344,24 @@ static Bit8u * VGA_Draw_LIN32_Line_HWMouse(Bitu vidstart, Bitu /*line*/) {
}
}
static const Bit8u* VGA_Text_Memwrap(Bitu vidstart) {
vidstart &= vga.draw.linear_mask;
Bitu line_end = 2 * vga.draw.blocks;
if (GCC_UNLIKELY((vidstart + line_end) > vga.draw.linear_mask)) {
// wrapping in this line
Bitu break_pos = (vga.draw.linear_mask - vidstart) + 1;
// need a temporary storage - TempLine/2 is ok for a bit more than 132 columns
memcpy(&TempLine[sizeof(TempLine)/2], &vga.tandy.draw_base[vidstart], break_pos);
memcpy(&TempLine[sizeof(TempLine)/2 + break_pos],&vga.tandy.draw_base[0], line_end - break_pos);
return &TempLine[sizeof(TempLine)/2];
} else return &vga.tandy.draw_base[vidstart];
}
static Bit32u FontMask[2]={0xffffffff,0x0};
static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart, Bitu line) {
Bits font_addr;
Bit32u * draw=(Bit32u *)TempLine;
const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
Bitu chr=vidmem[cx*2];
Bitu col=vidmem[cx*2+1];
@ -376,7 +389,7 @@ skip_cursor:
static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) {
Bits font_addr;
Bit32u * draw=(Bit32u *)TempLine;
const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
Bitu chr=vidmem[cx*2];
@ -415,8 +428,16 @@ static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) {
if (line<vga.draw.cursor.sline) goto skip_cursor;
if (line>vga.draw.cursor.eline) goto skip_cursor;
draw=(Bit32u *)&TempLine[font_addr*8];
Bit32u att=TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf];
*draw++=att;*draw++=att;
Bit8u attr = vga.tandy.draw_base[vga.draw.cursor.address+1];
Bit32u cg;
if (attr&0x8) {
cg = TXT_FG_Table[0xf];
} else if ((attr&0x77)==0x70) {
cg = TXT_FG_Table[0x0];
} else {
cg = TXT_FG_Table[0x7];
}
*draw++=cg;*draw++=cg;
}
skip_cursor:
return TempLine;
@ -425,7 +446,7 @@ skip_cursor:
static Bit8u * VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) {
Bits font_addr;
Bit16u * draw=(Bit16u *)TempLine;
const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
Bitu chr=vidmem[cx*2];
Bitu col=vidmem[cx*2+1];
@ -467,7 +488,7 @@ static Bit8u * VGA_TEXT_Draw_Line_9(Bitu vidstart, Bitu line) {
bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line;
Bit8u pel_pan=(Bit8u)vga.draw.panning;
if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0;
const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
Bit8u chr=vidmem[0];
Bit8u col=vidmem[1];
Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
@ -526,7 +547,7 @@ static Bit8u * VGA_TEXT_Xlat16_Draw_Line_9(Bitu vidstart, Bitu line) {
bool underline=(Bitu)(vga.crtc.underline_location&0x1f)==line;
Bit8u pel_pan=(Bit8u)vga.draw.panning;
if ((vga.attr.mode_control&0x20) && (vga.draw.lines_done>=vga.draw.split_line)) pel_pan=0;
const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
const Bit8u* vidmem = VGA_Text_Memwrap(vidstart);
Bit8u chr=vidmem[0];
Bit8u col=vidmem[1];
Bit8u font=(vga.draw.font_tables[(col >> 3)&1][chr*32+line])<<pel_pan;
@ -809,14 +830,16 @@ static void VGA_VerticalTimer(Bitu /*val*/) {
#endif
break;
case M_TEXT:
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) vga.draw.byte_panning_shift = 2;
else vga.draw.byte_panning_shift = 0;
if ((IS_VGA_ARCH) && (svgaCard==SVGA_None)) vga.draw.address = vga.config.real_start * 2;
else vga.draw.address = vga.config.display_start * 2;
vga.draw.address += vga.draw.bytes_skip*vga.draw.byte_panning_shift;
vga.draw.byte_panning_shift = 2;
vga.draw.address += vga.draw.bytes_skip;
// fall-through
case M_TANDY_TEXT:
case M_HERC_TEXT:
if (machine==MCH_HERC) vga.draw.linear_mask = 0xfff; // 1 page
else if (IS_EGAVGA_ARCH) vga.draw.linear_mask = 0x7fff; // 8 pages
else vga.draw.linear_mask = 0x3fff; // CGA, Tandy 4 pages
vga.draw.cursor.address=vga.config.cursor_start*2;
vga.draw.address *= 2;
vga.draw.cursor.count++;
/* check for blinking and blinking change delay */
FontMask[1]=(vga.draw.blinking & (vga.draw.cursor.count >> 4)) ?

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_memory.cpp,v 1.52 2009/03/22 21:04:41 c2woody Exp $ */
/* $Id: vga_memory.cpp,v 1.53 2009/07/04 21:23:35 qbix79 Exp $ */
#include <stdlib.h>
#include <string.h>
@ -114,6 +114,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) {
break;
case 0x03:
// Write Mode 3: In this mode, the data in the Set/Reset field is used as if the Enable Set/Reset field were set to 1111b. Then the host data is first rotated as per the Rotate Count field, then logical ANDed with the value of the Bit Mask field. The resulting value is used on the data obtained from the Set/Reset field in the same way that the Bit Mask field would ordinarily be used. to select which bits come from the expansion of the Set/Reset field and which come from the latch register. Finally, only the bit planes enabled by the Memory Plane Write Enable field are written to memory.
val=((val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)));
full=RasterOp(vga.config.full_set_reset,ExpandTable[val] & vga.config.full_bit_mask);
break;
default:

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_other.cpp,v 1.27 2009/06/29 18:43:33 c2woody Exp $ */
/* $Id: vga_other.cpp,v 1.28 2009/07/11 10:25:24 c2woody Exp $ */
#include <string.h>
#include <math.h>
@ -68,7 +68,8 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
vga.other.vsyncp=(Bit8u)val;
break;
case 0x09: //Max scanline
if (vga.other.max_scanline ^ val) VGA_StartResize();
val &= 0x1f; // VGADOC says bit 0-3 but the MC6845 datasheet says bit 0-4
if (vga.other.max_scanline ^ val) VGA_StartResize();
vga.other.max_scanline=(Bit8u)val;
break;
case 0x0A: /* Cursor Start Register */
@ -522,6 +523,7 @@ void VGA_SetupOther(void) {
Bitu i;
memset( &vga.tandy, 0, sizeof( vga.tandy ));
vga.attr.enabled = true;
vga.config.bytes_skip=0;
//Initialize values common for most machines, can be overwritten
vga.tandy.draw_base = vga.mem.linear;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: bios_disk.cpp,v 1.38 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: bios_disk.cpp,v 1.40 2009/08/23 17:24:54 c2woody Exp $ */
#include "dosbox.h"
#include "callback.h"
@ -196,7 +196,7 @@ imageDisk::imageDisk(FILE *imgFile, Bit8u *imgName, Bit32u imgSizeK, bool isHard
active = false;
hardDrive = isHardDisk;
if(!isHardDisk) {
Bitu i=0;
Bit8u i=0;
bool founddisk = false;
while (DiskGeometryList[i].ksize!=0x0) {
if ((DiskGeometryList[i].ksize==imgSizeK) ||
@ -309,6 +309,9 @@ static Bitu INT13_DiskHandler(void) {
if(imageDiskList[i]) any_images=true;
}
// unconditionally enable the interrupt flag
CALLBACK_SIF(true);
//drivenum = 0;
//LOG_MSG("INT13: Function %x called on drive %x (dos drive %d)", reg_ah, reg_dl, drivenum);
switch(reg_ah) {
@ -349,12 +352,15 @@ static Bitu INT13_DiskHandler(void) {
CALLBACK_SCF(true);
return CBRET_NONE;
}
if(!any_images && (reg_dh == 0)) { // Inherit the Earth cdrom (uses it as disk test)
reg_ah = 0;
CALLBACK_SCF(false);
return CBRET_NONE;
if (!any_images) {
// Inherit the Earth cdrom (uses it as disk test)
if (((reg_dl&0x80)==0x80) && (reg_dh==0) && ((reg_cl&0x3f)==1)) {
reg_ah = 0;
CALLBACK_SCF(false);
return CBRET_NONE;
}
}
if(driveInactive(drivenum)) {
if (driveInactive(drivenum)) {
reg_ah = 0xff;
CALLBACK_SCF(true);
return CBRET_NONE;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10.cpp,v 1.55 2009/04/11 07:58:39 qbix79 Exp $ */
/* $Id: int10.cpp,v 1.56 2009/09/06 19:25:34 c2woody Exp $ */
#include "dosbox.h"
#include "mem.h"
@ -329,11 +329,42 @@ graphics_chars:
case 0x20: /* Set alternate printscreen */
break;
case 0x30: /* Select vertical resolution */
if (!IS_VGA_ARCH) break;
LOG(LOG_INT10,LOG_ERROR)("Function 12:Call %2X not handled",reg_bl);
if (reg_al>2) reg_al=0; //invalid subfunction
else reg_al=0x12; //fake a success call
break;
{
if (!IS_VGA_ARCH) break;
LOG(LOG_INT10,LOG_WARN)("Function 12:Call %2X (select vertical resolution)",reg_bl);
if (svgaCard != SVGA_None) {
if (reg_al > 2) {
reg_al=0; // invalid subfunction
break;
}
}
Bit8u modeset_ctl = real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
Bit8u video_switches = real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES)&0xf0;
switch(reg_al) {
case 0: // 200
modeset_ctl &= 0xef;
modeset_ctl |= 0x80;
video_switches |= 8; // ega normal/cga emulation
break;
case 1: // 350
modeset_ctl &= 0x6f;
video_switches |= 9; // ega enhanced
break;
case 2: // 400
modeset_ctl &= 0x6f;
modeset_ctl |= 0x10; // use 400-line mode at next mode set
video_switches |= 9; // ega enhanced
break;
default:
modeset_ctl &= 0xef;
video_switches |= 8; // ega normal/cga emulation
break;
}
real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,modeset_ctl);
real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,video_switches);
reg_al=0x12; // success
break;
}
case 0x31: /* Palette loading on modeset */
{
if (!IS_VGA_ARCH) break;

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10.h,v 1.39 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: int10.h,v 1.42 2009/09/06 19:25:34 c2woody Exp $ */
#include "vga.h"
@ -95,14 +95,14 @@
#define VGAMEM_MTEXT 0xB000
#define BIOS_NCOLS Bit16u ncols=real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS);
#define BIOS_NROWS Bit16u nrows=real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
#define BIOS_NROWS Bit16u nrows=(Bit16u)real_readb(BIOSMEM_SEG,BIOSMEM_NB_ROWS)+1;
extern Bit8u int10_font_08[256 * 8];
extern Bit8u int10_font_14[256 * 14];
extern Bit8u int10_font_16[256 * 16];
struct VideoModeBlock {
Bitu mode;
Bit16u mode;
VGAModes type;
Bitu swidth, sheight;
Bitu twidth, theight;
@ -137,9 +137,9 @@ typedef struct {
Bit16u pmode_interface_start;
Bit16u pmode_interface_window;
Bit16u pmode_interface_palette;
Bitu used;
Bit16u used;
} rom;
Bitu vesa_setmode;
Bit16u vesa_setmode;
bool vesa_nolfb;
bool vesa_oldvbe;
} Int10Data;
@ -154,7 +154,7 @@ static Bit8u CURSOR_POS_ROW(Bit8u page) {
return real_readb(BIOSMEM_SEG,BIOSMEM_CURSOR_POS+page*2+1);
}
bool INT10_SetVideoMode(Bitu mode);
bool INT10_SetVideoMode(Bit16u mode);
void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page);
@ -175,6 +175,7 @@ void INT10_GetPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u * color);
/* Font Stuff */
void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height);
void INT10_ReloadFont(void);
/* Palette Group */
void INT10_SetBackgroundBorder(Bit8u val);
@ -230,4 +231,5 @@ bool INT10_VideoState_Save(Bitu state,RealPt buffer);
bool INT10_VideoState_Restore(Bitu state,RealPt buffer);
/* Video Parameter Tables */
Bitu INT10_SetupVideoParameterTable(PhysPt basepos);
Bit16u INT10_SetupVideoParameterTable(PhysPt basepos);
void INT10_SetupBasicVideoParameterTable(void);

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_char.cpp,v 1.58 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: int10_char.cpp,v 1.59 2009/07/11 10:25:25 c2woody Exp $ */
/* Character displaying moving functions */
@ -272,12 +272,19 @@ filling:
void INT10_SetActivePage(Bit8u page) {
Bit16u mem_address;
if (page>7) LOG(LOG_INT10,LOG_ERROR)("INT10_SetActivePage page %d",page);
if (IS_EGAVGA_ARCH && (svgaCard==SVGA_S3Trio)) page &= 7;
mem_address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE);
/* Write the new page start */
real_writew(BIOSMEM_SEG,BIOSMEM_CURRENT_START,mem_address);
if (IS_EGAVGA_ARCH && CurMode->mode<0x8) mem_address>>=1;
if (IS_EGAVGA_ARCH) {
if (CurMode->mode<8) mem_address>>=1;
// rare alternative: if (CurMode->type==M_TEXT) mem_address>>=1;
} else {
mem_address>>=1;
}
/* Write the new start address in vgahardware */
Bit16u base=real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS);
IO_Write(base,0x0c);
@ -587,7 +594,7 @@ static void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr,Bit8u pag
if(cur_row==nrows) {
//Fill with black on non-text modes and with 0x7 on textmode
Bit8u fill = (CurMode->type == M_TEXT)?0x7:0;
INT10_ScrollWindow(0,0,nrows-1,ncols-1,-1,fill,page);
INT10_ScrollWindow(0,0,(Bit8u)(nrows-1),ncols-1,-1,fill,page);
cur_row--;
}
// Set the cursor for the page

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_memory.cpp,v 1.28 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: int10_memory.cpp,v 1.30 2009/09/06 19:25:34 c2woody Exp $ */
#include "dosbox.h"
#include "mem.h"
@ -47,7 +47,7 @@ static Bit16u map_offset[8]={
};
void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu height) {
PhysPt ftwhere=PhysMake(0xa000,map_offset[map & 0x7]+offset*32);
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
@ -58,7 +58,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,old_6); //odd/even and b8000 adressing
if (IS_VGA_ARCH) IO_Write(0x3cf,(Bit8u)old_6); //odd/even and b8000 adressing
else IO_Write(0x3cf,0x0e);
/* Reload tables and registers with new values based on this height */
if (reload) {
@ -69,11 +69,26 @@ void INT10_LoadFont(PhysPt font,bool reload,Bitu count,Bitu offset,Bitu map,Bitu
//Vertical display end bios says, but should stay the same?
//Rows setting in bios segment
real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,(CurMode->sheight/height)-1);
real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,height);
real_writeb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit8u)height);
//TODO Reprogram cursor size?
}
}
void INT10_ReloadFont(void) {
switch(CurMode->cheight) {
case 8:
INT10_LoadFont(Real2Phys(int10.rom.font_8_first),true,256,0,0,8);
break;
case 14:
INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14);
break;
case 16:
default:
INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16);
break;
}
}
void INT10_SetupRomMemory(void) {
/* This should fill up certain structures inside the Video Bios Rom Area */
@ -181,6 +196,8 @@ void INT10_SetupRomMemory(void) {
phys_writed(rom_base+int10.rom.used,0); int10.rom.used+=4;
}
INT10_SetupBasicVideoParameterTable();
if (IS_TANDY_ARCH) {
RealSetVec(0x44,int10.rom.font_8_first);
}
@ -216,7 +233,7 @@ void INT10_SetupRomMemoryChecksum(void) {
Bitu last_rombyte = 32*1024 - 1; //32 KB romsize
for (Bitu i = 0;i < last_rombyte;i++)
sum += phys_readb(rom_base + i); //OVERFLOW IS OKAY
sum = 256 - sum;
sum = (Bit8u)((256 - (Bitu)sum)&0xff);
phys_writeb(rom_base + last_rombyte,sum);
}
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_modes.cpp,v 1.86 2009/06/28 14:56:14 c2woody Exp $ */
/* $Id: int10_modes.cpp,v 1.90 2009/09/06 19:25:34 c2woody Exp $ */
#include <string.h>
@ -124,6 +124,22 @@ VideoModeBlock ModeList_VGA[]={
{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 },
};
VideoModeBlock ModeList_VGA_Text_200lines[]={
/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */
{ 0x000 ,M_TEXT ,320 ,200 ,40 ,25 ,8 , 8 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
{ 0x001 ,M_TEXT ,320 ,200 ,40 ,25 ,8 , 8 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE},
{ 0x002 ,M_TEXT ,640 ,200 ,80 ,25 ,8 , 8 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE },
{ 0x003 ,M_TEXT ,640 ,200 ,80 ,25 ,8 , 8 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }
};
VideoModeBlock ModeList_VGA_Text_350lines[]={
/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */
{ 0x000 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK },
{ 0x001 ,M_TEXT ,320 ,350 ,40 ,25 ,8 ,14 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,350 ,_EGA_HALF_CLOCK },
{ 0x002 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 },
{ 0x003 ,M_TEXT ,640 ,350 ,80 ,25 ,8 ,14 ,8 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,350 ,0 }
};
VideoModeBlock ModeList_VGA_Tseng[]={
/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */
{ 0x000 ,M_TEXT ,360 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK },
@ -232,7 +248,7 @@ VideoModeBlock ModeList_OTHER[]={
};
VideoModeBlock Hercules_Mode=
{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,14 ,4 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 };
{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,14 ,1 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 };
static Bit8u text_palette[64][3]=
{
@ -340,7 +356,7 @@ static Bit8u vga_palette[256][3]=
};
VideoModeBlock * CurMode;
static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) {
static bool SetCurMode(VideoModeBlock modeblock[],Bit16u mode) {
Bitu i=0;
while (modeblock[i].mode!=0xffff) {
if (modeblock[i].mode!=mode) i++;
@ -394,7 +410,6 @@ static void FinishSetMode(bool clearmem) {
real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,(Bit16u)CurMode->cheight);
real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem?0:0x80)));
real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09);
real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f);
// this is an index into the dcc table:
if (IS_VGA_ARCH) real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x0b);
@ -418,7 +433,7 @@ static void FinishSetMode(bool clearmem) {
Mouse_NewVideoMode();
}
bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
bool INT10_SetVideoMode_OTHER(Bit16u mode,bool clearmem) {
switch (machine) {
case MCH_CGA:
if (mode>6) return false;
@ -569,12 +584,44 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select);
break;
}
RealPt vparams = RealGetVec(0x1d);
if ((vparams != RealMake(0xf000,0xf0a4)) && (mode < 8)) {
// load crtc parameters from video params table
Bit16u crtc_block_index = 0;
if (mode < 2) crtc_block_index = 0;
else if (mode < 4) crtc_block_index = 1;
else if (mode < 7) crtc_block_index = 2;
else {
if (machine==MCH_PCJR) {
if (mode < 9) crtc_block_index = 2;
else crtc_block_index = 3;
} else {
if (mode == 7) crtc_block_index = 3;
}
}
// init CRTC registers
for (Bit16u i = 0; i < 16; i++)
IO_WriteW(crtc_base, i | (real_readb(RealSeg(vparams),
RealOff(vparams) + i + crtc_block_index*16) << 8));
if (machine==MCH_CGA) {
// mode register
IO_WriteB(crtc_base + 4, real_readb(RealSeg(vparams),
RealOff(vparams) + 4*16 + 24 + mode));
}
if (machine==MCH_TANDY) {
E_Exit("INT10 modeset: video parameter table changed");
}
}
FinishSetMode(clearmem);
return true;
}
bool INT10_SetVideoMode(Bitu mode) {
bool INT10_SetVideoMode(Bit16u mode) {
bool clearmem=true;Bitu i;
if (mode>=0x100) {
if ((mode & 0x4000) && int10.vesa_nolfb) return false;
@ -588,7 +635,11 @@ bool INT10_SetVideoMode(Bitu mode) {
int10.vesa_setmode=0xffff;
LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode);
if (!IS_EGAVGA_ARCH) return INT10_SetVideoMode_OTHER(mode,clearmem);
Bit8u modeset_ctl,video_ctl,vga_switches;
/* First read mode setup settings from bios area */
// Bit8u video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
// Bit8u vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES);
Bit8u modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
if (IS_VGA_ARCH) {
if (svga.accepts_mode) {
@ -615,6 +666,18 @@ bool INT10_SetVideoMode(Bitu mode) {
return false;
}
}
// check for scanline backwards compatibility (VESA text modes??)
if (CurMode->type==M_TEXT) {
if ((modeset_ctl&0x90)==0x80) { // 200 lines emulation
if (CurMode->mode <= 3) {
CurMode = &ModeList_VGA_Text_200lines[CurMode->mode];
}
} else if ((modeset_ctl&0x90)==0x00) { // 350 lines emulation
if (CurMode->mode <= 3) {
CurMode = &ModeList_VGA_Text_350lines[CurMode->mode];
}
}
}
} else {
if (!SetCurMode(ModeList_EGA,mode)){
LOG(LOG_INT10,LOG_ERROR)("EGA:Trying to set illegal mode %X",mode);
@ -622,11 +685,6 @@ bool INT10_SetVideoMode(Bitu mode) {
}
}
/* First read mode setup settings from bios area */
video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL);
vga_switches=real_readb(BIOSMEM_SEG,BIOSMEM_SWITCHES);
modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL);
/* Setup the VGA to the correct mode */
Bit16u crtc_base;
@ -643,11 +701,14 @@ bool INT10_SetVideoMode(Bitu mode) {
/* Setup MISC Output Register */
Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1);
if ((CurMode->type==M_TEXT) && (CurMode->cwidth==9)) {
// 28MHz (16MHz EGA) clock for 9-pixel wide chars
misc_output|=0x4;
}
switch (CurMode->vdispend) {
case 400:
misc_output|=0x60;
if (CurMode->type==M_TEXT) // && (CurMode->pstart==0xB8000))
misc_output|=0x4;
break;
case 480:
misc_output|=0xe0;
@ -663,12 +724,13 @@ bool INT10_SetVideoMode(Bitu mode) {
/* Program Sequencer */
Bit8u seq_data[SEQ_REGS];
memset(seq_data,0,SEQ_REGS);
if (CurMode->cwidth==8) seq_data[1]|=1; //8 dot fonts by default
seq_data[1]|=0x01; //8 dot fonts by default
if (CurMode->special & _EGA_HALF_CLOCK) seq_data[1]|=0x08; //Check for half clock
if ((machine==MCH_EGA) && (CurMode->special & _EGA_HALF_CLOCK)) seq_data[1]|=0x02;
seq_data[4]|=0x02; //More than 64kb
switch (CurMode->type) {
case M_TEXT:
if (CurMode->cwidth==9) seq_data[1] &= ~1;
seq_data[2]|=0x3; //Enable plane 0 and 1
seq_data[4]|=0x01; //Alpanumeric
if (IS_VGA_ARCH) seq_data[4]|=0x04; //odd/even enabled
@ -1035,12 +1097,12 @@ bool INT10_SetVideoMode(Bitu mode) {
for (Bit8u ct=0;ct<16;ct++) att_data[ct]=ct;
break;
case M_TEXT:
if (machine==MCH_EGA) {
att_data[0x13]=0x00;
att_data[0x10]=0x08; //8 Bit characters
} else {
if (CurMode->cwidth==9) {
att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode
att_data[0x10]=0x0C; //Color Text with blinking
att_data[0x10]=0x0C; //Color Text with blinking, 9 Bit characters
} else {
att_data[0x13]=0x00;
att_data[0x10]=0x08; //Color Text with blinking, 8 Bit characters
}
real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30);
att_text16:
@ -1308,8 +1370,7 @@ dac_text16:
/* Load text mode font */
if (CurMode->type==M_TEXT) {
if (IS_VGA_ARCH) INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16);
else INT10_LoadFont(Real2Phys(int10.rom.font_14),true,256,0,0,14);
INT10_ReloadFont();
}
return true;
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_vesa.cpp,v 1.39 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: int10_vesa.cpp,v 1.40 2009/07/31 15:36:01 c2woody Exp $ */
#include <string.h>
#include <stddef.h>
@ -271,7 +271,7 @@ Bit8u VESA_SetSVGAMode(Bit16u mode) {
Bit8u VESA_GetSVGAMode(Bit16u & mode) {
if (int10.vesa_setmode!=0xffff) mode=int10.vesa_setmode;
else mode=(Bit16u)(CurMode->mode);
else mode=CurMode->mode;
return 0x00;
}
@ -297,7 +297,7 @@ Bit8u VESA_SetPalette(PhysPt data,Bitu index,Bitu count) {
Bit8u r,g,b;
if (index>255) return 0x1;
if (index+count>256) return 0x1;
IO_Write(0x3c8,index);
IO_Write(0x3c8,(Bit8u)index);
while (count) {
b = mem_readb(data++);
g = mem_readb(data++);
@ -316,7 +316,7 @@ Bit8u VESA_GetPalette(PhysPt data,Bitu index,Bitu count) {
Bit8u r,g,b;
if (index>255) return 0x1;
if (index+count>256) return 0x1;
IO_Write(0x3c7,index);
IO_Write(0x3c7,(Bit8u)index);
while (count) {
r = IO_Read(0x3c9);
g = IO_Read(0x3c9);
@ -428,8 +428,8 @@ Bit8u VESA_GetDisplayStart(Bit16u & x,Bit16u & y) {
Bitu pan=vga.config.pel_panning;
switch (CurMode->type) {
case M_LIN8:
y=times;
x=rem+pan;
y=(Bit16u)times;
x=(Bit16u)(rem+pan);
break;
default:
return 0x1;
@ -503,17 +503,17 @@ void INT10_SetupVESA(void) {
int10.rom.pmode_interface_window = int10.rom.used - RealOff( int10.rom.pmode_interface );
phys_writew( Real2Phys(int10.rom.pmode_interface) + 0, int10.rom.pmode_interface_window );
callback.pmWindow=CALLBACK_Allocate();
int10.rom.used += CALLBACK_Setup(callback.pmWindow, VESA_PMSetWindow, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Window");
int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmWindow, VESA_PMSetWindow, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Window");
/* PM Set start call */
int10.rom.pmode_interface_start = int10.rom.used - RealOff( int10.rom.pmode_interface );
phys_writew( Real2Phys(int10.rom.pmode_interface) + 2, int10.rom.pmode_interface_start);
callback.pmStart=CALLBACK_Allocate();
int10.rom.used += CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start");
int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmStart, VESA_PMSetStart, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Start");
/* PM Set Palette call */
int10.rom.pmode_interface_palette = int10.rom.used - RealOff( int10.rom.pmode_interface );
phys_writew( Real2Phys(int10.rom.pmode_interface) + 4, int10.rom.pmode_interface_palette);
callback.pmPalette=CALLBACK_Allocate();
int10.rom.used += CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Palette");
int10.rom.used += (Bit16u)CALLBACK_Setup(callback.pmPalette, VESA_PMSetPalette, CB_RETN, PhysMake(0xc000,int10.rom.used), "VESA PM Set Palette");
/* Finalize the size and clear the required ports pointer */
phys_writew( Real2Phys(int10.rom.pmode_interface) + 6, 0);
int10.rom.pmode_interface_size=int10.rom.used - RealOff( int10.rom.pmode_interface );

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_vptable.cpp,v 1.4 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: int10_vptable.cpp,v 1.6 2009/08/01 13:39:48 c2woody Exp $ */
#include "dosbox.h"
#include "mem.h"
@ -24,6 +24,77 @@
#include "int10.h"
const Bit8u vparams[] = {
// 40x25 mode 0 and 1 crtc registers
0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// 80x25 mode 2 and 3 crtc registers
0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// graphics modes 4, 5 and 6
0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x06, 0x07, 0,0,0,0,
// mode 7 MDA text
0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c, 0,0,0,0,
// buffer length words 2048, 4096, 16384, 16384
0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40,
// columns
40, 40, 80, 80, 40, 40, 80, 80,
// CGA mode register
0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29
};
const Bit8u vparams_pcjr[] = {
// 40x25 mode 0 and 1 crtc registers
0x38, 0x28, 0x2c, 0x06, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// 80x25 mode 2 and 3 crtc registers
0x71, 0x50, 0x5a, 0x0c, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// graphics modes 4, 5, 6, 8
0x38, 0x28, 0x2b, 0x06, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x26, 0x07, 0,0,0,0,
// other graphics modes
0x71, 0x50, 0x56, 0x0c, 0x3f, 0x06, 0x32, 0x38, 0x02, 0x03, 0x26, 0x07, 0,0,0,0,
// buffer length words 2048, 4096, 16384, 16384
0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40,
// columns
40, 40, 80, 80, 40, 40, 80, 80,
// CGA mode register
0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29
};
const Bit8u vparams_tandy[] = {
// 40x25 mode 0 and 1 crtc registers
0x38, 0x28, 0x2c, 0x08, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// 80x25 mode 2 and 3 crtc registers
0x71, 0x50, 0x58, 0x10, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// graphics modes 4, 5 and 6
0x38, 0x28, 0x2c, 0x08, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x06, 0x07, 0,0,0,0,
// graphics mode 7
0x71, 0x50, 0x58, 0x10, 0x3f, 0x06, 0x32, 0x38, 0x02, 0x03, 0x06, 0x07, 0,0,0,0,
// buffer length words 2048, 4096, 16384, 16384
0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40,
// columns
40, 40, 80, 80, 40, 40, 80, 80,
// CGA mode register
0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29
};
const Bit8u vparams_tandy_td[] = {
// 40x25 mode 0 and 1 crtc registers
0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// 80x25 mode 2 and 3 crtc registers
0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c, 0x02, 0x07, 0x06, 0x07, 0,0,0,0,
// graphics modes 4, 5 and 6
0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70, 0x02, 0x01, 0x06, 0x07, 0,0,0,0,
// mode 7 MDA text
0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19, 0x02, 0x0d, 0x0b, 0x0c, 0,0,0,0,
// ?? mode 2 and 3 crtc registers
0x71, 0x50, 0x5a, 0x0a, 0x3f, 0x06, 0x32, 0x38, 0x02, 0x03, 0x06, 0x07, 0,0,0,0,
// buffer length words 2048, 4096, 16384, 16384
0x00, 0x08, 0x00, 0x10, 0x00, 0x40, 0x00, 0x40,
// columns
40, 40, 80, 80, 40, 40, 80, 80,
// CGA mode register
0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29
};
static Bit8u video_parameter_table_vga[0x40*0x1d]={
// video parameter table for mode 0 (cga emulation)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -447,7 +518,7 @@ static Bit8u video_parameter_table_ega[0x40*0x17]={
};
Bitu INT10_SetupVideoParameterTable(PhysPt basepos) {
Bit16u INT10_SetupVideoParameterTable(PhysPt basepos) {
if (IS_VGA_ARCH) {
for (Bitu i=0;i<0x40*0x1d;i++) {
phys_writeb(basepos+i,video_parameter_table_vga[i]);
@ -461,6 +532,28 @@ Bitu INT10_SetupVideoParameterTable(PhysPt basepos) {
}
}
void INT10_SetupBasicVideoParameterTable(void) {
/* video parameter table at F000:F0A4 */
RealSetVec(0x1d,RealMake(0xF000, 0xF0A4));
switch (machine) {
case MCH_TANDY:
for (Bit16u i = 0; i < sizeof(vparams_tandy); i++) {
phys_writeb(0xFF0A4+i,vparams_tandy[i]);
}
break;
case MCH_PCJR:
for (Bit16u i = 0; i < sizeof(vparams_pcjr); i++) {
phys_writeb(0xFF0A4+i,vparams_pcjr[i]);
}
break;
default:
for (Bit16u i = 0; i < sizeof(vparams); i++) {
phys_writeb(0xFF0A4+i,vparams[i]);
}
break;
}
}
#if 0
void INT10_GenerateVideoParameterTable(void) {
if (!IS_VGA_ARCH) E_Exit("Be sure that all graphics registers are readable!");

View File

@ -1566,21 +1566,12 @@ int main(int argc, char *argv[])
atexit(SDL_Quit);
#ifdef HW_RVL
screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "Couldn't set 640x480x16 video mode: %s\n", SDL_GetError());
exit(1);
}
printf("GUI:: color depth %i\n",screen->format->BitsPerPixel);
#else
screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
if (screen == NULL) {
fprintf(stderr, "Couldn't set 640x480x32 video mode: %s\n", SDL_GetError());
exit(1);
}
printf("GUI:: color depth %i\n",screen->format->BitsPerPixel);
#endif
SDL_EnableUNICODE(true);
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY,SDL_DEFAULT_REPEAT_INTERVAL);

View File

@ -4,7 +4,7 @@
#define C_DEBUG 0
/* Define to 1 to enable screenshots, requires libpng */
#define C_SSHOT 0
#define C_SSHOT 1
/* Define to 1 to use opengl display output support */
#define C_OPENGL 1

View File

@ -28,7 +28,7 @@
#define C_DYNREC 0
/* Enable memory function inlining in */
#define C_CORE_INLINE 0
#define C_CORE_INLINE 1
/* Enable the FPU module, still only for beta testing */
#define C_FPU 1

View File

@ -20,22 +20,27 @@ void WiiInit()
void CreateAppPath(char origpath[])
{
char path[1024];
strncpy(path, origpath, 1024); // make a copy
char * path = strdup(origpath); // make a copy so we don't mess up original
char * loc;
int pos = -1;
if(!path)
return;
loc = strrchr(path,'/');
char * loc = strrchr(path,'/');
if (loc != NULL)
*loc = 0; // strip file name
loc = strchr(path,'/'); // looking for / from fat:/ (or sd:/)
if (loc != NULL)
pos = loc - path + 1;
int pos = 0;
if(pos >= 0 && pos < 1024)
sprintf(appPath, "sd:/%s", &(path[pos]));
// replace fat:/ with sd:/
if(strncmp(path, "fat:/", 5) == 0)
{
pos++;
path[1] = 's';
path[2] = 'd';
}
strncpy(appPath, &path[pos], MAXPATHLEN);
appPath[MAXPATHLEN-1] = 0;
free(path);
}
void WiiFinished()

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell.cpp,v 1.99 2009/05/14 18:44:54 qbix79 Exp $ */
/* $Id: shell.cpp,v 1.100 2009/07/08 20:05:41 c2woody Exp $ */
#include <stdlib.h>
#include <stdarg.h>
@ -35,7 +35,7 @@
Bitu call_shellstop;
/* Larger scope so shell_del autoexec can use it to
* remove things from the environment */
Program * first_shell = 0;
Program * first_shell = 0;
static Bitu shellstop_handler(void) {
return CBRET_STOP;
@ -621,7 +621,7 @@ void SHELL_Init() {
pspmcb.SetType(0x4d);
DOS_MCB envmcb((Bit16u)(env_seg-1));
envmcb.SetPSPSeg(psp_seg); // MCB of the command shell environment
envmcb.SetSize(0x28);
envmcb.SetSize(DOS_MEM_START-env_seg);
envmcb.SetType(0x4d);
/* Setup environment */

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell_batch.cpp,v 1.35 2009/05/27 09:15:42 qbix79 Exp $ */
/* $Id: shell_batch.cpp,v 1.36 2009/07/03 19:36:56 qbix79 Exp $ */
#include <stdlib.h>
#include <string.h>
@ -32,6 +32,7 @@ BatchFile::BatchFile(DOS_Shell * host,char const * const name, char const * cons
char totalname[DOS_PATHLENGTH+4];
DOS_Canonicalize(name,totalname); // Get fullname including drive specificiation
cmd = new CommandLine(totalname,cmd_line);
filename = totalname;
//Test if file is openable
if (!DOS_OpenFile(totalname,128,&file_handle)) {
@ -49,8 +50,8 @@ BatchFile::~BatchFile() {
bool BatchFile::ReadLine(char * line) {
//Open the batchfile and seek to stored postion
if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",cmd->GetFileName());
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("ReadLine Can't open BatchFile %s",filename.c_str());
delete this;
return false;
}
@ -143,8 +144,8 @@ emptyline:
bool BatchFile::Goto(char * where) {
//Open bat file and search for the where string
if (!DOS_OpenFile(cmd->GetFileName(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",cmd->GetFileName());
if (!DOS_OpenFile(filename.c_str(),128,&file_handle)) {
LOG(LOG_MISC,LOG_ERROR)("SHELL:Goto Can't open BatchFile %s",filename.c_str());
delete this;
return false;
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell_cmds.cpp,v 1.90 2009/04/02 19:08:26 qbix79 Exp $ */
/* $Id: shell_cmds.cpp,v 1.93 2009/09/21 21:04:25 h-a-l-9000 Exp $ */
#include "dosbox.h"
#include "shell.h"
@ -404,6 +404,10 @@ void DOS_Shell::CMD_DIR(char * args) {
bool optW=ScanCMDBool(args,"W");
ScanCMDBool(args,"S");
bool optP=ScanCMDBool(args,"P");
if (ScanCMDBool(args,"WP") || ScanCMDBool(args,"PW")) {
optW=optP=true;
}
bool optB=ScanCMDBool(args,"B");
bool optAD=ScanCMDBool(args,"AD");
char * rem=ScanCMDRemain(args);
if (rem) {
@ -450,7 +454,7 @@ void DOS_Shell::CMD_DIR(char * args) {
return;
}
*(strrchr(path,'\\')+1)=0;
WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path);
if (!optB) WriteOut(MSG_Get("SHELL_CMD_DIR_INTRO"),path);
/* Command uses dta so set it to our internal dta */
RealPt save_dta=dos.dta();
@ -458,7 +462,7 @@ void DOS_Shell::CMD_DIR(char * args) {
DOS_DTA dta(dos.dta());
bool ret=DOS_FindFirst(args,0xffff & ~DOS_ATTR_VOLUME);
if (!ret) {
WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args);
if (!optB) WriteOut(MSG_Get("SHELL_CMD_FILE_NOT_FOUND"),args);
dos.dta(save_dta);
return;
}
@ -483,53 +487,62 @@ void DOS_Shell::CMD_DIR(char * args) {
Bit8u minute = (Bit8u)((time >> 5) & 0x003f);
/* output the file */
if (attr & DOS_ATTR_DIRECTORY) {
if (optW) {
WriteOut("[%s]",name);
size_t namelen = strlen(name);
if (namelen <= 14) {
for (size_t i=14-namelen;i>0;i--) WriteOut(" ");
}
} else {
WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"<DIR>",day,month,year,hour,minute);
if (optB) {
// this overrides pretty much everything
if (strcmp(".",name) && strcmp("..",name)) {
if ((attr & DOS_ATTR_DIRECTORY)||(strlen(ext)==0)) WriteOut("%s\n",name);
else WriteOut("%s.%s\n",name,ext);
}
dir_count++;
} else {
if (optW) {
WriteOut("%-16s",name);
if (attr & DOS_ATTR_DIRECTORY) {
if (optW) {
WriteOut("[%s]",name);
size_t namelen = strlen(name);
if (namelen <= 14) {
for (size_t i=14-namelen;i>0;i--) WriteOut(" ");
}
} else {
WriteOut("%-8s %-3s %-16s %02d-%02d-%04d %2d:%02d\n",name,ext,"<DIR>",day,month,year,hour,minute);
}
dir_count++;
} else {
FormatNumber(size,numformat);
WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",name,ext,numformat,day,month,year,hour,minute);
if (optW) {
WriteOut("%-16s",name);
} else {
FormatNumber(size,numformat);
WriteOut("%-8s %-3s %16s %02d-%02d-%04d %2d:%02d\n",name,ext,numformat,day,month,year,hour,minute);
}
file_count++;
byte_count+=size;
}
file_count++;
byte_count+=size;
}
if (optW) {
w_count++;
}
if(optP) {
if(!(++p_count%(22*w_size))) {
CMD_PAUSE(empty_string);
if (optW) {
w_count++;
}
if (optP) {
if (!(++p_count%(22*w_size))) {
CMD_PAUSE(empty_string);
}
}
}
} while ( (ret=DOS_FindNext()) );
if (optW) {
if (w_count%5) WriteOut("\n");
}
/* Show the summary of results */
FormatNumber(byte_count,numformat);
WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat);
Bit8u drive=dta.GetSearchDrive();
//TODO Free Space
Bitu free_space=1024*1024*100;
if (Drives[drive]) {
Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters;
Drives[drive]->AllocationInfo(&bytes_sector,&sectors_cluster,&total_clusters,&free_clusters);
free_space=bytes_sector*sectors_cluster*free_clusters;
if (!optB) {
/* Show the summary of results */
FormatNumber(byte_count,numformat);
WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_USED"),file_count,numformat);
Bit8u drive=dta.GetSearchDrive();
//TODO Free Space
Bitu free_space=1024*1024*100;
if (Drives[drive]) {
Bit16u bytes_sector;Bit8u sectors_cluster;Bit16u total_clusters;Bit16u free_clusters;
Drives[drive]->AllocationInfo(&bytes_sector,&sectors_cluster,&total_clusters,&free_clusters);
free_space=bytes_sector*sectors_cluster*free_clusters;
}
FormatNumber(free_space,numformat);
WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat);
}
FormatNumber(free_space,numformat);
WriteOut(MSG_Get("SHELL_CMD_DIR_BYTES_FREE"),dir_count,numformat);
dos.dta(save_dta);
}
@ -570,11 +583,25 @@ void DOS_Shell::CMD_COPY(char * args) {
// Concatating files go as follows: All parts except for the last bear the concat flag.
// This construction allows them to be counted (only the non concat set)
char* source_p = NULL;
char source_x[DOS_PATHLENGTH+CROSS_LEN];
while ( (source_p = StripWord(args)) && *source_p ) {
do {
char* plus = strchr(source_p,'+');
if(plus) *plus++ = 0;
sources.push_back(copysource(source_p,(plus)?true:false));
if (plus) *plus++ = 0;
safe_strncpy(source_x,source_p,CROSS_LEN);
bool has_drive_spec = false;
size_t source_x_len = strlen(source_x);
if (source_x_len>0) {
if (source_x[source_x_len-1]==':') has_drive_spec = true;
}
if (!has_drive_spec) {
if (DOS_FindFirst(source_p,0xffff & ~DOS_ATTR_VOLUME)) {
dta.GetResult(name,size,date,time,attr);
if (attr & DOS_ATTR_DIRECTORY && !strstr(source_p,"*.*"))
strcat(source_x,"\\*.*");
}
}
sources.push_back(copysource(source_x,(plus)?true:false));
source_p = plus;
} while(source_p && *source_p);
}

View File

@ -1,19 +1,21 @@
Microsoft Visual Studio Solution File, Format Version 10.00
# Visual C++ Express 2008
Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dosbox", "dosbox.vcproj", "{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Release|Win32 = Release|Win32
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
Release = Release
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Debug|Win32.ActiveCfg = Debug|Win32
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Debug|Win32.Build.0 = Debug|Win32
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Release|Win32.ActiveCfg = Release|Win32
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Release|Win32.Build.0 = Release|Win32
GlobalSection(ProjectConfiguration) = postSolution
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Debug.ActiveCfg = Debug|Win32
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Debug.Build.0 = Debug|Win32
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Release.ActiveCfg = Release|Win32
{7FCFFB9B-8629-4D51-849C-8490CECF8AB7}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

File diff suppressed because it is too large Load Diff