sgi_gr1: small steps (nw)

* fifo half-full interrupt latching
* address map banking
* conf not dip switches
* logging improvements
This commit is contained in:
Patrick Mackinlay 2019-10-14 19:12:50 +07:00
parent 84a61fd14f
commit bd6b6b5e51
7 changed files with 188 additions and 78 deletions

View File

@ -219,6 +219,7 @@ private:
u16 m_lio_isr; u16 m_lio_isr;
u8 m_lio_imr; u8 m_lio_imr;
bool m_lio_int; bool m_lio_int;
int m_lio_fifo;
u16 m_dmalo; u16 m_dmalo;
u8 m_mapindex; u8 m_mapindex;
@ -359,6 +360,15 @@ void pi4d2x_state::map(address_map &map)
{ {
m_lio_imr = data; m_lio_imr = data;
// fifo interrupt status follows line state if not enabled
if (!BIT(m_lio_imr, LIO_FIFO))
{
if (m_lio_fifo)
m_lio_isr |= (1U << LIO_FIFO);
else
m_lio_isr &= ~(1U << LIO_FIFO);
}
// update interrupt line // update interrupt line
bool const lio_int = ~m_lio_isr & m_lio_imr; bool const lio_int = ~m_lio_isr & m_lio_imr;
if (m_lio_imr ^ lio_int) if (m_lio_imr ^ lio_int)
@ -616,7 +626,7 @@ void pi4d2x_state::common(machine_config &config)
else else
m_lio_isr |= (1U << LIO_VRSTAT); m_lio_isr |= (1U << LIO_VRSTAT);
}); });
m_gfx->out_int_ge().set(*this, FUNC(pi4d2x_state::lio_interrupt<LIO_GE>)).invert(); m_gfx->out_int().set(*this, FUNC(pi4d2x_state::lio_interrupt<LIO_GE>)).invert();
m_gfx->out_int_fifo().set(*this, FUNC(pi4d2x_state::lio_interrupt<LIO_FIFO>)).invert(); m_gfx->out_int_fifo().set(*this, FUNC(pi4d2x_state::lio_interrupt<LIO_FIFO>)).invert();
// TODO: vme slot, cpu interrupt 0 // TODO: vme slot, cpu interrupt 0
@ -643,14 +653,22 @@ void pi4d2x_state::initialize()
void pi4d2x_state::lio_interrupt(unsigned number, int state) void pi4d2x_state::lio_interrupt(unsigned number, int state)
{ {
// TODO: special handling for fifo half-full interrupt
u16 const mask = 1 << number; u16 const mask = 1 << number;
if (number == LIO_FIFO)
{
m_lio_fifo = state;
// special handling for enabled fifo interrupt
if ((m_lio_imr & mask) && !(m_lio_isr & mask))
return;
}
// record interrupt state // record interrupt state
if (!state) if (state)
m_lio_isr &= ~mask;
else
m_lio_isr |= mask; m_lio_isr |= mask;
else
m_lio_isr &= ~mask;
// update interrupt line // update interrupt line
bool const lio_int = ~m_lio_isr & m_lio_imr; bool const lio_int = ~m_lio_isr & m_lio_imr;

View File

@ -16,7 +16,6 @@
* TODO: * TODO:
* - implement host dma * - implement host dma
* - verify some operations * - verify some operations
* - tidy up latch/timing logic
* - implement single stepping * - implement single stepping
* - redo disassembly * - redo disassembly
* - save state * - save state
@ -29,6 +28,7 @@
#define LOG_GENERAL (1U << 0) #define LOG_GENERAL (1U << 0)
#define LOG_TOKEN (1U << 1) #define LOG_TOKEN (1U << 1)
#define LOG_MEMORY (1U << 2) #define LOG_MEMORY (1U << 2)
#define LOG_DMA (1U << 3)
//#define VERBOSE (LOG_GENERAL) //#define VERBOSE (LOG_GENERAL)
#include "logmacro.h" #include "logmacro.h"
@ -343,7 +343,9 @@ void sgi_ge5_device::execute_run()
if (token < ARRAY_LENGTH(token_puc)) if (token < ARRAY_LENGTH(token_puc))
string = token_puc[token]; string = token_puc[token];
} }
else if (space(1).read_dword(0x50d) == 0x004d0005 || space(1).read_dword(0x536) == 0x12345678) else if (space(1).read_dword(0x50d) == 0x004d0005
|| space(1).read_dword(0x536) == 0x12345678
|| space(1).read_dword(0x540) == 0x12345678)
{ {
if (token < ARRAY_LENGTH(token_gl)) if (token < ARRAY_LENGTH(token_gl))
string = token_gl[token]; string = token_gl[token];
@ -398,6 +400,8 @@ void sgi_ge5_device::execute_run()
case 0xf: // dma cycle case 0xf: // dma cycle
if (--m_dma_count) if (--m_dma_count)
m_pc -= m_decode.secondary ? 2 : 1; m_pc -= m_decode.secondary ? 2 : 1;
else
LOGMASKED(LOG_DMA, "dma complete\n");
break; break;
} }
break; break;
@ -546,6 +550,7 @@ void sgi_ge5_device::secondary()
switch (m_decode.immediate) switch (m_decode.immediate)
{ {
case 0: // TODO: assert dma ready case 0: // TODO: assert dma ready
LOGMASKED(LOG_DMA, "dma ready\n");
break; break;
default: // assert interrupt default: // assert interrupt
@ -559,10 +564,12 @@ void sgi_ge5_device::secondary()
switch (m_decode.immediate) switch (m_decode.immediate)
{ {
case 0: // TODO: reset dma? case 0: // TODO: reset dma?
LOGMASKED(LOG_DMA, "dma reset\n");
break; break;
default: // load dma count default: // load dma count
m_dma_count = m_bus; m_dma_count = m_bus;
LOGMASKED(LOG_DMA, "dma count %d\n", m_dma_count);
break; break;
} }
break; break;
@ -594,22 +601,26 @@ void sgi_ge5_device::command_w(offs_t offset, u16 data, u16 mem_mask)
break; break;
} }
} }
template u32 sgi_ge5_device::code_r<false>(offs_t offset);
template u32 sgi_ge5_device::code_r<true>(offs_t offset);
template void sgi_ge5_device::code_w<false>(offs_t offset, u32 data, u32 mem_mask);
template void sgi_ge5_device::code_w<true>(offs_t offset, u32 data, u32 mem_mask);
u32 sgi_ge5_device::code_r(offs_t offset) template <bool High> u32 sgi_ge5_device::code_r(offs_t offset)
{ {
m_pc = offset | offs_t(m_mar & 0x7f) << 8; m_pc = offset | offs_t(m_mar & 0x7f) << 8;
u64 const data = space(0).read_qword(m_pc); u64 const data = space(0).read_qword(m_pc);
return m_mar_msb ? u32(data >> 32) : u32(data); return High ? u32(data >> 32) : u32(data);
} }
void sgi_ge5_device::code_w(offs_t offset, u32 data, u32 mem_mask) template <bool High> void sgi_ge5_device::code_w(offs_t offset, u32 data, u32 mem_mask)
{ {
m_pc = offset | offs_t(m_mar & 0x7f) << 8; m_pc = offset | offs_t(m_mar & 0x7f) << 8;
LOGMASKED(LOG_MEMORY, "code_w msb %d offset 0x%08x data 0x%08x mask 0x%08x (%s)\n", m_mar_msb, m_pc, data, mem_mask, machine().describe_context()); LOGMASKED(LOG_MEMORY, "code_w msb %d offset 0x%08x data 0x%08x mask 0x%08x (%s)\n", High, m_pc, data, mem_mask, machine().describe_context());
if (m_mar_msb) if (High)
{ {
u64 const mask = u64(mem_mask & 0x000000ffU) << 32; u64 const mask = u64(mem_mask & 0x000000ffU) << 32;
@ -628,16 +639,14 @@ void sgi_ge5_device::code_w(offs_t offset, u32 data, u32 mem_mask)
u32 sgi_ge5_device::data_r(offs_t offset) u32 sgi_ge5_device::data_r(offs_t offset)
{ {
// FIXME: 5 or 6 bits from MAR? m_memptr = offset | offs_t(m_mar & 0x3f) << 8;
m_memptr = offset | offs_t(m_mar & 0x1f) << 8;
return space(1).read_dword(m_memptr); return space(1).read_dword(m_memptr);
} }
void sgi_ge5_device::data_w(offs_t offset, u32 data, u32 mem_mask) void sgi_ge5_device::data_w(offs_t offset, u32 data, u32 mem_mask)
{ {
// FIXME: 5 or 6 bits from MAR? m_memptr = offset | offs_t(m_mar & 0x3f) << 8;
m_memptr = offset | offs_t(m_mar & 0x1f) << 8;
space(1).write_dword(m_memptr, data, mem_mask); space(1).write_dword(m_memptr, data, mem_mask);
} }

View File

@ -42,15 +42,16 @@ public:
virtual void execute_run() override; virtual void execute_run() override;
virtual void execute_set_input(int inputnum, int state) override {} virtual void execute_set_input(int inputnum, int state) override {}
u32 code_r(offs_t offset); u32 buffer_r(offs_t offset) { return m_bus; }
template <bool High> u32 code_r(offs_t offset);
u32 data_r(offs_t offset); u32 data_r(offs_t offset);
void code_w(offs_t offset, u32 data, u32 mem_mask); template <bool High> void code_w(offs_t offset, u32 data, u32 mem_mask);
void data_w(offs_t offset, u32 data, u32 mem_mask); void data_w(offs_t offset, u32 data, u32 mem_mask);
void command_w(offs_t offset, u16 data, u16 mem_mask); void command_w(offs_t offset, u16 data, u16 mem_mask);
u16 pc_r() { return m_pc; } u16 pc_r() { return m_pc; }
void mar_w(offs_t offset, u32 data, u32 mem_mask) { m_mar = offset & 0x7f; } void mar_w(offs_t offset, u32 data, u32 mem_mask) { m_mar = offset & 0x7f; }
void mar_msb_w(offs_t offset, u32 data, u32 mem_mask) { m_mar_msb = bool(offset); }
void cwen_w(int state) { m_cwen = bool(state); } void cwen_w(int state) { m_cwen = bool(state); }
u32 finish_r(offs_t offset) { return m_finish[offset]; } u32 finish_r(offs_t offset) { return m_finish[offset]; }
@ -105,7 +106,6 @@ private:
bool m_re_drq; bool m_re_drq;
// hq1 registers // hq1 registers
bool m_mar_msb;
u8 m_mar; u8 m_mar;
u16 m_pc; u16 m_pc;
unsigned m_sp; unsigned m_sp;

View File

@ -70,68 +70,74 @@ DEFINE_DEVICE_TYPE(SGI_GR1, sgi_gr1_device, "sgi_gr1", "SGI GR1 Graphics")
sgi_gr1_device::sgi_gr1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) sgi_gr1_device::sgi_gr1_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
: device_t(mconfig, SGI_GR1, tag, owner, clock) : device_t(mconfig, SGI_GR1, tag, owner, clock)
, m_bank(*this, "bank")
, m_screen(*this, "screen") , m_screen(*this, "screen")
, m_ge(*this, "ge5") , m_ge(*this, "ge5")
, m_re(*this, "re2") , m_re(*this, "re2")
, m_xmap(*this, "xmap%u", 0U) , m_xmap(*this, "xmap%u", 0U)
, m_cursor(*this, "cursor%u", 0U) , m_cursor(*this, "cursor%u", 0U)
, m_ramdac(*this, "ramdac%u", 0U) , m_ramdac(*this, "ramdac%u", 0U)
, m_vblank_cb(*this)
, m_int_fifo_cb(*this) , m_int_fifo_cb(*this)
{ {
} }
static INPUT_PORTS_START(sgi_gr1) static INPUT_PORTS_START(sgi_gr1)
PORT_START("options") PORT_START("options")
PORT_DIPNAME(0x08, 0x08, "Turbo") PORT_CONFNAME(0x08, 0x08, "Turbo")
PORT_DIPSETTING(0x00, DEF_STR(Yes)) PORT_CONFSETTING(0x00, DEF_STR(Yes))
PORT_DIPSETTING(0x08, DEF_STR(No)) PORT_CONFSETTING(0x08, DEF_STR(No))
PORT_DIPNAME(0x10, 0x00, "Z Buffer") PORT_CONFNAME(0x10, 0x00, "Z Buffer")
PORT_DIPSETTING(0x00, DEF_STR(Yes)) PORT_CONFSETTING(0x00, DEF_STR(Yes))
PORT_DIPSETTING(0x10, DEF_STR(No)) PORT_CONFSETTING(0x10, DEF_STR(No))
INPUT_PORTS_END INPUT_PORTS_END
void sgi_gr1_device::map(address_map &map) void sgi_gr1_device::map(address_map &map)
{ {
// TODO: bank based on mar_msb map(0x0000, 0x7fff).m(m_bank, FUNC(address_map_bank_device::amap32));
}
map(0x0000, 0x03ff).rw(m_ge, FUNC(sgi_ge5_device::code_r), FUNC(sgi_ge5_device::code_w)); void sgi_gr1_device::map_bank(address_map &map)
{
// bit 15 of the map offset represents mar_msb
map(0x0000, 0x03ff).rw(m_ge, FUNC(sgi_ge5_device::code_r<false>), FUNC(sgi_ge5_device::code_w<false>));
map(0x8000, 0x83ff).rw(m_ge, FUNC(sgi_ge5_device::code_r<true>), FUNC(sgi_ge5_device::code_w<true>));
map(0x0400, 0x041f).rw(m_xmap[0], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff); map(0x8400, 0x841f).rw(m_xmap[0], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff);
map(0x0420, 0x043f).rw(m_xmap[1], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff); map(0x8420, 0x843f).rw(m_xmap[1], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff);
map(0x0440, 0x045f).rw(m_xmap[2], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff); map(0x8440, 0x845f).rw(m_xmap[2], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff);
map(0x0460, 0x047f).rw(m_xmap[3], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff); map(0x8460, 0x847f).rw(m_xmap[3], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff);
map(0x0480, 0x049f).rw(m_xmap[4], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff); map(0x8480, 0x849f).rw(m_xmap[4], FUNC(sgi_xmap2_device::reg_r), FUNC(sgi_xmap2_device::reg_w)).umask32(0x000000ff);
map(0x04a0, 0x04bf).lw8("xmap_broadcast", map(0x84a0, 0x84bf).lw8("xmap_broadcast",
[this](offs_t offset, u8 data) [this](offs_t offset, u8 data)
{ {
for (sgi_xmap2_device *xmap : m_xmap) for (sgi_xmap2_device *xmap : m_xmap)
xmap->reg_w(offset, data); xmap->reg_w(offset, data);
}).umask32(0x000000ff); }).umask32(0x000000ff);
map(0x04c0, 0x04c3).rw(FUNC(sgi_gr1_device::dr1_r), FUNC(sgi_gr1_device::dr1_w)).umask32(0xff000000); map(0x84c0, 0x84c3).rw(FUNC(sgi_gr1_device::dr1_r), FUNC(sgi_gr1_device::dr1_w)).umask32(0xff000000);
map(0x04e0, 0x04e3).rw(FUNC(sgi_gr1_device::dr0_r), FUNC(sgi_gr1_device::dr0_w)).umask32(0xff000000); map(0x84e0, 0x84e3).rw(FUNC(sgi_gr1_device::dr0_r), FUNC(sgi_gr1_device::dr0_w)).umask32(0xff000000);
map(0x0500, 0x050f).m(m_ramdac[0], FUNC(bt457_device::map)).umask32(0x000000ff); map(0x8500, 0x850f).m(m_ramdac[0], FUNC(bt457_device::map)).umask32(0x000000ff);
map(0x0520, 0x052f).m(m_ramdac[1], FUNC(bt457_device::map)).umask32(0x000000ff); map(0x8520, 0x852f).m(m_ramdac[1], FUNC(bt457_device::map)).umask32(0x000000ff);
map(0x0540, 0x054f).m(m_ramdac[2], FUNC(bt457_device::map)).umask32(0x000000ff); map(0x8540, 0x854f).m(m_ramdac[2], FUNC(bt457_device::map)).umask32(0x000000ff);
map(0x0560, 0x056f).m(m_cursor[0], FUNC(bt431_device::map)).umask32(0x000000ff); map(0x8560, 0x856f).m(m_cursor[0], FUNC(bt431_device::map)).umask32(0x000000ff);
map(0x0580, 0x058f).m(m_cursor[1], FUNC(bt431_device::map)).umask32(0x000000ff); map(0x8580, 0x858f).m(m_cursor[1], FUNC(bt431_device::map)).umask32(0x000000ff);
map(0x05a0, 0x05a3).rw(FUNC(sgi_gr1_device::dr4_r), FUNC(sgi_gr1_device::dr4_w)).umask32(0xff000000); map(0x85a0, 0x85a3).rw(FUNC(sgi_gr1_device::dr4_r), FUNC(sgi_gr1_device::dr4_w)).umask32(0xff000000);
map(0x05c0, 0x05c3).rw(FUNC(sgi_gr1_device::dr3_r), FUNC(sgi_gr1_device::dr3_w)).umask32(0xff000000); map(0x85c0, 0x85c3).rw(FUNC(sgi_gr1_device::dr3_r), FUNC(sgi_gr1_device::dr3_w)).umask32(0xff000000);
map(0x05e0, 0x05e3).rw(FUNC(sgi_gr1_device::dr2_r), FUNC(sgi_gr1_device::dr2_w)).umask32(0xff000000); map(0x85e0, 0x85e3).rw(FUNC(sgi_gr1_device::dr2_r), FUNC(sgi_gr1_device::dr2_w)).umask32(0xff000000);
map(0x0640, 0x783).w(m_ge, FUNC(sgi_ge5_device::command_w)).umask32(0xffff0000); map(0x8640, 0x8783).w(m_ge, FUNC(sgi_ge5_device::command_w)).umask32(0xffff0000);
map(0x0740, 0x743).r(m_ge, FUNC(sgi_ge5_device::pc_r)).umask32(0xffff0000); map(0x8740, 0x8743).r(m_ge, FUNC(sgi_ge5_device::pc_r)).umask32(0xffff0000);
map(0x0800, 0x0bff).rw(FUNC(sgi_gr1_device::fifo_r), FUNC(sgi_gr1_device::fifo_w)); map(0x0800, 0x0bff).r(m_ge, FUNC(sgi_ge5_device::buffer_r)).mirror(0x8000);
map(0x0c00, 0x0dff).w(m_ge, FUNC(sgi_ge5_device::mar_w)); map(0x0800, 0x0bff).w(FUNC(sgi_gr1_device::fifo_w)).mirror(0x8000);
map(0x0e00, 0x0e07).w(m_ge, FUNC(sgi_ge5_device::mar_msb_w)); map(0x0c00, 0x0dff).w(m_ge, FUNC(sgi_ge5_device::mar_w)).mirror(0x8000);
map(0x0e00, 0x0e07).lw32("mar_msb", [this](offs_t offset, u32 data) { m_bank->set_bank(offset); }).mirror(0x8000);
map(0x1400, 0x17ff).rw(m_ge, FUNC(sgi_ge5_device::data_r), FUNC(sgi_ge5_device::data_w)); map(0x1400, 0x17ff).rw(m_ge, FUNC(sgi_ge5_device::data_r), FUNC(sgi_ge5_device::data_w));
map(0x2000, 0x2007).rw(m_ge, FUNC(sgi_ge5_device::finish_r), FUNC(sgi_ge5_device::finish_w)); map(0x2000, 0x2007).rw(m_ge, FUNC(sgi_ge5_device::finish_r), FUNC(sgi_ge5_device::finish_w)).mirror(0x8000);
//map(0x207c, 0x207f); // gr1 vs gr2 //map(0x207c, 0x207f); // gr1 vs gr2
} }
@ -140,7 +146,7 @@ void sgi_gr1_device::device_add_mconfig(machine_config &config)
{ {
unsigned pixel_clock = 107'352'000; unsigned pixel_clock = 107'352'000;
//ADDRESS_MAP_BANK(config, m_ext).set_map(&lle_device_base::ext_map).set_options(ENDIANNESS_NATIVE, 8, 12, 0x100); ADDRESS_MAP_BANK(config, m_bank).set_map(&sgi_gr1_device::map_bank).set_options(ENDIANNESS_NATIVE, 32, 32, 0x8000);
/* /*
* 1280x1024 @ 60Hz * 1280x1024 @ 60Hz
@ -160,11 +166,10 @@ void sgi_gr1_device::device_add_mconfig(machine_config &config)
SCREEN(config, m_screen, SCREEN_TYPE_RASTER); SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(pixel_clock, 1680, 246, 246 + 1280, 1065, 39, 39 + 1024); m_screen->set_raw(pixel_clock, 1680, 246, 246 + 1280, 1065, 39, 39 + 1024);
m_screen->set_screen_update(m_re.finder_tag(), FUNC(sgi_re2_device::screen_update)); m_screen->set_screen_update(m_re.finder_tag(), FUNC(sgi_re2_device::screen_update));
m_screen->screen_vblank().set([this](int state) { m_vblank_cb(state); });
SGI_GE5(config, m_ge, 10_MHz_XTAL); SGI_GE5(config, m_ge, 10_MHz_XTAL);
m_ge->fifo_empty().set([this]() { return int(m_fifo.empty()); }); m_ge->fifo_empty().set([this]() { return int(m_fifo.empty()); });
m_ge->fifo_read().set(FUNC(sgi_gr1_device::ge_fifo_r)); m_ge->fifo_read().set(FUNC(sgi_gr1_device::fifo_r));
m_ge->re_r().set(m_re, FUNC(sgi_re2_device::reg_r)); m_ge->re_r().set(m_re, FUNC(sgi_re2_device::reg_r));
m_ge->re_w().set(m_re, FUNC(sgi_re2_device::reg_w)); m_ge->re_w().set(m_re, FUNC(sgi_re2_device::reg_w));
@ -194,7 +199,6 @@ ioport_constructor sgi_gr1_device::device_input_ports() const
void sgi_gr1_device::device_start() void sgi_gr1_device::device_start()
{ {
m_vblank_cb.resolve_safe();
m_int_fifo_cb.resolve_safe(); m_int_fifo_cb.resolve_safe();
//save_item(NAME()); //save_item(NAME());
@ -204,6 +208,8 @@ void sgi_gr1_device::device_start()
void sgi_gr1_device::device_reset() void sgi_gr1_device::device_reset()
{ {
m_bank->set_bank(0);
m_dr0 = DR0_GRF1EN | DR0_SMALLMON0; m_dr0 = DR0_GRF1EN | DR0_SMALLMON0;
m_dr1 = DR1_TURBO; m_dr1 = DR1_TURBO;
//m_dr2 = 0; //m_dr2 = 0;
@ -213,9 +219,74 @@ void sgi_gr1_device::device_reset()
m_fifo.clear(); m_fifo.clear();
} }
u8 sgi_gr1_device::dr0_r()
{
LOG("dr0_r 0x%02x (%s)\n", m_dr0, machine().describe_context());
return m_dr0;
}
u8 sgi_gr1_device::dr1_r()
{
LOG("dr1_r 0x%02x (%s)\n", m_dr1, machine().describe_context());
return m_dr1;
}
u8 sgi_gr1_device::dr2_r()
{
LOG("dr2_r 0x%02x (%s)\n", m_dr2, machine().describe_context());
return m_dr2;
}
u8 sgi_gr1_device::dr3_r()
{
LOG("dr3_r 0x%02x (%s)\n", m_dr3, machine().describe_context());
return m_dr3;
}
u8 sgi_gr1_device::dr4_r()
{
LOG("dr4_r 0x%02x (%s)\n", m_dr4, machine().describe_context());
return (m_dr4 | (m_ge->suspended() ? 0 : DR4_GESTALL)) & DR4_RM;
}
void sgi_gr1_device::dr0_w(u8 data)
{
LOG("dr0_w 0x%02x (%s)\n", data, machine().describe_context());
m_dr0 = (m_dr0 & ~DR0_WM) | (data & DR0_WM);
}
void sgi_gr1_device::dr1_w(u8 data)
{
LOG("dr1_w 0x%02x (%s)\n", data, machine().describe_context());
m_dr1 = (m_dr1 & ~DR1_WM) | (data & DR1_WM);
m_ge->cwen_w(BIT(data, 1));
}
void sgi_gr1_device::dr2_w(u8 data)
{
LOG("dr2_w 0x%02x (%s)\n", data, machine().describe_context());
m_dr2 = (m_dr2 & ~DR2_WM) | (data & DR2_WM);
}
void sgi_gr1_device::dr3_w(u8 data)
{
LOG("dr3_w 0x%02x (%s)\n", data, machine().describe_context());
m_dr3 = (m_dr3 & ~DR3_WM) | (data & DR3_WM);
}
void sgi_gr1_device::dr4_w(u8 data) void sgi_gr1_device::dr4_w(u8 data)
{ {
LOG("dr4_w 0x%02x\n", data); LOG("dr4_w 0x%02x (%s)\n", data, machine().describe_context());
m_dr4 = (m_dr4 & ~DR4_WM) | (data & DR4_WM); m_dr4 = (m_dr4 & ~DR4_WM) | (data & DR4_WM);
@ -223,7 +294,7 @@ void sgi_gr1_device::dr4_w(u8 data)
xmap->map_select_w(m_dr4 & DR4_MS); xmap->map_select_w(m_dr4 & DR4_MS);
} }
u64 sgi_gr1_device::ge_fifo_r() u64 sgi_gr1_device::fifo_r()
{ {
u64 data = m_fifo.dequeue(); u64 data = m_fifo.dequeue();
@ -241,7 +312,7 @@ u64 sgi_gr1_device::ge_fifo_r()
void sgi_gr1_device::fifo_w(offs_t offset, u32 data, u32 mem_mask) void sgi_gr1_device::fifo_w(offs_t offset, u32 data, u32 mem_mask)
{ {
LOG("fifo_w 0x%010x\n", (u64(offset) << 32) | data); LOG("fifo_w 0x%010x (%s)\n", (u64(offset) << 32) | data, machine().describe_context());
m_fifo.enqueue((u64(offset) << 32) | data); m_fifo.enqueue((u64(offset) << 32) | data);

View File

@ -22,37 +22,43 @@ public:
static constexpr feature_type imperfect_features() { return feature::GRAPHICS; } static constexpr feature_type imperfect_features() { return feature::GRAPHICS; }
// configuration // configuration
auto out_vblank() { return m_vblank_cb.bind(); } auto out_vblank() { return subdevice<screen_device>("screen")->screen_vblank(); }
auto out_int_ge() { return subdevice<sgi_ge5_device>("ge5")->out_int(); } auto out_int() { return subdevice<sgi_ge5_device>("ge5")->out_int(); }
auto out_int_fifo() { return m_int_fifo_cb.bind(); } auto out_int_fifo() { return m_int_fifo_cb.bind(); }
u32 dma_r() { return subdevice<sgi_ge5_device>("ge5")->buffer_r(0); }
void dma_w(u32 data) { fifo_w(0, data, 0xffffffffU); }
void reset_w(int state); void reset_w(int state);
virtual void map(address_map &map); void map(address_map &map);
protected: protected:
void map_bank(address_map& map);
// device_t overrides // device_t overrides
virtual ioport_constructor device_input_ports() const override; virtual ioport_constructor device_input_ports() const override;
virtual void device_add_mconfig(machine_config &config) override; virtual void device_add_mconfig(machine_config &config) override;
virtual void device_start() override; virtual void device_start() override;
virtual void device_reset() override; virtual void device_reset() override;
u8 dr0_r() { return m_dr0; } // display registers
u8 dr1_r() { return m_dr1; } u8 dr0_r();
u8 dr2_r() { return m_dr2; } u8 dr1_r();
u8 dr3_r() { return m_dr3; } u8 dr2_r();
u8 dr4_r() { return (m_dr4 | (m_ge->suspended() ? 0 : DR4_GESTALL)) & DR4_RM; } u8 dr3_r();
void dr0_w(u8 data) { m_dr0 = (m_dr0 & ~DR0_WM) | (data & DR0_WM); } u8 dr4_r();
void dr1_w(u8 data) { m_dr1 = (m_dr1 & ~DR1_WM) | (data & DR1_WM); m_ge->cwen_w(BIT(data, 1)); } void dr0_w(u8 data);
void dr2_w(u8 data) { m_dr2 = (m_dr2 & ~DR2_WM) | (data & DR2_WM); } void dr1_w(u8 data);
void dr3_w(u8 data) { m_dr3 = (m_dr3 & ~DR3_WM) | (data & DR3_WM); } void dr2_w(u8 data);
void dr3_w(u8 data);
void dr4_w(u8 data); void dr4_w(u8 data);
u64 ge_fifo_r(); u64 fifo_r();
u32 fifo_r() { return u32(ge_fifo_r()); }
void fifo_w(offs_t offset, u32 data, u32 mem_mask); void fifo_w(offs_t offset, u32 data, u32 mem_mask);
private: private:
required_device<address_map_bank_device> m_bank;
required_device<screen_device> m_screen; required_device<screen_device> m_screen;
required_device<sgi_ge5_device> m_ge; required_device<sgi_ge5_device> m_ge;
required_device<sgi_re2_device> m_re; required_device<sgi_re2_device> m_re;
@ -60,7 +66,6 @@ private:
required_device_array<bt431_device, 2> m_cursor; required_device_array<bt431_device, 2> m_cursor;
required_device_array<bt457_device, 3> m_ramdac; required_device_array<bt457_device, 3> m_ramdac;
devcb_write_line m_vblank_cb;
devcb_write_line m_int_fifo_cb; devcb_write_line m_int_fifo_cb;
enum dr0_mask : u8 enum dr0_mask : u8

View File

@ -93,6 +93,9 @@ void sgi_re2_device::device_reset()
set_rdy(true); set_rdy(true);
set_drq(false); set_drq(false);
for (u32 &reg : m_reg)
reg = 0;
// reset register values indicate presence of RE2 // reset register values indicate presence of RE2
m_reg[REG_DZF] = 0; m_reg[REG_DZF] = 0;
m_reg[REG_DZF] = ~u32(0); m_reg[REG_DZF] = ~u32(0);
@ -139,11 +142,11 @@ void sgi_re2_device::reg_w(offs_t offset, u32 data)
{ {
if (regmask[offset]) if (regmask[offset])
{ {
if (offset != REG_RWDATA)
LOGMASKED(LOG_REG, "reg_w register 0x%02x (%s) data 0x%x\n", offset, regname[offset], data);
m_reg[offset] = data & regmask[offset]; m_reg[offset] = data & regmask[offset];
if (offset != REG_RWDATA)
LOGMASKED(LOG_REG, "reg_w register 0x%02x (%s) data 0x%x\n", offset, regname[offset], m_reg[offset]);
// special case register handling // special case register handling
switch (offset) switch (offset)
{ {
@ -272,12 +275,12 @@ void sgi_re2_device::execute()
break; break;
case IR_READBUF: case IR_READBUF:
LOG("ri read buffer\n"); LOG("ri read buffer rwmode %d\n", m_reg[REG_RWMODE]);
read_buffer(); read_buffer();
break; break;
case IR_WRITEBUF: case IR_WRITEBUF:
LOG("write buffer\n"); LOG("write buffer rwmode %d\n", m_reg[REG_RWMODE]);
write_buffer(); write_buffer();
break; break;
} }

View File

@ -84,6 +84,8 @@ u8 sgi_xmap2_device::reg_r(offs_t offset)
return m_wid_aux; return m_wid_aux;
else if (m_addr == 0x21) else if (m_addr == 0x21)
return m_options; return m_options;
else
logerror("read unknown address 0x%04x\n", m_addr);
break; break;
case 6: // address msb case 6: // address msb
@ -164,6 +166,8 @@ void sgi_xmap2_device::reg_w(offs_t offset, u8 data)
} }
else if (m_addr == 0x20) else if (m_addr == 0x20)
m_wid_aux = BIT(data, 0); m_wid_aux = BIT(data, 0);
else
logerror("write unknown address 0x%04x\n", m_addr);
break; break;
case 6: // address msb case 6: // address msb