summaryrefslogblamecommitdiffstats
path: root/src/mame/drivers/nexus3d.cpp
blob: 695c99a9a3e6cafd2b016c00101a0da55cc9e4f2 (plain) (tree)
1
2
3
4
5
6
7
8
                       
                                

                                                                         
                                             
 
                           
 



                                                                





                              
                             
                   
                   
                     
 

                             
 
 


                                          
                                                                                       
                                                    
                                            




                                            
           
 

                                             

                             

        
                                              

                                                
                                                    

                                                  
 



                                           
 
                                              

                                              

                                                                                                       
                                           
 






                                                  
 



                                                  
 











                                               

  










                                                                                                             
 


                                                                                     
 








                                                
 





                                                
 



                                                                      

 
 





                                         
 

















                                           
 
























                                                                                                                 
 

                                    
 



































                                                                                    

                                                                         






                                                                         
 

                                                                   
 
                                                           
 



                                                       

                


                                                                                           
 








                                                                                                           
                                         

                                            




                                                                                                                 
 
                                                                          
 
                                      

                                                                                                 
 

                                                                               

                                                             
 
 

                                   

                                                          
 

                                                          
 


                                                          
 
                                   
 

                                                                                                                  

 
                                   
 

                                                                           

 
                                               
 






                            

 

                                                   
                                    

                                                                        
 
                                                     
                                                                                                                        


                                                                          
 
                                                            
 
                                        
 

 

                    
                                                                  
                                                                                                                            












                                                                                                                                                            
                     
                                                                  
                                                                                                                               








                                                                                                                   
                                                                                                                                                            

       
                                  
 










                                                             

 

                                                                                                                                  
// license:BSD-3-Clause
// copyright-holders:Scott Stone
/************************************************************************

    NEXUS 3D Version 1.0 Board from Interpark

    Games on this platform:

    Arcana Heart FULL, Examu Inc, 2006

    MagicEyes VRENDER 3D Soc (200 MHz ARM920T CPU / GFX / Sound)
    Also Has 2x QDSP QS1000 for sound

*/

#include "emu.h"
#include "cpu/arm7/arm7.h"
#include "cpu/arm7/arm7core.h"
#include "machine/serflash.h"
#include "emupal.h"
#include "screen.h"
#include "debugger.h"

//#include "machine/i2cmem.h"



class nexus3d_state : public driver_device
{
public:
	nexus3d_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag),
		m_maincpu(*this, "maincpu"),
		m_mainram(*this, "mainram"),
		m_fbram(*this, "fbram"),
		m_serflash(*this, "flash"),
		m_screen(*this, "screen"),
		m_palette(*this, "palette")
	{ }

	void nexus3d(machine_config &config);

	void init_acheart();
	void init_acheartf();

private:
	required_device<cpu_device> m_maincpu;
	required_shared_ptr<uint32_t> m_mainram;
	required_shared_ptr<uint32_t> m_fbram;
	required_device<serflash_device> m_serflash;
	required_device<screen_device> m_screen;
	required_device<palette_device> m_palette;

//  DECLARE_READ32_MEMBER(nexus3d_unk2_r);
//  DECLARE_READ32_MEMBER(nexus3d_unk3_r);
//  DECLARE_WRITE32_MEMBER(nexus3d_unk2_w);
//  DECLARE_WRITE32_MEMBER(nexus3d_unk3_w);

	virtual void machine_start() override;
	virtual void machine_reset() override;
	virtual void video_start() override;
	uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
	DECLARE_WRITE_LINE_MEMBER(screen_vblank);
	void nexus3d_map(address_map &map);

	uint32_t m_intpend, m_intmask, m_intlevel;
	DECLARE_READ32_MEMBER(int_pending_r);
	DECLARE_WRITE32_MEMBER(int_ack_w);
	DECLARE_READ32_MEMBER(int_level_r);
	DECLARE_READ32_MEMBER(int_mask_r);
	DECLARE_WRITE32_MEMBER(int_mask_w);
	void IntReq(int level);

	DECLARE_READ32_MEMBER(vrender3d_status_r);
	DECLARE_WRITE32_MEMBER(rop_data_w);
	DECLARE_WRITE16_MEMBER(rop_register_w);
	DECLARE_READ16_MEMBER(rop_status_r);

	DECLARE_READ32_MEMBER(timer_status_r);
	DECLARE_WRITE32_MEMBER(timer_status_w);
	DECLARE_READ32_MEMBER(timer_count_r);
	DECLARE_WRITE32_MEMBER(timer_count_w);
	uint32_t m_timer_status;
	uint32_t m_timer_count;
	emu_timer  *m_timer;
	TIMER_CALLBACK_MEMBER(timercb);
	bool m_timer_irq;
	bool m_timer_result;

	DECLARE_READ32_MEMBER(crtc_vblank_r);
};

void nexus3d_state::video_start()
{
	// ...
}

uint32_t nexus3d_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	uint16_t *fbram = reinterpret_cast<uint16_t *>(m_fbram.target());
	const int width = 640;

	uint16_t *visible = fbram + (m_screen->frame_number() & 1) * (0x96000/2);

	uint32_t const dx = cliprect.left();
	for (int y = cliprect.top(); y <= cliprect.bottom(); y++)
		std::copy_n(&visible[(y * width) + dx], width, &bitmap.pix16(y, dx));

	return 0;
}

READ32_MEMBER(nexus3d_state::vrender3d_status_r)
{
	return (0xbf<<16) | m_screen->vpos();
}

void nexus3d_state::IntReq(int level)
{
	if (level != -1)
	{
		m_intlevel = level;
		m_intpend |= 1 << level;
	}
	uint32_t inten = m_intmask ^ 0xffffffff;

	if (m_intpend & inten)
		m_maincpu->set_input_line(ARM7_IRQ_LINE, ASSERT_LINE);
	else
		m_maincpu->set_input_line(ARM7_IRQ_LINE, CLEAR_LINE);
}


READ32_MEMBER(nexus3d_state::int_mask_r)
{
	return m_intmask;
}

WRITE32_MEMBER(nexus3d_state::int_mask_w)
{
	COMBINE_DATA(&m_intmask);
}

READ32_MEMBER(nexus3d_state::int_pending_r)
{
	return m_intpend;
}

WRITE32_MEMBER(nexus3d_state::int_ack_w)
{
	m_intpend &= ~data;
	IntReq(-1);
}

READ32_MEMBER(nexus3d_state::int_level_r)
{
	return m_intlevel;
}

WRITE16_MEMBER(nexus3d_state::rop_register_w)
{
	//printf("%04x REG\n",data);
}

WRITE32_MEMBER(nexus3d_state::rop_data_w)
{
	//printf("%04x DATA\n",data);
}

READ16_MEMBER(nexus3d_state::rop_status_r)
{
	return machine().rand() & 0x1000;
}

READ32_MEMBER(nexus3d_state::timer_status_r)
{
	uint32_t res = (m_timer_status & ~0x30) | ((m_timer_irq == true) << 5) | ((m_timer_result == true) << 4);
	return res;
}

WRITE32_MEMBER(nexus3d_state::timer_status_w)
{
	COMBINE_DATA(&m_timer_status);
	//printf("%08x %08x\n",m_timer_status, m_timer_count);

	if (m_timer_status & 0x20)
		m_timer_irq = false;

	if (m_timer_status & 8)
	{
		m_timer_result = false;
		// TODO: unknown formula, should be counter / (bits 0-1 and maybe 2)
		attotime period = attotime::from_hz(14318180 * 3);
		m_timer->adjust(period);
	}
}

READ32_MEMBER(nexus3d_state::timer_count_r)
{
	return m_timer_count;
}

WRITE32_MEMBER(nexus3d_state::timer_count_w)
{
	COMBINE_DATA(&m_timer_count);
}

TIMER_CALLBACK_MEMBER(nexus3d_state::timercb)
{
	m_timer_result = true;
	m_timer_status &= ~8;
	#if 0
	if (m_timer_irq == false && m_timer_status & 0x10)
	{
		m_timer_irq = true;
		// lv 10 (the only enabled irq at POST) should be UART
		IntReq(?);
	}
	#endif
}


READ32_MEMBER(nexus3d_state::crtc_vblank_r)
{
	uint16_t res = (m_screen->vblank()<<1) | (m_screen->hblank()<<0);

	return (res<<16);
}

void nexus3d_state::nexus3d_map(address_map &map)
{
	map(0x00000000, 0x01ffffff).ram().share("mainram");
	map(0x02000000, 0x023fffff).ram().share("fbram"); // boundary tbd

	map(0x03720000, 0x0373ffff).ram(); // 3d fifo, boundary tbd
	map(0x046c0000, 0x046fffff).ram(); // """

	map(0x60000000, 0x67ffffff).ram(); // color tables?

	// actually USB hubs (prints "USB STRAGE" if 0)
	map(0x8c000000, 0x8c000003).portr("IN0");
	map(0x8c800000, 0x8c800003).portr("IN1");
	map(0x8d000000, 0x8d000003).portr("IN2");

	// flash
	map(0x9C000000, 0x9C000003).r(m_serflash, FUNC(serflash_device::n3d_flash_r));
	map(0x9C000010, 0x9C000013).w(m_serflash, FUNC(serflash_device::n3d_flash_cmd_w));
	map(0x9C000018, 0x9C00001b).w(m_serflash, FUNC(serflash_device::n3d_flash_addr_w));

	// read on irq 9 service, unknown purpose
	map(0xc0000200, 0xc00002bf).nopr();

	// on irq, acknowledge happens to both 800 and 810 ports
	map(0xc0000800, 0xc0000803).nopw();
	map(0xc0000808, 0xc000080b).rw(FUNC(nexus3d_state::int_mask_r), FUNC(nexus3d_state::int_mask_w));
	map(0xc0000810, 0xc0000813).rw(FUNC(nexus3d_state::int_pending_r), FUNC(nexus3d_state::int_ack_w));
	map(0xc0000814, 0xc0000817).r(FUNC(nexus3d_state::int_level_r));

	// lots of accesses in this range
	// 0xc00018xx seems CRTC related
	// 0xc000091x loads a "gfx charset"?
	map(0xc0000910, 0xc0000913).w(FUNC(nexus3d_state::rop_data_w));
	map(0xc000091c, 0xc000091f).w(FUNC(nexus3d_state::rop_register_w)).umask32(0xffff0000);

	map(0xc0000d00, 0xc0000d03).rw(FUNC(nexus3d_state::timer_status_r), FUNC(nexus3d_state::timer_status_w));
	map(0xc0000d04, 0xc0000d07).rw(FUNC(nexus3d_state::timer_count_r), FUNC(nexus3d_state::timer_count_w));

	map(0xc0001844, 0xc0001847).r(FUNC(nexus3d_state::crtc_vblank_r));

//  map(0xc0000f40, 0xc0000f4f).ram();
//  map(0xC0000F44, 0xC0000F47) (nexus3d_unk2_r, nexus3d_unk2_w ) // often, status for something.
	map(0xc0000f4c, 0xc0000f4f).r(FUNC(nexus3d_state::rop_status_r)).umask32(0xffff0000);

	map(0xe0000014, 0xe0000017).r(FUNC(nexus3d_state::vrender3d_status_r));

//  map(0xe0000000, 0xe00000ff) General / Control registers
//  map(0xe0000300, 0xe00003ff) GTE constant vector registers

}

static INPUT_PORTS_START( nexus3d )
	PORT_START("IN0")
	PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START("IN1")
	PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )

	PORT_START("IN2")
	PORT_BIT( 0xffffffff, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END

void nexus3d_state::machine_start()
{
	m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(nexus3d_state::timercb),this), 0);

}

void nexus3d_state::machine_reset()
{
	// the first part of the flash ROM automatically gets copied to RAM
	memcpy(m_mainram, memregion("flash")->base(), 4 * 1024);
}

WRITE_LINE_MEMBER(nexus3d_state::screen_vblank)
{
	// rising edge
	if (state)
	{
		// EXTINT1?
		//IntReq(9);
		IntReq(1);
	}
}

void nexus3d_state::nexus3d(machine_config &config)
{
	/* basic machine hardware */
	ARM920T(config, m_maincpu, 200000000);
	m_maincpu->set_addrmap(AS_PROGRAM, &nexus3d_state::nexus3d_map);

	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
	m_screen->set_raw((XTAL(14'318'181)*2), 454*2, 0, 640, 262*2, 0, 480); // not accurate, needs CRTC understanding
	m_screen->set_screen_update(FUNC(nexus3d_state::screen_update));
	m_screen->screen_vblank().set(FUNC(nexus3d_state::screen_vblank));
	m_screen->set_palette("palette");

	PALETTE(config, "palette", palette_device::RGB_565);

	SERFLASH(config, m_serflash, 0);
}



ROM_START( acheart )
	ROM_REGION( 0x10800898, "flash", 0 ) /* ARM 32 bit code */
	ROM_LOAD( "arcanaheart.u1",     0x000000, 0x10800898, CRC(109bf439) SHA1(33fd39355923ef384d5eaeec8ae3f296509bde93) )

	ROM_REGION( 0x200000, "user2", 0 ) // QDSP stuff
	ROM_LOAD( "u38.bin",     0x000000, 0x200000, CRC(29ecfba3) SHA1(ab02c7a579a3c05a19b79e42342fd5ed84c7b046) )
	ROM_LOAD( "u39.bin",     0x000000, 0x200000, CRC(eef0b1ee) SHA1(5508e6b2f0ae1555662793313a05e94a87599890) )
	ROM_LOAD( "u44.bin",     0x000000, 0x200000, CRC(b9723bdf) SHA1(769090ada7375ecb3d0bc10e89fe74a8e89129f2) )
	ROM_LOAD( "u45.bin",     0x000000, 0x200000, CRC(1c6a3169) SHA1(34a2ca00a403dc1e3909ed1c55320cf2bbd9d49e) )
	ROM_LOAD( "u46.bin",     0x000000, 0x200000, CRC(1e8a7e73) SHA1(3270bc359b266e57debf8fd4283a46e08d679ae2) )

	ROM_REGION( 0x080000, "wavetable", ROMREGION_ERASEFF ) /* QDSP wavetable rom */
//  ROM_LOAD( "qs1001a",  0x000000, 0x80000, CRC(d13c6407) SHA1(57b14f97c7d4f9b5d9745d3571a0b7115fbe3176) ) // missing from this set, but should be the same
ROM_END


ROM_START( acheartf )
	ROM_REGION( 0x10800898, "flash", 0 ) /* ARM 32 bit code */
	ROM_LOAD( "arcanaheartfull.u1",     0x000000, 0x10800898, CRC(54b57a9d) SHA1(dee5a43b3aea854d2b98869dca74c57b66fb06eb))

	ROM_REGION( 0x200000, "user2", 0 ) // QDSP stuff
	ROM_LOAD( "u38.bin",     0x000000, 0x200000, CRC(29ecfba3) SHA1(ab02c7a579a3c05a19b79e42342fd5ed84c7b046) )
	ROM_LOAD( "u39.bin",     0x000000, 0x200000, CRC(eef0b1ee) SHA1(5508e6b2f0ae1555662793313a05e94a87599890) )
	ROM_LOAD( "u44.bin",     0x000000, 0x200000, CRC(b9723bdf) SHA1(769090ada7375ecb3d0bc10e89fe74a8e89129f2) )
	ROM_LOAD( "u45.bin",     0x000000, 0x200000, CRC(1c6a3169) SHA1(34a2ca00a403dc1e3909ed1c55320cf2bbd9d49e) )
	ROM_LOAD( "u46.bin",     0x000000, 0x200000, CRC(1e8a7e73) SHA1(3270bc359b266e57debf8fd4283a46e08d679ae2) )

	ROM_REGION( 0x080000, "wavetable", ROMREGION_ERASEFF ) /* QDSP wavetable rom */
//  ROM_LOAD( "qs1001a",  0x000000, 0x80000, CRC(d13c6407) SHA1(57b14f97c7d4f9b5d9745d3571a0b7115fbe3176) ) // missing from this set, but should be the same
ROM_END

void nexus3d_state::init_acheart()
{
	// 0x1230 BL <vector>
	// 0x1234 CMPS, #$0 <- if R0 = 1 then stops at 0x1244
}

void nexus3d_state::init_acheartf()
{
	// 0x1290 BL <vector>
	// 0x1294 CMPS, #$0 <- if R0 = 1 then stops at 0x1244

	// patch additional unknown check after $c0000a00
	// 0x107c serial?
}

GAME( 2005, acheart,  0, nexus3d, nexus3d, nexus3d_state, init_acheart,  ROT0, "Examu", "Arcana Heart",      MACHINE_IS_SKELETON )
GAME( 2006, acheartf, 0, nexus3d, nexus3d, nexus3d_state, init_acheartf, ROT0, "Examu", "Arcana Heart Full", MACHINE_IS_SKELETON )