Intel AC97

(Currently not functional)
This commit is contained in:
Jasmine Iwanek
2022-08-10 17:48:32 -04:00
parent f58cbb2856
commit b362358285
4 changed files with 261 additions and 2 deletions

View File

@@ -0,0 +1,54 @@
/*
* Intel AC'97 Header
*
* Authors: Tiseno100,
*
* Copyright 2022 Tiseno100.
*/
/*
* Note: The Intel AC'97 code is divided into three parts
*
* 1. intel_ac97.c The main AC'97 code handling configuration.
* 3. intel_ac97_buffer.c The AC'97 buffer
*
*
* The general AC'97 configures the buffer base address and capabilities like channels, reset, interrupts etc.
* The AC'97 buffer is where all playback happens.
*/
#ifndef EMU_INTEL_AC97_H
# define EMU_INTEL_AC97_H
#ifdef __cplusplus
extern "C" {
#endif
#include <86box/mem.h>
#include <86box/snd_ac97.h>
typedef struct intel_ac97_t
{
uint16_t ac97_base;
uint16_t mixer_base;
uint32_t buffer_base;
uint8_t regs[256];
int irq;
ac97_codec_t *mixer;
mem_mapping_t *buffer_location;
} intel_ac97_t;
/* AC'97 Configuration */
extern void intel_ac97_base(int enable, uint16_t addr, intel_ac97_t *dev);
extern void intel_ac97_mixer_base(int enable, uint16_t addr, intel_ac97_t *dev);
extern void intel_ac97_set_irq(int irq, intel_ac97_t *dev);
extern const device_t intel_ac97_device;
extern const device_t intel_ac97_mixer_device;
#ifdef __cplusplus
}
#endif
#endif /*EMU_INTEL_AC97_H*/

View File

@@ -14,7 +14,7 @@
#
add_library(snd OBJECT sound.c snd_opl.c snd_opl_nuked.c snd_opl_ymfm.cpp snd_resid.cc
midi.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_via.c
midi.c snd_speaker.c snd_pssj.c snd_lpt_dac.c snd_ac97_codec.c snd_ac97_intel.c snd_ac97_via.c
snd_lpt_dss.c snd_ps1.c snd_adlib.c snd_adlibgold.c snd_ad1848.c snd_audiopci.c
snd_azt2316a.c snd_cms.c snd_cmi8x38.c snd_cs423x.c snd_gus.c snd_sb.c snd_sb_dsp.c
snd_emu8k.c snd_mpu401.c snd_sn76489.c snd_ssi2001.c snd_wss.c snd_ym7128.c)

205
src/sound/snd_ac97_intel.c Normal file
View File

@@ -0,0 +1,205 @@
/*
* Intel AC'97
*
* Authors: Tiseno100,
*
* Copyright 2022 Tiseno100.
*/
/*
* Buffers, AC-Link and other things require understanding.
* But I also need a functional board with AC'97 to continue.
*/
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#define HAVE_STDARG_H
#include <86box/86box.h>
#include "cpu.h"
#include <86box/timer.h>
#include <86box/io.h>
#include <86box/device.h>
#include <86box/snd_ac97.h>
#include <86box/snd_ac97_intel.h>
#ifdef ENABLE_INTEL_AC97_LOG
int intel_ac97_do_log = ENABLE_INTEL_AC97_LOG;
static void
intel_ac97_log(const char *fmt, ...)
{
va_list ap;
if (intel_ac97_do_log) {
va_start(ap, fmt);
pclog_ex(fmt, ap);
va_end(ap);
}
}
#else
#define intel_ac97_log(fmt, ...)
#endif
/* Mixer Configuration */
static void
intel_ac97_mixer_write(uint16_t addr, uint16_t val, void *priv)
{
intel_ac97_t *dev = (intel_ac97_t *) priv;
addr -= dev->mixer_base;
ac97_codec_writew(dev->mixer, addr, val);
}
static uint16_t
intel_ac97_mixer_read(uint16_t addr, void *priv)
{
intel_ac97_t *dev = (intel_ac97_t *) priv;
addr -= dev->mixer_base;
return ac97_codec_readw(dev->mixer, addr);
}
void
intel_ac97_mixer_base(int enable, uint16_t addr, intel_ac97_t *dev)
{
if(dev->mixer_base != 0)
io_removehandler(dev->mixer_base, 256, NULL, intel_ac97_mixer_read, NULL, NULL, intel_ac97_mixer_write, NULL, dev);
intel_ac97_log("Intel AC'97 Mixer: Base has been set on 0x%x\n", addr);
dev->mixer_base = addr;
if((addr != 0) && enable)
io_sethandler(addr, 256, NULL, intel_ac97_mixer_read, NULL, NULL, intel_ac97_mixer_write, NULL, dev);
}
/* AC'97 Configuration */
void
intel_ac97_set_irq(int irq, intel_ac97_t *dev)
{
intel_ac97_log("Intel AC'97: IRQ Base was set to %d\n");
dev->irq = irq;
}
static void
intel_ac97_write(uint16_t addr, uint8_t val, void *priv)
{
intel_ac97_t *dev = (intel_ac97_t *) priv;
addr -= dev->ac97_base;
intel_ac97_log("Intel AC'97: dev->regs[%02x] = %02x\n", addr, val);
switch(addr)
{
case 0x10 ... 0x13: /* Buffer BAR */
dev->regs[addr] = val;
break;
case 0x15: /* Last Valid Index */
dev->regs[addr] &= val;
break;
case 0x16: /* Status */
dev->regs[addr] &= val;
break;
case 0x1b: /* Control */
dev->regs[addr] = val & 0x1f;
break;
case 0x2c: /* Global Control */
dev->regs[addr] = val & 0x3f;
break;
case 0x2e: /* Global Control */
dev->regs[addr] = val & 0x30;
break;
case 0x34: /* Codec Access Semaphore */
dev->regs[addr] = val & 1;
break;
}
}
static uint8_t
intel_ac97_read(uint16_t addr, void *priv)
{
intel_ac97_t *dev = (intel_ac97_t *) priv;
addr -= dev->ac97_base;
if(addr < 0x40) {
intel_ac97_log("Intel AC'97: dev->regs[%02x] (%02x)\n", addr, dev->regs[addr]);
return dev->regs[addr];
}
else
return 0xff;
}
void
intel_ac97_base(int enable, uint16_t addr, intel_ac97_t *dev)
{
if(dev->ac97_base != 0)
io_removehandler(dev->ac97_base, 64, intel_ac97_read, NULL, NULL, intel_ac97_write, NULL, NULL, dev);
intel_ac97_log("Intel AC'97: Base has been set on 0x%x\n", addr);
dev->ac97_base = addr;
if((addr != 0) && enable)
io_sethandler(addr, 64, intel_ac97_read, NULL, NULL, intel_ac97_write, NULL, NULL, dev);
}
static void
intel_ac97_reset(void *priv)
{
intel_ac97_t *dev = (intel_ac97_t *) priv;
memset(dev->regs, 0, sizeof(dev->regs)); /* Wash out the registers */
// We got nothing here yet
}
static void
intel_ac97_close(void *priv)
{
intel_ac97_t *dev = (intel_ac97_t *) priv;
free(dev);
}
static void *
intel_ac97_init(const device_t *info)
{
intel_ac97_t *dev = (intel_ac97_t *) malloc(sizeof(intel_ac97_t));
memset(dev, 0, sizeof(intel_ac97_t));
intel_ac97_log("Intel AC'97: Started!\n");
// We got nothing here yet
dev->mixer = device_add(&ad1881_device); /* Add a mixer with no real functionality for now */
return dev;
}
const device_t intel_ac97_device = {
.name = "Intel AC'97 Version 2.1",
.internal_name = "intel_ac97",
.flags = 0,
.local = 0,
.init = intel_ac97_init,
.close = intel_ac97_close,
.reset = intel_ac97_reset,
{ .available = NULL },
.speed_changed = NULL,
.force_redraw = NULL,
.config = NULL
};

View File

@@ -690,7 +690,7 @@ SNDOBJ := sound.o \
snd_ps1.o \
snd_lpt_dac.o snd_lpt_dss.o \
snd_adlib.o snd_adlibgold.o snd_ad1848.o snd_audiopci.o \
snd_ac97_codec.o snd_ac97_via.o \
snd_ac97_codec.o snd_ac97_intel.o snd_ac97_via.o \
snd_azt2316a.o snd_cs423x.o snd_cmi8x38.o \
snd_cms.o \
snd_gus.o \