X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=libs%2Fmikmod%2Fdrivers%2Fdos%2Fdosgus.h;fp=libs%2Fmikmod%2Fdrivers%2Fdos%2Fdosgus.h;h=0000000000000000000000000000000000000000;hp=ae3488a0737e201a6b258dff28ec97cbe59fef2f;hb=b2c24e9d5b637bb78d18a377d9957c07d0759030;hpb=67c749060592270c9cd8b4f7dafe7d7c7a61a614 diff --git a/libs/mikmod/drivers/dos/dosgus.h b/libs/mikmod/drivers/dos/dosgus.h deleted file mode 100644 index ae3488a..0000000 --- a/libs/mikmod/drivers/dos/dosgus.h +++ /dev/null @@ -1,514 +0,0 @@ -/* MikMod sound library - (c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for - complete list. - - This library is free software; you can redistribute it and/or modify - it under the terms of the GNU Library General Public License as - published by the Free Software Foundation; either version 2 of - the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. -*/ - -/*============================================================================== - - $Id$ - - libGUS-alike definitions for DOS - -==============================================================================*/ - -#ifndef __DOSGUS_H__ -#define __DOSGUS_H__ - -#include -#include "dosdma.h" -#include "dosirq.h" -#include "libgus.h" - -/* Private header file for a libGUS-alike library for DOS */ - -#define JOYSTICK_TIMER (gus.port+0x201) /* 201 */ -#define JOYSTICK_DATA (gus.port+0x201) /* 201 */ - -#define GF1_MIDI_CTRL (gus.port+0x100) /* 3X0 */ -#define GF1_MIDI_DATA (gus.port+0x101) /* 3X1 */ - -#define GF1_VOICESEL (gus.port+0x102) /* 3X2 */ -#define GF1_REGSEL (gus.port+0x103) /* 3X3 */ -#define GF1_DATA (gus.port+0x104) /* 3X4 */ -#define GF1_DATA_LOW (gus.port+0x104) /* 3X4 */ -#define GF1_DATA_HIGH (gus.port+0x105) /* 3X5 */ -#define GF1_IRQ_STATUS (gus.port+0x006) /* 2X6 */ -#define GF1_DRAM (gus.port+0x107) /* 3X7 */ - -#define GF1_MIX_CTRL (gus.port+0x000) /* 2X0 */ -#define GF1_TIMER_CTRL (gus.port+0x008) /* 2X8 */ -#define GF1_TIMER_DATA (gus.port+0x009) /* 2X9 */ -#define GF1_IRQ_CTRL (gus.port+0x00B) /* 2XB */ -#define GF1_REG_CTRL (gus.port+0x00F) /* 2XF */ - -#define GF1_REVISION (gus.port+0x506) /* 7X6 */ - -/* The GF1 hardware clock rate */ -#define CLOCK_RATE 9878400L - -/* GF1 voice-independent registers */ -#define GF1R_DMA_CONTROL 0x41 -#define GF1R_DMA_ADDRESS 0x42 -#define GF1R_DRAM_LOW 0x43 -#define GF1R_DRAM_HIGH 0x44 - -#define GF1R_TIMER_CONTROL 0x45 -#define GF1R_TIMER1 0x46 -#define GF1R_TIMER2 0x47 - -#define GF1R_SAMPLE_RATE 0x48 -#define GF1R_SAMPLE_CONTROL 0x49 - -#define GF1R_JOYSTICK 0x4B -#define GF1R_RESET 0x4C - -/* GF1 voice-specific registers */ -#define GF1R_VOICE_CONTROL 0x00 -#define GF1R_FREQUENCY 0x01 -#define GF1R_START_HIGH 0x02 -#define GF1R_START_LOW 0x03 -#define GF1R_END_HIGH 0x04 -#define GF1R_END_LOW 0x05 -#define GF1R_VOLUME_RATE 0x06 -#define GF1R_VOLUME_START 0x07 -#define GF1R_VOLUME_END 0x08 -#define GF1R_VOLUME 0x09 -#define GF1R_ACC_HIGH 0x0a -#define GF1R_ACC_LOW 0x0b -#define GF1R_BALANCE 0x0c -#define GF1R_VOLUME_CONTROL 0x0d -#define GF1R_VOICES 0x0e -#define GF1R_IRQ_SOURCE 0x0f - -/* Add this to above registers for reading */ -#define GF1R_READ_MASK 0x80 - -/* MIDI */ -#define GF1M_MIDI_RESET 0x03 -#define GF1M_MIDI_ENABLE_XMIT 0x20 -#define GF1M_MIDI_ENABLE_RCV 0x80 - -#define GF1M_MIDI_RCV_FULL 0x01 -#define GF1M_MIDI_XMIT_EMPTY 0x02 -#define GF1M_MIDI_FRAME_ERR 0x10 -#define GF1M_MIDI_OVERRUN 0x20 -#define GF1M_MIDI_IRQ_PEND 0x80 - -/* Joystick */ -#define GF1M_JOY_POSITION 0x0f -#define GF1M_JOY_BUTTONS 0xf0 - -/* GF1_IRQ_STATUS (port 2X6) */ -#define GF1M_IRQ_MIDI_TX 0x01 /* pending MIDI xmit IRQ */ -#define GF1M_IRQ_MIDI_RX 0x02 /* pending MIDI recv IRQ */ -#define GF1M_IRQ_TIMER1 0x04 /* general purpose timer */ -#define GF1M_IRQ_TIMER2 0x08 /* general purpose timer */ -#define GF1M_IRQ_WAVETABLE 0x20 /* pending wavetable IRQ */ -#define GF1M_IRQ_ENVELOPE 0x40 /* pending volume envelope IRQ */ -#define GF1M_IRQ_DMA_COMPLETE 0x80 /* pending dma transfer complete IRQ */ - -/* GF1_MIX_CTRL (port 2X0) */ -#define GF1M_MIXER_NO_LINE_IN 0x01 /* 0: enable */ -#define GF1M_MIXER_NO_OUTPUT 0x02 /* 0: enable */ -#define GF1M_MIXER_MIC_IN 0x04 /* 1: enable */ -#define GF1M_MIXER_GF1_IRQ 0x08 /* 1: enable */ -#define GF1M_GF1_COMBINED_IRQ 0x10 /* 1: IRQ1 == IRQ2 */ -#define GF1M_MIDI_LOOPBACK 0x20 /* 1: enable loop back */ -#define GF1M_CONTROL_SELECT 0x40 /* 0: DMA latches; 1: IRQ latches */ - -/* Timer data register (2X9) */ -#define GF1M_START_TIMER1 0x01 -#define GF1M_START_TIMER2 0x02 -#define GF1M_MASK_TIMER1 0x20 -#define GF1M_MASK_TIMER2 0x40 -#define GF1M_TIMER_CLRIRQ 0x80 - -/* IRQ/DMA control register (2XB) */ -#define GF1M_IRQ_EQUAL 0x40 -#define GF1M_DMA_EQUAL 0x40 - -/* (0x41) DMA control register bits */ -#define GF1M_DMAR_ENABLE 0x01 /* 1: go */ -#define GF1M_DMAR_READ 0x02 /* 1: read (->RAM), 0: write (->DRAM) */ -#define GF1M_DMAR_CHAN16 0x04 /* 1: 16 bit, 0: 8 bit DMA channel */ -#define GF1M_DMAR_RATE 0x18 /* 00: fast, 11: slow */ -#define GF1M_DMAR_IRQ_ENABLE 0x20 /* 1: enable */ -#define GF1M_DMAR_IRQ_PENDING 0x40 /* R: DMA irq pending */ -#define GF1M_DMAR_DATA16 0x40 /* W: 0: 8 bits; 1: 16 bits per sample */ -#define GF1M_DMAR_TOGGLE_SIGN 0x80 /* W: 1: invert high bit */ - -/* DMA transfer rate divisors */ -#define GF1M_DMAR_RATE0 0x00 /* Fastest DMA xfer (~650khz) */ -#define GF1M_DMAR_RATE1 0x08 /* fastest / 2 */ -#define GF1M_DMAR_RATE2 0x10 /* fastest / 4 */ -#define GF1M_DMAR_RATE3 0x18 /* Slowest DMA xfer (fastest / 8) */ - -/* (0x45) Timer Control */ -#define GF1M_TIMER1 0x04 /* Enable timer 1 IRQ */ -#define GF1M_TIMER2 0x08 /* Enable timer 2 IRQ */ - -/* (0x49) Sampling (ADC) control register */ -#define GF1M_DMAW_ENABLE 0x01 /* 1: Start sampling */ -#define GF1M_DMAW_MODE 0x02 /* 0: mono, 1: stereo */ -#define GF1M_DMAW_CHAN16 0x04 /* 0: 8 bit, 1: 16 bit */ -#define GF1M_DMAW_IRQ_ENABLE 0x20 /* 1: enable IRQ */ -#define GF1M_DMAW_IRQ_PENDING 0x40 /* 1: irq pending */ -#define GF1M_DMAW_TOGGLE_SIGN 0x80 /* 1: invert sign bit */ - -/* (0x4C) GF1 reset register */ -#define GF1M_MASTER_RESET 0x01 /* 0: hold in reset */ -#define GF1M_OUTPUT_ENABLE 0x02 /* 1: enable output */ -#define GF1M_MASTER_IRQ 0x04 /* 1: master IRQ enable */ - -/* (0x0,0x80) Voice control register - GF1R_VOICE_CONTROL */ -#define GF1VC_STOPPED 0x01 /* 1: voice has stopped */ -#define GF1VC_STOP 0x02 /* 1: stop voice */ -#define GF1VC_DATA16 0x04 /* 0: 8 bit, 1: 16 bit */ -#define GF1VC_LOOP_ENABLE 0x08 /* 1: enable */ -#define GF1VC_BI_LOOP 0x10 /* 1: bi directional looping */ -#define GF1VC_IRQ 0x20 /* 1: enable voice's wave irq */ -#define GF1VC_BACKWARD 0x40 /* 0: increasing, 1: decreasing */ -#define GF1VC_IRQ_PENDING 0x80 /* 1: wavetable irq pending */ - -/* (0x01,0x81) Frequency control */ -/* Bit 0 - Unused */ -/* Bits 1-9 - Fractional portion */ -/* Bits 10-15 - Integer portion */ - -/* (0x02,0x82) Accumulator start address - GF1R_START_HIGH */ -/* Bits 0-11 - HIGH 12 bits of address */ -/* Bits 12-15 - Unused */ - -/* (0x03,0x83) Accumulator start address - GF1R_START_LOW */ -/* Bits 0-4 - Unused */ -/* Bits 5-8 - Fractional portion */ -/* Bits 9-15 - Low 7 bits of integer portion */ - -/* (0x04,0x84) Accumulator end address - GF1R_END_HIGH */ -/* Bits 0-11 - HIGH 12 bits of address */ -/* Bits 12-15 - Unused */ - -/* (0x05,0x85) Accumulator end address - GF1R_END_LOW */ -/* Bits 0-4 - Unused */ -/* Bits 5-8 - Fractional portion */ -/* Bits 9-15 - Low 7 bits of integer portion */ - -/* (0x06,0x86) Volume Envelope control register - GF1R_VOLUME_RATE */ -#define GF1VL_RATE_MANTISSA 0x3f -#define GF1VL_RATE_RANGE 0xC0 - -/* (0x07,0x87) Volume envelope start - GF1R_VOLUME_START */ -#define GF1VL_START_MANT 0x0F -#define GF1VL_START_EXP 0xF0 - -/* (0x08,0x88) Volume envelope end - GF1R_VOLUME_END */ -#define GF1VL_END_MANT 0x0F -#define GF1VL_END_EXP 0xF0 - -/* (0x09,0x89) Current volume register - GF1R_VOLUME */ -/* Bits 0-3 - Unused */ -/* Bits 4-11 - Mantissa of current volume */ -/* Bits 10-15 - Exponent of current volume */ - -/* (0x0A,0x8A) Accumulator value (high) */ -/* Bits 0-12 - HIGH 12 bits of current position (a19-a7) */ - -/* (0x0B,0x8B) Accumulator value (low) */ -/* Bits 0-8 - Fractional portion */ -/* Bits 9-15 - Integer portion of low adress (a6-a0) */ - -/* (0x0C,0x8C) Pan (balance) position */ -/* Bits 0-3 - Balance position 0=full left, 0x0f=full right */ - -/* (0x0D,0x8D) Volume control register - GF1R_VOLUME_CONTROL */ -#define GF1VL_STOPPED 0x01 /* volume has stopped */ -#define GF1VL_STOP 0x02 /* stop volume */ -#define GF1VL_ROLLOVER 0x04 /* Roll PAST end & gen IRQ */ -#define GF1VL_LOOP_ENABLE 0x08 /* 1: enable */ -#define GF1VL_BI_LOOP 0x10 /* 1: bi directional looping */ -#define GF1VL_IRQ 0x20 /* 1: enable voice's volume irq */ -#define GF1VL_BACKWARD 0x40 /* 0: increasing, 1: decreasing */ -#define GF1VL_IRQ_PENDING 0x80 /* 1: wavetable irq pending */ - -/* (0x0E,0x8E) Number of active voices */ -/* Bits 0-5 - Number of active voices - 1 */ - -/* (0x0F,0x8F) Sources of IRQs */ -/* Bits 0-4 - interrupting voice number */ -/* Bit 5 - Always a 1 */ -#define GF1IRQ_VOLUME 0x40 /* individual voice irq bit */ -#define GF1IRQ_WAVE 0x80 /* individual waveform irq bit */ - -/* Commands are pooled and executed ON TIMER (1st timer) interrupt. - * Currently there is a limit on the number of commands that you can - * issue between gus_do_flush (...); this should not be an issue however - * because each voice has a limited (little) set of parameters that - * you can change (freq, vol, pan... what else?) - * - * The pool is a pseudo-CPU code that gets executed once per timer interrupt. - */ - -/* Below are definitions for commands placed in GUS command pool */ -#define PCMD_NOP 0x00 /* Traditionally ... */ -#define PCMD_VOICE 0x01 /* +B: select voice */ -#define PCMD_START 0x02 /* +L: start voice */ -#define PCMD_STOP 0x03 /* stop voice */ -#define PCMD_FREQ 0x04 /* +W: set frequence */ -#define PCMD_VOLUME 0x05 /* +W: set volume */ -#define PCMD_VOLUME_PREPARE 0x06 /* +W: prepare to set volume on (soon to follow) kick */ -#define PCMD_PAN 0x07 /* +B: set panning */ -#define PCMD_OFFSET 0x08 /* +L: set DRAM offset */ -#define PCMD_STOP_LOOP 0x09 /* stop looping */ - -#define GUS_VOLCHANGE_RAMP 0x20 /* Volume change ramp speed */ - -/* Definition for the boolean type */ -typedef unsigned char boolean; -/* Prototype for functions that do block transfers to GUS DRAM: - flags can contain any of the following bits: - GUS_WAVE_16BIT - sample is 16-bit - GUS_WAVE_UNSIGNED - do not invert sign bit while downloading - */ -typedef void (*__gus_transfer_func) (unsigned long address, - unsigned char *source, - unsigned long size, int flags); -typedef void (*__gus_callback) (); -typedef void (*__gus_callback_3) (unsigned int, unsigned int, unsigned int); - -/* Structure used to keep track of all on-board GUS memory */ -typedef struct __struct_gus_mcb { - struct __struct_gus_mcb *next; /* Next MCB in chain */ - struct __struct_gus_mcb *prev; /* Previous MCB in chain */ - unsigned int addr; /* GUS DRAM address */ - unsigned int size; /* Memory block size */ - int free; /* 1: block is free */ -} __gus_mcb; - -/* Structure defining overall GUS state/information */ -typedef struct __gus_state_s { - unsigned int port; /* Base I/O port (0x220, 0x240, ...) */ - unsigned int irq[2]; /* GF1 IRQ and MIDI IRQ */ - unsigned int dma[2]; /* Play / record DMA */ - unsigned int ram; /* Memory size (K), i.e. 256, 1024 etc */ - unsigned int version; /* GUS version (see GUS_CARD_VERSION_XXX in libgus.h */ - unsigned int freq; /* Current mixing frequency */ - unsigned int voices; /* Active voices (14-32) */ - unsigned int dynmask; /* Dynamically allocated voices mask */ - unsigned int timer_base; /* The relative timer speed in percents (def: 100) */ - volatile unsigned int t1_ticks; /* Incremented per each timer1 tick */ - volatile unsigned int t2_ticks; /* Incremented per each timer2 tick */ - volatile unsigned int t1_countdown; /* t1_callback is called when this reaches zero */ - volatile unsigned int t2_countdown; /* t2_callback is called when this reaches zero */ - unsigned int t1_multiple; /* Timer1 handler is called once per such many ticks */ - unsigned int t2_multiple; /* Timer2 handler is called once per such many ticks */ - struct irq_handle *gf1_irq; /* The interrupt handler for GF1 events */ - dma_buffer *dma_buff; /* Pre-allocated DMA buffer */ - __gus_callback dma_callback; /* Routine called at end of DMA transfers */ - __gus_callback t1_callback; /* Routine called on Timer1 events */ - __gus_callback t2_callback; /* Routine called on Timer1 events */ - __gus_callback timer_callback; /* Called once per TEMPO ticks */ - __gus_callback_3 wt_callback; /* Routine called on WaveTable events */ - __gus_callback_3 vl_callback; /* Routine called on Volume ramp events */ - __gus_mcb *mcb; /* Chained list of memory control blocks */ - __gus_transfer_func transfer; /* Best working function for DRAM transfer */ - gus_instrument_t *instr; /* The list of registered instruments */ - unsigned short mixer; /* Current mixer register state */ - unsigned char dma_rate; /* One of GF1M_DMAR_RATEX constants defined above */ - unsigned char timer_ctl; /* Timer control register value (2x8/2x9) */ - unsigned char timer_ctl_reg; /* Timer control register value (GF1/0x45) */ - boolean ok; /* Is the information below okay? */ - boolean open; /* 1 if between gus_open() and gus_close() */ - boolean ics; /* Is it equipped with an ICS mixer? */ - boolean ics_flipped; /* rev 5 (3.7) has flipped R/L mixer */ - boolean codec; /* Is it equipped with a GUS MAX codec? */ - boolean interwave; /* GUS InterWave card */ - volatile boolean dma_active; /* DMA is transferring data */ - volatile boolean cmd_pool_ready; /* Flush cmd_pool during timer interrupt */ - unsigned char cmd_voice; /* Pool selection index cache */ - unsigned int cmd_pool_top; /* Command pool top */ - unsigned char *cmd_pool; /* Async commands pool */ - /* The following data is for private use only by interrupt routines! */ - gus_wave_t *cur_wave[32]; /* Currently played waves */ - boolean voice_kick[32]; /* Kick wave on next volume ramp IRQ */ - unsigned int kick_offs[32]; /* Sample start position on kick */ - unsigned short cur_vol[32]; /* Current voice volumes */ - unsigned int cur_voice; /* Current voice */ - unsigned int eow_ignore; /* Temp ignore end-of-wave IRQ for these voices */ -} __gus_state; - -extern __gus_state gus; -extern void __gus_delay(); - -static unsigned long __gus_convert_addr16(unsigned long address) -{ - return ((address & 0x0003ffff) >> 1) | (address & ~0x0003ffff); -} - -/* The XXX_slow routines cannot be used outside IRQ handler! */ -static inline void __gus_outregb_slow(unsigned char reg, unsigned char value) -{ - outportb(GF1_REGSEL, reg); - outportb(GF1_DATA_HIGH, value); - __gus_delay(); - outportb(GF1_DATA_HIGH, value); -} - -static inline void __gus_outregw_slow(unsigned char reg, unsigned short value) -{ - outportb(GF1_REGSEL, reg); - outportw(GF1_DATA, value); - __gus_delay(); - outportw(GF1_DATA, value); -} - -static inline void __gus_outregb(unsigned char reg, unsigned char value) -{ - outportb(GF1_REGSEL, reg); - outportb(GF1_DATA_HIGH, value); -} - -static inline void __gus_outregw(unsigned char reg, unsigned short value) -{ - outportb(GF1_REGSEL, reg); - outportw(GF1_DATA, value); -} - -static inline unsigned char __gus_inregb(unsigned char reg) -{ - if (reg < 0x10) - reg |= GF1R_READ_MASK; - outportb(GF1_REGSEL, reg); - return inportb(GF1_DATA_HIGH); -} - -static inline unsigned short __gus_inregw(unsigned char reg) -{ - if (reg < 0x10) - reg |= GF1R_READ_MASK; - outportb(GF1_REGSEL, reg); - return inportw(GF1_DATA); -} - -static inline void __gus_set_dram_address(unsigned int address) -{ - __gus_outregb(GF1R_DRAM_HIGH, address >> 16); - __gus_outregw(GF1R_DRAM_LOW, address); -} - -static inline unsigned char __gus_peek(unsigned int address) -{ - __gus_set_dram_address(address); - return inportb(GF1_DRAM); -} - -static inline void __gus_poke(unsigned int address, unsigned char value) -{ - __gus_set_dram_address(address); - outportb(GF1_DRAM, value); -} - -static inline void __gus_select_voice(unsigned char voice) -{ - outportb(GF1_VOICESEL, voice); -} - -static inline void __gus_set_current(unsigned char mode, - unsigned long address) -{ - if (mode & GF1VC_DATA16) - address = __gus_convert_addr16(address); - __gus_outregw_slow(GF1R_ACC_HIGH, address >> 11); - __gus_outregw_slow(GF1R_ACC_LOW, address << 5); -} - -static inline void __gus_set_loop_start(unsigned char mode, - unsigned long address) -{ - if (mode & GF1VC_DATA16) - address = __gus_convert_addr16(address); - __gus_outregw_slow(GF1R_START_HIGH, address >> 11); - __gus_outregw_slow(GF1R_START_LOW, address << 5); -} - -static inline void __gus_set_loop_end(unsigned char mode, - unsigned long address) -{ - address--; - if (mode & GF1VC_DATA16) - address = __gus_convert_addr16(address); - __gus_outregw_slow(GF1R_END_HIGH, address >> 11); - __gus_outregw_slow(GF1R_END_LOW, address << 5); -} - -static inline void __gus_mixer_output(boolean state) -{ - if (state) - gus.mixer &= ~GF1M_MIXER_NO_OUTPUT; - else - gus.mixer |= GF1M_MIXER_NO_OUTPUT; - outportb(GF1_MIX_CTRL, gus.mixer); - /* Dummy read to avoid touching DMA latches */ - __gus_inregb(GF1R_BALANCE); -} - -/* Inline routines for working with command pools */ - -/* WARNING: no bounds checking due to performance reasons */ -#define __POOL_VALUE(type,value) \ - *((unsigned type *)&gus.cmd_pool [gus.cmd_pool_top]) = value; \ - gus.cmd_pool_top += sizeof (type); - -static inline void __pool_command(unsigned char command) -{ - __POOL_VALUE(char, command); -} - -static inline void __pool_command_b(unsigned char command, unsigned char arg) -{ - __POOL_VALUE(char, command); - __POOL_VALUE(char, arg); -} - -static inline void __pool_command_w(unsigned char command, unsigned short arg) -{ - __POOL_VALUE(char, command); - __POOL_VALUE(short, arg); -} - -static inline void __pool_command_l(unsigned char command, unsigned long arg) -{ - __POOL_VALUE(char, command); - __POOL_VALUE(long, arg); -} - -static inline void __pool_select_voice(unsigned char voice) -{ - if (gus.cmd_voice != voice) - __pool_command_b(PCMD_VOICE, gus.cmd_voice = voice); -} - -#undef __POOL_VALUE - -#ifdef DEBUG -/* Debug dump of GUS DRAM heap */ -extern void __gus_mem_dump(); -#endif - -#endif /* __DOSGUS_H__ */ - -/* ex:set ts=4: */