trunk/src/emu/video/tms3556.c
| r30776 | r30777 | |
| 20 | 20 | |
| 21 | 21 | #define LOG 0 |
| 22 | 22 | |
| 23 | |
| 24 | |
| 23 | 25 | //************************************************************************** |
| 24 | 26 | // GLOBAL VARIABLES |
| 25 | 27 | //************************************************************************** |
| r30776 | r30777 | |
| 54 | 56 | |
| 55 | 57 | inline UINT8 tms3556_device::readbyte(offs_t address) |
| 56 | 58 | { |
| 57 | | return space().read_byte(address); |
| 59 | return space().read_byte(address&0xFFFF); |
| 58 | 60 | } |
| 59 | 61 | |
| 60 | 62 | |
| r30776 | r30777 | |
| 64 | 66 | |
| 65 | 67 | inline void tms3556_device::writebyte(offs_t address, UINT8 data) |
| 66 | 68 | { |
| 67 | | space().write_byte(address, data); |
| 69 | space().write_byte(address&0xFFFF, data); |
| 68 | 70 | } |
| 69 | 71 | |
| 70 | 72 | |
| r30776 | r30777 | |
| 80 | 82 | : device_t(mconfig, TMS3556, "Texas Instruments VDP TMS3556", tag, owner, clock, "tms3556", __FILE__), |
| 81 | 83 | device_memory_interface(mconfig, *this), |
| 82 | 84 | m_space_config("videoram", ENDIANNESS_LITTLE, 8, 17, 0, NULL, *ADDRESS_MAP_NAME(tms3556)), |
| 83 | | m_write_ptr(0), |
| 84 | | m_reg_ptr(0), |
| 85 | 85 | m_reg_access_phase(0), |
| 86 | | m_magical_mystery_flag(0), |
| 86 | m_row_col_written(0), |
| 87 | m_bamp_written(0), |
| 88 | m_colrow(0), |
| 89 | m_vdp_acmpxy_mode(dma_write), |
| 90 | m_vdp_acmpxy(0), |
| 91 | m_vdp_acmp(0), |
| 92 | m_init_read(0), |
| 87 | 93 | m_scanline(0), |
| 88 | 94 | m_blink(0), |
| 89 | 95 | m_blink_count(0), |
| r30776 | r30777 | |
| 92 | 98 | for (int i = 0; i < 8; i++) |
| 93 | 99 | { |
| 94 | 100 | m_control_regs[i] = 0; |
| 95 | | m_address_regs[i] = 0; |
| 101 | m_address_regs[i] = 0xFFFF; |
| 96 | 102 | } |
| 97 | 103 | } |
| 98 | 104 | |
| r30776 | r30777 | |
| 106 | 112 | // register for state saving |
| 107 | 113 | save_item(NAME(m_control_regs)); |
| 108 | 114 | save_item(NAME(m_address_regs)); |
| 109 | | save_item(NAME(m_write_ptr)); |
| 110 | | save_item(NAME(m_reg_ptr)); |
| 111 | 115 | save_item(NAME(m_reg_access_phase)); |
| 112 | | save_item(NAME(m_magical_mystery_flag)); |
| 116 | save_item(NAME(m_row_col_written)); |
| 117 | save_item(NAME(m_bamp_written)); |
| 118 | save_item(NAME(m_colrow)); |
| 119 | // save_item(NAME(m_vdp_acmpxy_mode)); // FIXME : mame cannot save enum |
| 120 | save_item(NAME(m_vdp_acmpxy)); |
| 121 | save_item(NAME(m_vdp_acmp)); |
| 113 | 122 | save_item(NAME(m_scanline)); |
| 114 | 123 | save_item(NAME(m_blink)); |
| 115 | 124 | save_item(NAME(m_blink_count)); |
| r30776 | r30777 | |
| 139 | 148 | |
| 140 | 149 | READ8_MEMBER( tms3556_device::vram_r ) |
| 141 | 150 | { |
| 142 | | if (LOG) logerror("TMS3556 VRAM Read: %06x\n", offset); |
| 151 | UINT8 ret; |
| 152 | if (m_bamp_written) { |
| 153 | m_bamp_written=false; |
| 154 | m_vdp_acmpxy_mode=dma_write; |
| 155 | if (m_init_read) |
| 156 | m_vdp_acmp=VDP_BAMP; |
| 157 | else |
| 158 | m_vdp_acmp=(VDP_BAMP-1)&0xFFFF; |
| 159 | } |
| 143 | 160 | |
| 144 | | if (m_magical_mystery_flag) |
| 145 | | { |
| 146 | | m_write_ptr = ((m_control_regs[2] << 8) | m_control_regs[1]) + 1; |
| 147 | | m_magical_mystery_flag = 0; |
| 148 | | } |
| 161 | if (m_row_col_written) { |
| 162 | m_row_col_written=0; |
| 163 | m_vdp_acmpxy_mode=dma_read; |
| 164 | if (m_init_read) |
| 165 | m_vdp_acmpxy=m_colrow; |
| 166 | else |
| 167 | m_vdp_acmpxy=(m_colrow-1)&0xFFFF; |
| 168 | } |
| 149 | 169 | |
| 150 | | return readbyte(m_address_regs[1]++); |
| 170 | m_init_read=false; |
| 171 | if (m_vdp_acmpxy_mode==dma_read) { |
| 172 | ret=readbyte(m_vdp_acmpxy); |
| 173 | m_vdp_acmpxy++; |
| 174 | if (m_vdp_acmpxy==VDP_BAMTF) m_vdp_acmpxy=VDP_BAMP; |
| 175 | } else { |
| 176 | ret=readbyte(m_vdp_acmp); |
| 177 | m_vdp_acmp++; |
| 178 | if (m_vdp_acmp==VDP_BAMTF) m_vdp_acmp=VDP_BAMP; |
| 179 | } |
| 180 | return ret; |
| 151 | 181 | } |
| 152 | 182 | |
| 153 | 183 | //------------------------------------------------- |
| r30776 | r30777 | |
| 156 | 186 | |
| 157 | 187 | WRITE8_MEMBER( tms3556_device::vram_w ) |
| 158 | 188 | { |
| 159 | | if (LOG) logerror("TMS3556 VRAM Write: %06x = %02x\n", offset, data); |
| 189 | if (m_bamp_written) { |
| 190 | m_bamp_written=false; |
| 191 | m_vdp_acmpxy_mode=dma_read; |
| 192 | m_vdp_acmp=VDP_BAMP; |
| 193 | } |
| 160 | 194 | |
| 161 | | if (m_magical_mystery_flag) |
| 162 | | { |
| 163 | | m_write_ptr = (m_control_regs[2] << 8) | m_control_regs[1]; |
| 164 | | m_magical_mystery_flag = 0; |
| 165 | | } |
| 195 | if (m_row_col_written) { |
| 196 | m_row_col_written=0; |
| 197 | m_vdp_acmpxy_mode=dma_write; |
| 198 | m_vdp_acmpxy=m_colrow; |
| 199 | } |
| 166 | 200 | |
| 167 | | writebyte(m_write_ptr++, data); |
| 201 | if (m_vdp_acmpxy_mode==dma_write) { |
| 202 | writebyte(m_vdp_acmpxy,data); |
| 203 | m_vdp_acmpxy++; |
| 204 | if (m_vdp_acmpxy==VDP_BAMTF) m_vdp_acmpxy=VDP_BAMP; |
| 205 | } else { |
| 206 | writebyte(m_vdp_acmp,data); |
| 207 | m_vdp_acmp++; |
| 208 | if (m_vdp_acmp==VDP_BAMTF) m_vdp_acmp=VDP_BAMP; |
| 209 | } |
| 210 | |
| 168 | 211 | } |
| 169 | 212 | |
| 170 | 213 | |
| r30776 | r30777 | |
| 176 | 219 | { |
| 177 | 220 | if (LOG) logerror("TMS3556 Reg Read: %06x\n", offset); |
| 178 | 221 | |
| 179 | | int reply = 0; |
| 180 | | |
| 181 | | if (m_reg_ptr < 8) |
| 182 | | { |
| 183 | | reply = m_control_regs[m_reg_ptr]; |
| 184 | | m_reg_access_phase = 0; |
| 185 | | } |
| 186 | | else |
| 187 | | { |
| 188 | | // ??? |
| 189 | | } |
| 190 | | |
| 222 | int reply = 0; // FIXME : will send internal status (VBL, HBL...) |
| 223 | m_reg_access_phase=0; |
| 191 | 224 | return reply; |
| 192 | 225 | } |
| 193 | 226 | |
| r30776 | r30777 | |
| 197 | 230 | |
| 198 | 231 | WRITE8_MEMBER( tms3556_device::reg_w ) |
| 199 | 232 | { |
| 233 | static int reg2=0; // FIXME : this static makes that only one TMS3556 will be present in one system... |
| 234 | static int reg=0; |
| 235 | |
| 200 | 236 | if (LOG) logerror("TMS3556 Reg Write: %06x = %02x\n", offset, data); |
| 201 | 237 | |
| 202 | | if ((m_reg_access_phase == 3) && (data)) |
| 203 | | m_reg_access_phase = 0; /* ???????????? */ |
| 238 | switch (m_reg_access_phase) { |
| 239 | case 0: |
| 240 | reg=data&0x0F; |
| 241 | reg2=(data&0xF0)>>4; |
| 242 | if (reg!=0) |
| 243 | m_reg_access_phase=1; |
| 244 | return; |
| 204 | 245 | |
| 205 | | switch (m_reg_access_phase) |
| 206 | | { |
| 207 | | case 0: |
| 208 | | m_reg_ptr = data & 0x0f; |
| 209 | | m_reg_access_phase = 1; |
| 210 | | break; |
| 246 | case 1: |
| 247 | if (reg<8) { |
| 248 | m_control_regs[reg]=data; |
| 249 | // leve un flag si le dernier registre ecrit est row ou col |
| 250 | if ((reg==2) || (reg==1)) { |
| 251 | m_colrow=(m_control_regs[2]<<8)|m_control_regs[1]; |
| 252 | m_row_col_written=true; |
| 253 | } |
| 211 | 254 | |
| 212 | | case 1: |
| 213 | | if (m_reg_ptr < 8) |
| 214 | | { |
| 215 | | m_control_regs[m_reg_ptr] = data; |
| 216 | | m_reg_access_phase = 0; |
| 217 | | if (m_reg_ptr == 2) |
| 218 | | m_magical_mystery_flag = 1; |
| 219 | | } |
| 220 | | else if (m_reg_ptr == 9) |
| 221 | | { /* I don't understand what is going on, but it is the only way to |
| 222 | | get this to work */ |
| 223 | | m_address_regs[m_reg_ptr - 8] = ((m_control_regs[2] << 8) | m_control_regs[1]) + 1; |
| 224 | | m_reg_access_phase = 0; |
| 225 | | m_magical_mystery_flag = 0; |
| 226 | | } |
| 227 | | else |
| 228 | | { |
| 229 | | m_address_regs[m_reg_ptr - 8] = (m_control_regs[m_reg_ptr - 8] & 0xff00) | m_control_regs[1]; |
| 230 | | m_reg_access_phase = 2; |
| 231 | | m_magical_mystery_flag = 0; |
| 232 | | } |
| 233 | | break; |
| 255 | if (reg2==0) { |
| 256 | m_reg_access_phase=0; |
| 257 | return; |
| 258 | } |
| 259 | else { |
| 260 | m_reg_access_phase=1; |
| 261 | reg=reg2; |
| 262 | reg2=0; |
| 263 | return; |
| 264 | } |
| 265 | } else { |
| 266 | m_address_regs[reg-8]=(m_control_regs[2]<<8)|m_control_regs[1]; |
| 267 | // cas speciaux de decalage pour les generateurs |
| 268 | if ((reg>=0xB) && (reg<=0xE)) { |
| 269 | m_address_regs[reg-8]+=2; |
| 270 | m_address_regs[reg-8]&=0xFFFF; |
| 271 | } else { |
| 272 | m_address_regs[reg-8]+=1; |
| 273 | m_address_regs[reg-8]&=0xFFFF; |
| 274 | } |
| 275 | if (reg==9) { |
| 276 | m_row_col_written=false; |
| 277 | m_bamp_written=true; |
| 278 | m_reg_access_phase=0; |
| 279 | return; |
| 280 | } else { |
| 281 | m_row_col_written=0; |
| 282 | m_bamp_written=false; |
| 283 | m_reg_access_phase=2;//??? |
| 284 | return; |
| 285 | } |
| 286 | logerror("VDP16[%d] = x%x",reg,m_address_regs[reg-8]); |
| 287 | if (reg2==0) { |
| 288 | m_reg_access_phase=0; |
| 289 | return; |
| 290 | } |
| 291 | else { |
| 292 | m_reg_access_phase=1; |
| 293 | reg=reg2; |
| 294 | reg2=0; |
| 295 | return; |
| 296 | } |
| 297 | } |
| 298 | case 2: |
| 299 | m_reg_access_phase=0; |
| 300 | return; |
| 301 | } |
| 302 | } |
| 234 | 303 | |
| 235 | | case 2: |
| 236 | | m_address_regs[m_reg_ptr - 8] = (m_control_regs[m_reg_ptr - 8] & 0x00ff) | (m_control_regs[2] << 8); |
| 237 | | if ((m_reg_ptr <= 10) || (m_reg_ptr == 15)) |
| 238 | | m_address_regs[m_reg_ptr - 8]++; |
| 239 | | else |
| 240 | | m_address_regs[m_reg_ptr - 8] += 2; |
| 241 | | m_reg_access_phase = 3; |
| 242 | | break; |
| 304 | //-------------------------------------------------------------------------- |
| 305 | // initptr_r - set VDP in read mode (not exacly on the VDP but on the TAL) |
| 306 | //-------------------------------------------------------------------------- |
| 243 | 307 | |
| 244 | | case 3: |
| 245 | | m_reg_access_phase = 0; |
| 246 | | break; |
| 247 | | } |
| 308 | READ8_MEMBER( tms3556_device::initptr_r ) |
| 309 | { |
| 310 | m_init_read=true; |
| 311 | return 0xff; |
| 248 | 312 | } |
| 249 | 313 | |
| 250 | 314 | |
| r30776 | r30777 | |
| 509 | 573 | { |
| 510 | 574 | /* draw top and bottom borders */ |
| 511 | 575 | draw_line_empty(ln); |
| 576 | m_cg_flag=0; // FIXME : forme text mode for 1st line in mixed |
| 512 | 577 | } |
| 513 | 578 | else |
| 514 | 579 | { |
trunk/src/mess/drivers/exelv.c
| r30776 | r30777 | |
| 21 | 21 | |
| 22 | 22 | Specs: |
| 23 | 23 | * main CPU is a variant of tms7020 (exl100) or tms7040 (exeltel). AFAIK, |
| 24 | | the only difference compared to a stock tms7020/7040 is the SWAP R0 |
| 24 | the only difference compared to a stock tms7020/7040 is the SWAP register |
| 25 | 25 | instruction is replaced by a custom microcoded LVDP instruction that |
| 26 | 26 | reads a byte from the VDP VRAM read port; it seems that the first 6 bytes |
| 27 | 27 | of internal ROM (0xF000-0xF005 on an exeltel) are missing, too. |
| r30776 | r30777 | |
| 37 | 37 | CPU |
| 38 | 38 | * keyboard and joystick: an I/R interface controlled by the I/O CPU enables |
| 39 | 39 | to use a keyboard and two joysticks |
| 40 | | * mass storage: tape interface controlled by the I/O CPU |
| 40 | * mass storage: tape interface controlled by the main CPU |
| 41 | 41 | |
| 42 | 42 | STATUS: |
| 43 | 43 | * EXL 100 cannot be emulated because the ROMs are not dumped |
| r30776 | r30777 | |
| 55 | 55 | #include "video/tms3556.h" |
| 56 | 56 | #include "sound/tms5220.h" |
| 57 | 57 | #include "machine/spchrom.h" |
| 58 | | //#include "imagedev/cartslot.h" |
| 58 | #include "imagedev/cartslot.h" |
| 59 | 59 | //#include "imagedev/cassette.h" |
| 60 | 60 | |
| 61 | 61 | |
| r30776 | r30777 | |
| 105 | 105 | UINT8 m_wx319; /* data of 74sl374 labeled wx319 */ |
| 106 | 106 | DECLARE_PALETTE_INIT(exelv); |
| 107 | 107 | TIMER_DEVICE_CALLBACK_MEMBER(exelv_hblank_interrupt); |
| 108 | |
| 109 | DECLARE_DEVICE_IMAGE_LOAD_MEMBER( exelvision_cartridge ); |
| 110 | |
| 108 | 111 | }; |
| 109 | 112 | |
| 110 | 113 | |
| 114 | DEVICE_IMAGE_LOAD_MEMBER( exelv_state, exelvision_cartridge ) |
| 115 | { |
| 116 | UINT8* pos = memregion("user1")->base(); |
| 117 | offs_t size; |
| 118 | |
| 119 | if (image.software_entry() == NULL) |
| 120 | size = image.length(); |
| 121 | else |
| 122 | size = image.get_software_region_length("rom"); |
| 123 | |
| 124 | |
| 125 | if (image.software_entry() == NULL) |
| 126 | { |
| 127 | image.fread( pos, size ); |
| 128 | } |
| 129 | else |
| 130 | { |
| 131 | memcpy(pos, image.get_software_region("rom"), size); |
| 132 | } |
| 133 | |
| 134 | return IMAGE_INIT_PASS; |
| 135 | } |
| 136 | |
| 137 | |
| 138 | |
| 111 | 139 | TIMER_DEVICE_CALLBACK_MEMBER(exelv_state::exelv_hblank_interrupt) |
| 112 | 140 | { |
| 113 | 141 | m_tms3556->interrupt(machine()); |
| r30776 | r30777 | |
| 184 | 212 | >0a: synthesizer data |
| 185 | 213 | >0b: standard generator request |
| 186 | 214 | >0c: I/O CPU CRC (EXELTEL only?) |
| 187 | | >0d: send exelvision logo (EXL 100 only?), start speech ROM sound (EXELTEL only?) |
| 215 | >0d: send exelvision logo (EXL 100 only), start speech ROM sound (EXELTEL only?) |
| 188 | 216 | >0e: data for speech on ROM (EXELTEL only?) |
| 189 | 217 | >0f: do not decode joystick 0 keys (EXELTEL only?) |
| 190 | 218 | >10: do not decode joystick 1 keys (EXELTEL only?) |
| r30776 | r30777 | |
| 201 | 229 | |
| 202 | 230 | READ8_MEMBER(exelv_state::mailbox_wx319_r) |
| 203 | 231 | { |
| 232 | logerror("[TMS7220] reading mailbox %d", m_wx319); |
| 204 | 233 | return m_wx319; |
| 205 | 234 | } |
| 206 | 235 | |
| r30776 | r30777 | |
| 276 | 305 | READ8_MEMBER(exelv_state::tms7041_porta_r) |
| 277 | 306 | { |
| 278 | 307 | UINT8 data = 0x00; |
| 308 | static UINT8 data_last=0; |
| 279 | 309 | |
| 280 | | logerror("tms7041_porta_r\n"); |
| 310 | // TMS5220 OK |
| 311 | data |= m_tms5220c->intq_r() ? 0x08 : 0x00; // A3 |
| 312 | data |= m_tms5220c->readyq_r() ? 0x80 : 0x00; // A7 |
| 281 | 313 | |
| 282 | | data |= (m_tms7020_portb & 0x01 ) ? 0x04 : 0x00; |
| 283 | | data |= m_tms5220c->intq_r() ? 0x08 : 0x00; |
| 284 | | data |= (m_tms7020_portb & 0x02) ? 0x10 : 0x00; |
| 285 | | data |= m_tms5220c->readyq_r() ? 0x80 : 0x00; |
| 314 | // TMS7220 |
| 315 | data |= (m_tms7020_portb & 0x01 ) ? 0x04 : 0x00; // A2 |
| 316 | data |= (m_tms7020_portb & 0x02) ? 0x10 : 0x00; // A4 |
| 317 | |
| 318 | // SERIAL PORT |
| 286 | 319 | |
| 320 | if (data!=data_last) { |
| 321 | logerror("tms7041_porta_r %x\n",data); |
| 322 | } |
| 323 | data_last=data; |
| 324 | |
| 287 | 325 | return data; |
| 288 | 326 | } |
| 289 | 327 | |
| r30776 | r30777 | |
| 321 | 359 | m_tms5220c->wsq_w((data & 0x01) ? 1 : 0); |
| 322 | 360 | m_tms5220c->rsq_w((data & 0x02) ? 1 : 0); |
| 323 | 361 | |
| 362 | logerror("TMS7020 %s int1\n",((data & 0x04) ? "clear" : "assert")); |
| 324 | 363 | m_maincpu->set_input_line(TMS7000_IRQ1_LINE, (data & 0x04) ? CLEAR_LINE : ASSERT_LINE); |
| 325 | 364 | |
| 326 | 365 | /* Check for low->high transition on B6 */ |
| r30776 | r30777 | |
| 371 | 410 | READ8_MEMBER(exelv_state::tms7041_portd_r) |
| 372 | 411 | { |
| 373 | 412 | UINT8 data = 0xff; |
| 413 | data=m_tms5220c->status_r(space, 0, data); |
| 374 | 414 | logerror("tms7041_portd_r\n"); |
| 375 | 415 | return data; |
| 376 | 416 | } |
| r30776 | r30777 | |
| 380 | 420 | { |
| 381 | 421 | logerror("tms7041_portd_w: data = 0x%02x\n", data); |
| 382 | 422 | |
| 383 | | m_tms5220c->data_w(space, 0, BITSWAP8(data,0,1,2,3,4,5,6,7)); |
| 423 | m_tms5220c->data_w(space, 0, data); |
| 384 | 424 | m_tms7041_portd = data; |
| 385 | 425 | } |
| 386 | 426 | |
| r30776 | r30777 | |
| 410 | 450 | */ |
| 411 | 451 | |
| 412 | 452 | static ADDRESS_MAP_START(tms7020_mem, AS_PROGRAM, 8, exelv_state) |
| 413 | | //AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w)/* tms7020 internal RAM */ |
| 414 | 453 | AM_RANGE(0x0080, 0x00ff) AM_NOP |
| 415 | | //AM_RANGE(0x0100, 0x010b) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w)/* tms7020 internal I/O ports */ |
| 416 | | //AM_RANGE(0x010c, 0x01ff) AM_READWRITE(SMH_NOP, SMH_NOP) /* external I/O ports */ |
| 417 | | AM_RANGE(0x012d, 0x0012d) AM_DEVREADWRITE("tms3556", tms3556_device, reg_r/*right???*/, reg_w) |
| 418 | | AM_RANGE(0x012e, 0x0012e) AM_DEVREADWRITE("tms3556", tms3556_device, vram_r/*right???*/, vram_w) |
| 454 | AM_RANGE(0x0124, 0x00124) AM_DEVREAD("tms3556", tms3556_device, vram_r) |
| 455 | AM_RANGE(0x0125, 0x00125) AM_DEVREAD("tms3556", tms3556_device, reg_r) |
| 456 | AM_RANGE(0x0128, 0x00128) AM_DEVREAD("tms3556", tms3556_device, initptr_r) |
| 457 | AM_RANGE(0x012d, 0x0012d) AM_DEVWRITE("tms3556", tms3556_device, reg_w) |
| 458 | AM_RANGE(0x012e, 0x0012e) AM_DEVWRITE("tms3556", tms3556_device, vram_w) |
| 459 | |
| 419 | 460 | AM_RANGE(0x0130, 0x00130) AM_READWRITE(mailbox_wx319_r, mailbox_wx318_w) |
| 420 | 461 | AM_RANGE(0x0200, 0x7fff) AM_ROMBANK("bank1") /* system ROM */ |
| 421 | 462 | AM_RANGE(0x8000, 0xbfff) AM_NOP |
| r30776 | r30777 | |
| 445 | 486 | |
| 446 | 487 | |
| 447 | 488 | static ADDRESS_MAP_START(tms7040_mem, AS_PROGRAM, 8, exelv_state) |
| 448 | | //AM_RANGE(0x0000, 0x007f) AM_READWRITE(tms7000_internal_r, tms7000_internal_w)/* tms7040 internal RAM */ |
| 449 | 489 | AM_RANGE(0x0080, 0x00ff) AM_NOP |
| 450 | | //AM_RANGE(0x0100, 0x010b) AM_READWRITE(tms70x0_pf_r, tms70x0_pf_w)/* tms7020 internal I/O ports */ |
| 451 | | //AM_RANGE(0x010c, 0x01ff) AM_READWRITE(SMH_NOP, SMH_NOP) /* external I/O ports */ |
| 452 | | AM_RANGE(0x012d, 0x0012d) AM_DEVREADWRITE("tms3556", tms3556_device, reg_r/*right???*/, reg_w) |
| 453 | | AM_RANGE(0x012e, 0x0012e) AM_DEVREADWRITE("tms3556", tms3556_device, vram_r/*right???*/, vram_w) |
| 490 | AM_RANGE(0x0124, 0x00124) AM_DEVREAD("tms3556", tms3556_device, vram_r) |
| 491 | AM_RANGE(0x0125, 0x00125) AM_DEVREAD("tms3556", tms3556_device, reg_r) |
| 492 | AM_RANGE(0x0128, 0x00128) AM_DEVREAD("tms3556", tms3556_device, initptr_r) |
| 493 | AM_RANGE(0x012d, 0x0012d) AM_DEVWRITE("tms3556", tms3556_device, reg_w) |
| 494 | AM_RANGE(0x012e, 0x0012e) AM_DEVWRITE("tms3556", tms3556_device, vram_w) |
| 454 | 495 | AM_RANGE(0x0130, 0x00130) AM_READWRITE(mailbox_wx319_r, mailbox_wx318_w) |
| 455 | 496 | AM_RANGE(0x0200, 0x7fff) AM_ROMBANK("bank1") /* system ROM */ |
| 456 | 497 | AM_RANGE(0x8000, 0xbfff) AM_NOP |
| r30776 | r30777 | |
| 461 | 502 | |
| 462 | 503 | |
| 463 | 504 | static ADDRESS_MAP_START(tms7042_map, AS_PROGRAM, 8, exelv_state) |
| 464 | | AM_RANGE(0xe000, 0xefff) AM_ROM AM_REGION("tms7042",0x0000) |
| 465 | | AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("tms7042",0x0000) /* Duplicated until a proper dump surfaces */ |
| 505 | AM_RANGE(0xf000, 0xffff) AM_ROM AM_REGION("tms7042",0x0000) |
| 466 | 506 | ADDRESS_MAP_END |
| 467 | 507 | |
| 468 | 508 | |
| r30776 | r30777 | |
| 533 | 573 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH*2-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 534 | 574 | #else |
| 535 | 575 | MCFG_SCREEN_SIZE(TMS3556_TOTAL_WIDTH, TMS3556_TOTAL_HEIGHT*2) |
| 536 | | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 576 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH-1, 0, TMS3556_TOTAL_HEIGHT-1) |
| 537 | 577 | #endif |
| 538 | 578 | MCFG_SCREEN_REFRESH_RATE(50) |
| 539 | 579 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| r30776 | r30777 | |
| 542 | 582 | MCFG_PALETTE_ADD("palette", 8) |
| 543 | 583 | MCFG_PALETTE_INIT_OWNER(exelv_state, exelv) |
| 544 | 584 | |
| 545 | | MCFG_DEVICE_ADD("vsm", SPEECHROM, 0) |
| 585 | // MCFG_DEVICE_ADD("vsm", SPEECHROM, 0) |
| 546 | 586 | |
| 547 | 587 | /* sound */ |
| 548 | 588 | MCFG_SPEAKER_STANDARD_MONO("mono") |
| 549 | 589 | MCFG_SOUND_ADD("tms5220c", TMS5220C, 640000) |
| 550 | | MCFG_TMS52XX_SPEECHROM("vsm") |
| 590 | // MCFG_TMS52XX_SPEECHROM("vsm") |
| 551 | 591 | MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) |
| 592 | |
| 593 | /* cartridge */ |
| 594 | MCFG_CARTSLOT_ADD("cart") |
| 595 | MCFG_CARTSLOT_EXTENSION_LIST("bin,rom") |
| 596 | MCFG_CARTSLOT_NOT_MANDATORY |
| 597 | MCFG_CARTSLOT_LOAD(exelv_state,exelvision_cartridge) |
| 598 | MCFG_CARTSLOT_INTERFACE("exelvision_cart") |
| 599 | MCFG_SOFTWARE_LIST_ADD("cart_list","exelvision_cart") |
| 600 | |
| 552 | 601 | MACHINE_CONFIG_END |
| 553 | 602 | |
| 554 | 603 | |
| r30776 | r30777 | |
| 577 | 626 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH*2-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 578 | 627 | #else |
| 579 | 628 | MCFG_SCREEN_SIZE(TMS3556_TOTAL_WIDTH, TMS3556_TOTAL_HEIGHT*2) |
| 580 | | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH-1, 0, TMS3556_TOTAL_HEIGHT*2-1) |
| 629 | MCFG_SCREEN_VISIBLE_AREA(0, TMS3556_TOTAL_WIDTH-1, 0, TMS3556_TOTAL_HEIGHT-1) |
| 581 | 630 | #endif |
| 582 | 631 | MCFG_SCREEN_REFRESH_RATE(50) |
| 583 | 632 | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */ |
| r30776 | r30777 | |
| 601 | 650 | */ |
| 602 | 651 | ROM_START(exl100) |
| 603 | 652 | ROM_REGION(0x800, "maincpu", 0) |
| 604 | | ROM_LOAD("exl100in.bin", 0x0000, 0x0800, CRC(049109a3) SHA1(98a07297dcdacef41c793c197b6496dac1e8e744)) /* TMS7020 ROM, verification would be welcome */ |
| 653 | ROM_LOAD("exl100in.bin", 0x0000, 0x0800, CRC(049109a3) SHA1(98a07297dcdacef41c793c197b6496dac1e8e744)) /* TMS7020 ROM, correct */ |
| 605 | 654 | |
| 606 | 655 | ROM_REGION(0x1000, "tms7041", 0) |
| 607 | | ROM_LOAD("exl100_7041.bin", 0x0000, 0x1000, CRC(a0163507) SHA1(8452849df7eac8a89cf03ee98e2306047c1c4c38)) /* TMS7041 internal ROM, verification would be welcome */ |
| 656 | ROM_LOAD("exl100_7041.bin", 0x0000, 0x1000, CRC(38f6fc7a) SHA1(b71d545664a974d8ad39bdf600c5b9884c3efab6)) /* TMS7041 internal ROM, correct */ |
| 657 | // ROM_REGION(0x8000, "vsm", 0) |
| 608 | 658 | |
| 609 | 659 | ROM_REGION(0x10000, "user1", ROMREGION_ERASEFF) /* cartridge area */ |
| 610 | | |
| 611 | | /* is this correct for exl100? */ |
| 612 | | ROM_REGION(0x8000, "vsm", 0) |
| 613 | | ROM_LOAD("cm62312.bin", 0x0000, 0x4000, CRC(93b817de) SHA1(03863087a071b8f22d36a52d18243f1c33e17ff7)) /* system speech ROM */ |
| 614 | 660 | ROM_END |
| 615 | 661 | |
| 616 | 662 | |
| r30776 | r30777 | |
| 635 | 681 | /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME */ |
| 636 | 682 | COMP(1984, exl100, 0, 0, exl100, exelv, driver_device, 0, "Exelvision", "EXL 100", GAME_NOT_WORKING) |
| 637 | 683 | COMP(1986, exeltel, exl100, 0, exeltel, exelv, driver_device, 0, "Exelvision", "Exeltel", GAME_NOT_WORKING) |
| 684 | |