// license:BSD-3-Clause
// copyright-holders:Angelo Salese
/**************************************************************************************************

    PC-9801 MEMSW interface

    A CMOS-like interface that maps in the TVRAM area

    Reference URL:
    http://ohta.music.coocan.jp/packen/board/memsw.htm
    Running the MON command under BASIC allows the user to change these
    settings.
    ssw -> for displaying current settings on screen;
    ssw# -> to change the given #

    List of settings, parenthesis for default if not zero
    SW1 $A3FE2
    xx-- ---- stop bit length (01)
    --x- ---- parity specification
    ---x ---- parity check
    ---- xx-- data bit length (10)
    ---- --x- communication method
    ---- ---x X parameter

    SW2 $A3FE6
    x--- ---- S parameter
    -x-- ---- line feed code when sending
    --x- ---- line feed code when receiving
    ---x ---- Japanese shift code
    ---- xxxx transfer speed (0101)

    SW3 $A3FEA
    x--- ---- Operation when DEL code is received (input / output mode)
    x--- ---- Operation when DEL code is received (terminal mode)
    -x-- ---- Text screen color
    --x- ---- Maximum operating frequency for V30 coprocessor
    ---x ---- With or without V30 coprocessor
    ---- x--- Coprocessor for 80286,386
    ---- -xxx Conventional memory size (100)

    SW4 $A3FEE
    x--- ---- Expansion ROM CE000-CFFFF
    -x-- ---- Expansion ROM CA000-CBFFF
    --x- ---- Expansion ROM D4000-D5FFF
    ---x ---- Expansion ROM D0000-D3FFF
    ---- x--- Expansion ROM CC000-CFFFF
    ---- -x-- Expansion ROM C8000-C9FFF
    ---- --xx (Unused)

    SW5 $A3FF2
    xxxx ---- Select boot device (0000)
    1100 ---- SCSI HDD #1
    1011 ---- HDD #2
    1010 ---- HDD #1
    1000 ---- ROM BASIC
    0110 ---- MO disk
    0100 ---- 1MB FDD
    0010 ---- 640K FDD
    0000 ---- standard
    ???? ---- ROM BASIC
    ---- x--- Screen Hard copy color
    ---- -x-- Use HDD user ID
    ---- --x- Prioritize HDD with device name
    ---- ---x PC-PR201 series used (1)

    SW5 $A3FF6
    --x- ---- Use modem-NCU control function
    ---x ---- Extended screen hard copy function
    ---- x--- Use monitor mode (Use extended monitor mode)
    xx-- -xxx (Unused)


    TODO:
    - Is the mapping truly aligned to 2 bytes? Looks more like 4, needs real
      HW verification.

**************************************************************************************************/

#include "emu.h"
#include "pc98_memsw.h"

#include "coreutil.h"

DEFINE_DEVICE_TYPE(PC98_MEMSW, pc98_memsw_device, "pc98_memsw", "NEC PC-98 Memory Switch device")

pc98_memsw_device::pc98_memsw_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, PC98_MEMSW, tag, owner, clock)
	, device_nvram_interface(mconfig, *this)
{
}

void pc98_memsw_device::device_start()
{
	save_pointer(NAME(m_bram), m_bram_size);
}


void pc98_memsw_device::device_reset()
{
}


void pc98_memsw_device::nvram_default()
{
	system_time systime;

	const uint8_t default_memsw_data[0x10] =
	{
		0xe1, 0x48, 0xe1, 0x05,
		0xe1, 0x04, 0xe1, 0x00,
		0xe1, 0x01, 0xe1, 0x00,
		0xe1, 0x00, 0xe1, 0x00
	};

	memcpy(m_bram, default_memsw_data, m_bram_size);

	machine().current_datetime(systime);
	m_bram[0xf] = dec_2_bcd(systime.local_time.year - 2000) & 0xff;
}

bool pc98_memsw_device::nvram_read(util::read_stream &file)
{
	auto const [err, actual_size] = util::read(file, m_bram, m_bram_size);
	return !err && (actual_size == m_bram_size);
}

bool pc98_memsw_device::nvram_write(util::write_stream &file)
{
	auto const [err, actual_size] = util::write(file, m_bram, m_bram_size);
	return !err;
}


uint8_t pc98_memsw_device::read(offs_t offset)
{
	return m_bram[offset];
}

void pc98_memsw_device::write(offs_t offset, uint8_t data )
{
	m_bram[offset] = data;
}
