diff options
author | 2013-01-04 13:18:27 +0000 | |
---|---|---|
committer | 2013-01-04 13:18:27 +0000 | |
commit | 2187a8afa73212d6807031e2120467f0a600f17f (patch) | |
tree | a5bb40598b53c18c417741dc3b2998bb1d433268 | |
parent | e8738c6a899d8ad0ef5aa205041ca9735c04fd24 (diff) |
(mess) D-110: Preliminary driver [Lord_Nightmare, O. Galibert]
-rw-r--r-- | src/emu/cpu/mcs96/i8x9x.c | 4 | ||||
-rw-r--r-- | src/emu/cpu/mcs96/i8xc196.h | 9 | ||||
-rw-r--r-- | src/emu/cpu/mcs96/mcs96.c | 60 | ||||
-rw-r--r-- | src/emu/cpu/mcs96/mcs96.h | 7 | ||||
-rw-r--r-- | src/emu/cpu/mcs96/mcs96ops.lst | 64 | ||||
-rw-r--r-- | src/mess/drivers/rd110.c | 272 | ||||
-rw-r--r-- | src/mess/machine/msm6222b.c | 277 | ||||
-rw-r--r-- | src/mess/machine/msm6222b.h | 92 | ||||
-rw-r--r-- | src/mess/mess.lst | 1 | ||||
-rw-r--r-- | src/mess/mess.mak | 2 |
10 files changed, 778 insertions, 10 deletions
diff --git a/src/emu/cpu/mcs96/i8x9x.c b/src/emu/cpu/mcs96/i8x9x.c index 886f2da7887..74921d2aa34 100644 --- a/src/emu/cpu/mcs96/i8x9x.c +++ b/src/emu/cpu/mcs96/i8x9x.c @@ -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); diff --git a/src/emu/cpu/mcs96/i8xc196.h b/src/emu/cpu/mcs96/i8xc196.h index de509ba0b7e..7a7fcd2b77d 100644 --- a/src/emu/cpu/mcs96/i8xc196.h +++ b/src/emu/cpu/mcs96/i8xc196.h @@ -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 }; diff --git a/src/emu/cpu/mcs96/mcs96.c b/src/emu/cpu/mcs96/mcs96.c index 849163fb2e3..224cd944e27 100644 --- a/src/emu/cpu/mcs96/mcs96.c +++ b/src/emu/cpu/mcs96/mcs96.c @@ -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); diff --git a/src/emu/cpu/mcs96/mcs96.h b/src/emu/cpu/mcs96/mcs96.h index a1a1b0aa175..570a48f78a7 100644 --- a/src/emu/cpu/mcs96/mcs96.h +++ b/src/emu/cpu/mcs96/mcs96.h @@ -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); diff --git a/src/emu/cpu/mcs96/mcs96ops.lst b/src/emu/cpu/mcs96/mcs96ops.lst index bef886451f6..0eefa2e2d92 100644 --- a/src/emu/cpu/mcs96/mcs96ops.lst +++ b/src/emu/cpu/mcs96/mcs96ops.lst @@ -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 diff --git a/src/mess/drivers/rd110.c b/src/mess/drivers/rd110.c index e69de29bb2d..90acc874d27 100644 --- a/src/mess/drivers/rd110.c +++ b/src/mess/drivers/rd110.c @@ -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 ) + diff --git a/src/mess/machine/msm6222b.c b/src/mess/machine/msm6222b.c index e69de29bb2d..f8980253be9 100644 --- a/src/mess/machine/msm6222b.c +++ b/src/mess/machine/msm6222b.c @@ -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; +} diff --git a/src/mess/machine/msm6222b.h b/src/mess/machine/msm6222b.h index e69de29bb2d..0abcecd8be8 100644 --- a/src/mess/machine/msm6222b.h +++ b/src/mess/machine/msm6222b.h @@ -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 diff --git a/src/mess/mess.lst b/src/mess/mess.lst index 55156bfd232..02514a4a95f 100644 --- a/src/mess/mess.lst +++ b/src/mess/mess.lst @@ -346,6 +346,7 @@ mu100 // 1997 MU-100 // Roland mt32 cm32l +d110 //***************COMPUTERS************************************************** diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 8fde7b3fae0..166b83c8c21 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -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 \ |