mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
(mess) D-110: Preliminary driver [Lord_Nightmare, O. Galibert]
This commit is contained in:
parent
e8738c6a89
commit
2187a8afa7
@ -81,7 +81,7 @@ void i8x9x_device::commit_hso_cam()
|
||||
{
|
||||
for(int i=0; i<8; i++)
|
||||
if(!hso_info[i].active) {
|
||||
if(hso_command != 0x18)
|
||||
if(hso_command != 0x18 && hso_command != 0x19)
|
||||
logerror("%s: hso cam %02x %04x in slot %d (%04x)\n", tag(), hso_command, hso_time, i, PPC);
|
||||
hso_info[i].active = true;
|
||||
hso_info[i].command = hso_command;
|
||||
@ -347,7 +347,7 @@ void i8x9x_device::internal_update(UINT64 current_time)
|
||||
UINT16 t = hso_info[i].time;
|
||||
if(((cmd & 0x40) && t == current_timer2) ||
|
||||
(!(cmd & 0x40) && t == current_timer1)) {
|
||||
if(cmd != 0x18)
|
||||
if(cmd != 0x18 && cmd != 0x19)
|
||||
logerror("%s: hso cam %02x %04x in slot %d triggered\n",
|
||||
tag(), cmd, t, i);
|
||||
trigger_cam(i, current_time);
|
||||
|
@ -61,13 +61,14 @@ public:
|
||||
#define O(o) void o ## _196_full(); void o ## _196_partial()
|
||||
|
||||
O(bmov_direct_2);
|
||||
O(cmpl_direct_2);
|
||||
O(bmovi_direct_2);
|
||||
O(pop_indirect_1);
|
||||
O(pop_indexed_1);
|
||||
O(cmpl_direct_2);
|
||||
O(djnzw_rrel8);
|
||||
O(pusha_none);
|
||||
O(idlpd_none);
|
||||
O(pop_indexed_1);
|
||||
O(pop_indirect_1);
|
||||
O(popa_none);
|
||||
O(pusha_none);
|
||||
|
||||
#undef O
|
||||
};
|
||||
|
@ -692,6 +692,66 @@ UINT16 mcs96_device::do_sub(UINT16 v1, UINT16 v2)
|
||||
return diff;
|
||||
}
|
||||
|
||||
UINT8 mcs96_device::do_addcb(UINT8 v1, UINT8 v2)
|
||||
{
|
||||
UINT16 sum = v1+v2+(PSW & F_C ? 1 : 0);
|
||||
PSW &= ~(F_Z|F_N|F_C|F_V);
|
||||
if(!UINT8(sum))
|
||||
PSW |= F_Z;
|
||||
else if(INT8(sum) < 0)
|
||||
PSW |= F_N;
|
||||
if(~(v1^v2) & (v1^sum) & 0x80)
|
||||
PSW |= F_V|F_VT;
|
||||
if(sum & 0xff00)
|
||||
PSW |= F_C;
|
||||
return sum;
|
||||
}
|
||||
|
||||
UINT16 mcs96_device::do_addc(UINT16 v1, UINT16 v2)
|
||||
{
|
||||
UINT32 sum = v1+v2+(PSW & F_C ? 1 : 0);
|
||||
PSW &= ~(F_Z|F_N|F_C|F_V);
|
||||
if(!UINT16(sum))
|
||||
PSW |= F_Z;
|
||||
else if(INT16(sum) < 0)
|
||||
PSW |= F_N;
|
||||
if(~(v1^v2) & (v1^sum) & 0x8000)
|
||||
PSW |= F_V|F_VT;
|
||||
if(sum & 0xffff0000)
|
||||
PSW |= F_C;
|
||||
return sum;
|
||||
}
|
||||
|
||||
UINT8 mcs96_device::do_subcb(UINT8 v1, UINT8 v2)
|
||||
{
|
||||
UINT16 diff = v1 - v2 - (PSW & F_C ? 0 : 1);
|
||||
PSW &= ~(F_N|F_V|F_Z|F_C);
|
||||
if(!UINT8(diff))
|
||||
PSW |= F_Z;
|
||||
else if(INT8(diff) < 0)
|
||||
PSW |= F_N;
|
||||
if((v1^v2) & (v1^diff) & 0x80)
|
||||
PSW |= F_V;
|
||||
if(!(diff & 0xff00))
|
||||
PSW |= F_C;
|
||||
return diff;
|
||||
}
|
||||
|
||||
UINT16 mcs96_device::do_subc(UINT16 v1, UINT16 v2)
|
||||
{
|
||||
UINT32 diff = v1 - v2 - (PSW & F_C ? 0 : 1);
|
||||
PSW &= ~(F_N|F_V|F_Z|F_C);
|
||||
if(!UINT16(diff))
|
||||
PSW |= F_Z;
|
||||
else if(INT16(diff) < 0)
|
||||
PSW |= F_N;
|
||||
if((v1^v2) & (v1^diff) & 0x8000)
|
||||
PSW |= F_V;
|
||||
if(!(diff & 0xffff0000))
|
||||
PSW |= F_C;
|
||||
return diff;
|
||||
}
|
||||
|
||||
void mcs96_device::set_nz8(UINT8 v)
|
||||
{
|
||||
PSW &= ~(F_N|F_V|F_Z|F_C);
|
||||
|
@ -163,6 +163,11 @@ protected:
|
||||
UINT8 do_subb(UINT8 v1, UINT8 v2);
|
||||
UINT16 do_sub(UINT16 v1, UINT16 v2);
|
||||
|
||||
UINT8 do_addcb(UINT8 v1, UINT8 v2);
|
||||
UINT16 do_addc(UINT16 v1, UINT16 v2);
|
||||
UINT8 do_subcb(UINT8 v1, UINT8 v2);
|
||||
UINT16 do_subc(UINT16 v1, UINT16 v2);
|
||||
|
||||
void set_nz8(UINT8 v);
|
||||
void set_nz16(UINT16 v);
|
||||
|
||||
@ -233,10 +238,8 @@ protected:
|
||||
O(or_direct_2); O(or_immed_2w); O(or_indexed_2); O(or_indirect_2);
|
||||
O(orb_direct_2); O(orb_immed_2b); O(orb_indexed_2); O(orb_indirect_2);
|
||||
O(pop_direct_1); O(pop_indexed_1); O(pop_indirect_1);
|
||||
O(popa_none);
|
||||
O(popf_none);
|
||||
O(push_direct_1); O(push_immed_1w); O(push_indexed_1); O(push_indirect_1);
|
||||
O(pusha_none);
|
||||
O(pushf_none);
|
||||
O(ret_none);
|
||||
O(rst_none);
|
||||
|
@ -1218,7 +1218,7 @@ fe8f div indexed_2
|
||||
9a cmpb indirect_2
|
||||
TMP = any_r8(OP1);
|
||||
do_subb(reg_r8(OP2), TMP);
|
||||
post_indirect 2 6 7 // +5 when external
|
||||
post_indirect 1 6 7 // +5 when external
|
||||
|
||||
9b cmpb indexed_2
|
||||
TMP = any_r8(OP1);
|
||||
@ -1352,20 +1352,50 @@ a3 ld indexed_2
|
||||
post_indexed 6 7 // +5 when external
|
||||
|
||||
a4 addc direct_2
|
||||
TMP = reg_r16(OP1);
|
||||
TMP = do_addc(reg_r16(OP2), TMP);
|
||||
reg_w16(OP2, TMP);
|
||||
next(4);
|
||||
|
||||
a5 addc immed_2w
|
||||
TMP = do_addc(reg_r16(OP2), OP1);
|
||||
reg_w16(OP2, TMP);
|
||||
next(5);
|
||||
|
||||
a6 addc indirect_2
|
||||
TMP = any_r16(OP1);
|
||||
TMP = do_addc(reg_r16(OP2), TMP);
|
||||
reg_w16(OP2, TMP);
|
||||
post_indirect 2 6 7 // +5 when external
|
||||
|
||||
a7 addc indexed_2
|
||||
TMP = any_r16(OP1);
|
||||
TMP = do_addc(reg_r16(OP2), TMP);
|
||||
reg_w16(OP2, TMP);
|
||||
post_indexed 6 7 // +5 when external
|
||||
|
||||
a8 subc direct_2
|
||||
TMP = reg_r16(OP1);
|
||||
TMP = do_subc(reg_r16(OP2), TMP);
|
||||
reg_w16(OP2, TMP);
|
||||
next(4);
|
||||
|
||||
a9 subc immed_2w
|
||||
TMP = do_subc(reg_r16(OP2), OP1);
|
||||
reg_w16(OP2, TMP);
|
||||
next(5);
|
||||
|
||||
aa subc indirect_2
|
||||
TMP = any_r16(OP1);
|
||||
TMP = do_subc(reg_r16(OP2), TMP);
|
||||
reg_w16(OP2, TMP);
|
||||
post_indirect 2 6 7 // +5 when external
|
||||
|
||||
ab subc indexed_2
|
||||
TMP = any_r16(OP1);
|
||||
TMP = do_subc(reg_r16(OP2), TMP);
|
||||
reg_w16(OP2, TMP);
|
||||
post_indexed 6 7 // +5 when external
|
||||
|
||||
ac ldbze direct_2
|
||||
reg_w16(OP2, UINT8(reg_r8(OP1)));
|
||||
@ -1400,20 +1430,50 @@ b3 ldb indexed_2
|
||||
post_indexed 6 7 // +5 when external
|
||||
|
||||
b4 addcb direct_2
|
||||
TMP = reg_r8(OP1);
|
||||
TMP = do_addcb(reg_r8(OP2), TMP);
|
||||
reg_w8(OP2, TMP);
|
||||
next(4);
|
||||
|
||||
b5 addcb immed_2w
|
||||
TMP = do_addcb(reg_r8(OP2), OP1);
|
||||
reg_w8(OP2, TMP);
|
||||
next(4);
|
||||
|
||||
b6 addcb indirect_2
|
||||
TMP = any_r8(OP1);
|
||||
TMP = do_addcb(reg_r8(OP2), TMP);
|
||||
reg_w8(OP2, TMP);
|
||||
post_indirect 1 6 7 // +5 when external
|
||||
|
||||
b7 addcb indexed_2
|
||||
TMP = any_r8(OP1);
|
||||
TMP = do_addcb(reg_r8(OP2), TMP);
|
||||
reg_w8(OP2, TMP);
|
||||
post_indexed 6 7 // +5 when external
|
||||
|
||||
b8 subcb direct_2
|
||||
TMP = reg_r8(OP1);
|
||||
TMP = do_subcb(reg_r8(OP2), TMP);
|
||||
reg_w8(OP2, TMP);
|
||||
next(4);
|
||||
|
||||
b9 subcb immed_2w
|
||||
TMP = do_subcb(reg_r8(OP2), OP1);
|
||||
reg_w8(OP2, TMP);
|
||||
next(4);
|
||||
|
||||
ba subcb indirect_2
|
||||
TMP = any_r8(OP1);
|
||||
TMP = do_subcb(reg_r8(OP2), TMP);
|
||||
reg_w8(OP2, TMP);
|
||||
post_indirect 1 6 7 // +5 when external
|
||||
|
||||
bb subcb indexed_2
|
||||
TMP = any_r8(OP1);
|
||||
TMP = do_subcb(reg_r8(OP2), TMP);
|
||||
reg_w8(OP2, TMP);
|
||||
post_indexed 6 7 // +5 when external
|
||||
|
||||
bc ldbse direct_2
|
||||
reg_w16(OP2, INT8(reg_r8(OP1)));
|
||||
@ -1727,7 +1787,7 @@ f3 popf none
|
||||
|
||||
f4 pusha none 196
|
||||
|
||||
f5 popa none
|
||||
f5 popa none 196
|
||||
|
||||
f6 idlpd none 196
|
||||
|
||||
|
@ -0,0 +1,272 @@
|
||||
/*************************************************************************************************
|
||||
|
||||
Roland D-110 driver
|
||||
|
||||
Driver by Olivier Galibert and Jonathan Gevaryahu
|
||||
|
||||
The Roland D-110 is an expander (synthesizer without the keyboard)
|
||||
from 1988. Internally it's very similar to a mt32, with a better
|
||||
LCD screen (16x2) and more control buttons. More importantly, it
|
||||
has more sound rom, a battery-backed ram and a port for memory
|
||||
cards allowing to load and save new sounds.
|
||||
|
||||
After the first boot, the ram needs to be reinitialized to factory
|
||||
default values. Press Write/Copy (I) while resetting then
|
||||
validate with Enter (K).
|
||||
*/
|
||||
|
||||
#include "emu.h"
|
||||
#include "machine/ram.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/msm6222b.h"
|
||||
#include "cpu/mcs96/i8x9x.h"
|
||||
|
||||
static INPUT_PORTS_START( d110 )
|
||||
PORT_START("SC0")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Write/Copy") PORT_CODE(KEYCODE_I)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Number +") PORT_CODE(KEYCODE_U)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Bank +") PORT_CODE(KEYCODE_Y)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Group +") PORT_CODE(KEYCODE_T)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part +") PORT_CODE(KEYCODE_R)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Timbre") PORT_CODE(KEYCODE_E)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Patch") PORT_CODE(KEYCODE_W)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Exit") PORT_CODE(KEYCODE_Q)
|
||||
|
||||
PORT_START("SC1")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Enter") PORT_CODE(KEYCODE_K)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Number -") PORT_CODE(KEYCODE_J)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Bank -") PORT_CODE(KEYCODE_H)
|
||||
PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Group -") PORT_CODE(KEYCODE_G)
|
||||
PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part -") PORT_CODE(KEYCODE_F)
|
||||
PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("System") PORT_CODE(KEYCODE_D)
|
||||
PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part") PORT_CODE(KEYCODE_S)
|
||||
PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Edit") PORT_CODE(KEYCODE_A)
|
||||
INPUT_PORTS_END
|
||||
|
||||
class d110_state : public driver_device
|
||||
{
|
||||
public:
|
||||
required_device<i8x9x_device> cpu;
|
||||
required_device<ram_device> ram;
|
||||
required_device<nvram_device> rams;
|
||||
required_device<ram_device> memc;
|
||||
required_device<nvram_device> memcs;
|
||||
required_device<msm6222b_device> lcd;
|
||||
required_device<timer_device> midi_timer;
|
||||
|
||||
d110_state(const machine_config &mconfig, device_type type, const char *tag);
|
||||
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
virtual void palette_init();
|
||||
|
||||
UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(bank_w);
|
||||
DECLARE_WRITE8_MEMBER(so_w);
|
||||
DECLARE_WRITE16_MEMBER(midi_w);
|
||||
|
||||
DECLARE_READ8_MEMBER(lcd_ctrl_r);
|
||||
DECLARE_WRITE8_MEMBER(lcd_ctrl_w);
|
||||
DECLARE_WRITE8_MEMBER(lcd_data_w);
|
||||
DECLARE_READ16_MEMBER(port0_r);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(midi_timer_cb);
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(samples_timer_cb);
|
||||
|
||||
private:
|
||||
UINT8 lcd_data_buffer[256];
|
||||
int lcd_data_buffer_pos;
|
||||
UINT8 midi;
|
||||
int midi_pos;
|
||||
UINT8 port0;
|
||||
};
|
||||
|
||||
d110_state::d110_state(const machine_config &mconfig, device_type type, const char *tag) :
|
||||
driver_device(mconfig, type, tag),
|
||||
cpu(*this, "maincpu"),
|
||||
ram(*this, "ram"),
|
||||
rams(*this, "rams"),
|
||||
memc(*this, "memc"),
|
||||
memcs(*this, "memcs"),
|
||||
lcd(*this, "lcd"),
|
||||
midi_timer(*this, "midi_timer")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
UINT32 d110_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bitmap.fill(0);
|
||||
const UINT8 *data = lcd->render();
|
||||
for(int l=0; l<2; l++)
|
||||
for(int c=0; c<20; c++)
|
||||
for(int y=0; y<8; y++) {
|
||||
UINT8 v = data[c*16 + l*40*16 + y];
|
||||
for(int x=0; x<5; x++)
|
||||
bitmap.pix16(y+9*l, c*6+x) = v & (0x10 >> x) ? 1 : 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void d110_state::machine_start()
|
||||
{
|
||||
rams->set_base(ram->pointer(), 32768);
|
||||
memcs->set_base(memc->pointer(), 32768);
|
||||
|
||||
membank("bank")->configure_entries(0x00, 4, memregion("maincpu")->base(), 0x4000);
|
||||
membank("bank")->configure_entries(0x10, 2, ram->pointer(), 0x4000);
|
||||
membank("bank")->configure_entries(0x20, 8, memregion("presets")->base(), 0x4000);
|
||||
membank("bank")->configure_entries(0x30, 2, memc->pointer(), 0x4000);
|
||||
membank("fixed")->set_base(ram->pointer());
|
||||
|
||||
lcd_data_buffer_pos = 0;
|
||||
}
|
||||
|
||||
void d110_state::machine_reset()
|
||||
{
|
||||
// midi_timer->adjust(attotime::from_hz(1));
|
||||
midi_pos = 0;
|
||||
port0 = 0x80; // battery ok
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(d110_state::lcd_ctrl_w)
|
||||
{
|
||||
lcd->control_w(data);
|
||||
for(int i=0; i != lcd_data_buffer_pos; i++)
|
||||
lcd->data_w(lcd_data_buffer[i]);
|
||||
lcd_data_buffer_pos = 0;
|
||||
}
|
||||
|
||||
READ8_MEMBER(d110_state::lcd_ctrl_r)
|
||||
{
|
||||
// Busy flag in the msm622b is bit 7, while the software expects it in bit 0...
|
||||
return lcd->control_r() >> 7;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(d110_state::lcd_data_w)
|
||||
{
|
||||
if(lcd_data_buffer_pos == sizeof(lcd_data_buffer)) {
|
||||
logerror("Warning: lcd data buffer overflow (%04x)\n", cpu->pc());
|
||||
return;
|
||||
}
|
||||
lcd_data_buffer[lcd_data_buffer_pos++] = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(d110_state::bank_w)
|
||||
{
|
||||
membank("bank")->set_entry(data);
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(d110_state::midi_w)
|
||||
{
|
||||
logerror("midi_out %02x\n", data);
|
||||
midi = data;
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(d110_state::midi_timer_cb)
|
||||
{
|
||||
const static UINT8 midi_data[3] = { 0x91, 0x40, 0x7f };
|
||||
midi = midi_data[midi_pos++];
|
||||
logerror("midi_in %02x\n", midi);
|
||||
cpu->serial_w(midi);
|
||||
if(midi_pos < sizeof(midi_data))
|
||||
midi_timer->adjust(attotime::from_hz(1250));
|
||||
}
|
||||
|
||||
READ16_MEMBER(d110_state::port0_r)
|
||||
{
|
||||
return port0;
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(d110_state::samples_timer_cb)
|
||||
{
|
||||
port0 ^= 0x10;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(d110_state::so_w)
|
||||
{
|
||||
// bit 0 = led
|
||||
// bit 1-2 = reverb program a13/a14
|
||||
// bit 3 = R. SW. to ananlog board
|
||||
// bit 5 = boss 8Mhz clock, handled internally
|
||||
// logerror("so: rw=%d bank=%d led=%d\n", (data >> 3) & 1, (data >> 1) & 3, data & 1);
|
||||
}
|
||||
|
||||
void d110_state::palette_init()
|
||||
{
|
||||
palette_set_color(machine(), 0, MAKE_RGB(0, 255, 0));
|
||||
palette_set_color(machine(), 1, MAKE_RGB(0, 0, 0));
|
||||
}
|
||||
|
||||
static ADDRESS_MAP_START( d110_map, AS_PROGRAM, 8, d110_state )
|
||||
AM_RANGE(0x0100, 0x0100) AM_WRITE(bank_w)
|
||||
AM_RANGE(0x0200, 0x0200) AM_WRITE(so_w)
|
||||
AM_RANGE(0x021a, 0x021a) AM_READ_PORT("SC0") AM_WRITENOP
|
||||
AM_RANGE(0x021c, 0x021c) AM_READ_PORT("SC1")
|
||||
AM_RANGE(0x0300, 0x0300) AM_WRITE(lcd_data_w)
|
||||
AM_RANGE(0x0380, 0x0380) AM_READWRITE(lcd_ctrl_r, lcd_ctrl_w)
|
||||
AM_RANGE(0x1000, 0x7fff) AM_ROM AM_REGION("maincpu", 0x1000)
|
||||
AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank")
|
||||
AM_RANGE(0xc000, 0xffff) AM_RAMBANK("fixed")
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START( d110_io, AS_IO, 16, d110_state )
|
||||
AM_RANGE(i8x9x_device::SERIAL, i8x9x_device::SERIAL) AM_WRITE(midi_w)
|
||||
AM_RANGE(i8x9x_device::P0, i8x9x_device::P0) AM_READ(port0_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static MACHINE_CONFIG_START( d110, d110_state )
|
||||
MCFG_CPU_ADD( "maincpu", P8098, XTAL_12MHz )
|
||||
MCFG_CPU_PROGRAM_MAP( d110_map )
|
||||
MCFG_CPU_IO_MAP( d110_io )
|
||||
|
||||
// Battery-backed main ram
|
||||
MCFG_RAM_ADD( "ram" )
|
||||
MCFG_RAM_DEFAULT_SIZE( "32K" )
|
||||
MCFG_NVRAM_ADD_0FILL( "rams" )
|
||||
|
||||
|
||||
// Shall become a proper memcard device someday
|
||||
MCFG_RAM_ADD( "memc" )
|
||||
MCFG_RAM_DEFAULT_SIZE( "32K" )
|
||||
MCFG_NVRAM_ADD_0FILL( "memcs" )
|
||||
|
||||
MCFG_SCREEN_ADD( "screen", LCD )
|
||||
MCFG_SCREEN_REFRESH_RATE(50)
|
||||
MCFG_SCREEN_UPDATE_DRIVER(d110_state, screen_update)
|
||||
// MCFG_SCREEN_SIZE(20*6-1, 2*9-1)
|
||||
MCFG_SCREEN_SIZE(16*6-1, (16*6-1)*3/4)
|
||||
MCFG_SCREEN_VISIBLE_AREA(0, 16*6-2, 0, (16*6-1)*3/4-1)
|
||||
MCFG_PALETTE_LENGTH(2)
|
||||
|
||||
MCFG_MSM6222B_01_ADD( "lcd" )
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD( "midi_timer", d110_state, midi_timer_cb )
|
||||
|
||||
MCFG_TIMER_DRIVER_ADD_PERIODIC( "samples_timer", d110_state, samples_timer_cb, attotime::from_hz(32000*2) )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
ROM_START( d110 )
|
||||
ROM_REGION( 0x10000, "maincpu", 0 )
|
||||
ROM_DEFAULT_BIOS( "110" )
|
||||
|
||||
ROM_SYSTEM_BIOS( 0, "106", "Firmware 1.06" )
|
||||
ROMX_LOAD( "d-110.v1.06.ic19.bin", 0, 0x8000, CRC(3dd5b6e9) SHA1(73b155fb0a8adc2362e73cb0803dafba9ccfb508), ROM_BIOS(1) )
|
||||
|
||||
ROM_SYSTEM_BIOS( 1, "110", "Firmware 1.10" )
|
||||
ROMX_LOAD( "d-110.v1.10.ic19.bin", 0, 0x8000, CRC(3ae68187) SHA1(28635510f30d6c1fb88e00da03e5b4e045c380cb), ROM_BIOS(2) )
|
||||
|
||||
ROM_REGION( 0x20000, "presets", 0 )
|
||||
ROM_LOAD( "r15179873-lh5310-97.ic12.bin", 0, 0x20000, CRC(580a8f9e) SHA1(05587a0542b01625dcde37de5bb339880e47eb93) )
|
||||
|
||||
ROM_REGION( 0x100000, "la32", 0 )
|
||||
ROM_LOAD( "r15179878.ic7.bin", 0, 0x80000, CRC(e117e6ab) SHA1(6760d14900161b8715c2bfd4ebe997877087c90c) )
|
||||
ROM_LOAD( "r15179880.ic8.bin", 0x80000, 0x80000, CRC(b329f945) SHA1(9c59f50518a070461b2ec6cb4e43ee7cc1e905b6) )
|
||||
|
||||
ROM_REGION( 0x8000, "boss", 0 )
|
||||
ROM_LOAD( "r15179879.ic6.bin", 0, 0x8000, CRC(5d34174e) SHA1(17bd2887711c5c5458aba6d3be5972b2096eb450) )
|
||||
ROM_END
|
||||
|
||||
CONS( 1988, d110, 0, 0, d110, d110, driver_device, 0, "Roland", "D110", GAME_NOT_WORKING|GAME_NO_SOUND )
|
||||
|
@ -0,0 +1,277 @@
|
||||
/***************************************************************************
|
||||
|
||||
MSM6222B
|
||||
|
||||
A somewhat hd44780-compatible LCD controller.
|
||||
|
||||
The -01 variant has a fixed cgrom, the other variants are mask-programmed.
|
||||
|
||||
****************************************************************************
|
||||
|
||||
Copyright Olivier Galibert
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name 'MAME' nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "msm6222b.h"
|
||||
|
||||
const device_type MSM6222B = &device_creator<msm6222b_device>;
|
||||
const device_type MSM6222B_01 = &device_creator<msm6222b_01_device>;
|
||||
|
||||
ROM_START( msm6222b_01 )
|
||||
ROM_REGION( 0x1000, "cgrom", 0 )
|
||||
ROM_LOAD( "msm6222b-01.bin", 0x0000, 0x1000, CRC(8ffa8521) SHA1(e108b520e6d20459a7bbd5958bbfa1d551a690bd) )
|
||||
ROM_END
|
||||
|
||||
msm6222b_device::msm6222b_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)
|
||||
{
|
||||
m_shortname = "msm6222b";
|
||||
}
|
||||
|
||||
msm6222b_device::msm6222b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, MSM6222B, "msm6222b-xx", tag, owner, clock)
|
||||
{
|
||||
m_shortname = "msm6222b";
|
||||
}
|
||||
|
||||
msm6222b_01_device::msm6222b_01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
msm6222b_device(mconfig, MSM6222B_01, "msm6222b-01", tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
const rom_entry *msm6222b_01_device::device_rom_region() const
|
||||
{
|
||||
return ROM_NAME(msm6222b_01);
|
||||
}
|
||||
|
||||
void msm6222b_device::device_start()
|
||||
{
|
||||
if(memregion("cgrom"))
|
||||
cgrom = memregion("cgrom")->base();
|
||||
else if(m_region)
|
||||
cgrom = m_region->base();
|
||||
else
|
||||
cgrom = NULL;
|
||||
|
||||
memset(cgram, 0, sizeof(cgram));
|
||||
memset(ddram, 0x20, sizeof(ddram));
|
||||
|
||||
cursor_direction = true;
|
||||
cursor_blinking = false;
|
||||
display_on = false;
|
||||
two_line = false;
|
||||
cursor_on = false;
|
||||
shift_on_write = false;
|
||||
double_height = false;
|
||||
adc = 0x00;
|
||||
shift = 0;
|
||||
}
|
||||
|
||||
void msm6222b_device::control_w(UINT8 data)
|
||||
{
|
||||
int cmd;
|
||||
for(cmd = 7; cmd >= 0 && !(data & (1<<cmd)); cmd--);
|
||||
switch(cmd) {
|
||||
case 0:
|
||||
memset(ddram, 0x20, sizeof(ddram));
|
||||
adc = 0x00;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
adc = 0x00;
|
||||
shift = 0x00;
|
||||
break;
|
||||
case 2:
|
||||
shift_on_write = data & 1;
|
||||
cursor_direction = data & 2;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
display_on = data & 4;
|
||||
cursor_on = data & 2;
|
||||
cursor_blinking = data & 1;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if(data & 8)
|
||||
shift_step(data & 4);
|
||||
else
|
||||
cursor_step(data & 4);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
two_line = data & 8;
|
||||
double_height = (data & 0xc) == 4;
|
||||
// Bit 4 is 4bits/8bits data access
|
||||
break;
|
||||
|
||||
case 6:
|
||||
adc = data & 0x3f;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
adc = data; // Bit 7 is set
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
UINT8 msm6222b_device::control_r()
|
||||
{
|
||||
return adc & 0x7f;
|
||||
}
|
||||
|
||||
void msm6222b_device::data_w(UINT8 data)
|
||||
{
|
||||
if(adc & 0x80) {
|
||||
int adr = adc & 0x7f;
|
||||
if(two_line) {
|
||||
if((adr >= 40 && adr < 64) || adr >= 64+40)
|
||||
adr = -1;
|
||||
if(adr >= 64)
|
||||
adr += 40-64;
|
||||
} else {
|
||||
if(adr >= 80)
|
||||
adr = -1;
|
||||
}
|
||||
if(adr != -1) {
|
||||
ddram[adr] = data;
|
||||
if(shift_on_write)
|
||||
shift_step(cursor_direction);
|
||||
else
|
||||
cursor_step(cursor_direction);
|
||||
}
|
||||
} else {
|
||||
if(adc < 8*8) {
|
||||
cgram[adc] = data;
|
||||
cursor_step(cursor_direction);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msm6222b_device::cursor_step(bool direction)
|
||||
{
|
||||
if(direction) {
|
||||
if(adc & 0x80) {
|
||||
if(two_line && adc == (0x80|39))
|
||||
adc = 0x80|64;
|
||||
else if(two_line && adc == (0x80|(64+39)))
|
||||
adc = 0x80;
|
||||
else if((!two_line) && adc == (0x80|79))
|
||||
adc = 0x80;
|
||||
else
|
||||
adc++;
|
||||
} else {
|
||||
if(adc == 8*8-1)
|
||||
adc = 0x00;
|
||||
else
|
||||
adc++;
|
||||
}
|
||||
} else {
|
||||
if(adc & 0x80) {
|
||||
if(adc == 0x80)
|
||||
adc = two_line ? 0x80|(64+39) : 0x80|79;
|
||||
else if(two_line && adc == (0x80|64))
|
||||
adc = 0x80|39;
|
||||
else
|
||||
adc--;
|
||||
} else {
|
||||
if(adc == 0x00)
|
||||
adc = 8*8-1;
|
||||
else
|
||||
adc--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void msm6222b_device::shift_step(bool direction)
|
||||
{
|
||||
if(direction) {
|
||||
if(shift == 79)
|
||||
shift = 0;
|
||||
else
|
||||
shift++;
|
||||
} else {
|
||||
if(shift == 0)
|
||||
shift = 79;
|
||||
else
|
||||
shift--;
|
||||
}
|
||||
}
|
||||
|
||||
bool msm6222b_device::blink_on() const
|
||||
{
|
||||
if(!cursor_blinking)
|
||||
return false;
|
||||
UINT64 clocks = machine().time().as_ticks(250000);
|
||||
if(double_height)
|
||||
return clocks % 281600 >= 140800;
|
||||
else
|
||||
return clocks % 204800 >= 102400;
|
||||
}
|
||||
|
||||
const UINT8 *msm6222b_device::render()
|
||||
{
|
||||
memset(render_buf, 0, 80*16);
|
||||
if(!display_on)
|
||||
return render_buf;
|
||||
|
||||
int char_height = double_height ? 11 : 8;
|
||||
|
||||
for(int i=0; i<80; i++) {
|
||||
UINT8 c = ddram[(i+shift) % 80];
|
||||
if(c < 16)
|
||||
memcpy(render_buf + 16*i, double_height ? cgram + 8*(c & 6) : cgram + 8*(c & 7), char_height);
|
||||
else if(cgrom)
|
||||
memcpy(render_buf + 16*i, cgrom + 16*c, char_height);
|
||||
}
|
||||
|
||||
if(cursor_on) {
|
||||
int cpos = adc & 0x7f;
|
||||
if(two_line) {
|
||||
if((cpos >= 40 && cpos < 64) || cpos >= 64+40)
|
||||
cpos = -1;
|
||||
else if(cpos >= 64)
|
||||
cpos += 40-64;
|
||||
} else {
|
||||
if(cpos >= 80)
|
||||
cpos = -1;
|
||||
}
|
||||
if(cpos != -1) {
|
||||
cpos = (cpos + shift) % 80;
|
||||
render_buf[cpos*16 + (double_height ? 10 : 7)] |= 0x1f;
|
||||
if(blink_on())
|
||||
for(int i=0; i<char_height; i++)
|
||||
render_buf[cpos*16 + i] ^= 0x1f;
|
||||
}
|
||||
}
|
||||
|
||||
return render_buf;
|
||||
}
|
@ -0,0 +1,92 @@
|
||||
/***************************************************************************
|
||||
|
||||
MSM6222B
|
||||
|
||||
A somewhat hd44780-compatible LCD controller.
|
||||
|
||||
The -01 variant has a fixed cgrom, the other variants are mask-programmed.
|
||||
|
||||
****************************************************************************
|
||||
|
||||
Copyright Olivier Galibert
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name 'MAME' nor the names of its contributors may be
|
||||
used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __MSM6222B_H__
|
||||
#define __MSM6222B_H__
|
||||
|
||||
#define MCFG_MSM6222B_ADD( _tag ) \
|
||||
MCFG_DEVICE_ADD( _tag, MSM6222B, 0 )
|
||||
|
||||
#define MCFG_MSM6222B_01_ADD( _tag ) \
|
||||
MCFG_DEVICE_ADD( _tag, MSM6222B_01, 0 )
|
||||
|
||||
class msm6222b_device : public device_t {
|
||||
public:
|
||||
msm6222b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
msm6222b_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
void control_w(UINT8 data);
|
||||
UINT8 control_r();
|
||||
void data_w(UINT8 data);
|
||||
UINT8 data_r();
|
||||
|
||||
// Character n bits are at bytes n*16..n*16+7 when 8-high, +10 when 11-high. Only the low 5 bits are used.
|
||||
// In one line mode n = 0..79. In two line mode first line is 0..39 and second is 40..79.
|
||||
const UINT8 *render();
|
||||
|
||||
protected:
|
||||
virtual void device_start();
|
||||
|
||||
private:
|
||||
UINT8 cgram[8*8];
|
||||
UINT8 ddram[80];
|
||||
UINT8 render_buf[80*16];
|
||||
bool cursor_direction, cursor_blinking, two_line, shift_on_write, double_height, cursor_on, display_on;
|
||||
UINT8 adc, shift;
|
||||
const UINT8 *cgrom;
|
||||
|
||||
void cursor_step(bool direction);
|
||||
void shift_step(bool direction);
|
||||
bool blink_on() const;
|
||||
};
|
||||
|
||||
class msm6222b_01_device : public msm6222b_device {
|
||||
public:
|
||||
msm6222b_01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
protected:
|
||||
virtual const rom_entry *device_rom_region() const;
|
||||
};
|
||||
|
||||
extern const device_type MSM6222B;
|
||||
extern const device_type MSM6222B_01;
|
||||
|
||||
#endif
|
@ -346,6 +346,7 @@ mu100 // 1997 MU-100
|
||||
// Roland
|
||||
mt32
|
||||
cm32l
|
||||
d110
|
||||
|
||||
//***************COMPUTERS**************************************************
|
||||
|
||||
|
@ -532,6 +532,7 @@ $(MESSOBJ)/shared.a: \
|
||||
$(MESS_MACHINE)/mos6530.o \
|
||||
$(MESS_MACHINE)/s100.o \
|
||||
$(MESS_MACHINE)/sed1200.o \
|
||||
$(MESS_MACHINE)/msm6222b.o \
|
||||
$(MESS_MACHINE)/serial.o \
|
||||
$(MESS_MACHINE)/ncr5380.o \
|
||||
$(MESS_MACHINE)/ncr5390.o \
|
||||
@ -1594,6 +1595,7 @@ $(MESSOBJ)/robotron.a: \
|
||||
|
||||
$(MESSOBJ)/roland.a: \
|
||||
$(MESS_DRIVERS)/rmt32.o \
|
||||
$(MESS_DRIVERS)/rd110.o \
|
||||
|
||||
$(MESSOBJ)/rockwell.a: \
|
||||
$(MESS_MACHINE)/aim65.o \
|
||||
|
Loading…
Reference in New Issue
Block a user