home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 10 / 10.iso / l / l320 / 2.img / EXAMPLES / MUSIC.F < prev    next >
Encoding:
Text File  |  1989-08-23  |  6.2 KB  |  170 lines

  1. C MUSIC.F
  2. C Usage: RUN386 -CALLBUFS 1 MUSIC
  3. C Purpose: demonstrates interfacing between assembly
  4. C language and NDP Fortran programs. The NDP code calls
  5. C protected mode assembly language routines. These
  6. C in turn communicate with a real mode assembly
  7. C language routine. These assembly routines are used
  8. C to control the underlying PC hardware. They do so
  9. C by reading from and writing to ports and by
  10. C taking over the timer tick interrupt.
  11. C Copyright (C) MicroWay, Inc., 1989
  12. C
  13.  
  14.       INTEGER WHOLE,WHOLEDOT,HALF,HALFDOT
  15.       INTEGER QUARTER,QUARTERDOT,EIGHTH,EIGHTHDOT
  16.       INTEGER SIXTEENTH,SIXTEENTHDOT
  17.       INTEGER THIRTYSECOND,THIRTYSECONDDOT
  18.       INTEGER SIXTYFOURTH,NONE
  19.  
  20.       PARAMETER (WHOLE=64,WHOLEDOT=WHOLE+WHOLE/2)
  21.       PARAMETER (HALF=WHOLE/2,HALFDOT=WHOLE/2+WHOLE/4)
  22.       PARAMETER (QUARTER=WHOLE/4,QUARTERDOT=WHOLE/4+WHOLE/8)
  23.       PARAMETER (EIGHTH=WHOLE/8,EIGHTHDOT=WHOLE/8+WHOLE/16)
  24.       PARAMETER (SIXTEENTH=WHOLE/16)
  25.       PARAMETER (SIXTEENTHDOT=WHOLE/16+WHOLE/32)
  26.       PARAMETER (THIRTYSECOND=WHOLE/32)
  27.       PARAMETER (THIRTYSECONDDOT=WHOLE/32+WHOLE/64)
  28.       PARAMETER (SIXTYFOURTH=WHOLE/64,NONE=0)
  29.  
  30.       INTEGER ERROR_VAL
  31.       PARAMETER (ERROR_VAL=-1)
  32.  
  33. C assembly langauage functions called by main program
  34.       INTEGER INIT_TIMER_ISR
  35.       INTEGER PLAY
  36.       INTEGER RESTORE_TIMER_ISR
  37.  
  38. C This example plays musical tunes. The tune is
  39. C represented by a special data construct which
  40. C is contrived to mimic the functionality of a
  41. C a struct in C or a record in Pascal. Each 
  42. C construct represents a note: the first field
  43. C gives the note's duration and the second field
  44. C denotes its name. Each name represents a note
  45. C in the tempered chromatic scale. The names take
  46. C one of three forms:
  47. C            'A-G' ['#'|'b'] '0-8'
  48. C   or       'A-G' '0-8'
  49. C   or       'R'
  50. C The first letter of every note must be in upper
  51. C case - lower case 'b' is reserved to indicate the
  52. C tone is a flat. If the note is a sharp or a flat,
  53. C the second character is a '#' or a 'b' and the
  54. C third character is a digit indicating the octave.
  55. C If the note is not a sharp or a flat, then the
  56. C second character is a digit indicating the octave.
  57. C The only other character allowed is an upper case
  58. C 'R', to denote rest or pause. Every name occupies
  59. C 4 bytes and has 1, 2 or 3 visible characters, being
  60. C padded on the right with blanks (value 32, hexadecimal
  61. C 20). Since this is a tempered scale, the frequency of
  62. C adjacent sharps and flats is the same, e.g., G#0 and
  63. C Ab0 have the same pitch.
  64. C The construct is created by a pair of EQUIVALENCED
  65. C arrays, one being declared INTEGER*4, the other being
  66. C declared CHARACTER*4
  67.  
  68.       INTEGER*4 DURATION (0:10)
  69.       CHARACTER*4 NOTENAME (0:10)
  70.       EQUIVALENCE (DURATION,NOTENAME)
  71.  
  72. C The two arrays declared above begin with element 0.
  73. C The even numbered elements hold amount of time to
  74. C sound the note, the odd numbered elements hold the
  75. C name of the note.
  76.  
  77. C The following construct was contrived to overlay
  78. C an array of structures defined in the assembly
  79. C language module PLAY.S. Each structure holds
  80. C information about a tone in the tempered chromatic
  81. C scale and the entire array spans eight octaves.
  82. C The first field of these is the name of the tone
  83. C and takes essentially the same form as the name
  84. C field in the NOTENAME array. The tones range from
  85. C C0 to C8, middle C being C4. The second field is
  86. C the frequency of the tone, e.g., A4 is 440 Hertz.
  87. C The third field is the count between pulses to the
  88. C speaker and is inversely proportional to the
  89. C frequency. Notes C0 to E0 will not play, because
  90. C their frequency is too low (i.e., their count is
  91. C too high and occupies more than 16 bits) - using
  92. C them will generate an error. For details on these
  93. C structures, see PLAY.S.
  94. C Each of the three equivalenced arrays below are used
  95. C to access a field in the tone structure. The lowest
  96. C element in all three is 0. Starting at element 0 in
  97. C array TONENAME, every third element holds the name of
  98. C the tone (e.g.,0,3,6,9...). Starting at element 1 in
  99. C array FREQ, every third element holds the frequency of
  100. C the tone (e.g.,1,4,7,10...). Starting at element 2 in
  101. C array COUNT, every third element holds the count of the
  102. C tone (e.g.,2,5,8,11...). Note that these arrays are
  103. C placed in blank COMMON.
  104.  
  105.       CHARACTER*4 TONENAME (0:411)
  106.       REAL*4 FREQ (0:411)
  107.       INTEGER*4 COUNT (0:411)
  108.  
  109.       COMMON TONENAME
  110.  
  111.       EQUIVALENCE (TONENAME,FREQ,COUNT)
  112.       INTEGER I
  113.  
  114. C next, the tune to be played
  115.        DATA DURATION(0)/WHOLE/,    NOTENAME(1)/'C5'/
  116.        DATA DURATION(2)/HALF/,     NOTENAME(3)/'E5'/
  117.        DATA DURATION(4)/WHOLE/,    NOTENAME(5)/'G5'/
  118.        DATA DURATION(6)/HALF/,     NOTENAME(7)/'E5'/
  119.        DATA DURATION(8)/QUARTER/,  NOTENAME(9)/'R'/
  120.        DATA DURATION(10)/WHOLE/,   NOTENAME(11)/'F4'/
  121.        DATA DURATION(12)/QUARTER/, NOTENAME(13)/'D5'/
  122.        DATA DURATION(14)/HALF/     NOTENAME(15)/'B4'/
  123.        DATA DURATION(16)/WHOLE/,   NOTENAME(17)/'C5'/
  124.        DATA DURATION(18)/NONE/,    NOTENAME(19)/''/
  125.  
  126. C begin main program
  127.  
  128. C initialize tempered chromatic scales
  129.       CALL INIT_TCS
  130.  
  131. C display initialized tempered chromatic scales
  132.       DO 1000, I = 0,410,3
  133.           WRITE (*,1010) TONENAME(I),FREQ(I+1),COUNT(I+2)
  134.  1000 CONTINUE
  135.  1010 FORMAT (1X,A,2X,F10.2,2X,I5)
  136.  
  137. C skip a line
  138.       WRITE (*,1050)
  139.  1050 FORMAT(1X)
  140.  
  141. C set up new timer interrupt service routine
  142.       I = INIT_TIMER_ISR()
  143.       IF (I.EQ.ERROR_VAL) THEN
  144.           WRITE (*,2000)
  145.  2000 FORMAT (1X,'Problem in initializing new timer ISR')
  146.           WRITE (*,2010)
  147.  2010 FORMAT (1X,'Be sure to invoke RUN386.EXE with ',$)
  148.           WRITE (*,2020)
  149.  2020 FORMAT (1X,'-CALLBUFS equal to at least 1')
  150.           STOP
  151.       ENDIF
  152.  
  153. C play a little tune
  154.       I = PLAY(DURATION(0))
  155.       IF (I.EQ.ERROR_VAL) THEN
  156.           WRITE (*,3000)
  157.  3000 FORMAT (1X,'Problem in play function')
  158.           STOP
  159.       ENDIF
  160.  
  161. C restore old timer interrupt service routine
  162.       I = RESTORE_TIMER_ISR()
  163.       IF (I.EQ.ERROR_VAL) THEN
  164.           WRITE (*,4000)
  165.  4000 FORMAT (1X,'Problem in restoring old timer ISR')
  166.           STOP
  167.       ENDIF
  168.  
  169.       END
  170.