dosbox能否在windows下使用c 串口通信信

使用Win32API实现Windows下异步串口通讯(下)
&HANDLE m_hCom = CreateFile("com1",GENERIC_READ |
GENERIC_WRITE, 0, NULL,
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
&if (m_hCom == INVALID_HANDLE_VALUE)
&&cout&&"CreateFile
fail!"&&&return -1;
&cout&&"CreateFile
OK!"&&/SPAN&
&if(!SetupComm(m_hCom,))
&&cout&&"SetupComm fail!
Comm!"&&&CloseHandle(m_hCom);
&&return -1;
&cout&&"SetupComm
OK!"&&/SPAN&
COMMTIMEOUTS TimeO
memset(&TimeOuts,0,sizeof(TimeOuts));
TimeOuts.ReadIntervalTimeout = MAXDWORD;
TimeOuts.ReadTotalTimeoutConstant = 0;
TimeOuts.ReadTotalTimeoutMultiplier = 0;
TimeOuts.WriteTotalTimeoutConstant = 2000;
TimeOuts.WriteTotalTimeoutMultiplier = 50;
SetCommTimeouts(m_hCom,&TimeOuts);
&if (!GetCommState(m_hCom,&dcb))
&&cout&&"GetCommState fail!
close"&&&CloseHandle(m_hCom);
&&return -1;
&cout&&"GetCommState
&dcb.DCBlength = sizeof(dcb);
(!BuildCommDCB("9600,n,8,1",&dcb))//
&&cout&&"BuileCOmmDCB
close!"&&&CloseHandle(m_hCom);
&&return -1;
&if(SetCommState(m_hCom,&dcb))
&&cout&&"SetCommState
&OVERLAPPED wrO
&ZeroMemory(&wrOverlapped,sizeof(wrOverlapped));
&if (wrOverlapped.hEvent != NULL)
&&ResetEvent(wrOverlapped.hEvent);
&&wrOverlapped.hEvent =
CreateEvent(NULL,TRUE,FALSE,NULL);
typedef enum
&HEAT_BEAT, //
&NET_STATE,//
&PACKET& //
}ProtocolT
&Train_No,//
&Attemper_Command,//
&Revert_Command,//
&Replay_Command,//
KGL_SING&&&
}PacketDataT
typedef struct SerialNetProto
&unsigned long& PacketS
&ProtocolType& NetS
&PacketDataType DataT //
&unsigned long SourcedA //
&unsigned long DestinationA
&unsigned long
&unsigned long
&int DataLen = 100;
&char *pBuf = new char[DataLen];
&strcpy(pBuf,"Hello World!");
&DataLen&& =
strlen(pBuf);
&PacketHead M
&Myhead.DestinationAddr = 11;
&Myhead.SourcedAddr = 10;
&Myhead.DataType = Attemper_C
&Myhead.DataLength = DataL
&Myhead.NetState = PACKET;
&Myhead.PacketSize = sizeof(PacketHead) -
sizeof(unsigned long);
&Myhead.Offset = sizeof(Myhead.DestinationAddr)
+sizeof(Myhead.SourcedAddr) + sizeof(Myhead.DataType)
+sizeof(Myhead.DataLength) + sizeof(Myhead.NetState) +
sizeof(Myhead.PacketSize);
&char *pSendBuffer = new
char[sizeof(Myhead)+DataLen+ 4];//
&memcpy(pSendBuffer,"##",2);//
&memcpy(pSendBuffer+2,(char*)&Myhead,sizeof(Myhead));//
&memcpy(pSendBuffer+2+sizeof(Myhead),pBuf,DataLen);//
&memcpy(pSendBuffer+2+sizeof(Myhead)+DataLen,"@@",2);//
&DWORD dwE
&//DWORD dwWantSend = 100;
&DWORD dwRealSend = 0;
&char* pReadBuf = NULL;
(ClearCommError(m_hCom,&dwError,NULL))
&&PurgeComm(m_hCom,PURGE_TXABORT
| PURGE_TXCLEAR);
&&cout&&"PurgeComm
(!WriteFile(m_hCom,pSendBuffer,sizeof(Myhead)+DataLen+
4,&dwRealSend,&wrOverlapped))
&&if (GetLastError() ==
ERROR_IO_PENDING)
(!GetOverlappedResult(m_hCom,&wrOverlapped,&dwRealSend,FALSE))&&&{
(GetLastError() == ERROR_IO_INCOMPLETE)
&&&&&//cout&&"!"&&&&&&
&&&&&cout&&""&&&&&&ClearCommError(m_hCom,&dwError,NULL);
&DWORD dwE
&DWORD dwWantRead = 100;
&DWORD dwRealRead = 0;
&char* pReadBuf = new char[100];
(ClearCommError(m_hCom,&dwError,NULL))
&&PurgeComm(m_hCom,PURGE_TXABORT
| PURGE_TXCLEAR);
&&cout&&"PurgeComm
&if(!ReadFile(m_hComm,pReadBuf,dwWantRead,&RealRead,&wrOverlapped))
&&if(dwError =
GetLastError()==ERROR_IO_PENDING)
&&&While(GetOverlappedResult(m_hComm,&wrOverlapped,&dwRealRead,FALSE))
&&&&//............
&&&&cout&&"dwRealRead
MAX_SERIAL_BUFFER 4096
BOOL CanGetFullFrame(char* pReadBuf,int& dwRealRead)
&static char
Buf[MAX_SERIAL_BUFFER*2];//
&static unsigned long nFrameStart =
&static unsigned long nFrameEnd =
&static unsigned long nCurrectPos =
&char *pdest = NULL;
&if (pReadBuf && (dwRealRead!= 0))
&&memcpy(&Buf[nCurrectPos],pReadBuf,dwRealRead);
&&nCurrectPos = nCurrectPos +
(char*)Find(Buf,"##",MAX_SERIAL_BUFFER*2,2);
&if (pdest)
&&nFrameStart = unsigned
long(pdest - Buf);//
&else//"##"
&&Buf[0] =
Buf[nCurrectPos];//
&&nFrameStart = 0;
&&return FALSE;
(char*)Find(Buf,"@@",MAX_SERIAL_BUFFER*2,2);
&if (pdest)
&&nFrameEnd = unsigned long
(pdest - Buf+2);
&&dwRealRead= nFrameEnd -
&&memcpy(pReadBuf,&Buf[nFrameStart],dwRealRead);
&&nFrameStart =
&&nCurrectPos = nCurrectPos -
dwRealR//nCurrentPos
&&memcpy(Buf,&Buf[nFrameEnd],nCurrectPos);//
&&return TRUE;
&&return FALSE;
void* Find(const char *pSour,const char *pDest,int SourLen,int
&int i = 0, j = 0;
&while(i & SourLen && j &
&&if(*(pSour + i) == *(pDest +
&&&i =i - j +
&if(j == DestLen)
&&return (void*)(pSour + (i -
DestLen));
&&return NULL;
}Overlapped......
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。1364人阅读
windows platform(1)
c/c++(4)
Network(5)
windows下可以通过RFCOMM虚拟的串口进行通信.
RFCOMM简介:
RFCOMM仿真RS232串口,该仿真过程包括非数据通路状态的传输。RFCOMM不限制人工速率或步长,如果通信链路两端的设备都是负责将数据转发到其他通信介质的第二类设备,或在两端RFCOMM设备接口上进行数据传输,实际数据吞吐一般将反映波特率的设置.RFCOMM支持两个设备之间的多串口仿真,也支持多个设备多串口的仿真.
winsock支持RFCOMM,其地址是SOCKADDR_BTH,地址族是AF_BTH.
1.首先把蓝牙名字转换成能链接的地址。
ULONG CBlueTooth::NameToBthAddr( const char *pszRemoteName, PSOCKADDR_BTH pRemoteBtAddr)
iResult = CXN_SUCCESS;
bContinueLookup = FALSE, bRemoteDeviceFound = FALSE;
ulFlags = 0, ulPQSSize = sizeof(WSAQUERYSET);
hLookup = NULL;
PWSAQUERYSET
pWSAQuerySet = NULL;
ZeroMemory(pRemoteBtAddr, sizeof(*pRemoteBtAddr));
pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
ulPQSSize);
if ( NULL == pWSAQuerySet )
iResult = STATUS_NO_MEMORY;
if ( CXN_SUCCESS == iResult)
for ( int iRetryCount = 0;!bRemoteDeviceFound && (iRetryCount & CXN_MAX_INQUIRY_RETRY);iRetryCount++ )
ulFlags = LUP_CONTAINERS;
ulFlags |= LUP_RETURN_NAME;
ulFlags |= LUP_RETURN_ADDR;
if ( 0 != iRetryCount )
ulFlags |= LUP_FLUSHCACHE;
Sleep(CXN_DELAY_NEXT_INQUIRY * 1000);
iResult = CXN_SUCCESS;
hLookup = 0;
bContinueLookup = FALSE;
ZeroMemory(pWSAQuerySet, ulPQSSize);
pWSAQuerySet-&dwNameSpace = NS_BTH;
pWSAQuerySet-&dwSize = sizeof(WSAQUERYSET);
iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);
if ( (NO_ERROR == iResult) && (NULL != hLookup) )
bContinueLookup = TRUE;
} else if ( 0 & iRetryCount )
while ( bContinueLookup )
if ( NO_ERROR == WSALookupServiceNext(hLookup,
&ulPQSSize,
pWSAQuerySet) )
if ( ( pWSAQuerySet-&lpszServiceInstanceName != NULL ) &&
( CXN_SUCCESS == stricmp(pWSAQuerySet-&lpszServiceInstanceName, pszRemoteName) ) )
CopyMemory(pRemoteBtAddr,
(PSOCKADDR_BTH) pWSAQuerySet-&lpcsaBuffer-&RemoteAddr.lpSockaddr,
sizeof(*pRemoteBtAddr));
bRemoteDeviceFound = TRUE;
bContinueLookup = FALSE;
iResult = WSAGetLastError();
if ( WSA_E_NO_MORE == iResult )
bContinueLookup = FALSE;
else if ( WSAEFAULT == iResult )
HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
ulPQSSize);
if ( NULL == pWSAQuerySet )
iResult = STATUS_NO_MEMORY;
bContinueLookup = FALSE;
bContinueLookup = FALSE;
WSALookupServiceEnd(hLookup);
if ( STATUS_NO_MEMORY == iResult )
if ( NULL != pWSAQuerySet )
HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
pWSAQuerySet = NULL;
if ( bRemoteDeviceFound )
iResult = CXN_SUCCESS;
iResult = CXN_ERROR;
2.建立链接
DEFINE_GUID(g_guidServiceClass,0x,0x0000,0x1000,0x80,0x00,0x00,0x80,0x5f,0x9b,0x34,0xfb);
SOCKADDR_BTH
SockAddrBthServer= RemoteBthA
SockAddrBthServer.addressFamily = AF_BTH;
SockAddrBthServer.serviceClassId = g_guidServiceC
SockAddrBthServer.port = 0;
if (INVALID_SOCKET != LocalSocket)
closesocket(LocalSocket);
LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if ( INVALID_SOCKET == LocalSocket )
if ( 0 == connect(LocalSocket,
(struct sockaddr *) &SockAddrBthServer,
sizeof(SOCKADDR_BTH)) )
status=true;
3.发送数据
ResetEvent(hSendEvent);
int sum=0;
while (sum & PDU.size())
int iCount=send(LocalSocket,PDU.data()+sum,PDU.size()-sum,0);
if (iCount == SOCKET_ERROR)
bConnect = false;
4.接收数据
char buffer[100]={0};
int count=recv(LocalSocket,buffer,sizeof(buffer),0);
if (count & 0)
CurSum +=count;
if (0 != count)
for (int i=0;i&count;i++)
ReceiveBuffer.push_back(buffer[i]);
if(ReceiveBuffer.size() &= 6 && (DestSum == 8))
unsigned short int *p =(unsigned short int*)(ReceiveBuffer.data()+4);
DestSum += *p;
if (DestSum != 0 && CurSum &= DestSum)
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:7604次
排名:千里之外
原创:31篇
(2)(13)(6)(10)(1)(5)&&&&Windows Mobile 6下使用serialPort控件进行串口通讯的代码
Windows Mobile 6下使用serialPort控件进行串口通讯的代码
在仪表的Modbus通讯中,上位机可以是PLC、PC、PDA或智能手机。本人使用Windows Mobile 6操作系统下的多普达P660进行了上位机的编程。现在将调试程序说一下。
使用VS2005进行开发。
控件有3个button,两个TextBox,两个Label和一个SerialPort等。button1打开串口,button2将txtSend的字符发出,接收是自动的。接收txtReceive
若举报审核通过,可奖励20下载分
被举报人:
举报的资源分:
请选择类型
资源无法下载
资源无法使用
标题与实际内容不符
含有危害国家安全内容
含有反动色情等内容
含广告内容
版权问题,侵犯个人或公司的版权
*详细原因:
VIP下载&&免积分60元/年(1200次)
您可能还需要
操作系统下载排行后使用快捷导航没有帐号?
查看: 5592|回复: 1
注册时间最后登录阅读权限40积分504精华0帖子
举人, 积分 504, 距离下一级还需 496 积分
TA的每日心情开心 09:58签到天数: 4 天[LV.2]偶尔看看I
在没有网络,没用键盘,没有显示器的情况下,控制树莓派就成了一个问题。 通过串口通讯果断的试用了一次发现效果不错,下面就和大家一起分享一下。
所需设备:
1.raspberry pi 板子一块
2.一张SD卡(至少2G我们采用8G)
3.一根USB电源线(5v/700ma以上)
4.一根usb B型口线
5. 一个USB to TTL Board(USB 转串口)
6.3P 杜邦线一个
09:55 上传
具体操作过程:
下载系统镜像文件,并写入sd卡中
首先要把镜像文件下载到准备的sd卡上去,镜像文件可以到官网下载,在官网上可以看到多个不同的系统镜像,可以根据自己的需要下载所需的镜像。我下载了Raspbian “wheezy”这个镜像,接下来要把镜像文件写入到sd卡上去。把下载下来的zip文件解压以后,得到一个img文件。然后把sd卡通过读卡器插到电脑上,系统会自己挂载sd卡,千万不要直接直接把镜像文件拖进去,这样是没有用的。我们可以通过USB Image Tool将镜像文件写入到SD卡中。
09:54 上传
打开软件点击Favorites添加系统镜像文件,点击Restore开始将镜像文件写入到SD卡中。
09:54 上传
09:54 上传
这样一个带有系统的树莓派SD卡就制作完成了。在这是会看到8G的内存只剩下50多MB说明系统已经成功刷入到SD卡中,不见存储空间为Linux系统下的分区在Windows下部显示。
09:54 上传
串口的连接串口我使用的是USB to TTL Board,通常串口共有4根,分别为红,绿,白,黑。这里我们不需要从串口取电,所以红色的在这里不需要用到。
黑线是接地线(图中的ground),TXD(下图的GPIO 14),RXD(下图的GPIO 15)
09:56 上传
09:56 上传
此USB to TTL Board是不需要驱动,在电脑可以直接在设备管理中找到COM口,连接好线路后,将usb口连接到电脑上,然后使用PuTTY软件和串口进行通讯。打开软件选择serial设置串口号,波特率设置为115200。
09:54 上传
点击Open给树莓派上电会在窗口中看到类似Linux终端的界面。
09:54 上传
开机会加载系统文件当加载好内核文件后为我们输入账号和密码,账号是pi,密码为raspberry当我们输入无误后就可以访问系统中的目录文件。
09:54 上传
下面我们就可以尽情的享受树莓派神奇了,不用东奔西走的在寻找显示了,你还在犹豫么快买个pi上手试试吧让自己也成为 有pi一族。
注册时间最后登录阅读权限10积分28精华0帖子
白丁, 积分 28, 距离下一级还需 22 积分
TA的每日心情擦汗 10:50签到天数: 1 天[LV.1]初来乍到
看起来不错,只是如果显示图像界面有没有问题?
站长推荐 /3
日之前,在本活动页面下载Calibre/Veloce emulation 进阶攻略白皮书,就有几乎参与转盘抽奖并赢取小熊早餐蛋卷杯等众多精美奖品啦!快来参加吧!
CoM-P6UL集成了 ARM Cortex-A7 700Hz(MAX) 恩智浦 I.MX6UL 处理器,稳定运行Linux 3.14。日之前可在爱板网论坛免费申请,快来参加吧!
即日起,通过爱板网申请TI样片,即可免费赢取Kindle、200元京东券、KFC套餐券等多重好礼啦!邀请自己身边的好友,更可获得现金奖励哦!快来参加吧!
Powered by Discuz!1892人阅读
MFC应用(6)
转载请注明出处
&往串口发送数据用writefile, 有如下几个参数:
HANDLE hFile
之前用CreateFile打开的有效的串口句柄.
LPCVOID lpBuffer
待发送的数据缓冲区. 把要发送的数据放在这里.
DWORD nNumberOfBytesToWrite
这里指定要发送的字节数, 可以比发送缓冲区总字节数小,具体看实际应用中要发多少.
LPDWORD lpNumberOfBytesWritten
该值由函数返回, 指明函数返回时,实际发送成功的字节数. 这个值很有用, 有些时候,函数返回TRUE, 但由于一些原因(比如超时), 实际发送的少于nNumberOfBytesToWrite, 这种情况要继续发送.
LPOVERLAPPED lpOverlapped
这个参数指出当前发送数据,是用异步,还是用同步. 如果是前者, 传进一个指向OVERLAPPED变量的指针, 如果是后者,该值为NULL.
在同步模式下, 发送数据是比较简单的. 可以用类似下面的形式:
If(!WriteFile(hComm, buffer, strlen(buffer), &dwBytesWritten, NULL))
//错误处理.
一般情况下,WriteFile都会返回TRUE,数据就会按指定的长度发送成功. 如果想更安全一些,也可以加入类似下面这样的判断.
If(dwBytesWritten != strlen(buffer))
    //错误处理
在同步模式下,WriteFile会一直等待指定的数据发送完毕,直到超时,如果未指定超超时间,数据发送完毕之前,程序会一直挂起.
异步模式下的处理稍复杂一些. 首先, 如果WriteFile返回FALSE,不一定表示发送失败, 可以用GetLastError获取错误码,如果错误码是ERROR_IO_PENDING,表示操作正在进行, 这种不是真正的失败. 在错误码是ERROR_IO_PENDING的情况下, 可以用WaitForSingleObject等待操作完成.&
如果你做过windows下的多线程应用,应该比较熟悉这个函数. 通过串口发送数据时, 这个函数类似下面这样用:
dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
switch(dwRes)
// OVERLAPPED structure's event has been signaled.
case WAIT_OBJECT_0:
//错误处理
第一个参数osWrite.hEvent是要等待的事件, 第二个参数是超时时间. 要注意这个超时时间并不是前面讲到的读写超时时间. 它是WaitForSingleObject等待osWrite.hEvent变为有信号的时间.
举个例子,如果设置的写超超时间是5秒, WaitForSingleObject第二个参数用INFINITE, 如果5秒写操作还没有完成,这时出现写超时, 但WaitForSingleObject返回的是WAIT_OBJECT_0,而不是WAIT_TIMEOUT. 因为对WaitForSingleObject来说, 写操作已经完成了.为了避免混淆,建议WaitForSingleObject的第二个参数用INFINITE.
还有一点要注意, WaitForSingleObject返回WAIT_OBJECT_0, 并不表示发送是成功的, 只说明发送数据的操作完成了. 是否成功, 还要通过另一个函数GetOverlappedResult来判断. 这个函数有必要说明一下, 它有如下几个参数:
HANDLE hFile
LPOVERLAPPED lpOverlapped
指向OVERLAPPED变量的指针
LPDWORD lpNumberOfBytesTransferred
这个值返回实际发送的字节数
BOOL bWait
如果该值是TRUE,这个函数会一直等待操作完成才返回, 如果是FALSE, 该函数立即返回, 如果这个时候操作还没有完成, 函数返回FALSE, 用GetLastError可以获取错误码是ERROR_IO_INCOMPLETE
如果你细心的话可能已经发现, GetOverlappedResult也要传进一个指向OVERLAPPED变量的指针, 加上对bWait参数的描述, 很明显,这个函数跟WaitForSingleObject功能基本相同, 是的,在串口应用中,它们两个的用法基本相同, 当bWait为TRUE时, 跟WaitForSingleObject的第二个参数用INFINITE效果是一样的.&
但GetOverlappedResult可以判读操作是否成功, 方法就是当WaitForSingleObject返回WAIT_OBJECT_0时,调用GetOverlappedResult,如果它返回TRUE就表示操作成功完成, 否则表示操作失败. 调用过程类似下面的形式:
dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
switch(dwRes)
case WAIT_OBJECT_0:
if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, FALSE))
//操作失败
//操作成功完成
// An error has occurred in WaitForSingleObject.
//错误处理
这样,在异步模式下的写操作, 就可以用类似下面这样的语句来实现:
if (!WriteFile(hComm, lpBuf, dwToWrite, &dwWritten, &osWrite)) {
if (GetLastError() != ERROR_IO_PENDING)
//真正的出错情况
fRes = FALSE;
else// 操作还未完成, 等待操作完成
dwRes = WaitForSingleObject(osWrite.hEvent, INFINITE);
switch(dwRes)
case WAIT_OBJECT_0:// 写操作完成, 但不确定是否成功?
if (!GetOverlappedResult(hComm, &osWrite, &dwWritten, FALSE))
//操作失败,错误处理
//操作成功
//错误处理
有时候看到一些串口通信的代码并没有上面那样繁琐的判断. 有些只用了WaitForSingleObject,或者只用了GetOverlappedResult, 其实也是可以的, 有些简单的应用场合并没有必要做这么细致的流程设计, 上述流程是MSDN推荐的,应该算是比较完整和健壮的.
接收数据的操作跟发送数据差别不大,在接收数据之前, 一般会先用ClearCommError读取接收缓冲区中有多少未读的数据(未用ReadFile读取), 然后读取这个长度的数据. 如果读到的数据长度小于自己想要读的长度,则继续读.
ClearCommError获取接收缓冲区未读数据原理是传出一个指向COMSTAT 的参数变量, COMSTAT中的cbInQ&ue成员就是当前未被读出的接收到的数据长度.
这里有一个问题要讨论一下, 系统什么时候置cbInQue不为零呢, 答案是, 它跟前面讲到的读字节超时间隔有关系, 它的机制是几个byte超时时间内没有收到数据,认为这一次接收完成,然后用当前接收到的字节数置cbInQue.
举个例子, 设备返回给主机的字节一共有10个, 每隔100ms返回一个, 如果, ReadIntervalTimeout设置为10ms, 那么, 主机读到一个字节就会置cbInQue为1, 如果ReadIntervalTimeout设置大一些,比如100ms, 那么主机会读完10个字节才会置cbInQue为10.实际应用中,ReadIntervalTimeout应该设置大一些还是小一些要根据不同应用场合. 明白了原理,就可以灵活的应对各种应用
其实对于串口通信, 还有更复杂的高阶应用,在这些应用中会涉及到多线程, 窗体的消息传递与通知(与MFC结合)等, 如果有时间,后续我会接着写相关的文章. 但用上面讲到的那些,设计一个简单实用的串口通信类应该不成问题.
源码下载地址:
/pony-maggie/LKE_lke2600_CardReader
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1002153次
积分:9177
积分:9177
排名:第1564名
原创:224篇
转载:57篇
评论:323条
原创的博文,转载必须在明显位置注明出处和相关链接。交流可在文章评论或发邮件至:pony_
文章:28篇
阅读:41700
文章:25篇
阅读:238090
文章:39篇
阅读:156295
文章:10篇
阅读:137635
(2)(2)(5)(7)(8)(14)(8)(1)(2)(1)(3)(1)(3)(1)(4)(2)(3)(6)(15)(21)(1)(3)(6)(4)(11)(12)(9)(14)(5)(1)(1)(3)(3)(1)(1)(1)(2)(3)(2)(3)(4)(2)(1)(1)(2)(3)(2)(5)(1)(2)(3)(2)(3)(2)(7)(6)(46)

我要回帖

更多关于 dosbox安装windows98 的文章

 

随机推荐