#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include "emuxki.h"
#include "io.h"
#include "debug.h"
#include "midi_driver.h"
#include "util.h"
extern generic_mpu401_module * mpu401;
void
midi_interrupt_op(
int32 op,
void * data)
{
cpu_status status;
midi_dev * port = (midi_dev *)data;
LOG(("mpu401:midi_interrupt_op %x\n",op));
LOG(("port = %p\n", port));
if (op == B_MPU_401_ENABLE_CARD_INT) {
LOG(("emuxki: B_MPU_401_ENABLE_CARD_INT\n"));
status = lock();
emuxki_reg_write_32(&(port->card->config), EMU_INTE,
emuxki_reg_read_32(&(port->card->config), EMU_INTE) | EMU_INTE_MIDIRXENABLE );
unlock(status);
LOG(("INTE address: %x\n",&port->card->config));
}
else if (op == B_MPU_401_DISABLE_CARD_INT) {
LOG(("emuxki: B_MPU_401_DISABLE_CARD_INT\n"));
status = lock();
emuxki_reg_write_32(&port->card->config, EMU_INTE,
emuxki_reg_read_32(&port->card->config, EMU_INTE) & ~ EMU_INTE_MIDIRXENABLE);
unlock(status);
}
LOG(("midi_interrupt_op() done\n"));
}
static status_t midi_open(const char *name, uint32 flags, void **cookie);
static status_t midi_close(void *cookie);
static status_t midi_free(void *cookie);
static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
device_hooks midi_hooks = {
&midi_open,
&midi_close,
&midi_free,
&midi_control,
&midi_read,
&midi_write,
NULL,
NULL,
NULL,
NULL
};
static status_t
midi_open(
const char * name,
uint32 flags,
void ** cookie)
{
int ix;
int ret;
LOG(("midi_open()\n"));
*cookie = NULL;
for (ix=0; ix<num_cards; ix++) {
if (!strcmp(name, cards[ix].midi.name)) {
break;
}
}
if (ix >= num_cards) {
LOG(("bad device\n"));
return ENODEV;
}
LOG(("mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi.driver));
ret = (*mpu401->open_hook)(cards[ix].midi.driver, flags, cookie);
if (ret >= B_OK) {
cards[ix].midi.cookie = *cookie;
atomic_add(&cards[ix].midi.count, 1);
}
LOG(("mpu401: open returns %x / %p\n", ret, *cookie));
return ret;
}
static status_t
midi_close(
void * cookie)
{
LOG(("midi_close()\n"));
return (*mpu401->close_hook)(cookie);
}
static status_t
midi_free(
void * cookie)
{
int ix;
status_t f;
LOG(("midi_free()\n"));
f = (*mpu401->free_hook)(cookie);
for (ix=0; ix<num_cards; ix++) {
if (cards[ix].midi.cookie == cookie) {
if (atomic_add(&cards[ix].midi.count, -1) == 1) {
cards[ix].midi.cookie = NULL;
LOG(("cleared %p card %d\n", cookie, ix));
}
break;
}
}
LOG(("midi_free() done\n"));
return f;
}
static status_t
midi_control(
void * cookie,
uint32 iop,
void * data,
size_t len)
{
return (*mpu401->control_hook)(cookie, iop, data, len);
}
static status_t
midi_read(
void * cookie,
off_t pos,
void * ptr,
size_t * nread)
{
return (*mpu401->read_hook)(cookie, pos, ptr, nread);
}
static status_t
midi_write(
void * cookie,
off_t pos,
const void * ptr,
size_t * nwritten)
{
return (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
}
bool
midi_interrupt(emuxki_dev *card)
{
TRACE(("midi_interrupt\n"));
if (!card->midi.driver) {
dprintf("aiigh\n");
return false;
}
return (*mpu401->interrupt_hook)(card->midi.driver);
}