mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
-newport: Added Display Control Bus timeout. Prevents Presenter board from being erroneously detected. [Ryan Holtz]
-sgi_mc: Fixed VDMA TLB which caused corrupt bitmap transfers. [Ryan Holtz]
This commit is contained in:
parent
bef9f293b6
commit
a7e4e9b676
@ -40,7 +40,7 @@
|
||||
#define LOG_REJECTS (1 << 8)
|
||||
#define LOG_ALL (LOG_UNKNOWN | LOG_VC2 | LOG_CMAP0 | LOG_CMAP1 | LOG_XMAP0 | LOG_XMAP1 | LOG_REX3 | LOG_COMMANDS | LOG_REJECTS)
|
||||
|
||||
#define VERBOSE (0)
|
||||
#define VERBOSE (0)//(LOG_REX3 | LOG_COMMANDS)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(GIO_XL8, gio_xl8_device, "gio_xl8", "SGI 8-bit XL board")
|
||||
@ -79,6 +79,8 @@ void newport_base_device::device_start()
|
||||
m_cid = make_unique_clear<uint32_t[]>((1280+64) * (1024+64));
|
||||
m_vt_table = make_unique_clear<uint32_t[]>(2048 * 2048);
|
||||
|
||||
m_dcb_timeout_timer = timer_alloc(DCB_TIMEOUT);
|
||||
|
||||
save_pointer(NAME(m_rgbci), (1280+64) * (1024+64));
|
||||
save_pointer(NAME(m_olay), (1280+64) * (1024+64));
|
||||
save_pointer(NAME(m_pup), (1280+64) * (1024+64));
|
||||
@ -283,6 +285,14 @@ void newport_base_device::stop_logging()
|
||||
}
|
||||
#endif
|
||||
|
||||
void newport_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (id == DCB_TIMEOUT)
|
||||
{
|
||||
m_rex3.m_status &= ~STATUS_BACKBUSY;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t newport_base_device::get_cursor_pixel(int x, int y)
|
||||
{
|
||||
if (x < 0 || y < 0)
|
||||
@ -1302,7 +1312,7 @@ WRITE_LINE_MEMBER(newport_base_device::vblank_w)
|
||||
{
|
||||
if (BIT(m_vc2.m_display_ctrl, 0))
|
||||
{
|
||||
m_rex3.m_status |= 0x20;
|
||||
m_rex3.m_status |= STATUS_VRINT;
|
||||
m_gio->get_hpc3()->raise_local_irq(1, ioc2_device::INT3_LOCAL1_RETRACE);
|
||||
}
|
||||
}
|
||||
@ -1612,21 +1622,36 @@ READ64_MEMBER(newport_base_device::rex3_r)
|
||||
{
|
||||
switch (m_rex3.m_dcb_slave_select)
|
||||
{
|
||||
case 0x00:
|
||||
case DCB_ADDR_VC2:
|
||||
ret |= (uint64_t)vc2_read() << 32;
|
||||
break;
|
||||
case 0x02:
|
||||
case DCB_ADDR_CMAP0:
|
||||
ret |= (uint64_t)cmap0_read() << 32;
|
||||
break;
|
||||
case 0x03:
|
||||
case DCB_ADDR_CMAP1:
|
||||
ret |= (uint64_t)cmap1_read() << 32;
|
||||
break;
|
||||
case 0x05:
|
||||
case DCB_ADDR_XMAP0:
|
||||
ret |= (uint64_t)xmap0_read() << 32;
|
||||
break;
|
||||
case 0x06:
|
||||
case DCB_ADDR_XMAP1:
|
||||
ret |= (uint64_t)xmap1_read() << 32;
|
||||
break;
|
||||
case DCB_ADDR_RAMDAC:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Read from RAMDAC (not yet implemented)\n");
|
||||
break;
|
||||
case DCB_ADDR_CC1:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Read from CC1 (not yet implemented)\n");
|
||||
break;
|
||||
case DCB_ADDR_AB1:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Read from AB1 (not yet implemented)\n");
|
||||
break;
|
||||
case DCB_ADDR_PCD:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Read from PCD (not yet implemented)\n");
|
||||
// Presenter not connected; simulate a bus timeout
|
||||
m_rex3.m_status |= STATUS_BACKBUSY;
|
||||
m_dcb_timeout_timer->adjust(attotime::from_msec(1));
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Read: %08x\n", m_rex3.m_dcb_data_msw);
|
||||
ret |= (uint64_t)m_rex3.m_dcb_data_msw << 32;
|
||||
@ -1723,7 +1748,7 @@ READ64_MEMBER(newport_base_device::rex3_r)
|
||||
{
|
||||
LOGMASKED(LOG_REX3, "REX3 Status Read: %08x\n", m_rex3.m_status);
|
||||
uint32_t old_status = m_rex3.m_status;
|
||||
m_rex3.m_status = 0;
|
||||
m_rex3.m_status &= ~STATUS_VRINT;
|
||||
m_gio->get_hpc3()->lower_local_irq(1, ioc2_device::INT3_LOCAL1_RETRACE);
|
||||
ret |= (uint64_t)(old_status | 3) << 32;
|
||||
}
|
||||
@ -3727,22 +3752,44 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
|
||||
m_rex3.m_dcb_data_msw = data32;
|
||||
switch (m_rex3.m_dcb_slave_select)
|
||||
{
|
||||
case 0x00:
|
||||
case DCB_ADDR_VC2:
|
||||
vc2_write(data32);
|
||||
break;
|
||||
case 0x01:
|
||||
case DCB_ADDR_CMAP01:
|
||||
cmap0_write(data32);
|
||||
//cmap1_write(data32);
|
||||
break;
|
||||
case DCB_ADDR_CMAP0:
|
||||
cmap0_write(data32);
|
||||
break;
|
||||
case 0x04:
|
||||
case DCB_ADDR_CMAP1:
|
||||
//cmap1_write(data32);
|
||||
break;
|
||||
case DCB_ADDR_XMAP01:
|
||||
xmap0_write(data32);
|
||||
xmap1_write(data32);
|
||||
break;
|
||||
case 0x05:
|
||||
case DCB_ADDR_XMAP0:
|
||||
xmap0_write(data32);
|
||||
break;
|
||||
case 0x06:
|
||||
case DCB_ADDR_XMAP1:
|
||||
xmap1_write(data32);
|
||||
break;
|
||||
case DCB_ADDR_RAMDAC:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Write to RAMDAC (not yet implemented): %08x\n", data32);
|
||||
break;
|
||||
case DCB_ADDR_CC1:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Write to CC1 (not yet implemented): %08x\n", data32);
|
||||
break;
|
||||
case DCB_ADDR_AB1:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Write to AB1 (not yet implemented): %08x\n", data32);
|
||||
break;
|
||||
case DCB_ADDR_PCD:
|
||||
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Write to PCD (not yet implemented): %08x\n", data32);
|
||||
// Presenter not connected; simulate a bus timeout
|
||||
m_rex3.m_status |= STATUS_BACKBUSY;
|
||||
m_dcb_timeout_timer->adjust(attotime::from_msec(1));
|
||||
break;
|
||||
default:
|
||||
LOGMASKED(LOG_REX3 | LOG_UNKNOWN, "REX3 Display Control Bus Data MSW Write: %08x\n", data32);
|
||||
break;
|
||||
|
@ -32,6 +32,7 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER(vblank_w);
|
||||
|
||||
protected:
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual uint32_t palette_entries() const override { return 0x2000; }
|
||||
virtual void device_start() override;
|
||||
@ -39,6 +40,8 @@ protected:
|
||||
|
||||
void mem_map(address_map &map) override;
|
||||
|
||||
static constexpr device_timer_id DCB_TIMEOUT = 0;
|
||||
|
||||
enum
|
||||
{
|
||||
DCR_CURSOR_FUNC_ENABLE_BIT = 4,
|
||||
@ -53,6 +56,35 @@ protected:
|
||||
DCR_CURSOR_SIZE_64 = 1
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DCB_ADDR_VC2,
|
||||
DCB_ADDR_CMAP01,
|
||||
DCB_ADDR_CMAP0,
|
||||
DCB_ADDR_CMAP1,
|
||||
DCB_ADDR_XMAP01,
|
||||
DCB_ADDR_XMAP0,
|
||||
DCB_ADDR_XMAP1,
|
||||
DCB_ADDR_RAMDAC,
|
||||
DCB_ADDR_CC1,
|
||||
DCB_ADDR_AB1,
|
||||
DCB_ADDR_PCD = 12
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
STATUS_GFXBUSY = (1 << 3),
|
||||
STATUS_BACKBUSY = (1 << 4),
|
||||
STATUS_VRINT = (1 << 5),
|
||||
STATUS_VIDEOINT = (1 << 6),
|
||||
STATUS_GFIFOLEVEL_SHIFT = 7,
|
||||
STATUS_GFIFOLEVEL_MASK = (0x3f << STATUS_GFIFOLEVEL_SHIFT),
|
||||
STATUS_BFIFOLEVEL_SHIFT = 13,
|
||||
STATUS_BFIFOLEVEL_MASK = (0x1f << STATUS_BFIFOLEVEL_SHIFT),
|
||||
STATUS_BFIFO_INT = 18,
|
||||
STATUS_GFIFO_INT = 19
|
||||
};
|
||||
|
||||
struct vc2_t
|
||||
{
|
||||
uint16_t m_vid_entry;
|
||||
@ -268,6 +300,7 @@ protected:
|
||||
std::unique_ptr<uint32_t[]> m_vt_table;
|
||||
cmap_t m_cmap0;
|
||||
uint32_t m_global_mask;
|
||||
emu_timer *m_dcb_timeout_timer;
|
||||
|
||||
int m_readout_x0;
|
||||
int m_readout_y0;
|
||||
|
@ -23,7 +23,7 @@
|
||||
#define LOG_DMA (1 << 8)
|
||||
#define LOG_DEFAULT (LOG_READS | LOG_WRITES | LOG_RPSS | LOG_WATCHDOG | LOG_UNKNOWN)
|
||||
|
||||
#define VERBOSE (0)
|
||||
#define VERBOSE (LOG_DMA)
|
||||
#include "logmacro.h"
|
||||
|
||||
DEFINE_DEVICE_TYPE(SGI_MC, sgi_mc_device, "sgi_mc", "SGI Memory Controller")
|
||||
@ -196,9 +196,9 @@ uint32_t sgi_mc_device::dma_translate(uint32_t address)
|
||||
{
|
||||
for (int entry = 0; entry < 4; entry++)
|
||||
{
|
||||
if ((address & 0xffe00000) == (m_dma_tlb_entry_hi[entry] & 0xffe00000))
|
||||
if ((address & 0xffc00000) == (m_dma_tlb_entry_hi[entry] & 0xffc00000))
|
||||
{
|
||||
const uint32_t vpn_lo = (address & 0x001ff000) >> 12;
|
||||
const uint32_t vpn_lo = (address & 0x003ff000) >> 12;
|
||||
const uint32_t pte = m_space->read_dword(((m_dma_tlb_entry_lo[entry] & 0x003fffc0) << 6) + (vpn_lo << 2));
|
||||
const uint32_t offset = address & 0xfff;
|
||||
return ((pte & 0x03ffffc0) << 6) + offset;
|
||||
@ -207,91 +207,103 @@ uint32_t sgi_mc_device::dma_translate(uint32_t address)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sgi_mc_device::dma_tick()
|
||||
void sgi_mc_device::dma_immediate()
|
||||
{
|
||||
uint32_t addr = m_dma_mem_addr;
|
||||
if (m_dma_control & (1 << 8))
|
||||
{ // Enable virtual address translation
|
||||
addr = dma_translate(addr);
|
||||
}
|
||||
|
||||
if (m_dma_mode & (1 << 1))
|
||||
{ // Graphics to host
|
||||
if (m_dma_mode & (1 << 3))
|
||||
{ // Fill mode
|
||||
m_space->write_dword(addr, m_dma_gio64_addr);
|
||||
m_dma_mem_addr += 4;
|
||||
m_dma_count -= 4;
|
||||
}
|
||||
else
|
||||
uint32_t memory_addr = m_dma_mem_addr;
|
||||
uint32_t linecount = get_line_count();
|
||||
uint32_t zoomcount = get_zoom_count();
|
||||
uint32_t bytecount = get_byte_count();
|
||||
const uint32_t gio_addr = m_dma_gio64_addr;
|
||||
const uint32_t linewidth = get_line_width();
|
||||
const uint32_t linezoom = get_line_zoom();
|
||||
const uint32_t stride = get_stride();
|
||||
m_dma_size &= 0x0000ffff;
|
||||
m_dma_count = 0;
|
||||
while (linecount > 0)
|
||||
{
|
||||
linecount--;
|
||||
while (zoomcount > 0)
|
||||
{
|
||||
const uint32_t remaining = m_dma_count & 0x0000ffff;
|
||||
uint32_t length = 8;
|
||||
uint64_t shift = 56;
|
||||
if (remaining < 8)
|
||||
length = remaining;
|
||||
|
||||
uint64_t data = m_space->read_qword(m_dma_gio64_addr);
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
zoomcount--;
|
||||
while (bytecount > 0)
|
||||
{
|
||||
m_space->write_byte(addr, (uint8_t)(data >> shift));
|
||||
addr++;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
m_dma_mem_addr += length;
|
||||
m_dma_count -= length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // Host to graphics
|
||||
const uint32_t remaining = m_dma_count & 0x0000ffff;
|
||||
uint32_t length = 8;
|
||||
uint64_t shift = 56;
|
||||
if (remaining < 8)
|
||||
length = remaining;
|
||||
|
||||
uint64_t data = 0;
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
data |= (uint64_t)m_space->read_byte(addr) << shift;
|
||||
addr++;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
m_space->write_qword(m_dma_gio64_addr, data);
|
||||
m_dma_mem_addr += length;
|
||||
m_dma_count -= length;
|
||||
}
|
||||
|
||||
if ((m_dma_count & 0x0000ffff) == 0)
|
||||
{ // If remaining byte count is 0, deduct zoom count
|
||||
m_dma_count -= 0x00010000;
|
||||
if (m_dma_count == 0)
|
||||
{ // If remaining zoom count is also 0, move to next line
|
||||
m_dma_mem_addr += m_dma_stride & 0x0000ffff;
|
||||
m_dma_size -= 0x00010000;
|
||||
if ((m_dma_size & 0xffff0000) == 0)
|
||||
{ // If no remaining lines, DMA is done.
|
||||
m_dma_timer->adjust(attotime::never);
|
||||
m_dma_run |= (1 << 3);
|
||||
m_dma_run &= ~(1 << 6);
|
||||
if (BIT(m_dma_control, 4))
|
||||
if (m_dma_mode & MODE_TO_HOST)
|
||||
{
|
||||
m_dma_int_cause |= (1 << 3);
|
||||
m_hpc3->raise_local_irq(0, ioc2_device::INT3_LOCAL0_MC_DMA);
|
||||
if (m_dma_mode & MODE_FILL)
|
||||
{ // Fill mode
|
||||
m_space->write_dword(dma_translate(memory_addr), m_dma_gio64_addr);
|
||||
if (m_dma_mode & MODE_DIR)
|
||||
memory_addr += 4;
|
||||
else
|
||||
memory_addr -= 4;
|
||||
bytecount -= 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t length = 8;
|
||||
uint64_t shift = 56;
|
||||
if (bytecount < 8)
|
||||
length = bytecount;
|
||||
|
||||
uint64_t data = m_space->read_qword(gio_addr);
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
m_space->write_byte(dma_translate(memory_addr), (uint8_t)(data >> shift));
|
||||
if (m_dma_mode & MODE_DIR)
|
||||
memory_addr++;
|
||||
else
|
||||
memory_addr--;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
bytecount -= length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t length = 8;
|
||||
uint64_t shift = 56;
|
||||
if (bytecount < 8)
|
||||
length = bytecount;
|
||||
|
||||
uint64_t data = 0;
|
||||
for (uint32_t i = 0; i < length; i++)
|
||||
{
|
||||
data |= (uint64_t)m_space->read_byte(dma_translate(memory_addr)) << shift;
|
||||
if (m_dma_mode & MODE_DIR)
|
||||
memory_addr++;
|
||||
else
|
||||
memory_addr--;
|
||||
shift -= 8;
|
||||
}
|
||||
|
||||
m_space->write_qword(gio_addr, data);
|
||||
bytecount -= length;
|
||||
}
|
||||
}
|
||||
else
|
||||
bytecount = linewidth;
|
||||
|
||||
if (zoomcount > 0)
|
||||
{
|
||||
m_dma_count = (m_dma_stride & 0x03ff0000) | (m_dma_size & 0x0000ffff);
|
||||
if (m_dma_mode & MODE_DIR)
|
||||
memory_addr -= linewidth;
|
||||
else
|
||||
memory_addr += linewidth;
|
||||
}
|
||||
}
|
||||
else
|
||||
{ // If remaining zoom count is non-zero, reload byte count and return source address to the beginning of the line.
|
||||
m_dma_count |= m_dma_size & 0x0000ffff;
|
||||
m_dma_mem_addr -= m_dma_size & 0x0000ffff;
|
||||
}
|
||||
zoomcount = linezoom;
|
||||
memory_addr += stride;
|
||||
}
|
||||
|
||||
m_dma_mem_addr = memory_addr;
|
||||
|
||||
m_dma_timer->adjust(attotime::never);
|
||||
m_dma_run |= (1 << 3);
|
||||
m_dma_run &= ~(1 << 6);
|
||||
if (BIT(m_dma_control, 4))
|
||||
{
|
||||
m_dma_int_cause |= (1 << 3);
|
||||
m_hpc3->raise_local_irq(0, ioc2_device::INT3_LOCAL0_MC_DMA);
|
||||
}
|
||||
}
|
||||
|
||||
@ -720,9 +732,6 @@ void sgi_mc_device::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
}
|
||||
else if (id == TIMER_DMA)
|
||||
{
|
||||
while (m_dma_run & (1 << 6))
|
||||
{
|
||||
dma_tick();
|
||||
}
|
||||
dma_immediate();
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,24 @@ protected:
|
||||
static const device_timer_id TIMER_DMA = 1;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
MODE_TO_HOST = (1 << 1),
|
||||
MODE_SYNC = (1 << 2),
|
||||
MODE_FILL = (1 << 3),
|
||||
MODE_DIR = (1 << 4),
|
||||
MODE_SNOOP = (1 << 5)
|
||||
};
|
||||
|
||||
uint32_t dma_translate(uint32_t address);
|
||||
void dma_tick();
|
||||
void dma_immediate();
|
||||
|
||||
uint32_t get_line_count() { return m_dma_size >> 16; }
|
||||
uint32_t get_line_width() { return (uint16_t)m_dma_size; }
|
||||
uint32_t get_line_zoom() { return (m_dma_stride >> 16) & 0x3ff; }
|
||||
int16_t get_stride() { return (int16_t)m_dma_stride; }
|
||||
uint32_t get_zoom_count() { return (m_dma_count >> 16) & 0x3ff; }
|
||||
uint32_t get_byte_count() { return (uint16_t)m_dma_count; }
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<eeprom_serial_93cxx_device> m_eeprom;
|
||||
|
Loading…
Reference in New Issue
Block a user