中国DOS联盟论坛

中国DOS联盟

-- 联合DOS 推动DOS 发展DOS --

联盟域名:www.cn-dos.net  论坛域名:www.cn-dos.net/forum
DOS,代表着自由开放与发展,我们努力起来,学习FreeDOS和Linux的自由开放与GNU精神,共同创造和发展美好的自由与GNU GPL世界吧!

游客:  注册 | 登录 | 命令行 | 搜索 | 上传 | 帮助 »
作者:
标题: DOS/WIN两栖的CD Player 上一主题 | 下一主题
happybasic
中级用户





积分 298
发帖 118
注册 2006-3-1
状态 离线
『楼 主』:  DOS/WIN两栖的CD Player 使用 LLM 解释/回答一下

可以在DOS下播入CD, 不需要MSCDEX的支持,
ps: 在WINDOWS下也可以哦~




欢迎光临happyBASIC小站:http://yxbasic.51.net
2007-4-7 06:25
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
Wengier
系统支持

“新DOS时代”站长


积分 27736
发帖 10521
注册 2002-10-9
状态 离线
『第 2 楼』:   使用 LLM 解释/回答一下

看日期是2007/04/06,是原创的吗?




Wengier - 新DOS时代

欢迎大家来到我的“新DOS时代”网站,里面有各类DOS软件和资料,地址:
http://wendos.mycool.net/

E-Mail & MSN: wengierwu AT hotmail.com (最近比较忙,有事请联系DOSroot和雨露,谢谢!)

2007-4-7 19:17
查看资料  发送邮件  访问主页  发短消息  网志  OICQ (29206679)  编辑帖子  回复  引用回复
happybasic
中级用户





积分 298
发帖 118
注册 2006-3-1
状态 离线
『第 3 楼』:   使用 LLM 解释/回答一下

当然了,俺一般要发就发原创。虽然比较差。。。




欢迎光临happyBASIC小站:http://yxbasic.51.net
2007-4-7 21:07
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
Wengier
系统支持

“新DOS时代”站长


积分 27736
发帖 10521
注册 2002-10-9
状态 离线
『第 4 楼』:   使用 LLM 解释/回答一下

楼上谦虚了,写得比较不错,支持原创!

建议加入按上下光标键调节音量的功能,并且可以按PageUp和PageDown键切换到上一首/下一首歌曲(PageUp/PageDown键切换歌曲比起F4/F5键似乎要更自然些)。

发现有一处笔误,“暂停”的英文应为PAUSE,而不是PASUE。另外建议除按F6键外也可以按空格键来暂停。




Wengier - 新DOS时代

欢迎大家来到我的“新DOS时代”网站,里面有各类DOS软件和资料,地址:
http://wendos.mycool.net/

E-Mail & MSN: wengierwu AT hotmail.com (最近比较忙,有事请联系DOSroot和雨露,谢谢!)

2007-4-7 22:32
查看资料  发送邮件  访问主页  发短消息  网志  OICQ (29206679)  编辑帖子  回复  引用回复
happybasic
中级用户





积分 298
发帖 118
注册 2006-3-1
状态 离线
『第 5 楼』:   使用 LLM 解释/回答一下

哎呀,这个笔误真是。。。已经改正了, 另你的建议也加了:

1.除按F6键外也可以按空格键来暂停。
2.除F4/F5键外也可以按PageUp和PageDown键切换到上一首/下一首歌曲。

至于按上下光标键调节音量的功能, 很多光驱模拟播放时,是不支持控制音量的啊,只能用前面板的电位器调...


附件 1: CDPLAY.rar (2007-4-8 00:37, 20.29 KiB,下载次数: 66)


欢迎光临happyBASIC小站:http://yxbasic.51.net
2007-4-8 00:37
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
Wengier
系统支持

“新DOS时代”站长


积分 27736
发帖 10521
注册 2002-10-9
状态 离线
『第 6 楼』:   使用 LLM 解释/回答一下

不知道楼主有没有兴趣给DOS下的MPlayer播放器写一个简单的文本方式的GUI界面?MPlayer可以在DOS下(包括纯DOS和CMD下)播放各种多媒体格式,包括AVI、MOV、MKV、MPG、RMVB、WMV,以及CD/VCD/DVD等,可惜就是只有命令行方式,没有一个像QV那样能选择文件的界面,所以使用起来有些不太方便。如果您愿意的话不妨给它写一个简单的文本方式的GUI界面试试看。更详细信息可见下面的帖子:

http://www.cn-dos.net/forum/viewthread.php?tid=16206&fpage=1
http://www.cn-dos.net/forum/viewthread.php?tid=28707&fpage=1




Wengier - 新DOS时代

欢迎大家来到我的“新DOS时代”网站,里面有各类DOS软件和资料,地址:
http://wendos.mycool.net/

E-Mail & MSN: wengierwu AT hotmail.com (最近比较忙,有事请联系DOSroot和雨露,谢谢!)

2007-4-13 02:39
查看资料  发送邮件  访问主页  发短消息  网志  OICQ (29206679)  编辑帖子  回复  引用回复
happybasic
中级用户





积分 298
发帖 118
注册 2006-3-1
状态 离线
『第 7 楼』:   使用 LLM 解释/回答一下

我试试看。。。




欢迎光临happyBASIC小站:http://yxbasic.51.net
2007-4-13 06:50
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
GOTOmsdos
铂金会员

C++启程者


积分 5154
发帖 1827
注册 2003-7-18
状态 离线
『第 8 楼』:   使用 LLM 解释/回答一下

DOS/WIN两栖的CD Player



这个程序只是DOS程序,在WIN, 要在WIN的DOS虚拟器的环境中才能运行.
所以,它不是DOS/WIN两栖的

不需要WIN的DOS虚拟器,就能运行的才是.
比如, win98的 REGEDIT


2007-4-13 08:09
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
defrag
中级用户

痴迷DOS者


积分 456
发帖 570
注册 2004-10-9
状态 离线
『第 9 楼』:  用WDOS/X 使用 LLM 解释/回答一下

用WDOS/X




DOS不是万能的,没有DOS是万万不能的
自古系统谁无死?留取胆清照汗青!uploadImages/20035317345478982.png
2007-5-4 20:51
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
happybasic
中级用户





积分 298
发帖 118
注册 2006-3-1
状态 离线
『第 10 楼』:   使用 LLM 解释/回答一下

WDOS/X是什么啊??没用过....




欢迎光临happyBASIC小站:http://yxbasic.51.net
2007-6-18 19:10
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
byxyk
初级用户





积分 112
发帖 54
注册 2007-6-18
状态 离线
『第 11 楼』:   使用 LLM 解释/回答一下

win32+stub ?


2007-6-19 00:35
查看资料  发短消息  网志   编辑帖子  回复  引用回复
xing7749
高级用户

文盲



积分 833
发帖 349
注册 2004-1-26
状态 离线
『第 12 楼』:   使用 LLM 解释/回答一下

看起来不错


2007-6-19 16:43
查看资料  发短消息  网志   编辑帖子  回复  引用回复
AlexZhang
系统支持





积分 995
发帖 427
注册 2007-2-8
状态 在线
『第 13 楼』:  Excellent 使用 LLM 解释/回答一下

Excellent!Successfully loaded and run under WindowsXP[sp2 build2600] environment withOUT any extra tools


2007-6-27 18:25
查看资料  访问主页  发短消息  网志   编辑帖子  回复  引用回复
happybasic
中级用户





积分 298
发帖 118
注册 2006-3-1
状态 离线
『第 14 楼』:   使用 LLM 解释/回答一下

最新版请到这里下载
http://yxbasic.51.net/zhxs-dostool.htm




欢迎光临happyBASIC小站:http://yxbasic.51.net
2008-12-3 20:21
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复
happybasic
中级用户





积分 298
发帖 118
注册 2006-3-1
状态 离线
『第 15 楼』:   [已使用 LLM 解释]

好久没有来了, 想不到还有不少人关注
分享一下源码....

/***************************************************************************
name: atapiEject
action: loads or ejects CD-ROM
returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiEject(driveinfo *Drive, bool Load)
{
u8 Pkt={ATAPI_CMD_START_STOP, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
drivecmd Cmd;

printf("atapiEject:");
memset(&Cmd, 0, sizeof(Cmd));

Pkt= (Load ? 3 : 2);

return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
name: atapiGetEventStatus
action: Get Disc is present && Tray opend or Closed
returns: whatever atapiCmd() returns
****************************************************************************/
static int atapiGetEventStatus(driveinfo *Drive, u8 *Buffer, unsigned Count)
{
u8 Pkt={ATAPI_CMD_GET_EVENT, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
drivecmd Cmd;

printf("atapiGetEventStatus:");
memset(&Cmd, 0, sizeof(Cmd));

Cmd.Count=Count;
Cmd.Data=Buffer;

Pkt=1;
Pkt=0x10;
Pkt=Count;

return(atapiCmd(Drive, &Cmd, Pkt));

}

/***************************************************************************
name: atapiChkTrayIsOpen
action: check cd-rom tray opened or closed
returns: 1 is opend , 0 is closed and -1 is Error
****************************************************************************/
static int atapiChkTrayIsOpen(driveinfo *Drive)
{
u8 Buffer;
int Temp;

Temp=atapiGetEventStatus(Drive, Buffer, 6);

if (Temp != 0)
{
return(-1);
}

return(Buffer&0x01); // Bit 0 is Tray Status, See SFF-8090 v6R7 P362
}

/***************************************************************************
name: atapiTOCEnt
action: reads one or more table-of-contents entries from audio CD
returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiTOCEnt(driveinfo *Drive, u8 *Buffer, unsigned Count)
{
u8 Pkt={ATAPI_CMD_READTOC, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
drivecmd Cmd;

printf("atapiTOCEnt:");
memset(&Cmd, 0, sizeof(Cmd));

Cmd.Count=Count;
Cmd.Data=Buffer;

Pkt=2;
Pkt=Count >> 8;
Pkt=Count;

return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
name: atapiTOC
action: reads table of contents of audio CD and prints starting
time of each track
returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiTOC(driveinfo *Drive)
{
u8 *Entry, Buffer;
int TOCEnt, Temp;

printf("atapiTOC:\n");

// 16-bit TOC length, 8-bit first track, 8-bit last track
TOCEnt = 4;

#ifdef DEBUG
printf(" calling atapiTOCEnt with Count=%u\n", TOCEnt);
#endif

// Read TOC
Temp=atapiTOCEnt(Drive, Buffer, TOCEnt);
if(Temp != 0)
{
return(Temp);
}

// NumTracks = LastTrack - FristTrack + 1
NumTracks=Buffer - Buffer + 1;

// Check NumTracks(must in range 1~99)
if(NumTracks <= 0 || NumTracks > 99)
{
printf(" error: bad number of tracks %d\n", NumTracks);
return(-1);
}

// Check MAX_TRACKS handle
if(NumTracks > MAX_TRACKS)
{
printf(" warning: too many tracks(%u); reducing to %u.\n",NumTracks, MAX_TRACKS);
NumTracks=MAX_TRACKS;
}

// read 4-byte header and 8-byte table-of-contents entries
TOCEnt = 4 + 8 * (NumTracks+1);

#ifdef DEBUG
printf(" calling atapiTOCEnt with Count=%u\n", TOCEnt);
#endif

// Read TOC
Temp=atapiTOCEnt(Drive, Buffer, TOCEnt);
if(Temp != 0)
{
return(Temp);
}

// point to first TOC entry
Entry=Buffer + 4;

// read NumTracks+1 entries the last entry is for the disk lead-out
for(Temp=0; Temp < NumTracks + 1; Temp++)
{
Track.Min=Entry;
Track.Sec=Entry;
Track.Frame=Entry;

printf("%02u:%02u:%02u ", Track.Min, Track.Sec, Track.Frame);

// advance to next entry
Entry += 8;
}

printf("\n");

return(0);
}

/***************************************************************************
name: atapiPlay
action: plays audio from time index Start to End (units of 1/75 sec)
returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiPlay(driveinfo *Drive, atapimsf *Start, atapimsf *End)
{
u8 Pkt={ATAPI_CMD_PLAY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
drivecmd Cmd;

printf("atapiPlay:");
memset(&Cmd, 0, sizeof(Cmd));

Pkt=Start->Min;
Pkt=Start->Sec;
Pkt=Start->Frame;

Pkt=End->Min;
Pkt=End->Sec;
Pkt=End->Frame;

return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
name: atapiPause
action: pauses or continues audio CD
returns:whatever atapiCmd() returns
****************************************************************************/
static int atapiPause(driveinfo *Drive, bool Continue)
{
u8 Pkt={ATAPI_CMD_PAUSE,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
drivecmd Cmd;

printf("atapiPause:");
memset(&Cmd, 0, sizeof(Cmd));

Pkt=Continue ? 1 : 0;

return(atapiCmd(Drive, &Cmd, Pkt));
}

/***************************************************************************
name: atapiStop
action: stop audio play or scan
return: whatever atapiCmd() returns
****************************************************************************/
static int atapiStop(driveinfo *Drive)
{
u8 Pkt={ATAPI_CMD_STOP,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
drivecmd Cmd;

printf("atapiStop:");
memset(&Cmd, 0, sizeof(Cmd));

return(atapiCmd(Drive, &Cmd, Pkt));
}
LLM 解释

ATAPI CD-ROM 控制功能模块解析

模块概述

该代码实现了通过ATAPI命令集控制CD-ROM设备的核心功能,包括托盘操作、TOC读取、播放控制等,适用于DOS环境下的CD播放应用开发。代码采用模块化设计,每个函数封装特定的ATAPI命令,通过构造12字节CDB(Command Descriptor Block)实现与CD-ROM驱动器的通信。

核心功能解析

1. 托盘控制函数
static int atapiEject(driveinfo *Drive, bool Load)
  • 功能:控制CD-ROM托盘弹出/关闭
  • 实现细节
    • 使用ATAPI_CMD_START_STOP命令(0x1B)
    • Pkt[4]位设置操作模式:0x03为关闭托盘,0x02为弹出托盘
    • 通过atapiCmd()发送命令并返回执行结果
2. 托盘状态检测
static int atapiChkTrayIsOpen(driveinfo *Drive)
  • 功能:检测托盘当前状态(打开/关闭)
  • 技术要点
    • 调用atapiGetEventStatus()获取事件状态
    • 解析返回缓冲区第5字节的第0位(依据SFF-8090 v6R7规范P362)
    • 返回值定义:1(打开)/0(关闭)/-1(错误)
3. TOC(目录表)读取
static int atapiTOC(driveinfo *Drive)
  • 功能:读取CD音轨信息并存储音轨起始时间
  • 处理流程
    1. 首次读取4字节获取TOC头部(包含首尾轨号)
    2. 计算音轨数量并校验有效性(1-99范围)
    3. 二次读取完整TOC数据(4字节头 + 8字节/轨 × (轨数+1))
    4. 解析每个音轨的起始时间(分:秒:帧格式)
  • 数据结构:使用Track[]数组存储各轨MSF(分/秒/帧)信息
4. 播放控制函数集
  • 播放atapiPlay()使用ATAPI_CMD_PLAY命令(0x43),通过Pkt[3-5]和Pkt[6-8]设置起止MSF时间
  • 暂停/继续atapiPause()使用ATAPI_CMD_PAUSE命令(0x4B),Pkt[8]位控制暂停(0)或继续(1)
  • 停止atapiStop()使用ATAPI_CMD_STOP命令(0x4E)终止当前播放

技术特点与兼容性

  1. ATAPI命令规范:严格遵循SCSI-2/ATAPI标准,命令包(CDB)长度固定为12字节,符合大多数IDE/ATAPI CD-ROM驱动器要求

  2. 错误处理:每个函数返回atapiCmd()的执行结果,便于上层调用者处理硬件通信错误

  3. 调试支持:通过#ifdef DEBUG条件编译提供调试信息输出,便于开发阶段问题定位

  4. 资源限制:定义MAX_TRACKS宏限制最大处理音轨数,防止缓冲区溢出

潜在优化方向

  1. 错误信息增强:可添加ATAPI错误码解析,提供更具体的故障原因
  2. 多驱动器支持:扩展driveinfo结构以支持多CD-ROM设备枚举
  3. 播放状态查询:实现ATAPI_CMD_GET_PERFORMANCE命令获取实时播放位置
  4. DOS环境适配:需补充实模式下的端口I/O函数(inb/outb)及中断处理代码

使用注意事项

  • 需实现atapiCmd()函数完成底层ATAPI命令发送与数据传输
  • driveinfo结构需包含CD-ROM驱动器的端口地址、DMA通道等硬件信息
  • 在DOS环境下使用时需注意内存模式(实模式/保护模式)对指针操作的影响
  • 音轨时间以CD标准帧率(75帧/秒)存储,转换为标准时间需进行帧到秒的换算

该模块可作为DOS/WIN两栖CD播放程序的底层驱动,通过条件编译区分不同环境下的I/O实现,从而达到跨平台兼容的目标。





欢迎光临happyBASIC小站:http://yxbasic.51.net
2009-3-13 11:02
查看资料  发送邮件  发短消息  网志   编辑帖子  回复  引用回复

请注意:您目前尚未注册或登录,请您注册登录以使用论坛的各项功能,例如发表和回复帖子等。


可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题



论坛跳转: