trunk/src/mame/machine/archimds.c
| r20842 | r20843 | |
| 28 | 28 | |
| 29 | 29 | #include "emu.h" |
| 30 | 30 | #include "cpu/arm/arm.h" |
| 31 | | #include "sound/dac.h" |
| 32 | 31 | #include "includes/archimds.h" |
| 33 | | #include "machine/i2cmem.h" |
| 34 | 32 | #include "debugger.h" |
| 35 | | #include "machine/wd17xx.h" |
| 36 | 33 | |
| 37 | 34 | static const int page_sizes[4] = { 4096, 8192, 16384, 32768 }; |
| 38 | 35 | static const UINT32 pixel_rate[4] = { 8000000, 12000000, 16000000, 24000000}; |
| r20842 | r20843 | |
| 45 | 42 | m_ioc_regs[IRQ_STATUS_A] |= mask; |
| 46 | 43 | |
| 47 | 44 | if (m_ioc_regs[IRQ_STATUS_A] & m_ioc_regs[IRQ_MASK_A]) |
| 48 | | machine().device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, ASSERT_LINE); |
| 45 | { |
| 46 | m_maincpu->set_input_line(ARM_IRQ_LINE, ASSERT_LINE); |
| 47 | } |
| 49 | 48 | |
| 50 | 49 | if ((m_ioc_regs[IRQ_STATUS_A] & m_ioc_regs[IRQ_MASK_A]) == 0) |
| 51 | | machine().device("maincpu")->execute().set_input_line(ARM_IRQ_LINE, CLEAR_LINE); |
| 52 | | |
| 50 | { |
| 51 | m_maincpu->set_input_line(ARM_IRQ_LINE, CLEAR_LINE); |
| 52 | } |
| 53 | 53 | } |
| 54 | 54 | |
| 55 | 55 | void archimedes_state::archimedes_request_irq_b(int mask) |
| r20842 | r20843 | |
| 58 | 58 | |
| 59 | 59 | if (m_ioc_regs[IRQ_STATUS_B] & m_ioc_regs[IRQ_MASK_B]) |
| 60 | 60 | { |
| 61 | | generic_pulse_irq_line(machine().device("maincpu")->execute(), ARM_IRQ_LINE, 1); |
| 61 | generic_pulse_irq_line(m_maincpu, ARM_IRQ_LINE, 1); |
| 62 | 62 | } |
| 63 | 63 | } |
| 64 | 64 | |
| r20842 | r20843 | |
| 68 | 68 | |
| 69 | 69 | if (m_ioc_regs[FIQ_STATUS] & m_ioc_regs[FIQ_MASK]) |
| 70 | 70 | { |
| 71 | | generic_pulse_irq_line(machine().device("maincpu")->execute(), ARM_FIRQ_LINE, 1); |
| 71 | generic_pulse_irq_line(m_maincpu, ARM_FIRQ_LINE, 1); |
| 72 | 72 | } |
| 73 | 73 | } |
| 74 | 74 | |
| r20842 | r20843 | |
| 113 | 113 | /* TODO: what type of DMA this is, burst or cycle steal? Docs doesn't explain it (4 usec is the DRAM refresh). */ |
| 114 | 114 | void archimedes_state::vidc_video_tick() |
| 115 | 115 | { |
| 116 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 117 | | static UINT8 *vram = machine().root_device().memregion("vram")->base(); |
| 116 | address_space &space = m_maincpu->space(AS_PROGRAM); |
| 117 | static UINT8 *vram = m_region_vram->base(); |
| 118 | 118 | UINT32 size; |
| 119 | 119 | |
| 120 | 120 | size = m_vidc_vidend-m_vidc_vidstart+0x10; |
| r20842 | r20843 | |
| 131 | 131 | /* audio DMA */ |
| 132 | 132 | void archimedes_state::vidc_audio_tick() |
| 133 | 133 | { |
| 134 | | address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM); |
| 134 | address_space &space = m_maincpu->space(AS_PROGRAM); |
| 135 | 135 | UINT8 ulaw_comp; |
| 136 | 136 | INT16 res; |
| 137 | 137 | UINT8 ch; |
| 138 | | static const char *const dac_port[8] = { "dac0", "dac1", "dac2", "dac3", "dac4", "dac5", "dac6", "dac7" }; |
| 139 | 138 | static const INT16 mulawTable[256] = |
| 140 | 139 | { |
| 141 | 140 | -32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956, |
| r20842 | r20843 | |
| 180 | 179 | |
| 181 | 180 | res = mulawTable[ulaw_comp]; |
| 182 | 181 | |
| 183 | | machine().device<dac_device>(dac_port[ch & 7])->write_signed16(res^0x8000); |
| 182 | m_dac[ch & 7]->write_signed16(res^0x8000); |
| 184 | 183 | } |
| 185 | 184 | |
| 186 | 185 | m_vidc_sndcur+=8; |
| r20842 | r20843 | |
| 194 | 193 | { |
| 195 | 194 | m_snd_timer->adjust(attotime::never); |
| 196 | 195 | for(ch=0;ch<8;ch++) |
| 197 | | machine().device<dac_device>(dac_port[ch & 7])->write_signed16(0x8000); |
| 196 | { |
| 197 | m_dac[ch & 7]->write_signed16(0x8000); |
| 198 | } |
| 198 | 199 | } |
| 199 | 200 | } |
| 200 | 201 | } |
| r20842 | r20843 | |
| 259 | 260 | |
| 260 | 261 | void archimedes_state::archimedes_init() |
| 261 | 262 | { |
| 263 | static const char *const dac_names[8] = { "dac0", "dac1", "dac2", "dac3", "dac4", "dac5", "dac6", "dac7" }; |
| 264 | |
| 262 | 265 | m_memc_pagesize = 0; |
| 263 | 266 | |
| 264 | 267 | m_vbl_timer = timer_alloc(TIMER_VBLANK); |
| r20842 | r20843 | |
| 276 | 279 | m_vid_timer = timer_alloc(TIMER_VIDEO); |
| 277 | 280 | m_snd_timer = timer_alloc(TIMER_AUDIO); |
| 278 | 281 | m_snd_timer->adjust(attotime::never); |
| 282 | |
| 283 | for ( int i = 0; i < 8; i++ ) |
| 284 | { |
| 285 | m_dac[i] = machine().device<dac_device>(dac_names[i]); |
| 286 | } |
| 279 | 287 | } |
| 280 | 288 | |
| 281 | 289 | READ32_MEMBER(archimedes_state::archimedes_memc_logical_r) |
| r20842 | r20843 | |
| 287 | 295 | { |
| 288 | 296 | UINT32 *rom; |
| 289 | 297 | |
| 290 | | rom = (UINT32 *)machine().root_device().memregion("maincpu")->base(); |
| 298 | rom = (UINT32 *)m_region_maincpu->base(); |
| 291 | 299 | |
| 292 | 300 | return rom[offset & 0x1fffff]; |
| 293 | 301 | } |
| r20842 | r20843 | |
| 353 | 361 | { |
| 354 | 362 | UINT32 *rom; |
| 355 | 363 | |
| 356 | | rom = (UINT32 *)machine().root_device().memregion("maincpu")->base(); |
| 364 | rom = (UINT32 *)m_region_maincpu->base(); |
| 357 | 365 | |
| 358 | 366 | return rom[offset & 0x1fffff]; |
| 359 | 367 | } |
| r20842 | r20843 | |
| 394 | 402 | |
| 395 | 403 | void archimedes_state::archimedes_driver_init() |
| 396 | 404 | { |
| 397 | | m_archimedes_memc_physmem = reinterpret_cast<UINT32 *>(machine().root_device().memshare("physicalram")->ptr()); |
| 398 | | // address_space &space = machine.device<arm_device>("maincpu")->space(AS_PROGRAM); |
| 405 | m_archimedes_memc_physmem = reinterpret_cast<UINT32 *>(memshare("physicalram")->ptr()); |
| 406 | // address_space &space = m_maincpu->space(AS_PROGRAM); |
| 399 | 407 | // space.set_direct_update_handler(direct_update_delegate(FUNC(a310_setopbase), &machine)); |
| 400 | 408 | } |
| 401 | 409 | |
| r20842 | r20843 | |
| 446 | 454 | READ32_MEMBER( archimedes_state::ioc_ctrl_r ) |
| 447 | 455 | { |
| 448 | 456 | if(IOC_LOG) |
| 449 | | logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], m_ioc_regs[offset&0x1f], space.device() .safe_pc( ),offset & 0x1f); |
| 457 | logerror("IOC: R %s = %02x (PC=%x) %02x\n", ioc_regnames[offset&0x1f], m_ioc_regs[offset&0x1f], m_maincpu->pc(),offset & 0x1f); |
| 450 | 458 | |
| 451 | 459 | switch (offset & 0x1f) |
| 452 | 460 | { |
| 453 | 461 | case CONTROL: |
| 454 | 462 | { |
| 455 | | UINT8 i2c_data; |
| 463 | UINT8 i2c_data = 1; |
| 456 | 464 | static UINT8 flyback; //internal name for vblank here |
| 457 | 465 | int vert_pos; |
| 458 | 466 | |
| 459 | 467 | vert_pos = machine().primary_screen->vpos(); |
| 460 | 468 | flyback = (vert_pos <= m_vidc_regs[VIDC_VDSR] || vert_pos >= m_vidc_regs[VIDC_VDER]) ? 0x80 : 0x00; |
| 461 | 469 | |
| 462 | | i2c_data = (i2cmem_sda_read(space.machine().device("i2cmem")) & 1); |
| 470 | if ( m_i2cmem ) |
| 471 | { |
| 472 | i2c_data = (i2cmem_sda_read(m_i2cmem) & 1); |
| 473 | } |
| 463 | 474 | |
| 464 | 475 | return (flyback) | (m_ioc_regs[CONTROL] & 0x7c) | (m_i2c_clk<<1) | i2c_data; |
| 465 | 476 | } |
| r20842 | r20843 | |
| 524 | 535 | { |
| 525 | 536 | case CONTROL: // I2C bus control |
| 526 | 537 | //logerror("IOC I2C: CLK %d DAT %d\n", (data>>1)&1, data&1); |
| 527 | | i2cmem_sda_write(machine().device("i2cmem"), data & 0x01); |
| 528 | | i2cmem_scl_write(machine().device("i2cmem"), (data & 0x02) >> 1); |
| 538 | if ( m_i2cmem ) |
| 539 | { |
| 540 | i2cmem_sda_write(m_i2cmem, data & 0x01); |
| 541 | i2cmem_scl_write(m_i2cmem, (data & 0x02) >> 1); |
| 542 | } |
| 529 | 543 | m_i2c_clk = (data & 2) >> 1; |
| 530 | 544 | break; |
| 531 | 545 | |
| r20842 | r20843 | |
| 632 | 646 | READ32_MEMBER(archimedes_state::archimedes_ioc_r) |
| 633 | 647 | { |
| 634 | 648 | UINT32 ioc_addr; |
| 635 | | device_t *fdc = (device_t *)space.machine().device("wd1772"); |
| 636 | 649 | |
| 637 | 650 | ioc_addr = offset*4; |
| 638 | 651 | |
| r20842 | r20843 | |
| 649 | 662 | { |
| 650 | 663 | case 0: return ioc_ctrl_r(space,offset,mem_mask); |
| 651 | 664 | case 1: |
| 652 | | if (fdc) { |
| 665 | if (m_wd1772) { |
| 653 | 666 | logerror("17XX: R @ addr %x mask %08x\n", offset*4, mem_mask); |
| 654 | | return wd17xx_data_r(fdc, space, offset&0xf); |
| 667 | return wd17xx_data_r(m_wd1772, space, offset&0xf); |
| 655 | 668 | } else { |
| 656 | 669 | logerror("Read from FDC device?\n"); |
| 657 | 670 | return 0; |
| r20842 | r20843 | |
| 666 | 679 | logerror("IOC: Internal Podule Read\n"); |
| 667 | 680 | return 0xffff; |
| 668 | 681 | case 5: |
| 669 | | if (fdc) { |
| 682 | if (m_wd1772) { |
| 670 | 683 | switch(ioc_addr & 0xfffc) |
| 671 | 684 | { |
| 672 | 685 | case 0x50: return 0; //fdc type, new model returns 5 here |
| r20842 | r20843 | |
| 688 | 701 | WRITE32_MEMBER(archimedes_state::archimedes_ioc_w) |
| 689 | 702 | { |
| 690 | 703 | UINT32 ioc_addr; |
| 691 | | device_t *fdc = (device_t *)space.machine().device("wd1772"); |
| 692 | 704 | |
| 693 | 705 | ioc_addr = offset*4; |
| 694 | 706 | |
| r20842 | r20843 | |
| 705 | 717 | { |
| 706 | 718 | case 0: ioc_ctrl_w(space,offset,data,mem_mask); return; |
| 707 | 719 | case 1: |
| 708 | | if (fdc) { |
| 720 | if (m_wd1772) { |
| 709 | 721 | logerror("17XX: %x to addr %x mask %08x\n", data, offset*4, mem_mask); |
| 710 | | wd17xx_data_w(fdc, space, offset&0xf, data&0xff); |
| 722 | wd17xx_data_w(m_wd1772, space, offset&0xf, data&0xff); |
| 711 | 723 | } else { |
| 712 | 724 | logerror("Write to FDC device?\n"); |
| 713 | 725 | } |
| r20842 | r20843 | |
| 722 | 734 | logerror("IOC: Internal Podule Write\n"); |
| 723 | 735 | return; |
| 724 | 736 | case 5: |
| 725 | | if (fdc) { |
| 737 | if (m_wd1772) { |
| 726 | 738 | switch(ioc_addr & 0xfffc) |
| 727 | 739 | { |
| 728 | 740 | case 0x18: // latch B |
| 729 | | wd17xx_dden_w(fdc, BIT(data, 1)); |
| 741 | wd17xx_dden_w(m_wd1772, BIT(data, 1)); |
| 730 | 742 | return; |
| 731 | 743 | |
| 732 | 744 | case 0x40: // latch A |
| 733 | | if (data & 1) { wd17xx_set_drive(fdc,0); } |
| 734 | | if (data & 2) { wd17xx_set_drive(fdc,1); } |
| 735 | | if (data & 4) { wd17xx_set_drive(fdc,2); } |
| 736 | | if (data & 8) { wd17xx_set_drive(fdc,3); } |
| 745 | if (data & 1) { wd17xx_set_drive(m_wd1772,0); } |
| 746 | if (data & 2) { wd17xx_set_drive(m_wd1772,1); } |
| 747 | if (data & 4) { wd17xx_set_drive(m_wd1772,2); } |
| 748 | if (data & 8) { wd17xx_set_drive(m_wd1772,3); } |
| 737 | 749 | |
| 738 | | wd17xx_set_side(fdc,(data & 0x10)>>4); |
| 750 | wd17xx_set_side(m_wd1772,(data & 0x10)>>4); |
| 739 | 751 | //bit 5 is motor on |
| 740 | 752 | return; |
| 741 | 753 | } |
trunk/src/mame/includes/archimds.h
| r20842 | r20843 | |
| 8 | 8 | #define _ARCHIMEDES_H_ |
| 9 | 9 | |
| 10 | 10 | #include "machine/aakart.h" |
| 11 | #include "sound/dac.h" |
| 12 | #include "machine/i2cmem.h" |
| 13 | #include "machine/wd17xx.h" |
| 11 | 14 | |
| 12 | 15 | // interrupt definitions. these are for the real Archimedes computer - arcade |
| 13 | 16 | // and gambling knockoffs likely are a bit different. |
| r20842 | r20843 | |
| 40 | 43 | { |
| 41 | 44 | public: |
| 42 | 45 | archimedes_state(const machine_config &mconfig, device_type type, const char *tag) |
| 43 | | : driver_device(mconfig, type, tag), |
| 44 | | m_kart(*this, "kart") |
| 45 | | { } |
| 46 | : driver_device(mconfig, type, tag) |
| 47 | , m_kart(*this, "kart") |
| 48 | , m_maincpu(*this, "maincpu") |
| 49 | , m_i2cmem(*this, "i2cmem") |
| 50 | , m_wd1772(*this, "wd1772") |
| 51 | , m_region_maincpu(*this, "maincpu") |
| 52 | , m_region_vram(*this, "vram") |
| 53 | { } |
| 46 | 54 | |
| 47 | 55 | optional_device<aakart_device> m_kart; |
| 48 | 56 | void archimedes_init(); |
| r20842 | r20843 | |
| 78 | 86 | |
| 79 | 87 | UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 80 | 88 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); |
| 89 | |
| 90 | protected: |
| 91 | required_device<cpu_device> m_maincpu; |
| 92 | optional_device<device_t> m_i2cmem; |
| 93 | optional_device<device_t> m_wd1772; |
| 94 | required_memory_region m_region_maincpu; |
| 95 | required_memory_region m_region_vram; |
| 96 | dac_device *m_dac[8]; |
| 97 | |
| 81 | 98 | private: |
| 82 | 99 | |
| 83 | 100 | static const device_timer_id TIMER_VBLANK = 0; |