trunk/src/mess/machine/msm6222b.c
| r20056 | r20057 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | MSM6222B |
| 4 | |
| 5 | A somewhat hd44780-compatible LCD controller. |
| 6 | |
| 7 | The -01 variant has a fixed cgrom, the other variants are mask-programmed. |
| 8 | |
| 9 | **************************************************************************** |
| 10 | |
| 11 | Copyright Olivier Galibert |
| 12 | All rights reserved. |
| 13 | |
| 14 | Redistribution and use in source and binary forms, with or without |
| 15 | modification, are permitted provided that the following conditions are |
| 16 | met: |
| 17 | |
| 18 | * Redistributions of source code must retain the above copyright |
| 19 | notice, this list of conditions and the following disclaimer. |
| 20 | * Redistributions in binary form must reproduce the above copyright |
| 21 | notice, this list of conditions and the following disclaimer in |
| 22 | the documentation and/or other materials provided with the |
| 23 | distribution. |
| 24 | * Neither the name 'MAME' nor the names of its contributors may be |
| 25 | used to endorse or promote products derived from this software |
| 26 | without specific prior written permission. |
| 27 | |
| 28 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 29 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 31 | DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT, |
| 32 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 34 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 35 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 36 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 37 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 38 | POSSIBILITY OF SUCH DAMAGE. |
| 39 | |
| 40 | ***************************************************************************/ |
| 41 | |
| 42 | #include "emu.h" |
| 43 | #include "msm6222b.h" |
| 44 | |
| 45 | const device_type MSM6222B = &device_creator<msm6222b_device>; |
| 46 | const device_type MSM6222B_01 = &device_creator<msm6222b_01_device>; |
| 47 | |
| 48 | ROM_START( msm6222b_01 ) |
| 49 | ROM_REGION( 0x1000, "cgrom", 0 ) |
| 50 | ROM_LOAD( "msm6222b-01.bin", 0x0000, 0x1000, CRC(8ffa8521) SHA1(e108b520e6d20459a7bbd5958bbfa1d551a690bd) ) |
| 51 | ROM_END |
| 52 | |
| 53 | msm6222b_device::msm6222b_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock) : |
| 54 | device_t(mconfig, type, name, tag, owner, clock) |
| 55 | { |
| 56 | m_shortname = "msm6222b"; |
| 57 | } |
| 58 | |
| 59 | msm6222b_device::msm6222b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 60 | device_t(mconfig, MSM6222B, "msm6222b-xx", tag, owner, clock) |
| 61 | { |
| 62 | m_shortname = "msm6222b"; |
| 63 | } |
| 64 | |
| 65 | msm6222b_01_device::msm6222b_01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 66 | msm6222b_device(mconfig, MSM6222B_01, "msm6222b-01", tag, owner, clock) |
| 67 | { |
| 68 | } |
| 69 | |
| 70 | const rom_entry *msm6222b_01_device::device_rom_region() const |
| 71 | { |
| 72 | return ROM_NAME(msm6222b_01); |
| 73 | } |
| 74 | |
| 75 | void msm6222b_device::device_start() |
| 76 | { |
| 77 | if(memregion("cgrom")) |
| 78 | cgrom = memregion("cgrom")->base(); |
| 79 | else if(m_region) |
| 80 | cgrom = m_region->base(); |
| 81 | else |
| 82 | cgrom = NULL; |
| 83 | |
| 84 | memset(cgram, 0, sizeof(cgram)); |
| 85 | memset(ddram, 0x20, sizeof(ddram)); |
| 86 | |
| 87 | cursor_direction = true; |
| 88 | cursor_blinking = false; |
| 89 | display_on = false; |
| 90 | two_line = false; |
| 91 | cursor_on = false; |
| 92 | shift_on_write = false; |
| 93 | double_height = false; |
| 94 | adc = 0x00; |
| 95 | shift = 0; |
| 96 | } |
| 97 | |
| 98 | void msm6222b_device::control_w(UINT8 data) |
| 99 | { |
| 100 | int cmd; |
| 101 | for(cmd = 7; cmd >= 0 && !(data & (1<<cmd)); cmd--); |
| 102 | switch(cmd) { |
| 103 | case 0: |
| 104 | memset(ddram, 0x20, sizeof(ddram)); |
| 105 | adc = 0x00; |
| 106 | break; |
| 107 | |
| 108 | case 1: |
| 109 | adc = 0x00; |
| 110 | shift = 0x00; |
| 111 | break; |
| 112 | case 2: |
| 113 | shift_on_write = data & 1; |
| 114 | cursor_direction = data & 2; |
| 115 | break; |
| 116 | |
| 117 | case 3: |
| 118 | display_on = data & 4; |
| 119 | cursor_on = data & 2; |
| 120 | cursor_blinking = data & 1; |
| 121 | break; |
| 122 | |
| 123 | case 4: |
| 124 | if(data & 8) |
| 125 | shift_step(data & 4); |
| 126 | else |
| 127 | cursor_step(data & 4); |
| 128 | break; |
| 129 | |
| 130 | case 5: |
| 131 | two_line = data & 8; |
| 132 | double_height = (data & 0xc) == 4; |
| 133 | // Bit 4 is 4bits/8bits data access |
| 134 | break; |
| 135 | |
| 136 | case 6: |
| 137 | adc = data & 0x3f; |
| 138 | break; |
| 139 | |
| 140 | case 7: |
| 141 | adc = data; // Bit 7 is set |
| 142 | break; |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | UINT8 msm6222b_device::control_r() |
| 147 | { |
| 148 | return adc & 0x7f; |
| 149 | } |
| 150 | |
| 151 | void msm6222b_device::data_w(UINT8 data) |
| 152 | { |
| 153 | if(adc & 0x80) { |
| 154 | int adr = adc & 0x7f; |
| 155 | if(two_line) { |
| 156 | if((adr >= 40 && adr < 64) || adr >= 64+40) |
| 157 | adr = -1; |
| 158 | if(adr >= 64) |
| 159 | adr += 40-64; |
| 160 | } else { |
| 161 | if(adr >= 80) |
| 162 | adr = -1; |
| 163 | } |
| 164 | if(adr != -1) { |
| 165 | ddram[adr] = data; |
| 166 | if(shift_on_write) |
| 167 | shift_step(cursor_direction); |
| 168 | else |
| 169 | cursor_step(cursor_direction); |
| 170 | } |
| 171 | } else { |
| 172 | if(adc < 8*8) { |
| 173 | cgram[adc] = data; |
| 174 | cursor_step(cursor_direction); |
| 175 | } |
| 176 | } |
| 177 | } |
| 178 | |
| 179 | void msm6222b_device::cursor_step(bool direction) |
| 180 | { |
| 181 | if(direction) { |
| 182 | if(adc & 0x80) { |
| 183 | if(two_line && adc == (0x80|39)) |
| 184 | adc = 0x80|64; |
| 185 | else if(two_line && adc == (0x80|(64+39))) |
| 186 | adc = 0x80; |
| 187 | else if((!two_line) && adc == (0x80|79)) |
| 188 | adc = 0x80; |
| 189 | else |
| 190 | adc++; |
| 191 | } else { |
| 192 | if(adc == 8*8-1) |
| 193 | adc = 0x00; |
| 194 | else |
| 195 | adc++; |
| 196 | } |
| 197 | } else { |
| 198 | if(adc & 0x80) { |
| 199 | if(adc == 0x80) |
| 200 | adc = two_line ? 0x80|(64+39) : 0x80|79; |
| 201 | else if(two_line && adc == (0x80|64)) |
| 202 | adc = 0x80|39; |
| 203 | else |
| 204 | adc--; |
| 205 | } else { |
| 206 | if(adc == 0x00) |
| 207 | adc = 8*8-1; |
| 208 | else |
| 209 | adc--; |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | void msm6222b_device::shift_step(bool direction) |
| 215 | { |
| 216 | if(direction) { |
| 217 | if(shift == 79) |
| 218 | shift = 0; |
| 219 | else |
| 220 | shift++; |
| 221 | } else { |
| 222 | if(shift == 0) |
| 223 | shift = 79; |
| 224 | else |
| 225 | shift--; |
| 226 | } |
| 227 | } |
| 228 | |
| 229 | bool msm6222b_device::blink_on() const |
| 230 | { |
| 231 | if(!cursor_blinking) |
| 232 | return false; |
| 233 | UINT64 clocks = machine().time().as_ticks(250000); |
| 234 | if(double_height) |
| 235 | return clocks % 281600 >= 140800; |
| 236 | else |
| 237 | return clocks % 204800 >= 102400; |
| 238 | } |
| 239 | |
| 240 | const UINT8 *msm6222b_device::render() |
| 241 | { |
| 242 | memset(render_buf, 0, 80*16); |
| 243 | if(!display_on) |
| 244 | return render_buf; |
| 245 | |
| 246 | int char_height = double_height ? 11 : 8; |
| 247 | |
| 248 | for(int i=0; i<80; i++) { |
| 249 | UINT8 c = ddram[(i+shift) % 80]; |
| 250 | if(c < 16) |
| 251 | memcpy(render_buf + 16*i, double_height ? cgram + 8*(c & 6) : cgram + 8*(c & 7), char_height); |
| 252 | else if(cgrom) |
| 253 | memcpy(render_buf + 16*i, cgrom + 16*c, char_height); |
| 254 | } |
| 255 | |
| 256 | if(cursor_on) { |
| 257 | int cpos = adc & 0x7f; |
| 258 | if(two_line) { |
| 259 | if((cpos >= 40 && cpos < 64) || cpos >= 64+40) |
| 260 | cpos = -1; |
| 261 | else if(cpos >= 64) |
| 262 | cpos += 40-64; |
| 263 | } else { |
| 264 | if(cpos >= 80) |
| 265 | cpos = -1; |
| 266 | } |
| 267 | if(cpos != -1) { |
| 268 | cpos = (cpos + shift) % 80; |
| 269 | render_buf[cpos*16 + (double_height ? 10 : 7)] |= 0x1f; |
| 270 | if(blink_on()) |
| 271 | for(int i=0; i<char_height; i++) |
| 272 | render_buf[cpos*16 + i] ^= 0x1f; |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | return render_buf; |
| 277 | } |
trunk/src/mess/machine/msm6222b.h
| r20056 | r20057 | |
| 1 | /*************************************************************************** |
| 2 | |
| 3 | MSM6222B |
| 4 | |
| 5 | A somewhat hd44780-compatible LCD controller. |
| 6 | |
| 7 | The -01 variant has a fixed cgrom, the other variants are mask-programmed. |
| 8 | |
| 9 | **************************************************************************** |
| 10 | |
| 11 | Copyright Olivier Galibert |
| 12 | All rights reserved. |
| 13 | |
| 14 | Redistribution and use in source and binary forms, with or without |
| 15 | modification, are permitted provided that the following conditions are |
| 16 | met: |
| 17 | |
| 18 | * Redistributions of source code must retain the above copyright |
| 19 | notice, this list of conditions and the following disclaimer. |
| 20 | * Redistributions in binary form must reproduce the above copyright |
| 21 | notice, this list of conditions and the following disclaimer in |
| 22 | the documentation and/or other materials provided with the |
| 23 | distribution. |
| 24 | * Neither the name 'MAME' nor the names of its contributors may be |
| 25 | used to endorse or promote products derived from this software |
| 26 | without specific prior written permission. |
| 27 | |
| 28 | THIS SOFTWARE IS PROVIDED BY OLIVIER GALIBERT ''AS IS'' AND ANY EXPRESS OR |
| 29 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| 30 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| 31 | DISCLAIMED. IN NO EVENT SHALL OLIVIER GALIBERT BE LIABLE FOR ANY DIRECT, |
| 32 | INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 33 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
| 34 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 35 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
| 36 | STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
| 37 | IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| 38 | POSSIBILITY OF SUCH DAMAGE. |
| 39 | |
| 40 | ***************************************************************************/ |
| 41 | |
| 42 | #ifndef __MSM6222B_H__ |
| 43 | #define __MSM6222B_H__ |
| 44 | |
| 45 | #define MCFG_MSM6222B_ADD( _tag ) \ |
| 46 | MCFG_DEVICE_ADD( _tag, MSM6222B, 0 ) |
| 47 | |
| 48 | #define MCFG_MSM6222B_01_ADD( _tag ) \ |
| 49 | MCFG_DEVICE_ADD( _tag, MSM6222B_01, 0 ) |
| 50 | |
| 51 | class msm6222b_device : public device_t { |
| 52 | public: |
| 53 | msm6222b_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 54 | msm6222b_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock); |
| 55 | |
| 56 | void control_w(UINT8 data); |
| 57 | UINT8 control_r(); |
| 58 | void data_w(UINT8 data); |
| 59 | UINT8 data_r(); |
| 60 | |
| 61 | // 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. |
| 62 | // In one line mode n = 0..79. In two line mode first line is 0..39 and second is 40..79. |
| 63 | const UINT8 *render(); |
| 64 | |
| 65 | protected: |
| 66 | virtual void device_start(); |
| 67 | |
| 68 | private: |
| 69 | UINT8 cgram[8*8]; |
| 70 | UINT8 ddram[80]; |
| 71 | UINT8 render_buf[80*16]; |
| 72 | bool cursor_direction, cursor_blinking, two_line, shift_on_write, double_height, cursor_on, display_on; |
| 73 | UINT8 adc, shift; |
| 74 | const UINT8 *cgrom; |
| 75 | |
| 76 | void cursor_step(bool direction); |
| 77 | void shift_step(bool direction); |
| 78 | bool blink_on() const; |
| 79 | }; |
| 80 | |
| 81 | class msm6222b_01_device : public msm6222b_device { |
| 82 | public: |
| 83 | msm6222b_01_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 84 | |
| 85 | protected: |
| 86 | virtual const rom_entry *device_rom_region() const; |
| 87 | }; |
| 88 | |
| 89 | extern const device_type MSM6222B; |
| 90 | extern const device_type MSM6222B_01; |
| 91 | |
| 92 | #endif |
trunk/src/mess/drivers/rd110.c
| r20056 | r20057 | |
| 1 | /************************************************************************************************* |
| 2 | |
| 3 | Roland D-110 driver |
| 4 | |
| 5 | Driver by Olivier Galibert and Jonathan Gevaryahu |
| 6 | |
| 7 | The Roland D-110 is an expander (synthesizer without the keyboard) |
| 8 | from 1988. Internally it's very similar to a mt32, with a better |
| 9 | LCD screen (16x2) and more control buttons. More importantly, it |
| 10 | has more sound rom, a battery-backed ram and a port for memory |
| 11 | cards allowing to load and save new sounds. |
| 12 | |
| 13 | After the first boot, the ram needs to be reinitialized to factory |
| 14 | default values. Press Write/Copy (I) while resetting then |
| 15 | validate with Enter (K). |
| 16 | */ |
| 17 | |
| 18 | #include "emu.h" |
| 19 | #include "machine/ram.h" |
| 20 | #include "machine/nvram.h" |
| 21 | #include "machine/msm6222b.h" |
| 22 | #include "cpu/mcs96/i8x9x.h" |
| 23 | |
| 24 | static INPUT_PORTS_START( d110 ) |
| 25 | PORT_START("SC0") |
| 26 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Write/Copy") PORT_CODE(KEYCODE_I) |
| 27 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Number +") PORT_CODE(KEYCODE_U) |
| 28 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Bank +") PORT_CODE(KEYCODE_Y) |
| 29 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Group +") PORT_CODE(KEYCODE_T) |
| 30 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part +") PORT_CODE(KEYCODE_R) |
| 31 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Timbre") PORT_CODE(KEYCODE_E) |
| 32 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Patch") PORT_CODE(KEYCODE_W) |
| 33 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Exit") PORT_CODE(KEYCODE_Q) |
| 34 | |
| 35 | PORT_START("SC1") |
| 36 | PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Enter") PORT_CODE(KEYCODE_K) |
| 37 | PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Number -") PORT_CODE(KEYCODE_J) |
| 38 | PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Bank -") PORT_CODE(KEYCODE_H) |
| 39 | PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Group -") PORT_CODE(KEYCODE_G) |
| 40 | PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part -") PORT_CODE(KEYCODE_F) |
| 41 | PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("System") PORT_CODE(KEYCODE_D) |
| 42 | PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Part") PORT_CODE(KEYCODE_S) |
| 43 | PORT_BIT(0x80, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Edit") PORT_CODE(KEYCODE_A) |
| 44 | INPUT_PORTS_END |
| 45 | |
| 46 | class d110_state : public driver_device |
| 47 | { |
| 48 | public: |
| 49 | required_device<i8x9x_device> cpu; |
| 50 | required_device<ram_device> ram; |
| 51 | required_device<nvram_device> rams; |
| 52 | required_device<ram_device> memc; |
| 53 | required_device<nvram_device> memcs; |
| 54 | required_device<msm6222b_device> lcd; |
| 55 | required_device<timer_device> midi_timer; |
| 56 | |
| 57 | d110_state(const machine_config &mconfig, device_type type, const char *tag); |
| 58 | |
| 59 | virtual void machine_start(); |
| 60 | virtual void machine_reset(); |
| 61 | virtual void palette_init(); |
| 62 | |
| 63 | UINT32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 64 | |
| 65 | DECLARE_WRITE8_MEMBER(bank_w); |
| 66 | DECLARE_WRITE8_MEMBER(so_w); |
| 67 | DECLARE_WRITE16_MEMBER(midi_w); |
| 68 | |
| 69 | DECLARE_READ8_MEMBER(lcd_ctrl_r); |
| 70 | DECLARE_WRITE8_MEMBER(lcd_ctrl_w); |
| 71 | DECLARE_WRITE8_MEMBER(lcd_data_w); |
| 72 | DECLARE_READ16_MEMBER(port0_r); |
| 73 | |
| 74 | TIMER_DEVICE_CALLBACK_MEMBER(midi_timer_cb); |
| 75 | TIMER_DEVICE_CALLBACK_MEMBER(samples_timer_cb); |
| 76 | |
| 77 | private: |
| 78 | UINT8 lcd_data_buffer[256]; |
| 79 | int lcd_data_buffer_pos; |
| 80 | UINT8 midi; |
| 81 | int midi_pos; |
| 82 | UINT8 port0; |
| 83 | }; |
| 84 | |
| 85 | d110_state::d110_state(const machine_config &mconfig, device_type type, const char *tag) : |
| 86 | driver_device(mconfig, type, tag), |
| 87 | cpu(*this, "maincpu"), |
| 88 | ram(*this, "ram"), |
| 89 | rams(*this, "rams"), |
| 90 | memc(*this, "memc"), |
| 91 | memcs(*this, "memcs"), |
| 92 | lcd(*this, "lcd"), |
| 93 | midi_timer(*this, "midi_timer") |
| 94 | { |
| 95 | } |
| 96 | |
| 97 | |
| 98 | UINT32 d110_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 99 | { |
| 100 | bitmap.fill(0); |
| 101 | const UINT8 *data = lcd->render(); |
| 102 | for(int l=0; l<2; l++) |
| 103 | for(int c=0; c<20; c++) |
| 104 | for(int y=0; y<8; y++) { |
| 105 | UINT8 v = data[c*16 + l*40*16 + y]; |
| 106 | for(int x=0; x<5; x++) |
| 107 | bitmap.pix16(y+9*l, c*6+x) = v & (0x10 >> x) ? 1 : 0; |
| 108 | } |
| 109 | return 0; |
| 110 | } |
| 111 | |
| 112 | void d110_state::machine_start() |
| 113 | { |
| 114 | rams->set_base(ram->pointer(), 32768); |
| 115 | memcs->set_base(memc->pointer(), 32768); |
| 116 | |
| 117 | membank("bank")->configure_entries(0x00, 4, memregion("maincpu")->base(), 0x4000); |
| 118 | membank("bank")->configure_entries(0x10, 2, ram->pointer(), 0x4000); |
| 119 | membank("bank")->configure_entries(0x20, 8, memregion("presets")->base(), 0x4000); |
| 120 | membank("bank")->configure_entries(0x30, 2, memc->pointer(), 0x4000); |
| 121 | membank("fixed")->set_base(ram->pointer()); |
| 122 | |
| 123 | lcd_data_buffer_pos = 0; |
| 124 | } |
| 125 | |
| 126 | void d110_state::machine_reset() |
| 127 | { |
| 128 | // midi_timer->adjust(attotime::from_hz(1)); |
| 129 | midi_pos = 0; |
| 130 | port0 = 0x80; // battery ok |
| 131 | } |
| 132 | |
| 133 | WRITE8_MEMBER(d110_state::lcd_ctrl_w) |
| 134 | { |
| 135 | lcd->control_w(data); |
| 136 | for(int i=0; i != lcd_data_buffer_pos; i++) |
| 137 | lcd->data_w(lcd_data_buffer[i]); |
| 138 | lcd_data_buffer_pos = 0; |
| 139 | } |
| 140 | |
| 141 | READ8_MEMBER(d110_state::lcd_ctrl_r) |
| 142 | { |
| 143 | // Busy flag in the msm622b is bit 7, while the software expects it in bit 0... |
| 144 | return lcd->control_r() >> 7; |
| 145 | } |
| 146 | |
| 147 | WRITE8_MEMBER(d110_state::lcd_data_w) |
| 148 | { |
| 149 | if(lcd_data_buffer_pos == sizeof(lcd_data_buffer)) { |
| 150 | logerror("Warning: lcd data buffer overflow (%04x)\n", cpu->pc()); |
| 151 | return; |
| 152 | } |
| 153 | lcd_data_buffer[lcd_data_buffer_pos++] = data; |
| 154 | } |
| 155 | |
| 156 | WRITE8_MEMBER(d110_state::bank_w) |
| 157 | { |
| 158 | membank("bank")->set_entry(data); |
| 159 | } |
| 160 | |
| 161 | WRITE16_MEMBER(d110_state::midi_w) |
| 162 | { |
| 163 | logerror("midi_out %02x\n", data); |
| 164 | midi = data; |
| 165 | } |
| 166 | |
| 167 | TIMER_DEVICE_CALLBACK_MEMBER(d110_state::midi_timer_cb) |
| 168 | { |
| 169 | const static UINT8 midi_data[3] = { 0x91, 0x40, 0x7f }; |
| 170 | midi = midi_data[midi_pos++]; |
| 171 | logerror("midi_in %02x\n", midi); |
| 172 | cpu->serial_w(midi); |
| 173 | if(midi_pos < sizeof(midi_data)) |
| 174 | midi_timer->adjust(attotime::from_hz(1250)); |
| 175 | } |
| 176 | |
| 177 | READ16_MEMBER(d110_state::port0_r) |
| 178 | { |
| 179 | return port0; |
| 180 | } |
| 181 | |
| 182 | TIMER_DEVICE_CALLBACK_MEMBER(d110_state::samples_timer_cb) |
| 183 | { |
| 184 | port0 ^= 0x10; |
| 185 | } |
| 186 | |
| 187 | WRITE8_MEMBER(d110_state::so_w) |
| 188 | { |
| 189 | // bit 0 = led |
| 190 | // bit 1-2 = reverb program a13/a14 |
| 191 | // bit 3 = R. SW. to ananlog board |
| 192 | // bit 5 = boss 8Mhz clock, handled internally |
| 193 | // logerror("so: rw=%d bank=%d led=%d\n", (data >> 3) & 1, (data >> 1) & 3, data & 1); |
| 194 | } |
| 195 | |
| 196 | void d110_state::palette_init() |
| 197 | { |
| 198 | palette_set_color(machine(), 0, MAKE_RGB(0, 255, 0)); |
| 199 | palette_set_color(machine(), 1, MAKE_RGB(0, 0, 0)); |
| 200 | } |
| 201 | |
| 202 | static ADDRESS_MAP_START( d110_map, AS_PROGRAM, 8, d110_state ) |
| 203 | AM_RANGE(0x0100, 0x0100) AM_WRITE(bank_w) |
| 204 | AM_RANGE(0x0200, 0x0200) AM_WRITE(so_w) |
| 205 | AM_RANGE(0x021a, 0x021a) AM_READ_PORT("SC0") AM_WRITENOP |
| 206 | AM_RANGE(0x021c, 0x021c) AM_READ_PORT("SC1") |
| 207 | AM_RANGE(0x0300, 0x0300) AM_WRITE(lcd_data_w) |
| 208 | AM_RANGE(0x0380, 0x0380) AM_READWRITE(lcd_ctrl_r, lcd_ctrl_w) |
| 209 | AM_RANGE(0x1000, 0x7fff) AM_ROM AM_REGION("maincpu", 0x1000) |
| 210 | AM_RANGE(0x8000, 0xbfff) AM_RAMBANK("bank") |
| 211 | AM_RANGE(0xc000, 0xffff) AM_RAMBANK("fixed") |
| 212 | ADDRESS_MAP_END |
| 213 | |
| 214 | static ADDRESS_MAP_START( d110_io, AS_IO, 16, d110_state ) |
| 215 | AM_RANGE(i8x9x_device::SERIAL, i8x9x_device::SERIAL) AM_WRITE(midi_w) |
| 216 | AM_RANGE(i8x9x_device::P0, i8x9x_device::P0) AM_READ(port0_r) |
| 217 | ADDRESS_MAP_END |
| 218 | |
| 219 | static MACHINE_CONFIG_START( d110, d110_state ) |
| 220 | MCFG_CPU_ADD( "maincpu", P8098, XTAL_12MHz ) |
| 221 | MCFG_CPU_PROGRAM_MAP( d110_map ) |
| 222 | MCFG_CPU_IO_MAP( d110_io ) |
| 223 | |
| 224 | // Battery-backed main ram |
| 225 | MCFG_RAM_ADD( "ram" ) |
| 226 | MCFG_RAM_DEFAULT_SIZE( "32K" ) |
| 227 | MCFG_NVRAM_ADD_0FILL( "rams" ) |
| 228 | |
| 229 | |
| 230 | // Shall become a proper memcard device someday |
| 231 | MCFG_RAM_ADD( "memc" ) |
| 232 | MCFG_RAM_DEFAULT_SIZE( "32K" ) |
| 233 | MCFG_NVRAM_ADD_0FILL( "memcs" ) |
| 234 | |
| 235 | MCFG_SCREEN_ADD( "screen", LCD ) |
| 236 | MCFG_SCREEN_REFRESH_RATE(50) |
| 237 | MCFG_SCREEN_UPDATE_DRIVER(d110_state, screen_update) |
| 238 | // MCFG_SCREEN_SIZE(20*6-1, 2*9-1) |
| 239 | MCFG_SCREEN_SIZE(16*6-1, (16*6-1)*3/4) |
| 240 | MCFG_SCREEN_VISIBLE_AREA(0, 16*6-2, 0, (16*6-1)*3/4-1) |
| 241 | MCFG_PALETTE_LENGTH(2) |
| 242 | |
| 243 | MCFG_MSM6222B_01_ADD( "lcd" ) |
| 244 | |
| 245 | MCFG_TIMER_DRIVER_ADD( "midi_timer", d110_state, midi_timer_cb ) |
| 246 | |
| 247 | MCFG_TIMER_DRIVER_ADD_PERIODIC( "samples_timer", d110_state, samples_timer_cb, attotime::from_hz(32000*2) ) |
| 248 | MACHINE_CONFIG_END |
| 249 | |
| 250 | ROM_START( d110 ) |
| 251 | ROM_REGION( 0x10000, "maincpu", 0 ) |
| 252 | ROM_DEFAULT_BIOS( "110" ) |
| 253 | |
| 254 | ROM_SYSTEM_BIOS( 0, "106", "Firmware 1.06" ) |
| 255 | ROMX_LOAD( "d-110.v1.06.ic19.bin", 0, 0x8000, CRC(3dd5b6e9) SHA1(73b155fb0a8adc2362e73cb0803dafba9ccfb508), ROM_BIOS(1) ) |
| 256 | |
| 257 | ROM_SYSTEM_BIOS( 1, "110", "Firmware 1.10" ) |
| 258 | ROMX_LOAD( "d-110.v1.10.ic19.bin", 0, 0x8000, CRC(3ae68187) SHA1(28635510f30d6c1fb88e00da03e5b4e045c380cb), ROM_BIOS(2) ) |
| 259 | |
| 260 | ROM_REGION( 0x20000, "presets", 0 ) |
| 261 | ROM_LOAD( "r15179873-lh5310-97.ic12.bin", 0, 0x20000, CRC(580a8f9e) SHA1(05587a0542b01625dcde37de5bb339880e47eb93) ) |
| 262 | |
| 263 | ROM_REGION( 0x100000, "la32", 0 ) |
| 264 | ROM_LOAD( "r15179878.ic7.bin", 0, 0x80000, CRC(e117e6ab) SHA1(6760d14900161b8715c2bfd4ebe997877087c90c) ) |
| 265 | ROM_LOAD( "r15179880.ic8.bin", 0x80000, 0x80000, CRC(b329f945) SHA1(9c59f50518a070461b2ec6cb4e43ee7cc1e905b6) ) |
| 266 | |
| 267 | ROM_REGION( 0x8000, "boss", 0 ) |
| 268 | ROM_LOAD( "r15179879.ic6.bin", 0, 0x8000, CRC(5d34174e) SHA1(17bd2887711c5c5458aba6d3be5972b2096eb450) ) |
| 269 | ROM_END |
| 270 | |
| 271 | CONS( 1988, d110, 0, 0, d110, d110, driver_device, 0, "Roland", "D110", GAME_NOT_WORKING|GAME_NO_SOUND ) |
| 272 | |