mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-25 18:11:50 +01:00
sync with official
This commit is contained in:
parent
48fb8600dd
commit
c19daa723d
@ -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
|
||||
|
@ -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
|
@ -1,3 +0,0 @@
|
||||
|
||||
noinst_HEADERS = ea_lookup.h load.h loadwrite.h op.h optable.h save.h \
|
||||
string.h support.h
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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, ¶mline, 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, ¶mline, 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
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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>
|
||||
|
@ -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
|
@ -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,®_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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue
Block a user