Previous 15994 Revisions Next

r8668 Saturday 31st July, 2010 at 16:33:18 UTC by Sandro Ronco
[PSION] Implemented memory bank, keyboard and LCD controller
[src/mess/drivers]psion.c

src/mess/drivers/psion.c
r8667r8668
11/***************************************************************************
2   
2
33        Psion Organiser II series
44
5      Driver by Sandro Ronco
6
7      TODO:
8      - implement Datapack read/write interface
9      - add save state and NVRAM
10      - dump CGROM of the HD44780
11      - move HD44780 implementation in a device
12
13      Note:
14      - 4 lines dysplay has an custom LCD controller derived from an HD66780
15
516        16/07/2010 Skeleton driver.
617
718      Memory map info :
819         http://archive.psion2.org/org2/techref/memory.htm
9         
20
1021****************************************************************************/
1122
1223#include "emu.h"
1324#include "cpu/m6800/m6800.h"
25#include "sound/beep.h"
1426
15static ADDRESS_MAP_START(psion_mem, ADDRESS_SPACE_PROGRAM, 8)
16   ADDRESS_MAP_UNMAP_HIGH
17   AM_RANGE(0x0000, 0x7fff) AM_RAM
27static struct _psion
28{
29   UINT8 kb_counter;
30   UINT8 enable_nmi;
31   UINT8 *sys_register;
32   UINT8 tcsr_value;
33
34   /* RAM/ROM banks */
35   UINT8 *ram;
36   UINT8 rom_bank;
37   UINT8 ram_bank;
38   UINT8 ram_bank_count;
39   UINT8 rom_bank_count;
40} psion;
41
42/*************************************************
43
44    Hitachi HD44780 LCD controller implemantation
45
46*************************************************/
47
48static struct _hd44780
49{
50   UINT8 busy_flag;
51
52   //HD44780 has only 80 bytes of DDRAM, customized HD66780 has 128 bytes
53   UINT8 ddram[128];   //internal display data RAM,
54   UINT8 cgram[64];   //internal chargen RAM
55
56   UINT8 ac;         //address counter
57   UINT8 ddram_a;      //DDRAM address
58   UINT8 cgram_a;      //CGRAM address
59   UINT8 ac_mode;      //0=DDRAM 1=CGRAM
60
61   UINT8 cursor_pos;   //cursor position
62   UINT8 display_on;   //display on/off
63   UINT8 cursor_on;   //cursor on/off
64   UINT8 blink_on;      //blink on/off
65
66   UINT8 direction;   //auto increment/decrement
67   UINT8 data_len;      //interface data length 4 or 8 bit
68   UINT8 n_line;      //number of lines
69   UINT8 char_size;   //char size 5x8 or 5x10
70
71   UINT8 disp_shift;   //display shift
72
73   UINT8 blink;
74} hd44780;
75
76static TIMER_CALLBACK( bf_clear )
77{
78   hd44780.busy_flag = 0;
79}
80
81void set_busy_flag(running_machine *machine, UINT16 usec)
82{
83   hd44780.busy_flag = 1;
84   timer_set(machine, ATTOTIME_IN_USEC(usec), NULL, 0, bf_clear);
85}
86
87void hd44780_reset(running_machine *machine)
88{
89   memset(&hd44780, 0x00, sizeof(_hd44780));
90   hd44780.direction = 1;
91   hd44780.data_len = 1;
92   set_busy_flag(machine, 1520);
93}
94
95void hd44780_control_w(running_machine *machine, UINT8 data)
96{
97   if (BIT(data, 7))
98   {
99      hd44780.ac_mode = 0;
100      hd44780.ac = data & 0x7f;
101      hd44780.ddram_a = data & 0x7f;
102      if (data != 0x81)
103         hd44780.cursor_pos = hd44780.ddram_a;
104      set_busy_flag(machine, 37);
105   }
106   else if (BIT(data, 6))
107   {
108      hd44780.ac_mode = 1;
109      hd44780.ac = data & 0x3f;
110      hd44780.cgram_a = data & 0x3f;
111      set_busy_flag(machine, 37);
112   }
113   else if (BIT(data, 5))
114   {
115      hd44780.data_len = BIT(data, 4);
116      hd44780.n_line = BIT(data, 3);
117      hd44780.char_size = BIT(data, 2);
118      set_busy_flag(machine, 37);
119   }
120   else if (BIT(data, 4))
121   {
122      UINT8 direction = (BIT(data, 2)) ? +1 : -1;
123
124      if (BIT(data, 3))
125         hd44780.disp_shift += direction;
126      else
127      {
128         hd44780.ac += direction;
129
130         if (hd44780.ac_mode == 0)
131         {
132            hd44780.ddram_a += hd44780.direction;
133            hd44780.cursor_pos += hd44780.direction;
134         }
135         else
136            hd44780.cgram_a += hd44780.direction;
137      }
138      set_busy_flag(machine, 37);
139   }
140   else if (BIT(data, 3))
141   {
142      hd44780.display_on = BIT(data, 2);
143      hd44780.cursor_on = BIT(data, 1);
144      hd44780.blink_on = BIT(data, 0);
145
146      set_busy_flag(machine, 37);
147   }
148   else if (BIT(data, 2))
149   {
150      hd44780.direction = (BIT(data, 1)) ? +1 : -1;
151      if (BIT(data, 0))
152         hd44780.disp_shift += hd44780.direction;
153
154      set_busy_flag(machine, 37);
155   }
156   else if (BIT(data, 1))
157   {
158      hd44780.ac = 0;
159      hd44780.ddram_a = 0;
160      hd44780.cgram_a = 0;
161      hd44780.cursor_pos = 0;
162      hd44780.ac_mode = 0;
163      hd44780.direction = 1;
164      set_busy_flag(machine, 1520);
165   }
166   else if (BIT(data, 0))
167   {
168      hd44780.ac = 0;
169      hd44780.ddram_a = 0;
170      hd44780.cgram_a = 0;
171      hd44780.cursor_pos = 0;
172      hd44780.ac_mode = 0;
173      hd44780.direction = 1;
174      memset(hd44780.ddram, 0x20, ARRAY_LENGTH(hd44780.ddram));
175      memset(hd44780.cgram, 0x20, ARRAY_LENGTH(hd44780.cgram));
176      set_busy_flag(machine, 1520);
177   }
178}
179
180UINT8 hd44780_control_r(running_machine *machine)
181{
182   return hd44780.busy_flag<<7 || hd44780.ac&0x7f;
183}
184
185void hd44780_data_w(running_machine *machine, UINT8 data)
186{
187   if (hd44780.ac_mode == 0)
188   {
189      hd44780.ddram[hd44780.ac] = data;
190      hd44780.ddram_a += hd44780.direction;
191      hd44780.cursor_pos += hd44780.direction;
192   }
193   else
194   {
195      hd44780.cgram[hd44780.ac] = data;
196      hd44780.cgram_a += hd44780.direction;
197   }
198
199   hd44780.ac += hd44780.direction;
200}
201
202UINT8 hd44780_data_r(running_machine *machine)
203{
204   UINT8 data;
205
206   if (hd44780.ac_mode == 0)
207   {
208      data = hd44780.ddram[hd44780.ac];
209      hd44780.ddram_a += hd44780.direction;
210      hd44780.cursor_pos += hd44780.direction;
211   }
212   else
213   {
214      data = hd44780.cgram[hd44780.ac];
215      hd44780.cgram_a += hd44780.direction;
216   }
217
218   hd44780.ac += hd44780.direction;
219
220   return data;
221}
222
223/***********************************************
224
225    basic machine
226
227***********************************************/
228
229static TIMER_CALLBACK( nmi_timer )
230{
231   if (psion.enable_nmi)
232      cputag_set_input_line(machine, "maincpu", INPUT_LINE_NMI, PULSE_LINE);
233}
234
235static TIMER_CALLBACK( blink_timer )
236{
237   hd44780.blink = ~hd44780.blink;
238}
239
240UINT8 kb_read(running_machine *machine)
241{
242   static const char *const bitnames[] = {"K1", "K2", "K3", "K4", "K5", "K6", "K7"};
243   UINT8 line, data = 0x7c;
244
245   if (psion.kb_counter)
246   {
247      for (line = 0; line < 7; line++)
248         if (psion.kb_counter == (0x7f & ~(1 << line)))
249            data = input_port_read(machine, bitnames[line]);
250   }
251   else
252   {
253      for (line = 0; line < 7; line++)
254         data &= input_port_read(machine, bitnames[line]);
255   }
256
257   return data & 0x7c;
258}
259
260void update_bank(running_machine *machine)
261{
262   if (psion.ram_bank < psion.ram_bank_count && psion.ram_bank_count)
263      memory_set_bankptr(machine,"rambank", psion.ram + psion.ram_bank*0x4000);
264
265   if (psion.rom_bank_count)
266   {
267      if (psion.rom_bank==0)
268         memory_set_bankptr(machine,"rombank", memory_region(machine, "maincpu") + 0x8000);
269      else if (psion.rom_bank < psion.rom_bank_count)
270         memory_set_bankptr(machine,"rombank", memory_region(machine, "maincpu") + psion.rom_bank*0x4000 + 0xc000);
271   }
272}
273
274WRITE8_HANDLER( hd63701_int_reg_w )
275{
276   switch (offset)
277   {
278   case 0x08:
279      psion.tcsr_value = data;
280      break;
281   }
282
283   hd63701_internal_registers_w(space, offset, data);
284}
285
286READ8_HANDLER( hd63701_int_reg_r )
287{
288   switch (offset)
289   {
290   case 0x15:
291      /*
292      x--- ---- ON key active high
293      -xxx xx-- keys matrix active low
294      ---- --x- ??
295      ---- ---x battery status
296      */
297      return kb_read(space->machine) | input_port_read(space->machine, "BATTERY") | input_port_read(space->machine, "ON");
298   case 0x08:
299      hd63701_internal_registers_w(space, offset, psion.tcsr_value);
300   default:
301      return hd63701_internal_registers_r(space, offset);
302   }
303}
304
305/* Read/Write common */
306void io_rw(const address_space* space, UINT16 offset)
307{
308   switch (offset & 0xffc0)
309   {
310   case 0xc0:
311      //Switch off
312      break;
313   case 0x100:
314      //Pulse enable
315      break;
316   case 0x140:
317      //Pulse disable
318      break;
319   case 0x200:
320      psion.kb_counter = 0;
321      break;
322   case 0x180:
323      beep_set_state(space->machine->device("beep"), 1);
324      break;
325   case 0x1c0:
326      beep_set_state(space->machine->device("beep"), 0);
327      break;
328   case 0x240:
329      if (offset == 0x260 && (psion.rom_bank_count || psion.ram_bank_count))
330      {
331         psion.ram_bank=0;
332         psion.rom_bank=0;
333         update_bank(space->machine);
334      }
335      else
336         psion.kb_counter++;
337      break;
338   case 0x280:
339      if (offset == 0x2a0 && psion.ram_bank_count)
340      {
341         psion.ram_bank++;
342         update_bank(space->machine);
343      }
344      else
345         psion.enable_nmi = 1;
346      break;
347   case 0x2c0:
348      if (offset == 0x2e0 && psion.rom_bank_count)
349      {
350         psion.rom_bank++;
351         update_bank(space->machine);
352      }
353      else
354         psion.enable_nmi = 0;
355      break;
356   }
357}
358
359WRITE8_HANDLER( io_w )
360{
361   switch (offset & 0x0ffc0)
362   {
363   case 0x80:
364      if (offset & 1)
365         hd44780_data_w(space->machine, data);
366      else
367         hd44780_control_w(space->machine, data);
368      break;
369   default:
370      io_rw(space, offset);
371   }
372}
373
374READ8_HANDLER( io_r )
375{
376   switch (offset & 0xffc0)
377   {
378   case 0x80:
379      if (offset& 1)
380         return hd44780_data_r(space->machine);
381      else
382         return hd44780_control_r(space->machine);
383   default:
384      io_rw(space, offset);
385   }
386
387   return 0;
388}
389
390static ADDRESS_MAP_START(psioncm_mem, ADDRESS_SPACE_PROGRAM, 8)
391   ADDRESS_MAP_UNMAP_LOW
392   AM_RANGE(0x0000, 0x001f) AM_READWRITE(hd63701_int_reg_r, hd63701_int_reg_w)
393   AM_RANGE(0x0040, 0x00ff) AM_RAM AM_BASE(&psion.sys_register)
394   AM_RANGE(0x0100, 0x03ff) AM_READWRITE(io_r, io_w)
395   AM_RANGE(0x2000, 0x3fff) AM_RAM
18396   AM_RANGE(0x8000, 0xffff) AM_ROM
19397ADDRESS_MAP_END
20398
399static ADDRESS_MAP_START(psionla_mem, ADDRESS_SPACE_PROGRAM, 8)
400   ADDRESS_MAP_UNMAP_LOW
401   AM_RANGE(0x0000, 0x001f) AM_READWRITE(hd63701_int_reg_r, hd63701_int_reg_w)
402   AM_RANGE(0x0040, 0x00ff) AM_RAM AM_BASE(&psion.sys_register)
403   AM_RANGE(0x0100, 0x03ff) AM_READWRITE(io_r, io_w)
404   AM_RANGE(0x0400, 0x5fff) AM_RAM
405   AM_RANGE(0x8000, 0xffff) AM_ROM
406ADDRESS_MAP_END
407
408static ADDRESS_MAP_START(psionp350_mem, ADDRESS_SPACE_PROGRAM, 8)
409   ADDRESS_MAP_UNMAP_LOW
410   AM_RANGE(0x0000, 0x001f) AM_READWRITE(hd63701_int_reg_r, hd63701_int_reg_w)
411   AM_RANGE(0x0040, 0x00ff) AM_RAM AM_BASE(&psion.sys_register)
412   AM_RANGE(0x0100, 0x03ff) AM_READWRITE(io_r, io_w)
413   AM_RANGE(0x0400, 0x3fff) AM_RAM
414   AM_RANGE(0x4000, 0x7fff) AM_RAMBANK("rambank")
415   AM_RANGE(0x8000, 0xffff) AM_ROM
416ADDRESS_MAP_END
417
418static ADDRESS_MAP_START(psionlam_mem, ADDRESS_SPACE_PROGRAM, 8)
419   ADDRESS_MAP_UNMAP_LOW
420   AM_RANGE(0x0000, 0x001f) AM_READWRITE(hd63701_int_reg_r, hd63701_int_reg_w)
421   AM_RANGE(0x0040, 0x00ff) AM_RAM AM_BASE(&psion.sys_register)
422   AM_RANGE(0x0100, 0x03ff) AM_READWRITE(io_r, io_w)
423   AM_RANGE(0x0400, 0x7fff) AM_RAM
424   AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("rombank")
425   AM_RANGE(0xc000, 0xffff) AM_ROM
426ADDRESS_MAP_END
427
428static ADDRESS_MAP_START(psionlz_mem, ADDRESS_SPACE_PROGRAM, 8)
429   ADDRESS_MAP_UNMAP_LOW
430   AM_RANGE(0x0000, 0x001f) AM_READWRITE(hd63701_int_reg_r, hd63701_int_reg_w)
431   AM_RANGE(0x0040, 0x00ff) AM_RAM AM_BASE(&psion.sys_register)
432   AM_RANGE(0x0100, 0x03ff) AM_READWRITE(io_r, io_w)
433   AM_RANGE(0x0400, 0x3fff) AM_RAM
434   AM_RANGE(0x4000, 0x7fff) AM_RAMBANK("rambank")
435   AM_RANGE(0x8000, 0xbfff) AM_ROMBANK("rombank")
436   AM_RANGE(0xc000, 0xffff) AM_ROM
437ADDRESS_MAP_END
438
21439/* Input ports */
22440INPUT_PORTS_START( psion )
441   PORT_START("BATTERY")
442      PORT_CONFNAME( 0x01, 0x00, "Battery Status" )
443      PORT_CONFSETTING( 0x00, DEF_STR( Normal ) )
444      PORT_CONFSETTING( 0x01, "Low Battery" )
445
446   PORT_START("ON")
447      PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("ON/CLEAR") PORT_CODE(KEYCODE_F10)
448
449   PORT_START("K1")
450      PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("MODE") PORT_CODE(KEYCODE_EQUALS)
451      PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Up [CAP]") PORT_CODE(KEYCODE_UP)
452      PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Down [NUM]") PORT_CODE(KEYCODE_DOWN)
453      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Left") PORT_CODE(KEYCODE_LEFT)
454      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT)
455
456   PORT_START("K2")
457      PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Shift") PORT_CODE(KEYCODE_LSHIFT)
458      PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("S [;]") PORT_CODE(KEYCODE_S)
459      PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("M [,]") PORT_CODE(KEYCODE_M)
460      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("G [=]") PORT_CODE(KEYCODE_G)
461      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("A [<]") PORT_CODE(KEYCODE_A)
462
463   PORT_START("K3")
464      PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("DEL") PORT_CODE(KEYCODE_DEL)
465      PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("T [:]") PORT_CODE(KEYCODE_T)
466      PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("N [$]") PORT_CODE(KEYCODE_N)
467      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("H [\"]") PORT_CODE(KEYCODE_H)
468      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("B [>]") PORT_CODE(KEYCODE_B)
469
470   PORT_START("K4")
471      PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Y [0]") PORT_CODE(KEYCODE_Y)
472      PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("U [1]") PORT_CODE(KEYCODE_U)
473      PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("O [4]") PORT_CODE(KEYCODE_O)
474      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("I [7]") PORT_CODE(KEYCODE_I)
475      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("C [(]") PORT_CODE(KEYCODE_C)
476
477   PORT_START("K5")
478      PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Space") PORT_CODE(KEYCODE_SPACE)
479      PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("W [3]") PORT_CODE(KEYCODE_W)
480      PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Q [6]") PORT_CODE(KEYCODE_Q)
481      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("K [9]") PORT_CODE(KEYCODE_K)
482      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("E [%]") PORT_CODE(KEYCODE_E)
483
484   PORT_START("K6")
485      PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("EXE") PORT_CODE(KEYCODE_ENTER)
486      PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("X [+]") PORT_CODE(KEYCODE_X)
487      PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("R [-]") PORT_CODE(KEYCODE_R)
488      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("L [*]") PORT_CODE(KEYCODE_L)
489      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("F [/]") PORT_CODE(KEYCODE_F)
490
491   PORT_START("K7")
492      PORT_BIT(0x04, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("Z [.]") PORT_CODE(KEYCODE_Z)
493      PORT_BIT(0x08, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("V [2]") PORT_CODE(KEYCODE_V)
494      PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("P [5]") PORT_CODE(KEYCODE_P)
495      PORT_BIT(0x20, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("J [8]") PORT_CODE(KEYCODE_J)
496      PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYBOARD) PORT_NAME("D [)]") PORT_CODE(KEYCODE_D)
23497INPUT_PORTS_END
24498
499static MACHINE_START(psion)
500{
501   if (!strcmp(machine->gamedrv->name, "psionlam"))
502   {
503      psion.rom_bank_count = 3;
504      psion.ram_bank_count = 0;
505   }
506   else if (!strcmp(machine->gamedrv->name, "psionp350"))
507   {
508      psion.rom_bank_count = 0;
509      psion.ram_bank_count = 5;
510   }
511   else if (!strncmp(machine->gamedrv->name, "psionlz", 7))
512   {
513      psion.rom_bank_count = 3;
514      psion.ram_bank_count = 3;
515   }
516   else if (!strcmp(machine->gamedrv->name, "psionp464"))
517   {
518      psion.rom_bank_count = 3;
519      psion.ram_bank_count = 9;
520   }
521   else
522   {
523      psion.rom_bank_count = 0;
524      psion.ram_bank_count = 0;
525   }
25526
26static MACHINE_RESET(psion)
27{   
527   if (psion.ram_bank_count)
528      psion.ram = auto_alloc_array(machine, UINT8, psion.ram_bank_count * 0x4000);
529
530   timer_pulse(machine, ATTOTIME_IN_SEC(1), NULL, 0, nmi_timer);
531   timer_pulse(machine, ATTOTIME_IN_MSEC(500), NULL, 0, blink_timer);
532
533   state_save_register_global_array(machine, hd44780.ddram);
534   state_save_register_global_array(machine, hd44780.cgram);
28535}
29536
537static MACHINE_RESET(psion)
538{
539   psion.enable_nmi=0;
540   psion.kb_counter=0;
541   psion.ram_bank=0;
542   psion.rom_bank=0;
543
544   hd44780_reset(machine);
545
546   if (psion.rom_bank_count || psion.ram_bank_count)
547      update_bank(machine);
548}
549
30550static VIDEO_START( psion )
31551{
32552}
33553
34static VIDEO_UPDATE( psion )
554static VIDEO_UPDATE( psion_2lines )
35555{
556   char lcd_map[2][16];
557   UINT8 cur_x = 0;
558   UINT8 cur_y = 0;
559   UINT8 display_layout[2] = {0x00, 0x40};
560
561   memset(lcd_map, 0, 2*16);
562
563   for (int i=0; i<2; i++)
564   {
565      if (hd44780.cursor_pos >= display_layout[i] && hd44780.cursor_pos < display_layout[i]+16)
566      {
567         cur_y = i+1;
568         cur_x = hd44780.cursor_pos - display_layout[i];
569      }
570
571      memcpy(&lcd_map[i], hd44780.ddram + display_layout[i], 16);
572   }
573
574   bitmap_fill(bitmap, NULL, 0);
575
576   if (hd44780.display_on)
577   {
578      for (int l=0; l<2; l++)
579         for (int i=0; i<16; i++)
580            for (int y=0; y<8; y++)
581               for (int x=0; x<5; x++)
582                  if (lcd_map[l][i] <= 0x10)
583                  {
584                     //draw CGRAM characters
585                     *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(hd44780.cgram[(lcd_map[l][i]&0x07)*8+y], 4-x);
586                  }
587                  else
588                  {
589                     //draw CGROM characters
590                     UINT8 * gc_base = memory_region(screen->machine, "chargen");
591                     *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(gc_base[(lcd_map[l][i]-0x20)*8+y], 4-x);
592                  }
593
594      //draw the cursor
595      if (hd44780.cursor_on)
596         for (int i=0; i<5; i++)
597            *BITMAP_ADDR16(bitmap, cur_y * 9-2, cur_x*6 + i) = 1;
598
599      if (!hd44780.blink && hd44780.blink_on)
600         for (int l=0; l<7; l++)
601            for (int i=0; i<5; i++)
602               *BITMAP_ADDR16(bitmap, (cur_y-1) * 9 + l, cur_x*6 + i) = 1;
603   }
604
605#if(1)
606   popmessage("cur: %u, pos %u, shift %u", hd44780.cursor_on, hd44780.ddram_a, hd44780.disp_shift);
607#endif
36608    return 0;
37609}
38610
39static MACHINE_DRIVER_START( psion )
40    /* basic machine hardware */
611static VIDEO_UPDATE( psion_4lines )
612{
613   UINT8 lcd_map[4][20];
614   UINT8 cur_x = 0;
615   UINT8 cur_y = 0;
616   UINT8 line_pos = 0;
617   UINT8 display_layout[4][3]=
618   {
619      {0x00, 0x08, 0x18},
620      {0x40, 0x48, 0x58},
621      {0x04, 0x10, 0x20},
622      {0x44, 0x50, 0x60}
623   };
624
625   memset(lcd_map, 0, 4*20);
626
627   for (int i=0; i<4; i++)
628   {
629      line_pos = 0;
630
631      for (int j=0; j<3; j++)
632      {
633         if (hd44780.cursor_pos >= display_layout[i][j] && hd44780.cursor_pos < display_layout[i][j] + ((j==0)?4:8))
634         {
635            cur_y = i+1;
636            cur_x = line_pos + hd44780.cursor_pos - display_layout[i][j];
637         }
638
639         memcpy(&lcd_map[i][line_pos], hd44780.ddram + display_layout[i][j], ((j==0)?4:8));
640
641         line_pos += (j==0)?4:8;
642      }
643   }
644
645   bitmap_fill(bitmap, NULL, 0);
646
647   if (hd44780.display_on)
648   {
649      for (int l=0; l<4; l++)
650         for (int i=0; i<20; i++)
651            for (int y=0; y<8; y++)
652               for (int x=0; x<5; x++)
653                  if (lcd_map[l][i] <= 0x10)
654                  {
655                     //draw CGRAM characters
656                     *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(hd44780.cgram[(lcd_map[l][i]&0x07)*8+y], 4-x);
657                  }
658                  else
659                  {
660                     //draw CGROM characters
661                     UINT8 * gc_base = memory_region(screen->machine, "chargen");
662                     *BITMAP_ADDR16(bitmap, l*9 + y, i*6 + x) = BIT(gc_base[(lcd_map[l][i]-0x20)*8+y], 4-x);
663                  }
664
665      //draw the cursor
666      if (hd44780.cursor_on)
667         for (int i=0; i<5; i++)
668            *BITMAP_ADDR16(bitmap, cur_y * 9-2, cur_x*6 + i) = 1;
669
670      if (!hd44780.blink && hd44780.blink_on)
671         for (int l=0; l<7; l++)
672            for (int i=0; i<5; i++)
673               *BITMAP_ADDR16(bitmap, (cur_y-1) * 9 + l, cur_x*6 + i) = 1;
674   }
675
676#if(1)
677   popmessage("cur: %u, pos %u, shift %u", hd44780.cursor_on, hd44780.cursor_pos, hd44780.disp_shift);
678#endif
679    return 0;
680}
681
682static PALETTE_INIT( psion )
683{
684   palette_set_color(machine, 0, MAKE_RGB(138, 146, 148));
685   palette_set_color(machine, 1, MAKE_RGB(92, 83, 88));
686}
687
688static const gfx_layout psion_charlayout =
689{
690   5, 8,               /* 5 x 8 characters */
691   224,               /* 224 characters */
692   1,                  /* 1 bits per pixel */
693   { 0 },               /* no bitplanes */
694   { 3, 4, 5, 6, 7},
695   { 0, 8, 2*8, 3*8, 4*8, 5*8, 6*8, 7*8},
696   8*8                  /* 8 bytes */
697};
698
699static GFXDECODE_START( psion )
700   GFXDECODE_ENTRY( "chargen", 0x0000, psion_charlayout, 0, 1 )
701GFXDECODE_END
702
703/* basic configuration for 2 lines display */
704static MACHINE_DRIVER_START( psion_2lines )
705   /* basic machine hardware */
41706    MDRV_CPU_ADD("maincpu",HD63701, 980000) // should be HD6303 at 0.98MHz
42    MDRV_CPU_PROGRAM_MAP(psion_mem)
43707
708   MDRV_MACHINE_START(psion)
44709    MDRV_MACHINE_RESET(psion)
45   
710
46711    /* video hardware */
47712    MDRV_SCREEN_ADD("screen", RASTER)
48713    MDRV_SCREEN_REFRESH_RATE(50)
49714    MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
50715    MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
51    MDRV_SCREEN_SIZE(640, 480)
52    MDRV_SCREEN_VISIBLE_AREA(0, 640-1, 0, 480-1)
716   MDRV_SCREEN_SIZE(6*16, 9*2)
717   MDRV_SCREEN_VISIBLE_AREA(0, 6*16-1, 0, 9*2-1)
718   MDRV_DEFAULT_LAYOUT(layout_lcd)
53719    MDRV_PALETTE_LENGTH(2)
54    MDRV_PALETTE_INIT(black_and_white)
720    MDRV_PALETTE_INIT(psion)
721   MDRV_GFXDECODE(psion)
55722
56723    MDRV_VIDEO_START(psion)
57    MDRV_VIDEO_UPDATE(psion)
724    MDRV_VIDEO_UPDATE(psion_2lines)
725
726   /* sound hardware */
727   MDRV_SPEAKER_STANDARD_MONO( "mono" )
728   MDRV_SOUND_ADD( "beep", BEEP, 0 )
729   MDRV_SOUND_ROUTE( ALL_OUTPUTS, "mono", 1.00 )
730
58731MACHINE_DRIVER_END
59732
733/* basic configuration for 4 lines display */
734static MACHINE_DRIVER_START( psion_4lines )
735   /* basic machine hardware */
736    MDRV_CPU_ADD("maincpu",HD63701, 980000) // should be HD6303 at 0.98MHz
737
738   MDRV_MACHINE_START(psion)
739    MDRV_MACHINE_RESET(psion)
740
741    /* video hardware */
742    MDRV_SCREEN_ADD("screen", RASTER)
743    MDRV_SCREEN_REFRESH_RATE(50)
744    MDRV_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(2500)) /* not accurate */
745    MDRV_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
746   MDRV_SCREEN_SIZE(6*20, 9*4)
747   MDRV_SCREEN_VISIBLE_AREA(0, 6*20-1, 0, 9*4-1)
748   MDRV_DEFAULT_LAYOUT(layout_lcd)
749    MDRV_PALETTE_LENGTH(2)
750    MDRV_PALETTE_INIT(psion)
751   MDRV_GFXDECODE(psion)
752
753    MDRV_VIDEO_START(psion)
754    MDRV_VIDEO_UPDATE(psion_4lines)
755
756   /* sound hardware */
757   MDRV_SPEAKER_STANDARD_MONO( "mono" )
758   MDRV_SOUND_ADD( "beep", BEEP, 0 )
759   MDRV_SOUND_ROUTE( ALL_OUTPUTS, "mono", 1.00 )
760MACHINE_DRIVER_END
761
762static MACHINE_DRIVER_START( psioncm )
763   MDRV_IMPORT_FROM( psion_2lines )
764
765   MDRV_CPU_MODIFY("maincpu")
766   MDRV_CPU_PROGRAM_MAP(psioncm_mem)
767MACHINE_DRIVER_END
768
769static MACHINE_DRIVER_START( psionla )
770   MDRV_IMPORT_FROM( psion_2lines )
771
772   MDRV_CPU_MODIFY("maincpu")
773   MDRV_CPU_PROGRAM_MAP(psionla_mem)
774MACHINE_DRIVER_END
775
776static MACHINE_DRIVER_START( psionlam )
777   MDRV_IMPORT_FROM( psion_2lines )
778
779   MDRV_CPU_MODIFY("maincpu")
780   MDRV_CPU_PROGRAM_MAP(psionlam_mem)
781MACHINE_DRIVER_END
782
783static MACHINE_DRIVER_START( psionp350 )
784   MDRV_IMPORT_FROM( psion_2lines )
785
786   MDRV_CPU_MODIFY("maincpu")
787   MDRV_CPU_PROGRAM_MAP(psionp350_mem)
788MACHINE_DRIVER_END
789
790static MACHINE_DRIVER_START( psionlz )
791   MDRV_IMPORT_FROM( psion_4lines )
792
793   MDRV_CPU_MODIFY("maincpu")
794   MDRV_CPU_PROGRAM_MAP(psionlz_mem)
795MACHINE_DRIVER_END
796
60797/* ROM definition */
61798ROM_START( psioncm )
62799    ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
63800   ROM_LOAD( "24-cm.dat",    0x8000, 0x8000,  CRC(f6798394) SHA1(736997f0db9a9ee50d6785636bdc3f8ff1c33c66))
801
802    ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
803   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
64804ROM_END
65805
66806ROM_START( psionla )
67807    ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
68808   ROM_LOAD( "33-la.dat",    0x8000, 0x8000,  CRC(02668ed4) SHA1(e5d4ee6b1cde310a2970ffcc6f29a0ce09b08c46))
809
810   ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
811   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
69812ROM_END
70813
71814ROM_START( psionp350 )
72815    ROM_REGION( 0x10000, "maincpu", ROMREGION_ERASEFF )
73816   ROM_LOAD( "36-p350.dat",  0x8000, 0x8000,  CRC(3a371a74) SHA1(9167210b2c0c3bd196afc08ca44ab23e4e62635e))
74817   ROM_LOAD( "38-p350.dat",  0x8000, 0x8000,  CRC(1b8b082f) SHA1(a3e875a59860e344f304a831148a7980f28eaa4a))
818
819   ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
820   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
75821ROM_END
76822
77823ROM_START( psionlam )
78824    ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
79   ROM_LOAD( "37-lam.dat",   0x8000, 0x10000, CRC(7ee3a1bc) SHA1(c7fbd6c8e47c9b7d5f636e9f56e911b363d6796b))   
825   ROM_LOAD( "37-lam.dat",   0x8000, 0x10000, CRC(7ee3a1bc) SHA1(c7fbd6c8e47c9b7d5f636e9f56e911b363d6796b))
826
827   ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
828   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
80829ROM_END
81830
82831ROM_START( psionlz64 )
83832    ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
84833   ROM_LOAD( "44-lz64.dat",  0x8000, 0x10000, CRC(aa487913) SHA1(5a44390f63fc8c1bc94299ab2eb291bc3a5b989a))
834
835   ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
836   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
85837ROM_END
86838
87839ROM_START( psionlz64s )
88840    ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
89841   ROM_LOAD( "46-lz64s.dat", 0x8000, 0x10000, CRC(328d9772) SHA1(7f9e2d591d59ecfb0822d7067c2fe59542ea16dd))
842
843   ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
844   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
90845ROM_END
91846
92847ROM_START( psionlz )
93848    ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
94849   ROM_LOAD( "46-lz.dat",    0x8000, 0x10000, CRC(22715f48) SHA1(cf460c81cadb53eddb7afd8dadecbe8c38ea3fc2))
850
851   ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
852   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
95853ROM_END
96854
97855ROM_START( psionp464 )
98856    ROM_REGION( 0x18000, "maincpu", ROMREGION_ERASEFF )
99857   ROM_LOAD( "46-p464.dat",  0x8000, 0x10000, CRC(672a0945) SHA1(d2a6e3fe1019d1bd7ae4725e33a0b9973f8cd7d8))
858
859   ROM_REGION( 0x00700, "chargen", ROMREGION_ERASE )
860   ROM_LOAD( "chargen.bin",    0x0000, 0x0700,  BAD_DUMP CRC(4c64fc7d) SHA1(123a87b2dc7efd7afcd8e27eb9bc74f54a8f1bc9))
100861ROM_END
101862
102863/* Driver */
103864
104865/*    YEAR  NAME    PARENT  COMPAT   MACHINE    INPUT    INIT COMPANY   FULLNAME       FLAGS */
105COMP( 1986, psioncm,   0,       0,    psion,       psion,     0,   "Psion",   "Organiser II CM",      GAME_NOT_WORKING | GAME_NO_SOUND)
106COMP( 198?, psionla,   psioncm, 0,    psion,       psion,     0,   "Psion",   "Organiser II LA",      GAME_NOT_WORKING | GAME_NO_SOUND)
107COMP( 198?, psionp350,   psioncm, 0,    psion,       psion,     0,   "Psion",   "Organiser II P350",   GAME_NOT_WORKING | GAME_NO_SOUND)
108COMP( 198?, psionlam,   psioncm, 0,    psion,       psion,     0,   "Psion",   "Organiser II LAM",   GAME_NOT_WORKING | GAME_NO_SOUND)
109COMP( 1989, psionlz64,  psioncm, 0,    psion,       psion,     0,   "Psion",   "Organiser II LZ64",   GAME_NOT_WORKING | GAME_NO_SOUND)
110COMP( 1989, psionlz64s,   psioncm, 0,    psion,       psion,     0,   "Psion",   "Organiser II LZ64S",   GAME_NOT_WORKING | GAME_NO_SOUND)
111COMP( 1989, psionlz,   psioncm, 0,    psion,       psion,     0,   "Psion",   "Organiser II LZ",      GAME_NOT_WORKING | GAME_NO_SOUND)
112COMP( 198?, psionp464,   psioncm, 0,    psion,       psion,     0,   "Psion",   "Organiser II P464",   GAME_NOT_WORKING | GAME_NO_SOUND)
866COMP( 1986, psioncm,   0,       0,    psioncm,       psion,     0,   "Psion",   "Organiser II CM",      GAME_NOT_WORKING | GAME_NO_SOUND)
867COMP( 198?, psionla,   psioncm, 0,    psionla,        psion,     0,   "Psion",   "Organiser II LA",      GAME_NOT_WORKING | GAME_NO_SOUND)
868COMP( 198?, psionp350,   psioncm, 0,    psionp350,        psion,     0,   "Psion",   "Organiser II P350",   GAME_NOT_WORKING | GAME_NO_SOUND)
869COMP( 198?, psionlam,   psioncm, 0,    psionlam,        psion,     0,   "Psion",   "Organiser II LAM",   GAME_NOT_WORKING | GAME_NO_SOUND)
870COMP( 1989, psionlz64,  psioncm, 0,    psionlz,        psion,     0,   "Psion",   "Organiser II LZ64",   GAME_NOT_WORKING | GAME_NO_SOUND)
871COMP( 1989, psionlz64s,   psioncm, 0,    psionlz,        psion,     0,   "Psion",   "Organiser II LZ64S",   GAME_NOT_WORKING | GAME_NO_SOUND)
872COMP( 1989, psionlz,   psioncm, 0,    psionlz,        psion,     0,   "Psion",   "Organiser II LZ",      GAME_NOT_WORKING | GAME_NO_SOUND)
873COMP( 198?, psionp464,   psioncm, 0,    psionlz,        psion,     0,   "Psion",   "Organiser II P464",   GAME_NOT_WORKING | GAME_NO_SOUND)

Previous 15994 Revisions Next


© 1998-2018 The MESS Team