mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
sinclair/pentevo.cpp: New working clone. (#10337)
* sinclar/atm.cpp: Refactored shadow I/O handling. New working clones ------------------ NedoPC ZX Evolution: BASECONF
This commit is contained in:
parent
cebdec28dc
commit
1802f087ba
@ -261,6 +261,11 @@ void spi_sdcard_device::do_command()
|
||||
send_data(5, SD_STATE_IDLE);
|
||||
break;
|
||||
|
||||
case 9: // CMD9 - SEND_CSD
|
||||
m_data[0] = 0x00; // TODO
|
||||
send_data(1, SD_STATE_STBY);
|
||||
break;
|
||||
|
||||
case 10: // CMD10 - SEND_CID
|
||||
m_data[0] = 0x00; // initial R1 response
|
||||
m_data[1] = 0xff; // throwaway byte before data transfer
|
||||
@ -297,6 +302,11 @@ void spi_sdcard_device::do_command()
|
||||
send_data(1, m_state == SD_STATE_RCV ? SD_STATE_PRG : SD_STATE_TRAN);
|
||||
break;
|
||||
|
||||
case 13: // CMD13 - SEND_STATUS
|
||||
m_data[0] = 0; // TODO
|
||||
send_data(1, SD_STATE_STBY);
|
||||
break;
|
||||
|
||||
case 16: // CMD16 - SET_BLOCKLEN
|
||||
m_blksize = (u16(m_cmd[3]) << 8) | u16(m_cmd[4]);
|
||||
if (m_harddisk && m_harddisk->set_block_size(m_blksize))
|
||||
@ -406,6 +416,12 @@ void spi_sdcard_device::do_command()
|
||||
send_data(5, SD_STATE_DATA);
|
||||
break;
|
||||
|
||||
case 59: // CMD59 - CRC_ON_OFF
|
||||
m_data[0] = 0;
|
||||
// TODO CRC 1-on, 0-off
|
||||
send_data(1, SD_STATE_STBY);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGMASKED(LOG_COMMAND, "SDCARD: Unsupported %02x\n", m_cmd[0] & 0x3f);
|
||||
clean_cmd = false;
|
||||
|
@ -3167,6 +3167,10 @@ mwskinst // (c) 2000 Midway
|
||||
@source:sinclair/atm.cpp
|
||||
atm //
|
||||
atmtb2 //
|
||||
atmtb2plus //
|
||||
|
||||
@source:sinclair/pentevo.cpp
|
||||
pentevo //
|
||||
|
||||
@source:acorn/atom.cpp
|
||||
atom // 1979 Acorn Atom
|
||||
|
@ -756,6 +756,7 @@ siemens/pg685.cpp
|
||||
sinclair/atm.cpp
|
||||
sinclair/elwro800.cpp
|
||||
sinclair/pentagon.cpp
|
||||
sinclair/pentevo.cpp
|
||||
sinclair/ql.cpp
|
||||
sinclair/scorpion.cpp
|
||||
sinclair/spec128.cpp
|
||||
|
@ -8,160 +8,86 @@ 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
|
||||
* better handling of SHADOW ports
|
||||
* validate screen timings
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "spec128.h"
|
||||
#include "specpls3.h"
|
||||
#include "atm.h"
|
||||
|
||||
#include "beta_m.h"
|
||||
#include "glukrs.h"
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
||||
namespace {
|
||||
#include "bus/ata/atapicdr.h"
|
||||
#include "bus/ata/idehd.h"
|
||||
|
||||
#define LOG_MEM (1U << 1)
|
||||
#define LOG_VIDEO (1U << 2)
|
||||
#define LOG_WARN (1U << 3)
|
||||
|
||||
#define VERBOSE ( /*LOG_MEM | LOG_VIDEO |*/ LOG_WARN )
|
||||
#define VERBOSE ( /*LOG_GENERAL | 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 ROM_MASK = 0x7;
|
||||
static constexpr u8 PEN_RAM_MASK = 0x40;
|
||||
static constexpr u8 PEN_DOS7FFD_MASK = 0x80;
|
||||
|
||||
class atm_state : public spectrum_128_state
|
||||
void atm_state::atm_update_cpu()
|
||||
{
|
||||
public:
|
||||
atm_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: spectrum_128_state(mconfig, type, tag)
|
||||
, 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_glukrs(*this, "glukrs")
|
||||
, m_palette(*this, "palette")
|
||||
{ }
|
||||
m_maincpu->set_clock(X1_128_SINCLAIR / 10 * (1 << BIT(m_port_77_data, 3))); // 0 - 3.5MHz, 1 - 7MHz
|
||||
}
|
||||
|
||||
void atm(machine_config &config);
|
||||
void atmtb2(machine_config &config);
|
||||
|
||||
protected:
|
||||
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:
|
||||
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_eff7_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();
|
||||
|
||||
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;
|
||||
|
||||
required_device<beta_disk_device> m_beta;
|
||||
required_device<centronics_device> m_centronics;
|
||||
required_device<glukrs_device> m_glukrs;
|
||||
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_io()
|
||||
{
|
||||
if (is_dos_active())
|
||||
m_io_view.select(0);
|
||||
else
|
||||
m_io_view.disable();
|
||||
}
|
||||
|
||||
void atm_state::atm_update_memory()
|
||||
{
|
||||
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));
|
||||
LOGMEM("PEN%d.%X ", BIT(m_port_7ffd_data, 4), (m_port_7ffd_data & 0x07));
|
||||
for (auto bank = 0; bank < 4 ; bank++)
|
||||
{
|
||||
u8 page = m_pen ? pen_page(bank) : ROM_MASK;
|
||||
if (page & PEN_RAM_MASK)
|
||||
u16 page = atm_update_memory_get_page(bank);
|
||||
const char* is_dos7ffd = page & PEN_DOS7FFD_MASK ? "+" : " ";
|
||||
if (page & PEN_RAMNROM_MASK)
|
||||
{
|
||||
if (page & PEN_DOS7FFD_MASK)
|
||||
page = (page & 0xf8) | (m_port_7ffd_data & 0x07);
|
||||
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);
|
||||
page = merge_ram_with_7ffd(page);
|
||||
LOGMEM("RA%s%X ", is_dos7ffd, page & ram_pages_mask);
|
||||
m_bank_ram[bank]->set_entry(page & ram_pages_mask);
|
||||
if (page & PEN_WRDISBL_MASK)
|
||||
views[bank].get().select(1);
|
||||
else
|
||||
views[bank].get().disable();
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((page & PEN_DOS7FFD_MASK) && !BIT(page, 1))
|
||||
page = (page & ~1) | is_shadow_active();
|
||||
page &= ROM_MASK;
|
||||
m_bank_rom[bank]->set_entry(page);
|
||||
if (page & PEN_DOS7FFD_MASK)
|
||||
page = (page & ~1) | is_dos_active();
|
||||
LOGMEM("RO%s%X ", is_dos7ffd, page & rom_pages_mask);
|
||||
m_bank_rom[bank]->set_entry(page & rom_pages_mask);
|
||||
views[bank].get().select(0);
|
||||
LOGMEM(" RO(%X>%X)", m_bank_rom[bank]->entry(), page);
|
||||
}
|
||||
}
|
||||
LOGMEM("\n");
|
||||
}
|
||||
|
||||
u16 atm_state::atm_update_memory_get_page(u8 bank)
|
||||
{
|
||||
return m_pen ? pen_page(bank) : (~PEN_RAMNROM_MASK & ~PEN_DOS7FFD_MASK);
|
||||
}
|
||||
|
||||
void atm_state::atm_ula_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_br3 = ~offset & 0x08;
|
||||
spectrum_128_state::spectrum_ula_w(offset, data);
|
||||
}
|
||||
|
||||
void atm_state::atm_port_ffff_w(offs_t offset, u8 data)
|
||||
void atm_state::atm_port_ff_w(offs_t offset, u8 data)
|
||||
{
|
||||
if(!is_shadow_active())
|
||||
return;
|
||||
|
||||
if (m_pen2)
|
||||
{
|
||||
m_beta_drive_selected = data;
|
||||
m_beta->param_w(data);
|
||||
}
|
||||
else
|
||||
@ -169,6 +95,7 @@ void atm_state::atm_port_ffff_w(offs_t offset, u8 data)
|
||||
// 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_data[pen] = data;
|
||||
m_palette->set_pen_color(pen,
|
||||
(BIT(~data, 1) * 0xaa) | (BIT(~data, 6) * 0x55),
|
||||
(BIT(~data, 4) * 0xaa) | (BIT(~data, 7) * 0x55),
|
||||
@ -178,8 +105,7 @@ void atm_state::atm_port_ffff_w(offs_t offset, u8 data)
|
||||
|
||||
void atm_state::atm_port_7ffd_w(offs_t offset, u8 data)
|
||||
{
|
||||
/* disable paging */
|
||||
if (BIT(m_port_7ffd_data, 5))
|
||||
if (is_port_7ffd_locked())
|
||||
return;
|
||||
|
||||
m_port_7ffd_data = data;
|
||||
@ -189,18 +115,19 @@ void atm_state::atm_port_7ffd_w(offs_t offset, u8 data)
|
||||
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)
|
||||
void atm_state::atm_port_77_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (!is_shadow_active())
|
||||
return;
|
||||
m_port_77_data = data;
|
||||
|
||||
m_pen = BIT(offset, 8);
|
||||
m_cpm = BIT(offset, 9);
|
||||
m_cpm_n = BIT(offset, 9);
|
||||
atm_update_io();
|
||||
|
||||
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");
|
||||
LOGMASKED(LOG_VIDEO | LOG_MEM, "PEN %s, CPM %s, PEN2 %s\n", m_pen ? "on" : "off", m_cpm_n ? "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
|
||||
atm_update_cpu();
|
||||
|
||||
int rg = data & 0x07;
|
||||
if ( m_rg ^ rg )
|
||||
@ -210,42 +137,38 @@ void atm_state::atm_port_ff77_w(offs_t offset, u8 data)
|
||||
}
|
||||
}
|
||||
|
||||
void atm_state::atm_port_eff7_w(offs_t offset, u8 data)
|
||||
void atm_state::atm_port_f7_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_maincpu->set_clock(X1_128_SINCLAIR / 10 * (1 << BIT(data, 4))); // 0 - 3.5MHz, 1 - 7MHz
|
||||
if (BIT(data, 7))
|
||||
m_glukrs->enable();
|
||||
else
|
||||
m_glukrs->disable();
|
||||
}
|
||||
|
||||
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);
|
||||
u16 page = (u16(data & 0xc0) << 8) | u8(~data & 0x3f);
|
||||
|
||||
LOGMEM("PEN%s.%s = %X %s%d: %02X\n", (page | PEN_DOS7FFD_MASK) ? "+" : "!", BIT(m_port_7ffd_data, 4), data, (page & PEN_RAM_MASK) ? "RAM" : "ROM", bank, page & 0x3f);
|
||||
LOGMEM("ATM%s=%X %s%d%s%02X\n", BIT(m_port_7ffd_data, 4), data, (page & PEN_RAMNROM_MASK) ? "RAM" : "ROM", bank, (page & PEN_DOS7FFD_MASK) ? "+" : " ", page & 0x3f);
|
||||
pen_page(bank) = page;
|
||||
atm_update_memory();
|
||||
atm_update_io();
|
||||
}
|
||||
|
||||
INTERRUPT_GEN_MEMBER(atm_state::atm_interrupt)
|
||||
{
|
||||
// 14395=64*224+59 z80(3.5Hz) clocks between INT and screen paper begins. Screen clock is 7Hz.
|
||||
m_irq_on_timer->adjust(m_screen->time_until_pos(80 - 64, 80) - m_screen->clocks_to_attotime(118));
|
||||
}
|
||||
|
||||
rectangle atm_state::get_screen_area()
|
||||
{
|
||||
switch (m_rg)
|
||||
{
|
||||
case 0b111:
|
||||
case 0b110: // 80x25txt
|
||||
case 0b010: // 640x200
|
||||
return rectangle { 208, 208 + 639, 76, 76 + 199 };
|
||||
return rectangle { 80, 80 + 639, 80, 80 + 199 };
|
||||
break;
|
||||
case 0b000: // 320x200
|
||||
return rectangle { 104, 104 + 319, 76, 76 + 199 };
|
||||
return rectangle { 80, 80 + 319, 80, 80 + 199 };
|
||||
break;
|
||||
case 0b011: // 256x192
|
||||
case 0b011: // 256x192zx
|
||||
default:
|
||||
return rectangle { 136, 136 + 255, 80, 80 + 191 };
|
||||
return rectangle { 80, 80 + 255, 80, 80 + 191 };
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -257,12 +180,12 @@ u8 atm_state::get_border_color(u16 hpos, u16 vpos)
|
||||
|
||||
void atm_state::atm_update_video_mode()
|
||||
{
|
||||
bool zx_scale = BIT(m_rg, 0);
|
||||
bool zx_scale = m_rg == 0b011;
|
||||
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());
|
||||
m_screen->configure(448 << double_width, m_screen->height(), {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);
|
||||
@ -352,7 +275,7 @@ void atm_state::atm_update_screen_tx(screen_device &screen, bitmap_ind16 &bitmap
|
||||
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));
|
||||
u8 chunk = *(m_char_location + (*symb_location << 3) + (y & 0x07));
|
||||
for (u8 i = 0x80; i; i >>= 1)
|
||||
{
|
||||
bitmap.pix(vpos, hpos++) = (chunk & i) ? fg : bg;
|
||||
@ -368,67 +291,114 @@ u8 atm_state::beta_neutral_r(offs_t offset)
|
||||
|
||||
u8 atm_state::beta_enable_r(offs_t offset)
|
||||
{
|
||||
if (!machine().side_effects_disabled()) {
|
||||
u8 page = pen_page(0);
|
||||
if (!(page & PEN_RAM_MASK) && !is_shadow_active()) {
|
||||
if (!machine().side_effects_disabled() && !m_beta->is_active())
|
||||
{
|
||||
bool is_rom0 = !(atm_update_memory_get_page(0) & PEN_RAMNROM_MASK);
|
||||
if (is_rom0 || !m_cpm_n)
|
||||
{
|
||||
m_beta->enable();
|
||||
atm_update_memory();
|
||||
atm_update_io();
|
||||
}
|
||||
}
|
||||
return m_program.read_byte(offset + 0x3d00);
|
||||
return beta_neutral_r(offset + 0x3d00);
|
||||
}
|
||||
|
||||
u8 atm_state::beta_disable_r(offs_t offset)
|
||||
{
|
||||
if (!machine().side_effects_disabled()) {
|
||||
if (is_shadow_active() && m_cpm) {
|
||||
if (!machine().side_effects_disabled() && m_beta->is_active())
|
||||
{
|
||||
if (m_cpm_n)
|
||||
{
|
||||
m_beta->disable();
|
||||
atm_update_memory();
|
||||
atm_update_io();
|
||||
}
|
||||
}
|
||||
return m_program.read_byte(offset + 0x4000);
|
||||
return beta_neutral_r(offset + 0x4000);
|
||||
}
|
||||
|
||||
u8 atm_state::ata_r(offs_t offset)
|
||||
{
|
||||
u8 ata_offset = BIT(offset, 5, 3);
|
||||
u16 data = m_ata->cs0_r(ata_offset);
|
||||
|
||||
if (!machine().side_effects_disabled() && !ata_offset)
|
||||
m_ata_data_latch = data >> 8;
|
||||
|
||||
return data & 0xff;
|
||||
}
|
||||
|
||||
void atm_state::ata_w(offs_t offset, u8 data)
|
||||
{
|
||||
u8 ata_offset = BIT(offset, 5, 3);
|
||||
u16 ata_data = data;
|
||||
if (!ata_offset)
|
||||
ata_data |= m_ata_data_latch << 8;
|
||||
|
||||
m_ata->cs0_w(ata_offset, ata_data);
|
||||
}
|
||||
|
||||
template <u8 Bank> void atm_state::atm_ram_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (m_rg == 0b011 && (m_bank_ram[Bank]->entry() == (BIT(m_port_7ffd_data, 3) ? 7 : 5)) && offset < 0x1b00)
|
||||
m_screen->update_now();
|
||||
|
||||
((u8*)m_bank_ram[Bank]->base())[offset] = data;
|
||||
}
|
||||
|
||||
void atm_state::atm_mem(address_map &map)
|
||||
{
|
||||
map(0x0000, 0x3fff).bankrw(m_bank_ram[0]);
|
||||
map(0x0000, 0x3fff).bankr(m_bank_ram[0]).w(FUNC(atm_state::atm_ram_w<0>));
|
||||
map(0x0000, 0x3fff).view(m_bank_view0);
|
||||
m_bank_view0[0](0x0000, 0x3fff).bankr(m_bank_rom[0]).nopw();
|
||||
m_bank_view0[1](0x0000, 0x3fff).nopw(); // RO RAM
|
||||
|
||||
map(0x4000, 0x7fff).bankrw(m_bank_ram[1]);
|
||||
map(0x4000, 0x7fff).bankr(m_bank_ram[1]).w(FUNC(atm_state::atm_ram_w<1>));
|
||||
map(0x4000, 0x7fff).view(m_bank_view1);
|
||||
m_bank_view1[0](0x4000, 0x7fff).bankr(m_bank_rom[1]).nopw();
|
||||
m_bank_view1[1](0x4000, 0x7fff).nopw();
|
||||
|
||||
map(0x8000, 0xbfff).bankrw(m_bank_ram[2]);
|
||||
map(0x8000, 0xbfff).bankr(m_bank_ram[2]).w(FUNC(atm_state::atm_ram_w<2>));
|
||||
map(0x8000, 0xbfff).view(m_bank_view2);
|
||||
m_bank_view2[0](0x8000, 0xbfff).bankr(m_bank_rom[2]).nopw();
|
||||
m_bank_view2[1](0x8000, 0xbfff).nopw();
|
||||
|
||||
map(0xc000, 0xffff).bankrw(m_bank_ram[3]);
|
||||
map(0xc000, 0xffff).bankr(m_bank_ram[3]).w(FUNC(atm_state::atm_ram_w<3>));
|
||||
map(0xc000, 0xffff).view(m_bank_view3);
|
||||
m_bank_view3[0](0xc000, 0xffff).bankr(m_bank_rom[3]).nopw();
|
||||
m_bank_view3[1](0xc000, 0xffff).nopw();
|
||||
}
|
||||
|
||||
void atm_state::atm_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map(0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w));
|
||||
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(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));
|
||||
|
||||
// PORTS: Always
|
||||
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(0xeff7, 0xeff7).w(FUNC(atm_state::atm_port_eff7_w));
|
||||
map(0xdef7, 0xdef7).mirror(0x0100).w(m_glukrs, FUNC(glukrs_device::address_w));
|
||||
map(0xbff7, 0xbff7).r(m_glukrs, FUNC(glukrs_device::data_r));
|
||||
map(0xbef7, 0xbef7).rw(m_glukrs, FUNC(glukrs_device::data_r), FUNC(glukrs_device::data_w));
|
||||
|
||||
map(0xfadf, 0xfadf).mirror(0x0500).nopr(); // TODO 0xfadf, 0xfbdf, 0xffdf Kempston Mouse
|
||||
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));
|
||||
|
||||
// PORTS: Shadow
|
||||
map(0x0000, 0xffff).view(m_io_view);
|
||||
m_io_view[0](0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w));
|
||||
m_io_view[0](0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w));
|
||||
m_io_view[0](0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w));
|
||||
m_io_view[0](0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w));
|
||||
m_io_view[0](0x00ff, 0x00ff).mirror(0xff00).r(m_beta, FUNC(beta_disk_device::state_r)).w(FUNC(atm_state::atm_port_ff_w));
|
||||
|
||||
m_io_view[0](0x0077, 0x0077).select(0xff00).w(FUNC(atm_state::atm_port_77_w));
|
||||
m_io_view[0](0x00f7, 0x00f7).select(0xff00).w(FUNC(atm_state::atm_port_f7_w));
|
||||
|
||||
// A: .... .... nnn0 1111
|
||||
m_io_view[0](0x000f, 0x000f).select(0xffe0).rw(FUNC(atm_state::ata_r), FUNC(atm_state::ata_w));
|
||||
// A: .... ...1 0000 1111
|
||||
m_io_view[0](0x010f, 0x010f).mirror(0xfe00).lrw8(NAME([this](offs_t offset) { return m_ata_data_latch; })
|
||||
, NAME([this](offs_t offset, u8 data) { m_ata_data_latch = data; }));
|
||||
}
|
||||
|
||||
void atm_state::atm_switch(address_map &map)
|
||||
@ -443,18 +413,23 @@ void atm_state::machine_start()
|
||||
{
|
||||
spectrum_128_state::machine_start();
|
||||
|
||||
save_item(NAME(m_port_77_data));
|
||||
save_item(NAME(m_pen));
|
||||
save_item(NAME(m_cpm));
|
||||
save_item(NAME(m_cpm_n));
|
||||
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_beta_drive_selected));
|
||||
|
||||
// reconfigure ROMs
|
||||
memory_region *rom = memregion("maincpu");
|
||||
rom_pages_mask = (rom->bytes() - 0x10001) / 0x4000;
|
||||
for (auto i = 0; i < 4; i++)
|
||||
m_bank_rom[i]->configure_entries(0, 8, rom->base() + 0x10000, 0x4000);
|
||||
m_bank_ram[0]->configure_entries(0, m_ram->size() / 0x4000, m_ram->pointer(), 0x4000);
|
||||
m_bank_rom[i]->configure_entries(0, rom_pages_mask + 1, rom->base() + 0x10000, 0x4000); // todo dyn
|
||||
|
||||
ram_pages_mask = (m_ram->size() - 1) / 0x4000;
|
||||
m_bank_ram[0]->configure_entries(0, ram_pages_mask + 1, m_ram->pointer(), 0x4000);
|
||||
|
||||
m_maincpu->space(AS_PROGRAM).specific(m_program);
|
||||
}
|
||||
@ -462,19 +437,23 @@ void atm_state::machine_start()
|
||||
void atm_state::machine_reset()
|
||||
{
|
||||
m_beta->enable();
|
||||
m_glukrs->disable();
|
||||
m_beta_drive_selected = 0;
|
||||
|
||||
m_port_7ffd_data = 0;
|
||||
m_port_1ffd_data = -1;
|
||||
m_port_77_data = 0;
|
||||
|
||||
m_br3 = 0;
|
||||
atm_port_ff77_w(0x4000, 3); // CPM=0(on), PEN=0(off), PEN2=1(off); vmode: zx
|
||||
m_palette_data = { 0xff };
|
||||
atm_port_77_w(0x4000, 3); // m_port_77_data: 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_char_location = m_char_rom;
|
||||
subdevice<gfxdecode_device>("gfxdecode")->gfx(0)->set_source(m_char_location);
|
||||
m_contention_pattern = {};
|
||||
}
|
||||
|
||||
@ -493,7 +472,7 @@ static const gfx_layout spectrum_charlayout =
|
||||
static const gfx_layout atm_charlayout =
|
||||
{
|
||||
8, 8, // 8 x 8 characters
|
||||
256, // 96 characters
|
||||
256, // 256 characters
|
||||
1, // 1 bits per pixel
|
||||
{ 0 }, // no bitplanes
|
||||
{ STEP8(0, 1) }, // x offsets
|
||||
@ -502,14 +481,21 @@ static const gfx_layout atm_charlayout =
|
||||
};
|
||||
|
||||
static GFXDECODE_START( gfx_atm )
|
||||
GFXDECODE_ENTRY( "maincpu", 0, atm_charlayout, 7, 1 ) // charrom
|
||||
GFXDECODE_ENTRY( "maincpu", 0x1fd00, spectrum_charlayout, 7, 1 )
|
||||
GFXDECODE_END
|
||||
|
||||
static GFXDECODE_START( gfx_atmtb2 )
|
||||
GFXDECODE_ENTRY( "charrom", 0, atm_charlayout, 7, 1 )
|
||||
GFXDECODE_ENTRY( "maincpu", 0, atm_charlayout, 7, 1 ) // charrom
|
||||
GFXDECODE_ENTRY( "maincpu", 0x13d00, spectrum_charlayout, 7, 1 )
|
||||
GFXDECODE_END
|
||||
|
||||
static void atm_ata_devices(device_slot_interface &device)
|
||||
{
|
||||
device.option_add("hdd", IDE_HARDDISK);
|
||||
device.option_add("cdrom", ATAPI_CDROM);
|
||||
}
|
||||
|
||||
void atm_state::atm(machine_config &config)
|
||||
{
|
||||
spectrum_128(config);
|
||||
@ -517,13 +503,14 @@ 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->set_vblank_int("screen", FUNC(atm_state::atm_interrupt));
|
||||
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);
|
||||
GLUKRS(config, m_glukrs);
|
||||
ATA_INTERFACE(config, m_ata).options(atm_ata_devices, nullptr, nullptr, false);;
|
||||
|
||||
CENTRONICS(config, m_centronics, centronics_devices, "covox");
|
||||
output_latch_device ¢_data_out(OUTPUT_LATCH(config, "cent_data_out"));
|
||||
@ -532,40 +519,63 @@ void atm_state::atm(machine_config &config)
|
||||
config.device_remove("exp");
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* ATM Turbo 2
|
||||
* ***************************************************************************/
|
||||
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");
|
||||
m_ram->set_default_size("512K").set_extra_options("128K,256K");
|
||||
|
||||
subdevice<gfxdecode_device>("gfxdecode")->set_info(gfx_atmtb2);
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* ATM Turbo 2+
|
||||
* ***************************************************************************/
|
||||
void atm_state::atmtb2plus(machine_config &config)
|
||||
{
|
||||
atmtb2(config);
|
||||
|
||||
m_ram->set_default_size("1M").set_extra_options("128K,256K,512K");
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
|
||||
Game driver(s)
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
* Game driver(s)
|
||||
* ************************************************************************/
|
||||
ROM_START( atm )
|
||||
ROM_REGION(0x030000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_REGION(0x020000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_SYSTEM_BIOS(0, "v1", "v.1.03")
|
||||
ROMX_LOAD( "atm103.rom", 0x020000, 0x10000, CRC(4912e249) SHA1(a4adff05bb215dd126c47201b36956115b8fed76), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v2", "v.1.06 joined")
|
||||
ROMX_LOAD( "atm106.rom", 0x020000, 0x10000, CRC(75350b37) SHA1(2afc9994f026645c74b6c4b35bcee2e0bc0d6edc), ROM_BIOS(1))
|
||||
ROM_SYSTEM_BIOS(2, "v3", "v.1.06")
|
||||
ROMX_LOAD( "atm106-1.rom", 0x020000, 0x4000, CRC(658c98f1) SHA1(1ec694795aa6cac10147e58f38a9db0bdf7ed89b), ROM_BIOS(2))
|
||||
ROMX_LOAD( "atm106-2.rom", 0x024000, 0x4000, CRC(8fe367f9) SHA1(56de8fd39061663b9c315b74fd3c31acddae279c), ROM_BIOS(2))
|
||||
ROMX_LOAD( "atm106-3.rom", 0x028000, 0x4000, CRC(124ad9e0) SHA1(d07fcdeca892ee80494d286ea9ea5bf3928a1aca), ROM_BIOS(2))
|
||||
ROMX_LOAD( "atm106-4.rom", 0x02c000, 0x4000, CRC(f352f2ab) SHA1(6045500ab01be708cef62327e9821b4a358a4673), ROM_BIOS(2))
|
||||
ROM_SYSTEM_BIOS(3, "v4", "v.1.03rs")
|
||||
ROMX_LOAD( "atm103rs.rom", 0x020000, 0x10000, CRC(cdec1dfb) SHA1(08190807c6b110cb2e657d8e7d0ad18668915375), ROM_BIOS(3))
|
||||
ROMX_LOAD( "atm103.rom", 0x010000, 0x10000, CRC(4912e249) SHA1(a4adff05bb215dd126c47201b36956115b8fed76), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v2", "v.1.03rs")
|
||||
ROMX_LOAD( "atm103rs.rom", 0x010000, 0x10000, CRC(cdec1dfb) SHA1(08190807c6b110cb2e657d8e7d0ad18668915375), ROM_BIOS(1))
|
||||
ROM_END
|
||||
|
||||
ROM_START( atmtb2 )
|
||||
ROM_REGION(0x020000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_SYSTEM_BIOS(0, "v1.06", "BIOS v1.06") // joined dump
|
||||
ROMX_LOAD( "atm106.rom", 0x010000, 0x10000, CRC(75350b37) SHA1(2afc9994f026645c74b6c4b35bcee2e0bc0d6edc), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v1.06a", "BIOS v1.06 (split)")
|
||||
ROMX_LOAD( "atm106-1.rom", 0x010000, 0x4000, CRC(658c98f1) SHA1(1ec694795aa6cac10147e58f38a9db0bdf7ed89b), ROM_BIOS(1))
|
||||
ROMX_LOAD( "atm106-2.rom", 0x014000, 0x4000, CRC(8fe367f9) SHA1(56de8fd39061663b9c315b74fd3c31acddae279c), ROM_BIOS(1))
|
||||
ROMX_LOAD( "atm106-3.rom", 0x018000, 0x4000, CRC(124ad9e0) SHA1(d07fcdeca892ee80494d286ea9ea5bf3928a1aca), ROM_BIOS(1))
|
||||
ROMX_LOAD( "atm106-4.rom", 0x01c000, 0x4000, CRC(f352f2ab) SHA1(6045500ab01be708cef62327e9821b4a358a4673), ROM_BIOS(1))
|
||||
|
||||
ROM_REGION(0x01000, "keyboard", ROMREGION_ERASEFF)
|
||||
ROM_LOAD( "rf2ve3.rom", 0x0000, 0x0580, CRC(35e0f9ec) SHA1(adcf14758fab8472cfa0167af7e8326c66416416)) // XT Keyboard
|
||||
ROM_LOAD( "rfat710.rom", 0x0600, 0x0680, CRC(03734365) SHA1(6cb6311727fad9bc4ccb18919c3c39b37529b8e6)) // AT Keyboard
|
||||
|
||||
ROM_REGION(0x08000, "charrom", ROMREGION_ERASEFF) // Char gen rom
|
||||
ROM_LOAD( "sgen.rom", 0x0000, 0x0800, CRC(1f4387d6) SHA1(93b3774dc8a486643a1bdd48c606b0c84fa0e22b))
|
||||
ROM_END
|
||||
|
||||
ROM_START( atmtb2plus )
|
||||
ROM_REGION(0x030000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_DEFAULT_BIOS("v1.07.13")
|
||||
ROM_DEFAULT_BIOS("v1.37")
|
||||
ROM_SYSTEM_BIOS(0, "v1.07.12", "BIOS v1.07.12, CP/M v2.2, TR-DOS v5.03") // joined dump
|
||||
ROMX_LOAD( "atmtb2.rom", 0x020000, 0x10000,CRC(05218c26) SHA1(71ed9864e7aa85131de97cf1e53dc152e7c79488), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v1.07.12a", "BIOS v1.07.12, CP/M v2.2, TR-DOS v5.03 (split)")
|
||||
@ -579,20 +589,14 @@ ROM_START( atmtb2 )
|
||||
ROMX_LOAD( "atmtb2x37xt.rom", 0x010000, 0x20000, CRC(e5ef44d9) SHA1(3fbb9ace7cb031e7365c19e4f8b67ed366e24064), ROM_BIOS(3))
|
||||
|
||||
ROM_REGION(0x01000, "keyboard", ROMREGION_ERASEFF)
|
||||
// XT Keyboard
|
||||
ROM_LOAD( "rf2ve3.rom", 0x0000, 0x0580, CRC(35e0f9ec) SHA1(adcf14758fab8472cfa0167af7e8326c66416416))
|
||||
// AT Keyboard
|
||||
ROM_LOAD( "rfat710.rom", 0x0600, 0x0680, CRC(03734365) SHA1(6cb6311727fad9bc4ccb18919c3c39b37529b8e6))
|
||||
ROM_LOAD( "rf2ve3.rom", 0x0000, 0x0580, CRC(35e0f9ec) SHA1(adcf14758fab8472cfa0167af7e8326c66416416)) // XT Keyboard
|
||||
ROM_LOAD( "rfat710.rom", 0x0600, 0x0680, CRC(03734365) SHA1(6cb6311727fad9bc4ccb18919c3c39b37529b8e6)) // AT Keyboard
|
||||
|
||||
ROM_REGION(0x08000, "charrom", ROMREGION_ERASEFF)
|
||||
// Char gen rom
|
||||
ROM_REGION(0x08000, "charrom", ROMREGION_ERASEFF) // Char gen rom
|
||||
ROM_LOAD( "sgen.rom", 0x0000, 0x0800, CRC(1f4387d6) SHA1(93b3774dc8a486643a1bdd48c606b0c84fa0e22b))
|
||||
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-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
|
||||
/* 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, atmtb2plus, spec128, 0, atmtb2plus, spec_plus, atm_state, empty_init, "MicroART", "ATM-Turbo 2+", MACHINE_SUPPORTS_SAVE)
|
||||
|
111
src/mame/sinclair/atm.h
Normal file
111
src/mame/sinclair/atm.h
Normal file
@ -0,0 +1,111 @@
|
||||
// license:BSD-3-Clause
|
||||
#ifndef MAME_SINCLAIR_ATM_H
|
||||
#define MAME_SINCLAIR_ATM_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "spec128.h"
|
||||
|
||||
#include "beta_m.h"
|
||||
#include "bus/ata/ataintf.h"
|
||||
#include "bus/centronics/ctronics.h"
|
||||
#include "sound/ay8910.h"
|
||||
|
||||
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_bank_view0(*this, "bank_view0")
|
||||
, m_bank_view1(*this, "bank_view1")
|
||||
, m_bank_view2(*this, "bank_view2")
|
||||
, m_bank_view3(*this, "bank_view3")
|
||||
, m_io_view(*this, "io_view")
|
||||
, m_bank_rom(*this, "bank_rom%u", 0U)
|
||||
, m_char_rom(*this, "charrom")
|
||||
, m_beta(*this, BETA_DISK_TAG)
|
||||
, m_ata(*this, "ata")
|
||||
, m_centronics(*this, "centronics")
|
||||
, m_palette(*this, "palette")
|
||||
{ }
|
||||
|
||||
void atm(machine_config &config);
|
||||
void atmtb2(machine_config &config);
|
||||
void atmtb2plus(machine_config &config);
|
||||
|
||||
protected:
|
||||
static constexpr u16 PEN_WRDISBL_MASK = 1 << 13;
|
||||
static constexpr u16 PEN_RAMNROM_MASK = 1 << 14; // 1-RAM, 0-ROM
|
||||
static constexpr u16 PEN_DOS7FFD_MASK = 1 << 15;
|
||||
|
||||
virtual void machine_start() override;
|
||||
virtual void machine_reset() override;
|
||||
virtual void video_start() override;
|
||||
|
||||
void atm_io(address_map &map);
|
||||
void atm_mem(address_map &map);
|
||||
void atm_switch(address_map &map);
|
||||
template <u8 Bank> void atm_ram_w(offs_t offset, u8 data);
|
||||
|
||||
u8 beta_neutral_r(offs_t offset);
|
||||
u8 beta_enable_r(offs_t offset);
|
||||
u8 beta_disable_r(offs_t offset);
|
||||
u8 ata_r(offs_t offset);
|
||||
void ata_w(offs_t offset, u8 data);
|
||||
|
||||
void atm_ula_w(offs_t offset, u8 data);
|
||||
virtual void atm_port_ff_w(offs_t offset, u8 data);
|
||||
void atm_port_77_w(offs_t offset, u8 data);
|
||||
void atm_port_f7_w(offs_t offset, u8 data);
|
||||
void atm_port_7ffd_w(offs_t offset, u8 data);
|
||||
|
||||
virtual void atm_update_cpu();
|
||||
virtual void atm_update_io();
|
||||
u16 &pen_page(u8 bank) { return m_pages_map[BIT(m_port_7ffd_data, 4)][bank]; }
|
||||
void atm_update_memory();
|
||||
virtual u8 merge_ram_with_7ffd(u8 ram_page) { return (ram_page & ~0x07) | (m_port_7ffd_data & 0x07); }
|
||||
virtual bool is_port_7ffd_locked() { return BIT(m_port_7ffd_data, 5); };
|
||||
bool is_dos_active() { return !m_cpm_n || m_beta->is_active(); }
|
||||
|
||||
virtual void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
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);
|
||||
virtual u16 atm_update_memory_get_page(u8 bank);
|
||||
virtual u8 get_border_color(u16 hpos, u16 vpos) override;
|
||||
rectangle get_screen_area() override;
|
||||
INTERRUPT_GEN_MEMBER(atm_interrupt);
|
||||
|
||||
memory_view m_bank_view0;
|
||||
memory_view m_bank_view1;
|
||||
memory_view m_bank_view2;
|
||||
memory_view m_bank_view3;
|
||||
memory_view m_io_view;
|
||||
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;
|
||||
|
||||
required_device<beta_disk_device> m_beta;
|
||||
required_device<ata_interface_device> m_ata;
|
||||
required_device<centronics_device> m_centronics;
|
||||
required_device<device_palette_interface> m_palette;
|
||||
|
||||
u8 *m_char_location;
|
||||
u8 rom_pages_mask;
|
||||
u8 ram_pages_mask;
|
||||
|
||||
u8 m_port_77_data;
|
||||
bool m_pen; // PEN - extended memory manager
|
||||
bool m_cpm_n;
|
||||
u16 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;
|
||||
std::vector<u8> m_palette_data;
|
||||
u8 m_ata_data_latch;
|
||||
u8 m_beta_drive_selected;
|
||||
};
|
||||
|
||||
#endif // MAME_SINCLAIR_ATM_H
|
@ -9,8 +9,8 @@
|
||||
04/05/2008 Created by Miodrag Milanovic
|
||||
|
||||
*********************************************************************/
|
||||
#ifndef MAME_MACHINE_BETA_H
|
||||
#define MAME_MACHINE_BETA_H
|
||||
#ifndef MAME_SINCLAIR_BETA_H
|
||||
#define MAME_SINCLAIR_BETA_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -67,4 +67,4 @@ private:
|
||||
DECLARE_DEVICE_TYPE(BETA_DISK, beta_disk_device)
|
||||
|
||||
|
||||
#endif // MAME_MACHINE_BETA_H
|
||||
#endif // MAME_SINCLAIR_BETA_H
|
||||
|
@ -3,6 +3,7 @@
|
||||
/***************************************************************************
|
||||
|
||||
Mr Gluk Reset Service
|
||||
TODO implementation must be based on KR512VI1 clone MC146818
|
||||
|
||||
Refs:
|
||||
https://zxart.ee/spa/software/prikladnoe-po/electronics/pzu/mr-gluk-reset-service-663/mr-gluk-reset-service-663/action:viewFile/id:250389/fileId:814961/
|
||||
|
@ -15,12 +15,12 @@ class glukrs_device : public device_t,
|
||||
public:
|
||||
glukrs_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 32'768);
|
||||
|
||||
void enable() { m_glukrs_active = true; };
|
||||
void disable() { m_glukrs_active = false; };
|
||||
bool is_active() { return m_glukrs_active; };
|
||||
void enable() { m_glukrs_active = true; }
|
||||
void disable() { m_glukrs_active = false; }
|
||||
bool is_active() { return m_glukrs_active; }
|
||||
u8 address_r() { return m_glukrs_active ? m_address : 0xff; }
|
||||
void address_w(u8 address) { if (m_glukrs_active) m_address = address; };
|
||||
u8 data_r() { return m_glukrs_active ? m_cmos[m_address] : 0xff; };
|
||||
void address_w(u8 address) { if (m_glukrs_active) m_address = address; }
|
||||
u8 data_r() { return m_glukrs_active ? m_cmos[m_address] : 0xff; }
|
||||
void data_w(u8 data) { if (m_glukrs_active) { m_cmos[m_address] = data; } }
|
||||
|
||||
TIMER_CALLBACK_MEMBER(timer_callback);
|
||||
|
@ -101,8 +101,10 @@ u8 pentagon_state::beta_neutral_r(offs_t offset)
|
||||
|
||||
u8 pentagon_state::beta_enable_r(offs_t offset)
|
||||
{
|
||||
if (!(machine().side_effects_disabled())) {
|
||||
if (m_bank_rom[0]->entry() == 1) {
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_bank_rom[0]->entry() == 1)
|
||||
{
|
||||
m_beta->enable();
|
||||
m_bank_rom[0]->set_entry(3);
|
||||
}
|
||||
@ -112,8 +114,10 @@ u8 pentagon_state::beta_enable_r(offs_t offset)
|
||||
|
||||
u8 pentagon_state::beta_disable_r(offs_t offset)
|
||||
{
|
||||
if (!(machine().side_effects_disabled())) {
|
||||
if (m_beta->is_active()) {
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_beta->is_active())
|
||||
{
|
||||
m_beta->disable();
|
||||
m_bank_rom[0]->set_entry(BIT(m_port_7ffd_data, 4));
|
||||
}
|
||||
|
768
src/mame/sinclair/pentevo.cpp
Normal file
768
src/mame/sinclair/pentevo.cpp
Normal file
@ -0,0 +1,768 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Andrei I. Holub
|
||||
/***************************************************************************
|
||||
|
||||
ZX Evolution: BASECONF machine driver.
|
||||
Implementation: Revision C
|
||||
|
||||
Hobby computer ZX Evolution is Spectrum-compatible with extensions.
|
||||
|
||||
Hardware (ZX Evolution):
|
||||
- Z80 3.5 MHz (classic mode)/ 7 MHz (turbo mode without CPU wait cycles)/ 14 MHz (mega turbo with CPU wait cycles);
|
||||
- 4 Mb RAM, 512Kb ROM;
|
||||
- MiniITX board (172x170mm), 2 ZXBUS slots, power ATX or +5,+12V;
|
||||
- Based on fpga (Altera EP1K50);
|
||||
- Peripheral MCU ATMEGA128;
|
||||
- PS/2 keyboard and mouse support;
|
||||
- Floppy (WDC1793) Beta-disk compatible interface, IDE (one channel, up to 2 devices on master/slave mode), SD(HC) card, RS232;
|
||||
- Sound: AY, Beeper, Covox (PWM);
|
||||
- Real-time clock.
|
||||
|
||||
Refs:
|
||||
ZxEvo: http://nedopc.com/zxevo/zxevo_eng.php
|
||||
Principal scheme (rev. C) :: http://nedopc.com/zxevo/zxevo_sch_revc.pdf
|
||||
Montage scheme (rev. C) :: http://nedopc.com/zxevo/zxevo_mon_revc.pdf
|
||||
|
||||
TODO:
|
||||
* Keyboard enabled
|
||||
* zx 16c
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "atm.h"
|
||||
|
||||
#include "glukrs.h"
|
||||
#include "machine/pckeybrd.h"
|
||||
#include "machine/spi_sdcard.h"
|
||||
#include "machine/timer.h"
|
||||
|
||||
#define LOG_MEM (1U << 1)
|
||||
#define LOG_VIDEO (1U << 2)
|
||||
#define LOG_WARN (1U << 3)
|
||||
|
||||
#define VERBOSE ( /*LOG_GENERAL | 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__)
|
||||
|
||||
namespace {
|
||||
|
||||
class pentevo_state : public atm_state
|
||||
{
|
||||
public:
|
||||
pentevo_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: atm_state(mconfig, type, tag)
|
||||
, m_gfxdecode(*this, "gfxdecode")
|
||||
, m_char_ram(*this, "char_ram")
|
||||
, m_io_dos_view(*this, "io_dos_view")
|
||||
, m_glukrs(*this, "glukrs")
|
||||
, m_sdcard(*this, "sdcard")
|
||||
, m_keyboard(*this, "pc_keyboard")
|
||||
, m_io_mouse(*this, "mouse_input%u", 1U)
|
||||
{ }
|
||||
|
||||
void pentevo(machine_config &config);
|
||||
|
||||
protected:
|
||||
void machine_start() override;
|
||||
void machine_reset() override;
|
||||
void video_start() override;
|
||||
|
||||
private:
|
||||
void init_mem_write();
|
||||
void pentevo_io(address_map &map);
|
||||
|
||||
void atm_port_ff_w(offs_t offset, u8 data) override;
|
||||
void pentevo_port_7f7_w(offs_t offset, u8 data);
|
||||
void pentevo_port_bf7_w(offs_t offset, u8 data);
|
||||
void pentevo_port_eff7_w(offs_t offset, u8 data);
|
||||
u8 pentevo_port_bf_r(offs_t offset);
|
||||
void pentevo_port_bf_w(offs_t offset, u8 data);
|
||||
u8 pentevo_port_0nbd_r(offs_t offset);
|
||||
u8 pentevo_port_1nbd_r(offs_t offset);
|
||||
void pentevo_port_1nbd_w(offs_t offset, u8 data);
|
||||
|
||||
void spi_port_77_w(offs_t offset, u8 data);
|
||||
u8 spi_port_57_r(offs_t offset);
|
||||
void spi_port_57_w(offs_t offset, u8 data);
|
||||
void spi_miso_w(u8 data);
|
||||
u8 nemo_ata_r(u8 cmd);
|
||||
void nemo_ata_w(u8 cmd, u8 data);
|
||||
u8 gluk_data_r(offs_t offset);
|
||||
void gluk_data_w(offs_t offset, u8 data);
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(nmi_check_callback);
|
||||
void nmi_on();
|
||||
|
||||
void atm_update_cpu() override;
|
||||
void atm_update_io() override;
|
||||
u8 merge_ram_with_7ffd(u8 ram_page) override;
|
||||
bool is_port_7ffd_locked() override { return !is_pent1024() && BIT(m_port_7ffd_data, 5); }
|
||||
bool is_pent1024() { return !BIT(m_port_eff7_data, 2); }
|
||||
|
||||
void spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) override;
|
||||
void pentevo_update_screen_zxhw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void pentevo_update_screen_zx16(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
void pentevo_update_screen_tx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
u16 atm_update_memory_get_page(u8 bank) override;
|
||||
INTERRUPT_GEN_MEMBER(pentevo_interrupt);
|
||||
|
||||
required_device<gfxdecode_device> m_gfxdecode;
|
||||
required_device<ram_device> m_char_ram;
|
||||
memory_view m_io_dos_view;
|
||||
|
||||
required_device<glukrs_device> m_glukrs;
|
||||
required_device<spi_sdcard_sdhc_device> m_sdcard;
|
||||
required_device<at_keyboard_device> m_keyboard;
|
||||
required_ioport_array<3> m_io_mouse;
|
||||
|
||||
u8 m_port_bf_data;
|
||||
u8 m_port_eff7_data;
|
||||
u8 m_beta_drive_virtual;
|
||||
|
||||
u8 m_gluk_ext;
|
||||
bool m_ata_data_hi_ready;
|
||||
u16 m_nmi_trap_offset;
|
||||
bool m_nmi_active;
|
||||
u8 m_nmi_active_flip_countdown;
|
||||
|
||||
u8 m_zctl_di = 0;
|
||||
u8 m_zctl_cs = 0;
|
||||
};
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* ZX Evolution: BASECONF
|
||||
* ***************************************************************************/
|
||||
|
||||
void pentevo_state::atm_update_cpu()
|
||||
{
|
||||
u8 multiplier = BIT(m_port_77_data, 3) ? 4 : (2 - BIT(m_port_eff7_data, 4));
|
||||
m_maincpu->set_clock(X1_128_SINCLAIR / 10 * multiplier);
|
||||
}
|
||||
|
||||
void pentevo_state::atm_update_io()
|
||||
{
|
||||
if (BIT(m_port_bf_data, 0) || is_dos_active())
|
||||
{
|
||||
m_io_view.select(0);
|
||||
if (m_beta_drive_selected && m_beta_drive_virtual == m_beta_drive_selected)
|
||||
m_io_dos_view.disable();
|
||||
else
|
||||
m_io_dos_view.select(0);
|
||||
|
||||
m_glukrs->enable();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_io_view.disable();
|
||||
if (BIT(m_port_eff7_data, 7))
|
||||
m_glukrs->enable();
|
||||
else
|
||||
m_glukrs->disable();
|
||||
}
|
||||
}
|
||||
|
||||
u16 pentevo_state::atm_update_memory_get_page(u8 bank)
|
||||
{
|
||||
if (bank == 0)
|
||||
{
|
||||
if (BIT(m_port_eff7_data, 3))
|
||||
return ~PEN_RAMNROM_MASK & 0x00;
|
||||
else if (m_nmi_active)
|
||||
return PEN_RAMNROM_MASK | 0xff;
|
||||
else if (m_beta_drive_selected && m_beta_drive_virtual == m_beta_drive_selected)
|
||||
return PEN_RAMNROM_MASK | 0xfe;
|
||||
}
|
||||
return atm_state::atm_update_memory_get_page(bank);
|
||||
}
|
||||
|
||||
void pentevo_state::atm_port_ff_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (BIT(m_port_bf_data, 5) && !m_pen2)
|
||||
{
|
||||
u8 pen = get_border_color(m_screen->hpos(), m_screen->vpos());
|
||||
m_palette_data[pen] = data;
|
||||
m_palette->set_pen_color(pen,
|
||||
(BIT(~data, 1) * 0x88) | (BIT(~data, 6) * 0x44) | (BIT(~offset, 9) * 0x22) | (BIT(~offset, 14) * 0x11),
|
||||
(BIT(~data, 4) * 0x88) | (BIT(~data, 7) * 0x44) | (BIT(~offset, 12) * 0x22) | (BIT(~offset, 15) * 0x11),
|
||||
(BIT(~data, 0) * 0x88) | (BIT(~data, 5) * 0x44) | (BIT(~offset, 8) * 0x22) | (BIT(~offset, 13) * 0x11));
|
||||
}
|
||||
else
|
||||
{
|
||||
atm_state::atm_port_ff_w(offset, data);
|
||||
}
|
||||
}
|
||||
|
||||
TIMER_DEVICE_CALLBACK_MEMBER(pentevo_state::nmi_check_callback)
|
||||
{
|
||||
if ((m_io_nmi->read() & 0x01) && !m_nmi_active)
|
||||
nmi_on();
|
||||
}
|
||||
|
||||
void pentevo_state::nmi_on()
|
||||
{
|
||||
m_nmi_active = true;
|
||||
m_nmi_active_flip_countdown = 0;
|
||||
atm_update_memory();
|
||||
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
|
||||
}
|
||||
|
||||
u8 pentevo_state::merge_ram_with_7ffd(u8 ram_page)
|
||||
{
|
||||
u8 page = atm_state::merge_ram_with_7ffd(ram_page);
|
||||
if (is_pent1024())
|
||||
page = (page & ~0x38) | ((m_port_7ffd_data & 0xe0) >> 2);
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_port_eff7_w(offs_t offset, u8 data)
|
||||
{
|
||||
u8 changed = m_port_eff7_data ^ data;
|
||||
m_port_eff7_data = data;
|
||||
|
||||
if (BIT(changed, 3)) atm_update_memory();
|
||||
if (BIT(changed, 4)) atm_update_cpu();
|
||||
if (BIT(changed, 7)) atm_update_io();
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_port_7f7_w(offs_t offset, u8 data)
|
||||
{
|
||||
u8 bank = offset >> 14;
|
||||
u16 page = (pen_page(bank) & PEN_DOS7FFD_MASK) | PEN_RAMNROM_MASK | u8(~data);
|
||||
|
||||
LOGMEM("EVO%s=%X RAM%d%s%02X\n", BIT(m_port_7ffd_data, 4), data, bank, (page & PEN_DOS7FFD_MASK) ? "+" : " ", page & ram_pages_mask);
|
||||
pen_page(bank) = page;
|
||||
atm_update_memory();
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_port_bf7_w(offs_t offset, u8 data)
|
||||
{
|
||||
u8 bank = offset >> 14;
|
||||
if (BIT(data, 0))
|
||||
pen_page(bank) |= PEN_WRDISBL_MASK;
|
||||
else
|
||||
pen_page(bank) &= ~PEN_WRDISBL_MASK;
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_port_bf_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (BIT(m_port_bf_data, 3) && !BIT(data, 3)) // 1>0
|
||||
// Due to the fact current z80 handles NMI detection before (not after) instruction OUT(#BF),0:HALT freezes driver.
|
||||
// With fixed z80 this must be replaced with:
|
||||
// nmi_on()
|
||||
m_nmi_active_flip_countdown = 1;
|
||||
|
||||
m_port_bf_data = data;
|
||||
atm_update_io();
|
||||
}
|
||||
|
||||
u8 pentevo_state::pentevo_port_bf_r(offs_t offset)
|
||||
{
|
||||
return m_port_bf_data & 0x1f;
|
||||
}
|
||||
|
||||
u8 pentevo_state::pentevo_port_0nbd_r(offs_t offset)
|
||||
{
|
||||
u8 opt = (offset >> 8) & 0x0f;
|
||||
if (opt <= 0x07)
|
||||
return ~(m_pages_map[BIT(opt, 2)][opt & 0x03] & 0xff);
|
||||
else if (opt == 0x08 || opt == 0x09)
|
||||
{
|
||||
u8 data = 0;
|
||||
for (s8 i = 7; i >= 0; i--)
|
||||
data = (data << 1) | bool(m_pages_map[BIT(i, 2)][i & 0x03] & (opt == 0x08 ? PEN_RAMNROM_MASK : PEN_DOS7FFD_MASK));
|
||||
return data;
|
||||
}
|
||||
else if (opt == 0x0a)
|
||||
return m_port_7ffd_data;
|
||||
else if (opt == 0x0b)
|
||||
return m_port_eff7_data;
|
||||
else if (opt == 0x0c)
|
||||
return (m_pen2 << 7) | (m_cpm_n << 6) | (m_pen << 5) | ((m_nmi_active && m_beta->is_active()) << 4) | (m_port_77_data & 0x0f);
|
||||
else if (opt == 0x0d)
|
||||
return m_palette_data[get_border_color(m_screen->hpos(), m_screen->vpos())];
|
||||
else if (opt == 0x0e)
|
||||
{
|
||||
u8* screen_location = m_ram->pointer() + ((BIT(m_port_7ffd_data, 3) ? 10 : 8) << 14);
|
||||
u16 y = m_screen->vpos() - get_screen_area().top();
|
||||
u16 x = m_screen->hpos() - get_screen_area().left();
|
||||
u8 *symb_location = screen_location + 0x1c0 + (x >> 4) + ((y >> 3) * 64);
|
||||
if (BIT(x, 3)) symb_location += 0x1000;
|
||||
return m_char_ram->read((*symb_location << 3) + (y & 0x07));
|
||||
}
|
||||
else //if (opt == 0x0f)
|
||||
return get_border_color(m_screen->hpos(), m_screen->vpos());
|
||||
}
|
||||
|
||||
u8 pentevo_state::pentevo_port_1nbd_r(offs_t offset)
|
||||
{
|
||||
u8 opt = (offset >> 8) & 0x03;
|
||||
if (opt == 0x00)
|
||||
return m_nmi_trap_offset & 0x0f;
|
||||
else if (opt == 0x01)
|
||||
return (m_nmi_trap_offset & 0xf0) >> 8;
|
||||
else if (opt == 0x02)
|
||||
{
|
||||
u8 data = 0;
|
||||
for (s8 i = 7; i >= 0; i--)
|
||||
data = (data << 1) | bool(m_pages_map[BIT(i, 2)][i & 0x03] & PEN_WRDISBL_MASK);
|
||||
return data;
|
||||
}
|
||||
else //if (opt == 0x03)
|
||||
return m_beta_drive_virtual;
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_port_1nbd_w(offs_t offset, u8 data)
|
||||
{
|
||||
u8 opt = (offset >> 8) & 0x03;
|
||||
if (opt == 0x00)
|
||||
m_nmi_trap_offset = (m_nmi_trap_offset & 0xf0) | data;
|
||||
else if (opt == 0x01)
|
||||
m_nmi_trap_offset = (m_nmi_trap_offset & 0x0f) | (data << 8);
|
||||
else if (opt == 0x02)
|
||||
{
|
||||
u8 data = 0;
|
||||
for (s8 i = 7; i >= 0; i--)
|
||||
{
|
||||
m_pages_map[BIT(i, 2)][i & 0x03] &= ~PEN_WRDISBL_MASK;
|
||||
if (BIT(data, i)) m_pages_map[BIT(i, 2)][i & 0x03] |= PEN_WRDISBL_MASK;
|
||||
}
|
||||
}
|
||||
else if (opt == 0x03)
|
||||
m_beta_drive_virtual = data & 0x0f;
|
||||
}
|
||||
|
||||
INTERRUPT_GEN_MEMBER(pentevo_state::pentevo_interrupt)
|
||||
{
|
||||
// 17989=80*224+69 z80(3.5Hz) clocks between INT and screen paper begins. Screen clock is 7Hz.
|
||||
m_irq_on_timer->adjust(m_screen->time_until_pos(80 - 80, 80) - m_screen->clocks_to_attotime(128));
|
||||
}
|
||||
|
||||
void pentevo_state::spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
if (m_rg == 0b011 && (BIT(m_port_eff7_data, 0) || BIT(m_port_eff7_data, 5)))
|
||||
{
|
||||
if (BIT(m_port_eff7_data, 5))
|
||||
pentevo_update_screen_zxhw(screen, bitmap, cliprect);
|
||||
else
|
||||
pentevo_update_screen_zx16(screen, bitmap, cliprect);
|
||||
}
|
||||
else if (m_rg == 0b111)
|
||||
pentevo_update_screen_tx(screen, bitmap, cliprect);
|
||||
else
|
||||
atm_state::spectrum_update_screen(screen, bitmap, cliprect);
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_update_screen_zxhw(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
bool invert_attrs = u64(screen.frame_number() / m_frame_invert_count) & 1;
|
||||
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
|
||||
{
|
||||
u16 hpos = cliprect.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 = &scr[0x2000];
|
||||
u16 *pix = &(bitmap.pix(vpos, hpos));
|
||||
|
||||
while (hpos <= cliprect.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 % 8)); b; b >>= 1, x++, hpos++)
|
||||
*pix++ = (pix8 & b) ? ink : pap;
|
||||
scr++;
|
||||
attr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_update_screen_zx16(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
// TODO attrs not decoded
|
||||
for (u16 vpos = cliprect.top(); vpos <= cliprect.bottom(); vpos++)
|
||||
{
|
||||
u16 hpos = cliprect.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)];
|
||||
u16 *pix = &(bitmap.pix(vpos, hpos));
|
||||
|
||||
while (hpos <= cliprect.right())
|
||||
{
|
||||
u16 ink = 0;
|
||||
u16 pap = 7;
|
||||
u8 pix8 = *scr;
|
||||
|
||||
for (u8 b = (0x80 >> (x % 8)); b; b >>= 1, x++, hpos++)
|
||||
*pix++ = (pix8 & b) ? ink : pap;
|
||||
scr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_update_screen_tx(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
u8* screen_location = m_ram->pointer() + ((BIT(m_port_7ffd_data, 3) ? 10 : 8) << 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 *symb_location = screen_location + 0x1c0 + (x >> 4) + ((y >> 3) * 64);
|
||||
u8 *attr_location = symb_location + 0x2000 + BIT(x, 3);
|
||||
if (BIT(x, 3))
|
||||
symb_location += 0x1000;
|
||||
else
|
||||
attr_location += 0x1000;
|
||||
|
||||
u8 attr = *attr_location;
|
||||
u8 fg = ((attr & 0x40) >> 3) | (attr & 0x07);
|
||||
u8 bg = (((attr & 0x80) >> 1) | (attr & 0x38)) >> 3;
|
||||
|
||||
u8 chunk = m_char_ram->read((*symb_location << 3) + (y & 0x07));
|
||||
for (u8 i = 0x80; i; i >>= 1)
|
||||
{
|
||||
bitmap.pix(vpos, hpos++) = (chunk & i) ? fg : bg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
u8 pentevo_state::nemo_ata_r(u8 cmd)
|
||||
{
|
||||
if (machine().side_effects_disabled())
|
||||
return 0xff;
|
||||
|
||||
bool data_read = (cmd & 0x7) == 0;
|
||||
u8 data;
|
||||
if (data_read && m_ata_data_hi_ready)
|
||||
{
|
||||
data = m_ata_data_latch;
|
||||
m_ata_data_hi_ready = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = atm_state::ata_r(cmd << 5);
|
||||
m_ata_data_hi_ready = data_read;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void pentevo_state::nemo_ata_w(u8 cmd, u8 data)
|
||||
{
|
||||
bool data_write = (cmd & 0x7) == 0;
|
||||
if (data_write && !m_ata_data_hi_ready)
|
||||
{
|
||||
m_ata_data_latch = data;
|
||||
m_ata_data_hi_ready = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
atm_state::ata_w(cmd << 5, data);
|
||||
m_ata_data_hi_ready = false;
|
||||
}
|
||||
}
|
||||
|
||||
void pentevo_state::spi_port_77_w(offs_t offset, u8 data)
|
||||
{
|
||||
m_sdcard->spi_ss_w(BIT(data, 0));
|
||||
m_zctl_cs = BIT(data, 1);
|
||||
}
|
||||
|
||||
u8 pentevo_state::spi_port_57_r(offs_t offset)
|
||||
{
|
||||
if (m_zctl_cs)
|
||||
return 0xff;
|
||||
|
||||
u8 din = m_zctl_di;
|
||||
if (!machine().side_effects_disabled())
|
||||
spi_port_57_w(0, 0xff);
|
||||
|
||||
return din;
|
||||
}
|
||||
|
||||
void pentevo_state::spi_port_57_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (!m_zctl_cs)
|
||||
{
|
||||
for (u8 m = 0x80; m; m >>= 1)
|
||||
{
|
||||
m_sdcard->spi_clock_w(CLEAR_LINE); // 0-S R
|
||||
m_sdcard->spi_mosi_w(data & m ? 1 : 0);
|
||||
m_sdcard->spi_clock_w(ASSERT_LINE); // 1-L W
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void pentevo_state::spi_miso_w(u8 data)
|
||||
{
|
||||
m_zctl_di <<= 1;
|
||||
m_zctl_di |= data;
|
||||
}
|
||||
|
||||
u8 pentevo_state::gluk_data_r(offs_t offset)
|
||||
{
|
||||
if (m_glukrs->is_active())
|
||||
{
|
||||
if (m_gluk_ext == 2)
|
||||
return m_keyboard->read();
|
||||
else if (m_glukrs->address_r() == 0x0a)
|
||||
return 0x20 | (m_glukrs->data_r() & 0x0f);
|
||||
else if (m_glukrs->address_r() == 0x0b)
|
||||
return 0x02 | (m_glukrs->data_r() & 0x04);
|
||||
else if (m_glukrs->address_r() == 0x0c)
|
||||
return 0x10;
|
||||
else if (m_glukrs->address_r() == 0x0d)
|
||||
return 0x80;
|
||||
}
|
||||
return m_glukrs->data_r(); // returns 0xff if inactive
|
||||
}
|
||||
|
||||
void pentevo_state::gluk_data_w(offs_t offset, u8 data)
|
||||
{
|
||||
if (!m_glukrs->is_active())
|
||||
return;
|
||||
|
||||
u8 addr = m_glukrs->address_r();
|
||||
if (addr >= 0xf0 && addr <= 0xf0)
|
||||
{
|
||||
m_gluk_ext = data;
|
||||
u8 m_fx[0xf] = {0x00};
|
||||
if (data == 0 || data == 1) // BASECONF_VERSION + BOOTLOADER_VERSION
|
||||
{
|
||||
strcpy((char *)m_fx, "M.A.M.E.");
|
||||
PAIR16 m_ver;
|
||||
m_ver.w = ((22 << 9) | (9 << 5) | 3); // y.m.d
|
||||
m_fx[0x0c] = m_ver.b.l;
|
||||
m_fx[0x0d] = m_ver.b.h;
|
||||
}
|
||||
|
||||
for (u8 i = 0; i < 0xf; i++)
|
||||
{
|
||||
m_glukrs->address_w(0xf0 + i);
|
||||
m_glukrs->data_w(m_fx[i]);
|
||||
}
|
||||
m_glukrs->address_w(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_glukrs->data_w(data);
|
||||
}
|
||||
}
|
||||
|
||||
void pentevo_state::pentevo_io(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
|
||||
// PORTS: Always
|
||||
map(0x00f6, 0x00f6).select(0xff08).rw(FUNC(pentevo_state::spectrum_ula_r), FUNC(pentevo_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(pentevo_state::atm_port_7ffd_w));
|
||||
|
||||
// Gluk
|
||||
map(0xdff7, 0xdff7).lw8(NAME([this](offs_t offset, u8 data) { m_glukrs->address_w(data); } ));
|
||||
map(0xbff7, 0xbff7).rw(FUNC(pentevo_state::gluk_data_r), FUNC(pentevo_state::gluk_data_w));
|
||||
|
||||
// Configuration
|
||||
map(0xeff7, 0xeff7).w(FUNC(pentevo_state::pentevo_port_eff7_w));
|
||||
map(0x00bf, 0x00bf).select(0xff00).rw(FUNC(pentevo_state::pentevo_port_bf_r), FUNC(pentevo_state::pentevo_port_bf_w));
|
||||
map(0x00be, 0x00be).select(0x0f00).r(FUNC(pentevo_state::pentevo_port_0nbd_r));
|
||||
map(0x00bd, 0x00bd).select(0x0f00).r(FUNC(pentevo_state::pentevo_port_0nbd_r));
|
||||
map(0x10be, 0x10be).select(0x0f00).r(FUNC(pentevo_state::pentevo_port_1nbd_r));
|
||||
map(0x10bd, 0x10bd).select(0x0f00).rw(FUNC(pentevo_state::pentevo_port_1nbd_r), FUNC(pentevo_state::pentevo_port_1nbd_w));
|
||||
map(0x00be, 0x00be).select(0xff00).lw8(NAME([this](offs_t offset) { m_nmi_active_flip_countdown = 2; }));
|
||||
|
||||
// AY
|
||||
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));
|
||||
|
||||
// HDD: NEMO
|
||||
map(0x0010, 0x0010).select(0xffe0).lrw8(NAME([this](offs_t offset) { return nemo_ata_r(offset >> 5); })
|
||||
, NAME([this](offs_t offset, u8 data) { nemo_ata_w(offset >> 5, data); }));
|
||||
map(0x0011, 0x0011).mirror(0xff00).lrw8(NAME([this]() { m_ata_data_hi_ready = false; return m_ata_data_latch; })
|
||||
, NAME([this](offs_t offset, u8 data) { m_ata_data_hi_ready = true; m_ata_data_latch = data; }));
|
||||
map(0x00c8, 0x00c8).mirror(0xff00).lrw8(NAME([this]() { return m_ata->cs1_r(6 /* ? */); })
|
||||
, NAME([this](offs_t offset, u8 data) { m_ata->cs1_w(6, data); }));
|
||||
|
||||
// SPI
|
||||
map(0x0077, 0x0077).select(0xff00).lr8(NAME([]() { return 0x00; })).w(FUNC(pentevo_state::spi_port_77_w));
|
||||
map(0x0057, 0x0057).select(0xff00).rw(FUNC(pentevo_state::spi_port_57_r), FUNC(pentevo_state::spi_port_57_w));
|
||||
|
||||
// Mouse
|
||||
map(0xfadf, 0xfadf).lr8(NAME([this]() { return 0x80 | (m_io_mouse[2]->read() & 0x07); }));
|
||||
map(0xfbdf, 0xfbdf).lr8(NAME([this]() { return m_io_mouse[0]->read(); }));
|
||||
map(0xffdf, 0xffdf).lr8(NAME([this]() { return ~m_io_mouse[1]->read(); }));
|
||||
map(0x001f, 0x001f).mirror(0xff00).lr8(NAME([]() { return 0x00; })); // TODO Kepmston Joystick
|
||||
|
||||
// PORTS: Shadow
|
||||
map(0x0000, 0xffff).view(m_io_view);
|
||||
m_io_view[0](0x0000, 0xffff).view(m_io_dos_view);
|
||||
m_io_dos_view[0](0x001f, 0x001f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::status_r), FUNC(beta_disk_device::command_w));
|
||||
m_io_dos_view[0](0x003f, 0x003f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::track_r), FUNC(beta_disk_device::track_w));
|
||||
m_io_dos_view[0](0x005f, 0x005f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::sector_r), FUNC(beta_disk_device::sector_w));
|
||||
m_io_dos_view[0](0x007f, 0x007f).mirror(0xff00).rw(m_beta, FUNC(beta_disk_device::data_r), FUNC(beta_disk_device::data_w));
|
||||
m_io_dos_view[0](0x00ff, 0x00ff).select(0xff00).r(m_beta, FUNC(beta_disk_device::state_r));
|
||||
|
||||
m_io_view[0](0x00ff, 0x00ff).select(0xff00).w(FUNC(pentevo_state::atm_port_ff_w));
|
||||
m_io_view[0](0x0077, 0x0077).select(0xff00).lr8(NAME([]() { return 0xff; })).w(FUNC(pentevo_state::atm_port_77_w));
|
||||
m_io_view[0](0x3ff7, 0x3ff7).select(0xc000).w(FUNC(pentevo_state::atm_port_f7_w)); // ATM
|
||||
m_io_view[0](0x37f7, 0x37f7).select(0xc000).w(FUNC(pentevo_state::pentevo_port_7f7_w)); // PENTEVO
|
||||
m_io_view[0](0x3bf7, 0x3bf7).select(0xc000).w(FUNC(pentevo_state::pentevo_port_bf7_w)); // RO
|
||||
|
||||
// SPI
|
||||
m_io_view[0](0x0057, 0x0057).select(0xff00)
|
||||
.lw8(NAME([this](offs_t offset, u8 data) { if (BIT(offset, 15)) spi_port_77_w(offset, data); else spi_port_57_w(offset, data); }));
|
||||
|
||||
// Gluk
|
||||
m_io_view[0](0xdef7, 0xdef7).lw8(NAME([this](offs_t offset, u8 data) { m_glukrs->address_w(data); } ));
|
||||
m_io_view[0](0xbef7, 0xbef7).rw(FUNC(pentevo_state::gluk_data_r), FUNC(pentevo_state::gluk_data_w));
|
||||
}
|
||||
|
||||
void pentevo_state::init_mem_write()
|
||||
{
|
||||
address_space &mem = m_maincpu->space(AS_PROGRAM);
|
||||
mem.install_write_tap(0x0000, 0xffff, "charrom_w", [this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (BIT(m_port_bf_data, 2))
|
||||
{
|
||||
m_char_ram->write(offset & 0x7ff, data);
|
||||
m_gfxdecode->gfx(0)->mark_dirty((offset & 0x7ff) / 8);
|
||||
}
|
||||
}
|
||||
return data;
|
||||
});
|
||||
|
||||
address_space &opc = m_maincpu->space(AS_OPCODES);
|
||||
opc.install_read_tap(0x0000, 0xffff, "nmi_exit", [this](offs_t offset, u8 &data, u8 mem_mask)
|
||||
{
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_nmi_active_flip_countdown)
|
||||
{
|
||||
if(--m_nmi_active_flip_countdown == 0)
|
||||
{
|
||||
if (m_nmi_active)
|
||||
{
|
||||
m_nmi_active = false;
|
||||
atm_update_memory();
|
||||
}
|
||||
else
|
||||
nmi_on(); // see: pentevo_port_bf_w()
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void pentevo_state::machine_start()
|
||||
{
|
||||
atm_state::machine_start();
|
||||
|
||||
save_item(NAME(m_port_bf_data));
|
||||
save_item(NAME(m_port_eff7_data));
|
||||
save_item(NAME(m_beta_drive_virtual));
|
||||
save_item(NAME(m_gluk_ext));
|
||||
save_item(NAME(m_ata_data_hi_ready));
|
||||
save_item(NAME(m_nmi_trap_offset));
|
||||
save_item(NAME(m_nmi_active));
|
||||
save_item(NAME(m_nmi_active_flip_countdown));
|
||||
save_item(NAME(m_zctl_di));
|
||||
save_item(NAME(m_zctl_cs));
|
||||
|
||||
init_mem_write();
|
||||
}
|
||||
|
||||
void pentevo_state::machine_reset()
|
||||
{
|
||||
m_nmi_active = false;
|
||||
m_port_eff7_data = 0;
|
||||
atm_state::machine_reset();
|
||||
|
||||
m_port_bf_data = 0;
|
||||
m_nmi_active_flip_countdown = 0;
|
||||
m_beta_drive_virtual = 0;
|
||||
|
||||
m_ata_data_hi_ready = false;
|
||||
m_gluk_ext = 0xff;
|
||||
m_zctl_cs = 1;
|
||||
m_zctl_di = 0xff;
|
||||
|
||||
m_keyboard->write(0xff);
|
||||
while (m_keyboard->read() != 0) { /* invalidate buffer */ }
|
||||
}
|
||||
|
||||
void pentevo_state::video_start()
|
||||
{
|
||||
atm_state::video_start();
|
||||
m_char_location = m_char_ram->pointer();
|
||||
m_gfxdecode->gfx(0)->set_source(m_char_location);
|
||||
}
|
||||
|
||||
INPUT_PORTS_START( pentevo )
|
||||
PORT_INCLUDE( spec_plus )
|
||||
|
||||
PORT_START("mouse_input1")
|
||||
PORT_BIT(0xff, 0, IPT_MOUSE_X) PORT_SENSITIVITY(30)
|
||||
|
||||
PORT_START("mouse_input2")
|
||||
PORT_BIT(0xff, 0, IPT_MOUSE_Y) PORT_SENSITIVITY(30)
|
||||
|
||||
PORT_START("mouse_input3")
|
||||
PORT_BIT(0x01, IP_ACTIVE_LOW, IPT_BUTTON4) PORT_NAME("Left mouse button") PORT_CODE(MOUSECODE_BUTTON1)
|
||||
PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_BUTTON5) PORT_NAME("Right mouse button") PORT_CODE(MOUSECODE_BUTTON2)
|
||||
PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_BUTTON6) PORT_NAME("Middle mouse button") PORT_CODE(MOUSECODE_BUTTON3)
|
||||
|
||||
INPUT_PORTS_END
|
||||
|
||||
void pentevo_state::pentevo(machine_config &config)
|
||||
{
|
||||
atmtb2(config);
|
||||
m_maincpu->set_addrmap(AS_IO, &pentevo_state::pentevo_io);
|
||||
m_maincpu->set_vblank_int("screen", FUNC(pentevo_state::pentevo_interrupt));
|
||||
TIMER(config, "nmi_timer").configure_periodic(FUNC(pentevo_state::nmi_check_callback), attotime::from_hz(50));
|
||||
|
||||
m_screen->set_raw(X1_128_SINCLAIR / 5, 448, 320, {get_screen_area().left() - 40, get_screen_area().right() + 40, get_screen_area().top() - 40, get_screen_area().bottom() + 40});
|
||||
|
||||
m_ram->set_default_size("4M");
|
||||
RAM(config, m_char_ram).set_default_size("2048").set_default_value(0);
|
||||
|
||||
GLUKRS(config, m_glukrs);
|
||||
SPI_SDCARD(config, m_sdcard, 0);
|
||||
m_sdcard->spi_miso_callback().set(FUNC(pentevo_state::spi_miso_w));
|
||||
|
||||
AT_KEYB(config, m_keyboard, pc_keyboard_device::KEYBOARD_TYPE::AT, 3);
|
||||
}
|
||||
|
||||
|
||||
ROM_START( pentevo )
|
||||
ROM_REGION(0x090000, "maincpu", ROMREGION_ERASEFF)
|
||||
ROM_DEFAULT_BIOS("v0.59.02fe_tr503")
|
||||
|
||||
// http://svn.zxevo.ru/revision.php?repname=pentevo&path=%2From%2Fzxevo_fe.rom&rev=1012&peg=1021
|
||||
ROM_SYSTEM_BIOS(0, "v0.59.02fe_tr503", "Reset Service v0.59.02 (FE), TR-DOS v5.03")
|
||||
ROMX_LOAD( "zxevo_05902fe_trd503.rom", 0x010000, 0x80000, CRC(f7f29dd8) SHA1(dfbcce980cf6244a9491aedf68ebb372677b0593), ROM_BIOS(0))
|
||||
ROM_SYSTEM_BIOS(1, "v0.59.02fe", "Reset Service v0.59.02 (FE), NEO-DOS v0.53")
|
||||
ROMX_LOAD( "zxevo_05902fe.rom", 0x010000, 0x80000, CRC(df144c82) SHA1(e48b8a95576e0123764ff8cc34d9373dc95159bf), ROM_BIOS(1))
|
||||
|
||||
// http://svn.zxevo.ru/revision.php?repname=pentevo&path=%2Fcfgs%2Fstandalone_base_trdemu%2Ftrunk%2Fzxevo_fw.bin&rev=994&peg=1021
|
||||
ROM_REGION(0x0C280, "fw", ROMREGION_ERASEFF)
|
||||
ROM_LOAD( "zxevo_fw.bin", 0x0000, 0xC280, CRC(aefbd8e5) SHA1(ac9a551ba15eeead76b5527fd5d23d824ae5176f))
|
||||
ROM_END
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
|
||||
COMP( 2009, pentevo, spec128, 0, pentevo, pentevo, pentevo_state, empty_init, "NedoPC", "ZX Evolution: BASECONF", 0)
|
@ -6,8 +6,8 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_QIMI_H
|
||||
#define MAME_MACHINE_QIMI_H
|
||||
#ifndef MAME_SINCLAIR_QIMI_H
|
||||
#define MAME_SINCLAIR_QIMI_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -62,4 +62,4 @@ private:
|
||||
DECLARE_DEVICE_TYPE(QIMI, qimi_device)
|
||||
|
||||
|
||||
#endif // MAME_MACHINE_QIMI_H
|
||||
#endif // MAME_SINCLAIR_QIMI_H
|
||||
|
@ -135,10 +135,12 @@ u8 scorpion_state::beta_neutral_r(offs_t offset)
|
||||
|
||||
u8 scorpion_state::beta_enable_r(offs_t offset)
|
||||
{
|
||||
if (!(machine().side_effects_disabled())) {
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_maincpu->total_cycles() & 1) m_maincpu->eat_cycles(1);
|
||||
|
||||
if (m_beta->started() && m_bank_rom[0]->entry() == 1) {
|
||||
if (m_beta->started() && m_bank_rom[0]->entry() == 1)
|
||||
{
|
||||
m_beta->enable();
|
||||
m_bank_rom[0]->set_entry(3);
|
||||
}
|
||||
@ -148,10 +150,12 @@ u8 scorpion_state::beta_enable_r(offs_t offset)
|
||||
|
||||
u8 scorpion_state::beta_disable_r(offs_t offset)
|
||||
{
|
||||
if (!(machine().side_effects_disabled())) {
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_maincpu->total_cycles() & 1) m_maincpu->eat_cycles(1);
|
||||
|
||||
if (m_beta->started() && m_beta->is_active()) {
|
||||
if (m_beta->started() && m_beta->is_active())
|
||||
{
|
||||
m_beta->disable();
|
||||
m_bank_rom[0]->set_entry(BIT(m_port_7ffd_data, 4));
|
||||
}
|
||||
|
@ -6,8 +6,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_INCLUDES_SPEC128_H
|
||||
#define MAME_INCLUDES_SPEC128_H
|
||||
#ifndef MAME_SINCLAIR_SPEC128_H
|
||||
#define MAME_SINCLAIR_SPEC128_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -65,4 +65,4 @@ private:
|
||||
#define SPEC128_RETRACE_CYCLES 52
|
||||
#define SPEC128_CYCLES_PER_LINE 228
|
||||
|
||||
#endif // MAME_INCLUDES_SPEC128_H
|
||||
#endif // MAME_SINCLAIR_SPEC128_H
|
||||
|
@ -6,8 +6,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_SPEC_SNQK_H
|
||||
#define MAME_MACHINE_SPEC_SNQK_H
|
||||
#ifndef MAME_SINCLAIR_SPEC_SNQK_H
|
||||
#define MAME_SINCLAIR_SPEC_SNQK_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -164,4 +164,4 @@ enum SPECTRUM_Z80_SNAPSHOT_TYPE {
|
||||
#define RAW_HDR 9
|
||||
#define RAW_SIZE (RAW_HDR + 3*SPECTRUM_BANK)
|
||||
|
||||
#endif // MAME_MACHINE_SPEC_SNQK_H
|
||||
#endif // MAME_SINCLAIR_SPEC_SNQK_H
|
||||
|
@ -6,8 +6,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_INCLUDES_SPECPLS3_H
|
||||
#define MAME_INCLUDES_SPECPLS3_H
|
||||
#ifndef MAME_SINCLAIR_SPECPLS3_H
|
||||
#define MAME_SINCLAIR_SPECPLS3_H
|
||||
|
||||
#include "spectrum.h"
|
||||
#include "spec128.h"
|
||||
@ -55,4 +55,4 @@ private:
|
||||
optional_device_array<floppy_connector, 2> m_flop;
|
||||
};
|
||||
|
||||
#endif // MAME_INCLUDES_SPECPLS3_H
|
||||
#endif // MAME_SINCLAIR_SPECPLS3_H
|
||||
|
@ -6,8 +6,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_INCLUDES_SPECTRUM_H
|
||||
#define MAME_INCLUDES_SPECTRUM_H
|
||||
#ifndef MAME_SINCLAIR_SPECTRUM_H
|
||||
#define MAME_SINCLAIR_SPECTRUM_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -220,4 +220,4 @@ INPUT_PORTS_EXTERN( spectrum );
|
||||
INPUT_PORTS_EXTERN( spec128 );
|
||||
INPUT_PORTS_EXTERN( spec_plus );
|
||||
|
||||
#endif // MAME_INCLUDES_SPECTRUM_H
|
||||
#endif // MAME_SINCLAIR_SPECTRUM_H
|
||||
|
@ -116,7 +116,8 @@ u32 spectrum_state::screen_update_spectrum(screen_device &screen, bitmap_ind16 &
|
||||
{
|
||||
rectangle scr = get_screen_area();
|
||||
rectangle vis = screen.visible_area();
|
||||
if (vis != scr) {
|
||||
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()),
|
||||
@ -171,12 +172,12 @@ px: | 0 | 1 | 2 | 3 |*4*| 5 | 6 | 7 |*0*| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
||||
TODO Curren implementation only tracks char switch position. In order to track both (char and attr) we need to share
|
||||
some state between screen->update() events.
|
||||
*/
|
||||
void spectrum_state::spectrum_update_screen(screen_device &screen_d, bitmap_ind16 &bitmap, const rectangle &screen)
|
||||
void spectrum_state::spectrum_update_screen(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
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();
|
||||
bool chunk_right = x & 8;
|
||||
if (x % 8 <= (chunk_right ? 0 : 4))
|
||||
@ -197,7 +198,7 @@ void spectrum_state::spectrum_update_screen(screen_device &screen_d, bitmap_ind1
|
||||
u8 *attr = &m_screen_location[0x1800 + (((y & 0xf8) << 2) | (x >> 3))];
|
||||
u16 *pix = &(bitmap.pix(vpos, hpos));
|
||||
|
||||
while ((hpos + (chunk_right ? 0 : 4)) <= screen.right())
|
||||
while ((hpos + (chunk_right ? 0 : 4)) <= cliprect.right())
|
||||
{
|
||||
u16 ink = ((*attr >> 3) & 0x08) | (*attr & 0x07);
|
||||
u16 pap = (*attr >> 3) & 0x0f;
|
||||
|
@ -6,8 +6,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_INCLUDES_TIMEX_H
|
||||
#define MAME_INCLUDES_TIMEX_H
|
||||
#ifndef MAME_SINCLAIR_TIMEX_H
|
||||
#define MAME_SINCLAIR_TIMEX_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -100,4 +100,4 @@ private:
|
||||
};
|
||||
|
||||
|
||||
#endif // MAME_INCLUDES_TIMEX_H
|
||||
#endif // MAME_SINCLAIR_TIMEX_H
|
||||
|
@ -2,21 +2,7 @@
|
||||
// copyright-holders:Andrei I. Holub
|
||||
/***************************************************************************
|
||||
|
||||
TS-Configuration (ZX Evolution) machine driver.
|
||||
Implementation: Revision C / 5-bit VDAC
|
||||
|
||||
Hobby computer ZX Evolution is Spectrum-compatible with extensions.
|
||||
|
||||
Hardware (ZX Evolution):
|
||||
- Z80 3.5 MHz (classic mode)/ 7 MHz (turbo mode without CPU wait circles)/ 14 MHz (mega turbo with CPU wait circles);
|
||||
- 4 Mb RAM, 512Kb ROM;
|
||||
- MiniITX board (172x170mm), 2 ZXBUS slots, power ATX or +5,+12V;
|
||||
- Based on fpga (Altera EP1K50);
|
||||
- Peripheral MCU ATMEGA128;
|
||||
- PS/2 keyboard and mouse support;
|
||||
- Floppy (WDC1793) Beta-disk compatible interface, IDE (one channel, up to 2 devices on master/slave mode), SD(HC) card, RS232;
|
||||
- Sound: AY, Beeper, Covox (PWM);
|
||||
- Real-time clock.
|
||||
see: pentevo.cpp
|
||||
|
||||
Features (TS-Configuration):
|
||||
- Resolutions: 360x288, 320x240, 320x200, 256x192
|
||||
@ -36,16 +22,12 @@ Features (TS-Configuration):
|
||||
- DRAM-to-Device, Device-to-DRAM and DRAM-to-DRAM DMA Controller
|
||||
|
||||
Refs:
|
||||
ZxEvo: http://nedopc.com/zxevo/zxevo_eng.php
|
||||
Principal scheme (rev. C) :: http://nedopc.com/zxevo/zxevo_sch_revc.pdf
|
||||
Montage scheme (rev. C) :: http://nedopc.com/zxevo/zxevo_mon_revc.pdf
|
||||
TsConf: https://github.com/tslabs/zx-evo/blob/master/pentevo/docs/TSconf/tsconf_en.md
|
||||
https://github.com/tslabs/zx-evo/raw/master/pentevo/docs/TSconf/TSconf.xls
|
||||
FAQ-RUS: https://forum.tslabs.info/viewtopic.php?f=35&t=157
|
||||
ROM: https://github.com/tslabs/zx-evo/blob/master/pentevo/rom/bin/ts-bios.rom (validated on: 2021-12-14)
|
||||
|
||||
HowTo:
|
||||
# Use ts-bios.rom above. You also need tr-dos roms which simpliest(?) to get from pentagon.
|
||||
# Create SD image "wc.img"
|
||||
# Copy WC files from archive https://github.com/tslabs/zx-evo/blob/master/pentevo/soft/WC/wc.zip
|
||||
# Tech Demos (currently *.spg only): http://prods.tslabs.info/index.php?t=4
|
||||
@ -66,6 +48,7 @@ TODO:
|
||||
|
||||
#include "emu.h"
|
||||
#include "tsconf.h"
|
||||
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "sound/ay8910.h"
|
||||
#include "speaker.h"
|
||||
@ -310,4 +293,4 @@ ROM_START(tsconf)
|
||||
ROM_END
|
||||
|
||||
// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
|
||||
COMP( 2011, tsconf, spec128, 0, tsconf, spec_plus, tsconf_state, empty_init, "NedoPC, TS-Labs", "ZX Evolution TS-Configuration", 0)
|
||||
COMP( 2011, tsconf, spec128, 0, tsconf, spec_plus, tsconf_state, empty_init, "NedoPC, TS-Labs", "ZX Evolution: TS-Configuration", 0)
|
||||
|
@ -5,8 +5,8 @@
|
||||
* includes/tsconfig.h
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifndef MAME_INCLUDES_TSCONF_H
|
||||
#define MAME_INCLUDES_TSCONF_H
|
||||
#ifndef MAME_SINCLAIR_TSCONF_H
|
||||
#define MAME_SINCLAIR_TSCONF_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -214,4 +214,4 @@ private:
|
||||
|
||||
INPUT_PORTS_EXTERN(tsconf);
|
||||
|
||||
#endif // MAME_INCLUDES_TSCONF_H
|
||||
#endif // MAME_SINCLAIR_TSCONF_H
|
||||
|
@ -729,8 +729,14 @@ void tsconf_state::tsconf_port_57_zctr_w(offs_t port, u8 data)
|
||||
|
||||
u8 tsconf_state::tsconf_port_57_zctr_r(offs_t port)
|
||||
{
|
||||
tsconf_port_57_zctr_w(0, 0xff);
|
||||
return m_zctl_cs ? 0xff : m_zctl_di;
|
||||
if (m_zctl_cs)
|
||||
return 0xff;
|
||||
|
||||
u8 data = m_zctl_di;
|
||||
if (!machine().side_effects_disabled())
|
||||
tsconf_port_57_zctr_w(0, 0xff);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void tsconf_state::tsconf_spi_miso_w(u8 data)
|
||||
@ -819,7 +825,8 @@ u8 tsconf_state::beta_neutral_r(offs_t offset)
|
||||
|
||||
u8 tsconf_state::beta_enable_r(offs_t offset)
|
||||
{
|
||||
if (!(machine().side_effects_disabled())) {
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (!W0_RAM && m_bank_rom[0]->entry() == 3)
|
||||
{
|
||||
if (m_beta->started() && !m_beta->is_active())
|
||||
@ -834,7 +841,8 @@ u8 tsconf_state::beta_enable_r(offs_t offset)
|
||||
|
||||
u8 tsconf_state::beta_disable_r(offs_t offset)
|
||||
{
|
||||
if (!(machine().side_effects_disabled())) {
|
||||
if (!machine().side_effects_disabled())
|
||||
{
|
||||
if (m_beta->started() && m_beta->is_active())
|
||||
{
|
||||
m_beta->disable();
|
||||
|
@ -6,8 +6,8 @@
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef MAME_INCLUDES_ZX_H
|
||||
#define MAME_INCLUDES_ZX_H
|
||||
#ifndef MAME_SINCLAIR_ZX_H
|
||||
#define MAME_SINCLAIR_ZX_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -112,4 +112,4 @@ private:
|
||||
void recalc_hsync();
|
||||
};
|
||||
|
||||
#endif // MAME_INCLUDES_ZX_H
|
||||
#endif // MAME_SINCLAIR_ZX_H
|
||||
|
@ -29,8 +29,8 @@
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#ifndef MAME_MACHINE_ZX8302_H
|
||||
#define MAME_MACHINE_ZX8302_H
|
||||
#ifndef MAME_SINCLAIR_ZX8302_H
|
||||
#define MAME_SINCLAIR_ZX8302_H
|
||||
|
||||
#pragma once
|
||||
|
||||
@ -207,4 +207,4 @@ DECLARE_DEVICE_TYPE(ZX8302, zx8302_device)
|
||||
|
||||
|
||||
|
||||
#endif // MAME_MACHINE_ZX8302_H
|
||||
#endif // MAME_SINCLAIR_ZX8302_H
|
||||
|
Loading…
Reference in New Issue
Block a user