summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Michael Zapf <Michael.Zapf@mizapf.de>2019-04-17 22:39:50 +0200
committer Michael Zapf <Michael.Zapf@mizapf.de>2019-04-17 22:39:50 +0200
commit0c70ab307932c8d8c46122a341e03a6d2193088b (patch)
treed3027382f61a5e265418650a45f1717e0632c0f4
parentcdd6766fe48154e389ae639c60023a28d28d1849 (diff)
tms99xx: Change setaddress method signature to (address,buslines); treating an address as a value to be written does not work with memory maps. Also fix 99/4p regression with wrong cru address access to peribox/evpc.
-rw-r--r--src/devices/bus/ti99/internal/992board.h4
-rw-r--r--src/devices/bus/ti99/internal/998board.cpp4
-rw-r--r--src/devices/bus/ti99/internal/998board.h2
-rw-r--r--src/devices/bus/ti99/internal/datamux.cpp42
-rw-r--r--src/devices/bus/ti99/internal/datamux.h7
-rw-r--r--src/devices/bus/ti99/internal/genboard.cpp4
-rw-r--r--src/devices/bus/ti99/internal/genboard.h2
-rw-r--r--src/devices/bus/ti99/peb/evpc.cpp10
-rw-r--r--src/devices/cpu/tms9900/tms9900.cpp71
-rw-r--r--src/devices/cpu/tms9900/tms9980a.cpp26
-rw-r--r--src/devices/cpu/tms9900/tms9995.cpp20
-rw-r--r--src/mame/drivers/ti99_4p.cpp8
12 files changed, 110 insertions, 90 deletions
diff --git a/src/devices/bus/ti99/internal/992board.h b/src/devices/bus/ti99/internal/992board.h
index 5b99519f81f..dff4f570d79 100644
--- a/src/devices/bus/ti99/internal/992board.h
+++ b/src/devices/bus/ti99/internal/992board.h
@@ -33,10 +33,6 @@ public:
static constexpr unsigned TOTAL_HORZ = 342;
static constexpr unsigned TOTAL_VERT_NTSC = 262;
- template <class Object> devcb_base &set_readmem_callback(Object &&cb) { return m_mem_read_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_hold_callback(Object &&cb) { return m_hold_cb.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_int_callback(Object &&cb) { return m_int_cb.set_callback(std::forward<Object>(cb)); }
-
// Delay(2) + ColorBurst(14) + Delay(8) + LeftBorder(13)
static constexpr unsigned HORZ_DISPLAY_START = 2 + 14 + 8 + 13;
// RightBorder(15) + Delay(8) + HorizSync(26)
diff --git a/src/devices/bus/ti99/internal/998board.cpp b/src/devices/bus/ti99/internal/998board.cpp
index 243c3e8c4b9..a91ad55344d 100644
--- a/src/devices/bus/ti99/internal/998board.cpp
+++ b/src/devices/bus/ti99/internal/998board.cpp
@@ -367,10 +367,10 @@ void mainboard8_device::cruwrite(offs_t offset, uint8_t data)
// =============== Memory bus access ==================
-void mainboard8_device::setaddress(offs_t mode, uint16_t offset)
+void mainboard8_device::setaddress(offs_t offset, uint8_t busctrl)
{
+ m_dbin_level = ((busctrl & TMS99xx_BUS_DBIN)!=0);
LOGMASKED(LOG_ADDRESS, "set %s %04x\n", (m_dbin_level==ASSERT_LINE)? "R" : "W", offset);
- m_dbin_level = ((mode & TMS99xx_BUS_DBIN)!=0);
// No data is waiting on the data bus
m_pending_write = false;
diff --git a/src/devices/bus/ti99/internal/998board.h b/src/devices/bus/ti99/internal/998board.h
index 47e52c0ae13..4040295470b 100644
--- a/src/devices/bus/ti99/internal/998board.h
+++ b/src/devices/bus/ti99/internal/998board.h
@@ -541,7 +541,7 @@ public:
// Memory space
uint8_t read(offs_t offset);
void write(offs_t offset, uint8_t data);
- void setaddress(offs_t mode, uint16_t address);
+ void setaddress(offs_t offset, uint8_t busctrl);
// Memory space for debugger access
uint8_t debugger_read(offs_t offset);
diff --git a/src/devices/bus/ti99/internal/datamux.cpp b/src/devices/bus/ti99/internal/datamux.cpp
index 875eda20465..ec2db94ce3e 100644
--- a/src/devices/bus/ti99/internal/datamux.cpp
+++ b/src/devices/bus/ti99/internal/datamux.cpp
@@ -98,6 +98,9 @@ datamux_device::datamux_device(const machine_config &mconfig, const char *tag, d
m_ram16b(*owner, TI99_EXPRAM_TAG),
m_padram(*owner, TI99_PADRAM_TAG),
m_cpu(*owner, "maincpu"),
+ m_grom0(*owner, TI99_GROM0_TAG),
+ m_grom1(*owner, TI99_GROM1_TAG),
+ m_grom2(*owner, TI99_GROM2_TAG),
m_ready(*this),
m_addr_buf(0),
m_dbin(CLEAR_LINE),
@@ -130,10 +133,9 @@ void datamux_device::read_all(uint16_t addr, uint8_t *value)
{
if (m_console_groms_present)
{
- for (int i=0; i < 3; i++)
- {
- m_grom[i]->readz(value);
- }
+ m_grom0->readz(value);
+ m_grom1->readz(value);
+ m_grom2->readz(value);
}
// GROMport (GROMs)
m_gromport->readz(addr, value);
@@ -164,8 +166,9 @@ void datamux_device::write_all(uint16_t addr, uint8_t value)
{
if (m_console_groms_present)
{
- for (int i=0; i < 3; i++)
- m_grom[i]->write(value);
+ m_grom0->write(value);
+ m_grom1->write(value);
+ m_grom2->write(value);
}
// GROMport
m_gromport->write(addr, value);
@@ -212,8 +215,11 @@ void datamux_device::setaddress_all(uint16_t addr)
if (isgrom) m_grom_idle = false;
if (m_console_groms_present)
- for (int i=0; i < 3; i++)
- m_grom[i]->set_lines((line_state)m_dbin, a14, gsq);
+ {
+ m_grom0->set_lines((line_state)m_dbin, a14, gsq);
+ m_grom1->set_lines((line_state)m_dbin, a14, gsq);
+ m_grom2->set_lines((line_state)m_dbin, a14, gsq);
+ }
// GROMport (GROMs)
m_gromport->set_gromlines((line_state)m_dbin, a14, gsq);
@@ -428,11 +434,11 @@ void datamux_device::write(offs_t offset, uint16_t data)
Called when the memory access starts by setting the address bus. From that
point on, we suspend the CPU until all operations are done.
*/
-void datamux_device::setaddress(offs_t mode, uint16_t addr)
+void datamux_device::setaddress(offs_t offset, uint16_t busctrl)
{
- m_addr_buf = addr;
+ m_addr_buf = offset << 1;
m_waitcount = 0;
- m_dbin = ((mode & TMS99xx_BUS_DBIN)!=0);
+ m_dbin = ((busctrl & TMS99xx_BUS_DBIN)!=0);
LOGMASKED(LOG_ADDRESS, "Set address %04x\n", m_addr_buf);
@@ -558,8 +564,10 @@ WRITE_LINE_MEMBER( datamux_device::gromclk_in )
// Propagate to the GROMs
if (m_console_groms_present)
{
- for (int i=0; i < 3; i++) m_grom[i]->gclock_in(state);
- m_grom_idle = m_grom[0]->idle();
+ m_grom0->gclock_in(state);
+ m_grom1->gclock_in(state);
+ m_grom2->gclock_in(state);
+ m_grom_idle = m_grom0->idle();
}
m_gromport->gclock_in(state);
@@ -610,14 +618,6 @@ void datamux_device::device_reset(void)
m_dbin = CLEAR_LINE;
}
-void datamux_device::device_config_complete()
-{
- m_grom[0] = downcast<tmc0430_device*>(owner()->subdevice(TI99_GROM0_TAG));
- m_grom[1] = downcast<tmc0430_device*>(owner()->subdevice(TI99_GROM1_TAG));
- m_grom[2] = downcast<tmc0430_device*>(owner()->subdevice(TI99_GROM2_TAG));
-}
-
-
INPUT_PORTS_START( datamux )
PORT_START( "RAM" ) /* config */
PORT_CONFNAME( 0x01, 0x00, "Console 32 KiB RAM upgrade (16 bit)" )
diff --git a/src/devices/bus/ti99/internal/datamux.h b/src/devices/bus/ti99/internal/datamux.h
index 829ef608bda..32e73a091b2 100644
--- a/src/devices/bus/ti99/internal/datamux.h
+++ b/src/devices/bus/ti99/internal/datamux.h
@@ -35,7 +35,7 @@ public:
datamux_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
uint16_t read(offs_t offset);
void write(offs_t offset, uint16_t data);
- void setaddress(offs_t mode, uint16_t address);
+ void setaddress(offs_t offset, uint16_t busctrl);
DECLARE_WRITE_LINE_MEMBER( clock_in );
DECLARE_WRITE_LINE_MEMBER( dbin_in );
@@ -50,7 +50,6 @@ protected:
void device_start() override;
void device_stop() override;
void device_reset() override;
- void device_config_complete() override;
ioport_constructor device_input_ports() const override;
private:
@@ -79,7 +78,9 @@ private:
uint16_t* m_consolerom;
// Console GROMs
- tmc0430_device* m_grom[3];
+ required_device<tmc0430_device> m_grom0;
+ required_device<tmc0430_device> m_grom1;
+ required_device<tmc0430_device> m_grom2;
// Common read routine
void read_all(uint16_t addr, uint8_t *target);
diff --git a/src/devices/bus/ti99/internal/genboard.cpp b/src/devices/bus/ti99/internal/genboard.cpp
index 718f7652966..d8998a2f33f 100644
--- a/src/devices/bus/ti99/internal/genboard.cpp
+++ b/src/devices/bus/ti99/internal/genboard.cpp
@@ -907,13 +907,13 @@ void geneve_mapper_device::write_to_pfm(offs_t offset, uint8_t data)
This decoding will later be used in the READ/WRITE member functions. Also,
we initiate wait state creation here.
*/
-void geneve_mapper_device::setaddress(offs_t mode, uint16_t address)
+void geneve_mapper_device::setaddress(offs_t address, uint8_t busctrl)
{
LOGMASKED(LOG_DETAIL, "setaddress = %04x\n", address);
m_debug_no_ws = false;
m_decoded.offset = address;
- m_read_mode = ((mode & TMS99xx_BUS_DBIN)!=0);
+ m_read_mode = ((busctrl & TMS99xx_BUS_DBIN)!=0);
decode_logical(m_read_mode, &m_decoded);
if (m_decoded.function == MUNDEF)
diff --git a/src/devices/bus/ti99/internal/genboard.h b/src/devices/bus/ti99/internal/genboard.h
index fe30b92e6c9..b0d6ba7bb1c 100644
--- a/src/devices/bus/ti99/internal/genboard.h
+++ b/src/devices/bus/ti99/internal/genboard.h
@@ -123,7 +123,7 @@ public:
uint8_t readm(offs_t offset);
void writem(offs_t offset, uint8_t data);
- void setaddress(offs_t mode, uint16_t address);
+ void setaddress(offs_t offset, uint8_t busctrl);
DECLARE_INPUT_CHANGED_MEMBER( settings_changed );
diff --git a/src/devices/bus/ti99/peb/evpc.cpp b/src/devices/bus/ti99/peb/evpc.cpp
index 6b17d75ef74..881a0104bab 100644
--- a/src/devices/bus/ti99/peb/evpc.cpp
+++ b/src/devices/bus/ti99/peb/evpc.cpp
@@ -321,11 +321,13 @@ READ8Z_MEMBER(snug_enhanced_video_device::crureadz)
{
if ((offset & 0xff00)==EVPC_CRU_BASE)
{
- if ((offset & 0x00f0)==0) // offset 0 delivers bits 0-7 (address 00-0f)
+ switch ((offset>>1) & 7)
{
- uint8_t p = ~(ioport("EVPC-SW1")->read() | (ioport("EVPC-SW3")->read()<<2)
- | (ioport("EVPC-SW4")->read()<<3) | (ioport("EVPC-SW8")->read()<<7));
- *value = BIT(p, (offset >> 1) & 7);
+ case 0: *value = ~(ioport("EVPC-SW1")->read()); break;
+ case 2: *value = ~(ioport("EVPC-SW3")->read()); break;
+ case 3: *value = ~(ioport("EVPC-SW4")->read()); break;
+ case 7: *value = ~(ioport("EVPC-SW8")->read()); break;
+ default: *value = ~0; break;
}
}
}
diff --git a/src/devices/cpu/tms9900/tms9900.cpp b/src/devices/cpu/tms9900/tms9900.cpp
index de0621bb6bd..c2ef748a925 100644
--- a/src/devices/cpu/tms9900/tms9900.cpp
+++ b/src/devices/cpu/tms9900/tms9900.cpp
@@ -159,12 +159,12 @@ enum
tms99xx_device::tms99xx_device(const machine_config &mconfig, device_type type, const char *tag, int data_width, int prg_addr_bits, int cru_addr_bits, device_t *owner, uint32_t clock)
: cpu_device(mconfig, type, tag, owner, clock),
m_program_config("program", ENDIANNESS_BIG, data_width, prg_addr_bits),
- m_setaddress_config("setaddress", ENDIANNESS_BIG, prg_addr_bits, prg_addr_bits), // data = address
+ m_setaddress_config("setaddress", ENDIANNESS_BIG, data_width, prg_addr_bits), // choose the same width as the program space
m_io_config("cru", ENDIANNESS_LITTLE, 8, cru_addr_bits + 1, 1),
m_prgspace(nullptr),
m_cru(nullptr),
- m_prgaddr_mask((1<<prg_addr_bits)-1),
- m_cruaddr_mask((2<<cru_addr_bits)-2),
+ m_prgaddr_mask((1<<prg_addr_bits)-2), // fffe for 16 bits, 3ffe for 14 bits (only even addresses)
+ m_cruaddr_mask((2<<cru_addr_bits)-2), // Address is shifted left by one
m_iaq(false),
m_clock_out_line(*this),
m_wait_line(*this),
@@ -328,10 +328,10 @@ void tms99xx_device::state_import(const device_state_entry &entry)
// bits of the STATUS register
break;
case TMS9900_PC:
- PC = (uint16_t)(m_state_any & m_prgaddr_mask & 0xfffe);
+ PC = (uint16_t)(m_state_any & m_prgaddr_mask);
break;
case TMS9900_WP:
- WP = (uint16_t)(m_state_any & m_prgaddr_mask & 0xfffe);
+ WP = (uint16_t)(m_state_any & m_prgaddr_mask);
break;
case TMS9900_STATUS:
ST = (uint16_t)m_state_any;
@@ -404,7 +404,7 @@ uint16_t tms99xx_device::read_workspace_register_debug(int reg)
{
int temp = m_icount;
auto dis = machine().disable_side_effects();
- uint16_t value = m_prgspace->read_word((WP+(reg<<1)) & m_prgaddr_mask & 0xfffe);
+ uint16_t value = m_prgspace->read_word((WP+(reg<<1)) & m_prgaddr_mask);
m_icount = temp;
return value;
}
@@ -413,10 +413,26 @@ void tms99xx_device::write_workspace_register_debug(int reg, uint16_t data)
{
int temp = m_icount;
auto dis = machine().disable_side_effects();
- m_prgspace->write_word((WP+(reg<<1)) & m_prgaddr_mask & 0xfffe, data);
+ m_prgspace->write_word((WP+(reg<<1)) & m_prgaddr_mask, data);
m_icount = temp;
}
+/*
+ The setaddress space is used to implement a split-phase memory access
+ where the address bus is first set, then the CPU samples the READY line,
+ (when low, enters wait states,) then the CPU reads the address bus. For
+ writing, setting the address and setting the data bus is done in direct
+ succession.
+
+ It is an optional feature, where drivers may connect to this space to
+ make use of it, or to completely ignore it when there is no need for
+ waitstate control.
+
+ In order to allow for using address maps, the setaddress space shows the
+ same widths as the normal program space. Its values are the levels of
+ certains lines that are set or reset during the memory access, in
+ particular DBIN and IAQ.
+*/
device_memory_interface::space_config_vector tms99xx_device::memory_space_config() const
{
if (has_configured_map(AS_SETADDRESS))
@@ -1511,7 +1527,7 @@ void tms99xx_device::acquire_instruction()
LOGMASKED(LOG_EXEC, "%04x\n", PC);
debugger_instruction_hook(PC);
- PC = (PC + 2) & 0xfffe & m_prgaddr_mask;
+ PC = (PC + 2) & m_prgaddr_mask;
// IAQ will be cleared in the main loop
}
}
@@ -1530,8 +1546,7 @@ void tms99xx_device::mem_read()
{
LOGMASKED(LOG_ADDRESSBUS, "set address (r) %04x\n", m_address);
if (m_setaddr)
- // Note that the bus lines form a pseudo address that is shifted right by one in the handler
- m_setaddr->write_word((TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0))<<1, m_address & m_prgaddr_mask & 0xfffe);
+ m_setaddr->write_word(m_address & m_prgaddr_mask, (TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0)));
m_check_ready = true;
m_mem_phase = 2;
m_pass = 2;
@@ -1541,7 +1556,7 @@ void tms99xx_device::mem_read()
else
{
// Second phase (after READY was raised again)
- m_current_value = m_prgspace->read_word(m_address & m_prgaddr_mask & 0xfffe);
+ m_current_value = m_prgspace->read_word(m_address & m_prgaddr_mask);
pulse_clock(1);
m_mem_phase = 1; // reset to phase 1
LOGMASKED(LOG_MEM, "mem r %04x -> %04x\n", m_address, m_current_value);
@@ -1555,9 +1570,9 @@ void tms99xx_device::mem_write()
LOGMASKED(LOG_ADDRESSBUS, "set address (w) %04x\n", m_address);
// When writing, the data bus is asserted immediately after the address bus
if (m_setaddr)
- m_setaddr->write_word(TMS99xx_BUS_WRITE, m_address & m_prgaddr_mask & 0xfffe);
+ m_setaddr->write_word(m_address & m_prgaddr_mask, TMS99xx_BUS_WRITE);
LOGMASKED(LOG_MEM, "mem w %04x <- %04x\n", m_address, m_current_value);
- m_prgspace->write_word(m_address & m_prgaddr_mask & 0xfffe, m_current_value);
+ m_prgspace->write_word(m_address & m_prgaddr_mask, m_current_value);
m_check_ready = true;
m_mem_phase = 2;
m_pass = 2;
@@ -1595,7 +1610,7 @@ void tms99xx_device::register_write()
{
// This will be called twice; m_pass is set by the embedded mem_write
uint16_t addr_save = m_address;
- m_address = (WP + (m_regnumber<<1)) & m_prgaddr_mask & 0xfffe;
+ m_address = (WP + (m_regnumber<<1)) & m_prgaddr_mask;
mem_write();
m_address = addr_save;
}
@@ -1820,7 +1835,7 @@ void tms99xx_device::alu_pcaddr_advance()
{
// Set PC as new read address, increase by 2
m_address = PC;
- PC = (PC + 2) & 0xfffe & m_prgaddr_mask;
+ PC = (PC + 2) & m_prgaddr_mask;
pulse_clock(2);
}
@@ -1836,7 +1851,7 @@ void tms99xx_device::alu_imm()
m_value_copy = m_current_value;
m_address_copy = m_address;
m_address = PC;
- PC = (PC + 2) & 0xfffe & m_prgaddr_mask;
+ PC = (PC + 2) & m_prgaddr_mask;
pulse_clock(2);
}
@@ -2118,7 +2133,7 @@ void tms99xx_device::alu_xop()
break;
case 1:
m_value_copy = WP; // save the old WP
- WP = m_current_value & m_prgaddr_mask & 0xfffe; // the new WP has been read in the previous microoperation
+ WP = m_current_value & m_prgaddr_mask; // the new WP has been read in the previous microoperation
m_current_value = m_address_saved; // we saved the address of the source operand; retrieve it
m_address = WP + 0x0016; // Next register is R11
break;
@@ -2139,7 +2154,7 @@ void tms99xx_device::alu_xop()
set_status_bit(ST_X, true);
break;
case 6:
- PC = m_current_value & m_prgaddr_mask & 0xfffe;
+ PC = m_current_value & m_prgaddr_mask;
break;
}
pulse_clock(2);
@@ -2264,7 +2279,7 @@ void tms99xx_device::alu_b()
// retrieves the value at 0xa000, but in fact it will load the PC
// with the address 0xa000
m_current_value = PC;
- PC = m_address & m_prgaddr_mask & 0xfffe;
+ PC = m_address & m_prgaddr_mask;
m_address = WP + 22;
pulse_clock(2);
}
@@ -2275,7 +2290,7 @@ void tms99xx_device::alu_blwp()
{
case 0:
m_value_copy = WP;
- WP = m_current_value & m_prgaddr_mask & 0xfffe; // set new WP (*m_destination)
+ WP = m_current_value & m_prgaddr_mask; // set new WP (*m_destination)
m_address_saved = (m_address + 2) & m_prgaddr_mask; // Save the location of the WP
m_address = WP + 30;
m_current_value = ST; // get status register
@@ -2292,7 +2307,7 @@ void tms99xx_device::alu_blwp()
m_address = m_address_saved; // point to PC component of branch vector
break;
case 4:
- PC = m_current_value & m_prgaddr_mask & 0xfffe;
+ PC = m_current_value & m_prgaddr_mask;
LOGMASKED(LOG_CONTEXT, "Context switch (blwp): WP=%04x, PC=%04x, ST=%04x\n", WP, PC, ST);
break;
}
@@ -2492,7 +2507,7 @@ void tms99xx_device::alu_jmp()
else
{
displacement = (IR & 0xff);
- PC = (PC + (displacement<<1)) & m_prgaddr_mask & 0xfffe;
+ PC = (PC + (displacement<<1)) & m_prgaddr_mask;
}
m_state++;
pulse_clock(2);
@@ -2623,7 +2638,7 @@ void tms99xx_device::alu_li()
void tms99xx_device::alu_lwpi()
{
- WP = m_current_value & m_prgaddr_mask & 0xfffe;
+ WP = m_current_value & m_prgaddr_mask;
pulse_clock(2);
}
@@ -2672,11 +2687,11 @@ void tms99xx_device::alu_rtwp()
m_address -= 2; // R14
break;
case 2:
- PC = m_current_value & m_prgaddr_mask & 0xfffe;
+ PC = m_current_value & m_prgaddr_mask;
m_address -= 2; // R13
break;
case 3:
- WP = m_current_value & m_prgaddr_mask & 0xfffe;
+ WP = m_current_value & m_prgaddr_mask;
pulse_clock(2);
// Just for debugging purposes
m_log_interrupt = false;
@@ -2710,7 +2725,7 @@ void tms99xx_device::alu_int()
case 1:
m_address_copy = m_address;
m_value_copy = WP; // old WP
- WP = m_current_value & m_prgaddr_mask & 0xfffe; // new WP
+ WP = m_current_value & m_prgaddr_mask; // new WP
m_current_value = ST;
m_address = (WP + 30) & m_prgaddr_mask;
LOGMASKED(LOG_INTD, "interrupt service (1): Read new WP = %04x, save ST to %04x\n", WP, m_address);
@@ -2726,11 +2741,11 @@ void tms99xx_device::alu_int()
LOGMASKED(LOG_INTD, "interrupt service (3): Save WP to %04x\n", m_address);
break;
case 4:
- m_address = (m_address_copy + 2) & 0xfffe & m_prgaddr_mask;
+ m_address = (m_address_copy + 2) & m_prgaddr_mask;
LOGMASKED(LOG_INTD, "interrupt service (4): Read PC from %04x\n", m_address);
break;
case 5:
- PC = m_current_value & m_prgaddr_mask & 0xfffe;
+ PC = m_current_value & m_prgaddr_mask;
if (m_irq_level > 0 )
{
ST = (ST & 0xfff0) | (m_irq_level - 1);
diff --git a/src/devices/cpu/tms9900/tms9980a.cpp b/src/devices/cpu/tms9900/tms9980a.cpp
index b48dae0de8b..67212697f0e 100644
--- a/src/devices/cpu/tms9900/tms9980a.cpp
+++ b/src/devices/cpu/tms9900/tms9980a.cpp
@@ -109,7 +109,7 @@ void tms9980a_device::resolve_lines()
uint16_t tms9980a_device::read_workspace_register_debug(int reg)
{
int temp = m_icount;
- int addr = (WP+(reg<<1)) & 0xfffe & m_prgaddr_mask;
+ int addr = (WP+(reg<<1)) & m_prgaddr_mask;
uint16_t value = (m_prgspace->read_byte(addr) << 8) | (m_prgspace->read_byte(addr+1) & 0xff);
m_icount = temp;
return value;
@@ -118,7 +118,7 @@ uint16_t tms9980a_device::read_workspace_register_debug(int reg)
void tms9980a_device::write_workspace_register_debug(int reg, uint16_t data)
{
int temp = m_icount;
- int addr = (WP+(reg<<1)) & 0xfffe & m_prgaddr_mask;
+ int addr = (WP+(reg<<1)) & m_prgaddr_mask;
m_prgspace->write_byte(addr, data>>8);
m_prgspace->write_byte(addr+1, data & 0xff);
m_icount = temp;
@@ -195,19 +195,19 @@ void tms9980a_device::mem_read()
case 1:
m_pass = 4; // make the CPU visit this method more than once
if (m_setaddr)
- m_setaddr->write_word((TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0))<<1, m_address & m_prgaddr_mask & ~1);
- LOGMASKED(LOG_ADDRESSBUS, "Set address bus %04x\n", m_address & m_prgaddr_mask & ~1);
+ m_setaddr->write_byte(m_address & m_prgaddr_mask, (TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0)));
+ LOGMASKED(LOG_ADDRESSBUS, "Set address bus %04x\n", m_address & m_prgaddr_mask);
m_check_ready = true;
break;
case 2:
// Sample the value on the data bus (high byte)
- value = m_prgspace->read_byte(m_address & m_prgaddr_mask & ~1);
- LOGMASKED(LOG_MEM, "Memory read high byte %04x -> %02x\n", m_address & m_prgaddr_mask & ~1, value);
+ value = m_prgspace->read_byte(m_address & m_prgaddr_mask);
+ LOGMASKED(LOG_MEM, "Memory read high byte %04x -> %02x\n", m_address & m_prgaddr_mask, value);
m_current_value = (value << 8) & 0xff00;
break;
case 3:
if (m_setaddr)
- m_setaddr->write_word((TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0))<<1, (m_address & m_prgaddr_mask) | 1);
+ m_setaddr->write_byte((m_address & m_prgaddr_mask) | 1, (TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0)));
LOGMASKED(LOG_ADDRESSBUS, "Set address bus %04x\n", (m_address & m_prgaddr_mask) | 1);
break;
case 4:
@@ -229,10 +229,10 @@ void tms9980a_device::mem_write()
case 1:
m_pass = 4; // make the CPU visit this method once more
if (m_setaddr)
- m_setaddr->write_word(TMS99xx_BUS_WRITE, m_address & m_prgaddr_mask & ~1);
- LOGMASKED(LOG_ADDRESSBUS, "Set address bus %04x\n", m_address & m_prgaddr_mask & ~1);
- m_prgspace->write_byte(m_address & 0x3ffe & ~1, (m_current_value >> 8)&0xff);
- LOGMASKED(LOG_MEM, "Memory write high byte %04x <- %02x\n", m_address & m_prgaddr_mask & ~1, (m_current_value >> 8)&0xff);
+ m_setaddr->write_byte(m_address & m_prgaddr_mask, TMS99xx_BUS_WRITE);
+ LOGMASKED(LOG_ADDRESSBUS, "Set address bus %04x\n", m_address & m_prgaddr_mask);
+ m_prgspace->write_byte(m_address & 0x3ffe, (m_current_value >> 8)&0xff);
+ LOGMASKED(LOG_MEM, "Memory write high byte %04x <- %02x\n", m_address & m_prgaddr_mask, (m_current_value >> 8)&0xff);
m_check_ready = true;
break;
case 2:
@@ -240,7 +240,7 @@ void tms9980a_device::mem_write()
break;
case 3:
if (m_setaddr)
- m_setaddr->write_word(TMS99xx_BUS_WRITE, (m_address & m_prgaddr_mask) | 1);
+ m_setaddr->write_byte((m_address & m_prgaddr_mask) | 1, TMS99xx_BUS_WRITE);
LOGMASKED(LOG_ADDRESSBUS, "Set address bus %04x\n", (m_address & m_prgaddr_mask) | 1);
m_prgspace->write_byte((m_address & m_prgaddr_mask) | 1, m_current_value & 0xff);
LOGMASKED(LOG_MEM, "Memory write low byte %04x <- %02x\n", (m_address & m_prgaddr_mask) | 1, m_current_value & 0xff);
@@ -268,7 +268,7 @@ void tms9980a_device::acquire_instruction()
decode(m_current_value);
LOGMASKED(LOG_OP, "===== Next operation %04x (%s) at %04x =====\n", IR, opname[m_command], PC);
debugger_instruction_hook(PC);
- PC = (PC + 2) & 0xfffe & m_prgaddr_mask;
+ PC = (PC + 2) & m_prgaddr_mask;
}
// IAQ will be cleared in the main loop
}
diff --git a/src/devices/cpu/tms9900/tms9995.cpp b/src/devices/cpu/tms9900/tms9995.cpp
index 5f1a88948e2..2c24f7e7697 100644
--- a/src/devices/cpu/tms9900/tms9995.cpp
+++ b/src/devices/cpu/tms9900/tms9995.cpp
@@ -170,7 +170,7 @@ tms9995_device::tms9995_device(const machine_config &mconfig, device_type type,
PC_debug(0),
m_iaq(false),
m_program_config("program", ENDIANNESS_BIG, 8, 16),
- m_setaddress_config("setaddress", ENDIANNESS_BIG, 16, 16), // data = address
+ m_setaddress_config("setaddress", ENDIANNESS_BIG, 8, 16), // see tms9900.cpp
m_io_config("cru", ENDIANNESS_LITTLE, 8, 16, 1),
m_prgspace(nullptr),
m_setaddr(nullptr),
@@ -438,6 +438,12 @@ void tms9995_device::write_workspace_register_debug(int reg, uint16_t data)
m_icount = temp;
}
+/*
+ The setaddress space is used to implement a split-phase memory access
+ where the address bus is first set, then the CPU samples the READY line,
+ (when low, enters wait states,) then the CPU reads the address bus. See
+ tms9900.cpp for more information.
+*/
device_memory_interface::space_config_vector tms9995_device::memory_space_config() const
{
if (has_configured_map(AS_SETADDRESS))
@@ -1851,9 +1857,9 @@ void tms9995_device::mem_read()
else m_pass = 2;
m_check_hold = false;
- LOGMASKED(LOG_ADDRESSBUS, "set address bus %04x\n", m_address & ~1);
+ LOGMASKED(LOG_ADDRESSBUS, "set address bus %04x\n", m_address & 0xfffe);
if (m_setaddr)
- m_setaddr->write_word((TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0))<<1, address);
+ m_setaddr->write_byte(address, (TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0)));
m_request_auto_wait_state = m_auto_wait;
pulse_clock(1);
break;
@@ -1861,14 +1867,14 @@ void tms9995_device::mem_read()
// Sample the value on the data bus (high byte)
if (m_word_access || !m_byteop) address &= 0xfffe;
value = m_prgspace->read_byte(address);
- LOGMASKED(LOG_MEM, "memory read byte %04x -> %02x\n", m_address & ~1, value);
+ LOGMASKED(LOG_MEM, "memory read byte %04x -> %02x\n", m_address & 0xfffe, value);
m_current_value = (value << 8) & 0xff00;
break;
case 3:
// Set address + 1 (unless byte command)
LOGMASKED(LOG_ADDRESSBUS, "set address bus %04x\n", m_address | 1);
if (m_setaddr)
- m_setaddr->write_word((TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0))<<1, m_address | 1);
+ m_setaddr->write_byte(m_address | 1, (TMS99xx_BUS_DBIN | (m_iaq? TMS99xx_BUS_IAQ : 0)));
m_request_auto_wait_state = m_auto_wait;
pulse_clock(1);
break;
@@ -1985,7 +1991,7 @@ void tms9995_device::mem_write()
m_check_hold = false;
LOGMASKED(LOG_ADDRESSBUS, "set address bus %04x\n", address);
if (m_setaddr)
- m_setaddr->write_word(TMS99xx_BUS_WRITE, address);
+ m_setaddr->write_byte(address, TMS99xx_BUS_WRITE);
LOGMASKED(LOG_MEM, "memory write byte %04x <- %02x\n", address, (m_current_value >> 8)&0xff);
m_prgspace->write_byte(address, (m_current_value >> 8)&0xff);
m_request_auto_wait_state = m_auto_wait;
@@ -1999,7 +2005,7 @@ void tms9995_device::mem_write()
// Set address + 1 (unless byte command)
LOGMASKED(LOG_ADDRESSBUS, "set address bus %04x\n", m_address | 1);
if (m_setaddr)
- m_setaddr->write_word(TMS99xx_BUS_WRITE, m_address | 1);
+ m_setaddr->write_byte(m_address | 1, TMS99xx_BUS_WRITE);
LOGMASKED(LOG_MEM, "memory write byte %04x <- %02x\n", m_address | 1, m_current_value & 0xff);
m_prgspace->write_byte(m_address | 1, m_current_value & 0xff);
m_request_auto_wait_state = m_auto_wait;
diff --git a/src/mame/drivers/ti99_4p.cpp b/src/mame/drivers/ti99_4p.cpp
index 5884054f796..3b0be43a5b4 100644
--- a/src/mame/drivers/ti99_4p.cpp
+++ b/src/mame/drivers/ti99_4p.cpp
@@ -429,11 +429,11 @@ int ti99_4p_state::decode_address(int address)
Called when the memory access starts by setting the address bus. From that
point on, we suspend the CPU until all operations are done.
*/
-void ti99_4p_state::setaddress(offs_t mode, uint16_t address)
+void ti99_4p_state::setaddress(offs_t address, uint16_t busctrl)
{
- m_addr_buf = address;
+ m_addr_buf = address << 1;
m_waitcount = 0;
- m_dbin = ((mode & TMS99xx_BUS_DBIN)!=0);
+ m_dbin = ((busctrl & TMS99xx_BUS_DBIN)!=0);
LOGMASKED(LOG_ADDRESS, "set address %04x\n", m_addr_buf);
@@ -717,7 +717,7 @@ void ti99_4p_state::cruwrite(offs_t offset, uint8_t data)
uint8_t ti99_4p_state::cruread(offs_t offset)
{
uint8_t value = 0;
- m_peribox->crureadz(offset<<4, &value);
+ m_peribox->crureadz(offset<<1, &value);
return value;
}