Subversion Repositories ngs

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ;
  2. ;       ╔═══════════════════════════════════════════════╗
  3. ;       ║                                               ║
  4. TITLE   ║ SOUNDBLASTER MODPLAYER  (SB/SBPRO/16 & COMP.)
  5. ;       ║                                               ║
  6. ;       ╚═══════════════════════════════════════════════╝
  7. ;
  8. ; THIS MODULE PLAYER WAS CODED IN EARLY 1994
  9. ;
  10. ;                        BY SILVIO TURELLO (FRONTMAN/CREW242)
  11. ;
  12. ; IT IS A COMPLETELY REVISED VERSION OF THE MODLIB
  13. ;
  14. ;                        BY SERGE HUBER (NUMERUS/IMPHOBIA)
  15. ;
  16. ; PC-CONVERSION OF AMIGA PROTRACKER CODE (FOR SUPER PRO PLAY > MODLIB)
  17. ;
  18. ;                        BY JOSHUA C. JENSEN (CYBERSTRIKE/FORM. RENAISSANCE)
  19. ;
  20. ; ORIGIN SOURCE CODE CAME FROM THE PROTRACKER V2.1A
  21. ;
  22. ;                        BY LARS "ZAP" HAMRE (AMIGA FREELANCERS)
  23. ;
  24. ; FEATURES: 4/8-CHANNEL-MODS (M.K./FLT4/FLT8/8CHN), MIXINGRATE 10000-22222 HZ
  25. ;
  26. ;           1/2-FX-CHANNELS, FULL MOD-FX SUPPORT EXCEPT FILTER & REVERSE FUNK
  27. ;
  28. ;           STEREO FOR SBPRO&16, ONLY 10% (APPROX.) PERFORMANCE REDUCTION
  29. ;
  30. ;           544 KB EMS-MEMORY SUPPORT FOR FX
  31. ;
  32. DOSSEG
  33. .MODEL TINY
  34. STACKLENGTH     = 0100H
  35. ASSUME CS:DGROUP, DS:DGROUP; SS:DGROUP
  36. ;=============================================================================
  37. MAX_CHAN_NUMB   = 8
  38. IRQ1            = 20H
  39. IRQ2            = 21H
  40. IRQ3            =0A0H
  41. IRQ4            =0A1H
  42. TIMER0          = 40H
  43. PIT1            = 43H
  44. UHR_INDEX       = 70H
  45. UHR_PORT        = 71H
  46. UHR_STATA       = 0AH
  47. UHR_STATB       = 0BH
  48. UHR_STATC       = 0CH
  49. ;-----------------------------------------------------------------------------
  50. .DATA
  51. PROG_START_SEG  DW 0
  52. PROG_END_SEG    DW 0
  53. SYSTEM          DB 0
  54. IRQCOUNT        DB 56
  55. SBPRO_FLAG      DB 0            ;0=SB, 1= SBPRO
  56. SB_TYP          DB 1            ;0=GUS, 1=SBPRO, 2=SB, 3=NO_SOUND
  57. SB_MODUS        DB 0            ;0=MUSIC&FX 1=MUSIC 2=FX 3=NO_SOUND
  58. SAM_FLAG        DB 0            ;FLIP SAMPLE CHANNEL
  59. SAMPLE_RATE     DW 22222
  60. SBP_MIXERI      DW 0224H
  61. SBP_MIXERD      DW 0225H
  62. SB_RESET        DW 0226H
  63. SB_READ         DW 022AH
  64. SB_WRITE        DW 022CH
  65. SB_RSTAT        DW 022EH
  66. IRQ_NUMBER      DB 7
  67. DMA_CHANNEL     DB 1
  68. DMA_RATE        DB 211
  69. DMA_PAGE        DB 0
  70. DMA_POFF        DW 0
  71. DMA_DATA        DB 87H,83H,81H,82H
  72. MAINFREQ        DD 41236
  73. DMA_CX          DW 434
  74. DMA_MORE        DW 434*4
  75. DMA_MAX         DW 434*16
  76. DMA_NEWPTR      DW 0
  77. DMA_PTR         DW 0
  78. DMA_SEG         DW 0
  79. DMA_OFFSET      DW 0
  80. MIXMUL_OFFSET   DW 0
  81. COMP_SPEED2     DW 0106H
  82. COMP_SPEED3     DW 4006H
  83. COMP_SPEED4     DW 0
  84. COMP_SPEED5     DW 1165
  85. HOLD70  LABEL   DWORD
  86.                 DW OFFSET TIMER_HANDLER, 0
  87. HOLDSB  LABEL   DWORD
  88.                 DW OFFSET SBIRQ_HANDLER, 0
  89. STEREO_PANNING  DW 2,-2,0,2,0,-2,0,2,0
  90. ;-----------------------------------------------------------------------------
  91. GDDLENGTH       DD 0
  92. GDDREST         DW 0
  93. GDDHANDLE       DW 0
  94. ;GDDMIN         DW -1
  95. ;GDDNEW         DW 0
  96. ;GDDPOSL        DW 0
  97. ;GDDPOSH        DW 0
  98. GDDZEIG         DB 0
  99. ;-----------------------------------------------------------------------------
  100. ERROR1_TEXT     DB "MOD ERROR",13,10,"$"
  101. ERROR2_TEXT     DB "FX ERROR",13,10,"$"
  102. ERROR3_TEXT     DB "SB ERROR",13,10,"$"
  103. OUT_TEXT        DB "+/- VOLUME",13,10
  104.                 DB "1   PLAY SAMPLE",13,10
  105.                 DB "9   INIT REPEAT",13,10
  106.                 DB "0   MUSIC MODE",13,10,"$"
  107. SAMPLE_NAME     DB "SAMPLE1.SAM",0
  108. CONFIG_NAME     DB "SS.CFG",0
  109. VOL_NAME        DB "FM.VOL",0
  110. CFG_TEXT1       DB "DEFAULT MUSIC SYSTEM = ",0
  111. CFG_TEXT2       DB "DEFAULT MUSIC MODE = ",0
  112. CFG_TEXT3       DB "SOUNDCARD BASE PORT = ",0
  113. CFG_TEXT4       DB "SOUNDCARD IRQ NUMBER = ",0
  114. CFG_TEXT5       DB "SOUNDCARD DMA NUMBER = ",0
  115. CFG_TEXT6       DB "DEFAULT SAMPLINGRATE = ",0
  116. CFG_TEXT7       DB "SYSTEM COMPATIBILITY = ",0
  117. ;-----------------------------------------------------------------------------
  118. ; PLAYER - CONTROL STRUCTURES
  119. ;-----------------------------------------------------------------------------
  120. ALIGN 2
  121. MUSIC_VOL       DB 255
  122. MUSIC_VOLUME    DB 255
  123. FX_VOL          DB 255
  124. FX_VOLUME       DB 255
  125. MASTER_VOLUME   DB 255
  126. MOD_STAT        DB 0
  127. BPM_COUNT       DB 1
  128. BPM_SPEED       DB 20
  129. CH_NUMB         DW 4
  130. QUEUE_BUFFER    LABEL   WORD            ;256 BYTES
  131. NOTE            DW MAX_CHAN_NUMB DUP(0)
  132. CMD             DB MAX_CHAN_NUMB DUP(0)
  133. CMDLO           DB MAX_CHAN_NUMB DUP(0)
  134. START           DW MAX_CHAN_NUMB DUP(0)
  135. LENGTHI         DW MAX_CHAN_NUMB DUP(0)
  136. LOOPSTART       DW MAX_CHAN_NUMB DUP(0)
  137. REPLEN          DW MAX_CHAN_NUMB DUP(0)
  138. PERIOD          DW MAX_CHAN_NUMB DUP(0)
  139. FINETUNE        DB MAX_CHAN_NUMB DUP(0)
  140. VOLUME          DB MAX_CHAN_NUMB DUP(0)
  141. TONEPORTDIREC   DB MAX_CHAN_NUMB DUP(1)
  142. TONEPORTSPEED   DB MAX_CHAN_NUMB DUP(0)
  143. WANTEDPERIOD    DW MAX_CHAN_NUMB DUP(0)
  144. VIBRATOCMD      DB MAX_CHAN_NUMB DUP(0)
  145. VIBRATOPOS      DB MAX_CHAN_NUMB DUP(0)
  146. TREMOLOCMD      DB MAX_CHAN_NUMB DUP(0)
  147. TREMOLOPOS      DB MAX_CHAN_NUMB DUP(0)
  148. WAVECONTROL     DB MAX_CHAN_NUMB DUP(0)
  149. GLISSFUNK       DB MAX_CHAN_NUMB DUP(0)
  150. SAMPLEOFFSET    DB MAX_CHAN_NUMB DUP(0)
  151. PATTPOS         DB MAX_CHAN_NUMB DUP(0)
  152. LOOPCOUNT       DB MAX_CHAN_NUMB DUP(0)
  153.  
  154. MFREQ           DW MAX_CHAN_NUMB DUP(0)
  155. MOFLOW          DB MAX_CHAN_NUMB DUP(0)
  156. SONG_DATA       LABEL   BYTE            ;128 BYTES
  157. MVOL            DB MAX_CHAN_NUMB DUP(0)
  158. MSEG            DW MAX_CHAN_NUMB DUP(0)
  159. MOFS            DW MAX_CHAN_NUMB DUP(0)
  160. MREPEAT         DW MAX_CHAN_NUMB DUP(0)
  161. MREPLEN         DW MAX_CHAN_NUMB DUP(0)
  162. MMAXREP         DW MAX_CHAN_NUMB DUP(0)
  163. MOD_NAME        DB 40 DUP(0)
  164. ;-----------------------------------------------------------------------------
  165. ; Seg                           Stores the segment of the current sample.  If
  166. ;                               the segment is zero, then there is no sample
  167. ;                               begin played.
  168. ; Offset                        The current offset of the sample being played
  169. ;                               in the segment specified.
  170. ; MaxRep                        The offset of the place in the sample to
  171. ;                               repeat from (i.e. the end of the sample).
  172. ; Freq                          The frequency to be played out the output
  173. ;                               device.  It is actually a playback period,
  174. ;                               the upper byte determining the number of
  175. ;                               bytes to be added to the sample offset each
  176. ;                               interrupt, and the lower byte to be added
  177. ;                               over and over to generate carry flags to be
  178. ;                               added to additional offsets.
  179. ; Vol                           The actual volume to multiply the frequency
  180. ;                               by.
  181. ; Repeat                        The place to repeat from when the end of the
  182. ;                               loop is found.
  183. ; RepLen                        The number of bytes from Repeat to go to.
  184. ;                               When the end of this is found, it goes back
  185. ;                               to Repeat.
  186. ; OFlow                         The overflow variable used to generate the
  187. ;                               carry flags.
  188. ;-----------------------------------------------------------------------------
  189. ; PROTRACKER VARIABLES
  190. ;-----------------------------------------------------------------------------
  191. ALIGN 2
  192. MT_SPEED                DB 6
  193. MT_COUNTER              DB 0
  194. MT_PATTERNPOS           DW 0
  195. MT_SONGPOS              DB 0
  196. MT_PATTDELAYTIME2       DB 0
  197. MT_PATTDELAYTIME        DB 0
  198. MT_PBREAKFLAG           DB 0
  199. MT_PBREAKPOS            DB 0
  200. MT_POSJUMPFLAG          DB 0
  201. MT_LOWMASK              DB 0FFH
  202.  
  203. ALIGN 2
  204. Effect_Jump_Table1      LABEL   WORD
  205. DW OFFSET Go_Arpeggio, OFFSET Go_PortaUp, OFFSET Go_PortaDown
  206. DW OFFSET Go_TonePortamento, OFFSET Go_vibrato, OFFSET Go_TonePlusVolSlide
  207. DW OFFSET Go_VibratoPlusVolSlide, OFFSET Go_Tremolo, OFFSET Go_Return
  208. DW OFFSET Go_Return, OFFSET Go_VolumeSlide, OFFSET Go_Return, OFFSET Go_Return
  209. DW OFFSET Go_Return, OFFSET Go_E_Commands, OFFSET Go_Return
  210.  
  211. Effect_Jump_Table2      LABEL   WORD
  212. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  213. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  214. DW OFFSET Go_PerNop, OFFSET Go_PerNop, OFFSET Go_PerNop
  215. DW OFFSET Go_SampleOffset, OFFSET Go_PerNop, OFFSET Go_PositionJump
  216. DW OFFSET Go_VolumeChange, OFFSET Go_PatternBreak
  217. DW OFFSET Go_E_Commands, OFFSET Go_SetSpeed
  218.  
  219. Effect_Jump_Table3      LABEL   WORD
  220. DW OFFSET Go_Return, OFFSET Go_FinePortaUp, OFFSET Go_FinePortaDown
  221. DW OFFSET Go_SetGlissControl, OFFSET Go_SetVibratoControl
  222. DW OFFSET Go_SeTFineTune, OFFSET Go_JumpLoop, OFFSET Go_SetTremoloControl
  223. DW OFFSET Go_Return, OFFSET Go_RetrigNote, OFFSET Go_VolumeFineUp
  224. DW OFFSET Go_VolumeFineDown, OFFSET Go_NoteCut, OFFSET Go_NoteDelay
  225. DW OFFSET Go_PatternDelay, OFFSET Go_Return
  226.  
  227. ALIGN 2
  228. MT_VIBRATOTABLE         DB   0, 24, 49, 74, 97,120,141,161
  229.                         DB 180,197,212,224,235,244,250,253
  230.                         DB 255,253,250,244,235,224,212,197
  231.                         DB 180,161,141,120, 97, 74, 49, 24
  232.  
  233. ALIGN 2
  234. MT_PERIODTABLE  LABEL   WORD
  235. DW 856,808,762,720,678,640,604,570,538,508,480,453 ;C-1 to H-1 Finetune +0.
  236. DW 428,404,381,360,339,320,302,285,269,254,240,226 ;C-2 to H-2 Finetune +0.
  237. DW 214,202,190,180,170,160,151,143,135,127,120,113 ;C-3 to H-3 Finetune +0.
  238. DW 107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60, 56 ;C-4 to H-4 Finetune +0.
  239.  
  240. DW 850,802,757,715,674,637,601,567,535,505,477,450 ;C-1 to H-1 Finetune +1.
  241. DW 425,401,379,357,337,318,300,284,268,253,239,225 ;C-2 to H-2 Finetune +1.
  242. DW 213,201,189,179,169,159,150,142,134,126,119,113 ;C-3 to H-3 Finetune +1.
  243. DW 106,100, 94, 89, 84, 79, 75, 71, 67, 83, 59, 56 ;C-4 to H-4 Finetune +1.
  244.  
  245. DW 844,796,752,709,670,632,597,563,532,502,474,447 ;C-1 to H-1 Finetune +2.
  246. DW 422,398,376,355,335,316,298,282,266,251,237,224 ;C-2 to H-2 Finetune +2.
  247. DW 211,199,188,177,167,158,149,141,133,125,118,112 ;C-3 to H-3 Finetune +2.
  248. DW 105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59, 56 ;C-4 to H-4 Finetune +2.
  249.  
  250. DW 838,791,746,704,665,628,592,559,528,498,470,444 ;C-1 to H-1 Finetune +3.
  251. DW 419,395,373,352,332,314,296,280,264,249,235,222 ;C-2 to H-2 Finetune +3.
  252. DW 209,198,187,176,166,157,148,140,132,125,118,111 ;C-3 to H-3 Finetune +3.
  253. DW 104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59, 55 ;C-4 to H-4 Finetune +3.
  254.  
  255. DW 832,785,741,699,660,623,588,555,524,495,467,441 ;C-1 to H-1 Finetune +4.
  256. DW 416,392,370,350,330,312,294,278,262,247,233,220 ;C-2 to H-2 Finetune +4.
  257. DW 208,196,185,175,165,156,147,139,131,124,117,110 ;C-3 to H-3 Finetune +4.
  258. DW 104, 98, 92, 87, 82, 78, 73, 69, 65, 62, 58, 55 ;C-4 to H-4 Finetune +4.
  259.  
  260. DW 826,779,736,694,655,619,584,551,520,491,463,437 ;C-1 to H-1 Finetune +5.
  261. DW 413,390,368,347,328,309,292,276,260,245,232,219 ;C-2 to H-2 Finetune +5.
  262. DW 206,195,184,174,164,155,146,138,130,123,116,109 ;C-3 to H-3 Finetune +5.
  263. DW 103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58, 54 ;C-4 to H-4 Finetune +5.
  264.  
  265. DW 820,774,730,689,651,614,580,547,516,487,460,434 ;C-1 to H-1 Finetune +6.
  266. DW 410,387,365,345,325,307,290,274,258,244,230,217 ;C-2 to H-2 Finetune +6.
  267. DW 205,193,183,172,163,154,145,137,129,122,115,109 ;C-3 to H-3 Finetune +6.
  268. DW 102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57, 54 ;C-4 to H-4 Finetune +6.
  269.  
  270. DW 814,768,725,684,646,610,575,543,513,484,457,431 ;C-1 to H-1 Finetune +7.
  271. DW 407,384,363,342,323,305,288,272,256,242,228,216 ;C-2 to H-2 Finetune +7.
  272. DW 204,192,181,171,161,152,144,136,128,121,114,108 ;C-3 to H-3 Finetune +7.
  273. DW 102, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57, 54 ;C-4 to H-4 Finetune +7.
  274.  
  275. DW 907,856,808,762,720,678,640,604,570,538,504,480 ;C-1 to H-1 Finetune -8.
  276. DW 453,428,404,381,360,339,320,302,285,269,254,240 ;C-2 to H-2 Finetune -8.
  277. DW 226,214,202,190,180,170,160,151,143,135,127,120 ;C-3 to H-3 Finetune -8.
  278. DW 113,107,101, 95, 90, 85, 80, 75, 71, 67, 63, 60 ;C-4 to H-4 Finetune -8.
  279.  
  280. DW 900,850,802,757,715,675,636,601,567,535,505,477 ;C-1 to H-1 Finetune -7.
  281. DW 450,425,401,379,357,337,318,300,284,268,253,238 ;C-2 to H-2 Finetune -7.
  282. DW 225,212,200,189,179,169,159,150,142,134,126,119 ;C-3 to H-3 Finetune -7.
  283. DW 112,106,100, 94, 89, 84, 79, 75, 71, 67, 63, 59 ;C-4 to H-4 Finetune -7.
  284.  
  285. DW 894,844,796,752,709,670,632,597,563,532,502,474 ;C-1 to H-1 Finetune -6.
  286. DW 447,422,398,376,355,335,316,298,282,266,251,237 ;C-2 to H-2 Finetune -6.
  287. DW 223,211,199,188,177,167,158,149,141,133,125,118 ;C-3 to H-3 Finetune -6.
  288. DW 111,105, 99, 94, 88, 83, 79, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -6.
  289.  
  290. DW 887,838,791,746,704,665,628,592,559,528,498,470 ;C-1 to H-1 Finetune -5.
  291. DW 444,419,395,373,352,332,314,296,280,264,249,235 ;C-2 to H-2 Finetune -5.
  292. DW 222,209,198,187,176,166,157,148,140,132,125,118 ;C-3 to H-3 Finetune -5.
  293. DW 111,104, 99, 93, 88, 83, 78, 74, 70, 66, 62, 59 ;C-4 to H-4 Finetune -5.
  294.  
  295. DW 881,832,785,741,699,660,623,588,555,524,494,467 ;C-1 to H-1 Finetune -4.
  296. DW 441,416,392,370,350,330,312,294,278,262,247,233 ;C-2 to H-2 Finetune -4.
  297. DW 220,208,196,185,175,165,156,147,139,131,123,117 ;C-3 to H-3 Finetune -4.
  298. DW 110,104, 98, 92, 87, 82, 78, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -4.
  299.  
  300. DW 875,826,779,736,694,655,619,584,551,520,491,463 ;C-1 to H-1 Finetune -3.
  301. DW 437,413,390,368,347,338,309,292,276,260,245,232 ;C-2 to H-2 Finetune -3.
  302. DW 219,206,195,184,174,164,155,146,138,130,123,116 ;C-3 to H-3 Finetune -3.
  303. DW 109,103, 97, 92, 87, 82, 77, 73, 69, 65, 61, 58 ;C-4 to H-4 Finetune -3.
  304.  
  305. DW 868,820,774,730,689,651,614,580,547,516,487,460 ;C-1 to H-1 Finetune -2.
  306. DW 434,410,387,365,345,325,307,290,274,258,244,230 ;C-2 to H-2 Finetune -2.
  307. DW 217,205,193,183,172,163,154,145,137,129,122,115 ;C-3 to H-3 Finetune -2.
  308. DW 108,102, 96, 91, 86, 81, 77, 72, 68, 64, 61, 57 ;C-4 to H-4 Finetune -2.
  309.  
  310. DW 862,814,768,725,684,646,610,575,543,513,484,457 ;C-1 to H-1 Finetune -1.
  311. DW 431,407,384,363,342,323,305,288,272,256,242,228 ;C-2 to H-2 Finetune -1.
  312. DW 216,203,192,181,171,161,152,144,136,128,121,114 ;C-3 to H-3 Finetune -1.
  313. DW 108,101, 96, 90, 85, 80, 76, 72, 68, 64, 60, 57 ;C-4 to H-4 Finetune -1.
  314. ;-----------------------------------------------------------------------------
  315. ; MTM - TRACK STRUCTURE
  316. ;-----------------------------------------------------------------------------
  317. ALIGN 2
  318. TRACK_NUMBER    DW 0
  319. TRACK_INFO      DB 8 DUP(0)
  320. TRACK_SEG       DW 0
  321. TRACKS_OFFSET   DW OFFSET TRACK1_DATA, OFFSET TRACK2_DATA, OFFSET TRACK3_DATA
  322.                 DW OFFSET TRACK4_DATA, OFFSET TRACK5_DATA, OFFSET TRACK6_DATA
  323.                 DW OFFSET TRACK7_DATA, OFFSET TRACK8_DATA
  324. TRACK1_DATA     DB 128 DUP(0)
  325. TRACK2_DATA     DB 128 DUP(0)
  326. TRACK3_DATA     DB 128 DUP(0)
  327. TRACK4_DATA     DB 128 DUP(0)
  328. TRACK5_DATA     DB 128 DUP(0)
  329. TRACK6_DATA     DB 128 DUP(0)
  330. TRACK7_DATA     DB 128 DUP(0)
  331. TRACK8_DATA     DB 128 DUP(0)
  332. ;-----------------------------------------------------------------------------
  333. ; MOD - FILE STRUCTURE
  334. ;-----------------------------------------------------------------------------
  335. ALIGN 2
  336. SAMPLE_SIZE     DW 0
  337. PATTERN_SIZE    DW 0
  338. PATTERN_SEG     DW 0
  339. PATTERN_NUMBER  DW 0
  340. PATTERN_CURRENT DW 0
  341. ISIZE           DW 31 DUP(0)
  342. IVOL_FINETUNE   DW 31 DUP(0)
  343. ILOOP_START     DW 31 DUP(0)
  344. ILOOP_SIZE      DW 31 DUP(0)
  345. SONG_SIZE       DB 0
  346. SONG_LOOP       DB 0
  347. MOD_SIGN        DD 0
  348. SAMPLE_SEG      DW 31 DUP(0)
  349. ;-----------------------------------------------------------------------------
  350. ; SINGLE SAMPLE VARIABLES
  351. ;-----------------------------------------------------------------------------
  352. SAMPLE_ZEIG     DW 0
  353. SAMPLE_MEM      DW 48 DUP(0)
  354. SAMPLE_BIG      DW 48 DUP(0)
  355. EMS_SEG         DW 0
  356. EMS_OFFSET      DW 0
  357. EMS_HANDLE      DW 0
  358. SAM_SEG1        DW 0
  359. SAM_SEG2        DW 0
  360. SAM_OFS1        DD 0
  361. SAM_OFS2        DD 0
  362. SAM_FRQ1        DW 0
  363. SAM_FRQ2        DW 0
  364. SAM_OFL1        DB 0
  365. SAM_OFL2        DB 0
  366. SAM_MAX1        DW 0
  367. SAM_MAX2        DW 0
  368. ;-----------------------------------------------------------------------------
  369. PROG_END        LABEL   BYTE    ;THIS MUST BE THE LAST ROW IN DATA SEGMENT!
  370. ;-----------------------------------------------------------------------------
  371.  
  372.  
  373.  
  374. .386
  375. .CODE
  376. ORG 100H
  377. ;=============================================================================
  378. MAIN PROC NEAR
  379.         JMP     MAIN_CONT               ;0100
  380.         RETF
  381.         CALL    CONFIG_INIT             ;0104
  382.         RETF
  383.         CALL    LOAD_MOD                ;0108
  384.         RETF
  385.         CALL    PLAY_MUSIC              ;010C
  386.         RETF
  387.         CALL    STOP_MUSIC              ;0110
  388.         RETF
  389.         CALL    END_MUSIC               ;0114
  390.         RETF
  391.         CALL    LOAD_SAMPLE             ;0118
  392.         RETF
  393.         CALL    PLAY_SAMPLE             ;011C
  394.         RETF
  395.         CALL    END_SAMPLE              ;0120
  396.         RETF
  397.         CALL    SET_SAMPLERATE          ;0124
  398.         RETF
  399.         CALL    GET_VOLUME              ;0128
  400.         RETF
  401.         CALL    SET_VOLUME              ;012C
  402.         RETF
  403.         CALL    SET_SONGLOOP            ;0130
  404.         RETF
  405.         CALL    GET_SONGPOSITION        ;0134
  406.         RETF
  407.         CALL    SET_SONGPOSITION        ;0138
  408.         RETF
  409.         CALL    GET_SONGMOD             ;013C
  410.         RETF
  411.         CALL    SET_SONGMOD             ;0140
  412.         RETF
  413.         CALL    DSP_OFF                 ;0144
  414.         RETF
  415.         CALL    DSP_RESET               ;0148
  416.         RETF
  417.         CALL    DSP_RESET               ;014C/FREE
  418.         RETF
  419.         CALL    DSP_RESET               ;0150/FREE
  420.         RETF
  421. MAIN ENDP
  422. ;=============================================================================
  423. ;
  424. ; MOD ROUTINES
  425. ;
  426. ;=============================================================================
  427. ; Format of a note: (ORIGINALLY MOD)
  428. ;
  429. ;                   0 0          0 0          0 0           0 0
  430. ;                   | |          | |          | |           | |
  431. ;                  /   \        / /          /   \           \ \
  432. ;         MSB of Ins.     Note        LSB Ins.  Spec. Com.   Data for special
  433. ;
  434. ; Format of a note: (MODIFIED BY LOADER)
  435. ;
  436. ;                   0 0          0 0          0 0           0 0
  437. ;                   | |          | |          | |           | |
  438. ;                  / /          /   \         \ \           \ \
  439. ;            LSB NOTE   SPEC.COM.    MSB NOTE  INSTRUMENT    DATA FOR SPECIAL
  440. ;
  441. ;╒═══════════════════════════════════════════════════════════════════════════╕
  442. ;│ DESCRIPTION: This procedure shouldn't need to be called by anything else  │
  443. ;│              but the interrupt (ever).  It handles all note updating,     │
  444. ;│              special effects, pointers, etc.                              │
  445. ;│                                                                           │
  446. ;│              *** This code came directly from the Amiga Protracker        │
  447. ;│                  playback code, written by Lars "Zap" Hamre.  Give this   │
  448. ;│                  guy a pat on the back for such excellent code.           │
  449. ;│                                                                           │
  450. ;│ BUGS       : Or rather, non-implementations.  Command EF - Funk it is     │
  451. ;│              not all the way implemented.  Command E0 - Filter is not     │
  452. ;│              implemented at all.  It is Amiga-specific, directly with     │
  453. ;│              the Paula chip.                                              │
  454. ;│                                                                           │
  455. ;│ IMPROVEMENTS:    Optimized code for PC-architecure by the Frontman        │
  456. ;│                                                                           │
  457. ;╘═══════════════════════════════════════════════════════════════════════════╛
  458. CONTROL_CHANNELS PROC NEAR
  459.         CMP     MOD_STAT,3
  460.         JAE     Go_NoNewPosYet
  461.         INC     MT_COUNTER
  462.         MOV     AL,MT_COUNTER
  463.         CMP     AL,MT_SPEED             ; Does it match the current speed?
  464.         JB      SHORT Go_NoNewNote      ; No, just do fx.
  465.         MOV     MT_COUNTER,0
  466.         CMP     MT_PATTDELAYTIME2,0
  467.         JE      SHORT Go_GetNewNote
  468.         CALL    Go_CheckEfx             ; Otherwise, just do fx only.
  469.         JMP     Go_Dskip                ; Then, jump to update block values.
  470. Go_NoNewNote:
  471.         CALL    Go_CheckEfx             ; Do fx.
  472.         JMP     Go_NoNewPosYet          ; We don't update block values
  473.                                         ; when we are just doing fx.
  474. Go_GetNewNote:
  475.         MOV     ES,TRACK_SEG
  476.         XOR     SI,SI
  477. Go_PlayVoice:
  478.         PUSH    SI
  479.         MOV     DI,SI
  480.         SHL     DI,1
  481.         MOVZX   BX,MT_SONGPOS           ; BLOCK BEGINNING TO ES:BX
  482.         ADD     BX,[TRACKS_OFFSET+DI]
  483.         MOVZX   BX,[BX]
  484.         XCHG    BL,BH                   ; MULTIPLY WITH 256 (TRACK-SIZE)
  485.         ADD     BX,MT_PATTERNPOS
  486.         CMP     [NOTE+DI],0             ; See if there is a note.
  487.         JNE     SHORT Go_plvskip        ; No, go on.
  488.         CMP     [CMD+SI],0
  489.         JNE     SHORT Go_plvskip
  490.         CMP     [CMDLO+SI],0
  491.         JNE     SHORT Go_plvskip
  492.         CALL    Go_PerNop               ; Otherwise, figure out the frequency.
  493. Go_plvskip:
  494.         MOV     AX,ES:[BX]              ; Load this channel's information
  495.         MOV     [NOTE+DI],AX            ; from the actual track block and
  496.         AND     [NOTE+DI],0FFFH
  497.         SHR     AH,4                    ; into our own internal structure
  498.         MOV     [CMD+SI],AH             ; to access it from.
  499.         MOV     AX,ES:[BX+2]
  500.         MOV     [CMDLO+SI],AH
  501.         OR      AL,AL                   ; Instrument byte.  Is there an ins?
  502.         JZ      SHORT Go_SetRegs
  503.         DEC     AL
  504.         MOVZX   BX,AL                   ; GET SAMPLE SEGMENT
  505.         SHL     BX,1
  506.         MOV     AX,[SAMPLE_SEG+BX]
  507.         MOV     [START+DI],AX           ; Store it in our structure.
  508.         MOV     AX,[ISIZE+BX]           ; Get the length.
  509.         MOV     [LENGTHI+DI],AX         ; Store it appropriately.
  510.         MOV     [REPLEN+DI],AX
  511.         MOV     AX,[IVOL_FINETUNE+BX]   ; Get the instrument volume and fine tune.
  512.         MOV     [VOLUME+SI],AL          ; Store it appropriately.
  513.         MOV     [FINETUNE+SI],AH
  514.         MOV     [MVOL+SI],AL
  515.         MOV     CX,[ILOOP_SIZE+BX]      ; Get Repeat length
  516.         CMP     CX,8                    ; If the length is less than four,
  517.         JB      SHORT Go_NoLoop         ; then there is no loop.
  518.         MOV     AX,[ILOOP_START+BX]     ; Get the Repeat start.
  519.         MOV     [MREPEAT+DI],AX         ; Move it into the appropriate
  520.         MOV     [LOOPSTART+DI],AX       ; structures and locations.
  521.         MOV     [REPLEN+DI],CX          ; Move the length into its storage.
  522.         ADD     AX,CX                   ; We're figuring out the offset of
  523.         MOV     [MREPLEN+DI],AX
  524.         MOV     [MMAXREP+DI],AX         ; where the repeat length breaks.
  525.         JMP     SHORT Go_SetRegs        ; Skip the no loop part.
  526. Go_NoLoop:
  527.         XOR     AX,AX                   ; Zero out AX.
  528.         MOV     [MREPLEN+DI],AX         ; Make sure that no loop exists and
  529.         MOV     [MREPEAT+DI],AX
  530.         MOV     [LOOPSTART+DI],AX
  531. Go_SetRegs:
  532.         CMP     [NOTE+DI],0             ; Grab the note.
  533.         JE      Go_CheckMore            ; Check the fx.
  534.         MOV     AH,[CMD+SI]             ; Get the special fx command.
  535.         MOV     AL,[CMDLO+SI]
  536.         AND     AL,0F0H                 ; Mask out the bits we don't want.
  537.         CMP     AX,0E50H                ; Is there a fine tune command
  538.         JE      SHORT Go_DoSetFineTune
  539.         CMP     AH,3                    ; Is it a tone portamento?
  540.         JE      SHORT Go_ChkTonePorta
  541.         CMP     AH,5                    ; Is it a tone and volume slide?
  542.         JE      SHORT Go_ChkTonePorta
  543.         CMP     AH,9                    ; Is it a sample offset command?
  544.         JNE     SHORT Go_SetPeriod      ; If not, go do the actual note.
  545.         PUSH    AX                      ; keep the command byte in mem
  546.         CALL    Go_CheckMoreEfx
  547.         POP     AX
  548.         JMP     SHORT Go_SetPeriod      ; Go do the actual note.
  549. Go_ChkTonePorta:
  550.         CALL    Go_SetTonePorta         ; Do part of the tone portamento.
  551.         JMP     Go_CheckMore            ; Go do the fx.
  552. Go_DoSetFineTune:
  553.         PUSH    AX
  554.         CALL    Go_SetFineTune          ; Update the fine tune.
  555.         POP     AX
  556. ;-----------------------------------------------------------------------------
  557. ; ──── We are now going to find the note in the period table.  If it
  558. ; ──── doesn't exist, then no fine tuning can be performed.  If it
  559. ; ──── does, and fine tuning is specified, then we can update it.
  560. ;-----------------------------------------------------------------------------
  561. Go_SetPeriod:
  562.         MOV     CL,AH
  563.         MOV     AX,[NOTE+DI]            ; Get the note.
  564.         DEC     AX
  565.         MOV     BX,OFFSET MT_PERIODTABLE; Set pointer to beginning of table.
  566.         CMP     CL,3
  567.         JE      SHORT Seek_Period
  568.         CMP     CL,5
  569.         JNE     SHORT Go_ftufound
  570. Seek_Period:
  571.         INC     AX
  572.         MOV     CX,36+12                ; 36 periods to cycle through.
  573. Go_ftuloop:
  574.         CMP     AX,[BX]                 ; Check the note against the period.
  575.         JAE     SHORT Go_Wizzyfound     ; We found it!
  576.         INC     BX
  577.         INC     BX                      ; Otherwise, update the pointer and
  578.         LOOP    Go_ftuloop              ; keep looping.
  579.         JMP     SHORT Go_Wizzyfound
  580. Go_ftufound:
  581.         ADD     BX,AX
  582. Go_WizzyFound:
  583.         MOV     AL,[FINETUNE+SI]        ; Get the fine tune.
  584.         MOV     CL,(36+12)*2            ; The period table's size is 72.
  585.         MUL     CL                      ; Multiply it by the fine tune.
  586.         ADD     BX,AX                   ; Add it onto the pointer to point to
  587.         MOV     AX,[BX]                 ; the new period and get it.
  588.         MOV     [PERIOD+DI],AX          ; Store it.
  589.         MOV     AH,[CMD+SI]             ; Get the special fx command.
  590.         MOV     AL,[CMDLO+SI]
  591.         AND     AL,0F0H                 ; Mask out the bits we don't want.
  592.         CMP     AX,0ED0H
  593.         JE      SHORT Go_delnoc
  594.         MOV     AL,[WAVECONTROL+SI]     ; Get the WaveControl.
  595.         TEST    AL,00000100B            ; Amiga: BTST #2,WaveControl.
  596.         JZ      SHORT Go_vibnoc         ; If it is zero, then skip.
  597.         MOV     [VIBRATOPOS+SI],0
  598. Go_vibnoc:
  599.         TEST    AL,01000000B            ; Amiga: BTST #6,WaveControl
  600.         JZ      SHORT Go_trenoc         ; If it is zero, then skip.
  601.         MOV     [TREMOLOPOS+SI],0       ; Zero the Tremolo offset.
  602. Go_trenoc:
  603.         MOV     AX,[START+DI]           ; Get the start segment.
  604.         MOV     [MSEG+DI],AX            ; Store it to be updated.
  605.         MOV     [MOFS+DI],0             ; Set the offset to zero.
  606.         MOV     [MOFLOW+SI],0
  607.         MOV     AX,[LENGTHI+DI]
  608.         MOV     [MMAXREP+DI],AX         ; Store in MaxRepeat
  609.         MOV     CX,[PERIOD+DI]
  610.         CALL    Go_PerNop2
  611.         JMP     SHORT Go_CheckMore
  612. Go_delnoc:
  613.         MOV     AX,[MMAXREP+DI]
  614.         MOV     [MOFS+DI],AX
  615. Go_CheckMore:
  616.         CALL    Go_CheckMoreEfx
  617. Go_DoNext:
  618.         POP     SI                      ;SKIP TO NEXT CHANNEL
  619.         INC     SI
  620.         CMP     SI,CH_NUMB
  621.         JB      Go_PlayVoice
  622. ;-----------------------------------------------------------------------------
  623. Go_Dskip:
  624.         ADD     MT_PATTERNPOS,4         ; Increment position by one
  625.         MOV     AL,MT_PATTDELAYTIME
  626.         OR      AL,AL
  627.         JZ      SHORT Go_dskc
  628.         MOV     MT_PATTDELAYTIME2,AL
  629.         MOV     MT_PATTDELAYTIME,0
  630. Go_dskc:
  631.         CMP     MT_PATTDELAYTIME2,0
  632.         JE      SHORT Go_dska
  633.         DEC     MT_PATTDELAYTIME2
  634.         JZ      SHORT Go_dska
  635.         SUB     MT_PATTERNPOS,4
  636. Go_dska:
  637.         CMP     MT_PBREAKFLAG,0
  638.         JE      SHORT Go_nnpysk
  639.         MOV     MT_PBREAKFLAG,0
  640.         MOVZX   AX,MT_PBREAKPOS
  641.         MOV     MT_PBREAKPOS,AH
  642.         SHL     AX,2
  643.         MOV     MT_PATTERNPOS,AX
  644. Go_nnpysk:
  645.         CMP     MT_PATTERNPOS,256
  646.         JB      SHORT Go_NoNewPosYet
  647. Go_NextPosition:
  648.         MOVZX   AX,MT_PBREAKPOS
  649.         SHL     AX,2
  650.         MOV     MT_PATTERNPOS,AX
  651.         MOV     MT_PBREAKPOS,0
  652.         MOV     MT_POSJUMPFLAG,0
  653.         MOV     AL,MT_SONGPOS
  654.         INC     AL
  655.         AND     AL,7FH
  656.         CMP     AL,SONG_SIZE
  657.         JB      SHORT Go_NoSongRestart
  658.         MOV     AL,SONG_LOOP
  659.         CMP     AL,SONG_SIZE
  660.         JB      SHORT Go_NoSongRestart
  661.         MOV     MOD_STAT,3
  662.         XOR     AL,AL
  663. Go_NoSongRestart:
  664.         MOV     MT_SONGPOS,AL
  665. Go_NoNewPosYet:
  666.         CMP     MT_POSJUMPFLAG,0
  667.         JNE     Go_NextPosition
  668.         RET
  669. CONTROL_CHANNELS ENDP
  670. ;=============================================================================
  671. Go_CheckEfx PROC NEAR
  672.         XOR     SI,SI
  673. Go_DoEfx:
  674.         PUSH    SI
  675.         MOV     DI,SI
  676.         SHL     DI,1
  677.         MOV     BL,[CMD+SI]              ; Get the special command
  678.         MOV     BH,[CMDLO+SI]
  679.         OR      BX,BX
  680.         JNZ     SHORT SetBack1
  681.         CALL    Go_PerNop
  682.         JMP     SHORT SetBack2
  683. SetBack1:
  684.         XOR     BH,BH
  685.         SHL     BX,1
  686.         CALL    [Effect_Jump_Table1+BX]
  687. SetBack2:
  688.         POP     SI
  689.         INC     SI
  690.         CMP     SI,CH_NUMB
  691.         JB      Go_DoEfx
  692. Go_Return:
  693.         RET
  694. ;-----------------------------------------------------------------------------
  695. Go_PerNop PROC NEAR
  696.         MOV     CX,[PERIOD+DI]
  697. Go_PerNop2 PROC NEAR
  698.         XOR     AX,AX
  699.         JCXZ    SHORT Go_DivZero
  700.         MOV     AX,WORD PTR MAINFREQ
  701.         MOV     DX,WORD PTR MAINFREQ+2
  702.         DIV     CX
  703. Go_DivZero:
  704.         MOV     [MFREQ+DI],AX
  705.         RET
  706. Go_PerNop2 ENDP
  707. Go_PerNop ENDP
  708. Go_CheckEfx ENDP
  709. ;=============================================================================
  710. ;
  711. ; SI IS THE CHANNEL-BYTE-INDEX, DI IS THE CHANNEL-WORD-INDEX
  712. ;
  713. ;─────────────────────────────────────────────────────────────────────────────
  714. ; Effect 0 -- Arpeggio
  715. ;─────────────────────────────────────────────────────────────────────────────
  716. Go_Arpeggio PROC NEAR
  717.         MOVZX   AX,MT_COUNTER
  718.         MOV     BL,3
  719.         MOV     CX,[PERIOD+DI]
  720.         DIV     BL
  721.         OR      AH,AH
  722.         JZ      SHORT Go_Arpeggio1
  723.         MOV     AL,[CMDLO+SI]
  724.         CMP     AH,2
  725.         JE      SHORT Go_Arpeggio2
  726.         SHR     AL,4
  727. Go_Arpeggio2:
  728.         AND     AL,0FH
  729.         SHL     AL,1
  730.         MOVZX   BX,AL
  731.         MOV     AL,[FINETUNE+SI]
  732.         MOV     DX,CX
  733.         MOV     CL,(36+12)*2
  734.         MUL     CL
  735.         PUSH    DI
  736.         MOV     DI,OFFSET MT_PERIODTABLE
  737.         ADD     DI,AX
  738.         MOV     AH,36+12
  739. Go_arploop:
  740.         MOV     CX,[BX+DI]
  741.         CMP     DX,[DI]
  742.         JAE     SHORT Go_arpafterloop
  743.         INC     DI
  744.         INC     DI
  745.         DEC     AH
  746.         JNZ     Go_arploop
  747.         POP     DI
  748.         RET
  749. Go_arpafterloop:
  750.         POP     DI
  751. Go_Arpeggio1:
  752.         CALL    Go_PerNop2
  753.         RET
  754. Go_Arpeggio ENDP
  755. ;─────────────────────────────────────────────────────────────────────────────
  756. ; Effect 1 -- Portamento Up
  757. ;─────────────────────────────────────────────────────────────────────────────
  758. Go_PortaUp PROC NEAR
  759.         MOVZX   AX,[CMDLO+SI]           ; Number to slide up (was lo)
  760.         AND     AL,MT_LOWMASK
  761.         MOV     MT_LOWMASK,0FFH
  762.         SUB     [PERIOD+DI],AX
  763.         MOV     CX,[PERIOD+DI]
  764.         CMP     CX,113
  765.         JGE     SHORT Go_PortaUSkip
  766.         MOV     CX,113
  767.         MOV     [PERIOD+DI],CX
  768. Go_PortaUSkip:
  769.         CALL    Go_PerNop2
  770.         RET
  771. Go_PortaUp ENDP
  772. ;────────────────────────────────────────────────────────────────────────────
  773. ; Effect 2 -- Portamento Down
  774. ;────────────────────────────────────────────────────────────────────────────
  775. Go_PortaDown PROC NEAR
  776.         MOVZX   AX,[CMDLO+SI]           ; Number to slide down
  777.         AND     AL,MT_LOWMASK
  778.         MOV     MT_LOWMASK,0FFH
  779.         ADD     [PERIOD+DI],AX
  780.         MOV     CX,[PERIOD+DI]
  781.         CMP     CX,856
  782.         JL      SHORT Go_PortaDSkip
  783.         MOV     CX,856
  784.         MOV     [PERIOD+DI],CX
  785. Go_PortaDSkip:
  786.         CALL    Go_PerNop2
  787.         RET
  788. Go_PortaDown ENDP
  789. ;────────────────────────────────────────────────────────────────────────────
  790. ; Effect 3 -- Tone Portamento
  791. ;────────────────────────────────────────────────────────────────────────────
  792. Go_TonePortamento PROC NEAR
  793.         MOV     AL,[CMDLO+SI]
  794.         OR      AL,AL
  795.         JZ      SHORT Go_TonePortNoChange
  796.         MOV     [TONEPORTSPEED+SI],AL
  797.         MOV     [CMDLO+SI],0
  798. Go_TonePortNoChange:
  799.         CMP     [WANTEDPERIOD+DI],0
  800.         JZ      Go_Return
  801.         MOVZX   DX,[TONEPORTSPEED+SI]
  802.         MOV     CX,[PERIOD+DI]
  803.         MOV     AX,[WANTEDPERIOD+DI]
  804.         CMP     [TONEPORTDIREC+SI],0
  805.         JNE     SHORT Go_TonePortaUp
  806. Go_TonePortaDown:
  807.         ADD     CX,DX
  808.         CMP     AX,CX
  809.         JG      SHORT Go_TonePortaSetPer
  810.         JMP     SHORT Go_TonePortaEnd
  811. Go_TonePortaUp:
  812.         SUB     CX,DX
  813.         CMP     AX,CX
  814.         JL      SHORT Go_TonePortaSetPer
  815. Go_TonePortaEnd:
  816.         MOV     CX,AX
  817.         MOV     [WANTEDPERIOD+DI],0
  818. Go_TonePortaSetPer:
  819.         MOV     [PERIOD+DI],CX
  820.         MOV     AL,[GLISSFUNK+SI]
  821.         AND     AL,0FH
  822.         JZ      SHORT Go_GlissSkip
  823.         MOV     AL,[FINETUNE+SI]
  824.         MOV     BL,(36+12)*2
  825.         MUL     BL
  826.         PUSH    DI
  827.         MOV     DI,OFFSET MT_PERIODTABLE
  828.         ADD     DI,AX
  829.         XOR     BX,BX
  830. Go_GlissLoop:
  831.         CMP     CX,[BX+DI]
  832.         JAE     SHORT Go_GlissFound
  833.         INC     BX
  834.         INC     BX
  835.         CMP     BX,(36+12)*2
  836.         JB      Go_GlissLoop
  837.         MOV     BX,(35+12)*2
  838. Go_GlissFound:
  839.         MOV     CX,[BX+DI]
  840.         POP     DI
  841. Go_GlissSkip:
  842.         CALL    Go_PerNop2
  843.         RET
  844. Go_TonePortamento ENDP
  845. ;-----------------------------------------------------------------------------
  846. Go_SetTonePorta PROC NEAR
  847.         MOV     DX,[NOTE+DI]
  848.         MOV     AL,[FINETUNE+SI]
  849.         MOV     CL,48*2                 ;37
  850.         MUL     CL
  851.         PUSH    DI
  852.         MOV     DI,OFFSET MT_PERIODTABLE
  853.         ADD     DI,AX
  854.         XOR     BX,BX
  855. Go_StpLoop:
  856.         CMP     DX,[BX+DI]
  857.         JAE     SHORT Go_StpFound
  858.         INC     BX
  859.         INC     BX
  860.         CMP     BX,48*2                 ;37
  861.         JB      Go_StpLoop
  862.         MOV     BX,47*2                 ;35
  863. Go_StpFound:
  864.         MOV     DL,[FINETUNE+SI]
  865.         AND     DL,8
  866.         JZ      SHORT Go_StpGoss
  867.         OR      BX,BX
  868.         JZ      SHORT Go_StpGoss
  869.         DEC     BX
  870.         DEC     BX
  871. Go_StpGoss:
  872.         MOV     DX,[BX+DI]
  873.         POP     DI
  874.         MOV     [WANTEDPERIOD+DI],DX
  875.         MOV     AX,[PERIOD+DI]
  876.         MOV     [TONEPORTDIREC+SI],0
  877.         CMP     DX,AX
  878.         JE      SHORT Go_ClearTonePorta
  879.         JA      Go_Return
  880.         INC     [TONEPORTDIREC+SI]
  881.         RET
  882. Go_ClearTonePorta:
  883.         MOV     [WANTEDPERIOD+DI],0
  884.         RET
  885. Go_SetTonePorta ENDP
  886. ;────────────────────────────────────────────────────────────────────────────
  887. ; Effect 4 -- Vibrato
  888. ;────────────────────────────────────────────────────────────────────────────
  889. Go_Vibrato PROC NEAR
  890.         MOV     AL,[CMDLO+SI]
  891.         OR      AL,AL
  892.         JZ      SHORT Go_Vibrato2
  893.         MOV     BL,[VIBRATOCMD+SI]
  894.         AND     AL,0FH
  895.         JZ      SHORT Go_vibskip
  896.         AND     BL,0F0H
  897.         OR      BL,AL
  898. Go_vibskip:
  899.         MOV     AL,[CMDLO+SI]
  900.         AND     AL,0F0H
  901.         JZ      SHORT Go_vibskip2
  902.         AND     BL,0FH
  903.         OR      BL,AL
  904. Go_vibskip2:
  905.         MOV     [VIBRATOCMD+SI],BL
  906. Go_Vibrato2:
  907.         MOV     AL,[VIBRATOPOS+SI]
  908.         SHR     AL,2
  909.         AND     AX,1FH
  910.         MOV     BL,[WAVECONTROL+SI]
  911.         AND     BL,3
  912.         JZ      SHORT Go_vib_sine
  913.         SHL     AL,3
  914.         CMP     BL,1
  915.         JE      SHORT Go_vib_rampdown
  916.         MOV     BL,255
  917.         JMP     SHORT Go_vib_set
  918. Go_vib_rampdown:
  919.         CMP     [VIBRATOPOS+SI],0
  920.         JG      SHORT Go_vib_rampdown2
  921.         MOV     BL,AL
  922.         NOT     BL
  923.         JMP     SHORT Go_vib_set
  924. Go_vib_rampdown2:
  925.         MOV     BL,AL
  926.         JMP     SHORT Go_vib_set
  927. Go_vib_sine:
  928.         MOVZX   BX,AL
  929.         MOV     BL,[MT_VIBRATOTABLE+BX]
  930. Go_vib_set:
  931.         MOV     AL,[VIBRATOCMD+SI]
  932.         AND     AL,0FH
  933.         MUL     BL
  934.         SHR     AX,7
  935.         MOV     BX,AX
  936.         MOV     AX,[PERIOD+DI]
  937.         CMP     [VIBRATOPOS+SI],0
  938.         JG      SHORT Go_VibratoNeg     ; BMI
  939.         NEG     BX
  940. Go_VibratoNeg:
  941.         ADD     AX,BX
  942. Go_Vibrato3:
  943.         MOV     CX,AX
  944.         CALL    Go_PerNop2
  945.         MOV     AL,[VIBRATOCMD+SI]
  946.         AND     AL,0F0H
  947.         SHR     AL,2
  948.         ADD     [VIBRATOPOS+SI],AL
  949.         RET
  950. Go_Vibrato ENDP
  951. ;────────────────────────────────────────────────────────────────────────────
  952. ; Effect 5 -- Tone and Volume Slide
  953. ;────────────────────────────────────────────────────────────────────────────
  954. Go_TonePlusVolSlide PROC NEAR
  955.         CALL    Go_TonePortNoChange
  956.         JMP     Go_VolumeSlide
  957. Go_TonePlusVolSlide ENDP
  958. ;────────────────────────────────────────────────────────────────────────────
  959. ; Effect 6 -- Vibrato and Volume Slide
  960. ;────────────────────────────────────────────────────────────────────────────
  961. Go_VibratoPlusVolSlide PROC NEAR
  962.         CALL    Go_Vibrato2             ;was mt_vibrato2
  963.         JMP     Go_VolumeSlide
  964. Go_VibratoPlusVolSlide ENDP
  965. ;────────────────────────────────────────────────────────────────────────────
  966. ; Effect 7 -- Tremolo
  967. ;────────────────────────────────────────────────────────────────────────────
  968. Go_Tremolo PROC NEAR
  969.         MOV     AL,[CMDLO+SI]
  970.         OR      AL,AL
  971.         JZ      SHORT Go_Tremolo2
  972.         MOV     BL,[TREMOLOCMD+SI]
  973.         AND     AL,0FH
  974.         JZ      SHORT Go_treskip
  975.         AND     BL,0F0H
  976.         OR      BL,AL
  977. Go_treskip:
  978.         MOV     AL,[CMDLO+SI]
  979.         AND     AL,0F0H
  980.         JZ      SHORT Go_treskip2
  981.         AND     BL,0FH
  982.         OR      BL,AL
  983. Go_treskip2:
  984.         MOV     [TREMOLOCMD+SI],BL
  985. Go_Tremolo2:
  986.         MOV     AL,[TREMOLOPOS+SI]
  987.         SHR     AL,2
  988.         AND     AX,1FH
  989.         MOV     BL,[WAVECONTROL+SI]
  990.         SHR     BL,4
  991.         AND     BL,3
  992.         JZ      SHORT Go_tre_sine
  993.         SHL     AL,3
  994.         CMP     BL,1
  995.         JE      SHORT Go_tre_rampdown
  996.         MOV     BL,255
  997.         JMP     SHORT Go_tre_set
  998. Go_tre_rampdown:
  999.         CMP     [TREMOLOPOS+SI],0
  1000.         JG      SHORT Go_tre_rampdown2
  1001.         MOV     BL,AL
  1002.         NOT     BL
  1003.         JMP     SHORT Go_tre_set
  1004. Go_tre_rampdown2:
  1005.         MOV     BL,AL
  1006.         JMP     SHORT Go_tre_set
  1007. Go_tre_sine:
  1008.         MOVZX   BX,AL
  1009.         MOV     BL,[MT_VIBRATOTABLE+BX]
  1010. Go_tre_set:
  1011.         MOV     AL,[TREMOLOCMD+SI]
  1012.         AND     AL,0FH
  1013.         MUL     BL
  1014.         MOV     BX,AX
  1015.         SHR     BX,6
  1016.         MOV     AL,[VOLUME+SI]
  1017.         CMP     [TREMOLOPOS+SI],0
  1018.         JG      SHORT Go_TremoloNeg             ; BMI  jns
  1019.         ADD     AL,BL
  1020.         JMP     SHORT Go_Tremolo3
  1021. Go_TremoloNeg:
  1022.         SUB     AL,BL
  1023. Go_Tremolo3:
  1024.         JNC     SHORT Go_TremoloSkip
  1025.         XOR     AX,AX
  1026. Go_TremoloSkip:
  1027.         CMP     AL,40H
  1028.         JBE     SHORT Go_TremoloOK              ; BLS
  1029.         MOV     AL,40H
  1030. Go_TremoloOK:
  1031.         MOV     [MVOL+SI],AL                    ;was ah
  1032.         MOV     AL,[TREMOLOCMD+SI]
  1033.         AND     AL,0F0H
  1034.         SHR     AL,2
  1035.         ADD     [TREMOLOPOS+SI],AL
  1036.         RET
  1037. Go_Tremolo ENDP
  1038. ;────────────────────────────────────────────────────────────────────────────
  1039. ; Effect 9 -- Sample Offset
  1040. ;────────────────────────────────────────────────────────────────────────────
  1041. Go_SampleOffset PROC NEAR
  1042.         MOVZX   AX,[CMDLO+SI]
  1043.         OR      AL,AL
  1044.         JZ      SHORT Go_sononew
  1045.         MOV     [SAMPLEOFFSET+SI],AL
  1046. Go_sononew:
  1047.         MOVZX   AX,[SAMPLEOFFSET+SI]
  1048.         XCHG    AL,AH
  1049.         CMP     AX,[MMAXREP+DI]
  1050.         JAE     SHORT Go_sofskip
  1051.         MOV     [MOFS+DI],AX
  1052.         RET
  1053. Go_sofskip:
  1054.         MOV     AX,[MOFS+DI]
  1055.         MOV     [MMAXREP+DI],AX
  1056.         RET
  1057. Go_SampleOffset ENDP
  1058. ;────────────────────────────────────────────────────────────────────────────
  1059. ; Effect A -- Volume Slide
  1060. ;────────────────────────────────────────────────────────────────────────────
  1061. Go_VolumeSlide PROC NEAR
  1062.         MOV     AL,[CMDLO+SI]
  1063.         SHR     AL,4
  1064.         OR      AL,AL
  1065.         JZ      SHORT Go_VolSlideDown
  1066. Go_VolSlideUp:
  1067.         ADD     [VOLUME+SI],AL
  1068.         CMP     [VOLUME+SI],40H
  1069.         JBE     SHORT Go_vsdskip
  1070.         MOV     [VOLUME+SI],40H
  1071.         JMP     SHORT Go_vsdskip
  1072. Go_VolSlideDown:
  1073.         MOV     AL,[CMDLO+SI]
  1074.         AND     AL,0FH
  1075. Go_VolSlideDown2:
  1076.         SUB     [VOLUME+SI],AL
  1077.         JNC     SHORT Go_vsdskip
  1078.         MOV     [VOLUME+SI],0
  1079. Go_vsdskip:
  1080.         MOV     AL,[VOLUME+SI]
  1081.         MOV     [MVOL+SI],AL            ;was ah
  1082.         RET
  1083. Go_VolumeSlide ENDP
  1084. ;────────────────────────────────────────────────────────────────────────────
  1085. ; Effect B -- Position Jump
  1086. ;────────────────────────────────────────────────────────────────────────────
  1087. Go_PositionJump PROC NEAR
  1088.         MOV     AL,[CMDLO+SI]           ; Get where to jump
  1089.         DEC     AL                      ; Update the
  1090.         MOV     MT_SONGPOS,AL           ; information.
  1091. Go_pj2: MOV     MT_PBREAKPOS,0
  1092.         MOV     MT_POSJUMPFLAG,1
  1093.         RET
  1094. Go_PositionJump ENDP
  1095. ;────────────────────────────────────────────────────────────────────────────
  1096. ; Effect C -- Volume Change
  1097. ;────────────────────────────────────────────────────────────────────────────
  1098. Go_VolumeChange PROC NEAR
  1099.         MOV     AL,[CMDLO+SI]           ; Get value for volume
  1100.         CMP     AL,40H                  ; Is it greater than 40h?
  1101.         JBE     SHORT Go_VolumeOK       ; Nope
  1102.         MOV     AL,40H
  1103. Go_VolumeOK:
  1104.         MOV     [VOLUME+SI],AL
  1105.         MOV     [MVOL+SI],AL            ;was ah
  1106.         RET
  1107. Go_VolumeChange ENDP
  1108. ;────────────────────────────────────────────────────────────────────────────
  1109. ; Effect D -- Pattern Break
  1110. ;────────────────────────────────────────────────────────────────────────────
  1111. Go_PatternBreak PROC NEAR
  1112.         MOV     AL,[CMDLO+SI]           ; Break to where?
  1113.         MOV     BL,AL                   ; POSITION IS IN DECIMAL
  1114.         SHR     AL,4
  1115.         MOV     CL,10
  1116.         MUL     CL
  1117.         AND     BL,0FH
  1118.         ADD     AL,BL
  1119.         CMP     AL,63
  1120.         JG      Go_pj2
  1121.         MOV     MT_PBREAKPOS,AL
  1122.         MOV     MT_POSJUMPFLAG,1
  1123.         RET
  1124. Go_PatternBreak ENDP
  1125. ;────────────────────────────────────────────────────────────────────────────
  1126. ; Effect F -- Set Speed
  1127. ;────────────────────────────────────────────────────────────────────────────
  1128. Go_SetSpeed PROC NEAR
  1129.         MOV     AL,[CMDLO+SI]           ; Get value for speed
  1130.         OR      AL,AL
  1131.         JZ      Go_Return
  1132.         CMP     AL,32                   ; Is it a BPM value ?
  1133.         JAE     SHORT Go_SetBPM
  1134.         MOV     MT_COUNTER,0
  1135.         MOV     MT_SPEED,AL
  1136.         RET
  1137. Go_SetBPM:
  1138.         MOVZX   CX,AL
  1139.         ADD     CX,100
  1140.         MOV     AX,4500
  1141.         XOR     DX,DX
  1142.         DIV     CX                      ; NORMAL BPM SPEED IS 125
  1143.         MOV     BPM_SPEED,AL
  1144.         RET
  1145. Go_SetSpeed ENDP
  1146. ;=============================================================================
  1147. Go_CheckMoreEfx PROC NEAR
  1148.         MOVZX   BX,[CMD+SI]
  1149.         SHL     BL,1
  1150.         JMP     [Effect_Jump_Table2+BX]
  1151. Go_CheckMoreEfx ENDP
  1152. ;─────────────────────────────────────────────────────────────────────────────
  1153. ; Effect E
  1154. ;─────────────────────────────────────────────────────────────────────────────
  1155. Go_E_Commands PROC NEAR
  1156.         MOVZX   BX,[CMDLO+SI]
  1157.         SHR     BL,4
  1158.         SHL     BL,1
  1159.         MOV     AL,[CMDLO+SI]
  1160.         AND     AL,0FH
  1161.         JMP     [Effect_Jump_Table3+BX]
  1162. ;-----------------------------------------------------------------------------
  1163. ; Effect 0 -- FilterOnOff
  1164. ; Effect 1 -- Fine Porta Up
  1165. ;-----------------------------------------------------------------------------
  1166. Go_FinePortaUp:
  1167.         CMP     MT_COUNTER,0
  1168.         JNE     Go_Return
  1169.         MOV     MT_LOWMASK,0FH
  1170.         JMP     Go_PortaUp
  1171. ;-----------------------------------------------------------------------------
  1172. ; Effect 2 -- Fine Porta Down
  1173. ;-----------------------------------------------------------------------------
  1174. Go_FinePortaDown:
  1175.         CMP     MT_COUNTER,0
  1176.         JNE     Go_Return
  1177.         MOV     MT_LOWMASK,0FH
  1178.         JMP     Go_PortaDown
  1179. ;-----------------------------------------------------------------------------
  1180. ; Effect 3 -- Set Gliss Control
  1181. ;-----------------------------------------------------------------------------
  1182. Go_SetGlissControl:
  1183.         AND     [GLISSFUNK+SI],0F0H
  1184.         OR      [GLISSFUNK+SI],AL
  1185.         RET
  1186. ;-----------------------------------------------------------------------------
  1187. ; Effect 4 -- Set Vibrato Control
  1188. ;-----------------------------------------------------------------------------
  1189. Go_SetVibratoControl:
  1190.         AND     [WAVECONTROL+SI],0F0H
  1191.         OR      [WAVECONTROL+SI],AL
  1192.         RET
  1193. ;-----------------------------------------------------------------------------
  1194. ; Effect 5 -- Set Fine Tune
  1195. ;-----------------------------------------------------------------------------
  1196. Go_SetFineTune:
  1197.         MOV     [FINETUNE+SI],AL
  1198.         RET
  1199. ;-----------------------------------------------------------------------------
  1200. ; Effect 6 -- Jump Loop
  1201. ;-----------------------------------------------------------------------------
  1202. Go_JumpLoop:
  1203.         CMP     MT_COUNTER,0
  1204.         JNE     Go_Return
  1205.         OR      AL,AL
  1206.         JZ      SHORT Go_SetLoop
  1207.         CMP     [LOOPCOUNT+SI],0
  1208.         JE      SHORT Go_jumpcnt
  1209.         DEC     [LOOPCOUNT+SI]
  1210.         JZ      Go_Return
  1211. Go_jmploop:
  1212.         MOV     AL,[PATTPOS+SI]
  1213.         MOV     MT_PBREAKPOS,AL
  1214.         MOV     MT_PBREAKFLAG,1
  1215.         RET
  1216. Go_jumpcnt:
  1217.         MOV     [LOOPCOUNT+SI],AL
  1218.         JMP     Go_jmploop
  1219. Go_SetLoop:
  1220.         MOV     AX,MT_PATTERNPOS
  1221.         SHR     AX,2
  1222.         MOV     [PATTPOS+SI],AL
  1223.         RET
  1224. ;-----------------------------------------------------------------------------
  1225. ; Effect 7 -- Set Tremolo Control
  1226. ;-----------------------------------------------------------------------------
  1227. Go_SetTremoloControl:
  1228.         SHL     AL,4
  1229.         AND     [WAVECONTROL+SI],0FH
  1230.         OR      [WAVECONTROL+SI],AL
  1231.         RET
  1232. ;-----------------------------------------------------------------------------
  1233. ; Effect 9 -- Retrig Note
  1234. ;-----------------------------------------------------------------------------
  1235. Go_RetrigNote:
  1236.         MOV     BL,AL
  1237.         OR      BL,BL
  1238.         JZ      SHORT Go_rtnend
  1239.         MOVZX   AX,MT_COUNTER
  1240.         OR      AL,AL
  1241.         JNZ     SHORT Go_rtnskp
  1242.         CMP     [NOTE+DI],0
  1243.         JNE     SHORT Go_rtnskp
  1244.         MOV     MT_COUNTER,0
  1245. Go_rtnskp:
  1246.         DIV     BL
  1247.         XCHG    AL,AH
  1248.         OR      AL,AL
  1249.         JNZ     SHORT Go_rtnend
  1250. Go_DoRetrig:
  1251.         XOR     AX,AX
  1252.         MOV     [MOFS+DI],AX
  1253.         MOV     [MOFLOW+SI],AL
  1254.         MOV     AX,[LENGTHI+DI]
  1255.         MOV     [MMAXREP+DI],AX
  1256.         MOV     AX,[LOOPSTART+DI]
  1257.         MOV     [MREPEAT+DI],AX
  1258.         ADD     AX,[REPLEN+DI]
  1259.         MOV     [MREPLEN+DI],AX
  1260. Go_rtnend:
  1261.         RET
  1262. ;-----------------------------------------------------------------------------
  1263. ; Effect A -- Volume Fine Up
  1264. ;-----------------------------------------------------------------------------
  1265. Go_VolumeFineUp:
  1266.         CMP     MT_COUNTER,0
  1267.         JNE     Go_Return
  1268.         JMP     Go_VolSlideUp
  1269. ;-----------------------------------------------------------------------------
  1270. ; Effect B -- Volume Fine Down
  1271. ;-----------------------------------------------------------------------------
  1272. Go_VolumeFineDown:
  1273.         CMP     MT_COUNTER,0
  1274.         JNZ     Go_Return
  1275.         JMP     Go_VolSlideDown2
  1276. ;-----------------------------------------------------------------------------
  1277. ; Effect C -- Note Cut
  1278. ;-----------------------------------------------------------------------------
  1279. Go_NoteCut:
  1280.         CMP     AL,MT_COUNTER
  1281.         JNE     Go_Return
  1282.         MOV     [VOLUME+SI],0
  1283.         MOV     [MVOL+SI],AL
  1284.         RET
  1285. ;-----------------------------------------------------------------------------
  1286. ; Effect D -- Note Delay
  1287. ;-----------------------------------------------------------------------------
  1288. Go_NoteDelay:
  1289.         CMP     AL,MT_COUNTER
  1290.         JNE     Go_Return
  1291.         CMP     [NOTE+DI],0
  1292.         JE      Go_Return
  1293.         JMP     Go_DoRetrig
  1294. ;-----------------------------------------------------------------------------
  1295. ; Effect E -- Pattern Delay
  1296. ;-----------------------------------------------------------------------------
  1297. Go_PatternDelay:
  1298.         CMP     MT_COUNTER,0
  1299.         JNE     Go_Return
  1300.         CMP     MT_PATTDELAYTIME2,0
  1301.         JNZ     Go_Return
  1302.         INC     AL
  1303.         MOV     MT_PATTDELAYTIME,AL
  1304.         RET
  1305. ;-----------------------------------------------------------------------------
  1306. ; Effect F -- Funk It
  1307. ;-----------------------------------------------------------------------------
  1308. Go_E_Commands ENDP
  1309. ;=============================================================================
  1310.  
  1311.  
  1312. ;=============================================================================
  1313. MIXUP_CHANNELS PROC NEAR
  1314.         CMP     MOD_STAT,3              ;MOD HAS FINISHED
  1315.         JB      SHORT GMX7
  1316.         XOR     AX,AX
  1317.         XOR     BX,BX
  1318.         MOV     CX,MAX_CHAN_NUMB
  1319. LMX4:   MOV     [MSEG+BX],AX
  1320.         INC     BX
  1321.         INC     BX
  1322.         LOOP    LMX4
  1323. GMX7:   MOV     CX,DMA_CX
  1324.         CMP     MOD_STAT,2
  1325.         JB      SHORT GMX3
  1326.         OUT     0CH,AL                  ;DMA FLIP-FLOP RESET
  1327.         MOVZX   DX,DMA_CHANNEL
  1328.         SHL     DL,1
  1329.         IN      AL,DX                   ;GET DMA POSITION
  1330.         XCHG    AL,AH
  1331.         IN      AL,DX
  1332.         XCHG    AL,AH
  1333.         SUB     AX,DMA_POFF             ;AX IS OFFSET OF DMA-POS
  1334.         AND     AX,0FFFEH
  1335.         ADD     AX,DMA_MORE
  1336.         CMP     AX,DMA_MAX
  1337.         JB      SHORT GMX1
  1338.         SUB     AX,DMA_MAX
  1339. GMX1:   ADD     AX,DMA_OFFSET
  1340.         SUB     AX,DMA_PTR
  1341.         JNC     SHORT GMX2
  1342.         ADD     AX,DMA_MAX
  1343. GMX2:   MOV     CX,AX                   ;CX IS NUMBER OF BYTES TO CALCULATE
  1344.         ADD     AX,DMA_PTR
  1345.         SUB     AX,DMA_OFFSET
  1346.         SUB     AX,2000H
  1347.         JC      SHORT GMX3
  1348.         SUB     CX,AX
  1349. GMX3:   XOR     BX,BX
  1350.         XOR     DI,DI
  1351.         CLD
  1352.         SHR     CX,1
  1353.         JZ      SHORT GMX5
  1354.         TEST    SBPRO_FLAG,1
  1355.         JNZ     SHORT SBPRO_MIXING      ;SB MONO-MIXING
  1356.         CALL    MIX_CHANNELA            ;INIT BUFFER WITH FIRST CHANNEL
  1357.         INC     BX
  1358.         INC     DI
  1359.         INC     DI
  1360.         DEC     CH_NUMB
  1361. LMX1:   CALL    MIX_CHANNELM            ;MIX CHANNELS
  1362.         INC     BX
  1363.         INC     DI
  1364.         INC     DI
  1365.         CMP     BX,CH_NUMB
  1366.         JB      LMX1
  1367.         INC     CH_NUMB
  1368.         CALL    MIX_CHANNELX            ;END UP BUFFER WITH LAST CHANNEL
  1369.         CALL    MIX_CHANNELS            ;SAMPLE1: MIDDLE CHANNEL
  1370. LMX2:   MOV     AX,DMA_NEWPTR           ;CHECK DMA-BUFFER OVERFLOW
  1371.         MOV     SI,DMA_MAX              ;ITS A RING BUFFER
  1372.         ADD     SI,DMA_OFFSET
  1373.         CMP     AX,SI
  1374.         JB      SHORT GMX4
  1375.         MOV     CX,AX
  1376.         MOV     DI,DMA_OFFSET
  1377.         SUB     CX,SI
  1378.         JZ      SHORT GMX6
  1379.         CLD
  1380.         SHR     CX,1
  1381.         PUSH    DS
  1382.         MOV     ES,DMA_SEG
  1383.         MOV     DS,DMA_SEG
  1384.         REP MOVSW                       ;MOVE OVERFLOW DATA
  1385.         POP     DS
  1386. GMX6:   MOV     AX,DI
  1387. GMX4:   MOV     DMA_PTR,AX              ;START DSP OUTPUT
  1388.         CMP     MOD_STAT,1
  1389.         JNE     SHORT GMX5
  1390.         INC     MOD_STAT
  1391.         CALL    DSP_OUT
  1392. GMX5:   RET
  1393. SBPRO_MIXING:
  1394.         SHR     CX,1                    ;SBPRO STEREO-MIXING
  1395.         JZ      GMX5
  1396.         MOV     AX,[STEREO_PANNING+DI]
  1397.         ADD     DMA_PTR,AX
  1398.         CALL    MIX_CHANNELA            ;INIT BUFFER WITH FIRST CHANNEL
  1399.         INC     BX
  1400.         INC     DI
  1401.         INC     DI
  1402.         MOV     AX,[STEREO_PANNING+DI]
  1403.         ADD     DMA_PTR,AX
  1404.         CALL    MIX_CHANNELA            ;THIS CHANNEL SHOULD BE ON RIGHT
  1405.         INC     BX                      ;(OTHERWISE DMA_NEWPTR IS 2 TOO HIGH)
  1406.         INC     DI
  1407.         INC     DI
  1408. LMX3:   MOV     AX,[STEREO_PANNING+DI]
  1409.         ADD     DMA_PTR,AX
  1410.         CALL    MIX_CHANNELM            ;MIX CHANNELS
  1411.         INC     BX
  1412.         INC     DI
  1413.         INC     DI
  1414.         CMP     BX,CH_NUMB
  1415.         JB      LMX3
  1416.         MOV     AX,[STEREO_PANNING+DI]
  1417.         ADD     DMA_PTR,AX
  1418.         PUSH    CX
  1419.         CALL    MIX_CHANNELS1           ;SAMPLE1: LEFT CHANNEL
  1420.         POP     CX
  1421.         SUB     DMA_PTR,2
  1422.         PUSH    CX
  1423.         CALL    MIX_CHANNELS2           ;SAMPLE2: RIGHT CHANNEL
  1424.         POP     CX
  1425.         CALL    FIXUP_CHANNELS          ;END UP CHANNEL BY CONVERTING IT TO PC
  1426.         JMP     LMX2
  1427. MIXUP_CHANNELS ENDP
  1428. ;-----------------------------------------------------------------------------
  1429. MIX_CHANNELA PROC NEAR
  1430.         PUSH    CX BX DI
  1431.         MOV     SI,[MOFS+DI]            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1432.         MOV     DX,[MFREQ+DI]           ;OFF ADD AFTER FIXED POINT (X/256)
  1433.         MOVZX   BP,DH                   ;OFF ADD BEFORE FIXED POINT
  1434.         MOV     DH,[MOFLOW+BX]          ;ACTUAL AFTER FIXED POINT VALUE
  1435.         MOV     AL,[MVOL+BX]            ;SAMPLE VOLUME
  1436.         MOV     BL,MUSIC_VOL            ;MASTER VOLUME
  1437.         MUL     BL
  1438.         XOR     AL,AL
  1439.         ADD     AX,MIXMUL_OFFSET
  1440.         MOV     BX,AX                   ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1441.         MOV     ES,[MSEG+DI]
  1442.         MOV     AX,[MMAXREP+DI]         ;SP IS OFFSET OF SAMPLE ENDING
  1443.         MOV     WORD PTR SELFM1+2,AX
  1444.         MOV     WORD PTR SELFM2+2,AX
  1445.         MOV     AL,2
  1446. CLEAR_PENT_PREF1:
  1447.         DEC     AL                      ;CLEAR ALSO PENTIUM PQ!!
  1448.         JNZ     CLEAR_PENT_PREF1
  1449.         JMP     SHORT CLEAR_PREF1       ;CLEAR PREFETCH QUEUE!!!
  1450. CLEAR_PREF1:
  1451.         MOV     DI,DMA_PTR
  1452.         MOV     DS,DMA_SEG              ;DS:DI IS DMA-BUFFER POINTER
  1453.         MOV     AX,ES                   ;ES:SI IS SAMPLE-DATA POINTER
  1454.         OR      AX,AX
  1455.         JZ      SHORT SILENT_FILLA
  1456. MIX_LOOPA:
  1457. SELFM1: CMP     SI,0FFFFH               ;SELFMODIFYING CODE
  1458.         JAE     SHORT REST_FILLA
  1459.         MOV     AH,ES:[SI]
  1460.         ADD     DH,DL
  1461.         ADC     SI,BP
  1462. SELFM2: CMP     SI,0FFFFH               ;SELFMODIFYING CODE
  1463.         JAE     SHORT REST_FILLA
  1464.         MOV     AL,ES:[SI]
  1465.         ADD     DH,DL
  1466.         ADC     SI,BP
  1467.         XLATB
  1468.         XCHG    AL,AH
  1469.         XLATB
  1470.         MOV     [DI],AX
  1471. SELFN1: ADD     DI,2                    ;SELFMODIFYING CODE
  1472.         LOOP    MIX_LOOPA
  1473. MIX_ENDA:
  1474.         MOV     AX,CS
  1475.         MOV     DS,AX
  1476.         MOV     AX,ES
  1477.         MOV     DMA_NEWPTR,DI
  1478.         POP     DI BX CX
  1479.         MOV     [MSEG+DI],AX
  1480.         MOV     [MOFLOW+BX],DH
  1481.         MOV     [MOFS+DI],SI
  1482.         RET
  1483. REST_FILLA:
  1484.         POP     SI
  1485.         PUSH    SI
  1486.         MOV     AX,CS:[MREPLEN+SI]
  1487.         OR      AX,AX
  1488.         JZ      SHORT SILENT_FILLA
  1489.         MOV     CS:[MMAXREP+SI],AX
  1490.         MOV     WORD PTR CS:SELFM1+2,AX
  1491.         MOV     WORD PTR CS:SELFM2+2,AX
  1492.         MOV     SI,CS:[MREPEAT+SI]
  1493.         JMP     MIX_LOOPA
  1494. SILENT_FILLA:
  1495.         MOV     BX,DS
  1496.         MOV     ES,BX
  1497.         TEST    CS:SBPRO_FLAG,1
  1498.         JNZ     SHORT SILENT_FILLB
  1499.         REP STOSW
  1500.         MOV     ES,AX
  1501.         JMP     MIX_ENDA
  1502. SILENT_FILLB:
  1503.         STOSW
  1504.         INC     DI
  1505.         INC     DI
  1506.         LOOP    SILENT_FILLB
  1507.         MOV     ES,AX
  1508.         JMP     MIX_ENDA
  1509. MIX_CHANNELA ENDP
  1510. ;-----------------------------------------------------------------------------
  1511. MIX_CHANNELM PROC NEAR
  1512.         PUSH    CX BX DI
  1513.         MOV     SI,[MOFS+DI]            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1514.         MOV     DX,[MFREQ+DI]           ;OFF ADD AFTER FIXED POINT (X/256)
  1515.         MOVZX   BP,DH                   ;OFF ADD BEFORE FIXED POINT
  1516.         MOV     DH,[MOFLOW+BX]          ;ACTUAL AFTER FIXED POINT VALUE
  1517.         MOV     AL,[MVOL+BX]            ;SAMPLE VOLUME
  1518.         MOV     BL,MUSIC_VOL            ;MASTER VOLUME
  1519.         MUL     BL
  1520.         XOR     AL,AL
  1521.         ADD     AX,MIXMUL_OFFSET
  1522.         MOV     BX,AX                   ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1523.         MOV     ES,[MSEG+DI]
  1524.         MOV     AX,[MMAXREP+DI]         ;OFFSET OF SAMPLE ENDING
  1525.         MOV     WORD PTR SELFM3+2,AX
  1526.         MOV     WORD PTR SELFM4+2,AX
  1527.         MOV     AL,2
  1528. CLEAR_PENT_PREF2:
  1529.         DEC     AL                      ;CLEAR ALSO PENTIUM PQ!!
  1530.         JNZ     CLEAR_PENT_PREF2
  1531.         JMP     SHORT CLEAR_PREF2       ;CLEAR PREFETCH QUEUE!!!
  1532. CLEAR_PREF2:
  1533.         MOV     DI,DMA_PTR
  1534.         MOV     DS,DMA_SEG              ;DS:DI IS DMA-BUFFER POINTER
  1535.         MOV     AX,ES
  1536.         OR      AX,AX
  1537.         JZ      SHORT MIX_ENDM
  1538. MIX_LOOPM:
  1539. SELFM3: CMP     SI,0FFFFH               ;SELFMODIFYING CODE
  1540.         JAE     SHORT REST_FILLM
  1541.         MOV     AH,ES:[SI]
  1542.         ADD     DH,DL
  1543.         ADC     SI,BP
  1544. SELFM4: CMP     SI,0FFFFH               ;SELFMODIFYING CODE
  1545.         JAE     SHORT REST_FILLM
  1546.         MOV     AL,ES:[SI]
  1547.         ADD     DH,DL
  1548.         ADC     SI,BP
  1549.         XLATB
  1550.         XCHG    AL,AH
  1551.         XLATB
  1552.         ADD     [DI],AX
  1553. SELFN2: ADD     DI,2                    ;SELFMODIFYING CODE
  1554.         LOOP    MIX_LOOPM
  1555. MIX_ENDM:
  1556.         MOV     AX,CS
  1557.         MOV     DS,AX
  1558.         MOV     AX,ES
  1559.         POP     DI BX CX
  1560.         MOV     [MSEG+DI],AX
  1561.         MOV     [MOFLOW+BX],DH
  1562.         MOV     [MOFS+DI],SI
  1563.         RET
  1564. REST_FILLM:
  1565.         POP     SI
  1566.         PUSH    SI
  1567.         MOV     AX,CS:[MREPLEN+SI]
  1568.         OR      AX,AX
  1569.         JZ      SHORT SILENT_FILLM
  1570.         MOV     CS:[MMAXREP+SI],AX
  1571.         MOV     WORD PTR CS:SELFM3+2,AX
  1572.         MOV     WORD PTR CS:SELFM4+2,AX
  1573.         MOV     SI,CS:[MREPEAT+SI]
  1574.         JMP     MIX_LOOPM
  1575. SILENT_FILLM:
  1576.         MOV     ES,AX
  1577.         JMP     MIX_ENDM
  1578. MIX_CHANNELM ENDP
  1579. ;-----------------------------------------------------------------------------
  1580. MIX_CHANNELX PROC NEAR
  1581.         PUSH    CX BX DI
  1582.         MOV     SI,[MOFS+DI]            ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1583.         MOV     DX,[MFREQ+DI]           ;OFF ADD AFTER FIXED POINT (X/256)
  1584.         MOVZX   BP,DH                   ;OFF ADD BEFORE FIXED POINT
  1585.         MOV     DH,[MOFLOW+BX]          ;ACTUAL AFTER FIXED POINT VALUE
  1586.         MOV     AL,[MVOL+BX]            ;SAMPLE VOLUME
  1587.         MOV     BL,MUSIC_VOL            ;MASTER VOLUME
  1588.         MUL     BL
  1589.         XOR     AL,AL
  1590.         ADD     AX,MIXMUL_OFFSET
  1591.         MOV     BX,AX                   ;DS:BX POINTS INTO MIXMUL_VOLUMETABLE
  1592.         MOV     ES,[MSEG+DI]
  1593.         MOV     AX,[MMAXREP+DI]         ;SP IS OFFSET OF SAMPLE ENDING
  1594.         MOV     WORD PTR SELFM5+2,AX
  1595.         MOV     WORD PTR SELFM6+2,AX
  1596.         MOV     WORD PTR SELFM7+2,8080H
  1597.         CMP     SAM_SEG1,0
  1598.         JE      SHORT NO_SAMPLES
  1599.         MOV     WORD PTR SELFM7+2,0
  1600. NO_SAMPLES:
  1601.         MOV     AL,2
  1602. CLEAR_PENT_PREF3:
  1603.         DEC     AL                      ;CLEAR ALSO PENTIUM PQ!!
  1604.         JNZ     CLEAR_PENT_PREF3
  1605.         JMP     SHORT CLEAR_PREF3       ;CLEAR PREFETCH QUEUE!!!
  1606. CLEAR_PREF3:
  1607.         MOV     DI,DMA_PTR
  1608.         MOV     DS,DMA_SEG              ;DS:DI IS DMA-BUFFER POINTER
  1609.         MOV     AX,ES                   ;ES:SI IS SAMPLE-DATA POINTER
  1610.         OR      AX,AX
  1611.         JZ      SHORT SILENT_FILLX
  1612. MIX_LOOPX:
  1613. SELFM5: CMP     SI,0FFFFH               ;SELFMODIFYING CODE
  1614.         JAE     SHORT REST_FILLX
  1615.         MOV     AH,ES:[SI]
  1616.         ADD     DH,DL
  1617.         ADC     SI,BP
  1618. SELFM6: CMP     SI,0FFFFH               ;SELFMODIFYING CODE
  1619.         JAE     SHORT REST_FILLX
  1620.         MOV     AL,ES:[SI]
  1621.         ADD     DH,DL
  1622.         ADC     SI,BP
  1623.         XLATB
  1624.         XCHG    AL,AH
  1625.         XLATB
  1626.         ADD     [DI],AX
  1627. SELFM7: XOR     WORD PTR [DI],8080H
  1628.         INC     DI
  1629.         INC     DI
  1630.         LOOP    MIX_LOOPX
  1631. MIX_ENDX:
  1632.         MOV     AX,CS
  1633.         MOV     DS,AX
  1634.         MOV     AX,ES
  1635.         POP     DI BX CX
  1636.         MOV     [MSEG+DI],AX
  1637.         MOV     [MOFLOW+BX],DH
  1638.         MOV     [MOFS+DI],SI
  1639.         RET
  1640. REST_FILLX:
  1641.         POP     SI
  1642.         PUSH    SI
  1643.         MOV     AX,CS:[MREPLEN+SI]
  1644.         OR      AX,AX
  1645.         JZ      SHORT SILENT_FILLX
  1646.         MOV     CS:[MMAXREP+SI],AX
  1647.         MOV     WORD PTR CS:SELFM5+2,AX
  1648.         MOV     WORD PTR CS:SELFM6+2,AX
  1649.         MOV     SI,CS:[MREPEAT+SI]
  1650.         JMP     MIX_LOOPX
  1651. SILENT_FILLX:
  1652.         MOV     ES,AX
  1653.         CMP     CS:[SAM_SEG1],0
  1654.         JNE     MIX_ENDX
  1655. SILENT_FILLL:
  1656.         XOR     WORD PTR [DI],8080H
  1657.         INC     DI
  1658.         INC     DI
  1659.         LOOP    SILENT_FILLL
  1660.         JMP     MIX_ENDX
  1661. MIX_CHANNELX ENDP
  1662. ;-----------------------------------------------------------------------------
  1663. FIXUP_CHANNELS PROC NEAR
  1664.         MOV     DI,DMA_PTR
  1665.         MOV     DS,DMA_SEG
  1666. FIXUP_LOOP:
  1667.         XOR     DWORD PTR [DI],80808080H
  1668.         INC     DI
  1669.         ROL     WORD PTR [DI],8
  1670.         ADD     DI,3
  1671.         LOOP    FIXUP_LOOP
  1672.         MOV     AX,CS
  1673.         MOV     DS,AX
  1674.         RET
  1675. FIXUP_CHANNELS ENDP
  1676. ;-----------------------------------------------------------------------------
  1677. MIX_CHANNELS PROC NEAR
  1678.         CMP     SAM_SEG1,0
  1679.         JE      SHORT GO_BACKS
  1680.         CALL    EMS_SAVE
  1681.         PUSH    EAX
  1682.         MOV     EAX,SAM_OFS1
  1683.         CALL    EMS_PAGING
  1684.         POP     EAX
  1685.         MOV     SI,DI                   ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1686.         MOV     DX,SAM_FRQ1             ;OFF ADD AFTER FIXED POINT (X/256)
  1687.         MOVZX   BP,DH                   ;OFF ADD BEFORE FIXED POINT
  1688.         MOV     DH,SAM_OFL1             ;ACTUAL AFTER FIXED POINT VALUE
  1689.         MOV     BX,SAM_MAX1             ;COUNTER FOR SAMPLE ENDING
  1690.         MOV     DI,DMA_PTR
  1691.         MOV     DS,DMA_SEG              ;DS:DI IS DMA-BUFFER POINTER
  1692.         PUSH    SI
  1693. MIX_LOOPS:
  1694.         MOV     AL,ES:[SI]
  1695.         ADD     DH,DL
  1696.         ADC     SI,BP
  1697.         SUB     DH,DL
  1698.         ADD     DH,DL
  1699.         SBB     BX,BP
  1700.         JC      SHORT REST_FILLS
  1701.         JZ      SHORT REST_FILLS
  1702.         SAR     BYTE PTR [DI],1
  1703.         MOV     AH,ES:[SI]
  1704.         SAR     BYTE PTR [DI+1],1
  1705.         ADD     DH,DL
  1706.         ADC     SI,BP
  1707.         ADD     [DI],AX
  1708.         XOR     WORD PTR [DI],8080H
  1709.         INC     DI
  1710.         INC     DI
  1711.         SUB     DH,DL
  1712.         ADD     DH,DL
  1713.         SBB     BX,BP
  1714.         JC      SHORT REST_FILLS
  1715.         JZ      SHORT REST_FILLS
  1716.         LOOP    MIX_LOOPS
  1717. MIX_ENDS:
  1718.         MOV     AX,CS
  1719.         MOV     DS,AX
  1720.         MOV     SAM_OFL1,DH
  1721.         POP     AX
  1722.         SUB     SI,AX
  1723.         PUSH    EAX
  1724.         MOVZX   EAX,SI
  1725.         ADD     SAM_OFS1,EAX
  1726.         POP     EAX
  1727.         MOV     SAM_MAX1,BX
  1728.         CALL    EMS_RESTORE
  1729. GO_BACKS:
  1730.         RET
  1731. REST_FILLS:
  1732.         MOV     CS:SAM_SEG1,0
  1733. SILENT_FILLS:
  1734.         XOR     WORD PTR [DI],8080H
  1735.         INC     DI
  1736.         INC     DI
  1737.         LOOP    SILENT_FILLS
  1738.         JMP     MIX_ENDS
  1739. MIX_CHANNELS ENDP
  1740. ;-----------------------------------------------------------------------------
  1741. MIX_CHANNELS1 PROC NEAR
  1742.         CMP     SAM_SEG1,0
  1743.         JE      SHORT GO_BACKS1
  1744.         CALL    EMS_SAVE
  1745.         PUSH    EAX
  1746.         MOV     EAX,SAM_OFS1
  1747.         CALL    EMS_PAGING
  1748.         POP     EAX
  1749.         MOV     SI,DI                   ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1750.         MOV     DX,SAM_FRQ1             ;OFF ADD AFTER FIXED POINT (X/256)
  1751.         MOVZX   BP,DH                   ;OFF ADD BEFORE FIXED POINT
  1752.         MOV     DH,SAM_OFL1             ;ACTUAL AFTER FIXED POINT VALUE
  1753.         MOV     BX,SAM_MAX1             ;COUNTER FOR SAMPLE ENDING
  1754.         MOV     DI,DMA_PTR
  1755.         MOV     DS,DMA_SEG              ;DS:DI IS DMA-BUFFER POINTER
  1756.         PUSH    SI
  1757. MIX_LOOPS1:
  1758.         MOV     AL,ES:[SI]
  1759.         ADD     DH,DL
  1760.         ADC     SI,BP
  1761.         SUB     DH,DL
  1762.         ADD     DH,DL
  1763.         SBB     BX,BP
  1764.         JC      SHORT MIX_ENDS1
  1765.         JZ      SHORT MIX_ENDS1
  1766.         SAR     BYTE PTR [DI],1
  1767.         MOV     AH,ES:[SI]
  1768.         SAR     BYTE PTR [DI+1],1
  1769.         ADD     DH,DL
  1770.         ADC     SI,BP
  1771.         ADD     [DI],AX
  1772.         ADD     DI,4
  1773.         SUB     DH,DL
  1774.         ADD     DH,DL
  1775.         SBB     BX,BP
  1776.         JC      SHORT MIX_ENDS1
  1777.         JZ      SHORT MIX_ENDS1
  1778.         LOOP    MIX_LOOPS1
  1779. MIX_REST1:
  1780.         MOV     AX,CS
  1781.         MOV     DS,AX
  1782.         MOV     SAM_OFL1,DH
  1783.         POP     AX
  1784.         SUB     SI,AX
  1785.         PUSH    EAX
  1786.         MOVZX   EAX,SI
  1787.         ADD     SAM_OFS1,EAX
  1788.         POP     EAX
  1789.         MOV     SAM_MAX1,BX
  1790.         CALL    EMS_RESTORE
  1791. GO_BACKS1:
  1792.         RET
  1793. MIX_ENDS1:
  1794.         MOV     CS:SAM_SEG1,0
  1795.         JMP     MIX_REST1
  1796. MIX_CHANNELS1 ENDP
  1797. ;-----------------------------------------------------------------------------
  1798. MIX_CHANNELS2 PROC NEAR
  1799.         CMP     SAM_SEG2,0
  1800.         JE      SHORT GO_BACKS2
  1801.         CALL    EMS_SAVE
  1802.         PUSH    EAX
  1803.         MOV     EAX,SAM_OFS2
  1804.         CALL    EMS_PAGING
  1805.         POP     EAX
  1806.         MOV     SI,DI                   ;GET OFFSET IN SAMPLE (START ALWAYS= 0)
  1807.         MOV     DX,SAM_FRQ2             ;OFF ADD AFTER FIXED POINT (X/256)
  1808.         MOVZX   BP,DH                   ;OFF ADD BEFORE FIXED POINT
  1809.         MOV     DH,SAM_OFL2             ;ACTUAL AFTER FIXED POINT VALUE
  1810.         MOV     BX,SAM_MAX2             ;COUNTER FOR SAMPLE ENDING
  1811.         MOV     DI,DMA_PTR
  1812.         MOV     DS,DMA_SEG              ;DS:DI IS DMA-BUFFER POINTER
  1813.         PUSH    SI
  1814. MIX_LOOPS2:
  1815.         MOV     AL,ES:[SI]
  1816.         ADD     DH,DL
  1817.         ADC     SI,BP
  1818.         SUB     DH,DL
  1819.         ADD     DH,DL
  1820.         SBB     BX,BP
  1821.         JC      SHORT MIX_ENDS2
  1822.         JZ      SHORT MIX_ENDS2
  1823.         SAR     BYTE PTR [DI],1
  1824.         MOV     AH,ES:[SI]
  1825.         SAR     BYTE PTR [DI+1],1
  1826.         ADD     DH,DL
  1827.         ADC     SI,BP
  1828.         ADD     [DI],AX
  1829.         ADD     DI,4
  1830.         SUB     DH,DL
  1831.         ADD     DH,DL
  1832.         SBB     BX,BP
  1833.         JC      SHORT MIX_ENDS2
  1834.         JZ      SHORT MIX_ENDS2
  1835.         LOOP    MIX_LOOPS2
  1836. MIX_REST2:
  1837.         MOV     AX,CS
  1838.         MOV     DS,AX
  1839.         MOV     SAM_OFL2,DH
  1840.         POP     AX
  1841.         SUB     SI,AX
  1842.         PUSH    EAX
  1843.         MOVZX   EAX,SI
  1844.         ADD     SAM_OFS2,EAX
  1845.         POP     EAX
  1846.         MOV     SAM_MAX2,BX
  1847.         CALL    EMS_RESTORE
  1848. GO_BACKS2:
  1849.         RET
  1850. MIX_ENDS2:
  1851.         MOV     CS:SAM_SEG2,0
  1852.         JMP     MIX_REST2
  1853. MIX_CHANNELS2 ENDP
  1854. ;-----------------------------------------------------------------------------
  1855. ; SET EMS-PAGES
  1856. ; IN:  EAX= EMS-OFFSET
  1857. ; OUT: ES:DI= SEGMENT & OFFSET IN EMS PAGE
  1858. ;-----------------------------------------------------------------------------
  1859. EMS_PAGING PROC NEAR
  1860.         MOV     DI,AX
  1861.         AND     DI,3FFFH
  1862.         MOV     ES,EMS_SEG
  1863.         PUSHA
  1864.         PUSH    EAX
  1865.         SHR     EAX,14
  1866.         MOV     BX,AX
  1867.         XOR     AL,AL
  1868.         MOV     DX,EMS_HANDLE
  1869.         MOV     AH,44H
  1870.         INT     67H
  1871.         INC     AL
  1872.         INC     BX
  1873.         MOV     AH,44H
  1874.         INT     67H
  1875.         INC     AL
  1876.         INC     BX
  1877.         MOV     AH,44H
  1878.         INT     67H
  1879.         INC     AL
  1880.         INC     BX
  1881.         MOV     AH,44H
  1882.         INT     67H
  1883.         POP     EAX
  1884.         POPA
  1885.         RET
  1886. EMS_PAGING ENDP
  1887. ;-----------------------------------------------------------------------------
  1888. EMS_SAVE PROC NEAR
  1889.         PUSH    AX DX
  1890.         MOV     DX,EMS_HANDLE           ;EMS MAPPING SAVE
  1891.         MOV     AH,47H
  1892.         INT     67H
  1893.         POP     DX AX
  1894.         RET
  1895. EMS_SAVE ENDP
  1896. ;-----------------------------------------------------------------------------
  1897. EMS_RESTORE PROC NEAR
  1898.         PUSH    AX DX
  1899.         MOV     DX,EMS_HANDLE           ;EMS MAPPING RESTORE
  1900.         MOV     AH,48H
  1901.         INT     67H
  1902.         POP     DX AX
  1903.         RET
  1904. EMS_RESTORE ENDP
  1905. ;╒═══════════════════════════════════════════════════════════════════════════╕
  1906. ;│ DESCRIPTION: Calculates the values for the mixing multiplication table.   │
  1907. ;│              This table is used during 4/8-channel mixing to speed up the │
  1908. ;│              operation by avoiding 'mul' instructions.                    │
  1909. ;╘═══════════════════════════════════════════════════════════════════════════╛
  1910. MAKE_MIXMUL_VOLUMETABLE PROC NEAR
  1911.         MOV     ES,DMA_SEG
  1912.         MOV     DI,MIXMUL_OFFSET
  1913.         CLD
  1914.         MOV     CX,CH_NUMB
  1915.         SHR     CL,3
  1916.         MOV     CH,SBPRO_FLAG
  1917.         XOR     BX,BX                   ; start with volume 0
  1918.         INC     BH
  1919. VOLUMELOOP:                             ; start with sample 0
  1920. SAMPLELOOP:
  1921.         MOV     AL,BL
  1922.         XCHG    CL,CH
  1923.         IMUL    BH
  1924.         OR      AH,AH                   ; ROUND UP
  1925.         JNS     SHORT GMK1
  1926.         OR      AL,AL
  1927.         JZ      SHORT GMK1
  1928.         INC     AH
  1929. GMK1:   SAL     AX,CL
  1930.         XCHG    CL,CH
  1931.         MOV     AL,AH
  1932.         SAR     AL,CL                   ; 8- CHANNEL MIXING
  1933.         STOSB
  1934.         INC     BL
  1935.         JNZ     SAMPLELOOP
  1936.         INC     BH
  1937.         CMP     BH,64
  1938.         JBE     VOLUMELOOP
  1939.         RET
  1940. MAKE_MIXMUL_VOLUMETABLE ENDP
  1941. ;=============================================================================
  1942.  
  1943.  
  1944. ;=============================================================================
  1945. ;
  1946. ; DOS ROUTINES
  1947. ;
  1948. ;=============================================================================
  1949. ;-----------------------------------------------------------------------------
  1950. ; TIMER-IRQ-HANDLER: 1024 HZ CALLING FREQUENCE
  1951. ;-----------------------------------------------------------------------------
  1952. TIMER_HANDLER PROC FAR
  1953.         PUSH    AX
  1954.         CMP     CS:SYSTEM,0
  1955.         JNE     SHORT WT6
  1956.         MOV     AL,UHR_STATC
  1957.         OUT     UHR_INDEX,AL
  1958.         JMP     SHORT WT1
  1959. WT1:    JMP     SHORT WT2
  1960. WT2:    IN      AL,UHR_PORT
  1961. WT6:    MOV     AL,20H
  1962.         OUT     IRQ3,AL
  1963.         OUT     IRQ1,AL
  1964.         CMP     CS:MOD_STAT,0
  1965.         JE      SHORT WT3
  1966.         DEC     CS:BPM_COUNT            ;1024/20= 50 HZ
  1967.         JNZ     SHORT WT3
  1968.         STI
  1969.         PUSHA
  1970.         PUSH    DS ES CS
  1971.         POP     DS
  1972.         MOV     AL,BPM_SPEED
  1973.         MOV     BPM_COUNT,AL
  1974.         CALL    CONTROL_CHANNELS
  1975.         CALL    MIXUP_CHANNELS
  1976.         TEST    SB_MODUS,2
  1977.         JZ      SHORT WT5
  1978.         MOV     MOD_STAT,4
  1979.         JMP     SHORT WT4
  1980. WT5:    CMP     MOD_STAT,4
  1981.         JB      SHORT WT4
  1982.         MOV     MOD_STAT,2
  1983. WT4:    POP     ES DS
  1984.         POPA
  1985. WT3:    POP     AX
  1986.         CMP     CS:SYSTEM,0
  1987.         JE      SHORT WT7
  1988.         DEC     CS:IRQCOUNT
  1989.         JNZ     SHORT WT7
  1990.         MOV     CS:IRQCOUNT,56
  1991.         JMP     DWORD PTR CS:[HOLD70]
  1992. WT7:    IRET
  1993. TIMER_HANDLER ENDP
  1994. ;-----------------------------------------------------------------------------
  1995. ; SOUNDBLASTER-IRQ-HANDLER
  1996. ;-----------------------------------------------------------------------------
  1997. SBIRQ_HANDLER PROC FAR
  1998.         PUSH    AX CX DX
  1999.         MOV     DX,CS:SB_RSTAT          ;CLEAR IRQ
  2000.         IN      AL,DX
  2001.         DEC     DX
  2002.         DEC     DX
  2003.         MOV     CX,1000H
  2004. WUV1:   IN      AL,DX
  2005.         OR      AL,AL
  2006.         JNS     SHORT WUW1
  2007.         LOOP    WUV1
  2008. WUW1:   CMP     CS:SBPRO_FLAG,1
  2009.         JE      SHORT WUV4
  2010.         MOV     AL,14H                  ;SB MONO
  2011.         OUT     DX,AL
  2012.         MOV     CX,1000H
  2013. WUV2:   IN      AL,DX                   ;WAIT UNTIL READY
  2014.         OR      AL,AL
  2015.         JNS     SHORT WUW2
  2016.         LOOP    WUV2
  2017. WUW2:   MOV     AL,0FFH                 ;SET MAX BLOCK SIZE
  2018.         OUT     DX,AL
  2019.         MOV     CX,1000H
  2020. WUV3:   IN      AL,DX                   ;WAIT UNTIL READY
  2021.         OR      AL,AL
  2022.         JNS     SHORT WUW3
  2023.         LOOP    WUV3
  2024. WUW3:   MOV     AL,0FFH
  2025.         OUT     DX,AL
  2026.         MOV     AL,20H
  2027.         OUT     IRQ1,AL
  2028.         POP     DX CX AX
  2029.         IRET
  2030. WUV4:   MOV     AL,48H                  ;SB STEREO
  2031.         OUT     DX,AL
  2032.         MOV     CX,1000H
  2033. WUV5:   IN      AL,DX                   ;WAIT UNTIL READY
  2034.         OR      AL,AL
  2035.         JNS     SHORT WUW5
  2036.         LOOP    WUV5
  2037. WUW5:   MOV     AL,0FFH                 ;SET MAX BLOCK SIZE
  2038.         OUT     DX,AL
  2039.         MOV     CX,1000H
  2040. WUV6:   IN      AL,DX                   ;WAIT UNTIL READY
  2041.         OR      AL,AL
  2042.         JNS     SHORT WUW6
  2043.         LOOP    WUV6
  2044. WUW6:   MOV     AL,0FFH
  2045.         OUT     DX,AL
  2046.         MOV     CX,1000H
  2047. WUV7:   IN      AL,DX                   ;WAIT UNTIL READY
  2048.         OR      AL,AL
  2049.         JNS     SHORT WUW7
  2050.         LOOP    WUV7
  2051. WUW7:   MOV     AL,91H                  ;START SBPRO
  2052.         OUT     DX,AL
  2053.         MOV     AL,20H
  2054.         OUT     IRQ1,AL
  2055.         POP     DX CX AX
  2056.         IRET
  2057. SBIRQ_HANDLER ENDP
  2058. ;-----------------------------------------------------------------------------
  2059. ; SERVICE IRQ SWAPPING; USES THE REAL-TIME-CLOCK OR TIMER IRQ
  2060. ;-----------------------------------------------------------------------------
  2061. IRQ_INIT PROC NEAR
  2062.         CLI
  2063.         XOR     AX,AX
  2064.         MOV     ES,AX
  2065.         CMP     SYSTEM,0
  2066.         JNE     WU11
  2067.         MOV     AX,COMP_SPEED2          ;XCHANGE INIT & STOP DATA FOR DOS
  2068.         MOV     DX,COMP_SPEED3
  2069.         MOV     COMP_SPEED2,DX
  2070.         MOV     COMP_SPEED3,AX
  2071.         MOV     AL,UHR_STATA            ;SET CLOCK-IRQ-RATE (1024 HZ)
  2072.         OUT     UHR_INDEX,AL
  2073.         JMP     SHORT WU1
  2074. WU1:    JMP     SHORT WU2
  2075. WU2:    XCHG    AL,AH
  2076.         IN      AL,UHR_PORT
  2077.         AND     AL,0F0H
  2078.         OR      AL,DL
  2079.         XCHG    AL,AH
  2080.         OUT     UHR_INDEX,AL
  2081.         JMP     SHORT WU3
  2082. WU3:    JMP     SHORT WU4
  2083. WU4:    XCHG    AL,AH
  2084.         OUT     UHR_PORT,AL
  2085.         JMP     SHORT WU5
  2086. WU5:    JMP     SHORT WU6
  2087. WU6:    MOV     AL,UHR_STATB            ;SET CLOCK-IRQ-MODUS
  2088.         OUT     UHR_INDEX,AL
  2089.         JMP     SHORT WU7
  2090. WU7:    JMP     SHORT WU8
  2091. WU8:    XCHG    AL,AH
  2092.         IN      AL,UHR_PORT
  2093.         AND     AL,08FH
  2094.         MOV     DL,DH
  2095.         AND     DL,40H
  2096.         OR      AL,DL
  2097.         XCHG    AL,AH
  2098.         OUT     UHR_INDEX,AL
  2099.         JMP     SHORT WU9
  2100. WU9:    JMP     SHORT WU10
  2101. WU10:   XCHG    AL,AH
  2102.         OUT     UHR_PORT,AL
  2103.         IN      AL,IRQ4                 ;IRQ8 DE-/MASK
  2104.         AND     AL,0FEH
  2105.         MOV     DL,DH
  2106.         AND     DL,1
  2107.         OR      AL,DL
  2108.         OUT     IRQ4,AL
  2109.         IN      AL,IRQ2                 ;SBIRQ DE-/MASK
  2110.         MOV     CL,IRQ_NUMBER
  2111.         SHL     DL,CL
  2112.         MOV     DH,0FEH
  2113.         ROL     DH,CL
  2114.         AND     AL,DH
  2115.         OR      AL,DL
  2116.         OUT     IRQ2,AL
  2117.         MOV     BX,4*70H                ;CLOCK-IRQ DETOUR
  2118.         MOV     EAX,ES:[BX]
  2119.         MOV     EDX,HOLD70
  2120.         MOV     ES:[BX],EDX
  2121.         MOV     HOLD70,EAX
  2122.         JMP     WU12
  2123. WU11:   MOV     AX,COMP_SPEED4          ;FOR WINDOWS
  2124.         MOV     DX,COMP_SPEED5
  2125.         MOV     COMP_SPEED4,DX
  2126.         MOV     COMP_SPEED5,AX
  2127.         MOV     AL,00110110B            ;SET TIMER0 TO 1.024 KHZ
  2128.         OUT     PIT1,AL                 ;DIVIDER =1193
  2129.         MOV     AL,DL
  2130.         OUT     TIMER0,AL
  2131.         JMP     SHORT OUT40
  2132. OUT40:  MOV     AL,DH
  2133.         OUT     TIMER0,AL
  2134.         MOV     AX,COMP_SPEED2          ;XCHANGE INIT & STOP DATA FOR DOS
  2135.         MOV     DX,COMP_SPEED3
  2136.         MOV     COMP_SPEED2,DX
  2137.         MOV     COMP_SPEED3,AX
  2138.         IN      AL,IRQ2                 ;SBIRQ DE-/MASK
  2139.         MOV     CL,IRQ_NUMBER
  2140.         SHL     DL,CL
  2141.         MOV     DH,0FEH
  2142.         ROL     DH,CL
  2143.         AND     AL,DH
  2144.         OR      AL,DL
  2145.         OUT     IRQ2,AL
  2146.         MOV     BX,4*8H                 ;TIMEOUT-IRQ DETOUR
  2147.         MOV     EAX,ES:[BX]
  2148.         MOV     EDX,HOLD70
  2149.         MOV     ES:[BX],EDX
  2150.         MOV     HOLD70,EAX
  2151. WU12:   MOV     BL,CL                   ;SOUNDBLASTER-IRQ DETOUR
  2152.         ADD     BL,8
  2153.         SHL     BL,2
  2154.         XOR     BH,BH
  2155.         MOV     EAX,ES:[BX]
  2156.         MOV     EDX,HOLDSB
  2157.         MOV     ES:[BX],EDX
  2158.         MOV     HOLDSB,EAX
  2159.         MOV     AL,20H
  2160.         OUT     IRQ3,AL
  2161.         OUT     IRQ1,AL
  2162.         STI
  2163.         RET
  2164. IRQ_INIT ENDP
  2165. ;----------------------------------------------------------------------------
  2166. ; ALLOCATES MEMORY FOR TRACKS, CARRY-FLAG 0=OK 1=ABBRUCH
  2167. ;----------------------------------------------------------------------------
  2168. SET_TMEM PROC NEAR
  2169.         MOV     AH,48H
  2170.         MOV     BX,1000H                ;64K TRACK BUFFER (WILL BE RESIZED)
  2171.         INT     21H
  2172.         JC      SHORT STCM1
  2173.         MOV     TRACK_SEG,AX
  2174.         MOV     AH,48H
  2175.         MOV     BX,80H                  ;2K PATTERN BUFFER
  2176.         INT     21H
  2177.         JC      SHORT STCM1
  2178.         MOV     PATTERN_SEG,AX
  2179. STCM1:  RET
  2180. SET_TMEM ENDP
  2181. ;----------------------------------------------------------------------------
  2182. ; DEALLOCATES MEMORY OF TRACKS
  2183. ;----------------------------------------------------------------------------
  2184. FREE_TMEM PROC NEAR
  2185.         MOV     AX,SAMPLE_SEG
  2186.         MOV     ES,AX
  2187.         MOV     AH,49H
  2188.         INT     21H
  2189.         MOV     AX,TRACK_SEG
  2190.         MOV     ES,AX
  2191.         MOV     AH,49H
  2192.         INT     21H
  2193.         RET
  2194. FREE_TMEM ENDP
  2195. ;----------------------------------------------------------------------------
  2196. ; ALLOCATES MEMORY OF DMA_BUFFER & MIXMUL_TABLE, CARRY 0=OK 1=ERROR
  2197. ;----------------------------------------------------------------------------
  2198. SET_DMEM PROC NEAR
  2199.         MOV     AH,48H
  2200.         MOV     BX,0600H                ;24K BUFFER
  2201.         INT     21H
  2202.         JC      SHORT SDCM1
  2203.         MOV     DMA_SEG,AX
  2204.         MOV     DMA_OFFSET,0            ;DMA_BUFFER CA.  8K
  2205.         MOV     MIXMUL_OFFSET,2000H     ;MIXMUL_TAB CA. 16K
  2206.         AND     AX,0FFFH                ;CHECK FOR 64K DMA PAGE
  2207.         CMP     AX,0E00H
  2208.         JB      SHORT SDCM2
  2209.         MOV     DMA_OFFSET,4000H
  2210.         MOV     MIXMUL_OFFSET,0
  2211. SDCM2:  CLC
  2212. SDCM1:  RET
  2213. SET_DMEM ENDP
  2214. ;----------------------------------------------------------------------------
  2215. ; DEALLOCATES MEMORY OF DMA & MIXMUL_VOLUMETABLE
  2216. ;----------------------------------------------------------------------------
  2217. FREE_DMEM PROC NEAR
  2218.         MOV     AX,DMA_SEG
  2219.         MOV     ES,AX
  2220.         MOV     AH,49H
  2221.         INT     21H
  2222.         RET
  2223. FREE_DMEM ENDP
  2224. ;-----------------------------------------------------------------------------
  2225. FREE_MEM PROC NEAR
  2226.         MOV     BX,PROG_END_SEG
  2227.         SUB     BX,PROG_START_SEG
  2228.         MOV     ES,PROG_START_SEG
  2229.         MOV     AH,4AH
  2230.         INT     21H
  2231.         RET
  2232. FREE_MEM ENDP
  2233. ;=============================================================================
  2234.  
  2235.  
  2236.  
  2237. ;=============================================================================
  2238. ;
  2239. ; SOUNDBLASTER HARDWARE ROUTINES
  2240. ;
  2241. ;=============================================================================
  2242. ; SET MIXER IF PRESENT
  2243. ;-----------------------------------------------------------------------------
  2244. MIXER_INIT PROC NEAR
  2245.         MOV     DX,SBP_MIXERI
  2246. COMMENT *                              
  2247.         XOR     AL,AL                   ;RESET MIXER SWITCHED OFF
  2248.         OUT     DX,AL                   ;BECAUSE IT IS NOT WORKING PROPERLY
  2249.         MOV     CX,100                  ;WITH SB16 ASP (GAIN x2,x3,..)
  2250.         CALL    WAIT_TIME
  2251.         MOV     DX,SBP_MIXERD
  2252.         XOR     AL,AL
  2253.         OUT     DX,AL
  2254.         DEC     DX
  2255.         *
  2256.         MOV     AL,22H
  2257.         OUT     DX,AL
  2258.         INC     DX
  2259.         MOV     AL,255                  ;MAX MASTERVOLUME
  2260.         OUT     DX,AL
  2261.         DEC     DX
  2262.         MOV     AL,2
  2263.         OUT     DX,AL
  2264.         INC     DX
  2265.         MOV     AL,255                  ;MAX DSPVOLUME
  2266.         OUT     DX,AL
  2267.         DEC     DX
  2268.         MOV     AL,0EH
  2269.         OUT     DX,AL
  2270.         INC     DX
  2271.         MOV     AL,0H                   ;FILTER & MONO
  2272.         MOV     SBPRO_FLAG,AL
  2273.         CMP     SB_TYP,1                ;SBPRO ENABLED?
  2274.         JNE     SHORT GMIX1
  2275.         MOV     SBPRO_FLAG,1
  2276.         MOV     AL,2H                   ;FILTER & STEREO
  2277. GMIX1:  OUT     DX,AL
  2278.         RET
  2279. MIXER_INIT ENDP
  2280. ;-----------------------------------------------------------------------------
  2281. ; SET DMA READY FOR TRANSFER WITH AUTOINIT
  2282. ; IN: DX:BX= BLOCKPOINTER, CX= SIZE
  2283. ;-----------------------------------------------------------------------------
  2284. DMA_INIT PROC NEAR
  2285.         MOV     AX,DX                   ;CONVERT ADDRESS TO PAGE AND OFFSET
  2286.         SHL     DX,4
  2287.         SHR     AH,4                    ;PAGE
  2288.         ADD     BX,DX                   ;OFFSET NEW
  2289.         ADC     AH,0
  2290.         MOV     DMA_PAGE,AH
  2291.         MOV     DMA_POFF,BX
  2292.         DEC     CX                      ;DMA SIZE= BLOCK SIZE -1
  2293.         MOV     AL,DMA_CHANNEL
  2294.         OR      AL,4
  2295.         OUT     0AH,AL                  ;DMA-CHANNEL MASK
  2296.         AND     AL,3
  2297.         OR      AL,01011000B
  2298.         OUT     0BH,AL                  ;DMA-MODUS FOR SB
  2299.         OUT     0CH,AL                  ;FLIP-FLOP CLEAR
  2300.         AND     AL,3
  2301.         MOVZX   DX,AL
  2302.         SHL     DL,1
  2303.         MOV     AL,BL                   ;DMA CHANNEL 1-4
  2304.         OUT     DX,AL                   ;OFFSET LOW
  2305.         MOV     AL,BH
  2306.         OUT     DX,AL                   ;OFFSET HIGH
  2307.         INC     DL
  2308.         MOV     AL,CL
  2309.         OUT     DX,AL                   ;SIZE LOW
  2310.         MOV     AL,CH
  2311.         OUT     DX,AL                   ;SIZE HIGH
  2312.         MOV     BX,DX
  2313.         SHR     BL,1
  2314.         MOV     DL,[DMA_DATA+BX]
  2315.         MOV     AL,AH
  2316.         OUT     DX,AL                   ;PAGE
  2317.         MOV     AL,BL
  2318.         OUT     0AH,AL                  ;DMA-CHANNEL DEMASK
  2319.         RET
  2320. DMA_INIT ENDP
  2321. ;-----------------------------------------------------------------------------
  2322. ; DSP SET SAMPLE RATE
  2323. ; IN: AH= RATE (= 256-(1000000/FREQ))
  2324. ;-----------------------------------------------------------------------------
  2325. DSP_RATE PROC NEAR
  2326.         PUSH    AX
  2327.         MOV     AH,40H
  2328.         CALL    DSP_WRITE
  2329.         POP     AX
  2330.         CALL    DSP_WRITE
  2331.         RET
  2332. DSP_RATE ENDP
  2333. ;-----------------------------------------------------------------------------
  2334. ; DSP OUT BLOCK
  2335. ;-----------------------------------------------------------------------------
  2336. DSP_OUT PROC NEAR
  2337.         CMP     SBPRO_FLAG,1
  2338.         JE      SHORT GDSP1
  2339.         MOV     AH,14H                  ;MONO DMA-OUTPUT NEW
  2340.         CALL    DSP_WRITE
  2341.         MOV     AH,0FFH                 ;SIZE LOW
  2342.         CALL    DSP_WRITE
  2343.         MOV     AH,0FFH                 ;SIZE HIGH
  2344.         CALL    DSP_WRITE
  2345.         RET
  2346. GDSP1:  MOV     AH,48H                  ;STEREO DMA-OUTPUT NEW
  2347.         CALL    DSP_WRITE
  2348.         MOV     AH,0FFH                 ;SIZE LOW
  2349.         CALL    DSP_WRITE
  2350.         MOV     AH,0FFH                 ;SIZE HIGH
  2351.         CALL    DSP_WRITE
  2352.         MOV     AH,91H                  ;START
  2353.         CALL    DSP_WRITE
  2354.         RET
  2355. DSP_OUT ENDP
  2356. ;-----------------------------------------------------------------------------
  2357. ; DSP RESET
  2358. ; OUT: CARRY 1= FAILURE
  2359. ;-----------------------------------------------------------------------------
  2360. DSP_RESET PROC NEAR
  2361.         CALL    DSP_OFF
  2362.         OUT     0DH,AL                  ;DMA MASTER CLEAR
  2363.         CALL    MIXER_INIT
  2364.         MOV     DX,SB_RESET
  2365.         MOV     AL,1
  2366.         OUT     DX,AL                   ;SEND RESET COMMAND
  2367.         MOV     CX,4
  2368.         CALL    WAIT_TIME               ;WAIT
  2369.         XOR     AL,AL
  2370.         OUT     DX,AL                   ;CLEAR RESET COMMAND
  2371.         MOV     CX,120
  2372.         CALL    WAIT_TIME               ;WAIT
  2373.         MOV     DX,SB_RSTAT
  2374.         IN      AL,DX                   ;CHECK IF SUCCESSFUL
  2375.         OR      AL,AL
  2376.         JNS     SHORT GDRES1
  2377.         MOV     DX,SB_READ
  2378.         IN      AL,DX
  2379.         CMP     AL,0AAH
  2380.         JNE     SHORT GDRES1
  2381.         CALL    DSP_ON
  2382.         CLC                             ;RESET OK
  2383.         RET
  2384. GDRES1: STC                             ;RESET FAILURE
  2385.         RET
  2386. DSP_RESET ENDP
  2387. ;-----------------------------------------------------------------------------
  2388. ; SPEAKER ON
  2389. ;-----------------------------------------------------------------------------
  2390. DSP_ON PROC NEAR
  2391.         MOV     AH,0D1H                 ;SPEAKER ON
  2392.         CALL    DSP_WRITE
  2393.         MOV     CX,120
  2394.         CALL    WAIT_TIME               ;WAIT
  2395.         RET
  2396. DSP_ON ENDP
  2397. ;-----------------------------------------------------------------------------
  2398. ; SPEAKER OFF
  2399. ;-----------------------------------------------------------------------------
  2400. DSP_OFF PROC NEAR
  2401.         PUSH    CS
  2402.         POP     DS
  2403.         CMP     SB_TYP,1
  2404.         JE      SHORT GDSPF1            ;SB
  2405.         MOV     AL,DMA_CHANNEL          ;DMA DEMASK
  2406.         OUT     0AH,AL
  2407.         MOV     AH,0D0H                 ;DMA STOP
  2408.         CALL    DSP_WRITE
  2409.         MOV     AH,0D3H                 ;DSP OFF
  2410.         CALL    DSP_WRITE
  2411.         MOV     CX,240
  2412.         CALL    WAIT_TIME               ;WAIT
  2413.         RET
  2414. GDSPF1: MOV     DX,SBP_MIXERI           ;SBPRO
  2415.         MOV     AL,22H
  2416.         OUT     DX,AL
  2417.         INC     DX
  2418.         MOV     AL,0                    ;MIN MASTERVOLUME
  2419.         OUT     DX,AL
  2420.         DEC     DX
  2421.         MOV     AL,2
  2422.         OUT     DX,AL
  2423.         INC     DX
  2424.         MOV     AL,0                    ;MIN DSPVOLUME
  2425.         OUT     DX,AL
  2426.         MOV     CX,240
  2427.         CALL    WAIT_TIME
  2428.         RET
  2429. DSP_OFF ENDP
  2430. ;-----------------------------------------------------------------------------
  2431. ; READ BYTE
  2432. ; OUT: AL= BYTE
  2433. ;-----------------------------------------------------------------------------
  2434. DSP_READ PROC NEAR
  2435.         MOV     DX,SB_READ
  2436.         MOV     CX,-1                   ;FAIL SAFE
  2437. LDRD1:  IN      AL,DX
  2438.         CMP     AL,0AAH
  2439.         JNE     SHORT LDRD2
  2440.         LOOP    LDRD1
  2441. LDRD2:  RET
  2442. DSP_READ ENDP
  2443. ;-----------------------------------------------------------------------------
  2444. ; WRITE BYTE
  2445. ; IN: AH= BYTE
  2446. ;-----------------------------------------------------------------------------
  2447. DSP_WRITE PROC NEAR
  2448.         MOV     DX,SB_WRITE
  2449.         MOV     CX,1000H                ;FAIL SAFE
  2450. LDWR1:  IN      AL,DX
  2451.         OR      AL,AL
  2452.         JNS     SHORT LDWR2
  2453.         LOOP    LDWR1
  2454. LDWR2:  MOV     AL,AH
  2455.         OUT     DX,AL
  2456.         RET
  2457. DSP_WRITE ENDP
  2458. ;-----------------------------------------------------------------------------
  2459. ; WAIT TIME
  2460. ; CX = XXX MILLISECONDS
  2461. ;-----------------------------------------------------------------------------
  2462. WAIT_TIME PROC NEAR
  2463.         PUSH    AX BX EDX
  2464. LWT1:   IN      AL,TIMER0
  2465.         MOV     BL,AL
  2466.         IN      AL,TIMER0
  2467.         MOV     BH,AL
  2468.         MOV     EDX,500000              ;FAIL SAFE
  2469. LWT2:   IN      AL,TIMER0               ;1 MILLISEC WAIT
  2470.         XCHG    AL,AH
  2471.         IN      AL,TIMER0
  2472.         XCHG    AL,AH
  2473.         SUB     AX,BX
  2474.         NEG     AX
  2475.         DEC     EDX
  2476.         JZ      SHORT LWT3
  2477.         CMP     AX,1193
  2478.         JB      LWT2
  2479. LWT3:   LOOP    LWT1
  2480.         POP     EDX BX AX
  2481.         RET
  2482. WAIT_TIME ENDP
  2483. ;=============================================================================
  2484.  
  2485.  
  2486. ;=============================================================================
  2487. ;
  2488. ; MOD LOAD ROUTINES
  2489. ;
  2490. ;=============================================================================
  2491. ; LOAD A MODFILE
  2492. ; DS:DX= FILENAME
  2493. ;-----------------------------------------------------------------------------
  2494. LOAD_MOD PROC NEAR
  2495.         MOV     AX,3D00H                ;OPEN MOD
  2496.         INT     21H
  2497.         JC      GLDM1
  2498.         PUSH    CS
  2499.         POP     DS
  2500.         MOV     GDDHANDLE,AX
  2501. GLDM0:  CALL    SET_DMEM                ;ALLOCATE DMA-BUFFER
  2502.         CALL    SET_TMEM                ;ALLOCATE TRACK-BUFFER
  2503.         MOV     BX,GDDHANDLE
  2504.         MOV     GDDZEIG,0
  2505.         MOV     CX,10                   ;GET SONG-NAME
  2506. LLDM1:  CALL    GET_QUEUE
  2507.         JC      GLDM2
  2508.         LOOP    LLDM1
  2509.         MOV     SAMPLE_SIZE,0
  2510.         XOR     SI,SI                   ;31 INSTRUMENTS
  2511. LLDM2:  MOV     AX,SAMPLE_SIZE
  2512.         MOV     [SAMPLE_SEG+SI],AX
  2513.         MOV     CX,11                   ;INSTRUMENT NAME
  2514. LLDM3:  CALL    GET_QUEUE      
  2515.         JC      GLDM2
  2516.         LOOP    LLDM3
  2517.         XOR     EAX,EAX
  2518.         CALL    GET_QUEUE               ;INSTRUMENT SIZE
  2519.         XCHG    AL,AH
  2520.         CMP     AX,2
  2521.         JAE     SHORT GLDM20
  2522.         XOR     AX,AX
  2523. GLDM20: SHL     AX,1
  2524.         MOV     [ISIZE+SI],AX           ;NO MORE THAN 64K
  2525.         OR      EAX,EAX
  2526.         JZ      SHORT GLDM9
  2527.         SHR     EAX,4
  2528.         INC     AX
  2529.         ADD     SAMPLE_SIZE,AX
  2530. GLDM9:  CALL    GET_QUEUE               ;IVOLUME & FINETUNE
  2531.         XCHG    AL,AH
  2532.         MOV     [IVOL_FINETUNE+SI],AX
  2533.         CALL    GET_QUEUE               ;ILOOP_START
  2534.         XCHG    AL,AH
  2535.         SHL     AX,1
  2536.         MOV     [ILOOP_START+SI],AX
  2537.         CALL    GET_QUEUE               ;ILOOP_SIZE
  2538.         XCHG    AL,AH
  2539.         SHL     AX,1
  2540.         MOV     [ILOOP_SIZE+SI],AX
  2541.         INC     SI
  2542.         INC     SI
  2543.         CMP     SI,62
  2544.         JB      LLDM2
  2545.         CALL    GET_QUEUE               ;SONG_SIZE & LOOP_BYTE OR NOTHING
  2546.         JC      GLDM2
  2547.         MOV     SONG_SIZE,AL
  2548.         MOV     SONG_LOOP,AH
  2549.         XOR     DX,DX
  2550.         MOV     CX,64                   ;SONG_DATA
  2551.         MOV     DI,OFFSET SONG_DATA
  2552. LLDM4:  CALL    GET_QUEUE
  2553.         JC      GLDM2
  2554.         MOV     [DI],AX
  2555.         CMP     AL,DL                   ;FIND HIGHEST PATTERN NUMBER
  2556.         JBE     SHORT GLDM12
  2557.         MOV     DL,AL
  2558. GLDM12: CMP     AH,DL
  2559.         JBE     SHORT GLDM13
  2560.         MOV     DL,AH
  2561. GLDM13: INC     DI
  2562.         INC     DI
  2563.         LOOP    LLDM4
  2564.         INC     DL
  2565.         CLD
  2566.         MOV     PATTERN_NUMBER,DX
  2567.         CALL    GET_QUEUE
  2568.         PUSH    AX
  2569.         CALL    GET_QUEUE
  2570.         SHL     EAX,16
  2571.         POP     AX
  2572.         MOV     MOD_SIGN,EAX
  2573.         CMP     EAX,"NHC8"              ;8CHN-MOD
  2574.         JE      SHORT GLDM3
  2575.         CMP     EAX,"8TLF"              ;FLT8-MOD
  2576.         JE      SHORT GLDM3
  2577.         CMP     EAX,".K.M"              ;M.K.-MOD
  2578.         JE      SHORT GLDM10
  2579.         CMP     EAX,"4TLF"              ;FLT4-MOD
  2580.         JNE     GLDM2
  2581.  
  2582. GLDM10: MOV     CH_NUMB,4               ;4-CHANNEL-MOD
  2583.         MOV     PATTERN_SIZE,1024
  2584.         MOV     AH,0
  2585.         MOV     TRACK_INFO+4,AH
  2586.         MOV     TRACK_INFO+5,AH
  2587.         MOV     TRACK_INFO+6,AH
  2588.         MOV     TRACK_INFO+7,AH
  2589.         JMP     SHORT GLDM11
  2590. GLDM3:  MOV     CH_NUMB,8               ;8-CHANNEL-MOD: GET-PATTERNS
  2591.         MOV     PATTERN_SIZE,2048
  2592. GLDM11: MOV     PATTERN_CURRENT,0
  2593.         MOV     TRACK_NUMBER,0
  2594. LLDM7:  MOV     ES,PATTERN_SEG
  2595.         MOV     BX,GDDHANDLE
  2596.         XOR     DI,DI
  2597. LLDM6:  XOR     SI,SI
  2598. LLDM5:  CALL    GET_QUEUE               ;GET PATTERNS AND SPLIT INTO TRACKS
  2599.         JC      GLDM2
  2600.         MOV     DX,AX
  2601.         CALL    GET_QUEUE
  2602.         JC      GLDM2
  2603.         ROL     AL,4                    ;MODIFY PATTERN DATA
  2604.         MOV     CL,AL                   ;LOOK AT PROTRACKER-CODE HEADER
  2605.         AND     AL,0FH
  2606.         AND     CL,0F0H
  2607.         MOV     CH,DL
  2608.         AND     DL,0FH
  2609.         AND     CH,0F0H
  2610.         OR      AL,CH
  2611.         OR      DL,CL
  2612.         XCHG    DL,DH
  2613.         PUSH    DI
  2614.         ADD     DI,SI
  2615.         SHL     EAX,16
  2616.         MOV     AX,DX
  2617.         STOSD
  2618.         POP     DI
  2619.         ADD     SI,256
  2620.         CMP     SI,PATTERN_SIZE         ;NEXT TRACK/CHANNEL
  2621.         JB      LLDM5
  2622.         ADD     DI,4                    ;NEXT NOTE
  2623.         CMP     DI,256
  2624.         JB      LLDM6
  2625.         CALL    SET_FREQUENCIES
  2626.         MOV     ES,TRACK_SEG            ;INTEGRATE TRACK1-8
  2627.         MOV     DX,TRACK_NUMBER
  2628.         XCHG    DL,DH
  2629.         MOV     DS,PATTERN_SEG
  2630.         XOR     SI,SI
  2631.         XOR     BX,BX
  2632. LLDM8:  XOR     DI,DI
  2633. LLDM9:  CMP     DX,DI
  2634.         JBE     SHORT GLDM4
  2635.         PUSH    SI DI
  2636.         MOV     CX,256/4
  2637.         REPE CMPSD                      ;TRACK ALREADY EXISTS?
  2638.         POP     DI SI
  2639.         PUSHF
  2640.         ADD     DI,256
  2641.         POPF
  2642.         JNE     LLDM9
  2643.         JMP     SHORT GLDM5
  2644. GLDM4:  INC     DH                      ;NO, ADD TRACK TO BUFFER
  2645.         PUSH    SI
  2646.         MOV     CX,256/4
  2647.         REP MOVSD
  2648.         POP     SI
  2649. GLDM5:  MOV     AX,DI                   ;YES
  2650.         DEC     AH
  2651.         MOV     CS:[TRACK_INFO+BX],AH
  2652.         INC     BX
  2653.         ADD     SI,256
  2654.         CMP     BX,CS:CH_NUMB
  2655.         JB      LLDM8
  2656.         PUSH    CS
  2657.         POP     DS
  2658.         XCHG    DL,DH
  2659.         MOV     TRACK_NUMBER,DX
  2660.         XOR     BX,BX                   ;MAKE TRACKLISTE
  2661.         MOV     AX,PATTERN_CURRENT
  2662. LLDM10: CMP     [SONG_DATA+BX],AL
  2663.         JNE     SHORT GLDM6
  2664.         MOV     AH,TRACK_INFO
  2665.         MOV     [TRACK1_DATA+BX],AH
  2666.         MOV     AH,TRACK_INFO+1
  2667.         MOV     [TRACK2_DATA+BX],AH
  2668.         MOV     AH,TRACK_INFO+2
  2669.         MOV     [TRACK3_DATA+BX],AH
  2670.         MOV     AH,TRACK_INFO+3
  2671.         MOV     [TRACK4_DATA+BX],AH
  2672.         MOV     AH,TRACK_INFO+4
  2673.         MOV     [TRACK5_DATA+BX],AH
  2674.         MOV     AH,TRACK_INFO+5
  2675.         MOV     [TRACK6_DATA+BX],AH
  2676.         MOV     AH,TRACK_INFO+6
  2677.         MOV     [TRACK7_DATA+BX],AH
  2678.         MOV     AH,TRACK_INFO+7
  2679.         MOV     [TRACK8_DATA+BX],AH
  2680. GLDM6:  INC     BX
  2681.         CMP     BL,128
  2682.         JB      LLDM10
  2683.         INC     PATTERN_CURRENT         ;GET NEXT PATTERN
  2684.         MOV     AX,PATTERN_CURRENT
  2685.         CMP     AX,PATTERN_NUMBER
  2686.         JB      LLDM7
  2687.  
  2688. GLDM7:  MOV     ES,PATTERN_SEG          ;CLEAR PATTERN SEGMENT
  2689.         MOV     AH,49H
  2690.         INT     21H
  2691.         MOV     BX,TRACK_NUMBER         ;TRACK SEGMENT RESIZE
  2692.         SHL     BX,4
  2693.         MOV     ES,TRACK_SEG
  2694.         MOV     AH,4AH
  2695.         INT     21H
  2696.         MOV     BX,SAMPLE_SIZE          ;SAMPLE SEGMENT ALLOCATE
  2697.         MOV     AH,48H
  2698.         INT     21H
  2699.         XOR     BX,BX
  2700. LLDM11: ADD     [SAMPLE_SEG+BX],AX
  2701.         INC     BX
  2702.         INC     BX
  2703.         CMP     BX,62
  2704.         JB      LLDM11
  2705.         MOV     BX,GDDHANDLE
  2706.         XOR     SI,SI                   ;LOAD SAMPLES
  2707. LLDM12: MOV     CX,[ISIZE+SI]
  2708.         MOV     ES,[SAMPLE_SEG+SI]
  2709.         XOR     DI,DI
  2710.         SHR     CX,1
  2711.         JCXZ    SHORT GLDM8
  2712. LLDM13: CALL    GET_QUEUE
  2713.         STOSW
  2714.         LOOP    LLDM13
  2715. GLDM8:  INC     SI
  2716.         INC     SI
  2717.         CMP     SI,62
  2718.         JB      LLDM12
  2719.         CLC
  2720.         JMP     SHORT GLDM15
  2721. GLDM2:  STC
  2722. GLDM15: PUSHF
  2723.         MOV     AH,3EH
  2724.         INT     21H
  2725.         POPF
  2726. GLDM1:  RET
  2727. LOAD_MOD ENDP
  2728. ;-----------------------------------------------------------------------------
  2729. ; REPLACE MOST PERIODS WITH INDEX INTO PERIOD TABLE
  2730. ;-----------------------------------------------------------------------------
  2731. SET_FREQUENCIES PROC NEAR
  2732.         XOR     DI,DI
  2733. SET_FREQ1:
  2734.         MOV     AX,ES:[DI]              ;get fx
  2735.         MOV     DX,AX
  2736.         SHR     AH,4
  2737.         CMP     AH,3
  2738.         JE      SHORT SET_FREQ4
  2739.         CMP     AH,5
  2740.         JE      SHORT SET_FREQ4
  2741.         MOV     AX,DX
  2742.         AND     AX,0FFFH                ; Mask out unwanted bits.
  2743.         JZ      SHORT SET_FREQ4
  2744.         XOR     BX,BX
  2745.         MOV     CX,48                   ; 36 periods to cycle through.
  2746. SET_FREQ2:
  2747.         CMP     AX,[MT_PERIODTABLE+BX]  ; Check the note against the period.
  2748.         JAE     SHORT SET_FREQ3         ; We found it!
  2749.         INC     BX                      ; Otherwise, update the pointer and
  2750.         INC     BX
  2751.         LOOP    SET_FREQ2               ; keep looping.
  2752. SET_FREQ3:
  2753.         MOV     AX,DX                   ;recall the Note Value
  2754.         AND     AX,0F000H               ;just keep fx
  2755.         INC     BX
  2756.         OR      AX,BX                   ;put in the new offset
  2757.         STOSW                           ;store it
  2758.         DEC     DI
  2759.         DEC     DI
  2760. SET_FREQ4:
  2761.         ADD     DI,4                    ;and go to next channel
  2762.         CMP     DI,PATTERN_SIZE
  2763.         JB      SET_FREQ1
  2764.         RET
  2765. SET_FREQUENCIES ENDP
  2766. ;-----------------------------------------------------------------------------
  2767. ; GET WORD FROM BUFFER
  2768. ; IN: AX= WORD, BX= HANDLE
  2769. ;-----------------------------------------------------------------------------
  2770. GET_QUEUE PROC NEAR
  2771.         CMP     GDDZEIG,0
  2772.         JNE     SHORT GTQ1
  2773.         PUSH    CX DX
  2774.         MOV     DX,OFFSET QUEUE_BUFFER
  2775.         MOV     CX,256
  2776.         MOV     AH,3FH
  2777.         INT     21H
  2778.         MOV     GDDREST,AX
  2779.         POP     DX CX
  2780. GTQ1:   PUSH    BX
  2781.         MOV     BL,GDDZEIG
  2782.         XOR     BH,BH
  2783.         CMP     BX,GDDREST
  2784.         JAE     SHORT GTQ2
  2785.         MOV     AX,[QUEUE_BUFFER+BX]
  2786.         ADD     GDDZEIG,2
  2787.         POP     BX
  2788.         CLC
  2789.         RET
  2790. GTQ2:   POP     BX
  2791.         STC
  2792.         RET
  2793. GET_QUEUE ENDP
  2794. ;=============================================================================
  2795. ; LOAD A SAMPLE
  2796. ; INPUT: DS:DX= FILENAME, CL= 00H AMIGA-SAMPLE, 80H PC-SAMPLE
  2797. ; OUTPUT: AX= SAMPLE-HANDLE FOR PLAYING
  2798. ;-----------------------------------------------------------------------------
  2799. LOAD_SAMPLE PROC NEAR
  2800.         MOV     AX,3D00H                ;OPEN SAMPLE
  2801.         INT     21H
  2802.         JC      GSMP1
  2803.         PUSH    CS
  2804.         POP     DS
  2805.         MOV     GDDHANDLE,AX
  2806.         MOV     BX,AX
  2807.         PUSH    CX
  2808.         CALL    GET_FILESIZE
  2809.         POP     CX
  2810. GSMP0:  AND     CL,80H
  2811.         MOV     SAM_FLAG,CL
  2812.         MOV     GDDZEIG,0
  2813.         MOV     CX,AX
  2814.         AND     CX,0FFFEH
  2815.         SHR     AX,4
  2816.         INC     AX
  2817.         MOV     BX,AX
  2818.         CMP     EMS_SEG,0
  2819.         JNE     SHORT GSMP3
  2820.         PUSHA
  2821.         XOR     SI,SI
  2822.         XOR     AX,AX                   ;CHECK FOR EMS-MANAGER
  2823.         MOV     ES,AX
  2824.         MOV     EMS_HANDLE,AX
  2825.         MOV     AX,ES:[4*67H+2]
  2826.         MOV     ES,AX
  2827.         CMP     ES:[10],"XMME"
  2828.         JNE     GSMP2
  2829.         CMP     ES:[14],"0XXX"
  2830.         JNE     GSMP2
  2831.         MOV     AH,42H
  2832.         INT     67H
  2833.         OR      AH,AH
  2834.         JNZ     GSMP2
  2835.         CMP     BX,34
  2836.         JB      GSMP2
  2837.         MOV     AH,41H
  2838.         INT     67H
  2839.         MOV     EMS_SEG,BX
  2840.         MOV     AH,43H                  ;ALLOCATE 544K EMS FOR FX
  2841.         MOV     BX,34
  2842.         INT     67H
  2843.         MOV     EMS_HANDLE,DX
  2844.         XOR     AX,AX
  2845.         MOV     EMS_OFFSET,AX
  2846.         MOV     SAMPLE_ZEIG,AX
  2847.         POPA
  2848. GSMP3:  MOV     AX,EMS_OFFSET
  2849.         MOV     SI,SAMPLE_ZEIG
  2850.         MOV     [SAMPLE_MEM+SI],AX
  2851.         MOV     [SAMPLE_BIG+SI],CX
  2852.         ADD     SAMPLE_ZEIG,2
  2853.         MOV     DI,CX
  2854.         SHR     DI,4
  2855.         INC     DI
  2856.         ADD     EMS_OFFSET,DI
  2857.         XOR     DI,DI
  2858.         CLD
  2859.         INC     CX
  2860.         SHR     CX,1
  2861.         MOV     DL,SAM_FLAG
  2862.         MOV     DH,DL
  2863.         MOVZX   BP,FX_VOL
  2864.         INC     BP
  2865.         AND     EAX,0FFFFH
  2866.         SHL     EAX,4
  2867. LSMP1:  PUSH    EAX
  2868.         OR      DI,DI
  2869.         JNZ     SHORT GSMP4
  2870.         CALL    EMS_PAGING
  2871. GSMP4:  MOV     BX,GDDHANDLE
  2872.         CALL    GET_QUEUE
  2873.         XOR     AX,DX
  2874.         SAR     AH,1
  2875.         SAR     AL,1
  2876.         PUSH    DX
  2877.         MOV     BL,AH
  2878.         CBW
  2879.         IMUL    BP
  2880.         MOV     AL,BL
  2881.         MOV     BL,AH
  2882.         CBW
  2883.         IMUL    BP
  2884.         MOV     AL,BL
  2885.         POP     DX
  2886.         STOSW
  2887.         POP     EAX
  2888.         INC     EAX
  2889.         INC     EAX
  2890.         LOOP    LSMP1
  2891.         CLC
  2892. GSMP2:  PUSHF
  2893.         MOV     BX,GDDHANDLE
  2894.         MOV     AH,3EH
  2895.         INT     21H
  2896.         MOV     AX,SI
  2897.         POPF
  2898. GSMP1:  RET
  2899. LOAD_SAMPLE ENDP
  2900. ;-----------------------------------------------------------------------------
  2901. GET_FILESIZE PROC NEAR
  2902.         MOV     AX,4202H
  2903.         XOR     CX,CX
  2904.         XOR     DX,DX
  2905.         INT     21H
  2906.         PUSH    AX
  2907.         MOV     AX,4200H
  2908.         XOR     CX,CX
  2909.         XOR     DX,DX
  2910.         INT     21H
  2911.         POP     AX
  2912.         RET
  2913. GET_FILESIZE ENDP
  2914. ;=============================================================================
  2915. ; LOAD CONFIG DATA (PARSER)
  2916. ;-----------------------------------------------------------------------------
  2917. CONFIG_INIT PROC NEAR
  2918.         MOV     AX,CS                   ;SAVE THE SEGMENT OF CODE
  2919.         MOV     DS,AX
  2920.         MOV     WORD PTR HOLD70+2,AX    ;THIS LINE IS IMPORTANT
  2921.         MOV     WORD PTR HOLDSB+2,AX    ;THIS LINE IS IMPORTANT
  2922.         MOV     DX,OFFSET CONFIG_NAME
  2923.         MOV     AH,3DH
  2924.         MOV     AL,80H
  2925.         INT     21H
  2926.         JC      GCFG1
  2927.         MOV     GDDHANDLE,AX
  2928. LCFG1:  XOR     SI,SI
  2929.         MOV     DX,OFFSET QUEUE_BUFFER
  2930. LCFG2:  MOV     AH,3FH
  2931.         MOV     BX,GDDHANDLE
  2932.         MOV     CX,1
  2933.         INT     21H
  2934.         JC      GCFG2
  2935.         OR      AX,AX
  2936.         JZ      GCFG2
  2937.         MOV     DI,DX
  2938.         CMP     BYTE PTR [DI],0AH
  2939.         JE      SHORT GCFG6
  2940.         INC     DX
  2941.         INC     SI
  2942.         CMP     SI,256
  2943.         JB      LCFG2
  2944. GCFG6:  MOV     BX,OFFSET CFG_TEXT1
  2945.         CALL    SEEK_LINE
  2946.         JNC     SHORT GCFG3
  2947.         LODSB
  2948.         AND     AL,3
  2949.         MOV     SB_TYP,AL
  2950.         JMP     LCFG1
  2951. GCFG3:  MOV     BX,OFFSET CFG_TEXT2
  2952.         CALL    SEEK_LINE
  2953.         JNC     SHORT GCFG4
  2954.         LODSB
  2955.         AND     AL,3
  2956.         MOV     SB_MODUS,AL
  2957.         JMP     LCFG1
  2958. GCFG4:  MOV     BX,OFFSET CFG_TEXT3
  2959.         CALL    SEEK_LINE
  2960.         JNC     SHORT GCFG5
  2961.         INC     SI
  2962.         LODSB
  2963.         DEC     AL
  2964.         AND     AL,7
  2965.         INC     AL
  2966.         SHL     AL,4
  2967.         MOV     AH,2
  2968.         ADD     AL,4
  2969.         MOV     SBP_MIXERI,AX
  2970.         INC     AX
  2971.         MOV     SBP_MIXERD,AX
  2972.         INC     AX
  2973.         MOV     SB_RESET,AX
  2974.         ADD     AX,4
  2975.         MOV     SB_READ,AX
  2976.         ADD     AX,2
  2977.         MOV     SB_WRITE,AX
  2978.         ADD     AX,2
  2979.         MOV     SB_RSTAT,AX
  2980.         JMP     LCFG1
  2981. GCFG5:  MOV     BX,OFFSET CFG_TEXT4
  2982.         CALL    SEEK_LINE
  2983.         JNC     SHORT GCFG7
  2984.         LODSW
  2985.         AND     AL,7
  2986.         AND     AH,7
  2987.         MOV     BH,AH
  2988.         MOV     BL,10
  2989.         MUL     BL
  2990.         ADD     AL,BH
  2991.         MOV     IRQ_NUMBER,AL
  2992.         JMP     LCFG1
  2993. GCFG7:  MOV     BX,OFFSET CFG_TEXT5
  2994.         CALL    SEEK_LINE
  2995.         JNC     SHORT GCFG8
  2996.         LODSB
  2997.         AND     AL,3
  2998.         MOV     DMA_CHANNEL,AL
  2999.         JMP     LCFG1
  3000. GCFG8:  MOV     BX,OFFSET CFG_TEXT6
  3001.         CALL    SEEK_LINE
  3002.         JNC     SHORT GCFG9
  3003.         XOR     BX,BX
  3004.         MOV     CX,5
  3005. LCFG3:  MOV     AX,BX
  3006.         MOV     DX,10
  3007.         MUL     DX
  3008.         MOV     BX,AX
  3009.         LODSB
  3010.         AND     AL,0FH
  3011.         XOR     AH,AH
  3012.         ADD     BX,AX
  3013.         LOOP    LCFG3
  3014.         MOV     SAMPLE_RATE,BX
  3015.         JMP     LCFG1
  3016. GCFG9:  MOV     BX,OFFSET CFG_TEXT7
  3017.         CALL    SEEK_LINE
  3018.         JNC     LCFG1
  3019.         LODSB
  3020.         AND     AL,1
  3021.         MOV     SYSTEM,AL
  3022.         JMP     LCFG1
  3023. GCFG2:  MOV     BX,GDDHANDLE
  3024.         MOV     AH,3EH
  3025.         INT     21H
  3026. GCFG1:  RET
  3027. CONFIG_INIT ENDP
  3028. ;-----------------------------------------------------------------------------
  3029. SEEK_LINE PROC NEAR
  3030.         CLD
  3031.         MOV     SI,OFFSET QUEUE_BUFFER
  3032. LSKL1:  PUSH    BX
  3033. LSKL2:  CMP     BYTE PTR [BX],0
  3034.         JE      SHORT GSKL1
  3035.         CMP     SI,DX
  3036.         JAE     SHORT GSKL2
  3037.         LODSB
  3038.         CMP     AL,[BX]
  3039.         JNE     SHORT GSKL3
  3040.         INC     BX      
  3041.         JMP     LSKL2
  3042. GSKL3:  POP     BX
  3043.         JMP     LSKL1
  3044. GSKL2:  POP     BX
  3045.         CLC
  3046.         RET
  3047. GSKL1:  POP     BX
  3048.         STC
  3049.         RET
  3050. SEEK_LINE ENDP
  3051. ;=============================================================================
  3052.  
  3053.  
  3054. ;=============================================================================
  3055. PLAY_MUSIC PROC NEAR
  3056.         PUSH    CS
  3057.         POP     DS
  3058.         MOV     MOD_STAT,0              ;DEACTIVATE IRQ-HANDLING
  3059.         CALL    DSP_RESET
  3060.         JC      GPM1
  3061.         CALL    MAKE_MIXMUL_VOLUMETABLE
  3062.         CALL    IRQ_INIT
  3063.         XOR     EDX,EDX
  3064.         MOV     EAX,1000000
  3065.         MOVZX   EBX,SAMPLE_RATE
  3066.         MOV     CL,SBPRO_FLAG
  3067.         DIV     EBX
  3068.         SHR     AL,CL
  3069.         NEG     AL
  3070.         MOV     DMA_RATE,AL
  3071.         XOR     EDX,EDX
  3072.         MOV     EAX,369E9400H           ;1,193,180 * 300H FOR FREQ CALCS
  3073.         DIV     EBX
  3074.         MOV     MAINFREQ,EAX
  3075.         MOV     AX,BX
  3076.         MOV     BX,20                   ;AMIGA TIMING IS 50HZ (SCREEN-REFRESH)
  3077.         MUL     BX
  3078.         SHRD    AX,DX,10
  3079.         SHL     AX,CL
  3080.         MOV     DMA_CX,AX               ;# OF BYTE/CYCLE (434 FOR 22222 HZ)
  3081.         SHL     AX,2                    ;4 TIMES FORWARD
  3082.         MOV     DMA_MORE,AX
  3083.         SHL     AX,2                    ;16 TIMES MAXIMUM (6944 FOR 22222 HZ)
  3084.         SHR     AX,CL
  3085.         SUB     AH,CL
  3086.         SUB     AH,CL
  3087.         MOV     DMA_MAX,AX
  3088.         MOV     AX,DMA_OFFSET
  3089.         MOV     DMA_PTR,AX
  3090.         MOV     DMA_NEWPTR,AX
  3091.         MOV     BPM_SPEED,20            ;CLOCK-IRQ IS 1024HZ DIV 20 = 50HZ
  3092.         MOV     BPM_COUNT,1
  3093.         MOV     MT_SPEED,6              ;DEFAULT PROTRACKER SPEED
  3094.         XOR     AX,AX
  3095.         MOV     MT_COUNTER,AL           ;RESET PROTRACKER VARIABLES
  3096.         MOV     MT_PATTERNPOS,AX
  3097.         MOV     MT_SONGPOS,AL
  3098.         MOV     MT_PATTDELAYTIME2,AL
  3099.         MOV     MT_PATTDELAYTIME,AL
  3100.         MOV     MT_PBREAKFLAG,AL
  3101.         MOV     MT_PBREAKPOS,AL
  3102.         MOV     MT_POSJUMPFLAG,AL
  3103.         MOV     MT_LOWMASK,0FFH
  3104.         MOV     CX,43*8/2
  3105.         CLD
  3106.         PUSH    DS
  3107.         POP     ES
  3108.         MOV     DI,OFFSET NOTE
  3109.         REP STOSW
  3110.         INC     AL
  3111.         MOV     CX,MAX_CHAN_NUMB
  3112.         MOV     DI,OFFSET TONEPORTDIREC
  3113.         REP STOSB
  3114.         MOV     BYTE PTR SELFN1+2,2
  3115.         MOV     BYTE PTR SELFN2+2,2
  3116.         TEST    SBPRO_FLAG,1
  3117.         JZ      SHORT GPM2
  3118.         MOV     BYTE PTR SELFN1+2,4
  3119.         MOV     BYTE PTR SELFN2+2,4
  3120. GPM2:   MOV     CX,3                    ;PRECALCULATE SAMPLE DATA FOR INIT
  3121. LPM1:   PUSH    CX
  3122.         CALL    CONTROL_CHANNELS
  3123.         CALL    MIXUP_CHANNELS
  3124.         POP     CX
  3125.         LOOP    LPM1
  3126.         MOV     AH,DMA_RATE             ;SET SB-SAMPLERATE
  3127.         CALL    DSP_RATE
  3128.         MOV     DX,DMA_SEG              ;INITIALIZE DMA
  3129.         MOV     BX,DMA_OFFSET
  3130.         MOV     CX,DMA_MAX
  3131.         CALL    DMA_INIT
  3132.         MOV     MOD_STAT,1              ;ACTIVATE IRQ-HANDLING
  3133.         CLC
  3134. GPM1:   RET
  3135. PLAY_MUSIC ENDP
  3136. ;-----------------------------------------------------------------------------
  3137. STOP_MUSIC PROC NEAR
  3138.         PUSH    CS
  3139.         POP     DS
  3140.         MOV     MOD_STAT,0
  3141.         CALL    DSP_RESET
  3142.         CALL    IRQ_INIT
  3143.         MOV     IRQCOUNT,56
  3144.         RET
  3145. STOP_MUSIC ENDP
  3146. ;-----------------------------------------------------------------------------
  3147. END_MUSIC PROC NEAR
  3148.         PUSH    CS
  3149.         POP     DS
  3150.         CALL    FREE_TMEM
  3151.         CALL    FREE_DMEM
  3152.         RET
  3153. END_MUSIC ENDP
  3154. ;-----------------------------------------------------------------------------
  3155. GET_SONGMOD PROC NEAR
  3156.         MOV     AL,CS:SB_MODUS
  3157.         RET
  3158. GET_SONGMOD ENDP
  3159. ;-----------------------------------------------------------------------------
  3160. SET_SONGMOD PROC NEAR
  3161.         AND     AL,3
  3162.         MOV     CS:SB_MODUS,AL
  3163.         RET
  3164. SET_SONGMOD ENDP
  3165. ;-----------------------------------------------------------------------------
  3166. GET_SONGPOSITION PROC NEAR
  3167.         MOV     AL,CS:MT_SONGPOS
  3168.         RET
  3169. GET_SONGPOSITION ENDP
  3170. ;-----------------------------------------------------------------------------
  3171. SET_SONGPOSITION PROC NEAR
  3172.         AND     AL,7FH
  3173.         MOV     CS:MT_SONGPOS,AL
  3174.         MOV     CS:MT_PATTERNPOS,0
  3175.         RET
  3176. SET_SONGPOSITION ENDP
  3177. ;-----------------------------------------------------------------------------
  3178. SET_SONGLOOP PROC NEAR
  3179.         MOV     CS:SONG_LOOP,AL
  3180.         RET
  3181. SET_SONGLOOP ENDP
  3182. ;-----------------------------------------------------------------------------
  3183. GET_VOLUME PROC NEAR
  3184.         MOV     AL,CS:MASTER_VOLUME     ;0= MIN VOLUME, 255= MAX VOLUME
  3185.         MOV     BL,CS:MUSIC_VOLUME      ;0= MIN VOLUME, 255= MAX VOLUME
  3186.         MOV     BH,CS:FX_VOLUME         ;0= MIN VOLUME, 255= MAX VOLUME
  3187.         RET
  3188. GET_VOLUME ENDP
  3189. ;-----------------------------------------------------------------------------
  3190. SET_VOLUME PROC NEAR
  3191.         MOV     CS:MASTER_VOLUME,AL     ;0= MIN VOLUME, 255= MAX VOLUME
  3192.         MOV     CS:MUSIC_VOLUME,BL      ;0= MIN VOLUME, 255= MAX VOLUME
  3193.         MOV     CS:FX_VOLUME,BH         ;0= MIN VOLUME, 255= MAX VOLUME
  3194.         PUSH    AX DX
  3195.         MOVZX   DX,AL
  3196.         INC     DX
  3197.         PUSH    DX
  3198.         MOVZX   AX,BL
  3199.         MUL     DX
  3200.         MOV     CS:MUSIC_VOL,AH
  3201.         POP     DX
  3202.         MOVZX   AX,BH
  3203.         MUL     DX
  3204.         MOV     CS:FX_VOL,AH
  3205.         POP     DX AX
  3206.         RET
  3207. SET_VOLUME ENDP
  3208. ;-----------------------------------------------------------------------------
  3209. SET_SAMPLERATE PROC NEAR
  3210.         CMP     AX,10000
  3211.         JAE     SHORT GSSR1
  3212.         MOV     AX,10000
  3213. GSSR1:  CMP     AX,22222
  3214.         JBE     SHORT GSSR2
  3215.         MOV     AX,22222
  3216. GSSR2:  MOV     CS:SAMPLE_RATE,AX       ;BEST BETWEEN 10000 - 22222 Hz
  3217.         RET
  3218. SET_SAMPLERATE ENDP
  3219. ;-----------------------------------------------------------------------------
  3220. ; START FX SAMPLE
  3221. ; BX= SAMPLE-HANDLE, CX= SAMPLERATE
  3222. ;-----------------------------------------------------------------------------
  3223. PLAY_SAMPLE PROC NEAR
  3224.         PUSH    CS
  3225.         POP     DS
  3226.         TEST    SB_MODUS,1
  3227.         JNZ     GPSMP1
  3228.         CMP     EMS_SEG,0
  3229.         JE      GPSMP1
  3230.         MOVZX   EAX,CX 
  3231.         SHL     EAX,8
  3232.         MOVZX   ECX,SAMPLE_RATE
  3233.         XOR     EDX,EDX
  3234.         DIV     ECX
  3235.         OR      AX,AX
  3236.         JZ      SHORT GPSMP1
  3237.         CMP     SBPRO_FLAG,1
  3238.         JNE     SHORT GPSMP2
  3239.         XOR     SAM_FLAG,1
  3240.         TEST    SAM_FLAG,1
  3241.         JZ      SHORT GPSMP3
  3242.         CMP     SAM_SEG1,0
  3243.         JE      SHORT GPSMP2
  3244.         CMP     SAM_SEG2,0
  3245.         JNE     SHORT GPSMP2
  3246. GPSMP4: CLI                             ;RIGHT CHANNEL SAMPLE
  3247.         MOV     SAM_FRQ2,AX
  3248.         MOV     AX,EMS_SEG
  3249.         MOV     SAM_SEG2,AX
  3250.         MOVZX   EAX,[SAMPLE_MEM+BX]
  3251.         SHL     EAX,4
  3252.         MOV     SAM_OFS2,EAX
  3253.         MOV     AX,[SAMPLE_BIG+BX]
  3254.         MOV     SAM_MAX2,AX
  3255.         MOV     SAM_OFL2,0
  3256.         STI
  3257.         RET
  3258. GPSMP3: CMP     SAM_SEG2,0
  3259.         JE      GPSMP4
  3260.         CMP     SAM_SEG1,0
  3261.         JNE     GPSMP4
  3262. GPSMP2: CLI                             ;LEFT CHANNEL SAMPLE
  3263.         MOV     SAM_FRQ1,AX
  3264.         MOV     AX,EMS_SEG
  3265.         MOV     SAM_SEG1,AX
  3266.         MOVZX   EAX,[SAMPLE_MEM+BX]
  3267.         SHL     EAX,4
  3268.         MOV     SAM_OFS1,EAX
  3269.         MOV     AX,[SAMPLE_BIG+BX]
  3270.         MOV     SAM_MAX1,AX
  3271.         MOV     SAM_OFL1,0
  3272.         STI
  3273. GPSMP1: RET
  3274. PLAY_SAMPLE ENDP
  3275. ;-----------------------------------------------------------------------------
  3276. END_SAMPLE PROC NEAR
  3277.         PUSH    CS
  3278.         POP     DS
  3279.         MOV     SAM_SEG1,0
  3280.         MOV     SAM_SEG2,0
  3281.         CMP     EMS_SEG,0
  3282.         JE      SHORT GEMP1
  3283.         MOV     AH,45H
  3284.         MOV     DX,EMS_HANDLE
  3285.         INT     67H
  3286.         MOV     EMS_SEG,0
  3287. GEMP1:  RET
  3288. END_SAMPLE ENDP
  3289. ;=============================================================================
  3290.  
  3291.  
  3292. ;=============================================================================
  3293. ;
  3294. ; MAIN ROUTINE
  3295. ;
  3296. ;=============================================================================
  3297. MAIN_CONT PROC NEAR
  3298.         MOV     AX,CS                   ;DS SET
  3299.         MOV     DS,AX
  3300.         MOV     PROG_START_SEG,ES       ;PROGRAMM START
  3301.         MOV     AX,SS                   ;AND -END SET
  3302.         MOV     BX,OFFSET PROG_END
  3303.         ADD     BX,STACKLENGTH
  3304.         MOV     SP,BX
  3305.         SHR     BX,4
  3306.         INC     BX
  3307.         ADD     AX,BX
  3308.         MOV     PROG_END_SEG,AX
  3309.         XOR     BX,BX
  3310. GL1:    MOV     AL,ES:[82H+BX]
  3311.         OR      AL,AL
  3312.         JZ      SHORT GL2
  3313.         CMP     AL,20H
  3314.         JE      SHORT GL2
  3315.         CMP     AL,0DH
  3316.         JE      SHORT GL2
  3317.         MOV     [MOD_NAME+BX],AL
  3318.         INC     BX
  3319.         CMP     BX,40H
  3320.         JB      GL1
  3321. GL2:    OR      BX,BX
  3322.         JZ      GMEND
  3323.         XOR     AL,AL
  3324.         MOV     [MOD_NAME+BX],0
  3325.         CALL    FREE_MEM
  3326. ;-----------------------------------------------------------------------------
  3327. ; INITIALIZING & STARTING
  3328. ;       MOV     AX,22222                ;SET MAXIMUM SAMPLERATE
  3329. ;       CALL    SET_SAMPLERATE
  3330. ;       MOV     AL,255                  ;SET MAXIMUM VOLUME
  3331. ;       MOV     BL,AL
  3332. ;       MOV     BH,AL
  3333. ;       CALL    SET_VOLUME
  3334.         CALL    CONFIG_INIT             ;GET CONFIG
  3335.         MOV     DX,OFFSET MOD_NAME      ;FIRST, TRY LOADING
  3336.         CALL    LOAD_MOD
  3337.         JNC     SHORT GM1
  3338.         MOV     AH,9
  3339.         MOV     DX,OFFSET ERROR1_TEXT
  3340.         INT     21H
  3341.         JMP     SHORT GM4
  3342. GM1:    MOV     DX,OFFSET SAMPLE_NAME   ;GET SAMPLE
  3343.         MOV     CL,80H                  ;PC-SAMPLE
  3344.         CALL    LOAD_SAMPLE
  3345.         JNC     SHORT GM2
  3346.         MOV     AH,9
  3347.         MOV     DX,OFFSET ERROR2_TEXT
  3348.         INT     21H
  3349. GM2:    CALL    PLAY_MUSIC              ;TRY STARTING
  3350.         JNC     SHORT GM3
  3351.         MOV     AH,9
  3352.         MOV     DX,OFFSET ERROR3_TEXT
  3353.         INT     21H
  3354.         JMP     SHORT GM4
  3355. ;-----------------------------------------------------------------------------
  3356. ; THIS COULD BE THE MAIN ROUTINE
  3357. GM3:    MOV     AH,9
  3358.         MOV     DX,OFFSET OUT_TEXT
  3359.         INT     21H
  3360. LM1:    XOR     AH,AH
  3361.         INT     16H
  3362.         CMP     AL,27
  3363.         JE      SHORT GM5
  3364.         CMP     AL,"+"
  3365.         JNE     SHORT G1
  3366.         CALL    GET_VOLUME
  3367.         INC     AL
  3368.         CALL    SET_VOLUME
  3369.         JMP     LM1
  3370. G1:     CMP     AL,"-"
  3371.         JNE     SHORT G2
  3372.         CALL    GET_VOLUME
  3373.         DEC     AL
  3374.         CALL    SET_VOLUME
  3375.         JMP     LM1
  3376. G2:     CMP     AL,"9"
  3377.         JNE     SHORT G3
  3378.         MOV     AL,0
  3379.         CALL    SET_SONGLOOP
  3380.         JMP     LM1
  3381. G3:     CMP     AL,"0"
  3382.         JNE     SHORT G4
  3383.         INC     SB_MODUS
  3384.         AND     SB_MODUS,3
  3385.         JMP     LM1
  3386. G4:     CMP     AL,"1"
  3387.         JNE     LM1
  3388.         XOR     BX,BX                   ;HANDLE
  3389.         MOV     CX,22222                ;FREQUENCE
  3390.         CALL    PLAY_SAMPLE
  3391.         JMP     LM1
  3392. ;-----------------------------------------------------------------------------
  3393. ; CUTTING OFF
  3394. GM5:    CALL    STOP_MUSIC              ;STOP MUSIC
  3395. GM4:    CALL    END_SAMPLE              ;UNLOAD SAMPLES
  3396.         CALL    END_MUSIC               ;UNLOAD MUSIC
  3397. GMEND:  MOV     AX,4C00H                ;DOS
  3398.         INT     21H
  3399. MAIN_CONT ENDP
  3400. ;=============================================================================
  3401.  
  3402. END MAIN