1 // license:BSD-3-Clause
2 // copyright-holders:Sandro Ronco
3 /***************************************************************************
4
5 Psion Organiser II series
6
7 Driver by Sandro Ronco
8
9 TODO:
10 - dump CGROM of the HD44780
11 - emulate other devices in slot C(Comms Link, printer)
12
13 Note:
14 - 4 lines display has an custom LCD controller derived from an HD66780
15 - NVRAM works only if the machine is turned off (with OFF menu) before closing MESS
16
17 More info:
18 http://archive.psion2.org/org2/techref/index.htm
19
20 ****************************************************************************/
21
22
23 #include "emu.h"
24 #include "includes/psion.h"
25
26 #include "screen.h"
27 #include "softlist.h"
28 #include "speaker.h"
29
30
TIMER_DEVICE_CALLBACK_MEMBER(psion_state::nmi_timer)31 TIMER_DEVICE_CALLBACK_MEMBER(psion_state::nmi_timer)
32 {
33 if (m_enable_nmi)
34 m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
35 }
36
kb_read()37 uint8_t psion_state::kb_read()
38 {
39 uint8_t data = 0x7c;
40
41 if (m_kb_counter)
42 {
43 for (int line = 0; line < 7; line++)
44 if (m_kb_counter == (0x7f & ~(1 << line)))
45 data = m_kb_lines[line]->read();
46 }
47 else
48 {
49 //Read all the input lines
50 for (int line = 0; line < 7; line++)
51 data &= m_kb_lines[line]->read();
52 }
53
54 return data & 0x7c;
55 }
56
update_banks()57 void psion_state::update_banks()
58 {
59 if (m_ram_bank < m_ram_bank_count && m_ram_bank_count)
60 membank("rambank")->set_entry(m_ram_bank);
61
62 if (m_rom_bank < m_rom_bank_count && m_rom_bank_count)
63 membank("rombank")->set_entry(m_rom_bank);
64 }
65
port2_w(offs_t offset,uint8_t data,uint8_t ddr)66 void psion_state::port2_w(offs_t offset, uint8_t data, uint8_t ddr)
67 {
68 /* datapack i/o data bus */
69 m_pack1->data_w(data & ddr);
70 m_pack2->data_w(data & ddr);
71 }
72
port2_r()73 uint8_t psion_state::port2_r()
74 {
75 /* datapack i/o data bus */
76 return m_pack1->data_r() | m_pack2->data_r();
77 }
78
port5_r()79 uint8_t psion_state::port5_r()
80 {
81 /*
82 x--- ---- ON key active high
83 -xxx xx-- keys matrix active low
84 ---- --x- pulse
85 ---- ---x battery status
86 */
87 return kb_read() | ioport("BATTERY")->read() | ioport("ON")->read() | (m_kb_counter == 0x7ff)<<1 | m_pulse<<1;
88 }
89
port6_w(uint8_t data)90 void psion_state::port6_w(uint8_t data)
91 {
92 /*
93 datapack control lines
94 x--- ---- slot on/off
95 -x-- ---- slot 3
96 --x- ---- slot 2
97 ---x ---- slot 1
98 ---- x--- output enable
99 ---- -x-- program line
100 ---- --x- reset line
101 ---- ---x clock line
102 */
103 m_pack1->control_w((data & 0x8f) | (data & 0x10));
104 m_pack2->control_w((data & 0x8f) | ((data & 0x20) >> 1));
105 }
106
port6_r()107 uint8_t psion_state::port6_r()
108 {
109 /* datapack control lines */
110 return (m_pack1->control_r() | (m_pack2->control_r() & 0x8f)) | ((m_pack2->control_r() & 0x10)<<1);
111 }
112
113 /* Read/Write common */
io_rw(uint16_t offset)114 void psion_state::io_rw(uint16_t offset)
115 {
116 if (machine().side_effects_disabled())
117 return;
118
119 switch (offset & 0xffc0)
120 {
121 case 0xc0:
122 /* switch off, CPU goes into standby mode */
123 m_enable_nmi = 0;
124 m_stby_pwr = 1;
125 m_maincpu->suspend(SUSPEND_REASON_HALT, 1);
126 break;
127 case 0x100:
128 m_pulse = 1;
129 break;
130 case 0x140:
131 m_pulse = 0;
132 break;
133 case 0x200:
134 m_kb_counter = 0;
135 break;
136 case 0x180:
137 m_beep->set_state(1);
138 break;
139 case 0x1c0:
140 m_beep->set_state(0);
141 break;
142 case 0x240:
143 if (offset == 0x260 && (m_rom_bank_count || m_ram_bank_count))
144 {
145 m_ram_bank=0;
146 m_rom_bank=0;
147 update_banks();
148 }
149 else
150 m_kb_counter++;
151 break;
152 case 0x280:
153 if (offset == 0x2a0 && m_ram_bank_count)
154 {
155 m_ram_bank++;
156 update_banks();
157 }
158 else
159 m_enable_nmi = 1;
160 break;
161 case 0x2c0:
162 if (offset == 0x2e0 && m_rom_bank_count)
163 {
164 m_rom_bank++;
165 update_banks();
166 }
167 else
168 m_enable_nmi = 0;
169 break;
170 }
171 }
172
io_w(offs_t offset,uint8_t data)173 void psion_state::io_w(offs_t offset, uint8_t data)
174 {
175 switch (offset & 0x0ffc0)
176 {
177 case 0x80:
178 m_lcdc->write(offset & 0x01, data);
179 break;
180 default:
181 io_rw(offset);
182 }
183 }
184
io_r(offs_t offset)185 uint8_t psion_state::io_r(offs_t offset)
186 {
187 switch (offset & 0xffc0)
188 {
189 case 0x80:
190 return m_lcdc->read(offset & 0x01);
191 default:
192 if (!machine().side_effects_disabled())
193 io_rw(offset);
194 }
195
196 return 0;
197 }
198
INPUT_CHANGED_MEMBER(psion_state::psion_on)199 INPUT_CHANGED_MEMBER(psion_state::psion_on)
200 {
201 /* reset the CPU for resume from standby */
202 if (m_maincpu->suspended(SUSPEND_REASON_HALT))
203 m_maincpu->reset();
204 }
205
reset_kb_counter_r()206 uint8_t psion1_state::reset_kb_counter_r()
207 {
208 m_kb_counter = 0;
209 return 0;
210 }
211
inc_kb_counter_r()212 uint8_t psion1_state::inc_kb_counter_r()
213 {
214 m_kb_counter++;
215 return 0;
216 }
217
switchoff_r()218 uint8_t psion1_state::switchoff_r()
219 {
220 if (!m_stby_pwr)
221 {
222 m_stby_pwr = 1;
223 m_maincpu->reset();
224 }
225 return 0;
226 }
227
psion_int_reg(address_map & map)228 void psion_state::psion_int_reg(address_map &map)
229 {
230 // FIXME: this should all be made internal to the CPU device
231 map(0x0000, 0x001f).m(m_maincpu, FUNC(hd6301x_cpu_device::hd6301x_io));
232 }
233
psion1_mem(address_map & map)234 void psion1_state::psion1_mem(address_map &map)
235 {
236 psion_int_reg(map);
237 map(0x0040, 0x00ff).ram().share("sys_register");
238 map(0x2000, 0x2001).mirror(0x07fe).rw(m_lcdc, FUNC(hd44780_device::read), FUNC(hd44780_device::write));
239 map(0x2800, 0x2800).r(FUNC(psion1_state::reset_kb_counter_r));
240 map(0x2e00, 0x2e00).r(FUNC(psion1_state::switchoff_r));
241 map(0x3000, 0x3000).r(FUNC(psion1_state::inc_kb_counter_r));
242 map(0x4000, 0x47ff).ram().share("ram");
243 map(0xf000, 0xffff).rom();
244 }
245
psioncm_mem(address_map & map)246 void psion_state::psioncm_mem(address_map &map)
247 {
248 map.unmap_value_low();
249 psion_int_reg(map);
250 map(0x0040, 0x00ff).ram().share("sys_register");
251 map(0x0100, 0x03ff).rw(FUNC(psion_state::io_r), FUNC(psion_state::io_w));
252 map(0x2000, 0x3fff).ram().share("ram");
253 map(0x8000, 0xffff).rom();
254 }
255
psionla_mem(address_map & map)256 void psion_state::psionla_mem(address_map &map)
257 {
258 map.unmap_value_low();
259 psion_int_reg(map);
260 map(0x0040, 0x00ff).ram().share("sys_register");
261 map(0x0100, 0x03ff).rw(FUNC(psion_state::io_r), FUNC(psion_state::io_w));
262 map(0x0400, 0x5fff).ram().share("ram");
263 map(0x8000, 0xffff).rom();
264 }
265
psionp350_mem(address_map & map)266 void psion_state::psionp350_mem(address_map &map)
267 {
268 map.unmap_value_low();
269 psion_int_reg(map);
270 map(0x0040, 0x00ff).ram().share("sys_register");
271 map(0x0100, 0x03ff).rw(FUNC(psion_state::io_r), FUNC(psion_state::io_w));
272 map(0x0400, 0x3fff).ram().share("ram");
273 map(0x4000, 0x7fff).bankrw("rambank");
274 map(0x8000, 0xffff).rom();
275 }
276
psionlam_mem(address_map & map)277 void psion_state::psionlam_mem(address_map &map)
278 {
279 map.unmap_value_low();
280 psion_int_reg(map);
281 map(0x0040, 0x00ff).ram().share("sys_register");
282 map(0x0100, 0x03ff).rw(FUNC(psion_state::io_r), FUNC(psion_state::io_w));
283 map(0x0400, 0x7fff).ram().share("ram");
284 map(0x8000, 0xbfff).bankr("rombank");
285 map(0xc000, 0xffff).rom();
286 }
287
psionlz_mem(address_map & map)288 void psion_state::psionlz_mem(address_map &map)
289 {
290 map.unmap_value_low();
291 psion_int_reg(map);
292 map(0x0040, 0x00ff).ram().share("sys_register");
293 map(0x0100, 0x03ff).rw(FUNC(psion_state::io_r), FUNC(psion_state::io_w));
294 map(0x0400, 0x3fff).ram().share("ram");
295 map(0x4000, 0x7fff).bankrw("rambank");
296 map(0x8000, 0xbfff).bankr("rombank");
297 map(0xc000, 0xffff).rom();
298 }
299
300 /* Input ports */
301 INPUT_PORTS_START( psion )
302 PORT_START("BATTERY")
303 PORT_CONFNAME( 0x01, 0x00, "Battery Status" )
DEF_STR(Normal)304 PORT_CONFSETTING( 0x00, DEF_STR( Normal ) )
305 PORT_CONFSETTING( 0x01, "Low Battery" )
306
307 PORT_START("ON")
308 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ON/CLEAR") PORT_CODE(KEYCODE_MINUS) PORT_CHANGED_MEMBER(DEVICE_SELF, psion_state, psion_on, 0)
309
310 PORT_START("K1")
311 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MODE") PORT_CODE(KEYCODE_EQUALS)
312 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Up [CAP]") PORT_CODE(KEYCODE_UP)
313 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Down [NUM]") PORT_CODE(KEYCODE_DOWN)
314 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT)
315 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT)
316
317 PORT_START("K2")
318 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT)
319 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S [;]") PORT_CODE(KEYCODE_S)
320 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M [,]") PORT_CODE(KEYCODE_M)
321 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G [=]") PORT_CODE(KEYCODE_G)
322 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A [<]") PORT_CODE(KEYCODE_A)
323
324 PORT_START("K3")
325 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL)
326 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T [:]") PORT_CODE(KEYCODE_T)
327 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N [$]") PORT_CODE(KEYCODE_N)
328 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H [\"]") PORT_CODE(KEYCODE_H)
329 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B [>]") PORT_CODE(KEYCODE_B)
330
331 PORT_START("K4")
332 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y [0]") PORT_CODE(KEYCODE_Y)
333 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U [1]") PORT_CODE(KEYCODE_U)
334 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O [4]") PORT_CODE(KEYCODE_O)
335 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I [7]") PORT_CODE(KEYCODE_I)
336 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C [(]") PORT_CODE(KEYCODE_C)
337
338 PORT_START("K5")
339 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE)
340 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W [3]") PORT_CODE(KEYCODE_W)
341 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q [6]") PORT_CODE(KEYCODE_Q)
342 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K [9]") PORT_CODE(KEYCODE_K)
343 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E [%]") PORT_CODE(KEYCODE_E)
344
345 PORT_START("K6")
346 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXE") PORT_CODE(KEYCODE_ENTER)
347 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X [+]") PORT_CODE(KEYCODE_X)
348 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R [-]") PORT_CODE(KEYCODE_R)
349 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L [*]") PORT_CODE(KEYCODE_L)
350 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F [/]") PORT_CODE(KEYCODE_F)
351
352 PORT_START("K7")
353 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z [.]") PORT_CODE(KEYCODE_Z)
354 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V [2]") PORT_CODE(KEYCODE_V)
355 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P [5]") PORT_CODE(KEYCODE_P)
356 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J [8]") PORT_CODE(KEYCODE_J)
357 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D [)]") PORT_CODE(KEYCODE_D)
358 INPUT_PORTS_END
359
360 INPUT_PORTS_START( psion1 )
361 PORT_START("BATTERY")
362 PORT_CONFNAME( 0x01, 0x00, "Battery Status" )
363 PORT_CONFSETTING( 0x00, DEF_STR( Normal ) )
364 PORT_CONFSETTING( 0x01, "Low Battery" )
365
366 PORT_START("ON")
367 PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ON/CLEAR") PORT_CODE(KEYCODE_MINUS) PORT_CHANGED_MEMBER(DEVICE_SELF, psion_state, psion_on, 0)
368
369 PORT_START("K1")
370 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT)
371 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT)
372 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Down [NUM]") PORT_CODE(KEYCODE_DOWN)
373 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Up [CAP]") PORT_CODE(KEYCODE_UP)
374 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MODE") PORT_CODE(KEYCODE_EQUALS)
375
376 PORT_START("K2")
377 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT)
378 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S [;]") PORT_CODE(KEYCODE_S)
379 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M [,]") PORT_CODE(KEYCODE_M)
380 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G [=]") PORT_CODE(KEYCODE_G)
381 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A [<]") PORT_CODE(KEYCODE_A)
382
383 PORT_START("K3")
384 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y [0]") PORT_CODE(KEYCODE_Y)
385 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T [:]") PORT_CODE(KEYCODE_T)
386 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N [$]") PORT_CODE(KEYCODE_N)
387 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H [\"]") PORT_CODE(KEYCODE_H)
388 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B [>]") PORT_CODE(KEYCODE_B)
389
390 PORT_START("K4")
391 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z [.]") PORT_CODE(KEYCODE_Z)
392 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U [1]") PORT_CODE(KEYCODE_U)
393 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O [4]") PORT_CODE(KEYCODE_O)
394 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I [7]") PORT_CODE(KEYCODE_I)
395 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C [(]") PORT_CODE(KEYCODE_C)
396
397 PORT_START("K5")
398 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL)
399 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W [3]") PORT_CODE(KEYCODE_W)
400 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q [6]") PORT_CODE(KEYCODE_Q)
401 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K [9]") PORT_CODE(KEYCODE_K)
402 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E [%]") PORT_CODE(KEYCODE_E)
403
404 PORT_START("K6")
405 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXE") PORT_CODE(KEYCODE_ENTER)
406 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X [+]") PORT_CODE(KEYCODE_X)
407 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R [-]") PORT_CODE(KEYCODE_R)
408 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L [*]") PORT_CODE(KEYCODE_L)
409 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F [/]") PORT_CODE(KEYCODE_F)
410
411 PORT_START("K7")
412 PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE)
413 PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V [2]") PORT_CODE(KEYCODE_V)
414 PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P [5]") PORT_CODE(KEYCODE_P)
415 PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J [8]") PORT_CODE(KEYCODE_J)
416 PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D [)]") PORT_CODE(KEYCODE_D)
417 INPUT_PORTS_END
418
419
420 void psion_state::nvram_init(nvram_device &nvram, void *data, size_t size)
421 {
422 //cold start (by default is 1=warm start)
423 m_stby_pwr = 0;
424 }
425
426
machine_start()427 void psion_state::machine_start()
428 {
429 if (!strcmp(machine().system().name, "psionlam"))
430 {
431 m_rom_bank_count = 3;
432 m_ram_bank_count = 0;
433 }
434 else if (!strncmp(machine().system().name, "psionlz", 7))
435 {
436 m_rom_bank_count = 3;
437 m_ram_bank_count = 3;
438 }
439 else if (!strcmp(machine().system().name, "psionp464"))
440 {
441 m_rom_bank_count = 3;
442 m_ram_bank_count = 9;
443 }
444 else if (!strncmp(machine().system().name, "psionp", 6))
445 {
446 m_rom_bank_count = 0;
447 m_ram_bank_count = 5;
448 }
449 else
450 {
451 m_rom_bank_count = 0;
452 m_ram_bank_count = 0;
453 }
454
455 if (m_rom_bank_count)
456 {
457 uint8_t* rom_base = (uint8_t *)memregion("maincpu")->base();
458
459 membank("rombank")->configure_entry(0, rom_base + 0x8000);
460 membank("rombank")->configure_entries(1, m_rom_bank_count-1, rom_base + 0x10000, 0x4000);
461 membank("rombank")->set_entry(0);
462 }
463
464 if (m_ram_bank_count)
465 {
466 m_paged_ram = std::make_unique<uint8_t[]>(m_ram_bank_count * 0x4000);
467 memset(m_paged_ram.get(), 0, sizeof(uint8_t) * (m_ram_bank_count * 0x4000));
468 membank("rambank")->configure_entries(0, m_ram_bank_count, m_paged_ram.get(), 0x4000);
469 membank("rambank")->set_entry(0);
470 }
471
472 m_nvram1->set_base(m_sys_register, 0xc0);
473 m_nvram2->set_base(m_ram, m_ram.bytes());
474 if (m_nvram3)
475 m_nvram3->set_base(m_paged_ram.get(), m_ram_bank_count * 0x4000);
476
477 save_item(NAME(m_kb_counter));
478 save_item(NAME(m_enable_nmi));
479 save_item(NAME(m_stby_pwr));
480 save_item(NAME(m_pulse));
481 save_item(NAME(m_rom_bank));
482 save_item(NAME(m_ram_bank));
483 save_pointer(NAME(m_paged_ram), m_ram_bank_count * 0x4000);
484 }
485
machine_reset()486 void psion_state::machine_reset()
487 {
488 m_enable_nmi=0;
489 m_kb_counter=0;
490 m_ram_bank=0;
491 m_rom_bank=0;
492 m_pulse=0;
493
494 if (m_rom_bank_count || m_ram_bank_count)
495 update_banks();
496
497 // enable warm boot
498 u8 mcu_rp5cr = m_maincpu->space(AS_PROGRAM).read_byte(0x14);
499 m_maincpu->space(AS_PROGRAM).write_byte(0x14, (mcu_rp5cr & 0x7f) | (m_stby_pwr << 7));
500 }
501
machine_reset()502 void psion1_state::machine_reset()
503 {
504 psion_state::machine_reset();
505 m_enable_nmi = 1;
506 }
507
HD44780_PIXEL_UPDATE(psion_state::lz_pixel_update)508 HD44780_PIXEL_UPDATE(psion_state::lz_pixel_update)
509 {
510 if (pos < 40)
511 {
512 static const uint8_t psion_display_layout[] =
513 {
514 0x00, 0x01, 0x02, 0x03, 0x28, 0x29, 0x2a, 0x2b, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x2c, 0x2d, 0x2e, 0x2f,
515 0x30, 0x31, 0x32, 0x33, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
516 0x14, 0x15, 0x16, 0x17, 0x3c, 0x3d, 0x3e, 0x3f, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x40, 0x41, 0x42, 0x43,
517 0x44, 0x45, 0x46, 0x47, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f
518 };
519
520 uint8_t char_pos = psion_display_layout[line*40 + pos];
521 bitmap.pix((char_pos / 20) * 9 + y, (char_pos % 20) * 6 + x) = state;
522 }
523 }
524
HD44780_PIXEL_UPDATE(psion1_state::psion1_pixel_update)525 HD44780_PIXEL_UPDATE(psion1_state::psion1_pixel_update)
526 {
527 if (pos < 8 && line < 2)
528 bitmap.pix(y, (line * 8 + pos) * 6 + x) = state;
529 }
530
psion_palette(palette_device & palette) const531 void psion_state::psion_palette(palette_device &palette) const
532 {
533 palette.set_pen_color(0, rgb_t(138, 146, 148));
534 palette.set_pen_color(1, rgb_t(92, 83, 88));
535 }
536
537 static const gfx_layout psion_charlayout =
538 {
539 5, 8, /* 5 x 8 characters */
540 256, /* 256 characters */
541 1, /* 1 bits per pixel */
542 { 0 }, /* no bitplanes */
543 { 3, 4, 5, 6, 7},
544 { 0, 8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8},
545 8*8 /* 8 bytes */
546 };
547
548 static GFXDECODE_START( gfx_psion )
549 GFXDECODE_ENTRY( "hd44780:cgrom", 0x0000, psion_charlayout, 0, 1 )
550 GFXDECODE_END
551
552 /* basic configuration for 2 lines display */
psion_2lines(machine_config & config)553 void psion_state::psion_2lines(machine_config &config)
554 {
555 /* basic machine hardware */
556 HD6303X(config, m_maincpu, 3.6864_MHz_XTAL); // internal operating frequency is 0.9216 MHz
557 m_maincpu->in_p2_cb().set(FUNC(psion_state::port2_r));
558 m_maincpu->out_p2_cb().set(FUNC(psion_state::port2_w));
559 m_maincpu->in_p5_cb().set(FUNC(psion_state::port5_r));
560 m_maincpu->in_p6_cb().set(FUNC(psion_state::port6_r));
561 m_maincpu->out_p6_cb().set(FUNC(psion_state::port6_w));
562
563 /* video hardware */
564 screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_LCD));
565 screen.set_refresh_hz(50);
566 screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */
567 screen.set_screen_update("hd44780", FUNC(hd44780_device::screen_update));
568 screen.set_size(6*16, 9*2);
569 screen.set_visarea(0, 6*16-1, 0, 9*2-1);
570 screen.set_palette("palette");
571
572 PALETTE(config, "palette", FUNC(psion_state::psion_palette), 2);
573 GFXDECODE(config, "gfxdecode", "palette", gfx_psion);
574
575 HD44780(config, m_lcdc, 0);
576 m_lcdc->set_lcd_size(2, 16);
577
578 /* sound hardware */
579 SPEAKER(config, "mono").front_center();
580 BEEP(config, m_beep, 3250).add_route(ALL_OUTPUTS, "mono", 1.00);
581
582 NVRAM(config, "nvram1").set_custom_handler(FUNC(psion_state::nvram_init)); // sys_regs
583 NVRAM(config, "nvram2", nvram_device::DEFAULT_ALL_0); // RAM
584
585 TIMER(config, "nmi_timer").configure_periodic(FUNC(psion_state::nmi_timer), attotime::from_seconds(1));
586
587 /* Datapack */
588 PSION_DATAPACK(config, m_pack1, 0);
589 PSION_DATAPACK(config, m_pack2, 0);
590
591 /* Software lists */
592 SOFTWARE_LIST(config, "pack_list").set_original("psion2");
593 }
594
595 /* basic configuration for 4 lines display */
psion_4lines(machine_config & config)596 void psion_state::psion_4lines(machine_config &config)
597 {
598 psion_2lines(config);
599 /* video hardware */
600 subdevice<screen_device>("screen")->set_size(6*20, 9*4);
601 subdevice<screen_device>("screen")->set_visarea(0, 6*20-1, 0, 9*4-1);
602
603 m_lcdc->set_lcd_size(4, 20);
604 m_lcdc->set_pixel_update_cb(FUNC(psion_state::lz_pixel_update));
605 }
606
psion1(machine_config & config)607 void psion1_state::psion1(machine_config &config)
608 {
609 psion_2lines(config);
610 HD6301X0(config.replace(), m_maincpu, 3.6864_MHz_XTAL);
611 m_maincpu->set_addrmap(AS_PROGRAM, &psion1_state::psion1_mem);
612 m_maincpu->in_p2_cb().set(FUNC(psion1_state::port2_r));
613 m_maincpu->out_p2_cb().set(FUNC(psion1_state::port2_w));
614 m_maincpu->in_p5_cb().set(FUNC(psion1_state::port5_r));
615 m_maincpu->in_p6_cb().set(FUNC(psion1_state::port6_r));
616 m_maincpu->out_p6_cb().set(FUNC(psion1_state::port6_w));
617
618 subdevice<timer_device>("nmi_timer")->set_start_delay(attotime::from_seconds(1));
619
620 subdevice<screen_device>("screen")->set_size(6*16, 1*8);
621 subdevice<screen_device>("screen")->set_visarea(0, 6*16-1, 0, 8*1-1);
622
623 m_lcdc->set_lcd_size(1, 16);
624 m_lcdc->set_pixel_update_cb(FUNC(psion1_state::psion1_pixel_update));
625
626 /* Software lists */
627 SOFTWARE_LIST(config.replace(), "pack_list").set_original("psion1");
628 }
629
psioncm(machine_config & config)630 void psion_state::psioncm(machine_config &config)
631 {
632 psion_2lines(config);
633
634 m_maincpu->set_addrmap(AS_PROGRAM, &psion_state::psioncm_mem);
635 }
636
psionla(machine_config & config)637 void psion_state::psionla(machine_config &config)
638 {
639 psion_2lines(config);
640
641 m_maincpu->set_addrmap(AS_PROGRAM, &psion_state::psionla_mem);
642 }
643
psionlam(machine_config & config)644 void psion_state::psionlam(machine_config &config)
645 {
646 psion_2lines(config);
647
648 m_maincpu->set_addrmap(AS_PROGRAM, &psion_state::psionlam_mem);
649 }
650
psionp350(machine_config & config)651 void psion_state::psionp350(machine_config &config)
652 {
653 psion_2lines(config);
654
655 m_maincpu->set_addrmap(AS_PROGRAM, &psion_state::psionp350_mem);
656
657 NVRAM(config, "nvram3", nvram_device::DEFAULT_ALL_0); // paged RAM
658 }
659
psionlz(machine_config & config)660 void psion_state::psionlz(machine_config &config)
661 {
662 psion_4lines(config);
663
664 m_maincpu->set_addrmap(AS_PROGRAM, &psion_state::psionlz_mem);
665
666 NVRAM(config, "nvram3", nvram_device::DEFAULT_ALL_0); // paged RAM
667 }
668
669 /* ROM definition */
670
671 ROM_START( psion1 )
672 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
673 ROM_SYSTEM_BIOS(0, "v1", "Organiser I")
674 ROMX_LOAD( "psion1.rom", 0xf000, 0x1000, CRC(7e2609c1) SHA1(a3320ea8ac3ab9e0039ee16f7c571731adde5869), ROM_BIOS(0))
675 ROM_END
676
677 ROM_START( psioncm )
678 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
679 ROM_SYSTEM_BIOS(0, "v24", "CM v2.4")
680 ROMX_LOAD("24-cm.dat", 0x8000, 0x8000, CRC(f6798394) SHA1(736997f0db9a9ee50d6785636bdc3f8ff1c33c66), ROM_BIOS(0))
681 ROM_SYSTEM_BIOS(1, "v26", "CM v2.6")
682 ROMX_LOAD("26-cm.rom", 0x8000, 0x8000, CRC(21b7c94c) SHA1(e0a3168c96a3f0b37b8698e86574e40597fe3c62), ROM_BIOS(1))
683 ROM_SYSTEM_BIOS(2, "v33", "CM v3.3")
684 ROMX_LOAD("33-cm.rom", 0x8000, 0x8000, CRC(5c10b167) SHA1(6deea00fe648bddae1d61a22858023bc80277ea0), ROM_BIOS(2))
685 ROM_SYSTEM_BIOS(3, "v33f","CM v3.3 French")
686 ROMX_LOAD("33-cmf.rom", 0x8000, 0x8000, CRC(4d626ce2) SHA1(82b96f11a0abfc1931b6022b84733d975ad7ab2b), ROM_BIOS(3))
687 ROM_SYSTEM_BIOS(4, "v36f","CM v3.6 French")
688 ROMX_LOAD("36-cmf.rom", 0x8000, 0x8000, CRC(beabe0f5) SHA1(a5ef3bb92190a257cb0e94d58b2c23935436edeb), ROM_BIOS(4))
689 ROM_END
690
691 ROM_START( psionxp )
692 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
693 ROM_SYSTEM_BIOS(0, "v26", "XP v2.6")
694 ROMX_LOAD( "26-xp.rom", 0x8000, 0x8000, CRC(a81db40f) SHA1(af72d94ccee1fa1dade8776bdbd39920665a68b7), ROM_BIOS(0) )
695 ROM_END
696
697 ROM_START( psionla )
698 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
699 ROM_SYSTEM_BIOS(0, "v33", "LA v3.3")
700 ROMX_LOAD("33-la.dat", 0x8000, 0x8000, CRC(02668ed4) SHA1(e5d4ee6b1cde310a2970ffcc6f29a0ce09b08c46), ROM_BIOS(0))
701 ROM_SYSTEM_BIOS(1, "v34g", "LA v3.4 German")
702 ROMX_LOAD("34-lag.rom", 0x8000, 0x8000, CRC(13a92c4b) SHA1(dab8bd6a41a5fd509c5ad4b0b0ab80d14f2c421a), ROM_BIOS(1))
703 ROM_SYSTEM_BIOS(2, "v36", "LA v3.6")
704 ROMX_LOAD("36-la.rom", 0x8000, 0x8000, CRC(7442c7f6) SHA1(94f15bd06bd750be70fa4a4ab588237c5a703f65), ROM_BIOS(2))
705 ROM_SYSTEM_BIOS(3, "v30", "LA v3.0")
706 ROMX_LOAD("30-lahp.rom", 0x8000, 0x8000, CRC(50192528) SHA1(c556d53f70bf5ecae756b2ebfc6d954912316bbe), ROM_BIOS(3))
707 ROM_SYSTEM_BIOS(4, "v36f", "LA v3.6 French")
708 ROMX_LOAD("36-laf.rom", 0x8000, 0x8000, CRC(036ef00e) SHA1(98f303273e570e94a1e25a58cf1ffcec0db32165), ROM_BIOS(4))
709 ROM_END
710
711 ROM_START( psionp200 )
712 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
713 ROM_SYSTEM_BIOS(0, "v33", "POS200a v3.3")
714 ROMX_LOAD("33-p200a.rom", 0x8000, 0x8000, CRC(91e94998) SHA1(e9e8106eb9283d20452697859894aa407cc07bd1), ROM_BIOS(0))
715 ROM_SYSTEM_BIOS(1, "v36", "POS200 v3.6")
716 ROMX_LOAD("36-p200.rom", 0x8000, 0x8000, CRC(4569ef5b) SHA1(8c275474cc6e3f50156f0b6e32121cadd14ea8be), ROM_BIOS(1))
717 ROM_SYSTEM_BIOS(2, "v36a", "POS200a v3.6")
718 ROMX_LOAD("36-p200a.rom", 0x8000, 0x8000, CRC(36cceeb7) SHA1(57069812c5a16babfff91dc7d7e0842e5dc68652), ROM_BIOS(2))
719 ROM_SYSTEM_BIOS(3, "v36b", "POS250 v3.6")
720 ROMX_LOAD("36-p250.rom", 0x8000, 0x8000, CRC(235cc76a) SHA1(3229cdff4b049a1fbf9a758ce3abf3fdc9b547c9), ROM_BIOS(3))
721 ROM_END
722
723 ROM_START( psionp350 )
724 ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
725 ROM_SYSTEM_BIOS(0, "v36", "POS350 v3.6")
726 ROMX_LOAD("36-p350.dat", 0x8000, 0x8000, CRC(3a371a74) SHA1(9167210b2c0c3bd196afc08ca44ab23e4e62635e), ROM_BIOS(0))
727 ROM_SYSTEM_BIOS(1, "v38", "POS350 v3.8")
728 ROMX_LOAD("38-p350.dat", 0x8000, 0x8000, CRC(1b8b082f) SHA1(a3e875a59860e344f304a831148a7980f28eaa4a), ROM_BIOS(1))
729 ROM_END
730
731 ROM_START( psionlam )
732 ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
733 ROM_SYSTEM_BIOS(0, "v37", "LA v3.7")
734 ROMX_LOAD("37-lam.dat", 0x8000, 0x10000, CRC(7ee3a1bc) SHA1(c7fbd6c8e47c9b7d5f636e9f56e911b363d6796b), ROM_BIOS(0))
735 ROM_END
736
737 ROM_START( psionlz64 )
738 ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
739 ROM_SYSTEM_BIOS(0, "v44", "LZ64 v4.4")
740 ROMX_LOAD("44-lz64.dat", 0x8000, 0x10000, CRC(aa487913) SHA1(5a44390f63fc8c1bc94299ab2eb291bc3a5b989a), ROM_BIOS(0))
741 ROM_SYSTEM_BIOS(1, "v46si", "LZ64 v4.6 Spanish / Italian")
742 ROMX_LOAD("46-lz64i.rom", 0x8000, 0x10000, CRC(c96c7e65) SHA1(1b4af43657bbd3ecd92f370762bde166047b85e2), ROM_BIOS(1))
743 ROM_SYSTEM_BIOS(2, "v43", "LZ64 v4.3")
744 ROMX_LOAD("43-lz64.rom", 0x8000, 0x10000, CRC(57e7a372) SHA1(46c2da1cfe991c0c1f2486e4aa28388767937ddd), ROM_BIOS(2))
745 ROM_SYSTEM_BIOS(3, "v46a", "LZ64 v4.6a")
746 ROMX_LOAD("46a-lz64.rom", 0x8000, 0x10000, CRC(9b0d5a7a) SHA1(f1cdd6ef43cd65ef18e148deca0500f0c1ad2f80), ROM_BIOS(3))
747 ROM_SYSTEM_BIOS(4, "v46b", "LZ64 v4.6b")
748 ROMX_LOAD("46b-lz64.rom", 0x8000, 0x10000, CRC(8d1101e2) SHA1(eddd0c3a2881667a1485b0d66f82f8c7792995c2), ROM_BIOS(4))
749 ROM_SYSTEM_BIOS(5, "v45", "LZ64 v4.5")
750 ROMX_LOAD("45-lz64.rom", 0x8000, 0x10000, CRC(4fbd5d88) SHA1(43f97549d2060840aa6313d526000530f384a08f), ROM_BIOS(5))
751
752 ROM_REGION( 0x1000, "hd44780", 0 )
753 ROM_LOAD("psion_lz_charset.bin", 0x0000, 0x1000, BAD_DUMP CRC(44bff6f6) SHA1(aef544548b783d608a7d55456f6c46f421a11ed7))
754 ROM_END
755
756 ROM_START( psionlz64s )
757 ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
758 ROM_SYSTEM_BIOS(0, "v46", "LZ64 v4.6")
759 ROMX_LOAD("46-lz64s.dat", 0x8000, 0x10000, CRC(328d9772) SHA1(7f9e2d591d59ecfb0822d7067c2fe59542ea16dd), ROM_BIOS(0))
760
761 ROM_REGION( 0x1000, "hd44780", 0 )
762 ROM_LOAD("psion_lz_charset.bin", 0x0000, 0x1000, BAD_DUMP CRC(44bff6f6) SHA1(aef544548b783d608a7d55456f6c46f421a11ed7))
763 ROM_END
764
765 ROM_START( psionlz )
766 ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
767 ROM_SYSTEM_BIOS(0, "v46", "LZ v4.6")
768 ROMX_LOAD("46-lz.dat", 0x8000, 0x10000, CRC(22715f48) SHA1(cf460c81cadb53eddb7afd8dadecbe8c38ea3fc2), ROM_BIOS(0))
769 ROM_SYSTEM_BIOS(1, "v42", "LZ v4.2")
770 ROMX_LOAD("42-lz.rom", 0x8000, 0x10000, CRC(f2d6ad47) SHA1(ee8315ae872463068d805c6e0b71f62ae8eb65be), ROM_BIOS(1))
771 ROM_SYSTEM_BIOS(2, "v44", "LZ v4.4")
772 ROMX_LOAD("44-lz.rom", 0x8000, 0x10000, CRC(4a0a990b) SHA1(dde0ba69a4a7f02b610ad6bd69a8b8552b060223), ROM_BIOS(2))
773 ROM_SYSTEM_BIOS(3, "v45", "LZ v4.5")
774 ROMX_LOAD("45-lz.rom", 0x8000, 0x10000, CRC(f95d8f39) SHA1(cb64152c2418bf730c89999d1b13c1d1ada1f082), ROM_BIOS(3))
775 ROM_SYSTEM_BIOS(4, "v45s", "LZ v4.5S")
776 ROMX_LOAD("45-lzs.rom", 0x8000, 0x10000, CRC(2d082d7f) SHA1(fcd00864a0cc617e61997240945ea70a8e9fa211), ROM_BIOS(4))
777
778 ROM_REGION( 0x1000, "hd44780", 0 )
779 ROM_LOAD("psion_lz_charset.bin", 0x0000, 0x1000, BAD_DUMP CRC(44bff6f6) SHA1(aef544548b783d608a7d55456f6c46f421a11ed7))
780 ROM_END
781
782 ROM_START( psionp464 )
783 ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
784 ROM_SYSTEM_BIOS(0, "v46", "POS464 v4.6")
785 ROMX_LOAD( "46-p464.dat", 0x8000, 0x10000, CRC(672a0945) SHA1(d2a6e3fe1019d1bd7ae4725e33a0b9973f8cd7d8), ROM_BIOS(0))
786
787 ROM_REGION( 0x1000, "hd44780", 0 )
788 ROM_LOAD( "psion_lz_charset.bin", 0x0000, 0x1000, BAD_DUMP CRC(44bff6f6) SHA1(aef544548b783d608a7d55456f6c46f421a11ed7))
789 ROM_END
790
791 /* Driver */
792
793 // YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS
794 COMP( 1984, psion1, 0, 0, psion1, psion1, psion1_state, empty_init, "Psion", "Organiser I", MACHINE_NOT_WORKING )
795 COMP( 1986, psioncm, 0, 0, psioncm, psion, psion_state, empty_init, "Psion", "Organiser II CM", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
796 COMP( 1986, psionla, psioncm, 0, psionla, psion, psion_state, empty_init, "Psion", "Organiser II LA", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
797 COMP( 1986, psionxp, psioncm, 0, psionla, psion, psion_state, empty_init, "Psion", "Organiser II XP", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
798 COMP( 1986, psionp200, psioncm, 0, psionp350, psion, psion_state, empty_init, "Psion", "Organiser II P200", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
799 COMP( 1986, psionp350, psioncm, 0, psionp350, psion, psion_state, empty_init, "Psion", "Organiser II P350", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
800 COMP( 1986, psionlam, psioncm, 0, psionlam, psion, psion_state, empty_init, "Psion", "Organiser II LAM", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
801 COMP( 1989, psionlz, 0, 0, psionlz, psion, psion_state, empty_init, "Psion", "Organiser II LZ", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
802 COMP( 1989, psionlz64, psionlz, 0, psionlz, psion, psion_state, empty_init, "Psion", "Organiser II LZ64", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
803 COMP( 1989, psionlz64s, psionlz, 0, psionlz, psion, psion_state, empty_init, "Psion", "Organiser II LZ64S", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
804 COMP( 1989, psionp464, psionlz, 0, psionlz, psion, psion_state, empty_init, "Psion", "Organiser II P464", MACHINE_SUPPORTS_SAVE | MACHINE_IMPERFECT_GRAPHICS )
805