home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / msdos / music / polytc / poly_pla.tc < prev    next >
Text File  |  1991-05-25  |  5KB  |  171 lines

  1. /*
  2.  *    poly_play - Play a polyphonic tune.
  3.  */
  4. #include <stdio.h>
  5.  
  6. #define TRUE    (1)
  7. #define FALSE    (0)
  8.  
  9. int tune[5000];
  10. char name[80];
  11. FILE *tfp;
  12.  
  13. int *tunep;
  14. int tempo;
  15. int duration;
  16.  
  17. main( argc, argv )
  18. int argc;
  19. char *argv[];
  20. {
  21.     int tindex;
  22.  
  23.     if( argc != 2 )
  24.     {
  25.         fprintf( stderr, "\nUsage: poly_play tunefile\n\n");
  26.         exit( 1 );
  27.     }
  28.  
  29.     if( !(tfp = fopen(argv[1], "r")) )
  30.     {
  31.         fprintf( stderr, "\n*** Unable to open tune file ***\n" );
  32.         exit( 2 );
  33.     }
  34.  
  35.     fgets( name, 80, tfp );
  36.     tindex = 0;
  37.  
  38.     while( fscanf(tfp, "%d", &tune[tindex++]) != -1)
  39.         ;
  40.  
  41.     fclose( tfp );
  42.  
  43.     tunep = tune;                        /* Initialize tune pointer */
  44.     tempo = 0x1fff;                     /* Set up default tempo */
  45. /*
  46.  *  Now attempt to play the tune...
  47.  */
  48.     asm push ax;                    /* Save registers */
  49.     asm push bx;
  50.     asm push cx;
  51.     asm push dx;
  52.     asm push si;
  53.     asm push di;
  54.     asm push bp;
  55.     asm push es;
  56.     asm push tempo;                 /* Initialize tempo counter */
  57.     asm xor ax,ax;                    /* Must write 0 into voice count and */
  58.     asm mov bx,ax;                    /*  data registers */
  59.     asm mov dx,ax;
  60.     asm mov si,ax;
  61.     asm mov bp,ax;
  62.     asm mov di,ax;
  63.     asm mov es,ax;
  64.     asm mov cx,12h;                 /* Initialize shift value */
  65. /*
  66.  *  This section sorts the tune data into the appropriate registers
  67.  *  Voice period data is stored in ES for voice 1, DI for voice 2,
  68.  *  and SI for voice 3.  The voice period count is stored in BX for
  69.  *  voice 1, DX for voice 2, and BP for voice 3.
  70.  */
  71.     sort:;
  72.         asm push bx;
  73.         asm push dx;
  74.     sort_1:;
  75.         asm add tunep,2;
  76.         asm mov bx,tunep;        /* Get tune pointer */
  77.         asm mov ax,[bx];            /* Get tune data in AX */
  78.         asm mov dx,ax;                /* Make a copy in DX */
  79.         asm and dx,1FFFh;            /* Strip off 3 data type bits */
  80.         asm shl ax,1;                /* Move msb into carry bit */
  81.         asm jnc sort_4;            /* Jump if end, duration, or tempo data */
  82.         asm shl ax,1;                /* Move 2nd msb into carry bit */
  83.         asm jc sort_3;                /* Jump if voice 3 data */
  84.         asm shl ax,1;                /* Move 3rd msb into carry bit */
  85.         asm jc sort_2;                /* Jump if voice 2 data */
  86.         asm mov es,dx;                /* Store voice 1 data in ES */
  87.         asm jmp sort_1;
  88.     sort_2:;
  89.         asm mov di,dx;                /* Store voice 2 data in DI */
  90.         asm jmp sort_1;
  91.     sort_3:;
  92.         asm mov si,dx;                /* Store voice 3 data in SI */
  93.         asm jmp sort_1;            /* Ignore */
  94.     sort_4:;
  95.         asm shl ax,1;                /* Move 2nd msb into carry bit */
  96.         asm jnc sort_6;            /* Jump if end or duration data */
  97.         asm shl ax,1;
  98.         asm jnc sort_5;            /* Jump if tempo data */
  99.         asm jmp sort_1;            /* Ignore */
  100.         sort_5:;
  101.         asm mov tempo,dx;        /* Store tempo */
  102.         asm pop dx;                /* Restore registers */
  103.         asm pop bx;
  104.         asm pop ax;                /* Burn the current tempo counter */
  105.         asm push tempo;             /*  and put in the new one */
  106.         asm push bx;                /* Save registers again */
  107.         asm push dx;
  108.         asm jmp sort_1;
  109.     sort_6:;
  110.         asm shl ax,1;                /* Move 3rd msb into carry */
  111.         asm jc sort_7;                /* Jump if duration */
  112.         asm pop dx;
  113.         asm pop bx;
  114.         asm pop ax;                /* Get rid or tempo counter */
  115.         asm jmp theend;
  116.         sort_7:;
  117.         asm mov duration,dx;        /* Store duration data */
  118.         asm pop dx;
  119.         asm pop bx;
  120.         theloop:;
  121.         asm cli;                    /* Turn off interrupts during note */
  122.         asm pop ax;                /* Get tempo counter */
  123.         asm dec ax;                /* Decrement it */
  124.         asm push ax;                /* Put it back */
  125.         asm jnz play;                /* Jump if some tempo remains */
  126.         asm pop ax;                /* Get tempo counter */
  127.         asm mov ax,tempo;        /* Reset tempo counter */
  128.         asm push ax;                /*  and put it back */
  129.         asm dec duration;        /* Decrement duration counter */
  130.         asm jnz play;                /* Continue if not finished */
  131.         asm sti;                    /* Turn interrupts back on */
  132.         asm jmp sort;                /* Get new tune data if duration up */
  133. /*
  134.  *  This routine plays the notes until the duration counter
  135.  *  reaches zero.  At that time, the new data is sorted.
  136.  */
  137.         play:;
  138.         asm add bx,si;                /* Add voice 3 data to count */
  139.         asm rol bx,1;                /* Get msb of voice 3 count */
  140.         asm mov ax,cx;                /* Keeps keyboard clk on and */
  141.         asm rcl al,1;                /*  casette motor relay off */
  142.         asm rcl al,1;
  143.         asm out 061h, al;
  144.         asm ror bx,1;                /* Restore bx to original state */
  145.         asm add dx,di;                /* Add voice 2 data to count */
  146.         asm rol dx,1;
  147.         asm mov ax,cx;
  148.         asm rcl al,1;
  149.         asm rcl al,1;
  150.         asm out 061h, al;
  151.         asm ror dx,1;
  152.         asm mov ax,es;
  153.         asm add bp,ax;                /* Add voice 1 data to count */
  154.         asm rol bp,1;
  155.         asm mov ax,cx;
  156.         asm rcl al,1;
  157.         asm rcl al,1;
  158.         asm out 061h, al;
  159.         asm ror bp,1;
  160.         asm jmp theloop;
  161.         theend:;
  162.         asm pop es;                /* Restore registers */
  163.         asm pop bp;
  164.         asm pop di;
  165.         asm pop si;
  166.         asm pop dx;
  167.         asm pop cx;
  168.         asm pop bx;
  169.         asm pop ax;
  170. }
  171.