mirror of
https://github.com/holub/mame
synced 2025-04-21 16:01:56 +03:00
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.
This commit is contained in:
parent
cdd6766fe4
commit
0c70ab3079
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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)" )
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user