New working systems

-------------------
Macintosh TV [R. Belmont]
This commit is contained in:
arbee 2024-02-24 23:14:39 -05:00
parent 03b4f45800
commit 76740469bb
4 changed files with 290 additions and 24 deletions

View File

@ -3,11 +3,21 @@
/****************************************************************************
maclc.cpp
Mac LC, LC II, Classic II, Color Classic
Mac LC, LC II, Classic II, Color Classic, Macintosh TV
By R. Belmont
These are all lower-end machines based on versions of the "V8" system
controller, which has a 10 MB hard limit on RAM.
controller, which has a 10 MB hard limit on RAM (8MB in the Mac TV).
Mac TV video input chips:
TEA63330T - Sound fader control unit for car stereos
I2C: address 1000000x
TDA8708BT - Video analog input interface
SAA7197 T - Clock signal generator circuit for desktop video systems
SAA7191 WP - Digital multistandard colour decoder
I2C: address 1000101x
SAA7186 H - Digital video scaler
I2C: address 1011100x
****************************************************************************/
@ -39,7 +49,6 @@
#include "screen.h"
#include "softlist_dev.h"
namespace {
#define C32M (31.3344_MHz_XTAL)
@ -73,6 +82,7 @@ public:
void maclc2(machine_config &config);
void macclas2(machine_config &config);
void maccclas(machine_config &config);
void mactv(machine_config &config);
void maclc_map(address_map &map);
void maccclassic_map(address_map &map);
@ -335,7 +345,7 @@ void maclc_state::maclc_base(machine_config &config)
m_scsihelp->timeout_error_callback().set(FUNC(maclc_state::scsi_berr_w));
SOFTWARE_LIST(config, "hdd_list").set_original("mac_hdd");
SOFTWARE_LIST(config, "cd_list").set_original("mac_cdrom").set_filter("MC68020");
SOFTWARE_LIST(config, "cd_list").set_original("mac_cdrom").set_filter("MC68020,MC68020_32");
SOFTWARE_LIST(config, "flop35hd_list").set_original("mac_hdflop");
SCC85C30(config, m_scc, C7M);
@ -416,7 +426,7 @@ void maclc_state::maclc2(machine_config &config)
m_ram->set_extra_options("6M,8M,10M");
m_v8->set_baseram_is_4M(true);
SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030");
SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
}
void maclc_state::maccclas(machine_config &config)
@ -454,7 +464,46 @@ void maclc_state::maccclas(machine_config &config)
m_ram->set_extra_options("6M,8M,10M");
m_v8->set_baseram_is_4M(true);
SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030");
SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
}
void maclc_state::mactv(machine_config &config)
{
maclc_base(config);
M68030(config.replace(), m_maincpu, C32M);
m_maincpu->set_addrmap(AS_PROGRAM, &maclc_state::maccclassic_map);
m_maincpu->set_dasm_override(std::function(&mac68k_dasm_override), "mac68k_dasm_override");
config.device_remove("egret");
config.device_remove("fdc");
CUDA_V2XX(config, m_cuda, XTAL(32'768));
m_cuda->set_default_bios_tag("341s0788");
m_cuda->reset_callback().set(FUNC(maclc_state::egret_reset_w));
m_cuda->linechange_callback().set(m_macadb, FUNC(macadb_device::adb_linechange_w));
m_cuda->via_clock_callback().set(m_v8, FUNC(v8_device::cb1_w));
m_cuda->via_data_callback().set(m_v8, FUNC(v8_device::cb2_w));
m_macadb->adb_data_callback().set(m_cuda, FUNC(cuda_device::set_adb_line));
config.set_perfect_quantum(m_maincpu);
TINKERBELL(config.replace(), m_v8, C15M);
m_v8->set_maincpu_tag("maincpu");
m_v8->set_rom_tag("bootrom");
m_v8->hdsel_callback().set(FUNC(maclc_state::hdsel_w));
m_v8->pb3_callback().set(m_cuda, FUNC(cuda_device::get_treq));
m_v8->pb4_callback().set(m_cuda, FUNC(cuda_device::set_byteack));
m_v8->pb5_callback().set(m_cuda, FUNC(cuda_device::set_tip));
m_v8->cb2_callback().set(m_cuda, FUNC(cuda_device::set_via_data));
// Mac TV doesn't have an LC PDS
config.device_remove("pds");
m_ram->set_default_size("4M");
m_ram->set_extra_options("5M,6M,8M");
m_v8->set_baseram_is_4M(true);
SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
}
void maclc_state::macclas2(machine_config &config)
@ -481,7 +530,7 @@ void maclc_state::macclas2(machine_config &config)
m_ram->set_extra_options("6M,8M,10M");
m_v8->set_baseram_is_4M(true);
SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030");
SOFTWARE_LIST(config.replace(), "cd_list").set_original("mac_cdrom").set_filter("MC68030,MC68030_32");
}
ROM_START(maclc)
@ -510,9 +559,15 @@ ROM_START(maccclas)
ROM_LOAD("ecd99dc0.rom", 0x000000, 0x100000, CRC(c84c3aa5) SHA1(fd9e852e2d77fe17287ba678709b9334d4d74f1e))
ROM_END
ROM_START(mactv)
ROM_REGION32_BE(0x100000, "bootrom", 0)
ROM_LOAD("eaf1678d.bin", 0x000000, 0x100000, CRC(0644f05b) SHA1(74975c60d3a560fac9ad63125bb65a750fceaede))
ROM_END
} // anonymous namespace
COMP(1990, maclc, 0, 0, maclc, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh LC", MACHINE_SUPPORTS_SAVE)
COMP(1991, maclc2, 0, 0, maclc2, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh LC II", MACHINE_SUPPORTS_SAVE)
COMP(1991, macclas2, 0, 0, macclas2, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh Classic II", MACHINE_SUPPORTS_SAVE)
COMP(1993, maccclas, 0, 0, maccclas, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh Color Classic", MACHINE_SUPPORTS_SAVE)
COMP(1994, mactv, 0, 0, mactv, maclc, maclc_state, empty_init, "Apple Computer", "Macintosh TV", MACHINE_SUPPORTS_SAVE)

View File

@ -1,7 +1,7 @@
// license:BSD-3-Clause
// copyright-holders:R. Belmont
/*
Apple "V8", "Eagle", and "Spice" system ASICs
Apple "V8", "Eagle", "Spice", and "Tinkerbell" system ASICs
Emulation by R. Belmont
V8 (343S0116 or 343-0155) contains the following:
@ -22,6 +22,10 @@
and adds the option for an optional ROM expansion plus support for pushbutton sound volume
and display intensity controls and power saver mode.
Tinker Bell (343S1109) is an evolution of Spice with a simpler memory controller that has
an 8MB limit (4MB on the motherboard, 1, 2, or 4MB in the SIMM slot) and support for the
Macintosh TV's video input feature.
VISA (343S0101) is a predecessor of V8 and Eagle without support for dedicated VRAM banks
or VGA modes. It was coupled to a non-customized Bt450 RAMDAC on the Elsie prototype, and
did not offer video modes with more than 4 bits per pixel.
@ -34,12 +38,13 @@
#include "emu.h"
#include "v8.h"
#include "cpu/m68000/m68030.h"
#include "formats/ap_dsk35.h"
#include "layout/generic.h"
#define LOG_RAM (1U << 1)
#define VERBOSE (LOG_RAM)
#define VERBOSE (0)
#include "logmacro.h"
static constexpr u32 C7M = 7833600;
@ -52,6 +57,7 @@ static constexpr u32 C15M = (C7M * 2);
DEFINE_DEVICE_TYPE(V8, v8_device, "v8", "Apple V8 system ASIC")
DEFINE_DEVICE_TYPE(EAGLE, eagle_device, "v8eagle", "Apple Eagle system ASIC")
DEFINE_DEVICE_TYPE(SPICE, spice_device, "v8spice", "Apple Spice system ASIC")
DEFINE_DEVICE_TYPE(TINKERBELL, tinkerbell_device, "v8tkbell", "Apple Tinker Bell system ASIC")
static INPUT_PORTS_START( v8 )
PORT_START("MONTYPE")
@ -94,8 +100,6 @@ void v8_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(v8_device::screen_update));
m_screen->screen_vblank().set(FUNC(v8_device::slot_irq_w<0x40>));
config.set_default_layout(layout_monitors);
@ -133,6 +137,7 @@ v8_device::v8_device(const machine_config &mconfig, device_type type, const char
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_asc(*this, "asc"),
m_overlay(false),
write_pb4(*this),
write_pb5(*this),
write_cb2(*this),
@ -142,7 +147,6 @@ v8_device::v8_device(const machine_config &mconfig, device_type type, const char
m_montype(*this, "MONTYPE"),
m_via1(*this, "via1"),
m_rom(*this, finder_base::DUMMY_TAG),
m_overlay(false),
m_baseIs4M(false)
{
}
@ -966,12 +970,17 @@ void spice_device::device_add_mconfig(machine_config &config)
applefdintf_device::add_35_nc(config, m_floppy[1]);
}
spice_device::spice_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
: v8_device(mconfig, type, tag, owner, clock),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
m_cur_floppy(nullptr),
m_hdsel(0)
{
}
spice_device::spice_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: v8_device(mconfig, SPICE, tag, owner, clock),
m_fdc(*this, "fdc"),
m_floppy(*this, "fdc:%d", 0U),
m_cur_floppy(nullptr),
m_hdsel(0)
: spice_device(mconfig, SPICE, tag, owner, clock)
{
}
@ -1166,3 +1175,181 @@ void spice_device::bright_contrast_w(offs_t offset, u8 data)
// offset 1 = contrast (0-255)
}
// ================ tinkerbell_device
void tinkerbell_device::device_add_mconfig(machine_config &config)
{
spice_device::device_add_mconfig(config);
m_screen->set_raw(25175000, 800, 0, 640, 525, 0, 480);
}
tinkerbell_device::tinkerbell_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: spice_device(mconfig, TINKERBELL, tag, owner, clock)
{
}
u8 tinkerbell_device::via_in_a()
{
return 0x84;
}
u8 tinkerbell_device::pseudovia_r(offs_t offset)
{
if (offset < 0x100)
{
if (offset == 0x10)
{
return 0x06 << 3; // ID as an Apple 13" 640x480 monitor
}
}
return v8_device::pseudovia_r(offset);
}
u32 tinkerbell_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int hres, vres;
hres = 640;
vres = 480;
const pen_t *pens = m_palette->pens();
switch (m_pseudovia_regs[0x10] & 7)
{
case 0: // 1bpp
{
auto const vram8 = util::big_endian_cast<u8 const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
u32 *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x += 8)
{
u8 const pixels = vram8[(y * 1024) + (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<u8 const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
u32 *scanline = &bitmap.pix(y);
for (int x = 0; x < hres / 4; x++)
{
u8 const pixels = vram8[(y * 1024) + 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<u8 const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
u32 *scanline = &bitmap.pix(y);
for (int x = 0; x < hres / 2; x++)
{
u8 const pixels = vram8[(y * 1024) + x];
*scanline++ = pens[0x0f | (pixels & 0xf0)];
*scanline++ = pens[0x0f | ((pixels << 4) & 0xf0)];
}
}
}
break;
case 3: // 8bpp
{
auto const vram8 = util::big_endian_cast<u8 const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
u32 *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x++)
{
u8 const pixels = vram8[(y * 1024) + x];
*scanline++ = pens[pixels];
}
}
}
break;
case 4: // 16bpp
{
auto const vram16 = util::big_endian_cast<u16 const>(&m_vram[0]);
for (int y = 0; y < vres; y++)
{
u32 *scanline = &bitmap.pix(y);
for (int x = 0; x < hres; x++)
{
u16 const pixels = vram16[(y * hres) + x];
*scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3);
}
}
}
break;
}
return 0;
}
/*
Tinker Bell is different from the V8, but it still needs to kind of act like one.
The major difference: the RAM limit is 8MB instead of 10, and no RAM appears
above 0x7FFFFFFF. Also, when the bits are set for what on V8 would be 8MB SIMM
and no motherboard RAM except the 0x800000 image, that means 4MB of motherboard
and 4MB of SIMM here.
*/
void tinkerbell_device::ram_size(u8 config)
{
if (!m_overlay)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
const void *mb_ram = m_ram_ptr;
u32 simm_size = m_ram_size - 0x400000;
void *simm_ram = &m_ram_ptr[0x400000 / 4];
space.unmap_readwrite(0x000000, 0x9fffff);
// place the motherboard RAM at 0
LOGMASKED(LOG_RAM, "Motherboard RAM at 0x00000000 to 0x003fffff\n");
space.install_ram(0, 0x3fffff, 0, (void *)mb_ram);
// is SIMM RAM present? it always goes at 0x400000
if (simm_size > 0)
{
if ((config & 0xc0) != 0)
{
LOGMASKED(LOG_RAM, "SIMM RAM at 0x400000 to %x\n", simm_size - 1);
space.install_ram(0x400000, (0x400000 + simm_size) - 1, 0, (void *)simm_ram);
}
}
else
{
LOGMASKED(LOG_RAM, "Base config, no SIMM\n");
}
}
}

View File

@ -52,6 +52,8 @@ protected:
u8 m_pseudovia_regs[256];
u32 *m_ram_ptr;
u32 m_ram_size;
bool m_overlay;
v8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
@ -65,6 +67,8 @@ protected:
void asc_irq(int state);
virtual void ram_size(u8 config);
private:
devcb_write_line write_pb4, write_pb5, write_cb2, write_hdsel, write_hmmu_enable;
devcb_read_line read_pb3;
@ -77,13 +81,10 @@ private:
int m_via_interrupt, m_via2_interrupt, m_scc_interrupt, m_last_taken_interrupt;
u8 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_size;
bool m_baseIs4M;
u32 rom_switch_r(offs_t offset);
void ram_size(u8 config);
void pseudovia_w(offs_t offset, u8 data);
void pseudovia_recalc_irqs();
@ -140,30 +141,52 @@ public:
required_device_array<floppy_connector, 2> m_floppy;
protected:
spice_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
virtual void device_start() override;
virtual void device_add_mconfig(machine_config &config) override;
virtual ioport_constructor device_input_ports() const override;
void phases_w(u8 phases);
void devsel_w(u8 devsel);
private:
floppy_image_device *m_cur_floppy = nullptr;
int m_hdsel;
u8 via_in_a() override;
virtual u8 via_in_a() override;
virtual void via_out_a(u8 data) override;
u8 pseudovia_r(offs_t offset) override;
virtual u8 pseudovia_r(offs_t offset) override;
virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
void phases_w(u8 phases);
void devsel_w(u8 devsel);
u16 swim_r(offs_t offset, u16 mem_mask);
void swim_w(offs_t offset, u16 data, u16 mem_mask);
void bright_contrast_w(offs_t offset, u8 data);
};
// ======================> tinkerbell_device
class tinkerbell_device : public spice_device
{
public:
tinkerbell_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
virtual void device_add_mconfig(machine_config &config) override;
virtual void ram_size(u8 config) override;
private:
virtual u8 via_in_a() override;
virtual u8 pseudovia_r(offs_t offset) override;
virtual u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) override;
};
// device type definition
DECLARE_DEVICE_TYPE(V8, v8_device)
DECLARE_DEVICE_TYPE(EAGLE, eagle_device)
DECLARE_DEVICE_TYPE(SPICE, spice_device)
DECLARE_DEVICE_TYPE(TINKERBELL, tinkerbell_device)
#endif // MAME_APPLE_V8_H

View File

@ -887,6 +887,7 @@ maclc // 1990 Apple Macintosh LC
maclc2 // 1991 Apple Macintosh LC II
macclas2 // 1991 Apple Macintosh Classic II
maccclas // 1993 Apple Macintosh Color Classic
mactv // 1994 Apple Macintosh TV
@source:apple/maclc3.cpp
maclc3 // 1993 Apple Macintosh LC III