mirror of
https://github.com/chocolate-doom/research.git
synced 2024-11-29 15:32:34 +00:00
58512f18d4
Subversion-branch: /research Subversion-revision: 1480
110 lines
1.8 KiB
C
110 lines
1.8 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
#include <sys/io.h>
|
|
|
|
#define HEADER_STRING "DBRAWOPL"
|
|
#define ADLIB_PORT 0x388
|
|
|
|
void write_reg(unsigned int reg, unsigned int val)
|
|
{
|
|
int i;
|
|
|
|
outb(reg, ADLIB_PORT);
|
|
|
|
for (i=0; i<6; ++i) {
|
|
inb(ADLIB_PORT);
|
|
}
|
|
|
|
outb(val, ADLIB_PORT + 1);
|
|
|
|
for (i=0; i<35; ++i) {
|
|
inb(ADLIB_PORT);
|
|
}
|
|
}
|
|
|
|
|
|
void init(void)
|
|
{
|
|
if (ioperm(ADLIB_PORT, 2, 1) != 0)
|
|
{
|
|
fprintf(stderr, "Failed to get IO permissions\n");
|
|
exit(-1);
|
|
}
|
|
|
|
write_reg(4, 0x60);
|
|
write_reg(4, 0x80);
|
|
int val1 = inb(ADLIB_PORT) & 0xe0;
|
|
write_reg(2, 0xff);
|
|
write_reg(4, 0x21);
|
|
sleep(1);
|
|
int val2 = inb(ADLIB_PORT) & 0xe0;
|
|
write_reg(4, 0x60);
|
|
write_reg(4, 0x80);
|
|
|
|
if (val1 != 0 || val2 != 0xc0)
|
|
{
|
|
fprintf(stderr, "Adlib not detected\n");
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
void play_file(char *filename)
|
|
{
|
|
FILE *stream;
|
|
char buf[8];
|
|
|
|
stream = fopen(filename, "rb");
|
|
|
|
fread(buf, 1, 8, stream);
|
|
|
|
if (strncmp(buf, HEADER_STRING, 8) != 0)
|
|
{
|
|
fprintf(stderr, "Raw OPL header not found\n");
|
|
exit(-1);
|
|
}
|
|
|
|
fseek(stream, 28, SEEK_SET);
|
|
|
|
while (!feof(stream))
|
|
{
|
|
int reg, val;
|
|
|
|
reg = fgetc(stream);
|
|
val = fgetc(stream);
|
|
|
|
// Delay?
|
|
|
|
if (reg == 0x00)
|
|
{
|
|
usleep(val * 1000);
|
|
}
|
|
else if (reg == 0x01)
|
|
{
|
|
val |= (fgetc(stream) << 8);
|
|
usleep(val * 1000);
|
|
}
|
|
else
|
|
{
|
|
write_reg(reg, val);
|
|
}
|
|
}
|
|
|
|
fclose(stream);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
init();
|
|
|
|
if (argc < 2)
|
|
{
|
|
printf("Usage: %s <filename>\n", argv[0]);
|
|
exit(-1);
|
|
}
|
|
|
|
play_file(argv[1]);
|
|
|
|
}
|
|
|