trunk/src/mess/drivers/sun3.c
| r30684 | r30685 | |
| 1 | 1 | /*************************************************************************** |
| 2 | |
| 3 | sun3.c: preliminary driver for Sun 3 and Sun 3x models. |
| 4 | |
| 5 | status: 3/80 POSTs, 3/460 needs its unique RTC chip (also used by non-3x Sun 3s). |
| 6 | |
| 7 | TODO: |
| 8 | - Z8530 SCC needs to actually speak serial so we can hook up the mouse and keyboard. |
| 9 | - Improve interrupt controller emulation. |
| 10 | - Figure out how the IOMMU works. |
| 11 | - Intersil 7170 device for 3/460 and 3/480 (they use the same PROMs). |
| 12 | - Sun custom MMU for original Sun 3 models. |
| 13 | - AM7990 LANCE chip support for everyone. |
| 14 | - Figure out how the parallel printer port maps to Centronics and make it so. |
| 15 | - Much more... |
| 16 | |
| 17 | |
| 18 | Sun-3 Models |
| 19 | ------------ |
| 2 | 20 | |
| 3 | | Sun-3 Models |
| 4 | | ------------ |
| 5 | | |
| 6 | 21 | 3/160 |
| 7 | 22 | Processor(s): 68020 @ 16.67MHz, 68881, Sun-3 MMU, 8 hardware |
| 8 | 23 | contexts, 2 MIPS |
| r30684 | r30685 | |
| 203 | 218 | factor. Serial and keyboard ports. External RAM, |
| 204 | 219 | framebuffer, and SCSI/ethernet boards |
| 205 | 220 | available. |
| 221 | |
| 222 | Sun3X notes from NetBSD and Linux: |
| 206 | 223 | |
| 224 | RAM_END 0x40000000 |
| 225 | P4DAC 0x50200000 |
| 226 | VIDEO_P4ID 0x50300000 |
| 227 | BW2_ADDR 0x50400000 |
| 228 | ENA_PLANE 0x50600000 |
| 229 | FPA_ADDR 0x5c000000 |
| 230 | IOMMU 0x60000000 |
| 231 | ENABLEREG 0x61000000 |
| 232 | BUSERRREG 0x61000400 |
| 233 | DIAGREG 0x61000800 |
| 234 | IDPROM1 0x61000c00 (3/470) |
| 235 | MEMREG 0x61001000 |
| 236 | INTERREG 0x61001400 |
| 237 | SCC1 0x62000000 (keyboard/mouse) |
| 238 | SCC2 0x62002000 (serial console) |
| 239 | EEPROM 0x64000000 |
| 240 | IDPROM2 0x640007d8 (3/80) |
| 241 | CLOCK2 0x640007f8 (3/80 Mostek 48T02) |
| 242 | CLOCK1 0x64002000 (3/470 Intersil 7170) |
| 243 | INTELETH 0x65000000 |
| 244 | LANCEETH 0x65002000 |
| 245 | EMULEXSCSI 0x66000000 (3/80 5394) |
| 246 | EMULLEXDMA 0x66001000 (3/80) |
| 247 | PCACHETAG 0x68000000 |
| 248 | ECCPARREG 0x6a1e0000 |
| 249 | IOCTAGS 0x6c000000 |
| 250 | IOCFLUSH 0x6d000000 |
| 251 | FDC 0x6e000000 (3/80 Intel 82077) |
| 252 | FDC_CNTRL 0x6e000400 |
| 253 | FDC_VEC 0x6e000800 |
| 254 | PRINTER 0x6f00003c (3/80) |
| 207 | 255 | |
| 208 | | 25/08/2009 Skeleton driver. |
| 256 | The Sun3x System Enable Register controls the function of a few |
| 257 | on-board devices and general system operation. It is cleared when |
| 258 | the system is reset. |
| 209 | 259 | |
| 260 | 15 0 |
| 261 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---.---.---+ |
| 262 | |BT |FPP|DMA| 0 |VID|RES|FPA|DIA| 0 |CCH|IOC|LBK|DCH| UNUSED | |
| 263 | +---+---+---+---+---+---+---+---+---+---+---+---+---+---.---.---+ |
| 264 | |
| 265 | Where: DCH = debug mode for system cache |
| 266 | LBK = VME loopback |
| 267 | IOC = I/O cache enable |
| 268 | CCH = system cache enable |
| 269 | DIA = diagnostic switch |
| 270 | FPA = enable floating-point accelerator |
| 271 | RES = 0 for hi-res, 1 for low res |
| 272 | VID = enable video display |
| 273 | DMA = enable system DVMA |
| 274 | FPP = enable 68881/2 FPU |
| 275 | BT = 0 for boot state, 1 for normal state |
| 276 | |
| 277 | bad '030 MMU mapping: L fef82000 -> P 00000000 |
| 278 | |
| 210 | 279 | ****************************************************************************/ |
| 211 | 280 | |
| 212 | 281 | #include "emu.h" |
| 213 | 282 | #include "cpu/m68000/m68000.h" |
| 283 | #include "machine/timekpr.h" |
| 284 | #include "machine/8530scc.h" |
| 285 | #include "bus/scsi/scsi.h" |
| 286 | #include "bus/scsi/scsihd.h" |
| 287 | #include "bus/scsi/scsicd.h" |
| 288 | #include "machine/ncr539x.h" |
| 289 | #include "machine/upd765.h" |
| 290 | #include "formats/pc_dsk.h" |
| 291 | #include "formats/mfi_dsk.h" |
| 214 | 292 | |
| 293 | #define TIMEKEEPER_TAG "timekpr" |
| 294 | #define SCC1_TAG "scc1" |
| 295 | #define SCC2_TAG "scc2" |
| 296 | #define ESP_TAG "esp" |
| 297 | #define FDC_TAG "fdc" |
| 215 | 298 | |
| 216 | 299 | class sun3_state : public driver_device |
| 217 | 300 | { |
| 218 | 301 | public: |
| 219 | 302 | sun3_state(const machine_config &mconfig, device_type type, const char *tag) |
| 220 | | : driver_device(mconfig, type, tag), |
| 221 | | m_maincpu(*this, "maincpu") |
| 222 | | , |
| 223 | | m_p_ram(*this, "p_ram"){ } |
| 303 | : driver_device(mconfig, type, tag), |
| 304 | m_maincpu(*this, "maincpu"), |
| 305 | m_scc1(*this, SCC1_TAG), |
| 306 | m_scc2(*this, SCC2_TAG), |
| 307 | m_fdc(*this, FDC_TAG), |
| 308 | m_p_ram(*this, "p_ram"), |
| 309 | m_bw2_vram(*this, "bw2_vram") |
| 310 | { } |
| 224 | 311 | |
| 225 | 312 | required_device<cpu_device> m_maincpu; |
| 313 | required_device<scc8530_t> m_scc1; |
| 314 | required_device<scc8530_t> m_scc2; |
| 315 | optional_device<n82077aa_device> m_fdc; |
| 226 | 316 | virtual void machine_reset(); |
| 227 | 317 | |
| 228 | 318 | required_shared_ptr<UINT32> m_p_ram; |
| 319 | optional_shared_ptr<UINT32> m_bw2_vram; |
| 320 | |
| 321 | DECLARE_READ32_MEMBER(enable_r); |
| 322 | DECLARE_WRITE32_MEMBER(enable_w); |
| 323 | DECLARE_READ32_MEMBER(buserr_r); |
| 324 | DECLARE_WRITE32_MEMBER(buserr_w); |
| 325 | DECLARE_READ32_MEMBER(diag_r); |
| 326 | DECLARE_WRITE32_MEMBER(diag_w); |
| 327 | DECLARE_READ32_MEMBER(printer_r); |
| 328 | DECLARE_WRITE32_MEMBER(printer_w); |
| 329 | DECLARE_READ32_MEMBER(iommu_r); |
| 330 | DECLARE_WRITE32_MEMBER(iommu_w); |
| 331 | DECLARE_READ32_MEMBER(irqctrl_r); |
| 332 | DECLARE_WRITE32_MEMBER(irqctrl_w); |
| 333 | DECLARE_READ32_MEMBER(memreg_r); |
| 334 | DECLARE_WRITE32_MEMBER(memreg_w); |
| 335 | DECLARE_READ32_MEMBER(memrerraddr_r); |
| 336 | DECLARE_WRITE32_MEMBER(memrerraddr_w); |
| 337 | DECLARE_READ32_MEMBER(fdc_control_r); |
| 338 | DECLARE_WRITE32_MEMBER(fdc_control_w); |
| 339 | DECLARE_READ32_MEMBER(cause_buserr_r); |
| 340 | DECLARE_WRITE32_MEMBER(cause_buserr_w); |
| 341 | DECLARE_WRITE32_MEMBER(ramwrite_w); |
| 342 | DECLARE_READ32_MEMBER(fpa_r); |
| 343 | DECLARE_READ32_MEMBER(p4id_r); |
| 344 | |
| 345 | DECLARE_READ8_MEMBER(scc1_r); |
| 346 | DECLARE_WRITE8_MEMBER(scc1_w); |
| 347 | DECLARE_READ8_MEMBER(scc2_r); |
| 348 | DECLARE_WRITE8_MEMBER(scc2_w); |
| 349 | |
| 350 | DECLARE_FLOPPY_FORMATS( floppy_formats ); |
| 351 | |
| 352 | TIMER_DEVICE_CALLBACK_MEMBER(sun380_timer); |
| 353 | |
| 354 | UINT32 bw2_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 355 | |
| 356 | private: |
| 357 | UINT32 m_enable, m_buserr, m_diag, m_printer, m_irqctrl, m_memreg, m_memerraddr; |
| 358 | UINT32 m_iommu[0x800]; |
| 359 | bool m_bInBusErr; |
| 229 | 360 | }; |
| 230 | 361 | |
| 231 | 362 | static ADDRESS_MAP_START(sun3_mem, AS_PROGRAM, 32, sun3_state) |
| r30684 | r30685 | |
| 234 | 365 | AM_RANGE(0x0fef0000, 0x0fefffff) AM_ROM AM_REGION("user1",0) |
| 235 | 366 | ADDRESS_MAP_END |
| 236 | 367 | |
| 237 | | static ADDRESS_MAP_START(sun3x_mem, AS_PROGRAM, 32, sun3_state) |
| 238 | | AM_RANGE(0x00000000, 0x00ffffff) AM_RAM AM_SHARE("p_ram") // 16MB |
| 368 | static ADDRESS_MAP_START(sun3_80_mem, AS_PROGRAM, 32, sun3_state) |
| 369 | AM_RANGE(0x00000000, 0x03ffffff) AM_RAM AM_SHARE("p_ram") AM_WRITE(ramwrite_w) |
| 370 | AM_RANGE(0x40000000, 0x40000003) AM_READWRITE(cause_buserr_r, cause_buserr_w) |
| 371 | AM_RANGE(0x50300000, 0x50300003) AM_READ(p4id_r) |
| 372 | AM_RANGE(0x50400000, 0x504fffff) AM_RAM AM_SHARE("bw2_vram") |
| 373 | AM_RANGE(0x60000000, 0x60001fff) AM_READWRITE(iommu_r, iommu_w) |
| 374 | AM_RANGE(0x61000000, 0x61000003) AM_READWRITE(enable_r, enable_w) |
| 375 | AM_RANGE(0x61000400, 0x61000403) AM_READWRITE(buserr_r, buserr_w) |
| 376 | AM_RANGE(0x61000800, 0x61000803) AM_READWRITE(diag_r, diag_w) |
| 377 | AM_RANGE(0x61001000, 0x61001003) AM_READWRITE(memreg_r, memreg_w) |
| 378 | AM_RANGE(0x61001004, 0x61001007) AM_READWRITE(memrerraddr_r, memrerraddr_w) |
| 379 | AM_RANGE(0x61001400, 0x61001403) AM_READWRITE(irqctrl_r, irqctrl_w) |
| 380 | AM_RANGE(0x62000000, 0x6200000f) AM_READWRITE8(scc1_r, scc1_w, 0xff00ff00) |
| 381 | AM_RANGE(0x62002000, 0x6200200f) AM_READWRITE8(scc2_r, scc2_w, 0xff00ff00) |
| 382 | AM_RANGE(0x63000000, 0x6301ffff) AM_ROM AM_REGION("user1",0) |
| 383 | AM_RANGE(0x64000000, 0x640007ff) AM_DEVREADWRITE8(TIMEKEEPER_TAG, timekeeper_device, read, write, 0xffffffff) |
| 384 | AM_RANGE(0x66000000, 0x6600003f) AM_DEVREADWRITE8(ESP_TAG, ncr539x_device, read, write, 0xff000000) |
| 385 | AM_RANGE(0x6e000000, 0x6e000007) AM_DEVICE8(FDC_TAG, n82077aa_device, map, 0xffffffff) |
| 386 | AM_RANGE(0x6e000400, 0x6e000403) AM_READWRITE(fdc_control_r, fdc_control_w) |
| 387 | AM_RANGE(0x6f00003c, 0x6f00003f) AM_READWRITE(printer_r, printer_w) |
| 239 | 388 | AM_RANGE(0xfefe0000, 0xfefeffff) AM_ROM AM_REGION("user1",0) |
| 240 | 389 | ADDRESS_MAP_END |
| 241 | 390 | |
| 391 | static ADDRESS_MAP_START(sun3_460_mem, AS_PROGRAM, 32, sun3_state) |
| 392 | AM_RANGE(0x00000000, 0x03ffffff) AM_RAM AM_SHARE("p_ram") AM_WRITE(ramwrite_w) |
| 393 | AM_RANGE(0x09000000, 0x09000003) AM_READWRITE(cause_buserr_r, cause_buserr_w) |
| 394 | AM_RANGE(0x50300000, 0x50300003) AM_READ(p4id_r) |
| 395 | AM_RANGE(0x50400000, 0x504fffff) AM_RAM AM_SHARE("bw2_vram") |
| 396 | AM_RANGE(0x5c000f14, 0x5c000f17) AM_READ(fpa_r) |
| 397 | AM_RANGE(0x60000000, 0x60001fff) AM_READWRITE(iommu_r, iommu_w) |
| 398 | AM_RANGE(0x61000000, 0x61000003) AM_READWRITE(enable_r, enable_w) |
| 399 | AM_RANGE(0x61000400, 0x61000403) AM_READWRITE(buserr_r, buserr_w) |
| 400 | AM_RANGE(0x61000800, 0x61000803) AM_READWRITE(diag_r, diag_w) |
| 401 | AM_RANGE(0x61001000, 0x61001003) AM_READWRITE(memreg_r, memreg_w) |
| 402 | AM_RANGE(0x61001004, 0x61001007) AM_READWRITE(memrerraddr_r, memrerraddr_w) |
| 403 | AM_RANGE(0x61001400, 0x61001403) AM_READWRITE(irqctrl_r, irqctrl_w) |
| 404 | AM_RANGE(0x62000000, 0x6200000f) AM_READWRITE8(scc1_r, scc1_w, 0xff00ff00) |
| 405 | AM_RANGE(0x62002000, 0x6200200f) AM_READWRITE8(scc2_r, scc2_w, 0xff00ff00) |
| 406 | AM_RANGE(0x63000000, 0x6301ffff) AM_ROM AM_REGION("user1",0) |
| 407 | |
| 408 | AM_RANGE(0x6f00003c, 0x6f00003f) AM_READWRITE(printer_r, printer_w) |
| 409 | AM_RANGE(0xfefe0000, 0xfefeffff) AM_ROM AM_REGION("user1",0) |
| 410 | ADDRESS_MAP_END |
| 411 | |
| 412 | READ32_MEMBER( sun3_state::p4id_r ) |
| 413 | { |
| 414 | return (1<<24); // 0 = hires bw2 1600x1280, 1 = bw2 1152x900, 0x45 is "Ibis" color, blt 0x68 is "Lego" color |
| 415 | } |
| 416 | |
| 417 | WRITE32_MEMBER( sun3_state::fdc_control_w ) |
| 418 | { |
| 419 | logerror("FDC write %02x (%08x)\n", data >> 24, space.device().safe_pc()); |
| 420 | } |
| 421 | |
| 422 | READ32_MEMBER( sun3_state::fdc_control_r ) |
| 423 | { |
| 424 | // Type of floppy present |
| 425 | // 0 = no floppy in drive |
| 426 | // 1 = ed |
| 427 | // 2 = hd |
| 428 | // 3 = dd |
| 429 | |
| 430 | if(m_fdc) { |
| 431 | floppy_image_device *fdev = machine().device<floppy_connector>(":fdc:0")->get_device(); |
| 432 | if(fdev->exists()) { |
| 433 | UINT32 variant = fdev->get_variant(); |
| 434 | switch(variant) { |
| 435 | case floppy_image::SSSD: |
| 436 | case floppy_image::SSDD: |
| 437 | case floppy_image::DSDD: |
| 438 | return 3 << 24; |
| 439 | |
| 440 | case floppy_image::DSHD: |
| 441 | return 2 << 24; |
| 442 | |
| 443 | case floppy_image::DSED: |
| 444 | return 1 << 24; |
| 445 | } |
| 446 | } |
| 447 | } |
| 448 | |
| 449 | return 0 << 24; |
| 450 | } |
| 451 | |
| 452 | WRITE32_MEMBER(sun3_state::ramwrite_w) |
| 453 | { |
| 454 | UINT32 *pRAM = (UINT32 *)m_p_ram.target(); |
| 455 | |
| 456 | if (((m_memreg & 0xf0000000) == 0x70000000) && |
| 457 | (m_irqctrl & 0x01000000) && |
| 458 | !(m_bInBusErr)) |
| 459 | { |
| 460 | m_memerraddr = offset<<2; |
| 461 | |
| 462 | // low 4 bits of memreg are the byte lane(s) involved, negative logic |
| 463 | m_memreg |= 0x0f; |
| 464 | switch (mem_mask) |
| 465 | { |
| 466 | case 0xff000000: |
| 467 | m_memreg &= ~0x08; |
| 468 | break; |
| 469 | |
| 470 | case 0x00ff0000: |
| 471 | m_memerraddr += 1; |
| 472 | m_memreg &= ~0x04; |
| 473 | break; |
| 474 | |
| 475 | case 0x0000ff00: |
| 476 | m_memerraddr += 2; |
| 477 | m_memreg &= ~0x02; |
| 478 | break; |
| 479 | |
| 480 | case 0x000000ff: |
| 481 | m_memerraddr += 3; |
| 482 | m_memreg &= ~0x01; |
| 483 | break; |
| 484 | |
| 485 | case 0x0000ffff: |
| 486 | m_memerraddr += 2; |
| 487 | m_memreg &= ~0x03; |
| 488 | break; |
| 489 | |
| 490 | case 0xffff0000: |
| 491 | m_memreg &= ~0x0c; |
| 492 | break; |
| 493 | |
| 494 | case 0xffffffff: // no address adjust, show all 4 lanes as problematic |
| 495 | break; |
| 496 | } |
| 497 | |
| 498 | m_bInBusErr = true; // prevent recursion |
| 499 | m_maincpu->set_input_line_and_vector(M68K_IRQ_7, ASSERT_LINE, 2); |
| 500 | } |
| 501 | |
| 502 | COMBINE_DATA(&pRAM[offset]); |
| 503 | } |
| 504 | |
| 505 | // sun3: 0 = B control, 1 = B data, 2 = A control, 3 = A data |
| 506 | // 8530scc: 0 = B control, 1 = A control, 2 = B data, 3 = A data |
| 507 | READ8_MEMBER(sun3_state::scc1_r) |
| 508 | { |
| 509 | int regsel = ((offset & 1)<<1) | ((offset & 2) >> 1); |
| 510 | return m_scc1->reg_r(space, regsel); |
| 511 | } |
| 512 | |
| 513 | WRITE8_MEMBER(sun3_state::scc1_w) |
| 514 | { |
| 515 | int regsel = ((offset & 1)<<1) | ((offset & 2) >> 1); |
| 516 | m_scc1->reg_w(space, regsel, data); |
| 517 | } |
| 518 | |
| 519 | READ8_MEMBER(sun3_state::scc2_r) |
| 520 | { |
| 521 | int regsel = ((offset & 1)<<1) | ((offset & 2) >> 1); |
| 522 | return m_scc2->reg_r(space, regsel); |
| 523 | } |
| 524 | |
| 525 | WRITE8_MEMBER(sun3_state::scc2_w) |
| 526 | { |
| 527 | int regsel = ((offset & 1)<<1) | ((offset & 2) >> 1); |
| 528 | m_scc2->reg_w(space, regsel, data); |
| 529 | } |
| 530 | |
| 531 | READ32_MEMBER(sun3_state::enable_r) |
| 532 | { |
| 533 | return m_enable; |
| 534 | } |
| 535 | |
| 536 | WRITE32_MEMBER(sun3_state::enable_w) |
| 537 | { |
| 538 | // printf("sun3x: %08x to enable (mask %08x)\n", data, mem_mask); |
| 539 | COMBINE_DATA(&m_enable); |
| 540 | } |
| 541 | |
| 542 | READ32_MEMBER(sun3_state::buserr_r) |
| 543 | { |
| 544 | UINT32 rv = m_buserr; |
| 545 | m_buserr = 0; |
| 546 | return rv; |
| 547 | } |
| 548 | |
| 549 | WRITE32_MEMBER(sun3_state::buserr_w) |
| 550 | { |
| 551 | // printf("sun3x: %08x to buserr (mask %08x)\n", data, mem_mask); |
| 552 | COMBINE_DATA(&m_buserr); |
| 553 | } |
| 554 | |
| 555 | READ32_MEMBER(sun3_state::diag_r) |
| 556 | { |
| 557 | return m_diag; |
| 558 | } |
| 559 | |
| 560 | WRITE32_MEMBER(sun3_state::diag_w) |
| 561 | { |
| 562 | // printf("sun3x: %08x to diag (mask %08x)\n", data, mem_mask); |
| 563 | COMBINE_DATA(&m_diag); |
| 564 | } |
| 565 | |
| 566 | READ32_MEMBER(sun3_state::printer_r) |
| 567 | { |
| 568 | return m_printer; |
| 569 | } |
| 570 | |
| 571 | WRITE32_MEMBER(sun3_state::printer_w) |
| 572 | { |
| 573 | // printf("sun3x: %08x to printer (mask %08x)\n", data, mem_mask); |
| 574 | COMBINE_DATA(&m_printer); |
| 575 | } |
| 576 | |
| 577 | READ32_MEMBER(sun3_state::irqctrl_r) |
| 578 | { |
| 579 | return m_irqctrl; |
| 580 | } |
| 581 | |
| 582 | WRITE32_MEMBER(sun3_state::irqctrl_w) |
| 583 | { |
| 584 | // printf("sun3x: %08x to interrupt control (mask %08x)\n", data, mem_mask); |
| 585 | COMBINE_DATA(&m_irqctrl); |
| 586 | |
| 587 | if (data & 0x01000000) |
| 588 | { |
| 589 | if (data & 0x02000000) |
| 590 | { |
| 591 | m_maincpu->set_input_line(M68K_IRQ_1, ASSERT_LINE); |
| 592 | } |
| 593 | if (data & 0x04000000) |
| 594 | { |
| 595 | m_maincpu->set_input_line(M68K_IRQ_2, ASSERT_LINE); |
| 596 | } |
| 597 | if (data & 0x08000000) |
| 598 | { |
| 599 | m_maincpu->set_input_line(M68K_IRQ_3, ASSERT_LINE); |
| 600 | } |
| 601 | if (!(data & 0x80000000)) |
| 602 | { |
| 603 | m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); |
| 604 | } |
| 605 | } |
| 606 | else // master enable clear, clear all interrupts |
| 607 | { |
| 608 | m_maincpu->set_input_line(M68K_IRQ_1, CLEAR_LINE); |
| 609 | m_maincpu->set_input_line(M68K_IRQ_2, CLEAR_LINE); |
| 610 | m_maincpu->set_input_line(M68K_IRQ_3, CLEAR_LINE); |
| 611 | m_maincpu->set_input_line(M68K_IRQ_4, CLEAR_LINE); |
| 612 | m_maincpu->set_input_line(M68K_IRQ_5, CLEAR_LINE); |
| 613 | m_maincpu->set_input_line(M68K_IRQ_6, CLEAR_LINE); |
| 614 | m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); |
| 615 | } |
| 616 | } |
| 617 | |
| 618 | READ32_MEMBER(sun3_state::memreg_r) |
| 619 | { |
| 620 | return m_memreg; |
| 621 | } |
| 622 | |
| 623 | WRITE32_MEMBER(sun3_state::memreg_w) |
| 624 | { |
| 625 | // printf("sun3x: %08x to memory control (mask %08x)\n", data, mem_mask); |
| 626 | COMBINE_DATA(&m_memreg); |
| 627 | } |
| 628 | |
| 629 | READ32_MEMBER(sun3_state::memrerraddr_r) |
| 630 | { |
| 631 | m_bInBusErr = false; |
| 632 | m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); |
| 633 | return m_memerraddr; |
| 634 | } |
| 635 | |
| 636 | WRITE32_MEMBER(sun3_state::memrerraddr_w) |
| 637 | { |
| 638 | // printf("sun3x: %08x to memory error address (mask %08x)\n", data, mem_mask); |
| 639 | COMBINE_DATA(&m_memerraddr); |
| 640 | } |
| 641 | |
| 642 | READ32_MEMBER(sun3_state::iommu_r) |
| 643 | { |
| 644 | return m_iommu[offset]; |
| 645 | } |
| 646 | |
| 647 | // IOMMU entry defs: |
| 648 | // address mask: 0x03ffe000 |
| 649 | // cache inhibit: 0x00000040 |
| 650 | // full block: 0x00000020 |
| 651 | // modified: 0x00000010 |
| 652 | // used: 0x00000008 |
| 653 | // write prot: 0x00000004 |
| 654 | // bad: 0x00000002 |
| 655 | // valid: 0x00000001 |
| 656 | WRITE32_MEMBER(sun3_state::iommu_w) |
| 657 | { |
| 658 | COMBINE_DATA(&m_iommu[offset]); |
| 659 | } |
| 660 | |
| 661 | READ32_MEMBER(sun3_state::fpa_r) |
| 662 | { |
| 663 | m_buserr |= 0x04000000; |
| 664 | m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); |
| 665 | m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); |
| 666 | return 0xffffffff; |
| 667 | } |
| 668 | |
| 669 | READ32_MEMBER(sun3_state::cause_buserr_r) |
| 670 | { |
| 671 | m_buserr |= 0x20000000; |
| 672 | m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); |
| 673 | m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); |
| 674 | return 0xffffffff; |
| 675 | } |
| 676 | |
| 677 | WRITE32_MEMBER(sun3_state::cause_buserr_w) |
| 678 | { |
| 679 | m_buserr |= 0x20000000; |
| 680 | m_maincpu->set_input_line(M68K_LINE_BUSERROR, ASSERT_LINE); |
| 681 | m_maincpu->set_input_line(M68K_LINE_BUSERROR, CLEAR_LINE); |
| 682 | } |
| 683 | |
| 684 | TIMER_DEVICE_CALLBACK_MEMBER(sun3_state::sun380_timer) |
| 685 | { |
| 686 | if ((m_irqctrl & 0x81000000) == 0x81000000) |
| 687 | { |
| 688 | m_maincpu->set_input_line(M68K_IRQ_7, CLEAR_LINE); |
| 689 | m_maincpu->set_input_line(M68K_IRQ_7, ASSERT_LINE); |
| 690 | } |
| 691 | } |
| 692 | |
| 693 | UINT32 sun3_state::bw2_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) |
| 694 | { |
| 695 | UINT32 *scanline; |
| 696 | int x, y; |
| 697 | UINT8 pixels; |
| 698 | static const UINT32 palette[2] = { 0, 0xffffff }; |
| 699 | UINT8 *m_vram = (UINT8 *)m_bw2_vram.target(); |
| 700 | |
| 701 | for (y = 0; y < 900; y++) |
| 702 | { |
| 703 | scanline = &bitmap.pix32(y); |
| 704 | for (x = 0; x < 1152/8; x++) |
| 705 | { |
| 706 | pixels = m_vram[(y * (1152/8)) + (BYTE4_XOR_BE(x))]; |
| 707 | |
| 708 | *scanline++ = palette[(pixels>>7)&1]; |
| 709 | *scanline++ = palette[(pixels>>6)&1]; |
| 710 | *scanline++ = palette[(pixels>>5)&1]; |
| 711 | *scanline++ = palette[(pixels>>4)&1]; |
| 712 | *scanline++ = palette[(pixels>>3)&1]; |
| 713 | *scanline++ = palette[(pixels>>2)&1]; |
| 714 | *scanline++ = palette[(pixels>>1)&1]; |
| 715 | *scanline++ = palette[(pixels&1)]; |
| 716 | } |
| 717 | } |
| 718 | |
| 719 | return 0; |
| 720 | } |
| 721 | |
| 242 | 722 | /* Input ports */ |
| 243 | 723 | static INPUT_PORTS_START( sun3 ) |
| 244 | 724 | INPUT_PORTS_END |
| r30684 | r30685 | |
| 251 | 731 | memcpy((UINT8*)m_p_ram.target(),user1,0x10000); |
| 252 | 732 | |
| 253 | 733 | m_maincpu->reset(); |
| 734 | |
| 735 | memset(m_iommu, 0, sizeof(m_iommu)); |
| 736 | |
| 737 | m_enable = 0; |
| 738 | m_buserr = 0; |
| 739 | m_diag = 0; |
| 740 | m_printer = 0; |
| 741 | m_irqctrl = 0; |
| 742 | m_memreg = 0; |
| 743 | m_memerraddr = 0; |
| 744 | m_bInBusErr = false; |
| 254 | 745 | } |
| 255 | 746 | |
| 747 | FLOPPY_FORMATS_MEMBER( sun3_state::floppy_formats ) |
| 748 | FLOPPY_PC_FORMAT |
| 749 | FLOPPY_FORMATS_END |
| 256 | 750 | |
| 751 | static SLOT_INTERFACE_START( sun_floppies ) |
| 752 | SLOT_INTERFACE( "35hd", FLOPPY_35_HD ) |
| 753 | SLOT_INTERFACE_END |
| 754 | |
| 257 | 755 | static MACHINE_CONFIG_START( sun3, sun3_state ) |
| 258 | 756 | /* basic machine hardware */ |
| 259 | 757 | MCFG_CPU_ADD("maincpu", M68020, 16670000) |
| 260 | 758 | MCFG_CPU_PROGRAM_MAP(sun3_mem) |
| 759 | |
| 760 | MCFG_DEVICE_ADD(SCC1_TAG, SCC8530, XTAL_4_9152MHz) |
| 761 | MCFG_DEVICE_ADD(SCC2_TAG, SCC8530, XTAL_4_9152MHz) |
| 261 | 762 | MACHINE_CONFIG_END |
| 262 | 763 | |
| 263 | | static MACHINE_CONFIG_START( sun3x, sun3_state ) |
| 764 | static MACHINE_CONFIG_START( sun3_80, sun3_state ) |
| 264 | 765 | /* basic machine hardware */ |
| 265 | | MCFG_CPU_ADD("maincpu", M68030, 16670000) |
| 266 | | MCFG_CPU_PROGRAM_MAP(sun3x_mem) |
| 766 | MCFG_CPU_ADD("maincpu", M68030, 20000000) |
| 767 | MCFG_CPU_PROGRAM_MAP(sun3_80_mem) |
| 768 | |
| 769 | MCFG_M48T02_ADD(TIMEKEEPER_TAG) |
| 770 | |
| 771 | MCFG_DEVICE_ADD(SCC1_TAG, SCC8530, XTAL_4_9152MHz) |
| 772 | MCFG_DEVICE_ADD(SCC2_TAG, SCC8530, XTAL_4_9152MHz) |
| 773 | |
| 774 | MCFG_DEVICE_ADD("scsi", SCSI_PORT, 0) |
| 775 | MCFG_SCSIDEV_ADD("scsi:" SCSI_PORT_DEVICE1, "harddisk", SCSIHD, SCSI_ID_6) |
| 776 | MCFG_SCSIDEV_ADD("scsi:" SCSI_PORT_DEVICE2, "harddisk", SCSIHD, SCSI_ID_5) |
| 777 | |
| 778 | MCFG_DEVICE_ADD(ESP_TAG, NCR539X, 20000000/2) |
| 779 | MCFG_LEGACY_SCSI_PORT("scsi") |
| 780 | |
| 781 | MCFG_N82077AA_ADD("fdc", n82077aa_device::MODE_PS2) |
| 782 | MCFG_FLOPPY_DRIVE_ADD("fdc:0", sun_floppies, "35hd", sun3_state::floppy_formats) |
| 783 | |
| 784 | // the timekeeper has no interrupt output, so 3/80 includes a dedicated timer circuit |
| 785 | MCFG_TIMER_DRIVER_ADD_PERIODIC("timer", sun3_state, sun380_timer, attotime::from_hz(100)) |
| 786 | |
| 787 | MCFG_SCREEN_ADD("bwtwo", RASTER) |
| 788 | MCFG_SCREEN_UPDATE_DRIVER(sun3_state, bw2_update) |
| 789 | MCFG_SCREEN_SIZE(1152,900) |
| 790 | MCFG_SCREEN_VISIBLE_AREA(0, 1152-1, 0, 900-1) |
| 791 | MCFG_SCREEN_REFRESH_RATE(72) |
| 267 | 792 | MACHINE_CONFIG_END |
| 268 | 793 | |
| 794 | static MACHINE_CONFIG_START( sun3_460, sun3_state ) |
| 795 | /* basic machine hardware */ |
| 796 | MCFG_CPU_ADD("maincpu", M68030, 33000000) |
| 797 | MCFG_CPU_PROGRAM_MAP(sun3_460_mem) |
| 798 | |
| 799 | MCFG_M48T02_ADD(TIMEKEEPER_TAG) |
| 800 | |
| 801 | MCFG_DEVICE_ADD(SCC1_TAG, SCC8530, XTAL_4_9152MHz) |
| 802 | MCFG_DEVICE_ADD(SCC2_TAG, SCC8530, XTAL_4_9152MHz) |
| 803 | MACHINE_CONFIG_END |
| 804 | |
| 269 | 805 | /* ROM definition */ |
| 270 | 806 | |
| 271 | 807 | ROM_START( sun3_50 ) |
| r30684 | r30685 | |
| 402 | 938 | ROMX_LOAD( "sun3_80_v3.0", 0x0000, 0x20000, CRC(47e3b012) SHA1(1e045b6f542aaf7808d6567c28a9e734a8c5d815), ROM_BIOS(3)) |
| 403 | 939 | ROM_SYSTEM_BIOS(3, "rev292", "Rev 2.9.2") |
| 404 | 940 | ROMX_LOAD( "sun3_80_v2.9.2", 0x0000, 0x20000, CRC(32bcf711) SHA1(7ecd4a0d0988c1d1d53fd79ac16c8456ed73ace1), ROM_BIOS(4)) |
| 941 | |
| 942 | // default NVRAM: includes valid settings for console on framebuffer, boot from SCSI disk, Ethernet ID, more |
| 943 | ROM_REGION( 0x800, TIMEKEEPER_TAG, 0 ) |
| 944 | ROM_LOAD( "timekpr_380.bin", 0x000000, 0x000800, CRC(e76f1aae) SHA1(8e7c36e3928887a94a8133e8416ee4126c31edd7) ) |
| 405 | 945 | ROM_END |
| 406 | 946 | |
| 407 | 947 | ROM_START( sun3_460 ) |
| r30684 | r30685 | |
| 413 | 953 | Sun 3/460/480 V2.9.3 Bootprom |
| 414 | 954 | Sun 3/460/480 V3.0 Bootprom (2 Files, one for odd and one for even addresses) |
| 415 | 955 | */ |
| 416 | | ROM_SYSTEM_BIOS(0, "rev291", "Rev 2.9.1") |
| 417 | | ROMX_LOAD( "sun3_460_v2.9.1_0", 0x00000, 0x10000, CRC(d62dbf09) SHA1(4a6b5fd7840b44fe93c9058a8973d8dd3c9f7d24), ROM_BIOS(1)) |
| 418 | | ROMX_LOAD( "sun3_460_v2.9.1_1", 0x10000, 0x10000, CRC(3b5a5942) SHA1(ed6250e3c07d7cb62d4dd517a8637c8d37e16dc5), ROM_BIOS(1)) |
| 419 | | ROM_SYSTEM_BIOS(1, "rev30", "Rev 3.0") |
| 420 | | ROMX_LOAD( "3_400_l.300", 0x00000, 0x10000, CRC(1312a04b) SHA1(6c3b67ba3567991897a48fe20f589ebbfcf0a35d), ROM_BIOS(2)) |
| 421 | | ROMX_LOAD( "3_400_h.300", 0x10000, 0x10000, CRC(8d688672) SHA1(a5593844ce6af6c4f7f39bb653dc8f964b73b095), ROM_BIOS(2)) |
| 956 | ROM_SYSTEM_BIOS(0, "rev30", "Rev 3.0") |
| 957 | ROMX_LOAD( "3_400_l.300", 0x00000, 0x10000, CRC(1312a04b) SHA1(6c3b67ba3567991897a48fe20f589ebbfcf0a35d), ROM_BIOS(1)) |
| 958 | ROMX_LOAD( "3_400_h.300", 0x10000, 0x10000, CRC(8d688672) SHA1(a5593844ce6af6c4f7f39bb653dc8f964b73b095), ROM_BIOS(1)) |
| 959 | ROM_SYSTEM_BIOS(1, "rev291", "Rev 2.9.1") |
| 960 | ROMX_LOAD( "sun3_460_v2.9.1_0", 0x00000, 0x10000, CRC(d62dbf09) SHA1(4a6b5fd7840b44fe93c9058a8973d8dd3c9f7d24), ROM_BIOS(2)) |
| 961 | ROMX_LOAD( "sun3_460_v2.9.1_1", 0x10000, 0x10000, CRC(3b5a5942) SHA1(ed6250e3c07d7cb62d4dd517a8637c8d37e16dc5), ROM_BIOS(2)) |
| 422 | 962 | ROM_END |
| 423 | 963 | |
| 424 | 964 | /* Driver */ |
| r30684 | r30685 | |
| 431 | 971 | COMP( 198?, sun3_260, 0, 0, sun3, sun3, driver_device, 0, "Sun Microsystems", "Sun 3/260/280", GAME_NOT_WORKING | GAME_NO_SOUND) // Prism |
| 432 | 972 | COMP( 198?, sun3_e, 0, 0, sun3, sun3, driver_device, 0, "Sun Microsystems", "Sun 3/E", GAME_NOT_WORKING | GAME_NO_SOUND) // Polaris |
| 433 | 973 | |
| 434 | | COMP( 198?, sun3_80, 0, 0, sun3x, sun3, driver_device, 0, "Sun Microsystems", "Sun 3x/80", GAME_NOT_WORKING | GAME_NO_SOUND) // Hydra |
| 435 | | COMP( 198?, sun3_460, 0, 0, sun3x, sun3, driver_device, 0, "Sun Microsystems", "Sun 3x/460/470/480", GAME_NOT_WORKING | GAME_NO_SOUND) // Pegasus |
| 974 | COMP( 198?, sun3_80, 0, 0, sun3_80, sun3, driver_device, 0, "Sun Microsystems", "Sun 3x/80", GAME_NOT_WORKING | GAME_NO_SOUND) // Hydra |
| 975 | COMP( 198?, sun3_460, 0, 0, sun3_460, sun3, driver_device, 0, "Sun Microsystems", "Sun 3x/460/470/480", GAME_NOT_WORKING | GAME_NO_SOUND) // Pegasus |