pofo: Expansion WIP. (nw)

This commit is contained in:
Curt Coder 2016-08-08 20:59:48 +03:00
parent d3da9b6e91
commit ac0dc89ec1
4 changed files with 395 additions and 182 deletions

View File

@ -10,6 +10,14 @@
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
#define LOG 0
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
@ -157,8 +165,12 @@ UINT8 hpc104_t::nrdi_r(address_space &space, offs_t offset, UINT8 data, bool iom
{
data = m_exp->nrdi_r(space, offset, data, iom, bcom, m_ncc1_out || ncc1);
if (!iom)
{
if (!(!m_ncc1_out || ncc1))
{
if (LOG) logerror("%s %s CCM0 read %05x\n", machine().time().as_string(), machine().describe_context(), offset & 0x1ffff);
data = m_ccm->nrdi_r(space, offset & 0x1ffff);
}
@ -176,6 +188,7 @@ UINT8 hpc104_t::nrdi_r(address_space &space, offs_t offset, UINT8 data, bool iom
data = m_nvram[offset - 0x1f000] = data;
}
}
}
return data;
}
@ -189,16 +202,12 @@ void hpc104_t::nwri_w(address_space &space, offs_t offset, UINT8 data, bool iom,
{
m_exp->nwri_w(space, offset, data, iom, bcom, m_ncc1_out || ncc1);
if (!bcom)
if (!iom)
{
if ((offset & 0x0f) == 0x0c)
{
m_ncc1_out = BIT(data, 0);
}
}
if (!(!m_ncc1_out || ncc1))
{
if (LOG) logerror("%s %s CCM1 write %05x:%02x\n", machine().time().as_string(), machine().describe_context(), offset & 0x1ffff, data);
m_ccm->nwri_w(space, offset & 0x1ffff, data);
}
@ -217,3 +226,16 @@ void hpc104_t::nwri_w(address_space &space, offs_t offset, UINT8 data, bool iom,
}
}
}
else
{
if (!bcom)
{
if ((offset & 0x0f) == 0x0c)
{
m_ncc1_out = BIT(data, 0);
if (LOG) logerror("NCC1 out %u\n", machine().time().as_string(), machine().describe_context(), m_ncc1_out);
}
}
}
}

View File

@ -41,7 +41,7 @@ protected:
virtual void nvram_write(emu_file &file) override { if (m_nvram != nullptr) { file.write(m_nvram, m_nvram.bytes()); } }
// device_portfolio_memory_card_slot_interface overrides
bool cdet() override { return 0; }
virtual bool cdet() override { return 0; }
virtual UINT8 nrdi_r(address_space &space, offs_t offset) override;
virtual void nwri_w(address_space &space, offs_t offset, UINT8 data) override;

View File

@ -34,7 +34,7 @@ protected:
virtual void device_start() override;
// device_portfolio_memory_card_slot_interface overrides
bool cdet() override { return 0; }
virtual bool cdet() override { return 0; }
virtual UINT8 nrdi_r(address_space &space, offs_t offset) override;
};

View File

@ -18,12 +18,13 @@
TODO:
- cursor is missing
- where do CDET and NMD1 connect to ??
- create chargen ROM from tech manual
- memory error interrupt vector
- i/o port 8051
- screen contrast
- system tick frequency selection (1 or 128 Hz)
- speaker
- soft power off
*/
@ -38,6 +39,12 @@
#include "sound/speaker.h"
#include "video/hd61830.h"
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
#define LOG 0
#define M80C88A_TAG "u1"
@ -45,6 +52,14 @@
#define TIMER_TICK_TAG "tick"
#define SCREEN_TAG "screen"
static const UINT8 INTERRUPT_VECTOR[] = { 0x08, 0x09, 0x00 };
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class portfolio_state : public driver_device
{
public:
@ -56,6 +71,8 @@ public:
m_ccm(*this, PORTFOLIO_MEMORY_CARD_SLOT_A_TAG),
m_exp(*this, PORTFOLIO_EXPANSION_SLOT_TAG),
m_timer_tick(*this, TIMER_TICK_TAG),
m_nvram(*this, "nvram"),
m_ram(*this, "ram"),
m_rom(*this, M80C88A_TAG),
m_char_rom(*this, HD61830_TAG),
m_y0(*this, "Y0"),
@ -67,8 +84,7 @@ public:
m_y6(*this, "Y6"),
m_y7(*this, "Y7"),
m_battery(*this, "BATTERY"),
m_contrast(*this, "contrast"),
m_ram(*this, RAM_TAG)
m_keylatch(0xff)
{ }
required_device<cpu_device> m_maincpu;
@ -77,6 +93,8 @@ public:
required_device<portfolio_memory_card_slot_t> m_ccm;
required_device<portfolio_expansion_slot_t> m_exp;
required_device<timer_device> m_timer_tick;
required_device<nvram_device> m_nvram;
required_device<ram_device> m_ram;
required_region_ptr<UINT8> m_rom;
required_region_ptr<UINT8> m_char_rom;
required_ioport m_y0;
@ -112,8 +130,11 @@ public:
ROM_EXT
};
DECLARE_READ8_MEMBER( rom_b_r );
DECLARE_WRITE8_MEMBER( rom_b_w );
DECLARE_READ8_MEMBER( mem_r );
DECLARE_WRITE8_MEMBER( mem_w );
DECLARE_READ8_MEMBER( io_r );
DECLARE_WRITE8_MEMBER( io_w );
DECLARE_READ8_MEMBER( irq_status_r );
DECLARE_READ8_MEMBER( keyboard_r );
@ -123,47 +144,29 @@ public:
DECLARE_WRITE8_MEMBER( irq_mask_w );
DECLARE_WRITE8_MEMBER( speaker_w );
DECLARE_WRITE8_MEMBER( power_w );
DECLARE_WRITE8_MEMBER( unknown_w );
DECLARE_WRITE8_MEMBER( select_w );
DECLARE_WRITE8_MEMBER( counter_w );
DECLARE_WRITE8_MEMBER( contrast_w );
DECLARE_WRITE_LINE_MEMBER( iint_w );
DECLARE_WRITE_LINE_MEMBER( eint_w );
/* interrupt state */
UINT8 m_ip; /* interrupt pending */
UINT8 m_ie; /* interrupt enable */
/* counter state */
UINT8 m_ip;
UINT8 m_ie;
UINT16 m_counter;
/* keyboard state */
UINT8 m_keylatch;
int m_rom_b;
/* video state */
required_shared_ptr<UINT8> m_contrast;
/* peripheral state */
DECLARE_PALETTE_INIT(portfolio);
TIMER_DEVICE_CALLBACK_MEMBER(keyboard_tick);
TIMER_DEVICE_CALLBACK_MEMBER(system_tick);
TIMER_DEVICE_CALLBACK_MEMBER(counter_tick);
DECLARE_READ8_MEMBER(hd61830_rd_r);
IRQ_CALLBACK_MEMBER(portfolio_int_ack);
required_device<ram_device> m_ram;
};
//**************************************************************************
// MACROS / CONSTANTS
//**************************************************************************
static const UINT8 INTERRUPT_VECTOR[] = { 0x08, 0x09, 0x00 };
//**************************************************************************
// INTERRUPTS
//**************************************************************************
@ -189,12 +192,33 @@ void portfolio_state::trigger_interrupt(int level)
// set interrupt pending bit
m_ip |= 1 << level;
//logerror("%s IP set %01x : %u\n", machine().time().as_string(), m_ip, level);
check_interrupt();
}
//-------------------------------------------------
// iint_w - internal interrupt
//-------------------------------------------------
WRITE_LINE_MEMBER( portfolio_state::iint_w )
{
// TODO
}
//-------------------------------------------------
// eint_w - external interrupt
//-------------------------------------------------
WRITE_LINE_MEMBER( portfolio_state::eint_w )
{
if (state)
{
trigger_interrupt(INT_EXTERNAL);
}
}
//-------------------------------------------------
// irq_status_r - interrupt status read
//-------------------------------------------------
@ -213,7 +237,7 @@ WRITE8_MEMBER( portfolio_state::irq_mask_w )
{
m_ie = data;
if (LOG) logerror("IE %02x\n", data);
if (LOG) logerror("%s %s IE %01x\n", machine().time().as_string(), machine().describe_context(), data);
check_interrupt();
}
@ -234,6 +258,8 @@ IRQ_CALLBACK_MEMBER(portfolio_state::portfolio_int_ack)
// clear interrupt pending bit
m_ip &= ~(1 << i);
if (LOG) logerror("%s %s IP %01x\n", machine().time().as_string(), machine().describe_context(), m_ip);
if (i == 3)
vector = m_exp->eack_r();
else
@ -243,8 +269,6 @@ IRQ_CALLBACK_MEMBER(portfolio_state::portfolio_int_ack)
}
}
//logerror("IP ack %01x\n", m_ip);
check_interrupt();
return vector;
@ -352,9 +376,9 @@ WRITE8_MEMBER( portfolio_state::speaker_w )
*/
m_speaker->level_w(!BIT(data, 7));
if (LOG) logerror("%s %s SPEAKER %02x\n", machine().time().as_string(), machine().describe_context(), data);
if (LOG) logerror("SPEAKER %02x\n", data);
m_speaker->level_w(!BIT(data, 7));
}
@ -384,7 +408,12 @@ WRITE8_MEMBER( portfolio_state::power_w )
*/
if (LOG) logerror("POWER %02x\n", data);
if (LOG) logerror("%s %s POWER %02x\n", machine().time().as_string(), machine().describe_context(), data);
if (BIT(data, 1))
{
// TODO power off
}
}
@ -398,36 +427,51 @@ READ8_MEMBER( portfolio_state::battery_r )
bit signal description
0
1
2
3
4
0 ? 1=boots from B:
1 ? 1=boots from external ROM
2 ? 1=boots from B:
3 ? 1=boots from ???
4 ?
5 PDET 1=peripheral connected
6 BATD? 0=battery low
7 1=cold boot
7 ? 1=cold boot
*/
UINT8 data = 0;
/* peripheral detect */
// peripheral detect
data |= m_exp->pdet_r() << 5;
/* battery status */
data |= BIT(m_battery->read(), 0) << 6;
// battery status
data |= (m_battery->read() & 0x03) << 6;
return data;
}
//-------------------------------------------------
// unknown_w - ?
// select_w -
//-------------------------------------------------
WRITE8_MEMBER( portfolio_state::unknown_w )
WRITE8_MEMBER( portfolio_state::select_w )
{
if (LOG) logerror("UNKNOWN %02x\n", data);
/*
bit description
0 ?
1 ?
2 ?
3 ?
4
5
6 ?
7 ?
*/
if (LOG) logerror("%s %s SELECT %02x\n", machine().time().as_string(), machine().describe_context(), data);
switch (data & 0x0f)
{
@ -464,52 +508,6 @@ TIMER_DEVICE_CALLBACK_MEMBER(portfolio_state::counter_tick)
}
//-------------------------------------------------
// rom_b_r -
//-------------------------------------------------
READ8_MEMBER( portfolio_state::rom_b_r )
{
UINT8 data = 0;
switch (m_rom_b)
{
case ROM_APP:
data = m_rom[offset];
break;
case CCM_A:
data = m_ccm->nrdi_r(space, offset & 0x1ffff);
break;
case CCM_B:
// TODO this is wired thru the expansion slot
break;
case ROM_EXT:
// TODO ???
break;
}
return data;
}
//-------------------------------------------------
// rom_b_w -
//-------------------------------------------------
WRITE8_MEMBER( portfolio_state::rom_b_w )
{
switch (m_rom_b)
{
case CCM_A:
m_ccm->nwri_w(space, offset & 0x1ffff, data);
break;
}
}
//-------------------------------------------------
// counter_r - counter register read
//-------------------------------------------------
@ -553,6 +551,223 @@ WRITE8_MEMBER( portfolio_state::counter_w )
//**************************************************************************
// MEMORY MAPPING
//**************************************************************************
//-------------------------------------------------
// mem_r -
//-------------------------------------------------
READ8_MEMBER( portfolio_state::mem_r )
{
UINT8 data = 0;
int iom = 0;
int bcom = 1;
int ncc1 = 1;
if (offset < 0x1f000)
{
data = m_ram->read(offset);
}
else if (offset >= 0xb0000 && offset < 0xc0000)
{
data = m_ram->read(0x1f000 + (offset & 0xfff));
}
else if (offset >= 0xc0000 && offset < 0xe0000)
{
switch (m_rom_b)
{
case ROM_APP:
data = m_rom[offset & 0x3ffff];
break;
case CCM_A:
if (LOG) logerror("%s %s CCM0 read %05x\n", machine().time().as_string(), machine().describe_context(), offset & 0x1ffff);
data = m_ccm->nrdi_r(space, offset & 0x1ffff);
break;
case CCM_B:
ncc1 = 0;
break;
case ROM_EXT:
// TODO
break;
}
}
else if (offset >= 0xe0000)
{
data = m_rom[offset & 0x3ffff];
}
data = m_exp->nrdi_r(space, offset, data, iom, bcom, ncc1);
return data;
}
//-------------------------------------------------
// mem_w -
//-------------------------------------------------
WRITE8_MEMBER( portfolio_state::mem_w )
{
int iom = 0;
int bcom = 1;
int ncc1 = 1;
if (offset < 0x1f000)
{
m_ram->write(offset, data);
}
else if (offset >= 0xb0000 && offset < 0xc0000)
{
m_ram->write(0x1f000 + (offset & 0xfff), data);
}
else if (offset >= 0xc0000 && offset < 0xe0000)
{
switch (m_rom_b)
{
case CCM_A:
if (LOG) logerror("%s %s CCM0 write %05x:%02x\n", machine().time().as_string(), machine().describe_context(), offset & 0x1ffff, data);
m_ccm->nwri_w(space, offset & 0x1ffff, data);
break;
case CCM_B:
ncc1 = 0;
break;
}
}
m_exp->nwri_w(space, offset, data, iom, bcom, ncc1);
}
//-------------------------------------------------
// io_r -
//-------------------------------------------------
READ8_MEMBER( portfolio_state::io_r )
{
UINT8 data = 0;
int iom = 1;
int bcom = 1;
int ncc1 = 0;
if ((offset & 0xff00) == 0x8000)
{
switch ((offset >> 4) & 0x0f)
{
case 0:
data = keyboard_r(space, 0);
break;
case 1:
if (offset & 0x01)
{
data = m_lcdc->status_r(space, 0);
}
else
{
data = m_lcdc->data_r(space, 0);
}
break;
case 4:
data = counter_r(space, offset & 0x01);
break;
case 5:
if (offset & 0x01)
{
data = battery_r(space, 0);
}
else
{
data = irq_status_r(space, 0);
}
break;
case 7:
bcom = 0;
break;
}
}
data = m_exp->nrdi_r(space, offset, data, iom, bcom, ncc1);
return data;
}
//-------------------------------------------------
// io_w -
//-------------------------------------------------
WRITE8_MEMBER( portfolio_state::io_w )
{
int iom = 1;
int bcom = 1;
int ncc1 = 0;
if ((offset & 0xff00) == 0x8000)
{
switch ((offset >> 4) & 0x0f)
{
case 1:
if (offset & 0x01)
{
m_lcdc->control_w(space, 0, data);
}
else
{
m_lcdc->data_w(space, 0, data);
}
break;
case 2:
speaker_w(space, 0, data);
break;
case 3:
power_w(space, 0, data);
break;
case 4:
counter_w(space, offset & 0x01, data);
break;
case 5:
if (offset & 0x01)
{
select_w(space, 0, data);
}
else
{
irq_mask_w(space, 0, data);
}
break;
case 6:
contrast_w(space, 0, data);
break;
case 7:
bcom = 0;
break;
}
}
m_exp->nwri_w(space, offset, data, iom, bcom, ncc1);
}
//**************************************************************************
// ADDRESS MAPS
//**************************************************************************
@ -562,11 +777,7 @@ WRITE8_MEMBER( portfolio_state::counter_w )
//-------------------------------------------------
static ADDRESS_MAP_START( portfolio_mem, AS_PROGRAM, 8, portfolio_state )
AM_RANGE(0x00000, 0x1efff) AM_RAM AM_SHARE("nvram1")
AM_RANGE(0x1f000, 0x9efff) AM_RAM // expansion
AM_RANGE(0xb0000, 0xb0fff) AM_MIRROR(0xf000) AM_RAM AM_SHARE("nvram2") // video RAM
AM_RANGE(0xc0000, 0xdffff) AM_READWRITE(rom_b_r, rom_b_w)
AM_RANGE(0xe0000, 0xfffff) AM_ROM AM_REGION(M80C88A_TAG, 0x20000)
AM_RANGE(0x00000, 0xfffff) AM_READWRITE(mem_r, mem_w)
ADDRESS_MAP_END
@ -575,15 +786,7 @@ ADDRESS_MAP_END
//-------------------------------------------------
static ADDRESS_MAP_START( portfolio_io, AS_IO, 8, portfolio_state )
AM_RANGE(0x8000, 0x8000) AM_READ(keyboard_r)
AM_RANGE(0x8010, 0x8010) AM_DEVREADWRITE(HD61830_TAG, hd61830_device, data_r, data_w)
AM_RANGE(0x8011, 0x8011) AM_DEVREADWRITE(HD61830_TAG, hd61830_device, status_r, control_w)
AM_RANGE(0x8020, 0x8020) AM_WRITE(speaker_w)
AM_RANGE(0x8030, 0x8030) AM_WRITE(power_w)
AM_RANGE(0x8040, 0x8041) AM_READWRITE(counter_r, counter_w)
AM_RANGE(0x8050, 0x8050) AM_READWRITE(irq_status_r, irq_mask_w)
AM_RANGE(0x8051, 0x8051) AM_READWRITE(battery_r, unknown_w)
AM_RANGE(0x8060, 0x8060) AM_RAM AM_SHARE("contrast")
AM_RANGE(0x0000, 0xffff) AM_READWRITE(io_r, io_w)
ADDRESS_MAP_END
@ -681,6 +884,9 @@ static INPUT_PORTS_START( portfolio )
PORT_CONFNAME( 0x01, 0x01, "Battery Status" )
PORT_CONFSETTING( 0x01, DEF_STR( Normal ) )
PORT_CONFSETTING( 0x00, "Low Battery" )
PORT_CONFNAME( 0x02, 0x00, "Boot" )
PORT_CONFSETTING( 0x02, "Cold" )
PORT_CONFSETTING( 0x00, "Warm" )
INPUT_PORTS_END
@ -689,6 +895,20 @@ INPUT_PORTS_END
// VIDEO
//**************************************************************************
//-------------------------------------------------
// contrast_w -
//-------------------------------------------------
WRITE8_MEMBER( portfolio_state::contrast_w )
{
if (LOG) logerror("%s %s CONTRAST %02x\n", machine().time().as_string(), machine().describe_context(), data);
}
//-------------------------------------------------
// PALETTE_INIT( portfolio )
//-------------------------------------------------
PALETTE_INIT_MEMBER(portfolio_state, portfolio)
{
palette.set_pen_color(0, rgb_t(138, 146, 148));
@ -735,21 +955,6 @@ GFXDECODE_END
//**************************************************************************
// DEVICE CONFIGURATION
//**************************************************************************
WRITE_LINE_MEMBER( portfolio_state::iint_w )
{
}
WRITE_LINE_MEMBER( portfolio_state::eint_w )
{
if (state)
trigger_interrupt(INT_EXTERNAL);
}
//**************************************************************************
// MACHINE INITIALIZATION
//**************************************************************************
@ -760,29 +965,14 @@ WRITE_LINE_MEMBER( portfolio_state::eint_w )
void portfolio_state::machine_start()
{
address_space &program = m_maincpu->space(AS_PROGRAM);
m_nvram->set_base(m_ram->pointer(), m_ram->size());
/* memory expansions */
switch (m_ram->size())
{
case 128 * 1024:
program.unmap_readwrite(0x1f000, 0x9efff);
break;
case 384 * 1024:
program.unmap_readwrite(0x5f000, 0x9efff);
break;
}
/* set initial values */
m_keylatch = 0xff;
/* register for state saving */
// state saving
save_item(NAME(m_ip));
save_item(NAME(m_ie));
save_item(NAME(m_counter));
save_item(NAME(m_keylatch));
save_pointer(NAME(m_contrast.target()), m_contrast.bytes());
save_item(NAME(m_rom_b));
}
@ -792,6 +982,9 @@ void portfolio_state::machine_start()
void portfolio_state::machine_reset()
{
m_lcdc->reset();
m_exp->reset();
}
@ -805,13 +998,13 @@ void portfolio_state::machine_reset()
//-------------------------------------------------
static MACHINE_CONFIG_START( portfolio, portfolio_state )
/* basic machine hardware */
// basic machine hardware
MCFG_CPU_ADD(M80C88A_TAG, I8088, XTAL_4_9152MHz)
MCFG_CPU_PROGRAM_MAP(portfolio_mem)
MCFG_CPU_IO_MAP(portfolio_io)
MCFG_CPU_IRQ_ACKNOWLEDGE_DRIVER(portfolio_state,portfolio_int_ack)
/* video hardware */
// video hardware
MCFG_SCREEN_ADD(SCREEN_TAG, LCD)
MCFG_SCREEN_REFRESH_RATE(72)
MCFG_SCREEN_UPDATE_DEVICE(HD61830_TAG, hd61830_device, screen_update)
@ -830,7 +1023,7 @@ static MACHINE_CONFIG_START( portfolio, portfolio_state )
MCFG_HD61830_RD_CALLBACK(READ8(portfolio_state, hd61830_rd_r))
MCFG_VIDEO_SET_SCREEN(SCREEN_TAG)
/* sound hardware */
// sound hardware
MCFG_SPEAKER_STANDARD_MONO("mono")
MCFG_SOUND_ADD("speaker", SPEAKER_SOUND, 0)
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 0.25)
@ -847,19 +1040,17 @@ static MACHINE_CONFIG_START( portfolio, portfolio_state )
MCFG_TIMER_DRIVER_ADD_PERIODIC("counter", portfolio_state, counter_tick, attotime::from_hz(XTAL_32_768kHz/16384))
MCFG_TIMER_DRIVER_ADD_PERIODIC(TIMER_TICK_TAG, portfolio_state, system_tick, attotime::from_hz(XTAL_32_768kHz/32768))
/* fake keyboard */
// fake keyboard
MCFG_TIMER_DRIVER_ADD_PERIODIC("keyboard", portfolio_state, keyboard_tick, attotime::from_usec(2500))
/* software lists */
// software list
MCFG_SOFTWARE_LIST_ADD("cart_list", "pofo")
/* internal ram */
// internal ram
MCFG_RAM_ADD(RAM_TAG)
MCFG_RAM_DEFAULT_SIZE("128K")
MCFG_RAM_EXTRA_OPTIONS("384K,640K")
MCFG_NVRAM_ADD_RANDOM_FILL("nvram1")
MCFG_NVRAM_ADD_RANDOM_FILL("nvram2")
MCFG_NVRAM_ADD_RANDOM_FILL("nvram")
MACHINE_CONFIG_END
@ -888,5 +1079,5 @@ ROM_END
// SYSTEM DRIVERS
//**************************************************************************
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */
COMP( 1989, pofo, 0, 0, portfolio, portfolio, driver_device, 0, "Atari", "Portfolio", MACHINE_NOT_WORKING | MACHINE_IMPERFECT_SOUND | MACHINE_SUPPORTS_SAVE )
// YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS
COMP( 1989, pofo, 0, 0, portfolio, portfolio, driver_device, 0, "Atari", "Portfolio", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE )