summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/interpro_sga.cpp
blob: 6c7eb8f21d70f11fca97b99fd346cf3a6c307a49 (plain) (tree)
1
2
3
4



                                      











                                                                              
                


                         
                     
 

                                               










































                                                                                                                                                  
 
 
                                                                              

                                                                                                                         

                                                            




                                        
                              









































                                      





                                        
                                           
 


                                                                       

                                        



                                                                                             


                                                                                      
                                                    

                         
     
                                                      
                                                                                        
         
                                         


                                                                                 
                                                          
                                                                                                                           
                    
                                                                                                                           
 

                                                              
                                                                          
         
      
 
// license:BSD-3-Clause
// copyright-holders:Patrick Mackinlay

/*
 * An implementation of the SGA (SRX Gate Array) device found in Intergraph
 * InterPro family systems. There is no public documentation on this device,
 * so the implementation is being built to follow the logic of the system boot
 * ROM and its diagnostic tests.
 *
 * Please be aware that code in here is not only broken, it's likely wrong in
 * many cases.
 *
 * TODO
 *   - too long to list
 */

#include "emu.h"
#include "interpro_sga.h"

#define VERBOSE 0
#include "logmacro.h"

void interpro_sga_device::map(address_map &map)
{
	map(0x00, 0x03).rw(FUNC(interpro_sga_device::gcsr_r), FUNC(interpro_sga_device::gcsr_w));
	map(0x04, 0x07).rw(FUNC(interpro_sga_device::ipoll_r), FUNC(interpro_sga_device::ipoll_w));
	map(0x08, 0x0b).rw(FUNC(interpro_sga_device::imask_r), FUNC(interpro_sga_device::imask_w));
	map(0x0c, 0x0f).rw(FUNC(interpro_sga_device::range_base_r), FUNC(interpro_sga_device::range_base_w));
	map(0x10, 0x13).rw(FUNC(interpro_sga_device::range_end_r), FUNC(interpro_sga_device::range_end_w));
	map(0x14, 0x17).rw(FUNC(interpro_sga_device::cttag_r), FUNC(interpro_sga_device::cttag_w));           // aka diag1
	map(0x18, 0x1b).rw(FUNC(interpro_sga_device::address_r), FUNC(interpro_sga_device::address_w));       // aka diag0
	map(0x1c, 0x1f).rw(FUNC(interpro_sga_device::dmacsr_r), FUNC(interpro_sga_device::dmacsr_w));
	map(0x20, 0x23).rw(FUNC(interpro_sga_device::edmacsr_r), FUNC(interpro_sga_device::edmacsr_w));       // esga
	map(0x24, 0x27).rw(FUNC(interpro_sga_device::reg6_range_r), FUNC(interpro_sga_device::reg6_range_w)); // esga

	map(0x80, 0x83).rw(FUNC(interpro_sga_device::ddpta0_r), FUNC(interpro_sga_device::ddpta0_w)); // dma 0 device page table address (esga)
	map(0x84, 0x87).rw(FUNC(interpro_sga_device::ddpad0_r), FUNC(interpro_sga_device::ddpad0_w)); // dma 0 device page address
	map(0x88, 0x8b).rw(FUNC(interpro_sga_device::ddoff0_r), FUNC(interpro_sga_device::ddoff0_w)); // dma 0 device page offset
	map(0x8c, 0x8f).rw(FUNC(interpro_sga_device::ddtc0_r), FUNC(interpro_sga_device::ddtc0_w));   // dma 0 device transfer context

	map(0x90, 0x93).rw(FUNC(interpro_sga_device::dspta0_r), FUNC(interpro_sga_device::dspta0_w)); // dma 0 SRX page table address (esga)
	map(0x94, 0x97).rw(FUNC(interpro_sga_device::dspad0_r), FUNC(interpro_sga_device::dspad0_w)); // dma 0 SRX page address
	map(0x98, 0x9b).rw(FUNC(interpro_sga_device::dsoff0_r), FUNC(interpro_sga_device::dsoff0_w)); // dma 0 SRX page offset
	map(0x9c, 0x9f).rw(FUNC(interpro_sga_device::dstc0_r), FUNC(interpro_sga_device::dstc0_w));   // dma 0 SRX transfer context

	map(0xa4, 0xa7).rw(FUNC(interpro_sga_device::dspad1_r), FUNC(interpro_sga_device::dspad1_w)); // dma 1 source page address
	map(0xa8, 0xab).rw(FUNC(interpro_sga_device::dsoff1_r), FUNC(interpro_sga_device::dsoff1_w)); // dma 1 source page offset
	map(0xac, 0xaf).rw(FUNC(interpro_sga_device::dstc1_r), FUNC(interpro_sga_device::dstc1_w));   // dma 1 source transfer count

	map(0xb4, 0xb7).rw(FUNC(interpro_sga_device::ddpad1_r), FUNC(interpro_sga_device::ddpad1_w)); // dma 1 destination page address
	map(0xb8, 0xbb).rw(FUNC(interpro_sga_device::ddoff1_r), FUNC(interpro_sga_device::ddoff1_w)); // dma 1 destination page offset
	map(0xbc, 0xbf).rw(FUNC(interpro_sga_device::ddtc1_r), FUNC(interpro_sga_device::ddtc1_w));   // dma 1 destination transfer count

	map(0xc0, 0xc3).rw(FUNC(interpro_sga_device::ddpta2_r), FUNC(interpro_sga_device::ddpta2_w)); // dma 2 device page table address (esga)
	map(0xc4, 0xc7).rw(FUNC(interpro_sga_device::ddpad2_r), FUNC(interpro_sga_device::ddpad2_w)); // dma 2 device page address
	map(0xc8, 0xcb).rw(FUNC(interpro_sga_device::ddoff2_r), FUNC(interpro_sga_device::ddoff2_w)); // dma 2 device page offset
	map(0xcc, 0xcf).rw(FUNC(interpro_sga_device::ddtc2_r), FUNC(interpro_sga_device::ddtc2_w));   // dma 2 device transfer context

	map(0xd0, 0xd3).rw(FUNC(interpro_sga_device::dspta2_r), FUNC(interpro_sga_device::dspta2_w)); // dma 2 SRX page table address (esga)
	map(0xd4, 0xd7).rw(FUNC(interpro_sga_device::dspad2_r), FUNC(interpro_sga_device::dspad2_w)); // dma 2 SRX page address
	map(0xd8, 0xdb).rw(FUNC(interpro_sga_device::dsoff2_r), FUNC(interpro_sga_device::dsoff2_w)); // dma 2 SRX page offset
	map(0xdc, 0xdf).rw(FUNC(interpro_sga_device::dstc2_r), FUNC(interpro_sga_device::dstc2_w));   // dma 2 SRX transfer context

	map(0xe0, 0xe3).rw(FUNC(interpro_sga_device::ddrd2_r), FUNC(interpro_sga_device::ddrd2_w));     // dma 2 device record descriptor (esga)
	map(0xe4, 0xe7).rw(FUNC(interpro_sga_device::dsrd2_r), FUNC(interpro_sga_device::dsrd2_w));     // dma 2 SRX record descriptor (esga)
	map(0xe8, 0xeb).rw(FUNC(interpro_sga_device::dcksum0_r), FUNC(interpro_sga_device::dcksum0_w)); // dma 1 device checksum register 0 (esga)
	map(0xec, 0xef).rw(FUNC(interpro_sga_device::dcksum1_r), FUNC(interpro_sga_device::dcksum1_w)); // dma 1 device checksum register 1 (esga)
}

DEFINE_DEVICE_TYPE(INTERPRO_SGA, interpro_sga_device, "sga", "SRX Gate Array")

interpro_sga_device::interpro_sga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, INTERPRO_SGA, tag, owner, clock)
	, m_berr_func(*this)
{
}

void interpro_sga_device::device_start()
{
	m_berr_func.resolve();

	save_item(NAME(m_gcsr));
	save_item(NAME(m_ipoll));
	save_item(NAME(m_imask));
	save_item(NAME(m_range_base));
	save_item(NAME(m_range_end));
	save_item(NAME(m_cttag));
	save_item(NAME(m_address));
	save_item(NAME(m_dmacsr));

	save_item(NAME(m_edmacsr));
	save_item(NAME(m_reg6_range));

	save_item(NAME(m_ddpta0));
	save_item(NAME(m_ddpad0));
	save_item(NAME(m_ddoff0));
	save_item(NAME(m_ddtc0));
	save_item(NAME(m_dspta0));
	save_item(NAME(m_dspad0));
	save_item(NAME(m_dsoff0));
	save_item(NAME(m_dstc0));

	save_item(NAME(m_dspad1));
	save_item(NAME(m_dsoff1));
	save_item(NAME(m_dstc1));
	save_item(NAME(m_ddpad1));
	save_item(NAME(m_ddoff1));
	save_item(NAME(m_ddtc1));

	save_item(NAME(m_ddpta2));
	save_item(NAME(m_ddpad2));
	save_item(NAME(m_ddoff2));
	save_item(NAME(m_ddtc2));
	save_item(NAME(m_dspta2));
	save_item(NAME(m_dspad2));
	save_item(NAME(m_dsoff2));
	save_item(NAME(m_dstc2));

	save_item(NAME(m_ddrd2));
	save_item(NAME(m_dsrd2));
	save_item(NAME(m_dcksum0));
	save_item(NAME(m_dcksum1));
}

void interpro_sga_device::device_reset()
{
}

void interpro_sga_device::ddtc1_w(u32 data)
{
	m_ddtc1 = data;

	// assume that when this register is written, we should start a
	// memory to memory dma transfer

	LOG("  gcsr = 0x%08x dmacsr = 0x%08x\n", m_gcsr, m_dmacsr);
	LOG(" ipoll = 0x%08x  imask = 0x%08x\n", m_ipoll, m_imask);
	LOG("dspad1 = 0x%08x dsoff1 = 0x%08x dstc1 = 0x%08x\n", m_dspad1, m_dsoff1, m_dstc1);
	LOG("ddpad1 = 0x%08x ddoff1 = 0x%08x ddtc1 = 0x%08x\n", m_ddpad1, m_ddoff1, m_ddtc1);

	// when complete, we indicate by setting DMAEND(2) - 2 is probably the channel
	// we also turn off the INTBERR and INTMMBE flags
	m_ipoll &= ~(IPOLL_INTBERR | IPOLL_INTMMBE);
	m_ipoll |= 0x200;

#if 0
	// if the address is invalid, fake a bus error
	if ((m_dspad1 & 0xfffff000) == 0x40000000 || (m_ddpad1 & 0xfffff) == 0x40000000)
	{
		m_ipoll |= IPOLL_INTBERR;

		// error cycle - bit 0x10 indicates source address error (dspad1)
		// now expecting 0x5463?
		if ((m_dspad1 & 0xfffff000) == 0x40000000)
			m_berr_func(space, 0x5433, m_dspad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x30 | CT(3)
		else
			m_berr_func(space, 0x5423, m_ddpad1); // BINFO_SNAPOK | BINFO_BERR | BINFO_BG_ICAMMU | 0x20 | CT(3)

		// 0x5423 = BERR|SNAPOK | BG(ICAMMU)? | CT(23)
		// 0x5433 = BERR|SNAPOK | BG(ICAMMU)? | CT(33)
		// 0x5463 = BERR|SNAPOK | BG(ICAMMU)? | TAG(40=1) | CT(23)
	}
#endif
}