mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
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:
parent
7c98beb5f4
commit
c92c0c967f
@ -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
|
||||
|
@ -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 ¢_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
|
||||
|
@ -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
|
@ -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"
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user