trunk/src/mess/machine/vtech2.c
r18042 | r18043 | |
27 | 27 | |
28 | 28 | static const UINT8 laser_fdc_wrprot[2] = {0x80, 0x80}; |
29 | 29 | |
30 | | /* write to banked memory (handle memory mapped i/o and videoram) */ |
31 | | static void mwa_bank(running_machine &machine, int bank, int offs, int data); |
32 | | |
33 | 30 | /* wrappers for bank #1 to #4 */ |
34 | | static WRITE8_HANDLER ( mwa_bank1 ) { mwa_bank(space.machine(), 0,offset,data); } |
35 | | static WRITE8_HANDLER ( mwa_bank2 ) { mwa_bank(space.machine(), 1,offset,data); } |
36 | | static WRITE8_HANDLER ( mwa_bank3 ) { mwa_bank(space.machine(), 2,offset,data); } |
37 | | static WRITE8_HANDLER ( mwa_bank4 ) { mwa_bank(space.machine(), 3,offset,data); } |
| 31 | WRITE8_MEMBER(vtech2_state::mwa_bank1 ) { mwa_bank(0,offset,data); } |
| 32 | WRITE8_MEMBER(vtech2_state::mwa_bank2 ) { mwa_bank(1,offset,data); } |
| 33 | WRITE8_MEMBER(vtech2_state::mwa_bank3 ) { mwa_bank(2,offset,data); } |
| 34 | WRITE8_MEMBER(vtech2_state::mwa_bank4 ) { mwa_bank(3,offset,data); } |
38 | 35 | |
39 | | /* read from banked memory (handle memory mapped i/o) */ |
40 | | static int mra_bank(running_machine &machine, int bank, int offs); |
41 | | |
42 | 36 | /* wrappers for bank #1 to #4 */ |
43 | | static READ8_HANDLER ( mra_bank1 ) { return mra_bank(space.machine(),0,offset); } |
44 | | static READ8_HANDLER ( mra_bank2 ) { return mra_bank(space.machine(),1,offset); } |
45 | | static READ8_HANDLER ( mra_bank3 ) { return mra_bank(space.machine(),2,offset); } |
46 | | static READ8_HANDLER ( mra_bank4 ) { return mra_bank(space.machine(),3,offset); } |
| 37 | READ8_MEMBER(vtech2_state::mra_bank1 ) { return mra_bank(0,offset); } |
| 38 | READ8_MEMBER(vtech2_state::mra_bank2 ) { return mra_bank(1,offset); } |
| 39 | READ8_MEMBER(vtech2_state::mra_bank3 ) { return mra_bank(2,offset); } |
| 40 | READ8_MEMBER(vtech2_state::mra_bank4 ) { return mra_bank(3,offset); } |
47 | 41 | |
48 | | /* read banked memory (handle memory mapped i/o) */ |
49 | | static const struct { read8_space_func func; const char *name; } mra_bank_soft[4] = |
50 | | { |
51 | | { FUNC(mra_bank1) }, /* mapped in 0000-3fff */ |
52 | | { FUNC(mra_bank2) }, /* mapped in 4000-7fff */ |
53 | | { FUNC(mra_bank3) }, /* mapped in 8000-bfff */ |
54 | | { FUNC(mra_bank4) } /* mapped in c000-ffff */ |
55 | | }; |
56 | | |
57 | | /* write banked memory (handle memory mapped i/o and videoram) */ |
58 | | static const struct { write8_space_func func; const char *name; } mwa_bank_soft[4] = |
59 | | { |
60 | | { FUNC(mwa_bank1) }, /* mapped in 0000-3fff */ |
61 | | { FUNC(mwa_bank2) }, /* mapped in 4000-7fff */ |
62 | | { FUNC(mwa_bank3) }, /* mapped in 8000-bfff */ |
63 | | { FUNC(mwa_bank4) } /* mapped in c000-ffff */ |
64 | | }; |
65 | | |
66 | 42 | /* read banked memory (plain ROM/RAM) */ |
67 | 43 | static const char *const mra_bank_hard[4] = |
68 | 44 | { |
r18042 | r18043 | |
155 | 131 | /* memory mapped I/O bank selected? */ |
156 | 132 | if (data == 2) |
157 | 133 | { |
158 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_read_handler(offset * 0x4000, offset * 0x4000 + 0x3fff, mra_bank_soft[offset].func, mra_bank_soft[offset].name); |
159 | | machine().device("maincpu")->memory().space(AS_PROGRAM).install_legacy_write_handler(offset * 0x4000, offset * 0x4000 + 0x3fff, mwa_bank_soft[offset].func, mwa_bank_soft[offset].name); |
| 134 | static read8_delegate mra_bank_soft[] = |
| 135 | { |
| 136 | read8_delegate(FUNC(vtech2_state::mra_bank1), this), |
| 137 | read8_delegate(FUNC(vtech2_state::mra_bank2), this), |
| 138 | read8_delegate(FUNC(vtech2_state::mra_bank3), this), |
| 139 | read8_delegate(FUNC(vtech2_state::mra_bank4), this), |
| 140 | }; |
| 141 | |
| 142 | static write8_delegate mwa_bank_soft[] = |
| 143 | { |
| 144 | write8_delegate(FUNC(vtech2_state::mwa_bank1), this), |
| 145 | write8_delegate(FUNC(vtech2_state::mwa_bank2), this), |
| 146 | write8_delegate(FUNC(vtech2_state::mwa_bank3), this), |
| 147 | write8_delegate(FUNC(vtech2_state::mwa_bank4), this), |
| 148 | }; |
| 149 | |
| 150 | machine().device("maincpu")->memory().space(AS_PROGRAM).install_readwrite_handler(offset * 0x4000, offset * 0x4000 + 0x3fff, mra_bank_soft[offset], mwa_bank_soft[offset]); |
160 | 151 | } |
161 | 152 | else |
162 | 153 | { |
r18042 | r18043 | |
200 | 191 | * 1 column 1 |
201 | 192 | * 0 column 0 |
202 | 193 | ************************************************/ |
203 | | static int mra_bank(running_machine &machine, int bank, int offs) |
| 194 | int vtech2_state::mra_bank(int bank, int offs) |
204 | 195 | { |
205 | | vtech2_state *state = machine.driver_data<vtech2_state>(); |
206 | 196 | int level, data = 0xff; |
207 | 197 | |
208 | 198 | /* Laser 500/700 only: keyboard rows A through D */ |
r18042 | r18043 | |
210 | 200 | { |
211 | 201 | if( (offs & 0x0300) == 0x0000 ) /* keyboard row A */ |
212 | 202 | { |
213 | | if( machine.root_device().ioport("ROWA")->read() != state->m_row_a ) |
| 203 | if( machine().root_device().ioport("ROWA")->read() != m_row_a ) |
214 | 204 | { |
215 | | state->m_row_a = machine.root_device().ioport("ROWA")->read(); |
216 | | data &= state->m_row_a; |
| 205 | m_row_a = machine().root_device().ioport("ROWA")->read(); |
| 206 | data &= m_row_a; |
217 | 207 | } |
218 | 208 | } |
219 | 209 | if( (offs & 0x0300) == 0x0100 ) /* keyboard row B */ |
220 | 210 | { |
221 | | if( machine.root_device().ioport("ROWB")->read() != state->m_row_b ) |
| 211 | if( machine().root_device().ioport("ROWB")->read() != m_row_b ) |
222 | 212 | { |
223 | | state->m_row_b = machine.root_device().ioport("ROWB")->read(); |
224 | | data &= state->m_row_b; |
| 213 | m_row_b = machine().root_device().ioport("ROWB")->read(); |
| 214 | data &= m_row_b; |
225 | 215 | } |
226 | 216 | } |
227 | 217 | if( (offs & 0x0300) == 0x0200 ) /* keyboard row C */ |
228 | 218 | { |
229 | | if( machine.root_device().ioport("ROWC")->read() != state->m_row_c ) |
| 219 | if( machine().root_device().ioport("ROWC")->read() != m_row_c ) |
230 | 220 | { |
231 | | state->m_row_c = machine.root_device().ioport("ROWC")->read(); |
232 | | data &= state->m_row_c; |
| 221 | m_row_c = machine().root_device().ioport("ROWC")->read(); |
| 222 | data &= m_row_c; |
233 | 223 | } |
234 | 224 | } |
235 | 225 | if( (offs & 0x0300) == 0x0300 ) /* keyboard row D */ |
236 | 226 | { |
237 | | if( machine.root_device().ioport("ROWD")->read() != state->m_row_d ) |
| 227 | if( machine().root_device().ioport("ROWD")->read() != m_row_d ) |
238 | 228 | { |
239 | | state->m_row_d = machine.root_device().ioport("ROWD")->read(); |
240 | | data &= state->m_row_d; |
| 229 | m_row_d = machine().root_device().ioport("ROWD")->read(); |
| 230 | data &= m_row_d; |
241 | 231 | } |
242 | 232 | } |
243 | 233 | } |
r18042 | r18043 | |
245 | 235 | { |
246 | 236 | /* All Lasers keyboard rows 0 through 7 */ |
247 | 237 | if( !(offs & 0x01) ) |
248 | | data &= machine.root_device().ioport("ROW0")->read(); |
| 238 | data &= machine().root_device().ioport("ROW0")->read(); |
249 | 239 | if( !(offs & 0x02) ) |
250 | | data &= machine.root_device().ioport("ROW1")->read(); |
| 240 | data &= machine().root_device().ioport("ROW1")->read(); |
251 | 241 | if( !(offs & 0x04) ) |
252 | | data &= machine.root_device().ioport("ROW2")->read(); |
| 242 | data &= machine().root_device().ioport("ROW2")->read(); |
253 | 243 | if( !(offs & 0x08) ) |
254 | | data &= machine.root_device().ioport("ROW3")->read(); |
| 244 | data &= machine().root_device().ioport("ROW3")->read(); |
255 | 245 | if( !(offs & 0x10) ) |
256 | | data &= machine.root_device().ioport("ROW4")->read(); |
| 246 | data &= machine().root_device().ioport("ROW4")->read(); |
257 | 247 | if( !(offs & 0x20) ) |
258 | | data &= machine.root_device().ioport("ROW5")->read(); |
| 248 | data &= machine().root_device().ioport("ROW5")->read(); |
259 | 249 | if( !(offs & 0x40) ) |
260 | | data &= machine.root_device().ioport("ROW6")->read(); |
| 250 | data &= machine().root_device().ioport("ROW6")->read(); |
261 | 251 | if( !(offs & 0x80) ) |
262 | | data &= machine.root_device().ioport("ROW7")->read(); |
| 252 | data &= machine().root_device().ioport("ROW7")->read(); |
263 | 253 | } |
264 | 254 | |
265 | 255 | /* what's bit 7 good for? tape input maybe? */ |
266 | | level = (vtech2_cassette_image(machine))->input() * 65536.0; |
267 | | if( level < state->m_level_old - 511 ) |
268 | | state->m_cassette_bit = 0x00; |
269 | | if( level > state->m_level_old + 511 ) |
270 | | state->m_cassette_bit = 0x80; |
271 | | state->m_level_old = level; |
| 256 | level = (vtech2_cassette_image(machine()))->input() * 65536.0; |
| 257 | if( level < m_level_old - 511 ) |
| 258 | m_cassette_bit = 0x00; |
| 259 | if( level > m_level_old + 511 ) |
| 260 | m_cassette_bit = 0x80; |
| 261 | m_level_old = level; |
272 | 262 | |
273 | | data &= ~state->m_cassette_bit; |
| 263 | data &= ~m_cassette_bit; |
274 | 264 | // logerror("bank #%d keyboard_r [$%04X] $%02X\n", bank, offs, data); |
275 | 265 | |
276 | 266 | return data; |
r18042 | r18043 | |
287 | 277 | * 1 cassette out (LSB) |
288 | 278 | * 0 speaker A |
289 | 279 | ************************************************/ |
290 | | static void mwa_bank(running_machine &machine, int bank, int offs, int data) |
| 280 | void vtech2_state::mwa_bank(int bank, int offs, int data) |
291 | 281 | { |
292 | | vtech2_state *state = machine.driver_data<vtech2_state>(); |
293 | | device_t *speaker = machine.device(SPEAKER_TAG); |
294 | | offs += 0x4000 * state->m_laser_bank[bank]; |
295 | | switch (state->m_laser_bank[bank]) |
| 282 | device_t *speaker = machine().device(SPEAKER_TAG); |
| 283 | offs += 0x4000 * m_laser_bank[bank]; |
| 284 | switch (m_laser_bank[bank]) |
296 | 285 | { |
297 | 286 | case 0: /* ROM lower 16K */ |
298 | 287 | case 1: /* ROM upper 16K */ |
299 | 288 | logerror("bank #%d write to ROM [$%05X] $%02X\n", bank+1, offs, data); |
300 | 289 | break; |
301 | 290 | case 2: /* memory mapped output */ |
302 | | if (data != state->m_laser_latch) |
| 291 | if (data != m_laser_latch) |
303 | 292 | { |
304 | 293 | logerror("bank #%d write to I/O [$%05X] $%02X\n", bank+1, offs, data); |
305 | 294 | /* Toggle between graphics and text modes? */ |
306 | | if ((data ^ state->m_laser_latch) & 0x01) |
| 295 | if ((data ^ m_laser_latch) & 0x01) |
307 | 296 | speaker_level_w(speaker, data & 1); |
308 | | state->m_laser_latch = data; |
| 297 | m_laser_latch = data; |
309 | 298 | } |
310 | 299 | break; |
311 | 300 | case 12: /* ext. ROM #1 */ |
r18042 | r18043 | |
315 | 304 | logerror("bank #%d write to ROM [$%05X] $%02X\n", bank+1, offs, data); |
316 | 305 | break; |
317 | 306 | default: /* RAM */ |
318 | | if( state->m_laser_bank[bank] == state->m_laser_video_bank && state->m_mem[offs] != data ) |
| 307 | if( m_laser_bank[bank] == m_laser_video_bank && m_mem[offs] != data ) |
319 | 308 | { |
320 | 309 | logerror("bank #%d write to videoram [$%05X] $%02X\n", bank+1, offs, data); |
321 | 310 | } |
322 | | state->m_mem[offs] = data; |
| 311 | m_mem[offs] = data; |
323 | 312 | break; |
324 | 313 | } |
325 | 314 | } |