mirror of
https://github.com/retro100/dosbox-wii.git
synced 2024-12-26 02:21:49 +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.
|
* 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 <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -161,17 +161,13 @@ static void CAPTURE_AddAviChunk(const char * tag, Bit32u size, void * data, Bit3
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (C_SSHOT)
|
#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];
|
Bit8u avi_header[AVI_HEADER_SIZE];
|
||||||
Bitu main_list;
|
Bitu main_list;
|
||||||
Bitu header_pos=0;
|
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 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 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;
|
#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);
|
fwrite( capture.video.index, 1, capture.video.indexused, capture.video.handle);
|
||||||
fseek(capture.video.handle, 0, SEEK_SET);
|
fseek(capture.video.handle, 0, SEEK_SET);
|
||||||
fwrite(&avi_header, 1, AVI_HEADER_SIZE, capture.video.handle);
|
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 );
|
fclose( capture.video.handle );
|
||||||
free( capture.video.index );
|
free( capture.video.index );
|
||||||
free( capture.video.buf );
|
free( capture.video.buf );
|
||||||
@ -547,6 +557,9 @@ skip_shot:
|
|||||||
capture.video.audioused = 0;
|
capture.video.audioused = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Adds AVI header to the file */
|
||||||
|
CAPTURE_VideoHeader();
|
||||||
|
|
||||||
/* Everything went okay, set flag again for next frame */
|
/* Everything went okay, set flag again for next frame */
|
||||||
CaptureState |= CAPTURE_VIDEO;
|
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.
|
* 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"
|
#include "libserial.h"
|
||||||
|
|
||||||
@ -256,8 +256,8 @@ bool SERIAL_setCommParameters(COMPORT port,
|
|||||||
|
|
||||||
#if defined (LINUX) || defined (MACOSX)
|
#if defined (LINUX) || defined (MACOSX)
|
||||||
|
|
||||||
#include <memory.h> // strlen
|
#include <string.h> // strlen
|
||||||
#include <malloc.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.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.
|
* 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 "dosbox.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
@ -434,110 +434,126 @@ static Bitu INT17_Handler(void) {
|
|||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Bitu INT14_Handler(void)
|
static Bit8u INT14_Wait(Bit16u port, Bit8u mask, Bit8u timeout) {
|
||||||
{
|
double starttime = PIC_FullIndex();
|
||||||
if(reg_ah > 0x3 || reg_dx > 0x3) { // 0-3 serial port functions
|
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
|
// and no more than 4 serial ports
|
||||||
LOG_MSG("BIOS INT14: Unhandled call AH=%2X DX=%4x",reg_ah,reg_dx);
|
LOG_MSG("BIOS INT14: Unhandled call AH=%2X DX=%4x",reg_ah,reg_dx);
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
Bit16u port = real_readw(0x40,reg_dx*2); // DX is always port number
|
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);
|
LOG(LOG_BIOS,LOG_NORMAL)("BIOS INT14: port %d does not exist.",reg_dx);
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
switch (reg_ah)
|
switch (reg_ah) {
|
||||||
{
|
case 0x00: {
|
||||||
case 0x00: /* Init port */
|
// Initialize port
|
||||||
// Parameters:
|
// Parameters: Return:
|
||||||
// AL: port parameters
|
// AL: port parameters AL: modem status
|
||||||
// Return:
|
// AH: line status
|
||||||
// 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;}
|
|
||||||
|
|
||||||
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
|
baudresult = (Bit16u)(115200 / baudrate);
|
||||||
IO_WriteB(port,(Bit8u)baudresult&0xff);
|
|
||||||
IO_WriteB(port+1,(Bit8u)(baudresult>>8));
|
|
||||||
|
|
||||||
// set line parameters, disable divider access
|
IO_WriteB(port+3, 0x80); // enable divider access
|
||||||
IO_WriteB(port+3, reg_al&0x1F);//LCR
|
IO_WriteB(port, (Bit8u)baudresult&0xff);
|
||||||
|
IO_WriteB(port+1, (Bit8u)(baudresult>>8));
|
||||||
// disable interrupts
|
|
||||||
IO_WriteB(port+1, 0);
|
|
||||||
IO_ReadB(port+2);
|
|
||||||
|
|
||||||
// get result
|
// set line parameters, disable divider access
|
||||||
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
|
IO_WriteB(port+3, reg_al&0x1F); // LCR
|
||||||
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
|
|
||||||
CALLBACK_SCF(false);
|
// 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;
|
break;
|
||||||
case 0x01: /* Write character */
|
}
|
||||||
// Parameters:
|
case 0x01: { // Transmit character
|
||||||
// AL: character
|
// Parameters: Return:
|
||||||
// Return:
|
// AL: character AL: unchanged
|
||||||
// AH: line status
|
// AH: 0x01 AH: line status from just before the char was sent
|
||||||
// AL: modem status
|
// (0x80 | unpredicted) in case of timeout
|
||||||
{
|
// [undoc] (0x80 | line status) in case of tx timeout
|
||||||
if(serialports[reg_dx]) {
|
// [undoc] (0x80 | modem status) in case of dsr/cts timeout
|
||||||
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);
|
|
||||||
|
|
||||||
// RTS off
|
// set DTR & RTS on
|
||||||
IO_WriteB(port+4,0x1);
|
IO_WriteB(port+4,0x3);
|
||||||
// get result
|
|
||||||
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
|
// wait for DSR & CTS
|
||||||
if(timeout) reg_ah |= 0x80;
|
reg_ah = INT14_Wait(port+6, 0x30, timeout);
|
||||||
else reg_al=buffer;
|
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
|
case 0x03: // get status
|
||||||
{
|
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
|
||||||
reg_ah=(Bit8u)(IO_ReadB(port+5)&0xff);
|
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
|
||||||
reg_al=(Bit8u)(IO_ReadB(port+6)&0xff);
|
CALLBACK_SCF(false);
|
||||||
CALLBACK_SCF(false);
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
return CBRET_NONE;
|
return CBRET_NONE;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
* 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 <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -40,8 +40,10 @@
|
|||||||
#define EMM_MAX_PAGES (32 * 1024 / 16 )
|
#define EMM_MAX_PAGES (32 * 1024 / 16 )
|
||||||
#define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */
|
#define EMM_MAX_PHYS 4 /* 4 16kb pages in pageframe */
|
||||||
|
|
||||||
#define EMM_VERSION 0x40
|
#define EMM_VERSION 0x40
|
||||||
#define GEMMIS_VERSION 0x0001 // Version 1.0
|
#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 EMM_SYSTEM_HANDLE 0x0000
|
||||||
#define NULL_HANDLE 0xffff
|
#define NULL_HANDLE 0xffff
|
||||||
@ -180,8 +182,15 @@ bool device_EMM::ReadFromControlChannel(PhysPt bufptr,Bit16u size,Bit16u * retco
|
|||||||
}
|
}
|
||||||
case 0x02:
|
case 0x02:
|
||||||
if (size!=2) return false;
|
if (size!=2) return false;
|
||||||
mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4.0
|
mem_writeb(bufptr+0x00,EMM_VERSION>>4); // version 4
|
||||||
mem_writew(bufptr+0x01,EMM_VERSION&0x0f);
|
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;
|
*retcode=2;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1177,8 +1186,7 @@ static Bitu V86_Monitor() {
|
|||||||
static void SetupVCPI() {
|
static void SetupVCPI() {
|
||||||
vcpi.enabled=false;
|
vcpi.enabled=false;
|
||||||
|
|
||||||
/* Allocate one EMS-page for private VCPI-data in memory beyond 1MB */
|
vcpi.ems_handle=0; // use EMM system handle for VCPI data
|
||||||
if (EMM_AllocateMemory(1,vcpi.ems_handle,false) != EMM_NO_ERROR) return;
|
|
||||||
|
|
||||||
vcpi.enabled=true;
|
vcpi.enabled=true;
|
||||||
|
|
||||||
@ -1259,9 +1267,10 @@ class EMS: public Module_base {
|
|||||||
private:
|
private:
|
||||||
/* location in protected unfreeable memory where the ems name and callback are
|
/* location in protected unfreeable memory where the ems name and callback are
|
||||||
* stored 32 bytes.*/
|
* stored 32 bytes.*/
|
||||||
static Bit16u emsnameseg;
|
static Bit16u ems_baseseg;
|
||||||
RealPt old4b_pointer,old67_pointer;
|
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:
|
public:
|
||||||
EMS(Section* configuration):Module_base(configuration){
|
EMS(Section* configuration):Module_base(configuration){
|
||||||
@ -1280,24 +1289,21 @@ public:
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BIOS_ZeroExtendedSize(true);
|
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 */
|
/* Register the ems device */
|
||||||
//TODO MAYBE put it in the class.
|
//TODO MAYBE put it in the class.
|
||||||
DOS_Device * newdev = new device_EMM();
|
DOS_Device * newdev = new device_EMM();
|
||||||
DOS_AddDevice(newdev);
|
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 */
|
/* Clear handle and page tables */
|
||||||
Bitu i;
|
Bitu i;
|
||||||
@ -1315,7 +1321,7 @@ public:
|
|||||||
emm_segmentmappings[i].handle=NULL_HANDLE;
|
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;
|
if (!ENABLE_VCPI) return;
|
||||||
@ -1365,6 +1371,7 @@ public:
|
|||||||
~EMS() {
|
~EMS() {
|
||||||
Section_prop * section=static_cast<Section_prop *>(m_configuration);
|
Section_prop * section=static_cast<Section_prop *>(m_configuration);
|
||||||
if (!section->Get_bool("ems")) return;
|
if (!section->Get_bool("ems")) return;
|
||||||
|
|
||||||
/* Undo Biosclearing */
|
/* Undo Biosclearing */
|
||||||
BIOS_ZeroExtendedSize(false);
|
BIOS_ZeroExtendedSize(false);
|
||||||
|
|
||||||
@ -1375,7 +1382,7 @@ public:
|
|||||||
|
|
||||||
/* Remove the emsname and callback hack */
|
/* Remove the emsname and callback hack */
|
||||||
char buf[32]= { 0 };
|
char buf[32]= { 0 };
|
||||||
MEM_BlockWrite(PhysMake(emsnameseg,0),buf,32);
|
MEM_BlockWrite(PhysMake(ems_baseseg,0),buf,32);
|
||||||
RealSetVec(0x67,old67_pointer);
|
RealSetVec(0x67,old67_pointer);
|
||||||
|
|
||||||
/* Release memory allocated to system handle */
|
/* Release memory allocated to system handle */
|
||||||
@ -1388,9 +1395,6 @@ public:
|
|||||||
|
|
||||||
if ((!ENABLE_VCPI) || (!vcpi.enabled)) return;
|
if ((!ENABLE_VCPI) || (!vcpi.enabled)) return;
|
||||||
|
|
||||||
/* Free private data area in expanded memory */
|
|
||||||
EMM_ReleaseMemory(vcpi.ems_handle);
|
|
||||||
|
|
||||||
if (cpu.pmode && GETFLAG(VM)) {
|
if (cpu.pmode && GETFLAG(VM)) {
|
||||||
/* Switch back to real mode if in v86-mode */
|
/* Switch back to real mode if in v86-mode */
|
||||||
CPU_SET_CRX(0, 0);
|
CPU_SET_CRX(0, 0);
|
||||||
@ -1414,4 +1418,4 @@ void EMS_Init(Section* sec) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Initialize static members
|
//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