// 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 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) { dc_state::machine_reset(); m_aica->set_ram_base(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 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_AICA_MASTER MCFG_AICA_IRQ_CB(WRITELINE(dc_cons_state, aica_irq)) MCFG_AICA_MAIN_IRQ_CB(WRITELINE(dc_cons_state, sh4_aica_irq)) 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 )