mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
tama: add svg screen, svg shapes taken from BrickEmuPy [hap, azya]
This commit is contained in:
parent
abf2bacb4c
commit
4881a08752
@ -41,8 +41,8 @@ void e0c6s46_device::e0c6s46_program(address_map &map)
|
||||
void e0c6s46_device::e0c6s46_data(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x027f).ram();
|
||||
map(0x0e00, 0x0e4f).ram().share("vram1");
|
||||
map(0x0e80, 0x0ecf).ram().share("vram2");
|
||||
map(0x0e00, 0x0e4f).ram().share(m_vram[0]);
|
||||
map(0x0e80, 0x0ecf).ram().share(m_vram[1]);
|
||||
map(0x0f00, 0x0f7f).rw(FUNC(e0c6s46_device::io_r), FUNC(e0c6s46_device::io_w));
|
||||
}
|
||||
|
||||
@ -50,9 +50,9 @@ void e0c6s46_device::e0c6s46_data(address_map &map)
|
||||
// device definitions
|
||||
e0c6s46_device::e0c6s46_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
e0c6200_cpu_device(mconfig, E0C6S46, tag, owner, clock, address_map_constructor(FUNC(e0c6s46_device::e0c6s46_program), this), address_map_constructor(FUNC(e0c6s46_device::e0c6s46_data), this)),
|
||||
m_vram1(*this, "vram1"),
|
||||
m_vram2(*this, "vram2"),
|
||||
m_pixel_update_cb(*this),
|
||||
m_vram(*this, "vram%u", 1U),
|
||||
m_write_segs(*this),
|
||||
m_write_contrast(*this),
|
||||
m_write_r(*this),
|
||||
m_read_p(*this, 0),
|
||||
m_write_p(*this)
|
||||
@ -68,15 +68,19 @@ void e0c6s46_device::device_start()
|
||||
{
|
||||
e0c6200_cpu_device::device_start();
|
||||
|
||||
m_pixel_update_cb.resolve();
|
||||
|
||||
// create timers
|
||||
// misc init
|
||||
m_core_256_handle = timer_alloc(FUNC(e0c6s46_device::core_256_cb), this);
|
||||
m_core_256_handle->adjust(attotime::from_ticks(64, unscaled_clock()));
|
||||
m_prgtimer_handle = timer_alloc(FUNC(e0c6s46_device::prgtimer_cb), this);
|
||||
m_prgtimer_handle->adjust(attotime::never);
|
||||
m_buzzer_handle = timer_alloc(FUNC(e0c6s46_device::buzzer_cb), this);
|
||||
m_buzzer_handle->adjust(attotime::never);
|
||||
m_lcd_driver = timer_alloc(FUNC(e0c6s46_device::lcd_driver_cb), this);
|
||||
m_lcd_driver->adjust(attotime::from_ticks(1024, unscaled_clock()));
|
||||
|
||||
const u32 render_buf_size = m_vram[0].bytes() * 2 * 4;
|
||||
m_render_buf = make_unique_clear<u8[]>(render_buf_size);
|
||||
save_pointer(NAME(m_render_buf), render_buf_size);
|
||||
|
||||
// zerofill
|
||||
memset(m_port_r, 0x0, sizeof(m_port_r));
|
||||
@ -195,6 +199,8 @@ void e0c6s46_device::device_reset()
|
||||
m_data->write_byte(0xf7d, 0x0);
|
||||
m_data->write_byte(0xf7e, 0x0);
|
||||
|
||||
m_write_contrast(m_lcd_contrast);
|
||||
|
||||
// reset ports
|
||||
for (int i = 0; i < 5; i++)
|
||||
write_r(i, m_port_r[i]);
|
||||
@ -545,13 +551,11 @@ void e0c6s46_device::clock_bz_1shot()
|
||||
// LCD Driver
|
||||
//-------------------------------------------------
|
||||
|
||||
u32 e0c6s46_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
TIMER_CALLBACK_MEMBER(e0c6s46_device::lcd_driver_cb)
|
||||
{
|
||||
// call this 32 times per second (osc1/1024: 32hz at default clock of 32768hz)
|
||||
// this gets called 32 times per second (osc1/1024: 32hz at default clock of 32768hz)
|
||||
for (int bank = 0; bank < 2; bank++)
|
||||
{
|
||||
const u8* vram = bank ? m_vram2 : m_vram1;
|
||||
|
||||
// determine operating mode
|
||||
bool lcd_on = false;
|
||||
int pixel = 0;
|
||||
@ -563,26 +567,25 @@ u32 e0c6s46_device::screen_update(screen_device &screen, bitmap_ind16 &bitmap, c
|
||||
lcd_on = true;
|
||||
|
||||
// draw pixels
|
||||
for (int offset = 0; offset < 0x50; offset++)
|
||||
for (int offset = 0; offset < m_vram[0].bytes(); offset++)
|
||||
{
|
||||
for (int c = 0; c < 4; c++)
|
||||
{
|
||||
if (lcd_on)
|
||||
pixel = vram[offset] >> c & 1;
|
||||
pixel = m_vram[bank][offset] >> c & 1;
|
||||
|
||||
// 16 COM(common) pins, 40 SEG(segment) pins
|
||||
int seg = offset / 2;
|
||||
int com = bank * 8 + (offset & 1) * 4 + c;
|
||||
|
||||
if (!m_pixel_update_cb.isnull())
|
||||
m_pixel_update_cb(bitmap, cliprect, m_lcd_contrast, seg, com, pixel);
|
||||
else if (cliprect.contains(seg, com))
|
||||
bitmap.pix(com, seg) = pixel;
|
||||
const u8 width = m_vram[0].bytes() * 4 / 8;
|
||||
m_render_buf[com * width + seg] = pixel;
|
||||
m_write_segs(seg << 4 | com, pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
m_lcd_driver->adjust(attotime::from_ticks(1024, unscaled_clock()));
|
||||
}
|
||||
|
||||
|
||||
@ -760,6 +763,7 @@ void e0c6s46_device::io_w(offs_t offset, u8 data)
|
||||
case 0x72:
|
||||
// contrast adjustment (0=light, 15=dark)
|
||||
m_lcd_contrast = data;
|
||||
m_write_contrast(data);
|
||||
break;
|
||||
|
||||
// SVD circuit (supply voltage detection)
|
||||
|
@ -42,10 +42,6 @@ enum
|
||||
};
|
||||
|
||||
|
||||
// lcd driver
|
||||
#define E0C6S46_PIXEL_UPDATE(name) void name(bitmap_ind16 &bitmap, const rectangle &cliprect, int contrast, int seg, int com, int state)
|
||||
|
||||
|
||||
class e0c6s46_device : public e0c6200_cpu_device
|
||||
{
|
||||
public:
|
||||
@ -60,12 +56,14 @@ public:
|
||||
template <std::size_t Port> auto read_p() { return m_read_p[Port].bind(); }
|
||||
template <std::size_t Port> auto write_p() { return m_write_p[Port].bind(); }
|
||||
|
||||
template <typename... T> void set_pixel_update_cb(T &&... args) { m_pixel_update_cb.set(std::forward<T>(args)...); }
|
||||
// LCD segment outputs: COM0-COM15 as a0-a3, SEG0-SEGx as a4-a10
|
||||
auto write_segs() { return m_write_segs.bind(); }
|
||||
|
||||
u8 io_r(offs_t offset);
|
||||
void io_w(offs_t offset, u8 data);
|
||||
// LCD contrast (adjusts VL pins overall voltage level)
|
||||
auto write_contrast() { return m_write_contrast.bind(); }
|
||||
|
||||
u32 screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
const u8 *lcd_buffer() { return &m_render_buf[0]; } // get intermediate LCD pixel buffer
|
||||
//u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); // optional
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -81,17 +79,25 @@ protected:
|
||||
void e0c6s46_program(address_map &map) ATTR_COLD;
|
||||
|
||||
private:
|
||||
required_shared_ptr<u8> m_vram1;
|
||||
required_shared_ptr<u8> m_vram2;
|
||||
u8 io_r(offs_t offset);
|
||||
void io_w(offs_t offset, u8 data);
|
||||
|
||||
required_shared_ptr_array<u8, 2> m_vram;
|
||||
|
||||
u8 m_irqflag[6];
|
||||
u8 m_irqmask[6];
|
||||
u8 m_osc;
|
||||
u8 m_svd;
|
||||
|
||||
// lcd driver
|
||||
u8 m_lcd_control;
|
||||
u8 m_lcd_contrast;
|
||||
pixel_update_delegate m_pixel_update_cb;
|
||||
std::unique_ptr<u8[]> m_render_buf;
|
||||
devcb_write8 m_write_segs;
|
||||
devcb_write8 m_write_contrast;
|
||||
|
||||
emu_timer *m_lcd_driver;
|
||||
TIMER_CALLBACK_MEMBER(lcd_driver_cb);
|
||||
|
||||
// i/o ports
|
||||
devcb_write8::array<5> m_write_r;
|
||||
|
@ -1,6 +1,6 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:hap
|
||||
// thanks-to:digshadow, Segher
|
||||
// thanks-to:digshadow, Segher, azya
|
||||
/*******************************************************************************
|
||||
|
||||
Bandai Tamagotchi generation 1 hardware
|
||||
@ -12,7 +12,6 @@ Hardware notes:
|
||||
- 1-bit sound
|
||||
|
||||
TODO:
|
||||
- change to SVG screen
|
||||
- add the Mothra version that was recently dumped (has a E0C6S48)
|
||||
|
||||
*******************************************************************************/
|
||||
@ -22,12 +21,9 @@ TODO:
|
||||
#include "cpu/e0c6200/e0c6s46.h"
|
||||
#include "sound/spkrdev.h"
|
||||
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
|
||||
#include "tama.lh"
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
@ -48,8 +44,7 @@ protected:
|
||||
virtual void machine_start() override ATTR_COLD;
|
||||
|
||||
private:
|
||||
void tama_palette(palette_device &palette) const;
|
||||
E0C6S46_PIXEL_UPDATE(pixel_update);
|
||||
void lcd_segment_w(offs_t offset, u8 data) { m_out_x[offset & 0xf][offset >> 4] = data; }
|
||||
|
||||
required_device<e0c6s46_device> m_maincpu;
|
||||
output_finder<16, 40> m_out_x;
|
||||
@ -62,43 +57,6 @@ void tamag1_state::machine_start()
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Video
|
||||
*******************************************************************************/
|
||||
|
||||
E0C6S46_PIXEL_UPDATE(tamag1_state::pixel_update)
|
||||
{
|
||||
// 16 COM(common) pins, 40 SEG(segment) pins from MCU, 32x16 LCD screen:
|
||||
static const int seg2x[0x28] =
|
||||
{
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
35,8, 9, 10,11,12,13,14,
|
||||
15,34,33,32,31,30,29,28,
|
||||
27,26,25,24,36,23,22,21,
|
||||
20,19,18,17,16,37,38,39
|
||||
};
|
||||
|
||||
int y = com, x = seg2x[seg];
|
||||
if (cliprect.contains(x, y))
|
||||
bitmap.pix(y, x) = state;
|
||||
|
||||
// 2 rows of indicators:
|
||||
// above screen: 0:meal, 1:lamp, 2:play, 3:medicine
|
||||
// under screen: 4:bath, 5:scales, 6:shout, 7:attention
|
||||
// they are on pin SEG8(x=35) + COM0-3, pin SEG28(x=36) + COM12-15
|
||||
|
||||
// output to y.x
|
||||
m_out_x[y][x] = state;
|
||||
}
|
||||
|
||||
void tamag1_state::tama_palette(palette_device &palette) const
|
||||
{
|
||||
palette.set_pen_color(0, rgb_t(0xf1, 0xf0, 0xf9)); // background
|
||||
palette.set_pen_color(1, rgb_t(0x3c, 0x38, 0x38)); // lcd pixel
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
Input Ports
|
||||
*******************************************************************************/
|
||||
@ -127,20 +85,14 @@ void tamag1_state::tama(machine_config &config)
|
||||
{
|
||||
// basic machine hardware
|
||||
E0C6S46(config, m_maincpu, 32.768_kHz_XTAL);
|
||||
m_maincpu->set_pixel_update_cb(FUNC(tamag1_state::pixel_update));
|
||||
m_maincpu->write_segs().set(FUNC(tamag1_state::lcd_segment_w));
|
||||
m_maincpu->write_r<4>().set("speaker", FUNC(speaker_sound_device::level_w)).bit(3);
|
||||
|
||||
// video hardware
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
|
||||
screen.set_refresh_hz(32.768_kHz_XTAL/1024);
|
||||
screen.set_vblank_time(ATTOSECONDS_IN_USEC(0));
|
||||
screen.set_size(40, 16);
|
||||
screen.set_visarea(0, 32-1, 0, 16-1);
|
||||
screen.set_screen_update("maincpu", FUNC(e0c6s46_device::screen_update));
|
||||
screen.set_palette("palette");
|
||||
config.set_default_layout(layout_tama);
|
||||
|
||||
PALETTE(config, "palette", FUNC(tamag1_state::tama_palette), 2);
|
||||
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_SVG));
|
||||
screen.set_refresh_hz(32);
|
||||
screen.set_size(1119, 1080);
|
||||
screen.set_visarea_full();
|
||||
|
||||
// sound hardware
|
||||
SPEAKER(config, "mono").front_center();
|
||||
@ -159,6 +111,9 @@ ROM_START( tama )
|
||||
|
||||
ROM_REGION( 0x3000, "maincpu:test", 0 )
|
||||
ROM_LOAD( "test.bin", 0x0000, 0x3000, CRC(4372220e) SHA1(6e13d015113e16198c0059b9d0c38d7027ae7324) ) // this rom is on the die too, test pin enables it?
|
||||
|
||||
ROM_REGION( 139072, "screen", 0)
|
||||
ROM_LOAD( "tama.svg", 0, 139072, CRC(9468b964) SHA1(ab49471db21a00a3b3a68da39c40da69da5d7e1b) )
|
||||
ROM_END
|
||||
|
||||
} // anonymous namespace
|
||||
@ -169,5 +124,5 @@ ROM_END
|
||||
Drivers
|
||||
*******************************************************************************/
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
SYST( 1997, tama, 0, 0, tama, tama, tamag1_state, empty_init, "Bandai", "Tamagotchi (USA)", MACHINE_SUPPORTS_SAVE )
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
SYST( 1997, tama, 0, 0, tama, tama, tamag1_state, empty_init, "Bandai", "Tamagotchi (World)", MACHINE_SUPPORTS_SAVE | MACHINE_REQUIRES_ARTWORK )
|
||||
|
@ -1,68 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
license:CC0-1.0
|
||||
authors:hap
|
||||
-->
|
||||
<mamelayout version="2">
|
||||
|
||||
<!-- define elements -->
|
||||
|
||||
<element name="yellow"><rect><color red="0.91" green="0.9" blue="0.78" /></rect></element>
|
||||
|
||||
<element name="ind0" defstate="0">
|
||||
<text state="0" string="FOOD"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="FOOD"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
<element name="ind1" defstate="0">
|
||||
<text state="0" string="LAMP"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="LAMP"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
<element name="ind2" defstate="0">
|
||||
<text state="0" string="PLAY"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="PLAY"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
<element name="ind3" defstate="0">
|
||||
<text state="0" string="MEDS"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="MEDS"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
<element name="ind4" defstate="0">
|
||||
<text state="0" string="BATH"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="BATH"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
<element name="ind5" defstate="0">
|
||||
<text state="0" string="STATS"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="STATS"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
<element name="ind6" defstate="0">
|
||||
<text state="0" string="SHOUT"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="SHOUT"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
<element name="ind7" defstate="0">
|
||||
<text state="0" string="ATTN"><color red="0.87" green="0.86" blue="0.74" /></text>
|
||||
<text state="1" string="ATTN"><color red="0.22" green="0.2" blue="0.2" /></text>
|
||||
</element>
|
||||
|
||||
|
||||
<!-- build screen -->
|
||||
|
||||
<view name="Internal Layout">
|
||||
<bounds left="0" top="0" right="32" bottom="26" />
|
||||
|
||||
<screen index="0">
|
||||
<bounds x="0" y="5" width="32" height="16" />
|
||||
</screen>
|
||||
<element ref="yellow"><bounds x="0" y="0" width="32" height="4" /></element>
|
||||
<element ref="yellow"><bounds x="0" y="22" width="32" height="4" /></element>
|
||||
|
||||
<element name="0.35" ref="ind0"><bounds x="0" y="1" width="8" height="2" /></element>
|
||||
<element name="1.35" ref="ind1"><bounds x="8" y="1" width="8" height="2" /></element>
|
||||
<element name="2.35" ref="ind2"><bounds x="16" y="1" width="8" height="2" /></element>
|
||||
<element name="3.35" ref="ind3"><bounds x="24" y="1" width="8" height="2" /></element>
|
||||
|
||||
<element name="12.36" ref="ind4"><bounds x="0" y="23" width="8" height="2" /></element>
|
||||
<element name="13.36" ref="ind5"><bounds x="8" y="23" width="8" height="2" /></element>
|
||||
<element name="14.36" ref="ind6"><bounds x="16" y="23" width="8" height="2" /></element>
|
||||
<element name="15.36" ref="ind7"><bounds x="24" y="23" width="8" height="2" /></element>
|
||||
|
||||
</view>
|
||||
</mamelayout>
|
Loading…
Reference in New Issue
Block a user