sinclair/atm.cpp: Got ATM Turbo 2 mostly working. (#10149)

Implemented memory banking, video modes, palette and COVOX.

Machines promoted to working
--------------------------
MicroART ATM-Turbo 2
This commit is contained in:
holub 2022-08-04 11:41:30 -04:00 committed by GitHub
parent 7c98beb5f4
commit c92c0c967f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 419 additions and 143 deletions

View File

@ -4942,28 +4942,6 @@ if (MACHINES["NS32082"]~=null) then
}
end
---------------------------------------------------
--
--@src/devices/machine/tsconfdma.h,MACHINES["TSCONF_DMA"] = true
---------------------------------------------------
if (MACHINES["TSCONF_DMA"]~=null) then
files {
MAME_DIR .. "src/devices/machine/tsconfdma.cpp",
MAME_DIR .. "src/devices/machine/tsconfdma.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/glukrs.h,MACHINES["GLUKRS"] = true
---------------------------------------------------
if (MACHINES["GLUKRS"]~=null) then
files {
MAME_DIR .. "src/devices/machine/glukrs.cpp",
MAME_DIR .. "src/devices/machine/glukrs.h",
}
end
---------------------------------------------------
--
--@src/devices/machine/bitmap_printer.h,MACHINES["BITMAP_PRINTER"] = true

View File

@ -4,7 +4,17 @@
MicroART ATM (clone of Spectrum)
Not working because of banking issues.
NOTES:
Current implementation based on ATM Turbo 2+. If anybody wants to validate ATM1, existing
code must be moved to atmtb2_state not modified.
TODO:
* ports read
* ATM2+ (compare to ATM2) has only 1M RAM vs 512K
* Mem masks are hardcoded to 1M RAM, 64K ROM
* CMOS
* better handling of SHADOW ports
* validate screen timings
*******************************************************************************************/
@ -13,118 +23,379 @@ Not working because of banking issues.
#include "specpls3.h"
#include "beta_m.h"
#include "bus/centronics/ctronics.h"
#include "sound/ay8910.h"
namespace {
#define LOG_MEM (1U << 1)
#define LOG_VIDEO (1U << 2)
#define LOG_WARN (1U << 3)
#define VERBOSE ( /*LOG_MEM | LOG_VIDEO |*/ LOG_WARN )
#include "logmacro.h"
#define LOGMEM(...) LOGMASKED(LOG_MEM, __VA_ARGS__)
#define LOGVIDEO(...) LOGMASKED(LOG_VIDEO, __VA_ARGS__)
#define LOGWARN(...) LOGMASKED(LOG_WARN, __VA_ARGS__)
static constexpr u8 RAM_MASK = 0x40;
static constexpr u8 DOS7FFD_MASK = 0x80;
class atm_state : public spectrum_128_state
{
public:
atm_state(const machine_config &mconfig, device_type type, const char *tag)
: spectrum_128_state(mconfig, type, tag)
, m_bank1(*this, "bank1")
, m_bank2(*this, "bank2")
, m_bank3(*this, "bank3")
, m_bank4(*this, "bank4")
, m_bank_view0(*this, "bank_view0")
, m_bank_view1(*this, "bank_view1")
, m_bank_view2(*this, "bank_view2")
, m_bank_view3(*this, "bank_view3")
, m_bank_rom(*this, "bank_rom%u", 0U)
, m_char_rom(*this, "charrom")
, m_beta(*this, BETA_DISK_TAG)
, m_centronics(*this, "centronics")
, m_palette(*this, "palette")
{ }
void atm(machine_config &config);
void atmtb2(machine_config &config);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
void machine_start() override;
void machine_reset() override;
void video_start() override;
rectangle get_screen_area() override;
u8 get_border_color(u16 hpos, u16 vpos) override;
void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
private:
void atm_port_7ffd_w(uint8_t data);
uint8_t beta_neutral_r(offs_t offset);
uint8_t beta_enable_r(offs_t offset);
uint8_t beta_disable_r(offs_t offset);
u8 beta_neutral_r(offs_t offset);
u8 beta_enable_r(offs_t offset);
u8 beta_disable_r(offs_t offset);
void atm_ula_w(offs_t offset, u8 data);
void atm_port_ffff_w(offs_t offset, u8 data);
void atm_port_ff77_w(offs_t offset, u8 data);
void atm_port_fff7_w(offs_t offset, u8 data);
void atm_port_7ffd_w(offs_t offset, u8 data);
void atm_io(address_map &map);
void atm_mem(address_map &map);
void atm_switch(address_map &map);
void atm_update_video_mode();
void atm_update_screen_lo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void atm_update_screen_hi(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void atm_update_screen_tx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
void atm_update_memory();
required_memory_bank m_bank1;
required_memory_bank m_bank2;
required_memory_bank m_bank3;
required_memory_bank m_bank4;
required_device<beta_disk_device> m_beta;
memory_view m_bank_view0;
memory_view m_bank_view1;
memory_view m_bank_view2;
memory_view m_bank_view3;
required_memory_bank_array<4> m_bank_rom;
optional_region_ptr<u8> m_char_rom; // required for ATM2, absent in ATM1
memory_access<16, 0, 0, ENDIANNESS_LITTLE>::specific m_program;
address_space *m_program;
uint8_t *m_p_ram;
uint16_t m_rom_selection;
required_device<beta_disk_device> m_beta;
required_device<centronics_device> m_centronics;
required_device<device_palette_interface> m_palette;
bool is_shadow_active() { return m_beta->is_active(); }
u8 &pen_page(u8 bank) { return m_pages_map[BIT(m_port_7ffd_data, 4)][bank]; }
bool m_pen; // PEN - extended memory manager
bool m_cpm;
u8 m_pages_map[2][4]; // map: 0,1
bool m_pen2; // palette selector
u8 m_rg = 0b011; // 0:320x200lo, 2:640:200hi, 3:256x192zx, 6:80x25txt
u8 m_br3;
};
void atm_state::atm_update_memory()
{
uint8_t *messram = m_ram->pointer();
using views_link = std::reference_wrapper<memory_view>;
views_link views[] = { m_bank_view0, m_bank_view1, m_bank_view2, m_bank_view3 };
LOGMEM("7FFD.%d = %X:", BIT(m_port_7ffd_data, 4), (m_port_7ffd_data & 0x07));
for (auto bank = 0; bank < 4 ; bank++)
{
u8 page = pen_page(bank);
if (!m_pen)
page = 3;
m_screen_location = messram + ((m_port_7ffd_data & 8) ? (7<<14) : (5<<14));
m_bank4->set_base(messram + ((m_port_7ffd_data & 0x07) * 0x4000));
if (m_beta->started() && m_beta->is_active() && !( m_port_7ffd_data & 0x10 ) )
m_rom_selection = 3;
else
/* ROM switching */
m_rom_selection = BIT(m_port_7ffd_data, 4) ;
/* rom 0 is 128K rom, rom 1 is 48 BASIC */
m_bank1->set_base(&m_p_ram[0x10000 + (m_rom_selection<<14)]);
if (page & RAM_MASK)
{
if (page & DOS7FFD_MASK)
page = (page & 0xf8) | (m_port_7ffd_data & 0x07);
page = page & 0x3f; // TODO size dependent
m_bank_ram[bank]->set_entry(page);
views[bank].get().disable();
LOGMEM(" RA(%X>%X)", m_bank_ram[bank]->entry(), page);
}
else
{
if ((page & DOS7FFD_MASK) && !BIT(page, 1))
page = (page & ~1) | is_shadow_active();
page = page & 0x03; // TODO size dependent
m_bank_rom[bank]->set_entry(page);
views[bank].get().select(0);
LOGMEM(" RO(%X>%X)", m_bank_rom[bank]->entry(), page);
}
}
LOGMEM("\n");
}
void atm_state::atm_port_7ffd_w(uint8_t data)
void atm_state::atm_ula_w(offs_t offset, u8 data)
{
/* disable paging */
if (m_port_7ffd_data & 0x20)
m_br3 = ~offset & 0x08;
spectrum_128_state::spectrum_ula_w(offset, data);
}
void atm_state::atm_port_ffff_w(offs_t offset, u8 data)
{
if(!is_shadow_active())
return;
/* store new state */
m_port_7ffd_data = data;
if (m_pen2)
{
m_beta->param_w(data);
}
else
{
// Must read current ULA value (which is doesn't work now) from the BUS.
// Good enough as non-border case is too complicated and possibly no software uses it.
u8 pen = get_border_color(m_screen->hpos(), m_screen->vpos());
m_palette->set_pen_color(pen,
(BIT(~data, 1) * 0xaa) | (BIT(~data, 6) * 0x55),
(BIT(~data, 4) * 0xaa) | (BIT(~data, 7) * 0x55),
(BIT(~data, 0) * 0xaa) | (BIT(~data, 5) * 0x55));
}
}
/* update memory */
void atm_state::atm_port_7ffd_w(offs_t offset, u8 data)
{
/* disable paging */
if (BIT(m_port_7ffd_data, 5))
return;
m_port_7ffd_data = data;
atm_update_memory();
m_screen->update_now();
m_screen_location = m_ram->pointer() + ((BIT(m_port_7ffd_data, 3) ? 7 : 5) << 14);
}
void atm_state::atm_port_ff77_w(offs_t offset, u8 data)
{
if (!is_shadow_active())
return;
m_pen = BIT(offset, 8);
m_cpm = BIT(offset, 9);
m_pen2 = BIT(offset, 14);
LOGMASKED(LOG_VIDEO | LOG_MEM, "PEN %s, CPM %s, PEN2 %s\n", m_pen ? "on" : "off", m_cpm ? "off" : "on", m_pen2 ? "off" : "on");
atm_update_memory();
m_maincpu->set_clock(X1_128_SINCLAIR / 10 * (1 << BIT(data, 3))); // 0 - 3.5MHz, 1 - 7MHz
int rg = data & 0x07;
if ( m_rg ^ rg )
{
m_rg = rg;
atm_update_video_mode();
}
}
void atm_state::atm_port_fff7_w(offs_t offset, u8 data)
{
if (!is_shadow_active())
return;
u8 bank = offset >> 14;
u8 page = (data & 0xc0) | (~data & 0x3f);
LOGMEM("PEN%s.%s = %X %s%d: %02X\n", (page | DOS7FFD_MASK) ? "+" : "!", BIT(m_port_7ffd_data, 4), data, (page & RAM_MASK) ? "RAM" : "ROM", bank, page & 0x3f);
pen_page(bank) = page;
atm_update_memory();
}
uint8_t atm_state::beta_neutral_r(offs_t offset)
rectangle atm_state::get_screen_area()
{
return m_program->read_byte(offset);
switch (m_rg)
{
case 0b110: // 80x25txt
case 0b010: // 640x200
return rectangle { 208, 208 + 639, 76, 76 + 199 };
break;
case 0b000: // 320x200
return rectangle { 104, 104 + 319, 76, 76 + 199 };
break;
case 0b011: // 256x192
default:
return rectangle { 136, 136 + 255, 80, 80 + 191 };
break;
}
}
uint8_t atm_state::beta_enable_r(offs_t offset)
u8 atm_state::get_border_color(u16 hpos, u16 vpos)
{
if (m_rom_selection == 1) {
m_rom_selection = 3;
if (m_beta->started()) {
m_beta->enable();
m_bank1->set_base(&m_p_ram[0x18000]);
return m_br3 | (m_port_fe_data & 0x07);
}
void atm_state::atm_update_video_mode()
{
bool zx_scale = BIT(m_rg, 0);
bool double_width = BIT(m_rg, 1) && !zx_scale;
u8 border_x = (40 - (32 * !zx_scale)) << double_width;
u8 border_y = (40 - (4 * !zx_scale));
rectangle scr = get_screen_area();
m_screen->configure(448 << double_width, 312, {scr.left() - border_x, scr.right() + border_x, scr.top() - border_y, scr.bottom() + border_y}, m_screen->frame_period().as_attoseconds());
LOGVIDEO("Video mode: %d\n", m_rg);
//spectrum_palette(m_palette);
}
void atm_state::spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
switch (m_rg)
{
case 0b110: // txt
atm_update_screen_tx(screen, bitmap, cliprect);
break;
case 0b010: // 640x200
atm_update_screen_hi(screen, bitmap, cliprect);
break;
case 0b000: // 320x200
atm_update_screen_lo(screen, bitmap, cliprect);
break;
case 0b011: // 256x192
default: // + unsupported
spectrum_128_state::spectrum_update_screen(screen, bitmap, cliprect);
break;
}
}
void atm_state::atm_update_screen_lo(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
{
u16 y = vpos - get_screen_area().top();
for (u16 hpos = cliprect.left(); hpos <= cliprect.right(); hpos++)
{
u16 x = hpos - get_screen_area().left();
u8 *scr = m_screen_location;
if (!BIT(x, 1)) scr -= 4 << 14;
if (BIT(x, 2)) scr += 0x2000;
scr += (x >> 3) + y * 40;
u8 pix_pair = *scr;
pix_pair = x & 1
? (((pix_pair & 0x80) >> 1) | (pix_pair & 0x38)) >> 3
: ((pix_pair & 0x40) >> 3) | (pix_pair & 0x07);
bitmap.pix(vpos, hpos) = pix_pair;
}
}
return m_program->read_byte(offset + 0x3d00);
}
uint8_t atm_state::beta_disable_r(offs_t offset)
void atm_state::atm_update_screen_hi(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
if (m_beta->started() && m_beta->is_active()) {
m_rom_selection = BIT(m_port_7ffd_data, 4);
m_beta->disable();
m_bank1->set_base(&m_p_ram[0x10000 + (m_rom_selection<<14)]);
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
{
u16 y = vpos - get_screen_area().top();
for (u16 hpos = cliprect.left() & 0xfff8; hpos <= cliprect.right();)
{
u16 x = hpos - get_screen_area().left();
u8 *scr = m_screen_location + (x >> 4) + y * 40;
if (BIT(x, 3)) scr += 0x2000;
u8 attr = *(scr - (4 << 14));
u8 fg = ((attr & 0x40) >> 3) | (attr & 0x07);
u8 bg = (((attr & 0x80) >> 1) | (attr & 0x38)) >> 3;
u8 chunk = *scr;
for (u8 i = 0x80; i; i >>= 1)
{
bitmap.pix(vpos, hpos++) = (chunk & i) ? fg : bg;
}
}
}
return m_program->read_byte(offset + 0x4000);
}
void atm_state::atm_update_screen_tx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
{
u16 y = vpos - get_screen_area().top();
for (u16 hpos = cliprect.left() & 0xfff8; hpos <= cliprect.right();)
{
u16 x = hpos - get_screen_area().left();
u8 *symb_location = m_screen_location + 0x1c0 + (x >> 4) + ((y >> 3) * 64);
u8 *attr_location = symb_location - (4 << 14) + BIT(x, 3);
if (BIT(x, 3))
symb_location += 0x2000;
else
attr_location += 0x2000;
u8 attr = *attr_location;
u8 fg = ((attr & 0x40) >> 3) | (attr & 0x07);
u8 bg = (((attr & 0x80) >> 1) | (attr & 0x38)) >> 3;
u8 chunk = *(m_char_rom + (*symb_location << 3) + (y & 0x07));
for (u8 i = 0x80; i; i >>= 1)
{
bitmap.pix(vpos, hpos++) = (chunk & i) ? fg : bg;
}
}
}
}
u8 atm_state::beta_neutral_r(offs_t offset)
{
return m_program.read_byte(offset);
}
u8 atm_state::beta_enable_r(offs_t offset)
{
if (!machine().side_effects_disabled()) {
u8 page = pen_page(0);
if (!(page & RAM_MASK) && !is_shadow_active()) {
m_beta->enable();
atm_update_memory();
}
}
return m_program.read_byte(offset + 0x3d00);
}
u8 atm_state::beta_disable_r(offs_t offset)
{
if (!machine().side_effects_disabled()) {
if (is_shadow_active() && m_cpm) {
m_beta->disable();
atm_update_memory();
}
}
return m_program.read_byte(offset + 0x4000);
}
void atm_state::atm_mem(address_map &map)
{
map(0x0000, 0x3fff).bankr("bank1");
map(0x4000, 0x7fff).bankrw("bank2");
map(0x8000, 0xbfff).bankrw("bank3");
map(0xc000, 0xffff).bankrw("bank4");
map(0x0000, 0x3fff).bankrw(m_bank_ram[0]);
map(0x0000, 0x3fff).view(m_bank_view0);
m_bank_view0[0](0x0000, 0x3fff).bankr(m_bank_rom[0]);
map(0x4000, 0x7fff).bankrw(m_bank_ram[1]);
map(0x4000, 0x7fff).view(m_bank_view1);
m_bank_view1[0](0x4000, 0x7fff).bankr(m_bank_rom[1]);
map(0x8000, 0xbfff).bankrw(m_bank_ram[2]);
map(0x8000, 0xbfff).view(m_bank_view2);
m_bank_view2[0](0x8000, 0xbfff).bankr(m_bank_rom[2]);
map(0xc000, 0xffff).bankrw(m_bank_ram[3]);
map(0xc000, 0xffff).view(m_bank_view3);
m_bank_view3[0](0xc000, 0xffff).bankr(m_bank_rom[3]);
}
void atm_state::atm_io(address_map &map)
@ -134,9 +405,13 @@ void atm_state::atm_io(address_map &map)
map(0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w));
map(0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w));
map(0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w));
map(0x00fe, 0x00fe).select(0xff00).rw(FUNC(atm_state::spectrum_ula_r), FUNC(atm_state::spectrum_ula_w));
map(0x00ff, 0x00ff).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::state_r), FUNC(beta_disk_device::param_w));
map(0x4000, 0x4000).mirror(0x3ffd).w(FUNC(atm_state::atm_port_7ffd_w));
map(0x00ff, 0x00ff).mirror(0xff00).r(m_beta, FUNC(beta_disk_device::state_r));
map(0x00ff, 0x00ff).mirror(0xff00).w(FUNC(atm_state::atm_port_ffff_w));
map(0x00f6, 0x00f6).select(0xff08).rw(FUNC(atm_state::spectrum_ula_r), FUNC(atm_state::atm_ula_w));
map(0x00fb, 0x00fb).mirror(0xff00).w("cent_data_out", FUNC(output_latch_device::write));
map(0x00fd, 0x00fd).mirror(0xff00).w(FUNC(atm_state::atm_port_7ffd_w));
map(0x0077, 0x0077).select(0xff00).w(FUNC(atm_state::atm_port_ff77_w));
map(0x00f7, 0x00f7).select(0xff00).w(FUNC(atm_state::atm_port_fff7_w));
map(0x8000, 0x8000).mirror(0x3ffd).w("ay8912", FUNC(ay8910_device::data_w));
map(0xc000, 0xc000).mirror(0x3ffd).rw("ay8912", FUNC(ay8910_device::data_r), FUNC(ay8910_device::address_w));
}
@ -153,57 +428,72 @@ void atm_state::machine_start()
{
spectrum_128_state::machine_start();
m_rom_selection = 0;
save_item(NAME(m_pen));
save_item(NAME(m_cpm));
save_item(NAME(m_pages_map));
save_item(NAME(m_pen2));
save_item(NAME(m_rg));
save_item(NAME(m_br3));
save_item(NAME(m_rom_selection));
// reconfigure ROMs
memory_region *rom = memregion("maincpu");
for (auto i = 0; i < 4; i++)
m_bank_rom[i]->configure_entries(0, 4*8, rom->base() + 0x10000, 0x4000);
m_bank_ram[0]->configure_entries(0, m_ram->size() / 0x4000, m_ram->pointer(), 0x4000);
m_maincpu->space(AS_PROGRAM).specific(m_program);
}
void atm_state::machine_reset()
{
uint8_t *messram = m_ram->pointer();
m_program = &m_maincpu->space(AS_PROGRAM);
m_p_ram = memregion("maincpu")->base();
if (m_beta->started())
m_beta->enable();
memset(messram,0,128*1024);
/* Bank 5 is always in 0x4000 - 0x7fff */
m_bank2->set_base(messram + (5<<14));
/* Bank 2 is always in 0x8000 - 0xbfff */
m_bank3->set_base(messram + (2<<14));
m_beta->enable();
m_port_7ffd_data = 0;
m_port_1ffd_data = -1;
atm_update_memory();
m_br3 = 0;
atm_port_ff77_w(0x4000, 3); // CPM=0(on), PEN=0(off), PEN2=1(off); vmode: zx
}
void atm_state::video_start()
{
spectrum_state::video_start();
m_screen_location = m_ram->pointer() + (5 << 14);
m_contention_pattern = {};
}
/* 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 const gfx_layout atm_charlayout =
{
8, 8, // 8 x 8 characters
256, // 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_atm )
GFXDECODE_ENTRY( "maincpu", 0x1fd00, spectrum_charlayout, 0, 8 )
GFXDECODE_ENTRY( "maincpu", 0x1fd00, spectrum_charlayout, 7, 1 )
GFXDECODE_END
static GFXDECODE_START( gfx_atmtb2 )
GFXDECODE_ENTRY( "maincpu", 0x13d00, spectrum_charlayout, 0, 8 )
GFXDECODE_ENTRY( "charrom", 0, atm_charlayout, 7, 1 )
GFXDECODE_ENTRY( "maincpu", 0x13d00, spectrum_charlayout, 7, 1 )
GFXDECODE_END
void atm_state::atm(machine_config &config)
{
spectrum_128(config);
@ -211,10 +501,16 @@ void atm_state::atm(machine_config &config)
m_maincpu->set_addrmap(AS_PROGRAM, &atm_state::atm_mem);
m_maincpu->set_addrmap(AS_IO, &atm_state::atm_io);
m_maincpu->set_addrmap(AS_OPCODES, &atm_state::atm_switch);
m_maincpu->nomreq_cb().set_nop();
m_screen->set_raw(X1_128_SINCLAIR / 5, 448, 312, {get_screen_area().left() - 40, get_screen_area().right() + 40, get_screen_area().top() - 40, get_screen_area().bottom() + 40});
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_atm);
BETA_DISK(config, m_beta, 0);
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_atm);
CENTRONICS(config, m_centronics, centronics_devices, "covox");
output_latch_device &cent_data_out(OUTPUT_LATCH(config, "cent_data_out"));
m_centronics->set_output_latch(cent_data_out);
config.device_remove("exp");
}
@ -222,6 +518,9 @@ void atm_state::atm(machine_config &config)
void atm_state::atmtb2(machine_config &config)
{
atm(config);
// 1M in ATM2+ only. TODO mem masks for custom size
m_ram->set_default_size("1M");//.set_extra_options("128K,256K,512K,1M");
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_atmtb2);
}
@ -272,8 +571,7 @@ ROM_END
} // Anonymous namespace
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1991, atm, spec128, 0, atm, spec_plus, atm_state, empty_init, "MicroART", "ATM", MACHINE_NOT_WORKING)
//COMP( 1991, atmtb1, spec128, 0, atm, spec_plus, atm_state, empty_init, "MicroART", "ATM-turbo1", MACHINE_NOT_WORKING)
COMP( 1993, atmtb2, spec128, 0, atmtb2, spec_plus, atm_state, empty_init, "MicroART", "ATM-turbo2", MACHINE_NOT_WORKING)
//COMP( 1994, turbo2, spec128, 0, atm, spec_plus, atm_state, empty_init, "MicroART", "TURBO 2+", MACHINE_NOT_WORKING)
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
COMP( 1991, atm, spec128, 0, atm, spec_plus, atm_state, empty_init, "MicroART", "ATM-Turbo (ATM-CP)", MACHINE_NOT_WORKING)
COMP( 1992, atmtb2, spec128, 0, atmtb2, spec_plus, atm_state, empty_init, "MicroART", "ATM-Turbo 2", MACHINE_SUPPORTS_SAVE)
//COMP( 1993, atmtb2p, spec128, 0, atmtb2p, spec_plus, atm_state, empty_init, "MicroART", "ATM-Turbo 2+", MACHINE_NOT_WORKING) // only supports 1M RAM vs. 512K in atmtb2

View File

@ -1,8 +1,8 @@
// license:BSD-3-Clause
// copyright-holders:Andrei I. Holub
#ifndef MAME_MACHINE_GLUKRS_H
#define MAME_MACHINE_GLUKRS_H
#ifndef MAME_SINCLAIR_GLUKRS_H
#define MAME_SINCLAIR_GLUKRS_H
#pragma once
@ -32,4 +32,4 @@ private:
};
DECLARE_DEVICE_TYPE(GLUKRS, glukrs_device)
#endif // MAME_MACHINE_GLUKRS_H
#endif // MAME_SINCLAIR_GLUKRS_H

View File

@ -14,10 +14,10 @@
#include "beta_m.h"
#include "machine/glukrs.h"
#include "glukrs.h"
#include "machine/pckeybrd.h"
#include "machine/spi_sdcard.h"
#include "machine/tsconfdma.h"
#include "tsconfdma.h"
#include "tilemap.h"

View File

@ -154,27 +154,27 @@ void tsconf_state::spectrum_update_screen(screen_device &screen, bitmap_ind16 &b
}
}
void tsconf_state::tsconf_UpdateZxScreenBitmap(screen_device &screen_d, bitmap_ind16 &bitmap, const rectangle &screen)
void tsconf_state::tsconf_UpdateZxScreenBitmap(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
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++)
bool invert_attrs = u64(screen.frame_number() / m_frame_invert_count) & 1;
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
{
u16 hpos = screen.left();
u16 hpos = cliprect.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())
while (hpos <= cliprect.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++)
for (u8 b = 0x80 >> (x & 0x07); b != 0 && hpos <= cliprect.right(); b >>= 1, x++, hpos++)
*pix++ = (pix8 & b) ? ink : pap;
scr++;
attr++;
@ -182,13 +182,13 @@ void tsconf_state::tsconf_UpdateZxScreenBitmap(screen_device &screen_d, bitmap_i
}
}
void tsconf_state::tsconf_UpdateTxtBitmap(bitmap_ind16 &bitmap, const rectangle &screen)
void tsconf_state::tsconf_UpdateTxtBitmap(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
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++)
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
{
u16 hpos = screen.left();
u16 hpos = cliprect.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;
@ -196,28 +196,28 @@ void tsconf_state::tsconf_UpdateTxtBitmap(bitmap_ind16 &bitmap, const rectangle
// 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())
while (hpos <= cliprect.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++)
for (u8 b = 0x80 >> (x & 0x07); b != 0 && hpos <= cliprect.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)
void tsconf_state::tsconf_UpdateGfxBitmap(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
u8 pal_offset = m_regs[PAL_SEL] << 4;
for (u16 vpos = screen.top(); vpos <= screen.bottom(); vpos++)
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
{
u16 y_offset = (0x200 + OFFS_512(G_Y_OFFS_L) + m_gfx_y_frame_offset + vpos) & 0x1ff;
u16 x_offset = (OFFS_512(G_X_OFFS_L) + (screen.left() - get_screen_area().left())) & 0x1ff;
u16 x_offset = (OFFS_512(G_X_OFFS_L) + (cliprect.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();
u16 *bm = &(bitmap.pix(vpos, cliprect.left()));
s16 width = cliprect.width();
if (VM == VM_16C)
{
if (x_offset & 1)

View File

@ -6,8 +6,8 @@
***************************************************************************/
#ifndef MAME_MACHINE_TSCONF_DMA_H
#define MAME_MACHINE_TSCONF_DMA_H
#ifndef MAME_SINCLAIR_TSCONF_DMA_H
#define MAME_SINCLAIR_TSCONF_DMA_H
#pragma once
@ -59,4 +59,4 @@ private:
};
DECLARE_DEVICE_TYPE(TSCONF_DMA, tsconfdma_device)
#endif // MAME_MACHINE_TSCONF_DMA_H
#endif // MAME_SINCLAIR_TSCONF_DMA_H