summaryrefslogblamecommitdiffstatshomepage
path: root/src/mess/drivers/stratos.c
blob: 321584cb48cd389a55fc100eff8f96ac7b528f7e (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

















                                                                                       




                                                       









































































































































































































































                                                                                                                                                      



               













































































































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

    Saitek/Scisys Kasparov Stratos Chess Computer

    license: MAME, BSD-3-Clause
    copyright-holders: Olivier Galibert

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

#include "emu.h"
#include "cpu/m6502/m65c02.h"
#include "machine/nvram.h"

class stratos_state : public driver_device
{
public:
	stratos_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag),
			maincpu(*this, "maincpu"),
			nvram(*this, "nvram"),
			bank_8000(*this, "bank_8000"),
			bank_4000(*this, "bank_4000"),
			nvram_bank(*this, "nvram_bank")
	{ }

	required_device<m65c02_device> maincpu;
	required_device<nvram_device> nvram;
	required_memory_bank bank_8000;
	required_memory_bank bank_4000;
	required_memory_bank nvram_bank;

	UINT8 *nvram_data;
	UINT8 control, led_latch_control;
	UINT32 individual_leds;
	UINT8 latch_AH_red, latch_AH_green, latch_18_red, latch_18_green;

	DECLARE_DRIVER_INIT(stratos);
	DECLARE_WRITE8_MEMBER(p2000_w);
	DECLARE_READ8_MEMBER(p2200_r);
	DECLARE_WRITE8_MEMBER(p2200_w);
	DECLARE_WRITE8_MEMBER(p2400_w);
	DECLARE_READ8_MEMBER(control_r);
	DECLARE_WRITE8_MEMBER(control_w);
	DECLARE_READ8_MEMBER(lcd_r);
	DECLARE_WRITE8_MEMBER(lcd_w);

	TIMER_DEVICE_CALLBACK_MEMBER(irq_timer);

	void show_leds();
	UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
	void machine_reset();
};

DRIVER_INIT_MEMBER( stratos_state, stratos )
{
	nvram_data = auto_alloc_array(machine(), UINT8, 0x2000);
	nvram->set_base(nvram_data, 0x2000);

	bank_8000 ->configure_entries(0, 4, memregion("roms_8000")->base(), 0x8000);
	bank_4000 ->configure_entries(0, 4, memregion("roms_4000")->base(), 0x4000);
	nvram_bank->configure_entries(0, 2, nvram_data,                     0x1000);
}

void stratos_state::machine_reset()
{
	control = 0x00;
	led_latch_control = 0x00;
	individual_leds = 0x00000;
	latch_AH_red = 0;
	latch_AH_green = 0;
	latch_18_red = 0;
	latch_18_green = 0;
	bank_8000 ->set_entry(0);
	bank_4000 ->set_entry(0);
	nvram_bank->set_entry(0);
}

void stratos_state::show_leds()
{
	static const char *led_pos[18] = {
		0, 0, "gPawn", "gKnight", "gBishop", "gRook", "gQueen", "gKing", 0, 0, "rPawn", "rKnight", "rBishop", "rRook", "rQueen", "rKing", 0, 0
	};
	char str_red[64];
	char str_green[64];

	char *pr = str_red;
	char *pg = str_green;

	*pr = *pg = 0;

	for(int i=0; i != 18; i++)
		if(individual_leds & (1 << i)) {
			const char *pos = led_pos[i];
			if(!pos)
				pr += sprintf(pr, " <%d>", i);
			else if(pos[0] == 'r')
				pr += sprintf(pr, " %s", pos+1);
			else
				pg += sprintf(pg, " %s", pos+1);
		}

	// Obviously slightly incorrect
	if(!(led_latch_control & 8)) {
		pr += sprintf(pr, " %c%c", 'A' + latch_AH_red, '1' + latch_18_red);
		pg += sprintf(pg, " %c%c", 'A' + latch_AH_green, '1' + latch_18_green);
	}

	logerror("leds R:%s -- G:%s (%s)\n", str_red, str_green, machine().describe_context());
}

TIMER_DEVICE_CALLBACK_MEMBER(stratos_state::irq_timer)
{
	maincpu->set_input_line(M65C02_IRQ_LINE, HOLD_LINE);
}

UINT32 stratos_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	static bool nmi=false;

	if(machine().input().code_pressed(KEYCODE_W)) {
		if(!nmi) {
			maincpu->set_input_line(M65C02_NMI_LINE, PULSE_LINE);
			nmi = true;
		}
	} else
		nmi = false;


	return 0;
}

WRITE8_MEMBER(stratos_state::p2000_w)
{
	led_latch_control = data;

	if(!(data & 0x10))
		latch_18_red = data & 7;
	if(!(data & 0x20))
		latch_18_green = data & 7;
	if(!(data & 0x40))
		latch_AH_red = data & 7;
	if(!(data & 0x80))
		latch_AH_green = data & 7;

	show_leds();
}

READ8_MEMBER(stratos_state::p2200_r)
{
	logerror("p2200_r (%s)\n", machine().describe_context());
	return machine().rand();
}

WRITE8_MEMBER(stratos_state::p2200_w)
{
	logerror("p2200_w %02x -> %02x (%s)\n", data, data^0xff, machine().describe_context());
}

WRITE8_MEMBER(stratos_state::p2400_w)
{
	if(control & 0x20) {
		individual_leds = individual_leds & 0x100ff;
		individual_leds |= (data ^ 0xff) << 8;
		if(!(control & 0x04))
			individual_leds |= 0x20000;
	} else {
		individual_leds = individual_leds & 0x2ff00;
		individual_leds |= data ^ 0xff;
		if(!(control & 0x04))
			individual_leds |= 0x10000;
	}
}

READ8_MEMBER(stratos_state::control_r)
{
	static int xx = 0;
	xx = !xx;
	// [d659/d630]
	// d64e:
	//   2000 = f9
	//   2000 = f7
	//    8fb = (2600) & 20

	// d625: test device?
	//   8fb=00 : (00, 80) (05, 80) (06, 80)
	//   8fb=20 : (03, 20) (06, 20) (04, 20)
	//  { 2000=f9, 2000=f0 | first, test (2600) & second
	// -> 3-bit mask
	//  d518: 0c 0a 10 0e 14 18 0b 08 -> 1b, timing on loop at e788
	//  d520: 02cc 035b 0219 0266 01ad 0166 0300 0432 -> 8d7/8


	// table at f70e (index on d545 somehow):
	// 0c 0d 0e 0f 10 11 01 02

	// table at d545:
	// 00 4800 6800
	// 01 4802 6800
	// 02 4800 6802
	// 03 4801 6800
	// 04 4800 6801
	// 05 4801 6801
	// 06 4c00 6800
	// 07 4800 6c00
	// 08 4800 6c00
	// 09 4c00 6800
	// 0a 4c00 6c00
	// 0b 4c00 6c00
	// 0c 4880 6800
	// 0d 4840 6800
	// 0e 4820 6800
	// 0f 4810 6800
	// 10 4808 6800
	// 11 4804 6800
	// 12 4800 6880
	// 13 4800 6840
	// 14 4800 6820
	// 15 4800 6810
	// 16 4800 6808
	// 17 4800 6804
	// 18 4880 6880
	// 19 4840 6840
	// 1a 4820 6820
	// 1b 4810 6810
	// 1c 4808 6808
	// 1d 4804 6804

	// Power up led test table
	// 1208 Ki Green
	// 1308 Qu
	// 1408 Ro
	// 1508 Bi
	// 1608 Kn
	// 1708 Pa
	// 0727 8
	// 0026 7
	// 0025 6
	// 0024 5
	// 0023 4
	// 0022 3
	// 0021 2
	// 0020 1
	// 0080 A
	// 0081 B
	// 0082 C
	// 0083 D
	// 0084 E
	// 0085 F
	// 0086 G
	// 0087 H
	// 0008 -
	// 0c08 Ki Red
	// 0d08 Qu
	// 0e08 Ro
	// 0f08 Bi
	// 1008 Kn
	// 1108 Pa
	// 0108
	// 0208
	// 0308
	// 0408
	// 0617 8
	// 0016 7
	// 0015 6
	// 0014 5
	// 0013 4
	// 0012 3
	// 0011 2
	// 0010 1
	// 0040 A
	// 0041 B
	// 0042 C
	// 0043 D
	// 0044 E
	// 0045 F
	// 0046 G
	// 0047 H
	// 0009
	// 00c2

	// (20) = difficulty level

	logerror("control_r (%s)\n", machine().describe_context());
	return xx ? 0x20 : 0x00;
}

WRITE8_MEMBER(stratos_state::control_w)
{
	logerror("control_w %02x bank %d (%s)\n", data, data & 3, machine().describe_context());

	control = data;
	bank_8000->set_entry(data & 3);
	bank_4000->set_entry(data & 3);
	nvram_bank->set_entry((data >> 1) & 1);
}


READ8_MEMBER(stratos_state::lcd_r)
{
	return 0x00;
}

WRITE8_MEMBER(stratos_state::lcd_w)
{
	// 08 0b - 00?
	// 04 06 - 05
	// 02 0d - 07
	// 01 00 - 05

	static UINT8 vals[18];
	static int idx = 0;
	if(data == 0)
		idx = 0;
	if(idx/2 >= 18)
		return;
	if(idx & 1)
		vals[idx/2] = (vals[idx/2] & 0xf0) | (data & 0xf);
	else
		vals[idx/2] = (data & 0xf) << 4;

	idx++;
	if(idx == 18*2) {
		logerror("lcd");
		for(int i=0; i<18; i++)
			logerror(" %02x", vals[i]);
		logerror("\n");
	}
}

static ADDRESS_MAP_START( stratos_mem, AS_PROGRAM, 8, stratos_state )
	AM_RANGE(0x0000, 0x1fff) AM_RAM
	AM_RANGE(0x2000, 0x2000) AM_WRITE(p2000_w)
	AM_RANGE(0x2200, 0x2200) AM_READWRITE(p2200_r, p2200_w)
	AM_RANGE(0x2400, 0x2400) AM_WRITE(p2400_w)
	AM_RANGE(0x2600, 0x2600) AM_READWRITE(control_r, control_w)
	AM_RANGE(0x2800, 0x37ff) AM_RAMBANK("nvram_bank")
	AM_RANGE(0x3800, 0x3800) AM_READWRITE(lcd_r, lcd_w)
	AM_RANGE(0x4000, 0x7fff) AM_ROMBANK("bank_4000")
	AM_RANGE(0x8000, 0xffff) AM_ROMBANK("bank_8000")
ADDRESS_MAP_END

static INPUT_PORTS_START( stratos )
INPUT_PORTS_END

static MACHINE_CONFIG_START( stratos, stratos_state )
	MCFG_CPU_ADD("maincpu", M65C02, 5670000)
	MCFG_CPU_PROGRAM_MAP(stratos_mem)

	MCFG_SCREEN_ADD("screen", LCD)
	MCFG_SCREEN_REFRESH_RATE(50)
	MCFG_SCREEN_SIZE(240, 64)
	MCFG_SCREEN_VISIBLE_AREA(0, 239, 0, 63)
	MCFG_SCREEN_UPDATE_DRIVER(stratos_state, screen_update)

	MCFG_TIMER_DRIVER_ADD_PERIODIC("irq", stratos_state, irq_timer, attotime::from_hz(1000))

	MCFG_NVRAM_ADD_0FILL("nvram")
MACHINE_CONFIG_END

ROM_START( stratos )
	ROM_REGION(0x20000, "roms_8000", 0)
	ROM_LOAD("w1_728m_u3.u3",  0x0000, 0x8000, CRC(b58a7256) SHA1(75b3a3a65f4ca8d52aa5b17a06319bff59d9014f))
	ROM_LOAD("bw1_918n_u4.u4", 0x8000, 0x8000, CRC(cb0de631) SHA1(f78d40213be21775966cbc832d64acd9b73de632))
	ROM_FILL(0x10000, 0x10000, 0xff)

	ROM_REGION(0x10000, "roms_4000", 0)
	ROM_FILL(0x00000, 0x10000, 0xff)
ROM_END

/*     YEAR  NAME      PARENT   COMPAT  MACHINE    INPUT     CLASS          INIT     COMPANY    FULLNAME                           FLAGS */
CONS(  1986, stratos,  0,       0,      stratos,   stratos,  stratos_state, stratos, "Saitek",  "Kasparov Stratos Chess Computer", GAME_NO_SOUND)