Added preliminary MPU-401 emulation (UART mode only) for SB16. Currently outputs to default Windows MIDI device. This allows Windows 3.x SB16 drivers to work.
This commit is contained in:
parent
f822488656
commit
b9062a1d0c
7 changed files with 152 additions and 15 deletions
|
|
@ -9,17 +9,17 @@ OBJ = 386.o 808x.o acer386sx.o ali1429.o amstrad.o cdrom-ioctl.o \
|
|||
keyboard_olim24.o keyboard_xt.o lpt.o mcr.o mem.o model.o \
|
||||
mouse.o mouse_ps2.o mouse_serial.o neat.o nvr.o olivetti_m24.o \
|
||||
opti.o pc.o pci.o pic.o piix.o pit.o ppi.o serial.o sound.o sound_adlib.o \
|
||||
sound_adlibgold.o sound_cms.o sound_gus.o sound_opl.o sound_pas16.o sound_sb.o \
|
||||
sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_wss.o soundopenal.o timer.o \
|
||||
um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
||||
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o \
|
||||
vid_et4000.o vid_et4000w32.o vid_et4000w32i.o vid_hercules.o vid_icd2061.o \
|
||||
vid_ics2595.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o \
|
||||
vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \
|
||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tkd8001_ramdac.o \
|
||||
vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o video.o wd76c10.o \
|
||||
win.o win-ddraw.o win-keyboard.o win-mouse.o win-timer.o win-video.o \
|
||||
x86seg.o x87.o xtide.o pc.res
|
||||
sound_adlibgold.o sound_cms.o sound_gus.o sound_mpu401_uart.o sound_opl.o \
|
||||
sound_pas16.o sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o \
|
||||
sound_wss.o soundopenal.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o \
|
||||
vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \
|
||||
vid_cl5429.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_et4000w32i.o \
|
||||
vid_hercules.o vid_icd2061.o vid_ics2595.o vid_mda.o vid_olivetti_m24.o \
|
||||
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o \
|
||||
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
|
||||
vid_tandy.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
|
||||
vid_voodoo.o video.o wd76c10.o win.o win-ddraw.o win-keyboard.o win-midi.o \
|
||||
win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||
FMOBJ = fmopl.o ymf262.o
|
||||
|
||||
|
||||
|
|
|
|||
3
src/plat-midi.h
Normal file
3
src/plat-midi.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
void midi_init();
|
||||
void midi_close();
|
||||
void midi_out(uint8_t val);
|
||||
57
src/sound_mpu401_uart.c
Normal file
57
src/sound_mpu401_uart.c
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#include "ibm.h"
|
||||
#include "io.h"
|
||||
#include "sound_mpu401_uart.h"
|
||||
|
||||
enum
|
||||
{
|
||||
STATUS_OUTPUT_NOT_READY = 0x40,
|
||||
STATUS_INPUT_NOT_READY = 0x80
|
||||
};
|
||||
|
||||
static void mpu401_uart_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
mpu401_uart_t *mpu = (mpu401_uart_t *)p;
|
||||
|
||||
if (addr & 1) /*Command*/
|
||||
{
|
||||
switch (val)
|
||||
{
|
||||
case 0xff: /*Reset*/
|
||||
mpu->rx_data = 0xfe; /*Acknowledge*/
|
||||
mpu->status = 0;
|
||||
mpu->uart_mode = 0;
|
||||
break;
|
||||
|
||||
case 0x3f: /*Enter UART mode*/
|
||||
mpu->rx_data = 0xfe; /*Acknowledge*/
|
||||
mpu->status = 0;
|
||||
mpu->uart_mode = 1;
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*Data*/
|
||||
if (mpu->uart_mode)
|
||||
midi_out(val);
|
||||
}
|
||||
|
||||
static uint8_t mpu401_uart_read(uint16_t addr, void *p)
|
||||
{
|
||||
mpu401_uart_t *mpu = (mpu401_uart_t *)p;
|
||||
|
||||
if (addr & 1) /*Status*/
|
||||
return mpu->status;
|
||||
|
||||
/*Data*/
|
||||
mpu->status |= STATUS_INPUT_NOT_READY;
|
||||
return mpu->rx_data;
|
||||
}
|
||||
|
||||
void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr)
|
||||
{
|
||||
mpu->status = STATUS_INPUT_NOT_READY;
|
||||
mpu->uart_mode = 0;
|
||||
|
||||
io_sethandler(addr, 0x0002, mpu401_uart_read, NULL, NULL, mpu401_uart_write, NULL, NULL, mpu);
|
||||
}
|
||||
9
src/sound_mpu401_uart.h
Normal file
9
src/sound_mpu401_uart.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
typedef struct mpu401_uart_t
|
||||
{
|
||||
uint8_t status;
|
||||
uint8_t rx_data;
|
||||
|
||||
int uart_mode;
|
||||
} mpu401_uart_t;
|
||||
|
||||
void mpu401_uart_init(mpu401_uart_t *mpu, uint16_t addr);
|
||||
|
|
@ -1,9 +1,10 @@
|
|||
#include <stdlib.h>
|
||||
#include "ibm.h"
|
||||
#include "device.h"
|
||||
#include "sound_mpu401_uart.h"
|
||||
#include "sound_opl.h"
|
||||
#include "sound_sb.h"
|
||||
#include "sound_sb_dsp.h"
|
||||
#include "sound_opl.h"
|
||||
|
||||
#include "filters.h"
|
||||
|
||||
|
|
@ -22,9 +23,10 @@ typedef struct sb_mixer_t
|
|||
|
||||
typedef struct sb_t
|
||||
{
|
||||
opl_t opl;
|
||||
sb_dsp_t dsp;
|
||||
sb_mixer_t mixer;
|
||||
opl_t opl;
|
||||
sb_dsp_t dsp;
|
||||
sb_mixer_t mixer;
|
||||
mpu401_uart_t mpu;
|
||||
|
||||
int16_t opl_buffer[SOUNDBUFLEN * 2];
|
||||
int16_t dsp_buffer[SOUNDBUFLEN * 2];
|
||||
|
|
@ -336,6 +338,7 @@ void *sb_16_init()
|
|||
io_sethandler(0x0388, 0x0002, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &sb->opl);
|
||||
io_sethandler(0x0224, 0x0002, sb_16_mixer_read, NULL, NULL, sb_16_mixer_write, NULL, NULL, sb);
|
||||
sound_add_handler(sb_opl3_poll, sb_get_buffer, sb);
|
||||
mpu401_uart_init(&sb->mpu, 0x330);
|
||||
|
||||
sb->mixer.regs[0x30] = 31 << 3;
|
||||
sb->mixer.regs[0x31] = 31 << 3;
|
||||
|
|
|
|||
62
src/win-midi.c
Normal file
62
src/win-midi.c
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#include <windows.h>
|
||||
#include <mmsystem.h>
|
||||
#include "ibm.h"
|
||||
#include "plat-midi.h"
|
||||
|
||||
static int midi_id;
|
||||
static HMIDIOUT midi_out_device = NULL;
|
||||
|
||||
void midi_close();
|
||||
|
||||
void midi_init()
|
||||
{
|
||||
int c;
|
||||
int n;
|
||||
MIDIOUTCAPS ocaps;
|
||||
MMRESULT hr;
|
||||
|
||||
midi_id=0;
|
||||
|
||||
hr = midiOutOpen(&midi_out_device, midi_id, 0,
|
||||
0, CALLBACK_NULL);
|
||||
if (hr != MMSYSERR_NOERROR) {
|
||||
printf("midiOutOpen error - %08X\n",hr);
|
||||
return;
|
||||
}
|
||||
|
||||
midiOutReset(midi_out_device);
|
||||
}
|
||||
|
||||
void midi_close()
|
||||
{
|
||||
if (midi_out_device != NULL)
|
||||
{
|
||||
midiOutReset(midi_out_device);
|
||||
midiOutClose(midi_out_device);
|
||||
midi_out_device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int midi_pos, midi_len;
|
||||
static uint32_t midi_command;
|
||||
static int midi_lengths[8] = {3, 3, 3, 3, 2, 2, 3, 0};
|
||||
|
||||
void midi_out(uint8_t val)
|
||||
{
|
||||
if (val & 0x80)
|
||||
{
|
||||
midi_pos = 0;
|
||||
midi_len = midi_lengths[(val >> 4) & 7];
|
||||
midi_command = 0;
|
||||
}
|
||||
|
||||
if (midi_len)
|
||||
{
|
||||
midi_command |= (val << (midi_pos * 8));
|
||||
|
||||
midi_pos++;
|
||||
|
||||
if (midi_pos == midi_len)
|
||||
midiOutShortMsg(midi_out_device, midi_command);
|
||||
}
|
||||
}
|
||||
|
|
@ -18,6 +18,7 @@
|
|||
#include "nvr.h"
|
||||
#include "sound.h"
|
||||
|
||||
#include "plat-midi.h"
|
||||
#include "plat-keyboard.h"
|
||||
|
||||
#include "win-ddraw.h"
|
||||
|
|
@ -300,6 +301,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
|||
ghwnd=hwnd;
|
||||
|
||||
ddraw_init(hwnd);
|
||||
midi_init();
|
||||
atexit(midi_close);
|
||||
// d3d_init(hwnd);
|
||||
// opengl_init(hwnd);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue