mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
Rewritten Acorn VIDC10 into own device file [Angelo Salese] #5671
* Improved raster effects on games that dynamically change palette on active frame; * Added stereo sound support;
This commit is contained in:
parent
8ef0656299
commit
3e6b9f9756
@ -1638,9 +1638,9 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK but abuses of raster effects on menus, has trainer -->
|
||||
<software name="jksquash" supported="no">
|
||||
<description>Jahangir Khan Squash</description>
|
||||
<!-- boot OK, raster effect bug on title screen, long loading screen with black afterwards?, entering player name has stuck keys, has trainer -->
|
||||
<software name="jksquash" supported="partial">
|
||||
<description>Jahangir Khan's World Championship Squash</description>
|
||||
<year>1991</year>
|
||||
<publisher>Krisalis</publisher>
|
||||
<part name="flop1" interface="floppy_3_5">
|
||||
@ -1821,7 +1821,7 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- Mouse cursor autocenters too much especially on A5000 class machine, raster effect is off on gameplay screen -->
|
||||
<!-- Mouse cursor autocenters too much especially on A5000 class machine, raster effect bug on gameplay screen -->
|
||||
<software name="lemmings2" supported="partial">
|
||||
<description>Lemmings 2: The Tribes</description>
|
||||
<year>1994</year>
|
||||
@ -1853,7 +1853,7 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK, has raster effect bugs on gameplay -->
|
||||
<!-- boot OK, has raster effect bugs on gameplay (2p is even worse), sometimes inputs forgets being hit -->
|
||||
<software name="lotustc2" supported="partial">
|
||||
<description>Lotus Turbo Challenge 2</description>
|
||||
<year>1992</year>
|
||||
@ -1952,7 +1952,7 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK, incorrectly trips raster effect on top of screen -->
|
||||
<!-- boot OK, raster effect scroll & color bugs during gameplay, has CPU/RAM detection display after title screen -->
|
||||
<software name="manchutd" supported="partial">
|
||||
<description>Manchester United Europe</description>
|
||||
<year>1991</year>
|
||||
@ -2044,7 +2044,7 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK, has raster effect issues -->
|
||||
<!-- boot OK, has raster effect bugs on title/gameplay -->
|
||||
<software name="nebulus" supported="partial">
|
||||
<description>Nebulus</description>
|
||||
<year>1992</year>
|
||||
@ -2443,7 +2443,7 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK but flickers like mad due of incorrect raster effects -->
|
||||
<!-- boot OK but flickers like mad due of incorrect raster effects, also seems very slow with timing on gameplay even on A5000 class machine -->
|
||||
<software name="rotoros3" cloneof="rotor" supported="no">
|
||||
<description>Rotor (Patched RiscOS3)</description>
|
||||
<year>1989</year>
|
||||
@ -2565,7 +2565,7 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK, initial speech pitch sounds very low but it's likely a btanb -->
|
||||
<!-- boot OK, initial speech pitch sounds very low (btanb) -->
|
||||
<software name="small" supported="yes">
|
||||
<description>Small</description>
|
||||
<year>1993</year>
|
||||
@ -2954,8 +2954,8 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK, has incorrectly emulated raster effect when dying with the fan -->
|
||||
<software name="wimpgame" supported="partial">
|
||||
<!-- boot OK, has ZX Spectrum like raster effect when dying with the fan -->
|
||||
<software name="wimpgame" supported="yes">
|
||||
<description>The Wimp Game</description>
|
||||
<year>1990</year>
|
||||
<publisher>Fourth Dimension</publisher>
|
||||
@ -2967,8 +2967,8 @@ Zelanites: The Onslaught by Micro Power (RiscOS2)
|
||||
</part>
|
||||
</software>
|
||||
|
||||
<!-- boot OK, has incorrectly emulated raster effect when dying with the fan -->
|
||||
<software name="wimpgamec" cloneof="wimpgame" supported="partial">
|
||||
<!-- boot OK, has ZX Spectrum like raster effect when dying with the fan -->
|
||||
<software name="wimpgamec" cloneof="wimpgame" supported="yes">
|
||||
<description>The Wimp Game [cracked]</description>
|
||||
<year>1990</year>
|
||||
<publisher>Fourth Dimension</publisher>
|
||||
|
@ -4162,3 +4162,14 @@ if (MACHINES["VRENDER0"]~=null) then
|
||||
}
|
||||
end
|
||||
|
||||
--------------------------------------------------
|
||||
--
|
||||
--@src/devices/machine/acorn_vidc.h,MACHINES["ACORN_VIDC10"] = true
|
||||
--------------------------------------------------
|
||||
|
||||
if (MACHINES["ACORN_VIDC10"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/machine/acorn_vidc.cpp",
|
||||
MAME_DIR .. "src/devices/machine/acorn_vidc.h",
|
||||
}
|
||||
end
|
||||
|
@ -982,7 +982,6 @@ files {
|
||||
MAME_DIR .. "src/mame/drivers/aristmk5.cpp",
|
||||
MAME_DIR .. "src/mame/machine/archimds.cpp",
|
||||
MAME_DIR .. "src/mame/includes/archimds.h",
|
||||
MAME_DIR .. "src/mame/video/archimds.cpp",
|
||||
}
|
||||
|
||||
createMAMEProjects(_target, _subtarget, "adp")
|
||||
|
@ -1347,7 +1347,6 @@ if (_subtarget=="mess") then
|
||||
createMESSProjects(_target, _subtarget, "mameshared")
|
||||
files {
|
||||
MAME_DIR .. "src/mame/machine/archimds.cpp",
|
||||
MAME_DIR .. "src/mame/video/archimds.cpp",
|
||||
MAME_DIR .. "src/mame/machine/amiga.cpp",
|
||||
MAME_DIR .. "src/mame/video/amiga.cpp",
|
||||
MAME_DIR .. "src/mame/video/amigaaga.cpp",
|
||||
|
518
src/devices/machine/acorn_vidc.cpp
Normal file
518
src/devices/machine/acorn_vidc.cpp
Normal file
@ -0,0 +1,518 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Angelo Salese, R. Belmont, Juergen Buchmueller
|
||||
/**********************************************************************************************
|
||||
|
||||
Acorn VIDC10 (VIDeo Controller) device chip
|
||||
|
||||
based off legacy AA VIDC implementation by Angelo Salese, R. Belmont, Juergen Buchmueller
|
||||
|
||||
TODO:
|
||||
- subclass screen_device, derive h/vsync signals out there;
|
||||
- improve timings for raster effects:
|
||||
* nebulus: 20 lines off with aa310;
|
||||
* lotustc2: abuses color flipping;
|
||||
* quazer: needs in-flight DMA;
|
||||
- improve sound DAC writes;
|
||||
- subclass this for VIDC20 emulation (RiscPC);
|
||||
- Are CRTC values correct? VGA modes have a +1 in display line;
|
||||
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "acorn_vidc.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(ACORN_VIDC10, acorn_vidc10_device, "acorn_vidc10", "Acorn VIDC10")
|
||||
DEFINE_DEVICE_TYPE(ACORN_VIDC10_LCD, acorn_vidc10_lcd_device, "acorn_vidc10_lcd", "Acorn VIDC10 with LCD monitor")
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// acorn_vidc10_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
void acorn_vidc10_device::regs_map(address_map &map)
|
||||
{
|
||||
map(0x00, 0x3f).w(FUNC(acorn_vidc10_device::pal_data_display_w));
|
||||
map(0x40, 0x4f).w(FUNC(acorn_vidc10_device::pal_data_cursor_w));
|
||||
map(0x60, 0x7f).w(FUNC(acorn_vidc10_device::stereo_image_w));
|
||||
map(0x80, 0xbf).w(FUNC(acorn_vidc10_device::crtc_w));
|
||||
map(0xc0, 0xc3).w(FUNC(acorn_vidc10_device::sound_frequency_w));
|
||||
map(0xe0, 0xe3).w(FUNC(acorn_vidc10_device::control_w));
|
||||
}
|
||||
|
||||
|
||||
acorn_vidc10_device::acorn_vidc10_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, device_memory_interface(mconfig, *this)
|
||||
, device_video_interface(mconfig, *this)
|
||||
, m_screen(*this, "screen")
|
||||
, m_space_config("regs_space", ENDIANNESS_LITTLE, 32, 8, 0, address_map_constructor(FUNC(acorn_vidc10_device::regs_map), this))
|
||||
, m_palette(*this, "palette")
|
||||
, m_lspeaker(*this, "lspeaker")
|
||||
, m_rspeaker(*this, "rspeaker")
|
||||
, m_dac(*this, "dac%u", 0)
|
||||
, m_vblank_cb(*this)
|
||||
, m_sound_drq_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
acorn_vidc10_device::acorn_vidc10_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: acorn_vidc10_device(mconfig, ACORN_VIDC10, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
acorn_vidc10_lcd_device::acorn_vidc10_lcd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: acorn_vidc10_device(mconfig, ACORN_VIDC10_LCD, tag, owner, clock)
|
||||
{
|
||||
}
|
||||
|
||||
device_memory_interface::space_config_vector acorn_vidc10_device::memory_space_config() const
|
||||
{
|
||||
return space_config_vector {
|
||||
std::make_pair(AS_IO, &m_space_config)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - device-specific machine
|
||||
// configuration addiitons
|
||||
//-------------------------------------------------
|
||||
|
||||
void acorn_vidc10_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(XTAL(16'000'000), 1024,0,735, 624/2,0,292); // RiscOS 3 default screen settings
|
||||
m_screen->set_screen_update(FUNC(acorn_vidc10_device::screen_update));
|
||||
// m_screen->screen_vblank().set(FUNC(acorn_vidc10_device::screen_vblank));
|
||||
|
||||
// 8bpp + 1/2/4bpp + 2bpp for cursor
|
||||
PALETTE(config, m_palette, palette_device::BLACK).set_entries(0x100+0x10+4);
|
||||
|
||||
SPEAKER(config, m_lspeaker).front_left();
|
||||
SPEAKER(config, m_rspeaker).front_right();
|
||||
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
|
||||
for (int i = 0; i < m_sound_max_channels; i++)
|
||||
{
|
||||
// custom DAC
|
||||
DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac[i], 0).add_route(0, m_lspeaker, m_sound_input_gain).add_route(0, m_rspeaker, m_sound_input_gain);
|
||||
vref.add_route(0, m_dac[i], 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, m_dac[i], -1.0, DAC_VREF_NEG_INPUT);
|
||||
}
|
||||
}
|
||||
|
||||
void acorn_vidc10_lcd_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
acorn_vidc10_device::device_add_mconfig(config);
|
||||
m_screen->set_type(SCREEN_TYPE_LCD);
|
||||
// TODO: verify !Configure with automatic type detection, there must be an ID telling this is a LCD machine.
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void acorn_vidc10_device::device_start()
|
||||
{
|
||||
m_vblank_cb.resolve_safe();
|
||||
m_sound_drq_cb.resolve_safe();
|
||||
|
||||
save_item(NAME(m_bpp_mode));
|
||||
save_item(NAME(m_crtc_interlace));
|
||||
save_item(NAME(m_pixel_clock));
|
||||
save_item(NAME(m_sound_frequency_latch));
|
||||
save_item(NAME(m_sound_frequency_test_bit));
|
||||
save_item(NAME(m_cursor_enable));
|
||||
save_pointer(NAME(m_crtc_regs), CRTC_VCER+1);
|
||||
m_data_vram = auto_alloc_array_clear(machine(), u8, m_data_vram_size);
|
||||
m_cursor_vram = auto_alloc_array_clear(machine(), u8, m_cursor_vram_size);
|
||||
save_pointer(NAME(m_data_vram), m_data_vram_size);
|
||||
save_pointer(NAME(m_cursor_vram), m_cursor_vram_size);
|
||||
save_pointer(NAME(m_stereo_image), m_sound_max_channels);
|
||||
|
||||
m_video_timer = timer_alloc(TIMER_VIDEO);
|
||||
m_sound_timer = timer_alloc(TIMER_SOUND);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void acorn_vidc10_device::device_reset()
|
||||
{
|
||||
m_cursor_enable = false;
|
||||
memset(m_data_vram, 0, m_data_vram_size);
|
||||
memset(m_cursor_vram, 0, m_cursor_vram_size);
|
||||
memset(m_stereo_image, 4, m_sound_max_channels);
|
||||
for (int ch=0;ch<m_sound_max_channels;ch++)
|
||||
refresh_stereo_image(ch);
|
||||
m_video_timer->adjust(attotime::never);
|
||||
m_sound_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - device-specific timer
|
||||
//-------------------------------------------------
|
||||
|
||||
void acorn_vidc10_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_VIDEO:
|
||||
m_vblank_cb(ASSERT_LINE);
|
||||
screen_vblank_line_update();
|
||||
break;
|
||||
case TIMER_SOUND:
|
||||
m_sound_drq_cb(ASSERT_LINE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// CRTC section
|
||||
//**************************************************************************
|
||||
|
||||
inline void acorn_vidc10_device::screen_vblank_line_update()
|
||||
{
|
||||
int vline = (m_crtc_regs[CRTC_VDER]) * (m_crtc_interlace + 1);
|
||||
m_video_timer->adjust((vline > 2) ? m_screen->time_until_pos(vline) : attotime::never);
|
||||
}
|
||||
|
||||
void acorn_vidc10_device::screen_dynamic_res_change()
|
||||
{
|
||||
const int32_t pixel_rate[4] = { 8000000, 12000000, 16000000, 24000000};
|
||||
|
||||
// sanity checks
|
||||
if (m_crtc_regs[CRTC_HCR] <= 1 || m_crtc_regs[CRTC_VCR] <= 1)
|
||||
return;
|
||||
|
||||
if (m_crtc_regs[CRTC_HBER] <= 1 || m_crtc_regs[CRTC_VBER] <= 1)
|
||||
return;
|
||||
|
||||
// total cycles >= border end >= border start
|
||||
if (m_crtc_regs[CRTC_HCR] < m_crtc_regs[CRTC_HBER])
|
||||
return;
|
||||
|
||||
if (m_crtc_regs[CRTC_HBER] < m_crtc_regs[CRTC_HBSR])
|
||||
return;
|
||||
|
||||
if (m_crtc_regs[CRTC_VBER] < m_crtc_regs[CRTC_VBSR])
|
||||
return;
|
||||
|
||||
rectangle const visarea(
|
||||
0, m_crtc_regs[CRTC_HBER] - m_crtc_regs[CRTC_HBSR] - 1,
|
||||
0, (m_crtc_regs[CRTC_VBER] - m_crtc_regs[CRTC_VBSR]) * (m_crtc_interlace + 1));
|
||||
|
||||
#if 0
|
||||
// TODO: move to debugger custom command
|
||||
const int m_vidc_vblank_time = m_crtc_regs[CRTC_VDER] * (m_crtc_interlace+1);
|
||||
printf("Configuring: htotal %d vtotal %d border %d x %d display origin %d x %d vblank = %d\n",
|
||||
m_crtc_regs[CRTC_HCR], m_crtc_regs[CRTC_VCR],
|
||||
visarea.right(), visarea.bottom(),
|
||||
m_crtc_regs[CRTC_HDER]-m_crtc_regs[CRTC_HDSR],m_crtc_regs[CRTC_VDER]-m_crtc_regs[CRTC_VDSR]+1,
|
||||
m_vidc_vblank_time);
|
||||
#endif
|
||||
|
||||
attoseconds_t const refresh = HZ_TO_ATTOSECONDS(pixel_rate[m_pixel_clock]) * m_crtc_regs[CRTC_HCR] * m_crtc_regs[CRTC_VCR];
|
||||
|
||||
m_screen->configure(m_crtc_regs[CRTC_HCR], m_crtc_regs[CRTC_VCR] * (m_crtc_interlace+1), visarea, refresh);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// READ/WRITE HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
WRITE32_MEMBER( acorn_vidc10_device::write )
|
||||
{
|
||||
// TODO: check against mem_mask not 32-bit wide
|
||||
uint8_t reg = data >> 24;
|
||||
uint32_t val = data & 0xffffff;
|
||||
|
||||
this->space(AS_IO).write_dword(reg, val);
|
||||
}
|
||||
|
||||
inline void acorn_vidc10_device::update_4bpp_palette(uint16_t index, uint32_t paldata)
|
||||
{
|
||||
int r,g,b;
|
||||
|
||||
// TODO: for TV Tuner we need to output this, also check if cursor mode actually sets this up for offset = 0
|
||||
// i = (paldata & 0x1000) >> 12; //supremacy bit
|
||||
b = (paldata & 0x0f00) >> 8;
|
||||
g = (paldata & 0x00f0) >> 4;
|
||||
r = (paldata & 0x000f) >> 0;
|
||||
|
||||
m_palette->set_pen_color(index, pal4bit(r), pal4bit(g), pal4bit(b) );
|
||||
m_screen->update_partial(m_screen->vpos());
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( acorn_vidc10_device::pal_data_display_w )
|
||||
{
|
||||
update_4bpp_palette(offset+0x100, data);
|
||||
//printf("%02x: %01x %01x %01x [%d]\n",offset,r,g,b,m_screen->vpos());
|
||||
|
||||
// 8bpp
|
||||
for(int idx=0;idx<0x100;idx+=0x10)
|
||||
{
|
||||
int b = ((data & 0x700) >> 8) | ((idx & 0x80) >> 4);
|
||||
int g = ((data & 0x030) >> 4) | ((idx & 0x60) >> 3);
|
||||
int r = ((data & 0x007) >> 0) | ((idx & 0x10) >> 1);
|
||||
|
||||
m_palette->set_pen_color(offset + idx, pal4bit(r), pal4bit(g), pal4bit(b) );
|
||||
}
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( acorn_vidc10_device::pal_data_cursor_w )
|
||||
{
|
||||
update_4bpp_palette(offset+0x110, data);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( acorn_vidc10_device::control_w )
|
||||
{
|
||||
// TODO: not sure what the commented out bits do
|
||||
m_pixel_clock = (data & 0x03);
|
||||
m_bpp_mode = ((data & 0x0c) >> 2);
|
||||
//m_dma_request_mode = ((data & 0x30) >> 4);
|
||||
m_crtc_interlace = ((data & 0x40) >> 6);
|
||||
//m_composite_sync = BIT(data, 7);
|
||||
//m_test_mode = (data & 0xc100) != 0xc100;
|
||||
|
||||
//todo: vga/svga modes sets 0x1000?
|
||||
screen_vblank_line_update();
|
||||
screen_dynamic_res_change();
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( acorn_vidc10_device::crtc_w )
|
||||
{
|
||||
switch(offset)
|
||||
{
|
||||
case CRTC_HCR: m_crtc_regs[CRTC_HCR] = ((data >> 14)<<1)+2; break;
|
||||
// case CRTC_HSWR: m_crtc_regs[CRTC_HSWR] = (data >> 14)+1; break;
|
||||
case CRTC_HBSR: m_crtc_regs[CRTC_HBSR] = ((data >> 14)<<1)+1; break;
|
||||
case CRTC_HDSR: m_crtc_regs[CRTC_HDSR] = (data >> 14); break;
|
||||
case CRTC_HDER: m_crtc_regs[CRTC_HDER] = (data >> 14); break;
|
||||
case CRTC_HBER: m_crtc_regs[CRTC_HBER] = ((data >> 14)<<1)+1; break;
|
||||
case CRTC_HCSR: m_crtc_regs[CRTC_HCSR] = ((data >> 13) & 0x7ff) + 6; return;
|
||||
// case CRTC_HIR: // ...
|
||||
|
||||
case CRTC_VCR: m_crtc_regs[CRTC_VCR] = (data >> 14)+1; break;
|
||||
case CRTC_VSWR: m_crtc_regs[CRTC_VSWR] = (data >> 14)+1; break;
|
||||
case CRTC_VBSR:
|
||||
m_crtc_regs[CRTC_VBSR] = (data >> 14)+1;
|
||||
break;
|
||||
case CRTC_VDSR:
|
||||
m_crtc_regs[CRTC_VDSR] = (data >> 14)+1;
|
||||
break;
|
||||
case CRTC_VDER:
|
||||
m_crtc_regs[CRTC_VDER] = (data >> 14)+1;
|
||||
screen_vblank_line_update();
|
||||
break;
|
||||
case CRTC_VBER:
|
||||
m_crtc_regs[CRTC_VBER] = (data >> 14)+1;
|
||||
break;
|
||||
case CRTC_VCSR: m_crtc_regs[CRTC_VCSR] = ((data >> 14) & 0x3ff) + 1; return;
|
||||
case CRTC_VCER: m_crtc_regs[CRTC_VCER] = ((data >> 14) & 0x3ff) + 1; return;
|
||||
}
|
||||
|
||||
screen_dynamic_res_change();
|
||||
}
|
||||
|
||||
inline void acorn_vidc10_device::refresh_stereo_image(uint8_t channel)
|
||||
{
|
||||
/*
|
||||
-111 full right
|
||||
-110 83% right, 17% left
|
||||
-101 67% right, 33% left
|
||||
-100 center
|
||||
-011 67% left, 33% right
|
||||
-010 83% left, 17% right
|
||||
-001 full left
|
||||
-000 "undefined" TODO: verify what it actually means
|
||||
*/
|
||||
const float left_gain[8] = { 1.0, 2.0, 1.66, 1.34, 1.0, 0.66, 0.34, 0.0 };
|
||||
const float right_gain[8] = { 1.0, 0.0, 0.34, 0.66, 1.0, 1.34, 1.66, 2.0 };
|
||||
|
||||
m_lspeaker->set_input_gain(channel,left_gain[m_stereo_image[channel]]*m_sound_input_gain);
|
||||
m_rspeaker->set_input_gain(channel,right_gain[m_stereo_image[channel]]*m_sound_input_gain);
|
||||
//printf("%d %f %f\n",channel,m_lspeaker->input_gain(channel),m_rspeaker->input_gain(channel));
|
||||
}
|
||||
|
||||
|
||||
WRITE32_MEMBER( acorn_vidc10_device::stereo_image_w )
|
||||
{
|
||||
uint8_t channel = (offset + 7) & 0x7;
|
||||
m_stereo_image[channel] = data & 0x7;
|
||||
refresh_stereo_image(channel);
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( acorn_vidc10_device::sound_frequency_w )
|
||||
{
|
||||
m_sound_frequency_test_bit = BIT(data, 8);
|
||||
m_sound_frequency_latch = data & 0xff;
|
||||
if (m_sound_mode == true)
|
||||
refresh_sound_frequency();
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// MEMC comms
|
||||
//**************************************************************************
|
||||
|
||||
void acorn_vidc10_device::write_dac(uint8_t channel, uint8_t data)
|
||||
{
|
||||
uint8_t ulaw_comp;
|
||||
int16_t res;
|
||||
const int16_t mulawTable[256] =
|
||||
{
|
||||
-32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
|
||||
-23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
|
||||
-15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
|
||||
-11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
|
||||
-7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
|
||||
-5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
|
||||
-3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
|
||||
-2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
|
||||
-1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
|
||||
-1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
|
||||
-876, -844, -812, -780, -748, -716, -684, -652,
|
||||
-620, -588, -556, -524, -492, -460, -428, -396,
|
||||
-372, -356, -340, -324, -308, -292, -276, -260,
|
||||
-244, -228, -212, -196, -180, -164, -148, -132,
|
||||
-120, -112, -104, -96, -88, -80, -72, -64,
|
||||
-56, -48, -40, -32, -24, -16, -8, -1,
|
||||
32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
|
||||
23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
|
||||
15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
|
||||
11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
|
||||
7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
|
||||
5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
|
||||
3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
|
||||
2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
|
||||
1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
|
||||
1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
|
||||
876, 844, 812, 780, 748, 716, 684, 652,
|
||||
620, 588, 556, 524, 492, 460, 428, 396,
|
||||
372, 356, 340, 324, 308, 292, 276, 260,
|
||||
244, 228, 212, 196, 180, 164, 148, 132,
|
||||
120, 112, 104, 96, 88, 80, 72, 64,
|
||||
56, 48, 40, 32, 24, 16, 8, 0
|
||||
};
|
||||
|
||||
uint8_t ulaw_temp = data ^ 0xff;
|
||||
ulaw_comp = (ulaw_temp>>1) | ((ulaw_temp&1)<<7);
|
||||
res = mulawTable[ulaw_comp];
|
||||
m_dac[channel & 7]->write(res);
|
||||
}
|
||||
|
||||
void acorn_vidc10_device::refresh_sound_frequency()
|
||||
{
|
||||
// TODO: check against test bit (reloads sound frequency if 0)
|
||||
if (m_sound_mode == true)
|
||||
{
|
||||
// TODO: Range is between 3 and 256 usecs
|
||||
double sndhz = 1e6 / ((m_sound_frequency_latch & 0xff) + 2);
|
||||
sndhz /= 8.0;
|
||||
m_sound_timer->adjust(attotime::zero, 0, attotime::from_hz(sndhz));
|
||||
//printf("VIDC: audio DMA start, sound freq %d, sndhz = %f\n", (m_crtc_regs[0xc0] & 0xff)-2, sndhz);
|
||||
}
|
||||
else
|
||||
m_sound_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// Screen Update / VBlank / HBlank
|
||||
//**************************************************************************
|
||||
|
||||
void acorn_vidc10_device::draw(bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 *vram, uint8_t bpp, int xstart, int ystart, int xsize, int ysize, bool is_cursor)
|
||||
{
|
||||
const u16 pen_base = (bpp == 3 ? 0 : 0x100) + (is_cursor == true ? 0x10 : 0);
|
||||
const u16 pen_masks[4] = { 1, 3, 0xf, 0xff };
|
||||
const u16 pen_mask = pen_masks[bpp];
|
||||
const u16 xchar_size = 1 << (3 - bpp);
|
||||
const u8 pen_byte_sizes[4] = { 1, 2, 4, 1 };
|
||||
const u16 pen_byte_size = pen_byte_sizes[bpp];
|
||||
const int raster_ystart = std::max(0, cliprect.min_y-ystart);
|
||||
xsize >>= 3-bpp;
|
||||
|
||||
//printf("%d %d %d %d\n",ystart, ysize, cliprect.min_y, cliprect.max_y);
|
||||
|
||||
for (int srcy = raster_ystart; srcy<ysize; srcy++)
|
||||
{
|
||||
int dsty = (srcy + ystart)*(m_crtc_interlace+1);
|
||||
for (int srcx = 0; srcx<xsize; srcx++)
|
||||
{
|
||||
u8 pen = vram[srcx + srcy * xsize];
|
||||
int dstx = (srcx*xchar_size) + xstart;
|
||||
|
||||
for (int xi=0;xi<xchar_size;xi++)
|
||||
{
|
||||
u16 dot = ((pen>>(xi*pen_byte_size)) & pen_mask);
|
||||
if (is_cursor == true && dot == 0)
|
||||
continue;
|
||||
dot += pen_base;
|
||||
bitmap.pix32(dsty, dstx+xi) = m_palette->pen(dot);
|
||||
if (m_crtc_interlace)
|
||||
bitmap.pix32(dsty+1, dstx+xi) = m_palette->pen(dot);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u32 acorn_vidc10_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int xstart,ystart,xend,yend;
|
||||
int xsize,ysize;
|
||||
int calc_dxs = 0,calc_dxe = 0;
|
||||
const uint8_t x_step[4] = { 19, 11, 7, 5 };
|
||||
|
||||
/* border color */
|
||||
bitmap.fill(m_palette->pen(0x110), cliprect);
|
||||
|
||||
/* define X display area through BPP mode register */
|
||||
calc_dxs = (m_crtc_regs[CRTC_HDSR]*2)+x_step[m_bpp_mode & 3];
|
||||
calc_dxe = (m_crtc_regs[CRTC_HDER]*2)+x_step[m_bpp_mode & 3];
|
||||
|
||||
/* now calculate display clip rectangle start/end areas */
|
||||
xstart = (calc_dxs)-m_crtc_regs[CRTC_HBSR];
|
||||
ystart = (m_crtc_regs[CRTC_VDSR]-m_crtc_regs[CRTC_VBSR]);
|
||||
xend = (calc_dxe)+xstart;
|
||||
yend = (m_crtc_regs[CRTC_VDER] * (m_crtc_interlace+1))+ystart;
|
||||
|
||||
/* disable the screen if display params are invalid */
|
||||
if(xstart > xend || ystart > yend)
|
||||
return 0;
|
||||
|
||||
xsize = calc_dxe-calc_dxs;
|
||||
ysize = m_crtc_regs[CRTC_VDER]-m_crtc_regs[CRTC_VDSR];
|
||||
|
||||
if (xsize <= 0 || ysize <= 0)
|
||||
return 0;
|
||||
|
||||
draw(bitmap, cliprect, m_data_vram, m_bpp_mode, xstart, ystart, xsize, ysize, false);
|
||||
if (m_cursor_enable == true)
|
||||
{
|
||||
xstart = m_crtc_regs[CRTC_HCSR] - m_crtc_regs[CRTC_HBSR];
|
||||
ystart = m_crtc_regs[CRTC_VCSR] - m_crtc_regs[CRTC_VBSR];
|
||||
xsize = 32;
|
||||
ysize = m_crtc_regs[CRTC_VCER] - m_crtc_regs[CRTC_VCSR];
|
||||
if (ysize > 0)
|
||||
draw(bitmap, cliprect, m_cursor_vram, 1, xstart, ystart, xsize, ysize, true);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
READ_LINE_MEMBER(acorn_vidc10_device::flyback_r )
|
||||
{
|
||||
int vert_pos = m_screen->vpos();
|
||||
bool flyback = (vert_pos <= m_crtc_regs[CRTC_VDSR] || vert_pos >= m_crtc_regs[CRTC_VDER]);
|
||||
return flyback;
|
||||
}
|
145
src/devices/machine/acorn_vidc.h
Normal file
145
src/devices/machine/acorn_vidc.h
Normal file
@ -0,0 +1,145 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Angelo Salese, R. Belmont, Juergen Buchmueller
|
||||
/***************************************************************************
|
||||
|
||||
Acorn VIDC10 (VIDeo Controller) device chip
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_ACORN_VIDC_H
|
||||
#define MAME_MACHINE_ACORN_VIDC_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "screen.h"
|
||||
#include "speaker.h"
|
||||
#include "emupal.h"
|
||||
#include "sound/dac.h"
|
||||
#include "sound/volt_reg.h"
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> acorn_vidc10_device
|
||||
|
||||
class acorn_vidc10_device : public device_t,
|
||||
public device_memory_interface,
|
||||
public device_video_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
acorn_vidc10_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// I/O operations
|
||||
DECLARE_WRITE32_MEMBER( write );
|
||||
DECLARE_READ_LINE_MEMBER( flyback_r );
|
||||
auto vblank() { return m_vblank_cb.bind(); }
|
||||
auto sound_drq() { return m_sound_drq_cb.bind(); }
|
||||
// MEMC comms
|
||||
void write_vram(uint32_t offset, uint8_t data) { m_data_vram[offset & (m_data_vram_mask)] = data; }
|
||||
void write_cram(uint32_t offset, uint8_t data) { m_cursor_vram[offset & (m_cursor_vram_mask)] = data; }
|
||||
void write_dac(uint8_t channel, uint8_t data);
|
||||
void clear_dac(uint8_t channel) { m_dac[channel & 7]->write(0); }
|
||||
void update_sound_mode(bool state) { m_sound_mode = state; refresh_sound_frequency(); }
|
||||
void set_cursor_enable(bool state) { m_cursor_enable = state; }
|
||||
uint32_t get_cursor_size() { return (m_crtc_regs[CRTC_VCER] - m_crtc_regs[CRTC_VCSR]) * (32/4); }
|
||||
|
||||
protected:
|
||||
acorn_vidc10_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
// device-level overrides
|
||||
//virtual void device_validity_check(validity_checker &valid) const override;
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
virtual space_config_vector memory_space_config() const override;
|
||||
u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
required_device<screen_device> m_screen;
|
||||
|
||||
private:
|
||||
const address_space_config m_space_config;
|
||||
|
||||
void regs_map(address_map &map);
|
||||
|
||||
required_device<palette_device> m_palette;
|
||||
required_device<speaker_device> m_lspeaker;
|
||||
required_device<speaker_device> m_rspeaker;
|
||||
required_device_array<dac_16bit_r2r_twos_complement_device, 8> m_dac;
|
||||
devcb_write_line m_vblank_cb;
|
||||
devcb_write_line m_sound_drq_cb;
|
||||
|
||||
DECLARE_WRITE32_MEMBER( pal_data_display_w );
|
||||
DECLARE_WRITE32_MEMBER( pal_data_cursor_w );
|
||||
DECLARE_WRITE32_MEMBER( stereo_image_w );
|
||||
DECLARE_WRITE32_MEMBER( crtc_w );
|
||||
DECLARE_WRITE32_MEMBER( sound_frequency_w );
|
||||
DECLARE_WRITE32_MEMBER( control_w );
|
||||
|
||||
uint8_t m_pixel_clock, m_bpp_mode, m_crtc_interlace;
|
||||
//bool m_flyback;
|
||||
enum {
|
||||
TIMER_VIDEO = 1,
|
||||
TIMER_SOUND = 2
|
||||
};
|
||||
emu_timer *m_video_timer;
|
||||
emu_timer *m_sound_timer;
|
||||
|
||||
inline void screen_vblank_line_update();
|
||||
void screen_dynamic_res_change();
|
||||
|
||||
enum {
|
||||
CRTC_HCR = 0, CRTC_HSWR, CRTC_HBSR, CRTC_HDSR, CRTC_HDER, CRTC_HBER, CRTC_HCSR, CRTC_HIR,
|
||||
CRTC_VCR, CRTC_VSWR, CRTC_VBSR, CRTC_VDSR, CRTC_VDER, CRTC_VBER, CRTC_VCSR, CRTC_VCER
|
||||
};
|
||||
uint32_t m_crtc_regs[16];
|
||||
u8 *m_data_vram;
|
||||
u8 *m_cursor_vram;
|
||||
// TODO: correct data vram size
|
||||
const u32 m_data_vram_mask = 0x1fffff;
|
||||
const u32 m_cursor_vram_mask = 0x7fff;
|
||||
const u32 m_data_vram_size = m_data_vram_mask+1;
|
||||
const u32 m_cursor_vram_size = m_cursor_vram_mask+1;
|
||||
bool m_cursor_enable;
|
||||
void draw(bitmap_rgb32 &bitmap, const rectangle &cliprect, u8 *vram, uint8_t bpp, int xstart, int ystart, int xsize, int ysize, bool is_cursor);
|
||||
inline void update_4bpp_palette(uint16_t index, uint32_t paldata);
|
||||
|
||||
u8 m_sound_frequency_latch;
|
||||
bool m_sound_frequency_test_bit;
|
||||
bool m_sound_mode;
|
||||
u8 m_stereo_image[8];
|
||||
const float m_sound_input_gain = 0.05;
|
||||
const int m_sound_max_channels = 8;
|
||||
void refresh_sound_frequency();
|
||||
inline void refresh_stereo_image(uint8_t channel);
|
||||
};
|
||||
|
||||
class acorn_vidc10_lcd_device : public acorn_vidc10_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
acorn_vidc10_lcd_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
protected:
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(ACORN_VIDC10, acorn_vidc10_device)
|
||||
DECLARE_DEVICE_TYPE(ACORN_VIDC10_LCD, acorn_vidc10_lcd_device)
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
|
||||
#endif // MAME_MACHINE_ACORN_VIDC10_H
|
@ -198,7 +198,7 @@ void aa310_state::aa310_mem(address_map &map)
|
||||
map(0x00000000, 0x01ffffff).rw(FUNC(aa310_state::archimedes_memc_logical_r), FUNC(aa310_state::archimedes_memc_logical_w));
|
||||
map(0x02000000, 0x02ffffff).ram().share("physicalram"); /* physical RAM - 16 MB for now, should be 512k for the A310 */
|
||||
map(0x03000000, 0x033fffff).rw(FUNC(aa310_state::archimedes_ioc_r), FUNC(aa310_state::archimedes_ioc_w));
|
||||
map(0x03400000, 0x035fffff).rom().region("extension", 0x000000).w(FUNC(aa310_state::archimedes_vidc_w));
|
||||
map(0x03400000, 0x035fffff).rom().region("extension", 0x000000).w(m_vidc, FUNC(acorn_vidc10_device::write));
|
||||
map(0x03600000, 0x037fffff).rom().region("extension", 0x200000).w(FUNC(aa310_state::archimedes_memc_w));
|
||||
map(0x03800000, 0x03ffffff).rom().region("maincpu", 0).w(FUNC(aa310_state::archimedes_memc_page_w));
|
||||
}
|
||||
@ -428,12 +428,9 @@ void aa310_state::aa310(machine_config &config)
|
||||
|
||||
I2CMEM(config, "i2cmem", 0).set_data_size(0x100);
|
||||
|
||||
/* video hardware */
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(16_MHz_XTAL, 1024, 0, 735, 624/2, 0, 292); // RiscOS 3 default screen settings
|
||||
m_screen->set_screen_update(FUNC(archimedes_state::screen_update));
|
||||
|
||||
PALETTE(config, m_palette).set_entries(32768);
|
||||
ACORN_VIDC10(config, m_vidc, 0);
|
||||
m_vidc->vblank().set(FUNC(aa310_state::vblank_irq));
|
||||
m_vidc->sound_drq().set(FUNC(aa310_state::sound_drq));
|
||||
|
||||
RAM(config, m_ram).set_default_size("1M");
|
||||
|
||||
@ -448,21 +445,6 @@ void aa310_state::aa310(machine_config &config)
|
||||
|
||||
SOFTWARE_LIST(config, "flop_list").set_original("archimedes");
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac[i], 0).add_route(0, "speaker", 0.1); // unknown DAC
|
||||
}
|
||||
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
|
||||
vref.add_route(0, "dac0", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac0", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac1", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac1", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac2", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac2", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac3", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac3", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac4", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac4", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac5", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac5", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac6", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac6", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac7", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac7", -1.0, DAC_VREF_NEG_INPUT);
|
||||
|
||||
/* Expansion slots - 2-card backplane */
|
||||
}
|
||||
|
||||
@ -546,7 +528,9 @@ void aa310_state::aa4(machine_config &config)
|
||||
m_maincpu->set_clock(24_MHz_XTAL); // ARM3
|
||||
|
||||
/* video hardware */
|
||||
m_screen->set_type(SCREEN_TYPE_LCD);
|
||||
ACORN_VIDC10_LCD(config.replace(), m_vidc, 0);
|
||||
m_vidc->vblank().set(FUNC(aa310_state::vblank_irq));
|
||||
m_vidc->sound_drq().set(FUNC(aa310_state::sound_drq));
|
||||
|
||||
/* 765 FDC */
|
||||
|
||||
@ -619,7 +603,7 @@ ROM_START( aa305 )
|
||||
ROMX_LOAD( "0276,148-01.ic26", 0x000002, 0x10000, CRC(1ab02f2d) SHA1(dd7d216967524e64d1a03076a6081461ec8528c3), ROM_BIOS(8) | ROM_SKIP(3) )
|
||||
ROMX_LOAD( "0276,149-01.ic27", 0x000003, 0x10000, CRC(5fd6a406) SHA1(790af8a4c74d0f6714d528f7502443ce5898a618), ROM_BIOS(8) | ROM_SKIP(3) )
|
||||
|
||||
ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x400000, "extension", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x100, "i2cmem", ROMREGION_ERASE00 )
|
||||
@ -663,7 +647,7 @@ ROM_START( aa3000 )
|
||||
ROM_SYSTEM_BIOS( 5, "319", "RISC OS 3.19 (09 Jun 1993)" ) // Parts 0296,241-01, 0296,242-01, 0296,243-01, 0296,244-01,
|
||||
ROMX_LOAD( "riscos319.bin", 0x000000, 0x200000, CRC(00c7a3d3) SHA1(be7a8cba5d6c6c0e1c4838712524056cf4b8c8cb), ROM_BIOS(5) )
|
||||
|
||||
ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x400000, "extension", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x100, "i2cmem", ROMREGION_ERASE00 )
|
||||
@ -700,7 +684,7 @@ ROM_START( aa5000 )
|
||||
ROM_SYSTEM_BIOS( 3, "319", "RISC OS 3.19 (09 Jun 1993)" ) // Parts 0296,241-01, 0296,242-01, 0296,243-01, 0296,244-01,
|
||||
ROMX_LOAD( "riscos319.bin", 0x000000, 0x200000, CRC(00c7a3d3) SHA1(be7a8cba5d6c6c0e1c4838712524056cf4b8c8cb), ROM_BIOS(3) )
|
||||
|
||||
ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x400000, "extension", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x100, "i2cmem", ROMREGION_ERASE00 )
|
||||
@ -714,7 +698,7 @@ ROM_START( aa4 )
|
||||
ROM_LOAD32_WORD( "0296,061-01.ic4", 0x000000, 0x100000, CRC(b77fe215) SHA1(57b19ea4b97a9b6a240aa61211c2c134cb295aa0) )
|
||||
ROM_LOAD32_WORD( "0296,062-01.ic15", 0x000002, 0x100000, CRC(d42e196e) SHA1(64243d39d1bca38b10761f66a8042c883bde87a4) )
|
||||
|
||||
ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x400000, "extension", ROMREGION_ERASE00 )
|
||||
/* Power Management */
|
||||
ROM_LOAD32_BYTE( "0296,063-01.ic38", 0x000003, 0x010000, CRC(9ca3a6be) SHA1(75905b031f49960605d55c3e7350d309559ed440) )
|
||||
@ -728,7 +712,7 @@ ROM_START( aa3010 )
|
||||
ROM_LOAD32_WORD( "0296,061-02.ic17", 0x000000, 0x100000, CRC(552fc3aa) SHA1(b2f1911e53d7377f2e69e1a870139745d3df494b) )
|
||||
ROM_LOAD32_WORD( "0296,062-02.ic18", 0x000002, 0x100000, CRC(308d5a4a) SHA1(b309e1dd85670a06d77ec504dbbec6c42336329f) )
|
||||
|
||||
ROM_REGION( 0x200000, "vram", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x400000, "extension", ROMREGION_ERASE00 )
|
||||
|
||||
ROM_REGION( 0x100, "i2cmem", ROMREGION_ERASE00 )
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -21,13 +21,12 @@
|
||||
PCB has a single OSC at 24MHz
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/archimds.h"
|
||||
#include "cpu/arm/arm.h"
|
||||
#include "machine/aakart.h"
|
||||
#include "machine/i2cmem.h"
|
||||
#include "sound/volt_reg.h"
|
||||
#include "speaker.h"
|
||||
|
||||
|
||||
class ertictac_state : public archimedes_state
|
||||
@ -73,8 +72,8 @@ void ertictac_state::ertictac_map(address_map &map)
|
||||
map(0x03000000, 0x033fffff).rw(FUNC(ertictac_state::archimedes_ioc_r), FUNC(ertictac_state::archimedes_ioc_w));
|
||||
map(0x03340000, 0x0334001f).r(FUNC(ertictac_state::ertictac_podule_r));
|
||||
map(0x033c0000, 0x033c001f).r(FUNC(ertictac_state::ertictac_podule_r));
|
||||
map(0x03400000, 0x035fffff).rw(FUNC(ertictac_state::archimedes_vidc_r), FUNC(ertictac_state::archimedes_vidc_w));
|
||||
map(0x03600000, 0x037fffff).rw(FUNC(ertictac_state::archimedes_memc_r), FUNC(ertictac_state::archimedes_memc_w));
|
||||
map(0x03400000, 0x035fffff).w(m_vidc, FUNC(acorn_vidc10_device::write));
|
||||
map(0x03600000, 0x037fffff).w(FUNC(ertictac_state::archimedes_memc_w));
|
||||
map(0x03800000, 0x03ffffff).rom().region("maincpu", 0).w(FUNC(ertictac_state::archimedes_memc_page_w));
|
||||
}
|
||||
|
||||
@ -233,26 +232,9 @@ void ertictac_state::ertictac(machine_config &config)
|
||||
|
||||
// AAKART(config, m_kart, XTAL(24'000'000)/3); // TODO: frequency
|
||||
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(XTAL(16'000'000), 1024,0,735, 624/2,0,292); // RiscOS 3 default screen settings
|
||||
m_screen->set_screen_update(FUNC(archimedes_state::screen_update));
|
||||
|
||||
PALETTE(config, m_palette).set_entries(0x200);
|
||||
|
||||
SPEAKER(config, "speaker").front_center();
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
DAC_16BIT_R2R_TWOS_COMPLEMENT(config, m_dac[i], 0).add_route(0, "speaker", 0.05); // unknown DAC
|
||||
}
|
||||
voltage_regulator_device &vref(VOLTAGE_REGULATOR(config, "vref", 0));
|
||||
vref.add_route(0, "dac0", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac0", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac1", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac1", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac2", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac2", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac3", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac3", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac4", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac4", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac5", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac5", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac6", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac6", -1.0, DAC_VREF_NEG_INPUT);
|
||||
vref.add_route(0, "dac7", 1.0, DAC_VREF_POS_INPUT); vref.add_route(0, "dac7", -1.0, DAC_VREF_NEG_INPUT);
|
||||
ACORN_VIDC10(config, m_vidc, 0);
|
||||
m_vidc->vblank().set(FUNC(ertictac_state::vblank_irq));
|
||||
m_vidc->sound_drq().set(FUNC(ertictac_state::sound_drq));
|
||||
}
|
||||
|
||||
ROM_START( ertictac )
|
||||
@ -273,8 +255,6 @@ ROM_START( ertictac )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-14-", 0xc0001, 0x10000, CRC(3029567c) SHA1(6d49bea3a3f6f11f4182a602d37b53f1f896c154) )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-15-", 0xc0002, 0x10000, CRC(500997ab) SHA1(028c7b3ca03141e5b596ab1e2ab98d0ccd9bf93a) )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-16-", 0xc0003, 0x10000, CRC(70a8d136) SHA1(50b11f5701ed5b79a5d59c9a3c7d5b7528e66a4d) )
|
||||
|
||||
ROM_REGION(0x200000, "vram", ROMREGION_ERASE00)
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -296,8 +276,6 @@ ROM_START( ertictaca ) /* PCB had sticker printed "092121 EROTICTAC" */
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-14-", 0xc0001, 0x10000, CRC(3029567c) SHA1(6d49bea3a3f6f11f4182a602d37b53f1f896c154) )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-15-", 0xc0002, 0x10000, CRC(500997ab) SHA1(028c7b3ca03141e5b596ab1e2ab98d0ccd9bf93a) )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-16-", 0xc0003, 0x10000, CRC(70a8d136) SHA1(50b11f5701ed5b79a5d59c9a3c7d5b7528e66a4d) )
|
||||
|
||||
ROM_REGION(0x200000, "vram", ROMREGION_ERASE00)
|
||||
ROM_END
|
||||
|
||||
ROM_START( ertictacb )
|
||||
@ -318,8 +296,6 @@ ROM_START( ertictacb )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-14-", 0xc0001, 0x10000, CRC(3029567c) SHA1(6d49bea3a3f6f11f4182a602d37b53f1f896c154) )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-15-", 0xc0002, 0x10000, CRC(500997ab) SHA1(028c7b3ca03141e5b596ab1e2ab98d0ccd9bf93a) )
|
||||
ROM_LOAD32_BYTE( "eroti_ver01_-16-", 0xc0003, 0x10000, CRC(70a8d136) SHA1(50b11f5701ed5b79a5d59c9a3c7d5b7528e66a4d) )
|
||||
|
||||
ROM_REGION(0x200000, "vram", ROMREGION_ERASE00)
|
||||
ROM_END
|
||||
|
||||
|
||||
@ -342,8 +318,6 @@ ROM_START( poizone )
|
||||
ROM_LOAD32_BYTE( "p_son22.bin", 0x140001, 0x10000, CRC(16f0bb52) SHA1(893ab1e72b84de7a38f88f9d713769968ebd4553) )
|
||||
ROM_LOAD32_BYTE( "p_son23.bin", 0x140002, 0x10000, CRC(e9c118b2) SHA1(110d9a204e701b9b54d89f027f8892c3f3a819c7) )
|
||||
ROM_LOAD32_BYTE( "p_son24.bin", 0x140003, 0x10000, CRC(a09d7f55) SHA1(e0d562c655c16034b40db93de801b98b7948beb2) )
|
||||
|
||||
ROM_REGION(0x200000, "vram", ROMREGION_ERASE00)
|
||||
ROM_END
|
||||
|
||||
GAME( 1990, ertictac, 0, ertictac, ertictac, ertictac_state, init_ertictac, ROT0, "Sisteme", "Erotictac/Tactic", MACHINE_IMPERFECT_SOUND)
|
||||
|
@ -14,9 +14,7 @@
|
||||
#include "machine/aakart.h"
|
||||
#include "machine/i2cmem.h"
|
||||
#include "machine/wd_fdc.h"
|
||||
#include "sound/dac.h"
|
||||
#include "emupal.h"
|
||||
#include "screen.h"
|
||||
#include "machine/acorn_vidc.h"
|
||||
|
||||
// interrupt definitions. these are for the real Archimedes computer - arcade
|
||||
// and gambling knockoffs likely are a bit different.
|
||||
@ -53,15 +51,12 @@ public:
|
||||
m_kart(*this, "kart"),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_i2cmem(*this, "i2cmem"),
|
||||
m_vidc(*this, "vidc"),
|
||||
m_fdc(*this, "fdc"),
|
||||
m_floppy0(*this, "fdc:0"),
|
||||
m_floppy1(*this, "fdc:1"),
|
||||
m_region_maincpu(*this, "maincpu"),
|
||||
m_region_vram(*this, "vram"),
|
||||
m_screen(*this, "screen"),
|
||||
m_palette(*this, "palette"),
|
||||
m_joy(*this, "joy_p%u",1),
|
||||
m_dac(*this, { "dac0", "dac1", "dac2", "dac3", "dac4", "dac5", "dac6", "dac7" })
|
||||
m_joy(*this, "joy_p%u",1)
|
||||
{ }
|
||||
|
||||
optional_device<aakart_device> m_kart;
|
||||
@ -79,24 +74,16 @@ public:
|
||||
DECLARE_READ32_MEMBER(aristmk5_drame_memc_logical_r);
|
||||
DECLARE_READ32_MEMBER(archimedes_memc_logical_r);
|
||||
DECLARE_WRITE32_MEMBER(archimedes_memc_logical_w);
|
||||
DECLARE_READ32_MEMBER(archimedes_memc_r);
|
||||
DECLARE_WRITE32_MEMBER(archimedes_memc_w);
|
||||
DECLARE_WRITE32_MEMBER(archimedes_memc_page_w);
|
||||
DECLARE_READ32_MEMBER(archimedes_ioc_r);
|
||||
DECLARE_WRITE32_MEMBER(archimedes_ioc_w);
|
||||
DECLARE_READ32_MEMBER(archimedes_vidc_r);
|
||||
DECLARE_WRITE32_MEMBER(archimedes_vidc_w);
|
||||
DECLARE_WRITE_LINE_MEMBER( a310_kart_rx_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( a310_kart_tx_w );
|
||||
|
||||
uint8_t m_i2c_clk;
|
||||
int16_t m_memc_pages[0x2000]; // the logical RAM area is 32 megs, and the smallest page size is 4k
|
||||
uint32_t m_vidc_regs[256];
|
||||
uint8_t m_cursor_vram[0x8000]; // size -> max(VCER) - min(VCSR) * 32 = 0x7fe0
|
||||
uint8_t m_ioc_regs[0x80/4];
|
||||
uint8_t m_vidc_bpp_mode;
|
||||
uint8_t m_vidc_interlace;
|
||||
uint16_t m_vidc_vblank_time;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||
@ -104,29 +91,25 @@ public:
|
||||
protected:
|
||||
required_device<arm_cpu_device> m_maincpu;
|
||||
optional_device<i2cmem_device> m_i2cmem;
|
||||
required_device<acorn_vidc10_device> m_vidc;
|
||||
optional_device<wd1772_device> m_fdc;
|
||||
optional_device<floppy_connector> m_floppy0;
|
||||
optional_device<floppy_connector> m_floppy1;
|
||||
required_memory_region m_region_maincpu;
|
||||
required_memory_region m_region_vram;
|
||||
required_device<screen_device> m_screen;
|
||||
required_device<palette_device> m_palette;
|
||||
optional_ioport_array<2> m_joy;
|
||||
required_device_array<dac_16bit_r2r_twos_complement_device, 8> m_dac;
|
||||
|
||||
DECLARE_WRITE_LINE_MEMBER( vblank_irq );
|
||||
DECLARE_WRITE_LINE_MEMBER( sound_drq );
|
||||
|
||||
private:
|
||||
|
||||
static const device_timer_id TIMER_VBLANK = 0;
|
||||
static const device_timer_id TIMER_VIDEO = 1;
|
||||
static const device_timer_id TIMER_AUDIO = 2;
|
||||
static const device_timer_id TIMER_IOC = 3;
|
||||
|
||||
void vidc_vblank();
|
||||
// void vidc_vblank();
|
||||
void vidc_video_tick();
|
||||
void vidc_audio_tick();
|
||||
void ioc_timer(int param);
|
||||
|
||||
void vidc_dynamic_res_change();
|
||||
void latch_timer_cnt(int tmr);
|
||||
void a310_set_timer(int tmr);
|
||||
DECLARE_READ32_MEMBER(ioc_ctrl_r);
|
||||
@ -136,14 +119,11 @@ private:
|
||||
uint32_t m_memc_pagesize;
|
||||
int m_memc_latchrom;
|
||||
uint32_t m_ioc_timercnt[4], m_ioc_timerout[4];
|
||||
uint32_t m_vidc_vidstart, m_vidc_vidend, m_vidc_vidinit, m_vidc_vidcur,m_vidc_cinit;
|
||||
uint32_t m_vidc_vidstart, m_vidc_vidend, m_vidc_vidinit, m_vidc_vidcur, m_vidc_cinit;
|
||||
uint32_t m_vidc_sndstart, m_vidc_sndend, m_vidc_sndcur, m_vidc_sndendcur;
|
||||
uint8_t m_video_dma_on,m_audio_dma_on;
|
||||
uint8_t m_vidc_pixel_clk;
|
||||
uint8_t m_vidc_stereo_reg[8];
|
||||
bool m_cursor_enabled;
|
||||
emu_timer *m_timer[4], *m_snd_timer, *m_vid_timer;
|
||||
emu_timer *m_vbl_timer;
|
||||
emu_timer *m_timer[4];
|
||||
uint8_t m_floppy_select;
|
||||
bool check_floppy_ready();
|
||||
uint8_t m_joy_serial_data;
|
||||
@ -185,22 +165,4 @@ private:
|
||||
#define T3_GO 0x78/4
|
||||
#define T3_LATCH 0x7c/4
|
||||
|
||||
#define VIDC_HCR 0x80
|
||||
#define VIDC_HSWR 0x84
|
||||
#define VIDC_HBSR 0x88
|
||||
#define VIDC_HDSR 0x8c
|
||||
#define VIDC_HDER 0x90
|
||||
#define VIDC_HBER 0x94
|
||||
#define VIDC_HCSR 0x98
|
||||
#define VIDC_HIR 0x9c
|
||||
|
||||
#define VIDC_VCR 0xa0
|
||||
#define VIDC_VSWR 0xa4
|
||||
#define VIDC_VBSR 0xa8
|
||||
#define VIDC_VDSR 0xac
|
||||
#define VIDC_VDER 0xb0
|
||||
#define VIDC_VBER 0xb4
|
||||
#define VIDC_VCSR 0xb8
|
||||
#define VIDC_VCER 0xbc
|
||||
|
||||
#endif // MAME_INCLUDES_ARCHIMEDES_H
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "debugger.h"
|
||||
|
||||
static const int page_sizes[4] = { 4096, 8192, 16384, 32768 };
|
||||
static const uint32_t pixel_rate[4] = { 8000000, 12000000, 16000000, 24000000};
|
||||
//static const uint32_t pixel_rate[4] = { 8000000, 12000000, 16000000, 24000000};
|
||||
|
||||
#define IOC_LOG 0
|
||||
#define CRTC_LOG 0
|
||||
@ -97,30 +97,42 @@ void archimedes_state::device_timer(emu_timer &timer, device_timer_id id, int pa
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_VBLANK: vidc_vblank();break;
|
||||
case TIMER_VIDEO: vidc_video_tick(); break;
|
||||
case TIMER_AUDIO: vidc_audio_tick(); break;
|
||||
//case TIMER_VBLANK: vidc_vblank();break;
|
||||
//case TIMER_VIDEO: vidc_video_tick(); break;
|
||||
//case TIMER_AUDIO: vidc_audio_tick(); break;
|
||||
case TIMER_IOC: ioc_timer(param); break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void archimedes_state::vidc_vblank()
|
||||
WRITE_LINE_MEMBER( archimedes_state::vblank_irq )
|
||||
{
|
||||
archimedes_request_irq_a(ARCHIMEDES_IRQA_VBL);
|
||||
if (state)
|
||||
{
|
||||
archimedes_request_irq_a(ARCHIMEDES_IRQA_VBL);
|
||||
if (m_video_dma_on)
|
||||
vidc_video_tick();
|
||||
}
|
||||
|
||||
|
||||
// set up for next vbl
|
||||
m_vbl_timer->adjust(m_screen->time_until_pos(m_vidc_vblank_time));
|
||||
//m_vbl_timer->adjust(m_screen->time_until_pos(m_vidc_vblank_time));
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER( archimedes_state::sound_drq )
|
||||
{
|
||||
if (state)
|
||||
vidc_audio_tick();
|
||||
}
|
||||
|
||||
|
||||
/* video DMA */
|
||||
/* TODO: what type of DMA this is, burst or cycle steal? Docs doesn't explain it (4 usec is the DRAM refresh). */
|
||||
/* TODO: change m_region_vram into proper alloc array */
|
||||
/* TODO: Erotictac and Poizone sets up vidinit register AFTER vidend, for double buffering? (fixes Poizone "Eterna" logo display on attract) */
|
||||
// TODO: what type of DMA this is, burst or cycle steal? Docs doesn't explain it (4 usec is the DRAM refresh). */
|
||||
// TODO: Erotictac and Poizone sets up vidinit register AFTER vidend, for double buffering? (fixes Poizone "Eterna" logo display on attract)
|
||||
// TODO: understand how to make quazer to work (sets video DMA param in-flight)
|
||||
void archimedes_state::vidc_video_tick()
|
||||
{
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
static uint8_t *vram = m_region_vram->base();
|
||||
uint32_t size;
|
||||
uint32_t offset_ptr;
|
||||
|
||||
@ -134,7 +146,7 @@ void archimedes_state::vidc_video_tick()
|
||||
|
||||
for(m_vidc_vidcur = 0;m_vidc_vidcur < size;m_vidc_vidcur++)
|
||||
{
|
||||
vram[m_vidc_vidcur] = (space.read_byte(offset_ptr));
|
||||
m_vidc->write_vram(m_vidc_vidcur, space.read_byte(offset_ptr));
|
||||
offset_ptr++;
|
||||
if(offset_ptr >= m_vidc_vidend+0x10) // TODO: correct?
|
||||
offset_ptr = m_vidc_vidstart;
|
||||
@ -142,73 +154,21 @@ void archimedes_state::vidc_video_tick()
|
||||
|
||||
if(m_cursor_enabled == true)
|
||||
{
|
||||
uint32_t ccur_size = (m_vidc_regs[VIDC_VCER] - m_vidc_regs[VIDC_VCSR]) * 32;
|
||||
uint32_t ccur_size = m_vidc->get_cursor_size();
|
||||
|
||||
for(uint32_t ccur = 0; ccur < ccur_size; ccur++)
|
||||
m_cursor_vram[ccur] = (space.read_byte(m_vidc_cinit+ccur));
|
||||
m_vidc->write_cram(ccur, space.read_byte(m_vidc_cinit+ccur));
|
||||
}
|
||||
|
||||
if(m_video_dma_on)
|
||||
{
|
||||
m_vid_timer->adjust(m_screen->time_until_pos(m_vidc_vblank_time+1));
|
||||
}
|
||||
else
|
||||
m_vid_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
/* audio DMA */
|
||||
void archimedes_state::vidc_audio_tick()
|
||||
{
|
||||
address_space &space = m_maincpu->space(AS_PROGRAM);
|
||||
uint8_t ulaw_comp;
|
||||
int16_t res;
|
||||
uint8_t ch;
|
||||
static const int16_t mulawTable[256] =
|
||||
{
|
||||
-32124,-31100,-30076,-29052,-28028,-27004,-25980,-24956,
|
||||
-23932,-22908,-21884,-20860,-19836,-18812,-17788,-16764,
|
||||
-15996,-15484,-14972,-14460,-13948,-13436,-12924,-12412,
|
||||
-11900,-11388,-10876,-10364, -9852, -9340, -8828, -8316,
|
||||
-7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
|
||||
-5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
|
||||
-3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
|
||||
-2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
|
||||
-1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
|
||||
-1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
|
||||
-876, -844, -812, -780, -748, -716, -684, -652,
|
||||
-620, -588, -556, -524, -492, -460, -428, -396,
|
||||
-372, -356, -340, -324, -308, -292, -276, -260,
|
||||
-244, -228, -212, -196, -180, -164, -148, -132,
|
||||
-120, -112, -104, -96, -88, -80, -72, -64,
|
||||
-56, -48, -40, -32, -24, -16, -8, -1,
|
||||
32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
|
||||
23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
|
||||
15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
|
||||
11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
|
||||
7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
|
||||
5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
|
||||
3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
|
||||
2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
|
||||
1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
|
||||
1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
|
||||
876, 844, 812, 780, 748, 716, 684, 652,
|
||||
620, 588, 556, 524, 492, 460, 428, 396,
|
||||
372, 356, 340, 324, 308, 292, 276, 260,
|
||||
244, 228, 212, 196, 180, 164, 148, 132,
|
||||
120, 112, 104, 96, 88, 80, 72, 64,
|
||||
56, 48, 40, 32, 24, 16, 8, 0
|
||||
};
|
||||
|
||||
for(ch=0; ch<8; ch++)
|
||||
{
|
||||
uint8_t ulaw_temp = (space.read_byte(m_vidc_sndcur + ch)) ^ 0xff;
|
||||
|
||||
ulaw_comp = (ulaw_temp>>1) | ((ulaw_temp&1)<<7);
|
||||
|
||||
res = mulawTable[ulaw_comp];
|
||||
|
||||
m_dac[ch & 7]->write(res);
|
||||
}
|
||||
m_vidc->write_dac(ch, (space.read_byte(m_vidc_sndcur + ch)));
|
||||
|
||||
m_vidc_sndcur+=8;
|
||||
|
||||
@ -216,13 +176,12 @@ void archimedes_state::vidc_audio_tick()
|
||||
{
|
||||
archimedes_request_irq_b(ARCHIMEDES_IRQB_SOUND_EMPTY);
|
||||
|
||||
// TODO: nuke this implementation detail, repeated below
|
||||
m_vidc->update_sound_mode(m_audio_dma_on);
|
||||
if(!m_audio_dma_on)
|
||||
{
|
||||
m_snd_timer->adjust(attotime::never);
|
||||
for(ch=0; ch<8; ch++)
|
||||
{
|
||||
m_dac[ch & 7]->write(0);
|
||||
}
|
||||
m_vidc->clear_dac(ch);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -293,21 +252,12 @@ void archimedes_state::archimedes_reset()
|
||||
m_ioc_regs[IRQ_STATUS_B] = 0x00; //set up IL[1] On
|
||||
m_ioc_regs[FIQ_STATUS] = 0x80; //set up Force FIQ
|
||||
m_ioc_regs[CONTROL] = 0xff;
|
||||
|
||||
m_vidc_vblank_time = 10000; // set a stupidly high time so it doesn't fire off
|
||||
m_vbl_timer->adjust(attotime::never);
|
||||
|
||||
m_cursor_enabled = false;
|
||||
memset(m_cursor_vram, 0, sizeof(m_cursor_vram));
|
||||
}
|
||||
|
||||
void archimedes_state::archimedes_init()
|
||||
{
|
||||
m_memc_pagesize = 0;
|
||||
|
||||
m_vbl_timer = timer_alloc(TIMER_VBLANK);
|
||||
m_vbl_timer->adjust(attotime::never);
|
||||
|
||||
m_timer[0] = timer_alloc(TIMER_IOC);
|
||||
m_timer[1] = timer_alloc(TIMER_IOC);
|
||||
m_timer[2] = timer_alloc(TIMER_IOC);
|
||||
@ -316,10 +266,6 @@ void archimedes_state::archimedes_init()
|
||||
m_timer[1]->adjust(attotime::never);
|
||||
m_timer[2]->adjust(attotime::never);
|
||||
m_timer[3]->adjust(attotime::never);
|
||||
|
||||
m_vid_timer = timer_alloc(TIMER_VIDEO);
|
||||
m_snd_timer = timer_alloc(TIMER_AUDIO);
|
||||
m_snd_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
READ32_MEMBER(archimedes_state::archimedes_memc_logical_r)
|
||||
@ -520,13 +466,8 @@ READ32_MEMBER( archimedes_state::ioc_ctrl_r )
|
||||
case CONTROL:
|
||||
{
|
||||
uint8_t i2c_data = 1;
|
||||
uint8_t flyback; //internal name for vblank here
|
||||
int vert_pos;
|
||||
bool floppy_ready_state;
|
||||
|
||||
vert_pos = m_screen->vpos();
|
||||
flyback = (vert_pos <= m_vidc_regs[VIDC_VDSR] || vert_pos >= m_vidc_regs[VIDC_VDER]) ? 0x80 : 0x00;
|
||||
|
||||
if ( m_i2cmem )
|
||||
{
|
||||
i2c_data = (m_i2cmem->read_sda() & 1);
|
||||
@ -534,7 +475,7 @@ READ32_MEMBER( archimedes_state::ioc_ctrl_r )
|
||||
|
||||
floppy_ready_state = check_floppy_ready();
|
||||
|
||||
return (flyback) | (m_ioc_regs[CONTROL] & 0x78) | (floppy_ready_state<<2) | (m_i2c_clk<<1) | i2c_data;
|
||||
return (m_vidc->flyback_r()<<7) | (m_ioc_regs[CONTROL] & 0x78) | (floppy_ready_state<<2) | (m_i2c_clk<<1) | i2c_data;
|
||||
}
|
||||
|
||||
case KART: // keyboard read
|
||||
@ -628,8 +569,8 @@ WRITE32_MEMBER( archimedes_state::ioc_ctrl_w )
|
||||
/* bit 7 forces an IRQ trap */
|
||||
archimedes_request_irq_a((data & 0x80) ? ARCHIMEDES_IRQA_FORCE : 0);
|
||||
|
||||
if(data & 0x08) //set up the VBLANK timer
|
||||
m_vbl_timer->adjust(m_screen->time_until_pos(m_vidc_vblank_time));
|
||||
//if(data & 0x08) //set up the VBLANK timer
|
||||
// m_vbl_timer->adjust(m_screen->time_until_pos(m_vidc_vblank_time));
|
||||
|
||||
break;
|
||||
|
||||
@ -747,10 +688,11 @@ READ32_MEMBER(archimedes_state::archimedes_ioc_r)
|
||||
}
|
||||
case 2:
|
||||
// RTFM joystick interface routes here
|
||||
// TODO: slot interface for econet (reads registers 0 and 1 during boot)
|
||||
switch(ioc_addr)
|
||||
{
|
||||
case 0x3a0000:
|
||||
return 0xed; // ID? Status?
|
||||
return 0xed; // ID for econet
|
||||
case 0x3a0004:
|
||||
return m_joy[0].read_safe(0xff);
|
||||
case 0x3a0008:
|
||||
@ -770,12 +712,13 @@ READ32_MEMBER(archimedes_state::archimedes_ioc_r)
|
||||
case 5:
|
||||
if (m_fdc)
|
||||
{
|
||||
// TODO: IOEB slot interface
|
||||
switch(ioc_addr & 0xfffc)
|
||||
{
|
||||
case 0x18: return 0xff; // FDC latch B
|
||||
case 0x40: return 0xff; // FDC latch A
|
||||
case 0x50: return 0; //fdc type, new model returns 5 here
|
||||
case 0x70: return 0x0f;
|
||||
case 0x50: return 0; //fdc type, an 82c711 returns 5 here
|
||||
case 0x70: return 0x0f; // monitor type, TBD
|
||||
case 0x74: return 0xff; // unknown
|
||||
case 0x78: // serial joystick?
|
||||
case 0x7c:
|
||||
@ -917,178 +860,6 @@ WRITE32_MEMBER(archimedes_state::archimedes_ioc_w)
|
||||
logerror("(PC=%08x) I/O: W %x @ %x (mask %08x)\n", m_maincpu->pc(), data, (offset*4)+0x3000000, mem_mask);
|
||||
}
|
||||
|
||||
READ32_MEMBER(archimedes_state::archimedes_vidc_r)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void archimedes_state::vidc_dynamic_res_change()
|
||||
{
|
||||
/* sanity checks - first pass */
|
||||
/*
|
||||
total cycles + border end
|
||||
*/
|
||||
if(m_vidc_regs[VIDC_HCR] && m_vidc_regs[VIDC_HBER] &&
|
||||
m_vidc_regs[VIDC_VCR] && m_vidc_regs[VIDC_VBER])
|
||||
{
|
||||
/* sanity checks - second pass */
|
||||
/*
|
||||
total cycles >= border end >= border start
|
||||
*/
|
||||
if((m_vidc_regs[VIDC_HCR] >= m_vidc_regs[VIDC_HBER]) &&
|
||||
(m_vidc_regs[VIDC_HBER] >= m_vidc_regs[VIDC_HBSR]) &&
|
||||
(m_vidc_regs[VIDC_VBER] >= m_vidc_regs[VIDC_VBSR]))
|
||||
{
|
||||
rectangle const visarea(
|
||||
0, m_vidc_regs[VIDC_HBER] - m_vidc_regs[VIDC_HBSR] - 1,
|
||||
0, (m_vidc_regs[VIDC_VBER] - m_vidc_regs[VIDC_VBSR]) * (m_vidc_interlace + 1));
|
||||
|
||||
m_vidc_vblank_time = m_vidc_regs[VIDC_VBER] * (m_vidc_interlace+1);
|
||||
//logerror("Configuring: htotal %d vtotal %d border %d x %d display origin %d x %d vblank = %d\n",
|
||||
// m_vidc_regs[VIDC_HCR], m_vidc_regs[VIDC_VCR],
|
||||
// visarea.right(), visarea.bottom(),
|
||||
// m_vidc_regs[VIDC_HDER]-m_vidc_regs[VIDC_HDSR],m_vidc_regs[VIDC_VDER]-m_vidc_regs[VIDC_VDSR]+1,
|
||||
// m_vidc_vblank_time);
|
||||
|
||||
attoseconds_t const refresh = HZ_TO_ATTOSECONDS(pixel_rate[m_vidc_pixel_clk]) * m_vidc_regs[VIDC_HCR] * m_vidc_regs[VIDC_VCR];
|
||||
|
||||
m_screen->configure(m_vidc_regs[VIDC_HCR], m_vidc_regs[VIDC_VCR] * (m_vidc_interlace+1), visarea, refresh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(archimedes_state::archimedes_vidc_w)
|
||||
{
|
||||
uint32_t reg = data>>24;
|
||||
uint32_t val = data & 0xffffff;
|
||||
#if CRTC_LOG
|
||||
static const char *const vrnames[] =
|
||||
{
|
||||
"horizontal total",
|
||||
"horizontal sync width",
|
||||
"horizontal border start",
|
||||
"horizontal display start",
|
||||
"horizontal display end",
|
||||
"horizontal border end",
|
||||
"horizontal cursor start",
|
||||
"horizontal interlace",
|
||||
"vertical total",
|
||||
"vertical sync width",
|
||||
"vertical border start",
|
||||
"vertical display start",
|
||||
"vertical display end",
|
||||
"vertical border end",
|
||||
"vertical cursor start",
|
||||
"vertical cursor end",
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// 0x00 - 0x3c Video Palette Logical Colors (16 colors)
|
||||
// 0x40 Border Color
|
||||
// 0x44 - 0x4c Cursor Palette Logical Colors
|
||||
if (reg <= 0x4c)
|
||||
{
|
||||
int r,g,b;
|
||||
|
||||
//i = (val & 0x1000) >> 12; //supremacy bit
|
||||
b = (val & 0x0f00) >> 8;
|
||||
g = (val & 0x00f0) >> 4;
|
||||
r = (val & 0x000f) >> 0;
|
||||
|
||||
//if(reg == 0x40 && val & 0xfff)
|
||||
// logerror("WARNING: border color write here (PC=%08x)!\n",m_maincpu->pc());
|
||||
|
||||
m_palette->set_pen_color(reg >> 2, pal4bit(r), pal4bit(g), pal4bit(b) );
|
||||
|
||||
/* handle 8bpp colors here */
|
||||
if(reg <= 0x3c)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<0x100;i+=0x10)
|
||||
{
|
||||
b = ((val & 0x700) >> 8) | ((i & 0x80) >> 4);
|
||||
g = ((val & 0x030) >> 4) | ((i & 0x60) >> 3);
|
||||
r = ((val & 0x007) >> 0) | ((i & 0x10) >> 1);
|
||||
|
||||
m_palette->set_pen_color((reg >> 2) + 0x100 + i, pal4bit(r), pal4bit(g), pal4bit(b) );
|
||||
}
|
||||
}
|
||||
|
||||
// update partials
|
||||
m_screen->update_partial(m_screen->vpos());
|
||||
}
|
||||
else if (reg >= 0x60 && reg <= 0x7c)
|
||||
{
|
||||
m_vidc_stereo_reg[(reg >> 2) & 7] = val & 0x07;
|
||||
|
||||
// popmessage("%02x %02x %02x %02x %02x %02x %02x %02x",vidc_stereo_reg[0],vidc_stereo_reg[1],vidc_stereo_reg[2],vidc_stereo_reg[3]
|
||||
// ,vidc_stereo_reg[4],vidc_stereo_reg[5],vidc_stereo_reg[6],vidc_stereo_reg[7]);
|
||||
}
|
||||
else if (reg >= 0x80 && reg <= 0xbc)
|
||||
{
|
||||
switch(reg)
|
||||
{
|
||||
case VIDC_HCR: m_vidc_regs[VIDC_HCR] = ((val >> 14)<<1)+1; break;
|
||||
// case VIDC_HSWR: m_vidc_regs[VIDC_HSWR] = (val >> 14)+1; break;
|
||||
case VIDC_HBSR: m_vidc_regs[VIDC_HBSR] = ((val >> 14)<<1)+1; break;
|
||||
case VIDC_HDSR: m_vidc_regs[VIDC_HDSR] = (val >> 14); break;
|
||||
case VIDC_HDER: m_vidc_regs[VIDC_HDER] = (val >> 14); break;
|
||||
case VIDC_HBER: m_vidc_regs[VIDC_HBER] = ((val >> 14)<<1)+1; break;
|
||||
case VIDC_HCSR: m_vidc_regs[VIDC_HCSR] = ((val >> 13) & 0x7ff) + 6; break;
|
||||
// #define VIDC_HIR 0x9c
|
||||
|
||||
case VIDC_VCR: m_vidc_regs[VIDC_VCR] = ((val >> 14))+1; break;
|
||||
// #define VIDC_VSWR 0xa4
|
||||
case VIDC_VBSR: m_vidc_regs[VIDC_VBSR] = (val >> 14)+1; break;
|
||||
case VIDC_VDSR: m_vidc_regs[VIDC_VDSR] = (val >> 14)+1; break;
|
||||
case VIDC_VDER: m_vidc_regs[VIDC_VDER] = (val >> 14)+1; break;
|
||||
case VIDC_VBER: m_vidc_regs[VIDC_VBER] = (val >> 14)+1; break;
|
||||
case VIDC_VCSR: m_vidc_regs[VIDC_VCSR] = ((val >> 14) & 0x3ff) + 1; break;
|
||||
case VIDC_VCER: m_vidc_regs[VIDC_VCER] = ((val >> 14) & 0x3ff) + 1; break;
|
||||
}
|
||||
|
||||
|
||||
#if CRTC_LOG
|
||||
if(reg != VIDC_VCSR && reg != VIDC_VCER && reg != VIDC_HCSR)
|
||||
logerror("VIDC: %s = %d\n", vrnames[(reg-0x80)/4], m_vidc_regs[reg]);
|
||||
#endif
|
||||
|
||||
vidc_dynamic_res_change();
|
||||
}
|
||||
else if (reg == 0xc0)
|
||||
{
|
||||
m_vidc_regs[reg] = val & 0xffff;
|
||||
|
||||
if (m_audio_dma_on)
|
||||
{
|
||||
double sndhz = 1e6 / ((m_vidc_regs[0xc0] & 0xff) + 2);
|
||||
sndhz /= 8.0;
|
||||
m_snd_timer->adjust(attotime::zero, 0, attotime::from_hz(sndhz));
|
||||
//printf("VIDC: sound freq to %d, sndhz = %f\n", (val & 0xff)-2, sndhz);
|
||||
}
|
||||
}
|
||||
else if (reg == 0xe0)
|
||||
{
|
||||
m_vidc_bpp_mode = ((val & 0x0c) >> 2);
|
||||
m_vidc_interlace = ((val & 0x40) >> 6);
|
||||
m_vidc_pixel_clk = (val & 0x03);
|
||||
//todo: vga/svga modes sets 0x1000
|
||||
vidc_dynamic_res_change();
|
||||
}
|
||||
else
|
||||
{
|
||||
logerror("VIDC: %x to register %x\n", val, reg);
|
||||
m_vidc_regs[reg] = val&0xffff;
|
||||
}
|
||||
}
|
||||
|
||||
READ32_MEMBER(archimedes_state::archimedes_memc_r)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER(archimedes_state::archimedes_memc_w)
|
||||
{
|
||||
// is it a register?
|
||||
@ -1113,6 +884,7 @@ WRITE32_MEMBER(archimedes_state::archimedes_memc_w)
|
||||
|
||||
case 3: /* cursor init */
|
||||
m_cursor_enabled = true;
|
||||
m_vidc->set_cursor_enable(m_cursor_enabled);
|
||||
m_vidc_cinit = 0x2000000 | (((data>>2)&0x7fff)*16);
|
||||
//printf("MEMC: CURSOR INIT %08x\n",((data>>2)&0x7fff)*16);
|
||||
break;
|
||||
@ -1138,24 +910,25 @@ WRITE32_MEMBER(archimedes_state::archimedes_memc_w)
|
||||
|
||||
logerror("(PC = %08x) MEMC: %x to Control (page size %d, %s, %s)\n", m_maincpu->pc(), data & 0x1ffc, page_sizes[m_memc_pagesize], ((data>>10)&1) ? "Video DMA on" : "Video DMA off", ((data>>11)&1) ? "Sound DMA on" : "Sound DMA off");
|
||||
|
||||
m_video_dma_on = ((data>>10)&1);
|
||||
m_audio_dma_on = ((data>>11)&1);
|
||||
m_video_dma_on = BIT(data, 10);
|
||||
m_audio_dma_on = BIT(data, 11);
|
||||
|
||||
if ((data>>10)&1)
|
||||
if (m_video_dma_on)
|
||||
{
|
||||
m_vidc_vidcur = 0;
|
||||
m_vid_timer->adjust(m_screen->time_until_pos(m_vidc_vblank_time+1));
|
||||
// TODO: update internally
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cursor_enabled = false;
|
||||
m_vidc->set_cursor_enable(m_cursor_enabled);
|
||||
}
|
||||
|
||||
if ((data>>11) & 1)
|
||||
m_vidc->update_sound_mode(m_audio_dma_on);
|
||||
if (m_audio_dma_on)
|
||||
{
|
||||
//printf("MEMC: Starting audio DMA at %d uSec, buffer from %x to %x\n", ((m_vidc_regs[0xc0]&0xff)-2)*8, m_vidc_sndstart, m_vidc_sndend);
|
||||
|
||||
double sndhz = 1e6 / ((m_vidc_regs[0xc0] & 0xff) + 2);
|
||||
sndhz /= 8.0;
|
||||
m_snd_timer->adjust(attotime::zero, 0, attotime::from_hz(sndhz));
|
||||
//printf("MEMC: audio DMA start, sound freq %d, sndhz = %f\n", (m_vidc_regs[0xc0] & 0xff)-2, sndhz);
|
||||
|
||||
m_vidc_sndcur = m_vidc_sndstart;
|
||||
|
@ -1,229 +0,0 @@
|
||||
// license:LGPL-2.1+
|
||||
// copyright-holders:Angelo Salese, R. Belmont, Juergen Buchmueller
|
||||
/***************************************************************************
|
||||
|
||||
Acorn Archimedes VIDC (VIDeo Controller) emulation
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/archimds.h"
|
||||
|
||||
uint32_t archimedes_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
int xstart,ystart,xend,yend;
|
||||
int res_x,res_y;
|
||||
int xsize,ysize;
|
||||
int calc_dxs = 0,calc_dxe = 0;
|
||||
const uint8_t x_step[4] = { 19, 11, 7, 5 };
|
||||
|
||||
/* border color */
|
||||
bitmap.fill(m_palette->pen(0x10), cliprect);
|
||||
|
||||
/* define X display area through BPP mode register */
|
||||
calc_dxs = (m_vidc_regs[VIDC_HDSR]*2)+x_step[m_vidc_bpp_mode & 3];
|
||||
calc_dxe = (m_vidc_regs[VIDC_HDER]*2)+x_step[m_vidc_bpp_mode & 3];
|
||||
|
||||
/* now calculate display clip rectangle start/end areas */
|
||||
xstart = (calc_dxs)-m_vidc_regs[VIDC_HBSR];
|
||||
ystart = (m_vidc_regs[VIDC_VDSR]-m_vidc_regs[VIDC_VBSR]);
|
||||
xend = (calc_dxe)+xstart;
|
||||
yend = (m_vidc_regs[VIDC_VDER] * (m_vidc_interlace+1))+ystart;
|
||||
|
||||
/* disable the screen if display params are invalid */
|
||||
if(xstart > xend || ystart > yend)
|
||||
return 0;
|
||||
|
||||
xsize = calc_dxe-calc_dxs;
|
||||
ysize = m_vidc_regs[VIDC_VDER]-m_vidc_regs[VIDC_VDSR];
|
||||
|
||||
{
|
||||
int count;
|
||||
int x,y,xi;
|
||||
uint8_t pen;
|
||||
static uint8_t *vram = memregion("vram")->base();
|
||||
|
||||
count = (0);
|
||||
|
||||
switch(m_vidc_bpp_mode)
|
||||
{
|
||||
case 0: //1 bpp
|
||||
{
|
||||
for(y=0;y<ysize;y++)
|
||||
{
|
||||
for(x=0;x<xsize;x+=8)
|
||||
{
|
||||
pen = vram[count];
|
||||
|
||||
for(xi=0;xi<8;xi++)
|
||||
{
|
||||
res_x = x+xi+xstart;
|
||||
res_y = (y+ystart)*(m_vidc_interlace+1);
|
||||
|
||||
if(m_vidc_interlace)
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen>>(xi))&0x1);
|
||||
if (cliprect.contains(res_x, res_y+1) && (res_x) <= xend && (res_y+1) <= yend)
|
||||
bitmap.pix32(res_y+1, res_x) = m_palette->pen((pen>>(xi))&0x1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen>>(xi))&0x1);
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1: //2 bpp
|
||||
{
|
||||
for(y=0;y<ysize;y++)
|
||||
{
|
||||
for(x=0;x<xsize;x+=4)
|
||||
{
|
||||
pen = vram[count];
|
||||
|
||||
for(xi=0;xi<4;xi++)
|
||||
{
|
||||
res_x = x+xi+xstart;
|
||||
res_y = (y+ystart)*(m_vidc_interlace+1);
|
||||
|
||||
if(m_vidc_interlace)
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen>>(xi*2))&0x3);
|
||||
if (cliprect.contains(res_x, res_y+1) && (res_x) <= xend && (res_y+1) <= yend)
|
||||
bitmap.pix32(res_y+1, res_x) = m_palette->pen((pen>>(xi*2))&0x3);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen>>(xi*2))&0x3);
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2: //4 bpp
|
||||
{
|
||||
for(y=0;y<ysize;y++)
|
||||
{
|
||||
for(x=0;x<xsize;x+=2)
|
||||
{
|
||||
pen = vram[count];
|
||||
|
||||
for(xi=0;xi<2;xi++)
|
||||
{
|
||||
res_x = x+xi+xstart;
|
||||
res_y = (y+ystart)*(m_vidc_interlace+1);
|
||||
|
||||
if(m_vidc_interlace)
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen>>(xi*4))&0xf);
|
||||
if (cliprect.contains(res_x, res_y+1) && (res_x) <= xend && (res_y+1) <= yend)
|
||||
bitmap.pix32(res_y+1, res_x) = m_palette->pen((pen>>(xi*4))&0xf);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen>>(xi*4))&0xf);
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 3: //8 bpp
|
||||
{
|
||||
for(y=0;y<ysize;y++)
|
||||
{
|
||||
for(x=0;x<xsize;x++)
|
||||
{
|
||||
pen = vram[count];
|
||||
|
||||
res_x = x+xstart;
|
||||
res_y = (y+ystart)*(m_vidc_interlace+1);
|
||||
|
||||
if(m_vidc_interlace)
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen&0xff)+0x100);
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y+1) <= yend)
|
||||
bitmap.pix32(res_y+1, res_x) = m_palette->pen((pen&0xff)+0x100);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen((pen&0xff)+0x100);
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
popmessage("Unemulated bpp mode %02x, contact MAME/MESSdev",m_vidc_bpp_mode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(m_cursor_enabled == true)
|
||||
{
|
||||
count = 0;
|
||||
int cursor_h = m_vidc_regs[VIDC_VCER] - m_vidc_regs[VIDC_VCSR];
|
||||
|
||||
if (cursor_h <= 0)
|
||||
return 0;
|
||||
|
||||
for(y=0; y<cursor_h; y++)
|
||||
{
|
||||
for(x=0;x<32;x+=4)
|
||||
{
|
||||
for(xi=0;xi<4;xi++)
|
||||
{
|
||||
uint8_t cursor_dot;
|
||||
pen = m_cursor_vram[count];
|
||||
|
||||
res_x = m_vidc_regs[VIDC_HCSR] - m_vidc_regs[VIDC_HBSR] + x + xi;
|
||||
res_y = (m_vidc_regs[VIDC_VCSR] - m_vidc_regs[VIDC_VBSR] + y) * (m_vidc_interlace + 1);
|
||||
|
||||
cursor_dot = ((pen>>(xi*2))&0x3);
|
||||
|
||||
if(cursor_dot)
|
||||
{
|
||||
if(m_vidc_interlace)
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen(cursor_dot+0x10);
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y+1) <= yend)
|
||||
bitmap.pix32(res_y+1, res_x) = m_palette->pen(cursor_dot+0x10);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (cliprect.contains(res_x, res_y) && (res_x) <= xend && (res_y) <= yend)
|
||||
bitmap.pix32(res_y, res_x) = m_palette->pen(cursor_dot+0x10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user