summaryrefslogtreecommitdiffstats
path: root/src/mame/drivers/wy55.cpp
blob: f1d8abb4e0f083dc120aed25af14d094c5100207 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
// license:BSD-3-Clause
// copyright-holders:AJR
/***********************************************************************************************************************************

    Skeleton driver for Wyse WY-55 and related terminals.

    The WY-55's custom video gate array is numbered 211019-05. The WY-185 is believed to run on similar hardware, though with
    85 Hz and 60 Hz vertical refresh rates rather than 80 Hz and 70 Hz.

    WY-65's "PELVIS" ASIC (QFP160) supports refresh rates up to 94 Hz.

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

#include "emu.h"
#include "cpu/mcs51/mcs51.h"
//#include "machine/ins8250.h"
#include "machine/nvram.h"
#include "screen.h"

namespace {

class wy55_state : public driver_device
{
public:
	wy55_state(const machine_config &mconfig, device_type type, const char *tag)
		: driver_device(mconfig, type, tag)
		, m_maincpu(*this, "maincpu")
		, m_screen(*this, "screen")
		, m_progbank(*this, "progbank")
	{
	}

	void wy55(machine_config &config);
	void wy65(machine_config &config);
	void wy185es(machine_config &config);

protected:
	virtual void machine_start() override;
	virtual void driver_start() override;

private:
	void wy65_progbank_w(u8 data) { m_progbank->set_entry(data & 0x03); }

	u32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);

	void prog_map(address_map &map);
	void ext_map(address_map &map);
	void wy65_ext_map(address_map &map);

	required_device<mcs51_cpu_device> m_maincpu;
	required_device<screen_device> m_screen;
	required_memory_bank m_progbank;
};


void wy55_state::machine_start()
{
	memory_region *rgn = memregion("program");
	m_progbank->configure_entries(0, rgn->bytes() / 0x10000, rgn->base(), 0x10000);
	m_progbank->set_entry(0);
}

u32 wy55_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	return 0;
}

void wy55_state::prog_map(address_map &map)
{
	map(0x0000, 0xffff).bankr("progbank");
}

void wy55_state::ext_map(address_map &map)
{
	map(0x0000, 0x1fff).ram().share("nvram0");
	map(0x8000, 0x9fff).ram().share("nvram1");
	map(0xa000, 0xbfff).ram().share("fontram");
	//map(0xf028, 0xf037).rw("uart", FUNC(pc16552_device::read), FUNC(pc16552_device::write));
}

void wy55_state::wy65_ext_map(address_map &map)
{
	map(0x0000, 0xdfff).ram();
	map(0xee02, 0xee02).w(FUNC(wy55_state::wy65_progbank_w));
}


static INPUT_PORTS_START(wy55)
INPUT_PORTS_END

void wy55_state::wy55(machine_config &config)
{
	I80C32(config, m_maincpu, 14.7456_MHz_XTAL);
	m_maincpu->set_addrmap(AS_PROGRAM, &wy55_state::prog_map);
	m_maincpu->set_addrmap(AS_IO, &wy55_state::ext_map);
	m_maincpu->port_out_cb<1>().set_membank("progbank").bit(2);

	NVRAM(config, "nvram0", nvram_device::DEFAULT_ALL_0); // 8K SRAM + battery
	NVRAM(config, "nvram1", nvram_device::DEFAULT_ALL_0); // 8K SRAM + battery

	//PC16552D(config, "uart", 14.7456_MHz_XTAL / 2); // 16C452 (divider not verified)

	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
	m_screen->set_raw(49.4235_MHz_XTAL, 1575, 0, 1188, 448, 0, 416);
	//m_screen->set_raw(49.4235_MHz_XTAL * 2 / 3, 1050, 0, 800, 392, 0, 338);
	m_screen->set_screen_update(FUNC(wy55_state::screen_update));
}

void wy55_state::wy185es(machine_config &config)
{
	wy55(config);
	m_maincpu->port_out_cb<1>().set_nop();
}

void wy55_state::wy65(machine_config &config)
{
	DS80C320(config, m_maincpu, 58.9824_MHz_XTAL / 4);
	m_maincpu->set_addrmap(AS_PROGRAM, &wy55_state::prog_map);
	m_maincpu->set_addrmap(AS_IO, &wy55_state::wy65_ext_map);

	// TODO: NVRAM? (4x W24257S-70LL on board)

	SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
	m_screen->set_raw(58.9824_MHz_XTAL, 1575, 0, 1188, 448, 0, 416); // dimensions probably wrong
	m_screen->set_screen_update(FUNC(wy55_state::screen_update));
}


ROM_START(wy55)
	ROM_REGION(0x20000, "program", 0)
	ROM_LOAD("251352-12.bin", 0x00000, 0x20000, CRC(efe41862) SHA1(52ee76d636b166fa10a37356aef81011a9b079cc)) // v2.1
ROM_END

ROM_START(wy65)
	ROM_REGION(0x40000, "program", 0)
	ROM_LOAD("251455-03.bin", 0x00000, 0x40000, CRC(2afbf73b) SHA1(5a29b78ef377a6e2f2f91ff42a7e4d86eb511a5f)) // v2.1
ROM_END

ROM_START(wy185es)
	ROM_REGION(0x10000, "program", 0)
	ROM_LOAD("251201-03.bin", 0x00000, 0x10000, CRC(5b8cace5) SHA1(484bba8244a99edb80d7f7a5437c2be52c980fc1)) // v2.0
ROM_END

void wy55_state::driver_start()
{
	memory_region *rgn = memregion("program");
	uint8_t *rom = rgn->base();

	for (offs_t base = 0x00000; base < rgn->bytes(); base += 0x4000)
	{
		std::vector<uint8_t> orig(&rom[base], &rom[base + 0x4000]);

		for (offs_t offset = 0; offset < 0x4000; offset++)
			rom[base | offset] = bitswap<8>(orig[bitswap<14>(offset, 3, 8, 2, 0, 7, 4, 9, 10, 11, 12, 13, 5, 1, 6)], 3, 4, 5, 2, 6, 1, 7, 0);
	}
}

} // anonymous namespace

COMP(1991, wy185es, 0, 0, wy185es, wy55, wy55_state, empty_init, "Wyse Technology", "WY-185ES (v2.0)", MACHINE_IS_SKELETON)
COMP(1993, wy55,    0, 0, wy55,    wy55, wy55_state, empty_init, "Wyse Technology", "WY-55 (v2.1)", MACHINE_IS_SKELETON)
COMP(1996, wy65,    0, 0, wy65,    wy55, wy55_state, empty_init, "Wyse Technology", "WY-65 (v2.1)", MACHINE_IS_SKELETON)