📄 ibmsb.c
字号:
/* IbmSb.c
This file is part of the VGB-DOS project
Copyright (C) Marcel de Kogel (m.dekogel@student.utwente.nl), 1996
You may not use this file for commercial purposes
Please notify me if you make any changes to this file */
/* Currently, the SB is only used for volume control */
#include "GB.h"
#include "IbmMsDos.h"
byte mastervolume=10;
#include <stdlib.h>
#include <go32.h>
#include <dpmi.h>
#include <string.h>
#include <stdio.h>
#include <dos.h>
#include <pc.h>
#include <sys/farptr.h>
static int got_sb=0;
static int sb16=0;
static unsigned sb_dsp_version;
static word sb_port;
static byte sb_dma_channel;
static byte sb_irq;
static byte sb_irq_int;
static byte OldDacVolume[2],OldFmVolume[2],OldMasterVolume[2];
extern int stereomode;
static int sb_read_dsp()
{
int x;
for (x=0; x<0xffff; x++)
if (inportb(0x0E + sb_port) & 0x80)
return inportb(0x0A+sb_port);
return -1;
}
static int sb_write_dsp(byte val)
{
int x;
for (x=0; x<0xffff; x++)
{
if (!(inportb(0x0C+sb_port) & 0x80))
{
outportb(0x0C+sb_port, val);
return 1;
}
}
return 0;
}
static void sb_write_mixer (byte reg,byte val)
{
outportb(sb_port+4, reg);
outportb(sb_port+5, val);
}
static byte sb_read_mixer (byte reg)
{
outportb(sb_port+4, reg);
return inportb(sb_port+5);
}
static void sb_setmastervolume (void)
{
if (mastervolume>15)
mastervolume=15;
if (sb16)
{
sb_write_mixer (0x30,mastervolume<<4);
sb_write_mixer (0x31,mastervolume<<4);
}
else
sb_write_mixer (0x22,mastervolume|(mastervolume<<4));
}
static void sb_setvolumes()
{
if (sb16)
{
OldMasterVolume[0]=sb_read_mixer (0x30);
OldMasterVolume[1]=sb_read_mixer (0x31);
OldDacVolume[0]=sb_read_mixer (0x32);
OldDacVolume[1]=sb_read_mixer (0x33);
OldFmVolume[0]=sb_read_mixer (0x34);
OldFmVolume[1]=sb_read_mixer (0x35);
sb_write_mixer (0x32,0);
sb_write_mixer (0x33,0);
sb_write_mixer (0x34,0xFF);
sb_write_mixer (0x35,0xFF);
}
else
{
OldMasterVolume[0]=sb_read_mixer (0x22);
OldDacVolume[0]=sb_read_mixer (4);
OldFmVolume[0]=sb_read_mixer (0x26);
sb_write_mixer (4,0);
sb_write_mixer (0x26,0xFF);
}
sb_setmastervolume ();
}
void sb_setfmvolume (int left,int right)
{
int tmp;
if (left>15)
left=15;
if (right>15)
right=15;
switch (stereomode)
{
case 0:
left=right=(left+right)/2;
break;
case 1:
break;
default:
tmp=left; left=right; right=tmp;
break;
}
if (sb16)
{
sb_write_mixer (0x34,left<<4);
sb_write_mixer (0x35,right<<4);
}
else
sb_write_mixer (0x26,(left<<4)|right);
}
static void sb_resetvolumes(void)
{
if (mastervolume>15)
mastervolume=15;
if (sb16)
{
sb_write_mixer (0x30,OldMasterVolume[0]);
sb_write_mixer (0x31,OldMasterVolume[1]);
sb_write_mixer (0x32,OldDacVolume[0]);
sb_write_mixer (0x33,OldDacVolume[1]);
sb_write_mixer (0x34,OldFmVolume[0]);
sb_write_mixer (0x35,OldFmVolume[1]);
}
else
{
sb_write_mixer (0x22,OldMasterVolume[0]);
sb_write_mixer (4,OldDacVolume[0]);
sb_write_mixer (0x26,OldFmVolume[0]);
}
}
void sb_increasemastervolume (void)
{
if (mastervolume==15)
return;
++mastervolume;
sb_setmastervolume ();
}
void sb_decreasemastervolume (void)
{
if (mastervolume==0)
return;
--mastervolume;
sb_setmastervolume ();
}
static int sb_reset_dsp()
{
int i;
for (i=0;i<16;++i)
{
outportb(0x06+sb_port, 1);
inportb (0x06+sb_port);
inportb (0x06+sb_port);
inportb (0x06+sb_port);
inportb (0x06+sb_port);
outportb(0x06+sb_port, 0);
if (sb_read_dsp() == 0xAA)
return 1;
}
return 0;
}
static unsigned sb_read_dsp_version()
{
unsigned hi, lo;
sb_write_dsp(0xE1);
hi = sb_read_dsp();
lo = sb_read_dsp();
return ((hi << 8) + lo);
}
static int sb_detect()
{
sb_port=SB_Info.baseport;
sb_dma_channel=SB_Info.dma_low;
sb_irq=SB_Info.irq;
sb_irq_int=(sb_irq<8)? sb_irq+8 : sb_irq+0x70-8;
if (sb_port==0)
return 0;
if (!sb_reset_dsp())
return 0;
sb_dsp_version=sb_read_dsp_version();
if (sb_dsp_version<0x300)
return 0;
if (sb_dsp_version>=0x400)
sb16=1;
return 1;
}
int sb_init(void)
{
if (!sb_detect())
return 0;
sb_setvolumes ();
got_sb=1;
return 1+sb16;
}
void sb_exit(void)
{
if (!got_sb)
return;
sb_resetvolumes ();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -