| /* | |
| * SoundBlaster DSP code | |
| * This file is part of the DOSMid project | |
| * Copyright (C) Mateusz Viste 2015 | |
| */ | |
| #include <conio.h> /* inp() and outp() */ | |
| #include "timer.h" | |
| #include "sbdsp.h" /* include self for control */ | |
| /* convenience defines for the I/O addresses of the SoundBlaster */ | |
| #define IO_RESET (port+0x06) | |
| #define IO_READ (port+0x0A) | |
| #define IO_WRITE (port+0x0C) | |
| #define IO_WRSTAT (port+0x0C) | |
| #define IO_RDSTAT (port+0x0E) | |
| /* high resolution sleeping routine, waits n microseconds */ | |
| static void udelay(unsigned long us) { | |
| unsigned long t1, t2; | |
| timer_read(&t1); | |
| for (;;) { | |
| timer_read(&t2); | |
| if (t2 < t1) { /* detect timer wraparound */ | |
| break; | |
| } else if (t2 - t1 >= us) { | |
| break; | |
| } | |
| } | |
| } | |
| int dsp_reset(unsigned short port) { | |
| /* 1. Write a "1" to the Reset port (2x6h) and wait for 3 microseconds. | |
| * 2. Write a "0" to the Reset port. | |
| * 3. Poll for a ready byte 0AAh from the Read Data port. You must check the | |
| * the Read-Buffer Status port to ensure there is data before reading the | |
| * Read Data port. */ | |
| int x, timeout; | |
| outp(IO_RESET, 1); | |
| udelay(2000); /* wait 2 ms */ | |
| outp(IO_RESET, 0); | |
| /* wait for the DSP to give us the green light - no longer than 50ms (the | |
| * SoundBlaster docs state that the DSP should init in about 100us) */ | |
| for (timeout = 50; timeout != 0; timeout--) { | |
| udelay(1000); /* wait 1 ms */ | |
| /* check that we got something on the data port */ | |
| x = dsp_read(port); | |
| if (x < 0) continue; /* nothing available yet */ | |
| if (x == 0xAA) return(0); /* 0xAA means 'OK' */ | |
| return(-1); /* otherwise there's a problem */ | |
| } | |
| /* if we are here, then a timeout occured */ | |
| return(-1); | |
| } | |
| int dsp_read(unsigned short port) { | |
| /* When DSP data is available, it can be read in from the Read Data port. | |
| * Before the data is read in, bit-7 of the Read-Buffer Status port must be | |
| * checked to ensure that there is data to read. If bit-7 is 1, then there | |
| * is data to read. Otherwise, no data is available. */ | |
| if ((inp(IO_RDSTAT) & 128) == 0) return(-1); /* nothing to read */ | |
| return(inp(IO_READ)); | |
| } | |
| void dsp_write(unsigned short port, int databyte) { | |
| /* DSP commands and data are sent through the Write Command/Data port. | |
| * Before data is written to the DSP, bit-7 of the Write-Buffer Status port | |
| * must be checked to ensure that the DSP command/data buffer is empty. If | |
| * bit-7 is 0, the DSP buffer is empty and is ready to receive commands or | |
| * data. Otherwise, no commands or data should be written to the DSP. */ | |
| while ((inp(IO_WRSTAT) & 128) != 0); /* wait for the 'write' buffer to become available */ | |
| outp(IO_WRITE, databyte); | |
| } |