palm/palm.cpp: Improved Palm IIIc support. (#10684) [Ryan Holtz]

* machine/mc68328.cpp: Split MC68328 device into a base class with shared functionality, and derived MC68328 and MC68EZ328 models.
* video/sed1375.cpp: Added roughly-functional implementation of the Epson SED1375 LCD controller.

Machines promoted to working
------------------------
3Com Palm IIIc [Ryan Holtz]
This commit is contained in:
MooglyGuy 2022-12-16 13:44:37 +01:00 committed by GitHub
parent 6c00c8ef02
commit 16e265185e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 4452 additions and 1955 deletions

View File

@ -917,6 +917,17 @@ if (VIDEOS["SED1356"]~=null) then
}
end
--------------------------------------------------
--
--@src/devices/video/sed1375.h,VIDEOS["SED1375"] = true
--------------------------------------------------
if (VIDEOS["SED1375"]~=null) then
files {
MAME_DIR .. "src/devices/video/sed1375.cpp",
MAME_DIR .. "src/devices/video/sed1375.h",
}
end
--------------------------------------------------
--
--@src/devices/video/sed1500.h,VIDEOS["SED1500"] = true

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,549 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/**********************************************************************
Epson SED1375 LCD Controller emulation skeleton
- Currently hard-coded for use with the Palm IIIc driver.
- TODO: Find more test-case systems.
**********************************************************************/
#include "emu.h"
#include "sed1375.h"
#include "screen.h"
#define LOG_REG_READ (1 << 1)
#define LOG_REG_WRITE (1 << 2)
#define LOG_VRAM_READ (1 << 3)
#define LOG_VRAM_WRITE (1 << 4)
#define LOG_LUT_READ (1 << 5)
#define LOG_LUT_WRITE (1 << 6)
#define LOG_VBL_READ (1 << 7)
#define LOG_ALL (LOG_REG_READ | LOG_REG_WRITE | LOG_VRAM_READ | LOG_VRAM_WRITE | LOG_LUT_READ | LOG_LUT_WRITE | LOG_VBL_READ)
#define VERBOSE (0)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(SED1375, sed1375_device, "sed1375", "Epson SED1375")
sed1375_device::sed1375_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: device_t(mconfig, SED1375, tag, owner, clock)
, device_video_interface(mconfig, *this)
, m_vram(*this, "vram", 80 * 1024, ENDIANNESS_BIG)
{
}
void sed1375_device::device_start()
{
save_item(NAME(m_revision));
save_item(NAME(m_mode));
save_item(NAME(m_panel_hsize));
save_item(NAME(m_panel_vsize));
save_item(NAME(m_fpline_start));
save_item(NAME(m_hblank_period));
save_item(NAME(m_fpframe_start));
save_item(NAME(m_vblank_period));
save_item(NAME(m_mod_rate));
save_item(NAME(m_screen_start));
save_item(NAME(m_screen_start_ovf));
save_item(NAME(m_mem_addr_offset));
save_item(NAME(m_screen1_vsize));
save_item(NAME(m_lut_addr));
save_item(NAME(m_lut_index));
save_item(NAME(m_red_lut));
save_item(NAME(m_green_lut));
save_item(NAME(m_blue_lut));
save_item(NAME(m_gpio_config));
save_item(NAME(m_gpio_status));
save_item(NAME(m_scratch));
save_item(NAME(m_swivel_mode));
save_item(NAME(m_swivel_bytecnt));
}
void sed1375_device::device_reset()
{
m_revision = 0x24;
std::fill(std::begin(m_mode), std::end(m_mode), 0);
m_panel_hsize = 0x03;
m_panel_vsize = 0;
m_fpline_start = 0;
m_hblank_period = 0;
m_fpframe_start = 0;
m_vblank_period = 0;
m_mod_rate = 0;
std::fill(std::begin(m_screen_start), std::end(m_screen_start), 0);
m_screen_start_ovf = 0;
m_mem_addr_offset = 0;
m_screen1_vsize = 0;
m_lut_addr = 0;
m_lut_index = 0;
std::fill(std::begin(m_red_lut), std::end(m_red_lut), 0);
std::fill(std::begin(m_green_lut), std::end(m_green_lut), 0);
std::fill(std::begin(m_blue_lut), std::end(m_blue_lut), 0);
m_gpio_config = 0;
m_gpio_status = 0;
m_scratch = 0;
m_swivel_mode = 0;
m_swivel_bytecnt = 0;
}
void sed1375_device::map(address_map &map)
{
map(0x00000, 0x13fff).rw(FUNC(sed1375_device::vram_r), FUNC(sed1375_device::vram_w));
map(0x1ffe0, 0x1ffe0).r(FUNC(sed1375_device::revision_r));
map(0x1ffe1, 0x1ffe1).rw(FUNC(sed1375_device::mode0_r), FUNC(sed1375_device::mode0_w));
map(0x1ffe2, 0x1ffe2).rw(FUNC(sed1375_device::mode1_r), FUNC(sed1375_device::mode1_w));
map(0x1ffe3, 0x1ffe3).rw(FUNC(sed1375_device::mode2_r), FUNC(sed1375_device::mode2_w));
map(0x1ffe4, 0x1ffe4).rw(FUNC(sed1375_device::panel_hsize_r), FUNC(sed1375_device::panel_hsize_w));
map(0x1ffe5, 0x1ffe5).rw(FUNC(sed1375_device::panel_vsize_lsb_r), FUNC(sed1375_device::panel_vsize_lsb_w));
map(0x1ffe6, 0x1ffe6).rw(FUNC(sed1375_device::panel_vsize_msb_r), FUNC(sed1375_device::panel_vsize_msb_w));
map(0x1ffe7, 0x1ffe7).rw(FUNC(sed1375_device::fpline_start_r), FUNC(sed1375_device::fpline_start_w));
map(0x1ffe8, 0x1ffe8).rw(FUNC(sed1375_device::hblank_r), FUNC(sed1375_device::hblank_w));
map(0x1ffe9, 0x1ffe9).rw(FUNC(sed1375_device::fpframe_start_r), FUNC(sed1375_device::fpframe_start_w));
map(0x1ffea, 0x1ffea).rw(FUNC(sed1375_device::vblank_r), FUNC(sed1375_device::vblank_w));
map(0x1ffeb, 0x1ffeb).rw(FUNC(sed1375_device::mod_rate_r), FUNC(sed1375_device::mod_rate_w));
map(0x1ffec, 0x1ffec).rw(FUNC(sed1375_device::screen1_start_lsb_r), FUNC(sed1375_device::screen1_start_lsb_w));
map(0x1ffed, 0x1ffed).rw(FUNC(sed1375_device::screen1_start_msb_r), FUNC(sed1375_device::screen1_start_msb_w));
map(0x1ffee, 0x1ffee).rw(FUNC(sed1375_device::screen2_start_lsb_r), FUNC(sed1375_device::screen2_start_lsb_w));
map(0x1ffef, 0x1ffef).rw(FUNC(sed1375_device::screen2_start_msb_r), FUNC(sed1375_device::screen2_start_msb_w));
map(0x1fff0, 0x1fff0).rw(FUNC(sed1375_device::screen1_start_ovf_r), FUNC(sed1375_device::screen1_start_ovf_w));
map(0x1fff1, 0x1fff1).rw(FUNC(sed1375_device::mem_addr_offset_r), FUNC(sed1375_device::mem_addr_offset_w));
map(0x1fff2, 0x1fff2).rw(FUNC(sed1375_device::screen1_vsize_lsb_r), FUNC(sed1375_device::screen1_vsize_lsb_w));
map(0x1fff3, 0x1fff3).rw(FUNC(sed1375_device::screen1_vsize_msb_r), FUNC(sed1375_device::screen1_vsize_msb_w));
map(0x1fff5, 0x1fff5).rw(FUNC(sed1375_device::lut_addr_r), FUNC(sed1375_device::lut_addr_w));
map(0x1fff7, 0x1fff7).rw(FUNC(sed1375_device::lut_data_r), FUNC(sed1375_device::lut_data_w));
map(0x1fff8, 0x1fff8).rw(FUNC(sed1375_device::gpio_config_r), FUNC(sed1375_device::gpio_config_w));
map(0x1fff9, 0x1fff9).rw(FUNC(sed1375_device::gpio_r), FUNC(sed1375_device::gpio_w));
map(0x1fffa, 0x1fffa).rw(FUNC(sed1375_device::scratch_r), FUNC(sed1375_device::scratch_w));
map(0x1fffb, 0x1fffb).rw(FUNC(sed1375_device::swivel_mode_r), FUNC(sed1375_device::swivel_mode_w));
map(0x1fffc, 0x1fffc).rw(FUNC(sed1375_device::swivel_bytecnt_r), FUNC(sed1375_device::swivel_bytecnt_w));
}
u32 sed1375_device::get_pixel(int screen_idx, int x, int y)
{
const u32 pixels_per_line = (m_panel_hsize + 1) * 8;
const u32 bpp = 1 << ((m_mode[1] & MODE1_BPP_MASK) >> MODE1_BPP_SHIFT);
const u32 pixel_index = y * pixels_per_line + x;
const u32 byte_index = (pixel_index * bpp) / 8;
const u32 bit_index = x % (8 / bpp);
const u8 bpp_mask = (1 << bpp) - 1;
return (m_vram[(m_screen_start[screen_idx] << 1) + byte_index] >> (bit_index * bpp)) & bpp_mask;
}
u32 sed1375_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
if (BIT(m_mode[1], MODE1_BLANK_BIT))
{
bitmap.fill(0xff000000, cliprect);
return 0;
}
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
u32 *dst = &bitmap.pix(y);
for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
u32 pix = get_pixel(0, x, y);
if (BIT(m_mode[0], MODE0_TFT_BIT) || BIT(m_mode[0], MODE0_COLOR_BIT))
{
const u8 r = m_red_lut[pix];
const u8 g = m_green_lut[pix];
const u8 b = m_blue_lut[pix];
*dst++ = 0xff000000 | (((r << 4) | r) << 16) | (((g << 4) | g) << 8) | ((b << 4) | b);
}
else
{
switch ((m_mode[1] & MODE1_BPP_MASK) >> MODE1_BPP_SHIFT)
{
case 0: // 1bpp
*dst++ = 0xff000000 | (pix * 0xffffff);
break;
case 1: // 2bpp
*dst++ = 0xff000000 | (pix * 0x555555);
break;
case 2: // 4bpp
*dst++ = 0xff000000 | (pix * 0x111111);
break;
case 3: // 8bpp
*dst++ = 0xff000000 | (pix * 0x010101);
break;
}
}
}
}
return 0;
}
void sed1375_device::vram_w(offs_t offset, u8 data)
{
LOGMASKED(LOG_VRAM_WRITE, "%s: vram_w: VRAM Write[%05x] = %02x\n", machine().describe_context(), offset, data);
m_vram[offset] = data;
}
u8 sed1375_device::vram_r(offs_t offset)
{
LOGMASKED(LOG_VRAM_READ, "%s: vram_r: VRAM Read[%05x]: %02x\n", machine().describe_context(), offset, m_vram[offset]);
return m_vram[offset];
}
u8 sed1375_device::revision_r()
{
LOGMASKED(LOG_REG_READ, "%s: revision_r: %02x\n", machine().describe_context(), m_revision);
return m_revision;
}
void sed1375_device::mode0_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: mode0_w: Mode Register 0 = %02x\n", machine().describe_context(), data);
LOGMASKED(LOG_REG_WRITE, "%s Data Width Bits: %d\n", machine().describe_context(), data & MODE0_WIDTH_MASK);
LOGMASKED(LOG_REG_WRITE, "%s Mask FPSHIFT: %d\n", machine().describe_context(), BIT(data, MODE0_FPSHIFT_BIT));
LOGMASKED(LOG_REG_WRITE, "%s FPFRAME Polarity: %s\n", machine().describe_context(), BIT(data, MODE0_FPFRAME_POL_BIT) ? "Active-High" : "Active-Low");
LOGMASKED(LOG_REG_WRITE, "%s FPLINE Polarity: %s\n", machine().describe_context(), BIT(data, MODE0_FPLINE_POL_BIT) ? "Active-High" : "Active-Low");
LOGMASKED(LOG_REG_WRITE, "%s Color/Mono: %s\n", machine().describe_context(), BIT(data, MODE0_COLOR_BIT) ? "Color" : "Mono");
LOGMASKED(LOG_REG_WRITE, "%s Dual/Single: %s\n", machine().describe_context(), BIT(data, MODE0_DUAL_BIT) ? "Dual" : "Single");
LOGMASKED(LOG_REG_WRITE, "%s TFT/STN: %s\n", machine().describe_context(), BIT(data, MODE0_TFT_BIT) ? "TFT" : "STN");
m_mode[0] = data & MODE0_MASK;
}
u8 sed1375_device::mode0_r()
{
LOGMASKED(LOG_REG_READ, "%s: mode0_r: Mode Register 0: %02x\n", machine().describe_context(), m_mode[0]);
return m_mode[0];
}
void sed1375_device::mode1_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: mode1_w: Mode Register 1 = %02x\n", machine().describe_context(), data);
LOGMASKED(LOG_REG_WRITE, "%s Software Video Invert: %d\n", machine().describe_context(), BIT(data, MODE1_SWINVERT_BIT));
LOGMASKED(LOG_REG_WRITE, "%s Hardware Video Invert: %d\n", machine().describe_context(), BIT(data, MODE1_HWINVERT_BIT));
LOGMASKED(LOG_REG_WRITE, "%s Frame Repeat: %d\n", machine().describe_context(), BIT(data, MODE1_FRREPEAT_BIT));
LOGMASKED(LOG_REG_WRITE, "%s Display Blank: %d\n", machine().describe_context(), BIT(data, MODE1_BLANK_BIT));
LOGMASKED(LOG_REG_WRITE, "%s Input Clock Divider: %d\n", machine().describe_context(), BIT(data, MODE1_CLKDIV_BIT) + 1);
LOGMASKED(LOG_REG_WRITE, "%s High Performance: %d\n", machine().describe_context(), BIT(data, MODE1_HIPERF_BIT));
LOGMASKED(LOG_REG_WRITE, "%s Bits Per Pixel: %d\n", machine().describe_context(), 1 << ((data & MODE1_BPP_MASK) >> MODE1_BPP_SHIFT));
m_mode[1] = data & MODE1_MASK;
}
u8 sed1375_device::mode1_r()
{
LOGMASKED(LOG_REG_READ, "%s: mode1_r: Mode Register 1: %02x\n", machine().describe_context(), m_mode[1]);
return m_mode[1];
}
void sed1375_device::mode2_w(u8 data)
{
static const char *const SWPWRSAVE_NAMES[4] = { "Software Power Save", "Reserved (1)", "Reserved (2)", "Normal Operation" };
LOGMASKED(LOG_REG_WRITE, "%s: mode2_w: Mode Register 2 = %02x\n", machine().describe_context(), data);
LOGMASKED(LOG_REG_WRITE, "%s Software Power Save Mode: %s\n", machine().describe_context(), SWPWRSAVE_NAMES[data & MODE2_SWPWRSAVE_MASK]);
LOGMASKED(LOG_REG_WRITE, "%s Hardware Power Save: %d\n", machine().describe_context(), BIT(data, MODE2_HWPWRSAVE_BIT));
LOGMASKED(LOG_REG_WRITE, "%s LCDPWR Override: %d\n", machine().describe_context(), BIT(data, MODE2_LCDPWR_OVR_BIT));
m_mode[2] = data & MODE2_MASK;
}
u8 sed1375_device::mode2_r()
{
LOGMASKED(LOG_REG_READ, "%s: mode2_r: Mode Register 2: %02x\n", machine().describe_context(), m_mode[2]);
return m_mode[2];
}
void sed1375_device::panel_hsize_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: panel_hsize_w: Panel Horizontal Size = %02x\n", machine().describe_context(), data);
LOGMASKED(LOG_REG_WRITE, "%s: In Pixels: %d\n", machine().describe_context(), ((data & PANEL_HSIZE_MASK) + 1) * 8);
m_panel_hsize = data & PANEL_HSIZE_MASK;
}
u8 sed1375_device::panel_hsize_r()
{
LOGMASKED(LOG_REG_READ, "%s: panel_hsize_r: Panel Horizontal Size: %02x\n", machine().describe_context(), m_panel_hsize);
return m_panel_hsize;
}
void sed1375_device::panel_vsize_lsb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: panel_vsize_lsb_w: Panel Vertical Size (LSB) = %02x\n", machine().describe_context(), data);
m_panel_vsize = ((m_panel_vsize & 0xff00) | data) & PANEL_VSIZE_MASK;
}
u8 sed1375_device::panel_vsize_lsb_r()
{
LOGMASKED(LOG_REG_READ, "%s: panel_vsize_lsb_r: Panel Vertical Size (LSB): %02x\n", machine().describe_context(), m_panel_vsize & 0x00ff);
return m_panel_vsize;
}
void sed1375_device::panel_vsize_msb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: panel_vsize_msb_w: Panel Vertical Size (MSB) = %02x\n", machine().describe_context(), data);
m_panel_vsize = ((m_panel_vsize & 0x00ff) | (data << 8)) & PANEL_VSIZE_MASK;
}
u8 sed1375_device::panel_vsize_msb_r()
{
LOGMASKED(LOG_REG_READ, "%s: panel_vsize_msb_r: Panel Vertical Size (MSB): %02x\n", machine().describe_context(), m_panel_vsize >> 8);
return m_panel_vsize >> 8;
}
void sed1375_device::fpline_start_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: fpline_start_w: FPLINE Start Position = %02x\n", machine().describe_context(), data);
LOGMASKED(LOG_REG_WRITE, "%s: In Pixels: %d\n", machine().describe_context(), ((data & FPLINE_START_MASK) + 2) * 8);
m_fpline_start = data & FPLINE_START_MASK;
}
u8 sed1375_device::fpline_start_r()
{
LOGMASKED(LOG_REG_READ, "%s: fpline_start_r: FPLINE Start Position: %02x\n", machine().describe_context(), m_fpline_start);
return m_fpline_start;
}
void sed1375_device::hblank_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: hblank_w: Horizontal Blanking Period = %02x\n", machine().describe_context(), data);
LOGMASKED(LOG_REG_WRITE, "%s: In Pixels: %d\n", machine().describe_context(), ((data & HBLANK_MASK) + 4) * 8);
m_hblank_period = data & HBLANK_MASK;
}
u8 sed1375_device::hblank_r()
{
LOGMASKED(LOG_REG_READ, "%s: hblank_r: Horizontal Blanking Period: %02x\n", machine().describe_context(), m_hblank_period);
return m_hblank_period;
}
void sed1375_device::fpframe_start_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: fpline_start_w: FPFRAME Start Position = %02x\n", machine().describe_context(), data);
m_fpframe_start = data & FPFRAME_START_MASK;
}
u8 sed1375_device::fpframe_start_r()
{
LOGMASKED(LOG_REG_READ, "%s: fpframe_start_r: FPFRAME Start Position: %02x\n", machine().describe_context(), m_fpframe_start);
return m_fpframe_start;
}
void sed1375_device::vblank_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: vblank_w: Vertical Blanking Period = %02x\n", machine().describe_context(), data);
m_vblank_period = data & VBLANK_MASK;
}
u8 sed1375_device::vblank_r()
{
const u8 data = m_vblank_period | (screen().vblank() ? (1 << VBLANK_VBL_BIT) : 0);
LOGMASKED(LOG_VBL_READ, "%s: vblank_r: Vertical Blanking Period/Status: %02x\n", machine().describe_context(), data);
return data;
}
void sed1375_device::mod_rate_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: mod_rate_w: MOD Rate Register = %02x\n", machine().describe_context(), data);
m_mod_rate = data & MODRATE_MASK;
}
u8 sed1375_device::mod_rate_r()
{
LOGMASKED(LOG_REG_READ, "%s: mod_rate_r: MOD Rate Register: %02x\n", machine().describe_context(), m_mod_rate);
return m_mod_rate;
}
void sed1375_device::screen2_start_lsb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: screen2_start_w: Screen 2 Start Address (LSB) = %02x\n", machine().describe_context(), data);
m_screen_start[1] = ((m_screen_start[1] & 0xff00) | data) & SCREEN2_START_MASK;
}
u8 sed1375_device::screen2_start_lsb_r()
{
LOGMASKED(LOG_REG_READ, "%s: screen2_start_r: Screen 2 Start Address (LSB): %02x\n", machine().describe_context(), (u8)m_screen_start[1]);
return (u8)m_screen_start[1];
}
void sed1375_device::screen1_start_msb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: screen1_start_w: Screen 1 Start Address (MSB) = %02x\n", machine().describe_context(), data);
m_screen_start[0] = ((m_screen_start[0] & 0x00ff) | (data << 8)) & SCREEN1_START_MASK;
}
u8 sed1375_device::screen1_start_msb_r()
{
LOGMASKED(LOG_REG_READ, "%s: screen1_start_r: Screen 1 Start Address (MSB): %02x\n", machine().describe_context(), (u8)(m_screen_start[0] >> 8));
return (u8)(m_screen_start[0] >> 8);
}
void sed1375_device::screen1_start_lsb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: screen1_start_w: Screen 1 Start Address (LSB) = %02x\n", machine().describe_context(), data);
m_screen_start[0] = ((m_screen_start[0] & 0xff00) | data) & SCREEN1_START_MASK;
}
u8 sed1375_device::screen1_start_lsb_r()
{
LOGMASKED(LOG_REG_READ, "%s: screen1_start_r: Screen 1 Start Address (LSB): %02x\n", machine().describe_context(), (u8)m_screen_start[0]);
return (u8)m_screen_start[0];
}
void sed1375_device::screen2_start_msb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: screen2_start_w: Screen 2 Start Address (MSB) = %02x\n", machine().describe_context(), data);
m_screen_start[1] = ((m_screen_start[1] & 0x00ff) | (data << 8)) & SCREEN2_START_MASK;
}
u8 sed1375_device::screen2_start_msb_r()
{
LOGMASKED(LOG_REG_READ, "%s: screen2_start_r: Screen 2 Start Address (MSB): %02x\n", machine().describe_context(), (u8)(m_screen_start[1] >> 8));
return (u8)(m_screen_start[1] >> 8);
}
void sed1375_device::screen1_start_ovf_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: screen1_start_ovf_w: Screen Start Address Overflow Register = %02x\n", machine().describe_context(), data);
m_screen_start_ovf = data & START_OVF_MASK;
}
u8 sed1375_device::screen1_start_ovf_r()
{
LOGMASKED(LOG_REG_READ, "%s: screen1_start_ovf_r: Screen Start Address Overflow Register: %02x\n", machine().describe_context(), m_screen_start_ovf);
return m_screen_start_ovf;
}
void sed1375_device::mem_addr_offset_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: mem_addr_offset_w: Memory Address Offset Register = %02x\n", machine().describe_context(), data);
m_mem_addr_offset = data & MEM_ADDR_OFFSET_MASK;
}
u8 sed1375_device::mem_addr_offset_r()
{
LOGMASKED(LOG_REG_READ, "%s: mem_addr_offset_r: Memory Address Offset Register: %02x\n", machine().describe_context(), m_mem_addr_offset);
return m_mem_addr_offset;
}
void sed1375_device::screen1_vsize_lsb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: screen1_vsize_lsb_w: Screen 1 Vertical Size Register (LSB) = %02x\n", machine().describe_context(), data);
m_screen1_vsize = ((m_screen1_vsize & 0xff00) | data) & SCREEN1_VSIZE_MASK;
}
u8 sed1375_device::screen1_vsize_lsb_r()
{
LOGMASKED(LOG_REG_READ, "%s: screen1_vsize_lsb_r: Screen 1 Vertical Size Register (LSB): %02x\n", machine().describe_context(), (u8)m_screen1_vsize);
return (u8)m_screen1_vsize;
}
void sed1375_device::screen1_vsize_msb_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: screen1_vsize_msb_w: Screen 1 Vertical Size Register (MSB) = %02x\n", machine().describe_context(), data);
m_screen1_vsize = ((m_screen1_vsize & 0x00ff) | (data << 8)) & SCREEN1_VSIZE_MASK;
}
u8 sed1375_device::screen1_vsize_msb_r()
{
LOGMASKED(LOG_LUT_READ, "%s: screen1_vsize_msb_r: Screen 1 Vertical Size Register (MSB): %02x\n", machine().describe_context(), (u8)(m_screen1_vsize >> 8));
return (u8)(m_screen1_vsize >> 8);
}
void sed1375_device::lut_addr_w(u8 data)
{
LOGMASKED(LOG_LUT_WRITE, "%s: lut_addr_w: LUT Address Register = %02x\n", machine().describe_context(), data);
m_lut_addr = data & LUT_ADDR_MASK;
m_lut_index = 0;
}
u8 sed1375_device::lut_addr_r()
{
LOGMASKED(LOG_LUT_READ, "%s: lut_addr_r: LUT Address Register: %02x\n", machine().describe_context(), m_lut_addr);
return m_lut_addr;
}
void sed1375_device::lut_data_w(u8 data)
{
static const char *const LUT_INDEX_NAMES[3] = { "Red", "Green", "Blue" };
LOGMASKED(LOG_LUT_WRITE, "%s: lut_data_w: LUT Data[%d] = %02x (%s)\n", machine().describe_context(), (u32)m_lut_addr, data, LUT_INDEX_NAMES[m_lut_index]);
u8 *lut_data[3] = { m_red_lut, m_green_lut, m_blue_lut };
lut_data[m_lut_index++][m_lut_addr] = (data & LUT_DATA_MASK) >> LUT_DATA_SHIFT;
if (m_lut_index >= 3)
{
m_lut_addr++;
m_lut_index = 0;
}
}
u8 sed1375_device::lut_data_r()
{
static const char *const LUT_INDEX_NAMES[3] = { "Red", "Green", "Blue" };
u8 *lut_data[3] = { m_red_lut, m_green_lut, m_blue_lut };
const u8 data = lut_data[m_lut_index++][m_lut_addr];
LOGMASKED(LOG_REG_READ, "%s: lut_data_r: LUT Data[%d]: %02x (%s)\n", machine().describe_context(), (u32)m_lut_addr, data, LUT_INDEX_NAMES[m_lut_index]);
if (m_lut_index >= 3)
{
m_lut_addr++;
m_lut_index = 0;
}
return data;
}
void sed1375_device::gpio_config_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: gpio_config_w: GPIO Config Register = %02x\n", machine().describe_context(), data);
m_gpio_config = data & GPIO_CONFIG_MASK;
}
u8 sed1375_device::gpio_config_r()
{
LOGMASKED(LOG_REG_READ, "%s: gpio_config_r: GPIO Config Register: %02x\n", machine().describe_context(), m_gpio_config);
return m_gpio_config;
}
void sed1375_device::gpio_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: gpio_w: GPIO Output = %02x\n", machine().describe_context(), data);
m_gpio_status = data & GPIO_STATUS_MASK;
}
u8 sed1375_device::gpio_r()
{
LOGMASKED(LOG_REG_READ, "%s: gpio_r: GPIO Input: %02x\n", machine().describe_context(), m_gpio_status);
return m_gpio_status;
}
void sed1375_device::scratch_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: scratch_w: Scratch Pad Register = %02x\n", machine().describe_context(), data);
m_scratch = data & SCRATCH_MASK;
}
u8 sed1375_device::scratch_r()
{
LOGMASKED(LOG_REG_READ, "%s: scratch_r: Scratch Pad Register: %02x\n", machine().describe_context(), m_scratch);
return m_scratch;
}
void sed1375_device::swivel_mode_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: swivel_mode_w: SwivelView Mode Register = %02x\n", machine().describe_context(), data);
LOGMASKED(LOG_REG_WRITE, "%s: Pixel Clock Select Bits: %d\n", machine().describe_context(), data & SWIVEL_CLKSEL_MASK);
LOGMASKED(LOG_REG_WRITE, "%s: SwivelView Mode Select: %d\n", machine().describe_context(),
!BIT(data, SWIVEL_ENABLE_BIT) ? "Landscape" : (BIT(data, SWIVEL_MODE_BIT) ? "Alternate" : "Default"));
LOGMASKED(LOG_REG_WRITE, "%s: SwivelView Mode Enable: %d\n", machine().describe_context(), BIT(data, SWIVEL_ENABLE_BIT));
m_swivel_mode = data & SWIVEL_MODE_MASK;
}
u8 sed1375_device::swivel_mode_r()
{
LOGMASKED(LOG_REG_READ, "%s: swivel_mode_r: SwivelView Mode Register: %02x\n", machine().describe_context(), m_swivel_mode);
return m_swivel_mode;
}
void sed1375_device::swivel_bytecnt_w(u8 data)
{
LOGMASKED(LOG_REG_WRITE, "%s: swivel_bytecnt_w: SwivelView Line Byte Count = %02x\n", machine().describe_context(), data);
m_swivel_bytecnt = data & SWIVEL_BYTECNT_MASK;
}
u8 sed1375_device::swivel_bytecnt_r()
{
LOGMASKED(LOG_REG_READ, "%s: swivel_bytecnt_r: SwivelView Line Byte Count: %02x\n", machine().describe_context(), m_swivel_bytecnt);
return m_swivel_bytecnt;
}

196
src/devices/video/sed1375.h Normal file
View File

@ -0,0 +1,196 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
/**********************************************************************
Epson SED1375 LCD Controller emulation skeleton
- Currently hard-coded for use with the Palm IIIc driver.
- TODO: Find more test-case systems.
**********************************************************************/
#ifndef MAME_VIDEO_SED1375_H
#define MAME_VIDEO_SED1375_H
#pragma once
class sed1375_device : public device_t,
public device_video_interface
{
public:
// construction/destruction
sed1375_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
void map(address_map &map);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
u32 get_pixel(int screen_idx, int x, int y);
void vram_w(offs_t offset, u8 data);
u8 vram_r(offs_t offset);
void mode0_w(u8 data);
void mode1_w(u8 data);
void mode2_w(u8 data);
void panel_hsize_w(u8 data);
void panel_vsize_lsb_w(u8 data);
void panel_vsize_msb_w(u8 data);
void fpline_start_w(u8 data);
void hblank_w(u8 data);
void fpframe_start_w(u8 data);
void vblank_w(u8 data);
void mod_rate_w(u8 data);
void screen1_start_lsb_w(u8 data);
void screen1_start_msb_w(u8 data);
void screen2_start_lsb_w(u8 data);
void screen2_start_msb_w(u8 data);
void screen1_start_ovf_w(u8 data);
void mem_addr_offset_w(u8 data);
void screen1_vsize_lsb_w(u8 data);
void screen1_vsize_msb_w(u8 data);
void lut_addr_w(u8 data);
void lut_data_w(u8 data);
void gpio_config_w(u8 data);
void gpio_w(u8 data);
void scratch_w(u8 data);
void swivel_mode_w(u8 data);
void swivel_bytecnt_w(u8 data);
u8 revision_r();
u8 mode0_r();
u8 mode1_r();
u8 mode2_r();
u8 panel_hsize_r();
u8 panel_vsize_lsb_r();
u8 panel_vsize_msb_r();
u8 fpline_start_r();
u8 hblank_r();
u8 fpframe_start_r();
u8 vblank_r();
u8 mod_rate_r();
u8 screen1_start_lsb_r();
u8 screen1_start_msb_r();
u8 screen2_start_lsb_r();
u8 screen2_start_msb_r();
u8 screen1_start_ovf_r();
u8 mem_addr_offset_r();
u8 screen1_vsize_lsb_r();
u8 screen1_vsize_msb_r();
u8 lut_addr_r();
u8 lut_data_r();
u8 gpio_config_r();
u8 gpio_r();
u8 scratch_r();
u8 swivel_mode_r();
u8 swivel_bytecnt_r();
enum : u8
{
MODE0_MASK = 0xff,
MODE0_WIDTH_MASK = 0x03,
MODE0_FPSHIFT_BIT = 2,
MODE0_FPFRAME_POL_BIT = 3,
MODE0_FPLINE_POL_BIT = 4,
MODE0_COLOR_BIT = 5,
MODE0_DUAL_BIT = 6,
MODE0_TFT_BIT = 7,
MODE1_MASK = 0xff,
MODE1_SWINVERT_BIT = 0,
MODE1_HWINVERT_BIT = 1,
MODE1_FRREPEAT_BIT = 2,
MODE1_BLANK_BIT = 3,
MODE1_CLKDIV_BIT = 4,
MODE1_HIPERF_BIT = 5,
MODE1_BPP_MASK = 0xc0,
MODE1_BPP_SHIFT = 6,
MODE2_MASK = 0x0f,
MODE2_SWPWRSAVE_MASK = 0x03,
MODE2_SWPWRSAVE_SHIFT = 0,
MODE2_HWPWRSAVE_BIT = 2,
MODE2_LCDPWR_OVR_BIT = 3,
PANEL_HSIZE_MASK = 0x7f,
FPLINE_START_MASK = 0x1f,
HBLANK_MASK = 0x1f,
FPFRAME_START_MASK = 0x3f,
VBLANK_MASK = 0x3f,
VBLANK_VBL_BIT = 7,
MODRATE_MASK = 0x3f,
START_OVF_MASK = 0x01,
MEM_ADDR_OFFSET_MASK = 0xff,
LUT_ADDR_MASK = 0xff,
LUT_DATA_MASK = 0xf0,
LUT_DATA_SHIFT = 4,
GPIO_CONFIG_MASK = 0x1f,
GPIO_STATUS_MASK = 0x1f,
SCRATCH_MASK = 0xff,
SWIVEL_MODE_MASK = 0xc3,
SWIVEL_CLKSEL_MASK = 0x03,
SWIVEL_MODE_BIT = 6,
SWIVEL_ENABLE_BIT = 7,
SWIVEL_BYTECNT_MASK = 0xff
};
enum : u16
{
PANEL_VSIZE_MASK = 0x03ff,
SCREEN1_START_MASK = 0xffff,
SCREEN2_START_MASK = 0xffff,
SCREEN1_VSIZE_MASK = 0x03ff
};
memory_share_creator<u8> m_vram;
u8 m_revision;
u8 m_mode[3];
u8 m_panel_hsize;
u16 m_panel_vsize;
u8 m_fpline_start;
u8 m_hblank_period;
u8 m_fpframe_start;
u8 m_vblank_period;
u8 m_mod_rate;
u16 m_screen_start[2];
u8 m_screen_start_ovf;
u8 m_mem_addr_offset;
u16 m_screen1_vsize;
u8 m_lut_addr;
u8 m_lut_index;
u8 m_red_lut[256];
u8 m_green_lut[256];
u8 m_blue_lut[256];
u8 m_gpio_config;
u8 m_gpio_status;
u8 m_scratch;
u8 m_swivel_mode;
u8 m_swivel_bytecnt;
};
// device type definition
DECLARE_DEVICE_TYPE(SED1375, sed1375_device)
#endif // MAME_VIDEO_SED1375_H

View File

@ -16,168 +16,177 @@
#include "machine/mc68328.h"
#include "machine/ram.h"
#include "sound/dac.h"
#include "video/sed1375.h"
#include "emupal.h"
#include "screen.h"
#include "speaker.h"
#include "pilot1k.lh"
#define VERBOSE (0)
#include "logmacro.h"
namespace {
class palm_state : public driver_device
class palm_base_state : public driver_device
{
public:
palm_state(const machine_config &mconfig, device_type type, const char *tag) :
driver_device(mconfig, type, tag),
m_maincpu(*this, "maincpu"),
m_ram(*this, RAM_TAG),
m_screen(*this, "screen"),
m_palette(*this, "palette"),
m_io_penx(*this, "PENX"),
m_io_peny(*this, "PENY"),
m_io_penb(*this, "PENB"),
m_io_portd(*this, "PORTD")
{ }
void palmiii(machine_config &config);
void pilot1k(machine_config &config);
void palmvx(machine_config &config);
void palmv(machine_config &config);
void palm(machine_config &config);
void palmpro(machine_config &config);
void pilot5k(machine_config &config);
DECLARE_INPUT_CHANGED_MEMBER(pen_check);
DECLARE_INPUT_CHANGED_MEMBER(button_check);
protected:
palm_base_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
, m_ram(*this, RAM_TAG)
, m_screen(*this, "screen")
, m_io_penx(*this, "PENX")
, m_io_peny(*this, "PENY")
, m_io_penb(*this, "PENB")
{ }
virtual void machine_start() override;
virtual void machine_reset() override;
enum : uint8_t
{
PORTF_Y_VCCN_BIT = 0,
PORTF_Y_GND_BIT = 1,
PORTF_X_VCCN_BIT = 2,
PORTF_X_GND_BIT = 3,
PORTF_LCD_EN_BIT = 4,
PORTF_LCD_VCCN_BIT = 5,
PORTF_LCD_VEE_BIT = 6,
PORTF_ADC_CSN_BIT = 7,
PORTF_PEN_MASK = 0x8f,
PORTF_X_MASK = (1 << PORTF_X_VCCN_BIT) | (1 << PORTF_Y_GND_BIT),
PORTF_Y_MASK = (1 << PORTF_Y_VCCN_BIT) | (1 << PORTF_X_GND_BIT),
};
private:
offs_t dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer &params);
void mem_map(address_map &map);
void flm_out(int state);
void llp_out(int state);
void lsclk_out(int state);
void ld_out(uint8_t data);
virtual void lsclk_out(int state);
void ld_out(u8 data);
void lcd_info_changed(double refresh_hz, int width, int height);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void init_palette(palette_device &palette) const;
void port_f_out(uint8_t data);
uint8_t port_c_in();
uint8_t port_f_in();
virtual int spi_from_hw();
int spi_in();
required_device<mc68328_device> m_maincpu;
required_device<mc68328_base_device> m_maincpu;
required_device<ram_device> m_ram;
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
required_ioport m_io_penx;
required_ioport m_io_peny;
required_ioport m_io_penb;
required_ioport m_io_portd;
uint8_t m_port_f_latch;
uint16_t m_spim_data;
u16 m_spim_data;
bitmap_rgb32 m_lcd_bitmap;
int m_lcd_first_line;
int m_lcd_line_pulse;
int m_lcd_shift_clk;
uint8_t m_lcd_data;
u8 m_lcd_data;
int m_lcd_scan_x;
int m_lcd_scan_y;
static const int EXTRA_ARTWORK_HEIGHT = 60;
};
class palm_state : public palm_base_state
{
public:
palm_state(const machine_config &mconfig, device_type type, const char *tag)
: palm_base_state(mconfig, type, tag)
, m_palette(*this, "palette")
, m_io_portd(*this, "PORTD")
{ }
void palmiii(machine_config &config);
void pilot1k(machine_config &config);
void palmvx(machine_config &config);
void palmv(machine_config &config);
void palmpro(machine_config &config);
void pilot5k(machine_config &config);
DECLARE_INPUT_CHANGED_MEMBER(button_check);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
void palm_base(machine_config &config);
void mem_map(address_map &map);
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
void init_palette(palette_device &palette) const;
void check_pen_adc_read();
void adc_vcc_y_w(int state);
void adc_gnd_y_w(int state);
void adc_vcc_x_w(int state);
void adc_gnd_x_w(int state);
void adc_csn_w(int state);
int power_nmi_r();
virtual void lsclk_out(int state) override;
enum : int
{
PORTF_Y_VCCN_BIT = 0,
PORTF_Y_GND_BIT = 1,
PORTF_X_VCCN_BIT = 2,
PORTF_X_GND_BIT = 3,
PORTF_ADC_CSN_BIT = 7
};
required_device<palette_device> m_palette;
required_ioport m_io_portd;
u8 m_port_f_latch;
bool m_adc_csn;
bool m_adc_vcc_x;
bool m_adc_gnd_x;
bool m_adc_vcc_y;
bool m_adc_gnd_y;
};
class palmiiic_state : public palm_base_state
{
public:
palmiiic_state(const machine_config &mconfig, device_type type, const char *tag)
: palm_base_state(mconfig, type, tag)
, m_sed1375(*this, "lcdctrl")
, m_rows(*this, "ROW%u", 0u)
{ }
void palmiiic(machine_config &config);
DECLARE_INPUT_CHANGED_MEMBER(button_check);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
void mem_map(address_map &map);
void adc_enable_w(int state);
template <int Line> void kbd_row_w(int state);
template <int Line> void kbd_col_w(int state);
template <int Line> int kbd_scan_r();
void hardware_id_req_w(int state);
void spi_to_hw(int state);
virtual int spi_from_hw() override;
required_device<sed1375_device> m_sed1375;
required_ioport_array<3> m_rows;
u8 m_key_row_mask;
u8 m_key_col_mask;
bool m_port_d_hardware_id;
bool m_adc_enabled;
u8 m_adc_cmd_bit_count;
u8 m_adc_response_bit_count;
u8 m_adc_cmd;
};
/***************************************************************************
MACHINE HARDWARE
***************************************************************************/
INPUT_CHANGED_MEMBER(palm_state::pen_check)
// Shared platform hardware
void palm_base_state::machine_start()
{
uint8_t button = m_io_penb->read();
if(button)
m_maincpu->set_penirq_line(1);
else
m_maincpu->set_penirq_line(0);
}
INPUT_CHANGED_MEMBER(palm_state::button_check)
{
uint8_t button_state = m_io_portd->read();
m_maincpu->set_port_d_lines(button_state, (int)param);
}
void palm_state::port_f_out(uint8_t data)
{
const uint8_t old = m_port_f_latch;
m_port_f_latch = data;
const uint8_t changed = old ^ data;
if (BIT(changed, PORTF_ADC_CSN_BIT) && !BIT(m_port_f_latch, PORTF_ADC_CSN_BIT))
{
switch (m_port_f_latch & PORTF_PEN_MASK)
{
case PORTF_X_MASK:
m_spim_data = (0xff - m_io_penx->read()) * 2;
break;
case PORTF_Y_MASK:
m_spim_data = (0xff - m_io_peny->read()) * 2;
break;
}
}
}
uint8_t palm_state::port_c_in()
{
return 0x10;
}
uint8_t palm_state::port_f_in()
{
return m_port_f_latch;
}
int palm_state::spi_in()
{
int out_state = BIT(m_spim_data, 15);
m_spim_data <<= 1;
m_spim_data |= 1;
return out_state;
}
void palm_state::machine_start()
{
address_space &space = m_maincpu->space(AS_PROGRAM);
space.install_ram(0x000000, m_ram->size() - 1, m_ram->pointer());
save_item(NAME(m_port_f_latch));
save_item(NAME(m_spim_data));
save_item(NAME(m_lcd_first_line));
@ -188,10 +197,10 @@ void palm_state::machine_start()
save_item(NAME(m_lcd_scan_y));
}
void palm_state::machine_reset()
void palm_base_state::machine_reset()
{
// Copy boot ROM
uint8_t* bios = memregion("bios")->base();
u8* bios = memregion("bios")->base();
memset(m_ram->pointer(), 0, m_ram->size());
memcpy(m_ram->pointer(), bios, 0x20000);
@ -205,6 +214,244 @@ void palm_state::machine_reset()
m_lcd_scan_y = 0;
}
INPUT_CHANGED_MEMBER(palm_base_state::pen_check)
{
m_maincpu->irq5_w(m_io_penb->read() & 1);
}
int palm_base_state::spi_from_hw()
{
int out_state = BIT(m_spim_data, 15);
m_spim_data <<= 1;
m_spim_data |= 1;
return out_state;
}
// First-generation Palm hardware ("IDT")
void palm_state::machine_start()
{
palm_base_state::machine_start();
address_space &space = m_maincpu->space(AS_PROGRAM);
space.install_ram(0x000000, m_ram->size() - 1, m_ram->pointer());
//save_item(NAME(m_port_f_latch));
save_item(NAME(m_adc_csn));
save_item(NAME(m_adc_vcc_x));
save_item(NAME(m_adc_gnd_x));
save_item(NAME(m_adc_vcc_y));
save_item(NAME(m_adc_gnd_y));
}
void palm_state::machine_reset()
{
palm_base_state::machine_reset();
m_adc_csn = false;
m_adc_vcc_x = false;
m_adc_gnd_x = false;
m_adc_vcc_y = false;
m_adc_gnd_y = false;
}
INPUT_CHANGED_MEMBER(palm_state::button_check)
{
const u8 button_state = m_io_portd->read();
m_maincpu->port_d_in_w(BIT(button_state, param), param);
}
void palm_state::check_pen_adc_read()
{
if (!m_adc_csn)
{
if (m_adc_vcc_x && m_adc_gnd_y)
{
m_spim_data = (0xff - m_io_penx->read()) * 2;
}
else if (m_adc_vcc_y && m_adc_gnd_x)
{
m_spim_data = (0xff - m_io_peny->read()) * 2;
}
}
}
void palm_state::adc_vcc_y_w(int state)
{
m_adc_vcc_y = state;
check_pen_adc_read();
}
void palm_state::adc_gnd_y_w(int state)
{
m_adc_gnd_y = state;
check_pen_adc_read();
}
void palm_state::adc_vcc_x_w(int state)
{
m_adc_vcc_x = state;
check_pen_adc_read();
}
void palm_state::adc_gnd_x_w(int state)
{
m_adc_gnd_x = state;
check_pen_adc_read();
}
void palm_state::adc_csn_w(int state)
{
m_adc_csn = state;
check_pen_adc_read();
}
int palm_state::power_nmi_r()
{
return 1;
}
// Palm IIIc hardware ("Austin")
void palmiiic_state::machine_start()
{
palm_base_state::machine_start();
address_space &space = m_maincpu->space(AS_PROGRAM);
space.install_ram(0x000000, m_ram->size() - 1, m_ram->pointer());
save_item(NAME(m_key_row_mask));
save_item(NAME(m_key_col_mask));
save_item(NAME(m_port_d_hardware_id));
save_item(NAME(m_adc_enabled));
save_item(NAME(m_adc_cmd_bit_count));
save_item(NAME(m_adc_response_bit_count));
save_item(NAME(m_adc_cmd));
}
void palmiiic_state::machine_reset()
{
palm_base_state::machine_reset();
m_key_row_mask = 0;
m_key_col_mask = 0;
m_port_d_hardware_id = false;
m_adc_enabled = false;
m_adc_cmd_bit_count = 8;
m_adc_response_bit_count = 0;
m_adc_cmd = 0;
}
INPUT_CHANGED_MEMBER(palmiiic_state::button_check)
{
const u8 button_state = m_rows[param]->read();
for (int bit = 0; bit < 4; bit++)
{
m_maincpu->port_d_in_w(BIT(button_state, bit), bit);
}
}
void palmiiic_state::adc_enable_w(int state)
{
const bool was_enabled = m_adc_enabled;
m_adc_enabled = !state;
if (!was_enabled && m_adc_enabled)
{
m_adc_cmd_bit_count = 8;
m_spim_data = 0;
}
}
template <int Line>
void palmiiic_state::kbd_row_w(int state)
{
m_key_row_mask &= ~(1 << Line);
m_key_row_mask |= !state << Line;
}
template <int Line>
void palmiiic_state::kbd_col_w(int state)
{
m_key_col_mask &= ~(1 << Line);
m_key_col_mask |= state << Line;
}
template <int Line>
int palmiiic_state::kbd_scan_r()
{
int state = 0;
if (m_port_d_hardware_id)
{
state = BIT(~0x09, Line);
}
else
{
for (int i = 0; i < 3; i++)
{
if (BIT(m_key_row_mask, i))
{
state |= BIT(m_rows[i]->read(), Line);
}
}
}
return state;
}
void palmiiic_state::hardware_id_req_w(int state)
{
m_port_d_hardware_id = !state;
}
void palmiiic_state::spi_to_hw(int state)
{
if (m_adc_enabled && m_adc_cmd_bit_count > 0)
{
m_adc_cmd_bit_count--;
m_adc_cmd &= ~(1 << m_adc_cmd_bit_count);
m_adc_cmd |= state << m_adc_cmd_bit_count;
}
}
int palmiiic_state::spi_from_hw()
{
int state = palm_base_state::spi_from_hw();
if (m_adc_enabled && m_adc_cmd_bit_count == 0)
{
if (m_adc_response_bit_count == 0)
{
m_adc_response_bit_count = 16;
const u8 channel = (m_adc_cmd >> 4) & 7;
switch (channel)
{
case 1: // Pen Y
m_spim_data = ((0xff - m_io_peny->read()) * 2) << 3;
break;
case 2: // Battery Level
m_spim_data = 0x7ff8;
break;
case 5: // Pen X
m_spim_data = ((0xff - m_io_penx->read()) * 2) << 3;
break;
case 6: // Dock Serial
m_spim_data = 0;
break;
default:
LOG("%s: Unknown ADC Channel: %d (command %02x)\n", machine().describe_context(), channel, m_adc_cmd);
break;
}
}
else
{
m_adc_response_bit_count--;
if (m_adc_response_bit_count == 0)
{
m_adc_cmd_bit_count = 8;
}
}
}
return state;
}
/***************************************************************************
LCD HARDWARE
***************************************************************************/
@ -215,12 +462,12 @@ void palm_state::init_palette(palette_device &palette) const
palette.set_pen_color(1, 0x40, 0x40, 0x40);
}
void palm_state::flm_out(int state)
void palm_base_state::flm_out(int state)
{
m_lcd_first_line = state;
}
void palm_state::llp_out(int state)
void palm_base_state::llp_out(int state)
{
const int old = m_lcd_line_pulse;
m_lcd_line_pulse = state;
@ -238,13 +485,18 @@ void palm_state::llp_out(int state)
}
}
void palm_base_state::lsclk_out(int state)
{
m_lcd_shift_clk = state;
}
void palm_state::lsclk_out(int state)
{
const int old = m_lcd_shift_clk;
m_lcd_shift_clk = state;
palm_base_state::lsclk_out(state);
if (state && !old)
{
for (uint8_t i = 0; i < 4; i++)
for (u8 i = 0; i < 4; i++)
{
m_lcd_bitmap.pix(m_lcd_scan_y, m_lcd_scan_x) = m_palette->pen_color(BIT(m_lcd_data, 3 - i));
m_lcd_scan_x++;
@ -252,12 +504,12 @@ void palm_state::lsclk_out(int state)
}
}
void palm_state::ld_out(uint8_t data)
void palm_base_state::ld_out(u8 data)
{
m_lcd_data = data;
}
void palm_state::lcd_info_changed(double refresh_hz, int width, int height)
void palm_base_state::lcd_info_changed(double refresh_hz, int width, int height)
{
m_screen->set_refresh_hz(refresh_hz);
m_screen->set_size(width, height + EXTRA_ARTWORK_HEIGHT);
@ -265,19 +517,18 @@ void palm_state::lcd_info_changed(double refresh_hz, int width, int height)
m_lcd_bitmap.resize(width, height);
}
uint32_t palm_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
u32 palm_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
bitmap.fill(m_palette->pen_color(0));
if (m_lcd_bitmap.valid())
{
uint32_t *src = &m_lcd_bitmap.pix(0);
uint32_t *dst = &bitmap.pix(0);
u32 *src = &m_lcd_bitmap.pix(0);
u32 *dst = &bitmap.pix(0);
std::copy_n(src, m_lcd_bitmap.width() * m_lcd_bitmap.height(), dst);
}
return 0;
}
/***************************************************************************
ADDRESS MAPS
***************************************************************************/
@ -287,35 +538,107 @@ void palm_state::mem_map(address_map &map)
map(0xc00000, 0xe07fff).rom().region("bios", 0);
}
void palmiiic_state::mem_map(address_map &map)
{
map(0x00c00000, 0x00e07fff).rom().region("bios", 0);
map(0x10c00000, 0x10e07fff).rom().region("bios", 0);
map(0x1f000000, 0x1f01ffff).m(m_sed1375, FUNC(sed1375_device::map));
}
/***************************************************************************
INPUTS
***************************************************************************/
static INPUT_PORTS_START(palm_base)
PORT_START("PENX")
PORT_BIT(0xff, 0x50, IPT_LIGHTGUN_X) PORT_NAME("Pen X") PORT_MINMAX(0, 0xa0) PORT_SENSITIVITY(50) PORT_CROSSHAIR(X, 1.0, 0.0, 0)
PORT_START("PENY")
PORT_BIT(0xff, 0x50, IPT_LIGHTGUN_Y) PORT_NAME("Pen Y") PORT_MINMAX(0, 0xa0) PORT_SENSITIVITY(50) PORT_CROSSHAIR(Y, 1.0, 0.0, 0)
PORT_START("PENB")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Pen Button") PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_base_state, pen_check, 0)
INPUT_PORTS_END
static INPUT_PORTS_START(palm)
PORT_INCLUDE(palm_base)
PORT_START("PORTD")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Power") PORT_CODE(KEYCODE_D) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Up") PORT_CODE(KEYCODE_Y) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 1)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_NAME("Down") PORT_CODE(KEYCODE_H) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 2)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_NAME("Button 1") PORT_CODE(KEYCODE_F) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 3)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_NAME("Button 2") PORT_CODE(KEYCODE_G) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 4)
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_NAME("Button 3") PORT_CODE(KEYCODE_J) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 5)
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_NAME("Button 4") PORT_CODE(KEYCODE_K) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 6)
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END
static INPUT_PORTS_START(palmez)
PORT_INCLUDE(palm_base)
PORT_START("ROW0")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Button 1") PORT_CODE(KEYCODE_F) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 0)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Button 2") PORT_CODE(KEYCODE_G) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 0)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_NAME("Button 3") PORT_CODE(KEYCODE_J) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 0)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_NAME("Button 4") PORT_CODE(KEYCODE_K) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 0)
PORT_BIT(0xf0, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("ROW1")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_NAME("Up") PORT_CODE(KEYCODE_Y) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 1)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_NAME("Down") PORT_CODE(KEYCODE_H) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 1)
PORT_BIT(0xfc, IP_ACTIVE_HIGH, IPT_UNUSED)
PORT_START("ROW2")
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_NAME("Power") PORT_CODE(KEYCODE_D) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 2)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON9) PORT_NAME("Contrast") PORT_CODE(KEYCODE_C) PORT_CHANGED_MEMBER(DEVICE_SELF, palmiiic_state, button_check, 2)
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3)
PORT_BIT(0xf8, IP_ACTIVE_HIGH, IPT_UNUSED)
INPUT_PORTS_END
/***************************************************************************
MACHINE DRIVERS
***************************************************************************/
void palm_state::palm(machine_config &config)
void palm_state::palm_base(machine_config &config)
{
/* basic machine hardware */
MC68328(config, m_maincpu, 32768*506); /* 16.580608 MHz */
m_maincpu->set_addrmap(AS_PROGRAM, &palm_state::mem_map);
m_maincpu->set_dasm_override(FUNC(palm_state::dasm_override));
m_maincpu->out_port_f().set(FUNC(palm_state::port_f_out));
m_maincpu->in_port_c().set(FUNC(palm_state::port_c_in));
m_maincpu->in_port_f().set(FUNC(palm_state::port_f_in));
m_maincpu->out_port_f<PORTF_Y_VCCN_BIT>().set(FUNC(palm_state::adc_vcc_y_w));
m_maincpu->out_port_f<PORTF_Y_GND_BIT>().set(FUNC(palm_state::adc_gnd_y_w));
m_maincpu->out_port_f<PORTF_X_VCCN_BIT>().set(FUNC(palm_state::adc_vcc_x_w));
m_maincpu->out_port_f<PORTF_X_GND_BIT>().set(FUNC(palm_state::adc_gnd_x_w));
m_maincpu->out_port_f<PORTF_ADC_CSN_BIT>().set(FUNC(palm_state::adc_csn_w));
m_maincpu->in_port_c<4>().set(FUNC(palm_state::power_nmi_r));
m_maincpu->in_port_d<0>().set_ioport(m_io_penb).bit(0);
m_maincpu->in_port_d<1>().set_ioport(m_io_penb).bit(1);
m_maincpu->in_port_d<2>().set_ioport(m_io_penb).bit(2);
m_maincpu->in_port_d<3>().set_ioport(m_io_penb).bit(3);
m_maincpu->in_port_d<4>().set_ioport(m_io_penb).bit(4);
m_maincpu->in_port_d<5>().set_ioport(m_io_penb).bit(5);
m_maincpu->in_port_d<6>().set_ioport(m_io_penb).bit(6);
m_maincpu->in_port_d<7>().set_ioport(m_io_penb).bit(7);
//m_maincpu->in_port_f().set(FUNC(palm_state::port_f_in)); Port F latch
m_maincpu->out_pwm().set("dac", FUNC(dac_bit_interface::write));
m_maincpu->in_spim().set(FUNC(palm_state::spi_in));
m_maincpu->in_spim().set(FUNC(palm_state::spi_from_hw));
m_maincpu->out_flm().set(FUNC(palm_state::flm_out));
m_maincpu->out_llp().set(FUNC(palm_state::llp_out));
m_maincpu->out_lsclk().set(FUNC(palm_state::lsclk_out));
m_maincpu->out_ld().set(FUNC(palm_state::ld_out));
m_maincpu->set_lcd_info_changed(FUNC(palm_state::lcd_info_changed));
config.set_maximum_quantum(attotime::from_hz(60));
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_LCD);
m_screen->set_refresh_hz(60);
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(0));
m_screen->set_video_attributes(VIDEO_UPDATE_BEFORE_VBLANK);
m_screen->set_size(160, 160);
m_screen->set_visarea(0, 159, 0, 159);
m_screen->set_screen_update(FUNC(palm_state::screen_update));
@ -327,26 +650,113 @@ void palm_state::palm(machine_config &config)
DAC_1BIT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25);
}
static INPUT_PORTS_START( palm )
PORT_START( "PENX" )
PORT_BIT( 0xff, 0x50, IPT_LIGHTGUN_X ) PORT_NAME("Pen X") PORT_MINMAX(0, 0xa0) PORT_SENSITIVITY(50) PORT_CROSSHAIR(X, 1.0, 0.0, 0)
void palmiiic_state::palmiiic(machine_config &config)
{
/* basic machine hardware */
MC68EZ328(config, m_maincpu, 32768*506); /* 16.580608 MHz */
m_maincpu->set_addrmap(AS_PROGRAM, &palmiiic_state::mem_map);
m_maincpu->set_dasm_override(FUNC(palmiiic_state::dasm_override));
PORT_START( "PENY" )
PORT_BIT( 0xff, 0x50, IPT_LIGHTGUN_Y ) PORT_NAME("Pen Y") PORT_MINMAX(0, 0xa0) PORT_SENSITIVITY(50) PORT_CROSSHAIR(Y, 1.0, 0.0, 0)
m_maincpu->out_port_b<1>().set(FUNC(palmiiic_state::adc_enable_w));
PORT_START( "PENB" )
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Pen Button") PORT_CODE(MOUSECODE_BUTTON1) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, pen_check, 0)
m_maincpu->out_port_c<0>().set(FUNC(palmiiic_state::kbd_row_w<0>));
m_maincpu->out_port_c<1>().set(FUNC(palmiiic_state::kbd_row_w<1>));
m_maincpu->out_port_c<2>().set(FUNC(palmiiic_state::kbd_row_w<2>));
PORT_START( "PORTD" )
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Power") PORT_CODE(KEYCODE_D) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 0)
PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("Up") PORT_CODE(KEYCODE_Y) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 1)
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("Down") PORT_CODE(KEYCODE_H) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 2)
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_BUTTON5 ) PORT_NAME("Button 1") PORT_CODE(KEYCODE_F) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 3)
PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_BUTTON6 ) PORT_NAME("Button 2") PORT_CODE(KEYCODE_G) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 4)
PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON7 ) PORT_NAME("Button 3") PORT_CODE(KEYCODE_J) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 5)
PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON8 ) PORT_NAME("Button 4") PORT_CODE(KEYCODE_K) PORT_CHANGED_MEMBER(DEVICE_SELF, palm_state, button_check, 6)
PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_UNUSED )
INPUT_PORTS_END
m_maincpu->out_port_d<0>().set(FUNC(palmiiic_state::kbd_col_w<0>));
m_maincpu->out_port_d<1>().set(FUNC(palmiiic_state::kbd_col_w<1>));
m_maincpu->out_port_d<2>().set(FUNC(palmiiic_state::kbd_col_w<2>));
m_maincpu->out_port_d<3>().set(FUNC(palmiiic_state::kbd_col_w<3>));
m_maincpu->out_port_g<2>().set(FUNC(palmiiic_state::hardware_id_req_w));
m_maincpu->in_port_d<0>().set(FUNC(palmiiic_state::kbd_scan_r<0>));
m_maincpu->in_port_d<1>().set(FUNC(palmiiic_state::kbd_scan_r<1>));
m_maincpu->in_port_d<2>().set(FUNC(palmiiic_state::kbd_scan_r<2>));
m_maincpu->in_port_d<3>().set(FUNC(palmiiic_state::kbd_scan_r<3>));
m_maincpu->in_port_d<4>().set_constant(1); // Active-low, indicates hotsync/dock button press
m_maincpu->in_port_d<6>().set_constant(1); // Active-low, indicates external adapter installed
m_maincpu->in_port_d<7>().set_constant(1); // Active-low, indicates pending power failure
m_maincpu->in_port_f<0>().set_constant(1); // Active-high, indicates LCD is at full power
m_maincpu->in_port_f<6>().set_constant(1); // Active-high, indicates battery enabled
m_maincpu->in_port_f<7>().set_constant(1); // Active-low, determines sync port attachment
m_maincpu->out_pwm().set("dac", FUNC(dac_bit_interface::write));
m_maincpu->in_spim().set(FUNC(palmiiic_state::spi_from_hw));
m_maincpu->out_spim().set(FUNC(palmiiic_state::spi_to_hw));
m_maincpu->out_flm().set(FUNC(palmiiic_state::flm_out));
m_maincpu->out_llp().set(FUNC(palmiiic_state::llp_out));
m_maincpu->out_lsclk().set(FUNC(palmiiic_state::lsclk_out));
m_maincpu->out_ld().set(FUNC(palmiiic_state::ld_out));
m_maincpu->set_lcd_info_changed(FUNC(palmiiic_state::lcd_info_changed));
/* internal ram */
RAM(config, RAM_TAG).set_default_size("8M");
/* video hardware */
SED1375(config, m_sed1375);
SCREEN(config, m_screen, SCREEN_TYPE_LCD);
m_screen->set_refresh_hz(60);
m_screen->set_size(160, 262);
m_screen->set_visarea(0, 160-1, 0, 220-1);
m_screen->set_screen_update(m_sed1375, FUNC(sed1375_device::screen_update));
/* audio hardware */
SPEAKER(config, "speaker").front_center();
DAC_1BIT(config, "dac", 0).add_route(ALL_OUTPUTS, "speaker", 0.25);
}
void palm_state::pilot1k(machine_config &config)
{
palm_base(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("128K").set_extra_options("512K,1M,2M,4M,8M");
config.set_default_layout(layout_pilot1k);
}
void palm_state::pilot5k(machine_config &config)
{
palm_base(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("512K").set_extra_options("1M,2M,4M,8M");
}
void palm_state::palmpro(machine_config &config)
{
palm_base(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("1M").set_extra_options("2M,4M,8M");
}
void palm_state::palmiii(machine_config &config)
{
palm_base(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("2M").set_extra_options("4M,8M");
}
void palm_state::palmv(machine_config &config)
{
palm_base(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("2M").set_extra_options("4M,8M");
}
void palm_state::palmvx(machine_config &config)
{
palm_base(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("8M");
}
/***************************************************************************
@ -539,74 +949,24 @@ ROM_START( spt1740 )
ROM_RELOAD(0x000000, 0x004000)
ROM_END
void palm_state::pilot1k(machine_config &config)
{
palm(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("128K").set_extra_options("512K,1M,2M,4M,8M");
config.set_default_layout(layout_pilot1k);
}
void palm_state::pilot5k(machine_config &config)
{
palm(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("512K").set_extra_options("1M,2M,4M,8M");
}
void palm_state::palmpro(machine_config &config)
{
palm(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("1M").set_extra_options("2M,4M,8M");
}
void palm_state::palmiii(machine_config &config)
{
palm(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("2M").set_extra_options("4M,8M");
}
void palm_state::palmv(machine_config &config)
{
palm(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("2M").set_extra_options("4M,8M");
}
void palm_state::palmvx(machine_config &config)
{
palm(config);
/* internal ram */
RAM(config, RAM_TAG).set_default_size("8M");
}
} // anonymous namespace
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 1996, pilot1k, 0, 0, pilot1k, palm, palm_state, empty_init, "U.S. Robotics", "Pilot 1000", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND )
COMP( 1996, pilot5k, pilot1k, 0, pilot5k, palm, palm_state, empty_init, "U.S. Robotics", "Pilot 5000", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND )
COMP( 1997, palmpers, pilot1k, 0, pilot5k, palm, palm_state, empty_init, "U.S. Robotics", "Palm Pilot Personal", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND )
COMP( 1997, palmpro, pilot1k, 0, palmpro, palm, palm_state, empty_init, "U.S. Robotics", "Palm Pilot Pro", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND )
COMP( 1998, palmiii, pilot1k, 0, palmiii, palm, palm_state, empty_init, "3Com", "Palm III", MACHINE_SUPPORTS_SAVE | MACHINE_NO_SOUND )
COMP( 1998, palmiiic, pilot1k, 0, palmiii, palm, palm_state, empty_init, "Palm Inc", "Palm IIIc", MACHINE_NOT_WORKING )
COMP( 2000, palmm100, pilot1k, 0, palmiii, palm, palm_state, empty_init, "Palm Inc", "Palm m100", MACHINE_NOT_WORKING )
COMP( 2000, palmm130, pilot1k, 0, palmiii, palm, palm_state, empty_init, "Palm Inc", "Palm m130", MACHINE_NOT_WORKING )
COMP( 2001, palmm505, pilot1k, 0, palmiii, palm, palm_state, empty_init, "Palm Inc", "Palm m505", MACHINE_NOT_WORKING )
COMP( 2001, palmm515, pilot1k, 0, palmiii, palm, palm_state, empty_init, "Palm Inc", "Palm m515", MACHINE_NOT_WORKING )
COMP( 1999, palmv, pilot1k, 0, palmv, palm, palm_state, empty_init, "3Com", "Palm V", MACHINE_NOT_WORKING )
COMP( 1999, palmvx, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Palm Inc", "Palm Vx", MACHINE_NOT_WORKING )
COMP( 2001, visor, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Handspring", "Visor Edge", MACHINE_NOT_WORKING )
COMP( 19??, spt1500, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Symbol", "SPT 1500", MACHINE_NOT_WORKING )
COMP( 19??, spt1700, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Symbol", "SPT 1700", MACHINE_NOT_WORKING )
COMP( 19??, spt1740, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Symbol", "SPT 1740", MACHINE_NOT_WORKING )
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
COMP( 1996, pilot1k, 0, 0, pilot1k, palm, palm_state, empty_init, "U.S. Robotics", "Pilot 1000", MACHINE_SUPPORTS_SAVE )
COMP( 1996, pilot5k, pilot1k, 0, pilot5k, palm, palm_state, empty_init, "U.S. Robotics", "Pilot 5000", MACHINE_SUPPORTS_SAVE )
COMP( 1997, palmpers, pilot1k, 0, pilot5k, palm, palm_state, empty_init, "U.S. Robotics", "Palm Pilot Personal", MACHINE_SUPPORTS_SAVE )
COMP( 1997, palmpro, pilot1k, 0, palmpro, palm, palm_state, empty_init, "U.S. Robotics", "Palm Pilot Pro", MACHINE_SUPPORTS_SAVE )
COMP( 1998, palmiii, pilot1k, 0, palmiii, palm, palm_state, empty_init, "3Com", "Palm III", MACHINE_SUPPORTS_SAVE )
COMP( 1998, palmiiic, pilot1k, 0, palmiiic, palmez, palmiiic_state, empty_init, "3Com", "Palm IIIc", MACHINE_SUPPORTS_SAVE )
COMP( 2000, palmm100, pilot1k, 0, palmiii, palm, palm_state, empty_init, "3Com", "Palm m100", MACHINE_NOT_WORKING )
COMP( 2000, palmm130, pilot1k, 0, palmiii, palm, palm_state, empty_init, "3Com", "Palm m130", MACHINE_NOT_WORKING )
COMP( 2001, palmm505, pilot1k, 0, palmiii, palm, palm_state, empty_init, "3Com", "Palm m505", MACHINE_NOT_WORKING )
COMP( 2001, palmm515, pilot1k, 0, palmiii, palm, palm_state, empty_init, "3Com", "Palm m515", MACHINE_NOT_WORKING )
COMP( 1999, palmv, pilot1k, 0, palmv, palm, palm_state, empty_init, "3Com", "Palm V", MACHINE_NOT_WORKING )
COMP( 1999, palmvx, pilot1k, 0, palmvx, palm, palm_state, empty_init, "3Com", "Palm Vx", MACHINE_NOT_WORKING )
COMP( 2001, visor, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Handspring", "Visor Edge", MACHINE_NOT_WORKING )
COMP( 19??, spt1500, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Symbol", "SPT 1500", MACHINE_NOT_WORKING )
COMP( 19??, spt1700, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Symbol", "SPT 1700", MACHINE_NOT_WORKING )
COMP( 19??, spt1740, pilot1k, 0, palmvx, palm, palm_state, empty_init, "Symbol", "SPT 1740", MACHINE_NOT_WORKING )
#include "palm_dbg.ipp"

View File

@ -1162,7 +1162,7 @@ static const char *lookup_trap(uint16_t opcode)
return nullptr;
}
offs_t palm_state::dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer &params)
offs_t palm_base_state::dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer &params)
{
unsigned result = 0;
const char *trap;