trunk/src/mame/drivers/4enlinea.c
| r29365 | r29366 | |
| 137 | 137 | 8952 (PIN 04) --|02 19|-- GAL (PIN 17) 8952 (PIN 08) --|02 19|-- GAL (PIN 16) |
| 138 | 138 | MAIN Z80 (D7) --|03 18|-- MAIN Z80 (D0) MAIN Z80 (D7) --|03 18|-- MAIN Z80 (D0) |
| 139 | 139 | 8952 (PIN 03) --|04 17|-- 8952 (PIN 40) 8952 (PIN 07) --|04 17|-- 8952 (PIN 36) |
| 140 | | MAIN Z80 (D6) --|05 16|-- MAIN Z80 (D1) MAIN Z80 (D6) --|05 16|-- MAIN Z80 (D1) |
| 140 | MAIN Z80 (D6) --|05 16|-- MAIN Z80 (D1) MAIN Z80 (D6) --|05 16|-- MAIN Z80 (D1) |
| 141 | 141 | 8952 (PIN 02) --|06 15|-- 8952 (PIN 39) 8952 (PIN 06) --|06 15|-- 8952 (PIN 35) |
| 142 | 142 | MAIN Z80 (D5) --|07 14|-- MAIN Z80 (D2) MAIN Z80 (D5) --|07 14|-- MAIN Z80 (D2) |
| 143 | 143 | 8952 (PIN 01) --|08 13|-- 8952 (PIN 38) 8952 (PIN 05) --|08 13|-- 8952 (PIN 34) |
| 144 | | MAIN Z80 (D4) --|09 12|-- MAIN Z80 (D3) MAIN Z80 (D4) --|09 12|-- MAIN Z80 (D3) |
| 144 | MAIN Z80 (D4) --|09 12|-- MAIN Z80 (D3) MAIN Z80 (D4) --|09 12|-- MAIN Z80 (D3) |
| 145 | 145 | GND --|10 11|-- 8952 (PIN 37) GND --|10 11|-- 8952 (PIN 33) |
| 146 | 146 | '-------' '-------' |
| 147 | 147 | |
| r29365 | r29366 | |
| 198 | 198 | #include "cpu/z80/z80.h" |
| 199 | 199 | #include "video/mc6845.h" |
| 200 | 200 | #include "sound/ay8910.h" |
| 201 | #include "bus/isa/isa.h" |
| 202 | #include "bus/isa/cga.h" |
| 203 | #include "video/cgapal.h" |
| 201 | 204 | |
| 202 | 205 | class _4enlinea_state : public driver_device |
| 203 | 206 | { |
| r29365 | r29366 | |
| 205 | 208 | _4enlinea_state(const machine_config &mconfig, device_type type, const char *tag) |
| 206 | 209 | : driver_device(mconfig, type, tag), |
| 207 | 210 | m_ay(*this, "aysnd"), |
| 208 | | m_videoram(*this, "videoram"), |
| 209 | | m_videoram2(*this, "videoram2"), |
| 210 | | m_maincpu(*this, "maincpu"), |
| 211 | | m_gfxdecode(*this, "gfxdecode"), |
| 212 | | m_screen(*this, "screen"), |
| 213 | | m_palette(*this, "palette") { } |
| 211 | m_maincpu(*this, "maincpu") |
| 212 | { } |
| 214 | 213 | |
| 215 | 214 | |
| 216 | 215 | required_device<ay8910_device> m_ay; |
| 217 | | required_shared_ptr<UINT8> m_videoram; |
| 218 | | required_shared_ptr<UINT8> m_videoram2; |
| 219 | 216 | |
| 220 | | DECLARE_WRITE8_MEMBER(crtc_config_w); |
| 221 | | DECLARE_WRITE8_MEMBER(crtc_mode_ctrl_w); |
| 222 | | DECLARE_WRITE8_MEMBER(crtc_colormode_w); |
| 223 | | DECLARE_READ8_MEMBER(crtc_status_r); |
| 224 | 217 | DECLARE_READ8_MEMBER(unk_e000_r); |
| 225 | 218 | DECLARE_READ8_MEMBER(unk_e001_r); |
| 219 | INTERRUPT_GEN_MEMBER(_4enlinea_irq); |
| 220 | UINT8 m_irq_count; |
| 226 | 221 | |
| 227 | 222 | virtual void machine_start(); |
| 228 | 223 | virtual void machine_reset(); |
| 229 | | virtual void video_start(); |
| 230 | | DECLARE_PALETTE_INIT(_4enlinea); |
| 231 | | UINT32 screen_update_4enlinea(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); |
| 232 | 224 | required_device<cpu_device> m_maincpu; |
| 233 | | required_device<gfxdecode_device> m_gfxdecode; |
| 234 | | required_device<screen_device> m_screen; |
| 235 | | required_device<palette_device> m_palette; |
| 236 | | |
| 237 | | DECLARE_WRITE8_MEMBER(vram_w); |
| 238 | | DECLARE_WRITE8_MEMBER(vram2_w); |
| 239 | | |
| 240 | 225 | }; |
| 241 | 226 | |
| 242 | 227 | |
| r29365 | r29366 | |
| 244 | 229 | * Video Hardware * |
| 245 | 230 | ***********************************/ |
| 246 | 231 | |
| 247 | | void _4enlinea_state::video_start() |
| 232 | class isa8_cga_4enlinea_device : public isa8_cga_device |
| 248 | 233 | { |
| 249 | | m_gfxdecode->gfx(0)->set_source(m_videoram); |
| 250 | | } |
| 234 | public: |
| 235 | // construction/destruction |
| 236 | isa8_cga_4enlinea_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); |
| 251 | 237 | |
| 252 | | UINT32 _4enlinea_state::screen_update_4enlinea(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) |
| 238 | virtual void device_start(); |
| 239 | virtual const rom_entry *device_rom_region() const; |
| 240 | }; |
| 241 | |
| 242 | const rom_entry *isa8_cga_4enlinea_device::device_rom_region() const |
| 253 | 243 | { |
| 254 | | /* note: chars are 16*12 pixels */ |
| 244 | return NULL; |
| 245 | } |
| 255 | 246 | |
| 256 | | int offset = 0; |
| 257 | | int offset2 = 0; |
| 247 | const device_type ISA8_CGA_4ENLINEA = &device_creator<isa8_cga_4enlinea_device>; |
| 258 | 248 | |
| 259 | | for (int y = 0; y < 200; y++) |
| 260 | | { |
| 261 | | UINT16* dstptr_bitmap = &bitmap.pix16(y); |
| 249 | isa8_cga_4enlinea_device::isa8_cga_4enlinea_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : |
| 250 | isa8_cga_device( mconfig, ISA8_CGA_4ENLINEA, "ISA8_CGA_4ENLINEA", tag, owner, clock, "4enlinea_cga", __FILE__) |
| 251 | { |
| 252 | } |
| 262 | 253 | |
| 263 | | for (int x = 0; x < 320; x += 4) |
| 264 | | { |
| 265 | | UINT8 pix; |
| 266 | 254 | |
| 267 | | if (y & 1) pix = m_videoram2[offset2++]; |
| 268 | | else pix = m_videoram[offset++]; |
| 269 | 255 | |
| 270 | | dstptr_bitmap[x + 3] = (pix >> 0) & 0x3; |
| 271 | | dstptr_bitmap[x + 2] = (pix >> 2) & 0x3; |
| 272 | | dstptr_bitmap[x + 1] = (pix >> 4) & 0x3; |
| 273 | | dstptr_bitmap[x + 0] = (pix >> 6) & 0x3; |
| 274 | | } |
| 275 | | } |
| 256 | void isa8_cga_4enlinea_device::device_start() |
| 257 | { |
| 258 | if (m_palette != NULL && !m_palette->started()) |
| 259 | throw device_missing_dependencies(); |
| 276 | 260 | |
| 277 | | return 0; |
| 278 | | } |
| 261 | set_isa_device(); |
| 262 | m_vram_size = 0x4000; |
| 263 | m_vram.resize(m_vram_size); |
| 279 | 264 | |
| 265 | m_update_row = NULL; |
| 266 | m_isa->install_device(0x3d0, 0x3df, 0, 0, read8_delegate( FUNC(isa8_cga_device::io_read), this ), write8_delegate( FUNC(isa8_cga_device::io_write), this ) ); |
| 267 | m_isa->install_bank(0x8000, 0xbfff, 0, 0, "bank1", m_vram); |
| 280 | 268 | |
| 281 | | WRITE8_MEMBER(_4enlinea_state::vram_w) |
| 282 | | { |
| 283 | | m_videoram[offset] = data; |
| 284 | | // m_gfxdecode->gfx(0)->mark_dirty(offset/16); |
| 285 | | } |
| 269 | /* Initialise the cga palette */ |
| 270 | int i; |
| 286 | 271 | |
| 287 | | WRITE8_MEMBER(_4enlinea_state::vram2_w) |
| 288 | | { |
| 289 | | m_videoram2[offset] = data; |
| 290 | | // m_gfxdecode->gfx(0)->mark_dirty(offset/16); |
| 291 | | } |
| 292 | | |
| 293 | | WRITE8_MEMBER(_4enlinea_state::crtc_config_w) |
| 294 | | { |
| 295 | | /* Bit 6 enables the CGA mode, otherwise is MGA */ |
| 296 | | if(data & 0x40) |
| 272 | for ( i = 0; i < CGA_PALETTE_SETS * 16; i++ ) |
| 297 | 273 | { |
| 298 | | logerror("CRTC config mode (3BFh): CGA\n"); |
| 274 | m_palette->set_pen_color( i, cga_palette[i][0], cga_palette[i][1], cga_palette[i][2] ); |
| 299 | 275 | } |
| 300 | | else |
| 276 | |
| 277 | i = 0x8000; |
| 278 | for ( int r = 0; r < 32; r++ ) |
| 301 | 279 | { |
| 302 | | logerror("CRTC config mode (3BFh): MGA\n"); |
| 280 | for ( int g = 0; g < 32; g++ ) |
| 281 | { |
| 282 | for ( int b = 0; b < 32; b++ ) |
| 283 | { |
| 284 | m_palette->set_pen_color( i, r << 3, g << 3, b << 3 ); |
| 285 | i++; |
| 286 | } |
| 287 | } |
| 303 | 288 | } |
| 304 | | } |
| 305 | 289 | |
| 306 | | WRITE8_MEMBER(_4enlinea_state::crtc_mode_ctrl_w) |
| 307 | | { |
| 308 | | /* Bit 3 enables/disables the video (see the notes above) */ |
| 309 | | logerror("CRTC mode control (3D8h): %02x\n", data); |
| 290 | // astring tempstring; |
| 291 | // m_chr_gen_base = memregion(subtag(tempstring, "gfx1"))->base(); |
| 292 | // m_chr_gen = m_chr_gen_base + m_chr_gen_offset[1]; |
| 310 | 293 | } |
| 311 | 294 | |
| 312 | | WRITE8_MEMBER(_4enlinea_state::crtc_colormode_w) |
| 313 | | { |
| 314 | | logerror("CRTC color mode (3D9h): %02x\n", data); |
| 315 | | } |
| 316 | 295 | |
| 317 | | READ8_MEMBER(_4enlinea_state::crtc_status_r) |
| 318 | | { |
| 319 | | /*----- bits ----- |
| 320 | | 7 6 5 4 3 2 1 0 For CGA Mode. |
| 321 | | x x x x - - - - (bits 4-5-6-7 are unused) |
| 322 | | | | | | |
| 323 | | | | | '-- 0: Display active period. |
| 324 | | | | | 1: Non-display period. |
| 325 | | | | | |
| 326 | | | | '---- 0: Light pen reset. |
| 327 | | | | 1: Light pen set. |
| 328 | | | | |
| 329 | | | '------ 0: Light pen switch off. |
| 330 | | | 1: Light pen switch on. |
| 331 | | | |
| 332 | | '-------- 0: Non-vertical sync period. |
| 333 | | 1: Vertical sync period. |
| 334 | | |
| 335 | | */ |
| 336 | | return (m_screen->vpos() >= 200) ? 0x80 : 0x00; // bit 7 is suppossed to be unused in CGA mode |
| 337 | | } |
| 338 | | |
| 339 | 296 | READ8_MEMBER(_4enlinea_state::unk_e000_r) |
| 340 | 297 | { |
| 341 | 298 | logerror("read e000\n"); |
| r29365 | r29366 | |
| 350 | 307 | // return (machine().rand() & 0x0f); // after 30 seconds, random gfx appear on the screen. |
| 351 | 308 | } |
| 352 | 309 | |
| 353 | | |
| 354 | 310 | /*********************************** |
| 355 | 311 | * Memory Map Information * |
| 356 | 312 | ***********************************/ |
| 357 | 313 | |
| 358 | 314 | static ADDRESS_MAP_START( main_map, AS_PROGRAM, 8, _4enlinea_state ) |
| 359 | 315 | AM_RANGE(0x0000, 0x7fff) AM_ROM |
| 360 | | AM_RANGE(0x8000, 0x9fff) AM_RAM_WRITE(vram_w) AM_SHARE("videoram") // even lines |
| 361 | | AM_RANGE(0xa000, 0xbfff) AM_RAM_WRITE(vram2_w) AM_SHARE("videoram2") // odd lines |
| 316 | // AM_RANGE(0x8000, 0xbfff) AM_RAM // CGA VRAM |
| 362 | 317 | AM_RANGE(0xc000, 0xdfff) AM_RAM |
| 363 | 318 | |
| 364 | 319 | AM_RANGE(0xe000, 0xe000) AM_READ(unk_e000_r) |
| r29365 | r29366 | |
| 372 | 327 | static ADDRESS_MAP_START( main_portmap, AS_IO, 8, _4enlinea_state ) |
| 373 | 328 | ADDRESS_MAP_GLOBAL_MASK(0x3ff) |
| 374 | 329 | |
| 375 | | AM_RANGE(0x3d4, 0x3d4) AM_DEVWRITE("crtc", mc6845_device, address_w) |
| 376 | | AM_RANGE(0x3d5, 0x3d5) AM_DEVWRITE("crtc", mc6845_device, register_w) |
| 377 | | AM_RANGE(0x3d8, 0x3d8) AM_WRITE(crtc_mode_ctrl_w) |
| 378 | | AM_RANGE(0x3d9, 0x3d9) AM_WRITE(crtc_colormode_w) |
| 379 | | AM_RANGE(0x3da, 0x3da) AM_READ(crtc_status_r) |
| 380 | | AM_RANGE(0x3bf, 0x3bf) AM_WRITE(crtc_config_w) |
| 381 | | |
| 330 | // AM_RANGE(0x3d4, 0x3df) CGA regs |
| 382 | 331 | ADDRESS_MAP_END |
| 383 | 332 | |
| 384 | 333 | |
| r29365 | r29366 | |
| 423 | 372 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) |
| 424 | 373 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) |
| 425 | 374 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 375 | |
| 376 | |
| 377 | PORT_START( "pcvideo_cga_config" ) |
| 378 | PORT_BIT( 0xff, IP_ACTIVE_HIGH, IPT_UNUSED ) |
| 426 | 379 | INPUT_PORTS_END |
| 427 | 380 | |
| 428 | 381 | |
| r29365 | r29366 | |
| 430 | 383 | * Graphics Layouts * |
| 431 | 384 | ***********************************/ |
| 432 | 385 | |
| 433 | | static const gfx_layout charlayout = |
| 434 | | { |
| 435 | | 8,8, |
| 436 | | 0x4000/16, |
| 437 | | 2, |
| 438 | | { 0, 1 }, |
| 439 | | { 0, 2, 4, 6, 8, 10, 12, 14 }, |
| 440 | | { 0*16, 1*16, 2*16, 3*16, 4*16, 5*16, 6*16, 7*16 }, |
| 441 | | 8*16 |
| 442 | | }; |
| 443 | 386 | |
| 387 | |
| 444 | 388 | /**************************************** |
| 445 | 389 | * Graphics Decode Information * |
| 446 | 390 | ****************************************/ |
| 447 | 391 | |
| 448 | 392 | static GFXDECODE_START( 4enlinea ) |
| 449 | | GFXDECODE_ENTRY( NULL, 0, charlayout, 0, 1 ) |
| 450 | 393 | GFXDECODE_END |
| 451 | 394 | |
| 452 | 395 | |
| r29365 | r29366 | |
| 469 | 412 | * CRTC Interface * |
| 470 | 413 | **********************************/ |
| 471 | 414 | |
| 472 | | static MC6845_ON_UPDATE_ADDR_CHANGED(crtc_addr) |
| 473 | | { |
| 474 | 415 | |
| 475 | | } |
| 476 | 416 | |
| 477 | | static MC6845_INTERFACE( mc6845_intf ) |
| 478 | | { |
| 479 | | false, /* show border area */ |
| 480 | | 0,0,0,0, /* visarea adjustment */ |
| 481 | | 8, /* number of pixels per video memory address */ |
| 482 | | NULL, /* before pixel update callback */ |
| 483 | | NULL, /* row update callback */ |
| 484 | | NULL, /* after pixel update callback */ |
| 485 | | DEVCB_NULL, /* callback for display state changes */ |
| 486 | | DEVCB_NULL, /* callback for cursor state changes */ |
| 487 | | DEVCB_NULL, /* HSYNC callback */ |
| 488 | | DEVCB_NULL, /* VSYNC callback */ |
| 489 | | crtc_addr /* update address callback */ |
| 490 | | }; |
| 491 | | |
| 492 | | |
| 493 | 417 | /*********************************** |
| 494 | 418 | * Sound Interface * |
| 495 | 419 | ***********************************/ |
| r29365 | r29366 | |
| 509 | 433 | * Machine Drivers * |
| 510 | 434 | ***********************************/ |
| 511 | 435 | |
| 436 | SLOT_INTERFACE_START( 4enlinea_isa8_cards ) |
| 437 | SLOT_INTERFACE_INTERNAL("4enlinea", ISA8_CGA_4ENLINEA) |
| 438 | SLOT_INTERFACE_END |
| 439 | |
| 440 | static const isa8bus_interface _4enlinea_isabus_intf = |
| 441 | { |
| 442 | // interrupts |
| 443 | DEVCB_NULL, |
| 444 | DEVCB_NULL, |
| 445 | DEVCB_NULL, |
| 446 | DEVCB_NULL, |
| 447 | DEVCB_NULL, |
| 448 | DEVCB_NULL, |
| 449 | |
| 450 | // dma request |
| 451 | DEVCB_NULL, |
| 452 | DEVCB_NULL, |
| 453 | DEVCB_NULL |
| 454 | }; |
| 455 | |
| 456 | /* TODO: irq sources are unknown */ |
| 457 | INTERRUPT_GEN_MEMBER(_4enlinea_state::_4enlinea_irq) |
| 458 | { |
| 459 | if(m_irq_count == 0) |
| 460 | device.execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE); |
| 461 | else |
| 462 | device.execute().set_input_line(0, HOLD_LINE); |
| 463 | |
| 464 | m_irq_count++; |
| 465 | m_irq_count&=3; |
| 466 | } |
| 467 | |
| 512 | 468 | static MACHINE_CONFIG_START( 4enlinea, _4enlinea_state ) |
| 513 | 469 | |
| 514 | 470 | /* basic machine hardware */ |
| 515 | 471 | MCFG_CPU_ADD("maincpu", Z80, PRG_CPU_CLOCK) |
| 516 | 472 | MCFG_CPU_PROGRAM_MAP(main_map) |
| 517 | 473 | MCFG_CPU_IO_MAP(main_portmap) |
| 518 | | MCFG_CPU_VBLANK_INT_DRIVER("screen", _4enlinea_state, nmi_line_pulse) |
| 519 | | MCFG_CPU_PERIODIC_INT_DRIVER(_4enlinea_state, irq0_line_hold, 4*60) |
| 474 | MCFG_CPU_PERIODIC_INT_DRIVER(_4enlinea_state, _4enlinea_irq, 60) //TODO |
| 475 | // MCFG_CPU_PERIODIC_INT_DRIVER(_4enlinea_state, irq0_line_hold, 4*35) |
| 520 | 476 | |
| 521 | 477 | MCFG_CPU_ADD("audiocpu", Z80, SND_CPU_CLOCK) |
| 522 | 478 | MCFG_CPU_PROGRAM_MAP(audio_map) |
| 523 | 479 | MCFG_CPU_IO_MAP(audio_portmap) |
| 524 | 480 | |
| 525 | | /* video hardware */ |
| 526 | | MCFG_SCREEN_ADD("screen", RASTER) |
| 527 | | MCFG_SCREEN_REFRESH_RATE(60) |
| 528 | | MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0)) |
| 529 | | MCFG_SCREEN_SIZE(320, 200) |
| 530 | | MCFG_SCREEN_VISIBLE_AREA(0, 320-1, 0, 200-1) |
| 531 | | MCFG_SCREEN_UPDATE_DRIVER(_4enlinea_state, screen_update_4enlinea) |
| 532 | | MCFG_SCREEN_PALETTE("palette") |
| 481 | MCFG_ISA8_BUS_ADD("isa", ":maincpu", _4enlinea_isabus_intf) |
| 482 | MCFG_ISA8_SLOT_ADD("isa", "isa1", 4enlinea_isa8_cards, "4enlinea", true) |
| 533 | 483 | |
| 534 | | MCFG_GFXDECODE_ADD("gfxdecode", "palette", 4enlinea) |
| 535 | | MCFG_PALETTE_ADD("palette", 256) |
| 536 | 484 | |
| 537 | 485 | /* 6845 clock is a guess, since it's a UM6845R embedded in the UM487F. |
| 538 | 486 | CRTC_CLOCK is 8MHz, entering for pin 1 of UM487F. This clock is used |
| r29365 | r29366 | |
| 542 | 490 | CRTC_CLOCK / 4.5 = 59.521093 Hz. |
| 543 | 491 | CRTC_CLOCK / 5.0 = 53.569037 Hz. |
| 544 | 492 | */ |
| 545 | | // MCFG_MC6845_ADD("crtc", MC6845, "screen", CRTC_CLOCK / 2, mc6845_intf) // seems that MC6845 doesn't support the game mode |
| 546 | | MCFG_MC6845_ADD("crtc", R6545_1, "screen", CRTC_CLOCK / 4.5, mc6845_intf) |
| 547 | 493 | |
| 548 | 494 | /* sound hardware */ |
| 549 | 495 | MCFG_SPEAKER_STANDARD_MONO("mono") |