sync with official

This commit is contained in:
dborth 2009-10-14 07:04:37 +00:00
parent 48fb8600dd
commit c19daa723d
21 changed files with 159 additions and 1722 deletions

View File

@ -1,39 +0,0 @@
noinst_HEADERS = \
bios.h \
bios_disk.h \
callback.h \
cpu.h \
cross.h \
control.h \
debug.h \
dma.h \
dos_inc.h \
dos_system.h \
dosbox.h \
fpu.h \
hardware.h \
inout.h \
joystick.h \
ipx.h \
ipxserver.h \
keyboard.h \
logging.h \
mapper.h \
mem.h \
mixer.h \
modules.h \
mouse.h \
paging.h \
pic.h \
programs.h \
render.h \
regs.h \
render.h \
serialport.h \
setup.h \
shell.h \
support.h \
timer.h \
vga.h \
video.h

View File

@ -1,7 +0,0 @@
SUBDIRS = core_full core_normal core_dyn_x86 core_dynrec
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libcpu.a
libcpu_a_SOURCES = callback.cpp cpu.cpp flags.cpp modrm.cpp modrm.h core_full.cpp instructions.h \
paging.cpp lazyflags.h core_normal.cpp core_simple.cpp core_prefetch.cpp \
core_dyn_x86.cpp core_dynrec.cpp

View File

@ -1,3 +0,0 @@
noinst_HEADERS = ea_lookup.h load.h loadwrite.h op.h optable.h save.h \
string.h support.h

View File

@ -1,3 +0,0 @@
noinst_HEADERS = helpers.h prefix_none.h prefix_66.h prefix_0f.h support.h table_ea.h \
prefix_66_0f.h string.h

View File

@ -1,10 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libdos.a
EXTRA_DIST = scsidefs.h wnaspi32.h dos_codepages.h dos_keyboard_layout_data.h
libdos_a_SOURCES = dos.cpp dos_devices.cpp dos_execute.cpp dos_files.cpp dos_ioctl.cpp dos_memory.cpp \
dos_misc.cpp dos_classes.cpp dos_programs.cpp dos_tables.cpp \
drives.cpp drives.h drive_virtual.cpp drive_local.cpp drive_cache.cpp drive_fat.cpp \
drive_iso.cpp dev_con.h dos_mscdex.cpp dos_keyboard_layout.cpp \
cdrom.h cdrom.cpp cdrom_ioctl_win32.cpp cdrom_aspi_win32.cpp cdrom_ioctl_linux.cpp cdrom_image.cpp \
cdrom_ioctl_os2.cpp

View File

@ -1,5 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libfpu.a
libfpu_a_SOURCES = fpu.cpp fpu_instructions.h \
fpu_instructions_x86.h

View File

@ -1,15 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
SUBDIRS = serialport
EXTRA_DIST = opl.cpp opl.h fmopl.c fmopl.h ymf262.h ymf262.c adlib.h dbopl.h
noinst_LIBRARIES = libhardware.a
libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \
memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \
vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \
vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp vga_s3.cpp vga_tseng.cpp vga_paradise.cpp \
cmos.cpp disney.cpp gus.cpp mpu401.cpp ipx.cpp ipxserver.cpp dbopl.cpp

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: hardware.cpp,v 1.22 2009/04/26 18:24:36 qbix79 Exp $ */
/* $Id: hardware.cpp,v 1.23 2009/10/11 18:09:22 qbix79 Exp $ */
#include <string.h>
#include <stdlib.h>
@ -161,17 +161,13 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3
#endif
#if (C_SSHOT)
static void CAPTURE_VideoEvent(bool pressed) {
if (!pressed)
return;
if (CaptureState & CAPTURE_VIDEO) {
/* Close the video */
CaptureState &= ~CAPTURE_VIDEO;
LOG_MSG("Stopped capturing video.");
static void CAPTURE_VideoHeader() {
Bit8u avi_header[AVI_HEADER_SIZE];
Bitu main_list;
Bitu header_pos=0;
Bitu save_pos=ftell(capture.video.handle);
#define AVIOUT4(_S_) memcpy(&avi_header[header_pos],_S_,4);header_pos+=4;
#define AVIOUTw(_S_) host_writew(&avi_header[header_pos], _S_);header_pos+=2;
#define AVIOUTd(_S_) host_writed(&avi_header[header_pos], _S_);header_pos+=4;
@ -288,6 +284,20 @@ static void CAPTURE_VideoEvent(bool pressed) {
fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle);
fseek(capture.video.handle, 0, SEEK_SET);
fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle);
fseek(capture.video.handle, save_pos, SEEK_SET);
}
static void CAPTURE_VideoEvent(bool pressed) {
if (!pressed)
return;
if (CaptureState & CAPTURE_VIDEO) {
/* Close the video */
CaptureState &= ~CAPTURE_VIDEO;
LOG_MSG("Stopped capturing video.");
/* Adds AVI header to the file */
CAPTURE_VideoHeader();
fclose( capture.video.handle );
free( capture.video.index );
free( capture.video.buf );
@ -547,6 +557,9 @@ skip_shot:
capture.video.audioused = 0;
}
/* Adds AVI header to the file */
CAPTURE_VideoHeader();
/* Everything went okay, set flag again for next frame */
CaptureState |= CAPTURE_VIDEO;
}

View File

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

View File

@ -1,515 +0,0 @@
/*
* 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_os2.cpp,v 1.5 2009/05/27 09:15:41 qbix79 Exp $ */
#include "dosbox.h"
#if C_DIRECTSERIAL
#if defined(OS2)
#include "serialport.h"
#include "directserial_os2.h"
#include "misc_util.h"
#include "pic.h"
// OS/2 related headers
#define INCL_DOSFILEMGR
#define INCL_DOSERRORS
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_DOSPROCESS
#include <os2.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;
rx_retry = 0;
rx_retry_max = 0;
std::string tmpstring;
if (!cmd->FindStringBegin("realport:", tmpstring, false))
{
return;
}
#if SERIAL_DEBUG
if (dbg_modemcontrol)
{
fprintf(debugfp, "%12.3f Port type directserial realport %s\r\n", PIC_FullIndex(), tmpstring.c_str());
}
#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;
}
}
const char* tmpchar=tmpstring.c_str();
LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str());
ULONG ulAction = 0;
APIRET rc = DosOpen((unsigned char*)tmpstring.c_str(), &hCom, &ulAction, 0L, FILE_NORMAL, FILE_OPEN,
OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_SEQUENTIAL, 0L);
if (rc != NO_ERROR)
{
LOG_MSG ("Serial%d: Serial port \"%s\" could not be opened.", COMNUMBER, tmpstring.c_str());
if (rc == 2) {
LOG_MSG ("The specified port does not exist.");
} else if (rc == 99) {
LOG_MSG ("The specified port is already in use.");
} else {
LOG_MSG ("OS/2 error %d occurred.", rc);
}
hCom = 0;
return;
}
DCBINFO dcb;
ULONG ulParmLen = sizeof(DCBINFO);
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
if ( rc != NO_ERROR)
{
LOG_MSG("GetCommState failed with error %d.\n", rc);
DosClose(hCom);
hCom = 0;
return;
}
dcb.usWriteTimeout = 0;
dcb.usReadTimeout = 0; //65535;
dcb.fbCtlHndShake = dcb.fbFlowReplace = 0;
dcb.fbTimeout = 6;
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
if ( rc != NO_ERROR)
{
LOG_MSG("SetDCBInfo failed with error %d.\n", rc);
DosClose(hCom);
hCom = 0;
return;
}
struct {
ULONG baud;
BYTE fraction;
} setbaud;
setbaud.baud = 9600;
setbaud.fraction = 0;
ulParmLen = sizeof(setbaud);
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_EXTSETBAUDRATE, &setbaud, ulParmLen, &ulParmLen, 0, 0, 0);
if (rc != NO_ERROR)
{
LOG_MSG("ExtSetBaudrate failed with error %d.\n", rc);
DosClose (hCom);
hCom = 0;
return;
}
struct {
UCHAR data;
UCHAR parity;
UCHAR stop;
} paramline;
// byte length
paramline.data = 8;
paramline.parity = 0;
paramline.stop = 0;
ulParmLen = sizeof(paramline);
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, &paramline, ulParmLen, &ulParmLen, 0, 0, 0);
if ( rc != NO_ERROR)
{
LOG_MSG ("SetLineCtrl failed with error %d.\n", rc);
}
CSerial::Init_Registers();
InstallationSuccessful = true;
receiveblock = false;
// Clears comm errors
USHORT errors = 0;
ulParmLen = sizeof(errors);
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
setEvent(SERIAL_POLLING_EVENT, 1);
}
CDirectSerial::~CDirectSerial () {
if (hCom != 0)
DosClose (hCom);
}
/*****************************************************************************/
/* 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;
Bit8u bytelength = 0;
struct {
ULONG baud;
BYTE fraction;
} setbaud;
// baud
if (divider <= 0x1)
setbaud.baud = 115200;
else if (divider <= 0x2)
setbaud.baud = 57600;
else if (divider <= 0x3)
setbaud.baud = 38400;
else if (divider <= 0x6)
setbaud.baud = 19200;
else if (divider <= 0xc)
setbaud.baud = 9600;
else if (divider <= 0x18)
setbaud.baud = 4800;
else if (divider <= 0x30)
setbaud.baud = 2400;
else if (divider <= 0x60)
setbaud.baud = 1200;
else if (divider <= 0xc0)
setbaud.baud = 600;
else if (divider <= 0x180)
setbaud.baud = 300;
else if (divider <= 0x417)
setbaud.baud = 110;
// I read that windows can handle nonstandard baudrates:
else
setbaud.baud = 115200 / divider;
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)
{
LOG_MSG("Serial%d: Desired serial mode not supported (Baud: %d, %d, Error: %d)",
COMNUMBER, setbaud.baud, divider, rc);
}
struct {
UCHAR data;
UCHAR parity;
UCHAR stop;
} paramline;
// byte length
bytelength = lcr & 0x3;
bytelength += 5;
paramline.data = bytelength;
// parity
parity = lcr & 0x38;
parity = parity >> 3;
switch (parity) {
case 0x1:
paramline.parity = 1;
break;
case 0x3:
paramline.parity = 2;
break;
case 0x5:
paramline.parity = 3;
break;
case 0x7:
paramline.parity = 4;
break;
default:
paramline.parity = 0;
break;
}
// stopbits
if (lcr & 0x4) {
if (bytelength == 5)
paramline.stop = 1;
else
paramline.stop = 2;
} else {
paramline.stop = 0;
}
#ifdef SERIAL_DEBUG
LOG_MSG("_____________________________________________________");
LOG_MSG("Serial%d, new baud rate: %d", COMNUMBER, setbaud.baud);
LOG_MSG("Serial%d: new bytelen: %d", COMNUMBER, paramline.data);
LOG_MSG("Serial%d: new parity: %d", COMNUMBER, paramline.parity);
LOG_MSG("Serial%d: new stopbits: %d", COMNUMBER, paramline.stop);
#endif
ulParmLen = sizeof(paramline);
rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETLINECTRL, &paramline, ulParmLen, &ulParmLen, 0, 0, 0);
if ( rc != NO_ERROR)
{
#ifdef SERIAL_DEBUG
if (dbg_modemcontrol)
{
fprintf(debugfp, "%12.3f serial mode not supported: rate=%d, LCR=%x.\r\n", PIC_FullIndex(), setbaud.baud, lcr);
}
#endif
LOG_MSG("Serial%d: Desired serial mode not supported (%d,%d,%d,%d)",
COMNUMBER, setbaud.baud, paramline.data, paramline.parity, lcr);
}
}
void CDirectSerial::updateMSR () {
Bit8u newmsr = 0;
UCHAR dptr = 0;
ULONG ulParmLen = sizeof(dptr);
APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETMODEMINPUT, 0, 0, 0, &dptr, ulParmLen, &ulParmLen);
if (rc != NO_ERROR) {
LOG_MSG ("Serial port at %x: GetModemInput failed with %d !", idnumber, dptr);
}
setCTS( (dptr & 16) != 0);
setDSR( (dptr & 32) != 0);
setRI( (dptr & 64) != 0);
setCD( (dptr & 128) != 0);
}
void CDirectSerial::transmitByte (Bit8u val, bool first) {
ULONG bytesWritten = 0;
APIRET rc = DosWrite (hCom, &val, 1, &bytesWritten);
if (rc == NO_ERROR && bytesWritten > 0) {
//LOG_MSG("UART 0x%x: TX 0x%x", base,val);
} else {
LOG_MSG ("Serial%d: NO BYTE WRITTEN!", idnumber);
}
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) {
USHORT error;
ULONG ulParmLen = sizeof(error);
if (value)
DosDevIOCtl (hCom, IOCTL_ASYNC, ASYNC_SETBREAKON, 0,0,0, &error, ulParmLen, &ulParmLen);
else
DosDevIOCtl (hCom, IOCTL_ASYNC, ASYNC_SETBREAKOFF, 0,0,0, &error, ulParmLen, &ulParmLen);
}
/*****************************************************************************/
/* updateModemControlLines(mcr) sets DTR and RTS. **/
/*****************************************************************************/
void CDirectSerial::setRTSDTR(bool rts, bool dtr)
{
bool change = false;
DCBINFO dcb;
ULONG ulParmLen = sizeof(dcb);
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
/*** DTR ***/
if (dtr) { // DTR on
if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled
dcb.fbCtlHndShake |= 1;
change = true;
}
} else {
if (dcb.fbCtlHndShake && 3 == 1) { // DTR enabled
dcb.fbCtlHndShake &= ~3;
change = true;
}
}
/*** RTS ***/
if (rts) { // RTS on
if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled
dcb.fbFlowReplace |= 64;
change = true;
}
} else {
if (dcb.fbFlowReplace && 192 == 1) { // RTS enabled
dcb.fbFlowReplace &= ~192;
change = true;
}
}
if (change)
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
}
void CDirectSerial::setRTS(bool val)
{
bool change = false;
DCBINFO dcb;
ULONG ulParmLen = sizeof(dcb);
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
/*** RTS ***/
if (val) { // RTS on
if (dcb.fbFlowReplace && 192 == 0) { //RTS disabled
dcb.fbFlowReplace |= 64;
change = true;
}
} else {
if (dcb.fbFlowReplace && 192 == 1) { // RTS enabled
dcb.fbFlowReplace &= ~192;
change = true;
}
}
if (change)
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
}
void CDirectSerial::setDTR(bool val)
{
bool change = false;
DCBINFO dcb;
ULONG ulParmLen = sizeof(dcb);
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETDCBINFO, 0, 0, 0, &dcb, ulParmLen, &ulParmLen);
/*** DTR ***/
if (val) { // DTR on
if (dcb.fbCtlHndShake && 3 == 0) { // DTR disabled
dcb.fbCtlHndShake |= 1;
change = true;
}
} else {
if (dcb.fbCtlHndShake && 3 == 1) { // DTR enabled
dcb.fbCtlHndShake &= ~3;
change = true;
}
}
if (change)
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_SETDCBINFO, &dcb, ulParmLen, &ulParmLen, 0, 0, 0);
}
void CDirectSerial::handleUpperEvent(Bit16u type)
{
switch(type) {
case SERIAL_POLLING_EVENT: {
ULONG dwRead = 0;
ULONG errors = 0;
Bit8u chRead = 0;
setEvent(SERIAL_POLLING_EVENT, 1);
if(!receiveblock) {
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
rx_retry=0;
if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) {
if (dwRead) {
receiveByte (chRead);
setEvent(40, bytetime-0.03f); // receive timing
receiveblock=true;
}
}
} else rx_retry++;
}
// check for errors
CheckErrors();
// update Modem input line states
updateMSR ();
break;
}
case 40: {
// receive time is up
ULONG dwRead = 0;
Bit8u chRead = 0;
receiveblock=false;
// check if there is something to receive
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
rx_retry=0;
if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) {
if (dwRead) {
receiveByte (chRead);
setEvent(40, bytetime-0.03f); // receive timing
receiveblock=true;
}
}
} else rx_retry++;
break;
}
case SERIAL_TX_EVENT: {
ULONG dwRead = 0;
Bit8u chRead = 0;
if(!receiveblock) {
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
rx_retry=0;
if (DosRead (hCom, &chRead, 1, &dwRead) == NO_ERROR) {
if (dwRead) {
receiveByte (chRead);
setEvent(40, bytetime-0.03f); // receive timing
receiveblock=true;
}
}
} else rx_retry++;
}
ByteTransmitted();
break;
}
case SERIAL_THR_EVENT: {
ByteTransmitting();
setEvent(SERIAL_TX_EVENT,bytetime+0.03f);
break;
}
}
}
void CDirectSerial::CheckErrors() {
USHORT errors = 0, event = 0;
ULONG ulParmLen = sizeof(errors);
DosDevIOCtl(hCom, 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) errreg |= LSR_RX_BREAK_MASK;
if (event & 128) {
DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen);
if (errors & 8) errreg |= LSR_FRAMING_ERROR_MASK;
if (errors & 4) errreg |= LSR_PARITY_ERROR_MASK;
}
receiveError (errreg);
}
}
#endif
#endif

View File

@ -1,82 +0,0 @@
/*
* 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_os2.h,v 1.5 2009/05/27 09:15:41 qbix79 Exp $ */
// include guard
#ifndef DOSBOX_DIRECTSERIAL_OS2_H
#define DOSBOX_DIRECTSERIAL_OS2_H
#include "dosbox.h"
#if C_DIRECTSERIAL
#if defined(OS2)
#define DIRECTSERIAL_AVAILIBLE
#include "serialport.h"
#define INCL_DOSFILEMGR
#define INCL_DOSERRORS
#define INCL_DOSDEVICES
#define INCL_DOSDEVIOCTL
#define INCL_DOSPROCESS
#include <os2.h>
class CDirectSerial : public CSerial {
public:
HFILE hCom;
BOOL fSuccess;
CDirectSerial(Bitu id, CommandLine* cmd);
~CDirectSerial();
//Bitu lastChance; // If there is no space for new
// received data, it gets a little chance
//Bit8u ChanceChar;
//bool CanRecv(void);
//bool CanSend(void);
//void RXBufferEmpty();
bool receiveblock;
Bitu rx_retry;
Bitu rx_retry_max;
void CheckErrors();
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);
//void updateModemControlLines(/*Bit8u mcr*/);
//void Timer2(void);
};
#endif // IFDEF
#endif // C_DIRECTSERIAL
#endif // include guard

View File

@ -1,361 +0,0 @@
/*
* 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_posix.cpp,v 1.4 2009/05/27 09:15:41 qbix79 Exp $ */
#include "dosbox.h"
#if C_DIRECTSERIAL
// Posix version
#if defined (LINUX) || defined (MACOSX) || defined (BSD)
#include "serialport.h"
#include "directserial_posix.h"
#include "pic.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.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;
rx_retry = 0;
rx_retry_max = 0;
std::string prefix="/dev/";
std::string tmpstring;
if(!cmd->FindStringBegin("realport:",tmpstring,false)) return;
#if SERIAL_DEBUG
if(dbg_modemcontrol)
fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n",
PIC_FullIndex(),tmpstring.c_str());
#endif
prefix.append(tmpstring);
// 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;
}
const char* tmpchar=prefix.c_str();
LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpchar);
fileHandle = open (tmpchar, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fileHandle < 0) {
LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.",
COMNUMBER, tmpchar);
if (errno == 2) {
LOG_MSG ("The specified port does not exist.");
} else if (errno == EBUSY) {
LOG_MSG ("The specified port is already in use.");
} else {
LOG_MSG ("Errno %d occurred.", errno);
}
return;
}
int result = tcgetattr(fileHandle, &termInfo);
if (result==-1) {
// Handle the error.
LOG_MSG ("tcgetattr failed with error %d.\n", errno);
return;
}
// save it here to restore in destructor
tcgetattr(fileHandle,&backup);
// 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;
cfsetospeed (&termInfo, B9600);
cfsetispeed (&termInfo, B9600);
termInfo.c_cc[VMIN] = 0;
termInfo.c_cc[VTIME] = 0;
tcflush (fileHandle, TCIFLUSH);
tcsetattr (fileHandle, TCSANOW, &termInfo);
//initialise base class
CSerial::Init_Registers();
InstallationSuccessful = true;
receiveblock=false;
setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick
}
CDirectSerial::~CDirectSerial () {
if (fileHandle >= 0)
{
tcsetattr(fileHandle, TCSANOW, &backup);
close(fileHandle);
}
// We do not use own events so we don't have to clear them.
}
void CDirectSerial::handleUpperEvent(Bit16u type) {
switch(type) {
case SERIAL_POLLING_EVENT: {
setEvent(SERIAL_POLLING_EVENT, 1);
if(!receiveblock) {
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
ReadCharacter();
} else rx_retry++;
}
// check for errors
CheckErrors();
// update Modem input line states
updateMSR ();
break;
}
case 40: {
// receive time is up
receiveblock=false;
// check if there is something to receive
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
ReadCharacter();
} else rx_retry++;
break;
}
case SERIAL_TX_EVENT: {
if(!receiveblock) {
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
ReadCharacter();
} else rx_retry++;
}
ByteTransmitted();
break;
}
case SERIAL_THR_EVENT: {
ByteTransmitting();
setEvent(SERIAL_TX_EVENT,bytetime+0.03f);
break;
}
}
}
void CDirectSerial::ReadCharacter()
{
Bit8u chRead = 0;
int dwRead = 0;
rx_retry=0;
dwRead=read(fileHandle,&chRead,1);
if (dwRead==1) {
if(chRead==0xff) // error escape
{
dwRead=read(fileHandle,&chRead,1);
if(chRead==0x00) // an error
{
dwRead=read(fileHandle,&chRead,1);
if(chRead==0x0)receiveError(LSR_RX_BREAK_MASK);
else receiveError(LSR_PARITY_ERROR_MASK);
}
}
receiveByte (chRead);
setEvent(40, bytetime-0.03f); // receive timing
receiveblock=true;
}
}
void CDirectSerial::CheckErrors() {
}
/*****************************************************************************/
/* 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;
Bit8u bytelength = 0;
int baudrate=0;
// baud
termInfo.c_cflag = CREAD | CLOCAL;
if (divider == 0x1) baudrate = B115200;
else if (divider == 0x2) baudrate = B57600;
else if (divider == 0x3) baudrate = B38400;
else if (divider == 0x6) baudrate = B19200;
else if (divider == 0xc) baudrate = B9600;
else if (divider == 0x18) baudrate = B4800;
else if (divider == 0x30) baudrate = B2400;
else if (divider == 0x60) baudrate = B1200;
else if (divider == 0xc0) baudrate = B600;
else if (divider == 0x180) baudrate = B300;
else if (divider == 0x417) baudrate = B110;
// Don't think termios supports nonstandard baudrates
else baudrate = B9600;
// byte length
bytelength = lcr & 0x3;
bytelength += 5;
switch (bytelength) {
case 5:
termInfo.c_cflag |= CS5;
break;
case 6:
termInfo.c_cflag |= CS6;
break;
case 7:
termInfo.c_cflag |= CS7;
break;
case 8:
default:
termInfo.c_cflag |= CS8;
break;
}
// parity
parity = lcr & 0x38;
parity >>= 3;
switch (parity) {
case 0x1:
termInfo.c_cflag |= PARODD;
termInfo.c_cflag |= PARENB;
break;
case 0x3:
termInfo.c_cflag |= PARENB;
break;
case 0x5:
// "works on many systems"
#define CMSPAR 010000000000
termInfo.c_cflag |= PARODD;
termInfo.c_cflag |= PARENB;
termInfo.c_cflag |= CMSPAR;
//LOG_MSG("Serial%d: Mark parity not supported.", COMNUMBER);
break;
case 0x7:
termInfo.c_cflag |= PARENB;
termInfo.c_cflag |= CMSPAR;
//LOG_MSG("Serial%d: Space parity not supported.", COMNUMBER);
break;
default: // no parity
break;
}
// stopbits
if (lcr & 0x4) termInfo.c_cflag |= CSTOPB;
cfsetospeed (&termInfo, baudrate);
cfsetispeed (&termInfo, baudrate);
int retval = tcsetattr(fileHandle, TCSANOW, &termInfo);
if(retval==-1)
LOG_MSG ("Serial%d: Desired serial mode not supported", COMNUMBER);
}
void CDirectSerial::updateMSR () {
long flags = 0;
ioctl (fileHandle, TIOCMGET, &flags);
if (flags & TIOCM_CTS) setCTS(true);
else setCTS(false);
if (flags & TIOCM_DSR) setDSR(true);
else setDSR(false);
if (flags & TIOCM_RI) setRI(true);
else setRI(false);
if (flags & TIOCM_CD) setCD(true);
else setCD(false);
}
void CDirectSerial::transmitByte (Bit8u val, bool first) {
if((LCR&LCR_BREAK_MASK) == 0) {
int bytesWritten = write(fileHandle, &val, 1);
if (bytesWritten != 1)
LOG_MSG ("Serial%d: COM port error: write failed!", idnumber);
}
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) {
if (value) ioctl (fileHandle, TIOCSBRK);
else ioctl (fileHandle, TIOCCBRK);
}
/*****************************************************************************/
/* updateModemControlLines(mcr) sets DTR and RTS. **/
/*****************************************************************************/
void CDirectSerial::setRTSDTR(bool rts, bool dtr) {
long setflags = 0;
long clearflags = 0;
if(rts) setflags |= TIOCM_RTS;
else clearflags |= TIOCM_RTS;
if(dtr) setflags |= TIOCM_DTR;
else clearflags |= TIOCM_DTR;
if(setflags) ioctl (fileHandle, TIOCMBIS, &setflags);
if(clearflags) ioctl (fileHandle, TIOCMBIC, &clearflags);
}
void CDirectSerial::setRTS(bool val) {
long flag = TIOCM_RTS;
if(val) ioctl(fileHandle, TIOCMBIS, &flag);
else ioctl(fileHandle, TIOCMBIC, &flag);
}
void CDirectSerial::setDTR(bool val) {
long flag = TIOCM_DTR;
if(val) ioctl(fileHandle, TIOCMBIS, &flag);
else ioctl(fileHandle, TIOCMBIC, &flag);
}
#endif
#endif

View File

@ -1,69 +0,0 @@
/*
* 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_posix.h,v 1.4 2009/05/27 09:15:41 qbix79 Exp $ */
// include guard
#ifndef DOSBOX_DIRECTSERIAL_POSIX_H
#define DOSBOX_DIRECTSERIAL_POSIX_H
#include "dosbox.h"
#if C_DIRECTSERIAL
#if defined (LINUX) || defined (MACOSX) || defined (BSD)
#define DIRECTSERIAL_AVAILIBLE
#include "serialport.h"
#include <termios.h>
#include <unistd.h>
class CDirectSerial : public CSerial {
public:
termios termInfo;
termios backup;
int fileHandle;
CDirectSerial(Bitu id, CommandLine* cmd);
~CDirectSerial();
bool receiveblock; // It's not a block of data it rather blocks
Bitu rx_retry; // counter of retries
Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing
// a overrun error.
void ReadCharacter();
void CheckErrors();
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);
};
#endif // WIN32
#endif // C_DIRECTSERIAL
#endif // include guard

View File

@ -1,394 +0,0 @@
/*
* 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_win32.cpp,v 1.8 2009/05/27 09:15:41 qbix79 Exp $ */
#include "dosbox.h"
#if C_DIRECTSERIAL
/* Windows version */
#if defined (WIN32)
#include "serialport.h"
#include "directserial_win32.h"
#include "misc_util.h"
#include "pic.h"
// Win32 related headers
#include <windows.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;
hCom = INVALID_HANDLE_VALUE; // else destructor may close an invalid handle
rx_retry = 0;
rx_retry_max = 0;
// open the port in NT object space (recommended by Microsoft)
// allows the user to open COM10+ and custom port names.
std::string prefix="\\\\.\\";
std::string tmpstring;
if(!cmd->FindStringBegin("realport:",tmpstring,false)) return;
#if SERIAL_DEBUG
if(dbg_modemcontrol)
fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n",
PIC_FullIndex(),tmpstring.c_str());
#endif
prefix.append(tmpstring);
// 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;
}
}
const char* tmpchar=prefix.c_str();
LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str());
hCom = CreateFile (tmpchar,
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 (hCom == INVALID_HANDLE_VALUE) {
int error = GetLastError ();
LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.",
COMNUMBER, tmpstring.c_str());
if (error == 2) {
LOG_MSG ("The specified port does not exist.");
} else if (error == 5) {
LOG_MSG ("The specified port is already in use.");
} else {
LOG_MSG ("Windows error %d occurred.", error);
}
return;
}
dcb.DCBlength=sizeof(dcb);
fSuccess = GetCommState (hCom, &dcb);
if (!fSuccess) {
// Handle the error.
LOG_MSG ("GetCommState failed with error %d.\n", (int)GetLastError ());
hCom = INVALID_HANDLE_VALUE;
return;
}
// initialize the port
dcb.BaudRate=CBR_9600;
dcb.fBinary=true;
dcb.fParity=true;
dcb.fOutxCtsFlow=false;
dcb.fOutxDsrFlow=false;
dcb.fDtrControl=DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity=false;
dcb.fOutX=false;
dcb.fInX=false;
dcb.fErrorChar=0;
dcb.fNull=false;
dcb.fRtsControl=RTS_CONTROL_DISABLE;
dcb.fAbortOnError=false;
dcb.ByteSize=8;
dcb.Parity=NOPARITY;
dcb.StopBits=ONESTOPBIT;
fSuccess = SetCommState (hCom, &dcb);
if (!fSuccess) {
// Handle the error.
LOG_MSG ("SetCommState failed with error %d.\n", (int)GetLastError ());
hCom = INVALID_HANDLE_VALUE;
return;
}
// Configure timeouts to effectively use polling
COMMTIMEOUTS ct;
ct.ReadIntervalTimeout = MAXDWORD;
ct.ReadTotalTimeoutConstant = 0;
ct.ReadTotalTimeoutMultiplier = 0;
ct.WriteTotalTimeoutConstant = 0;
ct.WriteTotalTimeoutMultiplier = 0;
SetCommTimeouts (hCom, &ct);
CSerial::Init_Registers();
InstallationSuccessful = true;
receiveblock=false;
ClearCommBreak (hCom);
setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick
}
CDirectSerial::~CDirectSerial () {
if (hCom != INVALID_HANDLE_VALUE) CloseHandle (hCom);
// We do not use own events so we don't have to clear them.
}
void CDirectSerial::handleUpperEvent(Bit16u type) {
switch(type) {
case SERIAL_POLLING_EVENT: {
DWORD dwRead = 0;
Bit8u chRead = 0;
setEvent(SERIAL_POLLING_EVENT, 1);
if(!receiveblock) {
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
rx_retry=0;
if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) {
if (dwRead) {
receiveByte (chRead);
setEvent(40, bytetime-0.03f); // receive timing
receiveblock=true;
}
}
} else rx_retry++;
}
// check for errors
CheckErrors();
// update Modem input line states
updateMSR ();
break;
}
case 40: {
// receive time is up
DWORD dwRead = 0;
Bit8u chRead = 0;
receiveblock=false;
// check if there is something to receive
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
rx_retry=0;
if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) {
if (dwRead) {
receiveByte (chRead);
setEvent(40, bytetime-0.03f); // receive timing
receiveblock=true;
}
}
} else rx_retry++;
break;
}
case SERIAL_TX_EVENT: {
DWORD dwRead = 0;
Bit8u chRead = 0;
if(!receiveblock) {
if(((!(LSR&LSR_RX_DATA_READY_MASK)) || rx_retry>=rx_retry_max ))
{
rx_retry=0;
if (ReadFile (hCom, &chRead, 1, &dwRead, NULL)) {
if (dwRead) {
receiveByte (chRead);
setEvent(40, bytetime-0.03f); // receive timing
receiveblock=true;
}
}
} else rx_retry++;
}
ByteTransmitted();
break;
}
case SERIAL_THR_EVENT: {
ByteTransmitting();
setEvent(SERIAL_TX_EVENT,bytetime+0.03f);
break;
}
}
}
void CDirectSerial::CheckErrors() {
DWORD errors=0;
// check for errors
if (ClearCommError (hCom, &errors, NULL))
if (errors & (CE_BREAK | CE_FRAME | CE_RXPARITY)) {
Bit8u errreg = 0;
if (errors & CE_BREAK) errreg |= LSR_RX_BREAK_MASK;
if (errors & CE_FRAME) errreg |= LSR_FRAMING_ERROR_MASK;
if (errors & CE_RXPARITY) errreg |= LSR_PARITY_ERROR_MASK;
receiveError (errreg);
}
}
/*****************************************************************************/
/* 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;
Bit8u bytelength = 0;
// baud
if (divider == 0x1)
dcb.BaudRate = CBR_115200;
else if (divider == 0x2)
dcb.BaudRate = CBR_57600;
else if (divider == 0x3)
dcb.BaudRate = CBR_38400;
else if (divider == 0x6)
dcb.BaudRate = CBR_19200;
else if (divider == 0xc)
dcb.BaudRate = CBR_9600;
else if (divider == 0x18)
dcb.BaudRate = CBR_4800;
else if (divider == 0x30)
dcb.BaudRate = CBR_2400;
else if (divider == 0x60)
dcb.BaudRate = CBR_1200;
else if (divider == 0xc0)
dcb.BaudRate = CBR_600;
else if (divider == 0x180)
dcb.BaudRate = CBR_300;
else if (divider == 0x417)
dcb.BaudRate = CBR_110;
// I read that windows can handle nonstandard baudrates:
else
dcb.BaudRate = 115200 / divider;
// byte length
bytelength = lcr & 0x3;
bytelength += 5;
dcb.ByteSize = bytelength;
// parity
parity = lcr & 0x38;
parity = parity >> 3;
switch (parity) {
case 0x1:
dcb.Parity = ODDPARITY;
break;
case 0x3:
dcb.Parity = EVENPARITY;
break;
case 0x5:
dcb.Parity = MARKPARITY;
break;
case 0x7:
dcb.Parity = SPACEPARITY;
break;
default:
dcb.Parity = NOPARITY;
break;
}
// stopbits
if (lcr & 0x4) {
if (bytelength == 5)
dcb.StopBits = ONE5STOPBITS;
else
dcb.StopBits = TWOSTOPBITS;
} else {
dcb.StopBits = ONESTOPBIT;
}
#ifdef SERIALPORT_DEBUGMSG
LOG_MSG ("__________________________");
LOG_MSG ("Serial%d: new baud rate: %d", COMNUMBER, dcb.BaudRate);
LOG_MSG ("Serial%d: new bytelen: %d", COMNUMBER, dcb.ByteSize);
LOG_MSG ("Serial%d: new parity: %d", COMNUMBER, dcb.Parity);
LOG_MSG ("Serial%d: new stopbits: %d", COMNUMBER, dcb.StopBits);
#endif
if (!SetCommState (hCom, &dcb)) {
#if SERIAL_DEBUG
if(dbg_modemcontrol)
fprintf(debugfp,"%12.3f serial mode not supported: rate=%d,LCR=%x.\r\n",
PIC_FullIndex(),dcb.BaudRate,lcr);
#endif
LOG_MSG ("Serial%d: Desired serial mode not supported (%d,%d,%d,%d",
(Bit32u)dcb.BaudRate,(Bit32u)dcb.ByteSize,
(Bit32u)dcb.Parity,(Bit32u)dcb.StopBits, COMNUMBER);
}
}
void CDirectSerial::updateMSR () {
DWORD dptr = 0;
if (!GetCommModemStatus (hCom, &dptr)) {
#ifdef SERIALPORT_DEBUGMSG
// LOG_MSG ("Serial port at %x: GetCommModemStatus failed!", base);
#endif
//return;
}
setCTS((dptr & MS_CTS_ON)!=0);
setDSR((dptr & MS_DSR_ON)!=0);
setRI ((dptr & MS_RING_ON)!=0);
setCD((dptr & MS_RLSD_ON)!=0);
}
void CDirectSerial::transmitByte (Bit8u val, bool first) {
// mean bug: with break = 1, WriteFile will never return.
if((LCR&LCR_BREAK_MASK) == 0) {
DWORD bytesWritten = 0;
WriteFile (hCom, &val, 1, &bytesWritten, NULL);
if (bytesWritten != 1)
LOG_MSG ("Serial%d: COM port error: write failed!", idnumber);
}
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) {
if (value) SetCommBreak (hCom);
else ClearCommBreak (hCom);
}
/*****************************************************************************/
/* updateModemControlLines(mcr) sets DTR and RTS. **/
/*****************************************************************************/
void CDirectSerial::setRTSDTR(bool rts, bool dtr) {
if(rts) dcb.fRtsControl = RTS_CONTROL_ENABLE;
else dcb.fRtsControl = RTS_CONTROL_DISABLE;
if(dtr) dcb.fDtrControl = DTR_CONTROL_ENABLE;
else dcb.fDtrControl = DTR_CONTROL_DISABLE;
SetCommState (hCom, &dcb);
}
void CDirectSerial::setRTS(bool val) {
if(val) dcb.fRtsControl = RTS_CONTROL_ENABLE;
else dcb.fRtsControl = RTS_CONTROL_DISABLE;
SetCommState (hCom, &dcb);
}
void CDirectSerial::setDTR(bool val) {
if(val) dcb.fDtrControl = DTR_CONTROL_ENABLE;
else dcb.fDtrControl = DTR_CONTROL_DISABLE;
SetCommState (hCom, &dcb);
}
#endif
#endif

View File

@ -1,69 +0,0 @@
/*
* 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_win32.h,v 1.6 2009/05/27 09:15:41 qbix79 Exp $ */
// include guard
#ifndef DOSBOX_DIRECTSERIAL_WIN32_H
#define DOSBOX_DIRECTSERIAL_WIN32_H
#include "dosbox.h"
#if C_DIRECTSERIAL
#ifdef WIN32
#define DIRECTSERIAL_AVAILIBLE
#include "serialport.h"
#include <winsock2.h> //To prevent compilation problems with windows.h including winsock.h
#include <windows.h>
class CDirectSerial : public CSerial {
public:
HANDLE hCom;
DCB dcb;
BOOL fSuccess;
CDirectSerial(Bitu id, CommandLine* cmd/*const char* configstring*/);
~CDirectSerial();
bool receiveblock; // It's not a block of data it rather blocks
Bitu rx_retry; // counter of retries
Bitu rx_retry_max; // how many POLL_EVENTS to wait before causing
// a overrun error.
void CheckErrors();
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);
};
#endif // WIN32
#endif // C_DIRECTSERIAL
#endif // include guard

View File

@ -16,7 +16,7 @@
* 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 $ */
/* $Id: libserial.cpp,v 1.3 2009/10/12 12:55:20 h-a-l-9000 Exp $ */
#include "libserial.h"
@ -256,8 +256,8 @@ bool SERIAL_setCommParameters(COMPORT port,
#if defined (LINUX) || defined (MACOSX)
#include <memory.h> // strlen
#include <malloc.h>
#include <string.h> // strlen
#include <stdlib.h>
#include <termios.h>
#include <unistd.h>

View File

@ -1,7 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libints.a
libints_a_SOURCES = mouse.cpp xms.cpp xms.h ems.cpp \
int10.cpp int10.h int10_char.cpp int10_memory.cpp int10_misc.cpp int10_modes.cpp \
int10_vesa.cpp int10_pal.cpp int10_put_pixel.cpp int10_video_state.cpp int10_vptable.cpp \
bios.cpp bios_disk.cpp bios_keyboard.cpp

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: bios.cpp,v 1.77 2009/06/23 17:46:05 c2woody Exp $ */
/* $Id: bios.cpp,v 1.78 2009/10/10 13:26:46 h-a-l-9000 Exp $ */
#include "dosbox.h"
#include "mem.h"
@ -434,110 +434,126 @@ static Bitu INT17_Handler(void) {
return CBRET_NONE;
}
static Bitu INT14_Handler(void)
{
if(reg_ah > 0x3 || reg_dx > 0x3) { // 0-3 serial port functions
static Bit8u INT14_Wait(Bit16u port, Bit8u mask, Bit8u timeout) {
double starttime = PIC_FullIndex();
double timeout_f = timeout * 1000.0;
Bit8u retval;
while (((retval = IO_ReadB(port)) & mask) != mask) {
if (starttime < (PIC_FullIndex() - timeout_f)) {
retval |= 0x80;
break;
}
CALLBACK_Idle();
}
return retval;
}
static Bitu INT14_Handler(void) {
if (reg_ah > 0x3 || reg_dx > 0x3) { // 0-3 serial port functions
// and no more than 4 serial ports
LOG_MSG("BIOS INT14: Unhandled call AH=%2X DX=%4x",reg_ah,reg_dx);
return CBRET_NONE;
}
Bit16u port = real_readw(0x40,reg_dx*2); // DX is always port number
if(port==0) {
Bit8u timeout = mem_readb(BIOS_COM1_TIMEOUT + reg_dx);
if (port==0) {
LOG(LOG_BIOS,LOG_NORMAL)("BIOS INT14: port %d does not exist.",reg_dx);
return CBRET_NONE;
}
switch (reg_ah)
{
case 0x00: /* Init port */
// Parameters:
// AL: port parameters
// Return:
// AH: line status
// AL: modem status
{
// set baud rate
Bitu baudrate = 9600;
Bit16u baudresult;
Bitu rawbaud=reg_al>>5;
if(rawbaud==0){ baudrate=110;}
else if (rawbaud==1){ baudrate=150;}
else if (rawbaud==2){ baudrate=300;}
else if (rawbaud==3){ baudrate=600;}
else if (rawbaud==4){ baudrate=1200;}
else if (rawbaud==5){ baudrate=2400;}
else if (rawbaud==6){ baudrate=4800;}
else if (rawbaud==7){ baudrate=9600;}
switch (reg_ah) {
case 0x00: {
// Initialize port
// Parameters: Return:
// AL: port parameters AL: modem status
// AH: line status
baudresult = (Bit16u)(115200 / baudrate);
// set baud rate
Bitu baudrate = 9600;
Bit16u baudresult;
Bitu rawbaud=reg_al>>5;
if (rawbaud==0){ baudrate=110;}
else if (rawbaud==1){ baudrate=150;}
else if (rawbaud==2){ baudrate=300;}
else if (rawbaud==3){ baudrate=600;}
else if (rawbaud==4){ baudrate=1200;}
else if (rawbaud==5){ baudrate=2400;}
else if (rawbaud==6){ baudrate=4800;}
else if (rawbaud==7){ baudrate=9600;}
IO_WriteB(port+3, 0x80); // enable divider access
IO_WriteB(port,(Bit8u)baudresult&0xff);
IO_WriteB(port+1,(Bit8u)(baudresult>>8));
baudresult = (Bit16u)(115200 / baudrate);
// set line parameters, disable divider access
IO_WriteB(port+3, reg_al&0x1F);//LCR
// disable interrupts
IO_WriteB(port+1, 0);
IO_ReadB(port+2);
IO_WriteB(port+3, 0x80); // enable divider access
IO_WriteB(port, (Bit8u)baudresult&0xff);
IO_WriteB(port+1, (Bit8u)(baudresult>>8));
// get result
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
CALLBACK_SCF(false);
}
// set line parameters, disable divider access
IO_WriteB(port+3, reg_al&0x1F); // LCR
// disable interrupts
IO_WriteB(port+1, 0); // IER
// get result
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
CALLBACK_SCF(false);
break;
case 0x01: /* Write character */
// Parameters:
// AL: character
// Return:
// AH: line status
// AL: modem status
{
if(serialports[reg_dx]) {
bool timeout;
// switch modem lines on
IO_WriteB(port+4,0x3);
timeout = !serialports[reg_dx]->Putchar(reg_al,true,true,
mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000);
// get result
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
if(timeout) reg_ah |= 0x80;
}
CALLBACK_SCF(false);
}
break;
case 0x02: /* Read character */
{
if(serialports[reg_dx]) {
bool timeout;
Bit8u buffer;
// switch modem lines on
IO_WriteB(port+4,0x3);
// wait for something
timeout = !serialports[reg_dx]->Getchar(&buffer,&reg_ah,true,
mem_readb(BIOS_COM1_TIMEOUT+reg_dx)*1000);
}
case 0x01: { // Transmit character
// Parameters: Return:
// AL: character AL: unchanged
// AH: 0x01 AH: line status from just before the char was sent
// (0x80 | unpredicted) in case of timeout
// [undoc] (0x80 | line status) in case of tx timeout
// [undoc] (0x80 | modem status) in case of dsr/cts timeout
// RTS off
IO_WriteB(port+4,0x1);
// get result
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
if(timeout) reg_ah |= 0x80;
else reg_al=buffer;
// set DTR & RTS on
IO_WriteB(port+4,0x3);
// wait for DSR & CTS
reg_ah = INT14_Wait(port+6, 0x30, timeout);
if (!(reg_ah & 0x80)) {
// wait for TX buffer empty
reg_ah = INT14_Wait(port+5, 0x20, timeout);
if (!(reg_ah & 0x80)) {
// fianlly send the character
IO_WriteB(port,reg_al);
}
} // else timed out
CALLBACK_SCF(false);
break;
}
case 0x02: // Read character
// Parameters: Return:
// AH: 0x02 AL: received character
// [undoc] will be trashed in case of timeout
// AH: (line status & 0x1E) in case of success
// (0x80 | unpredicted) in case of timeout
// [undoc] (0x80 | line status) in case of rx timeout
// [undoc] (0x80 | modem status) in case of dsr timeout
// set DTR on
IO_WriteB(port+4,0x1);
// wait for DSR
reg_ah = INT14_Wait(port+6, 0x20, timeout);
if (!(reg_ah & 0x80)) {
// wait for character to arrive
reg_ah = INT14_Wait(port+5, 0x01, timeout);
if (!(reg_ah & 0x80)) {
reg_ah &= 0x1E;
reg_al = IO_ReadB(port);
}
CALLBACK_SCF(false);
break;
}
CALLBACK_SCF(false);
break;
case 0x03: // get status
{
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
CALLBACK_SCF(false);
}
break;
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
CALLBACK_SCF(false);
break;
}
return CBRET_NONE;
}

View File

@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: ems.cpp,v 1.64 2009/06/24 17:44:52 c2woody Exp $ */
/* $Id: ems.cpp,v 1.65 2009/10/11 17:11:52 c2woody Exp $ */
#include <string.h>
#include <stdlib.h>
@ -40,8 +40,10 @@
#define EMM_MAX_PAGES (32 * 1024 / 16 )
#define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */
#define EMM_VERSION 0x40
#define GEMMIS_VERSION 0x0001 // Version 1.0
#define EMM_VERSION 0x40
#define EMM_MINOR_VERSION 0x00
//#define EMM_MINOR_VERSION 0x30 // emm386 4.48
#define GEMMIS_VERSION 0x0001 // Version 1.0
#define EMM_SYSTEM_HANDLE 0x0000
#define NULL_HANDLE 0xffff
@ -180,8 +182,15 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco
}
case 0x02:
if (size!=2) return false;
mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4.0
mem_writew(bufptr+0x01,EMM_VERSION&0x0f);
mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4
mem_writeb(bufptr+0x01,EMM_MINOR_VERSION);
*retcode=2;
return true;
case 0x03:
if (EMM_MINOR_VERSION < 0x2d) return false;
if (size!=4) return false;
mem_writew(bufptr+0x00,(Bit16u)(MEM_TotalPages()*4)); // max size (kb)
mem_writew(bufptr+0x02,0x80); // min size (kb)
*retcode=2;
return true;
}
@ -1177,8 +1186,7 @@ static Bitu V86_Monitor() {
static void SetupVCPI() {
vcpi.enabled=false;
/* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */
if (EMM_AllocateMemory(1,vcpi.ems_handle,false) != EMM_NO_ERROR) return;
vcpi.ems_handle=0; // use EMM system handle for VCPI data
vcpi.enabled=true;
@ -1259,9 +1267,10 @@ class EMS: public Module_base {
private:
/* location in protected unfreeable memory where the ems name and callback are
* stored 32 bytes.*/
static Bit16u emsnameseg;
static Bit16u ems_baseseg;
RealPt old4b_pointer,old67_pointer;
CALLBACK_HandlerObject call_vdma,int67,call_vcpi,call_v86mon;
CALLBACK_HandlerObject call_vdma,call_vcpi,call_v86mon;
Bitu call_int67;
public:
EMS(Section* configuration):Module_base(configuration){
@ -1280,24 +1289,21 @@ public:
return;
}
BIOS_ZeroExtendedSize(true);
int67.Install(&INT67_Handler,CB_IRET,"Int 67 ems");
Bit16u call_int67=int67.Get_callback();
if (!ems_baseseg) ems_baseseg=DOS_GetMemory(2); //We have 32 bytes
/* Add a little hack so it appears that there is an actual ems device installed */
char const* emsname="EMMXXXX0";
MEM_BlockWrite(PhysMake(ems_baseseg,0xa),emsname,(Bitu)(strlen(emsname)+1));
call_int67=CALLBACK_Allocate();
CALLBACK_Setup(call_int67,&INT67_Handler,CB_IRET,PhysMake(ems_baseseg,4),"Int 67 ems");
RealSetVec(0x67,RealMake(ems_baseseg,4),old67_pointer);
/* Register the ems device */
//TODO MAYBE put it in the class.
DOS_Device * newdev = new device_EMM();
DOS_AddDevice(newdev);
/* Add a little hack so it appears that there is an actual ems device installed */
char const* emsname="EMMXXXX0";
if(!emsnameseg) emsnameseg=DOS_GetMemory(2); //We have 32 bytes
MEM_BlockWrite(PhysMake(emsnameseg,0xa),emsname,(Bitu)(strlen(emsname)+1));
/* Copy the callback piece into the beginning, and set the interrupt vector to it*/
char buf[16];
MEM_BlockRead(CALLBACK_PhysPointer(call_int67),buf,0xa);
MEM_BlockWrite(PhysMake(emsnameseg,0),buf,0xa);
RealSetVec(0x67,RealMake(emsnameseg,0),old67_pointer);
/* Clear handle and page tables */
Bitu i;
@ -1315,7 +1321,7 @@ public:
emm_segmentmappings[i].handle=NULL_HANDLE;
}
EMM_AllocateSystemHandle(4); // allocate OS-dedicated handle (ems handle zero, 16kb)
EMM_AllocateSystemHandle(8); // allocate OS-dedicated handle (ems handle zero, 128kb)
if (!ENABLE_VCPI) return;
@ -1365,6 +1371,7 @@ public:
~EMS() {
Section_prop * section=static_cast<Section_prop *>(m_configuration);
if (!section->Get_bool("ems")) return;
/* Undo Biosclearing */
BIOS_ZeroExtendedSize(false);
@ -1375,7 +1382,7 @@ public:
/* Remove the emsname and callback hack */
char buf[32]= { 0 };
MEM_BlockWrite(PhysMake(emsnameseg,0),buf,32);
MEM_BlockWrite(PhysMake(ems_baseseg,0),buf,32);
RealSetVec(0x67,old67_pointer);
/* Release memory allocated to system handle */
@ -1388,9 +1395,6 @@ public:
if ((!ENABLE_VCPI) || (!vcpi.enabled)) return;
/* Free private data area in expanded memory */
EMM_ReleaseMemory(vcpi.ems_handle);
if (cpu.pmode && GETFLAG(VM)) {
/* Switch back to real mode if in v86-mode */
CPU_SET_CRX(0, 0);
@ -1414,4 +1418,4 @@ void EMS_Init(Section* sec) {
}
//Initialize static members
Bit16u EMS::emsnameseg = 0;
Bit16u EMS::ems_baseseg = 0;

View File

@ -1,4 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libmisc.a
libmisc_a_SOURCES = cross.cpp messages.cpp programs.cpp setup.cpp support.cpp

View File

@ -1,4 +0,0 @@
AM_CPPFLAGS = -I$(top_srcdir)/include
noinst_LIBRARIES = libshell.a
libshell_a_SOURCES = shell.cpp shell_batch.cpp shell_cmds.cpp shell_misc.cpp