mac.cpp: Moved maclc3 and maclc520 to a new, cleaner, independent driver. [R. Belmont]

This commit is contained in:
arbee 2022-07-08 19:26:06 -04:00
parent 9403db09ee
commit 8d28264487
8 changed files with 1008 additions and 272 deletions

View File

@ -7,7 +7,7 @@
TODO:
- V8 and friends (LC, LC2, Classic 2, Color Classic) to own driver
- LC3 / LC520 / IIvx / IIvi to own driver
- IIvx / IIvi to own driver
****************************************************************************/
@ -146,23 +146,6 @@ void mac_state::ariel_ramdac_w(offs_t offset, uint32_t data, uint32_t mem_mask)
}
}
uint8_t mac_state::mac_sonora_vctl_r(offs_t offset)
{
if (offset == 2)
{
// printf("Sonora: read monitor ID at PC=%x\n", m_maincpu->pc());
return (m_montype.read_safe(6)<<4);
}
return m_sonora_vctl[offset];
}
void mac_state::mac_sonora_vctl_w(offs_t offset, uint8_t data)
{
// printf("Sonora: %02x to vctl %x\n", data, offset);
m_sonora_vctl[offset] = data;
}
void mac_state::rbv_recalc_irqs()
{
// check slot interrupts and bubble them down to IFR
@ -491,7 +474,6 @@ void mac_state::maclc3_map(address_map &map)
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(0x50028000, 0x50028003).rw(FUNC(mac_state::mac_sonora_vctl_r), FUNC(mac_state::mac_sonora_vctl_w)).mirror(0x00f00000);
map(0x5ffffffc, 0x5fffffff).r(FUNC(mac_state::mac_read_id));
@ -923,35 +905,6 @@ void mac_state::maccclas(machine_config &config)
m_via1->writepb_handler().set(FUNC(mac_state::mac_via_out_b_cdadb));
}
void mac_state::maclc3(machine_config &config, bool egret)
{
maclc(config, false, false, asc_device::asc_type::SONORA, 2);
M68030(config, m_maincpu, 25000000);
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,macsonora)
MCFG_VIDEO_RESET_OVERRIDE(mac_state,macsonora)
m_screen->set_screen_update(FUNC(mac_state::screen_update_macsonora));
m_ram->set_default_size("4M");
m_ram->set_extra_options("8M,16M,32M,48M,64M,80M");
if (egret)
{
add_egret(config, EGRET_341S0851);
}
}
void mac_state::maclc520(machine_config &config)
{
maclc3(config, false);
add_cuda(config, CUDA_341S0060);
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);
@ -1232,20 +1185,11 @@ ROM_START( maclc2 )
ROM_LOAD32_BYTE( "341-0473_ub2-ll.bin", 0x000003, 0x020000, CRC(8843c37c) SHA1(bb5104110507ca543d106f11c6061245fd90c1a7) )
ROM_END
ROM_START( maclc3 )
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD( "ecbbc41c.rom", 0x000000, 0x100000, CRC(e578f5f3) SHA1(c77df3220c861f37a2c553b6ee9241b202dfdffc) )
ROM_END
ROM_START( maccclas )
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD( "ecd99dc0.rom", 0x000000, 0x100000, CRC(c84c3aa5) SHA1(fd9e852e2d77fe17287ba678709b9334d4d74f1e) )
ROM_END
ROM_START( maclc520 )
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD( "ede66cbd.rom", 0x000000, 0x100000, CRC(a893cb0f) SHA1(c54ee2f45020a4adeb7451adce04cd6e5fb69790) )
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME */
COMP( 1987, macii, 0, 0, macii, macadb, mac_state, init_macii, "Apple Computer", "Macintosh II", MACHINE_SUPPORTS_SAVE )
@ -1261,7 +1205,5 @@ 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, 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, maclc3, 0, 0, maclc3, maciici, mac_state, init_maclc3, "Apple Computer", "Macintosh LC III", MACHINE_SUPPORTS_SAVE|MACHINE_IMPERFECT_SOUND )
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 )
COMP( 1993, maclc520, 0, 0, maclc520, maciici, mac_state, init_maclc520, "Apple Computer", "Macintosh LC 520", MACHINE_NOT_WORKING )

View File

@ -216,7 +216,6 @@ private:
{
RBV_TYPE_RBV = 0,
RBV_TYPE_V8,
RBV_TYPE_SONORA,
RBV_TYPE_DAFB
};
@ -236,7 +235,7 @@ private:
int m_screen_buffer = 0;
int irq_count = 0, ca1_data = 0, ca2_data = 0;
// 60.15 Hz timer for RBV/V8/Sonora/Eagle/VASP/etc.
// 60.15 Hz timer for RBV/V8/Eagle/VASP/etc.
emu_timer *m_6015_timer = nullptr;
// ADB refresh timer, independent of anything else going on
@ -248,7 +247,6 @@ private:
uint8_t m_rbv_regs[256]{}, m_rbv_ier = 0, m_rbv_ifr = 0, m_rbv_type = 0, m_rbv_montype = 0, m_rbv_vbltime = 0;
uint32_t m_rbv_colors[3]{}, m_rbv_count = 0, m_rbv_clutoffs = 0, m_rbv_immed10wr = 0;
uint32_t m_rbv_palette[256]{};
uint8_t m_sonora_vctl[8]{};
emu_timer *m_vbl_timer = nullptr, *m_cursor_timer = nullptr;
uint16_t m_cursor_line = 0;
@ -295,8 +293,6 @@ private:
uint32_t rbv_ramdac_r();
void rbv_ramdac_w(offs_t offset, uint32_t data);
void ariel_ramdac_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0);
uint8_t mac_sonora_vctl_r(offs_t offset);
void mac_sonora_vctl_w(offs_t offset, uint8_t data);
uint8_t mac_rbv_r(offs_t offset);
void mac_rbv_w(offs_t offset, uint8_t data);
@ -355,17 +351,14 @@ private:
void hdsel_w(int hdsel);
DECLARE_VIDEO_START(mac);
DECLARE_VIDEO_START(macsonora);
DECLARE_VIDEO_RESET(macrbv);
DECLARE_VIDEO_START(macv8);
DECLARE_VIDEO_RESET(macsonora);
DECLARE_VIDEO_RESET(maceagle);
DECLARE_VIDEO_START(macrbv);
uint32_t screen_update_macse30(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
uint32_t screen_update_macrbv(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_macrbvvram(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_macv8(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
uint32_t screen_update_macsonora(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(mac_rbv_vbl);
TIMER_CALLBACK_MEMBER(mac_6015_tick);

View File

@ -1005,7 +1005,7 @@ void mac_state::mac_via2_out_b(uint8_t data)
}
}
// This signal is generated internally on RBV, V8, Sonora, VASP, Eagle, etc.
// This signal is generated internally on RBV, V8, VASP, Eagle, etc.
TIMER_CALLBACK_MEMBER(mac_state::mac_6015_tick)
{
m_via1->write_ca1(0);
@ -1048,7 +1048,6 @@ void mac_state::machine_start()
save_item(NAME(m_rbv_count));
save_item(NAME(m_rbv_clutoffs));
save_item(NAME(m_rbv_palette));
save_item(NAME(m_sonora_vctl));
save_item(NAME(m_scc_interrupt));
save_item(NAME(m_via_interrupt));
save_item(NAME(m_via2_interrupt));

View File

@ -11,7 +11,7 @@
Classic)
Also emulates on-board video for systems with the
RBV, V8, Eagle, Sonora, and DAFB chips.
RBV, V8, Eagle, and DAFB chips.
----------------------------------------------------------------------
Monitor sense codes
@ -84,7 +84,7 @@ uint32_t mac_state::screen_update_macse30(screen_device &screen, bitmap_ind16 &b
return 0;
}
// IIci/IIsi RAM-Based Video (RBV) and children: V8, Eagle, Spice, VASP, Sonora
// IIci/IIsi RAM-Based Video (RBV) and children: V8, Eagle, Spice, VASP
VIDEO_START_MEMBER(mac_state,macrbv)
{
@ -150,77 +150,6 @@ VIDEO_RESET_MEMBER(mac_state,macrbv)
target->set_view(view);
}
VIDEO_RESET_MEMBER(mac_state,macsonora)
{
int htotal, vtotal;
double framerate;
int view = 0;
memset(m_rbv_regs, 0, sizeof(m_rbv_regs));
m_rbv_count = 0;
m_rbv_clutoffs = 0;
m_rbv_immed10wr = 0;
m_rbv_regs[2] = 0x7f;
m_rbv_regs[3] = 0;
m_rbv_type = RBV_TYPE_SONORA;
m_rbv_montype = m_montype.read_safe(2);
rectangle visarea;
switch (m_rbv_montype)
{
case 1: // 15" portrait display
visarea.set(0, 640-1, 0, 870-1);
htotal = 832;
vtotal = 918;
framerate = 75.0;
view = 1;
break;
case 2: // 12" RGB
visarea.set(0, 512-1, 0, 384-1);
htotal = 640;
vtotal = 407;
framerate = 60.15;
break;
case 6: // 13" RGB
default:
visarea.set(0, 640-1, 0, 480-1);
htotal = 800;
vtotal = 525;
framerate = 59.94;
break;
}
// logerror("Sonora reset: monitor is %dx%d @ %f Hz\n", visarea.width(), visarea.height(), framerate);
m_screen->configure(htotal, vtotal, visarea, HZ_TO_ATTOSECONDS(framerate));
render_target *target = machine().render().first_target();
target->set_view(view);
}
VIDEO_START_MEMBER(mac_state,macsonora)
{
memset(m_rbv_regs, 0, sizeof(m_rbv_regs));
m_rbv_count = 0;
m_rbv_clutoffs = 0;
m_rbv_immed10wr = 0;
m_rbv_regs[2] = 0x7f;
m_rbv_regs[3] = 0;
m_rbv_regs[4] = 0x6;
m_rbv_regs[5] = 0x3;
m_sonora_vctl[0] = 0x9f;
m_sonora_vctl[1] = 0;
m_sonora_vctl[2] = 0;
m_rbv_type = RBV_TYPE_SONORA;
}
VIDEO_START_MEMBER(mac_state,macv8)
{
memset(m_rbv_regs, 0, sizeof(m_rbv_regs));
@ -575,131 +504,3 @@ uint32_t mac_state::screen_update_macv8(screen_device &screen, bitmap_rgb32 &bit
return 0;
}
uint32_t mac_state::screen_update_macsonora(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int hres, vres, stride;
switch (m_rbv_montype)
{
case 1: // 15" portrait display
stride = hres = 640;
vres = 870;
break;
case 2: // 12" RGB
stride = hres = 512;
vres = 384;
break;
case 6: // 13" RGB
default:
stride = hres = 640;
vres = 480;
break;
}
// forced blank?
if (m_sonora_vctl[0] & 0x80)
{
return 0;
}
switch (m_sonora_vctl[1] & 7)
{
case 0: // 1bpp
{
uint8_t const *const vram8 = (uint8_t *)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 * (stride/8)) + ((x/8)^3)];
*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
{
uint8_t const *const vram8 = (uint8_t *)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 * (stride/4)) + (BYTE4_XOR_BE(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
{
uint8_t const *const vram8 = (uint8_t *)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 * (stride/2)) + (BYTE4_XOR_BE(x))];
*scanline++ = m_rbv_palette[(pixels&0xf0) | 0xf];
*scanline++ = m_rbv_palette[((pixels&0x0f)<<4) | 0xf];
}
}
}
break;
case 3: // 8bpp
{
uint8_t const *const vram8 = (uint8_t *)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 * stride) + (BYTE4_XOR_BE(x))];
*scanline++ = m_rbv_palette[pixels];
}
}
}
break;
case 4: // 16bpp
{
uint16_t const *const vram16 = (uint16_t *)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 * stride) + (x^1)];
*scanline++ = rgb_t(((pixels>>10) & 0x1f)<<3, ((pixels>>5) & 0x1f)<<3, (pixels & 0x1f)<<3);
}
}
}
break;
}
return 0;
}

323
src/mame/apple/maclc3.cpp Normal file
View File

@ -0,0 +1,323 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/****************************************************************************
drivers/maclc3.cpp
Mac LC III ("Vail")
Mac LC 520 ("Hook")
By R. Belmont
These are basically identical '030 machines, except the LC III is a pizzabox
while the LC 520 is an all-in-one with a 14" Sony Trinitron built-in.
LC III uses the Egret ADB microcontroller while LC 520 uses the later Cuda.
Everything else is the same.
****************************************************************************/
#include "emu.h"
#include "bus/nscsi/devices.h"
#include "bus/rs232/rs232.h"
#include "cpu/m68000/m68000.h"
#include "machine/ram.h"
#include "machine/timer.h"
#include "machine/z80scc.h"
#include "machine/nscsi_bus.h"
#include "machine/ncr5380.h"
#include "cuda.h"
#include "egret.h"
#include "macadb.h"
#include "macscsi.h"
#include "sonora.h"
#include "emupal.h"
#include "screen.h"
#include "softlist_dev.h"
static constexpr u32 C7M = 7833600;
static constexpr u32 C15M = (C7M * 2);
class macvail_state : public driver_device
{
public:
macvail_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_sonora(*this, "sonora"),
m_scsibus1(*this, "scsi"),
m_ncr5380(*this, "scsi:7:ncr5380"),
m_scsihelp(*this, "scsihelp"),
m_scc(*this, "scc"),
m_egret(*this, "egret"),
m_cuda(*this, "cuda")
{
}
void maclc3_base(machine_config &config);
void maclc3(machine_config &config);
void maclc520(machine_config &config);
void base_map(address_map &map);
void maclc3_map(address_map &map);
void maclc520_map(address_map &map);
private:
required_device<m68030_device> m_maincpu;
optional_device<macadb_device> m_macadb;
required_device<ram_device> m_ram;
required_device<sonora_device> m_sonora;
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;
optional_device<egret_device> m_egret;
optional_device<cuda_device> m_cuda;
virtual void machine_start() override;
WRITE_LINE_MEMBER(adb_irq_w) { m_adb_irq_pending = state; }
int m_adb_irq_pending = 0;
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);
}
};
void macvail_state::machine_start()
{
m_sonora->set_ram_info((u32 *) m_ram->pointer(), m_ram->size());
save_item(NAME(m_adb_irq_pending));
}
/***************************************************************************
ADDRESS MAPS
***************************************************************************/
void macvail_state::base_map(address_map &map)
{
// RAM, ROM, and base I/O mappings come from Sonora (LCIII) / Ardbeg (LC520)
map(0x40000000, 0x600fffff).m(m_sonora, FUNC(sonora_device::map));
map(0x50004000, 0x50005fff).rw(FUNC(macvail_state::scc_r), FUNC(macvail_state::scc_w)).mirror(0x00f00000);
map(0x50006000, 0x50007fff).rw(FUNC(macvail_state::scsi_drq_r), FUNC(macvail_state::scsi_drq_w)).mirror(0x00f00000);
map(0x50010000, 0x50011fff).rw(FUNC(macvail_state::scsi_r), FUNC(macvail_state::scsi_w)).mirror(0x00f00000);
map(0x50012000, 0x50013fff).rw(FUNC(macvail_state::scsi_drq_r), FUNC(macvail_state::scsi_drq_w)).mirror(0x00f00000);
}
void macvail_state::maclc3_map(address_map &map)
{
base_map(map);
map(0x5ffffffc, 0x5fffffff).lr32(NAME([](offs_t offset) { return 0xa55a0001; }));
}
void macvail_state::maclc520_map(address_map &map)
{
base_map(map);
map(0x5ffffffc, 0x5fffffff).lr32(NAME([](offs_t offset) { return 0xa55a0100; }));
}
u16 macvail_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 macvail_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 macvail_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 macvail_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;
}
}
/***************************************************************************
DEVICE CONFIG
***************************************************************************/
static INPUT_PORTS_START( macadb )
INPUT_PORTS_END
/***************************************************************************
MACHINE DRIVERS
***************************************************************************/
void macvail_state::maclc3_base(machine_config &config)
{
M68030(config, m_maincpu, 25000000);
RAM(config, m_ram);
m_ram->set_default_size("4M");
m_ram->set_extra_options("8M,16M,32M,48M,64M,80M");
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(macvail_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_sonora, FUNC(sonora_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));
SONORA(config, m_sonora, C15M);
m_sonora->set_maincpu_tag("maincpu");
m_sonora->set_rom_tag(":bootrom");
MACADB(config, m_macadb, C15M);
m_macadb->adb_irq_callback().set(FUNC(macvail_state::adb_irq_w));
m_macadb->set_mcu_mode(true);
}
void macvail_state::maclc3(machine_config &config)
{
maclc3_base(config);
m_maincpu->set_addrmap(AS_PROGRAM, &macvail_state::maclc3_map);
EGRET(config, m_egret, EGRET_341S0851);
m_egret->reset_callback().set(FUNC(macvail_state::cuda_reset_w));
m_egret->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_egret->via_clock_callback().set(m_sonora, FUNC(sonora_device::cb1_w));
m_egret->via_data_callback().set(m_sonora, FUNC(sonora_device::cb2_w));
m_macadb->adb_data_callback().set(m_egret, FUNC(egret_device::set_adb_line));
config.set_perfect_quantum(m_maincpu);
m_sonora->pb3_callback().set(m_egret, FUNC(egret_device::get_xcvr_session));
m_sonora->pb4_callback().set(m_egret, FUNC(egret_device::set_via_full));
m_sonora->pb5_callback().set(m_egret, FUNC(egret_device::set_sys_session));
m_sonora->cb2_callback().set(m_egret, FUNC(egret_device::set_via_data));
}
void macvail_state::maclc520(machine_config &config)
{
maclc3_base(config);
m_maincpu->set_addrmap(AS_PROGRAM, &macvail_state::maclc520_map);
CUDA(config, m_cuda, CUDA_341S0060);
m_cuda->reset_callback().set(FUNC(macvail_state::cuda_reset_w));
m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_cuda->via_clock_callback().set(m_sonora, FUNC(sonora_device::cb1_w));
m_cuda->via_data_callback().set(m_sonora, FUNC(sonora_device::cb2_w));
m_macadb->adb_data_callback().set(m_cuda, FUNC(cuda_device::set_adb_line));
config.set_perfect_quantum(m_maincpu);
m_sonora->pb3_callback().set(m_cuda, FUNC(cuda_device::get_treq));
m_sonora->pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
m_sonora->pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
m_sonora->cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
}
ROM_START( maclc3 )
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD( "ecbbc41c.rom", 0x000000, 0x100000, CRC(e578f5f3) SHA1(c77df3220c861f37a2c553b6ee9241b202dfdffc) )
ROM_END
ROM_START( maclc520 )
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD( "ede66cbd.rom", 0x000000, 0x100000, CRC(a893cb0f) SHA1(c54ee2f45020a4adeb7451adce04cd6e5fb69790) )
ROM_END
COMP(1993, maclc3, 0, 0, maclc3, macadb, macvail_state, empty_init, "Apple Computer", "Macintosh LC III", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_SOUND)
COMP(1993, maclc520, 0, 0, maclc520, macadb, macvail_state, empty_init, "Apple Computer", "Macintosh LC 520", MACHINE_NOT_WORKING)

569
src/mame/apple/sonora.cpp Normal file
View File

@ -0,0 +1,569 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/*
Apple "Sonora" system ASIC
Emulation by R. Belmont
Sonora contains the following:
- A memory controller for up to 36MB (up to 4MB soldered and 32MB of SIMMs)
- A VRAM controller and framebuffer controller
- 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.
- A SWIM2 floppy controller
- An ASC-like 4-channel audio controller
The "Ardbeg" ASIC (LC 520) appears to be a renamed copy of Sonora, and "Prime Time"
(LC 475/575 and some low-end Quadras) is Sonora adapted to the 68040 bus. "Prime Time II"
is similar but adds an ATA controller.
Sonora's video controller is in some of the PowerMac chipsets as well.
*/
#include "emu.h"
#include "sonora.h"
#include "formats/ap_dsk35.h"
static constexpr u32 C7M = 7833600;
static constexpr u32 C15M = (C7M * 2);
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SONORA, sonora_device, "sonora", "Apple Sonora system ASIC")
//-------------------------------------------------
// ADDRESS_MAP
//-------------------------------------------------
void sonora_device::map(address_map &map)
{
map(0x00000000, 0x000fffff).r(FUNC(sonora_device::rom_switch_r)).mirror(0x0ff00000);
map(0x10000000, 0x10001fff).rw(FUNC(sonora_device::mac_via_r), FUNC(sonora_device::mac_via_w)).mirror(0x00fc0000);
map(0x10014000, 0x10015fff).rw(m_asc, FUNC(asc_device::read), FUNC(asc_device::write)).mirror(0x00f00000);
map(0x10016000, 0x10017fff).rw(FUNC(sonora_device::swim_r), FUNC(sonora_device::swim_w)).mirror(0x00f00000);
map(0x10026000, 0x10027fff).rw(FUNC(sonora_device::pseudovia_r), FUNC(sonora_device::pseudovia_w)).mirror(0x00f00000);
map(0x10f24000, 0x10f24003).rw(m_video, FUNC(mac_video_sonora_device::dac_r), FUNC(mac_video_sonora_device::dac_w));
map(0x10f28000, 0x10f28007).rw(m_video, FUNC(mac_video_sonora_device::vctrl_r), FUNC(mac_video_sonora_device::vctrl_w));
map(0x20000000, 0x200fffff).ram().mirror(0x0ff00000).rw(FUNC(sonora_device::vram_r), FUNC(sonora_device::vram_w));
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
void sonora_device::device_add_mconfig(machine_config &config)
{
MAC_VIDEO_SONORA(config, m_video);
m_video->screen_vblank().set(FUNC(sonora_device::vbl_w));
R65NC22(config, m_via1, C7M / 10);
m_via1->readpa_handler().set(FUNC(sonora_device::via_in_a));
m_via1->readpb_handler().set(FUNC(sonora_device::via_in_b));
m_via1->writepa_handler().set(FUNC(sonora_device::via_out_a));
m_via1->writepb_handler().set(FUNC(sonora_device::via_out_b));
m_via1->cb2_handler().set(FUNC(sonora_device::via_out_cb2));
m_via1->irq_handler().set(FUNC(sonora_device::via1_irq));
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
ASC(config, m_asc, C15M, asc_device::asc_type::SONORA);
m_asc->add_route(0, "lspeaker", 1.0);
m_asc->add_route(1, "rspeaker", 1.0);
SWIM2(config, m_fdc, C15M);
m_fdc->devsel_cb().set(FUNC(sonora_device::devsel_w));
m_fdc->phases_cb().set(FUNC(sonora_device::phases_w));
applefdintf_device::add_35_hd(config, m_floppy[0]);
applefdintf_device::add_35_nc(config, m_floppy[1]);
}
//-------------------------------------------------
// sonora_device - constructor
//-------------------------------------------------
sonora_device::sonora_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, SONORA, tag, owner, clock),
write_pb4(*this),
write_pb5(*this),
write_cb2(*this),
read_pb3(*this),
m_maincpu(*this, finder_base::DUMMY_TAG),
m_video(*this, "sonora_video"),
m_via1(*this, "via1"),
m_asc(*this, "asc"),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
m_rom(*this, finder_base::DUMMY_TAG),
m_cur_floppy(nullptr),
m_hdsel(0),
m_overlay(false)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sonora_device::device_start()
{
m_vram = std::make_unique<u32[]>(0x100000 / sizeof(u32));
write_pb4.resolve_safe();
write_pb5.resolve_safe();
write_cb2.resolve_safe();
read_pb3.resolve_safe(0);
m_6015_timer = timer_alloc(FUNC(sonora_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_hdsel));
m_rom_ptr = &m_rom[0];
m_rom_size = m_rom.length() << 2;
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void sonora_device::device_reset()
{
m_video->set_vram_base((const u64 *)&m_vram[0]);
m_video->set_vram_offset(0);
m_video->set_32bit();
// 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[2] = 0x7f;
m_via_interrupt = m_via2_interrupt = m_scc_interrupt = 0;
m_last_taken_interrupt = -1;
m_hdsel = 0;
// 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 sonora_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 sonora_device::set_ram_info(u32 *ram, u32 size)
{
m_ram_ptr = ram;
m_ram_size = size;
}
TIMER_CALLBACK_MEMBER(sonora_device::mac_6015_tick)
{
m_via1->write_ca1(CLEAR_LINE);
m_via1->write_ca1(ASSERT_LINE);
}
uint8_t sonora_device::via_in_a()
{
return 0x80;
}
uint8_t sonora_device::via_in_b()
{
return read_pb3() << 3;
}
WRITE_LINE_MEMBER(sonora_device::via_out_cb2)
{
write_cb2(state & 1);
}
void sonora_device::via_out_a(uint8_t data)
{
int hdsel = BIT(data, 5);
if (hdsel != m_hdsel)
{
if (m_cur_floppy)
{
m_cur_floppy->ss_w(hdsel);
}
}
m_hdsel = hdsel;
}
void sonora_device::via_out_b(uint8_t data)
{
write_pb4(BIT(data, 4));
write_pb5(BIT(data, 5));
}
WRITE_LINE_MEMBER(sonora_device::via1_irq)
{
m_via_interrupt = state;
field_interrupts();
}
WRITE_LINE_MEMBER(sonora_device::via2_irq)
{
m_via2_interrupt = state;
field_interrupts();
}
void sonora_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(sonora_device::scc_irq_w)
{
m_scc_interrupt = (state == ASSERT_LINE);
field_interrupts();
}
WRITE_LINE_MEMBER(sonora_device::vbl_w)
{
if (!state)
{
return;
}
m_pseudovia_regs[2] &= ~0x40; // set vblank signal
if (m_pseudovia_regs[0x12] & 0x40)
{
pseudovia_recalc_irqs();
}
}
void sonora_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 sonora_device::pseudovia_r(offs_t offset)
{
int data = 0;
if (offset < 0x100)
{
data = m_pseudovia_regs[offset];
if (offset == 0x10)
{
data &= ~0x38;
}
// 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 sonora_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(sonora_device::cb1_w)
{
m_via1->write_cb1(state);
}
WRITE_LINE_MEMBER(sonora_device::cb2_w)
{
m_via1->write_cb2(state);
}
uint16_t sonora_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 sonora_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 sonora_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));
}
uint16_t sonora_device::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 sonora_device::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 sonora_device::phases_w(uint8_t phases)
{
if (m_cur_floppy)
m_cur_floppy->seek_phase_w(phases);
}
void sonora_device::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);
}
u32 sonora_device::vram_r(offs_t offset)
{
return m_vram[offset];
}
void sonora_device::vram_w(offs_t offset, u32 data, u32 mem_mask)
{
COMBINE_DATA(&m_vram[offset]);
}

107
src/mame/apple/sonora.h Normal file
View File

@ -0,0 +1,107 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
#ifndef MAME_MACHINE_SONORA_H
#define MAME_MACHINE_SONORA_H
#pragma once
#include "emu.h"
#include "machine/6522via.h"
#include "machine/applefdintf.h"
#include "machine/mv_sonora.h"
#include "machine/swim2.h"
#include "sound/asc.h"
#include "speaker.h"
// ======================> sonora_device
class sonora_device : public device_t
{
public:
// construction/destruction
sonora_device(const machine_config &mconfig, const char *tag, device_t *owner)
: sonora_device(mconfig, tag, owner, (uint32_t)0)
{
}
sonora_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 pb3_callback() { return read_pb3.bind(); }
void map(address_map &map);
template <typename T> void set_maincpu_tag(T &&cpu_tag) { m_maincpu.set_tag(std::forward<T>(cpu_tag)); }
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);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_add_mconfig(machine_config &config) override;
private:
devcb_write_line write_pb4, write_pb5, write_cb2;
devcb_read_line read_pb3;
required_device<cpu_device> m_maincpu;
required_device<mac_video_sonora_device> m_video;
required_device<via6522_device> m_via1;
required_device<asc_device> m_asc;
required_device<applefdintf_device> m_fdc;
required_device_array<floppy_connector, 2> m_floppy;
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;
uint8_t m_pseudovia_regs[256], m_pseudovia_ier, m_pseudovia_ifr;
floppy_image_device *m_cur_floppy = nullptr;
int m_hdsel;
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);
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);
u32 vram_r(offs_t offset);
void vram_w(offs_t offset, u32 data, u32 mem_mask);
};
// device type definition
DECLARE_DEVICE_TYPE(SONORA, sonora_device)
#endif // MAME_MACHINE_SONORA_H

View File

@ -20729,9 +20729,11 @@ maciivx // 1993 Apple Macintosh IIvx
maciix // 1988 Apple Macintosh IIx
maclc // 1990 Apple Macintosh LC
maclc2 // 1991 Apple Macintosh LC II
macse30 // 1989 Apple Macintosh SE/30
@source:apple/maclc3.cpp
maclc3 // 1993 Apple Macintosh LC III
maclc520 // 1993 Apple Macintosh LC 520
macse30 // 1989 Apple Macintosh SE/30
@source:apple/macpdm.cpp
pmac6100 // 1993 Apple Power Macintosh 6100
@ -27528,7 +27530,7 @@ m4hotrod__v //
m4holdtm // Hold Timer (Barcrest)
m4hpyjok // Happy Joker (Barcrest)
m4jok300 // Jokers Millenium 300
m4jok300a //
m4jok300a //
m4jolgem // Jolly Gems (Barcrest)
m4jolgem__0 //
m4jolgem__1 //