From 0c70ab307932c8d8c46122a341e03a6d2193088b Mon Sep 17 00:00:00 2001 From: Michael Zapf Date: Wed, 17 Apr 2019 22:39:50 +0200 Subject: 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. --- src/devices/bus/ti99/internal/992board.h | 4 -- src/devices/bus/ti99/internal/998board.cpp | 4 +- src/devices/bus/ti99/internal/998board.h | 2 +- src/devices/bus/ti99/internal/datamux.cpp | 42 +++++++++--------- src/devices/bus/ti99/internal/datamux.h | 7 +-- src/devices/bus/ti99/internal/genboard.cpp | 4 +- src/devices/bus/ti99/internal/genboard.h | 2 +- src/devices/bus/ti99/peb/evpc.cpp | 10 +++-- src/devices/cpu/tms9900/tms9900.cpp | 71 ++++++++++++++++++------------ src/devices/cpu/tms9900/tms9980a.cpp | 26 +++++------ src/devices/cpu/tms9900/tms9995.cpp | 20 ++++++--- src/mame/drivers/ti99_4p.cpp | 8 ++-- 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 devcb_base &set_readmem_callback(Object &&cb) { return m_mem_read_cb.set_callback(std::forward(cb)); } - template devcb_base &set_hold_callback(Object &&cb) { return m_hold_cb.set_callback(std::forward(cb)); } - template devcb_base &set_int_callback(Object &&cb) { return m_int_cb.set_callback(std::forward(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(owner()->subdevice(TI99_GROM0_TAG)); - m_grom[1] = downcast(owner()->subdevice(TI99_GROM1_TAG)); - m_grom[2] = downcast(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 m_grom0; + required_device m_grom1; + required_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<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; } -- cgit v1.2.3