mirror of
https://github.com/holub/mame
synced 2025-04-21 07:52:35 +03:00
machine/mv_sonora.cpp: Support 2, 4, and 16bpp modes. [R. Belmont]
apple/macpdm.cpp: Fix HMC reads and writes, map RAM properly, and hook up NuBus. [R. Belmont]
This commit is contained in:
parent
cd3147a831
commit
58b826f9ea
@ -52,6 +52,16 @@ void mac_nubus_cards(device_slot_interface &device)
|
||||
device.option_add("thunder4gx", NUBUS_THUNDERIVGX); // Radius Thunder IV GX video card
|
||||
}
|
||||
|
||||
void powermac_nubus_cards(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("mdc48", NUBUS_MDC48); // Apple Macintosh Display Card 4•8
|
||||
device.option_add("mdc824", NUBUS_MDC824); // Apple Macintosh Display Card 8•24
|
||||
device.option_add("cb264", NUBUS_CB264); // RasterOps ColorBoard 264
|
||||
device.option_add("asmc3nb", NUBUS_ASNTMC3NB); // Asante MC3NB Ethernet card
|
||||
device.option_add("enetnb", NUBUS_APPLEENET); // Apple NuBus Ethernet
|
||||
device.option_add("quadralink", NUBUS_QUADRALINK); // AE Quadralink serial card
|
||||
device.option_add("thunder4gx", NUBUS_THUNDERIVGX); // Radius Thunder IV GX video card
|
||||
}
|
||||
|
||||
void mac_pds030_cards(device_slot_interface &device)
|
||||
{
|
||||
|
@ -12,6 +12,7 @@
|
||||
#pragma once
|
||||
|
||||
void mac_nubus_cards(device_slot_interface &device) ATTR_COLD;
|
||||
void powermac_nubus_cards(device_slot_interface &device) ATTR_COLD;
|
||||
void mac_pds030_cards(device_slot_interface &device) ATTR_COLD;
|
||||
void mac_pdslc_cards(device_slot_interface &device) ATTR_COLD;
|
||||
void mac_pdslc_orig_cards(device_slot_interface &device) ATTR_COLD;
|
||||
|
@ -203,6 +203,32 @@ uint32_t mac_video_sonora_device::screen_update(screen_device &screen, bitmap_rg
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: // 2bpp
|
||||
for (uint32_t y = 0; y != vres; y++)
|
||||
{
|
||||
uint32_t *scanline = &bitmap.pix(y);
|
||||
for (uint32_t x = 0; x != hres; x += 32)
|
||||
{
|
||||
uint64_t pixels = *vram++;
|
||||
for (int32_t bit = 62; bit >= 0; bit -= 2)
|
||||
*scanline ++ = pens[(((pixels >> bit) & 0x3) << 6) | 0x3f];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: // 4bpp
|
||||
for (uint32_t y = 0; y != vres; y++)
|
||||
{
|
||||
uint32_t *scanline = &bitmap.pix(y);
|
||||
for (uint32_t x = 0; x != hres; x += 16)
|
||||
{
|
||||
uint64_t pixels = *vram++;
|
||||
for (int32_t bit = 60; bit >= 0; bit -= 4)
|
||||
*scanline ++ = pens[(((pixels >> bit) & 0x0f) << 4) | 0x0f];
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 3: // 8bpp
|
||||
for(uint32_t y = 0; y != vres; y++) {
|
||||
uint32_t *scanline = &bitmap.pix(y);
|
||||
@ -214,6 +240,21 @@ uint32_t mac_video_sonora_device::screen_update(screen_device &screen, bitmap_rg
|
||||
}
|
||||
break;
|
||||
|
||||
case 4: // 16bpp
|
||||
for (uint32_t y = 0; y != vres; y++)
|
||||
{
|
||||
uint32_t *scanline = &bitmap.pix(y);
|
||||
for (uint32_t x = 0; x != hres; x += 4)
|
||||
{
|
||||
const uint64_t pixels = *vram++;
|
||||
*scanline++ = rgb_t(((pixels >> 58) & 0x1f) << 3, ((pixels >> 53) & 0x1f) << 3, ((pixels >> 48) & 0x1f) << 3);
|
||||
*scanline++ = rgb_t(((pixels >> 42) & 0x1f) << 3, ((pixels >> 37) & 0x1f) << 3, ((pixels >> 32) & 0x1f) << 3);
|
||||
*scanline++ = rgb_t(((pixels >> 26) & 0x1f) << 3, ((pixels >> 21) & 0x1f) << 3, ((pixels >> 16) & 0x1f) << 3);
|
||||
*scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
bitmap.fill(0xff0000);
|
||||
break;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "bus/nscsi/cd.h"
|
||||
#include "bus/nscsi/devices.h"
|
||||
#include "bus/nubus/nubus.h"
|
||||
#include "bus/nubus/cards.h"
|
||||
#include "bus/rs232/rs232.h"
|
||||
#include "cpu/powerpc/ppc.h"
|
||||
#include "machine/6522via.h"
|
||||
@ -120,9 +121,9 @@ private:
|
||||
void sndi_err_irq(int state);
|
||||
|
||||
void vblank_irq(int state);
|
||||
[[maybe_unused]] void slot2_irq(int state);
|
||||
[[maybe_unused]] void slot1_irq(int state);
|
||||
void slot0_irq(int state);
|
||||
void slot2_irq_w(int state);
|
||||
void slot1_irq_w(int state);
|
||||
void slot0_irq_w(int state);
|
||||
|
||||
void fdc_irq(int state);
|
||||
void fdc_drq(int state);
|
||||
@ -167,6 +168,8 @@ private:
|
||||
uint8_t hmc_r(offs_t offset);
|
||||
void hmc_w(offs_t offset, uint8_t data);
|
||||
|
||||
void ram_size();
|
||||
|
||||
uint32_t id_r();
|
||||
|
||||
uint8_t diag_r(offs_t offset);
|
||||
@ -247,6 +250,7 @@ macpdm_state::macpdm_state(const machine_config &mconfig, device_type type, cons
|
||||
void macpdm_state::driver_init()
|
||||
{
|
||||
m_maincpu->space().install_ram(0, m_ram->mask(), 0, m_ram->pointer());
|
||||
|
||||
m_model_id = 0xa55a3011;
|
||||
// 7100 = a55a3012
|
||||
// 8100 = a55a3013
|
||||
@ -567,7 +571,9 @@ void macpdm_state::scsi_w(offs_t offset, uint8_t data)
|
||||
|
||||
uint8_t macpdm_state::hmc_r(offs_t offset)
|
||||
{
|
||||
return (m_hmc_reg >> m_hmc_bit) & 1 ? 0x80 : 0x00;
|
||||
const uint8_t rv = (m_hmc_reg >> m_hmc_bit) & 1;
|
||||
m_hmc_bit++;
|
||||
return rv;
|
||||
}
|
||||
|
||||
void macpdm_state::hmc_w(offs_t offset, uint8_t data)
|
||||
@ -575,14 +581,15 @@ void macpdm_state::hmc_w(offs_t offset, uint8_t data)
|
||||
if(offset & 8)
|
||||
m_hmc_bit = 0;
|
||||
else {
|
||||
if(data & 0x80)
|
||||
if(data & 1)
|
||||
m_hmc_buffer |= u64(1) << m_hmc_bit;
|
||||
else
|
||||
m_hmc_buffer &= ~(u64(1) << m_hmc_bit);
|
||||
m_hmc_bit ++;
|
||||
if(m_hmc_bit == 35) {
|
||||
m_hmc_reg = m_hmc_buffer & ~3; // csiz is readonly, we pretend there isn't a l2 cache
|
||||
m_video->set_vram_offset(m_hmc_reg & 0x200000000 ? 0x100000 : 0);
|
||||
m_video->set_vram_offset(m_hmc_reg & 0x200000000 ? 0 : 0x100000);
|
||||
ram_size();
|
||||
logerror("HMC l2=%c%c%c%c%c vbase=%c%s mbram=%cM size=%x%s romd=%d refresh=%02x w=%c%c%c%c ras=%d%d%d%d\n",
|
||||
m_hmc_reg & 0x008000000 ? '+' : '-', // l2_en
|
||||
m_hmc_reg & 0x400000000 ? '3' : '2', // l2_init
|
||||
@ -592,22 +599,82 @@ void macpdm_state::hmc_w(offs_t offset, uint8_t data)
|
||||
m_hmc_reg & 0x200000000 ? '1' : '0', // vbase
|
||||
m_hmc_reg & 0x100000000 ? " vtst" : "", // vtst
|
||||
m_hmc_reg & 0x080000000 ? '8' : '4', // mb_ram
|
||||
(m_hmc_reg >> 29) & 3, // size
|
||||
(uint32_t)((m_hmc_reg >> 29) & 3), // size
|
||||
m_hmc_reg & 0x001000000 ? " nblrom" : "", // nblrom
|
||||
12 - 2*((m_hmc_reg >> 22) & 3), // romd
|
||||
(m_hmc_reg >> 16) & 0x3f, // rfsh
|
||||
(uint32_t)(12 - 2*((m_hmc_reg >> 22) & 3)), // romd
|
||||
(uint32_t)((m_hmc_reg >> 16) & 0x3f), // rfsh
|
||||
m_hmc_reg & 0x000000008 ? '3' : '2', // winit
|
||||
m_hmc_reg & 0x000000004 ? '3' : '2', // wbrst
|
||||
m_hmc_reg & 0x000008000 ? '1' : '2', // wcasp
|
||||
m_hmc_reg & 0x000004000 ? '1' : '2', // wcasd
|
||||
3 - ((m_hmc_reg >> 12) & 3), // rdac
|
||||
6 - ((m_hmc_reg >> 8) & 3), // rasd
|
||||
5 - ((m_hmc_reg >> 6) & 3), // rasp
|
||||
4 - ((m_hmc_reg >> 4) & 3)); // rcasd
|
||||
(uint32_t)(3 - ((m_hmc_reg >> 12) & 3)), // rdac
|
||||
(uint32_t)(6 - ((m_hmc_reg >> 8) & 3)), // rasd
|
||||
(uint32_t)(5 - ((m_hmc_reg >> 6) & 3)), // rasp
|
||||
(uint32_t)(4 - ((m_hmc_reg >> 4) & 3))); // rcasd
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
PDM uses a variant on the V8/Sonora style memory controller.
|
||||
- Motherboard RAM can be 4 or 8 MiB
|
||||
- The hardware officially limits SIMMs to 2, 8, or 32 MiB, and SIMMs must be installed in pairs
|
||||
- In reality, 128 MiB SIMMs will also work.
|
||||
- 6100 has only 2 SIMM slots, so valid sizes are 8MiB (no SIMMs), 12MiB (2 MiB SIMM x2),
|
||||
24MiB (8 MiB SIMM x2), 72MiB (32 MiB SIMM x2), and 264MiB (128 MiB SIMM x2)
|
||||
- 7100 has 4 SIMM slots, allowing RAM up to 520MiB (128 MiB SIMM x4)
|
||||
- 8100 has 8 SIMM slots, which add valid sizes up to 264 MiB (32 MiB SIMM x8)
|
||||
*/
|
||||
void macpdm_state::ram_size(){
|
||||
static const uint32_t sizes[4] = { 128*1024*1024, 2*1024*1024, 8*1024*1024, 32*1024*1024 };
|
||||
const u8 config = (m_hmc_reg >> 29) & 3; // 0 = 128MiB, 1 = 2MiB, 2 = 8MiB, 3 = 32MiB
|
||||
const u8 mb_size = (m_hmc_reg & 0x00800000) ? 1 : 0;
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
const u32 total_ram = m_ram->size();
|
||||
const u32 mb_ram_size = (mb_size ? 8*1024*1024 : 4*1024*1024);
|
||||
|
||||
// SIMMs must be in identical pairs, so any leftover RAM after the motherboard 8MiB is
|
||||
// the number of slots times the SIMM size.
|
||||
const u32 simm_size = (total_ram - mb_ram_size) / 2;
|
||||
|
||||
u8 *mb_ram = (u8 *)m_ram->pointer();
|
||||
u8 *ram_a = mb_ram + mb_ram_size;
|
||||
u8 *ram_b = ram_a + simm_size;
|
||||
|
||||
// unmap the first GB of address space (reserved for RAM)
|
||||
space.unmap_readwrite(0x00000000, 0x3fffffff);
|
||||
|
||||
// map the motherboard 8MB
|
||||
space.install_ram(0x00000000, 0x007fffff, 0, (void *)mb_ram);
|
||||
|
||||
// install RAM A
|
||||
if (simm_size > 0)
|
||||
{
|
||||
if (simm_size <= 8*1024*1024)
|
||||
{
|
||||
space.install_ram(mb_ram_size, mb_ram_size + simm_size - 1, 0, (void *)ram_a);
|
||||
}
|
||||
else
|
||||
{
|
||||
space.install_ram(mb_ram_size, sizes[config] - 1, 0, (void *)(ram_a + mb_ram_size));
|
||||
}
|
||||
|
||||
// install a complete image of RAM A in the slot above the top of memory (which is actually where the ROM code looks for it)
|
||||
const u32 alias_base = (sizes[config] * 2);
|
||||
space.install_ram(alias_base, alias_base + simm_size - 1, 0, (void *)ram_a);
|
||||
|
||||
// install RAM B
|
||||
u32 b_base = sizes[config];
|
||||
|
||||
if (simm_size < (128*1024*1024))
|
||||
{
|
||||
b_base += mb_ram_size;
|
||||
}
|
||||
|
||||
space.install_ram(b_base, b_base + simm_size - 1, 0, (void *)ram_b);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t macpdm_state::diag_r(offs_t offset)
|
||||
{
|
||||
// returning 0 at address 0 gives the 'car crash' sound after the boot bong
|
||||
@ -680,16 +747,21 @@ void macpdm_state::vblank_irq(int state)
|
||||
via2_irq_slot_set(0x40, state);
|
||||
}
|
||||
|
||||
void macpdm_state::slot2_irq(int state)
|
||||
void macpdm_state::slot2_irq_w(int state)
|
||||
{
|
||||
via2_irq_slot_set(0x20, state);
|
||||
}
|
||||
|
||||
void macpdm_state::slot1_irq(int state)
|
||||
void macpdm_state::slot1_irq_w(int state)
|
||||
{
|
||||
via2_irq_slot_set(0x10, state);
|
||||
}
|
||||
|
||||
void macpdm_state::slot0_irq_w(int state)
|
||||
{
|
||||
via2_irq_slot_set(0x08, state);
|
||||
}
|
||||
|
||||
void macpdm_state::sndo_dma_irq(int state)
|
||||
{
|
||||
m_dma_irq_2 &= ~DMA2_IRQ_SND_OUT;
|
||||
@ -1190,7 +1262,16 @@ void macpdm_state::macpdm(machine_config &config)
|
||||
|
||||
RAM(config, m_ram);
|
||||
m_ram->set_default_size("8M");
|
||||
m_ram->set_extra_options("16M,32M,64M,128M");
|
||||
m_ram->set_extra_options("12M,24M,72M,264M");
|
||||
|
||||
nubus_device &nubus(NUBUS(config, "nubus", 0));
|
||||
nubus.set_space(m_maincpu, AS_PROGRAM);
|
||||
nubus.out_irqc_callback().set(FUNC(macpdm_state::slot0_irq_w));
|
||||
nubus.out_irqd_callback().set(FUNC(macpdm_state::slot1_irq_w));
|
||||
nubus.out_irqe_callback().set(FUNC(macpdm_state::slot2_irq_w));
|
||||
|
||||
// 6100 with the NuBus adapter has one slot, slot $E
|
||||
NUBUS_SLOT(config, "nbe", "nubus", powermac_nubus_cards, nullptr);
|
||||
|
||||
MACADB(config, m_macadb, IO_CLOCK/2);
|
||||
CUDA_V2XX(config, m_cuda, XTAL(32'768));
|
||||
|
Loading…
Reference in New Issue
Block a user