summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
author cracyc <cracyc@users.noreply.github.com>2014-04-06 16:03:17 +0000
committer cracyc <cracyc@users.noreply.github.com>2014-04-06 16:03:17 +0000
commit3a2d05048629902324044b4204cc7efe0c013af9 (patch)
treeef728540bb1b0d6aaed6ccd2a3ffff49938d2b76 /src
parent4a2be6f1637dfaeb98aea894c742457e9515cfca (diff)
(mess) x68k: rework bus errors (nw)
hd63450: don't set timer when transfer expects only drqs (nw) upd765: x68k hangs when it receives polling irqs so can only guess the upd72065 doesn't send them (nw)
Diffstat (limited to 'src')
-rw-r--r--src/emu/machine/hd63450.c4
-rw-r--r--src/emu/machine/upd765.c5
-rw-r--r--src/emu/machine/upd765.h2
-rw-r--r--src/mess/drivers/x68k.c102
-rw-r--r--src/mess/includes/x68k.h5
5 files changed, 47 insertions, 71 deletions
diff --git a/src/emu/machine/hd63450.c b/src/emu/machine/hd63450.c
index 60a68345702..a95a3ba9d5d 100644
--- a/src/emu/machine/hd63450.c
+++ b/src/emu/machine/hd63450.c
@@ -269,6 +269,8 @@ void hd63450_device::dma_transfer_start(int channel, int dir)
m_timer[channel]->adjust(attotime::from_usec(500), channel, m_our_clock[channel]);
else if((m_reg[channel].ocr & 3) == 3)
m_timer[channel]->adjust(attotime::from_usec(500), channel, attotime::never);
+ else if((m_reg[channel].ocr & 3) == 2)
+ m_timer[channel]->adjust(attotime::never, channel, attotime::never);
m_transfer_size[channel] = m_reg[channel].mtc;
@@ -284,6 +286,8 @@ void hd63450_device::set_timer(int channel, attotime tm)
TIMER_CALLBACK_MEMBER(hd63450_device::dma_transfer_timer)
{
+ if((m_reg[param].ocr & 3) == 2)
+ return;
single_transfer(param);
}
diff --git a/src/emu/machine/upd765.c b/src/emu/machine/upd765.c
index 7bb36a65835..788c19dcee6 100644
--- a/src/emu/machine/upd765.c
+++ b/src/emu/machine/upd765.c
@@ -107,6 +107,7 @@ upd765_family_device::upd765_family_device(const machine_config &mconfig, device
ready_connected = true;
select_connected = true;
external_ready = false;
+ no_poll_irq = false;
dor_reset = 0x00;
mode = MODE_AT;
}
@@ -2018,7 +2019,8 @@ void upd765_family_device::run_drive_ready_polling()
if(!flopi[fid].st0_filled) {
flopi[fid].st0 = ST0_ABRT | fid;
flopi[fid].st0_filled = true;
- other_irq = true;
+ if(!no_poll_irq)
+ other_irq = true;
}
}
}
@@ -2225,6 +2227,7 @@ i8272a_device::i8272a_device(const machine_config &mconfig, const char *tag, dev
upd72065_device::upd72065_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, UPD72065, "UPD72065", tag, owner, clock, "upd72065", __FILE__)
{
dor_reset = 0x0c;
+ no_poll_irq = true;
}
smc37c78_device::smc37c78_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : upd765_family_device(mconfig, SMC37C78, "SMC37C78", tag, owner, clock, "smc37c78", __FILE__)
diff --git a/src/emu/machine/upd765.h b/src/emu/machine/upd765.h
index 06cc942adff..9aee9f28d4a 100644
--- a/src/emu/machine/upd765.h
+++ b/src/emu/machine/upd765.h
@@ -298,7 +298,7 @@ protected:
bool ready_connected, ready_polled, select_connected;
- bool external_ready;
+ bool external_ready, no_poll_irq;
int mode;
int main_phase;
diff --git a/src/mess/drivers/x68k.c b/src/mess/drivers/x68k.c
index 215282bb4ae..f1ee83a0710 100644
--- a/src/mess/drivers/x68k.c
+++ b/src/mess/drivers/x68k.c
@@ -1042,20 +1042,22 @@ WRITE16_MEMBER(x68k_state::x68k_enh_areaset_w )
TIMER_CALLBACK_MEMBER(x68k_state::x68k_bus_error)
{
- int val = param;
- int v;
- UINT8 *ram = m_ram->pointer();
+ m_bus_error = false;
+}
- if(strcmp(machine().system().name,"x68030") == 0)
- v = 0x0b;
- else
- v = 0x09;
- if(ram[v] != 0x02) // normal vector for bus errors points to 02FF0540
- {
- m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
- m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
- popmessage("Bus error: Unused RAM access [%08x]", val);
- }
+void x68k_state::set_bus_error(UINT32 address, bool write, UINT16 mem_mask)
+{
+ if(m_bus_error)
+ return;
+ if(!ACCESSING_BITS_8_15)
+ address++;
+ m_bus_error = true;
+ m68k_set_buserror_details(m_maincpu, address, write, m68k_get_fc(m_maincpu));
+ m_maincpu->mmu_tmp_buserror_address = address; // Hack for x68030
+ m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE);
+ m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE);
+ timer_set(m_maincpu->cycles_to_attotime(16), TIMER_X68K_BUS_ERROR); // let rmw cycles complete
+ logerror("%s: Bus error: Unused RAM access [%08x]\n", machine().describe_context(), address);
}
READ16_MEMBER(x68k_state::x68k_rom0_r)
@@ -1064,14 +1066,8 @@ READ16_MEMBER(x68k_state::x68k_rom0_r)
then access causes a bus error */
m_current_vector[2] = 0x02; // bus error
m_current_irq_line = 2;
-// m_maincpu->set_input_line_and_vector(2,ASSERT_LINE,m_current_vector[2]);
- if(ioport("options")->read() & 0x02)
- {
- offset *= 2;
- if(ACCESSING_BITS_0_7)
- offset++;
- timer_set(m_maincpu->cycles_to_attotime(4), TIMER_X68K_BUS_ERROR, 0xbffffc+offset);
- }
+ if((ioport("options")->read() & 0x02) && !space.debugger_access())
+ set_bus_error((offset << 1) + 0xbffffc, 0, mem_mask);
return 0xff;
}
@@ -1081,14 +1077,8 @@ WRITE16_MEMBER(x68k_state::x68k_rom0_w)
then access causes a bus error */
m_current_vector[2] = 0x02; // bus error
m_current_irq_line = 2;
-// m_maincpu->set_input_line_and_vector(2,ASSERT_LINE,m_current_vector[2]);
- if(ioport("options")->read() & 0x02)
- {
- offset *= 2;
- if(ACCESSING_BITS_0_7)
- offset++;
- timer_set(m_maincpu->cycles_to_attotime(4), TIMER_X68K_BUS_ERROR, 0xbffffc+offset);
- }
+ if((ioport("options")->read() & 0x02) && !space.debugger_access())
+ set_bus_error((offset << 1) + 0xbffffc, 1, mem_mask);
}
READ16_MEMBER(x68k_state::x68k_emptyram_r)
@@ -1097,14 +1087,8 @@ READ16_MEMBER(x68k_state::x68k_emptyram_r)
Often a method for detecting amount of installed RAM, is to read or write at 1MB intervals, until a bus error occurs */
m_current_vector[2] = 0x02; // bus error
m_current_irq_line = 2;
-// m_maincpu->set_input_line_and_vector(2,ASSERT_LINE,m_current_vector[2]);
- if(ioport("options")->read() & 0x02)
- {
- offset *= 2;
- if(ACCESSING_BITS_0_7)
- offset++;
- timer_set(m_maincpu->cycles_to_attotime(4), TIMER_X68K_BUS_ERROR, offset);
- }
+ if((ioport("options")->read() & 0x02) && !space.debugger_access())
+ set_bus_error((offset << 1), 0, mem_mask);
return 0xff;
}
@@ -1114,45 +1098,27 @@ WRITE16_MEMBER(x68k_state::x68k_emptyram_w)
Often a method for detecting amount of installed RAM, is to read or write at 1MB intervals, until a bus error occurs */
m_current_vector[2] = 0x02; // bus error
m_current_irq_line = 2;
-// m_maincpu->set_input_line_and_vector(2,ASSERT_LINE,m_current_vector[2]);
- if(ioport("options")->read() & 0x02)
- {
- offset *= 2;
- if(ACCESSING_BITS_0_7)
- offset++;
- timer_set(m_maincpu->cycles_to_attotime(4), TIMER_X68K_BUS_ERROR, offset);
- }
+ if((ioport("options")->read() & 0x02) && !space.debugger_access())
+ set_bus_error((offset << 1), 1, mem_mask);
}
READ16_MEMBER(x68k_state::x68k_exp_r)
{
/* These are expansion devices, if not present, they cause a bus error */
- if(ioport("options")->read() & 0x02)
- {
- m_current_vector[2] = 0x02; // bus error
- m_current_irq_line = 2;
- offset *= 2;
- if(ACCESSING_BITS_0_7)
- offset++;
- timer_set(m_maincpu->cycles_to_attotime(16), TIMER_X68K_BUS_ERROR, 0xeafa00+offset);
-// m_maincpu->set_input_line_and_vector(2,ASSERT_LINE,state->m_current_vector[2]);
- }
- return 0xffff;
+ m_current_vector[2] = 0x02; // bus error
+ m_current_irq_line = 2;
+ if((ioport("options")->read() & 0x02) && !space.debugger_access())
+ set_bus_error((offset << 1) + 0xeafa00, 0, mem_mask);
+ return 0xff;
}
WRITE16_MEMBER(x68k_state::x68k_exp_w)
{
/* These are expansion devices, if not present, they cause a bus error */
- if(ioport("options")->read() & 0x02)
- {
- m_current_vector[2] = 0x02; // bus error
- m_current_irq_line = 2;
- offset *= 2;
- if(ACCESSING_BITS_0_7)
- offset++;
- timer_set(m_maincpu->cycles_to_attotime(16), TIMER_X68K_BUS_ERROR, 0xeafa00+offset);
-// m_maincpu->set_input_line_and_vector(2,ASSERT_LINE,state->m_current_vector[2]);
- }
+ m_current_vector[2] = 0x02; // bus error
+ m_current_irq_line = 2;
+ if((ioport("options")->read() & 0x02) && !space.debugger_access())
+ set_bus_error((offset << 1) + 0xeafa00, 1, mem_mask);
}
void x68k_state::dma_irq(int channel)
@@ -1766,8 +1732,8 @@ MACHINE_START_MEMBER(x68k_state,x68030)
address_space &space = m_maincpu->space(AS_PROGRAM);
/* Install RAM handlers */
m_spriteram = (UINT16*)(*memregion("user1"));
- space.install_read_handler(0x000000,0xbffffb,0xffffffff,0,read16_delegate(FUNC(x68k_state::x68k_rom0_r),this),0xffffffff);
- space.install_write_handler(0x000000,0xbffffb,0xffffffff,0,write16_delegate(FUNC(x68k_state::x68k_rom0_w),this),0xffffffff);
+ space.install_read_handler(0x000000,0xbffffb,0xffffffff,0,read16_delegate(FUNC(x68k_state::x68k_emptyram_r),this),0xffffffff);
+ space.install_write_handler(0x000000,0xbffffb,0xffffffff,0,write16_delegate(FUNC(x68k_state::x68k_emptyram_w),this),0xffffffff);
space.install_readwrite_bank(0x000000,m_ram->size()-1,0xffffffff,0,"bank1");
membank("bank1")->set_base(m_ram->pointer());
space.install_read_handler(0xc00000,0xdfffff,0xffffffff,0,read32_delegate(FUNC(x68k_state::x68k_gvram32_r),this));
diff --git a/src/mess/includes/x68k.h b/src/mess/includes/x68k.h
index 5cb1a626f75..0d5b2050f79 100644
--- a/src/mess/includes/x68k.h
+++ b/src/mess/includes/x68k.h
@@ -9,6 +9,7 @@
#ifndef X68K_H_
#define X68K_H_
+#include "cpu/m68000/m68000.h"
#include "machine/hd63450.h"
#include "machine/rp5c15.h"
#include "machine/upd765.h"
@@ -58,7 +59,7 @@ public:
m_gvram32(*this, "gvram32"),
m_tvram32(*this, "tvram32") { }
- required_device<cpu_device> m_maincpu;
+ required_device<m68000_base_device> m_maincpu;
required_device<okim6258_device> m_okim6258;
required_device<hd63450_device> m_hd63450;
required_device<ram_device> m_ram;
@@ -327,6 +328,8 @@ public:
protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+ void set_bus_error(UINT32 address, bool write, UINT16 mem_mask);
+ bool m_bus_error;
};