|
firstsail
高级用户
   
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
|
2008-2-27 14:42 |
|
|
fgckfl
初级用户
 
积分 46
发帖 22
注册 2006-11-13
状态 离线
|
『第 227 楼』:
用winsail开发的dos,win9x串口调试助手
使用 LLM 解释/回答一下
作的一个小程序,用winsail开发dos程序方便多了,很奇怪
该程序竟然在xp的c:盘下也可以通信,我用的是直接端口
操作,xp不是工作在保护模式下吗?firstsail能解释一下吗?
A small program I made. It's much more convenient to develop DOS programs with winsail. It's very strange. This program can actually communicate on the C: drive of XP. I used direct port operation. Doesn't XP work in protected mode? Could you, Firstsail, explain it?
|
|
2008-3-1 11:58 |
|
|
fgckfl
初级用户
 
积分 46
发帖 22
注册 2006-11-13
状态 离线
|
『第 228 楼』:
开发中遇到的几个问题-1,请郭兄及高手指点!
使用 LLM 解释/回答一下
1. “setsys.cpp” 文件中void far DisplayAttribSetting()函数中调用子程序::AddKeyboardString("SetSys 觞\xd");会在屏幕上显示“SetSys 觞”,如何屏蔽?
1. In the function `void far DisplayAttribSetting()` in the file "setsys.cpp", the subroutine `::AddKeyboardString("SetSys 觞\xd");` is called to display "SetSys 觞" on the screen. How to block it?
|
|
2008-3-1 12:13 |
|
|
fgckfl
初级用户
 
积分 46
发帖 22
注册 2006-11-13
状态 离线
|
『第 229 楼』:
开发中遇到的几个问题-2,请郭兄及高手指点!
使用 LLM 解释/回答一下
2.“demoser.cpp”文件中void far OnTime_DemoCUartDialog(CObject* pCurObj)函数,原准备作为定时器回调函数,可是似乎是程序太大,屏幕总是黑屏,后来用void OnTime_DemoCUartDialog1(CObject* pCurObj)为定时器回调函数,再调用void far OnTime_DemoCUartDialog(CObject* pCurObj)解决了上述问题,是否dos小中断函数大小有限制呢? 因为现在买不到dos编程得书,很多dos底层得东西不明白.
2. In the "demoser.cpp" file, the function `void far OnTime_DemoCUartDialog(CObject* pCurObj)` was originally prepared as a timer callback function. However, it seemed that the program was too large and the screen was always black. Later, `void OnTime_DemoCUartDialog1(CObject* pCurObj)` was used as the timer callback function, and then `void far OnTime_DemoCUartDialog(CObject* pCurObj)` was called to solve the above problem. Is there a limit on the size of DOS interrupt functions? Because now I can't buy books on DOS programming, and I don't understand many underlying DOS things.
|
|
2008-3-1 12:14 |
|
|
fgckfl
初级用户
 
积分 46
发帖 22
注册 2006-11-13
状态 离线
|
『第 230 楼』:
开发中遇到的几个问题-3,请郭兄及高手指点!
使用 LLM 解释/回答一下
3. “demoser.cpp”文件中 ,在void far OnTime_DemoCUartDialog(CObject* pCurObj)函数中,发现CMultiEdit编辑框有个很有意思现象.
Buf[]为串口接收的字符串, show_buf[]为格式化后显示的字符串, pEdit1为CMultiEdit*指针;
采用下面操作1:
strcat(show_buf,buf);
pEdit1->SetWindowText(show_buf);
pEdit1->Show();
将会在显示内容上自动换行
而采用如下操作2:
strcat(show_buf,"\n");
strcat(show_buf,buf);
pEdit1->SetWindowText(show_buf);
pEdit1->Show();
将会在显示内容上换2行
如:新接收buf[]=”abc1”, 原来显示内容show_buf[]=”123”;
采用操作1:显示为:
abc1
123
采用操作2:显示为
abc1
123
而采用操作3:
pEdit1->SetLineText(当前行数,buf);
pEdit1->Show();没反应
3. In the file "demoser.cpp", in the function void far OnTime_DemoCUartDialog(CObject* pCurObj), an interesting phenomenon is found in the CMultiEdit edit box.
Buf is the string received by the serial port, show_buf is the formatted string to be displayed, and pEdit1 is a CMultiEdit* pointer;
Adopt the following operation 1:
strcat(show_buf, buf);
pEdit1->SetWindowText(show_buf);
pEdit1->Show();
It will automatically wrap lines in the displayed content
And adopt the following operation 2:
strcat(show_buf, "\n");
strcat(show_buf, buf);
pEdit1->SetWindowText(show_buf);
pEdit1->Show();
It will wrap 2 lines in the displayed content
For example: newly received buf = "abc1", original displayed content show_buf = "123";
Adopt operation 1: the display is:
abc1
123
Adopt operation 2: the display is
abc1
123
And adopt operation 3:
pEdit1->SetLineText(current line number, buf);
pEdit1->Show(); no response
|
|
2008-3-1 12:14 |
|
|
fgckfl
初级用户
 
积分 46
发帖 22
注册 2006-11-13
状态 离线
|
『第 231 楼』:
上传程序为什么那么慢呢?
使用 LLM 解释/回答一下
上传程序太慢!!
Uploading the program is too slow!!
|
|
2008-3-1 12:15 |
|
|
firstsail
高级用户
   
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第 232 楼』:
使用 LLM 解释/回答一下
Originally posted by fgckfl at 2008-3-1 12:13:
1. “setsys.cpp” 文件中void far DisplayAttribSetting()函数中调用子程序::AddKeyboardString("SetSys 觞\xd");会在屏幕上显示“SetSys 觞”,如何屏蔽?
(1)如果在纯DOS或Win9x下运行,由于CPU运行速度快,人的眼睛是感觉不到的。
(2)如果在Win2000/WinXP下运行,由于命令行的解释器兼容问题,建议字符串加上"换行"标志。即::AddKeyboardString("SetSys 觞\xd\xa");
2.“demoser.cpp”文件中void far OnTime_DemoCUartDialog(CObject* pCurObj)函数,原准备作为定时器回调函数,可是似乎是程序太大,屏幕总是黑屏,后来用void OnTime_DemoCUartDialog1(CObject* pCurObj)为定时器回调函数,再调用void far OnTime_DemoCUartDialog(CObject* pCurObj)解决了上述问题,是否dos小中断函数大小有限制呢? 因为现在买不到dos编程得书,很多dos底层得东西不明白.
这可能是您的代码有错,可能的话贴上代码看一下,注意这时候的函数参数CObject* pCurObj是窗口指针
如果窗口是CWindows,则一般CWindow* pWindow = (CWindow *)pCurObj;
如果窗口是CDialog,则一般CDialog* pDialog = (CDialog *)pCurObj;
Last edited by firstsail on 2008-3-1 at 05:44 PM ]
Originally posted by fgckfl at 2008-3-1 12:13:
1. In the "setsys.cpp" file, the function void far DisplayAttribSetting() calls the subroutine ::AddKeyboardString("SetSys 觞\xd"), which will display "SetSys 觞" on the screen. How to block it?
(1) If running in pure DOS or Win9x, since the CPU runs at a fast speed, the human eye cannot perceive it.
(2) If running in Win2000/WinXP, due to the compatibility issue of the command line interpreter, it is recommended to add the "newline" flag to the string. That is, ::AddKeyboardString("SetSys 觞\xd\xa");
2. In the "demoser.cpp" file, the function void far OnTime_DemoCUartDialog(CObject* pCurObj) was originally prepared as a timer callback function. However, it seems that the program is too large and the screen is always black. Later, using void OnTime_DemoCUartDialog1(CObject* pCurObj) as the timer callback function and then calling void far OnTime_DemoCUartDialog(CObject* pCurObj) solves the above problem. Is there a limit on the size of DOS small interrupt functions? Because now I can't buy DOS programming books, and many underlying DOS things are not clear.
This may be an error in your code. If possible, paste the code and take a look. Note that the function parameter CObject* pCurObj at this time is the window pointer.
If the window is CWindows, generally CWindow* pWindow = (CWindow *)pCurObj;
If the window is CDialog, generally CDialog* pDialog = (CDialog *)pCurObj;
Last edited by firstsail on 2008-3-1 at 05:44 PM ]
|
|
2008-3-1 17:40 |
|
|
firstsail
高级用户
   
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第 233 楼』:
贴上CMulitEdit::SetWindowText(const char* pStr)源代码
使用 LLM 解释/回答一下
void CMultiEdit::SetWindowText(const char* pStr)
{
char buf;
int nLength = _fstrlen(pStr);
this->m_XmsMemoryData.InitListing(256);
int nPoint = 0;
for (int i = 0; i <= nLength; i++)
{
char ch = pStr;
if (ch == '\xd')
{
continue;
}
if (ch != '\xa' && ch != '\x0')
{
buf = ch;
buf = '\x0';
if (nPoint < EDIT_BUFFER_SIZE - 1)
{
continue;
}
}
nPoint = this->ModifyEditBuffer(buf, EDIT_BUFFER_SIZE);
DWORD dwLoc = this->m_XmsMemoryData.New(nPoint + 1, FALSE);
if (dwLoc == NULL)
{
continue;
}
this->m_XmsMemoryData.SetText(dwLoc, buf, nPoint + 1);
nPoint = 0;
*buf = '\0';
}
}
Last edited by firstsail on 2008-3-1 at 05:58 PM ]
void CMultiEdit::SetWindowText(const char* pStr)
{
char buf;
int nLength = _fstrlen(pStr);
this->m_XmsMemoryData.InitListing(256);
int nPoint = 0;
for (int i = 0; i <= nLength; i++)
{
char ch = pStr;
if (ch == '\xd')
{
continue;
}
if (ch != '\xa' && ch != '\x0')
{
buf = ch;
buf = '\x0';
if (nPoint < EDIT_BUFFER_SIZE - 1)
{
continue;
}
}
nPoint = this->ModifyEditBuffer(buf, EDIT_BUFFER_SIZE);
DWORD dwLoc = this->m_XmsMemoryData.New(nPoint + 1, FALSE);
if (dwLoc == NULL)
{
continue;
}
this->m_XmsMemoryData.SetText(dwLoc, buf, nPoint + 1);
nPoint = 0;
*buf = '\0';
}
}
Last edited by firstsail on 2008-3-1 at 05:58 PM ]
|
|
2008-3-1 17:50 |
|
|
pingziru
新手上路

积分 2
发帖 1
注册 2008-3-5
状态 离线
|
『第 234 楼』:
Sail3000工程实例为何无法Debug单步跟踪?
使用 LLM 解释/回答一下
Sail3000里面的例子在BC3.1下已编译通过,而且也能运行,可是想设断点或者单步跟踪一下,却无法跟进去,这是为何?
The examples in Sail3000 have been compiled and run successfully under BC 3.1, but I can't step in or set breakpoints. Why is that?
|
|
2008-3-5 14:32 |
|
|
godai
初级用户
 
积分 28
发帖 13
注册 2008-2-18
状态 离线
|
『第 235 楼』:
菜单和“打开”对话框
使用 LLM 解释/回答一下
郭兄, 新程序已下载试过了,Cmenu菜单已经可以了,感谢!:-)
除了Alt+F外,有没有方法可以用热键直接打开相应的菜单项? 如F1打开第一项一级菜单“文件”, F2打开第2项一级菜单“编辑”, F3打开第3项一级菜单“窗口”等类似这样的操作? 工业环境中有时用不到标准101/102键盘,太大; 这时就会考虑作模拟操作键盘,只模拟部分有用键。像“Alt+F” 这样的复合键就比较难以实现。
关于“打开”对话框,如果有接软驱,则读还是有问题: 插了A盘, 也还会出DOS提示符, 提示B盘没有准备好; 如果A盘里没插软盘,会直接产生DOS中断错误,从而退出程序。
另: 注意到了打开对话框加了“上一级目录”的按钮。另外的几个按钮可以控制吗?
如果选到相应的文件,可不可有消息通知当前选中高亮项的文件全路径名以便做操作,如预览类的处理?
Brother Guo, the new program has been downloaded and tested. The Cmenu menu is already okay. Thanks! :-)
Besides Alt+F, is there a way to directly open the corresponding menu item using a hotkey? For example, F1 opens the first top-level menu "File", F2 opens the second top-level menu "Edit", F3 opens the third top-level menu "Window" and similar operations? In industrial environments, sometimes the standard 101/102 keyboard is not used; it's too large. At this time, simulating an operation keyboard will be considered, only simulating some useful keys. Such composite keys like "Alt+F" are relatively difficult to implement.
Regarding the "Open" dialog box, if a floppy drive is connected, there is still a problem with reading: after inserting drive A, the DOS prompt still appears, prompting that drive B is not ready; if there is no floppy disk in drive A, a DOS interrupt error will directly occur, thus exiting the program.
Another point: I noticed that the "Up one level directory" button has been added to the open dialog box. Can the other several buttons be controlled? If the corresponding file is selected, can there be a message to notify the full path name of the currently selected highlighted item file for operations, such as preview processing?
|
|
2008-3-5 15:59 |
|
|
firstsail
高级用户
   
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第 236 楼』:
使用 LLM 解释/回答一下
(1)菜单增加了 F1激活菜单的第一项,F2激活菜单的第二项,...,F10激活菜单的第十项
(2)关于接软驱的问题,由于我周围找不到一台计算机装有软驱,所以代码无法测试,不过增加了absread()判断,但在windows下运行时总是错,错误代码为“权限拒绝”。
(3)如果用"_bios_disk()"或"biosdisk()"函数在纯DOS下是可行的,但在WinXP下运行时总是提示"企图直接仿问硬盘端口"
(4)希望“godai兄”给以指点
Last edited by firstsail on 2008-3-6 at 09:10 AM ]
(1) The menu is enhanced to have F1 activate the first item of the menu, F2 activate the second item,..., F10 activate the tenth item.
(2) Regarding the issue of connecting a floppy drive, since I can't find a computer with a floppy drive around me, the code can't be tested. However, absread() is added, but when running under Windows, it always has an error with the error code "Permission denied".
(3) If using the "_bios_disk()" or "biosdisk()" function, it works in pure DOS, but when running under WinXP, it always prompts "Attempt to directly access the hard disk port".
(4) Hope that Brother "godai" can give some guidance.
Last edited by firstsail on 2008-3-6 at 09:10 AM ]
|
|
2008-3-5 20:02 |
|
|
godai
初级用户
 
积分 28
发帖 13
注册 2008-2-18
状态 离线
|
『第 237 楼』:
使用 LLM 解释/回答一下
郭兄,您好!
程序已试, 菜单功能非常好用了, 谢谢! :-)
关于判断软盘或U盘程序,把我以前用过的一段程序copy上来,希望能对郭兄有点帮助:
用absread函数判断U盘(“D:”)是否存在; (隐掉的部分是用_bios_disk判断的程序):
BOOL IfUsbExist()
{//判断软盘是否存在
char buffer[512];
char ch[MAXPATH], ch1[50];
int Ifdrive = -1;
UINT nRetry;
char USBPATH[10];
strcpy(USBPATH, "D:"); //D盘为U盘
char cDrive=toupper(USBPATH[0])-'A';
//struct diskinfo_t di;
//di.drive = toupper(USBPATH[0])-'C'+0x80; //D驱USB
//di.head = 0;
//di.track = 0;
//di.sector = 1;
//di.nsectors = 1;
//di.buffer = buffer;
memset( buffer, 0, 512 );
Ifdrive = absread(cDrive,1,2,buffer);//Re_bios_disk( _DISK_READ, &di );
//no USB disk
if( Ifdrive!=0 ) return FALSE;
return TRUE;
}
BOOL IfFloppyExist()
{//判断软盘是否存在
char buffer[512];
struct diskinfo_t di;
int Ifdrive = -1;
char ch[MAXPATH], ch1[50];
UINT nRetry;
char FLOPPYPATH[10];
strcpy(FLOPPYPATH, "A:"); //软盘为A盘
memset( buffer, 0, 512 );
strcpy(ch,FLOPPYPATH);
di.drive = toupper(ch[0])-'A';
di.head = 1;
di.track = 1;
di.sector = 1;
di.nsectors = 1;
di.buffer = buffer;
Ifdrive = Re_bios_disk( _DISK_READ, &di );
//no floppy disk
if( Ifdrive != 0 ) return FALSE;
return TRUE;
}
UINT Re_bios_disk( unsigned cmd, struct diskinfo_t _FAR *dinfo )
{//retry _bios_disk for 3 times for anti noise
UINT ret;
for(char i=0;i<3;i++)
{
ret = _bios_disk( cmd, dinfo ) & 0xff00;
if(ret==0)
break;
}
return ret;
}
Hello, Brother Guo!
The program has been tested, and the menu functions are very easy to use. Thank you! :-)
Regarding the program to judge the floppy disk or USB flash drive, I will copy the segment of program I used before, hoping it can be a little help to Brother Guo:
Use the absread function to judge whether the USB flash drive ("D:") exists; (the hidden part is the program judged by _bios_disk):
BOOL IfUsbExist()
{//Judge whether the floppy disk exists
char buffer;
char ch, ch1;
int Ifdrive = -1;
UINT nRetry;
char USBPATH;
strcpy(USBPATH, "D:"); //The D drive is the USB flash drive
char cDrive = toupper(USBPATH) - 'A';
//struct diskinfo_t di;
//di.drive = toupper(USBPATH) - 'C' + 0x80; //D drive USB
//di.head = 0;
//di.track = 0;
//di.sector = 1;
//di.nsectors = 1;
//di.buffer = buffer;
memset(buffer, 0, 512);
Ifdrive = absread(cDrive, 1, 2, buffer); //Re_bios_disk(_DISK_READ, &di);
//No USB flash drive
if (Ifdrive!= 0) return FALSE;
return TRUE;
}
BOOL IfFloppyExist()
{//Judge whether the floppy disk exists
char buffer;
struct diskinfo_t di;
int Ifdrive = -1;
char ch, ch1;
UINT nRetry;
char FLOPPYPATH;
strcpy(FLOPPYPATH, "A:"); //The floppy disk is the A drive
memset(buffer, 0, 512);
strcpy(ch, FLOPPYPATH);
di.drive = toupper(ch) - 'A';
di.head = 1;
di.track = 1;
di.sector = 1;
di.nsectors = 1;
di.buffer = buffer;
Ifdrive = Re_bios_disk(_DISK_READ, &di);
//No floppy disk
if (Ifdrive != 0) return FALSE;
return TRUE;
}
UINT Re_bios_disk(unsigned cmd, struct diskinfo_t _FAR *dinfo)
{//Retry _bios_disk for 3 times to avoid noise
UINT ret;
for (char i = 0; i < 3; i++)
{
ret = _bios_disk(cmd, dinfo) & 0xff00;
if (ret == 0)
break;
}
return ret;
}
|
|
2008-3-6 15:29 |
|
|
firstsail
高级用户
   
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第 238 楼』:
使用 LLM 解释/回答一下
_bios_disk( cmd, dinfo )函数在以下操作系统中,
(1)纯DOS下正常运行
(2)Win9x下正常运行
(3)Win2000/WinXP下运行时总会弹出“不能直接仿问硬盘端口”的错误
初步分析是biosdisk或_bios_disk内部直接仿问了中断0x13,导致系统保护所致
“godai兄” 请明示!
Last edited by firstsail on 2008-3-6 at 06:30 PM ]
The function _bios_disk( cmd, dinfo ) under the following operating systems,
(1) Runs normally under pure DOS
(2) Runs normally under Win9x
(3) When running under Win2000/WinXP, it always pops up the error "Cannot directly access the hard disk port"
Preliminary analysis is that biosdisk or _bios_disk directly accesses interrupt 0x13 internally, resulting in system protection.
"Brother godai" please make it clear!
Last edited by firstsail on 2008-3-6 at 06:30 PM ]
|
|
2008-3-6 18:25 |
|
|
godai
初级用户
 
积分 28
发帖 13
注册 2008-2-18
状态 离线
|
『第 239 楼』:
使用 LLM 解释/回答一下
是的,我也试过了, 在Win2000/WinXP下运行是有这样的警告, 因为Win2000/WinXP下禁止了用户对BIOS一级的操作. 在纯DOS下运行_bios_disk函数没有问题. 这个问题在BIOS一级的操作上可能无法绕过Win2000/WinXP. 我原先编程的时候也是利用宏定义__WINXP__对Win2000/WinXP下和纯DOS下分别编译的两个版本运行的, 还没想出什么好办法. :-)
但是现在在纯DOS下的检测程序也有问题: 如果插上软盘,也会出现DOS提示符 "diskette B not ready", 如果没插软盘更会进入DOS错误中断INT25提示disk fail 之类的造成系统当机. 实用性还不如以前. 郭大大如果暂时也没有更好的办法还不如回到以前的版本不检测软盘,呵呵.
Yes, I have also tried. There are such warnings when running under Win2000/WinXP because user operations at the BIOS level are prohibited under Win2000/WinXP. There is no problem running the _bios_disk function under pure DOS. This problem may not be bypassed under Win2000/WinXP at the BIOS level. When I originally programmed, I also used the macro definition __WINXP__ to compile two versions for running under Win2000/WinXP and pure DOS respectively, and haven't come up with a good way yet. :-)
But now the detection program under pure DOS also has a problem: if a floppy disk is inserted, the DOS prompt "diskette B not ready" will also appear. If there is no floppy disk inserted, it will more likely enter the DOS error interrupt INT25 and prompt disk fail or something like that, causing the system to crash. The practicality is not as good as before. If Brother Guo doesn't have a better way for the time being, it's better to go back to the previous version without detecting the floppy disk, heh heh.
|
|
2008-3-6 19:21 |
|
|
firstsail
高级用户
   
积分 668
发帖 295
注册 2005-7-26 来自 广东深圳
状态 离线
|
『第 240 楼』:
使用 LLM 解释/回答一下
暂时恢复不检测软盘,请重新下载更新!
有一种思路是:读32位标志寄存器内容,如果“VM标志”即“虚拟8086状态标志”为“1”的话表示是在Windows下运行,不要用biosdisk函数判断软盘存在,如果标志为“0”,表示在纯DOS下运行,要用biosdisk函数判断软盘存在。
但是用以下的代码读到的标志寄存器的“高16位”总是"00000000",即永远无法知道是在“DOS虚拟机”下运行,“godai兄” 有没有其它的方法?
BOOL Is8086VM()
{
DWORD dwFlags;
asm pushfd
asm pop eax
asm mov dwFlags, eax
return ((0 == (dwFlags & (1L << 17))) ? TRUE : FALSE);
}
Last edited by firstsail on 2008-3-6 at 08:33 PM ]
Temporarily restore no floppy disk detection, please re-download the update!
There is an idea: read the content of the 32-bit flag register. If the "VM flag", that is, the "virtual 8086 state flag", is "1", it means running under Windows, and do not use the biosdisk function to judge the existence of the floppy disk. If the flag is "0", it means running under pure DOS, and use the biosdisk function to judge the existence of the floppy disk.
But the "high 16 bits" of the flag register read by the following code is always "00000000", that is, it is impossible to know whether it is running under the "DOS virtual machine" forever. Brother "godai", is there any other method?
BOOL Is8086VM()
{
DWORD dwFlags;
__asm pushfd
__asm pop eax
__asm mov dwFlags, eax
return ((0 == (dwFlags & (1L << 17))) ? TRUE : FALSE);
}
Last edited by firstsail on 2008-3-6 at 08:33 PM ]
|
|
2008-3-6 20:32 |
|
|