From mboxrd@z Thu Jan 1 00:00:00 1970 From: Stas Sergeev Subject: Re: no MIDI input with dosemu ? Date: Fri, 09 Jan 2004 04:18:47 +0300 Sender: linux-msdos-owner@vger.kernel.org Message-ID: <3FFE0177.5080405@aknet.ru> References: <3FFD60BF.2070007@aknet.ru> <3FFD7430.10505@bright.net> <3FFD9C0D.90804@aknet.ru> <3FFDA3E1.5070508@bright.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------070807010005030404070508" Return-path: In-Reply-To: <3FFDA3E1.5070508@bright.net> List-Id: To: Dave Phillips Cc: linux-msdos@vger.kernel.org This is a multi-part message in MIME format. --------------070807010005030404070508 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Hello. Dave Phillips wrote: >>> If adding MIDI input capability in DOSemu is trivial, hopefully these >>> reasons will convince you that it would still be greatly appreciated >>> by some of us. > Thanks for checking this out, Stas ! OK. Here goes the patch for midi input. Now at least I don't feel myself that guilty for not contributing for the half of a year already:) About the patch: - Must be applied against the CVS version, as 1.1.99.1 lacks the IRQ support for MPU401 needed for vapimpu. - Don't forget to restart configure after applying. - Create a ~/.dosemu/dosemu-midi_in pipe and forward your midi data to it. - Let me know how it goes as I cant really test it (no midi keyboard, and I am not a musician at all). --------------070807010005030404070508 Content-Type: text/plain; name="midi_in.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="midi_in.diff" --- src/include/config.h.in Thu Aug 28 00:58:37 2003 +++ src/include/config.h.in Fri Jan 9 02:16:16 2004 @@ -42,6 +42,7 @@ #define DEFAULT_CONFIG_SCRIPT "builtin" /* main configuration script */ #define DOSEMU_LOGLEVEL "dosemu.loglevel" /* logging configuration file */ #define DOSEMU_MIDI "dosemu-midi" /* fifo for midi daemon */ +#define DOSEMU_MIDI_IN "dosemu-midi_in" /* fifo for midi input */ EXTERN char *config_script_name INIT(DEFAULT_CONFIG_SCRIPT); EXTERN char *config_script_path INIT(0); @@ -63,6 +64,7 @@ EXTERN char *dexe_load_path INIT(dosemuhdimage_default); EXTERN char *ipx_dos_ini_path INIT(ALTERNATE_ETC "/dos.ini"); EXTERN char *dosemu_midi_path INIT("~/" LOCALDIR_BASE_NAME "/run/" DOSEMU_MIDI); +EXTERN char *dosemu_midi_in_path INIT("~/" LOCALDIR_BASE_NAME "/run/" DOSEMU_MIDI_IN); #define DOSEMU_USERS_FILE dosemu_users_file_path #define DOSEMU_LOGLEVEL_FILE dosemu_loglevel_file_path @@ -76,6 +78,7 @@ #define IPX_DOS_INI_PATH ipx_dos_ini_path #define DOSEMU_MAP_PATH dosemu_map_file_name #define DOSEMU_MIDI_PATH dosemu_midi_path +#define DOSEMU_MIDI_IN_PATH dosemu_midi_in_path #endif /* not __ASM__ */ --- src/include/sound.h Sun Oct 26 19:35:57 2003 +++ src/include/sound.h Fri Jan 9 02:01:09 2004 @@ -227,6 +227,7 @@ #define QUEUE_SIZE 64 #define Q_HOLDS(q) (q.end - q.start) +#define Q_AVAIL(q) (QUEUE_SIZE - q.end) #define Q_CLEAR(q) (q.start = q.end = 0) #define Q_PUT(q, v) { if (q.end < QUEUE_SIZE) q.output[q.end++] = v; } #define Q_GET(q) ({ \ @@ -234,6 +235,12 @@ if (!Q_HOLDS(q)) Q_CLEAR(q); \ __ret; \ }) +#define Q_ADD(q, buf, len) ({ \ + int __len = len; \ + int __to_copy = MIN(__len, Q_AVAIL(q)); \ + memcpy(q.output + q.end, buf, __to_copy); \ + q.end += __to_copy; \ +}) typedef struct { uint8_t output[QUEUE_SIZE]; /* Output Queue */ @@ -256,6 +263,8 @@ queue_t data; /* Architecture specific procedures */ void (*data_write)(uint8_t data); /* process 1 MIDI byte */ + int (*data_read)(uint8_t data[], int max_size); + void (*register_io_callback)(void (*io_callback)(void)); } mpu401_info; /* --- src/dosext/sound/sound.c Sun Oct 26 19:35:57 2003 +++ src/dosext/sound/sound.c Fri Jan 9 03:51:25 2004 @@ -347,7 +347,6 @@ /* DSP 8-bit IRQ Ack - SB */ S_printf("SB: 8-bit IRQ Ack: %x\n", SB_dsp.data); sb_deactivate_irq(SB_IRQ_8BIT); - SB_info.irq.active &= ~SB_IRQ_8BIT; /* may mean it never triggers! */ SB_dsp.ready = 0x7f; if(SB_dsp.empty_state & DREQ_AT_EOI) { @@ -361,7 +360,6 @@ case 0x0F: /* 0x0F: DSP 16-bit IRQ - SB16 */ S_printf("SB: 16-bit IRQ Ack: %x\n", SB_dsp.data); sb_deactivate_irq(SB_IRQ_16BIT); - SB_info.irq.active &= ~SB_IRQ_16BIT; /* may mean it never triggers! */ SB_dsp.ready = 0x7f; if(SB_dsp.empty_state & DREQ_AT_EOI) { @@ -648,7 +646,8 @@ case 0: /* Read data port */ r=Q_GET(mpu401_info.data); - S_printf("MPU401: Read data port = 0x%02x\n",r); + S_printf("MPU401: Read data port = 0x%02x, %i bytes still in queue\n", + r,Q_HOLDS(mpu401_info.data)); sb_deactivate_irq(SB_IRQ_MIDI); break; case 1: @@ -661,6 +660,17 @@ return r; } +static void mpu401_io_callback(void) +{ + char buf[QUEUE_SIZE]; + int n; + n = mpu401_info.data_read(buf, QUEUE_SIZE); + if (n <= 0) + return; + S_printf("MPU401: Processing IO callback, %i bytes\n", n); + Q_ADD(mpu401_info.data, buf, n); + sb_activate_irq(SB_IRQ_MIDI); +} /* * Main IO Routines - Write @@ -1824,6 +1834,7 @@ case 1: /* Write command port */ S_printf("MPU401: Write 0x%02x to command port\n",value); + Q_CLEAR(mpu401_info.data); Q_PUT(mpu401_info.data, 0xfe); /* A command is sent: MPU_ACK it next time */ sb_activate_irq(SB_IRQ_MIDI); switch (value) { @@ -2596,7 +2607,7 @@ SB_info.version = SB_NONE; } - (void) FM_driver_init(); + FM_driver_init(); } static void mpu401_init(void) @@ -2627,7 +2638,9 @@ Q_CLEAR(mpu401_info.data); - (void) MPU_driver_init(); + MPU_driver_init(); + + mpu401_info.register_io_callback(mpu401_io_callback); } @@ -2912,6 +2925,7 @@ S_printf("SB: Untriggering scheduled IRQ\n"); SB_dsp.empty_state &= ~IRQ_AT_EMPTY; } + SB_info.irq.active &= ~type; if(!(SB_info.irq.pending & type)) { return; } --- src/base/init/parser.y.in Sun Dec 28 06:22:09 2003 +++ src/base/init/parser.y.in Fri Jan 9 02:14:42 2004 @@ -2215,6 +2215,7 @@ LOCALDIR = get_dosemu_local_home(); RUNDIR = mkdir_under(LOCALDIR, "run", 0); DOSEMU_MIDI_PATH = assemble_path(RUNDIR, DOSEMU_MIDI, 0); + DOSEMU_MIDI_IN_PATH = assemble_path(RUNDIR, DOSEMU_MIDI_IN, 0); } static void lax_user_checking(void) --- src/arch/linux/dosext/sound/linux_sound.c Sat Oct 11 16:54:05 2003 +++ src/arch/linux/dosext/sound/linux_sound.c Fri Jan 9 02:27:26 2004 @@ -65,6 +65,7 @@ /* MPU static vars */ static int mpu_fd = -1; /* -1 = closed */ +static int mpu_in_fd = -1; /* -1 = closed */ static boolean mpu_disabled = FALSE; /* TRUE if MIDI output disabled */ static void linux_sb_dma_set_blocksize(int blocksize, int fragsize) @@ -653,9 +654,6 @@ SB_driver.DMA_complete = linux_sb_dma_complete; SB_driver.DMA_set_blocksize = linux_sb_dma_set_blocksize; - /* MPU-401 Functions */ - mpu401_info.data_write = linux_mpu401_data_write; - /* Miscellaneous Functions */ SB_driver.set_speed = linux_sb_set_speed; SB_driver.play_buffer = NULL; @@ -701,6 +699,11 @@ return linux_sb_get_version(); } +void linux_mpu401_register_callback(void (*io_callback)(void)) +{ + if (mpu_in_fd == -1) return; + add_to_io_select(mpu_in_fd, 1, io_callback); +} void linux_mpu401_data_write(uint8_t data) { @@ -724,6 +727,17 @@ } } +int linux_mpu401_data_read(uint8_t data[], int max_len) +{ + int ret; + if (mpu_in_fd == -1) return 0; + if ((ret = read(mpu_in_fd,data,max_len)) == -1) { + S_printf("MPU401:[Linux] Failed to write to file 'midi' (%s)\n", + strerror(errno)); + } + return ret; +} + int FM_driver_init(void) { @@ -735,6 +749,14 @@ int MPU_driver_init(void) { S_printf("MPU:[Linux] MPU Driver Initialisation Called\n"); + + /* MPU-401 Functions */ + mpu401_info.data_write = linux_mpu401_data_write; + mpu401_info.data_read = linux_mpu401_data_read; + mpu401_info.register_io_callback = linux_mpu401_register_callback; + + mpu_in_fd = RPT_SYSCALL(open(DOSEMU_MIDI_IN_PATH, O_RDONLY | O_NONBLOCK, 0777)); + mpu_disabled = FALSE; /* Output a MIDI byte to an external file */ /* Added NONBLOCK to prevent hanging - Karcher */ --- src/arch/linux/dosext/sound/linux_sound.h Mon Oct 6 22:16:11 2003 +++ src/arch/linux/dosext/sound/linux_sound.h Fri Jan 9 01:24:20 2004 @@ -46,6 +46,8 @@ void linux_sb_dma_complete(void); +int linux_mpu401_data_read(uint8_t data[], int max_len); void linux_mpu401_data_write(uint8_t data); +void linux_mpu401_register_callback(void (*io_callback)(void)); int linux_sb_get_free_fragments(int *total, int *free, int *bytes); --------------070807010005030404070508--