home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 3 / FREEWARE.BIN / towns_os / cdur / cdur.c < prev    next >
Text File  |  1980-01-02  |  12KB  |  453 lines

  1. /*                                                                    */
  2. /*            Cdur.C            ( Cdur.EXE LSI-C86 用ソース)            */
  3. /*                                                                    */
  4. /*        書式    Cdur         CD を 全曲リピート再生                    */
  5. /*                Cdur STOP    CD を 停止する                            */
  6. /*                Cdur PLAY [ start [end [loop]]]                        */
  7. /*                            CD を start曲目から end曲目まで            */
  8. /*                            loop 回 再生                            */
  9. /*                            デフォルト     start =  0                    */
  10. /*                                        end      = 99                    */
  11. /*                                        loop  =  1                    */
  12. /*                                                                    */
  13. /*                v1.00    90/11/24    By T.Takasaka                    */
  14. /*               ---- ひかりNET,まぐろBBS にuplload ----            */
  15. /*                v1.01   90/12/12    bugfix                            */
  16. /*                                    一部アセンブラ化(cdstop)        */
  17. /*                                    パラメータ数値の範囲検査をする    */
  18. /*               ---- FTOWNS1,まぐろBBS に upload 90/12/13 ----        */
  19. /*                v1.01a    90/12/13    time のbugfix                    */
  20. /*                v1.02    90/12/13    STAT をつける                    */
  21. /*              v1.03   90/12/30    vol をつける                     */
  22. /*                                                                  */
  23. /*                                                                  */
  24. /*                                TAKACHAN ( IMA00356   ひかりNET )    */
  25. /*                                おくと     ( PEE01566 NIFTY-Serve )    */
  26. /*                                                                    */
  27. /*                        PS. C-Dur は ドイツ語で ハ長調の意味です    */
  28.  
  29. #define Cdur_version "v1.03"
  30. #define Cdur_date    "90/12/30"
  31.  
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <dos.h>
  36. #include <machine.h>
  37.  
  38. #define chkcode(track) ((cd_info.cd_time[(track)-1].cd_min) & 0x80) 
  39. #define    cd_all_flame \
  40.           (cd_info.all_min*4500+cd_info.all_sec*75+cd_info.all_flame)
  41.  
  42. #define    VOL_MAX 63
  43. #define VOL1_DAT 0x04e0
  44. #define VOL1_COM 0x04e1
  45. #define VOL2_DAT 0x04e2
  46. #define VOL2_COM 0x04e3
  47.  
  48.  
  49. typedef    struct{
  50.                     unsigned char cd_min,cd_sec,cd_flame;
  51.                 }    CD_TIME;
  52.  
  53. typedef    struct{
  54.                     CD_TIME start_t,end_t;
  55.                 }    ENSOU_T;
  56.  
  57. typedef    struct{
  58.                     unsigned char dummy1,cd_flame,dummy2;
  59.                     CD_TIME track_t;
  60.                     unsigned char    dummy3;
  61.                     CD_TIME disk_t;
  62.                 }    ENSOU_STAT;
  63.  
  64. typedef struct{
  65.                     unsigned char cd_type,start_track,end_track;
  66.                     unsigned char all_min,all_sec,all_flame;
  67.                     CD_TIME        cd_time[98];
  68.                 }    TOC;
  69.  
  70. int setvol(int vol_no,int left,int right)
  71. /* ボリュームセット 
  72.         vol_no = 0 : line in
  73.         vol_no = 1 : cd
  74.         vol_no = 2 : mic
  75.         vol_no = 3 : modem
  76. */
  77. {
  78.     unsigned char mix;
  79.  
  80.     mix  = ((left + right)/2) & VOL_MAX ;
  81.     left = left & VOL_MAX;
  82.     right = right & VOL_MAX;
  83.  
  84.     switch (vol_no)
  85.     {
  86.     case    0:
  87.         if ( left > 0 ){
  88.             outp( VOL1_COM , 0x04 );
  89.         } else {
  90.             outp( VOL1_COM , 0x00 );
  91.         }    
  92.         outp( VOL1_DAT , (unsigned char)left  );
  93.         if ( right > 0 ){
  94.             outp( VOL1_COM , 0x05 );
  95.         } else {
  96.             outp( VOL1_COM , 0x01 );
  97.         }    
  98.         outp( VOL1_DAT , (unsigned char)right  );
  99.             if ( left == right ){
  100.     printf ("\n\x1b[32mLINEのvolumeを %d に設定しました。\x1b[0m\n"
  101.                                                                         ,left);
  102.             }else{ 
  103. printf("\n\x1b[32mLINEのvolumeを 左:%d 右:%d に設定しました。\x1b[0m\n"                                                                ,left,right);
  104.             }    
  105.         break;
  106.     case    1:
  107.         if ( left > 0 ){
  108.             outp( VOL2_COM , 0x04 );
  109.         } else {
  110.             outp( VOL2_COM , 0x00 );
  111.         }    
  112.             outp( VOL2_DAT , (unsigned char)left  );
  113.         if ( right > 0 ){
  114.             outp( VOL2_COM , 0x05 );
  115.         } else {
  116.             outp( VOL2_COM , 0x01 );
  117.         }    
  118.             outp( VOL2_DAT , (unsigned char)right  );
  119.             if ( left == right ){
  120.         printf ("\n\x1b[32mCDのvolumeを %d に設定しました。\x1b[0m\n"
  121.                                                                         ,left);
  122.             }else{ 
  123. printf ("\n\x1b[32mCDのvolumeを 左:%d 右:%d に設定しました。\x1b[0m\n"
  124.                                                                 ,left,right);
  125.             }    
  126.         break;
  127.     case    2:
  128.         if ( mix > 0 ){
  129.             outp( VOL2_COM , 0x02 );
  130.             outp( VOL2_DAT , mix  );
  131.         } else {
  132.             outp( VOL2_COM , 0x00 );
  133.         }    
  134.         printf ("\n\x1b[32mMICのvolumeを %d に設定しました。\x1b[0m\n"
  135.                                     ,mix );
  136.         break;
  137.     case    3:
  138.         if ( mix > 0 ){
  139.             outp( VOL2_COM , 0x03 );
  140.             outp( VOL2_DAT , mix  );
  141.         } else {
  142.             outp( VOL2_COM , 0x00 );
  143.         }    
  144.     printf ("\n\x1b[32mMODEMのvolumeを %d に設定しました。\x1b[0m\n"
  145.                                     ,mix );
  146.         break;
  147.     default:
  148.         return(-1);
  149.     }
  150. return(0);
  151. }
  152.  
  153. int get_cd_stat()
  154. {
  155.     union    REGS    reg;
  156.     struct    SREGS    sreg;
  157.     ENSOU_STAT      cd_stat;    
  158.  
  159.     reg.x.ax = 0x53c0;
  160.     reg.x.cx = 0x0000;
  161.     reg.x.di = FP_OFF(&cd_stat);
  162.     sreg.ds     = FP_SEG(&cd_stat);
  163.         
  164.     int86x(0x93,®,®,&sreg) ;
  165.  
  166.     if ( reg.h.ah == 0 ){
  167.         if ( reg.h.al != 0 ) {
  168.             printf("\n %d 曲目を演奏しています。CD先頭から %d分 %d秒\n"
  169.                 ,cd_stat.cd_flame,cd_stat.disk_t.cd_min,cd_stat.disk_t.cd_sec);
  170.         }            
  171.         else {
  172.             printf("\nCDを演奏していません。\n");
  173.         }
  174.     }
  175.     return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 ); 
  176. }
  177. int    read_cd_info(TOC *cd_info)
  178. /*                                            */
  179. {
  180.     union    REGS    reg;
  181.     struct SREGS    sreg;
  182.  
  183.     reg.x.ax = 0x54c0;
  184.     reg.x.cx = 0x0000;
  185.     reg.x.di = FP_OFF(cd_info);
  186.     sreg.ds     = FP_SEG(cd_info);
  187.  
  188.     int86x(0x93,®,®,&sreg) ;
  189.     
  190.     return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 ); 
  191.  
  192. }
  193.  
  194. int    cd_stop(); /* アセンブラ化しました cd_stop.a86 */
  195. /*
  196. {
  197.     union    REGS    reg;
  198.  
  199.     reg.x.ax = 0x52c0;
  200.     reg.x.cx = 0x0000;
  201.  
  202.     int86(0x93,®,®) ;
  203.     
  204. return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 ); 
  205.  
  206. }
  207. */
  208.  
  209. int        _asm_time(char *, int );
  210.  
  211. #define    stop_time_asm(c) _asm_time("\n\
  212. \tMOV\tCH,255\n\
  213. \tMOV\tCL,AL\n\
  214. \tMOV\tAX,21184\n\
  215. \tINT\t147\n\
  216. \tXOR\tAL,AL\n\
  217. \tCMP\tAH,128\n\
  218. \tJNE\t__aaa\n\
  219. \tMOV\tAL,CL\n\
  220. __aaa:\t", c )
  221.  
  222. /* インラインアセンブラ化したけどあまり意味がないなぁ */    
  223.  
  224. int    cd_time(int time)
  225. {
  226.     int    err_v;
  227.     
  228.     if    ( ( err_v = stop_time_asm( time ) ) == 0 ){
  229.         if    ( time != 0 )
  230.     printf ("\n\x1b[32mCDドライブの停止時間を %d 秒に設定しました。\x1b[0m\n"
  231.                                                                         ,time);
  232.         else
  233.     printf ("\n\x1b[32mCDドライブが停止しないように設定しました。\x1b[0m\n")            ;    
  234.     }
  235. return( err_v ); 
  236. }    
  237. /*
  238. {
  239.     union    REGS    reg;
  240.  
  241.     reg.x.ax = 0x52c0;
  242.     reg.x.cx = ( 0xff00 | ( time & 0x00ff) ) ;
  243.     
  244.     int86(0x93,®,®) ;
  245.  
  246.     if    ( reg.h.ah== 0 ){
  247.         if    ( time != 0 )
  248.     printf ("\n\x1b[32mCDドライブの停止時間を %d 秒に設定しました。\x1b[0m\n"
  249.                                                                         ,time);
  250.         else
  251.     printf ("\n\x1b[32mCDドライブが停止しないように設定しました。\x1b[0m\n")            ;    
  252.     }
  253. return( (reg.h.ah == 0x80) ? reg.h.ah * 256 + reg.h.cl : reg.h.ah *256 ); 
  254. }
  255. */
  256. int    cd_start(ENSOU_T *ensou_time,int kaisuu)
  257. {
  258.     union    REGS    reg;
  259.     struct SREGS    sreg;
  260.  
  261.     reg.x.ax = 0x50c0;
  262.  
  263.         if         ( kaisuu == 0 )
  264.                 reg.x.cx = 0xff01 ;
  265.         else if    ( kaisuu == 1 )
  266.                 reg.x.cx = 0x0001 ;
  267.         else {
  268.                 reg.x.cx = 0xfe01;
  269.                 reg.h.bh = kaisuu-1;
  270.         }
  271.  
  272.     reg.x.di = FP_OFF(ensou_time);
  273.     sreg.ds     = FP_SEG(ensou_time);
  274.     
  275.     int86x(0x93,®,®,&sreg);
  276.     
  277.     return( (reg.h.ah == 0x80) ? reg.h.ah*256 + reg.h.cl : reg.h.ah *256 ); 
  278. }
  279.  
  280. long int calc_flame(CD_TIME time)
  281. {
  282.     return((time.cd_min & 0x7f)*60*75+time.cd_sec*75+time.cd_flame);
  283. }
  284.  
  285. CD_TIME calc_time(long int flame)
  286. {
  287.     CD_TIME time;
  288.  
  289.     time.cd_min=flame/(60*75);
  290.     time.cd_sec=(flame-time.cd_min*60*75)/75;
  291.     time.cd_flame=flame-time.cd_min*75*60-time.cd_sec*75;
  292.  
  293.     return(time);
  294. }
  295.  
  296. int calc_ensou(int start,int end,TOC cd_info,ENSOU_T *ensou)
  297. /*
  298.     入力 演奏開始track no. 演奏終了track no.
  299.             cd_info 
  300. */
  301. {
  302.     if (start<cd_info.start_track)    start=cd_info.start_track;
  303.     if    (chkcode(start) !=0)        start++; 
  304.     if    (start>cd_info.end_track)    start=cd_info.end_track;
  305.     if    (start==cd_info.end_track && chkcode(start)!=0)
  306.                                     return(-1);
  307.  
  308.     if    (end>cd_info.end_track)        end=cd_info.end_track;
  309.     if    (chkcode(end) !=0)            end--; 
  310.     if    (end<cd_info.start_track)    end=cd_info.start_track;
  311.     if    (end==cd_info.start_track && chkcode(end)!=0)
  312.                                     return(-1);
  313.     if    (start>end)                    return(-1);    
  314.  
  315.         (*ensou).start_t=cd_info.cd_time[start-1];
  316.     if (end==cd_info.end_track)
  317.         (*ensou).end_t=calc_time(cd_all_flame -1);
  318.     else
  319.         (*ensou).end_t=calc_time(calc_flame(cd_info.cd_time[end])-1);
  320.  
  321.     return(start*256+end);
  322. }    
  323.  
  324. void    err_r( int erf )
  325. {
  326.     if ( erf == 0x0200      )
  327.                 printf ("\n\x1b[31mデバイス番号エラー\x1b[0m\n");
  328.     if ( erf == 0x1000      )
  329.                 printf ("\n\x1b[31m音楽演奏中\x1b[0m\n");
  330.     if ( erf == 0x8001 )
  331.                 printf ("\n\x1b[31mCDがはいっていません。\x1b[0m\n");
  332.     if ( erf == 0x8002  )
  333.                 printf ("\n\x1b[31mパラメータエラー\x1b[0m\n");
  334.     if ( erf == 0x8004  )
  335.                 printf ("\n\x1b[31mドライブがつながっていません。\x1b[0m\n");
  336.     if ( erf == 0x8008  )
  337.                 printf ("\n\x1b[31mコマンド異常終了\x1b[0m\n");
  338.     if ( erf == 0x8010  )
  339.                 printf ("\n\x1b[31mCDが読み取れません。\x1b[0m\n");
  340.     if ( erf == 0x8080     )
  341.                 printf ("\n\x1b[31mCDが交換されました。\x1b[0m\n");
  342.     if (erf == -1       ){
  343. puts("                                                          ");
  344. puts("  書式    Cdur        CD を 全曲リピート再生              ");
  345. puts("          Cdur STOP   CD を 停止する                      ");
  346. puts("          Cdur PLAY [ start [ end [ loop ]]]              ");
  347. puts("                      CD を start曲目から end曲目まで     ");
  348. puts("                      loop 回 再生                        ");
  349. puts("                      loop=0 で止めるまで連続再生         ");
  350. puts("          Cdur TIME   [time]                              ");
  351. puts("                      CDが停止するまでの時間を設定する    ");
  352. puts("                      timeの単位は秒、 0 で止まらない      ");
  353. puts("          Cdur STAT   CD を 演奏情報を表示する            ");
  354. puts("          Cdur VOL  [ [ { CD | LINE | MIC | MODEM }       ");
  355. puts("                        [ left_vol  [ right_vol ] ] ] ]   ");
  356. puts("                                                          ");
  357. }
  358.  
  359. }
  360.  
  361. int cd_play_main(int start,int end,int kaisuu)
  362. {
  363.     ENSOU_T ensou_time;
  364.     TOC     cd_info;
  365.     int        tim,erf,erf1;
  366.     
  367.     cd_stop();
  368.     for (tim=0,erf=1;tim<2 && erf!=0 ;tim++)
  369.         erf=read_cd_info(&cd_info);
  370.  
  371.     if ( erf!= 0 )    return(erf);
  372.     
  373.     if ((erf1=calc_ensou(start,end,cd_info,&ensou_time))==-1 )
  374.                 return(0x8002);
  375.     
  376.     if ((erf=cd_start(&ensou_time,kaisuu))!=0) return(erf);
  377.  
  378.     if ((erf1/256)==(erf1 % 256))
  379.         printf("\n\x1b[36m %d 曲目を",(erf1 / 256));
  380.     else
  381.        printf("\n\x1b[36m %d 曲目から %d 曲目まで",(erf1/256),(erf1 % 256));
  382.  
  383.     if ( kaisuu == 0)
  384.         printf("繰り返し演奏します\x1b[0m\n");
  385.     else if (kaisuu==1)  
  386.         printf("演奏します\x1b[0m\n");
  387.     else if (kaisuu>=1)  
  388.         printf(" %d 回演奏します\x1b[0m\n",kaisuu);
  389.     return(0);
  390. }
  391.  
  392.  
  393. main(int argc,char *argv[])
  394. {
  395.     int        start=1, end=99, kaisuu=1, time=0 ,erf=-1;
  396.     int        vol_set = 1,vol_left=VOL_MAX,vol_right=VOL_MAX;        
  397.  
  398.     printf("\n\x1b[32m");
  399.     printf("*** \x1b[36mCdur.exe \x1b[31m♪\x1b[32m    ");
  400.     printf( Cdur_version );
  401.     printf( "   " );
  402.     printf( Cdur_date );
  403.     printf("    By おくと ***\n\x1b[0m");
  404.  
  405.     if (argc==1){    
  406.         erf=cd_play_main(0,99,0);
  407.     }
  408.     if (argc>=2 && strcmpi(argv[1],"stop")== 0 ){
  409.             erf=cd_stop();     
  410.             if    ( erf== 0 )
  411.                 printf ("\n\x1b[1;34mCDを停止しました。\x1b[0m\n");
  412.     }
  413.     if (argc>=2 && strcmpi(argv[1],"play")== 0 ){
  414.         if    (argc>=3)    start    = atoi(argv[2]) ;
  415.         if    (argc>=4)    end        = atoi(argv[3])    ;
  416.         if    (argc>=5)    kaisuu    = atoi(argv[4]) ;
  417.         if ( 0<=start && start<=99 && 0<=end && end<=99 
  418.                         && 0<=kaisuu && kaisuu<=256 )
  419.         erf=cd_play_main(start,end,kaisuu);
  420.     }
  421.     if (argc>=2 && strcmpi(argv[1],"time")== 0 ){
  422.         if    (argc>=3)                     time    = atoi(argv[2]) ;
  423.         if    ( 0 <= time && time <= 255 ) erf    = cd_time(time) ;
  424.     }
  425.  
  426.     if ( argc==2 && strcmpi(argv[1],"stat")== 0 ){
  427.             erf=get_cd_stat();     
  428.     }
  429.  
  430.     if ( argc>=2 && strcmpi(argv[1],"vol")== 0 ){
  431.             if ( argc== 5 ){
  432.                 vol_left = atoi(argv[3]) ; 
  433.                 vol_right = atoi(argv[4]); 
  434.             }
  435.             else if ( argc == 4 ) { 
  436.                 vol_left=vol_right=atoi(argv[3]) ;
  437.             }
  438.             
  439.             if ( argc>=3 && strcmpi(argv[2],"cd") == 0 )         vol_set=1; 
  440.             else if ( argc>=3 && strcmpi(argv[2],"line") == 0 ) vol_set=0;
  441.             else if ( argc>=3 && strcmpi(argv[2],"mic") == 0 )     vol_set=2;
  442.             else if ( argc>=3 && strcmpi(argv[2],"modem") == 0 ) vol_set=3;
  443.      
  444.             if ( 0<= vol_left && vol_left<=VOL_MAX 
  445.                                     && 0<=vol_right && vol_right<=VOL_MAX)
  446.                 erf = setvol( vol_set , vol_left , vol_right );
  447.     }
  448.  
  449.     err_r(erf);
  450. }
  451.  
  452.  
  453.