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 \
|
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 \
|
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 \
|
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_adlibgold.o sound_cms.o sound_gus.o sound_mpu401_uart.o sound_opl.o \
|
||||||
sound_sb_dsp.o sound_sn76489.o sound_speaker.o sound_wss.o soundopenal.o timer.o \
|
sound_pas16.o sound_sb.o sound_sb_dsp.o sound_sn76489.o sound_speaker.o \
|
||||||
um8881f.o um8669f.o vid_ati_eeprom.o vid_ati_mach64.o vid_ati18800.o \
|
sound_wss.o soundopenal.o timer.o um8881f.o um8669f.o vid_ati_eeprom.o \
|
||||||
vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o vid_cl5429.o vid_ega.o \
|
vid_ati_mach64.o vid_ati18800.o vid_ati28800.o vid_ati68860_ramdac.o vid_cga.o \
|
||||||
vid_et4000.o vid_et4000w32.o vid_et4000w32i.o vid_hercules.o vid_icd2061.o \
|
vid_cl5429.o vid_ega.o vid_et4000.o vid_et4000w32.o vid_et4000w32i.o \
|
||||||
vid_ics2595.o vid_mda.o vid_olivetti_m24.o vid_oti067.o vid_paradise.o \
|
vid_hercules.o vid_icd2061.o vid_ics2595.o vid_mda.o vid_olivetti_m24.o \
|
||||||
vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o vid_s3_virge.o vid_sdac_ramdac.o \
|
vid_oti067.o vid_paradise.o vid_pc1512.o vid_pc1640.o vid_pc200.o vid_s3.o \
|
||||||
vid_stg_ramdac.o vid_svga.o vid_svga_render.o vid_tandy.o vid_tkd8001_ramdac.o \
|
vid_s3_virge.o vid_sdac_ramdac.o vid_stg_ramdac.o vid_svga.o vid_svga_render.o \
|
||||||
vid_tvga.o vid_unk_ramdac.o vid_vga.o vid_voodoo.o video.o wd76c10.o \
|
vid_tandy.o vid_tkd8001_ramdac.o vid_tvga.o vid_unk_ramdac.o vid_vga.o \
|
||||||
win.o win-ddraw.o win-keyboard.o win-mouse.o win-timer.o win-video.o \
|
vid_voodoo.o video.o wd76c10.o win.o win-ddraw.o win-keyboard.o win-midi.o \
|
||||||
x86seg.o x87.o xtide.o pc.res
|
win-mouse.o win-timer.o win-video.o x86seg.o x87.o xtide.o pc.res
|
||||||
FMOBJ = fmopl.o ymf262.o
|
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 <stdlib.h>
|
||||||
#include "ibm.h"
|
#include "ibm.h"
|
||||||
#include "device.h"
|
#include "device.h"
|
||||||
|
#include "sound_mpu401_uart.h"
|
||||||
|
#include "sound_opl.h"
|
||||||
#include "sound_sb.h"
|
#include "sound_sb.h"
|
||||||
#include "sound_sb_dsp.h"
|
#include "sound_sb_dsp.h"
|
||||||
#include "sound_opl.h"
|
|
||||||
|
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
|
|
||||||
|
|
@ -22,9 +23,10 @@ typedef struct sb_mixer_t
|
||||||
|
|
||||||
typedef struct sb_t
|
typedef struct sb_t
|
||||||
{
|
{
|
||||||
opl_t opl;
|
opl_t opl;
|
||||||
sb_dsp_t dsp;
|
sb_dsp_t dsp;
|
||||||
sb_mixer_t mixer;
|
sb_mixer_t mixer;
|
||||||
|
mpu401_uart_t mpu;
|
||||||
|
|
||||||
int16_t opl_buffer[SOUNDBUFLEN * 2];
|
int16_t opl_buffer[SOUNDBUFLEN * 2];
|
||||||
int16_t dsp_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(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);
|
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);
|
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[0x30] = 31 << 3;
|
||||||
sb->mixer.regs[0x31] = 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 "nvr.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
|
|
||||||
|
#include "plat-midi.h"
|
||||||
#include "plat-keyboard.h"
|
#include "plat-keyboard.h"
|
||||||
|
|
||||||
#include "win-ddraw.h"
|
#include "win-ddraw.h"
|
||||||
|
|
@ -300,6 +301,8 @@ int WINAPI WinMain (HINSTANCE hThisInstance,
|
||||||
ghwnd=hwnd;
|
ghwnd=hwnd;
|
||||||
|
|
||||||
ddraw_init(hwnd);
|
ddraw_init(hwnd);
|
||||||
|
midi_init();
|
||||||
|
atexit(midi_close);
|
||||||
// d3d_init(hwnd);
|
// d3d_init(hwnd);
|
||||||
// opengl_init(hwnd);
|
// opengl_init(hwnd);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue