Geneve: Added boot flash ROM support (PFM)

This commit is contained in:
Michael Zapf 2015-08-22 01:26:39 +02:00
parent a9b74b1d6b
commit bcdecc179c
5 changed files with 334 additions and 166 deletions

View File

@ -168,17 +168,42 @@
Waitstate behavior (Nov 2013) Waitstate behavior (Nov 2013)
Almost perfect. Only video read access from code in DRAM is too fast by one WS Almost perfect. Only video read access from code in DRAM is too fast by one WS
==========================
PFM expansion
==========================
The "Programmable Flash Memory expansion" is a replacement for the boot
EPROM.
PFM: Original version, 128 KiB
PFM+: Expansion of the original version, piggybacked, adds another 128KiB
PFM512: Using an AT29C040 (not A), 512 KiB
The PFM is visible as four banks in memory pages 0xF0 - 0xFF.
Bank switching is done by four 9901 pins:
0028: LSB of bank number
003A: MSB of bank number
Bank 0 is the boot code, while banks 1-3 can be used as flash drives
Michael Zapf, October 2011 Michael Zapf, October 2011
February 2012: rewritten as class, restructured February 2012: rewritten as class, restructured
Aug 2015: PFM added
***************************************************************************/ ***************************************************************************/
#include "genboard.h" #include "genboard.h"
#define VERBOSE 1 #define TRACE_READ 0
#define LOG logerror #define TRACE_WRITE 0
#define TRACE_DETAIL 0
#define TRACE_KEYBOARD 0
#define TRACE_CLOCK 0
#define TRACE_LINES 0
#define TRACE_SETTING 1
#define TRACE_PFM 0
geneve_mapper_device::geneve_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) geneve_mapper_device::geneve_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, GENEVE_MAPPER, "Geneve Gate Array", tag, owner, clock, "geneve_mapper", __FILE__), : device_t(mconfig, GENEVE_MAPPER, "Geneve Gate Array", tag, owner, clock, "geneve_mapper", __FILE__),
@ -187,23 +212,30 @@ geneve_mapper_device::geneve_mapper_device(const machine_config &mconfig, const
m_eprom = NULL; m_eprom = NULL;
} }
INPUT_CHANGED_MEMBER( geneve_mapper_device::gm_changed ) INPUT_CHANGED_MEMBER( geneve_mapper_device::settings_changed )
{ {
int number = (int)((UINT64)param&0x03); int number = (int)((UINT64)param&0x03);
int value = newval; int value = newval;
if (number==1) switch (number)
{ {
case 1:
// Turbo switch. May be changed at any time. // Turbo switch. May be changed at any time.
if (VERBOSE>0) LOG("genboard: Setting turbo flag to %d\n", value); if (TRACE_SETTING) logerror("%s: Setting turbo flag to %d\n", tag(), value);
m_turbo = (value!=0); m_turbo = (value!=0);
} break;
else case 2:
{
// TIMode switch. Causes reset when changed. // TIMode switch. Causes reset when changed.
if (VERBOSE>0) LOG("genboard: Setting timode flag to %d\n", value); if (TRACE_SETTING) logerror("%s: Setting timode flag to %d\n", tag(), value);
m_timode = (value!=0); m_timode = (value!=0);
machine().schedule_hard_reset(); machine().schedule_hard_reset();
break;
case 3:
// Used when switching the boot ROMs during runtime, especially the PFM
set_boot_rom(value);
break;
default:
logerror("%s: Unknown setting %d ignored\n", tag(), number);
} }
} }
@ -294,7 +326,7 @@ void geneve_mapper_device::set_wait(int min)
m_waitcount = min + 1; m_waitcount = min + 1;
if (m_waitcount > 1) if (m_waitcount > 1)
{ {
if (VERBOSE>7) LOG("genboard: Pulling down READY line for %d cycles\n", min); if (TRACE_LINES) logerror("%s: Pulling down READY line for %d cycles\n", tag(), min);
m_ready(CLEAR_LINE); m_ready(CLEAR_LINE);
m_ready_asserted = false; m_ready_asserted = false;
} }
@ -306,6 +338,71 @@ void geneve_mapper_device::set_ext_wait(int min)
m_ext_waitcount = min; m_ext_waitcount = min;
} }
void geneve_mapper_device::set_boot_rom(int selection)
{
switch (selection)
{
case GENEVE_098:
logerror("%s: Using 0.98 boot eprom\n", tag());
m_eprom = machine().root_device().memregion("maincpu")->base() + 0x4000;
m_pfm_mode = 0;
break;
case GENEVE_100:
logerror("%s: Using 1.00 boot eprom\n", tag());
m_eprom = machine().root_device().memregion("maincpu")->base();
m_pfm_mode = 0;
break;
case GENEVE_PFM512:
logerror("%s: Using PFM512 (AT29C040)\n", tag());
m_pfm_mode = 1;
break;
case GENEVE_PFM512A:
logerror("%s: Using PFM512A (AT29C040A)\n", tag());
m_pfm_mode = 2;
break;
default:
logerror("%s: Unknown boot ROM selection\n", tag());
}
}
void geneve_mapper_device::set_geneve_mode(bool geneve)
{
if (TRACE_SETTING) logerror("%s: Setting Geneve mode = %d\n", tag(), geneve);
m_geneve_mode = geneve;
}
void geneve_mapper_device::set_direct_mode(bool direct)
{
if (TRACE_SETTING) logerror("%s: Setting direct mode = %d\n", tag(), direct);
m_direct_mode = direct;
}
void geneve_mapper_device::set_cartridge_size(int size)
{
if (TRACE_SETTING) logerror("%s: Setting cartridge size to %d\n", tag(), size);
m_cartridge_size = size;
}
void geneve_mapper_device::set_cartridge_writable(int base, bool write)
{
if (TRACE_SETTING) logerror("%s: Cartridge %04x space writable = %d\n", tag(), base, write);
if (base==0x6000) m_cartridge6_writable = write;
else m_cartridge7_writable = write;
}
void geneve_mapper_device::set_video_waitstates(bool wait)
{
if (TRACE_SETTING) logerror("%s: Setting video waitstates = %d\n", tag(), wait);
m_video_waitstates = wait;
}
void geneve_mapper_device::set_extra_waitstates(bool wait)
{
if (TRACE_SETTING) logerror("%s: Setting extra waitstates = %d\n", tag(), wait);
m_extra_waitstates = wait;
}
/************************************************************************ /************************************************************************
Called by the address map Called by the address map
************************************************************************/ ************************************************************************/
@ -347,7 +444,6 @@ enum
READ8_MEMBER( geneve_mapper_device::readm ) READ8_MEMBER( geneve_mapper_device::readm )
{ {
UINT8 value = 0; UINT8 value = 0;
assert (m_eprom!=NULL);
decdata *dec; decdata *dec;
decdata debug; decdata debug;
@ -371,7 +467,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
{ {
case MLGVIDEO: case MLGVIDEO:
m_video->readz(space, dec->offset, &value, 0xff); m_video->readz(space, dec->offset, &value, 0xff);
if (VERBOSE>7) LOG("genboard: Read video %04x -> %02x\n", dec->offset, value); if (TRACE_READ) logerror("%s: Read video %04x -> %02x\n", tag(), dec->offset, value);
// Video wait states are created *after* the access // Video wait states are created *after* the access
// Accordingly, they have no effect when execution is in onchip RAM // Accordingly, they have no effect when execution is in onchip RAM
if (m_video_waitstates) set_ext_wait(15); if (m_video_waitstates) set_ext_wait(15);
@ -380,13 +476,13 @@ READ8_MEMBER( geneve_mapper_device::readm )
case MLGMAPPER: case MLGMAPPER:
// mapper // mapper
value = m_map[dec->offset]; value = m_map[dec->offset];
if (VERBOSE>7) LOG("genboard: read mapper %04x -> %02x\n", dec->offset, value); if (TRACE_READ) logerror("%s: read mapper %04x -> %02x\n", tag(), dec->offset, value);
break; break;
case MLGKEY: case MLGKEY:
// key // key
if (!space.debugger_access()) value = m_keyboard->get_recent_key(); if (!space.debugger_access()) value = m_keyboard->get_recent_key();
if (VERBOSE>7) LOG("genboard: Read keyboard -> %02x\n", value); if (TRACE_READ) logerror("%s: Read keyboard -> %02x\n", tag(), value);
break; break;
case MLGCLOCK: case MLGCLOCK:
@ -394,19 +490,19 @@ READ8_MEMBER( geneve_mapper_device::readm )
// tests on the real machine showed that // tests on the real machine showed that
// upper nibble is 0xf (probably because of the location at 0xf130?) // upper nibble is 0xf (probably because of the location at 0xf130?)
value = m_clock->read(space, dec->offset) | 0xf0; value = m_clock->read(space, dec->offset) | 0xf0;
if (VERBOSE>7) LOG("genboard: Read clock %04x -> %02x\n", dec->offset, value); if (TRACE_READ) logerror("%s: Read clock %04x -> %02x\n", tag(), dec->offset, value);
break; break;
case MLTMAPPER: case MLTMAPPER:
// mapper // mapper
value = m_map[dec->offset]; value = m_map[dec->offset];
if (VERBOSE>7) LOG("genboard: Read mapper %04x -> %02x\n", dec->offset, value); if (TRACE_READ) logerror("%s: Read mapper %04x -> %02x\n", tag(), dec->offset, value);
break; break;
case MLTKEY: case MLTKEY:
// key // key
if (!space.debugger_access()) value = m_keyboard->get_recent_key(); if (!space.debugger_access()) value = m_keyboard->get_recent_key();
if (VERBOSE>7) LOG("genboard: Read keyboard -> %02x\n", value); if (TRACE_READ) logerror("%s: Read keyboard -> %02x\n", tag(), value);
break; break;
case MLTCLOCK: case MLTCLOCK:
@ -420,7 +516,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
// value floating around. // value floating around.
value = m_clock->read(space, dec->offset); value = m_clock->read(space, dec->offset);
value |= (dec->offset==0x000f)? 0x20 : 0x10; value |= (dec->offset==0x000f)? 0x20 : 0x10;
if (VERBOSE>7) LOG("genboard: Read clock %04x -> %02x\n", dec->offset, value); if (TRACE_READ) logerror("%s: Read clock %04x -> %02x\n", tag(), dec->offset, value);
break; break;
case MLTVIDEO: case MLTVIDEO:
@ -428,7 +524,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
// ++++ ++-- ---- ---+ // ++++ ++-- ---- ---+
// 1000 1000 0000 00x0 // 1000 1000 0000 00x0
m_video->readz(space, dec->offset, &value, 0xff); m_video->readz(space, dec->offset, &value, 0xff);
if (VERBOSE>7) LOG("genboard: Read video %04x -> %02x\n", dec->offset, value); if (TRACE_READ) logerror("%s: Read video %04x -> %02x\n", tag(), dec->offset, value);
// See above // See above
if (m_video_waitstates) set_ext_wait(15); if (m_video_waitstates) set_ext_wait(15);
break; break;
@ -439,7 +535,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
// 1001 0000 0000 0000 // 1001 0000 0000 0000
// We need to add the address prefix bits // We need to add the address prefix bits
m_peribox->readz(space, dec->offset, &value, 0xff); m_peribox->readz(space, dec->offset, &value, 0xff);
if (VERBOSE>7) LOG("genboard: Read speech -> %02x\n", value); if (TRACE_READ) logerror("%s: Read speech -> %02x\n", tag(), value);
break; break;
case MLTGROM: case MLTGROM:
@ -447,7 +543,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
// ++++ ++-- ---- ---+ // ++++ ++-- ---- ---+
// 1001 1000 0000 00x0 // 1001 1000 0000 00x0
if (!space.debugger_access()) value = read_grom(space, dec->offset, 0xff); if (!space.debugger_access()) value = read_grom(space, dec->offset, 0xff);
if (VERBOSE>7) LOG("genboard: Read GROM %04x -> %02x\n", dec->offset, value); if (TRACE_READ) logerror("%s: Read GROM %04x -> %02x\n", tag(), dec->offset, value);
break; break;
case MLGSOUND: case MLGSOUND:
@ -460,20 +556,25 @@ READ8_MEMBER( geneve_mapper_device::readm )
// DRAM. // DRAM.
value = m_dram[dec->physaddr]; value = m_dram[dec->physaddr];
// LOG("dram read physaddr = %06x logaddr = %04x value = %02x\n", dec->physaddr, dec->offset, value); // LOG("dram read physaddr = %06x logaddr = %04x value = %02x\n", dec->physaddr, dec->offset, value);
if (VERBOSE>7) LOG("genboard: Read DRAM %04x (%06x) -> %02x\n", dec->offset, dec->physaddr, value); if (TRACE_READ) logerror("%s: Read DRAM %04x (%06x) -> %02x\n", tag(), dec->offset, dec->physaddr, value);
break; break;
case MPGEXP: case MPGEXP:
// On-board memory expansion for standard Geneve (never used) // On-board memory expansion for standard Geneve (never used)
if (VERBOSE>7) LOG("genboard: Read unmapped area %06x\n", dec->physaddr); if (TRACE_READ) logerror("%s: Read unmapped area %06x\n", tag(), dec->physaddr);
value = 0; value = 0;
break; break;
case MPGEPROM: case MPGEPROM:
// 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K) // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
// mirrored for f0, f2, f4, ...; f1, f3, f5, ... // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
value = m_eprom[dec->physaddr]; if (m_pfm_mode == 0)
if (VERBOSE>7) LOG("genboard: Read EPROM %04x (%06x) -> %02x\n", dec->offset, dec->physaddr, value); {
value = m_eprom[dec->physaddr & 0x003fff];
if (TRACE_READ) logerror("%s: Read EPROM %04x (%06x) -> %02x\n", tag(), dec->offset, dec->physaddr, value);
}
else value = read_from_pfm(space, dec->physaddr, 0xff);
break; break;
case MPGSRAM: case MPGSRAM:
@ -484,7 +585,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
else value = 0; else value = 0;
// Return in any case // Return in any case
// LOG("sram read physaddr = %06x logaddr = %04x value = %02x\n", dec->physaddr, dec->offset, value); // LOG("sram read physaddr = %06x logaddr = %04x value = %02x\n", dec->physaddr, dec->offset, value);
if (VERBOSE>7) LOG("genboard: Read SRAM %04x (%06x) -> %02x\n", dec->offset, dec->physaddr, value); if (TRACE_READ) logerror("%s: Read SRAM %04x (%06x) -> %02x\n", tag(), dec->offset, dec->physaddr, value);
break; break;
case MPGBOX: case MPGBOX:
@ -493,7 +594,7 @@ READ8_MEMBER( geneve_mapper_device::readm )
// 0x000000-0x1fffff for the GenMod.(AME,AMD,AMC,AMB,AMA,A0 ...,A15) // 0x000000-0x1fffff for the GenMod.(AME,AMD,AMC,AMB,AMA,A0 ...,A15)
m_peribox->readz(space, dec->physaddr, &value, 0xff); m_peribox->readz(space, dec->physaddr, &value, 0xff);
if (VERBOSE>7) LOG("genboard: Read P-Box %04x (%06x) -> %02x\n", dec->offset, dec->physaddr, value); if (TRACE_READ) logerror("%s: Read P-Box %04x (%06x) -> %02x\n", tag(), dec->offset, dec->physaddr, value);
break; break;
case MPGMDRAM: case MPGMDRAM:
@ -504,7 +605,12 @@ READ8_MEMBER( geneve_mapper_device::readm )
case MPGMEPROM: case MPGMEPROM:
// 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K) // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
// mirrored for f0, f2, f4, ...; f1, f3, f5, ... // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
value = m_eprom[dec->physaddr]; if (m_pfm_mode == 0)
{
value = m_eprom[dec->physaddr & 0x003fff];
if (TRACE_READ) logerror("%s: Read EPROM %04x (%06x) -> %02x\n", tag(), dec->offset, dec->physaddr, value);
}
else value = read_from_pfm(space, dec->physaddr, 0xff);
break; break;
case MPGMBOX: case MPGMBOX:
@ -541,7 +647,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
// ++++ ++++ ++++ ---+ // ++++ ++++ ++++ ---+
// 1111 0001 0000 .cc0 // 1111 0001 0000 .cc0
m_video->write(space, dec->offset, data, 0xff); m_video->write(space, dec->offset, data, 0xff);
if (VERBOSE>7) LOG("genboard: Write video %04x <- %02x\n", offset, data); if (TRACE_WRITE) logerror("%s: Write video %04x <- %02x\n", tag(), offset, data);
// See above // See above
if (m_video_waitstates) set_ext_wait(15); if (m_video_waitstates) set_ext_wait(15);
break; break;
@ -549,33 +655,33 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
case MLGMAPPER: case MLGMAPPER:
// mapper // mapper
m_map[dec->offset] = data; m_map[dec->offset] = data;
if (VERBOSE>7) LOG("genboard: Write mapper %04x <- %02x\n", offset, data); if (TRACE_WRITE) logerror("%s: Write mapper %04x <- %02x\n", tag(), offset, data);
break; break;
case MLGCLOCK: case MLGCLOCK:
// clock // clock
// ++++ ++++ ++++ ---- // ++++ ++++ ++++ ----
m_clock->write(space, dec->offset, data); m_clock->write(space, dec->offset, data);
if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data); if (TRACE_WRITE) logerror("%s: Write clock %04x <- %02x\n", tag(), offset, data);
break; break;
case MLGSOUND: case MLGSOUND:
// sound // sound
// ++++ ++++ ++++ ---+ // ++++ ++++ ++++ ---+
m_sound->write(space, 0, data, 0xff); m_sound->write(space, 0, data, 0xff);
if (VERBOSE>7) LOG("genboard: Write sound <- %02x\n", data); if (TRACE_WRITE) logerror("%s: Write sound <- %02x\n", tag(), data);
break; break;
case MLTMAPPER: case MLTMAPPER:
// mapper // mapper
m_map[dec->offset] = data; m_map[dec->offset] = data;
if (VERBOSE>7) LOG("genboard: Write mapper %04x <- %02x\n", offset, data); if (TRACE_WRITE) logerror("%s: Write mapper %04x <- %02x\n", tag(), offset, data);
break; break;
case MLTCLOCK: case MLTCLOCK:
// clock // clock
m_clock->write(space, dec->offset, data); m_clock->write(space, dec->offset, data);
if (VERBOSE>7) LOG("genboard: Write clock %04x <- %02x\n", offset, data); if (TRACE_WRITE) logerror("%s: Write clock %04x <- %02x\n", tag(), offset, data);
break; break;
case MLTVIDEO: case MLTVIDEO:
@ -584,7 +690,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
// 1000 1100 0000 00c0 // 1000 1100 0000 00c0
// Initialize waitstate timer // Initialize waitstate timer
m_video->write(space, dec->offset, data, 0xff); m_video->write(space, dec->offset, data, 0xff);
if (VERBOSE>7) LOG("genboard: Write video %04x <- %02x\n", offset, data); if (TRACE_WRITE) logerror("%s: Write video %04x <- %02x\n", tag(), offset, data);
// See above // See above
if (m_video_waitstates) set_ext_wait(15); if (m_video_waitstates) set_ext_wait(15);
break; break;
@ -595,7 +701,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
// 1001 0100 0000 0000 // 1001 0100 0000 0000
// We need to add the address prefix bits // We need to add the address prefix bits
m_peribox->write(space, dec->offset, data, 0xff); m_peribox->write(space, dec->offset, data, 0xff);
if (VERBOSE>7) LOG("genboard: Write speech <- %02x\n", data); if (TRACE_WRITE) logerror("%s: Write speech <- %02x\n", tag(), data);
break; break;
case MLTGROM: case MLTGROM:
@ -603,7 +709,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
// ++++ ++-- ---- ---+ // ++++ ++-- ---- ---+
// 1001 1100 0000 00c0 // 1001 1100 0000 00c0
write_grom(space, dec->offset, data, 0xff); write_grom(space, dec->offset, data, 0xff);
if (VERBOSE>7) LOG("genboard: Write GROM %04x <- %02x\n", offset, data); if (TRACE_WRITE) logerror("%s: Write GROM %04x <- %02x\n", tag(), offset, data);
break; break;
case MLTSOUND: case MLTSOUND:
@ -611,7 +717,7 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
// ++++ ++-- ---- ---+ // ++++ ++-- ---- ---+
// 1000 0100 0000 0000 // 1000 0100 0000 0000
m_sound->write(space, 0, data, 0xff); m_sound->write(space, 0, data, 0xff);
if (VERBOSE>7) LOG("genboard: Write sound <- %02x\n", data); if (TRACE_WRITE) logerror("%s: Write sound <- %02x\n", tag(), data);
break; break;
case MLTKEY: case MLTKEY:
@ -621,19 +727,21 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
case MPGDRAM: case MPGDRAM:
// DRAM write. One wait state. (only for normal Geneve) // DRAM write. One wait state. (only for normal Geneve)
m_dram[dec->physaddr] = data; m_dram[dec->physaddr] = data;
if (VERBOSE>7) LOG("genboard: Write DRAM %04x (%06x) <- %02x\n", offset, dec->physaddr, data); if (TRACE_WRITE) logerror("%s: Write DRAM %04x (%06x) <- %02x\n", tag(), offset, dec->physaddr, data);
break; break;
case MPGEXP: case MPGEXP:
// On-board memory expansion for standard Geneve (never used) // On-board memory expansion for standard Geneve (never used)
if (VERBOSE>7) LOG("genboard: Write unmapped area %06x\n", dec->physaddr); if (TRACE_WRITE) logerror("%s: Write unmapped area %06x\n", tag(), dec->physaddr);
break; break;
case MPGEPROM: case MPGEPROM:
// 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K) // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
// mirrored for f0, f2, f4, ...; f1, f3, f5, ... // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
// Ignore EPROM write // Ignore EPROM write (unless PFM)
if (VERBOSE>7) LOG("genboard: Write EPROM %04x (%06x) <- %02x, ignored\n", offset, dec->physaddr, data); if (m_pfm_mode != 0) write_to_pfm(space, dec->physaddr, data, 0xff);
else
logerror("%s: Write EPROM %04x (%06x) <- %02x, ignored\n", tag(), offset, dec->physaddr, data);
break; break;
case MPGSRAM: case MPGSRAM:
@ -641,12 +749,12 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
{ {
m_sram[dec->physaddr & ~m_sram_mask] = data; m_sram[dec->physaddr & ~m_sram_mask] = data;
} }
if (VERBOSE>7) LOG("genboard: Write SRAM %04x (%06x) <- %02x\n", offset, dec->physaddr, data); if (TRACE_WRITE) logerror("%s: Write SRAM %04x (%06x) <- %02x\n", tag(), offset, dec->physaddr, data);
break; break;
case MPGBOX: case MPGBOX:
dec->physaddr = (dec->physaddr & 0x0007ffff); // 19 bit address dec->physaddr = (dec->physaddr & 0x0007ffff); // 19 bit address
if (VERBOSE>7) LOG("genboard: Write P-Box %04x (%06x) <- %02x\n", offset, dec->physaddr, data); if (TRACE_WRITE) logerror("%s: Write P-Box %04x (%06x) <- %02x\n", tag(), offset, dec->physaddr, data);
m_peribox->write(space, dec->physaddr, data, 0xff); m_peribox->write(space, dec->physaddr, data, 0xff);
break; break;
@ -659,6 +767,9 @@ WRITE8_MEMBER( geneve_mapper_device::writem )
// 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K) // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
// mirrored for f0, f2, f4, ...; f1, f3, f5, ... // mirrored for f0, f2, f4, ...; f1, f3, f5, ...
// Ignore EPROM write // Ignore EPROM write
if (m_pfm_mode != 0) write_to_pfm(space, dec->physaddr, data, 0xff);
else
logerror("%s: Write EPROM %04x (%06x) <- %02x, ignored\n", tag(), offset, dec->physaddr, data);
break; break;
case MPGMBOX: case MPGMBOX:
@ -784,7 +895,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
// Determine physical address // Determine physical address
if (m_direct_mode) if (m_direct_mode)
{ {
dec->physaddr = 0x1e0000; // points to boot eprom dec->physaddr = 0x1f0000; // points to boot eprom (page F8)
} }
else else
{ {
@ -822,9 +933,8 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
if ((dec->physaddr & 0x1e0000)==0x1e0000) if ((dec->physaddr & 0x1e0000)==0x1e0000)
{ {
// 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K) // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
// mirrored for f0, f2, f4, ...; f1, f3, f5, ... // mirrored for f0, f2, f4, ...; f1, f3, f5, ... unless using PFM
dec->function = MPGEPROM; dec->function = MPGEPROM;
dec->physaddr = dec->physaddr & 0x003fff;
set_wait(0); set_wait(0);
return; return;
} }
@ -862,9 +972,8 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
if ((dec->physaddr & 0x1e0000)==0x1e0000) if ((dec->physaddr & 0x1e0000)==0x1e0000)
{ {
// 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K) // 1 111. ..xx xxxx xxxx xxxx on-board eprom (16K)
// mirrored for f0, f2, f4, ...; f1, f3, f5, ... // mirrored for f0, f2, f4, ...; f1, f3, f5, ... unless using PFM
dec->function = MPGMEPROM; dec->function = MPGMEPROM;
dec->physaddr = dec->physaddr & 0x003fff;
set_wait(0); set_wait(0);
return; return;
} }
@ -983,7 +1092,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
if (m_cartridge_size==0x4000) if (m_cartridge_size==0x4000)
{ {
m_cartridge_secondpage = ((dec->offset & 0x0002)!=0); m_cartridge_secondpage = ((dec->offset & 0x0002)!=0);
if (VERBOSE>7) LOG("genboard: Set cartridge page %02x\n", m_cartridge_secondpage); if (TRACE_WRITE) logerror("%s: Set cartridge page %02x\n", tag(), m_cartridge_secondpage);
set_wait(1); set_wait(1);
return; return;
} }
@ -993,7 +1102,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
if ((((dec->offset & 0x1000)==0x0000) && !m_cartridge6_writable) if ((((dec->offset & 0x1000)==0x0000) && !m_cartridge6_writable)
|| (((dec->offset & 0x1000)==0x1000) && !m_cartridge7_writable)) || (((dec->offset & 0x1000)==0x1000) && !m_cartridge7_writable))
{ {
if (VERBOSE>0) LOG("genboard: Writing to protected cartridge space %04x ignored\n", dec->offset); logerror("%s: Writing to protected cartridge space %04x ignored\n", tag(), dec->offset);
return; return;
} }
else else
@ -1049,7 +1158,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
{ {
// GenMod mode // GenMod mode
if ((dec->physaddr & 0x1e0000)==0x1e0000) if ((dec->physaddr & 0x1e0000)==0x1e0000)
{ // EPROM, ignore { // EPROM, ignore (unless PFM)
dec->function = MPGMEPROM; dec->function = MPGMEPROM;
set_wait(0); set_wait(0);
return; return;
@ -1072,6 +1181,54 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
} }
} }
/*
Read from PFM.
*/
READ8_MEMBER( geneve_mapper_device::read_from_pfm )
{
UINT8 value = 0;
if (!m_pfm_output_enable) return 0;
int address = (offset & 0x01ffff) | (m_pfm_bank<<17);
switch (m_pfm_mode)
{
case 1:
value = m_pfm512->read(space, address, mem_mask);
break;
case 2:
value = m_pfm512a->read(space, address, mem_mask);
break;
default:
logerror("%s: Illegal mode for reading PFM: %d\n", tag(), m_pfm_mode);
return 0;
}
if (TRACE_PFM) logerror("%s: Reading from PFM at address %05x -> %02x\n", tag(), address, value);
return value;
}
WRITE8_MEMBER( geneve_mapper_device::write_to_pfm )
{
// Nota bene: The PFM must be write protected on startup, or the RESET
// of the 9995 will attempt to write the return vector into the flash EEPROM
int address = (offset & 0x01ffff) | (m_pfm_bank<<17);
if (TRACE_PFM) logerror("%s: Writing to PFM at address %05x <- %02x\n", tag(), address, data);
switch (m_pfm_mode)
{
case 1:
m_pfm512->write(space, address, data, mem_mask);
break;
case 2:
m_pfm512a->write(space, address, data, mem_mask);
break;
default:
logerror("%s: Illegal mode for writing to PFM: %d\n", tag(), m_pfm_mode);
}
}
/* /*
Accept the address passed over the address bus and decode it appropriately. Accept the address passed over the address bus and decode it appropriately.
This decoding will later be used in the READ/WRITE member functions. Also, This decoding will later be used in the READ/WRITE member functions. Also,
@ -1079,7 +1236,7 @@ void geneve_mapper_device::decode(address_space& space, offs_t offset, bool read
*/ */
SETOFFSET_MEMBER( geneve_mapper_device::setoffset ) SETOFFSET_MEMBER( geneve_mapper_device::setoffset )
{ {
if (VERBOSE>7) LOG("genboard: setoffset = %04x\n", offset); if (TRACE_DETAIL) logerror("%s: setoffset = %04x\n", tag(), offset);
m_debug_no_ws = false; m_debug_no_ws = false;
decode(space, offset, m_read_mode, &m_decoded); decode(space, offset, m_read_mode, &m_decoded);
} }
@ -1108,13 +1265,13 @@ WRITE_LINE_MEMBER( geneve_mapper_device::clock_in )
m_waitcount--; m_waitcount--;
if (m_waitcount == 0) if (m_waitcount == 0)
{ {
if (VERBOSE>5) LOG("genboard: clock, READY asserted\n"); if (TRACE_CLOCK) logerror("%s: clock, READY asserted\n", tag());
m_ready(ASSERT_LINE); m_ready(ASSERT_LINE);
m_ready_asserted = true; m_ready_asserted = true;
} }
else else
{ {
if (VERBOSE>5) LOG("genboard: clock\n"); if (TRACE_CLOCK) logerror("%s: clock\n", tag());
} }
} }
else else
@ -1124,13 +1281,13 @@ WRITE_LINE_MEMBER( geneve_mapper_device::clock_in )
m_ext_waitcount--; m_ext_waitcount--;
if (m_ext_waitcount == 0) if (m_ext_waitcount == 0)
{ {
if (VERBOSE>5) LOG("genboard: clock, READY asserted after video\n"); if (TRACE_CLOCK) logerror("%s: clock, READY asserted after video\n", tag());
m_ready(ASSERT_LINE); m_ready(ASSERT_LINE);
m_ready_asserted = true; m_ready_asserted = true;
} }
else else
{ {
if (VERBOSE>5) LOG("genboard: vclock, ew=%d\n", m_ext_waitcount); if (TRACE_CLOCK) logerror("%s: vclock, ew=%d\n", tag(), m_ext_waitcount);
} }
} }
} }
@ -1142,7 +1299,7 @@ WRITE_LINE_MEMBER( geneve_mapper_device::clock_in )
// Do we have video wait states? In that case, clear the line again // Do we have video wait states? In that case, clear the line again
if ((m_waitcount == 0) && (m_ext_waitcount > 0) && m_ready_asserted) if ((m_waitcount == 0) && (m_ext_waitcount > 0) && m_ready_asserted)
{ {
if (VERBOSE>5) LOG("genboard: clock, READY cleared for video\n"); if (TRACE_CLOCK) logerror("%s: clock, READY cleared for video\n", tag());
m_ready(CLEAR_LINE); m_ready(CLEAR_LINE);
m_ready_asserted = false; m_ready_asserted = false;
} }
@ -1155,14 +1312,39 @@ WRITE_LINE_MEMBER( geneve_mapper_device::clock_in )
WRITE_LINE_MEMBER( geneve_mapper_device::dbin_in ) WRITE_LINE_MEMBER( geneve_mapper_device::dbin_in )
{ {
m_read_mode = (state==ASSERT_LINE); m_read_mode = (state==ASSERT_LINE);
if (VERBOSE>7) LOG("genboard: dbin = %02x\n", m_read_mode? 1:0); if (TRACE_DETAIL) logerror("%s: dbin = %02x\n", tag(), m_read_mode? 1:0);
} }
/*** DEVICE LIFECYCLE FUNCTIONS ***/ /*
PFM expansion: Setting the bank.
*/
WRITE_LINE_MEMBER( geneve_mapper_device::pfm_select_lsb )
{
if (state==ASSERT_LINE) m_pfm_bank |= 1;
else m_pfm_bank &= 0xfe;
logerror("%s: Setting bank (l) = %d\n", tag(), m_pfm_bank);
}
WRITE_LINE_MEMBER( geneve_mapper_device::pfm_select_msb )
{
if (state==ASSERT_LINE) m_pfm_bank |= 2;
else m_pfm_bank &= 0xfd;
logerror("%s: Setting bank (u) = %d\n", tag(), m_pfm_bank);
}
WRITE_LINE_MEMBER( geneve_mapper_device::pfm_output_enable )
{
// Negative logic
m_pfm_output_enable = (state==CLEAR_LINE);
logerror("%s: PFM output %s\n", tag(), m_pfm_output_enable? "enable" : "disable");
}
//====================================================================
// Common device lifecycle
//====================================================================
void geneve_mapper_device::device_start() void geneve_mapper_device::device_start()
{ {
if (VERBOSE>0) LOG("genboard: Starting Geneve mapper\n");
// Get pointers // Get pointers
m_peribox = machine().device<bus8z_device>(PERIBOX_TAG); m_peribox = machine().device<bus8z_device>(PERIBOX_TAG);
m_keyboard = machine().device<geneve_keyboard_device>(GKEYBOARD_TAG); m_keyboard = machine().device<geneve_keyboard_device>(GKEYBOARD_TAG);
@ -1170,6 +1352,10 @@ void geneve_mapper_device::device_start()
m_sound = machine().device<bus8z_device>(TISOUND_TAG); m_sound = machine().device<bus8z_device>(TISOUND_TAG);
m_clock = machine().device<mm58274c_device>(GCLOCK_TAG); m_clock = machine().device<mm58274c_device>(GCLOCK_TAG);
// PFM expansion
m_pfm512 = machine().device<at29c040_device>(PFM512_TAG);
m_pfm512a = machine().device<at29c040a_device>(PFM512A_TAG);
m_ready.resolve(); m_ready.resolve();
m_sram = machine().root_device().memregion(SRAM_TAG)->base(); m_sram = machine().root_device().memregion(SRAM_TAG)->base();
@ -1182,8 +1368,6 @@ void geneve_mapper_device::device_start()
void geneve_mapper_device::device_reset() void geneve_mapper_device::device_reset()
{ {
if (VERBOSE>1) LOG("genboard: Resetting mapper\n");
m_extra_waitstates = false; m_extra_waitstates = false;
m_video_waitstates = true; m_video_waitstates = true;
m_read_mode = false; m_read_mode = false;
@ -1198,33 +1382,25 @@ void geneve_mapper_device::device_reset()
m_cartridge6_writable = false; m_cartridge6_writable = false;
m_cartridge7_writable = false; m_cartridge7_writable = false;
m_grom_address = 0; m_grom_address = 0;
m_pfm_bank = 0;
m_pfm_output_enable = true;
// Clear map // Clear map
for (int i=0; i < 8; i++) m_map[i] = 0; for (int i=0; i < 8; i++) m_map[i] = 0;
m_genmod = false; m_genmod = false;
if (machine().root_device().ioport("MODE")->read()==0) // Check which boot EPROM we are using (or PFM)
set_boot_rom(machine().root_device().ioport("BOOTROM")->read());
// Check for GenMod. We assume that GenMod can be combined with PFM.
if (machine().root_device().ioport("MODE")->read()!=0)
{ {
switch (machine().root_device().ioport("BOOTROM")->read()) logerror("%s: Using GenMod modification\n", tag());
{
case GENEVE_098:
if (VERBOSE>0) LOG("genboard: Using 0.98 boot eprom\n");
m_eprom = machine().root_device().memregion("maincpu")->base() + 0x4000;
break;
case GENEVE_100:
if (VERBOSE>0) LOG("genboard: Using 1.00 boot eprom\n");
m_eprom = machine().root_device().memregion("maincpu")->base();
break;
}
}
else
{
if (VERBOSE>0) LOG("genboard: Using GenMod modification\n");
m_eprom = machine().root_device().memregion("maincpu")->base() + 0x8000; m_eprom = machine().root_device().memregion("maincpu")->base() + 0x8000;
if (m_eprom[0] != 0xf0) if (m_eprom[0] != 0xf0)
{ {
fatalerror("genboard: GenMod boot rom missing.\n"); fatalerror("genboard: GenMod boot ROM missing\n");
} }
m_genmod = true; m_genmod = true;
m_turbo = ((machine().root_device().ioport("GENMODDIPS")->read() & GM_TURBO)!=0); m_turbo = ((machine().root_device().ioport("GENMODDIPS")->read() & GM_TURBO)!=0);
@ -1301,7 +1477,7 @@ void geneve_keyboard_device::post_in_key_queue(int keycode)
m_key_queue[(m_key_queue_head + m_key_queue_length) % KEYQUEUESIZE] = keycode; m_key_queue[(m_key_queue_head + m_key_queue_length) % KEYQUEUESIZE] = keycode;
m_key_queue_length++; m_key_queue_length++;
if (VERBOSE>5) LOG("genboard: posting keycode %02x\n", keycode); if (TRACE_KEYBOARD) logerror("%s: Posting keycode %02x\n", tag(), keycode);
} }
void geneve_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) void geneve_keyboard_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
@ -1316,7 +1492,7 @@ void geneve_keyboard_device::poll()
int i, j; int i, j;
int keycode; int keycode;
int pressed; int pressed;
if (VERBOSE>7) LOG("genboard: poll keyboard\n"); if (TRACE_KEYBOARD) logerror("%s: Poll keyboard\n", tag());
if (m_key_reset) return; if (m_key_reset) return;
/* Poll keyboard */ /* Poll keyboard */
@ -1522,7 +1698,7 @@ void geneve_keyboard_device::signal_when_key_available()
// buffer clear is disabled, and key queue is not empty. */ // buffer clear is disabled, and key queue is not empty. */
if ((!m_key_reset) && (m_keyboard_clock) && (m_keep_keybuf) && (m_key_queue_length != 0)) if ((!m_key_reset) && (m_keyboard_clock) && (m_keep_keybuf) && (m_key_queue_length != 0))
{ {
if (VERBOSE>6) LOG("genboard: signalling key available\n"); if (TRACE_KEYBOARD) logerror("%s: Signalling key available\n", tag());
m_interrupt(ASSERT_LINE); m_interrupt(ASSERT_LINE);
m_key_in_buffer = true; m_key_in_buffer = true;
} }
@ -1532,7 +1708,7 @@ WRITE_LINE_MEMBER( geneve_keyboard_device::clock_control )
{ {
bool rising_edge = (!m_keyboard_clock && (state==ASSERT_LINE)); bool rising_edge = (!m_keyboard_clock && (state==ASSERT_LINE));
m_keyboard_clock = (state==ASSERT_LINE); m_keyboard_clock = (state==ASSERT_LINE);
if (VERBOSE>5) LOG("genboard: keyboard clock_control state=%d\n", m_keyboard_clock); if (TRACE_KEYBOARD) logerror("%s: Keyboard clock_control state=%d\n", tag(), m_keyboard_clock);
if (rising_edge) if (rising_edge)
signal_when_key_available(); signal_when_key_available();
} }
@ -1582,7 +1758,6 @@ WRITE_LINE_MEMBER( geneve_keyboard_device::reset_line )
void geneve_keyboard_device::device_start() void geneve_keyboard_device::device_start()
{ {
if (VERBOSE>2) LOG("genboard: Keyboard started\n");
m_timer = timer_alloc(0); m_timer = timer_alloc(0);
m_interrupt.resolve(); m_interrupt.resolve();
} }

View File

@ -18,6 +18,7 @@
#include "machine/mm58274c.h" #include "machine/mm58274c.h"
#include "video/v9938.h" #include "video/v9938.h"
#include "cpu/tms9900/tms9995.h" #include "cpu/tms9900/tms9995.h"
#include "machine/at29x.h"
extern const device_type GENEVE_MOUSE; extern const device_type GENEVE_MOUSE;
extern const device_type GENEVE_KEYBOARD; extern const device_type GENEVE_KEYBOARD;
@ -109,25 +110,27 @@ class geneve_mapper_device : public device_t
{ {
public: public:
geneve_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); geneve_mapper_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
inline void set_geneve_mode(bool geneve) { m_geneve_mode = geneve; } void set_geneve_mode(bool geneve);
inline void set_direct_mode(bool direct) { m_direct_mode = direct; } void set_direct_mode(bool direct);
inline void set_cartridge_size(int size) { m_cartridge_size = size; } void set_cartridge_size(int size);
inline void set_cartridge_writable(int base, bool write) void set_cartridge_writable(int base, bool write);
{ void set_video_waitstates(bool wait);
if (base==0x6000) m_cartridge6_writable = write; void set_extra_waitstates(bool wait);
else m_cartridge7_writable = write;
}
inline void set_video_waitstates(bool wait) { m_video_waitstates = wait; }
inline void set_extra_waitstates(bool wait) { m_extra_waitstates = wait; }
DECLARE_READ8_MEMBER( readm ); DECLARE_READ8_MEMBER( readm );
DECLARE_WRITE8_MEMBER( writem ); DECLARE_WRITE8_MEMBER( writem );
DECLARE_SETOFFSET_MEMBER( setoffset ); DECLARE_SETOFFSET_MEMBER( setoffset );
DECLARE_INPUT_CHANGED_MEMBER( gm_changed ); DECLARE_INPUT_CHANGED_MEMBER( settings_changed );
DECLARE_WRITE_LINE_MEMBER( clock_in ); DECLARE_WRITE_LINE_MEMBER( clock_in );
DECLARE_WRITE_LINE_MEMBER( dbin_in ); DECLARE_WRITE_LINE_MEMBER( dbin_in );
// PFM support
DECLARE_WRITE_LINE_MEMBER( pfm_select_lsb );
DECLARE_WRITE_LINE_MEMBER( pfm_select_msb );
DECLARE_WRITE_LINE_MEMBER( pfm_output_enable );
template<class _Object> static devcb_base &static_set_ready_callback(device_t &device, _Object object) { return downcast<geneve_mapper_device &>(device).m_ready.set_callback(object); } template<class _Object> static devcb_base &static_set_ready_callback(device_t &device, _Object object) { return downcast<geneve_mapper_device &>(device).m_ready.set_callback(object); }
protected: protected:
@ -177,6 +180,15 @@ private:
bool m_genmod; bool m_genmod;
bool m_timode; bool m_timode;
// PFM mod (0 = none, 1 = AT29C040, 2 = AT29C040A)
DECLARE_READ8_MEMBER( read_from_pfm );
DECLARE_WRITE8_MEMBER( write_to_pfm );
void set_boot_rom(int selection);
int m_pfm_mode;
int m_pfm_bank;
bool m_pfm_output_enable;
// SRAM access
int m_sram_mask; int m_sram_mask;
int m_sram_val; int m_sram_val;
@ -190,6 +202,8 @@ private:
// Devices // Devices
mm58274c_device* m_clock; mm58274c_device* m_clock;
tms9995_device* m_cpu; tms9995_device* m_cpu;
at29c040_device* m_pfm512;
at29c040a_device* m_pfm512a;
geneve_keyboard_device* m_keyboard; geneve_keyboard_device* m_keyboard;
bus8z_device* m_video; bus8z_device* m_video;

View File

@ -51,6 +51,8 @@
#define GMAPPER_TAG "gmapper" #define GMAPPER_TAG "gmapper"
#define GMOUSE_TAG "gmouse" #define GMOUSE_TAG "gmouse"
#define GCLOCK_TAG "mm58274c" #define GCLOCK_TAG "mm58274c"
#define PFM512_TAG "pfm512"
#define PFM512A_TAG "pfm512a"
#define READ16Z_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 *value, ATTR_UNUSED UINT16 mem_mask) #define READ16Z_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 *value, ATTR_UNUSED UINT16 mem_mask)
#define DECLARE_READ16Z_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 *value, ATTR_UNUSED UINT16 mem_mask = 0xffff) #define DECLARE_READ16Z_MEMBER(name) void name(ATTR_UNUSED address_space &space, ATTR_UNUSED offs_t offset, ATTR_UNUSED UINT16 *value, ATTR_UNUSED UINT16 mem_mask = 0xffff)
@ -106,7 +108,9 @@ enum
enum enum
{ {
GENEVE_098 = 0, GENEVE_098 = 0,
GENEVE_100 = 1 GENEVE_100,
GENEVE_PFM512,
GENEVE_PFM512A
}; };
#endif #endif

View File

@ -39,11 +39,11 @@
#include "at29x.h" #include "at29x.h"
#define TRACE_PRG 1 #define TRACE_PRG 0
#define TRACE_READ 0 #define TRACE_READ 0
#define TRACE_WRITE 1 #define TRACE_WRITE 0
#define TRACE_CONFIG 1 #define TRACE_CONFIG 0
#define TRACE_STATE 1 #define TRACE_STATE 0
enum enum
{ {
@ -228,7 +228,7 @@ READ8_MEMBER( at29x_device::read )
break; break;
case 0x00001: case 0x00001:
reply = 0xa4; // Device code reply = m_device_id; // Device code
break; break;
// Boot block lockout detection [1] // Boot block lockout detection [1]

View File

@ -215,9 +215,9 @@
#include "bus/ti99_peb/peribox.h" #include "bus/ti99_peb/peribox.h"
#define TRACE_READY 0
#define VERBOSE 1 #define TRACE_LINES 0
#define LOG logerror #define TRACE_CRU 0
#define SRAM_SIZE 384*1024 // maximum SRAM expansion on-board #define SRAM_SIZE 384*1024 // maximum SRAM expansion on-board
#define DRAM_SIZE 512*1024 #define DRAM_SIZE 512*1024
@ -318,9 +318,11 @@ static INPUT_PORTS_START(geneve)
PORT_CONFSETTING( GENMOD, "GenMod" ) PORT_CONFSETTING( GENMOD, "GenMod" )
PORT_START( "BOOTROM" ) PORT_START( "BOOTROM" )
PORT_CONFNAME( 0x01, GENEVE_098, "Boot ROM" ) PORT_CONDITION( "MODE", 0x01, EQUALS, 0x00 ) PORT_CONFNAME( 0x03, GENEVE_098, "Boot ROM" ) PORT_CHANGED_MEMBER(GMAPPER_TAG, geneve_mapper_device, settings_changed, 3)
PORT_CONFSETTING( GENEVE_098, "Version 0.98" ) PORT_CONFSETTING( GENEVE_098, "Version 0.98" )
PORT_CONFSETTING( GENEVE_100, "Version 1.00" ) PORT_CONFSETTING( GENEVE_100, "Version 1.00" )
PORT_CONFSETTING( GENEVE_PFM512, "PFM 512" )
PORT_CONFSETTING( GENEVE_PFM512A, "PFM 512A" )
PORT_START( "SRAM" ) PORT_START( "SRAM" )
PORT_CONFNAME( 0x03, 0x01, "Onboard SRAM" ) PORT_CONDITION( "MODE", 0x01, EQUALS, 0x00 ) PORT_CONFNAME( 0x03, 0x01, "Onboard SRAM" ) PORT_CONDITION( "MODE", 0x01, EQUALS, 0x00 )
@ -329,10 +331,10 @@ static INPUT_PORTS_START(geneve)
PORT_CONFSETTING( 0x02, "384 KiB" ) PORT_CONFSETTING( 0x02, "384 KiB" )
PORT_START( "GENMODDIPS" ) PORT_START( "GENMODDIPS" )
PORT_DIPNAME( GM_TURBO, 0x00, "Genmod Turbo mode") PORT_CONDITION( "MODE", 0x01, EQUALS, GENMOD ) PORT_CHANGED_MEMBER(GMAPPER_TAG, geneve_mapper_device, gm_changed, 1) PORT_DIPNAME( GM_TURBO, 0x00, "Genmod Turbo mode") PORT_CONDITION( "MODE", 0x01, EQUALS, GENMOD ) PORT_CHANGED_MEMBER(GMAPPER_TAG, geneve_mapper_device, settings_changed, 1)
PORT_CONFSETTING( 0x00, DEF_STR( Off )) PORT_CONFSETTING( 0x00, DEF_STR( Off ))
PORT_CONFSETTING( GM_TURBO, DEF_STR( On )) PORT_CONFSETTING( GM_TURBO, DEF_STR( On ))
PORT_DIPNAME( GM_TIM, GM_TIM, "Genmod TI mode") PORT_CONDITION( "MODE", 0x01, EQUALS, GENMOD ) PORT_CHANGED_MEMBER(GMAPPER_TAG, geneve_mapper_device, gm_changed, 2) PORT_DIPNAME( GM_TIM, GM_TIM, "Genmod TI mode") PORT_CONDITION( "MODE", 0x01, EQUALS, GENMOD ) PORT_CHANGED_MEMBER(GMAPPER_TAG, geneve_mapper_device, settings_changed, 2)
PORT_CONFSETTING( 0x00, DEF_STR( Off )) PORT_CONFSETTING( 0x00, DEF_STR( Off ))
PORT_CONFSETTING( GM_TIM, DEF_STR( On )) PORT_CONFSETTING( GM_TIM, DEF_STR( On ))
@ -354,7 +356,7 @@ WRITE8_MEMBER ( geneve_state::cruwrite )
if ((addroff & 0xffc0) == CRU_SSTEP_BASE) if ((addroff & 0xffc0) == CRU_SSTEP_BASE)
{ {
int bit = (addroff & 0x003e)>>1; int bit = (addroff & 0x003e)>>1;
if (VERBOSE>0) LOG("geneve: Single step not implemented; bit %d set to %d\n", bit, data); logerror("geneve: Single step not implemented; bit %d set to %d\n", bit, data);
return; return;
} }
@ -365,47 +367,47 @@ WRITE8_MEMBER ( geneve_state::cruwrite )
{ {
case 5: case 5:
// No one really cares... // No one really cares...
if (VERBOSE>8) LOG("geneve: Set PAL flag = %02x\n", data); if (TRACE_CRU) logerror("geneve: Set PAL flag = %02x\n", data);
// m_palvideo = (data!=0); // m_palvideo = (data!=0);
break; break;
case 7: case 7:
// m_capslock = (data!=0); // m_capslock = (data!=0);
if (VERBOSE>8) LOG("geneve: Set capslock flag = %02x\n", data); if (TRACE_CRU) logerror("geneve: Set capslock flag = %02x\n", data);
break; break;
case 8: case 8:
if (VERBOSE>8) LOG("geneve: Set keyboard clock flag = %02x\n", data); if (TRACE_CRU) logerror("geneve: Set keyboard clock flag = %02x\n", data);
m_keyboard->clock_control((data!=0)? ASSERT_LINE : CLEAR_LINE); m_keyboard->clock_control((data!=0)? ASSERT_LINE : CLEAR_LINE);
break; break;
case 9: case 9:
if (VERBOSE>8) LOG("geneve: Set keyboard scan flag = %02x\n", data); if (TRACE_CRU) logerror("geneve: Set keyboard scan flag = %02x\n", data);
m_keyboard->send_scancodes((data!=0)? ASSERT_LINE : CLEAR_LINE); m_keyboard->send_scancodes((data!=0)? ASSERT_LINE : CLEAR_LINE);
break; break;
case 10: case 10:
if (VERBOSE>8) LOG("geneve: Geneve mode = %02x\n", data); if (TRACE_CRU) logerror("geneve: Geneve mode = %02x\n", data);
m_mapper->set_geneve_mode(data!=0); m_mapper->set_geneve_mode(data!=0);
break; break;
case 11: case 11:
if (VERBOSE>8) LOG("geneve: Direct mode = %02x\n", data); if (TRACE_CRU) logerror("geneve: Direct mode = %02x\n", data);
m_mapper->set_direct_mode(data!=0); m_mapper->set_direct_mode(data!=0);
break; break;
case 12: case 12:
if (VERBOSE>8) LOG("geneve: Cartridge size 8K = %02x\n", data); if (TRACE_CRU) logerror("geneve: Cartridge size 8K = %02x\n", data);
m_mapper->set_cartridge_size((data!=0)? 0x2000 : 0x4000); m_mapper->set_cartridge_size((data!=0)? 0x2000 : 0x4000);
break; break;
case 13: case 13:
if (VERBOSE>8) LOG("geneve: Cartridge writable 6000 = %02x\n", data); if (TRACE_CRU) logerror("geneve: Cartridge writable 6000 = %02x\n", data);
m_mapper->set_cartridge_writable(0x6000, (data!=0)); m_mapper->set_cartridge_writable(0x6000, (data!=0));
break; break;
case 14: case 14:
if (VERBOSE>8) LOG("geneve: Cartridge writable 7000 = %02x\n", data); if (TRACE_CRU) logerror("geneve: Cartridge writable 7000 = %02x\n", data);
m_mapper->set_cartridge_writable(0x7000, (data!=0)); m_mapper->set_cartridge_writable(0x7000, (data!=0));
break; break;
case 15: case 15:
if (VERBOSE>8) LOG("geneve: Extra wait states = %02x\n", data==0); if (TRACE_CRU) logerror("geneve: Extra wait states = %02x\n", data==0);
m_mapper->set_extra_waitstates(data==0); // let's use the inverse semantics m_mapper->set_extra_waitstates(data==0); // let's use the inverse semantics
break; break;
default: default:
if (VERBOSE>0) LOG("geneve: set CRU address %04x=%02x ignored\n", addroff, data); logerror("geneve: set CRU address %04x=%02x ignored\n", addroff, data);
break; break;
} }
} }
@ -425,7 +427,7 @@ READ8_MEMBER( geneve_state::cruread )
if ((addroff & 0xffc0) == CRU_SSTEP_BASE) if ((addroff & 0xffc0) == CRU_SSTEP_BASE)
{ {
int bit = (addroff & 0x003e)>>1; int bit = (addroff & 0x003e)>>1;
if (VERBOSE>0) LOG("geneve: Single step not implemented; attempting to read bit %d\n", bit); logerror("geneve: Single step not implemented; attempting to read bit %d\n", bit);
return value; return value;
} }
@ -477,7 +479,7 @@ READ8_MEMBER( geneve_state::read_by_9901 )
if (m_intb==CLEAR_LINE) answer |= 0x10; if (m_intb==CLEAR_LINE) answer |= 0x10;
if (m_video_wait==ASSERT_LINE) answer |= 0x20; if (m_video_wait==ASSERT_LINE) answer |= 0x20;
// TODO: PAL pin 5 // TODO: PAL pin 5
if (VERBOSE>8) LOG("geneve: INT15-8 = %02x\n", answer); if (TRACE_LINES) logerror("geneve: INT15-8 = %02x\n", answer);
break; break;
case TMS9901_P0_P7: case TMS9901_P0_P7:
@ -505,7 +507,7 @@ READ8_MEMBER( geneve_state::read_by_9901 )
*/ */
WRITE_LINE_MEMBER( geneve_state::peripheral_bus_reset ) WRITE_LINE_MEMBER( geneve_state::peripheral_bus_reset )
{ {
if (VERBOSE>0) LOG("geneve: peripheral bus reset request; not implemented yet.\n"); logerror("geneve: Peripheral bus reset request; not implemented yet.\n");
} }
/* /*
@ -513,7 +515,7 @@ WRITE_LINE_MEMBER( geneve_state::peripheral_bus_reset )
*/ */
WRITE_LINE_MEMBER( geneve_state::VDP_reset ) WRITE_LINE_MEMBER( geneve_state::VDP_reset )
{ {
if (VERBOSE>0) LOG("geneve: Video reset request; not implemented yet.\n"); logerror("geneve: Video reset request; not implemented yet.\n");
} }
/* /*
@ -529,7 +531,7 @@ WRITE_LINE_MEMBER( geneve_state::joystick_select )
*/ */
WRITE_LINE_MEMBER( geneve_state::extbus_wait_states ) WRITE_LINE_MEMBER( geneve_state::extbus_wait_states )
{ {
if (VERBOSE>0) LOG("geneve: external bus wait states set to %d, not implemented yet.\n", state); logerror("geneve: External bus wait states set to %d, not implemented yet.\n", state);
} }
/* /*
@ -538,7 +540,7 @@ WRITE_LINE_MEMBER( geneve_state::extbus_wait_states )
*/ */
WRITE_LINE_MEMBER( geneve_state::video_wait_states ) WRITE_LINE_MEMBER( geneve_state::video_wait_states )
{ {
if (VERBOSE>1) LOG("geneve: video wait states set to %d\n", state); if (TRACE_LINES) logerror("geneve: Video wait states set to %d\n", state);
m_mapper->set_video_waitstates(state==ASSERT_LINE); m_mapper->set_video_waitstates(state==ASSERT_LINE);
m_video_wait = (state!=0)? ASSERT_LINE : CLEAR_LINE; m_video_wait = (state!=0)? ASSERT_LINE : CLEAR_LINE;
} }
@ -555,39 +557,6 @@ WRITE8_MEMBER( geneve_state::tms9901_interrupt )
m_cpu->set_input_line(INT_9995_INT1, data); m_cpu->set_input_line(INT_9995_INT1, data);
} }
/*
// tms9901 setup
const tms9901_interface tms9901_wiring_geneve =
{
TMS9901_INT1 | TMS9901_INT2 | TMS9901_INT8 | TMS9901_INTB | TMS9901_INTC,
// read handler
DEVCB_DRIVER_MEMBER(geneve_state, read_by_9901),
{ // write handlers
DEVCB_DRIVER_LINE_MEMBER(geneve_state, peripheral_bus_reset),
DEVCB_DRIVER_LINE_MEMBER(geneve_state, VDP_reset),
DEVCB_DRIVER_LINE_MEMBER(geneve_state, joystick_select),
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_DEVICE_LINE_MEMBER(GKEYBOARD_TAG, geneve_keyboard_device, reset_line),
DEVCB_DRIVER_LINE_MEMBER(geneve_state, extbus_wait_states),
DEVCB_NULL,
DEVCB_DRIVER_LINE_MEMBER(geneve_state, video_wait_states),
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL,
DEVCB_NULL
},
// interrupt handler
DEVCB_DRIVER_MEMBER(geneve_state, tms9901_interrupt)
};
*/
/******************************************************************* /*******************************************************************
Signal lines Signal lines
*******************************************************************/ *******************************************************************/
@ -613,14 +582,14 @@ WRITE_LINE_MEMBER( geneve_state::intb )
WRITE_LINE_MEMBER( geneve_state::ext_ready ) WRITE_LINE_MEMBER( geneve_state::ext_ready )
{ {
if (VERBOSE>6) LOG("geneve: READY level (ext) = %02x\n", state); if (TRACE_READY) logerror("geneve: READY level (ext) = %02x\n", state);
m_ready_line = state; m_ready_line = state;
m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE); m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE);
} }
WRITE_LINE_MEMBER( geneve_state::mapper_ready ) WRITE_LINE_MEMBER( geneve_state::mapper_ready )
{ {
if (VERBOSE>6) LOG("geneve: READY level (mapper) = %02x\n", state); if (TRACE_READY) logerror("geneve: READY level (mapper) = %02x\n", state);
m_ready_line1 = state; m_ready_line1 = state;
m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE); m_cpu->set_ready((m_ready_line == ASSERT_LINE && m_ready_line1 == ASSERT_LINE)? ASSERT_LINE : CLEAR_LINE);
} }
@ -667,8 +636,7 @@ TIMER_DEVICE_CALLBACK_MEMBER(geneve_state::geneve_hblank_interrupt)
WRITE8_MEMBER( geneve_state::external_operation ) WRITE8_MEMBER( geneve_state::external_operation )
{ {
static const char* extop[8] = { "inv1", "inv2", "IDLE", "RSET", "inv3", "CKON", "CKOF", "LREX" }; static const char* extop[8] = { "inv1", "inv2", "IDLE", "RSET", "inv3", "CKON", "CKOF", "LREX" };
if (VERBOSE>1) if (offset != IDLE_OP) logerror("geneve: External operation %s not implemented on Geneve board\n", extop[offset]);
if (offset != IDLE_OP) LOG("geneve: External operation %s not implemented on Geneve board\n", extop[offset]);
} }
/* /*
@ -739,9 +707,12 @@ static MACHINE_CONFIG_START( geneve_60hz, geneve_state )
MCFG_TMS9901_P0_HANDLER( WRITELINE( geneve_state, peripheral_bus_reset) ) MCFG_TMS9901_P0_HANDLER( WRITELINE( geneve_state, peripheral_bus_reset) )
MCFG_TMS9901_P1_HANDLER( WRITELINE( geneve_state, VDP_reset) ) MCFG_TMS9901_P1_HANDLER( WRITELINE( geneve_state, VDP_reset) )
MCFG_TMS9901_P2_HANDLER( WRITELINE( geneve_state, joystick_select) ) MCFG_TMS9901_P2_HANDLER( WRITELINE( geneve_state, joystick_select) )
MCFG_TMS9901_P4_HANDLER( DEVWRITELINE( GMAPPER_TAG, geneve_mapper_device, pfm_select_lsb) ) // new for PFM
MCFG_TMS9901_P5_HANDLER( DEVWRITELINE( GMAPPER_TAG, geneve_mapper_device, pfm_output_enable) ) // new for PFM
MCFG_TMS9901_P6_HANDLER( DEVWRITELINE( GKEYBOARD_TAG, geneve_keyboard_device, reset_line) ) MCFG_TMS9901_P6_HANDLER( DEVWRITELINE( GKEYBOARD_TAG, geneve_keyboard_device, reset_line) )
MCFG_TMS9901_P7_HANDLER( WRITELINE( geneve_state, extbus_wait_states) ) MCFG_TMS9901_P7_HANDLER( WRITELINE( geneve_state, extbus_wait_states) )
MCFG_TMS9901_P9_HANDLER( WRITELINE( geneve_state, video_wait_states) ) MCFG_TMS9901_P9_HANDLER( WRITELINE( geneve_state, video_wait_states) )
MCFG_TMS9901_P13_HANDLER( DEVWRITELINE( GMAPPER_TAG, geneve_mapper_device, pfm_select_msb) ) // new for PFM
MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( geneve_state, tms9901_interrupt) ) MCFG_TMS9901_INTLEVEL_HANDLER( WRITE8( geneve_state, tms9901_interrupt) )
// Mapper // Mapper
@ -769,6 +740,10 @@ static MACHINE_CONFIG_START( geneve_60hz, geneve_state )
MCFG_GENEVE_MOUSE_ADD( GMOUSE_TAG ) MCFG_GENEVE_MOUSE_ADD( GMOUSE_TAG )
MCFG_GENEVE_JOYPORT_ADD( JOYPORT_TAG ) MCFG_GENEVE_JOYPORT_ADD( JOYPORT_TAG )
// PFM expansion
MCFG_AT29C040_ADD( PFM512_TAG )
MCFG_AT29C040A_ADD( PFM512A_TAG )
MACHINE_CONFIG_END MACHINE_CONFIG_END
/* /*