home *** CD-ROM | disk | FTP | other *** search
/ PC-Blue - MS DOS Public Domain Library / PC-Blue MS-DOS Public Domain Library - NYACC.iso / vol093 / tri.asm < prev    next >
Encoding:
Assembly Source File  |  1986-12-15  |  3.8 KB  |  142 lines

  1. title TRI - 8088 routine CALLed from BASIC   Steve Muenter
  2.  
  3. comment *This routine produces polyphonic music with three
  4.     voices.  The frequencies and durations of the notes
  5.     are passed to this routine in an integer array.
  6.  
  7.     Called from BASIC via:
  8.  
  9.         CALL TRI(TUNE%(0))
  10.  
  11.     Where:
  12.  
  13.         TUNE% is an integer array
  14.  
  15.     TUNE% is treated by TRI as data words with the three most
  16.     significant bits identifying the type of data.    000 causes
  17.     the routine to terminate and return to BASIC.  001 sets
  18.     the duration of play of the voices before being updated.
  19.     010 sets the tempo of the playback.  011 is unused.  100
  20.     sets the period for voice 1 which is slightly louder than
  21.     the rest.  101 sets the period for voice 2.  110 sets the
  22.     period for voice 3.
  23.     *
  24.  
  25. cseg    segment
  26.     assume CS:cseg, DS:cseg, ES:nothing
  27. ;    db    0FDH        ;indicates BLOAD file
  28. ;    dw    0        ;segment--BASIC will use default
  29. ;    dw    0        ;offset--specify in BLOAD command
  30. ;    dw    rtn_len     ;length of the routine
  31.  
  32. spkr_io equ    61H
  33.  
  34. tri    proc    far
  35.     push    bp
  36.     mov    bp,sp
  37.     mov    ax,[bp+6]    ;get address of TUNE%(0) off stack
  38.     sub    ax,2        ;required for first time in sort
  39.     push    ax        ;save on stack
  40.     mov    ax,1FFFH    ;default tempo data
  41.     push    ax        ;save on stack
  42.     push    ax        ;initialize tempo counter
  43.     xor    ax,ax        ;must write 0 into voice count and
  44.     mov    bx,ax        ; data registers
  45.     mov    dx,ax
  46.     mov    si,ax
  47.     mov    bp,ax
  48.     mov    di,ax
  49.     mov    es,ax
  50. ;
  51. ;This section sorts the tune data into the appropriate registers
  52. ;Voice period data is stored in ES for voice 1, DI for voice 2,
  53. ;and SI for voice 3.  The voice period count is stored in BX for
  54. ;voice 1, DX for voice 2, and BP for voice 3.
  55. ;
  56. sort:    push    bx
  57.     push    dx
  58.     push    bp
  59.  
  60. sort_1: mov    bp,sp
  61.     mov    bx,[bp+10]    ;get tune pointer
  62.     add    bx,2        ;point to next tune data
  63.     mov    [bp+10],bx    ;restore updated tune pointer
  64.     mov    ax,[bx]     ;get tune data in AX
  65.     mov    dx,ax        ;make a copy in DX
  66.     and    dx,1FFFH    ;strip off 3 data type bits
  67.     shl    ax,1        ;move msb into carry bit
  68.     jnc    sort_4        ;jump if end, duration, or tempo data
  69.     shl    ax,1        ;move 2nd msb into carry bit
  70.     jc    sort_3        ;jump if voice 3 data
  71.     shl    ax,1        ;move 3rd msb into carry bit
  72.     jc    sort_2        ;jump if voice 2 data
  73.     mov    es,dx        ;store voice 1 data in ES
  74.     jmp    sort_1
  75. sort_2: mov    di,dx        ;store voice 2 data in DI
  76.     jmp    sort_1
  77. sort_3: mov    si,dx        ;store voice 3 data in SI
  78.     jmp    sort_1        ;ignore
  79. sort_4: shl    ax,1        ;move 2nd msb into carry bit
  80.     jnc    sort_6        ;jump if end or duration data
  81.     shl    ax,1
  82.     jnc    sort_5        ;jump if tempo data
  83.     jmp    sort_1        ;ignore
  84. sort_5: mov    [bp+8],dx    ;store tempo
  85.     mov    [bp+6],dx    ;initialize tempo counter
  86.     jmp    sort_1
  87. sort_6: shl    ax,1        ;move 3rd msb into carry
  88.     jc    sort_7        ;jump if duration
  89.     jmp    end
  90. sort_7: mov    cx,dx        ;store duration data
  91.     pop    bp
  92.     pop    dx
  93.     pop    bx
  94.     cli            ;turn off interrupts during play
  95. loop:    pop    ax        ;get current tempo count
  96.     dec    ax        ;subtract 1
  97.     push    ax        ;restore tempo count
  98.     jnz    play        ;jump if some tempo remains
  99.     pop    ax        ;reset tempo counter
  100.     pop    ax
  101.     push    ax
  102.     push    ax
  103.     loop    play        ;decrement duration counter
  104.     sti            ;turn ints back on during sort
  105.     jmp    sort        ;get new tune data if duration up
  106. ;
  107. ;This routine plays the notes until the duration counter in CX
  108. ;reaches zero.    At that time, the new data is sorted.
  109. ;
  110. play:    add    bx,si        ;add voice 3 data to count
  111.     rol    bx,1        ;get msb of voice 3 count
  112.     mov    al,12H        ;keeps keyboard clk on and
  113.     rcl    al,1        ; casette motor relay off
  114.     rcl    al,1
  115.     out    spkr_io,al    ;output voice 3 state to speaker
  116.     ror    bx,1        ;restore bx to original state
  117.     add    dx,di        ;add voice 2 data to count
  118.     rol    dx,1
  119.     mov    al,12H
  120.     rcl    al,1
  121.     rcl    al,1
  122.     out    spkr_io,al
  123.     ror    dx,1
  124.     mov    ax,es
  125.     add    bp,ax        ;add voice 1 data to count
  126.     rol    bp,1
  127.     mov    al,12H
  128.     rcl    al,1
  129.     rcl    al,1
  130.     out    spkr_io,al
  131.     ror    bp,1
  132.     jmp    loop
  133. end:    add    sp,12
  134.     pop    bp
  135.     mov    ax,cs
  136.     mov    es,ax
  137.     ret    2
  138. tri    endp
  139. rtn_len equ    $-tri        ;length of routine for header
  140. cseg    ends
  141.     end    tri
  142.