mirror of
https://github.com/holub/mame
synced 2025-07-05 09:57:47 +03:00
* Spectrum graphics improvements (continuation of #9218). Routines have been cleaned and optimized based on the current state of graphics_device. All configurations are done in terms of T-States/pixels which will simplify adjustment to proper timings.
This commit is contained in:
parent
c783127ce8
commit
32ef8f7eed
@ -238,6 +238,10 @@ public:
|
||||
xtal.validate(std::string("Configuring screen ") + tag());
|
||||
return set_raw(xtal.value(), htotal, hbend, hbstart, vtotal, vbend, vbstart);
|
||||
}
|
||||
screen_device &set_raw(const XTAL &xtal, u16 htotal, u16 vtotal, rectangle visarea)
|
||||
{
|
||||
return set_raw(xtal, htotal, visarea.left(), visarea.right() + 1, vtotal, visarea.top(), visarea.bottom() + 1);
|
||||
}
|
||||
void set_refresh(attoseconds_t rate) { m_refresh = rate; }
|
||||
|
||||
/// \brief Set refresh rate in Hertz
|
||||
|
@ -578,7 +578,6 @@ void elwro800_state::elwro800(machine_config &config)
|
||||
screen.set_raw(14_MHz_XTAL / 2, 448, 0, SPEC_SCREEN_WIDTH, 312, 0, SPEC_SCREEN_HEIGHT);
|
||||
// Sync and interrupt timings determined by 2716 EPROM
|
||||
screen.set_screen_update(FUNC(elwro800_state::screen_update_spectrum));
|
||||
screen.screen_vblank().set(FUNC(elwro800_state::screen_vblank_spectrum));
|
||||
screen.set_palette("palette");
|
||||
|
||||
PALETTE(config, "palette", FUNC(elwro800_state::spectrum_palette), 16);
|
||||
|
@ -16,8 +16,6 @@
|
||||
|
||||
namespace {
|
||||
|
||||
#define PENTAGON_SCREEN rectangle{138, 393, 80, 271}
|
||||
|
||||
class pentagon_state : public spectrum_128_state
|
||||
{
|
||||
public:
|
||||
@ -36,15 +34,8 @@ public:
|
||||
protected:
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
|
||||
|
||||
private:
|
||||
enum
|
||||
{
|
||||
TIMER_IRQ_ON,
|
||||
TIMER_IRQ_OFF
|
||||
};
|
||||
|
||||
void pentagon_port_7ffd_w(uint8_t data);
|
||||
void pentagon_scr_w(offs_t offset, uint8_t data);
|
||||
void pentagon_scr2_w(offs_t offset, uint8_t data);
|
||||
@ -52,8 +43,6 @@ private:
|
||||
uint8_t beta_enable_r(offs_t offset);
|
||||
uint8_t beta_disable_r(offs_t offset);
|
||||
INTERRUPT_GEN_MEMBER(pentagon_interrupt);
|
||||
TIMER_CALLBACK_MEMBER(irq_on);
|
||||
TIMER_CALLBACK_MEMBER(irq_off);
|
||||
void pentagon_io(address_map &map);
|
||||
void pentagon_mem(address_map &map);
|
||||
void pentagon_switch(address_map &map);
|
||||
@ -67,30 +56,19 @@ private:
|
||||
address_space *m_program;
|
||||
uint8_t *m_p_ram;
|
||||
void pentagon_update_memory();
|
||||
|
||||
// Redefined here as POC of improved screen porocessing. Intended to update original implementation.
|
||||
void to_display(unsigned int &x, unsigned int &y);
|
||||
void spectrum_UpdateScreenBitmap(bool eof = false) override;
|
||||
// Following 2 are obsolete
|
||||
u32 screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
void spectrum_UpdateBorderBitmap() override;
|
||||
rectangle get_screen_area() override;
|
||||
};
|
||||
|
||||
void pentagon_state::pentagon_update_memory()
|
||||
{
|
||||
uint8_t *messram = m_ram->pointer();
|
||||
|
||||
m_screen_location = messram + ((m_port_7ffd_data & 8) ? (7<<14) : (5<<14));
|
||||
|
||||
if (strcmp(machine().system().name, "pent1024") != 0)
|
||||
{
|
||||
m_bank4->set_base(messram + ((m_port_7ffd_data & 0x07) * 0x4000));
|
||||
}
|
||||
else
|
||||
{
|
||||
// currently 512Kb ram expansion supported
|
||||
m_bank4->set_base(messram + (((m_port_7ffd_data & 0x07) | ((m_port_7ffd_data & 0xc0) >> 3)) * 0x4000));
|
||||
}
|
||||
|
||||
if (m_beta->started() && m_beta->is_active() && !( m_port_7ffd_data & 0x10 ) )
|
||||
{
|
||||
@ -115,7 +93,7 @@ void pentagon_state::pentagon_port_7ffd_w(uint8_t data)
|
||||
return;
|
||||
|
||||
if ((m_port_7ffd_data ^ data) & 0x08)
|
||||
spectrum_UpdateScreenBitmap();
|
||||
m_screen->update_now();
|
||||
|
||||
/* store new state */
|
||||
m_port_7ffd_data = data;
|
||||
@ -126,121 +104,27 @@ void pentagon_state::pentagon_port_7ffd_w(uint8_t data)
|
||||
|
||||
void pentagon_state::pentagon_scr_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
spectrum_UpdateScreenBitmap();
|
||||
|
||||
m_screen->update_now();
|
||||
*((uint8_t*)m_bank2->base() + offset) = data;
|
||||
}
|
||||
|
||||
void pentagon_state::pentagon_scr2_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
if ((m_port_7ffd_data & 0x0f) == 0x0f || (m_port_7ffd_data & 0x0f) == 5)
|
||||
spectrum_UpdateScreenBitmap();
|
||||
m_screen->update_now();
|
||||
|
||||
*((uint8_t*)m_bank4->base() + offset) = data;
|
||||
}
|
||||
|
||||
// This one not needed as we draw directly at screen's bitmap.
|
||||
u32 pentagon_state::screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
rectangle pentagon_state::get_screen_area()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pentagon_state::to_display(unsigned int &x, unsigned int &y)
|
||||
{
|
||||
rectangle va = m_screen->visible_area();
|
||||
if(y < va.top() || y > va.bottom()) {
|
||||
x = va.left();
|
||||
y = va.top();
|
||||
} else if(x < va.left()) {
|
||||
x = va.left();
|
||||
} else if(x > va.right()) {
|
||||
x = va.left();
|
||||
y++;
|
||||
to_display(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
void pentagon_state::spectrum_UpdateScreenBitmap(bool eof)
|
||||
{
|
||||
unsigned int to_x = m_screen->hpos();
|
||||
unsigned int to_y = m_screen->vpos();
|
||||
to_display(to_x, to_y);
|
||||
|
||||
if ((m_previous_screen_x == to_x) && (m_previous_screen_y == to_y) && !eof)
|
||||
return;
|
||||
|
||||
bitmap_ind16 *bm = &m_screen->curbitmap().as_ind16();
|
||||
if (bm->valid())
|
||||
{
|
||||
u16 border_color = get_border_color();
|
||||
do
|
||||
{
|
||||
u16 x = m_previous_screen_x - PENTAGON_SCREEN.left();
|
||||
u16 y = m_previous_screen_y - PENTAGON_SCREEN.top();
|
||||
|
||||
if(PENTAGON_SCREEN.contains(m_previous_screen_x, m_previous_screen_y))
|
||||
{
|
||||
// this can/must be optimised
|
||||
if ((x & 7) == 0)
|
||||
{
|
||||
u16 *pix = &bm->pix(m_previous_screen_y, m_previous_screen_x);
|
||||
u8 attr = *(m_screen_location + ((y & 0xF8) << 2) + (x >> 3) + 0x1800);
|
||||
u8 scr = *(m_screen_location + ((y & 7) << 8) + ((y & 0x38) << 2) + ((y & 0xC0) << 5) + (x >> 3));
|
||||
u16 ink = (attr & 0x07) + ((attr >> 3) & 0x08);
|
||||
u16 pap = (attr >> 3) & 0x0f;
|
||||
|
||||
if (m_flash_invert && (attr & 0x80))
|
||||
scr = ~scr;
|
||||
|
||||
for (uint8_t b = 0x80; b != 0; b >>= 1)
|
||||
*pix++ = (scr & b) ? ink : pap;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bm->pix(m_previous_screen_y, m_previous_screen_x) = border_color;
|
||||
}
|
||||
|
||||
to_display(++m_previous_screen_x, m_previous_screen_y);
|
||||
} while (!((m_previous_screen_x == to_x) && (m_previous_screen_y == to_y)));
|
||||
}
|
||||
}
|
||||
|
||||
// Any calls must be replaced with spectrum_UpdateScreenBitmap()
|
||||
void pentagon_state::spectrum_UpdateBorderBitmap()
|
||||
{
|
||||
spectrum_UpdateScreenBitmap();
|
||||
}
|
||||
|
||||
void pentagon_state::device_timer(emu_timer &timer, device_timer_id id, int param)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_IRQ_ON:
|
||||
irq_on(param);
|
||||
break;
|
||||
case TIMER_IRQ_OFF:
|
||||
irq_off(param);
|
||||
break;
|
||||
default:
|
||||
throw emu_fatalerror("Unknown id in pentagon_state::device_timer");
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(pentagon_state::irq_on)
|
||||
{
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
timer_set(attotime::from_ticks(32, XTAL(14'000'000) / 4), TIMER_IRQ_OFF, 0);
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER(pentagon_state::irq_off)
|
||||
{
|
||||
m_maincpu->set_input_line(0, CLEAR_LINE);
|
||||
//TODO Possible because of incorrect z80 we have to adjust x+1 to make AccrossTheEdge look nicer
|
||||
return rectangle{137, 137 + 255, 80, 80 + 191};
|
||||
}
|
||||
|
||||
INTERRUPT_GEN_MEMBER(pentagon_state::pentagon_interrupt)
|
||||
{
|
||||
timer_set(attotime::zero, TIMER_IRQ_ON, 0);
|
||||
timer_set(m_screen->time_until_pos(0) - m_maincpu->clocks_to_attotime(1), TIMER_IRQ_ON, 0);
|
||||
}
|
||||
|
||||
uint8_t pentagon_state::beta_neutral_r(offs_t offset)
|
||||
@ -335,46 +219,35 @@ void pentagon_state::machine_reset()
|
||||
void pentagon_state::video_start()
|
||||
{
|
||||
m_frame_invert_count = 16;
|
||||
m_frame_number = 0;
|
||||
m_flash_invert = 0;
|
||||
|
||||
m_previous_border_x = m_previous_border_y = 0;
|
||||
m_previous_screen_x = m_previous_screen_y = 0;
|
||||
|
||||
m_screen_location = m_ram->pointer() + (5 << 14);
|
||||
}
|
||||
|
||||
/* F4 Character Displayer */
|
||||
static const gfx_layout spectrum_charlayout =
|
||||
{
|
||||
8, 8, /* 8 x 8 characters */
|
||||
96, /* 96 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
/* x offsets */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7 },
|
||||
/* y offsets */
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
|
||||
8*8 /* every char takes 8 bytes */
|
||||
8, 8, /* 8 x 8 characters */
|
||||
96, /* 96 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
{STEP8(0, 1)}, /* x offsets */
|
||||
{STEP8(0, 8)}, /* y offsets */
|
||||
8*8 /* every char takes 8 bytes */
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_pentagon )
|
||||
GFXDECODE_ENTRY( "maincpu", 0x17d00, spectrum_charlayout, 0, 8 )
|
||||
GFXDECODE_ENTRY( "maincpu", 0x17d00, spectrum_charlayout, 7, 8 )
|
||||
GFXDECODE_END
|
||||
|
||||
|
||||
|
||||
void pentagon_state::pentagon(machine_config &config)
|
||||
{
|
||||
spectrum_128(config);
|
||||
m_maincpu->set_clock(XTAL(14'000'000) / 4);
|
||||
m_maincpu->set_clock(14_MHz_XTAL / 4);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &pentagon_state::pentagon_mem);
|
||||
m_maincpu->set_addrmap(AS_IO, &pentagon_state::pentagon_io);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &pentagon_state::pentagon_switch);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(pentagon_state::pentagon_interrupt));
|
||||
|
||||
//m_screen->set_raw(XTAL(14'000'000) / 2, 448, 0, 352, 320, 0, 304);
|
||||
m_screen->set_raw(XTAL(14'000'000) / 2, 448, PENTAGON_SCREEN.left() - 48, PENTAGON_SCREEN.right() + 49, 320, PENTAGON_SCREEN.top() - 48, PENTAGON_SCREEN.bottom() + 49);
|
||||
m_screen->set_raw(14_MHz_XTAL / 2, 448, 320, {get_screen_area().left() - 48, get_screen_area().right() + 48, get_screen_area().top() - 48, get_screen_area().bottom() + 48});
|
||||
|
||||
BETA_DISK(config, m_beta, 0);
|
||||
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_pentagon);
|
||||
@ -382,7 +255,7 @@ void pentagon_state::pentagon(machine_config &config)
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
||||
ay8912_device &ay8912(AY8912(config.replace(), "ay8912", XTAL(14'000'000)/8));
|
||||
ay8912_device &ay8912(AY8912(config.replace(), "ay8912", 14_MHz_XTAL / 8));
|
||||
ay8912.add_route(0, "lspeaker", 0.50);
|
||||
ay8912.add_route(1, "lspeaker", 0.25);
|
||||
ay8912.add_route(1, "rspeaker", 0.25);
|
||||
@ -478,6 +351,6 @@ ROM_END
|
||||
} // Anonymous namespace
|
||||
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 1991, pentagon, spec128, 0, pentagon, spec_plus, pentagon_state, empty_init, "<unknown>", "Pentagon 128K", 0 )
|
||||
COMP( 2005, pent1024, spec128, 0, pent1024, spec_plus, pentagon_state, empty_init, "<unknown>", "Pentagon 1024SL", 0 )
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 1991, pentagon, spec128, 0, pentagon, spec_plus, pentagon_state, empty_init, "Vladimir Drozdov", "Pentagon 128K", 0 )
|
||||
COMP( 2005, pent1024, spec128, 0, pent1024, spec_plus, pentagon_state, empty_init, "Alex Zhabin", "Pentagon 1024SL", 0 )
|
||||
|
@ -213,7 +213,7 @@ void spectrum_128_state::spectrum_128_port_7ffd_w(offs_t offset, uint8_t data)
|
||||
return;
|
||||
|
||||
if ((m_port_7ffd_data ^ data) & 0x08)
|
||||
spectrum_UpdateScreenBitmap();
|
||||
m_screen->update_now();
|
||||
|
||||
/* store new state */
|
||||
m_port_7ffd_data = data;
|
||||
@ -248,19 +248,6 @@ uint8_t spectrum_128_state::spectrum_port_r(offs_t offset)
|
||||
return floating_bus_r();
|
||||
}
|
||||
|
||||
uint8_t spectrum_128_state::floating_bus_r()
|
||||
{
|
||||
// very basic "floating bus" implementation, see notes in spectrum.cpp
|
||||
uint8_t data = 0xff;
|
||||
int hpos = m_screen->hpos();
|
||||
int vpos = m_screen->vpos();
|
||||
|
||||
if ((hpos >= 48 && hpos < 304) && (vpos >= 48 && vpos < 240))
|
||||
data = m_screen_location[0x1800 + (((vpos-48)/8)*32) + ((hpos-48)/8)];
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void spectrum_128_state::spectrum_128_io(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x0000).select(0xfffe).rw(FUNC(spectrum_128_state::spectrum_ula_r), FUNC(spectrum_128_state::spectrum_ula_w));
|
||||
@ -304,30 +291,31 @@ void spectrum_128_state::machine_reset()
|
||||
spectrum_128_update_memory();
|
||||
}
|
||||
|
||||
/* F4 Character Displayer */
|
||||
static const gfx_layout spectrum_charlayout =
|
||||
{
|
||||
8, 8, /* 8 x 8 characters */
|
||||
96, /* 96 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
/* x offsets */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7 },
|
||||
/* y offsets */
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
|
||||
8*8 /* every char takes 8 bytes */
|
||||
8, 8, /* 8 x 8 characters */
|
||||
96, /* 96 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
{STEP8(0, 1)}, /* x offsets */
|
||||
{STEP8(0, 8)}, /* y offsets */
|
||||
8*8 /* every char takes 8 bytes */
|
||||
};
|
||||
|
||||
static GFXDECODE_START( spec128 )
|
||||
GFXDECODE_ENTRY( "maincpu", 0x17d00, spectrum_charlayout, 0, 8 )
|
||||
GFXDECODE_ENTRY( "maincpu", 0x17d00, spectrum_charlayout, 7, 8 )
|
||||
GFXDECODE_END
|
||||
|
||||
rectangle spectrum_128_state::get_screen_area()
|
||||
{
|
||||
return rectangle{48, 48 + 255, 63, 63 + 191};
|
||||
}
|
||||
|
||||
void spectrum_128_state::spectrum_128(machine_config &config)
|
||||
{
|
||||
spectrum(config);
|
||||
|
||||
Z80(config.replace(), m_maincpu, X1_128_SINCLAIR / 5);
|
||||
Z80(config.replace(), m_maincpu, X1_128_SINCLAIR / 10);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &spectrum_128_state::spectrum_128_mem);
|
||||
m_maincpu->set_addrmap(AS_IO, &spectrum_128_state::spectrum_128_io);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &spectrum_128_state::spectrum_128_fetch);
|
||||
@ -335,12 +323,12 @@ void spectrum_128_state::spectrum_128(machine_config &config)
|
||||
config.set_maximum_quantum(attotime::from_hz(60));
|
||||
|
||||
/* video hardware */
|
||||
m_screen->set_raw(X1_128_SINCLAIR / 2.5, 456, 0, 352, 311, 0, 296);
|
||||
m_screen->set_raw(X1_128_SINCLAIR / 5, 456, 311, {get_screen_area().left() - 48, get_screen_area().right() + 48, get_screen_area().top() - 48, get_screen_area().bottom() + 48});
|
||||
|
||||
subdevice<gfxdecode_device>("gfxdecode")->set_info(spec128);
|
||||
|
||||
/* sound hardware */
|
||||
AY8912(config, "ay8912", X1_128_SINCLAIR / 10).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
AY8912(config, "ay8912", X1_128_SINCLAIR / 20).add_route(ALL_OUTPUTS, "mono", 0.25);
|
||||
|
||||
/* expansion port */
|
||||
SPECTRUM_EXPANSION_SLOT(config.replace(), m_exp, spec128_expansion_devices, nullptr);
|
||||
@ -353,15 +341,12 @@ void spectrum_128_state::spectrum_128(machine_config &config)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game driver(s)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
ROM_START(spec128)
|
||||
ROM_REGION(0x18000,"maincpu",0)
|
||||
ROM_SYSTEM_BIOS( 0, "en", "English" )
|
||||
|
@ -339,30 +339,21 @@ uint8_t spectrum_state::spectrum_rom_r(offs_t offset)
|
||||
bit 3: MIC/Tape Output
|
||||
bit 2-0: border colour
|
||||
*/
|
||||
|
||||
void spectrum_state::spectrum_ula_w(offs_t offset, uint8_t data)
|
||||
{
|
||||
unsigned char Changed;
|
||||
|
||||
Changed = m_port_fe_data^data;
|
||||
unsigned char Changed = m_port_fe_data^data;
|
||||
|
||||
/* border colour changed? */
|
||||
if ((Changed & 0x07)!=0)
|
||||
{
|
||||
spectrum_UpdateBorderBitmap();
|
||||
}
|
||||
m_screen->update_now();
|
||||
|
||||
if ((Changed & (1<<4))!=0)
|
||||
{
|
||||
/* DAC output state */
|
||||
m_speaker->level_w(BIT(data, 4));
|
||||
}
|
||||
|
||||
if ((Changed & (1<<3))!=0)
|
||||
{
|
||||
/* write cassette data */
|
||||
m_cassette->output((data & (1<<3)) ? -1.0 : +1.0);
|
||||
}
|
||||
|
||||
// Some exp devices use ula port unused bits 5-7:
|
||||
// Beta v2/3/plus use bit 7, Beta clones use bits 6 and 7
|
||||
@ -508,8 +499,9 @@ uint8_t spectrum_state::floating_bus_r()
|
||||
// peek into attribute ram when beam is in display area
|
||||
// ula always returns ff when in border area (or h/vblank)
|
||||
|
||||
if ((hpos >= 48 && hpos < 304) && (vpos >= 48 && vpos < 240))
|
||||
data = m_video_ram[0x1800 + (((vpos-48)/8)*32) + ((hpos-48)/8)];
|
||||
rectangle screen = get_screen_area();
|
||||
if (screen.contains(hpos, vpos))
|
||||
data = m_screen_location[0x1800 + (((vpos - screen.top()) / 8) * 32) + ((hpos - screen.left()) / 8)];
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -713,12 +705,17 @@ INPUT_PORTS_START( spec_plus )
|
||||
INPUT_PORTS_END
|
||||
|
||||
/* Machine initialization */
|
||||
|
||||
void spectrum_state::init_spectrum()
|
||||
{
|
||||
m_specmem->space(AS_PROGRAM).install_ram(0x5b00, m_ram->size() + 0x3fff, m_ram->pointer() + 0x1b00);
|
||||
}
|
||||
|
||||
void spectrum_state::machine_start()
|
||||
{
|
||||
save_item(NAME(m_port_fe_data));
|
||||
//TODO more
|
||||
}
|
||||
|
||||
void spectrum_state::machine_reset()
|
||||
{
|
||||
m_port_7ffd_data = -1;
|
||||
@ -728,32 +725,39 @@ void spectrum_state::machine_reset()
|
||||
/* F4 Character Displayer */
|
||||
static const gfx_layout spectrum_charlayout =
|
||||
{
|
||||
8, 8, /* 8 x 8 characters */
|
||||
96, /* 96 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
/* x offsets */
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7 },
|
||||
/* y offsets */
|
||||
{ 0*8, 1*8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8 },
|
||||
8*8 /* every char takes 8 bytes */
|
||||
8, 8, /* 8 x 8 characters */
|
||||
96, /* 96 characters */
|
||||
1, /* 1 bits per pixel */
|
||||
{ 0 }, /* no bitplanes */
|
||||
{STEP8(0, 1)}, /* x offsets */
|
||||
{STEP8(0, 8)}, /* y offsets */
|
||||
8*8 /* every char takes 8 bytes */
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_spectrum )
|
||||
GFXDECODE_ENTRY( "maincpu", 0x3d00, spectrum_charlayout, 0, 8 )
|
||||
GFXDECODE_ENTRY( "maincpu", 0x3d00, spectrum_charlayout, 7, 8 )
|
||||
GFXDECODE_END
|
||||
|
||||
void spectrum_state::device_timer(emu_timer &timer, device_timer_id id, int param)
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TIMER_IRQ_ON:
|
||||
m_maincpu->set_input_line(0, HOLD_LINE);
|
||||
timer_set(m_maincpu->clocks_to_attotime(32), TIMER_IRQ_OFF, 0);
|
||||
break;
|
||||
case TIMER_IRQ_OFF:
|
||||
m_maincpu->set_input_line(0, CLEAR_LINE);
|
||||
break;
|
||||
case TIMER_SCANLINE:
|
||||
m_scanline_timer->adjust(m_maincpu->cycles_to_attotime(m_CyclesPerLine));
|
||||
spectrum_UpdateScreenBitmap();
|
||||
{
|
||||
auto vpos_next = m_screen->vpos() + 1;
|
||||
if(vpos_next <= get_screen_area().bottom()) {
|
||||
m_scanline_timer->adjust(m_screen->time_until_pos(vpos_next), get_screen_area().left());
|
||||
m_screen->update_now();
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw emu_fatalerror("Unknown id in spectrum_state::device_timer");
|
||||
}
|
||||
@ -761,8 +765,14 @@ void spectrum_state::device_timer(emu_timer &timer, device_timer_id id, int para
|
||||
|
||||
INTERRUPT_GEN_MEMBER(spectrum_state::spec_interrupt)
|
||||
{
|
||||
m_maincpu->set_input_line(0, ASSERT_LINE);
|
||||
m_irq_off_timer->adjust(m_maincpu->clocks_to_attotime(32));
|
||||
timer_set(m_screen->time_until_pos(0), TIMER_IRQ_ON, 0);
|
||||
|
||||
/* Default implementation performs screen updates per scanline. Some other
|
||||
clones e.g. pentagon do updates based on video_ram access, border updates,
|
||||
and full frame refresh (for attributes flashing). Such clones may define own
|
||||
*_interrupt config. */
|
||||
if (m_scanline_timer != nullptr)
|
||||
m_scanline_timer->adjust(m_screen->time_until_pos(get_screen_area().top() + 1));
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_common(machine_config &config)
|
||||
@ -784,9 +794,9 @@ void spectrum_state::spectrum_common(machine_config &config)
|
||||
|
||||
/* video hardware */
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_raw(X1 / 2, 448, 0, 352, 312, 0, 296);
|
||||
|
||||
m_screen->set_raw(X1 / 2, 448, 312, {get_screen_area().left() - 48, get_screen_area().right() + 48, get_screen_area().top() - 48, get_screen_area().bottom() + 48});
|
||||
m_screen->set_screen_update(FUNC(spectrum_state::screen_update_spectrum));
|
||||
m_screen->screen_vblank().set(FUNC(spectrum_state::screen_vblank_spectrum));
|
||||
m_screen->set_palette("palette");
|
||||
|
||||
PALETTE(config, "palette", FUNC(spectrum_state::spectrum_palette), 16);
|
||||
@ -1151,7 +1161,7 @@ COMP( 1993, didakm93, spectrum, 0, spectrum_clone, spec_plus, spectrum_stat
|
||||
COMP( 1988, mistrum, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "Amaterske RADIO", "Mistrum", 0 ) // keyboard could be spectrum in some models (since it was a build-yourself design)
|
||||
COMP( 198?, bk08, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "Orel", "BK-08", 0 )
|
||||
COMP( 1990, blitzs, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "<unknown>", "Blic", 0 ) // no keyboard images found
|
||||
COMP( 1990, byte, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "<unknown>", "Byte", 0 ) // no keyboard images found
|
||||
COMP( 1990, byte, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "BEMZ", "PEVM Byte", 0 ) // no keyboard images found
|
||||
COMP( 199?, orizon, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "<unknown>", "Orizon-Micro", 0 ) // no keyboard images found
|
||||
COMP( 1993, quorum48, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "<unknown>", "Kvorum 48K", MACHINE_NOT_WORKING )
|
||||
COMP( 1993, magic6, spectrum, 0, spectrum_clone, spectrum, spectrum_state, init_spectrum, "<unknown>", "Magic 6", MACHINE_NOT_WORKING ) // keyboard should be spectrum, but image was not clear
|
||||
|
@ -165,23 +165,23 @@ http://www.z88forever.org.uk/zxplus3e/
|
||||
/* TS2048 specific functions */
|
||||
|
||||
|
||||
uint8_t ts2068_state::port_f4_r()
|
||||
u8 ts2068_state::port_f4_r()
|
||||
{
|
||||
return m_port_f4_data;
|
||||
}
|
||||
|
||||
void ts2068_state::port_f4_w(uint8_t data)
|
||||
void ts2068_state::port_f4_w(u8 data)
|
||||
{
|
||||
m_port_f4_data = data;
|
||||
ts2068_update_memory();
|
||||
}
|
||||
|
||||
uint8_t tc2048_state::port_ff_r()
|
||||
u8 tc2048_state::port_ff_r()
|
||||
{
|
||||
return m_port_ff_data;
|
||||
}
|
||||
|
||||
void ts2068_state::port_ff_w(offs_t offset, uint8_t data)
|
||||
void ts2068_state::port_ff_w(offs_t offset, u8 data)
|
||||
{
|
||||
/* Bits 0-2 Video Mode Select
|
||||
Bits 3-5 64 column mode ink/paper selection
|
||||
@ -690,23 +690,21 @@ void ts2068_state::ts2068(machine_config &config)
|
||||
{
|
||||
spectrum_128(config);
|
||||
|
||||
Z80(config.replace(), m_maincpu, XTAL(14'112'000)/4); /* From Schematic; 3.528 MHz */
|
||||
Z80(config.replace(), m_maincpu, XTAL(14'112'000) / 4); /* From Schematic; 3.528 MHz */
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &ts2068_state::ts2068_mem);
|
||||
m_maincpu->set_addrmap(AS_IO, &ts2068_state::ts2068_io);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(ts2068_state::spec_interrupt));
|
||||
config.set_maximum_quantum(attotime::from_hz(60));
|
||||
|
||||
/* video hardware */
|
||||
// timings not confirmed! now same as spec128 but doubled for hires
|
||||
m_screen->set_raw(XTAL(14'112'000) / 2, 456 * 2, 311, {get_screen_area().left() - TS2068_LEFT_BORDER, get_screen_area().right() + TS2068_RIGHT_BORDER, get_screen_area().top() - TS2068_TOP_BORDER, get_screen_area().bottom() + TS2068_BOTTOM_BORDER});
|
||||
m_screen->set_refresh_hz(60);
|
||||
m_screen->set_size(TS2068_SCREEN_WIDTH, TS2068_SCREEN_HEIGHT);
|
||||
m_screen->set_visarea(0, TS2068_SCREEN_WIDTH-1, 0, TS2068_SCREEN_HEIGHT-1);
|
||||
m_screen->set_screen_update(FUNC(ts2068_state::screen_update));
|
||||
m_screen->screen_vblank().set(FUNC(ts2068_state::screen_vblank_timex));
|
||||
|
||||
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_ts2068);
|
||||
|
||||
/* sound */
|
||||
AY8912(config.replace(), "ay8912", XTAL(14'112'000)/8).add_route(ALL_OUTPUTS, "mono", 0.25); /* From Schematic; 1.764 MHz */
|
||||
AY8912(config.replace(), "ay8912", XTAL(14'112'000) / 8).add_route(ALL_OUTPUTS, "mono", 0.25); /* From Schematic; 1.764 MHz */
|
||||
|
||||
/* cartridge */
|
||||
GENERIC_CARTSLOT(config, "dockslot", generic_plain_slot, "timex_cart", "dck,bin").set_device_load(FUNC(ts2068_state::cart_load));
|
||||
@ -726,6 +724,9 @@ void ts2068_state::uk2086(machine_config &config)
|
||||
m_screen->set_refresh_hz(50);
|
||||
}
|
||||
|
||||
rectangle tc2048_state::get_screen_area() {
|
||||
return {TS2068_LEFT_BORDER, TS2068_LEFT_BORDER + TS2068_DISPLAY_XSIZE - 1, TS2068_TOP_BORDER, TS2068_TOP_BORDER + SPEC_DISPLAY_YSIZE - 1};
|
||||
}
|
||||
|
||||
void tc2048_state::tc2048(machine_config &config)
|
||||
{
|
||||
@ -734,11 +735,9 @@ void tc2048_state::tc2048(machine_config &config)
|
||||
m_maincpu->set_addrmap(AS_IO, &tc2048_state::tc2048_io);
|
||||
|
||||
/* video hardware */
|
||||
// timings not confirmed! now same as spec48 but doubled for hires
|
||||
m_screen->set_raw(X1 / 2, 448 * 2, 312, {get_screen_area().left() - TS2068_LEFT_BORDER, get_screen_area().right() + TS2068_RIGHT_BORDER, get_screen_area().top() - TS2068_TOP_BORDER, get_screen_area().bottom() + TS2068_BOTTOM_BORDER});
|
||||
m_screen->set_refresh_hz(50);
|
||||
m_screen->set_size(TS2068_SCREEN_WIDTH, SPEC_SCREEN_HEIGHT);
|
||||
m_screen->set_visarea(0, TS2068_SCREEN_WIDTH-1, 0, SPEC_SCREEN_HEIGHT-1);
|
||||
m_screen->set_screen_update(FUNC(tc2048_state::screen_update));
|
||||
m_screen->screen_vblank().set(FUNC(tc2048_state::screen_vblank_timex));
|
||||
|
||||
/* internal ram */
|
||||
m_ram->set_default_size("48K");
|
||||
|
@ -66,6 +66,7 @@ TODO:
|
||||
|
||||
#include "emu.h"
|
||||
#include "includes/tsconf.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "speaker.h"
|
||||
|
||||
@ -256,11 +257,11 @@ void tsconf_state::machine_reset()
|
||||
void tsconf_state::tsconf(machine_config &config)
|
||||
{
|
||||
spectrum_128(config);
|
||||
m_maincpu->set_clock(3.5_MHz_XTAL);
|
||||
|
||||
config.device_remove("exp");
|
||||
config.device_remove("palette");
|
||||
|
||||
Z80(config.replace(), m_maincpu, 14_MHz_XTAL / 4);
|
||||
m_maincpu->set_addrmap(AS_PROGRAM, &tsconf_state::tsconf_mem);
|
||||
m_maincpu->set_addrmap(AS_IO, &tsconf_state::tsconf_io);
|
||||
m_maincpu->set_addrmap(AS_OPCODES, &tsconf_state::tsconf_switch);
|
||||
@ -271,7 +272,7 @@ void tsconf_state::tsconf(machine_config &config)
|
||||
|
||||
GLUKRS(config, m_glukrs);
|
||||
|
||||
TSCONF_DMA(config, m_dma, 7_MHz_XTAL);
|
||||
TSCONF_DMA(config, m_dma, 14_MHz_XTAL / 2);
|
||||
m_dma->in_mreq_callback().set(FUNC(tsconf_state::ram_read16));
|
||||
m_dma->out_mreq_callback().set(FUNC(tsconf_state::ram_write16));
|
||||
m_dma->in_spireq_callback().set(FUNC(tsconf_state::spi_read16));
|
||||
@ -293,7 +294,7 @@ void tsconf_state::tsconf(machine_config &config)
|
||||
.add_route(2, "rspeaker", 0.50);
|
||||
|
||||
PALETTE(config, "palette", FUNC(tsconf_state::tsconf_palette), 256);
|
||||
m_screen->set_raw(7_MHz_XTAL, 448, with_hblank(), 448, 320, with_vblank(), 320);
|
||||
m_screen->set_raw(14_MHz_XTAL / 2, 448, with_hblank(), 448, 320, with_vblank(), 320);
|
||||
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_tsconf);
|
||||
RAM(config, m_cram).set_default_size("512").set_default_value(0);
|
||||
RAM(config, m_sfile).set_default_size("512").set_default_value(0); // 85*6
|
||||
|
@ -9,6 +9,9 @@
|
||||
#ifndef MAME_INCLUDES_SPEC128_H
|
||||
#define MAME_INCLUDES_SPEC128_H
|
||||
|
||||
#define X1_128_AMSTRAD 35'469'000 // Main clock (Amstrad 128K model, +2A?)
|
||||
#define X1_128_SINCLAIR 35.469_MHz_XTAL // Main clock (Sinclair 128K model)
|
||||
|
||||
/* 128K machines take an extra 4 cycles per scan line - add this to retrace */
|
||||
#define SPEC128_UNSEEN_LINES 15
|
||||
#define SPEC128_RETRACE_CYCLES 52
|
||||
|
@ -23,11 +23,8 @@
|
||||
|
||||
/* Spectrum crystals */
|
||||
|
||||
#define X1 XTAL(14'000'000) // Main clock (48k Spectrum)
|
||||
#define X1_128_AMSTRAD 35469000 // Main clock (Amstrad 128K model, +2A?)
|
||||
#define X1_128_SINCLAIR 17734475 // Main clock (Sinclair 128K model)
|
||||
|
||||
#define X2 XTAL(4'433'619) // PAL color subcarrier
|
||||
#define X1 14_MHz_XTAL // Main clock (48k Spectrum)
|
||||
#define X2 XTAL(4'433'619) // PAL color subcarrier
|
||||
|
||||
/* Spectrum screen size in pixels */
|
||||
#define SPEC_UNSEEN_LINES 16 /* Non-visible scanlines before first border
|
||||
@ -48,18 +45,6 @@
|
||||
#define SPEC_RETRACE_CYCLES 48 /* Cycles taken for horizontal retrace */
|
||||
#define SPEC_CYCLES_PER_LINE 224 /* Number of cycles to display a single line */
|
||||
|
||||
struct EVENT_LIST_ITEM
|
||||
{
|
||||
/* driver defined ID for this write */
|
||||
int Event_ID;
|
||||
/* driver defined data for this write */
|
||||
int Event_Data;
|
||||
/* time at which this write occurred */
|
||||
int Event_Time;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class spectrum_state : public driver_device
|
||||
{
|
||||
@ -100,6 +85,7 @@ public:
|
||||
void init_spectrum();
|
||||
|
||||
protected:
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param) override;
|
||||
@ -113,7 +99,7 @@ protected:
|
||||
{
|
||||
TIMER_IRQ_ON,
|
||||
TIMER_IRQ_OFF,
|
||||
TIMER_SCANLINE
|
||||
TIMER_SCANLINE // tsconf assumes it last know. if need more add above or fix references in clones
|
||||
};
|
||||
|
||||
int m_port_fe_data;
|
||||
@ -123,28 +109,17 @@ protected:
|
||||
int m_port_f4_data; /* Horizontal Select Register */
|
||||
|
||||
/* video support */
|
||||
int m_frame_invert_count;
|
||||
int m_frame_number; /* Used for handling FLASH 1 */
|
||||
int m_flash_invert;
|
||||
int m_frame_invert_count; /* Used for handling FLASH 1 */
|
||||
optional_shared_ptr<uint8_t> m_video_ram;
|
||||
uint8_t *m_screen_location;
|
||||
|
||||
int m_ROMSelection;
|
||||
|
||||
emu_timer *m_irq_off_timer;
|
||||
|
||||
// Build up the screen bitmap line-by-line as the z80 uses CPU cycles.
|
||||
// Elimiates sprite flicker on various games (E.g. Marauder and
|
||||
// Eliminates sprite flicker on various games (E.g. Marauder and
|
||||
// Stormlord) and makes Firefly playable.
|
||||
emu_timer *m_scanline_timer;
|
||||
|
||||
EVENT_LIST_ITEM *m_pCurrentItem;
|
||||
int m_NumEvents;
|
||||
int m_TotalEvents;
|
||||
char *m_pEventListBuffer;
|
||||
int m_LastFrameStartTime;
|
||||
int m_CyclesPerLine;
|
||||
|
||||
uint8_t m_ram_disabled_by_beta;
|
||||
uint8_t pre_opcode_fetch_r(offs_t offset);
|
||||
void spectrum_rom_w(offs_t offset, uint8_t data);
|
||||
@ -156,19 +131,13 @@ protected:
|
||||
uint8_t spectrum_ula_r(offs_t offset);
|
||||
void spectrum_port_w(offs_t offset, uint8_t data);
|
||||
virtual uint8_t spectrum_port_r(offs_t offset);
|
||||
virtual uint8_t floating_bus_r();
|
||||
uint8_t floating_bus_r();
|
||||
uint8_t spectrum_clone_port_r(offs_t offset);
|
||||
|
||||
void spectrum_palette(palette_device &palette) const;
|
||||
virtual uint32_t screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank_spectrum);
|
||||
virtual u32 screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
INTERRUPT_GEN_MEMBER(spec_interrupt);
|
||||
|
||||
unsigned int m_previous_border_x, m_previous_border_y;
|
||||
bitmap_ind16 m_border_bitmap;
|
||||
unsigned int m_previous_screen_x, m_previous_screen_y;
|
||||
bitmap_ind16 m_screen_bitmap;
|
||||
|
||||
DECLARE_SNAPSHOT_LOAD_MEMBER(snapshot_cb);
|
||||
DECLARE_QUICKLOAD_LOAD_MEMBER(quickload_cb);
|
||||
|
||||
@ -210,11 +179,11 @@ protected:
|
||||
optional_ioport m_io_joy1;
|
||||
optional_ioport m_io_joy2;
|
||||
|
||||
virtual void spectrum_UpdateBorderBitmap();
|
||||
virtual u16 get_border_color();
|
||||
virtual void spectrum_UpdateScreenBitmap(bool eof = false);
|
||||
inline unsigned char get_display_color(unsigned char color, int invert);
|
||||
inline void spectrum_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color);
|
||||
virtual u8 get_border_color(u16 hpos = ~0, u16 vpos = ~0);
|
||||
// Defines position of main screen excluding border
|
||||
virtual rectangle get_screen_area();
|
||||
virtual void spectrum_update_border(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
virtual void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
// snapshot helpers
|
||||
void update_paging();
|
||||
@ -255,6 +224,7 @@ protected:
|
||||
virtual void machine_reset() override;
|
||||
|
||||
virtual void spectrum_128_update_memory() override;
|
||||
virtual rectangle get_screen_area() override;
|
||||
|
||||
private:
|
||||
uint8_t spectrum_128_pre_opcode_fetch_r(offs_t offset);
|
||||
@ -262,7 +232,6 @@ private:
|
||||
uint8_t spectrum_128_bank1_r(offs_t offset);
|
||||
void spectrum_128_port_7ffd_w(offs_t offset, uint8_t data);
|
||||
virtual uint8_t spectrum_port_r(offs_t offset) override;
|
||||
virtual uint8_t floating_bus_r() override;
|
||||
//uint8_t spectrum_128_ula_r();
|
||||
|
||||
void spectrum_128_io(address_map &map);
|
||||
|
@ -39,17 +39,16 @@ public:
|
||||
protected:
|
||||
virtual void machine_reset() override;
|
||||
|
||||
uint8_t port_ff_r();
|
||||
DECLARE_WRITE_LINE_MEMBER(screen_vblank_timex);
|
||||
u8 port_ff_r();
|
||||
|
||||
void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
rectangle get_screen_area() override;
|
||||
void hires_scanline(bitmap_ind16 &bitmap, int y, int borderlines);
|
||||
void _64col_scanline(bitmap_ind16 &bitmap, int y, int borderlines, unsigned short inkcolor);
|
||||
void lores_scanline(bitmap_ind16 &bitmap, int y, int borderlines, int screen);
|
||||
|
||||
private:
|
||||
void port_ff_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void port_ff_w(offs_t offset, u8 data);
|
||||
|
||||
void tc2048_io(address_map &map);
|
||||
void tc2048_mem(address_map &map);
|
||||
@ -84,11 +83,9 @@ private:
|
||||
TIMEX_CART_HOME
|
||||
};
|
||||
|
||||
uint8_t port_f4_r();
|
||||
void port_f4_w(uint8_t data);
|
||||
void port_ff_w(offs_t offset, uint8_t data);
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
u8 port_f4_r();
|
||||
void port_f4_w(u8 data);
|
||||
void port_ff_w(offs_t offset, u8 data);
|
||||
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart_load);
|
||||
int m_dock_cart_type, m_ram_chunks;
|
||||
|
@ -144,17 +144,15 @@ private:
|
||||
template <u8 Layer>
|
||||
TILE_GET_INFO_MEMBER(get_tile_info_16c);
|
||||
|
||||
// Changing this consider to revert 'virtual' in spectrum.h
|
||||
u32 screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
void spectrum_UpdateScreenBitmap(bool eof = false) override;
|
||||
void spectrum_UpdateBorderBitmap() override;
|
||||
void spectrum_UpdateZxScreenBitmap();
|
||||
void tsconf_UpdateTxtBitmap(unsigned int from_x, unsigned int from_y);
|
||||
void tsconf_UpdateGfxBitmap(unsigned int from_x, unsigned int from_y);
|
||||
u8 get_border_color(u16 hpos = ~0, u16 vpos = ~0) override;
|
||||
rectangle get_screen_area() override;
|
||||
void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
void tsconf_UpdateZxScreenBitmap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void tsconf_UpdateTxtBitmap(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void tsconf_UpdateGfxBitmap(bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void tsconf_palette(palette_device &palette) const;
|
||||
void draw_sprites(const rectangle &cliprect);
|
||||
void tsconf_update_video_mode();
|
||||
rectangle get_screen_area();
|
||||
|
||||
void tsconf_port_7ffd_w(u8 data);
|
||||
void tsconf_ula_w(offs_t offset, u8 data);
|
||||
@ -209,13 +207,12 @@ private:
|
||||
gluk_ext m_port_f7_ext;
|
||||
u8 m_port_f7_gluk_reg;
|
||||
|
||||
u16 m_rendering_gfx_y_offset;
|
||||
s16 m_gfx_y_frame_offset;
|
||||
required_device<device_palette_interface> m_palette;
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
tilemap_t *m_ts_tilemap[3];
|
||||
required_device<ram_device> m_cram;
|
||||
required_device<ram_device> m_sfile;
|
||||
u16 m_previous_tsu_vpos;
|
||||
};
|
||||
|
||||
/*----------- defined in drivers/tsconf.c -----------*/
|
||||
|
@ -400,9 +400,11 @@ void spectrum_state::setup_sp(uint8_t *snapdata, uint32_t snapsize)
|
||||
m_maincpu->set_input_line(INPUT_LINE_IRQ0, intr);
|
||||
m_maincpu->set_input_line(INPUT_LINE_HALT, CLEAR_LINE);
|
||||
|
||||
/* Not supported as it's wrong anyway: even if we define current invert it can change to opposite either on next frame or N frames later depending on current state.
|
||||
data = BIT(status, 5);
|
||||
m_flash_invert = data;
|
||||
logerror("FLASH state: %s\n", data ? "PAPER on INK" : "INK on PAPER");
|
||||
*/
|
||||
|
||||
// Memory dump
|
||||
logerror("Loading %04X bytes of RAM at %04X\n", size, start);
|
||||
|
@ -50,9 +50,7 @@ rectangle tsconf_state::get_screen_area()
|
||||
{
|
||||
rectangle info = screen_area[BIT(m_regs[V_CONFIG], 6, 2)];
|
||||
if (VM == VM_TXT)
|
||||
{
|
||||
info.set_width(info.width() << 1);
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@ -107,183 +105,14 @@ void tsconf_state::tsconf_update_video_mode()
|
||||
m_screen->configure(visarea.max_x + 1, visarea.max_y + 1, visarea, m_screen->frame_period().as_attoseconds());
|
||||
}
|
||||
|
||||
uint32_t tsconf_state::screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
u8 tsconf_state::get_border_color(u16 hpos, u16 vpos)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void to_display(rectangle area, unsigned int &x, unsigned int &y)
|
||||
{
|
||||
if (y < area.top() || y > area.bottom())
|
||||
{
|
||||
x = area.left();
|
||||
y = area.top();
|
||||
}
|
||||
else if (x < area.left())
|
||||
x = area.left();
|
||||
else if (x > area.right())
|
||||
{
|
||||
x = area.left();
|
||||
to_display(area, x, ++y);
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::spectrum_UpdateZxScreenBitmap()
|
||||
{
|
||||
unsigned int to_x = m_screen->hpos();
|
||||
unsigned int to_y = m_screen->vpos();
|
||||
to_display(m_screen->visible_area(), to_x, to_y);
|
||||
|
||||
if ((m_previous_screen_x == to_x) && (m_previous_screen_y == to_y))
|
||||
return;
|
||||
|
||||
bitmap_ind16 *bm = &m_screen->curbitmap().as_ind16();
|
||||
if (bm->valid())
|
||||
{
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
u16 border_color = m_regs[BORDER];
|
||||
bool border_only = VM != VM_ZX || BIT(m_regs[V_CONFIG], 5);
|
||||
rectangle screen = screen_area[0];
|
||||
do
|
||||
{
|
||||
if (border_only || !screen.contains(m_previous_screen_x, m_previous_screen_y))
|
||||
bm->pix(m_previous_screen_y, m_previous_screen_x) = border_color;
|
||||
else
|
||||
{
|
||||
u16 x = m_previous_screen_x - screen.left();
|
||||
if ((x & 7) == 0)
|
||||
{
|
||||
u16 y = m_previous_screen_y - screen.top();
|
||||
u16 *pix = &bm->pix(m_previous_screen_y, m_previous_screen_x);
|
||||
u8 attr = *(m_ram->pointer() + PAGE4K(m_regs[V_PAGE]) + ((y & 0xF8) << 2) + (x >> 3) + 0x1800);
|
||||
u8 scr = *(m_ram->pointer() + PAGE4K(m_regs[V_PAGE]) + ((y & 7) << 8) + ((y & 0x38) << 2) + ((y & 0xC0) << 5) + (x >> 3));
|
||||
u16 ink = ((attr & 0x07) + ((attr >> 3) & 0x08)) | pal_offset;
|
||||
u16 pap = ((attr >> 3) & 0x0f) | pal_offset;
|
||||
|
||||
if (m_flash_invert && (attr & 0x80))
|
||||
scr = ~scr;
|
||||
|
||||
for (uint8_t b = 0x80; b != 0; b >>= 1)
|
||||
*pix++ = (scr & b) ? ink : pap;
|
||||
}
|
||||
}
|
||||
|
||||
to_display(m_screen->visible_area(), ++m_previous_screen_x, m_previous_screen_y);
|
||||
} while (!((m_previous_screen_x == to_x) && (m_previous_screen_y == to_y)));
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_UpdateTxtBitmap(unsigned int from_x, unsigned int from_y)
|
||||
{
|
||||
unsigned int to_x = m_screen->hpos();
|
||||
unsigned int to_y = m_screen->vpos();
|
||||
rectangle screen = get_screen_area();
|
||||
to_display(screen, to_x, to_y);
|
||||
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
while (!((from_x == to_x) && (from_y == to_y)))
|
||||
{
|
||||
if (from_x == screen.left() && (from_y == screen.top()))
|
||||
m_rendering_gfx_y_offset = OFFS_512(G_Y_OFFS_L);
|
||||
|
||||
u16 x = from_x - screen.left();
|
||||
u16 *bm = &m_screen->curbitmap().as_ind16().pix(from_y, from_x);
|
||||
s16 width = (screen.width() - x) / 8;
|
||||
|
||||
// TODO u16 x_offset = OFFS_512(G_X_OFFS_L);
|
||||
u8 *font_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE] ^ 0x01);
|
||||
u8 *text_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE]) + (m_rendering_gfx_y_offset / 8 * 256 + x / 8);
|
||||
for (; width > 0; width--)
|
||||
{
|
||||
u8 char_x = *(font_location + (*text_location * 8) + (m_rendering_gfx_y_offset % 8));
|
||||
u8 font_color = *(text_location + 128) & 0x0f;
|
||||
u8 bg_color = (*(text_location + 128) & 0xf0) >> 4;
|
||||
for (auto i = 7; i >= 0; i--)
|
||||
*bm++ = (BIT(char_x, i) ? font_color : bg_color) | pal_offset;
|
||||
text_location++;
|
||||
}
|
||||
|
||||
if (from_y == to_y)
|
||||
// done - scanline updated partially
|
||||
from_x = to_x;
|
||||
else
|
||||
{
|
||||
from_y += 1;
|
||||
m_rendering_gfx_y_offset = (m_rendering_gfx_y_offset + 1) & 0x1ff;
|
||||
from_x = screen.left();
|
||||
to_display(screen, from_x, from_y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_UpdateGfxBitmap(unsigned int from_x, unsigned int from_y)
|
||||
{
|
||||
unsigned int to_x = m_screen->hpos();
|
||||
unsigned int to_y = m_screen->vpos();
|
||||
rectangle screen = get_screen_area();
|
||||
to_display(screen, to_x, to_y);
|
||||
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
while (!((from_x == to_x) && (from_y == to_y)))
|
||||
{
|
||||
if (from_x == screen.left() && (from_y == screen.top()))
|
||||
m_rendering_gfx_y_offset = OFFS_512(G_Y_OFFS_L);
|
||||
|
||||
u16 x = from_x - screen.left();
|
||||
u16 x_offset = (OFFS_512(G_X_OFFS_L) + x) & 0x1ff;
|
||||
u16 *bm = &m_screen->curbitmap().as_ind16().pix(from_y, from_x);
|
||||
u8 *video_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE]) + ((m_rendering_gfx_y_offset * 512 + x_offset) >> (2 - VM));
|
||||
s16 width = screen.width() - x;
|
||||
if (VM == VM_16C)
|
||||
{
|
||||
if (x_offset & 1)
|
||||
{
|
||||
*bm++ = (*video_location++ & 0x0f) | pal_offset;
|
||||
x_offset++;
|
||||
width--;
|
||||
}
|
||||
for (; width > 0; width -= 2)
|
||||
{
|
||||
if (x_offset == 512)
|
||||
video_location -= 256;
|
||||
u8 pix = *video_location++;
|
||||
*bm++ = (pix >> 4) | pal_offset;
|
||||
if (width == 1)
|
||||
x_offset++;
|
||||
else
|
||||
{
|
||||
*bm++ = (pix & 0x0f) | pal_offset;
|
||||
x_offset += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // VM_256C
|
||||
{
|
||||
for (; width > 0; width--)
|
||||
{
|
||||
if (x_offset == 512)
|
||||
video_location -= 512;
|
||||
*bm++ = *video_location++;
|
||||
x_offset++;
|
||||
}
|
||||
}
|
||||
|
||||
if (from_y == to_y)
|
||||
// done - scanline updated partially
|
||||
from_x = to_x;
|
||||
else
|
||||
{
|
||||
from_y += 1;
|
||||
m_rendering_gfx_y_offset = (m_rendering_gfx_y_offset + 1) & 0x1ff;
|
||||
from_x = screen.left();
|
||||
to_display(screen, from_x, from_y);
|
||||
}
|
||||
}
|
||||
return m_regs[BORDER];
|
||||
}
|
||||
|
||||
/*
|
||||
Layered as:
|
||||
+ Border
|
||||
+ Border - already updated with screen_update_spectrum()
|
||||
+ Graphics
|
||||
+ Sprites 0
|
||||
+ Tiles 0
|
||||
@ -291,70 +120,135 @@ Layered as:
|
||||
+ Tiles 1
|
||||
+ Sprites 2
|
||||
*/
|
||||
void tsconf_state::spectrum_UpdateScreenBitmap(bool eof)
|
||||
void tsconf_state::spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
rectangle screen = get_screen_area();
|
||||
unsigned int from_x = m_previous_screen_x;
|
||||
unsigned int from_y = m_previous_screen_y;
|
||||
|
||||
spectrum_UpdateZxScreenBitmap();
|
||||
if (!BIT(m_regs[V_CONFIG], 5) && VM != VM_ZX)
|
||||
if (!BIT(m_regs[V_CONFIG], 5))
|
||||
{
|
||||
to_display(screen, from_x, from_y);
|
||||
if (VM == VM_TXT)
|
||||
tsconf_UpdateTxtBitmap(from_x, from_y);
|
||||
if (VM == VM_ZX)
|
||||
tsconf_UpdateZxScreenBitmap(screen, bitmap, cliprect);
|
||||
else if (VM == VM_TXT)
|
||||
tsconf_UpdateTxtBitmap(bitmap, cliprect);
|
||||
else
|
||||
tsconf_UpdateGfxBitmap(from_x, from_y);
|
||||
tsconf_UpdateGfxBitmap(bitmap, cliprect);
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap.fill(get_border_color(), cliprect);
|
||||
}
|
||||
|
||||
if (!BIT(m_regs[V_CONFIG], 4))
|
||||
{
|
||||
if (m_screen->vpos() == m_previous_tsu_vpos)
|
||||
return;
|
||||
screen.priority().fill(0, cliprect);
|
||||
if (BIT(m_regs[TS_CONFIG], 5))
|
||||
m_ts_tilemap[TM_TILES0]->draw(screen, bitmap, cliprect,
|
||||
BIT(m_regs[TS_CONFIG], 2) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 1);
|
||||
|
||||
bool draw = false;
|
||||
s16 y = m_screen->vpos() - screen.top();
|
||||
if (m_screen->vpos() == screen.bottom())
|
||||
if (BIT(m_regs[TS_CONFIG], 6))
|
||||
m_ts_tilemap[TM_TILES1]->draw(screen, bitmap, cliprect,
|
||||
BIT(m_regs[TS_CONFIG], 3) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 2);
|
||||
|
||||
if (BIT(m_regs[TS_CONFIG], 7))
|
||||
{
|
||||
m_previous_tsu_vpos = screen.top();
|
||||
screen.min_y = m_previous_tsu_vpos;
|
||||
draw = true;
|
||||
}
|
||||
else if (y >= 0 && y < screen.height())
|
||||
{
|
||||
// Update unrendered above excluding current line.
|
||||
screen.sety(m_previous_tsu_vpos, m_screen->vpos() - 1);
|
||||
// Too expencive to draw every line. Batch 8+ for now.
|
||||
draw = screen.height() > 7;
|
||||
if (!draw && (screen.bottom() + 1) == get_screen_area().bottom())
|
||||
{
|
||||
screen.max_y++;
|
||||
draw = true;
|
||||
}
|
||||
if (draw)
|
||||
m_previous_tsu_vpos = m_screen->vpos();
|
||||
}
|
||||
|
||||
if (draw)
|
||||
{
|
||||
m_screen->priority().fill(0, screen);
|
||||
if (BIT(m_regs[TS_CONFIG], 5))
|
||||
m_ts_tilemap[TM_TILES0]->draw(*m_screen, m_screen->curbitmap().as_ind16(), screen,
|
||||
BIT(m_regs[TS_CONFIG], 2) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 1);
|
||||
|
||||
if (BIT(m_regs[TS_CONFIG], 6))
|
||||
m_ts_tilemap[TM_TILES1]->draw(*m_screen, m_screen->curbitmap().as_ind16(), screen,
|
||||
BIT(m_regs[TS_CONFIG], 3) ? TILEMAP_DRAW_ALL_CATEGORIES : TILEMAP_DRAW_CATEGORY(1), 2);
|
||||
|
||||
if (BIT(m_regs[TS_CONFIG], 7))
|
||||
draw_sprites(screen);
|
||||
// draw_sprites(screen, bitmap, cliprect);
|
||||
// Avoid frequent expensive updates for now. Currently once per frame
|
||||
if (cliprect.bottom() == get_screen_area().bottom() && cliprect.right() == get_screen_area().right())
|
||||
draw_sprites(screen, bitmap, get_screen_area());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::spectrum_UpdateBorderBitmap()
|
||||
void tsconf_state::tsconf_UpdateZxScreenBitmap(screen_device &screen_d, bitmap_ind16 &bitmap, const rectangle &screen)
|
||||
{
|
||||
spectrum_UpdateScreenBitmap();
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
u8 *screen_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE]);
|
||||
u8 *attrs_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE]) + 0x1800;
|
||||
bool invert_attrs = u64(screen_d.frame_number() / m_frame_invert_count) & 1;
|
||||
for (u16 vpos = screen.top(); vpos <= screen.bottom(); vpos++)
|
||||
{
|
||||
u16 hpos = screen.left();
|
||||
u16 x = hpos - get_screen_area().left();
|
||||
u16 y = vpos - get_screen_area().top();
|
||||
u8 *scr = &screen_location[((y & 7) << 8) | ((y & 0x38) << 2) | ((y & 0xc0) << 5) | (x >> 3)];
|
||||
u8 *attr = &attrs_location[((y & 0xf8) << 2) | (x >> 3)];
|
||||
u16 *pix = &(bitmap.pix(vpos, hpos));
|
||||
while (hpos <= screen.right())
|
||||
{
|
||||
u16 ink = pal_offset | ((*attr >> 3) & 0x08) | (*attr & 0x07);
|
||||
u16 pap = pal_offset | ((*attr >> 3) & 0x0f);
|
||||
u8 pix8 = (invert_attrs && (*attr & 0x80)) ? ~*scr : *scr;
|
||||
|
||||
for (u8 b = 0x80 >> (x & 0x07); b != 0 && hpos <= screen.right(); b >>= 1, x++, hpos++)
|
||||
*pix++ = (pix8 & b) ? ink : pap;
|
||||
scr++;
|
||||
attr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_UpdateTxtBitmap(bitmap_ind16 &bitmap, const rectangle &screen)
|
||||
{
|
||||
u8 *font_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE] ^ 0x01);
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
for (u16 vpos = screen.top(); vpos <= screen.bottom(); vpos++)
|
||||
{
|
||||
u16 hpos = screen.left();
|
||||
u16 x = hpos - get_screen_area().left();
|
||||
u16 y = vpos - get_screen_area().top();
|
||||
u16 y_offset = (OFFS_512(G_Y_OFFS_L) + y) & 0x1ff;
|
||||
|
||||
// TODO? u16 x_offset = OFFS_512(G_X_OFFS_L);
|
||||
u8 *text_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE]) + (y_offset / 8 * 256 + x / 8);
|
||||
u16 *pix = &(bitmap.pix(vpos, hpos));
|
||||
while (hpos <= screen.right())
|
||||
{
|
||||
u8 font_color = *(text_location + 128) & 0x0f;
|
||||
u8 bg_color = (*(text_location + 128) & 0xf0) >> 4;
|
||||
u8 char_x = *(font_location + (*text_location * 8) + (y_offset % 8));
|
||||
for (u8 b = 0x80 >> (x & 0x07); b != 0 && hpos <= screen.right(); b >>= 1, x++, hpos++)
|
||||
*pix++ = pal_offset | ((char_x & b) ? font_color : bg_color);
|
||||
text_location++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_UpdateGfxBitmap(bitmap_ind16 &bitmap, const rectangle &screen)
|
||||
{
|
||||
u8 pal_offset = m_regs[PAL_SEL] << 4;
|
||||
for (u16 vpos = screen.top(); vpos <= screen.bottom(); vpos++)
|
||||
{
|
||||
u16 y_offset = (0x200 + OFFS_512(G_Y_OFFS_L) + m_gfx_y_frame_offset + (vpos - get_screen_area().top())) & 0x1ff;
|
||||
u16 x_offset = (OFFS_512(G_X_OFFS_L) + (screen.left() - get_screen_area().left())) & 0x1ff;
|
||||
u8 *video_location = m_ram->pointer() + PAGE4K(m_regs[V_PAGE]) + ((y_offset * 512 + x_offset) >> (2 - VM));
|
||||
u16 *bm = &(bitmap.pix(vpos, screen.left()));
|
||||
s16 width = screen.width();
|
||||
if (VM == VM_16C)
|
||||
{
|
||||
if (x_offset & 1)
|
||||
{
|
||||
*bm++ = pal_offset | (*video_location++ & 0x0f);
|
||||
x_offset++;
|
||||
width--;
|
||||
}
|
||||
for (; width > 0; width -= 2, x_offset += 2)
|
||||
{
|
||||
if (x_offset == 512)
|
||||
video_location -= 256;
|
||||
u8 pix = *video_location++;
|
||||
*bm++ = pal_offset | (pix >> 4);
|
||||
if (width != 1)
|
||||
*bm++ = pal_offset | (pix & 0x0f);
|
||||
}
|
||||
}
|
||||
else // VM_256C
|
||||
{
|
||||
for (; width > 0; width--, x_offset++)
|
||||
{
|
||||
if (x_offset == 512)
|
||||
video_location -= 512;
|
||||
*bm++ = *video_location++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -366,7 +260,7 @@ SFILE Reg.16 7 6 5 4 3 2 1 0
|
||||
4 R2L TNUM[7:0]
|
||||
5 R2H SPAL[7:4] TNUM[11:8]
|
||||
*/
|
||||
void tsconf_state::draw_sprites(const rectangle &cliprect)
|
||||
void tsconf_state::draw_sprites(screen_device &screen_d, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
rectangle screen = get_screen_area();
|
||||
|
||||
@ -415,7 +309,7 @@ void tsconf_state::draw_sprites(const rectangle &cliprect)
|
||||
u8 tile_col = (code % 64) + flipx * width8;
|
||||
for (auto ix = x; ix <= x + width8 * 8; ix = ix + 8)
|
||||
{
|
||||
m_gfxdecode->gfx(TM_SPRITES)->prio_transpen(m_screen->curbitmap().as_ind16(), cliprect, tmp_tile_oversized_to_code((tile_row % 64) * 64 + (tile_col % 64)), pal, flipx, flipy, ix, iy, m_screen->priority(), pmask, 0);
|
||||
m_gfxdecode->gfx(TM_SPRITES)->prio_transpen(bitmap, cliprect, tmp_tile_oversized_to_code((tile_row % 64) * 64 + (tile_col % 64)), pal, flipx, flipy, ix, iy, screen_d.priority(), pmask, 0);
|
||||
tile_col += flipx ? -1 : 1;
|
||||
}
|
||||
tile_row += flipy ? -1 : 1;
|
||||
@ -600,7 +494,7 @@ void tsconf_state::tsconf_port_xxaf_w(offs_t port, u8 data)
|
||||
{
|
||||
case BORDER:
|
||||
if (val_changed)
|
||||
spectrum_UpdateScreenBitmap();
|
||||
m_screen->update_now();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -751,13 +645,9 @@ u8 tsconf_state::tsconf_port_f7_r(offs_t offset)
|
||||
// BFF7
|
||||
u8 data = 0xff;
|
||||
if (m_port_f7_ext == PS2KEYBOARDS_LOG && m_port_f7_gluk_reg == 0xf0)
|
||||
{
|
||||
data = m_keyboard->read();
|
||||
}
|
||||
else if (m_port_f7_ext != DISABLED)
|
||||
{
|
||||
data = m_glukrs->read(m_port_f7_gluk_reg);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
@ -854,14 +744,12 @@ void tsconf_state::update_frame_timer()
|
||||
u16 vpos = OFFS_512(VS_INT_L);
|
||||
u16 hpos = m_regs[HS_INT];
|
||||
if (hpos > 0 && vpos <= 319 && hpos <= 223)
|
||||
{
|
||||
// Only if not overlapping with scanline. Otherwise we need to prioritize.
|
||||
m_frame_irq_timer->adjust(m_screen->time_until_pos(vpos, hpos << 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_frame_irq_timer->adjust(attotime::never);
|
||||
}
|
||||
|
||||
m_gfx_y_frame_offset = 0;
|
||||
}
|
||||
|
||||
INTERRUPT_GEN_MEMBER(tsconf_state::tsconf_vblank_interrupt)
|
||||
@ -875,7 +763,7 @@ void tsconf_state::dma_ready(int line)
|
||||
if (BIT(m_regs[INT_MASK], 4))
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(line, ASSERT_LINE, 0xfb);
|
||||
m_irq_off_timer->adjust(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))));
|
||||
timer_set(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))), TIMER_IRQ_OFF, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -888,12 +776,27 @@ void tsconf_state::device_timer(emu_timer &timer, device_timer_id id, int param)
|
||||
if (BIT(m_regs[INT_MASK], 0))
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, 0xff);
|
||||
m_irq_off_timer->adjust(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))));
|
||||
timer_set(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))), TIMER_IRQ_OFF, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TIMER_IRQ_SCANLINE:
|
||||
{
|
||||
u16 screen_vpos = m_screen->vpos();
|
||||
m_line_irq_timer->adjust(m_screen->time_until_pos(screen_vpos + 1));
|
||||
if (BIT(m_regs[INT_MASK], 1))
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, 0xfd);
|
||||
// Not quite precise. Scanline can't be skipped.
|
||||
timer_set(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))), TIMER_IRQ_OFF, 0);
|
||||
}
|
||||
if (BIT(m_regs[INT_MASK], 0) && OFFS_512(VS_INT_L) == screen_vpos && m_regs[HS_INT] == 0)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, 0xff);
|
||||
timer_set(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))), TIMER_IRQ_OFF, 0);
|
||||
}
|
||||
|
||||
m_screen->update_now();
|
||||
for (const auto &[reg, val] : m_scanline_delayed_regs_update)
|
||||
{
|
||||
m_regs[reg] = val;
|
||||
@ -901,7 +804,7 @@ void tsconf_state::device_timer(emu_timer &timer, device_timer_id id, int param)
|
||||
{
|
||||
case G_Y_OFFS_L:
|
||||
case G_Y_OFFS_H:
|
||||
m_rendering_gfx_y_offset = OFFS_512(G_Y_OFFS_L);
|
||||
m_gfx_y_frame_offset = get_screen_area().top() - m_screen->vpos();
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -909,21 +812,6 @@ void tsconf_state::device_timer(emu_timer &timer, device_timer_id id, int param)
|
||||
}
|
||||
}
|
||||
m_scanline_delayed_regs_update.clear();
|
||||
|
||||
u16 screen_vpos = m_screen->vpos();
|
||||
m_line_irq_timer->adjust(m_screen->time_until_pos(screen_vpos + 1));
|
||||
if (BIT(m_regs[INT_MASK], 1))
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, 0xfd);
|
||||
// Not quite precise. Scanline can't be skipped.
|
||||
m_irq_off_timer->adjust(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))));
|
||||
}
|
||||
if (BIT(m_regs[INT_MASK], 0) && OFFS_512(VS_INT_L) == screen_vpos && m_regs[HS_INT] == 0)
|
||||
{
|
||||
m_maincpu->set_input_line_and_vector(0, ASSERT_LINE, 0xff);
|
||||
m_irq_off_timer->adjust(m_maincpu->clocks_to_attotime(32 * (1 << (m_regs[SYS_CONFIG] & 0x03))));
|
||||
}
|
||||
spectrum_UpdateScreenBitmap();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -25,85 +25,23 @@
|
||||
void spectrum_state::video_start()
|
||||
{
|
||||
m_frame_invert_count = 16;
|
||||
m_frame_number = 0;
|
||||
m_flash_invert = 0;
|
||||
|
||||
m_previous_border_x = 0;
|
||||
m_previous_border_y = 0;
|
||||
m_screen->register_screen_bitmap(m_border_bitmap);
|
||||
m_previous_screen_x = 0;
|
||||
m_previous_screen_y = 0;
|
||||
m_screen->register_screen_bitmap(m_screen_bitmap);
|
||||
|
||||
m_screen_location = m_video_ram;
|
||||
|
||||
m_irq_off_timer = timer_alloc(TIMER_IRQ_OFF);
|
||||
|
||||
m_CyclesPerLine = SPEC_CYCLES_PER_LINE;
|
||||
m_scanline_timer = timer_alloc(TIMER_SCANLINE);
|
||||
m_scanline_timer->adjust(m_maincpu->cycles_to_attotime(m_CyclesPerLine));
|
||||
}
|
||||
|
||||
void spectrum_128_state::video_start()
|
||||
{
|
||||
m_frame_invert_count = 16;
|
||||
m_frame_number = 0;
|
||||
m_flash_invert = 0;
|
||||
|
||||
m_previous_border_x = 0;
|
||||
m_previous_border_y = 0;
|
||||
m_screen->register_screen_bitmap(m_border_bitmap);
|
||||
m_previous_screen_x = 0;
|
||||
m_previous_screen_y = 0;
|
||||
m_screen->register_screen_bitmap(m_screen_bitmap);
|
||||
|
||||
m_screen_location = m_ram->pointer() + (5 << 14);
|
||||
|
||||
m_irq_off_timer = timer_alloc(TIMER_IRQ_OFF);
|
||||
|
||||
m_CyclesPerLine = SPEC128_CYCLES_PER_LINE;
|
||||
m_scanline_timer = timer_alloc(TIMER_SCANLINE);
|
||||
m_scanline_timer->adjust(m_maincpu->cycles_to_attotime(m_CyclesPerLine));
|
||||
}
|
||||
|
||||
|
||||
/* return the color to be used inverting FLASHing colors if necessary */
|
||||
inline unsigned char spectrum_state::get_display_color (unsigned char color, int invert)
|
||||
{
|
||||
if (invert && (color & 0x80))
|
||||
return (color & 0xc0) + ((color & 0x38) >> 3) + ((color & 0x07) << 3);
|
||||
else
|
||||
return color;
|
||||
}
|
||||
|
||||
/* Code to change the FLASH status every 25 frames. Note this must be
|
||||
independent of frame skip etc. */
|
||||
WRITE_LINE_MEMBER(spectrum_state::screen_vblank_spectrum)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
spectrum_UpdateBorderBitmap();
|
||||
spectrum_UpdateScreenBitmap(true);
|
||||
|
||||
m_frame_number++;
|
||||
|
||||
if (m_frame_number >= m_frame_invert_count)
|
||||
{
|
||||
m_frame_number = 0;
|
||||
m_flash_invert = !m_flash_invert;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
Update the spectrum screen display.
|
||||
|
||||
The screen consists of 312 scanlines as follows:
|
||||
64 border lines (the last 48 are actual border lines; the others may be
|
||||
border lines or vertical retrace)
|
||||
border lines or vertical retrace)
|
||||
192 screen lines
|
||||
56 border lines
|
||||
|
||||
@ -121,72 +59,6 @@ WRITE_LINE_MEMBER(spectrum_state::screen_vblank_spectrum)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
inline void spectrum_state::spectrum_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color)
|
||||
{
|
||||
bitmap.pix(y, x) = (uint16_t)color;
|
||||
}
|
||||
|
||||
uint32_t spectrum_state::screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
static const rectangle rect(SPEC_LEFT_BORDER, SPEC_LEFT_BORDER + SPEC_DISPLAY_XSIZE - 1, SPEC_TOP_BORDER, SPEC_TOP_BORDER + SPEC_DISPLAY_YSIZE - 1);
|
||||
|
||||
if (m_border_bitmap.valid())
|
||||
copyscrollbitmap(bitmap, m_border_bitmap, 0, nullptr, 0, nullptr, cliprect);
|
||||
|
||||
spectrum_UpdateScreenBitmap();
|
||||
if (m_screen_bitmap.valid())
|
||||
copyscrollbitmap(bitmap, m_screen_bitmap, 0, nullptr, 0, nullptr, rect);
|
||||
|
||||
#if 0
|
||||
// note, don't update borders in here, this can time travel w/regards to other timers and may end up giving you
|
||||
// screen positions earlier than the last write handler gave you
|
||||
|
||||
/* for now do a full-refresh */
|
||||
int x, y, b, scrx, scry;
|
||||
unsigned short ink, pap;
|
||||
unsigned char *attr, *scr;
|
||||
// int full_refresh = 1;
|
||||
|
||||
scr=m_screen_location;
|
||||
|
||||
for (y=0; y<192; y++)
|
||||
{
|
||||
scrx=SPEC_LEFT_BORDER;
|
||||
scry=((y&7) * 8) + ((y&0x38)>>3) + (y&0xC0);
|
||||
attr=m_screen_location + ((scry>>3)*32) + 0x1800;
|
||||
|
||||
for (x=0;x<32;x++)
|
||||
{
|
||||
/* Get ink and paper colour with bright */
|
||||
if (m_flash_invert && (*attr & 0x80))
|
||||
{
|
||||
ink=((*attr)>>3) & 0x0f;
|
||||
pap=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
|
||||
}
|
||||
else
|
||||
{
|
||||
ink=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
|
||||
pap=((*attr)>>3) & 0x0f;
|
||||
}
|
||||
|
||||
for (b=0x80;b!=0;b>>=1)
|
||||
{
|
||||
if (*scr&b)
|
||||
spectrum_plot_pixel(bitmap,scrx++,SPEC_TOP_BORDER+scry,ink);
|
||||
else
|
||||
spectrum_plot_pixel(bitmap,scrx++,SPEC_TOP_BORDER+scry,pap);
|
||||
}
|
||||
|
||||
scr++;
|
||||
attr++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static constexpr rgb_t spectrum_pens[16] = {
|
||||
{ 0x00, 0x00, 0x00 },
|
||||
{ 0x00, 0x00, 0xbf },
|
||||
@ -205,111 +77,83 @@ static constexpr rgb_t spectrum_pens[16] = {
|
||||
{ 0xff, 0xff, 0x00 },
|
||||
{ 0xff, 0xff, 0xff }
|
||||
};
|
||||
|
||||
// Initialise the palette
|
||||
void spectrum_state::spectrum_palette(palette_device &palette) const
|
||||
{
|
||||
palette.set_pen_colors(0, spectrum_pens);
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_UpdateScreenBitmap(bool eof)
|
||||
rectangle spectrum_state::get_screen_area()
|
||||
{
|
||||
unsigned int x = m_screen->hpos();
|
||||
unsigned int y = m_screen->vpos();
|
||||
int width = m_screen_bitmap.width();
|
||||
int height = m_screen_bitmap.height();
|
||||
|
||||
|
||||
if ((m_previous_screen_x == x) && (m_previous_screen_y == y) && !eof)
|
||||
return;
|
||||
|
||||
if (m_screen_bitmap.valid())
|
||||
{
|
||||
//printf("update screen from %d,%d to %d,%d\n", m_previous_screen_x, m_previous_screen_y, x, y);
|
||||
|
||||
do
|
||||
{
|
||||
uint16_t scrx = m_previous_screen_x - SPEC_LEFT_BORDER;
|
||||
uint16_t scry = m_previous_screen_y - SPEC_TOP_BORDER;
|
||||
|
||||
if (scrx < SPEC_DISPLAY_XSIZE && scry < SPEC_DISPLAY_YSIZE)
|
||||
{
|
||||
// this can/must be optimised
|
||||
if ((scrx & 7) == 0) {
|
||||
uint16_t *bm = &m_screen_bitmap.pix(m_previous_screen_y, m_previous_screen_x);
|
||||
uint8_t attr = *(m_screen_location + ((scry & 0xF8) << 2) + (scrx >> 3) + 0x1800);
|
||||
uint8_t scr = *(m_screen_location + ((scry & 7) << 8) + ((scry & 0x38) << 2) + ((scry & 0xC0) << 5) + (scrx >> 3));
|
||||
uint16_t ink = (attr & 0x07) + ((attr >> 3) & 0x08);
|
||||
uint16_t pap = (attr >> 3) & 0x0f;
|
||||
|
||||
if (m_flash_invert && (attr & 0x80))
|
||||
scr = ~scr;
|
||||
|
||||
for (uint8_t b = 0x80; b != 0; b >>= 1)
|
||||
*bm++ = (scr & b) ? ink : pap;
|
||||
}
|
||||
}
|
||||
|
||||
m_previous_screen_x += 1;
|
||||
|
||||
if (m_previous_screen_x >= width)
|
||||
{
|
||||
m_previous_screen_x = 0;
|
||||
m_previous_screen_y += 1;
|
||||
|
||||
if (m_previous_screen_y >= height)
|
||||
{
|
||||
m_previous_screen_y = 0;
|
||||
}
|
||||
}
|
||||
} while (!((m_previous_screen_x == x) && (m_previous_screen_y == y)));
|
||||
|
||||
}
|
||||
// 256x192 screen position without border
|
||||
return rectangle{48, 48 + 255, 64, 64 + 191};
|
||||
}
|
||||
|
||||
u16 spectrum_state::get_border_color() {
|
||||
u8 spectrum_state::get_border_color(u16 hpos, u16 vpos)
|
||||
{
|
||||
//TODO snow effect
|
||||
return m_port_fe_data & 0x07;
|
||||
}
|
||||
|
||||
/* The code below is just a per-pixel 'partial update' for the border */
|
||||
|
||||
void spectrum_state::spectrum_UpdateBorderBitmap()
|
||||
u32 spectrum_state::screen_update_spectrum(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
unsigned int x = m_screen->hpos();
|
||||
unsigned int y = m_screen->vpos();
|
||||
int width = m_border_bitmap.width();
|
||||
int height = m_border_bitmap.height();
|
||||
|
||||
|
||||
if (m_border_bitmap.valid())
|
||||
{
|
||||
uint16_t border = get_border_color();
|
||||
|
||||
//printf("update border from %d,%d to %d,%d\n", m_previous_border_x, m_previous_border_y, x, y);
|
||||
|
||||
do
|
||||
rectangle scr = get_screen_area();
|
||||
rectangle vis = screen.visible_area();
|
||||
if (vis != scr) {
|
||||
rectangle bsides[4] = {
|
||||
rectangle(vis.left(), vis.right(), vis.top(), scr.top() - 1),
|
||||
rectangle(vis.left(), scr.left() - 1, scr.top(), scr.bottom()),
|
||||
rectangle(scr.right() + 1, vis.right(), scr.top(), scr.bottom()),
|
||||
rectangle(vis.left(), vis.right(), scr.bottom() + 1, vis.bottom())
|
||||
};
|
||||
for (auto i = 0; i < 4; i++)
|
||||
{
|
||||
m_border_bitmap.pix(m_previous_border_y, m_previous_border_x) = border;
|
||||
|
||||
m_previous_border_x += 1;
|
||||
|
||||
if (m_previous_border_x >= width)
|
||||
{
|
||||
m_previous_border_x = 0;
|
||||
m_previous_border_y += 1;
|
||||
|
||||
if (m_previous_border_y >= height)
|
||||
{
|
||||
m_previous_border_y = 0;
|
||||
}
|
||||
}
|
||||
rectangle border = bsides[i] & cliprect;
|
||||
if (!border.empty())
|
||||
spectrum_update_border(screen, bitmap, border);
|
||||
}
|
||||
while (!((m_previous_border_x == x) && (m_previous_border_y == y)));
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// no border bitmap allocated? fatalerror?
|
||||
}
|
||||
|
||||
scr &= cliprect;
|
||||
if (!scr.empty())
|
||||
spectrum_update_screen(screen, bitmap, scr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_update_border(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &border)
|
||||
{
|
||||
for (auto y = border.top(); y <= border.bottom(); y++)
|
||||
{
|
||||
u16 *pix = &(bitmap.pix(y, border.left()));
|
||||
for (auto x = border.left(); x <= border.right(); x++)
|
||||
*pix++ = get_border_color(y, x);
|
||||
}
|
||||
}
|
||||
|
||||
void spectrum_state::spectrum_update_screen(screen_device &screen_d, bitmap_ind16 &bitmap, const rectangle &screen)
|
||||
{
|
||||
u8 *attrs_location = m_screen_location + 0x1800;
|
||||
bool invert_attrs = u64(screen_d.frame_number() / m_frame_invert_count) & 1;
|
||||
for (u16 vpos = screen.top(); vpos <= screen.bottom(); vpos++)
|
||||
{
|
||||
u16 hpos = screen.left();
|
||||
u16 x = hpos - get_screen_area().left();
|
||||
u16 y = vpos - get_screen_area().top();
|
||||
u8 *scr = &m_screen_location[((y & 7) << 8) | ((y & 0x38) << 2) | ((y & 0xc0) << 5) | (x >> 3)];
|
||||
u8 *attr = &attrs_location[((y & 0xf8) << 2) | (x >> 3)];
|
||||
u16 *pix = &(bitmap.pix(vpos, hpos));
|
||||
while (hpos <= screen.right())
|
||||
{
|
||||
u16 ink = ((*attr >> 3) & 0x08) | (*attr & 0x07);
|
||||
u16 pap = (*attr >> 3) & 0x0f;
|
||||
u8 pix8 = (invert_attrs && (*attr & 0x80)) ? ~*scr : *scr;
|
||||
|
||||
for (u8 b = 0x80 >> (x & 0x07); b != 0 && hpos <= screen.right(); b >>= 1, x++, hpos++)
|
||||
*pix++ = (pix8 & b) ? ink : pap;
|
||||
scr++;
|
||||
attr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -22,44 +22,15 @@
|
||||
|
||||
inline void tc2048_state::spectrum_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color)
|
||||
{
|
||||
bitmap.pix(y, x) = (uint16_t)color;
|
||||
rectangle screen = m_screen->visible_area();
|
||||
bitmap.pix(screen.top() + y, screen.left() + x) = (uint16_t)color;
|
||||
}
|
||||
|
||||
/* Update FLASH status for ts2068. Assumes flash update every 1/2s. */
|
||||
void ts2068_state::video_start()
|
||||
{
|
||||
m_frame_invert_count = 30;
|
||||
|
||||
m_frame_number = 0;
|
||||
m_flash_invert = 0;
|
||||
|
||||
m_previous_border_x = 0;
|
||||
m_previous_border_y = 0;
|
||||
m_screen->register_screen_bitmap(m_border_bitmap);
|
||||
m_previous_screen_x = 0;
|
||||
m_previous_screen_y = 0;
|
||||
m_screen->register_screen_bitmap(m_screen_bitmap);
|
||||
|
||||
m_screen_location = m_video_ram;
|
||||
|
||||
m_irq_off_timer = timer_alloc(TIMER_IRQ_OFF);
|
||||
}
|
||||
|
||||
WRITE_LINE_MEMBER(tc2048_state::screen_vblank_timex)
|
||||
{
|
||||
// rising edge
|
||||
if (state)
|
||||
{
|
||||
spectrum_UpdateBorderBitmap();
|
||||
|
||||
m_frame_number++;
|
||||
|
||||
if (m_frame_number >= m_frame_invert_count)
|
||||
{
|
||||
m_frame_number = 0;
|
||||
m_flash_invert = !m_flash_invert;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -91,6 +62,7 @@ void tc2048_state::hires_scanline(bitmap_ind16 &bitmap, int y, int borderlines)
|
||||
int x,b,scrx,scry;
|
||||
unsigned short ink,pap;
|
||||
unsigned char *attr, *scr;
|
||||
bool invert_attrs = u64(m_screen->frame_number() / m_frame_invert_count) & 1;
|
||||
|
||||
scrx=TS2068_LEFT_BORDER;
|
||||
scry=((y&7) * 8) + ((y&0x38)>>3) + (y&0xC0);
|
||||
@ -101,7 +73,7 @@ void tc2048_state::hires_scanline(bitmap_ind16 &bitmap, int y, int borderlines)
|
||||
for (x=0;x<32;x++)
|
||||
{
|
||||
/* Get ink and paper colour with bright */
|
||||
if (m_flash_invert && (*attr & 0x80))
|
||||
if (invert_attrs && (*attr & 0x80))
|
||||
{
|
||||
ink=((*attr)>>3) & 0x0f;
|
||||
pap=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
|
||||
@ -116,13 +88,13 @@ void tc2048_state::hires_scanline(bitmap_ind16 &bitmap, int y, int borderlines)
|
||||
{
|
||||
if (*scr&b)
|
||||
{
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,ink);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,ink);
|
||||
}
|
||||
else
|
||||
{
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,pap);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,pap);
|
||||
}
|
||||
}
|
||||
scr++;
|
||||
@ -147,18 +119,18 @@ void tc2048_state::_64col_scanline(bitmap_ind16 &bitmap, int y, int borderlines,
|
||||
for (b=0x80;b!=0;b>>=1)
|
||||
{
|
||||
if (*scr1&b)
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,inkcolor);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,inkcolor);
|
||||
else
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,7-inkcolor);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,7-inkcolor);
|
||||
}
|
||||
scr1++;
|
||||
|
||||
for (b=0x80;b!=0;b>>=1)
|
||||
{
|
||||
if (*scr2&b)
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,inkcolor);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,inkcolor);
|
||||
else
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,7-inkcolor);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,7-inkcolor);
|
||||
}
|
||||
scr2++;
|
||||
}
|
||||
@ -170,6 +142,7 @@ void tc2048_state::lores_scanline(bitmap_ind16 &bitmap, int y, int borderlines,
|
||||
int x,b,scrx,scry;
|
||||
unsigned short ink,pap;
|
||||
unsigned char *attr, *scr;
|
||||
bool invert_attrs = u64(m_screen->frame_number() / m_frame_invert_count) & 1;
|
||||
|
||||
scrx=TS2068_LEFT_BORDER;
|
||||
scry=((y&7) * 8) + ((y&0x38)>>3) + (y&0xC0);
|
||||
@ -180,7 +153,7 @@ void tc2048_state::lores_scanline(bitmap_ind16 &bitmap, int y, int borderlines,
|
||||
for (x=0;x<32;x++)
|
||||
{
|
||||
/* Get ink and paper colour with bright */
|
||||
if (m_flash_invert && (*attr & 0x80))
|
||||
if (invert_attrs && (*attr & 0x80))
|
||||
{
|
||||
ink=((*attr)>>3) & 0x0f;
|
||||
pap=((*attr) & 0x07) + (((*attr)>>3) & 0x08);
|
||||
@ -195,13 +168,13 @@ void tc2048_state::lores_scanline(bitmap_ind16 &bitmap, int y, int borderlines,
|
||||
{
|
||||
if (*scr&b)
|
||||
{
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,ink);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,ink);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,ink);
|
||||
}
|
||||
else
|
||||
{
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
|
||||
spectrum_plot_pixel(bitmap,scrx++,scry+borderlines,pap);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,pap);
|
||||
spectrum_plot_pixel(bitmap, scrx++,scry+borderlines,pap);
|
||||
}
|
||||
}
|
||||
scr++;
|
||||
@ -209,76 +182,35 @@ void tc2048_state::lores_scanline(bitmap_ind16 &bitmap, int y, int borderlines,
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t ts2068_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
void tc2048_state::spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* for now TS2068 will do a full-refresh */
|
||||
int count;
|
||||
|
||||
if (m_border_bitmap.valid())
|
||||
copyscrollbitmap(bitmap, m_border_bitmap, 0, nullptr, 0, nullptr, cliprect);
|
||||
/* for now TC2048/TS2068 will do a full-refresh */
|
||||
if (cliprect.bottom() != get_screen_area().bottom() || cliprect.right() != get_screen_area().right())
|
||||
return;
|
||||
|
||||
if ((m_port_ff_data & 7) == 6)
|
||||
{
|
||||
/* 64 Column mode */
|
||||
unsigned short inkcolor = (m_port_ff_data & 0x38) >> 3;
|
||||
for (count = 0; count < 192; count++)
|
||||
for (auto count = 0; count < 192; count++)
|
||||
_64col_scanline(bitmap, count, TS2068_TOP_BORDER, inkcolor);
|
||||
}
|
||||
else if ((m_port_ff_data & 7) == 2)
|
||||
{
|
||||
/* Extended Color mode */
|
||||
for (count = 0; count < 192; count++)
|
||||
for (auto count = 0; count < 192; count++)
|
||||
hires_scanline(bitmap, count, TS2068_TOP_BORDER);
|
||||
}
|
||||
else if ((m_port_ff_data & 7) == 1)
|
||||
{
|
||||
/* Screen 6000-7aff */
|
||||
for (count = 0; count < 192; count++)
|
||||
for (auto count = 0; count < 192; count++)
|
||||
lores_scanline(bitmap, count, TS2068_TOP_BORDER, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Screen 4000-5aff */
|
||||
for (count = 0; count < 192; count++)
|
||||
for (auto count = 0; count < 192; count++)
|
||||
lores_scanline(bitmap, count, TS2068_TOP_BORDER, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t tc2048_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
/* for now TC2048 will do a full-refresh */
|
||||
int count;
|
||||
|
||||
if (m_border_bitmap.valid())
|
||||
copyscrollbitmap(bitmap, m_border_bitmap, 0, nullptr, 0, nullptr, cliprect);
|
||||
|
||||
if ((m_port_ff_data & 7) == 6)
|
||||
{
|
||||
/* 64 Column mode */
|
||||
unsigned short inkcolor = (m_port_ff_data & 0x38) >> 3;
|
||||
for (count = 0; count < 192; count++)
|
||||
_64col_scanline(bitmap, count, SPEC_TOP_BORDER, inkcolor);
|
||||
}
|
||||
else if ((m_port_ff_data & 7) == 2)
|
||||
{
|
||||
/* Extended Color mode */
|
||||
for (count = 0; count < 192; count++)
|
||||
hires_scanline(bitmap, count, SPEC_TOP_BORDER);
|
||||
}
|
||||
else if ((m_port_ff_data & 7) == 1)
|
||||
{
|
||||
/* Screen 6000-7aff */
|
||||
for (count = 0; count < 192; count++)
|
||||
lores_scanline(bitmap, count, SPEC_TOP_BORDER, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Screen 4000-5aff */
|
||||
for (count = 0; count < 192; count++)
|
||||
lores_scanline(bitmap, count, SPEC_TOP_BORDER, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user