mac.cpp: moved maciivx and maciivi to their own driver. [R. Belmont]

This commit is contained in:
arbee 2022-07-17 22:33:22 -04:00
parent d01d1a0029
commit 6f2d0788c5
8 changed files with 1281 additions and 254 deletions

View File

@ -7,7 +7,6 @@
TODO: TODO:
- V8 and friends (LC, LC2, Classic 2, Color Classic) to own driver - V8 and friends (LC, LC2, Classic 2, Color Classic) to own driver
- IIvx / IIvi to own driver
****************************************************************************/ ****************************************************************************/
@ -461,25 +460,6 @@ void mac_state::maclc_map(address_map &map)
map(0xf40000, 0xfbffff).ram().share("vram"); map(0xf40000, 0xfbffff).ram().share("vram");
} }
void mac_state::maclc3_map(address_map &map)
{
map(0x40000000, 0x400fffff).rom().region("bootrom", 0).mirror(0x0ff00000);
map(0x50000000, 0x50001fff).rw(FUNC(mac_state::mac_via_r), FUNC(mac_state::mac_via_w)).mirror(0x00f00000);
map(0x50004000, 0x50005fff).rw(FUNC(mac_state::mac_scc_r), FUNC(mac_state::mac_scc_2_w)).mirror(0x00f00000);
map(0x50006000, 0x50007fff).rw(FUNC(mac_state::macii_scsi_drq_r), FUNC(mac_state::macii_scsi_drq_w)).mirror(0x00f00000);
map(0x50010000, 0x50011fff).rw(FUNC(mac_state::macplus_scsi_r), FUNC(mac_state::macii_scsi_w)).mirror(0x00f00000);
map(0x50012000, 0x50013fff).rw(FUNC(mac_state::macii_scsi_drq_r), FUNC(mac_state::macii_scsi_drq_w)).mirror(0x00f00000);
map(0x50014000, 0x50015fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000);
map(0x50016000, 0x50017fff).rw(FUNC(mac_state::mac_iwm_r), FUNC(mac_state::mac_iwm_w)).mirror(0x00f00000);
map(0x50024000, 0x50025fff).w(FUNC(mac_state::ariel_ramdac_w)).mirror(0x00f00000);
map(0x50026000, 0x50027fff).rw(FUNC(mac_state::mac_rbv_r), FUNC(mac_state::mac_rbv_w)).mirror(0x00f00000);
map(0x5ffffffc, 0x5fffffff).r(FUNC(mac_state::mac_read_id));
map(0x60000000, 0x600fffff).ram().mirror(0x0ff00000).share("vram");
}
void mac_state::macii_map(address_map &map) void mac_state::macii_map(address_map &map)
{ {
map(0x40000000, 0x4003ffff).rom().region("bootrom", 0).mirror(0x0ffc0000); map(0x40000000, 0x4003ffff).rom().region("bootrom", 0).mirror(0x0ffc0000);
@ -908,33 +888,6 @@ void mac_state::maccclas(machine_config &config)
m_via1->writepb_handler().set(FUNC(mac_state::mac_via_out_b_cdadb)); m_via1->writepb_handler().set(FUNC(mac_state::mac_via_out_b_cdadb));
} }
void mac_state::maciivx(machine_config &config)
{
maclc(config, false, true, asc_device::asc_type::VASP);
M68030(config, m_maincpu, C32M);
m_maincpu->set_addrmap(AS_PROGRAM, &mac_state::maclc3_map);
m_maincpu->set_dasm_override(FUNC(mac_state::mac_dasm_override));
MCFG_VIDEO_START_OVERRIDE(mac_state,macv8)
MCFG_VIDEO_RESET_OVERRIDE(mac_state,macrbv)
m_screen->set_screen_update(FUNC(mac_state::screen_update_macrbvvram));
add_nubus(config, false);
m_ram->set_default_size("4M");
m_ram->set_extra_options("8M,12M,16M,20M,24M,28M,32M,36M,40M,44M,48M,52M,56M,60M,64M");
m_egret->set_type(EGRET_341S0851);
}
void mac_state::maciivi(machine_config &config)
{
maciivx(config);
m_maincpu->set_clock(C15M);
}
void mac_state::maciix(machine_config &config, bool nubus_bank1, bool nubus_bank2) void mac_state::maciix(machine_config &config, bool nubus_bank1, bool nubus_bank2)
{ {
macii(config, false, asc_device::asc_type::ASC, true, nubus_bank1, nubus_bank2); macii(config, false, asc_device::asc_type::ASC, true, nubus_bank1, nubus_bank2);
@ -1161,16 +1114,6 @@ ROM_START( maciisi )
ROM_LOAD( "36b7fb6c.rom", 0x000000, 0x080000, CRC(f304d973) SHA1(f923de4125aae810796527ff6e25364cf1d54eec) ) ROM_LOAD( "36b7fb6c.rom", 0x000000, 0x080000, CRC(f304d973) SHA1(f923de4125aae810796527ff6e25364cf1d54eec) )
ROM_END ROM_END
ROM_START( maciivx )
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD( "4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40) )
ROM_END
ROM_START( maciivi )
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD( "4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40) )
ROM_END
ROM_START( macclas2 ) ROM_START( macclas2 )
ROM_REGION32_BE(0x100000, "bootrom", 0) // 3193670e ROM_REGION32_BE(0x100000, "bootrom", 0) // 3193670e
//ROM_LOAD( "3193670e.rom", 0x000000, 0x080000, CRC(96d2e1fd) SHA1(50df69c1b6e805e12a405dc610bc2a1471b2eac2) ) //ROM_LOAD( "3193670e.rom", 0x000000, 0x080000, CRC(96d2e1fd) SHA1(50df69c1b6e805e12a405dc610bc2a1471b2eac2) )
@ -1208,5 +1151,3 @@ COMP( 1990, maciisi, 0, 0, maciisi, maciici, mac_state, init_maci
COMP( 1991, macclas2, 0, 0, macclas2, macadb, mac_state, init_macclassic2, "Apple Computer", "Macintosh Classic II", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND ) COMP( 1991, macclas2, 0, 0, macclas2, macadb, mac_state, init_macclassic2, "Apple Computer", "Macintosh Classic II", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND )
COMP( 1991, maclc2, 0, 0, maclc2, maciici, mac_state, init_maclc2, "Apple Computer", "Macintosh LC II", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND ) COMP( 1991, maclc2, 0, 0, maclc2, maciici, mac_state, init_maclc2, "Apple Computer", "Macintosh LC II", MACHINE_NOT_WORKING|MACHINE_IMPERFECT_SOUND )
COMP( 1993, maccclas, 0, 0, maccclas, macadb, mac_state, init_maclrcclassic, "Apple Computer", "Macintosh Color Classic", MACHINE_NOT_WORKING ) COMP( 1993, maccclas, 0, 0, maccclas, macadb, mac_state, init_maclrcclassic, "Apple Computer", "Macintosh Color Classic", MACHINE_NOT_WORKING )
COMP( 1993, maciivx, 0, 0, maciivx, maciici, mac_state, init_maciivx, "Apple Computer", "Macintosh IIvx", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND )
COMP( 1993, maciivi, maciivx, 0, maciivi, maciici, mac_state, init_maciivi, "Apple Computer", "Macintosh IIvi", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND )

View File

@ -2,9 +2,9 @@
// copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont
/***************************************************************************** /*****************************************************************************
* *
* includes/mac.h * mac.h
* *
* Macintosh driver declarations * Macintosh II driver declarations
* *
****************************************************************************/ ****************************************************************************/
#ifndef MAME_INCLUDES_MAC_H #ifndef MAME_INCLUDES_MAC_H
@ -93,14 +93,10 @@ public:
void maclc(machine_config &config, bool cpu = true, bool egret = true, asc_device::asc_type asc_type = asc_device::asc_type::V8, int woz_version = 1); void maclc(machine_config &config, bool cpu = true, bool egret = true, asc_device::asc_type asc_type = asc_device::asc_type::V8, int woz_version = 1);
void maciisi(machine_config &config); void maciisi(machine_config &config);
void maclc2(machine_config &config, bool egret = true, int woz_version = 1); void maclc2(machine_config &config, bool egret = true, int woz_version = 1);
void maclc3(machine_config &config, bool egret = true);
void macpd210(machine_config &config); void macpd210(machine_config &config);
void maciici(machine_config &config); void maciici(machine_config &config);
void maciix(machine_config &config, bool nubus_bank1 = true, bool nubus_bank2 = true); void maciix(machine_config &config, bool nubus_bank1 = true, bool nubus_bank2 = true);
void maclc520(machine_config &config);
void maciivx(machine_config &config);
void maccclas(machine_config &config); void maccclas(machine_config &config);
void maciivi(machine_config &config);
void maciicx(machine_config &config); void maciicx(machine_config &config);
void macse30(machine_config &config); void macse30(machine_config &config);
void maciifx(machine_config &config); void maciifx(machine_config &config);
@ -113,20 +109,15 @@ public:
void init_maclc2(); void init_maclc2();
void init_maciifdhd(); void init_maciifdhd();
void init_macse30(); void init_macse30();
void init_maciivx();
void init_maciivi();
void init_macii(); void init_macii();
void init_macclassic2(); void init_macclassic2();
void init_maciifx(); void init_maciifx();
void init_maclc(); void init_maclc();
void init_maclc520();
void init_maciici(); void init_maciici();
void init_maciix(); void init_maciix();
void init_maclrcclassic(); void init_maclrcclassic();
void init_maciisi(); void init_maciisi();
void init_maciicx(); void init_maciicx();
void init_maclc3();
void init_maclc3plus();
/* tells which model is being emulated (set by macxxx_init) */ /* tells which model is being emulated (set by macxxx_init) */
enum model_t enum model_t

View File

@ -2,7 +2,7 @@
// copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont
/**************************************************************************** /****************************************************************************
machine/mac.c mac_m.cpp
Mac II series hardware Mac II series hardware
@ -20,10 +20,8 @@
- Mac IIcx 030 SWIM MacII ADB ext NuBus card - Mac IIcx 030 SWIM MacII ADB ext NuBus card
- Mac IIci 030 SWIM MacII ADB ext Internal "RBV" type - Mac IIci 030 SWIM MacII ADB ext Internal "RBV" type
- Mac IIsi 030 SWIM Egret ADB n/a Internal "RBV" type - Mac IIsi 030 SWIM Egret ADB n/a Internal "RBV" type
- Mac IIvx/IIvi 030 SWIM Egret ADB n/a Internal "VASP" type
- Mac LC 020 SWIM Egret ADB n/a Internal "V8" type - Mac LC 020 SWIM Egret ADB n/a Internal "V8" type
- Mac LC II 030 SWIM Egret ADB n/a Internal "V8" type - Mac LC II 030 SWIM Egret ADB n/a Internal "V8" type
- Mac LC III 030 SWIM Egret ADB n/a Internal "Sonora" type
- Mac Classic II 030 SWIM Egret ADB n/a Internal "Eagle" type (V8 clone) - Mac Classic II 030 SWIM Egret ADB n/a Internal "Eagle" type (V8 clone)
- Mac Color Classic 030 SWIM Cuda ADB n/a Internal "Spice" type (V8 clone) - Mac Color Classic 030 SWIM Cuda ADB n/a Internal "Spice" type (V8 clone)
@ -320,7 +318,7 @@ void mac_state::set_memory_overlay(int overlay)
} }
/* install the memory */ /* install the memory */
if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC) && ((m_model != MODEL_MAC_LC_III) && (m_model != MODEL_MAC_LC_III_PLUS))) || (m_model == MODEL_MAC_CLASSIC_II)) if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC)) || (m_model == MODEL_MAC_CLASSIC_II))
{ {
m_overlay = overlay; m_overlay = overlay;
v8_resize(); v8_resize();
@ -345,24 +343,10 @@ void mac_state::set_memory_overlay(int overlay)
space.unmap_write(0x000000, 0x9fffff); space.unmap_write(0x000000, 0x9fffff);
mac_install_memory(0x000000, memory_size-1, memory_size, memory_data, is_rom); mac_install_memory(0x000000, memory_size-1, memory_size, memory_data, is_rom);
} }
else if ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30) && (m_model != MODEL_MAC_IIVX) && (m_model != MODEL_MAC_IIVI)) else if ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30))
{ {
mac_install_memory(0x00000000, 0x3fffffff, memory_size, memory_data, is_rom); mac_install_memory(0x00000000, 0x3fffffff, memory_size, memory_data, is_rom);
} }
else if ((m_model == MODEL_MAC_IIVX) || (m_model == MODEL_MAC_IIVI) || (m_model == MODEL_MAC_LC_III) || (m_model == MODEL_MAC_LC_III_PLUS) || (m_model >= MODEL_MAC_LC_475 && m_model <= MODEL_MAC_LC_580)) // up to 36 MB
{
mac_install_memory(0x00000000, memory_size-1, memory_size, memory_data, is_rom);
if (is_rom)
{
m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000000, 0x4fffffff, read32sm_delegate(*this, FUNC(mac_state::rom_switch_r)), 0xffffffff);
}
else
{
size_t rom_mirror = 0xfffffff ^ (m_rom_size - 1);
m_maincpu->space(AS_PROGRAM).install_rom(0x40000000, 0x4fffffff & ~rom_mirror, rom_mirror, m_rom_ptr);
}
}
else else
{ {
mac_install_memory(0x00000000, 0x003fffff, memory_size, memory_data, is_rom); mac_install_memory(0x00000000, 0x003fffff, memory_size, memory_data, is_rom);
@ -672,8 +656,6 @@ uint8_t mac_state::mac_via_in_a()
case MODEL_MAC_LC: case MODEL_MAC_LC:
case MODEL_MAC_LC_II: case MODEL_MAC_LC_II:
case MODEL_MAC_IIVX:
case MODEL_MAC_IIVI:
return 0x81 | PA6 | PA4 | PA2; return 0x81 | PA6 | PA4 | PA2;
case MODEL_MAC_IICI: case MODEL_MAC_IICI:
@ -1064,15 +1046,7 @@ void mac_state::machine_reset()
if (m_overlay_timeout != (emu_timer *)nullptr) if (m_overlay_timeout != (emu_timer *)nullptr)
{ {
if ((m_model == MODEL_MAC_LC_III) || (m_model == MODEL_MAC_LC_III_PLUS) || (m_model >= MODEL_MAC_LC_475 && m_model <= MODEL_MAC_LC_580)) // up to 36 MB if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC)) || (m_model == MODEL_MAC_CLASSIC_II))
{
m_overlay_timeout->adjust(attotime::never);
}
else if (((m_model >= MODEL_MAC_LC) && (m_model <= MODEL_MAC_COLOR_CLASSIC) && ((m_model != MODEL_MAC_LC_III) && (m_model != MODEL_MAC_LC_III_PLUS))) || (m_model == MODEL_MAC_CLASSIC_II))
{
m_overlay_timeout->adjust(attotime::never);
}
else if ((m_model >= MODEL_MAC_IIVX) && (m_model <= MODEL_MAC_IIVI))
{ {
m_overlay_timeout->adjust(attotime::never); m_overlay_timeout->adjust(attotime::never);
} }
@ -1138,18 +1112,9 @@ uint32_t mac_state::mac_read_id()
switch (m_model) switch (m_model)
{ {
case MODEL_MAC_LC_III:
return 0xa55a0001; // 25 MHz LC III
case MODEL_MAC_LC_III_PLUS:
return 0xa55a0003; // 33 MHz LC III+
case MODEL_MAC_LC_475: case MODEL_MAC_LC_475:
return 0xa55a2221; return 0xa55a2221;
case MODEL_MAC_LC_520:
return 0xa55a0100;
case MODEL_MAC_LC_550: case MODEL_MAC_LC_550:
return 0xa55a0101; return 0xa55a0101;
@ -1177,9 +1142,6 @@ uint32_t mac_state::mac_read_id()
case MODEL_MAC_QUADRA_840AV: case MODEL_MAC_QUADRA_840AV:
return 0xa55a2830; return 0xa55a2830;
case MODEL_MAC_IIVX:
return 0xa55a2015;
default: default:
return 0; return 0;
} }
@ -1202,8 +1164,8 @@ void mac_state::mac_driver_init(model_t model)
memset(m_ram->pointer(), 0, m_ram->size()); memset(m_ram->pointer(), 0, m_ram->size());
if ((model == MODEL_MAC_CLASSIC_II) || (model == MODEL_MAC_LC) || (model == MODEL_MAC_COLOR_CLASSIC) || (model >= MODEL_MAC_LC_475 && model <= MODEL_MAC_LC_580) || if ((model == MODEL_MAC_CLASSIC_II) || (model == MODEL_MAC_LC) || (model == MODEL_MAC_COLOR_CLASSIC) ||
(model == MODEL_MAC_LC_II) || (model == MODEL_MAC_LC_III) || (model == MODEL_MAC_LC_III_PLUS) || ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30))) (model == MODEL_MAC_LC_II) || ((m_model >= MODEL_MAC_II) && (m_model <= MODEL_MAC_SE30)))
{ {
m_overlay_timeout = timer_alloc(FUNC(mac_state::overlay_timeout_func), this); m_overlay_timeout = timer_alloc(FUNC(mac_state::overlay_timeout_func), this);
} }
@ -1224,21 +1186,16 @@ void mac_state::init_##label() \
MAC_DRIVER_INIT(maclc, MODEL_MAC_LC) MAC_DRIVER_INIT(maclc, MODEL_MAC_LC)
MAC_DRIVER_INIT(maclc2, MODEL_MAC_LC_II) MAC_DRIVER_INIT(maclc2, MODEL_MAC_LC_II)
MAC_DRIVER_INIT(maclc3, MODEL_MAC_LC_III)
MAC_DRIVER_INIT(maclc3plus, MODEL_MAC_LC_III_PLUS)
MAC_DRIVER_INIT(maciici, MODEL_MAC_IICI) MAC_DRIVER_INIT(maciici, MODEL_MAC_IICI)
MAC_DRIVER_INIT(maciisi, MODEL_MAC_IISI) MAC_DRIVER_INIT(maciisi, MODEL_MAC_IISI)
MAC_DRIVER_INIT(macii, MODEL_MAC_II) MAC_DRIVER_INIT(macii, MODEL_MAC_II)
MAC_DRIVER_INIT(macse30, MODEL_MAC_SE30) MAC_DRIVER_INIT(macse30, MODEL_MAC_SE30)
MAC_DRIVER_INIT(macclassic2, MODEL_MAC_CLASSIC_II) MAC_DRIVER_INIT(macclassic2, MODEL_MAC_CLASSIC_II)
MAC_DRIVER_INIT(maclrcclassic, MODEL_MAC_COLOR_CLASSIC) MAC_DRIVER_INIT(maclrcclassic, MODEL_MAC_COLOR_CLASSIC)
MAC_DRIVER_INIT(maciivx, MODEL_MAC_IIVX)
MAC_DRIVER_INIT(maciivi, MODEL_MAC_IIVI)
MAC_DRIVER_INIT(maciifx, MODEL_MAC_IIFX) MAC_DRIVER_INIT(maciifx, MODEL_MAC_IIFX)
MAC_DRIVER_INIT(maciicx, MODEL_MAC_IICX) MAC_DRIVER_INIT(maciicx, MODEL_MAC_IICX)
MAC_DRIVER_INIT(maciifdhd, MODEL_MAC_II_FDHD) MAC_DRIVER_INIT(maciifdhd, MODEL_MAC_II_FDHD)
MAC_DRIVER_INIT(maciix, MODEL_MAC_IIX) MAC_DRIVER_INIT(maciix, MODEL_MAC_IIX)
MAC_DRIVER_INIT(maclc520, MODEL_MAC_LC_520)
void mac_state::nubus_slot_interrupt(uint8_t slot, uint32_t state) void mac_state::nubus_slot_interrupt(uint8_t slot, uint32_t state)
{ {

View File

@ -2,16 +2,12 @@
// copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont // copyright-holders:Nathan Woods, Raphael Nabet, R. Belmont
/*************************************************************************** /***************************************************************************
video/mac.c video/mac.cpp
Macintosh video hardware Macintosh video hardware
Emulates the video hardware for compact Macintosh series (original Emulates the video hardware for systems with the
Macintosh (128k, 512k, 512ke), Macintosh Plus, Macintosh SE, Macintosh RBV, V8, and Eagle chips.
Classic)
Also emulates on-board video for systems with the
RBV, V8, Eagle, and DAFB chips.
---------------------------------------------------------------------- ----------------------------------------------------------------------
Monitor sense codes Monitor sense codes
@ -52,7 +48,6 @@ Apple color FPD 01 11 10 (FPD = Full Page Display)
***************************************************************************/ ***************************************************************************/
#include "emu.h" #include "emu.h"
#include "sound/asc.h" #include "sound/asc.h"
#include "mac.h" #include "mac.h"
@ -84,7 +79,7 @@ uint32_t mac_state::screen_update_macse30(screen_device &screen, bitmap_ind16 &b
return 0; return 0;
} }
// IIci/IIsi RAM-Based Video (RBV) and children: V8, Eagle, Spice, VASP // IIci/IIsi RAM-Based Video (RBV) and children: V8, Eagle, Spice
VIDEO_START_MEMBER(mac_state,macrbv) VIDEO_START_MEMBER(mac_state,macrbv)
{ {
@ -272,130 +267,6 @@ uint32_t mac_state::screen_update_macrbv(screen_device &screen, bitmap_rgb32 &bi
return 0; return 0;
} }
uint32_t mac_state::screen_update_macrbvvram(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int hres, vres;
switch (m_rbv_montype)
{
case 1: // 15" portrait display
hres = 640;
vres = 870;
break;
case 2: // 12" RGB
hres = 512;
vres = 384;
break;
case 6: // 13" RGB
default:
hres = 640;
vres = 480;
break;
}
switch (m_rbv_regs[0x10] & 7)
{
case 0: // 1bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target());
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x+=8)
{
uint8_t const pixels = vram8[(y * 2048) + (x / 8)];
*scanline++ = m_rbv_palette[0x7f|(pixels&0x80)];
*scanline++ = m_rbv_palette[0x7f|((pixels<<1)&0x80)];
*scanline++ = m_rbv_palette[0x7f|((pixels<<2)&0x80)];
*scanline++ = m_rbv_palette[0x7f|((pixels<<3)&0x80)];
*scanline++ = m_rbv_palette[0x7f|((pixels<<4)&0x80)];
*scanline++ = m_rbv_palette[0x7f|((pixels<<5)&0x80)];
*scanline++ = m_rbv_palette[0x7f|((pixels<<6)&0x80)];
*scanline++ = m_rbv_palette[0x7f|((pixels<<7)&0x80)];
}
}
}
break;
case 1: // 2bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target());
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres/4; x++)
{
uint8_t const pixels = vram8[(y * 2048) + x];
*scanline++ = m_rbv_palette[0x3f|(pixels&0xc0)];
*scanline++ = m_rbv_palette[0x3f|((pixels<<2)&0xc0)];
*scanline++ = m_rbv_palette[0x3f|((pixels<<4)&0xc0)];
*scanline++ = m_rbv_palette[0x3f|((pixels<<6)&0xc0)];
}
}
}
break;
case 2: // 4bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target());
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres/2; x++)
{
uint8_t const pixels = vram8[(y * 2048) + x];
*scanline++ = m_rbv_palette[0x0f|(pixels&0xf0)];
*scanline++ = m_rbv_palette[0x0f|((pixels<<4)&0xf0)];
}
}
}
break;
case 3: // 8bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(m_vram.target());
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x++)
{
uint8_t const pixels = vram8[(y * 2048) + x];
*scanline++ = m_rbv_palette[pixels];
}
}
}
break;
case 4: // 16bpp
{
auto const vram16 = util::big_endian_cast<uint16_t const>(m_vram.target());
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x++)
{
uint16_t const pixels = vram16[(y * 1024) + x];
*scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3);
}
}
}
break;
}
return 0;
}
uint32_t mac_state::screen_update_macv8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) uint32_t mac_state::screen_update_macv8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{ {
int hres, vres; int hres, vres;

401
src/mame/apple/maciivx.cpp Normal file
View File

@ -0,0 +1,401 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/****************************************************************************
maciivx.cpp
Mac IIvx
Mac IIvi
By R. Belmont
These 68030 machines were the last Mac IIs, and had development rushed
after then-CEO John Sculley told MacWorld Tokyo that Apple would soon
ship machines with a built-in CD-ROM drive.
They run on the "VASP" system ASIC, which is basically V8 with slightly
different video and the RAM size limit lifted to 68 MB.
****************************************************************************/
#include "emu.h"
#include "bus/nscsi/devices.h"
#include "bus/nubus/nubus.h"
#include "bus/nubus/cards.h"
#include "bus/rs232/rs232.h"
#include "cpu/m68000/m68000.h"
#include "machine/applefdintf.h"
#include "machine/ncr5380.h"
#include "machine/nscsi_bus.h"
#include "machine/ram.h"
#include "machine/swim1.h"
#include "machine/timer.h"
#include "machine/z80scc.h"
#include "cuda.h"
#include "egret.h"
#include "macadb.h"
#include "macscsi.h"
#include "vasp.h"
#include "emupal.h"
#include "screen.h"
#include "softlist_dev.h"
namespace {
#define C32M (31.3344_MHz_XTAL)
#define C15M (C32M/2)
#define C7M (C32M/4)
class maciivx_state : public driver_device
{
public:
maciivx_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_macadb(*this, "macadb"),
m_ram(*this, RAM_TAG),
m_vasp(*this, "vasp"),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
m_scsibus1(*this, "scsi"),
m_ncr5380(*this, "scsi:7:ncr5380"),
m_scsihelp(*this, "scsihelp"),
m_scc(*this, "scc"),
m_egret(*this, "egret"),
m_cur_floppy(nullptr),
m_hdsel(0)
{
}
void maciiv_base(machine_config &config);
void maciivx(machine_config &config);
void maciivi(machine_config &config);
void base_map(address_map &map);
void maciivx_map(address_map &map);
void maciivi_map(address_map &map);
private:
required_device<m68030_device> m_maincpu;
required_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
required_device<vasp_device> m_vasp;
required_device<applefdintf_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
required_device<nscsi_bus_device> m_scsibus1;
required_device<ncr5380_device> m_ncr5380;
required_device<mac_scsi_helper_device> m_scsihelp;
required_device<z80scc_device> m_scc;
required_device<egret_device> m_egret;
virtual void machine_start() override;
u16 scc_r(offs_t offset)
{
u16 result = m_scc->dc_ab_r(offset);
return (result << 8) | result;
}
void scc_w(offs_t offset, u16 data)
{
m_scc->dc_ab_w(offset, data >> 8);
}
u16 scsi_r(offs_t offset, u16 mem_mask = ~0);
void scsi_w(offs_t offset, u16 data, u16 mem_mask = ~0);
u32 scsi_drq_r(offs_t offset, u32 mem_mask = ~0);
void scsi_drq_w(offs_t offset, u32 data, u32 mem_mask = ~0);
void scsi_berr_w(u8 data)
{
m_maincpu->pulse_input_line(M68K_LINE_BUSERROR, attotime::zero);
}
WRITE_LINE_MEMBER(cuda_reset_w)
{
m_maincpu->set_input_line(INPUT_LINE_HALT, state);
m_maincpu->set_input_line(INPUT_LINE_RESET, state);
}
floppy_image_device *m_cur_floppy = nullptr;
int m_hdsel;
void phases_w(uint8_t phases);
void devsel_w(uint8_t devsel);
uint16_t swim_r(offs_t offset, u16 mem_mask);
void swim_w(offs_t offset, u16 data, u16 mem_mask);
WRITE_LINE_MEMBER(hdsel_w);
};
void maciivx_state::machine_start()
{
m_vasp->set_ram_info((u32 *) m_ram->pointer(), m_ram->size());
save_item(NAME(m_hdsel));
}
/***************************************************************************
ADDRESS MAPS
***************************************************************************/
void maciivx_state::base_map(address_map &map)
{
// RAM, ROM, and base I/O mappings come from VASP
map(0x40000000, 0x600fffff).m(m_vasp, FUNC(vasp_device::map));
map(0x50004000, 0x50005fff).rw(FUNC(maciivx_state::scc_r), FUNC(maciivx_state::scc_w)).mirror(0x00f00000);
map(0x50006000, 0x50007fff).rw(FUNC(maciivx_state::scsi_drq_r), FUNC(maciivx_state::scsi_drq_w)).mirror(0x00f00000);
map(0x50010000, 0x50011fff).rw(FUNC(maciivx_state::scsi_r), FUNC(maciivx_state::scsi_w)).mirror(0x00f00000);
map(0x50012000, 0x50013fff).rw(FUNC(maciivx_state::scsi_drq_r), FUNC(maciivx_state::scsi_drq_w)).mirror(0x00f00000);
map(0x50016000, 0x50017fff).rw(FUNC(maciivx_state::swim_r), FUNC(maciivx_state::swim_w)).mirror(0x00f00000);
}
void maciivx_state::maciivx_map(address_map &map)
{
base_map(map);
map(0x5ffffffc, 0x5fffffff).lr32(NAME([](offs_t offset) { return 0xa55a2015; }));
}
void maciivx_state::maciivi_map(address_map &map)
{
base_map(map);
map(0x5ffffffc, 0x5fffffff).lr32(NAME([](offs_t offset) { return 0xa55a2016; }));
}
u16 maciivx_state::scsi_r(offs_t offset, u16 mem_mask)
{
const int reg = (offset >> 3) & 0xf;
const bool pseudo_dma = (reg == 6) && (offset == 0x130);
return m_scsihelp->read_wrapper(pseudo_dma, reg) << 8;
}
void maciivx_state::scsi_w(offs_t offset, u16 data, u16 mem_mask)
{
const int reg = (offset >> 3) & 0xf;
const bool pseudo_dma = (reg == 0) && (offset == 0x100);
m_scsihelp->write_wrapper(pseudo_dma, reg, data >> 8);
}
u32 maciivx_state::scsi_drq_r(offs_t offset, u32 mem_mask)
{
switch (mem_mask)
{
case 0xff000000:
return m_scsihelp->read_wrapper(true, 6) << 24;
case 0xffff0000:
return (m_scsihelp->read_wrapper(true, 6) << 24) | (m_scsihelp->read_wrapper(true, 6) << 16);
case 0xffffffff:
return (m_scsihelp->read_wrapper(true, 6) << 24) | (m_scsihelp->read_wrapper(true, 6) << 16) | (m_scsihelp->read_wrapper(true, 6) << 8) | m_scsihelp->read_wrapper(true, 6);
default:
logerror("scsi_drq_r: unknown mem_mask %08x\n", mem_mask);
}
return 0;
}
void maciivx_state::scsi_drq_w(offs_t offset, u32 data, u32 mem_mask)
{
switch (mem_mask)
{
case 0xff000000:
m_scsihelp->write_wrapper(true, 0, data >> 24);
break;
case 0xffff0000:
m_scsihelp->write_wrapper(true, 0, data >> 24);
m_scsihelp->write_wrapper(true, 0, data >> 16);
break;
case 0xffffffff:
m_scsihelp->write_wrapper(true, 0, data >> 24);
m_scsihelp->write_wrapper(true, 0, data >> 16);
m_scsihelp->write_wrapper(true, 0, data >> 8);
m_scsihelp->write_wrapper(true, 0, data & 0xff);
break;
default:
logerror("scsi_drq_w: unknown mem_mask %08x\n", mem_mask);
break;
}
}
uint16_t maciivx_state::swim_r(offs_t offset, u16 mem_mask)
{
if (!machine().side_effects_disabled())
{
m_maincpu->adjust_icount(-5);
}
u16 result = m_fdc->read((offset >> 8) & 0xf);
return result << 8;
}
void maciivx_state::swim_w(offs_t offset, u16 data, u16 mem_mask)
{
if (ACCESSING_BITS_0_7)
m_fdc->write((offset >> 8) & 0xf, data & 0xff);
else
m_fdc->write((offset >> 8) & 0xf, data >> 8);
}
void maciivx_state::phases_w(uint8_t phases)
{
if (m_cur_floppy)
m_cur_floppy->seek_phase_w(phases);
}
void maciivx_state::devsel_w(uint8_t devsel)
{
if (devsel == 1)
m_cur_floppy = m_floppy[0]->get_device();
else if (devsel == 2)
m_cur_floppy = m_floppy[1]->get_device();
else
m_cur_floppy = nullptr;
m_fdc->set_floppy(m_cur_floppy);
if (m_cur_floppy)
m_cur_floppy->ss_w(m_hdsel);
}
WRITE_LINE_MEMBER(maciivx_state::hdsel_w)
{
if (state != m_hdsel)
{
if (m_cur_floppy)
{
m_cur_floppy->ss_w(state);
}
}
m_hdsel = state;
}
/***************************************************************************
DEVICE CONFIG
***************************************************************************/
static INPUT_PORTS_START( maciivx )
INPUT_PORTS_END
/***************************************************************************
MACHINE DRIVERS
***************************************************************************/
void maciivx_state::maciiv_base(machine_config &config)
{
RAM(config, m_ram);
m_ram->set_default_size("4M");
m_ram->set_extra_options("8M,16M,32M,36M,48M,64M,68M");
NSCSI_BUS(config, "scsi");
NSCSI_CONNECTOR(config, "scsi:0", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:1", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:2", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:3", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:4", mac_scsi_devices, "cdrom");
NSCSI_CONNECTOR(config, "scsi:5", mac_scsi_devices, nullptr);
NSCSI_CONNECTOR(config, "scsi:6", mac_scsi_devices, "harddisk");
NSCSI_CONNECTOR(config, "scsi:7").option_set("ncr5380", NCR53C80).machine_config([this](device_t *device)
{
ncr53c80_device &adapter = downcast<ncr53c80_device &>(*device);
adapter.drq_handler().set(m_scsihelp, FUNC(mac_scsi_helper_device::drq_w));
});
MAC_SCSI_HELPER(config, m_scsihelp);
m_scsihelp->scsi_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::read));
m_scsihelp->scsi_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::write));
m_scsihelp->scsi_dma_read_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_r));
m_scsihelp->scsi_dma_write_callback().set(m_ncr5380, FUNC(ncr53c80_device::dma_w));
m_scsihelp->cpu_halt_callback().set_inputline(m_maincpu, INPUT_LINE_HALT);
m_scsihelp->timeout_error_callback().set(FUNC(maciivx_state::scsi_berr_w));
SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd");
SOFTWARE_LIST(config, "flop35hd_list").set_original("mac_hdflop");
SCC85C30(config, m_scc, C7M);
m_scc->configure_channels(3'686'400, 3'686'400, 3'686'400, 3'686'400);
m_scc->out_int_callback().set(m_vasp, FUNC(vasp_device::scc_irq_w));
m_scc->out_txda_callback().set("printer", FUNC(rs232_port_device::write_txd));
m_scc->out_txdb_callback().set("modem", FUNC(rs232_port_device::write_txd));
rs232_port_device &rs232a(RS232_PORT(config, "printer", default_rs232_devices, nullptr));
rs232a.rxd_handler().set(m_scc, FUNC(z80scc_device::rxa_w));
rs232a.dcd_handler().set(m_scc, FUNC(z80scc_device::dcda_w));
rs232a.cts_handler().set(m_scc, FUNC(z80scc_device::ctsa_w));
rs232_port_device &rs232b(RS232_PORT(config, "modem", default_rs232_devices, nullptr));
rs232b.rxd_handler().set(m_scc, FUNC(z80scc_device::rxb_w));
rs232b.dcd_handler().set(m_scc, FUNC(z80scc_device::dcdb_w));
rs232b.cts_handler().set(m_scc, FUNC(z80scc_device::ctsb_w));
VASP(config, m_vasp, C15M);
m_vasp->set_maincpu_tag("maincpu");
m_vasp->set_rom_tag(":bootrom");
m_vasp->hdsel_callback().set(FUNC(maciivx_state::hdsel_w));
MACADB(config, m_macadb, C15M);
m_macadb->set_mcu_mode(true);
nubus_device &nubus(NUBUS(config, "nubus", 0));
nubus.set_space(m_maincpu, AS_PROGRAM);
nubus.out_irqc_callback().set(m_vasp, FUNC(vasp_device::slot0_irq_w));
nubus.out_irqd_callback().set(m_vasp, FUNC(vasp_device::slot1_irq_w));
nubus.out_irqe_callback().set(m_vasp, FUNC(vasp_device::slot2_irq_w));
NUBUS_SLOT(config, "nbc", "nubus", mac_nubus_cards, nullptr);
NUBUS_SLOT(config, "nbd", "nubus", mac_nubus_cards, nullptr);
NUBUS_SLOT(config, "nbe", "nubus", mac_nubus_cards, nullptr);
SWIM1(config, m_fdc, C15M);
m_fdc->devsel_cb().set(FUNC(maciivx_state::devsel_w));
m_fdc->phases_cb().set(FUNC(maciivx_state::phases_w));
applefdintf_device::add_35_hd(config, m_floppy[0]);
applefdintf_device::add_35_nc(config, m_floppy[1]);
}
void maciivx_state::maciivx(machine_config &config)
{
M68030(config, m_maincpu, C32M);
m_maincpu->set_addrmap(AS_PROGRAM, &maciivx_state::maciivx_map);
maciiv_base(config);
EGRET(config, m_egret, EGRET_341S0851);
m_egret->reset_callback().set(FUNC(maciivx_state::cuda_reset_w));
m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_egret->via_clock_callback().set(m_vasp, FUNC(vasp_device::cb1_w));
m_egret->via_data_callback().set(m_vasp, FUNC(vasp_device::cb2_w));
m_macadb->adb_data_callback().set(m_egret, FUNC(egret_device::set_adb_line));
config.set_perfect_quantum(m_maincpu);
m_vasp->pb3_callback().set(m_egret, FUNC(egret_device::get_xcvr_session));
m_vasp->pb4_callback().set(m_egret, FUNC(egret_device::set_via_full));
m_vasp->pb5_callback().set(m_egret, FUNC(egret_device::set_sys_session));
m_vasp->cb2_callback().set(m_egret, FUNC(egret_device::set_via_data));
}
void maciivx_state::maciivi(machine_config &config)
{
maciivx(config);
M68030(config.replace(), m_maincpu, C15M);
m_maincpu->set_addrmap(AS_PROGRAM, &maciivx_state::maciivi_map);
}
ROM_START(maciivx)
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD("4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40))
ROM_END
ROM_START(maciivi)
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD("4957eb49.rom", 0x000000, 0x100000, CRC(61be06e5) SHA1(560ce203d65178657ad09d03f532f86fa512bb40))
ROM_END
} // anonymous namespace
COMP(1993, maciivx, 0, 0, maciivx, maciivx, maciivx_state, empty_init, "Apple Computer", "Macintosh IIvx", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND)
COMP(1993, maciivi, maciivx, 0, maciivi, maciivx, maciivx_state, empty_init, "Apple Computer", "Macintosh IIvi", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND)

756
src/mame/apple/vasp.cpp Normal file
View File

@ -0,0 +1,756 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/*
Apple "VASP Integrated Controller" system ASIC
Emulation by R. Belmont
VASP contains the following:
- A memory controller for up to 68 MB (4 MB on the motherboard + one 64 MB SIMM)
- A VRAM controller and framebuffer controller, supporting monitor ID selection
- A full VIA (VIA1) and a "pseudo-VIA", which is basically a combination GPIO and
interrupt controller that looks somewhat like a VIA with no timers and no shift register
- An ASC-like 4-channel audio controller
- Support logic for various external subsystems (ADB, FDC, NuBus, SCC, SCSI)
*/
#include "emu.h"
#include "vasp.h"
#include "formats/ap_dsk35.h"
#include "layout/generic.h"
static constexpr u32 C7M = 7833600;
static constexpr u32 C15M = (C7M * 2);
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(VASP, vasp_device, "vasp", "Apple VASP system ASIC")
static INPUT_PORTS_START( vasp )
PORT_START("MONTYPE")
PORT_CONFNAME(0x0f, 0x06, "Connected monitor")
PORT_CONFSETTING( 0x01, "15\" Portrait Display (640x870)")
PORT_CONFSETTING( 0x02, "12\" RGB (512x384)")
PORT_CONFSETTING( 0x06, "13\" RGB (640x480)")
INPUT_PORTS_END
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
ioport_constructor vasp_device::device_input_ports() const
{
return INPUT_PORTS_NAME( vasp );
}
//-------------------------------------------------
// ADDRESS_MAP
//-------------------------------------------------
void vasp_device::map(address_map &map)
{
map(0x00000000, 0x000fffff).r(FUNC(vasp_device::rom_switch_r)).mirror(0x0ff00000);
map(0x10000000, 0x10001fff).rw(FUNC(vasp_device::mac_via_r), FUNC(vasp_device::mac_via_w)).mirror(0x00f00000);
map(0x10014000, 0x10015fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000);
map(0x10024000, 0x10025fff).rw(FUNC(vasp_device::dac_r), FUNC(vasp_device::dac_w)).mirror(0x00f00000);
map(0x10026000, 0x10027fff).rw(FUNC(vasp_device::pseudovia_r), FUNC(vasp_device::pseudovia_w)).mirror(0x00f00000);
map(0x20000000, 0x200fffff).ram().mirror(0x0ff00000).rw(FUNC(vasp_device::vram_r), FUNC(vasp_device::vram_w));
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void vasp_device::device_add_mconfig(machine_config &config)
{
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_raw(25175000, 800, 0, 640, 525, 0, 480);
m_screen->set_size(1024, 768);
m_screen->set_visarea(0, 640 - 1, 0, 480 - 1);
m_screen->set_screen_update(FUNC(vasp_device::screen_update));
m_screen->screen_vblank().set(FUNC(vasp_device::vbl_w));
config.set_default_layout(layout_monitors);
PALETTE(config, m_palette).set_entries(256);
R65NC22(config, m_via1, C7M / 10);
m_via1->readpa_handler().set(FUNC(vasp_device::via_in_a));
m_via1->readpb_handler().set(FUNC(vasp_device::via_in_b));
m_via1->writepa_handler().set(FUNC(vasp_device::via_out_a));
m_via1->writepb_handler().set(FUNC(vasp_device::via_out_b));
m_via1->cb2_handler().set(FUNC(vasp_device::via_out_cb2));
m_via1->irq_handler().set(FUNC(vasp_device::via1_irq));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
ASC(config, m_asc, C15M, asc_device::asc_type::VASP);
m_asc->add_route(0, "lspeaker", 1.0);
m_asc->add_route(1, "rspeaker", 1.0);
}
//-------------------------------------------------
// vasp_device - constructor
//-------------------------------------------------
vasp_device::vasp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, VASP, tag, owner, clock),
write_pb4(*this),
write_pb5(*this),
write_cb2(*this),
write_hdsel(*this),
read_pb3(*this),
m_maincpu(*this, finder_base::DUMMY_TAG),
m_montype(*this, "MONTYPE"),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_via1(*this, "via1"),
m_asc(*this, "asc"),
m_rom(*this, finder_base::DUMMY_TAG),
m_overlay(false)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void vasp_device::device_start()
{
m_vram = std::make_unique<u32[]>(0x100000 / sizeof(u32));
write_pb4.resolve_safe();
write_pb5.resolve_safe();
write_cb2.resolve_safe();
write_hdsel.resolve_safe();
read_pb3.resolve_safe(0);
m_6015_timer = timer_alloc(FUNC(vasp_device::mac_6015_tick), this);
m_6015_timer->adjust(attotime::never);
save_pointer(NAME(m_vram), 0x100000/sizeof(u32));
save_item(NAME(m_via_interrupt));
save_item(NAME(m_via2_interrupt));
save_item(NAME(m_scc_interrupt));
save_item(NAME(m_last_taken_interrupt));
save_item(NAME(m_pseudovia_regs));
save_item(NAME(m_pseudovia_ier));
save_item(NAME(m_pseudovia_ifr));
save_item(NAME(m_pal_address));
save_item(NAME(m_pal_idx));
save_item(NAME(m_pal_control));
save_item(NAME(m_pal_colkey));
save_item(NAME(m_overlay));
m_rom_ptr = &m_rom[0];
m_rom_size = m_rom.length() << 2;
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void vasp_device::device_reset()
{
// start 60.15 Hz timer
m_6015_timer->adjust(attotime::from_hz(60.15), 0, attotime::from_hz(60.15));
std::fill_n(m_pseudovia_regs, 256, 0);
m_pseudovia_regs[0] = 0x4f;
m_pseudovia_regs[1] = 0x06;
m_pseudovia_regs[2] = 0x7f;
m_pseudovia_regs[3] = 0;
m_via_interrupt = m_via2_interrupt = m_scc_interrupt = 0;
m_last_taken_interrupt = -1;
// main cpu shouldn't start until Egret wakes it up
m_maincpu->set_input_line(INPUT_LINE_HALT, ASSERT_LINE);
m_overlay = true;
// put ROM mirror at 0
address_space &space = m_maincpu->space(AS_PROGRAM);
const u32 memory_size = std::min((u32)0x3fffff, m_rom_size);
const u32 memory_end = memory_size - 1;
offs_t memory_mirror = memory_end & ~(memory_size - 1);
space.unmap_write(0x00000000, memory_end);
space.install_rom(0x00000000, memory_end & ~memory_mirror, memory_mirror, m_rom_ptr);
}
u32 vasp_device::rom_switch_r(offs_t offset)
{
// disable the overlay
if (m_overlay)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
const u32 memory_end = m_ram_size - 1;
void *memory_data = m_ram_ptr;
offs_t memory_mirror = memory_end & ~memory_end;
space.install_ram(0x00000000, memory_end & ~memory_mirror, memory_mirror, memory_data);
m_overlay = false;
}
return m_rom_ptr[offset & ((m_rom_size - 1) >> 2)];
}
void vasp_device::set_ram_info(u32 *ram, u32 size)
{
m_ram_ptr = ram;
m_ram_size = size;
}
TIMER_CALLBACK_MEMBER(vasp_device::mac_6015_tick)
{
m_via1->write_ca1(CLEAR_LINE);
m_via1->write_ca1(ASSERT_LINE);
}
uint8_t vasp_device::via_in_a()
{
return 0xd5;
}
uint8_t vasp_device::via_in_b()
{
return read_pb3() << 3;
}
WRITE_LINE_MEMBER(vasp_device::via_out_cb2)
{
write_cb2(state & 1);
}
void vasp_device::via_out_a(uint8_t data)
{
write_hdsel(BIT(data, 5));
}
void vasp_device::via_out_b(uint8_t data)
{
write_pb4(BIT(data, 4));
write_pb5(BIT(data, 5));
}
WRITE_LINE_MEMBER(vasp_device::via1_irq)
{
m_via_interrupt = state;
field_interrupts();
}
WRITE_LINE_MEMBER(vasp_device::via2_irq)
{
m_via2_interrupt = state;
field_interrupts();
}
void vasp_device::field_interrupts()
{
int take_interrupt = -1;
if (m_scc_interrupt)
{
take_interrupt = 4;
}
else if (m_via2_interrupt)
{
take_interrupt = 2;
}
else if (m_via_interrupt)
{
take_interrupt = 1;
}
if (m_last_taken_interrupt > -1)
{
m_maincpu->set_input_line(m_last_taken_interrupt, CLEAR_LINE);
m_last_taken_interrupt = -1;
}
if (take_interrupt > -1)
{
m_maincpu->set_input_line(take_interrupt, ASSERT_LINE);
m_last_taken_interrupt = take_interrupt;
}
}
WRITE_LINE_MEMBER(vasp_device::scc_irq_w)
{
m_scc_interrupt = (state == ASSERT_LINE);
field_interrupts();
}
WRITE_LINE_MEMBER(vasp_device::vbl_w)
{
if (!state)
{
return;
}
m_pseudovia_regs[2] &= ~0x40; // set vblank signal
if (m_pseudovia_regs[0x12] & 0x40)
{
pseudovia_recalc_irqs();
}
}
WRITE_LINE_MEMBER(vasp_device::slot0_irq_w)
{
if (state)
{
m_pseudovia_regs[2] &= ~0x08;
}
else
{
m_pseudovia_regs[2] |= 0x08;
}
pseudovia_recalc_irqs();
}
WRITE_LINE_MEMBER(vasp_device::slot1_irq_w)
{
if (state)
{
m_pseudovia_regs[2] &= ~0x10;
}
else
{
m_pseudovia_regs[2] |= 0x10;
}
pseudovia_recalc_irqs();
}
WRITE_LINE_MEMBER(vasp_device::slot2_irq_w)
{
if (state)
{
m_pseudovia_regs[2] &= ~0x20;
}
else
{
m_pseudovia_regs[2] |= 0x20;
}
pseudovia_recalc_irqs();
}
void vasp_device::pseudovia_recalc_irqs()
{
// check slot interrupts and bubble them down to IFR
uint8_t slot_irqs = (~m_pseudovia_regs[2]) & 0x78;
slot_irqs &= (m_pseudovia_regs[0x12] & 0x78);
if (slot_irqs)
{
m_pseudovia_regs[3] |= 2; // any slot
}
else // no slot irqs, clear the pending bit
{
m_pseudovia_regs[3] &= ~2; // any slot
}
uint8_t ifr = (m_pseudovia_regs[3] & m_pseudovia_ier) & 0x1b;
if (ifr != 0)
{
m_pseudovia_regs[3] = ifr | 0x80;
m_pseudovia_ifr = ifr | 0x80;
via2_irq(ASSERT_LINE);
}
else
{
via2_irq(CLEAR_LINE);
}
}
uint8_t vasp_device::pseudovia_r(offs_t offset)
{
int data = 0;
if (offset < 0x100)
{
data = m_pseudovia_regs[offset];
if (offset == 0x10)
{
data &= ~0x38;
data |= (m_montype->read() << 3);
}
// bit 7 of these registers always reads as 0 on pseudo-VIAs
if ((offset == 0x12) || (offset == 0x13))
{
data &= ~0x80;
}
}
else
{
offset >>= 9;
switch (offset)
{
case 13: // IFR
data = m_pseudovia_ifr;
break;
case 14: // IER
data = m_pseudovia_ier;
break;
default:
logerror("pseudovia_r: Unknown pseudo-VIA register %d access\n", offset);
break;
}
}
return data;
}
void vasp_device::pseudovia_w(offs_t offset, uint8_t data)
{
if (offset < 0x100)
{
switch (offset)
{
case 0x02:
m_pseudovia_regs[offset] |= (data & 0x40);
pseudovia_recalc_irqs();
break;
case 0x03: // write here to ack
if (data & 0x80) // 1 bits write 1s
{
m_pseudovia_regs[offset] |= data & 0x7f;
m_pseudovia_ifr |= data & 0x7f;
}
else // 1 bits write 0s
{
m_pseudovia_regs[offset] &= ~(data & 0x7f);
m_pseudovia_ifr &= ~(data & 0x7f);
}
pseudovia_recalc_irqs();
break;
case 0x10:
m_pseudovia_regs[offset] = data;
break;
case 0x12:
if (data & 0x80) // 1 bits write 1s
{
m_pseudovia_regs[offset] |= data & 0x7f;
}
else // 1 bits write 0s
{
m_pseudovia_regs[offset] &= ~(data & 0x7f);
}
pseudovia_recalc_irqs();
break;
case 0x13:
if (data & 0x80) // 1 bits write 1s
{
m_pseudovia_regs[offset] |= data & 0x7f;
if (data == 0xff)
m_pseudovia_regs[offset] = 0x1f; // I don't know why this is special, but the IIci ROM's POST demands it
}
else // 1 bits write 0s
{
m_pseudovia_regs[offset] &= ~(data & 0x7f);
}
break;
default:
m_pseudovia_regs[offset] = data;
break;
}
}
else
{
offset >>= 9;
switch (offset)
{
case 13: // IFR
if (data & 0x80)
{
data = 0x7f;
}
pseudovia_recalc_irqs();
break;
case 14: // IER
if (data & 0x80) // 1 bits write 1s
{
m_pseudovia_ier |= data & 0x7f;
}
else // 1 bits write 0s
{
m_pseudovia_ier &= ~(data & 0x7f);
}
pseudovia_recalc_irqs();
break;
default:
logerror("pseudovia_w: Unknown extended pseudo-VIA register %d access\n", offset);
break;
}
}
}
WRITE_LINE_MEMBER(vasp_device::cb1_w)
{
m_via1->write_cb1(state);
}
WRITE_LINE_MEMBER(vasp_device::cb2_w)
{
m_via1->write_cb2(state);
}
uint16_t vasp_device::mac_via_r(offs_t offset)
{
uint16_t data;
offset >>= 8;
offset &= 0x0f;
if (!machine().side_effects_disabled())
via_sync();
data = m_via1->read(offset);
return (data & 0xff) | (data << 8);
}
void vasp_device::mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask)
{
offset >>= 8;
offset &= 0x0f;
via_sync();
if (ACCESSING_BITS_0_7)
m_via1->write(offset, data & 0xff);
if (ACCESSING_BITS_8_15)
m_via1->write(offset, (data >> 8) & 0xff);
}
void vasp_device::via_sync()
{
// The via runs at 783.36KHz while the main cpu runs at 15MHz or
// more, so we need to sync the access with the via clock. Plus
// the whole access takes half a (via) cycle and ends when synced
// with the main cpu again.
// Get the main cpu time
u64 cycle = m_maincpu->total_cycles();
// Get the number of the cycle the via is in at that time
u64 via_cycle = cycle * m_via1->clock() / m_maincpu->clock();
// The access is going to start at via_cycle+1 and end at
// via_cycle+1.5, compute what that means in maincpu cycles (the
// +1 rounds up, since the clocks are too different to ever be
// synced).
u64 main_cycle = (via_cycle * 2 + 3) * m_maincpu->clock() / (2 * m_via1->clock()) + 1;
// Finally adjust the main cpu icount as needed.
m_maincpu->adjust_icount(-int(main_cycle - cycle));
}
u32 vasp_device::vram_r(offs_t offset)
{
return m_vram[offset];
}
void vasp_device::vram_w(offs_t offset, u32 data, u32 mem_mask)
{
COMBINE_DATA(&m_vram[offset]);
}
u8 vasp_device::dac_r(offs_t offset)
{
switch (offset)
{
case 2:
return m_pal_control;
default:
return 0;
}
}
void vasp_device::dac_w(offs_t offset, u8 data)
{
switch (offset)
{
case 0:
m_pal_address = data;
m_pal_idx = 0;
break;
case 1:
switch (m_pal_idx)
{
case 0:
m_palette->set_pen_red_level(m_pal_address, data);
break;
case 1:
m_palette->set_pen_green_level(m_pal_address, data);
break;
case 2:
m_palette->set_pen_blue_level(m_pal_address, data);
break;
}
m_pal_idx++;
if (m_pal_idx == 3)
{
m_pal_idx = 0;
m_pal_address++;
}
break;
case 2:
m_pal_control = data;
break;
case 3:
m_pal_colkey = data;
break;
}
}
u32 vasp_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int hres, vres;
switch (m_montype->read())
{
case 1: // 15" portrait display
hres = 640;
vres = 870;
break;
case 2: // 12" RGB
hres = 512;
vres = 384;
break;
case 6: // 13" RGB
default:
hres = 640;
vres = 480;
break;
}
const pen_t *pens = m_palette->pens();
switch (m_pseudovia_regs[0x10] & 7)
{
case 0: // 1bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x += 8)
{
uint8_t const pixels = vram8[(y * 2048) + (x / 8)];
*scanline++ = pens[0x7f | (pixels & 0x80)];
*scanline++ = pens[0x7f | ((pixels << 1) & 0x80)];
*scanline++ = pens[0x7f | ((pixels << 2) & 0x80)];
*scanline++ = pens[0x7f | ((pixels << 3) & 0x80)];
*scanline++ = pens[0x7f | ((pixels << 4) & 0x80)];
*scanline++ = pens[0x7f | ((pixels << 5) & 0x80)];
*scanline++ = pens[0x7f | ((pixels << 6) & 0x80)];
*scanline++ = pens[0x7f | ((pixels << 7) & 0x80)];
}
}
}
break;
case 1: // 2bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres / 4; x++)
{
uint8_t const pixels = vram8[(y * 2048) + x];
*scanline++ = pens[0x3f | (pixels & 0xc0)];
*scanline++ = pens[0x3f | ((pixels << 2) & 0xc0)];
*scanline++ = pens[0x3f | ((pixels << 4) & 0xc0)];
*scanline++ = pens[0x3f | ((pixels << 6) & 0xc0)];
}
}
}
break;
case 2: // 4bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres / 2; x++)
{
uint8_t const pixels = vram8[(y * 2048) + x];
*scanline++ = pens[0x0f | (pixels & 0xf0)];
*scanline++ = pens[0x0f | ((pixels << 4) & 0xf0)];
}
}
}
break;
case 3: // 8bpp
{
auto const vram8 = util::big_endian_cast<uint8_t const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x++)
{
uint8_t const pixels = vram8[(y * 2048) + x];
*scanline++ = pens[pixels];
}
}
}
break;
case 4: // 16bpp
{
auto const vram16 = util::big_endian_cast<uint16_t const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
uint32_t *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x++)
{
uint16_t const pixels = vram16[(y * 1024) + x];
*scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3);
}
}
}
break;
}
return 0;
}

108
src/mame/apple/vasp.h Normal file
View File

@ -0,0 +1,108 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
#ifndef MAME_APPLE_VASP_H
#define MAME_APPLE_VASP_H
#pragma once
#include "machine/6522via.h"
#include "sound/asc.h"
#include "emupal.h"
#include "speaker.h"
#include "screen.h"
// ======================> vasp_device
class vasp_device : public device_t
{
public:
// construction/destruction
vasp_device(const machine_config &mconfig, const char *tag, device_t *owner)
: vasp_device(mconfig, tag, owner, (uint32_t)0)
{
}
vasp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// interface routines
auto pb4_callback() { return write_pb4.bind(); }
auto pb5_callback() { return write_pb5.bind(); }
auto cb2_callback() { return write_cb2.bind(); }
auto hdsel_callback() { return write_hdsel.bind(); }
auto pb3_callback() { return read_pb3.bind(); }
void map(address_map &map);
template <typename... T> void set_maincpu_tag(T &&... args) { m_maincpu.set_tag(std::forward<T>(args)...); }
template <typename... T> void set_rom_tag(T &&... args) { m_rom.set_tag(std::forward<T>(args)...); }
void set_ram_info(u32 *ram, u32 size);
DECLARE_WRITE_LINE_MEMBER(cb1_w);
DECLARE_WRITE_LINE_MEMBER(cb2_w);
DECLARE_WRITE_LINE_MEMBER(vbl_w);
DECLARE_WRITE_LINE_MEMBER(scc_irq_w);
DECLARE_WRITE_LINE_MEMBER(slot0_irq_w);
DECLARE_WRITE_LINE_MEMBER(slot1_irq_w);
DECLARE_WRITE_LINE_MEMBER(slot2_irq_w);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
private:
devcb_write_line write_pb4, write_pb5, write_cb2, write_hdsel;
devcb_read_line read_pb3;
required_device<cpu_device> m_maincpu;
required_ioport m_montype;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_device<via6522_device> m_via1;
required_device<asc_device> m_asc;
required_region_ptr<u32> m_rom;
std::unique_ptr<u32[]> m_vram;
emu_timer *m_6015_timer;
int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt;
u8 m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr;
u8 m_pal_address, m_pal_idx, m_pal_control, m_pal_colkey;
bool m_overlay;
u32 *m_ram_ptr, *m_rom_ptr;
u32 m_ram_size, m_rom_size;
u32 rom_switch_r(offs_t offset);
uint8_t pseudovia_r(offs_t offset);
void pseudovia_w(offs_t offset, uint8_t data);
void pseudovia_recalc_irqs();
uint16_t mac_via_r(offs_t offset);
void mac_via_w(offs_t offset, uint16_t data, uint16_t mem_mask);
uint8_t via_in_a();
uint8_t via_in_b();
void via_out_a(uint8_t data);
void via_out_b(uint8_t data);
void via_sync();
void field_interrupts();
DECLARE_WRITE_LINE_MEMBER(via_out_cb2);
DECLARE_WRITE_LINE_MEMBER(via1_irq);
DECLARE_WRITE_LINE_MEMBER(via2_irq);
TIMER_CALLBACK_MEMBER(mac_6015_tick);
u32 vram_r(offs_t offset);
void vram_w(offs_t offset, u32 data, u32 mem_mask);
u8 dac_r(offs_t offset);
void dac_w(offs_t offset, u8 data);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
};
// device type definition
DECLARE_DEVICE_TYPE(VASP, vasp_device)
#endif // MAME_APPLE_VASP_H

View File

@ -20734,13 +20734,15 @@ maciicx // 1989 Apple Macintosh IIcx
maciifx // 1990 Apple Macintosh IIfx maciifx // 1990 Apple Macintosh IIfx
maciihmu // 1987 Apple Macintosh II (w/o 68851 MMU) maciihmu // 1987 Apple Macintosh II (w/o 68851 MMU)
maciisi // 1990 Apple Macintosh IIsi maciisi // 1990 Apple Macintosh IIsi
maciivi // 1993 Apple Macintosh IIvi
maciivx // 1993 Apple Macintosh IIvx
maciix // 1988 Apple Macintosh IIx maciix // 1988 Apple Macintosh IIx
maclc // 1990 Apple Macintosh LC maclc // 1990 Apple Macintosh LC
maclc2 // 1991 Apple Macintosh LC II maclc2 // 1991 Apple Macintosh LC II
macse30 // 1989 Apple Macintosh SE/30 macse30 // 1989 Apple Macintosh SE/30
@source:apple/maciivx.cpp
maciivx // 1993 Apple Macintosh IIvx
maciivi // 1993 Apple Macintosh IIvi
@source:apple/maclc3.cpp @source:apple/maclc3.cpp
maclc3 // 1993 Apple Macintosh LC III maclc3 // 1993 Apple Macintosh LC III
maclc520 // 1993 Apple Macintosh LC 520 maclc520 // 1993 Apple Macintosh LC 520