summaryrefslogtreecommitdiffstatshomepage
path: root/docs/source/advanced
ModeNameSize
-rw-r--r--bgfx.rst7868logstatsplainblame
-rw-r--r--ctrlr_config.rst9375logstatsplainblame
-rw-r--r--devicemap.rst4878logstatsplainblame
-rw-r--r--glsl.rst4981logstatsplainblame
-rw-r--r--hlsl.rst17901logstatsplainblame
-rw-r--r--index.rst200logstatsplainblame
-rw-r--r--linux-lightguns.rst2891logstatsplainblame
-rw-r--r--multiconfig.rst4944logstatsplainblame
-rw-r--r--paths.rst1477logstatsplainblame
-rw-r--r--shiftertoggle.rst2505logstatsplainblame
#n207'>207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759
// license:?
// copyright-holders:Angelo Salese, R. Belmont
/*

    dc.c - Sega Dreamcast driver
    by R. Belmont & Angelo Salese

    SH-4 @ 200 MHz
    ARM7DI @ 2.8223 MHz (no T or M extensions)
    PowerVR 3D video
    AICA audio
    GD-ROM drive (modified ATAPI interface)

            NTSC/N  NTSC/I   PAL/N   PAL/I   VGA
        (x/240) (x/480) (x/240)  (x/480) (640x480)
    VTOTAL   262     524      312     624    524
    HTOTAL   857     857      863     863    857

    PCLKs = 26917135 (NTSC 480 @ 59.94), 26944080 (VGA 480 @ 60.0), 13458568 (NTSC 240 @ 59.94),
            25925600 (PAL 480 @ 50.00), 13462800 (PAL 240 @ 50.00)

    TODO:
    - RTC error always pops up at start-up, no flash plus bug with ticks (needs rewrite)
    - Inputs doesn't work most of the time;
    - Candy Stripe: fills the log with "ATAPI_FEATURES_FLAG_OVL not supported", black screen
    - Carrier: Jaleco logo uses YUV, but y size is halved?
    - Close To: Hangs at FMV
    - F355 Challenge: black screen after Sega logo;
    - Gundam - Side Story 0079: currently hangs at Bandai logo (regression)
    - Idol Janshi wo Tsukucchaou: pixel aspect is way wrong (stretched and offsetted horizontally)
    - Power Stone: hangs at Capcom logo;
    - Sega GT: no cursor on main menu;
    - Tetris 4D: hangs at BPS FMV (bp 0C0B0C4E)

    Notes:
    - DC US and DC PAL flash ROMs are definitely hacked, they are set to have Chinese instead of Japanese.
    - 0x1a002 of flash ROM returns the region type (0x30=Japan, 0x31=USA, 0x32=Europe). Amusingly, if the value
      on a non-jp console is different than these ones, the system shows a black swirl (and nothing boots).
    - gdi file for DCLP (a Dreamcast tester) doesn't have first two tracks info, they are:
      1 0 4 2048 FILE0001.DUP 0
      2 1798 0 2352 FILE0002.DUP 0
      serial i/o also fails on that, work ram addresses that needs to be patched with 0x0009 (nop) are:
      0xc0196da
      0xc0196ec
    SH4 TEST:
        UBC test (0101):
            ok
        FPU test (0201):
            NG
        0xc03fe24 work ram flag check (1=error, 0=ok)
        Cache test (03xx):
            Cache Read/Write test (0301)
            NG
            Cache RAM mode Check (0305)
            NG
        MMU test (04xx):
            asserts
        TMU test (0501):
            *_reg check -> ok
            TCNT* reload -> NG
            TCNT* underflow irq -> NG
        MULT test (0601)
            ok
        DIVU test (0701)
            ok
        Store Queue test (0801):
            ok
        SCIF test (0901)
            NG
        Private Instruction test (0a01)
            NG
        Critical test (0dxx)
            Critical (Store Queue) test (0d01):
                ok
            Critical (Write back) test (0d02):
                ok
            Critical (ADD,CMP/EQ) test (0d03):
                ok
            Critical (OC_OIX) test (0d04):
                NG
            Critical (MAX current) test (0d05):
                ok (very slow!)
            Critical (IC Cross Talk) test (0d06):
                NG
            Critical (Cache D-array) test (0d07):
                NG
        SH-4 BUG (0exx)
            SH4_BUG 64bit FMOV
                ok
            SH4 BUG FIX (64bitFMOV)
                ok
    MEM TEST:
        AICA (0102)
            ok
        Work RAM (0204):
            ok
        PV64 area (0303):
            ok
        PV32 area (0403):
            ok
    CLX TEST:
        CLX internal RAM (0101):
            ok
        <Torus> check (0401):
            (sets up RGB888 mode 2, assuming it's critically failed)
    TA TEST:
        TA_YUVINT (0101):
            ok -> IST_EOXFER_YUV
        TA_OENDINT (0102):
            ok -> IST_EOXFER_OPLST
        TA_OMENDINT (0103):
            ok -> IST_EOXFER_OPMV
        TA_TENDINT (0104):
            ok -> IST_EOXFER_TRLST
        TA_TMENDINT (0105):
            ok -> IST_EOXFER_TRMV
        TA_PTENDINT (0106):
            ok -> IST_EOXFER_PTLST
        TA_ISPINT (0107):
            NG -> ISP/TSP Parameter Overflow (error)
        TA_OBJINT (0108):
            NG -> OBJect list pointer Overflow (error)
        TA_IPINT (0109):
            NG -> TA: Illegal parameter (error)
        YUV Converter (0201):
            ok
    DDT i/f TEST:
        Sort, Normal DMA (1) (0101)
            hangs (wants Sort DMA irq, of course)
        Sort, Normal DMA (2)
            ...
        Through
            NG, hangs again
        DC_DEINT (0201)
            ok
        DC_SDTEINT (0202)
            ok
        DC_SDTERINT (0203)
            ok (but returns error count ++, think it's a bug in the SW)
    G2 TEST
        DMA (0101):
            G2 EXT AREA DETECT:
            "!!!! ch00 ERROR DETECT !!!!"
        Interrupt (0301):
            G2 EXT AREA DETECT
            DMA END INT
                hangs
        Ext Interrupt (06xx)
            AICA INT  (0601)
                error detect
            Modem INT (0602)
                error detect
    AICA TEST
        Sound RAM (01xx)
            Pattern R/W check (0101)
                ok
        Register (02xx)
            CH Data (0201)
                ok
            EXT Input (0202)
                ok
            DSP Data (0203)
                ok
        S_Clock (03xx)
            50MSEC (0301)
                NG -> ~0xa58 in 0x702814, must be > 0x889 and < 0x8b0
            25MSEC (0302)
                NG -> ~0x372 in 0x702814, must be > 0x443 and < 0x45a
        Timer (04xx)
            Timer A (0401)
                NG
            Timer B (0402)
                NG
            Timer C (0403)
                NG
        DMA (05xx)
            SRAM -> CH Reg (0501)
                ok
            SRAM -> Comm Reg (0502)
                ok
            SRAM -> DSP Reg (0503)
                ok
            CH Reg -> SRAM (0504)
                ok
            Comm Reg -> SRAM (0505)
                ok
            DSP Reg -> SRAM (0506)
                ok
            Clear SRAM (0507)
                ok
            Clear CH Reg (0508)
                ok
            Clear Comm Reg (0509)
                ok
            Clear DSP Reg (050a)
                ok
        Interrupt (06xx)
            Sampling clock (0601)
                NG (irq 0x400)
            Timer A (0602)
                randomly NG/ok
            Timer B (0603)
                ok
            Timer C (0604)
                ok
            DMA End (0605)
                ok
            Midi Out (0606)
                NG
            Main CPU (0607)
                ok
        RTC (07xx)
            Write Protect (0701)
                ok
            RW Comp (0702)
                ok
            Clock (0703)
                NG
        ARM7 (08xx)
            Load & Start (0801)
                NG
            Timer & Intr (0802)
                NG
            DMA (0803)
                NG
            Ch-Reg R/W (0804)
                ok
            SRAM incr (0805)
                NG
            SRAM pattern (0806)
                ok
        EG (09xx)
            LSA-Reg Left (0901)
                ok/NG
            LSA-Reg Right (0902)
                ok/NG
            LSA-Reg Left & Right (0903)
                ok/NG
        MIDI (0axx)
            OEMP bit (0a01)
                NG
            OFLL bit (0a02)
                NG
    PVRi/f test
        DMA (01xx)
            CPU trig (0101)
                ok
            INT trig
                ok
        Interrupt (02xx)
            PVR DMA end Int (0201)
                ok
            PVR DMA IA Int (0202)
                NG
            PVR DMA end (0203)
                NG
    Flash test:
        (SH-4 jumps to la la land as soon as this is started)


*/

#include "emu.h"
#include "cpu/arm7/arm7.h"
#include "cpu/sh4/sh4.h"
#include "cpu/arm7/arm7core.h"
#include "sound/aica.h"
#include "machine/aicartc.h"
#include "includes/dc.h"
#include "includes/dccons.h"
#include "imagedev/chd_cd.h"
#include "machine/dc-ctrl.h"
#include "machine/gdrom.h"

#define CPU_CLOCK (200000000)

READ64_MEMBER(dc_cons_state::dcus_idle_skip_r )
{
	//if (space.device().safe_pc()==0xc0ba52a)
	//  space.device().execute().spin_until_time(attotime::from_usec(2500));
	//  device_spinuntil_int(&space.device());

	return dc_ram[0x2303b0/8];
}

READ64_MEMBER(dc_cons_state::dcjp_idle_skip_r )
{
	//if (space.device().safe_pc()==0xc0bac62)
	//  space.device().execute().spin_until_time(attotime::from_usec(2500));
	//  device_spinuntil_int(&space.device());

	return dc_ram[0x2302f8/8];
}

DRIVER_INIT_MEMBER(dc_cons_state,dc)
{
	dreamcast_atapi_init();
}

DRIVER_INIT_MEMBER(dc_cons_state,dcus)
{
	m_maincpu->space(AS_PROGRAM).install_read_handler(0xc2303b0, 0xc2303b7, read64_delegate(FUNC(dc_cons_state::dcus_idle_skip_r),this));

	DRIVER_INIT_CALL(dc);
}

DRIVER_INIT_MEMBER(dc_cons_state,dcjp)
{
	m_maincpu->space(AS_PROGRAM).install_read_handler(0xc2302f8, 0xc2302ff, read64_delegate(FUNC(dc_cons_state::dcjp_idle_skip_r),this));

	DRIVER_INIT_CALL(dc);
}

READ64_MEMBER(dc_cons_state::dc_pdtra_r )
{
	UINT64 out = PCTRA<<32;

	out |= PDTRA & ~0x0103;

	// if both bits are inputs
	if (!(PCTRA & 0x5))
	{
		out |= 0x03;
	}

	// one's input one's output, always pull up both bits
	if (((PCTRA & 5) == 1) || ((PCTRA & 5) == 4))
	{
		if (PDTRA & 3)
		{
			out |= 0x03;
		}
	}

	/*
	cable setting, (0-1) VGA, (2) TV RGB (3) TV VBS/Y + S/C.
	Note: several games doesn't like VGA setting (i.e. Idol Janshi wo Tsukucchaou, Airforce Delta), so hard-wire it to most common setting for now.
	*/
	out |= ioport("SCREEN_TYPE")->read() << 8;

	return out;
}

WRITE64_MEMBER(dc_cons_state::dc_pdtra_w )
{
	PCTRA = (data>>16) & 0xffff;
	PDTRA = (data & 0xffff);
}

READ64_MEMBER(dc_cons_state::dc_arm_r )
{
	return *((UINT64 *)dc_sound_ram.target()+offset);
}

WRITE64_MEMBER(dc_cons_state::dc_arm_w )
{
	COMBINE_DATA((UINT64 *)dc_sound_ram.target() + offset);
}

#if 0
READ8_MEMBER(dc_cons_state::dc_flash_r)
{
	return m_dcflash->read(offset);
}

WRITE8_MEMBER(dc_cons_state::dc_flash_w)
{
	m_dcflash->write(offset,data);
}
#endif

static ADDRESS_MAP_START( dc_map, AS_PROGRAM, 64, dc_cons_state )
	AM_RANGE(0x00000000, 0x001fffff) AM_ROM AM_WRITENOP             // BIOS
	AM_RANGE(0x00200000, 0x0021ffff) AM_ROM AM_REGION("dcflash",0)//AM_READWRITE8(dc_flash_r,dc_flash_w, U64(0xffffffffffffffff))
	AM_RANGE(0x005f6800, 0x005f69ff) AM_READWRITE(dc_sysctrl_r, dc_sysctrl_w )
	AM_RANGE(0x005f6c00, 0x005f6cff) AM_DEVICE32( "maple_dc", maple_dc_device, amap, U64(0xffffffffffffffff) )
	AM_RANGE(0x005f7000, 0x005f701f) AM_DEVREADWRITE16("ata", ata_interface_device, read_cs1, write_cs1, U64(0x0000ffff0000ffff) )
	AM_RANGE(0x005f7080, 0x005f709f) AM_DEVREADWRITE16("ata", ata_interface_device, read_cs0, write_cs0, U64(0x0000ffff0000ffff) )
	AM_RANGE(0x005f7400, 0x005f74ff) AM_READWRITE32(dc_mess_g1_ctrl_r, dc_mess_g1_ctrl_w, U64(0xffffffffffffffff) )
	AM_RANGE(0x005f7800, 0x005f78ff) AM_READWRITE(dc_g2_ctrl_r, dc_g2_ctrl_w )
	AM_RANGE(0x005f7c00, 0x005f7cff) AM_DEVICE32("powervr2", powervr2_device, pd_dma_map, U64(0xffffffffffffffff))
	AM_RANGE(0x005f8000, 0x005f9fff) AM_DEVICE32("powervr2", powervr2_device, ta_map, U64(0xffffffffffffffff))
	AM_RANGE(0x00600000, 0x006007ff) AM_READWRITE(dc_modem_r, dc_modem_w )
	AM_RANGE(0x00700000, 0x00707fff) AM_READWRITE32(dc_aica_reg_r, dc_aica_reg_w, U64(0xffffffffffffffff))
	AM_RANGE(0x00710000, 0x0071000f) AM_MIRROR(0x02000000) AM_DEVREADWRITE16("aicartc", aicartc_device, read, write, U64(0x0000ffff0000ffff) )
	AM_RANGE(0x00800000, 0x009fffff) AM_READWRITE(dc_arm_r, dc_arm_w )
//  AM_RANGE(0x01000000, 0x01ffffff) G2 Ext Device #1
//  AM_RANGE(0x02700000, 0x02707fff) AICA reg mirror
//  AM_RANGE(0x02800000, 0x02ffffff) AICA wave mem mirror

//  AM_RANGE(0x03000000, 0x03ffffff) G2 Ext Device #2

	/* Area 1 */
	AM_RANGE(0x04000000, 0x04ffffff) AM_RAM AM_SHARE("dc_texture_ram")      // texture memory 64 bit access
	AM_RANGE(0x05000000, 0x05ffffff) AM_RAM AM_SHARE("frameram") // apparently this actually accesses the same memory as the 64-bit texture memory access, but in a different format, keep it apart for now

	/* Area 3 */
	AM_RANGE(0x0c000000, 0x0cffffff) AM_RAM AM_SHARE("dc_ram")
	AM_RANGE(0x0d000000, 0x0dffffff) AM_RAM AM_SHARE("dc_ram")// extra ram on Naomi (mirror on DC)
	AM_RANGE(0x0e000000, 0x0effffff) AM_RAM AM_SHARE("dc_ram")// mirror
	AM_RANGE(0x0f000000, 0x0fffffff) AM_RAM AM_SHARE("dc_ram")// mirror

	/* Area 4 */
	AM_RANGE(0x10000000, 0x107fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_poly_w)
	AM_RANGE(0x10800000, 0x10ffffff) AM_DEVWRITE8("powervr2", powervr2_device, ta_fifo_yuv_w, U64(0xffffffffffffffff))
	AM_RANGE(0x11000000, 0x117fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath0_w) AM_MIRROR(0x00800000)  // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE0 register - cannot be written directly, only through dma / store queue

	AM_RANGE(0x12000000, 0x127fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_fifo_poly_w)
	AM_RANGE(0x12800000, 0x12ffffff) AM_DEVWRITE8("powervr2", powervr2_device, ta_fifo_yuv_w, U64(0xffffffffffffffff))
	AM_RANGE(0x13000000, 0x137fffff) AM_DEVWRITE("powervr2", powervr2_device, ta_texture_directpath1_w) AM_MIRROR(0x00800000) // access to texture / framebuffer memory (either 32-bit or 64-bit area depending on SB_LMMODE1 register - cannot be written directly, only through dma / store queue

//  AM_RANGE(0x14000000, 0x17ffffff) G2 Ext Device #3

	AM_RANGE(0x8c000000, 0x8cffffff) AM_RAM AM_SHARE("dc_ram")  // another RAM mirror

	AM_RANGE(0xa0000000, 0xa01fffff) AM_ROM AM_REGION("maincpu", 0)
ADDRESS_MAP_END

static ADDRESS_MAP_START( dc_port, AS_IO, 64, dc_cons_state )
	AM_RANGE(0x00000000, 0x00000007) AM_READWRITE(dc_pdtra_r, dc_pdtra_w )
ADDRESS_MAP_END

static ADDRESS_MAP_START( dc_audio_map, AS_PROGRAM, 32, dc_cons_state )
	ADDRESS_MAP_UNMAP_HIGH
	AM_RANGE(0x00000000, 0x001fffff) AM_RAM AM_SHARE("dc_sound_ram")        /* shared with SH-4 */
	AM_RANGE(0x00800000, 0x00807fff) AM_READWRITE(dc_arm_aica_r, dc_arm_aica_w)
ADDRESS_MAP_END

static INPUT_PORTS_START( dc )
	PORT_START("P1:0")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(1) PORT_NAME("P1 RIGHT")
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(1) PORT_NAME("P1 LEFT")
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(1) PORT_NAME("P1 DOWN")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(1) PORT_NAME("P1 UP")
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START1 ) PORT_NAME("P1 START")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 A")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P1 C")

	PORT_START("P1:1")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 2nd directional pad
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P1 D")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 X")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_NAME("P1 Y")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P1 Z")

	PORT_START("P1:A0")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P1 R") PORT_PLAYER(1)

	PORT_START("P1:A1")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P1 L") PORT_PLAYER(1)

	PORT_START("P1:A2")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(1)

	PORT_START("P1:A3")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(1)

	//A4 - A5, second analog stick, unused on DC

	PORT_START("P2:0")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(2) PORT_NAME("P2 RIGHT")
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(2) PORT_NAME("P2 LEFT")
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(2) PORT_NAME("P2 DOWN")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(2) PORT_NAME("P2 UP")
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START2 ) PORT_NAME("P2 START")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 A")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P2 C")

	PORT_START("P2:1")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 2nd directional pad
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P1 D")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 X")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_NAME("P2 Y")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P1 Z")

	PORT_START("P2:A0")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P2 R") PORT_PLAYER(2)

	PORT_START("P2:A1")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P2 L") PORT_PLAYER(2)

	PORT_START("P2:A2")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(2)

	PORT_START("P2:A3")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(2)

	//A4 - A5, second analog stick, unused on DC

	PORT_START("P3:0")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(3) PORT_NAME("P3 RIGHT")
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(3) PORT_NAME("P3 LEFT")
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(3) PORT_NAME("P3 DOWN")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(3) PORT_NAME("P3 UP")
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START3 ) PORT_NAME("P3 START")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 A")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P3 C")

	PORT_START("P3:1")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 2nd directional pad
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P3 D")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 X")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(3) PORT_NAME("P3 Y")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P3 Z")

	PORT_START("P3:A0")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P3 R") PORT_PLAYER(3)

	PORT_START("P3:A1")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P3 L") PORT_PLAYER(3)

	PORT_START("P3:A2")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(3)

	PORT_START("P3:A3")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(3)

	//A4 - A5, second analog stick, unused on DC

	PORT_START("P4:0")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_PLAYER(4) PORT_NAME("P4 RIGHT")
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_PLAYER(4) PORT_NAME("P4 LEFT")
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_PLAYER(4) PORT_NAME("P4 DOWN")
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY PORT_PLAYER(4) PORT_NAME("P4 UP")
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START4 ) PORT_NAME("P4 START")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4) PORT_NAME("P4 A")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4) PORT_NAME("P4 B")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P4 C")

	PORT_START("P4:1")
	PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // 2nd directional pad
	PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED )
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P3 D")
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4) PORT_NAME("P4 X")
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(4) PORT_NAME("P4 Y")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) //PORT_NAME("P3 Z")

	PORT_START("P4:A0")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL2 ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P4 R") PORT_PLAYER(4)

	PORT_START("P4:A1")
	PORT_BIT( 0xff, 0x00, IPT_PEDAL ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_NAME("P4 L") PORT_PLAYER(4)

	PORT_START("P4:A2")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(4)

	PORT_START("P4:A3")
	PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00,0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(10) PORT_CENTERDELTA(10) PORT_PLAYER(4)

	//A4 - A5, second analog stick, unused on DC

	PORT_START("MAMEDEBUG")
	PORT_DIPNAME( 0x01, 0x00, "Bilinear Filtering" )
	PORT_DIPSETTING(    0x00, DEF_STR( Off ) )
	PORT_DIPSETTING(    0x01, DEF_STR( On ) )

	PORT_START("SCREEN_TYPE")
	PORT_CONFNAME( 0x01, 0x01, "Screen Connection Type" )
	PORT_CONFSETTING(    0x00, "VGA" )
	PORT_CONFSETTING(    0x01, "Composite" )
INPUT_PORTS_END

MACHINE_RESET_MEMBER(dc_cons_state,dc_console)
{
	device_t *aica = machine().device("aica");
	dc_state::machine_reset();
	aica_set_ram_base(aica, dc_sound_ram, 2*1024*1024);
}

WRITE_LINE_MEMBER(dc_cons_state::aica_irq)
{
	m_soundcpu->set_input_line(ARM7_FIRQ_LINE, state ? ASSERT_LINE : CLEAR_LINE);
}

WRITE_LINE_MEMBER(dc_cons_state::sh4_aica_irq)
{
	if(state)
		dc_sysctrl_regs[SB_ISTEXT] |= IST_EXT_AICA;
	else
		dc_sysctrl_regs[SB_ISTEXT] &= ~IST_EXT_AICA;

	dc_update_interrupt_status();
}

static const aica_interface dc_aica_interface =
{
	TRUE,
	0,
	DEVCB_DRIVER_LINE_MEMBER(dc_cons_state,aica_irq),
	DEVCB_DRIVER_LINE_MEMBER(dc_cons_state,sh4_aica_irq)
};

static const struct sh4_config sh4cpu_config = {  1,  0,  1,  0,  0,  0,  1,  1,  0, CPU_CLOCK };

static MACHINE_CONFIG_FRAGMENT( gdrom_config )
	MCFG_DEVICE_MODIFY("cdda")
	MCFG_SOUND_ROUTE(0, "^^^^lspeaker", 1.0)
	MCFG_SOUND_ROUTE(1, "^^^^rspeaker", 1.0)
MACHINE_CONFIG_END

static MACHINE_CONFIG_START( dc, dc_cons_state )
	/* basic machine hardware */
	MCFG_CPU_ADD("maincpu", SH4LE, CPU_CLOCK)
	MCFG_CPU_CONFIG(sh4cpu_config)
	MCFG_CPU_PROGRAM_MAP(dc_map)
	MCFG_CPU_IO_MAP(dc_port)
	MCFG_TIMER_DRIVER_ADD_SCANLINE("scantimer", dc_state, dc_scanline, "screen", 0, 1)

	MCFG_CPU_ADD("soundcpu", ARM7, ((XTAL_33_8688MHz*2)/3)/8)   // AICA bus clock is 2/3rds * 33.8688.  ARM7 gets 1 bus cycle out of each 8.
	MCFG_CPU_PROGRAM_MAP(dc_audio_map)

	MCFG_MACHINE_RESET_OVERRIDE(dc_cons_state,dc_console )

//  MCFG_MACRONIX_29LV160TMC_ADD("dcflash")

	MCFG_MAPLE_DC_ADD( "maple_dc", "maincpu", dc_maple_irq )
	MCFG_DC_CONTROLLER_ADD("dcctrl0", "maple_dc", 0, ":P1:0", ":P1:1", ":P1:A0", ":P1:A1", ":P1:A2", ":P1:A3", ":P1:A4", ":P1:A5")
	MCFG_DC_CONTROLLER_ADD("dcctrl1", "maple_dc", 1, ":P2:0", ":P2:1", ":P2:A0", ":P2:A1", ":P2:A2", ":P2:A3", ":P2:A4", ":P2:A5")
	MCFG_DC_CONTROLLER_ADD("dcctrl2", "maple_dc", 2, ":P3:0", ":P3:1", ":P3:A0", ":P3:A1", ":P3:A2", ":P3:A3", ":P3:A4", ":P3:A5")
	MCFG_DC_CONTROLLER_ADD("dcctrl3", "maple_dc", 3, ":P4:0", ":P4:1", ":P4:A0", ":P4:A1", ":P4:A2", ":P4:A3", ":P4:A4", ":P4:A5")

	/* video hardware */
	MCFG_SCREEN_ADD("screen", RASTER)
	MCFG_SCREEN_RAW_PARAMS(13458568*2, 857, 0, 640, 524, 0, 480) /* TODO: where pclk actually comes? */
	MCFG_SCREEN_UPDATE_DEVICE("powervr2", powervr2_device, screen_update)
	MCFG_PALETTE_ADD("palette", 0x1000)
	MCFG_POWERVR2_ADD("powervr2", WRITE8(dc_state, pvr_irq))

	MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
	MCFG_SOUND_ADD("aica", AICA, 0)
	MCFG_SOUND_CONFIG(dc_aica_interface)
	MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
	MCFG_SOUND_ROUTE(0, "rspeaker", 1.0)

	MCFG_AICARTC_ADD("aicartc", XTAL_32_768kHz)

	MCFG_DEVICE_ADD("ata", ATA_INTERFACE, 0)
	MCFG_ATA_INTERFACE_IRQ_HANDLER(WRITELINE(dc_cons_state, ata_interrupt))

	MCFG_DEVICE_MODIFY("ata:0")
	MCFG_SLOT_OPTION_ADD("gdrom", GDROM)
	MCFG_SLOT_OPTION_MACHINE_CONFIG("gdrom", gdrom_config)
	MCFG_SLOT_DEFAULT_OPTION("gdrom")
MACHINE_CONFIG_END

/*
PsyMan notes:

Here's a basic report on the Dreamcast boot files used in MAME (BIOS+Flash pairs):

-----

"dc101d_us.bin", 0x000000, 0x200000, CRC(89f2b1a1) SHA1(8951d1bb219ab2ff8583033d2119c899cc81f18c) )   // BIOS
This is a proper European and USA BIOS. It's even possible that it was used at a later point for Japanese systems.
It only has minor differences compared to BIOS 1.01c.


"dcus_ntsc.bin", 0x000000, 0x020000, BAD_DUMP CRC(c611b498) SHA1(94d44d7f9529ec1642ba3771ed3c5f756d5bc872) )   // Flash
Checking at 0x0001A000 and the mirrored data at 0x0001A0A0 gives away that this is hacked from a PAL/European flash file.
The broadcast (0x0001A004) is also set at 50Hz which is a PAL standard.


"dc101d_eu.bin", 0x000000, 0x200000, CRC(a2564fad) SHA1(edc5d3d70a93c935703d26119b37731fd317d2bf),ROM_BIOS(1))   // BIOS
This BIOS has Chinese language added. So either this is a bad BIOS or Dreamcast was actually officially released there.


"dc101c_eu.bin", 0x000000, 0x200000, CRC(2f551bc5) SHA1(1ede8d5be49116a4c6f3fe0961175469537a0434),ROM_BIOS(2))   // BIOS
This seems to be a proper European and USA BIOS. It's even possible that it was used at a later point for Japanese systems.
It only has minor differences compared to BIOS 1.01d.



"dceu_pal.bin", 0x000000, 0x020000, BAD_DUMP CRC(b7e5aeeb) SHA1(11e02433e13b793ec7ffe0ae2356750bb8a575b4) )    // Flash
This appears to be a valid PAL/European flash. It's unknown if the data at 0x0001A0A0 (from 0x0001A000) should be mirrored there.
Maybe a game does this mirroring or maybe it's there by default. It's certain that some games wrote to this flash though.


"dc1004jp.bin", 0x000000, 0x200000, CRC(5454841f) SHA1(1ea132c0fbbf07ef76789eadc07908045c089bd6) )    // BIOS
This seems to be a proper Japanese BIOS. This BIOS was used at least by early Japanese Dreamcast models.
Code-wise, it has major differences compared to later BIOS versions.


"dcjp_ntsc.bin", 0x000000, 0x020000, CRC(5F92BF76) SHA1(BE78B834F512AB2CF3D67B96E377C9F3093FF82A) )  // Flash
Checking at 0x0001A000 and the mirrored data at 0x0001A0A0 gives away that this is hacked from a PAL/European flash file.
The broadcast (0x0001A004) is also set at 50Hz which is a PAL standard.

-----


From all the aforementioned files the only personally verified one is "dc101d_us.bin", CRC(89f2b1a1).
The resulting file was dumped twice, once from an NTSC/USA system and once from a PAL/EUR system. Both files had a side by side byte match.
*/

ROM_START(dc)
	ROM_REGION(0x200000, "maincpu", 0)
	ROM_LOAD( "dc101d_us.bin", 0x000000, 0x200000, CRC(89f2b1a1) SHA1(8951d1bb219ab2ff8583033d2119c899cc81f18c) )   // BIOS

	ROM_REGION(0x020000, "dcflash", 0)
	ROM_LOAD( "dcus_ntsc.bin", 0x000000, 0x020000, BAD_DUMP CRC(c611b498) SHA1(94d44d7f9529ec1642ba3771ed3c5f756d5bc872) )   // Flash
	ROM_FILL( 0x1a004, 1, 0x30 ) // patch broadcast back to NTSC
ROM_END

ROM_START( dceu )
	ROM_REGION(0x200000, "maincpu", 0)
	ROM_SYSTEM_BIOS(0, "101d", "v1.01d")
	ROMX_LOAD( "dc101d_eu.bin", 0x000000, 0x200000, CRC(a2564fad) SHA1(edc5d3d70a93c935703d26119b37731fd317d2bf),ROM_BIOS(1))   // BIOS
	ROM_SYSTEM_BIOS(1, "101c", "v1.01c")
	ROMX_LOAD( "dc101c_eu.bin", 0x000000, 0x200000, CRC(2f551bc5) SHA1(1ede8d5be49116a4c6f3fe0961175469537a0434),ROM_BIOS(2))   // BIOS

	ROM_REGION(0x020000, "dcflash", 0)
	ROM_LOAD( "dceu_pal.bin", 0x000000, 0x020000, BAD_DUMP CRC(b7e5aeeb) SHA1(11e02433e13b793ec7ffe0ae2356750bb8a575b4) )    // Flash
ROM_END

ROM_START( dcjp )
	ROM_REGION(0x200000, "maincpu", 0)
	ROM_LOAD( "dc1004jp.bin", 0x000000, 0x200000, CRC(5454841f) SHA1(1ea132c0fbbf07ef76789eadc07908045c089bd6) )    // BIOS

	ROM_REGION(0x020000, "dcflash", 0)
	/* ROM_LOAD( "dcjp_ntsc.bad", 0x000000, 0x020000, BAD_DUMP CRC(307a7035) SHA1(1411423a9d071340ea52c56e19c1aafc4e1309ee) )      // Hacked Flash */
	ROM_LOAD( "dcjp_ntsc.bin", 0x000000, 0x020000, BAD_DUMP CRC(5F92BF76) SHA1(BE78B834F512AB2CF3D67B96E377C9F3093FF82A) )  // Flash
	ROM_FILL( 0x1a004, 1, 0x30 ) // patch broadcast back to NTSC
ROM_END

ROM_START( dcdev )
	ROM_REGION(0x200000, "maincpu", 0)
	ROM_LOAD( "hkt-0120.bin", 0x000000, 0x200000, CRC(2186E0E5) SHA1(6BD18FB83F8FDB56F1941E079580E5DD672A6DAD) )        // BIOS

	ROM_REGION(0x020000, "dcflash", 0)
	ROM_LOAD( "hkt-0120-flash.bin", 0x000000, 0x020000, CRC(7784C304) SHA1(31EF57F550D8CD13E40263CBC657253089E53034) )  // Flash
ROM_END

ROM_START( dcprt )
	ROM_REGION(0x200000, "maincpu", 0)
	ROM_LOAD( "katana-set5-v0.41-98-08-27.bin", 0x000000, 0x200000, CRC(485877bd) SHA1(dc1af1f1248ffa87d57bc5ef2ea41aac95ecfc5e) ) // BIOS

	ROM_REGION(0x020000, "dcflash", 0)
	ROM_LOAD( "dcjp_ntsc.bin", 0x000000, 0x020000, CRC(5F92BF76) SHA1(BE78B834F512AB2CF3D67B96E377C9F3093FF82A) )  // Flash
ROM_END

/*    YEAR  NAME    PARENT  COMPAT  MACHINE INPUT   INIT      COMPANY FULLNAME */
CONS( 1999, dc,     dcjp,   0,      dc,     dc, dc_cons_state,     dcus,   "Sega", "Dreamcast (USA, NTSC)", GAME_NOT_WORKING )
CONS( 1998, dcjp,   0,      0,      dc,     dc, dc_cons_state,     dcjp,   "Sega", "Dreamcast (Japan, NTSC)", GAME_NOT_WORKING )
CONS( 1999, dceu,   dcjp,   0,      dc,     dc, dc_cons_state,     dcus,   "Sega", "Dreamcast (Europe, PAL)", GAME_NOT_WORKING )
CONS( 1998, dcdev,  dcjp,   0,      dc,     dc, dc_cons_state,     dc,     "Sega", "HKT-0120 Sega Dreamcast Development Box", GAME_NOT_WORKING )
CONS( 1998, dcprt,  dcjp,   0,      dc,     dc, dc_cons_state,     dcjp,   "Sega", "Katana Set 5 Prototype", GAME_NOT_WORKING )