diff --git a/hash/svision.xml b/hash/svision.xml
index 69f10de264e..bbbd8468131 100644
--- a/hash/svision.xml
+++ b/hash/svision.xml
@@ -23,8 +23,8 @@ license:CC0-1.0
-
-
+
+
@@ -36,8 +36,8 @@ license:CC0-1.0
-
-
+
+
@@ -49,8 +49,8 @@ license:CC0-1.0
-
-
+
+
@@ -60,8 +60,8 @@ license:CC0-1.0
199?
Watara
-
-
+
+
@@ -73,8 +73,8 @@ license:CC0-1.0
-
-
+
+
@@ -86,8 +86,8 @@ license:CC0-1.0
-
-
+
+
@@ -97,8 +97,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -110,8 +110,8 @@ license:CC0-1.0
-
-
+
+
@@ -121,8 +121,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -134,8 +134,8 @@ license:CC0-1.0
-
-
+
+
@@ -147,8 +147,8 @@ license:CC0-1.0
-
-
+
+
@@ -160,8 +160,8 @@ license:CC0-1.0
-
-
+
+
@@ -171,8 +171,8 @@ license:CC0-1.0
1993
Bon Treasure
-
-
+
+
@@ -182,8 +182,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -193,8 +193,8 @@ license:CC0-1.0
1991
GTC Inc
-
-
+
+
@@ -204,8 +204,19 @@ license:CC0-1.0
1991
Travellmate
-
-
+
+
+
+
+
+
+
+ Crystball (Euro, USA, earlier)
+ 1991
+ Travellmate
+
+
+
@@ -217,8 +228,8 @@ license:CC0-1.0
-
-
+
+
@@ -230,8 +241,8 @@ license:CC0-1.0
-
-
+
+
@@ -241,8 +252,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -254,8 +265,8 @@ license:CC0-1.0
-
-
+
+
@@ -265,8 +276,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -276,8 +287,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -287,8 +298,8 @@ license:CC0-1.0
199?
Watara
-
-
+
+
@@ -300,8 +311,8 @@ license:CC0-1.0
-
-
+
+
@@ -313,8 +324,8 @@ license:CC0-1.0
-
-
+
+
@@ -324,8 +335,8 @@ license:CC0-1.0
1992
Thin Chen Enterprise
-
-
+
+
@@ -337,8 +348,8 @@ license:CC0-1.0
-
-
+
+
@@ -350,8 +361,8 @@ license:CC0-1.0
-
-
+
+
@@ -363,8 +374,8 @@ license:CC0-1.0
-
-
+
+
@@ -376,8 +387,8 @@ license:CC0-1.0
-
-
+
+
@@ -387,8 +398,8 @@ license:CC0-1.0
1992
Thin Chen Enterprise
-
-
+
+
@@ -400,8 +411,8 @@ license:CC0-1.0
-
-
+
+
@@ -413,8 +424,8 @@ license:CC0-1.0
-
-
+
+
@@ -424,8 +435,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -437,8 +448,8 @@ license:CC0-1.0
-
-
+
+
@@ -450,8 +461,8 @@ license:CC0-1.0
-
-
+
+
@@ -463,8 +474,8 @@ license:CC0-1.0
-
-
+
+
@@ -474,8 +485,8 @@ license:CC0-1.0
199?
Watara
-
-
+
+
@@ -485,8 +496,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -496,8 +507,8 @@ license:CC0-1.0
1993
Thin Chen Enterprise
-
-
+
+
@@ -509,8 +520,8 @@ license:CC0-1.0
-
-
+
+
@@ -522,8 +533,8 @@ license:CC0-1.0
-
-
+
+
@@ -536,8 +547,8 @@ license:CC0-1.0
-
-
+
+
@@ -549,8 +560,8 @@ license:CC0-1.0
-
-
+
+
@@ -562,8 +573,8 @@ license:CC0-1.0
-
-
+
+
@@ -575,8 +586,8 @@ license:CC0-1.0
-
-
+
+
@@ -588,8 +599,8 @@ license:CC0-1.0
-
-
+
+
@@ -599,8 +610,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -612,8 +623,8 @@ license:CC0-1.0
-
-
+
+
@@ -625,8 +636,8 @@ license:CC0-1.0
-
-
+
+
@@ -638,8 +649,8 @@ license:CC0-1.0
-
-
+
+
@@ -649,8 +660,8 @@ license:CC0-1.0
199?
Watara
-
-
+
+
@@ -662,8 +673,8 @@ license:CC0-1.0
-
-
+
+
@@ -673,8 +684,8 @@ license:CC0-1.0
1992
Bon Treasure
-
-
+
+
@@ -686,8 +697,8 @@ license:CC0-1.0
-
-
+
+
@@ -697,8 +708,8 @@ license:CC0-1.0
199?
Watera
-
-
+
+
@@ -710,8 +721,8 @@ license:CC0-1.0
-
-
+
+
@@ -723,8 +734,8 @@ license:CC0-1.0
-
-
+
+
@@ -736,8 +747,8 @@ license:CC0-1.0
-
-
+
+
@@ -749,8 +760,8 @@ license:CC0-1.0
-
-
+
+
@@ -762,8 +773,8 @@ license:CC0-1.0
-
-
+
+
@@ -775,8 +786,8 @@ license:CC0-1.0
-
-
+
+
@@ -788,8 +799,8 @@ license:CC0-1.0
-
-
+
+
@@ -799,30 +810,41 @@ license:CC0-1.0
1992
Thin Chen Enterprise
-
-
+
+
- Treasure Hunter (Euro, USA)
- 199?
+ Treasure Hunter (Euro, USA, 1993)
+ 1993
Watara
-
-
+
+
-
+
+ Treasure Hunter (Euro, USA, 1992)
+ 1992
+ Watara
+
+
+
+
+
+
+
+
TV-Link
199?
Watara
-
-
+
+
@@ -832,8 +854,8 @@ license:CC0-1.0
199?
Bon Treasure
-
-
+
+
@@ -843,8 +865,8 @@ license:CC0-1.0
199?
Bon Treasure
-
-
+
+
@@ -856,8 +878,8 @@ license:CC0-1.0
Watara?
-
-
+
+
diff --git a/src/mame/svision/svis_snd.cpp b/src/mame/svision/svis_snd.cpp
index 90c08fe84f8..0444ecab3ea 100644
--- a/src/mame/svision/svis_snd.cpp
+++ b/src/mame/svision/svis_snd.cpp
@@ -9,6 +9,17 @@
#include "emu.h"
#include "svis_snd.h"
+// configurable logging
+#define LOG_DMA (1U << 1)
+#define LOG_NOISE (1U << 2)
+
+//#define VERBOSE (LOG_GENERAL | LOG_DMA | LOG_NOISE)
+
+#include "logmacro.h"
+
+#define LOGDMA(...) LOGMASKED(LOG_DMA, __VA_ARGS__)
+#define LOGNOISE(...) LOGMASKED(LOG_NOISE, __VA_ARGS__)
+
// device type definition
DEFINE_DEVICE_TYPE(SVISION_SND, svision_sound_device, "svision_sound", "Super Vision Custom Sound")
@@ -46,6 +57,36 @@ void svision_sound_device::device_start()
memset(m_channel, 0, sizeof(m_channel));
m_mixer_channel = stream_alloc(0, 2, machine().sample_rate());
+
+ save_item(STRUCT_MEMBER(m_noise, reg));
+ save_item(STRUCT_MEMBER(m_noise, on));
+ save_item(STRUCT_MEMBER(m_noise, right));
+ save_item(STRUCT_MEMBER(m_noise, left));
+ save_item(STRUCT_MEMBER(m_noise, play));
+ save_item(STRUCT_MEMBER(m_noise, state));
+ save_item(STRUCT_MEMBER(m_noise, volume));
+ save_item(STRUCT_MEMBER(m_noise, count));
+ save_item(STRUCT_MEMBER(m_noise, step));
+ save_item(STRUCT_MEMBER(m_noise, pos));
+ save_item(STRUCT_MEMBER(m_noise, value));
+
+ save_item(STRUCT_MEMBER(m_dma, reg));
+ save_item(STRUCT_MEMBER(m_dma, on));
+ save_item(STRUCT_MEMBER(m_dma, right));
+ save_item(STRUCT_MEMBER(m_dma, left));
+ save_item(STRUCT_MEMBER(m_dma, ca14to16));
+ save_item(STRUCT_MEMBER(m_dma, start));
+ save_item(STRUCT_MEMBER(m_dma, size));
+ save_item(STRUCT_MEMBER(m_dma, pos));
+ save_item(STRUCT_MEMBER(m_dma, step));
+ save_item(STRUCT_MEMBER(m_dma, finished));
+
+ save_item(STRUCT_MEMBER(m_channel, reg));
+ save_item(STRUCT_MEMBER(m_channel, waveform));
+ save_item(STRUCT_MEMBER(m_channel, volume));
+ save_item(STRUCT_MEMBER(m_channel, pos));
+ save_item(STRUCT_MEMBER(m_channel, size));
+ save_item(STRUCT_MEMBER(m_channel, count));
}
@@ -55,8 +96,8 @@ void svision_sound_device::device_start()
void svision_sound_device::sound_stream_update(sound_stream &stream, std::vector const &inputs, std::vector &outputs)
{
- auto &left=outputs[0];
- auto &right=outputs[1];
+ auto &left = outputs[0];
+ auto &right = outputs[1];
for (int i = 0; i < left.samples(); i++)
{
@@ -67,7 +108,7 @@ void svision_sound_device::sound_stream_update(sound_stream &stream, std::vector
CHANNEL &channel(m_channel[j]);
if (channel.size != 0)
{
- if (channel.on||channel.count)
+ if (channel.on || channel.count)
{
bool on = false;
switch (channel.waveform)
@@ -116,7 +157,7 @@ void svision_sound_device::sound_stream_update(sound_stream &stream, std::vector
m_noise.value = m_noise.state & 0x40 ? 1 : 0;
b1 = (m_noise.state & 0x40) != 0;
b2 = (m_noise.state & 0x20) != 0;
- m_noise.state=(m_noise.state<<1)+(b1!=b2?1:0);
+ m_noise.state = (m_noise.state << 1) + (b1 != b2 ? 1 : 0);
break;
case NOISE::Type::Type14Bit:
default:
@@ -132,7 +173,7 @@ void svision_sound_device::sound_stream_update(sound_stream &stream, std::vector
{
uint8_t sample;
int16_t s;
- uint16_t addr = m_dma.start + (unsigned) m_dma.pos / 2;
+ uint16_t const addr = m_dma.start + (unsigned) m_dma.pos / 2;
if (addr >= 0x8000 && addr < 0xc000)
{
sample = ((uint8_t*)m_cartrom->base())[(addr & 0x3fff) | m_dma.ca14to16];
@@ -153,7 +194,7 @@ void svision_sound_device::sound_stream_update(sound_stream &stream, std::vector
m_dma.pos += m_dma.step;
if (m_dma.pos >= m_dma.size)
{
- m_dma.finished = true;
+ m_dma.finished = true; // TODO: only ever set, never read?
m_dma.on = false;
m_irq_cb(1);
}
@@ -166,7 +207,7 @@ void svision_sound_device::sound_stream_update(sound_stream &stream, std::vector
void svision_sound_device::sounddma_w(offs_t offset, uint8_t data)
{
- logerror("%.6f svision snddma write %04x %02x\n", machine().time().as_double(),offset+0x18,data);
+ LOGDMA("%.6f svision snddma write %04x %02x\n", machine().time().as_double(), offset + 0x18, data);
m_dma.reg[offset] = data;
switch (offset)
{
@@ -196,13 +237,13 @@ void svision_sound_device::sounddma_w(offs_t offset, uint8_t data)
void svision_sound_device::noise_w(offs_t offset, uint8_t data)
{
- // logerror("%.6f svision noise write %04x %02x\n",machine.time(),offset+0x28,data);
- m_noise.reg[offset]=data;
+ LOGNOISE("%.6f svision noise write %04x %02x\n", machine().time().as_double(), offset + 0x28, data);
+ m_noise.reg[offset] = data;
switch (offset)
{
case 0:
- m_noise.volume=data&0xf;
- m_noise.step= unscaled_clock() / (256.0*machine().sample_rate()*(1+(data>>4)));
+ m_noise.volume = data & 0xf;
+ m_noise.step = unscaled_clock() / (256.0 * machine().sample_rate() * (1 + (data >> 4)));
break;
case 1:
m_noise.count = data + 1;
@@ -212,11 +253,11 @@ void svision_sound_device::noise_w(offs_t offset, uint8_t data)
m_noise.play = data & 2;
m_noise.right = data & 4;
m_noise.left = data & 8;
- m_noise.on = data & 0x10; /* honey bee start */
+ m_noise.on = data & 0x10; // honey bee start
m_noise.state = 1;
break;
}
- m_noise.pos=0.0;
+ m_noise.pos = 0.0;
}
@@ -231,37 +272,36 @@ void svision_sound_device::sound_decrement()
}
-void svision_sound_device::soundport_w(int which, int offset, int data)
+void svision_sound_device::soundport_w(uint8_t which, offs_t offset, uint8_t data)
{
- CHANNEL &channel(m_channel[which]);
uint16_t size;
m_mixer_channel->update();
- channel.reg[offset] = data;
+ m_channel[which].reg[offset] = data;
switch (offset)
{
case 0:
case 1:
- size = channel.reg[0] | ((channel.reg[1] & 7) << 8);
+ size = m_channel[which].reg[0] | ((m_channel[which].reg[1] & 7) << 8);
if (size)
{
- // channel.size=(int)(device->machine().sample_rate()*(size<<5)/4e6);
- channel.size = (int) (machine().sample_rate() * (size << 5) / unscaled_clock());
+ // m_channel[which].size = (int) (machine().sample_rate() * (size << 5) / 4e6);
+ m_channel[which].size = (int) (machine().sample_rate() * (size << 5) / unscaled_clock());
}
else
{
- channel.size = 0;
+ m_channel[which].size = 0;
}
- channel.pos = 0;
+ m_channel[which].pos = 0;
break;
case 2:
- channel.on = data & 0x40;
- channel.waveform = (data & 0x30) >> 4;
- channel.volume = data & 0xf;
+ m_channel[which].on = data & 0x40;
+ m_channel[which].waveform = (data & 0x30) >> 4;
+ m_channel[which].volume = data & 0xf;
break;
case 3:
- channel.count = data + 1;
+ m_channel[which].count = data + 1;
break;
}
}
diff --git a/src/mame/svision/svis_snd.h b/src/mame/svision/svis_snd.h
index 1af9039e4a1..9612423141b 100644
--- a/src/mame/svision/svis_snd.h
+++ b/src/mame/svision/svis_snd.h
@@ -34,7 +34,7 @@ public:
void noise_w(offs_t offset, uint8_t data);
void sound_decrement();
- void soundport_w(int which, int offset, int data);
+ void soundport_w(uint8_t which, offs_t offset, uint8_t data);
protected:
// device-level overrides
@@ -55,13 +55,13 @@ private:
NOISE() : reg{ 0, 0, 0 } { }
uint8_t reg[3];
- int on = 0, right = 0, left = 0, play = 0;
+ uint8_t on = 0, right = 0, left = 0, play = 0;
Type type = Type::Type7Bit;
- int state = 0;
- int volume = 0;
- int count = 0;
+ int32_t state = 0;
+ uint8_t volume = 0;
+ uint16_t count = 0;
double step = 0, pos = 0;
- int value = 0; // currently simple random function
+ uint8_t value = 0; // currently simple random function
};
struct DMA
@@ -69,11 +69,11 @@ private:
DMA() : reg{ 0, 0, 0, 0, 0 } { }
uint8_t reg[5];
- int on = 0, right = 0, left = 0;
- int ca14to16 = 0;
- int start = 0, size = 0;
+ uint8_t on = 0, right = 0, left = 0;
+ uint32_t ca14to16 = 0;
+ uint16_t start = 0, size = 0;
double pos = 0, step = 0;
- int finished = 0;
+ uint8_t finished = 0;
};
struct CHANNEL
@@ -81,11 +81,11 @@ private:
CHANNEL() : reg{ 0, 0, 0, 0 } { }
uint8_t reg[4];
- int on = 0;
- int waveform = 0, volume = 0;
- int pos = 0;
- int size = 0;
- int count = 0;
+ uint8_t on = 0;
+ uint8_t waveform = 0, volume = 0;
+ int32_t pos = 0;
+ int32_t size = 0;
+ uint16_t count = 0;
};
devcb_write_line m_irq_cb;
diff --git a/src/mame/svision/svision.cpp b/src/mame/svision/svision.cpp
index e3b5a4ce405..817944f782c 100644
--- a/src/mame/svision/svision.cpp
+++ b/src/mame/svision/svision.cpp
@@ -1,5 +1,6 @@
// license:GPL-2.0+
// copyright-holders:Peter Trauner
+
/******************************************************************************
watara supervision handheld
@@ -7,7 +8,15 @@
******************************************************************************/
#include "emu.h"
-#include "svision.h"
+
+#include "svis_snd.h"
+
+#include "bus/generic/carts.h"
+#include "bus/generic/slot.h"
+#include "cpu/m6502/m65c02.h"
+#include "machine/timer.h"
+
+#include "emupal.h"
#include "screen.h"
#include "softlist_dev.h"
#include "speaker.h"
@@ -15,11 +24,127 @@
#include "svision.lh"
-#define MAKE8_RGB32(red3, green3, blue2) ( ( (red3)<<(16+5)) | ( (green3)<<(8+5)) | ( (blue2)<<(0+6)) )
-#define MAKE9_RGB32(red3, green3, blue3) ( ( (red3)<<(16+5)) | ( (green3)<<(8+5)) | ( (blue3)<<(0+5)) )
-#define MAKE12_RGB32(red4, green4, blue4) ( ( (red4)<<(16+4)) | ((green4)<<(8+4)) | ((blue4)<<(0+4)) )
-#define MAKE24_RGB32(red8, green8, blue8) ( (((red8)&0xf8)<<16) | (((green8)&0xf8)<<8) | (((blue8)&0xf8)) )
+// configurable logging
+#define LOG_REGS (1U << 1)
+//#define VERBOSE (LOG_GENERAL | LOG_REGS)
+
+#include "logmacro.h"
+
+#define LOGREGS(...) LOGMASKED(LOG_REGS, __VA_ARGS__)
+
+
+namespace {
+
+class svision_state : public driver_device
+{
+public:
+ svision_state(const machine_config &mconfig, device_type type, const char *tag)
+ : driver_device(mconfig, type, tag)
+ , m_maincpu(*this, "maincpu")
+ , m_sound(*this, "custom")
+ , m_cart(*this, "cartslot")
+ , m_reg(*this, "reg")
+ , m_videoram(*this, "videoram")
+ , m_screen(*this, "screen")
+ , m_joy(*this, "JOY")
+ , m_joy2(*this, "JOY2")
+ , m_palette(*this, "palette")
+ , m_bank(*this, "bank%u", 1U)
+ { }
+
+ void svisionp(machine_config &config);
+ void svisions(machine_config &config);
+ void tvlinkp(machine_config &config);
+ void svision(machine_config &config);
+ void svisionn(machine_config &config);
+ void svision_base(machine_config &config);
+
+ void init_svisions();
+ void init_svision();
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ required_device m_maincpu;
+ required_device m_sound;
+ required_device m_cart;
+ required_shared_ptr m_reg;
+ required_shared_ptr m_videoram;
+ required_device m_screen;
+ required_ioport m_joy;
+ optional_ioport m_joy2;
+ required_device m_palette;
+
+ required_memory_bank_array<2> m_bank;
+
+ memory_region *m_cart_rom = nullptr;
+
+ enum
+ {
+ XSIZE = 0x00,
+ XPOS = 0x02,
+ YPOS = 0x03,
+ BANK = 0x26,
+ };
+
+ struct svision_t
+ {
+ emu_timer *timer1 = nullptr;
+ uint8_t timer_shot = 0;
+ };
+
+ struct svision_pet_t
+ {
+ uint8_t state = 0;
+ uint8_t on = 0, clock = 0, data = 0;
+ uint8_t input = 0;
+ emu_timer *timer = nullptr;
+ };
+
+ struct tvlink_t
+ {
+ uint32_t palette[4]; // 0x40? rgb8
+ uint8_t palette_on;
+ };
+
+ svision_t m_svision;
+ svision_pet_t m_pet;
+ tvlink_t m_tvlink;
+ bool m_dma_finished = false;
+
+ DECLARE_WRITE_LINE_MEMBER(sound_irq_w);
+ uint8_t regs_r(offs_t offset);
+ void regs_w(offs_t offset, uint8_t data);
+ uint8_t tvlink_r(offs_t offset);
+ void tvlink_w(offs_t offset, uint8_t data);
+
+ uint32_t screen_update_svision(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
+ uint32_t screen_update_tvlink(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ DECLARE_WRITE_LINE_MEMBER(frame_int_w);
+ DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
+
+ void svision_palette(palette_device &palette) const;
+ void svisionp_palette(palette_device &palette) const;
+ void svisionn_palette(palette_device &palette) const;
+ DECLARE_MACHINE_RESET(tvlink);
+
+ uint32_t make8_rgb32(uint8_t red3, uint8_t green3, uint8_t blue2) { return (red3 << (16 + 5)) | (green3 << (8 + 5)) | (blue2 << (0 + 6)); }
+ uint32_t make9_rgb32(uint8_t red3, uint8_t green3, uint8_t blue3) { return (red3 << (16 + 5)) | (green3 << (8 + 5)) | (blue3 << (0 + 5)); }
+ uint32_t make12_rgb32(uint8_t red4, uint8_t green4, uint8_t blue4) { return (red4 << (16 + 4)) | (green4 << (8 + 4)) | (blue4 << (0 + 4)); }
+ uint32_t make24_rgb32(uint8_t red8, uint8_t green8, uint8_t blue8) { return ((red8 & 0xf8) << 16) | ((green8 & 0xf8) << 8) | (blue8 & 0xf8); }
+
+ void check_irq();
+
+ TIMER_CALLBACK_MEMBER(svision_pet_timer);
+ TIMER_CALLBACK_MEMBER(svision_timer);
+ TIMER_DEVICE_CALLBACK_MEMBER(svision_pet_timer_dev);
+
+ void svision_mem(address_map &map);
+ void tvlink_mem(address_map &map);
+};
TIMER_CALLBACK_MEMBER(svision_state::svision_pet_timer)
{
@@ -76,7 +201,7 @@ TIMER_CALLBACK_MEMBER(svision_state::svision_timer)
check_irq();
}
-uint8_t svision_state::svision_r(offs_t offset)
+uint8_t svision_state::regs_r(offs_t offset)
{
int data = m_reg[offset];
switch (offset)
@@ -123,14 +248,14 @@ uint8_t svision_state::svision_r(offs_t offset)
break;
default:
- logerror("%.6f svision read %04x %02x\n", machine().time().as_double(),offset,data);
+ LOGREGS("%.6f svision read %04x %02x\n", machine().time().as_double(), offset, data);
break;
}
return data;
}
-void svision_state::svision_w(offs_t offset, uint8_t data)
+void svision_state::regs_w(offs_t offset, uint8_t data)
{
m_reg[offset] = data;
@@ -140,16 +265,16 @@ void svision_state::svision_w(offs_t offset, uint8_t data)
case 0x03:
break;
- case 0x26: /* bits 5,6 memory management for a000? */
+ case 0x26: // bits 5,6 memory management for a000?
{
- logerror("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
- int bank = ((m_reg[0x26] & 0xe0) >> 5) % (m_cart_rom->bytes() / 0x4000);
- m_bank1->set_base(m_cart_rom->base() + (bank * 0x4000));
+ LOGREGS("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
+ const int bank = ((m_reg[0x26] & 0xe0) >> 5) % (m_cart_rom->bytes() / 0x4000);
+ m_bank[0]->set_entry(bank);
check_irq();
break;
}
- case 0x23: /* delta hero irq routine write */
+ case 0x23: // delta hero irq routine write
{
int delay = (data == 0) ? 0x100 : data;
delay *= (BIT(m_reg[BANK], 4)) ? 0x4000 : 0x100;
@@ -175,7 +300,7 @@ void svision_state::svision_w(offs_t offset, uint8_t data)
break;
default:
- logerror("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
+ LOGREGS("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
break;
}
}
@@ -187,12 +312,12 @@ uint8_t svision_state::tvlink_r(offs_t offset)
default:
if (offset >= 0x800 && offset < 0x840)
{
- /* strange effects when modifying palette */
- return svision_r(offset);
+ // strange effects when modifying palette
+ return regs_r(offset);
}
else
{
- return svision_r(offset);
+ return regs_r(offset);
}
}
}
@@ -206,44 +331,44 @@ void svision_state::tvlink_w(offs_t offset, uint8_t data)
m_tvlink.palette_on = data & 1;
if (m_tvlink.palette_on)
{
- // hack, normally initialising with palette from ram
- m_tvlink.palette[0] = MAKE12_RGB32(163/16,172/16,115/16); // these are the tron colors messured from screenshot
- m_tvlink.palette[1] = MAKE12_RGB32(163/16,155/16,153/16);
- m_tvlink.palette[2] = MAKE12_RGB32(77/16,125/16,73/16);
- m_tvlink.palette[3] = MAKE12_RGB32(59/16,24/16,20/16);
+ // hack, normally initialising with palette from RAM
+ m_tvlink.palette[0] = make12_rgb32(163 / 16, 172 / 16, 115 / 16); // these are the tron colors measured from screenshot
+ m_tvlink.palette[1] = make12_rgb32(163 / 16, 155 / 16, 153 / 16);
+ m_tvlink.palette[2] = make12_rgb32(77 / 16, 125 / 16, 73 / 16);
+ m_tvlink.palette[3] = make12_rgb32(59 / 16, 24 / 16, 20 / 16);
}
else
{
// cleaner to use colors from compile time palette, or compose from "fixed" palette values
- m_tvlink.palette[0]=MAKE12_RGB32(0,0,0);
- m_tvlink.palette[1]=MAKE12_RGB32(5*16/256,18*16/256,9*16/256);
- m_tvlink.palette[2]=MAKE12_RGB32(48*16/256,76*16/256,100*16/256);
- m_tvlink.palette[3]=MAKE12_RGB32(190*16/256,190*16/256,190*16/256);
+ m_tvlink.palette[0] = make12_rgb32(0, 0, 0);
+ m_tvlink.palette[1] = make12_rgb32(5 * 16 / 256, 18 * 16 / 256, 9 * 16 / 256);
+ m_tvlink.palette[2] = make12_rgb32(48 * 16 / 256, 76 * 16 / 256, 100 * 16 / 256);
+ m_tvlink.palette[3] = make12_rgb32(190 * 16 / 256, 190 * 16 / 256, 190 * 16 / 256);
}
break;
default:
- svision_w(offset,data);
+ regs_w(offset, data);
if (offset >= 0x800 && offset < 0x840)
{
if (offset == 0x803 && data == 0x07)
{
- /* tron hack */
+ // tron hack
m_reg[0x0804] = 0x00;
m_reg[0x0805] = 0x01;
m_reg[0x0806] = 0x00;
m_reg[0x0807] = 0x00;
}
uint16_t c = m_reg[0x800] | (m_reg[0x804] << 8);
- m_tvlink.palette[0] = MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
+ m_tvlink.palette[0] = make9_rgb32((c >> 0) & 7, (c >> 3) & 7, (c >> 6) & 7);
c = m_reg[0x801] | (m_reg[0x805] << 8);
- m_tvlink.palette[1] = MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
+ m_tvlink.palette[1] = make9_rgb32((c >> 0) & 7, (c >> 3) & 7, (c >> 6) & 7);
c = m_reg[0x802] | (m_reg[0x806]<<8);
- m_tvlink.palette[2]=MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
+ m_tvlink.palette[2] = make9_rgb32((c >> 0) & 7, (c >> 3) & 7, (c >> 6) & 7);
c = m_reg[0x803] | (m_reg[0x807]<<8);
- m_tvlink.palette[3]=MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
- /* writes to palette effect video color immediately */
- /* some writes modify other registers, */
- /* encoding therefor not known (rgb8 or rgb9) */
+ m_tvlink.palette[3] = make9_rgb32((c >> 0) & 7, (c >> 3) & 7, (c >> 6) & 7);
+ /* writes to palette effect video color immediately
+ some writes modify other registers,
+ encoding therefor not known (rgb8 or rgb9) */
}
}
}
@@ -251,11 +376,11 @@ void svision_state::tvlink_w(offs_t offset, uint8_t data)
void svision_state::svision_mem(address_map &map)
{
map(0x0000, 0x1fff).ram();
- map(0x2000, 0x3fff).rw(FUNC(svision_state::svision_r), FUNC(svision_state::svision_w)).share(m_reg);
+ map(0x2000, 0x3fff).rw(FUNC(svision_state::regs_r), FUNC(svision_state::regs_w)).share(m_reg);
map(0x4000, 0x5fff).ram().share(m_videoram);
map(0x6000, 0x7fff).noprw();
- map(0x8000, 0xbfff).bankr(m_bank1);
- map(0xc000, 0xffff).bankr(m_bank2);
+ map(0x8000, 0xbfff).bankr(m_bank[0]);
+ map(0xc000, 0xffff).bankr(m_bank[1]);
}
void svision_state::tvlink_mem(address_map &map)
@@ -264,8 +389,8 @@ void svision_state::tvlink_mem(address_map &map)
map(0x2000, 0x3fff).rw(FUNC(svision_state::tvlink_r), FUNC(svision_state::tvlink_w)).share(m_reg);
map(0x4000, 0x5fff).ram().share(m_videoram);
map(0x6000, 0x7fff).noprw();
- map(0x8000, 0xbfff).bankr(m_bank1);
- map(0xc000, 0xffff).bankr(m_bank2);
+ map(0x8000, 0xbfff).bankr(m_bank[0]);
+ map(0xc000, 0xffff).bankr(m_bank[1]);
}
static INPUT_PORTS_START( svision )
@@ -301,7 +426,7 @@ static INPUT_PORTS_START( svisions )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START) PORT_NAME("2nd Start/Pause") PORT_PLAYER(2)
INPUT_PORTS_END
-// most games contain their graphics in roms, and have hardware to draw complete rectangular objects
+// most games contain their graphics in ROMs, and have hardware to draw complete rectangular objects
// palette in red, green, blue triples
static constexpr rgb_t svision_pens[] =
@@ -313,7 +438,7 @@ static constexpr rgb_t svision_pens[] =
{ 74, 107, 101 },
{ 54, 78, 85 }
#else
- // grabbed from chris covell's black white pics
+ // grabbed from Chris Covell's black & white pics
{ 0xe0, 0xe0, 0xe0 },
{ 0xb9, 0xb9, 0xb9 },
{ 0x54, 0x54, 0x54 },
@@ -363,9 +488,9 @@ uint32_t svision_state::screen_update_svision(screen_device &screen, bitmap_ind1
const int start_x = 3 - (m_reg[XPOS] & 3);
const int end_x = std::min(163, m_reg[XSIZE] | 3);
uint16_t *line = &bitmap.pix(y, start_x);
- for (int x = start_x, i = 0; x < end_x; x+=4, i++)
+ for (int x = start_x, i = 0; x < end_x; x += 4, i++)
{
- uint8_t b = m_videoram[j+i];
+ uint8_t b = m_videoram[j + i];
for (int pix = 0; pix < 4; pix++)
{
*line = b & 3;
@@ -467,10 +592,23 @@ void svision_state::machine_start()
if (m_cart_rom)
{
- int num_banks = m_cart_rom->bytes() / 0x4000;
- m_bank1->set_base(m_cart_rom->base());
- m_bank2->set_base(m_cart_rom->base() + (num_banks - 1) * 0x4000); // bank2 is set to the last bank
+ const int num_banks = m_cart_rom->bytes() / 0x4000;
+ m_bank[0]->configure_entries(0, num_banks, m_cart_rom->base(), 0x4000);
+ m_bank[1]->set_base(m_cart_rom->base() + (num_banks - 1) * 0x4000); // bank2 is set to the last bank
}
+
+ save_item(STRUCT_MEMBER(m_svision, timer_shot));
+
+ save_item(STRUCT_MEMBER(m_pet, state));
+ save_item(STRUCT_MEMBER(m_pet, on));
+ save_item(STRUCT_MEMBER(m_pet, clock));
+ save_item(STRUCT_MEMBER(m_pet, data));
+ save_item(STRUCT_MEMBER(m_pet, input));
+
+ save_item(STRUCT_MEMBER(m_tvlink, palette));
+ save_item(STRUCT_MEMBER(m_tvlink, palette_on));
+
+ save_item(NAME(m_dma_finished));
}
void svision_state::machine_reset()
@@ -488,10 +626,10 @@ MACHINE_RESET_MEMBER(svision_state,tvlink)
memset(m_reg + 0x800, 0xff, 0x40); // normally done from m_tvlink microcontroller
m_reg[0x82a] = 0xdf;
- m_tvlink.palette[0] = MAKE24_RGB32(svisionp_pens[0].r(), svisionp_pens[0].g(), svisionp_pens[0].b());
- m_tvlink.palette[1] = MAKE24_RGB32(svisionp_pens[1].r(), svisionp_pens[1].g(), svisionp_pens[1].b());
- m_tvlink.palette[2] = MAKE24_RGB32(svisionp_pens[2].r(), svisionp_pens[2].g(), svisionp_pens[2].b());
- m_tvlink.palette[3] = MAKE24_RGB32(svisionp_pens[3].r(), svisionp_pens[3].g(), svisionp_pens[3].b());
+ m_tvlink.palette[0] = make24_rgb32(svisionp_pens[0].r(), svisionp_pens[0].g(), svisionp_pens[0].b());
+ m_tvlink.palette[1] = make24_rgb32(svisionp_pens[1].r(), svisionp_pens[1].g(), svisionp_pens[1].b());
+ m_tvlink.palette[2] = make24_rgb32(svisionp_pens[2].r(), svisionp_pens[2].g(), svisionp_pens[2].b());
+ m_tvlink.palette[3] = make24_rgb32(svisionp_pens[3].r(), svisionp_pens[3].g(), svisionp_pens[3].b());
}
void svision_state::svision_base(machine_config &config)
@@ -500,7 +638,7 @@ void svision_state::svision_base(machine_config &config)
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
- SVISION_SND(config, m_sound, 4000000, m_maincpu, m_bank1);
+ SVISION_SND(config, m_sound, 4'000'000, m_maincpu, m_bank[0]);
m_sound->add_route(0, "lspeaker", 0.50);
m_sound->add_route(1, "rspeaker", 0.50);
m_sound->irq_cb().set(FUNC(svision_state::sound_irq_w));
@@ -516,7 +654,7 @@ void svision_state::svision(machine_config &config)
{
svision_base(config);
- M65C02(config, m_maincpu, 4000000);
+ M65C02(config, m_maincpu, 4'000'000);
m_maincpu->set_addrmap(AS_PROGRAM, &svision_state::svision_mem);
SCREEN(config, m_screen, SCREEN_TYPE_LCD);
@@ -540,7 +678,7 @@ void svision_state::svisionp(machine_config &config)
{
svision(config);
- m_maincpu->set_clock(4430000);
+ m_maincpu->set_clock(4'430'000);
m_screen->set_refresh(HZ_TO_ATTOSECONDS(50));
m_palette->set_init(FUNC(svision_state::svisionp_palette));
}
@@ -548,7 +686,7 @@ void svision_state::svisionp(machine_config &config)
void svision_state::svisionn(machine_config &config)
{
svision(config);
- m_maincpu->set_clock(3560000/*?*/);
+ m_maincpu->set_clock(3'560'000); // ?
m_screen->set_refresh(HZ_TO_ATTOSECONDS(60));
m_palette->set_init(FUNC(svision_state::svisionn_palette));
}
@@ -568,6 +706,16 @@ ROM_START(svision)
ROM_REGION(0x80000, "maincpu", ROMREGION_ERASE00)
ROM_END
+ROM_START(tvlinkp)
+ ROM_REGION(0x80000, "maincpu", ROMREGION_ERASE00)
+
+ ROM_REGION(0x10000, "bezel", 0 )
+ ROM_LOAD( "9307md_512d.glob", 0x00000, 0x10000, CRC(bc8b981b) SHA1(3328da4fd9462286e8cefe4372ffd17c8f5a229e) )
+ROM_END
+
+} // anonymous namespace
+
+
/***************************************************************************
Game driver(s)
@@ -577,16 +725,15 @@ ROM_END
#define rom_svisions rom_svision
#define rom_svisionn rom_svision
#define rom_svisionp rom_svision
-#define rom_tvlinkp rom_svision
// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
// marketed under a ton of firms and names
-CONS(1992, svision, 0, 0, svision, svision, svision_state, init_svision, "Watara", "Super Vision", 0 )
+CONS(1992, svision, 0, 0, svision, svision, svision_state, init_svision, "Watara", "Super Vision", MACHINE_SUPPORTS_SAVE )
// svdual 2 connected via communication port
-CONS( 1992, svisions, svision, 0, svisions, svisions, svision_state, init_svisions, "Watara", "Super Vision (PeT Communication Simulation)", 0 )
+CONS( 1992, svisions, svision, 0, svisions, svisions, svision_state, init_svisions, "Watara", "Super Vision (PeT Communication Simulation)", MACHINE_SUPPORTS_SAVE )
-CONS( 1993, svisionp, svision, 0, svisionp, svision, svision_state, init_svision, "Watara", "Super Vision (PAL TV Link Colored)", 0 )
-CONS( 1993, svisionn, svision, 0, svisionn, svision, svision_state, init_svision, "Watara", "Super Vision (NTSC TV Link Colored)", 0 )
+CONS( 1993, svisionp, svision, 0, svisionp, svision, svision_state, init_svision, "Watara", "Super Vision (PAL TV Link Colored)", MACHINE_SUPPORTS_SAVE )
+CONS( 1993, svisionn, svision, 0, svisionn, svision, svision_state, init_svision, "Watara", "Super Vision (NTSC TV Link Colored)", MACHINE_SUPPORTS_SAVE )
// svtvlink (2 supervisions)
// tvlink (pad supervision simulated)
-CONS( 199?, tvlinkp, svision, 0, tvlinkp, svision, svision_state, init_svision, "Watara", "TV Link PAL", 0 )
+CONS( 199?, tvlinkp, svision, 0, tvlinkp, svision, svision_state, init_svision, "Watara", "TV Link PAL", MACHINE_SUPPORTS_SAVE )
diff --git a/src/mame/svision/svision.h b/src/mame/svision/svision.h
deleted file mode 100644
index e0c8fe09756..00000000000
--- a/src/mame/svision/svision.h
+++ /dev/null
@@ -1,128 +0,0 @@
-// license:GPL-2.0+
-// copyright-holders:Peter Trauner
-/*****************************************************************************
- *
- * includes/svision.h
- *
- ****************************************************************************/
-
-#ifndef MAME_SVISION_SVISION_H
-#define MAME_SVISION_SVISION_H
-
-#pragma once
-
-#include "cpu/m6502/m65c02.h"
-#include "machine/timer.h"
-#include "svis_snd.h"
-#include "bus/generic/slot.h"
-#include "bus/generic/carts.h"
-#include "emupal.h"
-
-struct tvlink_t
-{
- uint32_t palette[4/*0x40?*/]; /* rgb8 */
- int palette_on;
-};
-
-class svision_state : public driver_device
-{
-public:
- svision_state(const machine_config &mconfig, device_type type, const char *tag)
- : driver_device(mconfig, type, tag)
- , m_maincpu(*this, "maincpu")
- , m_sound(*this, "custom")
- , m_cart(*this, "cartslot")
- , m_reg(*this, "reg")
- , m_videoram(*this, "videoram")
- , m_screen(*this, "screen")
- , m_joy(*this, "JOY")
- , m_joy2(*this, "JOY2")
- , m_palette(*this, "palette")
- , m_bank1(*this, "bank1")
- , m_bank2(*this, "bank2")
- { }
-
- void svisionp(machine_config &config);
- void svisions(machine_config &config);
- void tvlinkp(machine_config &config);
- void svision(machine_config &config);
- void svisionn(machine_config &config);
- void svision_base(machine_config &config);
-
- void init_svisions();
- void init_svision();
-
-protected:
- virtual void machine_start() override;
- virtual void machine_reset() override;
-
-private:
- struct svision_t
- {
- emu_timer *timer1 = nullptr;
- int timer_shot = 0;
- };
-
- struct svision_pet_t
- {
- int state = 0;
- int on = 0, clock = 0, data = 0;
- uint8_t input = 0;
- emu_timer *timer = nullptr;
- };
-
- DECLARE_WRITE_LINE_MEMBER(sound_irq_w);
- uint8_t svision_r(offs_t offset);
- void svision_w(offs_t offset, uint8_t data);
- uint8_t tvlink_r(offs_t offset);
- void tvlink_w(offs_t offset, uint8_t data);
-
- uint32_t screen_update_svision(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
- uint32_t screen_update_tvlink(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- DECLARE_WRITE_LINE_MEMBER(frame_int_w);
- DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
-
- void svision_palette(palette_device &palette) const;
- void svisionp_palette(palette_device &palette) const;
- void svisionn_palette(palette_device &palette) const;
- DECLARE_MACHINE_RESET(tvlink);
-
- enum
- {
- XSIZE = 0x00,
- XPOS = 0x02,
- YPOS = 0x03,
- BANK = 0x26,
- };
-
- void check_irq();
-
- TIMER_CALLBACK_MEMBER(svision_pet_timer);
- TIMER_CALLBACK_MEMBER(svision_timer);
- TIMER_DEVICE_CALLBACK_MEMBER(svision_pet_timer_dev);
-
- void svision_mem(address_map &map);
- void tvlink_mem(address_map &map);
-
- required_device m_maincpu;
- required_device m_sound;
- required_device m_cart;
- required_shared_ptr m_reg;
- required_shared_ptr m_videoram;
- required_device m_screen;
- required_ioport m_joy;
- optional_ioport m_joy2;
- required_device m_palette;
-
- required_memory_bank m_bank1;
- required_memory_bank m_bank2;
-
- memory_region *m_cart_rom = nullptr;
-
- svision_t m_svision;
- svision_pet_t m_pet;
- tvlink_t m_tvlink;
- bool m_dma_finished = false;
-};
-
-#endif // MAME_SVISION_SVISION_H