dosgus.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:49k
源码类别:

Windows CE

开发平台:

C/C++

  1. /* MikMod sound library
  2. (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
  3. complete list.
  4. This library is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Library General Public License as
  6. published by the Free Software Foundation; either version 2 of
  7. the License, or (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11. GNU Library General Public License for more details.
  12. You should have received a copy of the GNU Library General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  15. 02111-1307, USA.
  16. */
  17. /*==============================================================================
  18.   $Id: dosgus.c,v 1.1 2004/02/01 02:01:17 raph Exp $
  19.   
  20.   Driver for GUS cards under DOS
  21. ==============================================================================*/
  22. /*
  23. Written by Andrew Zabolotny <bit@eltech.ru>
  24. */
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <dos.h>
  28. #include <dpmi.h>
  29. #include <sys/farptr.h>
  30. #include <sys/nearptr.h>
  31. #include <go32.h>
  32. #include <string.h>
  33. #include "dosgus.h"
  34. /********************************************* Private variables/routines *****/
  35. /* The Gravis Ultrasound state/info */
  36. __gus_state gus;
  37. /* Try to avoid holes in DRAM less than this size */
  38. #define DRAM_HOLE_THRESHOLD 8192
  39. /* If hole is larger than that, create a free block describing it */
  40. #define DRAM_SPLIT_THRESHOLD 64
  41. /* The size of DMA buffer used for RAM->DRAM transfers */
  42. #define GF1_DMA_BUFFER_SIZE 8192
  43. /* Debug macro: useful to change screen locations when some event occurs */
  44. #ifdef MIKMOD_DEBUG
  45. #  define DEBUG_PRINT(x) printf x;
  46. #  define DEBUG_OFS(addr, attr)
  47.    {
  48.      unsigned short x;
  49.      _dosmemgetw (0xb8780 + addr*2, 1, &x);
  50.      if ((x >> 8) != attr) x = '0';
  51.      x = ((x + 1) & 0xff) | (attr << 8);
  52.      _dosmemputw (&x, 1, 0xb8780 + addr*2);
  53.    }
  54. #else
  55. #  define DEBUG_PRINT(x)
  56. #  define DEBUG_OFS(addr, attr)
  57. #endif
  58. static unsigned short __gus_volume_table[512] = {
  59. 0x0000, 0x7000, 0x7ff0, 0x8800, 0x8ff0, 0x9400, 0x9800, 0x9c00,
  60. 0x9ff0, 0xa200, 0xa400, 0xa600, 0xa800, 0xaa00, 0xac00, 0xae00,
  61. 0xaff0, 0xb100, 0xb200, 0xb300, 0xb400, 0xb500, 0xb600, 0xb700,
  62. 0xb800, 0xb900, 0xba00, 0xbb00, 0xbc00, 0xbd00, 0xbe00, 0xbf00,
  63. 0xbff0, 0xc080, 0xc100, 0xc180, 0xc200, 0xc280, 0xc300, 0xc380,
  64. 0xc400, 0xc480, 0xc500, 0xc580, 0xc600, 0xc680, 0xc700, 0xc780,
  65. 0xc800, 0xc880, 0xc900, 0xc980, 0xca00, 0xca80, 0xcb00, 0xcb80,
  66. 0xcc00, 0xcc80, 0xcd00, 0xcd80, 0xce00, 0xce80, 0xcf00, 0xcf80,
  67. 0xcff0, 0xd040, 0xd080, 0xd0c0, 0xd100, 0xd140, 0xd180, 0xd1c0,
  68. 0xd200, 0xd240, 0xd280, 0xd2c0, 0xd300, 0xd340, 0xd380, 0xd3c0,
  69. 0xd400, 0xd440, 0xd480, 0xd4c0, 0xd500, 0xd540, 0xd580, 0xd5c0,
  70. 0xd600, 0xd640, 0xd680, 0xd6c0, 0xd700, 0xd740, 0xd780, 0xd7c0,
  71. 0xd800, 0xd840, 0xd880, 0xd8c0, 0xd900, 0xd940, 0xd980, 0xd9c0,
  72. 0xda00, 0xda40, 0xda80, 0xdac0, 0xdb00, 0xdb40, 0xdb80, 0xdbc0,
  73. 0xdc00, 0xdc40, 0xdc80, 0xdcc0, 0xdd00, 0xdd40, 0xdd80, 0xddc0,
  74. 0xde00, 0xde40, 0xde80, 0xdec0, 0xdf00, 0xdf40, 0xdf80, 0xdfc0,
  75. 0xdff0, 0xe020, 0xe040, 0xe060, 0xe080, 0xe0a0, 0xe0c0, 0xe0e0,
  76. 0xe100, 0xe120, 0xe140, 0xe160, 0xe180, 0xe1a0, 0xe1c0, 0xe1e0,
  77. 0xe200, 0xe220, 0xe240, 0xe260, 0xe280, 0xe2a0, 0xe2c0, 0xe2e0,
  78. 0xe300, 0xe320, 0xe340, 0xe360, 0xe380, 0xe3a0, 0xe3c0, 0xe3e0,
  79. 0xe400, 0xe420, 0xe440, 0xe460, 0xe480, 0xe4a0, 0xe4c0, 0xe4e0,
  80. 0xe500, 0xe520, 0xe540, 0xe560, 0xe580, 0xe5a0, 0xe5c0, 0xe5e0,
  81. 0xe600, 0xe620, 0xe640, 0xe660, 0xe680, 0xe6a0, 0xe6c0, 0xe6e0,
  82. 0xe700, 0xe720, 0xe740, 0xe760, 0xe780, 0xe7a0, 0xe7c0, 0xe7e0,
  83. 0xe800, 0xe820, 0xe840, 0xe860, 0xe880, 0xe8a0, 0xe8c0, 0xe8e0,
  84. 0xe900, 0xe920, 0xe940, 0xe960, 0xe980, 0xe9a0, 0xe9c0, 0xe9e0,
  85. 0xea00, 0xea20, 0xea40, 0xea60, 0xea80, 0xeaa0, 0xeac0, 0xeae0,
  86. 0xeb00, 0xeb20, 0xeb40, 0xeb60, 0xeb80, 0xeba0, 0xebc0, 0xebe0,
  87. 0xec00, 0xec20, 0xec40, 0xec60, 0xec80, 0xeca0, 0xecc0, 0xece0,
  88. 0xed00, 0xed20, 0xed40, 0xed60, 0xed80, 0xeda0, 0xedc0, 0xede0,
  89. 0xee00, 0xee20, 0xee40, 0xee60, 0xee80, 0xeea0, 0xeec0, 0xeee0,
  90. 0xef00, 0xef20, 0xef40, 0xef60, 0xef80, 0xefa0, 0xefc0, 0xefe0,
  91. 0xeff0, 0xf010, 0xf020, 0xf030, 0xf040, 0xf050, 0xf060, 0xf070,
  92. 0xf080, 0xf090, 0xf0a0, 0xf0b0, 0xf0c0, 0xf0d0, 0xf0e0, 0xf0f0,
  93. 0xf100, 0xf110, 0xf120, 0xf130, 0xf140, 0xf150, 0xf160, 0xf170,
  94. 0xf180, 0xf190, 0xf1a0, 0xf1b0, 0xf1c0, 0xf1d0, 0xf1e0, 0xf1f0,
  95. 0xf200, 0xf210, 0xf220, 0xf230, 0xf240, 0xf250, 0xf260, 0xf270,
  96. 0xf280, 0xf290, 0xf2a0, 0xf2b0, 0xf2c0, 0xf2d0, 0xf2e0, 0xf2f0,
  97. 0xf300, 0xf310, 0xf320, 0xf330, 0xf340, 0xf350, 0xf360, 0xf370,
  98. 0xf380, 0xf390, 0xf3a0, 0xf3b0, 0xf3c0, 0xf3d0, 0xf3e0, 0xf3f0,
  99. 0xf400, 0xf410, 0xf420, 0xf430, 0xf440, 0xf450, 0xf460, 0xf470,
  100. 0xf480, 0xf490, 0xf4a0, 0xf4b0, 0xf4c0, 0xf4d0, 0xf4e0, 0xf4f0,
  101. 0xf500, 0xf510, 0xf520, 0xf530, 0xf540, 0xf550, 0xf560, 0xf570,
  102. 0xf580, 0xf590, 0xf5a0, 0xf5b0, 0xf5c0, 0xf5d0, 0xf5e0, 0xf5f0,
  103. 0xf600, 0xf610, 0xf620, 0xf630, 0xf640, 0xf650, 0xf660, 0xf670,
  104. 0xf680, 0xf690, 0xf6a0, 0xf6b0, 0xf6c0, 0xf6d0, 0xf6e0, 0xf6f0,
  105. 0xf700, 0xf710, 0xf720, 0xf730, 0xf740, 0xf750, 0xf760, 0xf770,
  106. 0xf780, 0xf790, 0xf7a0, 0xf7b0, 0xf7c0, 0xf7d0, 0xf7e0, 0xf7f0,
  107. 0xf800, 0xf810, 0xf820, 0xf830, 0xf840, 0xf850, 0xf860, 0xf870,
  108. 0xf880, 0xf890, 0xf8a0, 0xf8b0, 0xf8c0, 0xf8d0, 0xf8e0, 0xf8f0,
  109. 0xf900, 0xf910, 0xf920, 0xf930, 0xf940, 0xf950, 0xf960, 0xf970,
  110. 0xf980, 0xf990, 0xf9a0, 0xf9b0, 0xf9c0, 0xf9d0, 0xf9e0, 0xf9f0,
  111. 0xfa00, 0xfa10, 0xfa20, 0xfa30, 0xfa40, 0xfa50, 0xfa60, 0xfa70,
  112. 0xfa80, 0xfa90, 0xfaa0, 0xfab0, 0xfac0, 0xfad0, 0xfae0, 0xfaf0,
  113. 0xfb00, 0xfb10, 0xfb20, 0xfb30, 0xfb40, 0xfb50, 0xfb60, 0xfb70,
  114. 0xfb80, 0xfb90, 0xfba0, 0xfbb0, 0xfbc0, 0xfbd0, 0xfbe0, 0xfbf0,
  115. 0xfc00, 0xfc10, 0xfc20, 0xfc30, 0xfc40, 0xfc50, 0xfc60, 0xfc70,
  116. 0xfc80, 0xfc90, 0xfca0, 0xfcb0, 0xfcc0, 0xfcd0, 0xfce0, 0xfcf0,
  117. 0xfd00, 0xfd10, 0xfd20, 0xfd30, 0xfd40, 0xfd50, 0xfd60, 0xfd70,
  118. 0xfd80, 0xfd90, 0xfda0, 0xfdb0, 0xfdc0, 0xfdd0, 0xfde0, 0xfdf0,
  119. 0xfe00, 0xfe10, 0xfe20, 0xfe30, 0xfe40, 0xfe50, 0xfe60, 0xfe70,
  120. 0xfe80, 0xfe90, 0xfea0, 0xfeb0, 0xfec0, 0xfed0, 0xfee0, 0xfef0,
  121. 0xff00, 0xff10, 0xff20, 0xff30, 0xff40, 0xff50, 0xff60, 0xff70,
  122. 0xff80, 0xff90, 0xffa0, 0xffb0, 0xffc0, 0xffd0, 0xffe0, 0xfff0
  123. };
  124. /* Wait a bit for GUS before doing something
  125.  * Mark function as volatile: don't allow it to be inlined.
  126.  * It *should* be slow, no need to make it work faster :-)
  127.  */
  128. volatile void __gus_delay()
  129. {
  130. inportb(GF1_MIX_CTRL);
  131. inportb(GF1_MIX_CTRL);
  132. inportb(GF1_MIX_CTRL);
  133. inportb(GF1_MIX_CTRL);
  134. inportb(GF1_MIX_CTRL);
  135. inportb(GF1_MIX_CTRL);
  136. inportb(GF1_MIX_CTRL);
  137. inportb(GF1_MIX_CTRL);
  138. }
  139. static void __gus_stop_controller(unsigned char gf1reg)
  140. {
  141. register unsigned char value = __gus_inregb(gf1reg);
  142. __gus_outregb(gf1reg, (value | GF1VC_STOPPED | GF1VC_STOP) &
  143.                       ~(GF1VC_IRQ_PENDING | GF1VC_IRQ));
  144. }
  145. /* Returns 1 if volume is already at given position */
  146. static boolean __gus_volume_ramp_to(unsigned short volume,
  147.                                     unsigned char rate,
  148.                                     unsigned char vol_ctrl)
  149. {
  150. int svol = __gus_inregw(GF1R_VOLUME) & 0xfff0;
  151. int evol = volume;
  152. /* First of all, disable volume ramp */
  153. __gus_stop_controller(GF1R_VOLUME_CONTROL);
  154. /* If voice is stopped, set the volume to zero and return */
  155. if (__gus_inregb(GF1R_VOICE_CONTROL) & GF1VC_STOPPED) {
  156. __gus_outregw(GF1R_VOLUME, 0);
  157. return 1;
  158. }
  159. /* Avoid clicks when volume ramp goes too high or too low */
  160. if (svol < 0x0400)
  161. svol = 0x0400;
  162. if (svol > 0xfc00)
  163. svol = 0xfc00;
  164. if (evol < 0x0400)
  165. evol = 0x0400;
  166. if (evol > 0xfc00)
  167. evol = 0xfc00;
  168. /* Adjust start/end positions */
  169. if (svol > evol) {
  170. unsigned short tmp = evol;
  171. evol = svol;
  172. svol = tmp;
  173. vol_ctrl |= GF1VL_BACKWARD;
  174. }
  175. /* If we already are (near) the target volume, quit */
  176. if (evol - svol < 0x1000) {
  177. __gus_outregw(GF1R_VOLUME, volume);
  178. return 1;
  179. }
  180. __gus_outregb(GF1R_VOLUME_START, svol >> 8);
  181. __gus_outregb(GF1R_VOLUME_END, evol >> 8);
  182. __gus_outregb(GF1R_VOLUME_RATE, rate);
  183. __gus_outregb_slow(GF1R_VOLUME_CONTROL, vol_ctrl);
  184. return 0;
  185. }
  186. static inline void __gus_stop_voice()
  187. {
  188. __gus_stop_controller(GF1R_VOICE_CONTROL);
  189. __gus_outregb_slow(GF1R_VOICE_CONTROL, GF1VC_STOPPED | GF1VC_STOP);
  190. }
  191. /* The GUS IRQ handler */
  192. static void gf1_irq()
  193. {
  194. unsigned char irq_source; /* The contents of GF1_IRQ_STATUS register */
  195. boolean timer_cb = 0; /* Call timer callback function */
  196. DEBUG_OFS(0, 0xCE)
  197. gus.eow_ignore = 0;
  198. while ((irq_source = inportb(GF1_IRQ_STATUS))) {
  199. DEBUG_OFS(1, 0xCE)
  200.   if (irq_source & GF1M_IRQ_DMA_COMPLETE) {
  201. DEBUG_OFS(4, 0x9F)
  202.   /* reset the IRQ pending bit */
  203.   __gus_inregb(GF1R_DMA_CONTROL);
  204. gus.dma_active = 0;
  205. if (gus.dma_callback)
  206. gus.dma_callback();
  207. }
  208. if (irq_source & (GF1M_IRQ_WAVETABLE | GF1M_IRQ_ENVELOPE)) {
  209. unsigned char vcirq;
  210. unsigned int done_mask = 0;
  211. /* IRQ bits are inverse (i.e. 0 = IRQ pending) */
  212. while ((vcirq = __gus_inregb(GF1R_IRQ_SOURCE) ^
  213.                                (GF1IRQ_WAVE | GF1IRQ_VOLUME)) &
  214.                                (GF1IRQ_WAVE | GF1IRQ_VOLUME)) {
  215. unsigned long voice = (vcirq & 0x1f);
  216. unsigned char voice_ctl, volume_ctl;
  217. unsigned int voice_mask = (1 << voice);
  218. /* Don't handle more than one IRQ from same voice */
  219. if (done_mask & voice_mask)
  220. continue;
  221. done_mask |= voice_mask;
  222. /* Read voice/volume selection registers */
  223. __gus_select_voice(voice);
  224. voice_ctl = __gus_inregb(GF1R_VOICE_CONTROL);
  225. volume_ctl = __gus_inregb(GF1R_VOLUME_CONTROL);
  226. if ((vcirq & GF1IRQ_WAVE) && (gus.wt_callback)
  227. && !(gus.eow_ignore & voice_mask)) {
  228. DEBUG_OFS(5, 0xAF)
  229. gus.wt_callback(voice, voice_ctl, volume_ctl);
  230. }
  231. if ((vcirq & GF1IRQ_VOLUME) && (gus.vl_callback)) {
  232. DEBUG_OFS(6, 0xAF)
  233. gus.vl_callback(voice, voice_ctl, volume_ctl);
  234. }
  235. }
  236. }
  237. /* Reset timers that sent this IRQ */
  238. if (irq_source & (GF1M_IRQ_TIMER1 | GF1M_IRQ_TIMER2)) {
  239. unsigned char timer_ctl = gus.timer_ctl_reg;
  240. if (irq_source & GF1M_IRQ_TIMER1)
  241. timer_ctl &= ~GF1M_TIMER1;
  242. if (irq_source & GF1M_IRQ_TIMER2)
  243. timer_ctl &= ~GF1M_TIMER2;
  244. __gus_outregb_slow(GF1R_TIMER_CONTROL, timer_ctl);
  245. __gus_outregb_slow(GF1R_TIMER_CONTROL, gus.timer_ctl_reg);
  246. }
  247. if (irq_source & GF1M_IRQ_TIMER1)
  248. if (--gus.t1_countdown == 0) {
  249. gus.t1_countdown = gus.t1_multiple;
  250. gus.t1_ticks++;
  251. DEBUG_OFS(2, 0xCF)
  252. if (gus.t1_callback) {
  253. timer_cb = 1;
  254. gus.t1_callback();
  255. }
  256. }
  257. if (irq_source & GF1M_IRQ_TIMER2)
  258. if (--gus.t2_countdown == 0) {
  259. gus.t2_countdown = gus.t2_multiple;
  260. gus.t2_ticks++;
  261. DEBUG_OFS(3, 0xCF)
  262. if (gus.t2_callback)
  263. gus.t2_callback();
  264. }
  265. #if 0
  266. /* The following are not used and implemented yet */
  267. if (irq_source & (GF1M_IRQ_MIDI_TX | GF1M_IRQ_MIDI_RX)) {
  268. }
  269. #endif
  270. }
  271. irq_ack(gus.gf1_irq);
  272. if (timer_cb && gus.timer_callback)
  273. gus.timer_callback();
  274. }
  275. static void gf1_irq_end()
  276. {
  277. }
  278. static boolean __gus_detect()
  279. {
  280. /* A relatively relaxed autodetection;
  281.    We don't count on DRAM: GUS PnP could not have it
  282.    (although its anyway bad for us)
  283.  */
  284. __gus_select_voice(0);
  285. __gus_stop_voice();
  286. __gus_outregw(GF1R_FREQUENCY, 0x1234);
  287. __gus_outregw(GF1R_VOLUME, 0x5670);
  288. return ((__gus_inregw(GF1R_FREQUENCY) & 0xfffe) == 0x1234)
  289.   && ((__gus_inregw(GF1R_VOLUME) & 0xfff0) == 0x5670);
  290. }
  291. static void __gus_reset(boolean reset_io_dma)
  292. {
  293. static unsigned char irqctl[16] = { 0, 0, 1, 3, 0, 2, 0, 4, 0, 0, 0, 5, 6, 0, 0, 7 };
  294. static unsigned char dmactl[8] = { 0, 1, 0, 2, 0, 3, 4, 5 };
  295. unsigned char irqtmp, dmatmp;
  296. /* Disable interrupts while resetting to avoid spurious IRQs */
  297. int i, timer, old_ints = disable();
  298. /* Stop the timer so that GUS IRQ won't clobber registers */
  299. timer = (gus.timer_ctl_reg & GF1M_TIMER1);
  300. if (timer)
  301. gus_timer_stop();
  302. gus.dma_active = 0;
  303. __gus_outregb(GF1R_RESET, 0);
  304. for (i = 0; i < 10; i++)
  305. __gus_delay();
  306. __gus_outregb(GF1R_RESET, GF1M_MASTER_RESET);
  307. for (i = 0; i < 10; i++)
  308. __gus_delay();
  309. outportb(GF1_MIDI_CTRL, GF1M_MIDI_RESET);
  310. for (i = 0; i < 10; i++)
  311. __gus_delay();
  312. outportb(GF1_MIDI_CTRL, 0);
  313. /* Reset all IRQ sources */
  314. __gus_outregb(GF1R_DMA_CONTROL, 0);
  315. __gus_outregb(GF1R_TIMER_CONTROL, 0);
  316. __gus_outregb(GF1R_SAMPLE_CONTROL, 0);
  317. /* Reset all voices */
  318. gus_reset(gus.voices, gus.dynmask);
  319. /* Flush any pending IRQs */
  320. inportb(GF1_IRQ_STATUS);
  321. __gus_inregb(GF1R_DMA_CONTROL);
  322. __gus_inregb(GF1R_SAMPLE_CONTROL);
  323. __gus_inregb(GF1R_IRQ_SOURCE);
  324. if (reset_io_dma) {
  325. /* Now set up the GUS card to required IRQs and DMAs */
  326. if (gus.irq[0] == gus.irq[1])
  327. irqtmp = irqctl[gus.irq[0]] | GF1M_IRQ_EQUAL;
  328. else
  329. irqtmp = irqctl[gus.irq[0]] | (irqctl[gus.irq[1]] << 3);
  330. if (gus.dma[0] == gus.dma[1])
  331. dmatmp = dmactl[gus.dma[0]] | GF1M_DMA_EQUAL;
  332. else
  333. dmatmp = dmactl[gus.dma[0]] | (dmactl[gus.dma[1]] << 3);
  334. /* Reset IRQs if possible */
  335. gus.mixer =
  336.   GF1M_MIXER_NO_LINE_IN | GF1M_MIXER_NO_OUTPUT | GF1M_MIXER_GF1_IRQ;
  337. if (gus.version >= GUS_CARD_VERSION_CLASSIC1) {
  338. outportb(GF1_REG_CTRL, 0x05);
  339. outportb(GF1_MIX_CTRL, gus.mixer);
  340. outportb(GF1_IRQ_CTRL, 0x00); /* Reset IRQs */
  341. outportb(GF1_REG_CTRL, 0x00);
  342. }
  343. /* Set up DMA channels: NEVER disable MIXER_GF1_IRQ in the future */
  344. outportb(GF1_MIX_CTRL, gus.mixer);
  345. outportb(GF1_IRQ_CTRL, dmatmp);
  346. /* Set up IRQ channels */
  347. outportb(GF1_MIX_CTRL, gus.mixer | GF1M_CONTROL_SELECT);
  348. outportb(GF1_IRQ_CTRL, irqtmp);
  349. }
  350. __gus_outregb(GF1R_RESET, GF1M_MASTER_RESET | GF1M_OUTPUT_ENABLE | GF1M_MASTER_IRQ);
  351. __gus_delay();
  352. /* Flush IRQs again */
  353. inportb(GF1_IRQ_STATUS);
  354. __gus_inregb(GF1R_DMA_CONTROL);
  355. __gus_inregb(GF1R_SAMPLE_CONTROL);
  356. __gus_inregb(GF1R_IRQ_SOURCE);
  357. _irq_ack(gus.irq[0]);
  358. _irq_ack(gus.irq[1]);
  359. if (timer)
  360. gus_timer_continue();
  361. if (old_ints)
  362. enable();
  363. /* Enable output */
  364. __gus_mixer_output(1);
  365. }
  366. /* Transfer a block of data from GUS DRAM to main RAM through port I/O */
  367. static void __gus_transfer_io_in(unsigned long address, unsigned char *source,
  368.                                  unsigned long size)
  369. {
  370. while (size) {
  371. register unsigned int size64k;
  372. size64k = 0x10000 - (address & 0xffff);
  373. if (size64k > size)
  374. size64k = size;
  375. size -= size64k;
  376. __gus_outregb(GF1R_DRAM_HIGH, address >> 16);
  377. while (size64k--) {
  378. __gus_outregw(GF1R_DRAM_LOW, address++);
  379. *source++ = inportb(GF1_DRAM);
  380. }
  381. }
  382. }
  383. /* Transfer a block of data into GUS DRAM through port I/O */
  384. static void __gus_transfer_io(unsigned long address, unsigned char *source,
  385.                               unsigned long size, int flags)
  386. {
  387. while (size) {
  388. register unsigned int size64k;
  389. size64k = 0x10000 - (address & 0xffff);
  390. if (size64k > size)
  391. size64k = size;
  392. size -= size64k;
  393. __gus_outregb(GF1R_DRAM_HIGH, address >> 16);
  394. if (flags & GUS_WAVE_INVERT)
  395. if (flags & GUS_WAVE_16BIT)
  396. while (size64k-- && size64k--) {
  397. __gus_outregw(GF1R_DRAM_LOW, address++);
  398. outportb(GF1_DRAM, *source++);
  399. __gus_outregw(GF1R_DRAM_LOW, address++);
  400. outportb(GF1_DRAM, (*source++) ^ 0x80);
  401. } else
  402. while (size64k--) {
  403. __gus_outregw(GF1R_DRAM_LOW, address++);
  404. outportb(GF1_DRAM, (*source++) ^ 0x80);
  405. } else
  406. while (size64k--) {
  407. __gus_outregw(GF1R_DRAM_LOW, address++);
  408. outportb(GF1_DRAM, *source++);
  409. }
  410. }
  411. }
  412. /* Wait for DMA transfer to finish between 8-9 1/18sec timer ticks */
  413. static int __gus_wait_dma()
  414. {
  415. unsigned long timer;
  416. _farsetsel(_dos_ds);
  417. timer = _farnspeekl(0x46c);
  418. while (gus.dma_active)
  419. if (_farnspeekl(0x46c) - timer > 8) {
  420. /* Force DMA abort since something went wrong */
  421. __gus_reset(0);
  422. return -1;
  423. }
  424. return 0;
  425. }
  426. /* Transfer a block of data into GUS DRAM through DMA controller */
  427. static void __gus_transfer_dma(unsigned long address, unsigned char *source,
  428.                                unsigned long size, int flags)
  429. {
  430. unsigned char dma_control;
  431. unsigned long bytes_left;
  432. unsigned long cur_size;
  433. unsigned long dest_addr;
  434. if ((gus.dma[0] > 3) || (flags & GUS_WAVE_16BIT))
  435. size = (size + 1) & ~1;
  436. bytes_left = size;
  437. while (bytes_left) {
  438. __gus_wait_dma();
  439. cur_size = gus.dma_buff->size;
  440. if (cur_size > bytes_left)
  441. cur_size = bytes_left;
  442. bytes_left -= cur_size;
  443. dest_addr = address;
  444. if (gus.dma_buff->linear != source)
  445. memmove(gus.dma_buff->linear, source, cur_size);
  446. source += cur_size;
  447. address += cur_size;
  448. /* Disable GUS -> DMA tie */
  449. __gus_outregb(GF1R_DMA_CONTROL, 0);
  450. __gus_delay();
  451. /* Set up the DMA */
  452. dma_start(gus.dma_buff, cur_size, DMA_MODE_WRITE);
  453. gus.dma_active = 1;
  454. /* Reset the DMA IRQ pending bit if set */
  455. __gus_inregb(GF1R_DMA_CONTROL);
  456. /* The 16-bit DMA channels needs a slightly different approach */
  457. dma_control = GF1M_DMAR_ENABLE | GF1M_DMAR_IRQ_ENABLE | gus.dma_rate;
  458. if (gus.dma[0] > 3) {
  459. dest_addr = __gus_convert_addr16(dest_addr);
  460. dma_control |= GF1M_DMAR_CHAN16;
  461. }
  462. __gus_outregw(GF1R_DMA_ADDRESS, dest_addr >> 4);
  463. if (flags & GUS_WAVE_16BIT)
  464. dma_control |= GF1M_DMAR_DATA16;
  465. if (flags & GUS_WAVE_INVERT)
  466. dma_control |= GF1M_DMAR_TOGGLE_SIGN;
  467. /* Tell GUS to start transfer */
  468. __gus_outregb(GF1R_DMA_CONTROL, dma_control);
  469. }
  470. }
  471. static void __gus_detect_version()
  472. {
  473. unsigned char tmp;
  474. switch (gus.version = inportb(GF1_REVISION)) {
  475.   case 5:
  476. gus.version = GUS_CARD_VERSION_CLASSIC_ICS;
  477. gus.ics = 1;
  478. gus.ics_flipped = 1;
  479. break;
  480.   case 6:
  481.   case 7:
  482.   case 8:
  483.   case 9:
  484. gus.version = GUS_CARD_VERSION_CLASSIC_ICS;
  485. gus.ics = 1;
  486. break;
  487.   case 10:
  488. gus.version = GUS_CARD_VERSION_MAX;
  489. gus.codec = 1;
  490. break;
  491.   case 11:
  492. gus.version = GUS_CARD_VERSION_MAX1;
  493. gus.codec = 1;
  494. break;
  495.   case 0x30:
  496. gus.version = GUS_CARD_VERSION_ACE;
  497. break;
  498.   case 0x50:
  499. gus.version = GUS_CARD_VERSION_EXTREME;
  500. break;
  501.   case 0xff:
  502. /* Pre-3.7 board */
  503. outportb(GF1_REG_CTRL, 0x20);
  504. tmp = inportb(GF1_REG_CTRL);
  505. if ((tmp != 0xff) && (tmp & 0x06))
  506. gus.version = GUS_CARD_VERSION_CLASSIC1;
  507. else
  508. gus.version = GUS_CARD_VERSION_CLASSIC;
  509. break;
  510.   default:
  511. /* Hmm... unknown revision. Assume a safe Classic model */
  512. #ifdef MIKMOD_DEBUG
  513. fprintf(stderr, "libgus: Unknown board revision (%02x)n",
  514. gus.version);
  515. #endif
  516. gus.version = GUS_CARD_VERSION_CLASSIC;
  517. break;
  518. }
  519. }
  520. static void __gus_detect_transfer()
  521. {
  522. unsigned char *outbuff, *inbuff;
  523. unsigned int i, j, seed = 0x13243546;
  524. __gus_transfer_func func;
  525. #define TRANSFER_SIZE 0x4000
  526. outbuff = malloc(TRANSFER_SIZE);
  527. inbuff = malloc(TRANSFER_SIZE);
  528. /* Suppose we have an malfunctioning GUS */
  529. gus.transfer = NULL;
  530. for (i = (gus.dma_buff ? 0 : 4); i <= 4; i++) {
  531. switch (i) {
  532.   case 0:
  533. gus.dma_rate = GF1M_DMAR_RATE0;
  534. func = __gus_transfer_dma;
  535. break;
  536.   case 1:
  537. gus.dma_rate = GF1M_DMAR_RATE1;
  538. func = __gus_transfer_dma;
  539. break;
  540.   case 2:
  541. gus.dma_rate = GF1M_DMAR_RATE2;
  542. func = __gus_transfer_dma;
  543. break;
  544.   case 3:
  545. gus.dma_rate = GF1M_DMAR_RATE3;
  546. func = __gus_transfer_dma;
  547. break;
  548.   case 4:
  549. func = __gus_transfer_io;
  550. break;
  551. }
  552. /* Fill data array each time with pseudo-random values */
  553. for (j = 0; j < TRANSFER_SIZE; j++)
  554. outbuff[j] = seed, seed =
  555.   ((seed + 358979323) ^ (seed >> 16)) * 314159265;
  556. /* Transfer the random array to GUS */
  557. /* Poke a security fence around dest block */
  558. __gus_poke(0x100 - 1, 0xAA);
  559. __gus_poke(0x100 - 2, 0x55);
  560. __gus_poke(0x100 + TRANSFER_SIZE + 0, 0xAA);
  561. __gus_poke(0x100 + TRANSFER_SIZE + 1, 0x55);
  562. func(0x100, outbuff, TRANSFER_SIZE, 0);
  563. if (__gus_wait_dma() == 0) {
  564. /* Check if the security fence was not damaged */
  565. if ((__gus_peek(0x100 - 1) != 0xAA)
  566. || (__gus_peek(0x100 - 2) != 0x55)
  567. || (__gus_peek(0x100 + TRANSFER_SIZE + 0) != 0xAA)
  568. || (__gus_peek(0x100 + TRANSFER_SIZE + 1) != 0x55))
  569. continue;
  570. /* Now check if GUS DRAM really data that we expects to be transferred */
  571. __gus_transfer_io_in(0x100, inbuff, TRANSFER_SIZE);
  572. if (memcmp(outbuff, inbuff, TRANSFER_SIZE) == 0) {
  573. gus.transfer = func;
  574. break;
  575. }
  576. }
  577. }
  578. #undef TRANSFER_SIZE
  579. free(inbuff);
  580. free(outbuff);
  581. }
  582. static void __gus_detect_memory()
  583. {
  584. unsigned int size;
  585. for (size = 0; size < 1024; size += 256) {
  586. __gus_poke(size * 1024, 0xaa);
  587. if (__gus_peek(size * 1024) != 0xaa)
  588. break;
  589. __gus_poke(size * 1024, 0x55);
  590. if (__gus_peek(size * 1024) != 0x55)
  591. break;
  592. }
  593. gus.ram = size;
  594. }
  595. static void __gus_init()
  596. {
  597. char *gusenv = getenv("ULTRASND");
  598. memset((void *)&gus, 0, sizeof(gus));
  599. gus.cmd_voice = -1;
  600. if (!gusenv)
  601. return;
  602. sscanf(gusenv, "%x,%d,%d,%d,%d", &gus.port, &gus.dma[0], &gus.dma[1],
  603.    &gus.irq[0], &gus.irq[1]);
  604. /* A relaxed sanity check */
  605. if ((gus.port < 0x100) || (gus.port > 0x1000)
  606. || (gus.irq[0] < 2) || (gus.irq[0] > 15)
  607. || (gus.irq[1] < 2) || (gus.irq[1] > 15)
  608. || (gus.dma[0] < 0) || (gus.dma[0] > 7)
  609. || (gus.dma[1] < 0) || (gus.dma[1] > 7))
  610. return;
  611. gus.voices = 32;
  612. gus.timer_ctl = GF1M_MASK_TIMER1 | GF1M_MASK_TIMER2;
  613. /* Detect if the card is really there */
  614. if (__gus_detect() == 0)
  615. return;
  616. /* Detect the version of Gravis Ultrasound */
  617. __gus_detect_version();
  618. /* Reset the card */
  619. __gus_reset(1);
  620. /* Detect the amount of on-board memory */
  621. __gus_detect_memory();
  622. gus.ok = 1;
  623. }
  624. static void __gus_kick(gus_wave_t * wave, unsigned int wave_offset)
  625. {
  626. unsigned char vc;
  627. vc = GF1VC_IRQ;
  628. if (wave->format & GUS_WAVE_16BIT)
  629. vc |= GF1VC_DATA16;
  630. if (wave->format & GUS_WAVE_BACKWARD)
  631. vc |= GF1VC_BACKWARD;
  632. if (wave->format & GUS_WAVE_LOOP) {
  633. vc |= GF1VC_LOOP_ENABLE;
  634. if (wave->format & GUS_WAVE_BIDIR)
  635. vc |= GF1VC_BI_LOOP;
  636. }
  637. __gus_set_loop_start(vc, (wave->begin.memory << 4) + wave->loop_start);
  638. if (wave->format & GUS_WAVE_LOOP)
  639. __gus_set_loop_end(vc, (wave->begin.memory << 4) + wave->loop_end);
  640. else
  641. __gus_set_loop_end(vc, (wave->begin.memory + wave->size) << 4);
  642. __gus_set_current(vc, (wave->begin.memory << 4) + wave_offset + 100);
  643. __gus_outregb_slow(GF1R_VOICE_CONTROL, vc);
  644. }
  645. /* Timer 1 callback function (updates voices) */
  646. static void __gus_timer_update()
  647. {
  648. gus_wave_t *wave;
  649. unsigned long wave_offset;
  650. unsigned char *src, *top;
  651. unsigned int vmask = (1 << gus.cur_voice);
  652. if (!gus.cmd_pool_ready)
  653. return;
  654. __gus_select_voice(gus.cur_voice);
  655. wave_offset = 0;
  656. src = gus.cmd_pool;
  657. top = gus.cmd_pool + gus.cmd_pool_top;
  658. #define GET_B *src
  659. #define GET_W *((unsigned short *)src)
  660. #define GET_L *((unsigned long *)src)
  661. while (src < top) {
  662. __gus_delay();
  663. switch (GET_B++) {
  664.   case PCMD_VOICE:
  665. __gus_select_voice(gus.cur_voice = GET_B++);
  666. vmask = (1 << gus.cur_voice);
  667. break;
  668.   case PCMD_FREQ:
  669. __gus_outregw(GF1R_FREQUENCY, GET_W++);
  670. break;
  671.   case PCMD_PAN:
  672. __gus_outregb(GF1R_BALANCE, GET_B++);
  673. break;
  674.   case PCMD_VOLUME:
  675. __gus_volume_ramp_to(gus.cur_vol[gus.cur_voice] =
  676.  GET_W++, GUS_VOLCHANGE_RAMP, GF1VL_IRQ);
  677. break;
  678.   case PCMD_VOLUME_PREPARE:
  679. gus.cur_vol[gus.cur_voice] = GET_W++;
  680. break;
  681.   case PCMD_OFFSET:
  682. wave_offset = GET_L++;
  683. break;
  684.   case PCMD_START:
  685. wave = (gus_wave_t *) GET_L++;
  686. gus.cur_wave[gus.cur_voice] = wave;
  687. gus.kick_offs[gus.cur_voice] = wave_offset;
  688. if (__gus_volume_ramp_to(0, GUS_VOLCHANGE_RAMP, GF1VL_IRQ)) {
  689. __gus_kick(wave, wave_offset);
  690. __gus_volume_ramp_to(gus.cur_vol[gus.cur_voice],
  691.  GUS_VOLCHANGE_RAMP, GF1VL_IRQ);
  692. } else
  693. gus.voice_kick[gus.cur_voice] = 1;
  694. wave_offset = 0;
  695. gus.eow_ignore |= vmask;
  696. break;
  697.   case PCMD_STOP:
  698. /* If volume is close to nothing, abort immediately instead of
  699.    ramping */
  700. gus.cur_vol[gus.cur_voice] = 0;
  701. gus.cur_wave[gus.cur_voice] = NULL;
  702. if (__gus_volume_ramp_to(0, GUS_VOLCHANGE_RAMP, GF1VL_IRQ))
  703. __gus_stop_voice();
  704. break;
  705.   case PCMD_STOP_LOOP:
  706. __gus_outregb_slow(GF1R_VOICE_CONTROL,
  707.    (__gus_inregb(GF1R_VOICE_CONTROL) | GF1VC_IRQ)
  708.    & ~GF1VC_LOOP_ENABLE);
  709. __gus_outregb_slow(GF1R_VOLUME_CONTROL,
  710.    __gus_inregb(GF1R_VOLUME_CONTROL) &
  711.    ~GF1VL_ROLLOVER);
  712. break;
  713.   default:
  714. /* Alarm! Break out immediately */
  715. src = top;
  716. break;
  717. }
  718. }
  719. #undef GET_B
  720. #undef GET_W
  721. #undef GET_L
  722. gus.cmd_pool_ready = 0;
  723. gus.cmd_pool_top = 0;
  724. }
  725. static void __gus_wavetable_update(unsigned int voice, unsigned int voice_ctl,
  726.    unsigned int volume_ctl)
  727. {
  728. gus_wave_t *wave = gus.cur_wave[voice];
  729. if (!wave || !(wave->format & GUS_WAVE_LOOP)) {
  730. __gus_stop_voice();
  731. gus.cur_wave[voice] = NULL;
  732. gus.cur_vol[voice] = 0;
  733. if (__gus_volume_ramp_to(0, GUS_VOLCHANGE_RAMP, GF1VL_IRQ))
  734. __gus_stop_voice();
  735. }
  736. }
  737. static void __gus_volume_update(unsigned int voice, unsigned int voice_ctl,
  738. unsigned int volume_ctl)
  739. {
  740. __gus_volume_ramp_to(gus.cur_vol[voice], GUS_VOLCHANGE_RAMP, GF1VL_IRQ);
  741. if (!gus.cur_wave[voice])
  742. __gus_stop_voice();
  743. else if (gus.voice_kick[voice])
  744. __gus_kick(gus.cur_wave[voice], gus.kick_offs[voice]);
  745. gus.voice_kick[voice] = 0;
  746. }
  747. /***************************************************** GUS memory manager *****/
  748. /* Mark all GUS memory as available */
  749. static void __gus_mem_clear()
  750. {
  751. __gus_mcb *cur = gus.mcb;
  752. while (cur) {
  753. __gus_mcb *next = cur->next;
  754. if (cur != gus.mcb)
  755. free(cur);
  756. cur = next;
  757. }
  758. if (!gus.mcb)
  759. gus.mcb = malloc(sizeof(__gus_mcb));
  760. gus.mcb->next = gus.mcb->prev = NULL;
  761. gus.mcb->addr = 0;
  762. gus.mcb->size = gus.ram * 1024;
  763. gus.mcb->free = 1;
  764. }
  765. /* Return amount of free memory */
  766. static unsigned int __gus_mem_get_free()
  767. {
  768. __gus_mcb *cur = gus.mcb;
  769. unsigned int size = 0;
  770. if (!gus.open)
  771. return gus.ram * 1024;
  772. while (cur) {
  773. if (cur->free)
  774. size += cur->size;
  775. cur = cur->next;
  776. }
  777. return size;
  778. }
  779. /* Return largest size for a 8-bit sample */
  780. static unsigned int __gus_mem_get_free_8()
  781. {
  782. __gus_mcb *cur = gus.mcb;
  783. unsigned int size = 0;
  784. if (!gus.open)
  785. return 0;
  786. while (cur) {
  787. if (cur->free && (cur->size > size))
  788. size = cur->size;
  789. cur = cur->next;
  790. }
  791. return size;
  792. }
  793. /* Return largest size for a 16-bit sample */
  794. static unsigned int __gus_mem_get_free_16()
  795. {
  796. __gus_mcb *cur = gus.mcb;
  797. unsigned int size = 0;
  798. if (!gus.open)
  799. return 0;
  800. while (cur) {
  801. if (cur->free) {
  802. unsigned int size16 = cur->size;
  803. unsigned int tmp;
  804. /* 16-bit samples cannot cross 256K boundaries */
  805. tmp = 0x40000 - (cur->addr & 0x3ffff);
  806. if (size16 > tmp)
  807. size16 = tmp;
  808. /* 16-bit samples should be aligned on a 32-byte boundary */
  809. size16 -= (32 - cur->addr) & 0x1f;
  810. if (size16 > size)
  811. size = size16;
  812. /* Now try vice versa: skip a portion of aligned memory */
  813. size16 =
  814.   (cur->addr + cur->size) - ((cur->addr + 0x3ffff) & ~0x3ffff);
  815. if ((size16 < 0x7fffffff) && (size16 > size))
  816. size = size16;
  817. }
  818. cur = cur->next;
  819. }
  820. return size;
  821. }
  822. /* Allocate a segment of GUS DRAM for a sample with given bits per sample.
  823.  * The algorithm tries to find the smallest free block that fits requested
  824.  * size; but if found free block is larger by some (large) delta than
  825.  * requested block size, the largest possible block is preffered.
  826.  */
  827. static unsigned int __gus_mem_alloc(unsigned int size, int bits16)
  828. {
  829. __gus_mcb *cur = gus.mcb;
  830. __gus_mcb *best_max = NULL, *best_min = NULL;
  831. unsigned int best_max_delta = 0, best_min_delta = 0xffffffff;
  832. unsigned int best_max_prefix = 0, best_min_prefix = 0;
  833. unsigned int memaddr, memsize;
  834. if (!gus.open || !size || (bits16 && size > 0x40000))
  835. return -1;
  836. /* Round block size up to nearest acceptable DMA bound */
  837. if (bits16)
  838. size = (size + 0x1f) & ~0x1f;
  839. else
  840. size = (size + 0x0f) & ~0x0f;
  841. while (cur) {
  842. if (cur->free) {
  843. unsigned char fits = 0;
  844. memsize = cur->size;
  845. memaddr = cur->addr;
  846. if (bits16) {
  847. /* 16-bit samples cannot cross 256K boundaries */
  848. unsigned int tmp = 256 * 1024 - (memaddr & 0x3ffff);
  849. if (memsize > tmp)
  850. memsize = tmp;
  851. /* 16-bit samples should be aligned on a 32-byte boundary */
  852. memsize -= (32 - memaddr) & 0x1f;
  853. memaddr = (memaddr + 0x1f) & ~0x1f;
  854. }
  855. /* If block fits, analyze it */
  856. if (size <= memsize)
  857. fits = 1;
  858. /* Look if we still can complete the request by creating a free
  859.    block */
  860. else if (size <= cur->size) {
  861. /* Align start address to next 256k boundary */
  862. unsigned int endaddr = cur->addr + cur->size;
  863. memaddr = (cur->addr + 0x3ffff) & ~0x3ffff;
  864. /* Can we split current block by inserting a free block at the
  865.    beginning? */
  866. if ((memaddr < endaddr) && (memaddr + size <= endaddr))
  867. fits = 1;
  868. }
  869. if (fits) {
  870. unsigned int size_delta = cur->size - size;
  871. unsigned int size_prefix = memaddr - cur->addr;
  872. if (size_delta < best_min_delta)
  873. best_min = cur, best_min_delta =
  874.   size_delta, best_min_prefix = size_prefix;
  875. if (size_delta > best_max_delta)
  876. best_max = cur, best_max_delta =
  877.   size_delta, best_max_prefix = size_prefix;
  878. }
  879. }
  880. cur = cur->next;
  881. }
  882. if (!best_min)
  883. return -1;
  884. /* If minimal block that fits is too large, use largest block that fits */
  885. /* But if using the maximal block is going to create a small hole, forget
  886.    it */
  887. if ((best_max_prefix == 0)
  888. || (best_max_prefix >= DRAM_HOLE_THRESHOLD)
  889. || (best_min_prefix != 0))
  890. if (
  891. ((best_min_delta < DRAM_HOLE_THRESHOLD) &&
  892.  (best_max_delta >= DRAM_HOLE_THRESHOLD)) ||
  893. ((best_min_prefix > 0) && (best_min_prefix < DRAM_HOLE_THRESHOLD)
  894.  && ((best_max_prefix == 0) ||
  895.  (best_max_prefix > best_min_prefix))) ||
  896. ((best_min_prefix != 0) && (best_max_prefix == 0))) {
  897. best_min = best_max;
  898. best_min_delta = best_max_delta;
  899. best_min_prefix = best_max_prefix;
  900. }
  901. /* Compute the DRAM address to return */
  902. memaddr = best_min->addr + best_min_prefix;
  903. if (bits16)
  904. memaddr = (memaddr + 0x1f) & ~0x1f;
  905. else
  906. memaddr = (memaddr + 0x0f) & ~0x0f;
  907. /* If we have a considerable hole at the beginning of sample,
  908.    create a free node describing the hole */
  909. if (memaddr - best_min->addr >= DRAM_SPLIT_THRESHOLD) {
  910. __gus_mcb *newmcb = malloc(sizeof(__gus_mcb));
  911. newmcb->prev = best_min->prev;
  912. newmcb->next = best_min;
  913. newmcb->addr = best_min->addr;
  914. newmcb->size = memaddr - best_min->addr;
  915. newmcb->free = 1;
  916. best_min->addr = memaddr;
  917. best_min->size -= newmcb->size;
  918. best_min->prev = newmcb;
  919. if (newmcb->prev)
  920. newmcb->prev->next = newmcb;
  921. }
  922. /* Compute the size of hole at the end of block */
  923. memsize = (best_min->addr + best_min->size) - (memaddr + size);
  924. /* Split the block if the block is larger than requested amount */
  925. if (memsize > DRAM_SPLIT_THRESHOLD) {
  926. /* The next node cannot be free since free blocks are always glued
  927.    together */
  928. __gus_mcb *newmcb = malloc(sizeof(__gus_mcb));
  929. best_min->size -= memsize;
  930. newmcb->prev = best_min;
  931. newmcb->next = best_min->next;
  932. newmcb->addr = best_min->addr + best_min->size;
  933. newmcb->size = memsize;
  934. newmcb->free = 1;
  935. if (best_min->next)
  936. best_min->next->prev = newmcb;
  937. best_min->next = newmcb;
  938. }
  939. best_min->free = 0;
  940. return memaddr;
  941. }
  942. static void __gus_mem_free(unsigned int addr)
  943. {
  944. __gus_mcb *cur = gus.mcb;
  945. while (cur) {
  946. if (!cur->free && (cur->addr <= addr) &&
  947. (cur->addr + cur->size > addr)) {
  948. cur->free = 1;
  949. /* If next block is free as well, link them together */
  950. if (cur->next && cur->next->free) {
  951. __gus_mcb *next = cur->next;
  952. cur->size += next->size;
  953. cur->next = next->next;
  954. if (next->next)
  955. next->next->prev = cur;
  956. free(next);
  957. }
  958. /* If previous block is free, link current block with it */
  959. if (cur->prev && cur->prev->free) {
  960. cur->prev->size += cur->size;
  961. cur->prev->next = cur->next;
  962. if (cur->next)
  963. cur->next->prev = cur->prev;
  964. free(cur);
  965. }
  966. return;
  967. }
  968. cur = cur->next;
  969. }
  970. }
  971. static void __gus_mem_pack()
  972. {
  973. }
  974. #ifdef MIKMOD_DEBUG
  975. /* Debug dump of GUS DRAM heap */
  976. void __gus_mem_dump()
  977. {
  978. __gus_mcb *cur = gus.mcb;
  979. fprintf(stderr, "/-- Offset --+-- Prev --+-- Size --+-- Free --\n");
  980. while (cur) {
  981. fprintf(stderr, "|  %08X  | %08X |  %6d  |   %s    |n",
  982. cur->addr, cur->prev ? cur->prev->addr : -1, cur->size,
  983. cur->free ? "yes" : " no");
  984. cur = cur->next;
  985. }
  986. fprintf(stderr, "\------------+----------+----------+----------/n");
  987. }
  988. #endif
  989. /************************************************** Middle-level routines *****/
  990. static int __gus_instrument_free(gus_instrument_t * instrument)
  991. {
  992. gus_instrument_t **cur_instr;
  993. gus_layer_t *cur_layer;
  994. gus_wave_t *cur_wave, *wave_head;
  995. /* Remove the instrument from the list of registered instruments */
  996. cur_instr = (gus_instrument_t **) & gus.instr;
  997. while (*cur_instr) {
  998. if (*cur_instr == instrument) {
  999. *cur_instr = instrument->next;
  1000. goto instr_loaded;
  1001. }
  1002. cur_instr = &(*cur_instr)->next;
  1003. }
  1004. return -1;
  1005. instr_loaded:
  1006. wave_head = NULL;
  1007. for (cur_layer = instrument->info.layer; cur_layer;
  1008.  cur_layer = cur_layer->next)
  1009. /* Free all waves */
  1010. for (cur_wave = cur_layer->wave; cur_wave; cur_wave = cur_wave->next) {
  1011. if (!wave_head)
  1012. wave_head = cur_wave;
  1013. if (cur_wave->begin.memory != (unsigned int)-1)
  1014. __gus_mem_free(cur_wave->begin.memory);
  1015. }
  1016. if (wave_head)
  1017. free(wave_head);
  1018. free(instrument->info.layer);
  1019. if (instrument->name)
  1020. free(instrument->name);
  1021. free(instrument);
  1022. return 0;
  1023. }
  1024. static gus_instrument_t *__gus_instrument_get(int program)
  1025. {
  1026. gus_instrument_t *cur_instr = (gus_instrument_t *) gus.instr;
  1027. while (cur_instr) {
  1028. if (cur_instr->number.instrument == program)
  1029. return cur_instr;
  1030. cur_instr = cur_instr->next;
  1031. }
  1032. return NULL;
  1033. }
  1034. static gus_instrument_t *__gus_instrument_copy(gus_instrument_t * instrument)
  1035. {
  1036. gus_instrument_t **cur_instr, *instr;
  1037. gus_layer_t *cur_layer, *dest_layer;
  1038. gus_wave_t *cur_wave, *dest_wave;
  1039. unsigned int waves, layers;
  1040. if (!instrument || !instrument->info.layer || !gus.open)
  1041. return NULL;
  1042. if (__gus_instrument_get(instrument->number.instrument))
  1043. return NULL;
  1044. instr = malloc(sizeof(gus_instrument_t));
  1045. *instr = *instrument;
  1046. if (instrument->name)
  1047. instr->name = strdup(instrument->name);
  1048. /* Make a copy of all layers at once */
  1049. for (layers = 0, cur_layer = instrument->info.layer; cur_layer; layers++)
  1050. cur_layer = cur_layer->next;
  1051. if (!(dest_layer = instr->info.layer = malloc(sizeof(gus_layer_t) * layers))) {
  1052. if (instr->name)
  1053. free(instr->name);
  1054. free(instr);
  1055. return NULL;
  1056. }
  1057. for (waves = 0, cur_layer = instrument->info.layer; cur_layer;
  1058.  cur_layer = cur_layer->next) {
  1059. *dest_layer = *cur_layer;
  1060. dest_layer->wave = NULL;
  1061. /* Count the total number of waves */
  1062. for (cur_wave = cur_layer->wave; cur_wave; cur_wave = cur_wave->next)
  1063. waves++;
  1064. if (cur_layer->next)
  1065. dest_layer->next = dest_layer + 1;
  1066. else
  1067. dest_layer->next = NULL;
  1068. dest_layer++;
  1069. }
  1070. /* Allocate memory for waves */
  1071. if (!(dest_wave = malloc(sizeof(gus_wave_t) * waves))) {
  1072. free(instr->info.layer);
  1073. if (instr->name)
  1074. free(instr->name);
  1075. free(instr);
  1076. return NULL;
  1077. }
  1078. for (cur_layer = instrument->info.layer, dest_layer = instr->info.layer;
  1079.      cur_layer; cur_layer = cur_layer->next, dest_layer = dest_layer->next)
  1080. /* Copy all waves */
  1081. for (cur_wave = cur_layer->wave; cur_wave; cur_wave = cur_wave->next) {
  1082. if (!dest_layer->wave)
  1083. dest_layer->wave = dest_wave;
  1084. *dest_wave = *cur_wave;
  1085. /* Mark DRAM address as unallocated */
  1086. dest_wave->begin.memory = -1;
  1087. if (cur_wave->next)
  1088. dest_wave->next = (dest_wave + 1);
  1089. else
  1090. dest_wave->next = NULL;
  1091. dest_wave++;
  1092. }
  1093. /* Insert the instrument into list of registered instruments */
  1094. cur_instr = (gus_instrument_t **) & gus.instr;
  1095. while (*cur_instr)
  1096. cur_instr = &(*cur_instr)->next;
  1097. *cur_instr = instr;
  1098. return instr;
  1099. }
  1100. static void __gus_instruments_clear()
  1101. {
  1102. gus_instrument_t *next_instr, *cur_instr = (gus_instrument_t *) gus.instr;
  1103. while (cur_instr) {
  1104. next_instr = cur_instr->next;
  1105. __gus_instrument_free(cur_instr);
  1106. cur_instr = next_instr;
  1107. }
  1108. }
  1109. /******************************************************* libGUS interface *****/
  1110. /* return value: number of GUS cards installed in system */
  1111. int gus_cards()
  1112. {
  1113. if (!gus.ok)
  1114. __gus_init();
  1115. return gus.ok ? 1 : 0;
  1116. }
  1117. int gus_info(gus_info_t * info, int reread)
  1118. {
  1119. if (!gus.ok)
  1120. __gus_init();
  1121. if (!gus.ok)
  1122. return -1;
  1123. strcpy(info->id, "gus0");
  1124. info->flags = (gus.ram ? GUS_STRU_INFO_F_PCM : 0);
  1125. info->version = gus.version;
  1126. info->port = gus.port;
  1127. info->irq = gus.irq[0];
  1128. info->dma1 = gus.dma[0];
  1129. info->dma2 = gus.dma[1];
  1130. info->mixing_freq = gus.freq;
  1131. info->memory_size = gus.ram * 1024;
  1132. info->memory_free = __gus_mem_get_free();
  1133. info->memory_block_8 = __gus_mem_get_free_8();
  1134. info->memory_block_16 = __gus_mem_get_free_16();
  1135. return 0;
  1136. }
  1137. int gus_open(int card, size_t queue_buffer_size, int non_block)
  1138. {
  1139. __dpmi_meminfo struct_info, pool_info;
  1140. if (!gus.ok)
  1141. __gus_init();
  1142. if (!gus.ok || gus.open || card != 0)
  1143. return -1;
  1144. /* Now lock the gus structure in memory */
  1145. struct_info.address = __djgpp_base_address + (unsigned long)&gus;
  1146. struct_info.size = sizeof(gus);
  1147. if (__dpmi_lock_linear_region(&struct_info))
  1148. return -1;
  1149. /* And hook the GF1 interrupt */
  1150. __irq_stack_count = 4;
  1151. gus.gf1_irq =
  1152.   irq_hook(gus.irq[0], gf1_irq, (long)gf1_irq_end - (long)gf1_irq);
  1153. __irq_stack_count = 1;
  1154. if (!gus.gf1_irq) {
  1155. __dpmi_unlock_linear_region(&struct_info);
  1156. return -1;
  1157. }
  1158. /* Enable the interrupt */
  1159. irq_enable(gus.gf1_irq);
  1160. if (gus.irq[0] > 7)
  1161. _irq_enable(2);
  1162. /* Allocate a DMA buffer: if we fail, we just use I/O so don't fail */
  1163. if ((gus.transfer == NULL) || (gus.transfer == __gus_transfer_dma))
  1164. gus.dma_buff = dma_allocate(gus.dma[0], GF1_DMA_BUFFER_SIZE);
  1165. else
  1166. gus.dma_buff = NULL;
  1167. /* Detect the best available RAM -> DRAM transfer function */
  1168. if (!gus.transfer) {
  1169. __gus_detect_transfer();
  1170. if (gus.transfer != __gus_transfer_dma || !gus.transfer)
  1171. dma_free(gus.dma_buff), gus.dma_buff = NULL;
  1172. /* If no transfer function worked, fail */
  1173. if (!gus.transfer) {
  1174. if (gus.dma_buff)
  1175. dma_free(gus.dma_buff);
  1176. __dpmi_unlock_linear_region(&struct_info);
  1177. irq_unhook(gus.gf1_irq);
  1178. return -1;
  1179. }
  1180. }
  1181. /* Allocate and lock command pool buffer */
  1182. if (queue_buffer_size < 64)
  1183. queue_buffer_size = 64;
  1184. if (queue_buffer_size > 16384)
  1185. queue_buffer_size = 16384;
  1186. gus.cmd_pool = malloc(queue_buffer_size);
  1187. pool_info.address = __djgpp_base_address + (unsigned long)&gus.cmd_pool;
  1188. pool_info.size = sizeof(queue_buffer_size);
  1189. if (__dpmi_lock_linear_region(&pool_info)) {
  1190. if (gus.dma_buff)
  1191. dma_free(gus.dma_buff);
  1192. __dpmi_unlock_linear_region(&struct_info);
  1193. irq_unhook(gus.gf1_irq);
  1194. return -1;
  1195. }
  1196. gus.open++;
  1197. __gus_mem_clear();
  1198. gus.t1_callback = __gus_timer_update;
  1199. gus.wt_callback = __gus_wavetable_update;
  1200. gus.vl_callback = __gus_volume_update;
  1201. gus_do_tempo(60); /* Default is 60 Hz */
  1202. return 0;
  1203. }
  1204. int gus_close(int card)
  1205. {
  1206. __dpmi_meminfo struct_info;
  1207. if (!gus.open || card != 0)
  1208. return -1;
  1209. /* First reset the card: disable any operation it can currently perform */
  1210. __gus_reset(0);
  1211. gus.open--;
  1212. /* Stop the timer */
  1213. gus_timer_stop();
  1214. /* Free DMA buffer if used */
  1215. if (gus.dma_buff)
  1216. dma_free(gus.dma_buff);
  1217. /* And unhook the GF1 interrupt */
  1218. irq_unhook(gus.gf1_irq);
  1219. gus.gf1_irq = NULL;
  1220. /* Unlock the gus structure */
  1221. struct_info.address = __djgpp_base_address + (unsigned long)&gus;
  1222. struct_info.size = sizeof(gus);
  1223. __dpmi_unlock_linear_region(&struct_info);
  1224. __gus_mem_clear();
  1225. __gus_instruments_clear();
  1226. return 0;
  1227. }
  1228. int gus_select(int card)
  1229. {
  1230. if (!gus.open || (card != 0))
  1231. return -1;
  1232. return 0;
  1233. }
  1234. /* return value: same as gus_reset function
  1235.    note: this command doesn't change number of active voices and doesn't do
  1236.    hardware reset */
  1237. int gus_reset_engine_only()
  1238. {
  1239. gus.timer_base = 100;
  1240. return 0;
  1241. }
  1242. int gus_reset(int voices, unsigned int channel_voices)
  1243. {
  1244. static unsigned short freq_table[32 - 14 + 1] = {
  1245. 44100, 41160, 38587, 36317, 34300, 32494, 30870, 29400, 28063, 26843,
  1246. 25725, 24696, 23746, 22866, 22050, 21289, 20580, 19916, 19293
  1247. };
  1248. int voice;
  1249. int timer;
  1250. /* No support for dynamically allocated voices for now */
  1251. gus.dynmask = channel_voices;
  1252. if (voices < 14)
  1253. voices = 14;
  1254. if (voices > 32)
  1255. voices = 32;
  1256. /* Stop the timer so that GUS IRQ won't clobber registers */
  1257. timer = (gus.timer_ctl_reg & GF1M_TIMER1);
  1258. if (timer)
  1259. gus_timer_stop();
  1260. /* Stop all voices */
  1261. for (voice = 0; voice < 32; voice++) {
  1262. __gus_select_voice(voice);
  1263. __gus_stop_voice();
  1264. gus.cur_wave[voice] = NULL;
  1265. gus.cur_vol[voice] = 0;
  1266. __gus_delay();
  1267. /* Reset voice parameters to reasonable values */
  1268. __gus_set_current(0, 0);
  1269. __gus_set_loop_start(0, 0);
  1270. __gus_set_loop_end(0, 0);
  1271. __gus_outregw(GF1R_VOLUME, 0);
  1272. __gus_outregb(GF1R_VOLUME_RATE, 0);
  1273. __gus_outregb(GF1R_VOLUME_START, 0);
  1274. __gus_outregb(GF1R_VOLUME_END, 0);
  1275. __gus_outregb(GF1R_BALANCE, 0x7);
  1276. }
  1277. voice = (__gus_inregb(GF1R_VOICES) & 0x1f) + 1;
  1278. if (voice != voices) {
  1279. int reset = __gus_inregb(GF1R_RESET);
  1280. __gus_outregb(GF1R_RESET, reset & ~GF1M_OUTPUT_ENABLE);
  1281. __gus_delay();
  1282. __gus_outregb(GF1R_VOICES, 0xc0 | (voices - 1));
  1283. __gus_delay();
  1284. __gus_outregb(GF1R_RESET, reset);
  1285. }
  1286. /* Compute the discretization frequence */
  1287. gus.voices = voices;
  1288. if (gus.interwave)
  1289. gus.freq = 44100;
  1290. else
  1291. gus.freq = freq_table[voices - 14];
  1292. gus_reset_engine_only();
  1293. if (timer)
  1294. gus_timer_continue();
  1295. return gus.voices;
  1296. }
  1297. int gus_do_flush()
  1298. {
  1299. DEBUG_PRINT(("gus_do_flush: top = %dn", gus.cmd_pool_top))
  1300.   gus.cmd_pool_ready = 1;
  1301. return 0;
  1302. }
  1303. /* set new tempo */
  1304. void gus_do_tempo(unsigned int tempo)
  1305. {
  1306. DEBUG_PRINT(("gus_do_tempo (%d)n", tempo))
  1307.   gus_timer_tempo(tempo);
  1308. gus_timer_start();
  1309. }
  1310. /* set voice frequency in Hz */
  1311. void gus_do_voice_frequency(unsigned char voice, unsigned int freq)
  1312. {
  1313. DEBUG_PRINT(("gus_do_voice_frequency (%d, %d)n", voice, freq))
  1314.   __pool_select_voice(voice);
  1315. __pool_command_w(PCMD_FREQ,
  1316.  (((freq << 9) + (gus.freq >> 1)) / gus.freq) << 1);
  1317. }
  1318. /* set voice pan (0-16384) (full left - full right) */
  1319. void gus_do_voice_pan(unsigned char voice, unsigned short pan)
  1320. {
  1321. DEBUG_PRINT(("gus_do_voice_pan (%d, %d)n", voice, pan))
  1322.   pan >>= 10;
  1323. if (pan > 15)
  1324. pan = 15;
  1325. __pool_select_voice(voice);
  1326. __pool_command_b(PCMD_PAN, pan);
  1327. }
  1328. /* set voice volume level 0-16384 (linear) */
  1329. void gus_do_voice_volume(unsigned char voice, unsigned short vol)
  1330. {
  1331. DEBUG_PRINT(("gus_do_voice_volume (%d, %d)n", voice, vol))
  1332.   if (vol > 0x3fff)
  1333. vol = 0x3fff;
  1334. __pool_select_voice(voice);
  1335. __pool_command_w(PCMD_VOLUME, __gus_volume_table[vol >> 5]);
  1336. }
  1337. /* start voice
  1338.  *   voice    : voice #
  1339.  *   program  : program # or ~0 = current
  1340.  *   freq     : frequency in Hz
  1341.  *   volume   : volume level (0-16384) or ~0 = current
  1342.  *   pan      : pan level (0-16384) or ~0 = current
  1343.  */
  1344. void gus_do_voice_start(unsigned char voice, unsigned int program,
  1345. unsigned int freq, unsigned short volume,
  1346. unsigned short pan)
  1347. {
  1348. gus_do_voice_start_position(voice, program, freq, volume, pan, 0);
  1349. }
  1350. /* start voice
  1351.  *   voice    : voice #
  1352.  *   program  : program # or ~0 = current
  1353.  *   freq     : frequency in Hz
  1354.  *   volume   : volume level (0-16384) or ~0 = current
  1355.  *   pan      : pan level (0-16384) or ~0 = current
  1356.  *   position : offset to wave in bytes * 16 (lowest 4 bits - fraction)
  1357.  */
  1358. void gus_do_voice_start_position(unsigned char voice, unsigned int program,
  1359.  unsigned int freq, unsigned short volume,
  1360.  unsigned short pan, unsigned int position)
  1361. {
  1362. gus_instrument_t *instrument;
  1363. gus_wave_t *wave;
  1364. DEBUG_PRINT(
  1365. ("gus_do_voice_start_position (%d, %d, pos: %d)n", voice,
  1366.  program, position))
  1367.   instrument = __gus_instrument_get(program);
  1368. if (!instrument
  1369. || !instrument->info.layer
  1370. || !instrument->info.layer->wave
  1371. || instrument->flags == GUS_INSTR_F_NOT_FOUND
  1372. || instrument->flags == GUS_INSTR_F_NOT_LOADED) return;
  1373. gus_do_voice_frequency(voice, freq);
  1374. gus_do_voice_pan(voice, pan);
  1375. /* We have to set volume different way, to avoid unneeded work in handler */
  1376. if (volume > 0x3fff)
  1377. volume = 0x3fff;
  1378. __pool_command_w(PCMD_VOLUME_PREPARE, __gus_volume_table[volume >> 5]);
  1379. switch (instrument->mode) {
  1380.   case GUS_INSTR_SIMPLE:
  1381. wave = instrument->info.layer->wave;
  1382. if (position)
  1383. __pool_command_l(PCMD_OFFSET, position);
  1384. __pool_command_l(PCMD_START, (unsigned long)wave);
  1385. break;
  1386. }
  1387. }
  1388. /* stop voice
  1389.  *   mode = 0 : stop voice now
  1390.  *   mode = 1 : disable wave loop and finish it
  1391.  */
  1392. void gus_do_voice_stop(unsigned char voice, unsigned char mode)
  1393. {
  1394. __pool_select_voice(voice);
  1395. if (mode)
  1396. __pool_command(PCMD_STOP_LOOP);
  1397. else
  1398. __pool_command(PCMD_STOP);
  1399. }
  1400. /* wait x ticks - this command is block separator
  1401.    all commands between blocks are interpreted in the begining of one tick */
  1402. void gus_do_wait(unsigned int ticks)
  1403. {
  1404. DEBUG_PRINT(("gus_do_wait (%d)n", ticks))
  1405.   ticks += gus.t1_ticks;
  1406. while ((int)(ticks - gus.t1_ticks) > 0);
  1407. }
  1408. int gus_get_voice_status(int voice)
  1409. {
  1410. __gus_select_voice(voice);
  1411. return __gus_inregb(GF1R_VOICE_CONTROL) & GF1VC_STOPPED ? 0 : 1;
  1412. }
  1413. /* return value: file handle (descriptor) for /dev/gus */
  1414. int gus_get_handle()
  1415. {
  1416. /* Return stdout handle so that select() will "work" with it */
  1417. return 0;
  1418. }
  1419. /* return value: zero if instrument was successfully allocated */
  1420. int gus_memory_alloc(gus_instrument_t * instrument)
  1421. {
  1422. gus_instrument_t *instr = __gus_instrument_copy(instrument);
  1423. gus_layer_t *cur_layer;
  1424. gus_wave_t *cur_wave;
  1425. DEBUG_PRINT(("gus_memory_alloc (%d)n", instrument->number.instrument))
  1426.   if (!instr)
  1427. return -1;
  1428. for (cur_layer = instr->info.layer; cur_layer;
  1429.  cur_layer = cur_layer->next) for (cur_wave = cur_layer->wave;
  1430.    cur_wave;
  1431.    cur_wave = cur_wave->next) {
  1432. if (cur_layer->mode == GUS_INSTR_SIMPLE) {
  1433. cur_wave->begin.memory = __gus_mem_alloc(cur_wave->size,
  1434.  cur_wave->format &
  1435.  GUS_WAVE_16BIT);
  1436. if (cur_wave->begin.memory == (unsigned int)-1) {
  1437. __gus_instrument_free(instr);
  1438. return -1;
  1439. }
  1440. gus.transfer(cur_wave->begin.memory, cur_wave->begin.ptr,
  1441.  cur_wave->size, cur_wave->format);
  1442. } else if (cur_layer->mode == GUS_INSTR_PATCH)
  1443. /* not supported yet */ ;
  1444. }
  1445. return 0;
  1446. }
  1447. /* return value: zero if instrument was successfully removed */
  1448. int gus_memory_free(gus_instrument_t * instrument)
  1449. {
  1450. gus_instrument_t *cur_instr = gus.instr;
  1451. DEBUG_PRINT(("gus_memory_free (%d)n", instrument->number.instrument))
  1452.   for (; cur_instr; cur_instr = cur_instr->next)
  1453. if (cur_instr->number.instrument == instrument->number.instrument)
  1454. return __gus_instrument_free(cur_instr);
  1455. return -1;
  1456. }
  1457. /* return value: unused gus memory in bytes */
  1458. int gus_memory_free_size()
  1459. {
  1460. return __gus_mem_get_free();
  1461. }
  1462. /* return value: zero if success */
  1463. int gus_memory_pack()
  1464. {
  1465. __gus_mem_pack();
  1466. return 0;
  1467. }
  1468. /* return value: gus memory size in bytes */
  1469. int gus_memory_size()
  1470. {
  1471. return gus.ram * 1024;
  1472. }
  1473. /* return value: current largest free block for 8-bit or 16-bit wave */
  1474. int gus_memory_free_block(int w_16bit)
  1475. {
  1476. return w_16bit ? __gus_mem_get_free_16() : __gus_mem_get_free_8();
  1477. }
  1478. /* input value: see to GUS_DOWNLOAD_MODE_XXXX constants (gus.h) 
  1479.    return value: zero if samples & instruments was successfully removed from
  1480.    GF1 memory manager */
  1481. int gus_memory_reset(int mode)
  1482. {
  1483. __gus_mem_clear();
  1484. __gus_instruments_clear();
  1485. return 0;
  1486. }
  1487. /* return value: zero if command queue was successfully flushed */
  1488. int gus_queue_flush()
  1489. {
  1490. return 0;
  1491. }
  1492. /* input value: echo buffer size in items (if 0 - erase echo buffer) */
  1493. int gus_queue_read_set_size(int items)
  1494. {
  1495. return 0;
  1496. }
  1497. /* input value: write queue size in items (each item have 8 bytes) */
  1498. int gus_queue_write_set_size(int items)
  1499. {
  1500. return 0;
  1501. }
  1502. /* return value: zero if successfull */
  1503. int gus_timer_start()
  1504. {
  1505. gus.timer_ctl_reg |= GF1M_TIMER1;
  1506. __gus_outregb_slow(GF1R_TIMER_CONTROL, gus.timer_ctl_reg);
  1507. gus.timer_ctl = gus.timer_ctl & ~GF1M_MASK_TIMER1;
  1508. outportb(GF1_TIMER_CTRL, 0x04);
  1509. outportb(GF1_TIMER_DATA, gus.timer_ctl | GF1M_START_TIMER1);
  1510. return 0;
  1511. }
  1512. /* return value: zero if timer was stoped */
  1513. int gus_timer_stop()
  1514. {
  1515. gus.timer_ctl_reg &= ~GF1M_TIMER1;
  1516. __gus_outregb_slow(GF1R_TIMER_CONTROL, gus.timer_ctl_reg);
  1517. gus.timer_ctl = gus.timer_ctl | GF1M_MASK_TIMER1;
  1518. outportb(GF1_TIMER_CTRL, 0x04);
  1519. outportb(GF1_TIMER_DATA, gus.timer_ctl);
  1520. return 0;
  1521. }
  1522. /* return value: zero if setup was success */
  1523. int gus_timer_tempo(int ticks)
  1524. {
  1525. unsigned int counter;
  1526. /* Limit ticks per second to 1..1000 range */
  1527. if (ticks < 1)
  1528. ticks = 1;
  1529. if (ticks > 1000)
  1530. ticks = 1000;
  1531. /* GF1 timer1 period is 80 usecs, 12500 times per second */
  1532. counter = 1250000 / (ticks * gus.timer_base);
  1533. gus.t1_multiple = 1;
  1534. while (counter > 255) {
  1535. counter >>= 1;
  1536. gus.t1_multiple <<= 1;
  1537. }
  1538. gus.t1_countdown = gus.t1_multiple;
  1539. __gus_outregb(GF1R_TIMER1, 256 - counter);
  1540. return 0;
  1541. }
  1542. /* return value: zero if timer will be continue */
  1543. int gus_timer_continue()
  1544. {
  1545. return gus_timer_start();
  1546. }
  1547. /* return value: zero if setup was success (default timebase = 100) */
  1548. int gus_timer_base(int base)
  1549. {
  1550. gus.timer_base = base;
  1551. return 0;
  1552. }
  1553. void gus_timer_callback(void (*timer_callback) ())
  1554. {
  1555. gus.timer_callback = timer_callback;
  1556. }
  1557. void gus_convert_delta(unsigned int type, unsigned char *dest,
  1558.    unsigned char *src, size_t size)
  1559. {
  1560. if (!(type & GUS_WAVE_DELTA))
  1561. return;
  1562. /* This doesn't depend much on wave signedness, since addition/subtraction
  1563.    do not depend on operand signedness */
  1564. if (type & GUS_WAVE_16BIT) {
  1565. unsigned short delta = type & GUS_WAVE_UNSIGNED ? 0x8000 : 0;
  1566. while (size--) {
  1567. delta = *(unsigned short *)dest = *(unsigned short *)src + delta;
  1568. src += sizeof(unsigned short);
  1569. dest += sizeof(unsigned short);
  1570. }
  1571. } else {
  1572. unsigned char delta = type & GUS_WAVE_UNSIGNED ? 0x80 : 0;
  1573. while (size--) {
  1574. delta = *(unsigned char *)dest = *(unsigned char *)src + delta;
  1575. src++;
  1576. dest++;
  1577. }
  1578. }
  1579. }
  1580. int gus_dma_usage (int use)
  1581. {
  1582. if (gus.dma_buff)
  1583. return -1;
  1584. gus.transfer = __gus_transfer_io;
  1585. return 0;
  1586. }
  1587. /* ex:set ts=4: */