firebeat: split midi keyboard to separate device [Carl]

pc16552d: kill it (nw)
This commit is contained in:
cracyc 2013-06-05 14:36:19 +00:00
parent 6103f54ca6
commit 73e8901194
9 changed files with 273 additions and 507 deletions

4
.gitattributes vendored
View File

@ -1355,8 +1355,6 @@ src/emu/machine/nscsi_hd.c svneol=native#text/plain
src/emu/machine/nscsi_hd.h svneol=native#text/plain
src/emu/machine/nvram.c svneol=native#text/plain
src/emu/machine/nvram.h svneol=native#text/plain
src/emu/machine/pc16552d.c svneol=native#text/plain
src/emu/machine/pc16552d.h svneol=native#text/plain
src/emu/machine/pccard.c svneol=native#text/plain
src/emu/machine/pccard.h svneol=native#text/plain
src/emu/machine/pcf8593.c svneol=native#text/plain
@ -5056,6 +5054,8 @@ src/mame/machine/meters.h svneol=native#text/plain
src/mame/machine/mexico86.c svneol=native#text/plain
src/mame/machine/mhavoc.c svneol=native#text/plain
src/mame/machine/micro3d.c svneol=native#text/plain
src/mame/machine/midikbd.c svneol=native#text/plain
src/mame/machine/midikbd.h svneol=native#text/plain
src/mame/machine/midtunit.c svneol=native#text/plain
src/mame/machine/midwayic.c svneol=native#text/plain
src/mame/machine/midwayic.h svneol=native#text/plain

View File

@ -127,7 +127,6 @@ MACHINEOBJS += $(MACHINEOBJ)/53c7xx.o \
$(MACHINEOBJ)/nscsi_bus.o \
$(MACHINEOBJ)/nscsi_cd.o \
$(MACHINEOBJ)/nscsi_hd.o \
$(MACHINEOBJ)/pc16552d.o \
$(MACHINEOBJ)/pccard.o \
$(MACHINEOBJ)/pcf8593.o \
$(MACHINEOBJ)/pci.o \

View File

@ -16,7 +16,7 @@
const device_type MICROTOUCH = &device_creator<microtouch_device>;
microtouch_device::microtouch_device(const machine_config &mconfig, device_type type, const char* name, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, type, name, tag, owner, clock),
: device_t(mconfig, type, name, tag, owner, clock, "microtouch", __FILE__),
m_out_tx_func(*this),
m_touch(*this, "TOUCH"),
m_touchx(*this, "TOUCH_X"),
@ -25,7 +25,7 @@ microtouch_device::microtouch_device(const machine_config &mconfig, device_type
}
microtouch_device::microtouch_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, MICROTOUCH, "Microtouch Touchscreen", tag, owner, clock),
: device_t(mconfig, MICROTOUCH, "Microtouch Touchscreen", tag, owner, clock, "microtouch", __FILE__),
m_out_tx_func(*this),
m_touch(*this, "TOUCH"),
m_touchx(*this, "TOUCH_X"),

View File

@ -1,438 +0,0 @@
/*
National Semiconductor PC16552D
Dual Universal Asynchronous Receiver/Transmitter with FIFOs
Written by Ville Linde
*/
#include "emu.h"
#include "pc16552d.h"
#define REG_RECV_BUFFER 0x0 // Read
#define REG_XMIT_HOLD 0x0 // Write
#define REG_INT_ENABLE 0x1
#define REG_FIFO_CTRL 0x2 // Write
#define REG_LINE_CTRL 0x3
#define REG_MODEL_CTRL 0x4
#define REG_LINE_STATUS 0x5
#define REG_MODEM_STATUS 0x6
#define REG_SCRATCH 0x7
#define REG_DIV_LATCH_LSB 0x0 // When DLAB == 1
#define REG_DIV_LATCH_MSB 0x1 // When DLAB == 1
#define REG_ALT_FUNCTION 0x2 // When DLAB == 1
#define LINE_CTRL_DLAB 0x80
#define IRQ_RX_LINE_STATUS 0x1
#define IRQ_RX_DATA_AVAILABLE 0x2
#define IRQ_CHARACTER_TIMEOUT 0x4
#define IRQ_TX_HOLDING_REG_EMPTY 0x8
#define IRQ_MODEM_STATUS 0x10
#define INT_ENABLE_RX_DATA 0x01
#define INT_ENABLE_TX_EMPTY 0x02
#define INT_ENABLE_RX_LINE_STATUS 0x04
#define INT_ENABLE_MODEM_STATUS 0x08
struct PC16552D_CHANNEL
{
UINT16 divisor;
UINT8 reg[8];
UINT8 rx_fifo[16];
UINT8 tx_fifo[16];
int pending_interrupt;
int rx_fifo_read_ptr;
int rx_fifo_write_ptr;
int rx_fifo_num;
int tx_fifo_read_ptr;
int tx_fifo_write_ptr;
int tx_fifo_num;
emu_timer *tx_fifo_timer;
};
struct PC16552D_REGS
{
PC16552D_CHANNEL ch[2];
int frequency;
void (* irq_handler)(running_machine &machine, int channel, int value);
void (* tx_callback)(running_machine &machine, int channel, int count, UINT8* data);
};
#define MAX_PC16552D_CHIPS 4
static PC16552D_REGS duart[MAX_PC16552D_CHIPS];
static const int rx_trigger_level[4] = { 1, 4, 8, 14 };
static void check_interrupts(running_machine &machine, int chip, int channel)
{
PC16552D_CHANNEL *ch = &duart[chip].ch[channel];
int signal = 0;
if (ch->pending_interrupt != 0)
{
if (((ch->reg[REG_INT_ENABLE] & INT_ENABLE_RX_DATA) && (ch->pending_interrupt & IRQ_RX_DATA_AVAILABLE)) ||
((ch->reg[REG_INT_ENABLE] & INT_ENABLE_TX_EMPTY) && (ch->pending_interrupt & IRQ_TX_HOLDING_REG_EMPTY)) ||
((ch->reg[REG_INT_ENABLE] & INT_ENABLE_RX_LINE_STATUS) && (ch->pending_interrupt & IRQ_RX_LINE_STATUS)) ||
((ch->reg[REG_INT_ENABLE] & INT_ENABLE_MODEM_STATUS) && (ch->pending_interrupt & IRQ_MODEM_STATUS)))
{
signal = 1;
}
}
if (duart[chip].irq_handler != NULL)
{
duart[chip].irq_handler(machine, channel, signal ? ASSERT_LINE : CLEAR_LINE);
}
}
static void duart_push_rx_fifo(running_machine &machine, int chip, int channel, UINT8 data)
{
PC16552D_CHANNEL *ch = &duart[chip].ch[channel];
if (ch->rx_fifo_num >= 16)
{
printf("duart_push_rx_fifo: %d, %d, %02X, FIFO overflow\n", chip, channel, data);
return;
}
ch->rx_fifo[ch->rx_fifo_write_ptr++] = data;
if (ch->rx_fifo_write_ptr == 16)
{
ch->rx_fifo_write_ptr = 0;
}
ch->rx_fifo_num++;
if (ch->rx_fifo_num == rx_trigger_level[(ch->reg[REG_FIFO_CTRL] >> 6) & 3])
{
ch->pending_interrupt |= IRQ_RX_DATA_AVAILABLE; // INT ID: received data available
check_interrupts(machine, chip, channel);
}
}
static UINT8 duart_pop_rx_fifo(running_machine &machine, int chip, int channel)
{
UINT8 r;
PC16552D_CHANNEL *ch = &duart[chip].ch[channel];
if (ch->rx_fifo_num == 0)
{
printf("duart_pop_rx_fifo: %d, %d, FIFO underflow\n", chip, channel);
return 0;
}
r = ch->rx_fifo[ch->rx_fifo_read_ptr++];
if (ch->rx_fifo_read_ptr == 16)
{
ch->rx_fifo_read_ptr = 0;
}
ch->rx_fifo_num--;
if (ch->rx_fifo_num < rx_trigger_level[(ch->reg[REG_FIFO_CTRL] >> 6) & 3])
{
ch->pending_interrupt &= ~IRQ_RX_DATA_AVAILABLE;
check_interrupts(machine, chip, channel);
}
return r;
}
static TIMER_CALLBACK( tx_fifo_timer_callback )
{
PC16552D_CHANNEL *ch;
int chip = param >> 1;
int channel = param & 1;
ch = &duart[chip].ch[channel];
if (duart[chip].tx_callback)
duart[chip].tx_callback(machine, channel, ch->tx_fifo_num, ch->tx_fifo);
ch->tx_fifo_num = 0;
// set transmitter empty interrupt
ch->pending_interrupt |= IRQ_TX_HOLDING_REG_EMPTY;
check_interrupts(machine, chip, channel);
duart[chip].ch[channel].tx_fifo_timer->adjust(attotime::never, (chip * 2) + channel);
}
static void duart_push_tx_fifo(int chip, int channel, UINT8 data)
{
attotime period;
PC16552D_CHANNEL *ch = &duart[chip].ch[channel];
ch->tx_fifo[ch->tx_fifo_num] = data;
ch->tx_fifo_num++;
period = attotime::from_hz(duart[chip].frequency) * (ch->divisor * 16 * 16 * 8);
duart[chip].ch[channel].tx_fifo_timer->adjust(period, (chip * 2) + channel);
}
#ifdef UNUSED_FUNCTION
static UINT8 duart_pop_tx_fifo(int chip, int channel, UINT8 data)
{
return 0;
}
#endif
static UINT8 duart_r(running_machine &machine, int chip, int reg)
{
int channel = (reg >> 3) & 1;
PC16552D_CHANNEL *ch = &duart[chip].ch[channel];
reg &= 7;
// printf("duart_r: chip %d, ch %d, reg %d\n", chip, channel, reg);
switch (reg)
{
case 0:
{
if (ch->reg[REG_LINE_CTRL] & LINE_CTRL_DLAB)
{
// Divisor Latch (LSB)
return ch->divisor & 0xff;
}
else
{
// Receiver Buffer
ch->pending_interrupt &= ~IRQ_RX_DATA_AVAILABLE;
check_interrupts(machine, chip, channel);
return duart_pop_rx_fifo(machine, chip, channel);
}
}
case 1:
{
if (ch->reg[REG_LINE_CTRL] & LINE_CTRL_DLAB)
{
// Divisor Latch (MSB)
return (ch->divisor >> 8) & 0xff;
}
else
{
}
break;
}
case 2:
{
if (ch->reg[REG_LINE_CTRL] & LINE_CTRL_DLAB)
{
// Alternate Function
}
else
{
// Interrupt Identification Register
int i;
UINT8 r = 0x01;
for (i=0; i < 5; i++)
{
if (ch->pending_interrupt & (1 << i))
{
switch (i)
{
case 0: r = 0x06; break; // Receiver Line Status
case 1: r = 0x04; break; // Received Data Available
case 2: r = 0x0c; break; // Character Timeout Indication
case 3: r = 0x02; break; // Transmitter Holding Register Empty
case 4: r = 0x00; break; // MODEM Status
}
break;
}
}
if (ch->reg[REG_FIFO_CTRL] & 1)
{
r |= 0xc0;
}
return r;
}
break;
}
case 5: // Line Status Register
{
UINT8 r = 0;
// set Data Ready flag
if (ch->rx_fifo_num > 0)
{
r |= 0x1;
}
// set Transmitter Holding Register Empty flag
if (ch->tx_fifo_num == 0)
{
r |= 0x20;
}
// set Transmitter Empty flag
if (ch->tx_fifo_num == 0)
{
r |= 0x40;
}
return r;
}
}
return ch->reg[reg];
}
static void duart_w(running_machine &machine, int chip, int reg, UINT8 data)
{
int channel = (reg >> 3) & 1;
PC16552D_CHANNEL *ch = &duart[chip].ch[channel];
reg &= 7;
// printf("duart_w: chip %d, ch %d, reg %d, data %02X\n", chip, channel, reg, data);
switch (reg)
{
case 0:
{
if (ch->reg[REG_LINE_CTRL] & LINE_CTRL_DLAB)
{
// Divisor Latch (LSB)
ch->divisor &= 0xff00;
ch->divisor |= data;
return;
}
else
{
// Transmitter Holding Register
duart_push_tx_fifo(chip, channel, data);
ch->pending_interrupt &= ~IRQ_TX_HOLDING_REG_EMPTY;
check_interrupts(machine, chip, channel);
return;
}
}
case 1:
{
if (ch->reg[REG_LINE_CTRL] & LINE_CTRL_DLAB)
{
// Divisor Latch (MSB)
ch->divisor &= 0x00ff;
ch->divisor |= data << 8;
// printf("DUART %d %d bps\n", chip, duart[chip].frequency / (ch->divisor * 16));
return;
}
else
{
// Interrupt enable
ch->reg[REG_INT_ENABLE] = data;
check_interrupts(machine, chip, channel);
return;
}
}
case 2:
{
if (ch->reg[REG_LINE_CTRL] & LINE_CTRL_DLAB)
{
// Alternate Function
return;
}
else
{
// FIFO control
if (data & 0x02)
{
ch->rx_fifo_write_ptr = 0;
ch->rx_fifo_read_ptr = 0;
ch->rx_fifo_num = 0;
}
if (data & 0x04)
{
ch->tx_fifo_write_ptr = 0;
ch->tx_fifo_read_ptr = 0;
ch->tx_fifo_num = 0;
}
/*if (data & 0x1 && (ch->reg[reg] & 0x1) == 0)
{
// cause transmitter empty IRQ
ch->pending_interrupt |= IRQ_TX_HOLDING_REG_EMPTY;
check_interrupts(machine, chip, channel);
}
*/
}
break;
}
}
ch->reg[reg] = data;
}
/*****************************************************************************/
void pc16552d_init(running_machine &machine, int chip, int frequency, void (* irq_handler)(running_machine &machine, int channel, int value), void (* tx_callback)(running_machine &machine, int channel, int count, UINT8* data))
{
memset(&duart[chip], 0, sizeof(PC16552D_REGS));
duart[chip].frequency = frequency;
duart[chip].irq_handler = irq_handler;
duart[chip].tx_callback = tx_callback;
// clear interrupts
duart[chip].ch[0].pending_interrupt = 0;
duart[chip].ch[1].pending_interrupt = 0;
// allocate transmit timers
duart[chip].ch[0].tx_fifo_timer = machine.scheduler().timer_alloc(FUNC(tx_fifo_timer_callback));
duart[chip].ch[0].tx_fifo_timer->adjust(attotime::never, (chip * 2) + 0);
duart[chip].ch[1].tx_fifo_timer = machine.scheduler().timer_alloc(FUNC(tx_fifo_timer_callback));
duart[chip].ch[1].tx_fifo_timer->adjust(attotime::never, (chip * 2) + 1);
}
void pc16552d_rx_data(running_machine &machine, int chip, int channel, UINT8 data)
{
if (duart[chip].ch[channel].reg[REG_FIFO_CTRL] & 0x01) // RCVR & XMIT FIFO enable
{
duart_push_rx_fifo(machine, chip, channel, data);
}
}
/*****************************************************************************/
/* Read/Write handlers */
READ8_HANDLER(pc16552d_0_r)
{
return duart_r(space.machine(), 0, offset);
}
WRITE8_HANDLER(pc16552d_0_w)
{
duart_w(space.machine(), 0, offset, data);
}
READ8_HANDLER(pc16552d_1_r)
{
return duart_r(space.machine(), 1, offset);
}
WRITE8_HANDLER(pc16552d_1_w)
{
duart_w(space.machine(), 1, offset, data);
}

View File

@ -1,12 +0,0 @@
#ifndef PC16552D_H
#define PC16552D_H
void pc16552d_init(running_machine &machine, int chip, int frequency, void (* irq_handler)(running_machine &machine, int channel, int value), void (* tx_callback)(running_machine &machine, int channel, int count, UINT8* data));
void pc16552d_rx_data(running_machine &machine, int chip, int channel, UINT8 data);
DECLARE_READ8_HANDLER(pc16552d_0_r);
DECLARE_WRITE8_HANDLER(pc16552d_0_w);
DECLARE_READ8_HANDLER(pc16552d_1_r);
DECLARE_WRITE8_HANDLER(pc16552d_1_w);
#endif

View File

@ -135,7 +135,8 @@
#include "machine/intelfsh.h"
#include "machine/scsicd.h"
#include "machine/rtc65271.h"
#include "machine/pc16552d.h"
#include "machine/ins8250.h"
#include "machine/midikbd.h"
#include "sound/ymz280b.h"
#include "sound/cdda.h"
#include "cdrom.h"
@ -173,7 +174,11 @@ public:
m_work_ram(*this, "work_ram"),
m_flash_main(*this, "flash_main"),
m_flash_snd1(*this, "flash_snd1"),
m_flash_snd2(*this, "flash_snd2")
m_flash_snd2(*this, "flash_snd2"),
m_duart_midi(*this, "duart_midi"),
m_duart_com(*this, "duart_com"),
m_kbd0(*this, "kbd0"),
m_kbd1(*this, "kbd1")
{ }
required_device<cpu_device> m_maincpu;
@ -181,10 +186,14 @@ public:
required_device<fujitsu_29f016a_device> m_flash_main;
required_device<fujitsu_29f016a_device> m_flash_snd1;
required_device<fujitsu_29f016a_device> m_flash_snd2;
optional_device<pc16552_device> m_duart_midi;
required_device<pc16552_device> m_duart_com;
optional_device<midi_keyboard_device> m_kbd0;
optional_device<midi_keyboard_device> m_kbd1;
UINT8 m_extend_board_irq_enable;
UINT8 m_extend_board_irq_active;
emu_timer *m_keyboard_timer;
// emu_timer *m_keyboard_timer;
GCU_REGS m_gcu[2];
int m_tick;
int m_layer;
@ -200,7 +209,7 @@ public:
UINT8 m_temp_data[64*1024];
int m_cab_data_ptr;
const int * m_cur_cab_data;
int m_keyboard_state[2];
// int m_keyboard_state[2];
UINT8 m_spu_shared_ram[0x400];
IBUTTON m_ibutton;
int m_ibutton_state;
@ -230,12 +239,12 @@ public:
DECLARE_WRITE32_MEMBER(atapi_command_w);
DECLARE_READ32_MEMBER(atapi_control_r);
DECLARE_WRITE32_MEMBER(atapi_control_w);
DECLARE_READ32_MEMBER(comm_uart_r);
DECLARE_WRITE32_MEMBER(comm_uart_w);
// DECLARE_READ32_MEMBER(comm_uart_r);
// DECLARE_WRITE32_MEMBER(comm_uart_w);
DECLARE_READ32_MEMBER(cabinet_r);
DECLARE_READ32_MEMBER(keyboard_wheel_r);
DECLARE_READ32_MEMBER(midi_uart_r);
DECLARE_WRITE32_MEMBER(midi_uart_w);
DECLARE_READ8_MEMBER(midi_uart_r);
DECLARE_WRITE8_MEMBER(midi_uart_w);
DECLARE_READ32_MEMBER(extend_board_irq_r);
DECLARE_WRITE32_MEMBER(extend_board_irq_w);
DECLARE_WRITE32_MEMBER(lamp_output_w);
@ -248,7 +257,7 @@ public:
DECLARE_READ32_MEMBER(ppc_spu_share_r);
DECLARE_WRITE32_MEMBER(ppc_spu_share_w);
DECLARE_READ16_MEMBER(spu_unk_r);
TIMER_CALLBACK_MEMBER(keyboard_timer_callback);
// TIMER_CALLBACK_MEMBER(keyboard_timer_callback);
void gcu_draw_object(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd);
void gcu_fill_rect(bitmap_ind16 &bitmap, const rectangle &cliprect, UINT32 *cmd);
void gcu_draw_character(bitmap_ind16 &bitmap, const rectangle &cliprect, int chip, UINT32 *cmd);
@ -270,6 +279,8 @@ public:
void init_firebeat();
void init_keyboard();
DECLARE_WRITE_LINE_MEMBER(sound_irq_callback);
DECLARE_WRITE_LINE_MEMBER(midi_uart_ch0_irq_callback);
DECLARE_WRITE_LINE_MEMBER(midi_uart_ch1_irq_callback);
};
@ -1390,7 +1401,7 @@ WRITE32_MEMBER(firebeat_state::atapi_control_w )
/*****************************************************************************/
/*
READ32_MEMBER(firebeat_state::comm_uart_r )
{
UINT32 r = 0;
@ -1440,6 +1451,26 @@ static void comm_uart_irq_callback(running_machine &machine, int channel, int va
// TODO
//m_maincpu->set_input_line(INPUT_LINE_IRQ2, ASSERT_LINE);
}
*/
static const ins8250_interface firebeat_com0_interface =
{
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL
};
static const ins8250_interface firebeat_com1_interface =
{
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL
};
/*****************************************************************************/
@ -1484,52 +1515,58 @@ READ32_MEMBER(firebeat_state::keyboard_wheel_r )
return 0;
}
READ32_MEMBER(firebeat_state::midi_uart_r )
READ8_MEMBER(firebeat_state::midi_uart_r )
{
UINT32 r = 0;
if (ACCESSING_BITS_24_31)
{
r |= pc16552d_1_r(space, offset >> 6) << 24;
return m_duart_midi->read(space, offset >> 6);
}
return r;
WRITE8_MEMBER(firebeat_state::midi_uart_w )
{
m_duart_midi->write(space, offset >> 6, data);
}
WRITE32_MEMBER(firebeat_state::midi_uart_w )
WRITE_LINE_MEMBER(firebeat_state::midi_uart_ch0_irq_callback)
{
if (ACCESSING_BITS_24_31)
if ((m_extend_board_irq_enable & 0x02) == 0 && state != CLEAR_LINE)
{
pc16552d_1_w(space, offset >> 6, (data >> 24) & 0xff);
}
}
static void midi_uart_irq_callback(running_machine &machine, int channel, int value)
{
firebeat_state *state = machine.driver_data<firebeat_state>();
if (channel == 0)
{
if ((state->m_extend_board_irq_enable & 0x02) == 0 && value != CLEAR_LINE)
{
state->m_extend_board_irq_active |= 0x02;
state->m_maincpu->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
m_extend_board_irq_active |= 0x02;
m_maincpu->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
}
else
state->m_maincpu->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
}
else
{
if ((state->m_extend_board_irq_enable & 0x01) == 0 && value != CLEAR_LINE)
{
state->m_extend_board_irq_active |= 0x01;
state->m_maincpu->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
}
else
state->m_maincpu->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
}
m_maincpu->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
}
WRITE_LINE_MEMBER(firebeat_state::midi_uart_ch1_irq_callback)
{
if ((m_extend_board_irq_enable & 0x01) == 0 && state != CLEAR_LINE)
{
m_extend_board_irq_active |= 0x01;
m_maincpu->set_input_line(INPUT_LINE_IRQ1, ASSERT_LINE);
}
else
m_maincpu->set_input_line(INPUT_LINE_IRQ1, CLEAR_LINE);
}
static const ins8250_interface firebeat_midi0_interface =
{
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_DRIVER_LINE_MEMBER(firebeat_state, midi_uart_ch0_irq_callback),
DEVCB_NULL,
DEVCB_NULL
};
static const ins8250_interface firebeat_midi1_interface =
{
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_DRIVER_LINE_MEMBER(firebeat_state, midi_uart_ch1_irq_callback),
DEVCB_NULL,
DEVCB_NULL
};
/*
static const int keyboard_notes[24] =
{
0x3c, // C1
@ -1601,7 +1638,7 @@ TIMER_CALLBACK_MEMBER(firebeat_state::keyboard_timer_callback)
m_keyboard_state[keyboard] = kbstate;
}
}
*/
// Extend board IRQs
// 0x01: MIDI UART channel 2
// 0x02: MIDI UART channel 1
@ -1849,7 +1886,7 @@ MACHINE_START_MEMBER(firebeat_state,firebeat)
static ADDRESS_MAP_START( firebeat_map, AS_PROGRAM, 32, firebeat_state )
AM_RANGE(0x00000000, 0x01ffffff) AM_RAM AM_SHARE("work_ram")
AM_RANGE(0x70000000, 0x70000fff) AM_READWRITE(midi_uart_r, midi_uart_w)
AM_RANGE(0x70000000, 0x70000fff) AM_READWRITE8(midi_uart_r, midi_uart_w, 0xff000000)
AM_RANGE(0x70006000, 0x70006003) AM_WRITE(extend_board_irq_w)
AM_RANGE(0x70008000, 0x7000800f) AM_READ(keyboard_wheel_r)
AM_RANGE(0x7000a000, 0x7000a003) AM_READ(extend_board_irq_r)
@ -1860,7 +1897,7 @@ static ADDRESS_MAP_START( firebeat_map, AS_PROGRAM, 32, firebeat_state )
AM_RANGE(0x7d000800, 0x7d000803) AM_READ(input_r)
AM_RANGE(0x7d400000, 0x7d5fffff) AM_READWRITE(flashram_r, flashram_w)
AM_RANGE(0x7d800000, 0x7dbfffff) AM_READWRITE(soundflash_r, soundflash_w)
AM_RANGE(0x7dc00000, 0x7dc0000f) AM_READWRITE(comm_uart_r, comm_uart_w)
AM_RANGE(0x7dc00000, 0x7dc0000f) AM_DEVREADWRITE8("duart_com", pc16552_device, read, write, 0xffffffff)
AM_RANGE(0x7e000000, 0x7e00003f) AM_DEVREADWRITE8("rtc", rtc65271_device, rtc_r, rtc_w, 0xffffffff)
AM_RANGE(0x7e000100, 0x7e00013f) AM_DEVREADWRITE8("rtc", rtc65271_device, xram_r, xram_w, 0xffffffff)
AM_RANGE(0x7e800000, 0x7e8000ff) AM_READWRITE(gcu0_r, gcu0_w)
@ -1946,6 +1983,7 @@ static INPUT_PORTS_START(kbm)
PORT_START("WHEEL_P2") // Keyboard modulation wheel (P2)
PORT_BIT( 0xff, 0x80, IPT_PADDLE_V ) PORT_MINMAX(0xff, 0x00) PORT_SENSITIVITY(30) PORT_KEYDELTA(10)
/*
PORT_START("KEYBOARD_P1")
PORT_BIT( 0x000001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 C1") PORT_CODE(KEYCODE_Q)
PORT_BIT( 0x000002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 C1#") PORT_CODE(KEYCODE_W)
@ -1997,7 +2035,7 @@ static INPUT_PORTS_START(kbm)
PORT_BIT( 0x200000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 A2") PORT_CODE(KEYCODE_V)
PORT_BIT( 0x400000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 A2#") PORT_CODE(KEYCODE_B)
PORT_BIT( 0x800000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P2 B2") PORT_CODE(KEYCODE_N)
*/
INPUT_PORTS_END
static INPUT_PORTS_START(popn)
@ -2091,6 +2129,9 @@ static MACHINE_CONFIG_START( firebeat, firebeat_state )
MCFG_SOUND_MODIFY("scsi1:cdda")
MCFG_SOUND_ROUTE(0, "^^lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "^^rspeaker", 1.0)
MCFG_PC16552D_ADD("duart_com", firebeat_com0_interface, firebeat_com1_interface, XTAL_19_6608MHz) // pgmd to 9600baud
MCFG_PC16552D_ADD("duart_midi", firebeat_midi0_interface, firebeat_midi1_interface, XTAL_24MHz) // in all memory maps, pgmd to 31250baud
MACHINE_CONFIG_END
static MACHINE_CONFIG_START( firebeat2, firebeat_state )
@ -2144,6 +2185,11 @@ static MACHINE_CONFIG_START( firebeat2, firebeat_state )
MCFG_SOUND_MODIFY("scsi1:cdda")
MCFG_SOUND_ROUTE(0, "^^lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "^^rspeaker", 1.0)
MCFG_PC16552D_ADD("duart_com", firebeat_com0_interface, firebeat_com1_interface, XTAL_19_6608MHz)
MCFG_PC16552D_ADD("duart_midi", firebeat_midi0_interface, firebeat_midi1_interface, XTAL_24MHz)
MCFG_MIDI_KBD_ADD("kbd0", DEVWRITELINE("duart_midi:chan0", ins8250_uart_device, rx_w), 31250)
MCFG_MIDI_KBD_ADD("kbd1", DEVWRITELINE("duart_midi:chan1", ins8250_uart_device, rx_w), 31250)
MACHINE_CONFIG_END
static MACHINE_CONFIG_DERIVED( firebeat_spu, firebeat )
@ -2309,8 +2355,8 @@ void firebeat_state::init_firebeat()
atapi_init();
pc16552d_init(machine(), 0, 19660800, comm_uart_irq_callback, 0); // Network UART
pc16552d_init(machine(), 1, 24000000, midi_uart_irq_callback, 0); // MIDI UART
// pc16552d_init(machine(), 0, 19660800, comm_uart_irq_callback, 0); // Network UART
// pc16552d_init(machine(), 1, 24000000, midi_uart_irq_callback, 0); // MIDI UART
m_extend_board_irq_enable = 0x3f;
m_extend_board_irq_active = 0x00;
@ -2341,8 +2387,8 @@ DRIVER_INIT_MEMBER(firebeat_state,ppd)
void firebeat_state::init_keyboard()
{
// set keyboard timer
m_keyboard_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(firebeat_state::keyboard_timer_callback),this));
m_keyboard_timer->adjust(attotime::from_msec(10), 0, attotime::from_msec(10));
// m_keyboard_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(firebeat_state::keyboard_timer_callback),this));
// m_keyboard_timer->adjust(attotime::from_msec(10), 0, attotime::from_msec(10));
}
DRIVER_INIT_MEMBER(firebeat_state,kbm)

132
src/mame/machine/midikbd.c Normal file
View File

@ -0,0 +1,132 @@
#include "machine/midikbd.h"
const device_type MIDI_KBD = &device_creator<midi_keyboard_device>;
midi_keyboard_device::midi_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, MIDI_KBD, "Generic MIDI Keyboard", tag, owner, clock, "midi_kbd", __FILE__),
device_serial_interface(mconfig, *this),
m_out_tx_func(*this),
m_keyboard(*this, "KEYBOARD")
{
}
void midi_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
const int keyboard_notes[24] =
{
0x3c, // C1
0x3d, // C1#
0x3e, // D1
0x3f, // D1#
0x40, // E1
0x41, // F1
0x42, // F1#
0x43, // G1
0x44, // G1#
0x45, // A1
0x46, // A1#
0x47, // B1
0x48, // C2
0x49, // C2#
0x4a, // D2
0x4b, // D2#
0x4c, // E2
0x4d, // F2
0x4e, // F2#
0x4f, // G2
0x50, // G2#
0x51, // A2
0x52, // A2#
0x53, // B2
};
int i;
UINT32 kbstate = m_keyboard->read();
if(kbstate != m_keyboard_state)
{
for (i=0; i < 24; i++)
{
int kbnote = keyboard_notes[i];
if ((m_keyboard_state & (1 << i)) != 0 && (kbstate & (1 << i)) == 0)
{
// key was on, now off -> send Note Off message
push_tx(0x80);
push_tx(kbnote);
push_tx(0x7f);
}
else if ((m_keyboard_state & (1 << i)) == 0 && (kbstate & (1 << i)) != 0)
{
// key was off, now on -> send Note On message
push_tx(0x90);
push_tx(kbnote);
push_tx(0x7f);
}
}
}
else
// no messages, send Active Sense message instead
push_tx(0xfe);
m_keyboard_state = kbstate;
if(is_transmit_register_empty())
tra_complete();
}
void midi_keyboard_device::device_start()
{
set_data_frame(8, 1, SERIAL_PARITY_NONE); //8N1?
set_tra_rate(clock());
m_out_tx_func.resolve_safe();
m_head = m_tail = 0;
m_keyboard_timer = timer_alloc();
m_keyboard_timer->adjust(attotime::from_msec(10), 0, attotime::from_msec(10));
}
void midi_keyboard_device::tra_callback()
{
m_out_tx_func(transmit_register_get_data_bit());
}
void midi_keyboard_device::tra_complete()
{
if(m_head != m_tail)
{
transmit_register_setup(m_buffer[m_tail]);
++m_tail %= 16;
}
}
INPUT_PORTS_START(midi_keyboard)
PORT_START("KEYBOARD")
PORT_BIT( 0x000001, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 C1") PORT_CODE(KEYCODE_Q)
PORT_BIT( 0x000002, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 C1#") PORT_CODE(KEYCODE_W)
PORT_BIT( 0x000004, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 D1") PORT_CODE(KEYCODE_E)
PORT_BIT( 0x000008, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 D1#") PORT_CODE(KEYCODE_R)
PORT_BIT( 0x000010, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 E1") PORT_CODE(KEYCODE_T)
PORT_BIT( 0x000020, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 F1") PORT_CODE(KEYCODE_Y)
PORT_BIT( 0x000040, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 F1#") PORT_CODE(KEYCODE_U)
PORT_BIT( 0x000080, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 G1") PORT_CODE(KEYCODE_I)
PORT_BIT( 0x000100, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 G1#") PORT_CODE(KEYCODE_O)
PORT_BIT( 0x000200, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 A1") PORT_CODE(KEYCODE_A)
PORT_BIT( 0x000400, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 A1#") PORT_CODE(KEYCODE_S)
PORT_BIT( 0x000800, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 B1") PORT_CODE(KEYCODE_D)
PORT_BIT( 0x001000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 C2") PORT_CODE(KEYCODE_F)
PORT_BIT( 0x002000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 C2#") PORT_CODE(KEYCODE_G)
PORT_BIT( 0x004000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 D2") PORT_CODE(KEYCODE_H)
PORT_BIT( 0x008000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 D2#") PORT_CODE(KEYCODE_J)
PORT_BIT( 0x010000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 E2") PORT_CODE(KEYCODE_K)
PORT_BIT( 0x020000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 F2") PORT_CODE(KEYCODE_L)
PORT_BIT( 0x040000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 F2#") PORT_CODE(KEYCODE_Z)
PORT_BIT( 0x080000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 G2") PORT_CODE(KEYCODE_X)
PORT_BIT( 0x100000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 G2#") PORT_CODE(KEYCODE_C)
PORT_BIT( 0x200000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 A2") PORT_CODE(KEYCODE_V)
PORT_BIT( 0x400000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 A2#") PORT_CODE(KEYCODE_B)
PORT_BIT( 0x800000, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("P1 B2") PORT_CODE(KEYCODE_N)
INPUT_PORTS_END
ioport_constructor midi_keyboard_device::device_input_ports() const
{
return INPUT_PORTS_NAME(midi_keyboard);
}

View File

@ -0,0 +1,39 @@
#ifndef MIDIKBD_H_
#define MIDIKBD_H_
#include "emu.h"
#define MCFG_MIDI_KBD_ADD(_tag, _devcb, _clock) \
MCFG_DEVICE_ADD(_tag, MIDI_KBD, _clock) \
devcb = &midi_keyboard_device::static_set_tx_callback(*device, DEVCB2_##_devcb);
class midi_keyboard_device : public device_t,
public device_serial_interface
{
public:
midi_keyboard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
ioport_constructor device_input_ports() const;
template<class _Object> static devcb2_base &static_set_tx_callback(device_t &device, _Object object) { return downcast<midi_keyboard_device &>(device).m_out_tx_func.set_callback(object); }
void input_callback(UINT8 state) { m_input_state = state; }
protected:
void device_start();
void tra_callback();
void tra_complete();
void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
private:
void push_tx(UINT8 data) { ++m_head %= 16; m_buffer[m_head] = data; }
devcb2_write_line m_out_tx_func;
emu_timer *m_keyboard_timer;
required_ioport m_keyboard;
UINT32 m_keyboard_state;
UINT8 m_buffer[16];
UINT8 m_head, m_tail;
};
extern const device_type MIDI_KBD;
#endif /* MIDIKBD_H_ */

View File

@ -984,7 +984,7 @@ $(MAMEOBJ)/konami.a: \
$(DRIVERS)/fastfred.o $(VIDEO)/fastfred.o \
$(DRIVERS)/fastlane.o $(VIDEO)/fastlane.o \
$(DRIVERS)/finalizr.o $(VIDEO)/finalizr.o \
$(DRIVERS)/firebeat.o \
$(DRIVERS)/firebeat.o $(MACHINE)/midikbd.o \
$(DRIVERS)/flkatck.o $(VIDEO)/flkatck.o \
$(DRIVERS)/gberet.o $(VIDEO)/gberet.o \
$(DRIVERS)/gbusters.o $(VIDEO)/gbusters.o \