home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 3
/
FREEWARE.BIN
/
towns_os
/
cdur
/
cdur.c
< prev
next >
Wrap
Text File
|
1980-01-02
|
12KB
|
453 lines
/* */
/* Cdur.C ( Cdur.EXE LSI-C86 用ソース) */
/* */
/* 書式 Cdur CD を 全曲リピート再生 */
/* Cdur STOP CD を 停止する */
/* Cdur PLAY [ start [end [loop]]] */
/* CD を start曲目から end曲目まで */
/* loop 回 再生 */
/* デフォルト start = 0 */
/* end = 99 */
/* loop = 1 */
/* */
/* v1.00 90/11/24 By T.Takasaka */
/* ---- ひかりNET,まぐろBBS にuplload ---- */
/* v1.01 90/12/12 bugfix */
/* 一部アセンブラ化(cdstop) */
/* パラメータ数値の範囲検査をする */
/* ---- FTOWNS1,まぐろBBS に upload 90/12/13 ---- */
/* v1.01a 90/12/13 time のbugfix */
/* v1.02 90/12/13 STAT をつける */
/* v1.03 90/12/30 vol をつける */
/* */
/* */
/* TAKACHAN ( IMA00356 ひかりNET ) */
/* おくと ( PEE01566 NIFTY-Serve ) */
/* */
/* PS. C-Dur は ドイツ語で ハ長調の意味です */
#define Cdur_version "v1.03"
#define Cdur_date "90/12/30"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <machine.h>
#define chkcode(track) ((cd_info.cd_time[(track)-1].cd_min) & 0x80)
#define cd_all_flame \
(cd_info.all_min*4500+cd_info.all_sec*75+cd_info.all_flame)
#define VOL_MAX 63
#define VOL1_DAT 0x04e0
#define VOL1_COM 0x04e1
#define VOL2_DAT 0x04e2
#define VOL2_COM 0x04e3
typedef struct{
unsigned char cd_min,cd_sec,cd_flame;
} CD_TIME;
typedef struct{
CD_TIME start_t,end_t;
} ENSOU_T;
typedef struct{
unsigned char dummy1,cd_flame,dummy2;
CD_TIME track_t;
unsigned char dummy3;
CD_TIME disk_t;
} ENSOU_STAT;
typedef struct{
unsigned char cd_type,start_track,end_track;
unsigned char all_min,all_sec,all_flame;
CD_TIME cd_time[98];
} TOC;
int setvol(int vol_no,int left,int right)
/* ボリュームセット
vol_no = 0 : line in
vol_no = 1 : cd
vol_no = 2 : mic
vol_no = 3 : modem
*/
{
unsigned char mix;
mix = ((left + right)/2) & VOL_MAX ;
left = left & VOL_MAX;
right = right & VOL_MAX;
switch (vol_no)
{
case 0:
if ( left > 0 ){
outp( VOL1_COM , 0x04 );
} else {
outp( VOL1_COM , 0x00 );
}
outp( VOL1_DAT , (unsigned char)left );
if ( right > 0 ){
outp( VOL1_COM , 0x05 );
} else {
outp( VOL1_COM , 0x01 );
}
outp( VOL1_DAT , (unsigned char)right );
if ( left == right ){
printf ("\n\x1b[32mLINEのvolumeを %d に設定しました。\x1b[0m\n"
,left);
}else{
printf("\n\x1b[32mLINEのvolumeを 左:%d 右:%d に設定しました。\x1b[0m\n" ,left,right);
}
break;
case 1:
if ( left > 0 ){
outp( VOL2_COM , 0x04 );
} else {
outp( VOL2_COM , 0x00 );
}
outp( VOL2_DAT , (unsigned char)left );
if ( right > 0 ){
outp( VOL2_COM , 0x05 );
} else {
outp( VOL2_COM , 0x01 );
}
outp( VOL2_DAT , (unsigned char)right );
if ( left == right ){
printf ("\n\x1b[32mCDのvolumeを %d に設定しました。\x1b[0m\n"
,left);
}else{
printf ("\n\x1b[32mCDのvolumeを 左:%d 右:%d に設定しました。\x1b[0m\n"
,left,right);
}
break;
case 2:
if ( mix > 0 ){
outp( VOL2_COM , 0x02 );
outp( VOL2_DAT , mix );
} else {
outp( VOL2_COM , 0x00 );
}
printf ("\n\x1b[32mMICのvolumeを %d に設定しました。\x1b[0m\n"
,mix );
break;
case 3:
if ( mix > 0 ){
outp( VOL2_COM , 0x03 );
outp( VOL2_DAT , mix );
} else {
outp( VOL2_COM , 0x00 );
}
printf ("\n\x1b[32mMODEMのvolumeを %d に設定しました。\x1b[0m\n"
,mix );
break;
default:
return(-1);
}
return(0);
}
int get_cd_stat()
{
union REGS reg;
struct SREGS sreg;
ENSOU_STAT cd_stat;
reg.x.ax = 0x53c0;
reg.x.cx = 0x0000;
reg.x.di = FP_OFF(&cd_stat);
sreg.ds = FP_SEG(&cd_stat);
int86x(0x93,®,®,&sreg) ;
if ( reg.h.ah == 0 ){
if ( reg.h.al != 0 ) {
printf("\n %d 曲目を演奏しています。CD先頭から %d分 %d秒\n"
,cd_stat.cd_flame,cd_stat.disk_t.cd_min,cd_stat.disk_t.cd_sec);
}
else {
printf("\nCDを演奏していません。\n");
}
}
return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 );
}
int read_cd_info(TOC *cd_info)
/* */
{
union REGS reg;
struct SREGS sreg;
reg.x.ax = 0x54c0;
reg.x.cx = 0x0000;
reg.x.di = FP_OFF(cd_info);
sreg.ds = FP_SEG(cd_info);
int86x(0x93,®,®,&sreg) ;
return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 );
}
int cd_stop(); /* アセンブラ化しました cd_stop.a86 */
/*
{
union REGS reg;
reg.x.ax = 0x52c0;
reg.x.cx = 0x0000;
int86(0x93,®,®) ;
return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 );
}
*/
int _asm_time(char *, int );
#define stop_time_asm(c) _asm_time("\n\
\tMOV\tCH,255\n\
\tMOV\tCL,AL\n\
\tMOV\tAX,21184\n\
\tINT\t147\n\
\tXOR\tAL,AL\n\
\tCMP\tAH,128\n\
\tJNE\t__aaa\n\
\tMOV\tAL,CL\n\
__aaa:\t", c )
/* インラインアセンブラ化したけどあまり意味がないなぁ */
int cd_time(int time)
{
int err_v;
if ( ( err_v = stop_time_asm( time ) ) == 0 ){
if ( time != 0 )
printf ("\n\x1b[32mCDドライブの停止時間を %d 秒に設定しました。\x1b[0m\n"
,time);
else
printf ("\n\x1b[32mCDドライブが停止しないように設定しました。\x1b[0m\n") ;
}
return( err_v );
}
/*
{
union REGS reg;
reg.x.ax = 0x52c0;
reg.x.cx = ( 0xff00 | ( time & 0x00ff) ) ;
int86(0x93,®,®) ;
if ( reg.h.ah== 0 ){
if ( time != 0 )
printf ("\n\x1b[32mCDドライブの停止時間を %d 秒に設定しました。\x1b[0m\n"
,time);
else
printf ("\n\x1b[32mCDドライブが停止しないように設定しました。\x1b[0m\n") ;
}
return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 );
}
*/
int cd_start(ENSOU_T *ensou_time,int kaisuu)
{
union REGS reg;
struct SREGS sreg;
reg.x.ax = 0x50c0;
if ( kaisuu == 0 )
reg.x.cx = 0xff01 ;
else if ( kaisuu == 1 )
reg.x.cx = 0x0001 ;
else {
reg.x.cx = 0xfe01;
reg.h.bh = kaisuu-1;
}
reg.x.di = FP_OFF(ensou_time);
sreg.ds = FP_SEG(ensou_time);
int86x(0x93,®,®,&sreg);
return( (reg.h.ah == 0x80) ? reg.h.ah*256 + reg.h.cl : reg.h.ah *256 );
}
long int calc_flame(CD_TIME time)
{
return((time.cd_min & 0x7f)*60*75+time.cd_sec*75+time.cd_flame);
}
CD_TIME calc_time(long int flame)
{
CD_TIME time;
time.cd_min=flame/(60*75);
time.cd_sec=(flame-time.cd_min*60*75)/75;
time.cd_flame=flame-time.cd_min*75*60-time.cd_sec*75;
return(time);
}
int calc_ensou(int start,int end,TOC cd_info,ENSOU_T *ensou)
/*
入力 演奏開始track no. 演奏終了track no.
cd_info
*/
{
if (start<cd_info.start_track) start=cd_info.start_track;
if (chkcode(start) !=0) start++;
if (start>cd_info.end_track) start=cd_info.end_track;
if (start==cd_info.end_track && chkcode(start)!=0)
return(-1);
if (end>cd_info.end_track) end=cd_info.end_track;
if (chkcode(end) !=0) end--;
if (end<cd_info.start_track) end=cd_info.start_track;
if (end==cd_info.start_track && chkcode(end)!=0)
return(-1);
if (start>end) return(-1);
(*ensou).start_t=cd_info.cd_time[start-1];
if (end==cd_info.end_track)
(*ensou).end_t=calc_time(cd_all_flame -1);
else
(*ensou).end_t=calc_time(calc_flame(cd_info.cd_time[end])-1);
return(start*256+end);
}
void err_r( int erf )
{
if ( erf == 0x0200 )
printf ("\n\x1b[31mデバイス番号エラー\x1b[0m\n");
if ( erf == 0x1000 )
printf ("\n\x1b[31m音楽演奏中\x1b[0m\n");
if ( erf == 0x8001 )
printf ("\n\x1b[31mCDがはいっていません。\x1b[0m\n");
if ( erf == 0x8002 )
printf ("\n\x1b[31mパラメータエラー\x1b[0m\n");
if ( erf == 0x8004 )
printf ("\n\x1b[31mドライブがつながっていません。\x1b[0m\n");
if ( erf == 0x8008 )
printf ("\n\x1b[31mコマンド異常終了\x1b[0m\n");
if ( erf == 0x8010 )
printf ("\n\x1b[31mCDが読み取れません。\x1b[0m\n");
if ( erf == 0x8080 )
printf ("\n\x1b[31mCDが交換されました。\x1b[0m\n");
if (erf == -1 ){
puts(" ");
puts(" 書式 Cdur CD を 全曲リピート再生 ");
puts(" Cdur STOP CD を 停止する ");
puts(" Cdur PLAY [ start [ end [ loop ]]] ");
puts(" CD を start曲目から end曲目まで ");
puts(" loop 回 再生 ");
puts(" loop=0 で止めるまで連続再生 ");
puts(" Cdur TIME [time] ");
puts(" CDが停止するまでの時間を設定する ");
puts(" timeの単位は秒、 0 で止まらない ");
puts(" Cdur STAT CD を 演奏情報を表示する ");
puts(" Cdur VOL [ [ { CD | LINE | MIC | MODEM } ");
puts(" [ left_vol [ right_vol ] ] ] ] ");
puts(" ");
}
}
int cd_play_main(int start,int end,int kaisuu)
{
ENSOU_T ensou_time;
TOC cd_info;
int tim,erf,erf1;
cd_stop();
for (tim=0,erf=1;tim<2 && erf!=0 ;tim++)
erf=read_cd_info(&cd_info);
if ( erf!= 0 ) return(erf);
if ((erf1=calc_ensou(start,end,cd_info,&ensou_time))==-1 )
return(0x8002);
if ((erf=cd_start(&ensou_time,kaisuu))!=0) return(erf);
if ((erf1/256)==(erf1 % 256))
printf("\n\x1b[36m %d 曲目を",(erf1 / 256));
else
printf("\n\x1b[36m %d 曲目から %d 曲目まで",(erf1/256),(erf1 % 256));
if ( kaisuu == 0)
printf("繰り返し演奏します\x1b[0m\n");
else if (kaisuu==1)
printf("演奏します\x1b[0m\n");
else if (kaisuu>=1)
printf(" %d 回演奏します\x1b[0m\n",kaisuu);
return(0);
}
main(int argc,char *argv[])
{
int start=1, end=99, kaisuu=1, time=0 ,erf=-1;
int vol_set = 1,vol_left=VOL_MAX,vol_right=VOL_MAX;
printf("\n\x1b[32m");
printf("*** \x1b[36mCdur.exe \x1b[31m♪\x1b[32m ");
printf( Cdur_version );
printf( " " );
printf( Cdur_date );
printf(" By おくと ***\n\x1b[0m");
if (argc==1){
erf=cd_play_main(0,99,0);
}
if (argc>=2 && strcmpi(argv[1],"stop")== 0 ){
erf=cd_stop();
if ( erf== 0 )
printf ("\n\x1b[1;34mCDを停止しました。\x1b[0m\n");
}
if (argc>=2 && strcmpi(argv[1],"play")== 0 ){
if (argc>=3) start = atoi(argv[2]) ;
if (argc>=4) end = atoi(argv[3]) ;
if (argc>=5) kaisuu = atoi(argv[4]) ;
if ( 0<=start && start<=99 && 0<=end && end<=99
&& 0<=kaisuu && kaisuu<=256 )
erf=cd_play_main(start,end,kaisuu);
}
if (argc>=2 && strcmpi(argv[1],"time")== 0 ){
if (argc>=3) time = atoi(argv[2]) ;
if ( 0 <= time && time <= 255 ) erf = cd_time(time) ;
}
if ( argc==2 && strcmpi(argv[1],"stat")== 0 ){
erf=get_cd_stat();
}
if ( argc>=2 && strcmpi(argv[1],"vol")== 0 ){
if ( argc== 5 ){
vol_left = atoi(argv[3]) ;
vol_right = atoi(argv[4]);
}
else if ( argc == 4 ) {
vol_left=vol_right=atoi(argv[3]) ;
}
if ( argc>=3 && strcmpi(argv[2],"cd") == 0 ) vol_set=1;
else if ( argc>=3 && strcmpi(argv[2],"line") == 0 ) vol_set=0;
else if ( argc>=3 && strcmpi(argv[2],"mic") == 0 ) vol_set=2;
else if ( argc>=3 && strcmpi(argv[2],"modem") == 0 ) vol_set=3;
if ( 0<= vol_left && vol_left<=VOL_MAX
&& 0<=vol_right && vol_right<=VOL_MAX)
erf = setvol( vol_set , vol_left , vol_right );
}
err_r(erf);
}