⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ibmsb.c

📁 知名gba模拟器vgba代码
💻 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 + -