Skip to content

Commit 58b826f

Browse files
committed
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]
1 parent cd3147a commit 58b826f

File tree

4 files changed

+149
-16
lines changed

4 files changed

+149
-16
lines changed

src/devices/bus/nubus/cards.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@ void mac_nubus_cards(device_slot_interface &device)
5252
device.option_add("thunder4gx", NUBUS_THUNDERIVGX); // Radius Thunder IV GX video card
5353
}
5454

55+
void powermac_nubus_cards(device_slot_interface &device)
56+
{
57+
device.option_add("mdc48", NUBUS_MDC48); // Apple Macintosh Display Card 4•8
58+
device.option_add("mdc824", NUBUS_MDC824); // Apple Macintosh Display Card 8•24
59+
device.option_add("cb264", NUBUS_CB264); // RasterOps ColorBoard 264
60+
device.option_add("asmc3nb", NUBUS_ASNTMC3NB); // Asante MC3NB Ethernet card
61+
device.option_add("enetnb", NUBUS_APPLEENET); // Apple NuBus Ethernet
62+
device.option_add("quadralink", NUBUS_QUADRALINK); // AE Quadralink serial card
63+
device.option_add("thunder4gx", NUBUS_THUNDERIVGX); // Radius Thunder IV GX video card
64+
}
5565

5666
void mac_pds030_cards(device_slot_interface &device)
5767
{

src/devices/bus/nubus/cards.h

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#pragma once
1313

1414
void mac_nubus_cards(device_slot_interface &device) ATTR_COLD;
15+
void powermac_nubus_cards(device_slot_interface &device) ATTR_COLD;
1516
void mac_pds030_cards(device_slot_interface &device) ATTR_COLD;
1617
void mac_pdslc_cards(device_slot_interface &device) ATTR_COLD;
1718
void mac_pdslc_orig_cards(device_slot_interface &device) ATTR_COLD;

src/devices/machine/mv_sonora.cpp

+41
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,32 @@ uint32_t mac_video_sonora_device::screen_update(screen_device &screen, bitmap_rg
203203
}
204204
break;
205205

206+
case 1: // 2bpp
207+
for (uint32_t y = 0; y != vres; y++)
208+
{
209+
uint32_t *scanline = &bitmap.pix(y);
210+
for (uint32_t x = 0; x != hres; x += 32)
211+
{
212+
uint64_t pixels = *vram++;
213+
for (int32_t bit = 62; bit >= 0; bit -= 2)
214+
*scanline ++ = pens[(((pixels >> bit) & 0x3) << 6) | 0x3f];
215+
}
216+
}
217+
break;
218+
219+
case 2: // 4bpp
220+
for (uint32_t y = 0; y != vres; y++)
221+
{
222+
uint32_t *scanline = &bitmap.pix(y);
223+
for (uint32_t x = 0; x != hres; x += 16)
224+
{
225+
uint64_t pixels = *vram++;
226+
for (int32_t bit = 60; bit >= 0; bit -= 4)
227+
*scanline ++ = pens[(((pixels >> bit) & 0x0f) << 4) | 0x0f];
228+
}
229+
}
230+
break;
231+
206232
case 3: // 8bpp
207233
for(uint32_t y = 0; y != vres; y++) {
208234
uint32_t *scanline = &bitmap.pix(y);
@@ -214,6 +240,21 @@ uint32_t mac_video_sonora_device::screen_update(screen_device &screen, bitmap_rg
214240
}
215241
break;
216242

243+
case 4: // 16bpp
244+
for (uint32_t y = 0; y != vres; y++)
245+
{
246+
uint32_t *scanline = &bitmap.pix(y);
247+
for (uint32_t x = 0; x != hres; x += 4)
248+
{
249+
const uint64_t pixels = *vram++;
250+
*scanline++ = rgb_t(((pixels >> 58) & 0x1f) << 3, ((pixels >> 53) & 0x1f) << 3, ((pixels >> 48) & 0x1f) << 3);
251+
*scanline++ = rgb_t(((pixels >> 42) & 0x1f) << 3, ((pixels >> 37) & 0x1f) << 3, ((pixels >> 32) & 0x1f) << 3);
252+
*scanline++ = rgb_t(((pixels >> 26) & 0x1f) << 3, ((pixels >> 21) & 0x1f) << 3, ((pixels >> 16) & 0x1f) << 3);
253+
*scanline++ = rgb_t(((pixels >> 10) & 0x1f) << 3, ((pixels >> 5) & 0x1f) << 3, (pixels & 0x1f) << 3);
254+
}
255+
}
256+
break;
257+
217258
default:
218259
bitmap.fill(0xff0000);
219260
break;

src/mame/apple/macpdm.cpp

+97-16
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "bus/nscsi/cd.h"
1010
#include "bus/nscsi/devices.h"
1111
#include "bus/nubus/nubus.h"
12+
#include "bus/nubus/cards.h"
1213
#include "bus/rs232/rs232.h"
1314
#include "cpu/powerpc/ppc.h"
1415
#include "machine/6522via.h"
@@ -120,9 +121,9 @@ class macpdm_state : public driver_device
120121
void sndi_err_irq(int state);
121122

122123
void vblank_irq(int state);
123-
[[maybe_unused]] void slot2_irq(int state);
124-
[[maybe_unused]] void slot1_irq(int state);
125-
void slot0_irq(int state);
124+
void slot2_irq_w(int state);
125+
void slot1_irq_w(int state);
126+
void slot0_irq_w(int state);
126127

127128
void fdc_irq(int state);
128129
void fdc_drq(int state);
@@ -167,6 +168,8 @@ class macpdm_state : public driver_device
167168
uint8_t hmc_r(offs_t offset);
168169
void hmc_w(offs_t offset, uint8_t data);
169170

171+
void ram_size();
172+
170173
uint32_t id_r();
171174

172175
uint8_t diag_r(offs_t offset);
@@ -247,6 +250,7 @@ macpdm_state::macpdm_state(const machine_config &mconfig, device_type type, cons
247250
void macpdm_state::driver_init()
248251
{
249252
m_maincpu->space().install_ram(0, m_ram->mask(), 0, m_ram->pointer());
253+
250254
m_model_id = 0xa55a3011;
251255
// 7100 = a55a3012
252256
// 8100 = a55a3013
@@ -567,22 +571,25 @@ void macpdm_state::scsi_w(offs_t offset, uint8_t data)
567571

568572
uint8_t macpdm_state::hmc_r(offs_t offset)
569573
{
570-
return (m_hmc_reg >> m_hmc_bit) & 1 ? 0x80 : 0x00;
574+
const uint8_t rv = (m_hmc_reg >> m_hmc_bit) & 1;
575+
m_hmc_bit++;
576+
return rv;
571577
}
572578

573579
void macpdm_state::hmc_w(offs_t offset, uint8_t data)
574580
{
575581
if(offset & 8)
576582
m_hmc_bit = 0;
577583
else {
578-
if(data & 0x80)
584+
if(data & 1)
579585
m_hmc_buffer |= u64(1) << m_hmc_bit;
580586
else
581587
m_hmc_buffer &= ~(u64(1) << m_hmc_bit);
582588
m_hmc_bit ++;
583589
if(m_hmc_bit == 35) {
584590
m_hmc_reg = m_hmc_buffer & ~3; // csiz is readonly, we pretend there isn't a l2 cache
585-
m_video->set_vram_offset(m_hmc_reg & 0x200000000 ? 0x100000 : 0);
591+
m_video->set_vram_offset(m_hmc_reg & 0x200000000 ? 0 : 0x100000);
592+
ram_size();
586593
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",
587594
m_hmc_reg & 0x008000000 ? '+' : '-', // l2_en
588595
m_hmc_reg & 0x400000000 ? '3' : '2', // l2_init
@@ -592,19 +599,79 @@ void macpdm_state::hmc_w(offs_t offset, uint8_t data)
592599
m_hmc_reg & 0x200000000 ? '1' : '0', // vbase
593600
m_hmc_reg & 0x100000000 ? " vtst" : "", // vtst
594601
m_hmc_reg & 0x080000000 ? '8' : '4', // mb_ram
595-
(m_hmc_reg >> 29) & 3, // size
602+
(uint32_t)((m_hmc_reg >> 29) & 3), // size
596603
m_hmc_reg & 0x001000000 ? " nblrom" : "", // nblrom
597-
12 - 2*((m_hmc_reg >> 22) & 3), // romd
598-
(m_hmc_reg >> 16) & 0x3f, // rfsh
604+
(uint32_t)(12 - 2*((m_hmc_reg >> 22) & 3)), // romd
605+
(uint32_t)((m_hmc_reg >> 16) & 0x3f), // rfsh
599606
m_hmc_reg & 0x000000008 ? '3' : '2', // winit
600607
m_hmc_reg & 0x000000004 ? '3' : '2', // wbrst
601608
m_hmc_reg & 0x000008000 ? '1' : '2', // wcasp
602609
m_hmc_reg & 0x000004000 ? '1' : '2', // wcasd
603-
3 - ((m_hmc_reg >> 12) & 3), // rdac
604-
6 - ((m_hmc_reg >> 8) & 3), // rasd
605-
5 - ((m_hmc_reg >> 6) & 3), // rasp
606-
4 - ((m_hmc_reg >> 4) & 3)); // rcasd
610+
(uint32_t)(3 - ((m_hmc_reg >> 12) & 3)), // rdac
611+
(uint32_t)(6 - ((m_hmc_reg >> 8) & 3)), // rasd
612+
(uint32_t)(5 - ((m_hmc_reg >> 6) & 3)), // rasp
613+
(uint32_t)(4 - ((m_hmc_reg >> 4) & 3))); // rcasd
614+
}
615+
}
616+
}
617+
618+
/*
619+
PDM uses a variant on the V8/Sonora style memory controller.
620+
- Motherboard RAM can be 4 or 8 MiB
621+
- The hardware officially limits SIMMs to 2, 8, or 32 MiB, and SIMMs must be installed in pairs
622+
- In reality, 128 MiB SIMMs will also work.
623+
- 6100 has only 2 SIMM slots, so valid sizes are 8MiB (no SIMMs), 12MiB (2 MiB SIMM x2),
624+
24MiB (8 MiB SIMM x2), 72MiB (32 MiB SIMM x2), and 264MiB (128 MiB SIMM x2)
625+
- 7100 has 4 SIMM slots, allowing RAM up to 520MiB (128 MiB SIMM x4)
626+
- 8100 has 8 SIMM slots, which add valid sizes up to 264 MiB (32 MiB SIMM x8)
627+
*/
628+
void macpdm_state::ram_size(){
629+
static const uint32_t sizes[4] = { 128*1024*1024, 2*1024*1024, 8*1024*1024, 32*1024*1024 };
630+
const u8 config = (m_hmc_reg >> 29) & 3; // 0 = 128MiB, 1 = 2MiB, 2 = 8MiB, 3 = 32MiB
631+
const u8 mb_size = (m_hmc_reg & 0x00800000) ? 1 : 0;
632+
address_space &space = m_maincpu->space(AS_PROGRAM);
633+
const u32 total_ram = m_ram->size();
634+
const u32 mb_ram_size = (mb_size ? 8*1024*1024 : 4*1024*1024);
635+
636+
// SIMMs must be in identical pairs, so any leftover RAM after the motherboard 8MiB is
637+
// the number of slots times the SIMM size.
638+
const u32 simm_size = (total_ram - mb_ram_size) / 2;
639+
640+
u8 *mb_ram = (u8 *)m_ram->pointer();
641+
u8 *ram_a = mb_ram + mb_ram_size;
642+
u8 *ram_b = ram_a + simm_size;
643+
644+
// unmap the first GB of address space (reserved for RAM)
645+
space.unmap_readwrite(0x00000000, 0x3fffffff);
646+
647+
// map the motherboard 8MB
648+
space.install_ram(0x00000000, 0x007fffff, 0, (void *)mb_ram);
649+
650+
// install RAM A
651+
if (simm_size > 0)
652+
{
653+
if (simm_size <= 8*1024*1024)
654+
{
655+
space.install_ram(mb_ram_size, mb_ram_size + simm_size - 1, 0, (void *)ram_a);
656+
}
657+
else
658+
{
659+
space.install_ram(mb_ram_size, sizes[config] - 1, 0, (void *)(ram_a + mb_ram_size));
607660
}
661+
662+
// 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)
663+
const u32 alias_base = (sizes[config] * 2);
664+
space.install_ram(alias_base, alias_base + simm_size - 1, 0, (void *)ram_a);
665+
666+
// install RAM B
667+
u32 b_base = sizes[config];
668+
669+
if (simm_size < (128*1024*1024))
670+
{
671+
b_base += mb_ram_size;
672+
}
673+
674+
space.install_ram(b_base, b_base + simm_size - 1, 0, (void *)ram_b);
608675
}
609676
}
610677

@@ -680,16 +747,21 @@ void macpdm_state::vblank_irq(int state)
680747
via2_irq_slot_set(0x40, state);
681748
}
682749

683-
void macpdm_state::slot2_irq(int state)
750+
void macpdm_state::slot2_irq_w(int state)
684751
{
685752
via2_irq_slot_set(0x20, state);
686753
}
687754

688-
void macpdm_state::slot1_irq(int state)
755+
void macpdm_state::slot1_irq_w(int state)
689756
{
690757
via2_irq_slot_set(0x10, state);
691758
}
692759

760+
void macpdm_state::slot0_irq_w(int state)
761+
{
762+
via2_irq_slot_set(0x08, state);
763+
}
764+
693765
void macpdm_state::sndo_dma_irq(int state)
694766
{
695767
m_dma_irq_2 &= ~DMA2_IRQ_SND_OUT;
@@ -1190,7 +1262,16 @@ void macpdm_state::macpdm(machine_config &config)
11901262

11911263
RAM(config, m_ram);
11921264
m_ram->set_default_size("8M");
1193-
m_ram->set_extra_options("16M,32M,64M,128M");
1265+
m_ram->set_extra_options("12M,24M,72M,264M");
1266+
1267+
nubus_device &nubus(NUBUS(config, "nubus", 0));
1268+
nubus.set_space(m_maincpu, AS_PROGRAM);
1269+
nubus.out_irqc_callback().set(FUNC(macpdm_state::slot0_irq_w));
1270+
nubus.out_irqd_callback().set(FUNC(macpdm_state::slot1_irq_w));
1271+
nubus.out_irqe_callback().set(FUNC(macpdm_state::slot2_irq_w));
1272+
1273+
// 6100 with the NuBus adapter has one slot, slot $E
1274+
NUBUS_SLOT(config, "nbe", "nubus", powermac_nubus_cards, nullptr);
11941275

11951276
MACADB(config, m_macadb, IO_CLOCK/2);
11961277
CUDA_V2XX(config, m_cuda, XTAL(32'768));

0 commit comments

Comments
 (0)