summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/svision.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/svision.cpp')
-rw-r--r--src/mame/drivers/svision.cpp290
1 files changed, 131 insertions, 159 deletions
diff --git a/src/mame/drivers/svision.cpp b/src/mame/drivers/svision.cpp
index 5cd168ab6ff..a8b15a0a3f5 100644
--- a/src/mame/drivers/svision.cpp
+++ b/src/mame/drivers/svision.cpp
@@ -21,32 +21,26 @@
#define MAKE24_RGB32(red8, green8, blue8) ( (((red8)&0xf8)<<16) | (((green8)&0xf8)<<8) | (((blue8)&0xf8)) )
-// in pixel
-#define XSIZE (m_reg[0]&~3)
-#define XPOS m_reg[2]
-#define YPOS m_reg[3]
-#define BANK m_reg[0x26]
-
TIMER_CALLBACK_MEMBER(svision_state::svision_pet_timer)
{
switch (m_pet.state)
{
- case 0:
+ case 0x00:
if (m_joy2.found())
{
m_pet.input = m_joy2->read();
}
/* fall through */
- case 2: case 4: case 6: case 8:
- case 10: case 12: case 14:
+ case 0x02: case 0x04: case 0x06: case 0x08:
+ case 0x0a: case 0x0c: case 0x0e:
m_pet.clock = m_pet.state & 2;
m_pet.data = m_pet.input & 1;
m_pet.input >>= 1;
m_pet.state++;
break;
- case 16+15:
+ case 0x1f:
m_pet.state = 0;
break;
@@ -61,10 +55,16 @@ TIMER_DEVICE_CALLBACK_MEMBER(svision_state::svision_pet_timer_dev)
svision_pet_timer(ptr,param);
}
-void svision_state::svision_irq()
+WRITE_LINE_MEMBER(svision_state::sound_irq_w)
+{
+ m_dma_finished = true;
+ check_irq();
+}
+
+void svision_state::check_irq()
{
- int irq = m_svision.timer_shot && (BANK & 2);
- irq = irq || (*m_dma_finished && (BANK & 4));
+ bool irq = m_svision.timer_shot && BIT(m_reg[BANK], 1);
+ irq = irq || (m_dma_finished && BIT(m_reg[BANK], 2));
m_maincpu->set_input_line(M65C02_IRQ_LINE, irq ? ASSERT_LINE : CLEAR_LINE);
}
@@ -73,7 +73,7 @@ TIMER_CALLBACK_MEMBER(svision_state::svision_timer)
{
m_svision.timer_shot = true;
m_svision.timer1->enable(false);
- svision_irq();
+ check_irq();
}
READ8_MEMBER(svision_state::svision_r)
@@ -82,8 +82,7 @@ READ8_MEMBER(svision_state::svision_r)
switch (offset)
{
case 0x20:
- data = m_joy->read();
- break;
+ return m_joy->read();
case 0x21:
data &= ~0xf;
@@ -105,22 +104,22 @@ READ8_MEMBER(svision_state::svision_r)
data &= ~3;
if (m_svision.timer_shot)
{
- data|=1;
+ data |= 1;
}
- if (*m_dma_finished)
+ if (m_dma_finished)
{
- data|=2;
+ data |= 2;
}
break;
case 0x24:
m_svision.timer_shot = false;
- svision_irq();
+ check_irq();
break;
case 0x25:
- *m_dma_finished = false;
- svision_irq();
+ m_dma_finished = false;
+ check_irq();
break;
default:
@@ -133,39 +132,29 @@ READ8_MEMBER(svision_state::svision_r)
WRITE8_MEMBER(svision_state::svision_w)
{
- int value, delay, bank;
-
m_reg[offset] = data;
switch (offset)
{
- case 2:
- case 3:
+ case 0x02:
+ case 0x03:
break;
case 0x26: /* bits 5,6 memory management for a000? */
+ {
logerror("%.6f svision write %04x %02x\n", machine().time().as_double(), offset, data);
- bank = ((m_reg[0x26] & 0xe0) >> 5) % (m_cart_rom->bytes() / 0x4000);
+ int bank = ((m_reg[0x26] & 0xe0) >> 5) % (m_cart_rom->bytes() / 0x4000);
m_bank1->set_base(m_cart_rom->base() + (bank * 0x4000));
- svision_irq();
+ check_irq();
break;
+ }
case 0x23: /* delta hero irq routine write */
- value = data;
- if (!data)
- {
- value = 0x100;
- }
- if (BANK & 0x10)
- {
- delay = 16384;
- }
- else
- {
- delay = 256;
- }
m_svision.timer1->enable(true);
- m_svision.timer1->reset(m_maincpu->cycles_to_attotime(value * delay));
+ if (BIT(m_reg[BANK], 4))
+ m_svision.timer1->reset(m_maincpu->cycles_to_attotime(0x100 * 0x4000));
+ else
+ m_svision.timer1->reset(m_maincpu->cycles_to_attotime(0x100 * 0x100));
break;
case 0x10: case 0x11: case 0x12: case 0x13:
@@ -235,16 +224,15 @@ WRITE8_MEMBER(svision_state::tvlink_w)
svision_w(space, offset,data);
if (offset >= 0x800 && offset < 0x840)
{
- uint16_t c;
if (offset == 0x803 && data == 0x07)
{
/* tron hack */
- m_reg[0x0804]=0x00;
- m_reg[0x0805]=0x01;
- m_reg[0x0806]=0x00;
- m_reg[0x0807]=0x00;
+ m_reg[0x0804] = 0x00;
+ m_reg[0x0805] = 0x01;
+ m_reg[0x0806] = 0x00;
+ m_reg[0x0807] = 0x00;
}
- c = m_reg[0x800] | (m_reg[0x804] << 8);
+ 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);
c = m_reg[0x801] | (m_reg[0x805] << 8);
m_tvlink.palette[1] = MAKE9_RGB32( (c>>0)&7, (c>>3)&7, (c>>6)&7);
@@ -262,21 +250,21 @@ WRITE8_MEMBER(svision_state::tvlink_w)
void svision_state::svision_mem(address_map &map)
{
map(0x0000, 0x1fff).ram();
- map(0x2000, 0x3fff).rw(this, FUNC(svision_state::svision_r), FUNC(svision_state::svision_w)).share("reg");
- map(0x4000, 0x5fff).ram().share("videoram");
+ map(0x2000, 0x3fff).rw(this, FUNC(svision_state::svision_r), FUNC(svision_state::svision_w)).share(m_reg);
+ map(0x4000, 0x5fff).ram().share(m_videoram);
map(0x6000, 0x7fff).noprw();
- map(0x8000, 0xbfff).bankr("bank1");
- map(0xc000, 0xffff).bankr("bank2");
+ map(0x8000, 0xbfff).bankr(m_bank1);
+ map(0xc000, 0xffff).bankr(m_bank2);
}
void svision_state::tvlink_mem(address_map &map)
{
map(0x0000, 0x1fff).ram();
- map(0x2000, 0x3fff).rw(this, FUNC(svision_state::tvlink_r), FUNC(svision_state::tvlink_w)).share("reg");
- map(0x4000, 0x5fff).ram().share("videoram");
+ map(0x2000, 0x3fff).rw(this, 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("bank1");
- map(0xc000, 0xffff).bankr("bank2");
+ map(0x8000, 0xbfff).bankr(m_bank1);
+ map(0xc000, 0xffff).bankr(m_bank2);
}
static INPUT_PORTS_START( svision )
@@ -315,8 +303,6 @@ INPUT_PORTS_END
/* most games contain their graphics in roms, and have hardware to
draw complete rectangular objects */
-#define PALETTE_START 0
-
/* palette in red, green, blue triples */
static const unsigned char svision_palette[] =
{
@@ -337,7 +323,7 @@ static const unsigned char svision_palette[] =
#endif
};
-/* palette in red, green, blue tribles */
+/* palette in RGB triplets */
static const unsigned char svisionp_palette[] =
{
// pal
@@ -347,7 +333,7 @@ static const unsigned char svisionp_palette[] =
190, 190, 190
};
-/* palette in red, green, blue tribles */
+/* palette in RGB triplets */
static const unsigned char svisionn_palette[] =
{
0, 0, 0,
@@ -374,69 +360,71 @@ PALETTE_INIT_MEMBER(svision_state,svisionp)
uint32_t svision_state::screen_update_svision(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
- int x, y, i, j=XPOS/4+YPOS*0x30;
- uint8_t *videoram = m_videoram;
-
- if (BANK&8)
+ if (BIT(m_reg[BANK], 3))
{
- for (y=0; y<160; y++)
+ int j = m_reg[XPOS] / 4 + m_reg[YPOS] * 0x30;
+ for (int y = 0; y < 160; y++)
{
- uint16_t *line = &bitmap.pix16(y, 3 - (XPOS & 3));
- for (x=3-(XPOS&3),i=0; x<160+3 && x<XSIZE+3; x+=4,i++)
+ const int start_x = 3 - (m_reg[XPOS] & 3);
+ const int end_x = std::min(163, m_reg[XSIZE] | 3);
+ uint16_t *line = &bitmap.pix16(y, start_x);
+ for (int x = start_x, i = 0; x < end_x; x+=4, i++)
{
- uint8_t b=videoram[j+i];
- line[3]=((b>>6)&3)+PALETTE_START;
- line[2]=((b>>4)&3)+PALETTE_START;
- line[1]=((b>>2)&3)+PALETTE_START;
- line[0]=((b>>0)&3)+PALETTE_START;
- line+=4;
+ uint8_t b = m_videoram[j+i];
+ for (int pix = 0; pix < 4; pix++)
+ {
+ *line = b & 3;
+ b >>= 2;
+ line++;
+ }
}
j += 0x30;
- if (j >= 8160)
+ if (j >= 0x1fe0)
j = 0; //sssnake
}
}
else
{
- bitmap.plot_box(3, 0, 162, 159, PALETTE_START);
+ bitmap.plot_box(3, 0, 162, 159, 0);
}
return 0;
}
uint32_t svision_state::screen_update_tvlink(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- int x, y, i, j = XPOS/4+YPOS*0x30;
- uint8_t *videoram = m_videoram;
-
- if (BANK & 8)
+ if (BIT(m_reg[BANK], 3))
{
- for (y = 0; y < 160; y++)
+ int j = m_reg[XPOS] / 4 + m_reg[YPOS] * 0x30;
+ for (int y = 0; y < 160; y++)
{
- uint32_t *line = &bitmap.pix32(y, 3 - (XPOS & 3));
- for (x = 3 - (XPOS & 3), i = 0; x < 160 + 3 && x < XSIZE + 3; x += 4, i++)
+ const int start_x = 3 - (m_reg[XPOS] & 3);
+ const int end_x = std::min(163, m_reg[XSIZE] | 3);
+ uint32_t *line = &bitmap.pix32(y, start_x);
+ for (int x = start_x, i = 0; x < end_x; x += 4, i++)
{
- uint8_t b=videoram[j+i];
- line[3]=m_tvlink.palette[(b>>6)&3];
- line[2]=m_tvlink.palette[(b>>4)&3];
- line[1]=m_tvlink.palette[(b>>2)&3];
- line[0]=m_tvlink.palette[(b>>0)&3];
- line+=4;
+ uint8_t b = m_videoram[j + i];
+ for (int pix = 0; pix < 4; pix++)
+ {
+ *line = m_tvlink.palette[b & 3];
+ b >>= 2;
+ line++;
+ }
}
j += 0x30;
- if (j >= 8160)
+ if (j >= 0x1fe0)
j = 0; //sssnake
}
}
else
{
- bitmap.plot_box(3, 0, 162, 159, m_palette->pen(PALETTE_START));
+ bitmap.plot_box(3, 0, 162, 159, m_palette->pen(0));
}
return 0;
}
INTERRUPT_GEN_MEMBER(svision_state::svision_frame_int)
{
- if (BANK & 1)
+ if (BIT(m_reg[BANK], 0))
device.execute().pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_sound->sound_decrement();
@@ -445,14 +433,14 @@ INTERRUPT_GEN_MEMBER(svision_state::svision_frame_int)
void svision_state::init_svision()
{
m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this));
- m_dma_finished = m_sound->dma_finished();
+ m_dma_finished = false;
m_pet.on = false;
}
void svision_state::init_svisions()
{
m_svision.timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_timer),this));
- m_dma_finished = m_sound->dma_finished();
+ m_dma_finished = false;
m_pet.on = true;
m_pet.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(svision_state::svision_pet_timer),this));
}
@@ -475,28 +463,22 @@ DEVICE_IMAGE_LOAD_MEMBER( svision_state, svision_cart )
void svision_state::machine_start()
{
- int num_banks = 0;
- std::string region_tag;
- m_cart_rom = memregion(region_tag.assign(m_cart->tag()).append(GENERIC_ROM_REGION_TAG).c_str());
- if (m_cart_rom)
- num_banks = m_cart_rom->bytes() / 0x4000;
+ std::string region_tag(m_cart->tag());
+ region_tag.append(GENERIC_ROM_REGION_TAG);
+ m_cart_rom = memregion(region_tag.c_str());
- m_bank1 = membank("bank1");
- m_bank2 = membank("bank2");
- // bank1 is set to the first bank
- // do not crash if no cart
- if (num_banks)
+ if (m_cart_rom)
{
+ int num_banks = m_cart_rom->bytes() / 0x4000;
m_bank1->set_base(m_cart_rom->base());
- // bank2 is set to the last bank
- m_bank2->set_base(m_cart_rom->base() + (num_banks - 1) * 0x4000);
+ m_bank2->set_base(m_cart_rom->base() + (num_banks - 1) * 0x4000); // bank2 is set to the last bank
}
}
void svision_state::machine_reset()
{
m_svision.timer_shot = false;
- *m_dma_finished = false;
+ m_dma_finished = false;
}
@@ -508,49 +490,48 @@ 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_palette[(PALETTE_START+0)*3+0], svisionp_palette[(PALETTE_START+0)*3+1], svisionp_palette[(PALETTE_START+0)*3+2]);
- m_tvlink.palette[1] = MAKE24_RGB32(svisionp_palette[(PALETTE_START+1)*3+0], svisionp_palette[(PALETTE_START+1)*3+1], svisionp_palette[(PALETTE_START+1)*3+2]);
- m_tvlink.palette[2] = MAKE24_RGB32(svisionp_palette[(PALETTE_START+2)*3+0], svisionp_palette[(PALETTE_START+2)*3+1], svisionp_palette[(PALETTE_START+2)*3+2]);
- m_tvlink.palette[3] = MAKE24_RGB32(svisionp_palette[(PALETTE_START+3)*3+0], svisionp_palette[(PALETTE_START+3)*3+1], svisionp_palette[(PALETTE_START+3)*3+2]);
+ m_tvlink.palette[0] = MAKE24_RGB32(svisionp_palette[ 0], svisionp_palette[ 1], svisionp_palette[ 2]);
+ m_tvlink.palette[1] = MAKE24_RGB32(svisionp_palette[ 3], svisionp_palette[ 4], svisionp_palette[ 5]);
+ m_tvlink.palette[2] = MAKE24_RGB32(svisionp_palette[ 6], svisionp_palette[ 7], svisionp_palette[ 8]);
+ m_tvlink.palette[3] = MAKE24_RGB32(svisionp_palette[ 9], svisionp_palette[10], svisionp_palette[11]);
}
-MACHINE_CONFIG_START(svision_state::svision)
- /* basic machine hardware */
- MCFG_DEVICE_ADD("maincpu", M65C02, 4000000) /* ? stz used! speed? */
- MCFG_DEVICE_PROGRAM_MAP(svision_mem)
- MCFG_DEVICE_VBLANK_INT_DRIVER("screen", svision_state, svision_frame_int)
-
- /* video hardware */
- MCFG_SCREEN_ADD("screen", LCD)
- MCFG_SCREEN_REFRESH_RATE(61)
- MCFG_SCREEN_SIZE(3+160+3, 160)
- MCFG_SCREEN_VISIBLE_AREA(3+0, 3+160-1, 0, 160-1)
- MCFG_SCREEN_UPDATE_DRIVER(svision_state, screen_update_svision)
- MCFG_SCREEN_PALETTE("palette")
-
- MCFG_PALETTE_ADD("palette", ARRAY_LENGTH(svision_palette) * 3)
- MCFG_PALETTE_INIT_OWNER(svision_state, svision )
-
+MACHINE_CONFIG_START(svision_state::svision_base)
MCFG_DEFAULT_LAYOUT(layout_svision)
- /* sound hardware */
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
- MCFG_DEVICE_ADD("custom", SVISION_SND, 0)
+ MCFG_DEVICE_ADD(m_sound, SVISION_SND, 4000000, m_maincpu, m_bank1)
MCFG_SOUND_ROUTE(0, "lspeaker", 0.50)
MCFG_SOUND_ROUTE(1, "rspeaker", 0.50)
- SVISION_SND_IRQ_CB(svision_state, svision_irq)
+ MCFG_SVISION_SOUND_IRQ_CALLBACK(WRITELINE(*this, svision_state, sound_irq_w));
- /* cartridge */
- MCFG_GENERIC_CARTSLOT_ADD("cartslot", generic_plain_slot, "svision_cart")
+ MCFG_GENERIC_CARTSLOT_ADD(m_cart, generic_plain_slot, "svision_cart")
MCFG_GENERIC_EXTENSIONS("bin,ws,sv")
MCFG_GENERIC_MANDATORY
MCFG_GENERIC_LOAD(svision_state, svision_cart)
- /* Software lists */
MCFG_SOFTWARE_LIST_ADD("cart_list", "svision")
MACHINE_CONFIG_END
+MACHINE_CONFIG_START(svision_state::svision)
+ svision_base(config);
+
+ MCFG_DEVICE_ADD(m_maincpu, M65C02, 4000000)
+ MCFG_DEVICE_PROGRAM_MAP(svision_mem)
+ MCFG_DEVICE_VBLANK_INT_DRIVER(m_screen, svision_state, svision_frame_int)
+
+ MCFG_SCREEN_ADD(m_screen, LCD)
+ MCFG_SCREEN_REFRESH_RATE(61)
+ MCFG_SCREEN_SIZE(3+160+3, 160)
+ MCFG_SCREEN_VISIBLE_AREA(3+0, 3+160-1, 0, 160-1)
+ MCFG_SCREEN_UPDATE_DRIVER(svision_state, screen_update_svision)
+ MCFG_SCREEN_PALETTE(m_palette)
+
+ MCFG_PALETTE_ADD(m_palette, ARRAY_LENGTH(svision_palette) * 3)
+ MCFG_PALETTE_INIT_OWNER(svision_state, svision )
+MACHINE_CONFIG_END
+
MACHINE_CONFIG_START(svision_state::svisions)
svision(config);
MCFG_TIMER_DRIVER_ADD_PERIODIC("pet_timer", svision_state, svision_pet_timer_dev, attotime::from_seconds(8))
@@ -558,54 +539,45 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(svision_state::svisionp)
svision(config);
- MCFG_DEVICE_MODIFY("maincpu")
- MCFG_DEVICE_CLOCK(4430000)
- MCFG_SCREEN_MODIFY("screen")
- MCFG_SCREEN_REFRESH_RATE(50)
- MCFG_PALETTE_MODIFY("palette")
- MCFG_PALETTE_INIT_OWNER(svision_state, svisionp)
+
+ m_maincpu->set_clock(4430000);
+ m_screen->set_refresh(HZ_TO_ATTOSECONDS(50));
+ m_palette->set_init(palette_init_delegate(&svision_state::palette_init_svisionp, "svision_state::palette_init_svisionp", this));
MACHINE_CONFIG_END
MACHINE_CONFIG_START(svision_state::svisionn)
svision(config);
- MCFG_DEVICE_MODIFY("maincpu")
- MCFG_DEVICE_CLOCK(3560000/*?*/)
- MCFG_SCREEN_MODIFY("screen")
- MCFG_SCREEN_REFRESH_RATE(60)
- MCFG_PALETTE_MODIFY("palette")
- MCFG_PALETTE_INIT_OWNER(svision_state, svisionn)
+ m_maincpu->set_clock(3560000/*?*/);
+ m_screen->set_refresh(HZ_TO_ATTOSECONDS(60));
+ m_palette->set_init(palette_init_delegate(&svision_state::palette_init_svisionn, "svision_state::palette_init_svisionn", this));
MACHINE_CONFIG_END
MACHINE_CONFIG_START(svision_state::tvlinkp)
svisionp(config);
- MCFG_DEVICE_MODIFY("maincpu")
- MCFG_DEVICE_PROGRAM_MAP(tvlink_mem)
-
- MCFG_MACHINE_RESET_OVERRIDE(svision_state, tvlink)
+ m_maincpu->set_addrmap(AS_PROGRAM, address_map_constructor(&std::remove_pointer_t<decltype(this)>::tvlink_mem, tag(), this));
- MCFG_SCREEN_MODIFY("screen")
- MCFG_SCREEN_NO_PALETTE
- MCFG_SCREEN_UPDATE_DRIVER(svision_state, screen_update_tvlink)
+ m_screen->set_palette(finder_base::DUMMY_TAG);
+ m_screen->set_screen_update(screen_update_delegate_smart(&svision_state::screen_update_tvlink, "svision_state::screen_update_tvlink", nullptr));
+ MCFG_MACHINE_RESET_OVERRIDE(svision_state, tvlink)
MACHINE_CONFIG_END
ROM_START(svision)
ROM_REGION(0x80000, "maincpu", ROMREGION_ERASE00)
ROM_END
-
-#define rom_svisions rom_svision
-#define rom_svisionn rom_svision
-#define rom_svisionp rom_svision
-#define rom_tvlinkp rom_svision
-
/***************************************************************************
Game driver(s)
***************************************************************************/
-// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
+#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 )
// svdual 2 connected via communication port