home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / asm / wasm / sound.asm < prev    next >
Assembly Source File  |  1987-08-13  |  17KB  |  693 lines

  1.  
  2.  Title 'Wolfware Assembler Sample Program', 'Sound Generation'
  3.  
  4. ;=============================================================================
  5. ; Sound Generation
  6. ;
  7. ; This program allows you to enter frequencies, a rate of change (velocity),
  8. ; a rate of rate of change (acceleration), and a duration for any number
  9. ; (memory allowing) of speaker beeps.  The beeps can be added, modified, and
  10. ; played back all together to form a sort of music.  The sequence of beeps
  11. ; can also be saved to or read from a file (loading and playing a file at 
  12. ; random has an interesting effect).  The frequency is in hertz, the velocity
  13. ; is in hertz per 1/50 seconds, the acceleration is in hertz per 1/50
  14. ; seconds^2, and the duration is in 1/100 seconds.  
  15. ;
  16. ; The IO.BIN runtime library is needed on the default drive/path for
  17. ; execution, and the files IO.MAC, IO.RED, and DISPATCH.ASM are all needed for 
  18. ; assembly.  Also ANSI.SYS or a compatible device driver must be installed.
  19. ;
  20. ; This program is completely DOS compatible execept for the sound generation, 
  21. ; which is hardware dependent.  Note that all those mysterious characters
  22. ; stuck in the middle of strings are ANSI escape sequences which the ANSI.SYS
  23. ; device driver uses to control the screen attributes, cursor position, etc.
  24. ;
  25. ; The timing of this program is based on a 4.77 MHz 8088 microprocessor (see
  26. ; IO.ASM).  If a faster computer is used, the timing will probably be off.
  27.  
  28.  Jmp Begin
  29.  
  30. ;================================================
  31. ; Data
  32.  
  33. ;--- present sound data
  34.  
  35. Snd_Idx Dw 1            ;present sound number
  36.  
  37. Snd_Now Dw 523          ;frequency
  38. Snd_Vel Dw 1            ;velocity
  39. Snd_Acc Dw 10           ;acceleration
  40. Snd_Dur Dw 10           ;duration
  41.  
  42. Dwn_Snd Equ 01h         ;tone goes down instead of up
  43. Snd_Sta Dw 0            ;tone status
  44.  
  45. ;--- tone limits
  46.  
  47. Ton_Max Dw 2000         ;maximum tone
  48. Ton_Min Dw 100          ;minimum tone
  49. Dur_Max Dw 500          ;maximum duration, 5 seconds
  50.  
  51. ;--- tones defined
  52.  
  53. Snd_Num Dw 0            ;number of tones defined
  54. Snd_End Dw 0            ;end of tone sequence
  55. Snd_Seg Dw ?            ;segment of tone sequence
  56. Snd_Siz Dw ?            ;end of tone segment
  57.  
  58. ;--- other
  59.  
  60. Err_Ton Equ 500         ;error beep frequency
  61. Err_Dur Equ 5           ;error beep duration
  62. Nam_Siz Equ 60          ;file name size
  63.  
  64. Stack_Size Equ 100      ;bytes for stack
  65.  
  66. ;--- external source files
  67.  
  68.  Include 'Io.Mac'
  69.  Include 'Io.Red'
  70.  Include 'Dispatch.Asm'
  71.  
  72. ;------------------------------------------------
  73. ; Execute a DOS function call.
  74.  
  75. Dos Macro Func
  76.  Mov Ah, Func   ;load function
  77.  Int 21h        ;execute
  78.  Endm           ;Dos
  79.  
  80. ;================================================
  81. ; Main program.
  82.  
  83. Begin
  84.  
  85. ;--- initialization, set stack
  86.  
  87.  Mov Sp, Offset Stack_Top ;switch to local stack
  88.  
  89. ;--- reduce present memory
  90.  
  91.  Mov Bx, Offset End     ;end of program
  92.  Mov Cl, 4              ;bits to shift
  93.  Shr Bx, Cl             ;make paragraph form
  94.  Inc Bx
  95.  Dos 4ah                ;reduce memory allocation
  96.  
  97. ;--- allocate sequence space
  98.  
  99.  Mov Bx, 0fffh          ;try to allocate nearly whole segment
  100.  Dos 48h                ;allocate
  101.  Jnc Bigsong            ;jump if ok
  102.  Dos 48h                ;allocate what's available
  103.  Jc Memerror            ;jump if still error
  104.  
  105. Bigsong
  106.  Mov Snd_Seg, Ax        ;save segment
  107.  
  108.  Mov Cl, 4              ;bits to shift
  109.  Shl Bx, Cl             ;make byte form
  110.  Mov Ax, Bx
  111.  Mov Bx, 10
  112.  Sub Dx, DX
  113.  Div Ax, Bx             ;divide by ten
  114.  Mul Ax, Bx             ;multiply by ten
  115.  
  116.  Mov Snd_Siz, Ax        ;save end pointer (a multiple of ten)
  117.  
  118. ;--- set the screen
  119.  
  120.  Normal                 ;set to normal attribute
  121.  Cls                    ;clear screen
  122.  Jmps Maincont          ;jump if so
  123.  
  124. ;--- memory error
  125.  
  126. Memerror
  127.  Line 'SOUND: Memory error' ;display error message
  128.  Dos 4ch                ;exit
  129.  
  130. ;--- main program
  131.  
  132. Maincont
  133.  Display Mainmess1      ;show main menu
  134.  Decimal Snd_Num        ;make tone number a string
  135.  Locate 4, 20           ;goto position
  136.  Bold                   ;attribute
  137.  Display                ;show it
  138.  Normal                 ;fix attribute
  139.  
  140.  Locate 14, 1           ;goto position
  141.  Mov Si, Offset Mainmess3 ;choice message
  142.  Call Input_Chr         ;input character
  143.  
  144.  Cmp Al, 'A'            ;check if A
  145.  Je Main1
  146.  Cmp Al, 'M'            ;check if M
  147.  Je Main2
  148.  Cmp Al, 'P'            ;check if P
  149.  Je Main3
  150.  Cmp Al, 'S'            ;check if S
  151.  Je Main4
  152.  Cmp Al, 'L'            ;check if L
  153.  Je Main5
  154.  Cmp Al, 'C'            ;check if C
  155.  Je Main6
  156.  Cmp Al, 'Q'            ;check if Q
  157.  Je Main7
  158.  
  159.  Sound Err_Ton, Err_Dur ;error beep
  160.  Jmps Maincont
  161.  
  162. ;--- add new sound
  163.  
  164. Main1
  165.  Call Add_Sound         ;add new sound
  166.  Jmp Maincont
  167.  
  168. ;--- modify old sound
  169.  
  170. Main2
  171.  Call Mod_Sound         ;modify sound
  172.  Jmp Maincont
  173.  
  174. ;--- play all sounds
  175.  
  176. Main3
  177.  Call Play_Sounds       ;play all sounds
  178.  Jmp Maincont
  179.  
  180. ;--- save to file
  181.  
  182. Main4
  183.  Call Write_Sounds      ;write sounds to file
  184.  Jmp Maincont
  185.  
  186. ;--- load from file
  187.  
  188. Main5
  189.  Call Read_Sounds       ;read sounds from file
  190.  Jmp Maincont
  191.  
  192. ;--- clear all sounds
  193.  
  194. Main6
  195.  Call Clear_Sounds      ;clear all sounds
  196.  Jmp Maincont
  197.  
  198. ;--- exit program
  199.  
  200. Main7
  201.  Dos 4ch                ;exit
  202.  
  203. ;--- data
  204.  
  205. Mainmess1 Label Byte
  206.  Db Byte (Offset Mainmess2 - Offset Mainmess1 -1)
  207.  Db 27,'[2J'
  208.  Db 13,10
  209.  Db 'Sound Generator Version 1.00',13,10
  210.  Db 13,10
  211.  Db '  Defined sounds = ',13,10
  212.  Db 13,10
  213.  Db '  (',27,'[1mA',27,'[0m)dd a new sound',13,10
  214.  Db '  (',27,'[1mM',27,'[0m)odify an old sound',13,10
  215.  Db '  (',27,'[1mP',27,'[0m)lay all sounds',13,10
  216.  Db '  (',27,'[1mS',27,'[0m)ave to file',13,10
  217.  Db '  (',27,'[1mL',27,'[0m)oad from file',13,10
  218.  Db '  (',27,'[1mC',27,'[0m)lear all sounds',13,10
  219.  Db '  (',27,'[1mQ',27,'[0m)uit',13,10
  220. Mainmess2
  221.  
  222. Mainmess3 Db 14,'Enter choice: '
  223.  
  224. ;================================================
  225. ; Add new sound to sequence.
  226.  
  227. Add_Sound Proc Near
  228.  Mov Ax, Snd_End        ;end of sounds
  229.  Cmp Ax, Snd_Siz        ;check if full
  230.  Je Addsonerr           ;jump if so
  231.  
  232.  Inc Snd_Num            ;increment number of sounds
  233.  Display Addsonmess1    ;show message
  234.  Decimal Snd_Num        ;make string
  235.  Bold                   ;set to bold
  236.  Display                ;show number
  237.  Normal
  238.  Line
  239.  Line                   ;skip a line
  240.  
  241.  Mov Si, Snd_End        ;sound pointer
  242.  Call Set_Sound         ;set sound
  243.  Add Snd_End, 10        ;advance pointer
  244.  Ret
  245.  
  246. ;--- too many sounds
  247.  
  248. Addsonerr 
  249.  Display Addsonmess2    ;show error message
  250.  Sound Err_Ton, Err_Dur ;error beep
  251.  Call Wait              ;wait for key
  252.  Ret
  253.  
  254. ;--- messages
  255.  
  256. Addsonmess1 Db 15,13,10,'Adding sound '
  257. Addsonmess2 Db 15,'Too many sounds'
  258.  Endp                   ;Add_Sound
  259.  
  260. ;================================================
  261. ; Modify an old sound.
  262.  
  263. Mod_Sound Proc Near
  264.  Mov Si, Offset Modsonmess ;message
  265.  Mov Di, Offset Snd_Idx ;present sound
  266.  Call Input_Num         ;input number
  267.  
  268.  Dec Ax                 ;adjust to scale starting at zero
  269.  Cmp Ax, Snd_Num        ;check if past end
  270.  Jae Modsonadd          ;jump if so, add instead
  271.  
  272. ;--- modify old sound
  273.  
  274.  Line
  275.  Mov Bx, 10
  276.  Mul Ax, Bx             ;get offset into sequence
  277.  Mov Si, Ax
  278.  
  279.  Push Ds
  280.  Mov Ds, Snd_Seg        ;set tone segment
  281.  Mov Ax, [Si]           ;starting tone
  282.  Cs:
  283.  Mov Snd_Now, Ax        ;save
  284.  Mov Bx, [Si+2]         ;tone velocity
  285.  Cs:
  286.  Mov Snd_Vel, Bx        ;save
  287.  Mov Dx, [Si+4]         ;tone acceleration
  288.  Cs:
  289.  Mov Snd_Acc, Dx        ;save
  290.  Mov Cx, [Si+6]         ;tone duration
  291.  Cs:
  292.  Mov Snd_Dur, Cx        ;save
  293.  Mov Bp, [Si+8]         ;tone status
  294.  Cs:
  295.  Mov Snd_Sta, Bp        ;save
  296.  Pop Ds
  297.  
  298.  Call Set_Sound         ;set sound
  299.  Ret
  300.  
  301. ;--- add new sound
  302.  
  303. Modsonadd 
  304.  Call Add_Sound         ;add new sound
  305.  Ret
  306.  
  307. ;--- messages
  308.  
  309. Modsonmess Label Byte
  310.  Db 38
  311.  Db 13,10
  312.  Db 'Modifying old sound',13,10
  313.  Db 13,10
  314.  Db 'Enter index ['
  315.  Endp                   ;Mod_Sound
  316.  
  317. ;================================================
  318. ; Play all sounds.
  319.  
  320. Play_Sounds Proc Near
  321.  Display Playmess       ;show message
  322.  Sub Si, Si             ;start of segment
  323.  
  324. ;--- loop until end of tones is reached
  325.  
  326. Playloop
  327.  Cmp Si, Snd_End        ;check if done
  328.  Je Playdone            ;jump if so
  329.  
  330.  Keyboard               ;check if key
  331.  Jnz Playstop           ;jump if so
  332.  
  333.  Push Ds
  334.  Mov Ds, Snd_Seg        ;set tone segment
  335.  Mov Ax, [Si]           ;starting tone
  336.  Mov Bx, [Si+2]         ;tone velocity
  337.  Mov Dx, [Si+4]         ;tone acceleration
  338.  Mov Cx, [Si+6]         ;tone duration
  339.  Mov Bp, [Si+8]         ;tone status
  340.  Pop Ds
  341.  
  342.  Push Si
  343.  Test Bp, Dwn_Snd       ;test if down
  344.  Jnz Playtondn          ;jump if so
  345.  
  346. ;--- tone goes up
  347.  
  348.  Call Tone_Up           ;sound tone up
  349.  Pop Si
  350.  Add Si, 10             ;next entry
  351.  Jmps Playloop
  352.  
  353. ;--- tone goes down
  354.  
  355. Playtondn
  356.  Call Tone_Dn           ;sound tone down
  357.  Pop Si
  358.  Add Si, 10             ;next entry
  359.  Jmps Playloop
  360.  
  361. ;--- playing stopped or finished
  362.  
  363. Playstop
  364.  Input                  ;throw away key
  365. Playdone
  366.  Ret
  367.  
  368. ;--- message
  369.  
  370. Playmess Db 20,13,10, 'Playing all sounds'
  371.  Endp                   ;Play_Sounds
  372.  
  373. ;================================================
  374. ; Write sounds to a file.
  375.  
  376. Write_Sounds Proc Near
  377.  Display Writesmess1    ;display
  378.  Input Nam_Siz          ;input file name
  379.  Create                 ;create file
  380.  Jc Writeserr           ;jump if error
  381.  Write , Snd_End, 0, Snd_Seg ;write to file
  382.  Add Sp, 2              ;throw away bytes written
  383.  Close                  ;close it
  384.  Ret
  385.  
  386. ;--- error creating file
  387.  
  388. Writeserr
  389.  Add Sp, 2              ;throw away handle
  390.  Display Writesmess2    ;display error message
  391.  Sound Err_Ton, Err_Dur ;error beep
  392.  Call Wait              ;wait for key
  393.  Ret
  394.  
  395. ;--- data
  396.  
  397. Writesmess1 Label Byte
  398.  Db 45
  399.  Db 13,10
  400.  Db 'Writing sounds to file',13,10
  401.  Db 13,10
  402.  Db 'Enter file name: '
  403.  
  404. Writesmess2 Label Byte
  405.  Db 23,13,10,'Could not create file'
  406.  Endp                   ;Write_Sounds
  407.  
  408. ;================================================
  409. ; Load sounds from a file.
  410.  
  411. Read_Sounds Proc Near
  412.  Display Readsmess1     ;display
  413.  Input Nam_Siz          ;input file name
  414.  Open                   ;open file
  415.  Jc Readserr            ;jump if error
  416.  Read , Snd_Siz, 0, Snd_Seg ;read from file
  417.  
  418.  Pop Ax                 ;bytes read
  419.  Mov Bx, 10
  420.  Sub Dx, DX
  421.  Div Ax, Bx             ;divide by ten
  422.  Mov Snd_Num, Ax        ;save number of sounds
  423.  Mul Ax, Bx             ;multiply by ten
  424.  Mov Snd_End, Ax        ;make it an even ten multiple
  425.  Mov Snd_Idx, 1         ;reset last index
  426.  
  427.  Close                  ;close file
  428.  Ret
  429.  
  430. ;--- error opening file
  431.  
  432. Readserr
  433.  Add Sp, 2              ;throw away handle
  434.  Display Readsmess2     ;display error message
  435.  Sound Err_Ton, Err_Dur ;error beep
  436.  Call Wait              ;wait for key
  437.  Ret
  438.  
  439. ;--- data
  440.  
  441. Readsmess1 Label Byte
  442.  Db 47
  443.  Db 13,10
  444.  Db 'Reading sounds from file',13,10
  445.  Db 13,10
  446.  Db 'Enter file name: '
  447.  
  448. Readsmess2 Label Byte
  449.  Db 21,13,10,'Could not open file'
  450.  Endp                   ;Read_Sounds
  451.  
  452. ;================================================
  453. ; Clear all sounds.
  454.  
  455. Clear_Sounds Proc Near
  456.  Mov Snd_Num, 0         ;set number defined to zero
  457.  Mov Snd_End, 0         ;set pointer to start
  458.  Mov Snd_Idx, 1         ;set index to first
  459.  Ret
  460.  Endp                   ;Clear_Sounds
  461.  
  462. ;================================================
  463. ; Set all sound characteristics.  The sound is
  464. ; set to the seqence location at SI.
  465.  
  466. Set_Sound Proc Near
  467.  Push Si
  468.  
  469. ;--- set frequency
  470.  
  471.  Mov Si, Offset Tonmess1 ;message
  472.  Mov Di, Offset Snd_Now ;number
  473.  Call Input_Num         ;input number
  474.  
  475. ;--- set velocity
  476.  
  477.  Mov Si, Offset Tonmess2 ;message
  478.  Mov Di, Offset Snd_Vel ;number
  479.  Call Input_Num         ;input number
  480.  
  481. ;--- set acceleration
  482.  
  483.  Mov Si, Offset Tonmess3 ;message
  484.  Mov Di, Offset Snd_Acc ;number
  485.  Call Input_Num         ;input number
  486.  
  487. ;--- set duration
  488.  
  489.  Mov Si, Offset Tonmess4 ;message
  490.  Mov Di, Offset Snd_Dur ;number
  491.  Call Input_Num         ;input number
  492.  
  493. ;--- set up or down
  494.  
  495. Tonudrep
  496.  Mov Si, Offset Tonmess5 ;message
  497.  Call Input_Chr         ;input
  498.  Cmp Al, 'U'            ;check if U
  499.  Je Tonup
  500.  Cmp Al, 'D'            ;check if D
  501.  Je Tondn
  502.  Sound Err_Ton, Err_Dur ;error beep
  503.  Jmps Tonudrep          ;loop back if error
  504.  
  505. Tonup
  506.  And Snd_Sta, Not Dwn_Snd ;clear down bit
  507.  Jmps Toncont
  508.  
  509. Tondn
  510.  Or Snd_Sta, Dwn_Snd    ;set down bit
  511.  
  512. ;--- play tone
  513.  
  514. Toncont
  515.  Pop Si
  516.  Push Ds
  517.  Mov Ds, Snd_Seg        ;set tone segment
  518.  Cs:
  519.  Mov Ax, Snd_Now        ;starting tone
  520.  Mov [Si], Ax           ;save
  521.  Cs:
  522.  Mov Bx, Snd_Vel        ;tone velocity
  523.  Mov [Si+2], Bx         ;save
  524.  Cs:
  525.  Mov Dx, Snd_Acc        ;tone acceleration
  526.  Mov [Si+4], Dx         ;save
  527.  Cs:
  528.  Mov Cx, Snd_Dur        ;tone duration
  529.  Mov [Si+6], Cx         ;save
  530.  Cs:
  531.  Mov Bp, Snd_Sta        ;tone status
  532.  Mov [Si+8], Bp         ;save
  533.  Pop Ds
  534.  
  535.  Test Bp, Dwn_Snd       ;test if down
  536.  Jnz Gotondn            ;jump if so
  537.  
  538.  Call Tone_Up           ;sound tone up
  539.  Ret
  540.  
  541. Gotondn
  542.  Call Tone_Dn           ;sound tone down
  543.  Ret
  544.  
  545. ;--- data
  546.  
  547. Tonmess1 Db 12,'Enter tone ['
  548. Tonmess2 Db 16,'Enter velocity ['
  549. Tonmess3 Db 20,'Enter acceleration ['
  550. Tonmess4 Db 16,'Enter duration ['
  551. Tonmess5 Db 38,'Enter (',27,'[1mU',27,'[0m)p or (',27,'[1mD',27,'[0m)own: '
  552.  Endp
  553.  
  554. ;================================================
  555. ; Sound the speaker up. The the starting tone 
  556. ; must be in AX, velocity in BX, the acceleration
  557. ; in DX, and the duration in CX.
  558.  
  559. Tone_Up Proc Near
  560.  Mov Di, Ton_Max        ;maximum tone
  561.  
  562.  Cmp Cx, Dur_Max        ;check if too long
  563.  Jne Tonudok            ;jump if ok
  564.  Mov Cx, Dur_Max        ;set to max
  565.  
  566. Tonudok
  567.  Shr Cx                 ;cut duration in half
  568.  Inc Cx                 ;add one
  569.  
  570. Tonuploop
  571.  Sound Ax, 2            ;sound speaker
  572.  Add Ax, Bx             ;increase frequency
  573.  Jc Tonupdone           ;jump if overflow
  574.  
  575.  Cmp Ax, Di             ;check high range
  576.  Ja Tonupdone
  577.  
  578.  Add Bx, Dx             ;increase velocity
  579.  Loop Tonuploop         ;loop back if more
  580.  
  581. Tonupdone Ret
  582.  Endp                   ;Tone_Up
  583.  
  584. ;================================================
  585. ; Sound the speaker down. The the starting tone 
  586. ; must be in AX, velocity in BX, the acceleration
  587. ; in DX, and the duration in CX.
  588.  
  589. Tone_Dn Proc Near
  590.  Mov Di, Ton_Min        ;minimum tone
  591.  
  592.  Cmp Cx, Dur_Max        ;check if too long
  593.  Jne Tonddok            ;jump if ok
  594.  Mov Cx, Dur_Max        ;set to max
  595.  
  596. Tonddok
  597.  Shr Cx                 ;cut in duration in half
  598.  Inc Cx                 ;add one
  599.  
  600. Tondnloop
  601.  Sound Ax, 2            ;sound speaker
  602.  Sub Ax, Bx             ;decrease frequency
  603.  Jc Tondndone           ;jump if underflow
  604.  
  605.  Cmp Ax, Di             ;check lower range
  606.  Jb Tondndone           ;jump if out of range
  607.  
  608.  Add Bx, Dx             ;increase velocity
  609.  Loop Tondnloop         ;loop back if more
  610.  
  611. Tondndone Ret
  612.  Endp                   ;Tone_Dn
  613.  
  614. ;================================================
  615. ; Display the string at SI and input a single
  616. ; character. The character is converted to 
  617. ; upper-case.
  618.  
  619. Input_Chr Proc Near
  620.  Display Si             ;display string
  621.  Input                  ;input character to AL
  622.  Line Al                ;echo
  623.  Uppercase              ;convert to upper-case
  624.  Ret
  625.  Endp                   ;Input_Chr
  626.  
  627. ;================================================
  628. ; Display the string at SI and input a number. 
  629. ; The storage for the number should be at DI. The
  630. ; number is set to [DI] and returned in AX.
  631.  
  632. Input_Num Proc Near
  633.  
  634. Inputerrlo
  635.  Display Si             ;display string
  636.  Decimal Word [Di]      ;convert to string
  637.  Bold                   ;set to bold
  638.  Display                ;show it
  639.  Normal                 ;set to normal
  640.  Display Inpfinish      ;display end part
  641.  
  642.  Input 5                ;input number
  643.  Jz Inputndef           ;jump if default
  644.  
  645.  Binary                 ;convert to binary
  646.  Jc Inputnerr           ;jump if error
  647.  
  648.  Pop Dx
  649.  Pop Ax                 ;get number in DX:AX
  650.  Or Dx, Dx              ;check if really 16 bit
  651.  Jnz Input_Num          ;jump back and try again if not
  652.  
  653.  Mov [Di], Ax           ;save value
  654.  Ret
  655.  
  656. ;--- use default number
  657.  
  658. Inputndef
  659.  Add Sp, 4              ;throw away input string location
  660.  Mov Ax, [Di]           ;get number
  661.  Ret
  662.  
  663. ;--- error in number
  664.  
  665. Inputnerr
  666.  Add Sp, 4              ;throw away number returned, no good
  667.  Sound Err_Ton, Err_Dur ;error beep
  668.  Jmps Inputerrlo        ;try again
  669.  
  670. ;--- data
  671.  
  672. Inpfinish Db 3, ']: '
  673.  Endp                   ;Input_Num
  674.  
  675. ;================================================
  676. ; Display prompt and wait for any key.
  677.  
  678. Wait Proc Near
  679.  Line
  680.  Line
  681.  Display '[press any key]' ;show message
  682.  Input                  ;wait for key
  683.  Ret
  684.  Endp                   ;Wait
  685.  
  686. ;================================================
  687. ; Stack.
  688.  
  689.  Org +Stack_Size
  690. Stack_Top Label Byte
  691. End
  692.  
  693.