trunk/src/mess/machine/ti99/datamux.c
| r23565 | r23566 | |
| 84 | 84 | DEVICE ACCESSOR FUNCTIONS |
| 85 | 85 | ***************************************************************************/ |
| 86 | 86 | |
| 87 | void ti99_datamux_device::read_all(address_space& space, UINT16 addr, UINT8 *target) |
| 88 | { |
| 89 | attached_device *dev = m_devices.first(); |
| 90 | |
| 91 | // Reading the odd address first (addr+1) |
| 92 | while (dev != NULL) |
| 93 | { |
| 94 | if (dev->m_config->write_select != 0xffff) // write-only |
| 95 | { |
| 96 | if ((addr & dev->m_config->address_mask)==dev->m_config->select) |
| 97 | { |
| 98 | // Cast to the bus8z_device (see ti99defs.h) |
| 99 | bus8z_device *devz = static_cast<bus8z_device *>(dev->m_device); |
| 100 | devz->readz(space, addr, target); |
| 101 | } |
| 102 | // hope we don't have two devices answering... |
| 103 | // consider something like a logical OR and maybe some artificial smoke |
| 104 | } |
| 105 | dev = dev->m_next; |
| 106 | } |
| 107 | } |
| 108 | |
| 109 | void ti99_datamux_device::write_all(address_space& space, UINT16 addr, UINT8 value) |
| 110 | { |
| 111 | attached_device *dev = m_devices.first(); |
| 112 | while (dev != NULL) |
| 113 | { |
| 114 | if ((addr & dev->m_config->address_mask)==(dev->m_config->select | dev->m_config->write_select)) |
| 115 | { |
| 116 | bus8z_device *devz = static_cast<bus8z_device *>(dev->m_device); |
| 117 | devz->write(space, addr, value); |
| 118 | } |
| 119 | dev = dev->m_next; |
| 120 | } |
| 121 | } |
| 122 | |
| 87 | 123 | /* |
| 88 | 124 | Read access. We are using two loops because the delay between both |
| 89 | 125 | accesses must not occur within the loop. So we have one access on the bus, |
| r23565 | r23566 | |
| 97 | 133 | UINT8 hbyte = 0; |
| 98 | 134 | UINT16 addr = (offset << 1); |
| 99 | 135 | |
| 100 | | assert (mem_mask == 0xffff); |
| 101 | | |
| 102 | 136 | // Looks ugly, but this is close to the real thing. If the 16bit |
| 103 | 137 | // memory expansion is installed in the console, and the access hits its |
| 104 | 138 | // space, just respond to the memory access and don't bother the |
| r23565 | r23566 | |
| 113 | 147 | if (base != 0) |
| 114 | 148 | { |
| 115 | 149 | UINT16 reply = m_ram16b[offset-base]; |
| 116 | | return reply; |
| 150 | return reply & mem_mask; |
| 117 | 151 | } |
| 118 | 152 | } |
| 119 | 153 | |
| 120 | | attached_device *dev = m_devices.first(); |
| 154 | // Read the odd address into the latch |
| 155 | read_all(space, addr+1, &m_latch); |
| 121 | 156 | |
| 122 | | // Reading the odd address first (addr+1) |
| 123 | | while (dev != NULL) |
| 124 | | { |
| 125 | | if (((addr+1) & dev->m_config->address_mask)==dev->m_config->select) |
| 126 | | { |
| 127 | | // Cast to the bus8z_device (see ti99defs.h) |
| 128 | | bus8z_device *devz = static_cast<bus8z_device *>(dev->m_device); |
| 129 | | devz->readz(*m_space, addr+1, &m_latch); |
| 130 | | } |
| 131 | | // hope we don't have two devices answering... |
| 132 | | // consider something like a logical OR and maybe some artificial smoke |
| 133 | | dev = dev->m_next; |
| 134 | | } |
| 135 | | |
| 136 | | dev = m_devices.first(); |
| 137 | | |
| 138 | 157 | // Reading the even address now (addr) |
| 139 | | while (dev != NULL) |
| 140 | | { |
| 141 | | if (dev->m_config->write_select != 0xffff) // write-only |
| 142 | | { |
| 143 | | if ((addr & dev->m_config->address_mask)==dev->m_config->select) |
| 144 | | { |
| 145 | | bus8z_device *devz = static_cast<bus8z_device *>(dev->m_device); |
| 146 | | devz->readz(*m_space, addr, &hbyte); |
| 147 | | } |
| 148 | | } |
| 149 | | dev = dev->m_next; |
| 150 | | } |
| 158 | read_all(space, addr, &hbyte); |
| 151 | 159 | |
| 152 | 160 | // Insert four wait states and let CPU enter wait state |
| 153 | 161 | // The counter in the real console is implemented by a shift register |
| 154 | 162 | // that is triggered on a memory access |
| 163 | |
| 164 | // We cannot split the wait states between the read accesses before we |
| 165 | // have a split-phase read access in the core |
| 155 | 166 | m_waitcount = 6; |
| 156 | 167 | m_ready(CLEAR_LINE); |
| 157 | 168 | |
| 158 | 169 | // use the latch and the currently read byte and put it on the 16bit bus |
| 159 | | return (hbyte<<8) | m_latch; |
| 170 | return ((hbyte<<8) | m_latch) & mem_mask; |
| 160 | 171 | } |
| 161 | 172 | |
| 162 | 173 | /* |
| r23565 | r23566 | |
| 173 | 184 | |
| 174 | 185 | // printf("write addr=%04x, value=%04x\n", addr, data); |
| 175 | 186 | |
| 176 | | assert (mem_mask == 0xffff); |
| 177 | | |
| 178 | 187 | // Handle the internal 32K expansion |
| 179 | 188 | if (m_use32k) |
| 180 | 189 | { |
| 181 | | if (addr>=0x2000 && addr<0x4000) |
| 190 | UINT16 base = 0; |
| 191 | if ((addr & 0xe000)==0x2000) base = 0x1000; |
| 192 | if (((addr & 0xe000)==0xa000) || ((addr & 0xc000)==0xc000)) base = 0x4000; |
| 193 | |
| 194 | if (base != 0) |
| 182 | 195 | { |
| 183 | | m_ram16b[offset-0x1000] = data; // index 0000 - 0fff |
| 196 | m_ram16b[offset-base] = data; |
| 184 | 197 | return; |
| 185 | 198 | } |
| 186 | | if (addr>=0xa000) |
| 187 | | { |
| 188 | | m_ram16b[offset-0x4000] = data; // index 1000 - 4fff |
| 189 | | return; |
| 190 | | } |
| 191 | 199 | } |
| 192 | 200 | |
| 193 | | attached_device *dev = m_devices.first(); |
| 194 | | while (dev != NULL) |
| 195 | | { |
| 196 | | if (((addr+1) & dev->m_config->address_mask)==(dev->m_config->select | dev->m_config->write_select)) |
| 197 | | { |
| 198 | | bus8z_device *devz = static_cast<bus8z_device *>(dev->m_device); |
| 199 | | devz->write(*m_space, addr+1, data & 0xff); |
| 200 | | } |
| 201 | | dev = dev->m_next; |
| 202 | | } |
| 201 | // write odd byte |
| 202 | write_all(space, addr+1, data & 0xff); |
| 203 | // write even byte |
| 204 | write_all(space, addr, (data>>8) & 0xff); |
| 203 | 205 | |
| 204 | | dev = m_devices.first(); |
| 205 | | |
| 206 | | while (dev != NULL) |
| 207 | | { |
| 208 | | if ((addr & dev->m_config->address_mask)==(dev->m_config->select | dev->m_config->write_select)) |
| 209 | | { |
| 210 | | // write the byte from the upper 8 lines |
| 211 | | bus8z_device *devz = static_cast<bus8z_device *>(dev->m_device); |
| 212 | | devz->write(*m_space, addr, (data>>8) & 0xff); |
| 213 | | } |
| 214 | | dev = dev->m_next; |
| 215 | | } |
| 216 | | |
| 217 | 206 | // Insert four wait states and let CPU enter wait state |
| 218 | 207 | m_waitcount = 6; |
| 219 | 208 | m_ready(CLEAR_LINE); |
| r23565 | r23566 | |
| 254 | 243 | m_ready.resolve(conf->ready, *this); |
| 255 | 244 | |
| 256 | 245 | m_cpu = machine().device("maincpu"); |
| 257 | | m_space = &m_cpu->memory().space(AS_PROGRAM); |
| 246 | // m_space = &m_cpu->memory().space(AS_PROGRAM); |
| 258 | 247 | |
| 259 | 248 | m_devices.reset(); // clear the list |
| 260 | 249 | m_use32k = (ioport("RAM")->read()==1); |