src/mess/machine/comx35.c
| r9387 | r9388 | |
| 115 | 115 | */ |
| 116 | 116 | |
| 117 | 117 | #include "emu.h" |
| 118 | | #include "cpu/cdp1802/cdp1802.h" |
| 118 | #include "cpu/cosmac/cosmac.h" |
| 119 | 119 | #include "machine/wd17xx.h" |
| 120 | 120 | #include "devices/printer.h" |
| 121 | 121 | #include "devices/snapquik.h" |
| r9387 | r9388 | |
| 134 | 134 | PRINTER_PLOTTER |
| 135 | 135 | }; |
| 136 | 136 | |
| 137 | | static UINT8 read_expansion(running_machine *machine) |
| 137 | UINT8 comx35_state::read_expansion() |
| 138 | 138 | { |
| 139 | 139 | UINT8 result; |
| 140 | | switch(machine->phase()) |
| 140 | switch(m_machine.phase()) |
| 141 | 141 | { |
| 142 | 142 | case MACHINE_PHASE_RESET: |
| 143 | 143 | case MACHINE_PHASE_RUNNING: |
| 144 | | result = input_port_read(machine, "EXPANSION"); |
| 144 | result = input_port_read(&m_machine, "EXPANSION"); |
| 145 | 145 | break; |
| 146 | 146 | |
| 147 | 147 | default: |
| r9387 | r9388 | |
| 151 | 151 | return result; |
| 152 | 152 | } |
| 153 | 153 | |
| 154 | | static running_device *get_printer_device(running_machine *machine) |
| 154 | bool comx35_state::is_expansion_box_installed() |
| 155 | 155 | { |
| 156 | | return machine->device("printer"); |
| 156 | return (memory_region(&m_machine, CDP1802_TAG)[0xe800] != 0x00); |
| 157 | 157 | } |
| 158 | 158 | |
| 159 | | static int expansion_box_installed(running_machine *machine) |
| 159 | bool comx35_state::is_dos_card_active() |
| 160 | 160 | { |
| 161 | | return (memory_region(machine, CDP1802_TAG)[0xe800] != 0x00); |
| 162 | | } |
| 163 | | |
| 164 | | static int dos_card_active(running_machine *machine) |
| 165 | | { |
| 166 | | comx35_state *state = machine->driver_data<comx35_state>(); |
| 167 | | |
| 168 | | if (expansion_box_installed(machine)) |
| 161 | if (is_expansion_box_installed()) |
| 169 | 162 | { |
| 170 | | return (state->bank == BANK_FLOPPY); |
| 163 | return (m_bank == BANK_FLOPPY); |
| 171 | 164 | } |
| 172 | 165 | else |
| 173 | 166 | { |
| 174 | | return read_expansion(machine) == BANK_FLOPPY; |
| 167 | return read_expansion() == BANK_FLOPPY; |
| 175 | 168 | } |
| 176 | 169 | } |
| 177 | 170 | |
| r9387 | r9388 | |
| 179 | 172 | static WRITE_LINE_DEVICE_HANDLER( comx35_fdc_intrq_w ) |
| 180 | 173 | { |
| 181 | 174 | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 182 | | driver_state->fdc_irq = state; |
| 175 | driver_state->m_fdc_irq = state; |
| 183 | 176 | } |
| 184 | 177 | |
| 185 | 178 | static WRITE_LINE_DEVICE_HANDLER( comx35_fdc_drq_w ) |
| 186 | 179 | { |
| 187 | 180 | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 188 | 181 | |
| 189 | | if (driver_state->fdc_drq_enable) |
| 190 | | driver_state->cdp1802_ef4 = state; |
| 182 | if (driver_state->m_fdc_drq_enable) |
| 183 | driver_state->m_cdp1802_ef4 = state; |
| 191 | 184 | } |
| 192 | 185 | |
| 193 | 186 | const wd17xx_interface comx35_wd17xx_interface = |
| r9387 | r9388 | |
| 195 | 188 | DEVCB_NULL, |
| 196 | 189 | DEVCB_LINE(comx35_fdc_intrq_w), |
| 197 | 190 | DEVCB_LINE(comx35_fdc_drq_w), |
| 198 | | {FLOPPY_0, FLOPPY_1, FLOPPY_2, FLOPPY_3} |
| 191 | { FLOPPY_0, FLOPPY_1, NULL, NULL } |
| 199 | 192 | }; |
| 200 | 193 | |
| 201 | | static UINT8 fdc_r(address_space *space) |
| 194 | UINT8 comx35_state::fdc_r() |
| 202 | 195 | { |
| 203 | | comx35_state *state = space->machine->driver_data<comx35_state>(); |
| 204 | | running_device *fdc = space->machine->device(WD1770_TAG); |
| 205 | | |
| 206 | 196 | UINT8 data; |
| 207 | 197 | |
| 208 | | if (state->cdp1802_q) |
| 198 | if (m_cdp1802_q) |
| 209 | 199 | { |
| 210 | | data = state->fdc_irq; |
| 200 | data = m_fdc_irq; |
| 211 | 201 | } |
| 212 | 202 | else |
| 213 | 203 | { |
| 214 | | data = wd17xx_r(fdc, state->fdc_addr); |
| 204 | data = wd17xx_r(m_fdc, m_fdc_addr); |
| 215 | 205 | } |
| 216 | 206 | |
| 217 | 207 | return data; |
| 218 | 208 | } |
| 219 | 209 | |
| 220 | | static void fdc_w(address_space *space, UINT8 data) |
| 210 | void comx35_state::fdc_w(UINT8 data) |
| 221 | 211 | { |
| 222 | | running_device *fdc = space->machine->device(WD1770_TAG); |
| 223 | 212 | /* |
| 224 | 213 | |
| 225 | 214 | bit description |
| r9387 | r9388 | |
| 233 | 222 | |
| 234 | 223 | */ |
| 235 | 224 | |
| 236 | | comx35_state *state = space->machine->driver_data<comx35_state>(); |
| 237 | | |
| 238 | | if (state->cdp1802_q) |
| 225 | if (m_cdp1802_q) |
| 239 | 226 | { |
| 240 | 227 | // latch data to F3 |
| 228 | m_fdc_addr = data & 0x03; |
| 241 | 229 | |
| 242 | | state->fdc_addr = data & 0x03; |
| 243 | | |
| 244 | 230 | if (BIT(data, 2)) |
| 245 | 231 | { |
| 246 | | wd17xx_set_drive(fdc,0); |
| 232 | wd17xx_set_drive(m_fdc, 0); |
| 247 | 233 | } |
| 248 | 234 | else if (BIT(data, 3)) |
| 249 | 235 | { |
| 250 | | wd17xx_set_drive(fdc,1); |
| 236 | wd17xx_set_drive(m_fdc, 1); |
| 251 | 237 | } |
| 252 | 238 | |
| 253 | | state->fdc_drq_enable = BIT(data, 4); |
| 239 | m_fdc_drq_enable = BIT(data, 4); |
| 254 | 240 | |
| 255 | | if (!state->fdc_drq_enable) |
| 241 | if (!m_fdc_drq_enable) |
| 256 | 242 | { |
| 257 | | state->cdp1802_ef4 = 1; |
| 243 | m_cdp1802_ef4 = 1; |
| 258 | 244 | } |
| 259 | 245 | |
| 260 | | wd17xx_set_side(fdc,BIT(data, 5)); |
| 246 | wd17xx_set_side(m_fdc, BIT(data, 5)); |
| 261 | 247 | } |
| 262 | 248 | else |
| 263 | 249 | { |
| 264 | 250 | // write data to WD1770 |
| 265 | | |
| 266 | | wd17xx_w(fdc, state->fdc_addr, data); |
| 251 | wd17xx_w(m_fdc, m_fdc_addr, data); |
| 267 | 252 | } |
| 268 | 253 | } |
| 269 | 254 | |
| 270 | 255 | /* Printer */ |
| 271 | 256 | |
| 272 | | static UINT8 printer_r(running_machine *machine) |
| 257 | UINT8 comx35_state::printer_r() |
| 273 | 258 | { |
| 274 | | // comx35_state *state = machine->driver_data<comx35_state>(); |
| 275 | | |
| 276 | 259 | int printer = input_port_read(machine, "PRINTER") & 0x07; |
| 277 | 260 | UINT8 data = 0; |
| 278 | 261 | |
| r9387 | r9388 | |
| 310 | 293 | return data; |
| 311 | 294 | } |
| 312 | 295 | |
| 313 | | static void printer_w(running_machine *machine, UINT8 data) |
| 296 | void comx35_state::printer_w(UINT8 data) |
| 314 | 297 | { |
| 315 | | // comx35_state *state = machine->driver_data<comx35_state>(); |
| 316 | 298 | int printer = input_port_read(machine, "PRINTER") & 0x07; |
| 317 | 299 | |
| 318 | 300 | switch (printer) |
| r9387 | r9388 | |
| 323 | 305 | OUT 2 is used to send a byte to the printer |
| 324 | 306 | */ |
| 325 | 307 | |
| 326 | | printer_output(get_printer_device(machine), data); |
| 308 | //printer_output(m_printer, data); |
| 327 | 309 | break; |
| 328 | 310 | |
| 329 | 311 | case PRINTER_SERIAL: |
| r9387 | r9388 | |
| 346 | 328 | |
| 347 | 329 | /* Read/Write Handlers */ |
| 348 | 330 | |
| 349 | | static void get_active_bank(running_machine *machine, UINT8 data) |
| 331 | void comx35_state::get_active_bank(UINT8 data) |
| 350 | 332 | { |
| 351 | | comx35_state *state = machine->driver_data<comx35_state>(); |
| 352 | 333 | static const char *const slotnames[] = { "", "SLOT1", "SLOT2", "SLOT3", "SLOT4" }; |
| 353 | 334 | |
| 354 | | if (expansion_box_installed(machine)) |
| 335 | if (is_expansion_box_installed()) |
| 355 | 336 | { |
| 356 | 337 | // expansion box |
| 357 | | |
| 358 | 338 | int i; |
| 359 | 339 | |
| 360 | 340 | for (i = 1; i < 5; i++) |
| 361 | 341 | { |
| 362 | 342 | if (BIT(data, i)) |
| 363 | 343 | { |
| 364 | | state->slot = i; |
| 344 | m_slot = i; |
| 365 | 345 | break; |
| 366 | 346 | } |
| 367 | 347 | } |
| 368 | 348 | |
| 369 | | if (state->slot > 0) |
| 370 | | state->bank = input_port_read(machine, slotnames[state->slot]); |
| 349 | if (m_slot > 0) |
| 350 | m_bank = input_port_read(&m_machine, slotnames[m_slot]); |
| 371 | 351 | } |
| 372 | 352 | else |
| 373 | 353 | { |
| 374 | 354 | // no expansion box |
| 375 | | |
| 376 | | state->bank = read_expansion(machine); |
| 355 | m_bank = read_expansion(); |
| 377 | 356 | } |
| 378 | 357 | |
| 379 | 358 | // RAM expansion bank |
| 380 | | state->rambank = (data >> 5) & 0x03; |
| 359 | m_rambank = (data >> 5) & 0x03; |
| 381 | 360 | } |
| 382 | 361 | |
| 383 | | static void set_active_bank(running_machine *machine) |
| 362 | void comx35_state::set_active_bank() |
| 384 | 363 | { |
| 385 | | comx35_state *state = machine->driver_data<comx35_state>(); |
| 386 | | address_space *program = cputag_get_address_space(machine, CDP1802_TAG, ADDRESS_SPACE_PROGRAM); |
| 387 | | int bank = state->bank; |
| 364 | address_space *program = cpu_get_address_space(m_maincpu, ADDRESS_SPACE_PROGRAM); |
| 365 | int bank = m_bank; |
| 388 | 366 | |
| 389 | | switch (state->bank) |
| 367 | switch (m_bank) |
| 390 | 368 | { |
| 391 | 369 | case BANK_NONE: |
| 392 | 370 | memory_unmap_readwrite(program, 0xc000, 0xdfff, 0, 0); |
| r9387 | r9388 | |
| 427 | 405 | |
| 428 | 406 | case BANK_80_COLUMNS: |
| 429 | 407 | { |
| 430 | | running_device *mc6845 = machine->device(MC6845_TAG); |
| 431 | | |
| 432 | 408 | memory_install_read_bank(program, 0xc000, 0xc7ff, 0, 0, "bank1"); // ROM |
| 433 | 409 | memory_unmap_write(program, 0xc000, 0xc7ff, 0, 0); // ROM |
| 434 | 410 | memory_unmap_readwrite(program, 0xc800, 0xcfff, 0, 0); |
| 435 | | memory_install_readwrite8_handler(program, 0xd000, 0xd7ff, 0, 0, comx35_videoram_r, comx35_videoram_w); |
| 411 | memory_install_ram(program, 0xd000, 0xd7ff, 0, 0, m_videoram); |
| 436 | 412 | memory_unmap_read(program, 0xd800, 0xd800, 0, 0); |
| 437 | | memory_install_write8_device_handler(program, mc6845, 0xd800, 0xd800, 0, 0, mc6845_address_w); |
| 438 | | memory_install_readwrite8_device_handler(program, mc6845, 0xd801, 0xd801, 0, 0, mc6845_register_r, mc6845_register_w); |
| 413 | memory_install_write8_device_handler(program, m_crtc, 0xd800, 0xd800, 0, 0, mc6845_address_w); |
| 414 | memory_install_readwrite8_device_handler(program, m_crtc, 0xd801, 0xd801, 0, 0, mc6845_register_r, mc6845_register_w); |
| 439 | 415 | memory_unmap_readwrite(program, 0xd802, 0xdfff, 0, 0); |
| 440 | 416 | } |
| 441 | 417 | break; |
| 442 | 418 | |
| 443 | 419 | case BANK_RAMCARD: |
| 444 | 420 | { |
| 445 | | bank = BANK_RAMCARD + state->rambank; |
| 421 | bank = BANK_RAMCARD + m_rambank; |
| 446 | 422 | |
| 447 | 423 | memory_install_readwrite_bank(program, 0xc000, 0xdfff, 0, 0, "bank1"); |
| 448 | 424 | } |
| r9387 | r9388 | |
| 452 | 428 | memory_set_bank(machine, "bank1", bank); |
| 453 | 429 | } |
| 454 | 430 | |
| 455 | | WRITE8_HANDLER( comx35_bank_select_w ) |
| 431 | WRITE8_MEMBER( comx35_state::bank_select_w ) |
| 456 | 432 | { |
| 457 | | get_active_bank(space->machine, data); |
| 458 | | set_active_bank(space->machine); |
| 433 | get_active_bank(data); |
| 434 | set_active_bank(); |
| 459 | 435 | } |
| 460 | 436 | |
| 461 | | READ8_HANDLER( comx35_io_r ) |
| 437 | READ8_MEMBER( comx35_state::io_r ) |
| 462 | 438 | { |
| 463 | | comx35_state *state = space->machine->driver_data<comx35_state>(); |
| 464 | | |
| 465 | 439 | UINT8 data = 0xff; |
| 466 | 440 | |
| 467 | | switch (state->bank) |
| 441 | switch (m_bank) |
| 468 | 442 | { |
| 469 | 443 | case BANK_NONE: |
| 470 | 444 | break; |
| 471 | 445 | |
| 472 | 446 | case BANK_FLOPPY: |
| 473 | | data = fdc_r(space); |
| 447 | data = fdc_r(); |
| 474 | 448 | break; |
| 475 | 449 | |
| 476 | 450 | case BANK_PRINTER_PARALLEL: |
| 477 | 451 | case BANK_PRINTER_PARALLEL_FM: |
| 478 | 452 | case BANK_PRINTER_SERIAL: |
| 479 | 453 | case BANK_PRINTER_THERMAL: |
| 480 | | data = printer_r(space->machine); |
| 454 | data = printer_r(); |
| 481 | 455 | break; |
| 482 | 456 | |
| 483 | 457 | case BANK_JOYCARD: |
| 484 | | data = input_port_read(space->machine, "JOY1"); |
| 458 | data = input_port_read(&m_machine, "JOY1"); |
| 485 | 459 | break; |
| 486 | 460 | |
| 487 | 461 | case BANK_80_COLUMNS: |
| r9387 | r9388 | |
| 494 | 468 | return data; |
| 495 | 469 | } |
| 496 | 470 | |
| 497 | | READ8_HANDLER( comx35_io2_r ) |
| 471 | READ8_MEMBER( comx35_state::io2_r ) |
| 498 | 472 | { |
| 499 | | comx35_state *state = space->machine->driver_data<comx35_state>(); |
| 500 | | |
| 501 | 473 | UINT8 data = 0xff; |
| 502 | 474 | |
| 503 | | switch (state->bank) |
| 475 | switch (m_bank) |
| 504 | 476 | { |
| 505 | 477 | case BANK_NONE: |
| 506 | 478 | break; |
| r9387 | r9388 | |
| 515 | 487 | break; |
| 516 | 488 | |
| 517 | 489 | case BANK_JOYCARD: |
| 518 | | data = input_port_read(space->machine, "JOY2"); |
| 490 | data = input_port_read(&m_machine, "JOY2"); |
| 519 | 491 | break; |
| 520 | 492 | |
| 521 | 493 | case BANK_80_COLUMNS: |
| r9387 | r9388 | |
| 528 | 500 | return data; |
| 529 | 501 | } |
| 530 | 502 | |
| 531 | | WRITE8_HANDLER( comx35_io_w ) |
| 503 | WRITE8_MEMBER( comx35_state::io_w ) |
| 532 | 504 | { |
| 533 | | comx35_state *state = space->machine->driver_data<comx35_state>(); |
| 534 | | |
| 535 | | switch (state->bank) |
| 505 | switch (m_bank) |
| 536 | 506 | { |
| 537 | 507 | case BANK_NONE: |
| 538 | 508 | break; |
| 539 | 509 | |
| 540 | 510 | case BANK_FLOPPY: |
| 541 | | fdc_w(space, data); |
| 511 | fdc_w(data); |
| 542 | 512 | break; |
| 543 | 513 | |
| 544 | 514 | case BANK_PRINTER_PARALLEL: |
| 545 | 515 | case BANK_PRINTER_PARALLEL_FM: |
| 546 | 516 | case BANK_PRINTER_SERIAL: |
| 547 | 517 | case BANK_PRINTER_THERMAL: |
| 548 | | printer_w(space->machine, data); |
| 518 | printer_w(data); |
| 549 | 519 | break; |
| 550 | 520 | |
| 551 | 521 | case BANK_JOYCARD: |
| r9387 | r9388 | |
| 565 | 535 | { |
| 566 | 536 | comx35_state *state = machine->driver_data<comx35_state>(); |
| 567 | 537 | |
| 568 | | state->cdp1802_mode = CDP1802_MODE_RUN; |
| 538 | state->m_reset = 1; |
| 569 | 539 | } |
| 570 | 540 | |
| 571 | 541 | DIRECT_UPDATE_HANDLER( comx35_opbase_handler ) |
| 572 | 542 | { |
| 543 | comx35_state *state = machine->driver_data<comx35_state>(); |
| 544 | |
| 573 | 545 | if (address >= 0x0dd0 && address <= 0x0ddf) |
| 574 | 546 | { |
| 575 | | if (dos_card_active(machine)) |
| 547 | if (state->is_dos_card_active()) |
| 576 | 548 | { |
| 577 | 549 | // read opcode from DOS ROM |
| 578 | 550 | direct.explicit_configure(0x0dd0, 0x0ddf, 0x000f, memory_region(machine, "fdc")); |
| r9387 | r9388 | |
| 585 | 557 | |
| 586 | 558 | static STATE_POSTLOAD( comx35_state_save_postload ) |
| 587 | 559 | { |
| 588 | | set_active_bank(machine); |
| 560 | comx35_state *state = machine->driver_data<comx35_state>(); |
| 561 | |
| 562 | state->set_active_bank(); |
| 589 | 563 | } |
| 590 | 564 | |
| 591 | | MACHINE_START( comx35p ) |
| 565 | void comx35_state::machine_start() |
| 592 | 566 | { |
| 593 | | comx35_state *state = machine->driver_data<comx35_state>(); |
| 594 | | address_space *program = cputag_get_address_space(machine, CDP1802_TAG, ADDRESS_SPACE_PROGRAM); |
| 567 | address_space *program = cpu_get_address_space(m_maincpu, ADDRESS_SPACE_PROGRAM); |
| 595 | 568 | |
| 596 | 569 | /* opbase handling for DOS Card */ |
| 597 | | |
| 598 | 570 | program->set_direct_update_handler(direct_update_delegate_create_static(comx35_opbase_handler, *machine)); |
| 599 | 571 | |
| 600 | 572 | /* BASIC ROM banking */ |
| 601 | | |
| 602 | 573 | memory_install_read_bank(program, 0x1000, 0x17ff, 0, 0, "bank2"); |
| 603 | 574 | memory_unmap_write(program, 0x1000, 0x17ff, 0, 0); |
| 604 | | memory_configure_bank(machine, "bank2", 0, 1, memory_region(machine, CDP1802_TAG) + 0x1000, 0); // normal ROM |
| 605 | | memory_configure_bank(machine, "bank2", 1, 1, memory_region(machine, CDP1802_TAG) + 0xe000, 0); // expansion box ROM |
| 575 | memory_configure_bank(machine, "bank2", 0, 1, memory_region(&m_machine, CDP1802_TAG) + 0x1000, 0); // normal ROM |
| 576 | memory_configure_bank(machine, "bank2", 1, 1, memory_region(&m_machine, CDP1802_TAG) + 0xe000, 0); // expansion box ROM |
| 606 | 577 | |
| 607 | | memory_configure_bank(machine, "bank3", 0, 1, memory_region(machine, CDP1802_TAG) + 0xe000, 0); |
| 578 | memory_configure_bank(machine, "bank3", 0, 1, memory_region(&m_machine, CDP1802_TAG) + 0xe000, 0); |
| 608 | 579 | memory_set_bank(machine, "bank3", 0); |
| 609 | 580 | |
| 610 | | if (expansion_box_installed(machine)) |
| 581 | if (is_expansion_box_installed()) |
| 611 | 582 | { |
| 612 | 583 | memory_install_read_bank(program, 0xe000, 0xefff, 0, 0, "bank3"); |
| 613 | 584 | memory_unmap_write(program, 0xe000, 0xefff, 0, 0); |
| r9387 | r9388 | |
| 620 | 591 | } |
| 621 | 592 | |
| 622 | 593 | /* card slot banking */ |
| 594 | memory_configure_bank(machine, "bank1", 0, 1, memory_region(&m_machine, CDP1802_TAG) + 0xc000, 0); |
| 595 | memory_configure_bank(machine, "bank1", BANK_FLOPPY, 1, memory_region(&m_machine, "fdc"), 0); |
| 596 | memory_configure_bank(machine, "bank1", BANK_PRINTER_PARALLEL, 1, memory_region(&m_machine, "printer"), 0); |
| 597 | memory_configure_bank(machine, "bank1", BANK_PRINTER_PARALLEL_FM, 1, memory_region(&m_machine, "printer_fm"), 0); |
| 598 | memory_configure_bank(machine, "bank1", BANK_PRINTER_SERIAL, 1, memory_region(&m_machine, "rs232"), 0); |
| 599 | memory_configure_bank(machine, "bank1", BANK_PRINTER_THERMAL, 1, memory_region(&m_machine, "thermal"), 0); |
| 600 | memory_configure_bank(machine, "bank1", BANK_JOYCARD, 1, memory_region(&m_machine, CDP1802_TAG), 0); |
| 601 | memory_configure_bank(machine, "bank1", BANK_80_COLUMNS, 1, memory_region(&m_machine, "80column"), 0); |
| 602 | memory_configure_bank(machine, "bank1", BANK_RAMCARD, 4, messram_get_ptr(m_ram), 0x2000); |
| 623 | 603 | |
| 624 | | memory_configure_bank(machine, "bank1", 0, 1, memory_region(machine, CDP1802_TAG) + 0xc000, 0); |
| 625 | | memory_configure_bank(machine, "bank1", BANK_FLOPPY, 1, memory_region(machine, "fdc"), 0); |
| 626 | | memory_configure_bank(machine, "bank1", BANK_PRINTER_PARALLEL, 1, memory_region(machine, "printer"), 0); |
| 627 | | memory_configure_bank(machine, "bank1", BANK_PRINTER_PARALLEL_FM, 1, memory_region(machine, "printer_fm"), 0); |
| 628 | | memory_configure_bank(machine, "bank1", BANK_PRINTER_SERIAL, 1, memory_region(machine, "rs232"), 0); |
| 629 | | memory_configure_bank(machine, "bank1", BANK_PRINTER_THERMAL, 1, memory_region(machine, "thermal"), 0); |
| 630 | | memory_configure_bank(machine, "bank1", BANK_JOYCARD, 1, memory_region(machine, CDP1802_TAG), 0); |
| 631 | | memory_configure_bank(machine, "bank1", BANK_80_COLUMNS, 1, memory_region(machine, "80column"), 0); |
| 632 | | memory_configure_bank(machine, "bank1", BANK_RAMCARD, 4, messram_get_ptr(machine->device("messram")), 0x2000); |
| 633 | | |
| 634 | 604 | memory_set_bank(machine, "bank1", 0); |
| 635 | 605 | |
| 636 | | if (!expansion_box_installed(machine)) |
| 606 | if (!is_expansion_box_installed()) |
| 637 | 607 | { |
| 638 | | state->bank = read_expansion(machine); |
| 608 | m_bank = read_expansion(); |
| 639 | 609 | } |
| 640 | 610 | |
| 641 | 611 | /* allocate reset timer */ |
| 612 | m_reset_timer = timer_alloc(machine, reset_tick, NULL); |
| 642 | 613 | |
| 643 | | state->reset_timer = timer_alloc(machine, reset_tick, NULL); |
| 644 | | |
| 645 | | /* screen format */ |
| 646 | | |
| 647 | | state->pal_ntsc = 1; |
| 648 | | |
| 649 | 614 | /* register for state saving */ |
| 650 | | |
| 651 | 615 | state_save_register_postload(machine, comx35_state_save_postload, NULL); |
| 652 | | |
| 653 | | state_save_register_global(machine, state->cdp1802_mode); |
| 654 | | state_save_register_global(machine, state->cdp1802_q); |
| 655 | | state_save_register_global(machine, state->cdp1802_ef4); |
| 656 | | state_save_register_global(machine, state->iden); |
| 657 | | state_save_register_global(machine, state->slot); |
| 658 | | state_save_register_global(machine, state->bank); |
| 659 | | state_save_register_global(machine, state->rambank); |
| 660 | | state_save_register_global(machine, state->dma); |
| 661 | | |
| 662 | | state_save_register_global(machine, state->cdp1871_efxa); |
| 663 | | state_save_register_global(machine, state->cdp1871_efxb); |
| 664 | | |
| 665 | | state_save_register_global(machine, state->fdc_addr); |
| 666 | | state_save_register_global(machine, state->fdc_irq); |
| 667 | | state_save_register_global(machine, state->fdc_drq_enable); |
| 616 | state_save_register_global(machine, m_reset); |
| 617 | state_save_register_global(machine, m_cdp1802_q); |
| 618 | state_save_register_global(machine, m_cdp1802_ef4); |
| 619 | state_save_register_global(machine, m_iden); |
| 620 | state_save_register_global(machine, m_slot); |
| 621 | state_save_register_global(machine, m_bank); |
| 622 | state_save_register_global(machine, m_rambank); |
| 623 | state_save_register_global(machine, m_dma); |
| 624 | state_save_register_global(machine, m_fdc_addr); |
| 625 | state_save_register_global(machine, m_fdc_irq); |
| 626 | state_save_register_global(machine, m_fdc_drq_enable); |
| 668 | 627 | } |
| 669 | 628 | |
| 670 | | MACHINE_START( comx35n ) |
| 629 | void comx35_state::machine_reset() |
| 671 | 630 | { |
| 672 | | comx35_state *state = machine->driver_data<comx35_state>(); |
| 673 | | |
| 674 | | MACHINE_START_CALL(comx35p); |
| 675 | | |
| 676 | | // screen format |
| 677 | | |
| 678 | | state->pal_ntsc = 0; |
| 679 | | } |
| 680 | | |
| 681 | | MACHINE_RESET( comx35 ) |
| 682 | | { |
| 683 | | comx35_state *state = machine->driver_data<comx35_state>(); |
| 684 | 631 | int t = RES_K(27) * CAP_U(1) * 1000; // t = R1 * C1 |
| 685 | 632 | |
| 686 | | state->cdp1802_mode = CDP1802_MODE_RESET; |
| 687 | | state->iden = 1; |
| 688 | | state->cdp1802_ef4 = 1; |
| 633 | m_reset = 0; |
| 634 | m_iden = 1; |
| 635 | m_cdp1802_ef4 = 1; |
| 689 | 636 | |
| 690 | | timer_adjust_oneshot(state->reset_timer, ATTOTIME_IN_MSEC(t), 0); |
| 637 | timer_adjust_oneshot(m_reset_timer, ATTOTIME_IN_MSEC(t), 0); |
| 691 | 638 | } |
| 692 | 639 | |
| 693 | 640 | INPUT_CHANGED( comx35_reset ) |
| 694 | 641 | { |
| 642 | comx35_state *state = field->port->machine->driver_data<comx35_state>(); |
| 643 | |
| 695 | 644 | if (BIT(input_port_read(field->port->machine, "RESET"), 0) && BIT(input_port_read(field->port->machine, "D6"), 7)) |
| 696 | 645 | { |
| 697 | | running_machine *machine = field->port->machine; |
| 698 | | MACHINE_RESET_CALL(comx35); |
| 646 | state->machine_reset(); |
| 699 | 647 | } |
| 700 | 648 | } |
src/mess/video/tmc600.c
| r9387 | r9388 | |
| 2 | 2 | #include "sound/cdp1869.h" |
| 3 | 3 | #include "includes/tmc600.h" |
| 4 | 4 | |
| 5 | | WRITE8_HANDLER( tmc600_vismac_register_w ) |
| 5 | WRITE8_MEMBER( tmc600_state::vismac_register_w ) |
| 6 | 6 | { |
| 7 | | tmc600_state *state = space->machine->driver_data<tmc600_state>(); |
| 8 | | |
| 9 | | state->vismac_reg_latch = data; |
| 7 | m_vismac_reg_latch = data; |
| 10 | 8 | } |
| 11 | 9 | |
| 12 | | WRITE8_DEVICE_HANDLER( tmc600_vismac_data_w ) |
| 10 | WRITE8_MEMBER( tmc600_state::vismac_data_w ) |
| 13 | 11 | { |
| 14 | | tmc600_state *state = device->machine->driver_data<tmc600_state>(); |
| 15 | | |
| 16 | | switch (state->vismac_reg_latch) |
| 12 | switch (m_vismac_reg_latch) |
| 17 | 13 | { |
| 18 | 14 | case 0x20: |
| 19 | 15 | // set character color |
| 20 | | state->vismac_color_latch = data; |
| 16 | m_vismac_color_latch = data; |
| 21 | 17 | break; |
| 22 | 18 | |
| 23 | 19 | case 0x30: |
| 24 | 20 | // write cdp1869 command on the data bus |
| 25 | | state->vismac_bkg_latch = data & 0x07; |
| 26 | | cdp1869_out3_w(device, 0, data); |
| 21 | m_vismac_bkg_latch = data & 0x07; |
| 22 | cdp1869_out3_w(m_vis, 0, data); |
| 27 | 23 | break; |
| 28 | 24 | |
| 29 | 25 | case 0x40: |
| 30 | | cdp1869_out4_w(device, 0, data); |
| 26 | cdp1869_out4_w(m_vis, 0, data); |
| 31 | 27 | break; |
| 32 | 28 | |
| 33 | 29 | case 0x50: |
| 34 | | cdp1869_out5_w(device, 0, data); |
| 30 | cdp1869_out5_w(m_vis, 0, data); |
| 35 | 31 | break; |
| 36 | 32 | |
| 37 | 33 | case 0x60: |
| 38 | | cdp1869_out6_w(device, 0, data); |
| 34 | cdp1869_out6_w(m_vis, 0, data); |
| 39 | 35 | break; |
| 40 | 36 | |
| 41 | 37 | case 0x70: |
| 42 | | cdp1869_out7_w(device, 0, data); |
| 38 | cdp1869_out7_w(m_vis, 0, data); |
| 43 | 39 | break; |
| 44 | 40 | } |
| 45 | 41 | } |
| r9387 | r9388 | |
| 48 | 44 | { |
| 49 | 45 | tmc600_state *state = timer.machine->driver_data<tmc600_state>(); |
| 50 | 46 | |
| 51 | | state->blink = !state->blink; |
| 47 | state->m_blink = !state->m_blink; |
| 52 | 48 | } |
| 53 | 49 | |
| 54 | | static UINT8 tmc600_get_color(running_machine *machine, UINT16 pma) |
| 50 | UINT8 tmc600_state::get_color(UINT16 pma) |
| 55 | 51 | { |
| 56 | | tmc600_state *state = machine->driver_data<tmc600_state>(); |
| 57 | | |
| 58 | 52 | UINT16 pageaddr = pma & TMC600_PAGE_RAM_MASK; |
| 59 | | UINT8 color = state->color_ram[pageaddr]; |
| 53 | UINT8 color = m_color_ram[pageaddr]; |
| 60 | 54 | |
| 61 | | if (BIT(color, 3) && state->blink) |
| 55 | if (BIT(color, 3) && m_blink) |
| 62 | 56 | { |
| 63 | | color = state->vismac_bkg_latch; |
| 57 | color = m_vismac_bkg_latch; |
| 64 | 58 | } |
| 65 | 59 | |
| 66 | 60 | return color; |
| r9387 | r9388 | |
| 72 | 66 | |
| 73 | 67 | UINT16 addr = offset & TMC600_PAGE_RAM_MASK; |
| 74 | 68 | |
| 75 | | return state->page_ram[addr]; |
| 69 | return state->m_page_ram[addr]; |
| 76 | 70 | } |
| 77 | 71 | |
| 78 | 72 | static WRITE8_DEVICE_HANDLER( tmc600_page_ram_w ) |
| r9387 | r9388 | |
| 81 | 75 | |
| 82 | 76 | UINT16 addr = offset & TMC600_PAGE_RAM_MASK; |
| 83 | 77 | |
| 84 | | state->page_ram[addr] = data; |
| 85 | | state->color_ram[addr] = state->vismac_color_latch; |
| 78 | state->m_page_ram[addr] = data; |
| 79 | state->m_color_ram[addr] = state->m_vismac_color_latch; |
| 86 | 80 | } |
| 87 | 81 | |
| 88 | 82 | static CDP1869_CHAR_RAM_READ( tmc600_char_ram_r ) |
| r9387 | r9388 | |
| 90 | 84 | tmc600_state *state = device->machine->driver_data<tmc600_state>(); |
| 91 | 85 | |
| 92 | 86 | UINT16 pageaddr = pma & TMC600_PAGE_RAM_MASK; |
| 93 | | UINT8 column = state->page_ram[pageaddr]; |
| 94 | | UINT8 color = tmc600_get_color(device->machine, pageaddr); |
| 87 | UINT8 column = state->m_page_ram[pageaddr]; |
| 88 | UINT8 color = state->get_color(pageaddr); |
| 95 | 89 | UINT16 charaddr = ((cma & 0x08) << 8) | (column << 3) | (cma & 0x07); |
| 96 | | UINT8 cdb = state->char_rom[charaddr] & 0x3f; |
| 90 | UINT8 cdb = state->m_char_rom[charaddr] & 0x3f; |
| 97 | 91 | |
| 98 | 92 | int ccb0 = BIT(color, 2); |
| 99 | 93 | int ccb1 = BIT(color, 1); |
| r9387 | r9388 | |
| 103 | 97 | |
| 104 | 98 | static CDP1869_PCB_READ( tmc600_pcb_r ) |
| 105 | 99 | { |
| 100 | tmc600_state *state = device->machine->driver_data<tmc600_state>(); |
| 101 | |
| 106 | 102 | UINT16 pageaddr = pma & TMC600_PAGE_RAM_MASK; |
| 107 | | UINT8 color = tmc600_get_color(device->machine, pageaddr); |
| 103 | UINT8 color = state->get_color(pageaddr); |
| 108 | 104 | |
| 109 | 105 | return BIT(color, 0); |
| 110 | 106 | } |
| r9387 | r9388 | |
| 123 | 119 | DEVCB_NULL |
| 124 | 120 | }; |
| 125 | 121 | |
| 126 | | static VIDEO_START( tmc600 ) |
| 122 | void tmc600_state::video_start() |
| 127 | 123 | { |
| 128 | | tmc600_state *state = machine->driver_data<tmc600_state>(); |
| 129 | | |
| 130 | 124 | /* allocate memory */ |
| 125 | m_page_ram = auto_alloc_array(machine, UINT8, TMC600_PAGE_RAM_SIZE); |
| 126 | m_color_ram = auto_alloc_array(machine, UINT8, TMC600_PAGE_RAM_SIZE); |
| 131 | 127 | |
| 132 | | state->page_ram = auto_alloc_array(machine, UINT8, TMC600_PAGE_RAM_SIZE); |
| 133 | | state->color_ram = auto_alloc_array(machine, UINT8, TMC600_PAGE_RAM_SIZE); |
| 134 | | |
| 135 | | /* find devices */ |
| 136 | | |
| 137 | | state->cdp1869 = machine->device(CDP1869_TAG); |
| 138 | | |
| 139 | 128 | /* find memory regions */ |
| 129 | m_char_rom = memory_region(machine, "chargen"); |
| 140 | 130 | |
| 141 | | state->char_rom = memory_region(machine, "chargen"); |
| 142 | | |
| 143 | 131 | /* register for state saving */ |
| 132 | state_save_register_global_pointer(machine, m_page_ram, TMC600_PAGE_RAM_SIZE); |
| 133 | state_save_register_global_pointer(machine, m_color_ram, TMC600_PAGE_RAM_SIZE); |
| 144 | 134 | |
| 145 | | state_save_register_global_pointer(machine, state->page_ram, TMC600_PAGE_RAM_SIZE); |
| 146 | | state_save_register_global_pointer(machine, state->color_ram, TMC600_PAGE_RAM_SIZE); |
| 147 | | |
| 148 | | state_save_register_global(machine, state->vismac_reg_latch); |
| 149 | | state_save_register_global(machine, state->vismac_color_latch); |
| 150 | | state_save_register_global(machine, state->vismac_bkg_latch); |
| 151 | | state_save_register_global(machine, state->blink); |
| 135 | state_save_register_global(machine, m_vismac_reg_latch); |
| 136 | state_save_register_global(machine, m_vismac_color_latch); |
| 137 | state_save_register_global(machine, m_vismac_bkg_latch); |
| 138 | state_save_register_global(machine, m_blink); |
| 152 | 139 | } |
| 153 | 140 | |
| 154 | | static VIDEO_UPDATE( tmc600 ) |
| 141 | bool tmc600_state::video_update(screen_device &screen, bitmap_t &bitmap, const rectangle &cliprect) |
| 155 | 142 | { |
| 156 | | tmc600_state *state = screen->machine->driver_data<tmc600_state>(); |
| 143 | cdp1869_update(m_vis, &bitmap, &cliprect); |
| 157 | 144 | |
| 158 | | cdp1869_update(state->cdp1869, bitmap, cliprect); |
| 159 | | |
| 160 | 145 | return 0; |
| 161 | 146 | } |
| 162 | 147 | |
| r9387 | r9388 | |
| 167 | 152 | MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16) |
| 168 | 153 | MDRV_PALETTE_LENGTH(8+64) |
| 169 | 154 | MDRV_PALETTE_INIT(cdp1869) |
| 170 | | MDRV_VIDEO_START(tmc600) |
| 171 | | MDRV_VIDEO_UPDATE(tmc600) |
| 172 | 155 | MDRV_SCREEN_RAW_PARAMS(CDP1869_DOT_CLK_PAL, CDP1869_SCREEN_WIDTH, CDP1869_HBLANK_END, CDP1869_HBLANK_START, CDP1869_TOTAL_SCANLINES_PAL, CDP1869_SCANLINE_VBLANK_END_PAL, CDP1869_SCANLINE_VBLANK_START_PAL) |
| 173 | 156 | |
| 174 | 157 | MDRV_SPEAKER_STANDARD_MONO("mono") |
src/mess/video/comx35.c
| r9387 | r9388 | |
| 1 | 1 | #include "emu.h" |
| 2 | 2 | #include "rendlay.h" |
| 3 | 3 | #include "includes/comx35.h" |
| 4 | | #include "cpu/cdp1802/cdp1802.h" |
| 4 | #include "cpu/cosmac/cosmac.h" |
| 5 | 5 | #include "sound/cdp1869.h" |
| 6 | 6 | #include "sound/wave.h" |
| 7 | 7 | #include "video/mc6845.h" |
| r9387 | r9388 | |
| 14 | 14 | |
| 15 | 15 | UINT16 addr = offset & COMX35_PAGERAM_MASK; |
| 16 | 16 | |
| 17 | | return state->pageram[addr]; |
| 17 | return state->m_pageram[addr]; |
| 18 | 18 | } |
| 19 | 19 | |
| 20 | 20 | static WRITE8_DEVICE_HANDLER( comx35_pageram_w ) |
| r9387 | r9388 | |
| 23 | 23 | |
| 24 | 24 | UINT16 addr = offset & COMX35_PAGERAM_MASK; |
| 25 | 25 | |
| 26 | | state->pageram[addr] = data; |
| 26 | state->m_pageram[addr] = data; |
| 27 | 27 | } |
| 28 | 28 | |
| 29 | 29 | static CDP1869_CHAR_RAM_READ( comx35_charram_r ) |
| r9387 | r9388 | |
| 31 | 31 | comx35_state *state = device->machine->driver_data<comx35_state>(); |
| 32 | 32 | |
| 33 | 33 | UINT16 pageaddr = pma & COMX35_PAGERAM_MASK; |
| 34 | | UINT8 column = state->pageram[pageaddr] & 0x7f; |
| 34 | UINT8 column = state->m_pageram[pageaddr] & 0x7f; |
| 35 | 35 | UINT16 charaddr = (column << 4) | cma; |
| 36 | 36 | |
| 37 | | return state->charram[charaddr]; |
| 37 | return state->m_charram[charaddr]; |
| 38 | 38 | } |
| 39 | 39 | |
| 40 | 40 | static CDP1869_CHAR_RAM_WRITE( comx35_charram_w ) |
| r9387 | r9388 | |
| 42 | 42 | comx35_state *state = device->machine->driver_data<comx35_state>(); |
| 43 | 43 | |
| 44 | 44 | UINT16 pageaddr = pma & COMX35_PAGERAM_MASK; |
| 45 | | UINT8 column = state->pageram[pageaddr] & 0x7f; |
| 45 | UINT8 column = state->m_pageram[pageaddr] & 0x7f; |
| 46 | 46 | UINT16 charaddr = (column << 4) | cma; |
| 47 | 47 | |
| 48 | | state->charram[charaddr] = data; |
| 48 | state->m_charram[charaddr] = data; |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | 51 | static CDP1869_PCB_READ( comx35_pcb_r ) |
| r9387 | r9388 | |
| 54 | 54 | |
| 55 | 55 | UINT16 pageaddr = pma & COMX35_PAGERAM_MASK; |
| 56 | 56 | |
| 57 | | return BIT(state->pageram[pageaddr], 7); |
| 57 | return BIT(state->m_pageram[pageaddr], 7); |
| 58 | 58 | } |
| 59 | 59 | |
| 60 | 60 | static WRITE_LINE_DEVICE_HANDLER( comx35_prd_w ) |
| 61 | 61 | { |
| 62 | 62 | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 63 | 63 | |
| 64 | | if (!driver_state->iden && !state) |
| 64 | if (!driver_state->m_iden && !state) |
| 65 | 65 | { |
| 66 | | cputag_set_input_line(device->machine, CDP1802_TAG, CDP1802_INPUT_LINE_INT, ASSERT_LINE); |
| 66 | cpu_set_input_line(driver_state->m_maincpu, COSMAC_INPUT_LINE_INT, ASSERT_LINE); |
| 67 | 67 | } |
| 68 | 68 | |
| 69 | | driver_state->cdp1869_prd = state; |
| 69 | cpu_set_input_line(driver_state->m_maincpu, COSMAC_INPUT_LINE_EF1, state); |
| 70 | 70 | } |
| 71 | 71 | |
| 72 | 72 | static CDP1869_INTERFACE( pal_cdp1869_intf ) |
| r9387 | r9388 | |
| 97 | 97 | DEVCB_LINE(comx35_prd_w) |
| 98 | 98 | }; |
| 99 | 99 | |
| 100 | | static VIDEO_START( comx35 ) |
| 100 | void comx35_state::video_start() |
| 101 | 101 | { |
| 102 | | comx35_state *state = machine->driver_data<comx35_state>(); |
| 103 | | |
| 104 | 102 | // allocate memory |
| 103 | m_pageram = auto_alloc_array(machine, UINT8, COMX35_PAGERAM_SIZE); |
| 104 | m_charram = auto_alloc_array(machine, UINT8, COMX35_CHARRAM_SIZE); |
| 105 | m_videoram = auto_alloc_array(machine, UINT8, COMX35_VIDEORAM_SIZE); |
| 105 | 106 | |
| 106 | | state->pageram = auto_alloc_array(machine, UINT8, COMX35_PAGERAM_SIZE); |
| 107 | | state->charram = auto_alloc_array(machine, UINT8, COMX35_CHARRAM_SIZE); |
| 108 | | state->videoram = auto_alloc_array(machine, UINT8, COMX35_VIDEORAM_SIZE); |
| 109 | | |
| 110 | 107 | // register for save state |
| 111 | | |
| 112 | | state_save_register_global(machine, state->pal_ntsc); |
| 113 | | state_save_register_global(machine, state->cdp1869_prd); |
| 114 | | |
| 115 | | state_save_register_global_pointer(machine, state->pageram, COMX35_PAGERAM_SIZE); |
| 116 | | state_save_register_global_pointer(machine, state->charram, COMX35_CHARRAM_SIZE); |
| 117 | | state_save_register_global_pointer(machine, state->videoram, COMX35_VIDEORAM_SIZE); |
| 108 | state_save_register_global_pointer(machine, m_pageram, COMX35_PAGERAM_SIZE); |
| 109 | state_save_register_global_pointer(machine, m_charram, COMX35_CHARRAM_SIZE); |
| 110 | state_save_register_global_pointer(machine, m_videoram, COMX35_VIDEORAM_SIZE); |
| 118 | 111 | } |
| 119 | 112 | |
| 120 | | static VIDEO_UPDATE( comx35 ) |
| 113 | bool comx35_state::video_update(screen_device &screen, bitmap_t &bitmap, const rectangle &cliprect) |
| 121 | 114 | { |
| 122 | | screen_device *screen_40 = downcast<screen_device *>(screen->machine->device(SCREEN_TAG)); |
| 123 | | |
| 124 | | if (screen == screen_40) |
| 115 | if (screen.width() == CDP1869_SCREEN_WIDTH) |
| 125 | 116 | { |
| 126 | | running_device *cdp1869 = screen->machine->device(CDP1869_TAG); |
| 127 | | |
| 128 | | cdp1869_update(cdp1869, bitmap, cliprect); |
| 117 | cdp1869_update(m_vis, &bitmap, &cliprect); |
| 129 | 118 | } |
| 130 | 119 | else |
| 131 | 120 | { |
| 132 | | running_device *mc6845 = screen->machine->device(MC6845_TAG); |
| 133 | | |
| 134 | | mc6845_update(mc6845, bitmap, cliprect); |
| 121 | mc6845_update(m_crtc, &bitmap, &cliprect); |
| 135 | 122 | } |
| 136 | 123 | |
| 137 | 124 | return 0; |
| r9387 | r9388 | |
| 139 | 126 | |
| 140 | 127 | /* MC6845 */ |
| 141 | 128 | |
| 142 | | READ8_HANDLER( comx35_videoram_r ) |
| 143 | | { |
| 144 | | comx35_state *state = space->machine->driver_data<comx35_state>(); |
| 145 | | |
| 146 | | return state->videoram[offset]; |
| 147 | | } |
| 148 | | |
| 149 | | WRITE8_HANDLER( comx35_videoram_w ) |
| 150 | | { |
| 151 | | comx35_state *state = space->machine->driver_data<comx35_state>(); |
| 152 | | |
| 153 | | state->videoram[offset] = data; |
| 154 | | } |
| 155 | | |
| 156 | 129 | static MC6845_UPDATE_ROW( comx35_update_row ) |
| 157 | 130 | { |
| 158 | 131 | comx35_state *state = device->machine->driver_data<comx35_state>(); |
| r9387 | r9388 | |
| 163 | 136 | |
| 164 | 137 | for (column = 0; column < x_count; column++) |
| 165 | 138 | { |
| 166 | | UINT8 code = state->videoram[((ma + column) & 0x7ff)]; |
| 139 | UINT8 code = state->m_videoram[((ma + column) & 0x7ff)]; |
| 167 | 140 | UINT16 addr = (code << 3) | (ra & 0x07); |
| 168 | 141 | UINT8 data = charrom[addr & 0x7ff]; |
| 169 | 142 | |
| r9387 | r9388 | |
| 188 | 161 | { |
| 189 | 162 | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 190 | 163 | |
| 191 | | driver_state->cdp1802_ef4 = state; |
| 164 | driver_state->m_cdp1802_ef4 = state; |
| 192 | 165 | } |
| 193 | 166 | |
| 194 | 167 | static const mc6845_interface comx35_mc6845_interface = |
| r9387 | r9388 | |
| 205 | 178 | NULL |
| 206 | 179 | }; |
| 207 | 180 | |
| 181 | /* F4 Character Displayer */ |
| 182 | static const gfx_layout comx35_charlayout = |
| 183 | { |
| 184 | 8, 8, /* 8 x 8 characters */ |
| 185 | 256, /* 256 characters */ |
| 186 | 1, /* 1 bits per pixel */ |
| 187 | { 0 }, /* no bitplanes */ |
| 188 | /* x offsets */ |
| 189 | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 190 | /* y offsets */ |
| 191 | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, |
| 192 | 8*8 /* every char takes 8 bytes */ |
| 193 | }; |
| 194 | |
| 195 | static GFXDECODE_START( comx35 ) |
| 196 | GFXDECODE_ENTRY( "chargen", 0x0000, comx35_charlayout, 0, 36 ) |
| 197 | GFXDECODE_END |
| 198 | |
| 208 | 199 | /* Machine Drivers */ |
| 209 | 200 | |
| 210 | 201 | static MACHINE_CONFIG_FRAGMENT( comx35_80_video ) |
| r9387 | r9388 | |
| 223 | 214 | |
| 224 | 215 | MDRV_CDP1869_SCREEN_PAL_ADD(SCREEN_TAG, CDP1869_DOT_CLK_PAL) |
| 225 | 216 | |
| 226 | | MDRV_VIDEO_START(comx35) |
| 227 | | MDRV_VIDEO_UPDATE(comx35) |
| 217 | MDRV_GFXDECODE(comx35) |
| 228 | 218 | |
| 229 | 219 | /* sound hardware */ |
| 230 | 220 | MDRV_SPEAKER_STANDARD_MONO("mono") |
| r9387 | r9388 | |
| 243 | 233 | |
| 244 | 234 | MDRV_CDP1869_SCREEN_NTSC_ADD(SCREEN_TAG, CDP1869_DOT_CLK_NTSC) |
| 245 | 235 | |
| 246 | | MDRV_VIDEO_START(comx35) |
| 247 | | MDRV_VIDEO_UPDATE(comx35) |
| 236 | MDRV_GFXDECODE(comx35) |
| 248 | 237 | |
| 249 | 238 | /* sound hardware */ |
| 250 | 239 | MDRV_SPEAKER_STANDARD_MONO("mono") |
src/mess/includes/comx35.h
| r9387 | r9388 | |
| 1 | 1 | #ifndef __COMX35__ |
| 2 | 2 | #define __COMX35__ |
| 3 | 3 | |
| 4 | #include "cpu/cosmac/cosmac.h" |
| 4 | 5 | #include "devices/snapquik.h" |
| 5 | 6 | #include "machine/wd17xx.h" |
| 6 | 7 | |
| r9387 | r9388 | |
| 41 | 42 | { |
| 42 | 43 | public: |
| 43 | 44 | comx35_state(running_machine &machine, const driver_device_config_base &config) |
| 44 | | : driver_device(machine, config) { } |
| 45 | : driver_device(machine, config), |
| 46 | m_maincpu(*this, CDP1802_TAG), |
| 47 | m_vis(*this, CDP1869_TAG), |
| 48 | m_crtc(*this, MC6845_TAG), |
| 49 | m_fdc(*this, WD1770_TAG), |
| 50 | m_kbe(*this, CDP1871_TAG), |
| 51 | m_cassette(*this, CASSETTE_TAG), |
| 52 | m_ram(*this, "messram") |
| 53 | { } |
| 45 | 54 | |
| 46 | | /* processor state */ |
| 47 | | int cdp1802_mode; /* CPU mode */ |
| 48 | | int cdp1802_q; /* Q flag */ |
| 49 | | int cdp1802_ef4; /* EF4 flag */ |
| 50 | | int iden; /* interrupt/DMA enable */ |
| 51 | | int slot; /* selected slot */ |
| 52 | | int bank; /* selected device bank */ |
| 53 | | int rambank; /* selected RAM bank */ |
| 54 | | int dma; /* memory refresh DMA */ |
| 55 | required_device<cosmac_device> m_maincpu; |
| 56 | required_device<running_device> m_vis; |
| 57 | required_device<running_device> m_crtc; |
| 58 | required_device<running_device> m_fdc; |
| 59 | required_device<running_device> m_kbe; |
| 60 | required_device<running_device> m_cassette; |
| 61 | required_device<running_device> m_ram; |
| 55 | 62 | |
| 56 | | /* video state */ |
| 57 | | int pal_ntsc; /* PAL/NTSC */ |
| 58 | | int cdp1869_prd; /* CDP1869 predisplay */ |
| 63 | virtual void machine_start(); |
| 64 | virtual void machine_reset(); |
| 59 | 65 | |
| 60 | | UINT8 *pageram; /* page memory */ |
| 61 | | UINT8 *charram; /* character memory */ |
| 62 | | UINT8 *videoram; /* 80 column video memory */ |
| 66 | virtual void video_start(); |
| 67 | virtual bool video_update(screen_device &screen, bitmap_t &bitmap, const rectangle &cliprect); |
| 63 | 68 | |
| 64 | | /* keyboard state */ |
| 65 | | int cdp1871_efxa; /* keyboard data available */ |
| 66 | | int cdp1871_efxb; /* keyboard repeat */ |
| 69 | DECLARE_READ8_MEMBER(io_r); |
| 70 | DECLARE_READ8_MEMBER(io2_r); |
| 67 | 71 | |
| 72 | DECLARE_WRITE8_MEMBER(bank_select_w); |
| 73 | DECLARE_WRITE8_MEMBER(io_w); |
| 74 | |
| 75 | UINT8 read_expansion(); |
| 76 | bool is_expansion_box_installed(); |
| 77 | bool is_dos_card_active(); |
| 78 | UINT8 fdc_r(); |
| 79 | void fdc_w(UINT8 data); |
| 80 | UINT8 printer_r(); |
| 81 | void printer_w(UINT8 data); |
| 82 | void get_active_bank(UINT8 data); |
| 83 | void set_active_bank(); |
| 84 | |
| 85 | /* processor state */ |
| 86 | int m_reset; /* CPU mode */ |
| 87 | int m_cdp1802_q; /* Q flag */ |
| 88 | int m_cdp1802_ef4; /* EF4 flag */ |
| 89 | int m_iden; /* interrupt/DMA enable */ |
| 90 | int m_slot; /* selected slot */ |
| 91 | int m_bank; /* selected device bank */ |
| 92 | int m_rambank; /* selected RAM bank */ |
| 93 | int m_dma; /* memory refresh DMA */ |
| 94 | |
| 95 | UINT8 *m_pageram; /* page memory */ |
| 96 | UINT8 *m_charram; /* character memory */ |
| 97 | UINT8 *m_videoram; /* 80 column video memory */ |
| 98 | |
| 68 | 99 | /* floppy state */ |
| 69 | | int fdc_addr; /* FDC address */ |
| 70 | | int fdc_irq; /* interrupt request */ |
| 71 | | int fdc_drq_enable; /* EF4 enabled */ |
| 100 | int m_fdc_addr; /* FDC address */ |
| 101 | int m_fdc_irq; /* interrupt request */ |
| 102 | int m_fdc_drq_enable; /* EF4 enabled */ |
| 72 | 103 | |
| 73 | 104 | /* timers */ |
| 74 | | emu_timer *reset_timer; /* power on reset timer */ |
| 75 | | |
| 76 | | /* devices */ |
| 77 | | running_device *cassette; |
| 105 | emu_timer *m_reset_timer; /* power on reset timer */ |
| 78 | 106 | }; |
| 79 | 107 | |
| 80 | 108 | /* ---------- defined in machine/comx35.c ---------- */ |
| 81 | | |
| 82 | 109 | extern const wd17xx_interface comx35_wd17xx_interface; |
| 83 | 110 | |
| 84 | | WRITE8_HANDLER( comx35_bank_select_w ); |
| 85 | | READ8_HANDLER( comx35_io_r ); |
| 86 | | READ8_HANDLER( comx35_io2_r ); |
| 87 | | WRITE8_HANDLER( comx35_io_w ); |
| 88 | | |
| 89 | | MACHINE_START( comx35p ); |
| 90 | | MACHINE_START( comx35n ); |
| 91 | | MACHINE_RESET( comx35 ); |
| 92 | 111 | INPUT_CHANGED( comx35_reset ); |
| 93 | 112 | |
| 94 | 113 | /* ---------- defined in video/comx35.c ---------- */ |
| 95 | | |
| 96 | | WRITE8_HANDLER( comx35_videoram_w ); |
| 97 | | READ8_HANDLER( comx35_videoram_r ); |
| 98 | | |
| 99 | 114 | MACHINE_CONFIG_EXTERN( comx35_pal_video ); |
| 100 | 115 | MACHINE_CONFIG_EXTERN( comx35_ntsc_video ); |
| 101 | 116 | |
src/mess/drivers/tmc600.c
| r9387 | r9388 | |
| 79 | 79 | |
| 80 | 80 | */ |
| 81 | 81 | |
| 82 | #define ADDRESS_MAP_MODERN |
| 83 | |
| 82 | 84 | #include "emu.h" |
| 83 | 85 | #include "machine/ctronics.h" |
| 84 | 86 | #include "devices/flopdrv.h" |
| 85 | 87 | #include "formats/basicdsk.h" |
| 86 | 88 | #include "devices/cassette.h" |
| 87 | 89 | #include "devices/snapquik.h" |
| 88 | | #include "cpu/cdp1802/cdp1802.h" |
| 90 | #include "cpu/cosmac/cosmac.h" |
| 89 | 91 | #include "sound/cdp1869.h" |
| 90 | 92 | #include "includes/tmc600.h" |
| 91 | 93 | #include "devices/messram.h" |
| 92 | 94 | |
| 93 | 95 | /* Read/Write Handlers */ |
| 94 | 96 | |
| 95 | | static WRITE8_HANDLER( keyboard_latch_w ) |
| 97 | WRITE8_MEMBER( tmc600_state::keyboard_latch_w ) |
| 96 | 98 | { |
| 97 | | tmc600_state *state = space->machine->driver_data<tmc600_state>(); |
| 98 | | |
| 99 | | state->keylatch = data; |
| 99 | m_keylatch = data; |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | /* Memory Maps */ |
| 103 | 103 | |
| 104 | | static ADDRESS_MAP_START( tmc600_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 104 | static ADDRESS_MAP_START( tmc600_map, ADDRESS_SPACE_PROGRAM, 8, tmc600_state ) |
| 105 | 105 | AM_RANGE(0x0000, 0x4fff) AM_ROM |
| 106 | 106 | AM_RANGE(0x6000, 0xbfff) AM_RAM |
| 107 | | AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w) |
| 108 | | AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w) |
| 107 | AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE_LEGACY(CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w) |
| 108 | AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE_LEGACY(CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w) |
| 109 | 109 | ADDRESS_MAP_END |
| 110 | 110 | |
| 111 | | static ADDRESS_MAP_START( tmc600_io_map, ADDRESS_SPACE_IO, 8 ) |
| 111 | static ADDRESS_MAP_START( tmc600_io_map, ADDRESS_SPACE_IO, 8, tmc600_state ) |
| 112 | 112 | AM_RANGE(0x03, 0x03) AM_WRITE(keyboard_latch_w) |
| 113 | | AM_RANGE(0x04, 0x04) AM_DEVWRITE(CENTRONICS_TAG, centronics_data_w) |
| 114 | | AM_RANGE(0x05, 0x05) AM_DEVWRITE(CDP1869_TAG, tmc600_vismac_data_w) |
| 113 | AM_RANGE(0x04, 0x04) AM_DEVWRITE_LEGACY(CENTRONICS_TAG, centronics_data_w) |
| 114 | AM_RANGE(0x05, 0x05) AM_WRITE(vismac_data_w) |
| 115 | 115 | // AM_RANGE(0x06, 0x06) AM_WRITE(floppy_w) |
| 116 | | AM_RANGE(0x07, 0x07) AM_WRITE(tmc600_vismac_register_w) |
| 116 | AM_RANGE(0x07, 0x07) AM_WRITE(vismac_register_w) |
| 117 | 117 | ADDRESS_MAP_END |
| 118 | 118 | |
| 119 | 119 | /* Input Ports */ |
| r9387 | r9388 | |
| 211 | 211 | |
| 212 | 212 | /* CDP1802 Interface */ |
| 213 | 213 | |
| 214 | | static CDP1802_MODE_READ( tmc600_mode_r ) |
| 214 | static READ_LINE_DEVICE_HANDLER( clear_r ) |
| 215 | 215 | { |
| 216 | | if (input_port_read(device->machine, "RUN") & 0x01) |
| 217 | | { |
| 218 | | return CDP1802_MODE_RESET; |
| 219 | | } |
| 220 | | else |
| 221 | | { |
| 222 | | return CDP1802_MODE_RUN; |
| 223 | | } |
| 216 | return BIT(input_port_read(device->machine, "RUN"), 0); |
| 224 | 217 | } |
| 225 | 218 | |
| 226 | | static CDP1802_EF_READ( tmc600_ef_r ) |
| 219 | static READ_LINE_DEVICE_HANDLER( ef2_r ) |
| 227 | 220 | { |
| 228 | | tmc600_state *state = device->machine->driver_data<tmc600_state>(); |
| 221 | return cassette_input(device) < 0; |
| 222 | } |
| 229 | 223 | |
| 230 | | int flags = 0x0f; |
| 224 | static READ_LINE_DEVICE_HANDLER( ef3_r ) |
| 225 | { |
| 226 | tmc600_state *state = device->machine->driver_data<tmc600_state>(); |
| 231 | 227 | static const char *const keynames[] = { "IN0", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6", "IN7" }; |
| 228 | UINT8 data = ~input_port_read(device->machine, keynames[state->m_keylatch / 8]); |
| 232 | 229 | |
| 233 | | /* |
| 234 | | EF1 ? |
| 235 | | EF2 tape in |
| 236 | | EF3 keyboard |
| 237 | | EF4 ? |
| 238 | | */ |
| 239 | | |
| 240 | | // tape in |
| 241 | | |
| 242 | | if (cassette_input(state->cassette) < +0.0) flags -= EF2; |
| 243 | | |
| 244 | | // keyboard |
| 245 | | |
| 246 | | flags -= (~input_port_read(device->machine, keynames[state->keylatch / 8]) & (1 << (state->keylatch % 8))) ? EF3 : 0; |
| 247 | | |
| 248 | | return flags; |
| 230 | return BIT(data, state->m_keylatch % 8); |
| 249 | 231 | } |
| 250 | 232 | |
| 251 | 233 | static WRITE_LINE_DEVICE_HANDLER( tmc600_q_w ) |
| 252 | 234 | { |
| 253 | 235 | tmc600_state *driver_state = device->machine->driver_data<tmc600_state>(); |
| 254 | 236 | |
| 255 | | cassette_output(driver_state->cassette, state ? +1.0 : -1.0); |
| 237 | cassette_output(driver_state->m_cassette, state ? +1.0 : -1.0); |
| 256 | 238 | } |
| 257 | 239 | |
| 258 | | static CDP1802_INTERFACE( tmc600_cdp1802_config ) |
| 240 | static COSMAC_INTERFACE( cosmac_intf ) |
| 259 | 241 | { |
| 260 | | tmc600_mode_r, |
| 261 | | tmc600_ef_r, |
| 262 | | NULL, |
| 242 | DEVCB_LINE_VCC, |
| 243 | DEVCB_LINE(clear_r), |
| 244 | DEVCB_NULL, |
| 245 | DEVCB_DEVICE_LINE(CASSETTE_TAG, ef2_r), |
| 246 | DEVCB_LINE(ef3_r), |
| 247 | DEVCB_NULL, |
| 263 | 248 | DEVCB_LINE(tmc600_q_w), |
| 264 | 249 | DEVCB_NULL, |
| 250 | DEVCB_NULL, |
| 251 | NULL, |
| 252 | DEVCB_NULL, |
| 265 | 253 | DEVCB_NULL |
| 266 | 254 | }; |
| 267 | 255 | |
| 268 | 256 | /* Machine Initialization */ |
| 269 | 257 | |
| 270 | | static MACHINE_START( tmc600 ) |
| 258 | void tmc600_state::machine_start() |
| 271 | 259 | { |
| 272 | | tmc600_state *state = machine->driver_data<tmc600_state>(); |
| 273 | 260 | address_space *program = cputag_get_address_space(machine, CDP1802_TAG, ADDRESS_SPACE_PROGRAM); |
| 274 | 261 | |
| 275 | | /* find devices */ |
| 276 | | state->cassette = machine->device(CASSETTE_TAG); |
| 277 | | |
| 278 | 262 | /* configure RAM */ |
| 279 | | switch (messram_get_size(machine->device("messram"))) |
| 263 | switch (messram_get_size(m_ram)) |
| 280 | 264 | { |
| 281 | 265 | case 8*1024: |
| 282 | 266 | memory_unmap_readwrite(program, 0x8000, 0xbfff, 0, 0); |
| r9387 | r9388 | |
| 288 | 272 | } |
| 289 | 273 | |
| 290 | 274 | /* register for state saving */ |
| 291 | | state_save_register_global(machine, state->keylatch); |
| 275 | state_save_register_global(machine, m_keylatch); |
| 292 | 276 | } |
| 293 | 277 | |
| 294 | | static MACHINE_RESET( tmc600 ) |
| 278 | void tmc600_state::machine_reset() |
| 295 | 279 | { |
| 296 | 280 | cputag_set_input_line(machine, CDP1802_TAG, INPUT_LINE_RESET, PULSE_LINE); |
| 297 | 281 | } |
| r9387 | r9388 | |
| 305 | 289 | (cassette_state)(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED), |
| 306 | 290 | NULL |
| 307 | 291 | }; |
| 308 | | static FLOPPY_OPTIONS_START(tmc600) |
| 309 | | // dsk |
| 310 | | FLOPPY_OPTIONS_END |
| 311 | 292 | |
| 312 | 293 | static const floppy_config tmc600_floppy_config = |
| 313 | 294 | { |
| r9387 | r9388 | |
| 317 | 298 | DEVCB_NULL, |
| 318 | 299 | DEVCB_NULL, |
| 319 | 300 | FLOPPY_STANDARD_5_25_DSHD, |
| 320 | | FLOPPY_OPTIONS_NAME(tmc600), |
| 301 | FLOPPY_OPTIONS_NAME(default), |
| 321 | 302 | NULL |
| 322 | 303 | }; |
| 323 | 304 | |
| r9387 | r9388 | |
| 340 | 321 | GFXDECODE_END |
| 341 | 322 | |
| 342 | 323 | static MACHINE_CONFIG_START( tmc600, tmc600_state ) |
| 343 | | |
| 344 | 324 | // basic system hardware |
| 345 | | |
| 346 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, 3579545) // ??? |
| 325 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, 3579545) // ??? |
| 347 | 326 | MDRV_CPU_PROGRAM_MAP(tmc600_map) |
| 348 | 327 | MDRV_CPU_IO_MAP(tmc600_io_map) |
| 349 | | MDRV_CPU_CONFIG(tmc600_cdp1802_config) |
| 328 | MDRV_CPU_CONFIG(cosmac_intf) |
| 350 | 329 | |
| 351 | | MDRV_MACHINE_START(tmc600) |
| 352 | | MDRV_MACHINE_RESET(tmc600) |
| 353 | | |
| 354 | 330 | // sound and video hardware |
| 355 | | |
| 356 | 331 | MDRV_FRAGMENT_ADD(tmc600_video) |
| 357 | 332 | MDRV_GFXDECODE(tmc600) |
| 358 | 333 | |
| 359 | | /* printer */ |
| 334 | /* devices */ |
| 360 | 335 | MDRV_CENTRONICS_ADD(CENTRONICS_TAG, standard_centronics) |
| 361 | | |
| 362 | | /* cassette */ |
| 363 | 336 | MDRV_CASSETTE_ADD(CASSETTE_TAG, tmc600_cassette_config) |
| 337 | MDRV_FLOPPY_2_DRIVES_ADD(tmc600_floppy_config) |
| 364 | 338 | |
| 365 | | MDRV_FLOPPY_4_DRIVES_ADD(tmc600_floppy_config) |
| 366 | | |
| 367 | 339 | /* internal ram */ |
| 368 | 340 | MDRV_RAM_ADD("messram") |
| 369 | 341 | MDRV_RAM_DEFAULT_SIZE("8K") |
src/mess/drivers/eti660.c
| r9387 | r9388 | |
| 11 | 11 | |
| 12 | 12 | #include "emu.h" |
| 13 | 13 | #include "includes/eti660.h" |
| 14 | | #include "cpu/cdp1802/cdp1802.h" |
| 14 | #include "cpu/cosmac/cosmac.h" |
| 15 | 15 | #include "devices/cassette.h" |
| 16 | 16 | #include "devices/messram.h" |
| 17 | 17 | #include "machine/6821pia.h" |
| 18 | 18 | #include "machine/rescap.h" |
| 19 | 19 | #include "sound/cdp1864.h" |
| 20 | 20 | |
| 21 | static MACHINE_RESET( eti660 ); |
| 22 | |
| 21 | 23 | #define RX(_machine) \ |
| 22 | | cpu_get_reg(_machine->firstcpu, CDP1802_R0 + cpu_get_reg(_machine->firstcpu, CDP1802_X)) |
| 24 | cpu_get_reg(_machine->firstcpu, COSMAC_R0 + cpu_get_reg(_machine->firstcpu, COSMAC_X)) |
| 23 | 25 | |
| 24 | 26 | /* Read/Write Handlers */ |
| 25 | 27 | |
| r9387 | r9388 | |
| 63 | 65 | |
| 64 | 66 | /* Input Ports */ |
| 65 | 67 | |
| 66 | | static INPUT_CHANGED( trigger_reset ) |
| 68 | static INPUT_CHANGED( reset_pressed ) |
| 67 | 69 | { |
| 68 | | eti660_state *state = field->port->machine->driver_data<eti660_state>(); |
| 69 | | |
| 70 | | state->cdp1802_mode = newval ? CDP1802_MODE_RUN : CDP1802_MODE_RESET; |
| 70 | if (oldval && !newval) |
| 71 | { |
| 72 | running_machine *machine = field->port->machine; |
| 73 | MACHINE_RESET_CALL(eti660); |
| 74 | } |
| 71 | 75 | } |
| 72 | 76 | |
| 73 | 77 | static INPUT_PORTS_START( eti660 ) |
| r9387 | r9388 | |
| 96 | 100 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') |
| 97 | 101 | |
| 98 | 102 | PORT_START("SPECIAL") |
| 99 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_R) PORT_CHANGED(trigger_reset, 0) |
| 103 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_R) PORT_CHANGED(reset_pressed, 0) |
| 100 | 104 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("STEP") PORT_CODE(KEYCODE_S) |
| 101 | 105 | INPUT_PORTS_END |
| 102 | 106 | |
| 103 | 107 | /* Video */ |
| 104 | 108 | |
| 105 | | static WRITE_LINE_DEVICE_HANDLER( eti660_efx_w ) |
| 106 | | { |
| 107 | | eti660_state *driver_state = device->machine->driver_data<eti660_state>(); |
| 108 | | |
| 109 | | driver_state->cdp1864_efx = state; |
| 110 | | } |
| 111 | | |
| 112 | 109 | static READ_LINE_DEVICE_HANDLER( rdata_r ) |
| 113 | 110 | { |
| 114 | 111 | eti660_state *state = device->machine->driver_data<eti660_state>(); |
| r9387 | r9388 | |
| 138 | 135 | DEVCB_LINE(rdata_r), |
| 139 | 136 | DEVCB_LINE(bdata_r), |
| 140 | 137 | DEVCB_LINE(gdata_r), |
| 141 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_INT), |
| 142 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_DMAOUT), |
| 143 | | DEVCB_LINE(eti660_efx_w), |
| 138 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_INT), |
| 139 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_DMAOUT), |
| 140 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_EF1), |
| 144 | 141 | RES_K(2.2), /* R7 */ |
| 145 | 142 | RES_K(1), /* R5 */ |
| 146 | 143 | RES_K(4.7), /* R6 */ |
| r9387 | r9388 | |
| 158 | 155 | |
| 159 | 156 | /* CDP1802 Interface */ |
| 160 | 157 | |
| 161 | | static CDP1802_MODE_READ( eti660_mode_r ) |
| 158 | static READ_LINE_DEVICE_HANDLER( clear_r ) |
| 162 | 159 | { |
| 163 | | eti660_state *state = device->machine->driver_data<eti660_state>(); |
| 164 | | |
| 165 | | return state->cdp1802_mode; |
| 160 | return BIT(input_port_read(device->machine, "SPECIAL"), 0); |
| 166 | 161 | } |
| 167 | 162 | |
| 168 | | static CDP1802_EF_READ( eti660_ef_r ) |
| 163 | static READ_LINE_DEVICE_HANDLER( ef2_r ) |
| 169 | 164 | { |
| 170 | | eti660_state *state = device->machine->driver_data<eti660_state>(); |
| 165 | return cassette_input(device) < 0; |
| 166 | } |
| 171 | 167 | |
| 172 | | int ef = 0x0f; |
| 173 | | |
| 174 | | /* CDP1864 EFx */ |
| 175 | | if (state->cdp1864_efx) ef -= EF1; |
| 176 | | |
| 177 | | /* tape input */ |
| 178 | | if (cassette_input(state->cassette) < 0) ef -= EF2; |
| 179 | | |
| 180 | | /* STEP key */ |
| 181 | | if (!BIT(input_port_read(device->machine, "SPECIAL"), 1)) ef -= EF4; |
| 182 | | |
| 183 | | return ef; |
| 168 | static READ_LINE_DEVICE_HANDLER( ef4_r ) |
| 169 | { |
| 170 | return BIT(input_port_read(device->machine, "SPECIAL"), 1); |
| 184 | 171 | } |
| 185 | 172 | |
| 186 | 173 | static WRITE_LINE_DEVICE_HANDLER( eti660_q_w ) |
| r9387 | r9388 | |
| 208 | 195 | cdp1864_dma_w(state->cdp1864, offset, data); |
| 209 | 196 | } |
| 210 | 197 | |
| 211 | | static CDP1802_INTERFACE( eti660_config ) |
| 198 | static COSMAC_INTERFACE( eti660_config ) |
| 212 | 199 | { |
| 213 | | eti660_mode_r, |
| 214 | | eti660_ef_r, |
| 215 | | NULL, |
| 200 | DEVCB_LINE_VCC, |
| 201 | DEVCB_LINE(clear_r), |
| 202 | DEVCB_NULL, |
| 203 | DEVCB_DEVICE_LINE(CASSETTE_TAG, ef2_r), |
| 204 | DEVCB_NULL, |
| 205 | DEVCB_LINE(ef4_r), |
| 216 | 206 | DEVCB_LINE(eti660_q_w), |
| 217 | 207 | DEVCB_NULL, |
| 218 | | DEVCB_HANDLER(eti660_dma_w) |
| 208 | DEVCB_HANDLER(eti660_dma_w), |
| 209 | NULL, |
| 210 | DEVCB_NULL, |
| 211 | DEVCB_NULL |
| 219 | 212 | }; |
| 220 | 213 | |
| 221 | 214 | /* PIA6821 Interface */ |
| r9387 | r9388 | |
| 288 | 281 | |
| 289 | 282 | /* Machine Initialization */ |
| 290 | 283 | |
| 291 | | static TIMER_CALLBACK( set_cpu_mode ) |
| 292 | | { |
| 293 | | eti660_state *state = machine->driver_data<eti660_state>(); |
| 294 | | |
| 295 | | state->cdp1802_mode = CDP1802_MODE_RUN; |
| 296 | | } |
| 297 | | |
| 298 | 284 | static MACHINE_START( eti660 ) |
| 299 | 285 | { |
| 300 | 286 | eti660_state *state = machine->driver_data<eti660_state>(); |
| r9387 | r9388 | |
| 302 | 288 | /* find devices */ |
| 303 | 289 | state->cdp1864 = machine->device(CDP1864_TAG); |
| 304 | 290 | state->cassette = machine->device(CASSETTE_TAG); |
| 305 | | |
| 306 | | /* register for state saving */ |
| 307 | | state_save_register_global(machine, state->cdp1802_mode); |
| 308 | | state_save_register_global(machine, state->cdp1864_efx); |
| 309 | 291 | } |
| 310 | 292 | |
| 311 | 293 | static MACHINE_RESET( eti660 ) |
| 312 | 294 | { |
| 313 | 295 | eti660_state *state = machine->driver_data<eti660_state>(); |
| 314 | 296 | |
| 315 | | /* reset CPU */ |
| 316 | | state->cdp1802_mode = CDP1802_MODE_RESET; |
| 317 | | timer_set(machine, ATTOTIME_IN_MSEC(0), NULL, 0, set_cpu_mode); |
| 318 | | |
| 319 | 297 | /* reset CDP1864 */ |
| 320 | 298 | state->cdp1864->reset(); |
| 321 | 299 | } |
| r9387 | r9388 | |
| 331 | 309 | }; |
| 332 | 310 | |
| 333 | 311 | static MACHINE_CONFIG_START( eti660, eti660_state ) |
| 334 | | |
| 335 | 312 | /* basic machine hardware */ |
| 336 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_8_867238MHz/5) |
| 313 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, XTAL_8_867238MHz/5) |
| 337 | 314 | MDRV_CPU_PROGRAM_MAP(eti660_map) |
| 338 | 315 | MDRV_CPU_IO_MAP(eti660_io_map) |
| 339 | 316 | MDRV_CPU_CONFIG(eti660_config) |
src/mess/drivers/studio2.c
| r9387 | r9388 | |
| 193 | 193 | |
| 194 | 194 | */ |
| 195 | 195 | |
| 196 | #define ADDRESS_MAP_MODERN |
| 197 | |
| 196 | 198 | #include "emu.h" |
| 197 | 199 | #include "includes/studio2.h" |
| 198 | | #include "cpu/cdp1802/cdp1802.h" |
| 200 | #include "cpu/cosmac/cosmac.h" |
| 199 | 201 | #include "devices/cartslot.h" |
| 200 | 202 | #include "formats/studio2_st2.h" |
| 201 | 203 | #include "sound/beep.h" |
| r9387 | r9388 | |
| 205 | 207 | |
| 206 | 208 | /* Read/Write Handlers */ |
| 207 | 209 | |
| 208 | | static WRITE8_HANDLER( keylatch_w ) |
| 210 | WRITE8_MEMBER( studio2_state::keylatch_w ) |
| 209 | 211 | { |
| 210 | | studio2_state *state = space->machine->driver_data<studio2_state>(); |
| 211 | | |
| 212 | | state->keylatch = data & 0x0f; |
| 212 | m_keylatch = data & 0x0f; |
| 213 | 213 | } |
| 214 | 214 | |
| 215 | | static READ8_DEVICE_HANDLER( studio2_cdp1861_dispon_r ) |
| 215 | READ8_MEMBER( studio2_state::dispon_r ) |
| 216 | 216 | { |
| 217 | | cdp1861_dispon_w(device, 1); |
| 218 | | cdp1861_dispon_w(device, 0); |
| 217 | cdp1861_dispon_w(m_vdc, 1); |
| 218 | cdp1861_dispon_w(m_vdc, 0); |
| 219 | 219 | |
| 220 | 220 | return 0xff; |
| 221 | 221 | } |
| 222 | 222 | |
| 223 | | static WRITE8_DEVICE_HANDLER( visicom_cdp1861_dispon_w ) |
| 223 | WRITE8_MEMBER( studio2_state::dispon_w ) |
| 224 | 224 | { |
| 225 | | cdp1861_dispon_w(device, 1); |
| 226 | | cdp1861_dispon_w(device, 0); |
| 225 | cdp1861_dispon_w(m_vdc, 1); |
| 226 | cdp1861_dispon_w(m_vdc, 0); |
| 227 | 227 | } |
| 228 | 228 | |
| 229 | 229 | /* Memory Maps */ |
| 230 | 230 | |
| 231 | | static ADDRESS_MAP_START( studio2_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 231 | static ADDRESS_MAP_START( studio2_map, ADDRESS_SPACE_PROGRAM, 8, studio2_state ) |
| 232 | 232 | ADDRESS_MAP_UNMAP_HIGH |
| 233 | 233 | AM_RANGE(0x0000, 0x07ff) AM_ROM |
| 234 | 234 | AM_RANGE(0x0800, 0x09ff) AM_MIRROR(0xf400) AM_RAM |
| 235 | 235 | ADDRESS_MAP_END |
| 236 | 236 | |
| 237 | | static ADDRESS_MAP_START( studio2_io_map, ADDRESS_SPACE_IO, 8 ) |
| 237 | static ADDRESS_MAP_START( studio2_io_map, ADDRESS_SPACE_IO, 8, studio2_state ) |
| 238 | 238 | ADDRESS_MAP_UNMAP_HIGH |
| 239 | | AM_RANGE(0x01, 0x01) AM_DEVREAD(CDP1861_TAG, studio2_cdp1861_dispon_r) |
| 239 | AM_RANGE(0x01, 0x01) AM_READ(dispon_r) |
| 240 | 240 | AM_RANGE(0x02, 0x02) AM_WRITE(keylatch_w) |
| 241 | 241 | ADDRESS_MAP_END |
| 242 | 242 | |
| 243 | | static ADDRESS_MAP_START( visicom_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 243 | static ADDRESS_MAP_START( visicom_map, ADDRESS_SPACE_PROGRAM, 8, studio2_state ) |
| 244 | 244 | AM_RANGE(0x0000, 0x07ff) AM_ROM |
| 245 | 245 | AM_RANGE(0x1000, 0x10ff) AM_RAM |
| 246 | | AM_RANGE(0x1100, 0x11ff) AM_RAM AM_BASE_MEMBER(studio2_state, color_ram) |
| 247 | | AM_RANGE(0x1300, 0x13ff) AM_RAM AM_BASE_MEMBER(studio2_state, color_ram1) |
| 246 | AM_RANGE(0x1100, 0x11ff) AM_RAM AM_BASE(m_color_ram) |
| 247 | AM_RANGE(0x1300, 0x13ff) AM_RAM AM_BASE(m_color_ram1) |
| 248 | 248 | ADDRESS_MAP_END |
| 249 | 249 | |
| 250 | | static ADDRESS_MAP_START( visicom_io_map, ADDRESS_SPACE_IO, 8 ) |
| 251 | | AM_RANGE(0x01, 0x01) AM_DEVWRITE(CDP1861_TAG, visicom_cdp1861_dispon_w) |
| 250 | static ADDRESS_MAP_START( visicom_io_map, ADDRESS_SPACE_IO, 8, studio2_state ) |
| 251 | AM_RANGE(0x01, 0x01) AM_WRITE(dispon_w) |
| 252 | 252 | AM_RANGE(0x02, 0x02) AM_WRITE(keylatch_w) |
| 253 | 253 | ADDRESS_MAP_END |
| 254 | 254 | |
| 255 | | static ADDRESS_MAP_START( mpt02_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 255 | static ADDRESS_MAP_START( mpt02_map, ADDRESS_SPACE_PROGRAM, 8, studio2_state ) |
| 256 | 256 | AM_RANGE(0x0000, 0x07ff) AM_ROM |
| 257 | 257 | AM_RANGE(0x0800, 0x09ff) AM_RAM |
| 258 | | AM_RANGE(0x0b00, 0x0b3f) AM_RAM AM_BASE_MEMBER(studio2_state, color_ram) |
| 258 | AM_RANGE(0x0b00, 0x0b3f) AM_RAM AM_BASE(m_color_ram) |
| 259 | 259 | AM_RANGE(0x0c00, 0x0fff) AM_ROM |
| 260 | 260 | ADDRESS_MAP_END |
| 261 | 261 | |
| 262 | | static ADDRESS_MAP_START( mpt02_io_map, ADDRESS_SPACE_IO, 8 ) |
| 263 | | AM_RANGE(0x01, 0x01) AM_DEVREADWRITE(CDP1864_TAG, cdp1864_dispon_r, cdp1864_step_bgcolor_w) |
| 262 | static ADDRESS_MAP_START( mpt02_io_map, ADDRESS_SPACE_IO, 8, studio2_state ) |
| 263 | AM_RANGE(0x01, 0x01) AM_DEVREADWRITE_LEGACY(CDP1864_TAG, cdp1864_dispon_r, cdp1864_step_bgcolor_w) |
| 264 | 264 | AM_RANGE(0x02, 0x02) AM_WRITE(keylatch_w) |
| 265 | | AM_RANGE(0x04, 0x04) AM_DEVREADWRITE(CDP1864_TAG, cdp1864_dispoff_r, cdp1864_tone_latch_w) |
| 265 | AM_RANGE(0x04, 0x04) AM_DEVREADWRITE_LEGACY(CDP1864_TAG, cdp1864_dispoff_r, cdp1864_tone_latch_w) |
| 266 | 266 | ADDRESS_MAP_END |
| 267 | 267 | |
| 268 | 268 | /* Input Ports */ |
| 269 | 269 | |
| 270 | static INPUT_CHANGED( reset_w ) |
| 271 | { |
| 272 | studio2_state *state = field->port->machine->driver_data<studio2_state>(); |
| 273 | |
| 274 | if (oldval && !newval) |
| 275 | { |
| 276 | state->machine_reset(); |
| 277 | } |
| 278 | } |
| 279 | |
| 270 | 280 | static INPUT_PORTS_START( studio2 ) |
| 271 | 281 | PORT_START("A") |
| 272 | 282 | PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("A 0") PORT_CODE(KEYCODE_LALT) |
| r9387 | r9388 | |
| 291 | 301 | PORT_BIT( 0x080, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("B 7") PORT_CODE(KEYCODE_1_PAD) |
| 292 | 302 | PORT_BIT( 0x100, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("B 8") PORT_CODE(KEYCODE_2_PAD) |
| 293 | 303 | PORT_BIT( 0x200, IP_ACTIVE_HIGH, IPT_KEYPAD ) PORT_NAME("B 9") PORT_CODE(KEYCODE_3_PAD) |
| 304 | |
| 305 | PORT_START("CLEAR") |
| 306 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("Clear") PORT_CODE(KEYCODE_F3) PORT_CHAR(UCHAR_MAMEKEY(F3)) PORT_CHANGED(reset_w, 0) |
| 294 | 307 | INPUT_PORTS_END |
| 295 | 308 | |
| 296 | 309 | /* Video */ |
| 297 | 310 | |
| 298 | | static WRITE_LINE_DEVICE_HANDLER( studio2_efx_w ) |
| 299 | | { |
| 300 | | studio2_state *driver_state = device->machine->driver_data<studio2_state>(); |
| 301 | | |
| 302 | | driver_state->cdp1861_efx = state; |
| 303 | | } |
| 304 | | |
| 305 | 311 | static CDP1861_INTERFACE( studio2_cdp1861_intf ) |
| 306 | 312 | { |
| 307 | 313 | CDP1802_TAG, |
| 308 | 314 | SCREEN_TAG, |
| 309 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_INT), |
| 310 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_DMAOUT), |
| 311 | | DEVCB_LINE(studio2_efx_w) |
| 315 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_INT), |
| 316 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_DMAOUT), |
| 317 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_EF1) |
| 312 | 318 | }; |
| 313 | 319 | |
| 314 | 320 | static VIDEO_UPDATE( studio2 ) |
| 315 | 321 | { |
| 316 | 322 | studio2_state *state = screen->machine->driver_data<studio2_state>(); |
| 317 | 323 | |
| 318 | | cdp1861_update(state->cdp1861, bitmap, cliprect); |
| 324 | cdp1861_update(state->m_vdc, bitmap, cliprect); |
| 319 | 325 | |
| 320 | 326 | return 0; |
| 321 | 327 | } |
| r9387 | r9388 | |
| 328 | 334 | palette_set_color_rgb(machine, 3, 0xff, 0x00, 0x00); |
| 329 | 335 | } |
| 330 | 336 | |
| 331 | | static WRITE_LINE_DEVICE_HANDLER( mpt02_efx_w ) |
| 332 | | { |
| 333 | | studio2_state *driver_state = device->machine->driver_data<studio2_state>(); |
| 334 | | |
| 335 | | driver_state->cdp1864_efx = state; |
| 336 | | } |
| 337 | | |
| 338 | 337 | static READ_LINE_DEVICE_HANDLER( rdata_r ) |
| 339 | 338 | { |
| 340 | 339 | studio2_state *state = device->machine->driver_data<studio2_state>(); |
| 341 | 340 | |
| 342 | | return BIT(state->color, 0); |
| 341 | return BIT(state->m_color, 0); |
| 343 | 342 | } |
| 344 | 343 | |
| 345 | 344 | static READ_LINE_DEVICE_HANDLER( bdata_r ) |
| 346 | 345 | { |
| 347 | 346 | studio2_state *state = device->machine->driver_data<studio2_state>(); |
| 348 | 347 | |
| 349 | | return BIT(state->color, 1); |
| 348 | return BIT(state->m_color, 1); |
| 350 | 349 | } |
| 351 | 350 | |
| 352 | 351 | static READ_LINE_DEVICE_HANDLER( gdata_r ) |
| 353 | 352 | { |
| 354 | 353 | studio2_state *state = device->machine->driver_data<studio2_state>(); |
| 355 | 354 | |
| 356 | | return BIT(state->color, 2); |
| 355 | return BIT(state->m_color, 2); |
| 357 | 356 | } |
| 358 | 357 | |
| 359 | 358 | static CDP1864_INTERFACE( mpt02_cdp1864_intf ) |
| r9387 | r9388 | |
| 364 | 363 | DEVCB_LINE(rdata_r), |
| 365 | 364 | DEVCB_LINE(bdata_r), |
| 366 | 365 | DEVCB_LINE(gdata_r), |
| 367 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_INT), |
| 368 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_DMAOUT), |
| 369 | | DEVCB_LINE(mpt02_efx_w), |
| 366 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_INT), |
| 367 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_DMAOUT), |
| 368 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_EF1), |
| 370 | 369 | RES_K(2.2), // unverified |
| 371 | 370 | RES_K(1), // unverified |
| 372 | 371 | RES_K(5.1), // unverified |
| r9387 | r9388 | |
| 377 | 376 | { |
| 378 | 377 | studio2_state *state = screen->machine->driver_data<studio2_state>(); |
| 379 | 378 | |
| 380 | | cdp1864_update(state->cdp1864, bitmap, cliprect); |
| 379 | cdp1864_update(state->m_cti, bitmap, cliprect); |
| 381 | 380 | |
| 382 | 381 | return 0; |
| 383 | 382 | } |
| 384 | 383 | |
| 385 | 384 | /* CDP1802 Configuration */ |
| 386 | 385 | |
| 387 | | static CDP1802_MODE_READ( studio2_mode_r ) |
| 386 | static READ_LINE_DEVICE_HANDLER( clear_r ) |
| 388 | 387 | { |
| 388 | return BIT(input_port_read(device->machine, "CLEAR"), 0); |
| 389 | } |
| 390 | |
| 391 | static READ_LINE_DEVICE_HANDLER( ef3_r ) |
| 392 | { |
| 389 | 393 | studio2_state *state = device->machine->driver_data<studio2_state>(); |
| 390 | 394 | |
| 391 | | return state->cdp1802_mode; |
| 395 | return BIT(input_port_read(device->machine, "A"), state->m_keylatch); |
| 392 | 396 | } |
| 393 | 397 | |
| 394 | | static CDP1802_EF_READ( studio2_ef_r ) |
| 398 | static READ_LINE_DEVICE_HANDLER( ef4_r ) |
| 395 | 399 | { |
| 396 | 400 | studio2_state *state = device->machine->driver_data<studio2_state>(); |
| 397 | 401 | |
| 398 | | int ef = 0x0f; |
| 399 | | |
| 400 | | if (state->cdp1861_efx) ef -= EF1; |
| 401 | | |
| 402 | | if (input_port_read(device->machine, "A") & (1 << state->keylatch)) ef -= EF3; |
| 403 | | if (input_port_read(device->machine, "B") & (1 << state->keylatch)) ef -= EF4; |
| 404 | | |
| 405 | | return ef; |
| 402 | return BIT(input_port_read(device->machine, "B"), state->m_keylatch); |
| 406 | 403 | } |
| 407 | 404 | |
| 408 | 405 | static WRITE_LINE_DEVICE_HANDLER( studio2_q_w ) |
| r9387 | r9388 | |
| 411 | 408 | beep_set_state(speaker, state); |
| 412 | 409 | } |
| 413 | 410 | |
| 414 | | static CDP1802_INTERFACE( studio2_config ) |
| 411 | static COSMAC_INTERFACE( studio2_cosmac_intf ) |
| 415 | 412 | { |
| 416 | | studio2_mode_r, |
| 417 | | studio2_ef_r, |
| 418 | | NULL, |
| 413 | DEVCB_LINE_VCC, |
| 414 | DEVCB_LINE(clear_r), |
| 415 | DEVCB_NULL, |
| 416 | DEVCB_NULL, |
| 417 | DEVCB_LINE(ef3_r), |
| 418 | DEVCB_LINE(ef4_r), |
| 419 | 419 | DEVCB_LINE(studio2_q_w), |
| 420 | 420 | DEVCB_NULL, |
| 421 | | DEVCB_DEVICE_HANDLER(CDP1861_TAG, cdp1861_dma_w) |
| 421 | DEVCB_DEVICE_HANDLER(CDP1861_TAG, cdp1861_dma_w), |
| 422 | NULL, |
| 423 | DEVCB_NULL, |
| 424 | DEVCB_NULL |
| 422 | 425 | }; |
| 423 | 426 | |
| 424 | | static CDP1802_EF_READ( mpt02_ef_r ) |
| 425 | | { |
| 426 | | studio2_state *state = device->machine->driver_data<studio2_state>(); |
| 427 | | |
| 428 | | int ef = 0x0f; |
| 429 | | |
| 430 | | if (state->cdp1864_efx) ef -= EF1; |
| 431 | | |
| 432 | | if (input_port_read(device->machine, "A") & (1 << state->keylatch)) ef -= EF3; |
| 433 | | if (input_port_read(device->machine, "B") & (1 << state->keylatch)) ef -= EF4; |
| 434 | | |
| 435 | | return ef; |
| 436 | | } |
| 437 | | |
| 438 | 427 | static WRITE8_DEVICE_HANDLER( mpt02_dma_w ) |
| 439 | 428 | { |
| 440 | 429 | studio2_state *state = device->machine->driver_data<studio2_state>(); |
| 441 | 430 | UINT8 addr = ((offset & 0xe0) >> 2) | (offset & 0x07); |
| 442 | 431 | |
| 443 | | state->color = state->color_ram[addr]; |
| 432 | state->m_color = state->m_color_ram[addr]; |
| 444 | 433 | |
| 445 | | cdp1864_con_w(state->cdp1864, 0); // HACK |
| 446 | | cdp1864_dma_w(state->cdp1864, offset, data); |
| 434 | cdp1864_con_w(state->m_cti, 0); // HACK |
| 435 | cdp1864_dma_w(state->m_cti, offset, data); |
| 447 | 436 | } |
| 448 | 437 | |
| 449 | | static CDP1802_INTERFACE( mpt02_config ) |
| 438 | static COSMAC_INTERFACE( mpt02_cosmac_intf ) |
| 450 | 439 | { |
| 451 | | studio2_mode_r, |
| 452 | | mpt02_ef_r, |
| 453 | | NULL, |
| 440 | DEVCB_LINE_VCC, |
| 441 | DEVCB_LINE(clear_r), |
| 442 | DEVCB_NULL, |
| 443 | DEVCB_NULL, |
| 444 | DEVCB_LINE(ef3_r), |
| 445 | DEVCB_LINE(ef4_r), |
| 454 | 446 | DEVCB_LINE(studio2_q_w), |
| 455 | 447 | DEVCB_NULL, |
| 456 | | DEVCB_HANDLER(mpt02_dma_w) |
| 448 | DEVCB_DEVICE_HANDLER(CDP1864_TAG, mpt02_dma_w), |
| 449 | NULL, |
| 450 | DEVCB_NULL, |
| 451 | DEVCB_NULL |
| 457 | 452 | }; |
| 458 | 453 | |
| 459 | 454 | /* Machine Initialization */ |
| 460 | 455 | |
| 461 | | static TIMER_CALLBACK( set_cpu_mode ) |
| 456 | void studio2_state::machine_start() |
| 462 | 457 | { |
| 463 | | studio2_state *state = machine->driver_data<studio2_state>(); |
| 464 | | |
| 465 | | state->cdp1802_mode = CDP1802_MODE_RUN; |
| 458 | // register for state saving |
| 459 | state_save_register_global(machine, m_keylatch); |
| 466 | 460 | } |
| 467 | 461 | |
| 468 | | static MACHINE_START( studio2 ) |
| 462 | void studio2_state::machine_reset() |
| 469 | 463 | { |
| 470 | | studio2_state *state = machine->driver_data<studio2_state>(); |
| 471 | | |
| 472 | | /* find devices */ |
| 473 | | state->cdp1861 = machine->device(CDP1861_TAG); |
| 474 | | |
| 475 | | /* register for state saving */ |
| 476 | | state_save_register_global(machine, state->cdp1802_mode); |
| 477 | | state_save_register_global(machine, state->keylatch); |
| 478 | | state_save_register_global(machine, state->cdp1861_efx); |
| 464 | if (m_vdc) m_vdc->reset(); |
| 465 | if (m_cti) m_cti->reset(); |
| 479 | 466 | } |
| 480 | 467 | |
| 481 | | static MACHINE_RESET( studio2 ) |
| 482 | | { |
| 483 | | studio2_state *state = machine->driver_data<studio2_state>(); |
| 484 | | |
| 485 | | /* reset CPU */ |
| 486 | | state->cdp1802_mode = CDP1802_MODE_RESET; |
| 487 | | timer_set(machine, ATTOTIME_IN_MSEC(200), NULL, 0, set_cpu_mode); |
| 488 | | |
| 489 | | /* reset CDP1861 */ |
| 490 | | state->cdp1861->reset(); |
| 491 | | } |
| 492 | | |
| 493 | | static MACHINE_START( mpt02 ) |
| 494 | | { |
| 495 | | studio2_state *state = machine->driver_data<studio2_state>(); |
| 496 | | |
| 497 | | /* find devices */ |
| 498 | | state->cdp1864 = machine->device(CDP1864_TAG); |
| 499 | | |
| 500 | | /* register for state saving */ |
| 501 | | state_save_register_global(machine, state->cdp1802_mode); |
| 502 | | state_save_register_global(machine, state->keylatch); |
| 503 | | state_save_register_global(machine, state->cdp1864_efx); |
| 504 | | } |
| 505 | | |
| 506 | | static MACHINE_RESET( mpt02 ) |
| 507 | | { |
| 508 | | studio2_state *state = machine->driver_data<studio2_state>(); |
| 509 | | |
| 510 | | /* reset CPU */ |
| 511 | | state->cdp1802_mode = CDP1802_MODE_RESET; |
| 512 | | timer_set(machine, ATTOTIME_IN_MSEC(200), NULL, 0, set_cpu_mode); |
| 513 | | |
| 514 | | /* reset CDP1864 */ |
| 515 | | state->cdp1864->reset(); |
| 516 | | } |
| 517 | | |
| 518 | 468 | /* Machine Drivers */ |
| 519 | 469 | |
| 520 | 470 | static MACHINE_CONFIG_FRAGMENT( studio2_cartslot ) |
| r9387 | r9388 | |
| 525 | 475 | MACHINE_CONFIG_END |
| 526 | 476 | |
| 527 | 477 | static MACHINE_CONFIG_START( studio2, studio2_state ) |
| 528 | | |
| 529 | 478 | /* basic machine hardware */ |
| 530 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, 1760000) /* the real clock is derived from an oscillator circuit */ |
| 479 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, 1760000) /* the real clock is derived from an oscillator circuit */ |
| 531 | 480 | MDRV_CPU_PROGRAM_MAP(studio2_map) |
| 532 | 481 | MDRV_CPU_IO_MAP(studio2_io_map) |
| 533 | | MDRV_CPU_CONFIG(studio2_config) |
| 482 | MDRV_CPU_CONFIG(studio2_cosmac_intf) |
| 534 | 483 | |
| 535 | | MDRV_MACHINE_START(studio2) |
| 536 | | MDRV_MACHINE_RESET(studio2) |
| 537 | | |
| 538 | 484 | /* video hardware */ |
| 539 | 485 | MDRV_CDP1861_SCREEN_ADD(SCREEN_TAG, 1760000) |
| 540 | 486 | |
| r9387 | r9388 | |
| 553 | 499 | MACHINE_CONFIG_END |
| 554 | 500 | |
| 555 | 501 | static MACHINE_CONFIG_START( visicom, studio2_state ) |
| 556 | | |
| 557 | 502 | /* basic machine hardware */ |
| 558 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_3_579545MHz/2) |
| 503 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, XTAL_3_579545MHz/2) |
| 559 | 504 | MDRV_CPU_PROGRAM_MAP(visicom_map) |
| 560 | 505 | MDRV_CPU_IO_MAP(visicom_io_map) |
| 561 | | MDRV_CPU_CONFIG(studio2_config) |
| 506 | MDRV_CPU_CONFIG(studio2_cosmac_intf) |
| 562 | 507 | |
| 563 | | MDRV_MACHINE_START(studio2) |
| 564 | | MDRV_MACHINE_RESET(studio2) |
| 565 | | |
| 566 | 508 | /* video hardware */ |
| 567 | 509 | MDRV_CDP1861_SCREEN_ADD(SCREEN_TAG, XTAL_3_579545MHz/2) |
| 568 | 510 | |
| r9387 | r9388 | |
| 581 | 523 | MACHINE_CONFIG_END |
| 582 | 524 | |
| 583 | 525 | static MACHINE_CONFIG_START( mpt02, studio2_state ) |
| 584 | | |
| 585 | 526 | /* basic machine hardware */ |
| 586 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, CDP1864_CLOCK) |
| 527 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, CDP1864_CLOCK) |
| 587 | 528 | MDRV_CPU_PROGRAM_MAP(mpt02_map) |
| 588 | 529 | MDRV_CPU_IO_MAP(mpt02_io_map) |
| 589 | | MDRV_CPU_CONFIG(mpt02_config) |
| 530 | MDRV_CPU_CONFIG(mpt02_cosmac_intf) |
| 590 | 531 | |
| 591 | | MDRV_MACHINE_START(mpt02) |
| 592 | | MDRV_MACHINE_RESET(mpt02) |
| 593 | | |
| 594 | 532 | /* video hardware */ |
| 595 | 533 | MDRV_CDP1864_SCREEN_ADD(SCREEN_TAG, CDP1864_CLOCK) |
| 596 | 534 | |
src/mess/drivers/tmc1800.c
| r9387 | r9388 | |
| 107 | 107 | - tape input/output |
| 108 | 108 | - tmc2000: add missing keys |
| 109 | 109 | - tmc2000: TOOL-2000 rom banking |
| 110 | | - oscnano: correct time constant for EF4 RC circuit |
| 110 | - nano: correct time constant for EF4 RC circuit |
| 111 | 111 | |
| 112 | 112 | */ |
| 113 | 113 | |
| 114 | 114 | #include "emu.h" |
| 115 | 115 | #include "includes/tmc1800.h" |
| 116 | | #include "cpu/cdp1802/cdp1802.h" |
| 116 | #include "cpu/cosmac/cosmac.h" |
| 117 | 117 | #include "video/cdp1861.h" |
| 118 | 118 | #include "sound/cdp1864.h" |
| 119 | 119 | #include "devices/cassette.h" |
| r9387 | r9388 | |
| 135 | 135 | |
| 136 | 136 | static MACHINE_RESET( tmc1800 ); |
| 137 | 137 | static MACHINE_RESET( tmc2000 ); |
| 138 | | static MACHINE_RESET( oscnano ); |
| 138 | static MACHINE_RESET( nano ); |
| 139 | 139 | |
| 140 | 140 | /* Read/Write Handlers */ |
| 141 | 141 | |
| r9387 | r9388 | |
| 168 | 168 | state->keylatch = data & 0x3f; |
| 169 | 169 | } |
| 170 | 170 | |
| 171 | | static WRITE8_HANDLER( oscnano_keylatch_w ) |
| 171 | static WRITE8_HANDLER( nano_keylatch_w ) |
| 172 | 172 | { |
| 173 | 173 | /* |
| 174 | 174 | |
| r9387 | r9388 | |
| 185 | 185 | |
| 186 | 186 | */ |
| 187 | 187 | |
| 188 | | oscnano_state *state = space->machine->driver_data<oscnano_state>(); |
| 188 | nano_state *state = space->machine->driver_data<nano_state>(); |
| 189 | 189 | |
| 190 | 190 | state->keylatch = data & 0x0f; |
| 191 | 191 | } |
| r9387 | r9388 | |
| 235 | 235 | cdp1864_tone_latch_w(device, 0, data); |
| 236 | 236 | } |
| 237 | 237 | |
| 238 | | static WRITE8_DEVICE_HANDLER( oscnano_bankswitch_w ) |
| 238 | static WRITE8_DEVICE_HANDLER( nano_bankswitch_w ) |
| 239 | 239 | { |
| 240 | 240 | /* enable RAM */ |
| 241 | 241 | |
| r9387 | r9388 | |
| 304 | 304 | |
| 305 | 305 | // OSCOM Nano |
| 306 | 306 | |
| 307 | | static ADDRESS_MAP_START( oscnano_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 307 | static ADDRESS_MAP_START( nano_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 308 | 308 | AM_RANGE(0x0000, 0x7fff) AM_RAMBANK("bank1") |
| 309 | 309 | AM_RANGE(0x8000, 0x83ff) AM_ROM |
| 310 | 310 | ADDRESS_MAP_END |
| 311 | 311 | |
| 312 | | static ADDRESS_MAP_START( oscnano_io_map, ADDRESS_SPACE_IO, 8 ) |
| 312 | static ADDRESS_MAP_START( nano_io_map, ADDRESS_SPACE_IO, 8 ) |
| 313 | 313 | AM_RANGE(0x01, 0x01) AM_DEVREADWRITE(CDP1864_TAG, cdp1864_dispon_r, cdp1864_step_bgcolor_w) |
| 314 | | AM_RANGE(0x02, 0x02) AM_WRITE(oscnano_keylatch_w) |
| 315 | | AM_RANGE(0x04, 0x04) AM_DEVREADWRITE(CDP1864_TAG, cdp1864_dispoff_r, oscnano_bankswitch_w) |
| 314 | AM_RANGE(0x02, 0x02) AM_WRITE(nano_keylatch_w) |
| 315 | AM_RANGE(0x04, 0x04) AM_DEVREADWRITE(CDP1864_TAG, cdp1864_dispoff_r, nano_bankswitch_w) |
| 316 | 316 | ADDRESS_MAP_END |
| 317 | 317 | |
| 318 | 318 | /* Input Ports */ |
| r9387 | r9388 | |
| 406 | 406 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) |
| 407 | 407 | INPUT_PORTS_END |
| 408 | 408 | |
| 409 | | static INPUT_PORTS_START( oscnano ) |
| 409 | static INPUT_CHANGED( run_pressed ) |
| 410 | { |
| 411 | if (oldval && !newval) |
| 412 | { |
| 413 | running_machine *machine = field->port->machine; |
| 414 | MACHINE_RESET_CALL(nano); |
| 415 | } |
| 416 | } |
| 417 | |
| 418 | static INPUT_CHANGED( monitor_pressed ) |
| 419 | { |
| 420 | running_machine *machine = field->port->machine; |
| 421 | nano_state *state = machine->driver_data<nano_state>(); |
| 422 | |
| 423 | if (oldval && !newval) |
| 424 | { |
| 425 | MACHINE_RESET_CALL(nano); |
| 426 | |
| 427 | cputag_set_input_line(machine, CDP1802_TAG, COSMAC_INPUT_LINE_EF4, CLEAR_LINE); |
| 428 | } |
| 429 | else if (!oldval && newval) |
| 430 | { |
| 431 | // TODO: what are the correct values? |
| 432 | int t = RES_K(27) * CAP_U(1) * 1000; // t = R26 * C1 |
| 433 | timer_adjust_oneshot(state->ef4_timer, ATTOTIME_IN_MSEC(t), 0); |
| 434 | } |
| 435 | } |
| 436 | |
| 437 | static INPUT_PORTS_START( nano ) |
| 410 | 438 | PORT_START("IN0") |
| 411 | 439 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_0) PORT_CODE(KEYCODE_0_PAD) PORT_CHAR('0') |
| 412 | 440 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_1) PORT_CODE(KEYCODE_1_PAD) PORT_CHAR('1') |
| r9387 | r9388 | |
| 428 | 456 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') |
| 429 | 457 | |
| 430 | 458 | PORT_START("RUN") |
| 431 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RUN") PORT_CODE(KEYCODE_R) |
| 459 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("RUN") PORT_CODE(KEYCODE_R) PORT_CHANGED(run_pressed, 0) |
| 432 | 460 | |
| 433 | 461 | PORT_START("MONITOR") |
| 434 | | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("MONITOR") PORT_CODE(KEYCODE_M) |
| 462 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYPAD ) PORT_NAME("MONITOR") PORT_CODE(KEYCODE_M) PORT_CHANGED(monitor_pressed, 0) |
| 435 | 463 | INPUT_PORTS_END |
| 436 | 464 | |
| 437 | 465 | /* CDP1802 Interfaces */ |
| 438 | 466 | |
| 439 | 467 | // Telmac 1800 |
| 440 | 468 | |
| 441 | | static CDP1802_MODE_READ( tmc1800_mode_r ) |
| 469 | static READ_LINE_DEVICE_HANDLER( clear_r ) |
| 442 | 470 | { |
| 443 | | tmc1800_state *state = device->machine->driver_data<tmc1800_state>(); |
| 471 | return BIT(input_port_read(device->machine, "RUN"), 0); |
| 472 | } |
| 444 | 473 | |
| 445 | | if (input_port_read(device->machine, "RUN") & 0x01) |
| 446 | | { |
| 447 | | if (state->reset) |
| 448 | | { |
| 449 | | running_machine *machine = device->machine; |
| 450 | | MACHINE_RESET_CALL(tmc2000); |
| 451 | | |
| 452 | | state->reset = 0; |
| 453 | | } |
| 454 | | |
| 455 | | return CDP1802_MODE_RUN; |
| 456 | | } |
| 457 | | else |
| 458 | | { |
| 459 | | state->reset = 1; |
| 460 | | |
| 461 | | return CDP1802_MODE_RESET; |
| 462 | | } |
| 474 | static READ_LINE_DEVICE_HANDLER( ef2_r ) |
| 475 | { |
| 476 | return cassette_input(device) < 0; |
| 463 | 477 | } |
| 464 | 478 | |
| 465 | | static CDP1802_EF_READ( tmc1800_ef_r ) |
| 479 | static READ_LINE_DEVICE_HANDLER( ef3_r ) |
| 466 | 480 | { |
| 467 | 481 | tmc1800_state *state = device->machine->driver_data<tmc1800_state>(); |
| 468 | | |
| 469 | | UINT8 flags = 0x0f; |
| 470 | 482 | static const char *const keynames[] = { "IN0", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6", "IN7" }; |
| 483 | UINT8 data = ~input_port_read(device->machine, keynames[state->keylatch / 8]); |
| 471 | 484 | |
| 472 | | /* |
| 473 | | EF1 CDP1861 |
| 474 | | EF2 tape in |
| 475 | | EF3 keyboard |
| 476 | | EF4 ? |
| 477 | | */ |
| 478 | | |
| 479 | | /* CDP1861 */ |
| 480 | | if (state->cdp1861_efx) flags -= EF1; |
| 481 | | |
| 482 | | /* tape input */ |
| 483 | | if (cassette_input(state->cassette) < 0) flags -= EF2; |
| 484 | | |
| 485 | | /* keyboard */ |
| 486 | | if (~input_port_read(device->machine, keynames[state->keylatch / 8]) & (1 << (state->keylatch % 8))) flags -= EF3; |
| 487 | | |
| 488 | | return flags; |
| 485 | return BIT(data, state->keylatch % 8); |
| 489 | 486 | } |
| 490 | 487 | |
| 491 | 488 | static WRITE_LINE_DEVICE_HANDLER( tmc1800_q_w ) |
| r9387 | r9388 | |
| 496 | 493 | cassette_output(driver_state->cassette, state ? 1.0 : -1.0); |
| 497 | 494 | } |
| 498 | 495 | |
| 499 | | static CDP1802_INTERFACE( tmc1800_config ) |
| 496 | static COSMAC_INTERFACE( tmc1800_config ) |
| 500 | 497 | { |
| 501 | | tmc1800_mode_r, |
| 502 | | tmc1800_ef_r, |
| 503 | | NULL, |
| 498 | DEVCB_LINE_VCC, |
| 499 | DEVCB_LINE(clear_r), |
| 500 | DEVCB_NULL, |
| 501 | DEVCB_DEVICE_LINE(CASSETTE_TAG, ef2_r), |
| 502 | DEVCB_LINE(ef3_r), |
| 503 | DEVCB_NULL, |
| 504 | 504 | DEVCB_LINE(tmc1800_q_w), |
| 505 | 505 | DEVCB_NULL, |
| 506 | | DEVCB_DEVICE_HANDLER(CDP1861_TAG, cdp1861_dma_w) |
| 506 | DEVCB_DEVICE_HANDLER(CDP1861_TAG, cdp1861_dma_w), |
| 507 | NULL, |
| 508 | DEVCB_NULL, |
| 509 | DEVCB_NULL |
| 507 | 510 | }; |
| 508 | 511 | |
| 509 | | static CDP1802_INTERFACE( osc1000b_config ) |
| 512 | static COSMAC_INTERFACE( osc1000b_config ) |
| 510 | 513 | { |
| 511 | | tmc1800_mode_r, |
| 512 | | tmc1800_ef_r, |
| 513 | | NULL, |
| 514 | DEVCB_LINE_VCC, |
| 515 | DEVCB_LINE(clear_r), |
| 516 | DEVCB_NULL, |
| 517 | DEVCB_DEVICE_LINE(CASSETTE_TAG, ef2_r), |
| 518 | DEVCB_LINE(ef3_r), |
| 519 | DEVCB_NULL, |
| 514 | 520 | DEVCB_LINE(tmc1800_q_w), |
| 515 | 521 | DEVCB_NULL, |
| 522 | DEVCB_NULL, |
| 523 | NULL, |
| 524 | DEVCB_NULL, |
| 516 | 525 | DEVCB_NULL |
| 517 | 526 | }; |
| 518 | 527 | |
| 519 | 528 | // Telmac 2000 |
| 520 | 529 | |
| 521 | | static CDP1802_MODE_READ( tmc2000_mode_r ) |
| 522 | | { |
| 523 | | tmc2000_state *state = device->machine->driver_data<tmc2000_state>(); |
| 524 | | |
| 525 | | if (input_port_read(device->machine, "RUN") & 0x01) |
| 526 | | { |
| 527 | | if (state->reset) |
| 528 | | { |
| 529 | | running_machine *machine = device->machine; |
| 530 | | MACHINE_RESET_CALL(tmc2000); |
| 531 | | |
| 532 | | state->reset = 0; |
| 533 | | } |
| 534 | | |
| 535 | | return CDP1802_MODE_RUN; |
| 536 | | } |
| 537 | | else |
| 538 | | { |
| 539 | | state->reset = 1; |
| 540 | | |
| 541 | | return CDP1802_MODE_RESET; |
| 542 | | } |
| 543 | | } |
| 544 | | |
| 545 | | static CDP1802_EF_READ( tmc2000_ef_r ) |
| 546 | | { |
| 547 | | tmc2000_state *state = device->machine->driver_data<tmc2000_state>(); |
| 548 | | |
| 549 | | int flags = 0x0f; |
| 550 | | static const char *const keynames[] = { "IN0", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6", "IN7" }; |
| 551 | | |
| 552 | | /* |
| 553 | | EF1 CDP1864 |
| 554 | | EF2 tape in |
| 555 | | EF3 keyboard |
| 556 | | EF4 ? |
| 557 | | */ |
| 558 | | |
| 559 | | /* CDP1864 */ |
| 560 | | if (state->cdp1864_efx) flags -= EF1; |
| 561 | | |
| 562 | | /* tape input */ |
| 563 | | if (cassette_input(state->cassette) < 0) flags -= EF2; |
| 564 | | |
| 565 | | /* keyboard */ |
| 566 | | if (~input_port_read(device->machine, keynames[state->keylatch / 8]) & (1 << (state->keylatch % 8))) flags -= EF3; |
| 567 | | |
| 568 | | return flags; |
| 569 | | } |
| 570 | | |
| 571 | 530 | static WRITE_LINE_DEVICE_HANDLER( tmc2000_q_w ) |
| 572 | 531 | { |
| 573 | 532 | tmc2000_state *driver_state = device->machine->driver_data<tmc2000_state>(); |
| r9387 | r9388 | |
| 592 | 551 | cdp1864_dma_w(state->cdp1864, offset, data); |
| 593 | 552 | } |
| 594 | 553 | |
| 595 | | static CDP1802_INTERFACE( tmc2000_config ) |
| 554 | static COSMAC_INTERFACE( tmc2000_config ) |
| 596 | 555 | { |
| 597 | | tmc2000_mode_r, |
| 598 | | tmc2000_ef_r, |
| 599 | | NULL, |
| 556 | DEVCB_LINE_VCC, |
| 557 | DEVCB_LINE(clear_r), |
| 558 | DEVCB_NULL, |
| 559 | DEVCB_DEVICE_LINE(CASSETTE_TAG, ef2_r), |
| 560 | DEVCB_LINE(ef3_r), |
| 561 | DEVCB_NULL, |
| 600 | 562 | DEVCB_LINE(tmc2000_q_w), |
| 601 | 563 | DEVCB_NULL, |
| 602 | | DEVCB_HANDLER(tmc2000_dma_w) |
| 564 | DEVCB_HANDLER(tmc2000_dma_w), |
| 565 | NULL, |
| 566 | DEVCB_NULL, |
| 567 | DEVCB_NULL |
| 603 | 568 | }; |
| 604 | 569 | |
| 605 | 570 | // OSCOM Nano |
| 606 | 571 | |
| 607 | | static TIMER_CALLBACK( oscnano_ef4_tick ) |
| 572 | static TIMER_CALLBACK( nano_ef4_tick ) |
| 608 | 573 | { |
| 609 | | oscnano_state *state = machine->driver_data<oscnano_state>(); |
| 610 | | |
| 611 | | /* assert EF4 */ |
| 612 | | state->monitor_ef4 = 1; |
| 574 | cputag_set_input_line(machine, CDP1802_TAG, COSMAC_INPUT_LINE_EF4, ASSERT_LINE); |
| 613 | 575 | } |
| 614 | 576 | |
| 615 | | static CDP1802_MODE_READ( oscnano_mode_r ) |
| 577 | static READ_LINE_DEVICE_HANDLER( nano_clear_r ) |
| 616 | 578 | { |
| 617 | | oscnano_state *state = device->machine->driver_data<oscnano_state>(); |
| 579 | int run = BIT(input_port_read(device->machine, "RUN"), 0); |
| 580 | int monitor = BIT(input_port_read(device->machine, "MONITOR"), 0); |
| 618 | 581 | |
| 619 | | int run = input_port_read(device->machine, "RUN") & 0x01; |
| 620 | | int monitor = input_port_read(device->machine, "MONITOR") & 0x01; |
| 621 | | |
| 622 | | if (run && monitor) |
| 623 | | { |
| 624 | | if (state->reset) |
| 625 | | { |
| 626 | | running_machine *machine = device->machine; |
| 627 | | MACHINE_RESET_CALL(oscnano); |
| 628 | | |
| 629 | | state->reset = 0; |
| 630 | | } |
| 631 | | |
| 632 | | return CDP1802_MODE_RUN; |
| 633 | | } |
| 634 | | else |
| 635 | | { |
| 636 | | state->reset = 1; |
| 637 | | |
| 638 | | if (!monitor) |
| 639 | | { |
| 640 | | // TODO: what are the correct values? |
| 641 | | int t = RES_K(27) * CAP_U(1) * 1000; // t = R26 * C1 |
| 642 | | |
| 643 | | /* clear EF4 */ |
| 644 | | state->monitor_ef4 = 0; |
| 645 | | |
| 646 | | /* set EF4 timer */ |
| 647 | | timer_adjust_oneshot(state->ef4_timer, ATTOTIME_IN_MSEC(t), 0); |
| 648 | | } |
| 649 | | |
| 650 | | return CDP1802_MODE_RESET; |
| 651 | | } |
| 582 | return run & monitor; |
| 652 | 583 | } |
| 653 | 584 | |
| 654 | | static CDP1802_EF_READ( oscnano_ef_r ) |
| 585 | static READ_LINE_DEVICE_HANDLER( nano_ef2_r ) |
| 655 | 586 | { |
| 656 | | oscnano_state *state = device->machine->driver_data<oscnano_state>(); |
| 587 | return cassette_input(device) < 0; |
| 588 | } |
| 657 | 589 | |
| 590 | static READ_LINE_DEVICE_HANDLER( nano_ef3_r ) |
| 591 | { |
| 592 | nano_state *state = device->machine->driver_data<nano_state>(); |
| 658 | 593 | static const char *const keynames[] = { "IN0", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6", "IN7" }; |
| 594 | UINT8 data = ~input_port_read(device->machine, keynames[state->keylatch / 8]); |
| 659 | 595 | |
| 660 | | int flags = 0x0f; |
| 661 | | |
| 662 | | /* |
| 663 | | EF1 CDP1864 |
| 664 | | EF2 tape in |
| 665 | | EF3 keyboard |
| 666 | | EF4 monitor |
| 667 | | */ |
| 668 | | |
| 669 | | /* CDP1864 */ |
| 670 | | if (state->cdp1864_efx) flags -= EF1; |
| 671 | | |
| 672 | | /* tape input */ |
| 673 | | if (cassette_input(state->cassette) < 0) flags -= EF2; |
| 674 | | |
| 675 | | /* keyboard */ |
| 676 | | if (~input_port_read(device->machine, keynames[state->keylatch / 8]) & (1 << (state->keylatch % 8))) flags -= EF3; |
| 677 | | |
| 678 | | /* monitor */ |
| 679 | | if (state->monitor_ef4) flags -= EF4; |
| 680 | | |
| 681 | | return flags; |
| 596 | return BIT(data, state->keylatch % 8); |
| 682 | 597 | } |
| 683 | 598 | |
| 684 | | static WRITE_LINE_DEVICE_HANDLER( oscnano_q_w ) |
| 599 | static WRITE_LINE_DEVICE_HANDLER( nano_q_w ) |
| 685 | 600 | { |
| 686 | | oscnano_state *driver_state = device->machine->driver_data<oscnano_state>(); |
| 601 | nano_state *driver_state = device->machine->driver_data<nano_state>(); |
| 687 | 602 | |
| 688 | 603 | /* CDP1864 audio output enable */ |
| 689 | 604 | cdp1864_aoe_w(driver_state->cdp1864, state); |
| r9387 | r9388 | |
| 695 | 610 | cassette_output(driver_state->cassette, state ? 1.0 : -1.0); |
| 696 | 611 | } |
| 697 | 612 | |
| 698 | | static CDP1802_INTERFACE( oscnano_config ) |
| 613 | static COSMAC_INTERFACE( nano_config ) |
| 699 | 614 | { |
| 700 | | oscnano_mode_r, |
| 701 | | oscnano_ef_r, |
| 615 | DEVCB_LINE_VCC, |
| 616 | DEVCB_LINE(nano_clear_r), |
| 617 | DEVCB_NULL, |
| 618 | DEVCB_DEVICE_LINE(CASSETTE_TAG, nano_ef2_r), |
| 619 | DEVCB_LINE(nano_ef3_r), |
| 620 | DEVCB_NULL, |
| 621 | DEVCB_LINE(nano_q_w), |
| 622 | DEVCB_NULL, |
| 623 | DEVCB_DEVICE_HANDLER(CDP1864_TAG, cdp1864_dma_w), |
| 702 | 624 | NULL, |
| 703 | | DEVCB_LINE(oscnano_q_w), |
| 704 | 625 | DEVCB_NULL, |
| 705 | | DEVCB_DEVICE_HANDLER(CDP1864_TAG, cdp1864_dma_w) |
| 626 | DEVCB_NULL |
| 706 | 627 | }; |
| 707 | 628 | |
| 708 | 629 | /* Machine Initialization */ |
| r9387 | r9388 | |
| 718 | 639 | state->cassette = machine->device(CASSETTE_TAG); |
| 719 | 640 | |
| 720 | 641 | /* register for state saving */ |
| 721 | | state_save_register_global(machine, state->cdp1861_efx); |
| 722 | 642 | state_save_register_global(machine, state->keylatch); |
| 723 | | state_save_register_global(machine, state->reset); |
| 724 | 643 | } |
| 725 | 644 | |
| 726 | 645 | static MACHINE_RESET( tmc1800 ) |
| r9387 | r9388 | |
| 742 | 661 | |
| 743 | 662 | /* register for state saving */ |
| 744 | 663 | state_save_register_global(machine, state->keylatch); |
| 745 | | state_save_register_global(machine, state->reset); |
| 746 | 664 | } |
| 747 | 665 | |
| 748 | 666 | static MACHINE_RESET( osc1000b ) |
| r9387 | r9388 | |
| 778 | 696 | |
| 779 | 697 | /* register for state saving */ |
| 780 | 698 | state_save_register_global_pointer(machine, state->colorram, TMC2000_COLORRAM_SIZE); |
| 781 | | state_save_register_global(machine, state->cdp1864_efx); |
| 782 | 699 | state_save_register_global(machine, state->keylatch); |
| 783 | | state_save_register_global(machine, state->reset); |
| 784 | 700 | } |
| 785 | 701 | |
| 786 | 702 | static MACHINE_RESET( tmc2000 ) |
| r9387 | r9388 | |
| 803 | 719 | |
| 804 | 720 | // OSCOM Nano |
| 805 | 721 | |
| 806 | | static MACHINE_START( oscnano ) |
| 722 | static MACHINE_START( nano ) |
| 807 | 723 | { |
| 808 | | oscnano_state *state = machine->driver_data<oscnano_state>(); |
| 724 | nano_state *state = machine->driver_data<nano_state>(); |
| 809 | 725 | |
| 810 | 726 | /* RAM/ROM banking */ |
| 811 | 727 | memory_configure_bank(machine, "bank1", 0, 2, memory_region(machine, CDP1802_TAG), 0x8000); |
| 812 | 728 | |
| 813 | 729 | /* allocate monitor timer */ |
| 814 | | state->ef4_timer = timer_alloc(machine, oscnano_ef4_tick, NULL); |
| 730 | state->ef4_timer = timer_alloc(machine, nano_ef4_tick, NULL); |
| 815 | 731 | |
| 816 | | /* initialize variables */ |
| 817 | | state->monitor_ef4 = 1; |
| 818 | | |
| 819 | 732 | /* find devices */ |
| 820 | 733 | state->cdp1864 = machine->device(CDP1864_TAG); |
| 821 | 734 | state->cassette = machine->device(CASSETTE_TAG); |
| 822 | 735 | |
| 823 | 736 | /* register for state saving */ |
| 824 | | state_save_register_global(machine, state->monitor_ef4); |
| 825 | | state_save_register_global(machine, state->cdp1864_efx); |
| 826 | 737 | state_save_register_global(machine, state->keylatch); |
| 827 | | state_save_register_global(machine, state->reset); |
| 828 | 738 | } |
| 829 | 739 | |
| 830 | | static MACHINE_RESET( oscnano ) |
| 740 | static MACHINE_RESET( nano ) |
| 831 | 741 | { |
| 832 | | oscnano_state *state = machine->driver_data<oscnano_state>(); |
| 742 | nano_state *state = machine->driver_data<nano_state>(); |
| 833 | 743 | |
| 744 | /* assert EF4 */ |
| 745 | cputag_set_input_line(machine, CDP1802_TAG, COSMAC_INPUT_LINE_EF4, ASSERT_LINE); |
| 746 | |
| 834 | 747 | /* reset CDP1864 */ |
| 835 | 748 | state->cdp1864->reset(); |
| 836 | 749 | |
| r9387 | r9388 | |
| 850 | 763 | }; |
| 851 | 764 | |
| 852 | 765 | static MACHINE_CONFIG_START( tmc1800, tmc1800_state ) |
| 853 | | |
| 854 | 766 | // basic system hardware |
| 855 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_1_75MHz) |
| 767 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, XTAL_1_75MHz) |
| 856 | 768 | MDRV_CPU_PROGRAM_MAP(tmc1800_map) |
| 857 | 769 | MDRV_CPU_IO_MAP(tmc1800_io_map) |
| 858 | 770 | MDRV_CPU_CONFIG(tmc1800_config) |
| r9387 | r9388 | |
| 880 | 792 | MACHINE_CONFIG_END |
| 881 | 793 | |
| 882 | 794 | static MACHINE_CONFIG_START( osc1000b, osc1000b_state ) |
| 883 | | |
| 884 | 795 | // basic system hardware |
| 885 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_1_75MHz) |
| 796 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, XTAL_1_75MHz) |
| 886 | 797 | MDRV_CPU_PROGRAM_MAP(osc1000b_map) |
| 887 | 798 | MDRV_CPU_IO_MAP(osc1000b_io_map) |
| 888 | 799 | MDRV_CPU_CONFIG(osc1000b_config) |
| r9387 | r9388 | |
| 910 | 821 | MACHINE_CONFIG_END |
| 911 | 822 | |
| 912 | 823 | static MACHINE_CONFIG_START( tmc2000, tmc2000_state ) |
| 913 | | |
| 914 | 824 | // basic system hardware |
| 915 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_1_75MHz) |
| 825 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, XTAL_1_75MHz) |
| 916 | 826 | MDRV_CPU_PROGRAM_MAP(tmc2000_map) |
| 917 | 827 | MDRV_CPU_IO_MAP(tmc2000_io_map) |
| 918 | 828 | MDRV_CPU_CONFIG(tmc2000_config) |
| r9387 | r9388 | |
| 933 | 843 | MDRV_RAM_EXTRA_OPTIONS("16K,32K") |
| 934 | 844 | MACHINE_CONFIG_END |
| 935 | 845 | |
| 936 | | static MACHINE_CONFIG_START( oscnano, oscnano_state ) |
| 937 | | |
| 846 | static MACHINE_CONFIG_START( nano, nano_state ) |
| 938 | 847 | // basic system hardware |
| 939 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_1_75MHz) |
| 940 | | MDRV_CPU_PROGRAM_MAP(oscnano_map) |
| 941 | | MDRV_CPU_IO_MAP(oscnano_io_map) |
| 942 | | MDRV_CPU_CONFIG(oscnano_config) |
| 848 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, XTAL_1_75MHz) |
| 849 | MDRV_CPU_PROGRAM_MAP(nano_map) |
| 850 | MDRV_CPU_IO_MAP(nano_io_map) |
| 851 | MDRV_CPU_CONFIG(nano_config) |
| 943 | 852 | |
| 944 | | MDRV_MACHINE_START(oscnano) |
| 945 | | MDRV_MACHINE_RESET(oscnano) |
| 853 | MDRV_MACHINE_START(nano) |
| 854 | MDRV_MACHINE_RESET(nano) |
| 946 | 855 | |
| 947 | 856 | // video hardware |
| 948 | | MDRV_FRAGMENT_ADD(oscnano_video) |
| 857 | MDRV_FRAGMENT_ADD(nano_video) |
| 949 | 858 | |
| 950 | 859 | // devices |
| 951 | 860 | MDRV_QUICKLOAD_ADD("quickload", tmc1800, "bin", 0) |
| r9387 | r9388 | |
| 1024 | 933 | COMP( 1977, tmc1800, 0, 0, tmc1800, tmc1800, tmc1800, "Telercas Oy", "Telmac 1800", GAME_NOT_WORKING ) |
| 1025 | 934 | COMP( 1977, osc1000b, tmc1800,0, osc1000b, tmc1800, tmc1800, "OSCOM Oy", "OSCOM 1000B", GAME_NOT_WORKING ) |
| 1026 | 935 | COMP( 1980, tmc2000, 0, 0, tmc2000, tmc2000, 0, "Telercas Oy", "Telmac 2000", GAME_SUPPORTS_SAVE ) |
| 1027 | | COMP( 1980, nano, tmc2000,0, oscnano, oscnano, 0, "OSCOM Oy", "OSCOM Nano", GAME_SUPPORTS_SAVE ) |
| 936 | COMP( 1980, nano, tmc2000,0, nano, nano, 0, "OSCOM Oy", "OSCOM Nano", GAME_SUPPORTS_SAVE ) |
src/mess/drivers/comx35.c
| r9387 | r9388 | |
| 10 | 10 | |
| 11 | 11 | */ |
| 12 | 12 | |
| 13 | #define ADDRESS_MAP_MODERN |
| 14 | |
| 13 | 15 | #include "emu.h" |
| 14 | 16 | #include "includes/comx35.h" |
| 15 | | #include "cpu/cdp1802/cdp1802.h" |
| 17 | #include "cpu/cosmac/cosmac.h" |
| 16 | 18 | #include "sound/cdp1869.h" |
| 17 | 19 | #include "sound/wave.h" |
| 18 | 20 | #include "devices/flopdrv.h" |
| r9387 | r9388 | |
| 28 | 30 | |
| 29 | 31 | /* Memory Maps */ |
| 30 | 32 | |
| 31 | | static ADDRESS_MAP_START( comx35_map, ADDRESS_SPACE_PROGRAM, 8 ) |
| 33 | static ADDRESS_MAP_START( comx35_map, ADDRESS_SPACE_PROGRAM, 8, comx35_state ) |
| 32 | 34 | ADDRESS_MAP_UNMAP_HIGH |
| 33 | 35 | AM_RANGE(0x0000, 0x3fff) AM_ROM |
| 34 | 36 | AM_RANGE(0x1000, 0x17ff) AM_ROMBANK("bank2") |
| r9387 | r9388 | |
| 36 | 38 | AM_RANGE(0x4000, 0xbfff) AM_RAM |
| 37 | 39 | AM_RANGE(0xc000, 0xdfff) AM_RAMBANK("bank1") |
| 38 | 40 | AM_RANGE(0xe000, 0xefff) AM_ROMBANK("bank3") |
| 39 | | AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE(CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w) |
| 40 | | AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE(CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w) |
| 41 | AM_RANGE(0xf400, 0xf7ff) AM_DEVREADWRITE_LEGACY(CDP1869_TAG, cdp1869_charram_r, cdp1869_charram_w) |
| 42 | AM_RANGE(0xf800, 0xffff) AM_DEVREADWRITE_LEGACY(CDP1869_TAG, cdp1869_pageram_r, cdp1869_pageram_w) |
| 41 | 43 | ADDRESS_MAP_END |
| 42 | 44 | |
| 43 | | static ADDRESS_MAP_START( comx35_io_map, ADDRESS_SPACE_IO, 8 ) |
| 45 | static ADDRESS_MAP_START( comx35_io_map, ADDRESS_SPACE_IO, 8, comx35_state ) |
| 44 | 46 | ADDRESS_MAP_UNMAP_HIGH |
| 45 | | AM_RANGE(0x01, 0x01) AM_WRITE(comx35_bank_select_w) |
| 46 | | AM_RANGE(0x02, 0x02) AM_READWRITE(comx35_io_r, comx35_io_w) |
| 47 | | AM_RANGE(0x03, 0x03) AM_DEVREAD(CDP1871_TAG, cdp1871_data_r) AM_DEVWRITE(CDP1869_TAG, cdp1869_out3_w) |
| 48 | | AM_RANGE(0x04, 0x04) AM_READ(comx35_io2_r) AM_DEVWRITE(CDP1869_TAG, cdp1869_out4_w) |
| 49 | | AM_RANGE(0x05, 0x05) AM_DEVWRITE(CDP1869_TAG, cdp1869_out5_w) |
| 50 | | AM_RANGE(0x06, 0x06) AM_DEVWRITE(CDP1869_TAG, cdp1869_out6_w) |
| 51 | | AM_RANGE(0x07, 0x07) AM_DEVWRITE(CDP1869_TAG, cdp1869_out7_w) |
| 47 | AM_RANGE(0x01, 0x01) AM_WRITE(bank_select_w) |
| 48 | AM_RANGE(0x02, 0x02) AM_READWRITE(io_r, io_w) |
| 49 | AM_RANGE(0x03, 0x03) AM_DEVREAD_LEGACY(CDP1871_TAG, cdp1871_data_r) AM_DEVWRITE_LEGACY(CDP1869_TAG, cdp1869_out3_w) |
| 50 | AM_RANGE(0x04, 0x04) AM_READ(io2_r) AM_DEVWRITE_LEGACY(CDP1869_TAG, cdp1869_out4_w) |
| 51 | AM_RANGE(0x05, 0x05) AM_DEVWRITE_LEGACY(CDP1869_TAG, cdp1869_out5_w) |
| 52 | AM_RANGE(0x06, 0x06) AM_DEVWRITE_LEGACY(CDP1869_TAG, cdp1869_out6_w) |
| 53 | AM_RANGE(0x07, 0x07) AM_DEVWRITE_LEGACY(CDP1869_TAG, cdp1869_out7_w) |
| 52 | 54 | ADDRESS_MAP_END |
| 53 | 55 | |
| 54 | 56 | /* Input Ports */ |
| r9387 | r9388 | |
| 201 | 203 | |
| 202 | 204 | /* CDP1802 Interface */ |
| 203 | 205 | |
| 204 | | static CDP1802_MODE_READ( comx35_mode_r ) |
| 206 | static READ_LINE_DEVICE_HANDLER( clear_r ) |
| 205 | 207 | { |
| 206 | 208 | comx35_state *state = device->machine->driver_data<comx35_state>(); |
| 207 | 209 | |
| 208 | | return (cdp1802_control_mode)state->cdp1802_mode; |
| 210 | return state->m_reset; |
| 209 | 211 | } |
| 210 | 212 | |
| 211 | | static CDP1802_EF_READ( comx35_ef_r ) |
| 213 | static READ_LINE_DEVICE_HANDLER( ef2_r ) |
| 212 | 214 | { |
| 213 | 215 | comx35_state *state = device->machine->driver_data<comx35_state>(); |
| 214 | 216 | |
| 215 | | int flags = 0x0f; |
| 216 | | |
| 217 | | /* |
| 218 | | EF1 predis |
| 219 | | EF2 on power up: 1=PAL/0=NTSC, after toggle Q: _EFXB |
| 220 | | EF3 _EFXA |
| 221 | | EF4 cassette in (ear) |
| 222 | | */ |
| 223 | | |
| 224 | | // CDP1869 predisplay |
| 225 | | if (!state->cdp1869_prd) flags -= EF1; |
| 226 | | |
| 227 | | if (state->iden) |
| 217 | if (state->m_iden) |
| 228 | 218 | { |
| 229 | 219 | // interrupts disabled: PAL/NTSC |
| 230 | | if (!state->pal_ntsc) flags -= EF2; |
| 220 | return cdp1869_pal_ntsc_r(state->m_vis); |
| 231 | 221 | } |
| 232 | 222 | else |
| 233 | 223 | { |
| 234 | 224 | // interrupts enabled: keyboard repeat |
| 235 | | if (!state->cdp1871_efxb) flags -= EF2; |
| 225 | return cdp1871_rpt_r(state->m_kbe); |
| 236 | 226 | } |
| 227 | } |
| 237 | 228 | |
| 238 | | // keyboard data available |
| 239 | | if (!state->cdp1871_efxa) flags -= EF3; |
| 229 | static READ_LINE_DEVICE_HANDLER( ef4_r ) |
| 230 | { |
| 231 | comx35_state *state = device->machine->driver_data<comx35_state>(); |
| 240 | 232 | |
| 241 | | // cassette input, expansion device flag |
| 242 | | if ((state->cassette && (cassette_input(state->cassette) < +0.0)) || !state->cdp1802_ef4) flags -= EF4; |
| 243 | | |
| 244 | | return flags; |
| 233 | return (cassette_input(device) < 0) | state->m_cdp1802_ef4; |
| 245 | 234 | } |
| 246 | 235 | |
| 247 | | static CDP1802_SC_WRITE( comx35_sc_w ) |
| 236 | static COSMAC_SC_WRITE( comx35_sc_w ) |
| 248 | 237 | { |
| 249 | | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 238 | comx35_state *state = device->machine->driver_data<comx35_state>(); |
| 250 | 239 | |
| 251 | | switch (state) |
| 240 | switch (sc) |
| 252 | 241 | { |
| 253 | | case CDP1802_STATE_CODE_S0_FETCH: |
| 242 | case COSMAC_STATE_CODE_S0_FETCH: |
| 254 | 243 | // not connected |
| 255 | 244 | break; |
| 256 | 245 | |
| 257 | | case CDP1802_STATE_CODE_S1_EXECUTE: |
| 246 | case COSMAC_STATE_CODE_S1_EXECUTE: |
| 258 | 247 | // every other S1 triggers a DMAOUT request |
| 259 | | if (driver_state->dma) |
| 248 | if (state->m_dma) |
| 260 | 249 | { |
| 261 | | driver_state->dma = 0; |
| 250 | state->m_dma = 0; |
| 262 | 251 | |
| 263 | | if (!driver_state->iden) |
| 252 | if (!state->m_iden) |
| 264 | 253 | { |
| 265 | | cputag_set_input_line(device->machine, CDP1802_TAG, CDP1802_INPUT_LINE_DMAOUT, HOLD_LINE); |
| 254 | cpu_set_input_line(device, COSMAC_INPUT_LINE_DMAOUT, ASSERT_LINE); |
| 266 | 255 | } |
| 267 | 256 | } |
| 268 | 257 | else |
| 269 | 258 | { |
| 270 | | driver_state->dma = 1; |
| 259 | state->m_dma = 1; |
| 271 | 260 | } |
| 272 | 261 | break; |
| 273 | 262 | |
| 274 | | case CDP1802_STATE_CODE_S2_DMA: |
| 263 | case COSMAC_STATE_CODE_S2_DMA: |
| 275 | 264 | // DMA acknowledge clears the DMAOUT request |
| 276 | | cputag_set_input_line(device->machine, CDP1802_TAG, CDP1802_INPUT_LINE_DMAOUT, CLEAR_LINE); |
| 265 | cpu_set_input_line(device, COSMAC_INPUT_LINE_DMAOUT, CLEAR_LINE); |
| 277 | 266 | break; |
| 278 | 267 | |
| 279 | | case CDP1802_STATE_CODE_S3_INTERRUPT: |
| 268 | case COSMAC_STATE_CODE_S3_INTERRUPT: |
| 280 | 269 | // interrupt acknowledge clears the INT request |
| 281 | | cputag_set_input_line(device->machine, CDP1802_TAG, CDP1802_INPUT_LINE_INT, CLEAR_LINE); |
| 270 | cpu_set_input_line(device, COSMAC_INPUT_LINE_INT, CLEAR_LINE); |
| 282 | 271 | break; |
| 283 | 272 | } |
| 284 | 273 | } |
| r9387 | r9388 | |
| 287 | 276 | { |
| 288 | 277 | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 289 | 278 | |
| 290 | | driver_state->cdp1802_q = state; |
| 279 | driver_state->m_cdp1802_q = state; |
| 291 | 280 | |
| 292 | | if (driver_state->iden && state) |
| 281 | if (driver_state->m_iden && state) |
| 293 | 282 | { |
| 294 | 283 | // enable interrupts |
| 295 | | driver_state->iden = 0; |
| 284 | driver_state->m_iden = 0; |
| 296 | 285 | } |
| 297 | 286 | |
| 298 | 287 | // cassette output |
| 299 | | if (driver_state->cassette) cassette_output(driver_state->cassette, state ? +1.0 : -1.0); |
| 288 | cassette_output(driver_state->m_cassette, state ? +1.0 : -1.0); |
| 300 | 289 | } |
| 301 | 290 | |
| 302 | | static CDP1802_INTERFACE( comx35_cdp1802_config ) |
| 291 | static COSMAC_INTERFACE( cosmac_intf ) |
| 303 | 292 | { |
| 304 | | comx35_mode_r, |
| 305 | | comx35_ef_r, |
| 306 | | comx35_sc_w, |
| 307 | | DEVCB_LINE(comx35_q_w), |
| 308 | | DEVCB_NULL, |
| 309 | | DEVCB_NULL |
| 293 | DEVCB_LINE_VCC, // wait |
| 294 | DEVCB_LINE(clear_r), // clear |
| 295 | DEVCB_NULL, // EF1 |
| 296 | DEVCB_LINE(ef2_r), // EF2 |
| 297 | DEVCB_NULL, // EF3 |
| 298 | DEVCB_DEVICE_LINE(CASSETTE_TAG, ef4_r), // EF4 |
| 299 | DEVCB_LINE(comx35_q_w), // Q |
| 300 | DEVCB_NULL, // DMA in |
| 301 | DEVCB_NULL, // DMA out |
| 302 | comx35_sc_w, // SC |
| 303 | DEVCB_NULL, // TPA |
| 304 | DEVCB_NULL // TPB |
| 310 | 305 | }; |
| 311 | 306 | |
| 312 | 307 | /* CDP1871 Interface */ |
| 313 | 308 | |
| 314 | | static WRITE_LINE_DEVICE_HANDLER( comx35_da_w ) |
| 315 | | { |
| 316 | | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 317 | | |
| 318 | | driver_state->cdp1871_efxa = state; |
| 319 | | } |
| 320 | | |
| 321 | | static WRITE_LINE_DEVICE_HANDLER( comx35_rpt_w ) |
| 322 | | { |
| 323 | | comx35_state *driver_state = device->machine->driver_data<comx35_state>(); |
| 324 | | |
| 325 | | driver_state->cdp1871_efxb = state; |
| 326 | | } |
| 327 | | |
| 328 | 309 | static READ_LINE_DEVICE_HANDLER( comx35_shift_r ) |
| 329 | 310 | { |
| 330 | 311 | return BIT(input_port_read(device->machine, "MODIFIERS"), 0); |
| r9387 | r9388 | |
| 351 | 332 | DEVCB_LINE(comx35_shift_r), |
| 352 | 333 | DEVCB_LINE(comx35_control_r), |
| 353 | 334 | DEVCB_NULL, |
| 354 | | DEVCB_LINE(comx35_da_w), |
| 355 | | DEVCB_LINE(comx35_rpt_w) |
| 335 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_EF3), |
| 336 | DEVCB_NULL // polled |
| 356 | 337 | }; |
| 357 | 338 | |
| 358 | 339 | /* Machine Drivers */ |
| r9387 | r9388 | |
| 377 | 358 | NULL |
| 378 | 359 | }; |
| 379 | 360 | |
| 380 | | /* F4 Character Displayer */ |
| 381 | | static const gfx_layout comx35_charlayout = |
| 382 | | { |
| 383 | | 8, 8, /* 8 x 8 characters */ |
| 384 | | 256, /* 256 characters */ |
| 385 | | 1, /* 1 bits per pixel */ |
| 386 | | { 0 }, /* no bitplanes */ |
| 387 | | /* x offsets */ |
| 388 | | { 0, 1, 2, 3, 4, 5, 6, 7 }, |
| 389 | | /* y offsets */ |
| 390 | | { 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 }, |
| 391 | | 8*8 /* every char takes 8 bytes */ |
| 392 | | }; |
| 393 | | |
| 394 | | static GFXDECODE_START( comx35 ) |
| 395 | | GFXDECODE_ENTRY( "chargen", 0x0000, comx35_charlayout, 0, 36 ) |
| 396 | | GFXDECODE_END |
| 397 | | |
| 398 | | |
| 399 | | static MACHINE_CONFIG_START( comx35_pal, comx35_state ) |
| 400 | | |
| 361 | static MACHINE_CONFIG_START( pal, comx35_state ) |
| 401 | 362 | /* basic system hardware */ |
| 402 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, CDP1869_CPU_CLK_PAL) |
| 363 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, CDP1869_CPU_CLK_PAL) |
| 403 | 364 | MDRV_CPU_PROGRAM_MAP(comx35_map) |
| 404 | 365 | MDRV_CPU_IO_MAP(comx35_io_map) |
| 405 | | MDRV_CPU_CONFIG(comx35_cdp1802_config) |
| 366 | MDRV_CPU_CONFIG(cosmac_intf) |
| 406 | 367 | |
| 407 | | MDRV_MACHINE_START(comx35p) |
| 408 | | MDRV_MACHINE_RESET(comx35) |
| 409 | | |
| 410 | 368 | /* sound and video hardware */ |
| 411 | 369 | MDRV_FRAGMENT_ADD(comx35_pal_video) |
| 412 | | MDRV_GFXDECODE(comx35) |
| 413 | 370 | |
| 414 | 371 | /* peripheral hardware */ |
| 415 | 372 | MDRV_CDP1871_ADD(CDP1871_TAG, comx35_cdp1871_intf, CDP1869_CPU_CLK_PAL / 8) |
| r9387 | r9388 | |
| 425 | 382 | MDRV_RAM_DEFAULT_SIZE("32K") |
| 426 | 383 | MACHINE_CONFIG_END |
| 427 | 384 | |
| 428 | | static MACHINE_CONFIG_START( comx35_ntsc, comx35_state ) |
| 429 | | |
| 385 | static MACHINE_CONFIG_START( ntsc, comx35_state ) |
| 430 | 386 | /* basic system hardware */ |
| 431 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, CDP1869_CPU_CLK_NTSC) |
| 387 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, CDP1869_CPU_CLK_NTSC) |
| 432 | 388 | MDRV_CPU_PROGRAM_MAP(comx35_map) |
| 433 | 389 | MDRV_CPU_IO_MAP(comx35_io_map) |
| 434 | | MDRV_CPU_CONFIG(comx35_cdp1802_config) |
| 390 | MDRV_CPU_CONFIG(cosmac_intf) |
| 435 | 391 | |
| 436 | | MDRV_MACHINE_START(comx35n) |
| 437 | | MDRV_MACHINE_RESET(comx35) |
| 438 | | |
| 439 | 392 | /* sound and video hardware */ |
| 440 | 393 | MDRV_FRAGMENT_ADD(comx35_ntsc_video) |
| 441 | | MDRV_GFXDECODE(comx35) |
| 442 | 394 | |
| 443 | 395 | /* peripheral hardware */ |
| 444 | 396 | MDRV_CDP1871_ADD(CDP1871_TAG, comx35_cdp1871_intf, CDP1869_CPU_CLK_NTSC / 8) |
| r9387 | r9388 | |
| 498 | 450 | /* System Drivers */ |
| 499 | 451 | |
| 500 | 452 | // YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS |
| 501 | | COMP( 1983, comx35p, 0, 0, comx35_pal, comx35, 0, "Comx World Operations Ltd", "COMX 35 (PAL)", GAME_IMPERFECT_SOUND ) |
| 502 | | COMP( 1983, comx35n, comx35p,0, comx35_ntsc,comx35, 0, "Comx World Operations Ltd", "COMX 35 (NTSC)", GAME_IMPERFECT_SOUND ) |
| 453 | COMP( 1983, comx35p, 0, 0, pal, comx35, 0, "Comx World Operations Ltd", "COMX 35 (PAL)", GAME_IMPERFECT_SOUND ) |
| 454 | COMP( 1983, comx35n, comx35p,0, ntsc, comx35, 0, "Comx World Operations Ltd", "COMX 35 (NTSC)", GAME_IMPERFECT_SOUND ) |
src/mess/drivers/tmc2000e.c
| r9387 | r9388 | |
| 31 | 31 | |
| 32 | 32 | #include "emu.h" |
| 33 | 33 | #include "includes/tmc2000e.h" |
| 34 | | #include "cpu/cdp1802/cdp1802.h" |
| 34 | #include "cpu/cosmac/cosmac.h" |
| 35 | 35 | #include "devices/printer.h" |
| 36 | 36 | #include "devices/flopdrv.h" |
| 37 | 37 | #include "formats/basicdsk.h" |
| r9387 | r9388 | |
| 147 | 147 | return BIT(state->color, 0); |
| 148 | 148 | } |
| 149 | 149 | |
| 150 | | static WRITE_LINE_DEVICE_HANDLER( tmc2000e_efx_w ) |
| 151 | | { |
| 152 | | tmc2000e_state *driver_state = device->machine->driver_data<tmc2000e_state>(); |
| 153 | | |
| 154 | | driver_state->cdp1864_efx = state; |
| 155 | | } |
| 156 | | |
| 157 | 150 | static CDP1864_INTERFACE( tmc2000e_cdp1864_intf ) |
| 158 | 151 | { |
| 159 | 152 | CDP1802_TAG, |
| r9387 | r9388 | |
| 162 | 155 | DEVCB_LINE(rdata_r), |
| 163 | 156 | DEVCB_LINE(bdata_r), |
| 164 | 157 | DEVCB_LINE(gdata_r), |
| 165 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_INT), |
| 166 | | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, CDP1802_INPUT_LINE_DMAOUT), |
| 167 | | DEVCB_LINE(tmc2000e_efx_w), |
| 158 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_INT), |
| 159 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_DMAOUT), |
| 160 | DEVCB_CPU_INPUT_LINE(CDP1802_TAG, COSMAC_INPUT_LINE_EF1), |
| 168 | 161 | RES_K(2.2), // unverified |
| 169 | 162 | RES_K(1), // unverified |
| 170 | 163 | RES_K(5.1), // unverified |
| r9387 | r9388 | |
| 182 | 175 | |
| 183 | 176 | /* CDP1802 Interface */ |
| 184 | 177 | |
| 185 | | static CDP1802_MODE_READ( tmc2000e_mode_r ) |
| 178 | static READ_LINE_DEVICE_HANDLER( clear_r ) |
| 186 | 179 | { |
| 187 | | if (input_port_read(device->machine, "RUN") & 0x01) |
| 188 | | { |
| 189 | | return CDP1802_MODE_RUN; |
| 190 | | } |
| 191 | | else |
| 192 | | { |
| 193 | | return CDP1802_MODE_RESET; |
| 194 | | } |
| 180 | return BIT(input_port_read(device->machine, "RUN"), 0); |
| 195 | 181 | } |
| 196 | 182 | |
| 197 | | static CDP1802_EF_READ( tmc2000e_ef_r ) |
| 183 | static READ_LINE_DEVICE_HANDLER( ef2_r ) |
| 198 | 184 | { |
| 199 | | tmc2000e_state *state = device->machine->driver_data<tmc2000e_state>(); |
| 185 | return cassette_input(device) < 0; |
| 186 | } |
| 200 | 187 | |
| 201 | | UINT8 flags = 0x0f; |
| 188 | static READ_LINE_DEVICE_HANDLER( ef3_r ) |
| 189 | { |
| 190 | tmc2000e_state *state = device->machine->driver_data<tmc2000e_state>(); |
| 202 | 191 | static const char *const keynames[] = { "IN0", "IN1", "IN2", "IN3", "IN4", "IN5", "IN6", "IN7" }; |
| 192 | UINT8 data = ~input_port_read(device->machine, keynames[state->keylatch / 8]); |
| 203 | 193 | |
| 204 | | /* |
| 205 | | EF1 CDP1864 |
| 206 | | EF2 tape in/floppy |
| 207 | | EF3 keyboard |
| 208 | | EF4 I/O port |
| 209 | | */ |
| 210 | | |
| 211 | | // CDP1864 |
| 212 | | |
| 213 | | if (!state->cdp1864_efx) flags -= EF1; |
| 214 | | |
| 215 | | // tape in |
| 216 | | |
| 217 | | if (cassette_input(state->cassette) > +1.0) flags -= EF2; |
| 218 | | |
| 219 | | // keyboard |
| 220 | | |
| 221 | | if (~input_port_read(device->machine, keynames[state->keylatch / 8]) & (1 << (state->keylatch % 8))) flags -= EF3; |
| 222 | | |
| 223 | | return flags; |
| 194 | return BIT(data, state->keylatch % 8); |
| 224 | 195 | } |
| 225 | 196 | |
| 226 | 197 | static WRITE_LINE_DEVICE_HANDLER( tmc2000e_q_w ) |
| r9387 | r9388 | |
| 252 | 223 | cdp1864_dma_w(state->cdp1864, offset, data); |
| 253 | 224 | } |
| 254 | 225 | |
| 255 | | static CDP1802_INTERFACE( tmc2000e_config ) |
| 226 | static COSMAC_INTERFACE( tmc2000e_config ) |
| 256 | 227 | { |
| 257 | | tmc2000e_mode_r, |
| 258 | | tmc2000e_ef_r, |
| 259 | | NULL, |
| 228 | DEVCB_LINE_VCC, |
| 229 | DEVCB_LINE(clear_r), |
| 230 | DEVCB_NULL, |
| 231 | DEVCB_DEVICE_LINE(CASSETTE_TAG, ef2_r), |
| 232 | DEVCB_LINE(ef3_r), |
| 233 | DEVCB_NULL, |
| 260 | 234 | DEVCB_LINE(tmc2000e_q_w), |
| 261 | 235 | DEVCB_NULL, |
| 262 | | DEVCB_HANDLER(tmc2000e_dma_w) |
| 236 | DEVCB_HANDLER(tmc2000e_dma_w), |
| 237 | NULL, |
| 238 | DEVCB_NULL, |
| 239 | DEVCB_NULL |
| 263 | 240 | }; |
| 264 | 241 | |
| 265 | 242 | /* Machine Initialization */ |
| r9387 | r9388 | |
| 287 | 264 | |
| 288 | 265 | state->cdp1864->reset(); |
| 289 | 266 | |
| 290 | | cputag_set_input_line(machine, CDP1802_TAG, INPUT_LINE_RESET, PULSE_LINE); |
| 291 | | |
| 292 | 267 | // reset program counter to 0xc000 |
| 293 | 268 | } |
| 294 | 269 | |
| r9387 | r9388 | |
| 301 | 276 | (cassette_state)(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_MUTED), |
| 302 | 277 | NULL |
| 303 | 278 | }; |
| 304 | | static FLOPPY_OPTIONS_START(tmc2000e) |
| 305 | | // dsk |
| 306 | | FLOPPY_OPTIONS_END |
| 307 | 279 | |
| 308 | 280 | static const floppy_config tmc2000e_floppy_config = |
| 309 | 281 | { |
| r9387 | r9388 | |
| 312 | 284 | DEVCB_NULL, |
| 313 | 285 | DEVCB_NULL, |
| 314 | 286 | DEVCB_NULL, |
| 315 | | FLOPPY_STANDARD_5_25_DSHD, |
| 316 | | FLOPPY_OPTIONS_NAME(tmc2000e), |
| 287 | FLOPPY_STANDARD_5_25_DSDD, |
| 288 | FLOPPY_OPTIONS_NAME(default), |
| 317 | 289 | NULL |
| 318 | 290 | }; |
| 319 | 291 | |
| 320 | 292 | static MACHINE_CONFIG_START( tmc2000e, tmc2000e_state ) |
| 321 | | |
| 322 | 293 | // basic system hardware |
| 323 | | MDRV_CPU_ADD(CDP1802_TAG, CDP1802, XTAL_1_75MHz) |
| 294 | MDRV_CPU_ADD(CDP1802_TAG, COSMAC, XTAL_1_75MHz) |
| 324 | 295 | MDRV_CPU_PROGRAM_MAP(tmc2000e_map) |
| 325 | 296 | MDRV_CPU_IO_MAP(tmc2000e_io_map) |
| 326 | 297 | MDRV_CPU_CONFIG(tmc2000e_config) |
| r9387 | r9388 | |
| 343 | 314 | MDRV_PRINTER_ADD("printer") |
| 344 | 315 | MDRV_CASSETTE_ADD("cassette", tmc2000_cassette_config) |
| 345 | 316 | |
| 346 | | MDRV_FLOPPY_4_DRIVES_ADD(tmc2000e_floppy_config) |
| 317 | MDRV_FLOPPY_2_DRIVES_ADD(tmc2000e_floppy_config) |
| 347 | 318 | |
| 348 | 319 | /* internal ram */ |
| 349 | 320 | MDRV_RAM_ADD("messram") |