mirror of
https://github.com/retro100/dosbox-wii.git
synced 2025-01-12 18:29:07 +01:00
sync with official
This commit is contained in:
parent
d4f4b6ce52
commit
f0f4e75fe3
36
README
36
README
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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){}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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]) {
|
||||
|
@ -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();
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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 */
|
||||
|
@ -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(),®_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(),¶)) DOS_Terminate(true,0);
|
||||
Bit16u psp = mem_readw(SegPhys(ss)+reg_sp+2);
|
||||
if (DOS_ResizeMemory(psp,¶)) 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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
BIN
src/dosbox.ico
BIN
src/dosbox.ico
Binary file not shown.
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 82 KiB |
@ -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
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,9 @@
|
||||
|
||||
|
||||
#include <math.h>
|
||||
#ifdef HW_RVL
|
||||
#include <string.h>
|
||||
#endif
|
||||
#include <stdlib.h> // rand()
|
||||
#include "dosbox.h"
|
||||
#include "opl.h"
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
319
src/hardware/serialport/directserial.cpp
Normal file
319
src/hardware/serialport/directserial.cpp
Normal 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
|
71
src/hardware/serialport/directserial.h
Normal file
71
src/hardware/serialport/directserial.h
Normal 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
|
706
src/hardware/serialport/libserial.cpp
Normal file
706
src/hardware/serialport/libserial.cpp
Normal 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,
|
||||
¶mline, ulParmLen, &ulParmLen, 0, 0, 0);
|
||||
if ( rc != NO_ERROR)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
#endif
|
56
src/hardware/serialport/libserial.h
Normal file
56
src/hardware/serialport/libserial.h
Normal 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);
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)) ?
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 );
|
||||
|
@ -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!");
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,§ors_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,§ors_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);
|
||||
}
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user