Previous 199869 Revisions Next

r22755 Saturday 11th May, 2013 at 02:11:20 UTC by R. Belmont
this file's important too ;-) (nw)
[src/mess/video]apollo.c

trunk/src/mess/video/apollo.c
r22754r22755
11/*
22 * video/apollo.c
33 *
4 *  Created on: May 12, 2010
4 *  Created on: April 25, 2013
55 *      Author: Hans Ostermeyer
66 *
77 *  Released for general non-commercial use under the MAME license
88 *  Visit http://mamedev.org for licensing and usage restrictions.
99 *
10 *
1110 *  see also:
1211 *  - Domain Series 3000/Series 4000 Hardware Architecture Handbook (Order No. 007861 Rev. 02)
1312 *  - http://www.bitsavers.org/pdf/apollo/002398-04_Domain_Engineering_Handbook_Rev4_Jan87.pdf (page 12-16 ...)
13 *  - http://www.bitsavers.org/pdf/brooktree/Brooktree_1991.pdf (page 305 ...)
14 *
1415 */
1516
1617#define VERBOSE 0
r22754r22755
2021#include "apollo.lh"
2122#include "apollo_15i.lh"
2223
23
2424/***************************************************************************
2525 TYPE DEFINITIONS
2626 ***************************************************************************/
2727
2828// monochrome 1280x1024
29#define SCREEN_DEVICE_ID_19I 0x09
29#define SCREEN_DEVICE_ID_19I 9
3030
3131// monochrome 1024x800
32#define SCREEN_DEVICE_ID_15I 0x0b
32#define SCREEN_DEVICE_ID_15I 11
3333
34// 4 plane color 1024x800
35#define SCREEN_DEVICE_ID_C4P 8
36
37// 8 plane color 1024x800
38#define SCREEN_DEVICE_ID_C8P 10
39
3440#define VIDEO_SCREEN_TAG "screen"
3541
3642// status register
3743#define SR_BLANK        0x80
3844#define SR_V_BLANK      0x40
3945#define SR_H_SYNC       0x20
46#define SR_DONE         0x20   // 4- and 8-plane color
4047#define SR_R_M_W        0x10
4148#define SR_ALT          0x08
4249#define SR_V_SYNC       0x04
50#define SR_SYNC         0x04   // 4- and 8-plane color
4351#define SR_H_CK         0x02
4452#define SR_V_DATA       0x01
45
53#define SR_V_FLAG       0x01   // 4-plane color
54#define SR_LUT_OK       0x01   // 8-plane color
4655// control register 0
4756#define CR0_MODE(a)     ((a) >> 5)
4857#define CR0_MODE_0      0
r22754r22755
5564
5665// control register 1
5766#define CR1_INV         0x80
67#define CR1_AD_BIT      0x80   // 4- and 8-plane color
5868#define CR1_DADDR_16    0x40
59#define CR1_DV_CK       0x40
69#define CR1_DV_CK       0x40   // 4- and 8-plane color
6070#define CR1_DH_CK       0x20
6171#define CR1_ROP_EN      0x10
6272#define CR1_RESET       0x08
r22754r22755
7080#define CR2_PIXEL_ACCESS 0x01
7181#define CR2_SHIFT_ACCESS 0x02
7282#define CR2_PLANE_ACCESS 0x03
83#define CR2_S_PLANE(a)   (((a) >> 4) & 0x03)
84#define CR2_D_PLANE(a)   ((a) & 0x0f)
85#define CR2B_S_PLANE(a)  ((a) & 0x07)
86#define CR2A_D_PLANE(a)  (a)
7387
74struct screen_data_t {
75   UINT16 width;
76   UINT16 height;
77   UINT16 buffer_width;
78   UINT16 buffer_height;
88// Lookup table control register
89#define LUT_AD_CS       0x80
90#define LUT_CPAL_CS     0x40
91#define LUT_FIFO_CS     0x20
92#define LUT_FIFO_RST    0x10
93#define LUT_ST_LUK      0x08
94#define LUT_R_W         0x04
95#define LUT_C1          0x02
96#define LUT_C0          0x01
97#define LUT_C1_C0(a)    ((a)& (LUT_C1|LUT_C0))
7998
80   UINT8 status_register;
81   UINT8 device_id;
82   UINT16 write_enable_register;
83   UINT16 rop_register_0;
84   UINT16 diag_mem_request;
85   UINT8 cr0;
86   UINT8 cr1;
87   UINT8 cr2;
88   UINT8 cr3a;
99#define LUT_FIFO_SIZE   1024
89100
90   UINT8 update_flag;
91   UINT8 update_pending;
101//**************************************************************************
102//  class apollo_graphics
103//**************************************************************************
92104
93   UINT8 blt_cycle_count;
94   UINT32 guard_latch;
95   offs_t image_offset;
105class apollo_graphics /*: public device_t*/
106{
107public:
108   apollo_graphics()
109   {
110   }
96111
97   int h_clock;
98   int v_clock;
99   int pixel_clock;
100   int data_clock;
112   void device_start(running_machine &m_machine);
113   void device_reset();
114   void device_reset_mono19i();
101115
102   UINT16 *image_memory;
103   int image_memory_size;
116   // monochrome
117   READ8_DEVICE_HANDLER( apollo_mcr_r );
118   WRITE8_DEVICE_HANDLER( apollo_mcr_w );
119   READ16_DEVICE_HANDLER( apollo_mgm_r );
120   WRITE16_DEVICE_HANDLER( apollo_mgm_w );
104121
105   screen_device *screen;
122   // color
123   READ8_DEVICE_HANDLER( apollo_ccr_r );
124   WRITE8_DEVICE_HANDLER( apollo_ccr_w );
125
126   UINT32 screen_update(bitmap_rgb32 &bitmap, const rectangle &cliprect);
127   void vblank_state_changed(device_t *device, screen_device &screen, bool vblank_state);
128
129private:
130   class lut_fifo;
131   class bt458;
132
133   running_machine &machine() const
134   {
135      assert(m_machine != NULL);
136      return *m_machine;
137   }
138
139   const char *cr_text(offs_t offset, UINT8 data, UINT8 rw);
140
141   void increment_h_clock();
142   void increment_v_clock();
143   void increment_p_clock();
144
145   void log_cr1(const char * text, device_t *device);
146   void set_cr1(device_t *device, UINT8 data);
147   void set_cr3a(device_t *device, UINT8 data);
148   void set_cr3b(device_t *device, UINT8 data);
149   void set_lut_cr(device_t *device, UINT8 data);
150
151   UINT32 set_msb0(UINT32 value, UINT8 data)
152   {
153      return (value & 0xffffff00) | data;
154   }
155   UINT32 set_lsb0(UINT32 value, UINT8 data)
156   {
157      return (value & 0xffff00ff) | (data << 8);
158   }
159   UINT32 set_msb1(UINT32 value, UINT8 data)
160   {
161      return (value & 0xff00ffff) | (data << 16);
162   }
163   UINT32 set_lsb1(UINT32 value, UINT8 data)
164   {
165      return (value & 0x00ffffff) | (data << 24);
166   }
167   UINT8 get_msb1(UINT32 value)
168   {
169      return (value >> 16) & 0xff;
170   }
171   UINT8 get_lsb1(UINT32 value)
172   {
173      return (value >> 24) & 0xff;
174   }
175
176   void set_status_rmw();
177   UINT16 rop(UINT16 dest_data, UINT16 src_data, UINT8 plane);
178   void set_source_data(UINT32 offset);
179   UINT32 get_source_data(UINT8 plane);
180   void blt(UINT32 dest_addr, UINT16 mem_mask);
181
182   UINT8 get_pixel(UINT32 offset, UINT16 mask);
183   UINT8 c4p_read_adc(UINT8 data);
184   UINT8 c8p_read_adc(UINT8 data);
185
186   void screen_update1(bitmap_rgb32 &bitmap, const rectangle &cliprect);
187
188   UINT16 m_n_planes;
189   UINT16 m_width;
190   UINT16 m_height;
191   UINT16 m_buffer_width;
192   UINT16 m_buffer_height;
193
194   UINT8 m_sr;
195   UINT8 m_device_id;
196   UINT16 m_write_enable_register;
197   UINT32 m_rop_register;
198   UINT16 m_diag_mem_request;
199   UINT8 m_cr0;
200   UINT8 m_cr1;
201   UINT8 m_cr2;
202   UINT8 m_cr2b;
203   UINT8 m_cr2_s_data;
204   UINT8 m_cr2_s_plane;
205   UINT8 m_cr2_d_plane;
206   UINT8 m_cr3a;
207   UINT8 m_cr3b;
208   UINT8 m_ad_result;
209   UINT8 m_ad_pending;
210
211   UINT8 m_lut_control;
212   UINT8 m_lut_data;
213
214   UINT8 m_update_flag;
215   UINT8 m_update_pending;
216
217   UINT8 m_blt_cycle_count;
218   UINT32 m_image_offset;
219   UINT32 m_guard_latch[8];
220
221   int m_h_clock;
222   int m_v_clock;
223   int m_p_clock;
224   int m_data_clock;
225
226   UINT16 *m_image_memory;
227   int m_image_plane_size;
228   int m_image_memory_size;
229
230   UINT32 m_color_lookup_table[16];
231
232   lut_fifo *m_lut_fifo;
233   bt458 *m_bt458;
234
235   running_machine *m_machine;
106236};
107237
238 //**************************************************************************
239 // class LUT Fifo
240 //**************************************************************************
241
242class apollo_graphics::lut_fifo
243{
244public:
245   lut_fifo()
246   {
247      reset();
248   }
249
250   void reset()
251   {
252      m_size = LUT_FIFO_SIZE;
253      m_get_index = 0;
254      m_put_index = 0;
255   }
256
257   void put(const UINT8 data)
258   {
259      if (!is_full())
260      {
261         m_data[m_put_index] = data;
262         m_put_index = (m_put_index + 1) % m_size;
263      }
264   }
265
266   UINT8 get()
267   {
268      UINT8 data = is_empty() ? 0xff : m_data[m_get_index];
269      m_get_index = (m_get_index + 1) % m_size;
270      return data;
271   }
272
273   int is_empty()
274   {
275      return m_get_index == m_put_index;
276   }
277
278   int is_full()
279   {
280      return ((m_put_index + 1) % m_size) == m_get_index;
281   }
282
283private:
284   UINT16 m_size;
285   UINT16 m_get_index;
286   UINT16 m_put_index;
287   UINT8 m_data[LUT_FIFO_SIZE];
288};
289
290//**************************************************************************
291//  class Brooktree Bt458
292//**************************************************************************
293
294class apollo_graphics::bt458
295{
296public:
297   bt458(running_machine &running_machine);
298   void start();
299   void reset();
300   UINT8 read(UINT8 c10);
301   void write(UINT8 data, UINT8 c10);
302   UINT32 get_rgb(UINT8 index);
303
304private:
305   running_machine &machine() const
306   {
307      assert(m_machine != NULL);
308      return *m_machine;
309   }
310
311   UINT8 m_color_counter;
312   UINT8 m_red;
313   UINT8 m_green;
314
315   UINT8 m_address_register;
316   UINT32 m_color_palette_RAM[256];
317   UINT32 m_overlay_color[4];
318   UINT8 m_read_mask_register;
319   UINT8 m_blink_mask_register;
320   UINT8 m_command_register;
321   UINT8 m_control_test_register;
322
323   running_machine *m_machine;
324};
325
326apollo_graphics::bt458::bt458(running_machine &running_machine)
327{
328   m_machine = &running_machine;
329}
330
331void apollo_graphics::bt458::start()
332{
333   MLOG1(("start apollo_graphics::bt458"));
334}
335
336void apollo_graphics::bt458::reset()
337{
338   MLOG1(("reset apollo_graphics::bt458"));
339
340   m_color_counter = 0;
341   m_red = 0;
342   m_green = 0;
343
344   m_address_register = 0;
345   memset(m_color_palette_RAM, 0, sizeof(m_color_palette_RAM));
346   memset(m_overlay_color, 0, sizeof(m_overlay_color));
347   m_read_mask_register = 0;
348   m_blink_mask_register = 0;
349   m_command_register = 0;
350   m_control_test_register = 0;
351}
352
353void apollo_graphics::bt458::write(UINT8 data, UINT8 c10)
354{
355   MLOG1(("writing Bt458 data=%02x C1,C0=%d", data, c10));
356   switch (c10)
357   {
358   case 0: // address register
359      m_address_register = data;
360      m_color_counter = 0;
361      MLOG1(("bt458::write 0: addr=%02x", data));
362      break;
363   case 1: // color palette RAM
364      switch (m_color_counter)
365      {
366      case 0:
367         m_red = data;
368         m_color_counter++;
369         break;
370      case 1:
371         m_green = data;
372         m_color_counter++;
373         break;
374      case 2:
375         m_color_palette_RAM[m_address_register] = (m_red << 16) | (m_green << 8) | data;
376         m_address_register++;
377         m_color_counter = 0;
378         break;
379      }
380      break;
381   case 2: // registers
382      switch (m_address_register)
383      {
384      case 0x04:
385         m_read_mask_register = data;
386         MLOG1(("bt458::write: writing Bt458 m_read_mask_register=%02x", data))
387         break;
388      case 0x05:
389         m_blink_mask_register = data;
390         MLOG1(("bt458::write: writing Bt458 m_blink_mask_register=%02x", data))
391         break;
392      case 0x06:
393         m_command_register = data;
394         MLOG1(("bt458::write: writing Bt458 m_command_register=%02x", data))
395         break;
396      case 0x07:
397         m_control_test_register = data;
398         break;
399      default:
400         MLOG1(("bt458::write: writing unexpected Bt458 data=%02x C1,C0=%d at %02x", data, c10, m_address_register))
401         break;
402      }
403      break;
404   case 3: // overlay color
405      switch (m_address_register)
406      {
407      case 0x00:
408      case 0x01:
409      case 0x02:
410      case 0x03:
411         m_overlay_color[m_address_register] = data;
412         MLOG1(("bt458::write: writing Bt458 m_overlay_color[%d]=%02x",m_address_register, data));
413         break;
414      default:
415         MLOG1(("bt458::write: writing unexpected Bt458 data=%02x C1,C0=%d at %02x", data, c10, m_address_register));
416         break;
417      }
418      break;
419   default:
420      MLOG1(("bt458::write: writing unexpected Bt458 data=%02x C1,C0=%d", data, c10))
421      ;
422      break;
423   }
424}
425
426UINT8 apollo_graphics::bt458::read(UINT8 c10)
427{
428   UINT8 data = 0xff;
429
430   switch (c10)
431   {
432   case 0: // address register
433      data = m_address_register;
434      break;
435   case 1: // color palette RAM
436      switch (m_color_counter)
437      {
438      case 0: // red
439         data =  (m_color_palette_RAM[m_address_register] >> 16) & 0xff;
440         m_color_counter++;
441         break;
442      case 1: // Green
443         data =  (m_color_palette_RAM[m_address_register] >> 8) & 0xff;
444         m_color_counter++;
445         break;
446      case 2: // blue
447         data =  m_color_palette_RAM[m_address_register] & 0xff;
448         m_address_register++;
449         m_color_counter = 0;
450         break;
451      }
452      break;
453   case 2: // registers
454      switch (m_address_register)
455      {
456      case 0x04:
457         data = m_read_mask_register;
458         MLOG1(("bt458::read: reading Bt458 m_read_mask_register=%02x", data))
459         break;
460      case 0x05:
461         data = m_blink_mask_register;
462         MLOG1(("bt458::read: reading Bt458 m_blink_mask_register=%02x", data))
463         break;
464      case 0x06:
465         data = m_command_register;
466         MLOG1(("bt458::read: reading Bt458 m_command_register=%02x", data))
467         break;
468      case 0x07:
469         {
470            UINT32 rgb = m_color_palette_RAM[0];
471            switch (m_control_test_register & 0x0f)
472            {
473            case 0x01: data = 0x01 | ((rgb >> 16) & 0xf0); break;
474            case 0x09: data = 0x09 | ((rgb >> 12) & 0xf0); break;
475            case 0x02: data = 0x02 | ((rgb >> 8) & 0xf0); break;
476            case 0x0a: data = 0x0a | ((rgb >> 4) & 0xf0); break;
477            case 0x04: data = 0x04 | ((rgb >> 0) & 0xf0); break;
478            case 0x0c: data = 0x0c | ((rgb << 4) & 0xf0); break;
479            default: data = 0xff; break;
480            }
481         }
482         break;
483      default:
484         MLOG1(("bt458::read: reading unexpected Bt458 data=%02x C1,C0=%d at %02x", data, c10, m_address_register))
485         break;
486      }
487      break;
488   default:
489      MLOG1(("bt458::read: reading unexpected Bt458 data=%02x C1,C0=%d at %02x", data, c10, m_address_register))
490      break;
491   }
492
493//   MLOG1(("reading Bt458 data=%02x cs=%d", m_data, c10));
494   return data;
495}
496
497UINT32 apollo_graphics::bt458::get_rgb(UINT8 index)
498{
499   return m_color_palette_RAM[index];
500}
501
108502/*****************************************************************************
109503 INLINE FUNCTIONS
110504 *****************************************************************************/
111505
112INLINE screen_data_t *get_safe_token(device_t *device) {
506INLINE apollo_graphics *get_safe_token(device_t *device)
507{
113508   assert(device != NULL);
114   assert(device->type() == APOLLO_MONO15I || device->type() == APOLLO_MONO19I );
115   return (screen_data_t *)downcast<apollo_mono_device *>(device)->token();
509   assert(device->type() == APOLLO_GRAPHICS || device->type() == APOLLO_MONO19I );
510   return (apollo_graphics *) downcast<apollo_graphics_15i *> (device)->token();
116511}
117512
513void apollo_graphics::device_start(running_machine &running_machine)
514{
515   m_n_planes = 0;
516   m_width = 0;
517   m_height = 0;
518   m_buffer_width = 0;
519   m_buffer_height = 0;
520
521   m_sr = 0;
522   m_device_id = 0;
523   m_write_enable_register = 0;
524   m_rop_register = 0;
525   m_diag_mem_request = 0;
526   m_cr0 = 0;
527   m_cr1 = 0;
528   m_cr2 = 0;
529   m_cr2b = 0;
530   m_cr2_s_data = 0;
531   m_cr2_s_plane = 0x00;
532   m_cr2_d_plane = 0x0e;
533   m_cr3a = 0;
534   m_cr3b = 0;
535   m_ad_result = 0;
536   m_ad_pending = 0;
537
538   m_lut_control = 0;
539   m_lut_data = 0;
540
541   m_update_flag = 0;
542   m_update_pending = 0;
543
544   m_blt_cycle_count = 0;
545   m_image_offset = 0;
546   memset(m_guard_latch, 0, sizeof(m_guard_latch));
547
548   m_h_clock = 0;
549   m_v_clock = 0;
550   m_p_clock = 0;
551   m_data_clock = 0;
552
553   m_image_memory = 0;
554   m_image_plane_size = 0;
555   m_image_memory_size = 0;
556
557   memset(m_color_lookup_table, 0, sizeof(m_color_lookup_table));
558
559   m_lut_fifo = NULL;
560   m_bt458 = NULL;
561
562   m_machine = &running_machine;
563}
564
565void apollo_graphics::device_reset()
566{
567   if (m_n_planes == 0)
568   {
569      if (apollo_config(APOLLO_CONF_MONO_19I))
570      {
571         // monochrome 1280x1024
572         m_n_planes = 1;
573         m_device_id = SCREEN_DEVICE_ID_19I;
574         m_width = 1280;
575         m_height = 1024;
576         m_buffer_width = 2048;
577         m_buffer_height = 1024;
578      }
579      else if (apollo_config(APOLLO_CONF_MONO_15I))
580      {
581         // monochrome 1024x800
582         m_n_planes = 1;
583         m_device_id = SCREEN_DEVICE_ID_15I;
584         m_width = 1024;
585         m_height = 800;
586         m_buffer_width = 1024;
587         m_buffer_height = 1024;
588      }
589      else if (apollo_config(APOLLO_CONF_4_PLANES))
590      {
591         // 4-planes color 1024x800
592         m_n_planes = 4;
593         m_device_id = SCREEN_DEVICE_ID_C4P;
594         m_width = 1024;
595         m_height = 800;
596         m_buffer_width = 1024;
597         m_buffer_height = 1024;
598      }
599      else
600      {
601         // 8-planes color 1024x800
602         m_n_planes = 8;
603         m_device_id = SCREEN_DEVICE_ID_C8P;
604         m_width = 1024;
605         m_height = 800;
606         m_buffer_width = 1024;
607         m_buffer_height = 1024;
608
609         m_lut_fifo = new lut_fifo();
610
611         m_bt458 = new bt458(*m_machine);
612         m_bt458->start();
613         m_bt458->reset();
614      }
615   }
616
617   if (m_image_memory == NULL)
618   {
619      /* allocate the memory image */
620      m_image_plane_size = m_buffer_height * m_buffer_width / 16;
621      m_image_memory_size = m_image_plane_size * m_n_planes;
622      m_image_memory
623            = auto_alloc_array(machine(), UINT16, m_image_memory_size);
624      assert(m_image_memory != NULL);
625
626      MLOG1(("device reset apollo graphics: buffer=%p size=%0x", m_image_memory, m_image_memory_size));
627   }
628
629   memset(m_color_lookup_table, 0, sizeof(m_color_lookup_table));
630   memset(m_image_memory, 0, m_image_memory_size * 2);
631
632   //   register_vblank_callback(this);
633}
634
635void apollo_graphics::device_reset_mono19i()
636{
637   if (m_n_planes == 0)
638   {
639      // monochrome 1280x1024
640      m_n_planes = 1;
641      m_device_id = SCREEN_DEVICE_ID_19I;
642      m_width = 1280;
643      m_height = 1024;
644      m_buffer_width = 2048;
645      m_buffer_height = 1024;
646   }
647
648   device_reset();
649}
650
118651/***************************************************************************
119652 Monochrome Controller Registers at 0x5d800 - 0x5dc07
120653 ***************************************************************************/
121654
122static void log_cr1(const char * text, device_t *device, screen_data_t *screen_data) {
123   DLOG1(("%s: cr0=%02x cr1=%02x sr=%02x pixel_clock=%3d/%3d bl=%d vb=%d vs=%d hs=%d hc=%d vck=%d hck=%d pck=%d vd=%d",
124         text,
125         screen_data->cr0,
126         screen_data->cr1,
127         screen_data->status_register,
128         screen_data->pixel_clock,
129         screen_data->data_clock,
130         screen_data->status_register & SR_BLANK ? 1 : 0,
131         screen_data->status_register & SR_V_BLANK ? 1 : 0,
132         screen_data->status_register & SR_V_SYNC ? 1 : 0,
133         screen_data->status_register & SR_H_SYNC ? 1 : 0,
134         screen_data->status_register & SR_H_CK ? 1 : 0,
135         screen_data->cr1 & CR1_DV_CK ? 1 : 0,
136         screen_data->cr1 & CR1_DH_CK ? 1 : 0,
137         screen_data->cr1 & CR1_DP_CK ? 1 : 0,
138         screen_data->status_register & SR_V_DATA ? 1 : 0));
655const char *apollo_graphics::cr_text(offs_t offset, UINT8 data, UINT8 rw)
656{
657   static const char *cr0[8] =
658   { "cr0 mode=0 CPU dest BLT", "cr0 mode=1 Alternating BLT",
659         "cr0 mode=2 Vector mode", "cr0 mode=3 CPU Source BLT",
660         "cr0 mode=4 Double access BLT ", "cr0 mode=5 ???",
661         "cr0 mode=6 ???", "cr0 mode=7 Normal" };
662
663   static const char *cr2[4] =
664         { "cr2 Constant access", "cr2 Pixel access", "cr2 ???",
665               "cr2 Plane access" };
666
667   static const char *cr2b[4] =
668   { "cr2b Constant access", "cr2b Pixel access", "cr2b ???",
669         "cr2b Plane access" };
670
671   switch (offset & 0x407)
672   {
673   case 0:
674      return rw ? "sr" : "we";
675   case 1:
676      return rw ? "id" : "we";
677   case 2:
678   case 3:
679      return "rop0";
680   case 4:
681   case 5:
682      return m_n_planes == 8 ? "rop1" : "mem refresh";
683   case 6:
684   case 7:
685      return m_n_planes == 8 ? "mem refresh" : "???";
686   case 0x400:
687      return cr0[data >> 5];
688   case 0x401:
689      return m_n_planes == 8 ? "LUT data" : "red";
690   case 0x402:
691      return "cr1";
692   case 0x403:
693      return m_n_planes == 8 ? "LUT ctrl" : "green";
694   case 0x404:
695      return m_n_planes == 8 ? "cr2a" : cr2[data >> 6];
696   case 0x405:
697      return m_n_planes == 8 ? cr2b[data >> 6] : "blue";
698   case 0x406:
699      return "cr3";
700   case 0x407:
701      return m_n_planes == 8 ? "cr3b" : "a/d";
702   default:
703      return "???";
704   }
139705}
140706
141static void set_cr1(device_t *device, screen_data_t *screen_data,
142      UINT8 data) {
143   UINT8 diffs = screen_data->cr1 ^ data;
144   screen_data->cr1 = data;
707void apollo_graphics::log_cr1(const char * text, device_t *device)
708{
709   DLOG2(("%s: cr0=%02x cr1=%02x sr=%02x pixel_clock=%3d/%3d bl=%d vb=%d vs=%d hs=%d hc=%d vck=%d hck=%d pck=%d vd=%d",
710               text,
711               m_cr0,
712               m_cr1,
713               m_sr,
714               m_p_clock,
715               m_data_clock,
716               m_sr & SR_BLANK ? 1 : 0,
717               m_sr & SR_V_BLANK ? 1 : 0,
718               m_sr & SR_V_SYNC ? 1 : 0,
719               m_sr & SR_H_SYNC ? 1 : 0,
720               m_sr & SR_H_CK ? 1 : 0,
721               m_cr1 & CR1_DV_CK ? 1 : 0,
722               m_cr1 & CR1_DH_CK ? 1 : 0,
723               m_cr1 & CR1_DP_CK ? 1 : 0,
724               m_sr & SR_V_DATA ? 1 : 0));
725}
145726
146//  if (screen_data->cr1 & CR1_SYNC_EN) {
147//      // normal mode
148//  } else
727void apollo_graphics::increment_h_clock()
728{
729   MLOG1(("increment_h_clock: sr=%02x m_h_clock=%d", m_sr, m_h_clock));
149730
150   if ((screen_data->cr1 & CR1_RESET) == 0) {
151      if (diffs & CR1_RESET) {
152         screen_data->blt_cycle_count = 0;
153         screen_data->image_offset = 0;
154         screen_data->guard_latch = 0;
155
156         screen_data->h_clock = 0;
157         screen_data->v_clock = 0;
158         screen_data->pixel_clock = 0;
159         if (screen_data->device_id == SCREEN_DEVICE_ID_19I) {
160            screen_data->data_clock = -11; // TODO: why not 0 ????
161            screen_data->status_register = SR_H_CK | SR_V_BLANK | SR_H_SYNC
162                  | SR_V_SYNC;
163         } else {
164            screen_data->data_clock = -9; // TODO: why not 0 ????
165            screen_data->status_register = SR_V_BLANK | SR_V_SYNC;
731   if (m_device_id == SCREEN_DEVICE_ID_19I)
732   {
733      // DISP7A.DEX Test 5
734      // Note: 108 = 80 + 28 = 1280/16 + 448/16
735      switch (m_h_clock %= 108)
736      {
737      case 8: // Not blanking
738         m_sr |= SR_BLANK;
739         break;
740      case 88: // blanking
741         m_sr &= ~SR_BLANK;
742         break;
743      case 93: // HSync active
744         m_sr &= ~SR_H_SYNC;
745         // DISP7A.DEX.1 Test 6
746         increment_v_clock();
747         break;
748      case 104: // HSync inactive
749         m_sr |= SR_H_SYNC;
750         break;
751      }
752   }
753   else if (m_n_planes == 1)
754   {
755      switch (m_h_clock %= 84)
756      {
757      case 1: // HSync inactive
758         m_sr |= SR_H_SYNC;
759         break;
760      case 8: // Not blanking
761         m_sr |= SR_BLANK;
762         break;
763      case 72: // blanking
764         m_sr &= ~SR_BLANK;
765         break;
766      case 77: // HSync active
767         m_sr &= ~SR_H_SYNC;
768         // DISP7D.DEX.1 Test 6
769         increment_v_clock();
770         break;
771      }
772   }
773   else if (m_n_planes == 4)
774   {
775      switch (m_h_clock %= 84)
776      {
777      case 8: // Not blanking
778         m_sr |= SR_BLANK;
779         if (m_sr & SR_V_BLANK)
780         {
781            m_sr |= SR_V_FLAG;
166782         }
783         break;
784      case 73: // blanking
785         m_sr &= ~SR_BLANK;
786         if (m_sr & SR_V_BLANK)
787         {
788            m_sr &= ~SR_V_FLAG;
789         }
790         break;
167791      }
168      log_cr1("CR1_RESET", device, screen_data);
169   } else {
170      if ((diffs & CR1_RESET) && (screen_data->cr1 & CR1_RESET) != 0) {
171         log_cr1("CR1_RESET", device, screen_data);
792   }
793   else // m_n_planes == 8
794   {
795      switch (m_h_clock %= 84)
796      {
797      case 9: // Not blanking
798         m_sr |= SR_BLANK;
799         break;
800      case 73: // blanking
801         m_sr &= ~SR_BLANK;
802         break;
172803      }
804   }
805   m_h_clock++;
806}
173807
174      if ((diffs & CR1_DH_CK) && (screen_data->cr1 & CR1_DH_CK) == 0) {
175         if (screen_data->device_id == SCREEN_DEVICE_ID_19I) {
176            switch (screen_data->h_clock %= 108) {
177            case 8:
178               screen_data->status_register |= SR_BLANK;
179               break;
180            case 88:
181               screen_data->status_register &= ~SR_BLANK;
182               break;
183            case 93:
184               screen_data->status_register &= ~SR_H_SYNC;
185                  // trigger Dp_Ck
186                  diffs |= CR1_DP_CK;
187                  screen_data->cr1 &= ~CR1_DP_CK;
188               break;
189            case 104:
190               screen_data->status_register |= SR_H_SYNC;
191               break;
192            }
193         } else {
194            switch (screen_data->h_clock %= 84) {
195            case 1:
196               screen_data->status_register |= SR_H_SYNC;
197               break;
198            case 8:
199               screen_data->status_register |= SR_BLANK;
200               break;
201            case 72:
202               screen_data->status_register &= ~SR_BLANK;
203               break;
204            case 77:
205               screen_data->status_register &= ~SR_H_SYNC;
206               diffs |= CR1_DV_CK;
207               data &= ~CR1_DV_CK;
208               break;
209            }
210         }
211         screen_data->h_clock++;
212         log_cr1("CR1_DH_CK",device, screen_data);
808void apollo_graphics::increment_v_clock()
809{
810   MLOG1(("increment_v_clock: sr=%02x m_v_clock=%d", m_sr, m_v_clock));
811
812   if (m_device_id == SCREEN_DEVICE_ID_19I)
813   {
814      switch (m_v_clock %= 1066)
815      {
816      case 1023: // blanking
817         m_sr &= ~(SR_V_BLANK | SR_BLANK);
818         break;
819      case 1028: // VSync active
820         m_sr &= ~SR_V_SYNC;
821         break;
822      case 1032: // VSync inactive
823         m_sr |= SR_V_SYNC;
824         break;
825      case 1065: // not blanking
826         m_sr |= (SR_V_BLANK | SR_BLANK);
827         break;
213828      }
829   }
830   else if (m_n_planes == 1)
831   {
832      switch (m_v_clock %= 842)
833      {
834      case 799:
835         m_sr &= ~SR_V_BLANK;
836         break;
837      case 804:
838         m_sr &= ~SR_SYNC;
839         break;
840      case 808:
841         m_sr |= SR_SYNC;
842         break;
843      case 841:
844         m_sr |= SR_V_BLANK;
845         break;
846      }
847   }
848   else if (m_n_planes == 4)
849   {
850      // DISP7B.DEX Test 6 and Test 20
851      switch (m_v_clock %= 842)
852      {
853      case 799:
854         m_sr &= ~SR_V_BLANK;
855         m_sr &= ~SR_V_FLAG;
856         break;
857      case 803:
858         m_sr &= ~SR_SYNC;
859         break;
860      case 807:
861         m_sr |= SR_SYNC;
862         break;
863      case 836:
864         m_sr |= SR_V_FLAG;
865         break;
866      case 841:
867         m_sr |= SR_V_BLANK;
868         break;
869      }
870   }
871   else if (m_n_planes == 8)
872   {
873      // DISP7C.DEX Test 50
874      switch (m_v_clock %= 842)
875      {
876      case 800:
877         m_sr &= ~SR_V_BLANK;
878         break;
879      case 804:
880         m_sr &= ~SR_SYNC;
881         break;
882      case 808:
883         m_sr |= SR_SYNC;
884         break;
885      case 0:
886         m_sr |= SR_V_BLANK;
887         break;
888      }
889   }
890   m_v_clock++;
891   m_p_clock = 0;
892   m_data_clock = 0;
893}
214894
215      if ((diffs & CR1_DV_CK) && (screen_data->cr1 & CR1_DV_CK) == 0) {
216         // this is used for disp.dex Test 19: Video RAM Shift Reg. Test
217         if (screen_data->device_id == SCREEN_DEVICE_ID_15I) {
218            switch (screen_data->v_clock %= 842) {
219            case 799:
220               screen_data->status_register &= ~SR_V_BLANK;
221               break;
222            case 804:
223               screen_data->status_register &= ~SR_V_SYNC;
224               break;
225            case 808:
226               screen_data->status_register |= SR_V_SYNC;
227               break;
228            case 841:
229               screen_data->status_register |= SR_V_BLANK;
230               break;
231            }
232            screen_data->v_clock++;
233            log_cr1("CR1_DV_CK",device, screen_data);
234         }
895void apollo_graphics::increment_p_clock()
896{
897   if (m_n_planes == 1)
898   {
899      if ((m_cr1 & CR1_DISP_EN) == 0)
900      {
901         m_sr &= ~SR_V_DATA;
235902      }
903      else
904      {
905         int pixel_offset = (m_device_id == SCREEN_DEVICE_ID_19I) ? 10 : 8;
236906
237      if ((diffs & CR1_DP_CK) && (screen_data->cr1 & CR1_DP_CK) == 0) {
238         if (screen_data->device_id == SCREEN_DEVICE_ID_19I) {
239            switch (screen_data->pixel_clock %= 1066) {
240            case 1023:
241               screen_data->status_register &= ~SR_V_BLANK;
242               break;
243            case 1028:
244               screen_data->status_register &= ~SR_V_SYNC;
245               break;
246            case 1032:
247               screen_data->status_register |= SR_V_SYNC;
248               break;
249            case 1065:
250               screen_data->status_register |= SR_V_BLANK;
251               break;
252            }
253         } else /*if (screen_data->pixel_clock == 0)*/ {
254            // this is used for disp.dex Test 6: Vertical Counter Test
255            switch (screen_data->pixel_clock %= 842) {
256            case 799:
257               screen_data->status_register &= ~SR_V_BLANK;
258               break;
259            case 804:
260               screen_data->status_register &= ~SR_V_SYNC;
261               break;
262            case 808:
263               screen_data->status_register |= SR_V_SYNC;
264               break;
265            case 841:
266               screen_data->status_register |= SR_V_BLANK;
267               break;
268            }
907         if (m_p_clock > pixel_offset)
908         {
909            // FIXME: ok for DEX Test 5 6 17 19 - nok for 20
910            int pixel_addr = m_v_clock * m_width + m_data_clock;
911
912            // FIXME: ok for DEX Test 5 6 17 20 - nok for 19
913            // Note: for dn3500_19i DEX Test 17 18 20 will fail !!!!
914            // Note: must NOT reset m_data_clock in increment_p_clock !
915//            int pixel_addr = m_data_clock * 32;
916
917            UINT16 pixel = m_image_memory[pixel_addr / 16] & (0x8000 >> (pixel_addr % 16));
918
919            pixel = (pixel ? 1 : 0) ^ ((m_cr1 & CR1_INV) ? 0 : 1);
920
921            m_sr = pixel ? (m_sr | SR_V_DATA) : (m_sr & ~SR_V_DATA);
922
923            m_data_clock++;
269924         }
270925
271         if ((screen_data->cr1 & CR1_DISP_EN) == 0) {
272            screen_data->status_register &= ~SR_V_DATA;
273         }else           {
274            UINT16 pixel = screen_data->image_memory[screen_data->data_clock / 16]
275                        & (0x8000 >> (screen_data->data_clock % 16));
276            pixel = (pixel ? 1 : 0) ^ ((screen_data->cr1 & CR1_INV) ? 0 : 1);
926         m_p_clock++;
277927
278            if (pixel) {
279               screen_data->status_register |= SR_V_DATA;
280            } else {
281               screen_data->status_register &= ~SR_V_DATA;
282            }
283            screen_data->data_clock++;
928         // DEX Test 4: Pixel Counter Test
929         if ((m_p_clock % 8) == 0)
930         {
931            m_sr ^= SR_H_CK;
284932         }
933      }
934   }
935   else if (m_n_planes == 4)
936   {
937      if ((m_p_clock % 8) == 0 && m_p_clock > 0)
938      {
939         m_sr ^= SR_H_CK;
940      }
941      m_p_clock++;
942   }
943   else // m_n_planes == 8
944   {
945      if ((m_p_clock % 8) == 1 && m_p_clock > 1)
946      {
947         m_sr ^= SR_H_CK;
948      }
949      m_p_clock++;
950   }
951}
285952
286         screen_data->pixel_clock++;
287         if ((screen_data->pixel_clock % 8) == 0) {
288            screen_data->status_register ^= SR_H_CK;
953void apollo_graphics::set_cr1(device_t *device, UINT8 data)
954{
955   UINT8 diffs = m_cr1 ^ data;
956   m_cr1 = data;
957
958   UINT8 dp_clock = (diffs & CR1_DP_CK) && (m_cr1 & CR1_DP_CK) == 0;
959   UINT8 dh_clock = (diffs & CR1_DH_CK) && (m_cr1 & CR1_DH_CK) == 0;
960   UINT8 dv_clock = m_n_planes == 1 ? 0 : ((diffs & CR1_DV_CK) && (m_cr1 & CR1_DV_CK) == 0);
961
962   if ((m_cr1 & CR1_RESET) == 0)
963   {
964      if (diffs & CR1_RESET)
965      {
966         MLOG1(("!!! set_cr1: CR1_RESET"));
967
968         m_blt_cycle_count = 0;
969         m_sr &= ~SR_ALT;
970         m_image_offset = 0;
971         memset(m_guard_latch, 0, sizeof(m_guard_latch));
972
973         m_h_clock = 0;
974         m_v_clock = 0;
975         m_p_clock = 0;
976         m_data_clock = 0;
977
978         if (m_device_id == SCREEN_DEVICE_ID_19I)
979         {
980            m_sr = SR_H_CK | SR_V_BLANK | SR_H_SYNC | SR_V_SYNC;
289981         }
982         else if (m_n_planes == 1)
983         {
984            m_sr = SR_V_BLANK | SR_V_SYNC;
985         }
986         else
987         {
988            m_sr = SR_H_CK | SR_V_BLANK | SR_SYNC | SR_DONE;
989         }
990      }
991      log_cr1("CR1_RESET", device);
992   }
993   else
994   {
995      if ((diffs & CR1_RESET) && (m_cr1 & CR1_RESET) != 0)
996      {
997         log_cr1("CR1_RESET", device);
998      }
290999
291         log_cr1("CR1_DP_CK", device, screen_data);
1000      if (dh_clock)
1001      {
1002         increment_h_clock();
1003         log_cr1("CR1_DH_CK", device);
2921004      }
2931005
294      if ((screen_data->status_register & SR_V_BLANK) == 0) {
295         screen_data->status_register &= ~SR_BLANK;
1006      if (dv_clock)
1007      {
1008         increment_v_clock();
1009         log_cr1("CR1_DV_CK", device);
2961010      }
2971011
298      if (diffs & CR1_DISP_EN) {
1012      if (dp_clock)
1013      {
1014         increment_p_clock();
1015         log_cr1("CR1_DP_CK", device);
1016      }
1017
1018      if ((m_sr & SR_V_BLANK) == 0)
1019      {
1020         m_sr &= ~SR_BLANK;
1021      }
1022
1023      if (diffs & CR1_DISP_EN)
1024      {
2991025         // update screen
300         screen_data->update_flag = 1;
1026         m_update_flag = 1;
3011027      }
3021028   }
3031029}
3041030
305static void set_cr3(device_t *device, screen_data_t *screen_data, UINT8 data) {
306   screen_data->cr3a = data;
307   if ((data & 0x80) == 0) {
1031void apollo_graphics::set_cr3a(device_t *device, UINT8 data)
1032{
1033   m_cr3a = data;
1034   if ((data & 0x80) == 0)
1035   {
3081036      int shift = (data & 0x0f) >> 1;
3091037      UINT8 bit_mask = 1 << shift;
310      if (data & 0x01) {
311         set_cr1(device, screen_data, screen_data->cr1 | bit_mask);
312      } else {
313         set_cr1(device, screen_data, screen_data->cr1 & ~bit_mask);
1038      if (data & 0x01)
1039      {
1040         set_cr1(device, m_cr1 | bit_mask);
3141041      }
1042      else
1043      {
1044         set_cr1(device, m_cr1 & ~bit_mask);
1045      }
3151046   }
3161047}
3171048
318READ16_DEVICE_HANDLER( apollo_mcr_r ) {
319   screen_data_t *screen_data = get_safe_token(device);
320   UINT16 data;
321   switch (offset & 0x203) {
1049void apollo_graphics::set_cr3b(device_t *device, UINT8 data)
1050{
1051   m_cr3b = data;
1052   if ((data & 0x80) == 0)
1053   {
1054      int shift = (data & 0x0f) >> 1;
1055      UINT8 bit_mask = 1 << shift;
1056      if (data & 0x01)
1057      {
1058         set_lut_cr(device, m_lut_control | bit_mask);
1059      }
1060      else
1061      {
1062         set_lut_cr(device, m_lut_control & ~bit_mask);
1063      }
1064   }
1065}
1066
1067void apollo_graphics::set_lut_cr(device_t *device, UINT8 data)
1068{
1069   UINT8 diffs = m_lut_control ^ data;
1070   m_lut_control = data;
1071
1072   if ((diffs & LUT_CPAL_CS) && (data & LUT_CPAL_CS) != 0)
1073   {
1074      DLOG1(("writing Color Graphics Controller: LUT_CPAL_CS Disabled"));
1075      while (!m_lut_fifo->is_empty())
1076      {
1077         m_bt458->write(m_lut_fifo->get(), LUT_C1_C0(m_lut_control));
1078      }
1079   }
1080
1081   if ((diffs & LUT_FIFO_RST) && (data & LUT_FIFO_RST) == 0)
1082   {
1083      DLOG1(("writing Color Graphics Controller: LUT_FIFO_RST Active"));
1084      m_lut_fifo->reset();
1085      m_sr |= SR_LUT_OK;
1086   }
1087
1088   if ((diffs & LUT_FIFO_CS) && (data & LUT_FIFO_CS) == 0)
1089   {
1090      DLOG1(("writing Color Graphics Controller: LUT_FIFO_CS Enabled"));
1091   }
1092
1093   if ((diffs & LUT_ST_LUK) && (data & LUT_ST_LUK) == 0)
1094   {
1095      DLOG1(("writing Color Graphics Controller: LUT_ST_LUK Active"));
1096      m_sr &= ~SR_LUT_OK;
1097   }
1098}
1099
1100READ8_DEVICE_HANDLER( apollo_graphics::apollo_mcr_r )
1101{
1102   UINT8 data;
1103   switch (offset & 0x407)
1104   {
3221105   case 0:
1106      data = m_sr;
1107      if (m_ad_pending)
1108      {
1109         m_ad_pending = 0;
1110         m_sr &= ~SR_DONE;
1111      }
1112      break;
3231113   case 1:
324   case 2:
325   case 3:
326      data = (screen_data->status_register << 8)
327            | screen_data->device_id;
1114      data = m_n_planes == 1 ? m_device_id : 0xff;
3281115      break;
329   case 0x200:
330      data = screen_data->cr0 << 8 | 0xff;
1116   case 0x400:
1117      data = m_cr0;
3311118      break;
332   case 0x201:
333      data = screen_data->cr1 << 8 | 0xff;
1119   case 0x402:
1120      data = m_cr1;
3341121      break;
335   case 0x202:
336      data = screen_data->cr2 << 8 | 0xff;
1122   case 0x404:
1123      data = m_cr2;
3371124      break;
338   case 0x203:
339      data = screen_data->cr3a << 8 | 0xff;
1125   case 0x406:
1126      data = m_cr3a;
3401127      break;
3411128   default:
342      data = screen_data->device_id;
1129      data = 0xff;
3431130      break;
3441131   }
345   DLOG1(("reading Monochrome Controller at offset %03x = %04x and %04x", offset, data, mem_mask));
1132
1133   // omit excessive logging
1134   static UINT8 status0 = 0xff;
1135   if ((offset != 1) && (offset != 0 || data != status0))
1136   {
1137      if (offset == 0)
1138         status0 = data;
1139      DLOG1(("reading Graphics Controller at offset %03x = %02x (%s)", offset, data, cr_text(offset, data, 1)));
1140   }
1141
3461142   return data;
3471143}
3481144
349WRITE16_DEVICE_HANDLER(apollo_mcr_w ) {
350   screen_data_t *screen_data = get_safe_token(device);
351   if (offset != 0 && data != 0)
352      DLOG1(("writing Monochrome Controller at offset %03x = %04x and %04x", offset, data, mem_mask));
353
354   switch (offset & 0x203) {
1145WRITE8_DEVICE_HANDLER( apollo_graphics::apollo_mcr_w )
1146{
1147   DLOG1(("writing Graphics Controller at offset %03x = %02x (%s)", offset, data, cr_text(offset, data, 0)));
1148   switch (offset & 0x407)
1149   {
3551150   case 0:
356      screen_data->write_enable_register = data;
357      screen_data->blt_cycle_count = 0;
358      screen_data->status_register &= ~SR_ALT;
1151      m_write_enable_register = set_lsb0(m_write_enable_register, data);
3591152      break;
3601153   case 1:
361      screen_data->rop_register_0 = data;
362      switch (data & 0x0f) {
363      case 0: // zero
364      case 3: // Source
365      case 0x0c: // ~Source
366      case 0x0f: // one
367         screen_data->status_register &= ~SR_R_M_W;
368         break;
369      default:
370         screen_data->status_register |= SR_R_M_W;
371         break;
372      }
1154      m_write_enable_register = set_msb0(m_write_enable_register, data);
1155      // FIXME: seems to be necessary for dex
1156      m_blt_cycle_count = 0;
1157      m_sr &= ~SR_ALT;
3731158      break;
3741159   case 2:
1160      m_rop_register = set_lsb0(m_rop_register, data);
1161      break;
1162   case 3:
1163      m_rop_register = set_msb0(m_rop_register, data);
1164      set_status_rmw();
1165      break;
1166   case 4:
1167   case 5:
3751168      // trigger memory refresh in diagnostic mode
376      screen_data->diag_mem_request = data;
1169      m_diag_mem_request = data;
3771170      break;
378   case 0x200:
379      screen_data->cr0 = data >> 8;
380      screen_data->blt_cycle_count = 0;
1171   case 0x400:
1172      m_cr0 = data;
3811173      break;
382   case 0x201:
383      set_cr1(device, screen_data, data >> 8);
1174   case 0x402:
1175      set_cr1(device, data);
3841176      break;
385   case 0x202:
386      screen_data->cr2 = data >> 8;
1177   case 0x404:
1178      m_cr2 = data;
1179      m_cr2_s_data = CR2_S_DATA(data);
1180      m_cr2_s_plane = 0x00;
1181      m_cr2_d_plane = 0x0e;
1182      // for DISP7B.DEX Test 16
1183      m_sr |= SR_R_M_W;
3871184      break;
388   case 0x203:
389      set_cr3(device, screen_data, data >> 8);
1185   case 0x406:
1186      set_cr3a(device, data);
3901187      break;
1188   case 0x407: // A/D Channel Register
1189      m_ad_pending = 1;
1190      m_sr |= SR_DONE;
1191      break;
3911192   }
3921193}
3931194
394/***************************************************************************
395 Monochrome graphics memory space at FA0000 - FDFFFF
396 ***************************************************************************/
1195void apollo_graphics::set_status_rmw()
1196{
1197   UINT8 plane, d_plane_bit;
1198   UINT32 rop_reg;
3971199
398static UINT32 get_source_data(screen_data_t *screen_data, UINT32 src_data) {
399   switch (CR2_S_DATA(screen_data->cr2)) {
400   case CR2_CONST_ACCESS: // 0x00
401      // set source to all ones (used for vectors)
402      src_data= 0xffff;
403      break;
404   case CR2_PIXEL_ACCESS: // 0x01
405      // replicate 4 LSB of data bus
406      src_data= src_data & 1 ? 0xffff : 0;
407      break;
408   case CR2_SHIFT_ACCESS: // 0x02
409      // replicate LSB of shifter
410      src_data = src_data & 0xffff;
411      break;
412   case CR2_PLANE_ACCESS: // 0x03
413      // use source data unchanged (normal use)
414      if (CR0_SHIFT(screen_data->cr0) >= 16) {
415         src_data = (src_data << 16) | (src_data >> 16);
1200   m_sr &= ~SR_R_M_W;
1201   rop_reg = m_rop_register;
1202   d_plane_bit = 0x01;
1203   for (plane = 0; plane < m_n_planes; plane++)
1204   {
1205      if ((m_cr2_d_plane & d_plane_bit) == 0)
1206      {
1207         switch (rop_reg & 0x0f)
1208         {
1209         case 0: // zero
1210         case 3: // Source
1211         case 0x0c: // ~Source
1212         case 0x0f: // one
1213            break;
1214         default:
1215            m_sr |= SR_R_M_W;
1216            break;
1217         }
4161218      }
417      src_data >>= (CR0_SHIFT(screen_data->cr0) & 0x0f);
418      break;
1219      rop_reg >>= 4;
1220      d_plane_bit <<= 1;
4191221   }
420   return src_data;
4211222}
4221223
423static UINT16 rop(screen_data_t *screen_data, UINT16 dest_data) {
424   UINT32 src_data = get_source_data(screen_data, screen_data->guard_latch);
425
426   if ((screen_data->cr1 & CR1_ROP_EN)
427         /*&& (CR2_S_DATA(screen_data->cr2) == CR2_PLANE_ACCESS)*/) {
428      switch (screen_data->rop_register_0 & 0x0f) {
1224UINT16 apollo_graphics::rop(UINT16 dest_data, UINT16 src_data, UINT8 plane)
1225{
1226   UINT16 src_data1 = src_data;
1227   if (m_cr1 & CR1_ROP_EN)
1228   {
1229      switch ((m_rop_register >> (plane * 4)) & 0x0f)
1230      {
4291231      case 0: // zero
4301232         src_data = 0;
4311233         break;
r22754r22755
4751277         break;
4761278      }
4771279   }
1280   MLOG2(("rop: cr0=%02x cr1=%02x cr2=%02x rop_register=%08x dest=%04x src=%04x plane=%d s_plane=%d ->%04x", m_cr0, m_cr1, m_cr2, m_rop_register,dest_data, src_data1, plane, m_cr2_s_plane, src_data ))
1281   return src_data;
1282}
4781283
479   return src_data & 0xffff;
1284void apollo_graphics::set_source_data(UINT32 offset)
1285{
1286   if (m_n_planes == 1 || (m_cr1 & CR1_AD_BIT))
1287   {
1288      offset += m_image_plane_size * m_cr2_s_plane;
1289      m_guard_latch[m_cr2_s_plane] <<= 16;
1290      m_guard_latch[m_cr2_s_plane] |= m_image_memory[offset];
1291   }
1292   else
1293   {
1294      UINT8 plane;
1295      for (plane = 0; plane < m_n_planes; plane++)
1296      {
1297         m_guard_latch[plane] <<= 16;
1298         m_guard_latch[plane] |= m_image_memory[offset];
1299         offset += m_image_plane_size;
1300      }
1301   }
4801302}
4811303
482READ16_DEVICE_HANDLER( apollo_mgm_r ) {
483   screen_data_t *screen_data = get_safe_token(device);
484   UINT16 data;
1304UINT32 apollo_graphics::get_source_data(UINT8 plane)
1305{
1306   UINT32 src_data;
4851307
486   if (CR0_MODE(screen_data->cr0) == CR0_MODE_0
487         && screen_data->blt_cycle_count > 0) {
488      offset = screen_data->image_offset;
489      screen_data->blt_cycle_count = 0;
1308   if (m_n_planes == 1 || (m_cr1 & CR1_AD_BIT))
1309   {
1310      src_data = m_guard_latch[m_cr2_s_plane];
4901311   }
1312   else
1313   {
1314      src_data = m_guard_latch[plane];
1315   }
4911316
492   if (offset >= screen_data->image_memory_size) {
1317   switch (m_cr2_s_data)
1318   {
1319   case CR2_CONST_ACCESS: // 0x00
1320      // set source to all ones (used for vectors)
1321      src_data = 0xffff;
1322      break;
1323   case CR2_PIXEL_ACCESS: // 0x01
1324      // replicate 4 LSB of data bus
1325      src_data = src_data & (1 << plane) ? 0xffff : 0;
1326      break;
1327   case CR2_SHIFT_ACCESS: // 0x02
1328      // replicate LSB of shifter
1329      src_data = src_data & 1 ? 0xffff : 0;
1330      break;
1331   case CR2_PLANE_ACCESS: // 0x03
1332      // use source data unchanged (normal use)
1333      if (CR0_SHIFT(m_cr0) >= 16)
1334      {
1335         src_data = (src_data << 16) | (src_data >> 16);
1336      }
1337      src_data >>= (CR0_SHIFT(m_cr0) & 0x0f);
1338      break;
1339   }
1340   return src_data;
1341}
1342
1343void apollo_graphics::blt(UINT32 dest_addr, UINT16 mem_mask)
1344{
1345   UINT16 src_data, dest_data;
1346   UINT8 d_plane_bit;
1347   UINT8 plane;
1348
1349   d_plane_bit = 0x01;
1350   for (plane = 0; plane < m_n_planes; plane++)
1351   {
1352      if ((m_cr2_d_plane & d_plane_bit) == 0)
1353      {
1354         dest_data = m_image_memory[dest_addr];
1355         src_data = get_source_data(plane);
1356         src_data = rop(dest_data, src_data, plane);
1357         src_data &= ~(m_write_enable_register | ~mem_mask);
1358         dest_data &= (m_write_enable_register | ~mem_mask);
1359         m_image_memory[dest_addr] = dest_data | src_data;
1360      }
1361      dest_addr += m_image_plane_size;
1362      d_plane_bit <<= 1;
1363   }
1364}
1365
1366/***************************************************************************
1367 Monochrome graphics memory space at FA0000 - FDFFFF
1368 Color graphics memory space at A0000 - BFFFF
1369 ***************************************************************************/
1370
1371READ16_DEVICE_HANDLER( apollo_graphics::apollo_mgm_r )
1372{
1373   UINT16 data;
1374   UINT32 src_addr;
1375
1376   if (offset >= m_image_memory_size)
1377   {
4931378      // 128 kB display buffer of 15" screen seems to be shadowed from $fa0000 to $fc0000
494      DLOG1(("reading Monochrome Graphics Memory at invalid offset %05x", offset));
495      offset %= screen_data->image_memory_size;
1379      DLOG1(("reading Graphics Memory at invalid offset %05x", offset));
1380      offset %= m_image_memory_size;
4961381   }
4971382
498   switch (CR0_MODE(screen_data->cr0)) {
499   case CR0_MODE_VECTOR:
500      // vector or fill mode
501      UINT16 src_data, dest_data;
502      screen_data->status_register &= ~SR_ALT;
1383   src_addr = offset + m_image_plane_size * m_cr2_s_plane;
5031384
504      dest_data = screen_data->image_memory[offset];
505      src_data = rop(screen_data, dest_data);
1385   switch (CR0_MODE(m_cr0))
1386   {
1387   case CR0_MODE_VECTOR: // vector or fill mode
1388   case CR0_MODE_3: // CPU source BLT: read internal data bus
1389      data = m_guard_latch[m_cr2_s_plane];
1390      break;
5061391
507      src_data &= ~screen_data->write_enable_register;
508      dest_data &= (screen_data->write_enable_register | ~mem_mask);
509      screen_data->image_memory[offset] = dest_data | src_data;
510      data = screen_data->image_memory[offset];
511      break;
512   case CR0_MODE_3:
513      // CPU source BLT: read internal data bus
514      data = screen_data->guard_latch;
515      break;
5161392   default:
517      data = screen_data->image_memory[offset];
518      screen_data->guard_latch <<= 16;
519      screen_data->guard_latch |= data;
1393      set_source_data(offset);
1394      data = m_image_memory[src_addr];
5201395      break;
5211396   }
522   DLOG1(("reading Monochrome Graphics Memory with mode %d: offset %05x = %04x & %04x", CR0_MODE(screen_data->cr0), offset, data, mem_mask));
1397
1398   // omit excessive logging
1399   if ((offset & (m_image_plane_size - 1)) < 8)
1400   {
1401      DLOG1(("reading Graphics Memory with mode %d: src_addr %05x = %04x & %04x", CR0_MODE(m_cr0), src_addr, data, mem_mask));
1402   }
1403   else if ((offset & (m_image_plane_size - 1)) == 8)
1404   {
1405      DLOG1(("..."));
1406   }
5231407   return data;
5241408}
5251409
526WRITE16_DEVICE_HANDLER( apollo_mgm_w ) {
527   screen_data_t *screen_data = get_safe_token(device);
528   UINT16 src_data, dest_data;
1410WRITE16_DEVICE_HANDLER( apollo_graphics::apollo_mgm_w )
1411{
5291412   UINT32 dest_addr;
1413   UINT32 src_addr;
5301414
531   if (offset >= screen_data->image_memory_size) {
1415   if (offset >= m_image_memory_size)
1416   {
5321417      // 128 kB display buffer of 15" screen seems to be shadowed from $fa0000 to $fc0000
533      DLOG1(("writing Monochrome Graphics Memory at invalid offset %05x = %04x & %04x ", offset, data, mem_mask));
534      offset %= screen_data->image_memory_size;
1418      DLOG1(("writing Graphics Memory at invalid offset %05x = %04x & %04x ", offset, data, mem_mask));
1419      offset %= m_image_memory_size;
5351420   }
5361421
537   DLOG1(("writing Monochrome Graphics Memory with mode %d: offset=%04x data=%04x mask=%04x", CR0_MODE(screen_data->cr0), offset, data, mem_mask));
538   switch (CR0_MODE(screen_data->cr0)) {
1422   // omit excessive logging
1423   if (offset < 24)
1424   {
1425      DLOG1(("writing Graphics Memory with mode %d: offset=%04x data=%04x mask=%04x", CR0_MODE(m_cr0), offset, data, mem_mask));
1426   }
1427   else if (offset == 24)
1428   {
1429      DLOG1(("..."));
1430   }
1431
1432   switch (CR0_MODE(m_cr0))
1433   {
5391434   case CR0_MODE_0:
5401435      // CPU destination BLT
541      // bus write to provide display memory address
542      // bus read to get data
543      screen_data->image_offset = offset;
544      screen_data->blt_cycle_count = 1;
1436      // 1. bus write to provide display memory address
1437      // 2. bus read to get data
1438      src_addr = offset + m_image_plane_size * m_cr2_s_plane;
1439      m_guard_latch[m_cr2_s_plane] <<= 16;
1440      m_guard_latch[m_cr2_s_plane] |= m_image_memory[src_addr];
5451441      break;
1442
5461443   case CR0_MODE_1:
5471444      // Alternating BLT
5481445      // alternating bus writes provide src/dest address
5491446      // second write provides Write-enables
550      if (++screen_data->blt_cycle_count == 1) {
551         screen_data->status_register |= SR_ALT;
552         screen_data->guard_latch <<= 16;
553         screen_data->guard_latch |= screen_data->image_memory[offset];
554      } else {
555         screen_data->blt_cycle_count = 0;
556         screen_data->status_register &= ~SR_ALT;
557
558         dest_data = screen_data->image_memory[offset];
559         src_data = rop(screen_data, dest_data);
560
561         src_data &= (~data & mem_mask);
562         dest_data &= (data | ~mem_mask);
563         screen_data->image_memory[offset] = dest_data | src_data;
1447      if (++m_blt_cycle_count == 1)
1448      {
1449         m_sr |= SR_ALT;
1450         set_source_data(offset);
5641451      }
1452      else
1453      {
1454         m_blt_cycle_count = 0;
1455         m_sr &= ~SR_ALT;
1456         m_write_enable_register = data;
1457         blt(offset, mem_mask);
1458      }
5651459      break;
1460
5661461   case CR0_MODE_VECTOR:
5671462      // Vector or fill mode
5681463      // write provides Write-enables and address
569      screen_data->status_register &= ~SR_ALT;
1464      m_write_enable_register = data;
1465      blt(offset, mem_mask);
1466      break;
5701467
571      dest_data = screen_data->image_memory[offset];
572      src_data = rop(screen_data, dest_data);
573
574      src_data &= (~data & mem_mask);
575      dest_data &= (data | ~mem_mask);
576      screen_data->image_memory[offset] = dest_data | src_data;
577      break;
5781468   case CR0_MODE_3:
5791469      // CPU source BLT
580      // bus write to provide src data
581      // bus write to provide Write-enables and address
582      if (++screen_data->blt_cycle_count == 1) {
583         screen_data->status_register |= SR_ALT;
1470      // 1. bus write to provide src data
1471      // 2. bus write to provide Write-enables and address
1472      if (++m_blt_cycle_count == 1)
1473      {
1474         m_sr |= SR_ALT;
5841475
5851476         // strange: must fix byte access for /systest/grtest on sr10.2
5861477         if (mem_mask == 0xff00)
5871478         {
588            data >>=8;
1479            data >>= 8;
5891480            mem_mask >>= 8;
5901481         }
5911482
592         screen_data->guard_latch <<= 16;
593         screen_data->guard_latch |= data;
1483         m_guard_latch[m_cr2_s_plane] <<= 16;
1484         m_guard_latch[m_cr2_s_plane] |= (data & mem_mask);
1485      }
1486      else
1487      {
1488         m_blt_cycle_count = 0;
1489         m_sr &= ~SR_ALT;
5941490
595      } else {
596         screen_data->blt_cycle_count = 0;
597         screen_data->status_register &= ~SR_ALT;
598
599         dest_data = screen_data->image_memory[offset];
600         dest_data &= (data | ~mem_mask);
601
602         src_data = rop(screen_data, dest_data);
603         src_data &= (~data & mem_mask);
604
605         screen_data->image_memory[offset] = dest_data | src_data;
1491         m_write_enable_register = data;
1492         blt(offset, mem_mask);
6061493      }
6071494      break;
1495
6081496   case CR0_MODE_BLT:
6091497      // Double access BLT
6101498      // bus write to provide src addr on address lines
6111499      // dest addr on data lines (16-bit WORD Offset)
612      screen_data->guard_latch <<= 16;
613      screen_data->guard_latch |= screen_data->image_memory[offset];
6141500
1501      set_source_data(offset);
6151502      dest_addr = (data & mem_mask);
616      if (screen_data->device_id == SCREEN_DEVICE_ID_19I && (screen_data->cr1
617            & CR1_DADDR_16)) {
1503      if (m_device_id == SCREEN_DEVICE_ID_19I && (m_cr1 & CR1_DADDR_16))
1504      {
6181505         dest_addr += 0x10000;
6191506      }
620      dest_data = screen_data->image_memory[dest_addr];
1507      blt(dest_addr, 0xffff);
1508      break;
6211509
622      src_data = rop(screen_data, dest_data);
623      src_data &= ~screen_data->write_enable_register;
624
625      dest_data &= (screen_data->write_enable_register | ~mem_mask);
626      screen_data->image_memory[dest_addr] = dest_data | src_data;
1510   case CR0_MODE_NORMAL:
1511      m_guard_latch[m_cr2_s_plane] <<= 16;
1512      m_guard_latch[m_cr2_s_plane] |= (data & mem_mask);
1513      blt(offset, mem_mask);
6271514      break;
628   case CR0_MODE_NORMAL:
629      screen_data->guard_latch <<= 16;
630      screen_data->guard_latch |= (data & mem_mask);;
631      dest_data = screen_data->image_memory[offset];
632      src_data = rop(screen_data, dest_data);
6331515
634      src_data &= ~screen_data->write_enable_register;
635      dest_data &= (screen_data->write_enable_register | ~mem_mask);
636      screen_data->image_memory[offset] = dest_data | src_data;
1516   default:
1517      DLOG(("writing Graphics Memory - unexpected cr0 mode %d", CR0_MODE(m_cr0)))
1518      ;
6371519      break;
638   default:
639      DLOG(("writing Monochrome Graphics Memory - unexpected cr0 mode %d", CR0_MODE(screen_data->cr0)));
6401520   }
641   screen_data->update_flag = 1;
1521   m_update_flag = 1;
6421522}
6431523
6441524/***************************************************************************
645 VIDEO HARDWARE
1525 Color Screen
6461526 ***************************************************************************/
6471527
648static void apollo_screen_update(device_t *device, bitmap_ind16 &bitmap,
649      const rectangle &cliprect) {
650   screen_data_t *screen_data = get_safe_token(device);
1528READ8_DEVICE_HANDLER( apollo_graphics::apollo_ccr_r )
1529{
1530   UINT8 data;
6511531
652   UINT16 *source_ptr = screen_data->image_memory;
653   int x, y;
654   UINT16 data, mask;
655   UINT16 inverse = (screen_data->cr1 & CR1_INV) ? 0xffff : 0;
1532   if (m_n_planes == 4)
1533   {
1534      switch (offset & 0x407)
1535      {
1536      case 1:
1537         data = m_n_planes == 4 ? m_device_id : 0xff;
1538         break;
1539      case 0x407:
1540         data = m_ad_result;
1541         break;
1542      default:
1543         return apollo_mcr_r(device, space, offset, mem_mask);
1544      }
1545   }
1546   else if (m_n_planes == 8)
1547   {
1548      switch (offset & 0x407)
1549      {
1550      case 1:
1551         data = m_n_planes == 8 ? m_device_id : 0xff;
1552         break;
1553      case 4:
1554         data = get_lsb1(m_rop_register);
1555         break;
1556      case 5:
1557         data = get_msb1(m_rop_register);
1558         break;
6561559
657   DLOG1(("apollo_screen_update: size=%0x rowpixels=%d", screen_data->image_memory_size, bitmap.rowpixels()));
658
659   if ((screen_data->cr1 & CR1_DISP_EN) == 0) {
660      // display is disabled
661      for (y = 0; y < screen_data->height; y++) {
662         int dest = 0;
663         for (x = 0; x < screen_data->width; x += 16) {
664            for (mask = 0x8000; mask; mask >>= 1) {
665               bitmap.pix16(y, dest++) = 0;
666            }
1560      case 0x401:
1561         // LUT data register
1562         if ((m_lut_control & LUT_FIFO_CS) == 0)
1563         {
1564            data = m_lut_fifo->get();
6671565         }
668         source_ptr += (screen_data->buffer_width - screen_data->width) / 16;
669      }
670   } else {
671      for (y = 0; y < screen_data->height; y++) {
672         int dest = 0;
673         for (x = 0; x < screen_data->width; x += 16) {
674            data = *source_ptr++ ^ inverse;
675            for (mask = 0x8000; mask; mask >>= 1) {
676               bitmap.pix16(y, dest++) = data & mask ? 0 : 1;
677            }
1566         else if ((m_lut_control & LUT_R_W) == 0)
1567         {
1568            DLOG1(("apollo_graphics::apollo_ccr_r: reading LUT data register with unexpected RW = 0 in LUT Control register"));
1569            data = m_lut_data;
6781570         }
679         source_ptr += (screen_data->buffer_width - screen_data->width) / 16;
1571         else if ((m_lut_control & LUT_AD_CS) == 0)
1572         {
1573            data = m_ad_result;
1574         }
1575         else if ((m_lut_control & LUT_CPAL_CS) == 0)
1576         {
1577            data = m_bt458->read(LUT_C1_C0(m_lut_control));
1578         }
1579         else
1580         {
1581            DLOG1(("apollo_graphics::apollo_ccr_r: reading LUT data register with unexpected CS in LUT Control register"));
1582            data = m_lut_data;
1583         }
1584         break;
1585      case 0x403:
1586         // LUT control register
1587         data = m_lut_control;
1588         break;
1589      case 0x404:
1590         // cr2a
1591         data = m_cr2;
1592         break;
1593      case 0x405:
1594         // cr2b
1595         data = m_cr2b;
1596         break;
1597      case 0x407:
1598         // cr3b
1599         data = m_cr3b;
1600         break;
1601      default:
1602         return apollo_mcr_r(device, space, offset, mem_mask);
6801603      }
6811604   }
1605   else
1606   {
1607      data = 0xff;
1608   }
1609
1610   // omit excessive logging
1611   static UINT8 status1 = 0xff;
1612   if ((offset != 1) && (offset != 0 || data != status1))
1613   {
1614      if (offset == 0)
1615         status1 = data;
1616      DLOG1(("reading Color Graphics Controller at offset %03x = %02x (%s)", offset, data, cr_text(offset, data, 1)));
1617   }
1618
1619   return data;
6821620}
6831621
684/*-------------------------------------------------
685    vblank_state_changed -
686   called on each state change of the VBLANK signal
687-------------------------------------------------*/
688
689static void vblank_state_changed(device_t *device, screen_device &screen, bool vblank_state)
1622UINT8 apollo_graphics::get_pixel(UINT32 offset, UINT16 mask)
6901623{
691   screen_data_t *screen_data = get_safe_token(device);
1624   UINT8 data = 0;
1625   UINT16 *source_ptr = m_image_memory + offset;
6921626
693   if ((screen_data->cr1 & CR1_RESET) && (screen_data->cr1 & CR1_SYNC_EN)) {
694      if (vblank_state) {
695         screen_data->status_register &= ~(SR_V_BLANK | SR_BLANK);
696         // faking V_DATA for disp.dex test 16
697         if (screen_data->image_memory[0]) {
698            screen_data->status_register |= SR_V_DATA;
699         }
700      } else {
701         screen_data->status_register |= (SR_V_BLANK | SR_BLANK);
702         screen_data->status_register &= ~SR_V_DATA;
703      }
1627   if (m_n_planes == 4)
1628   {
1629      UINT16 data0 = source_ptr[0];
1630      UINT16 data1 = source_ptr[m_image_plane_size];
1631      UINT16 data2 = source_ptr[m_image_plane_size * 2];
1632      UINT16 data3 = source_ptr[m_image_plane_size * 3];
1633
1634      data = (data0 & mask) ? 1 : 0;
1635      data |= (data1 & mask) ? 2 : 0;
1636      data |= (data2 & mask) ? 4 : 0;
1637      data |= (data3 & mask) ? 8 : 0;
7041638   }
705}
1639   else if (m_n_planes == 8)
1640   {
1641      UINT16 data0 = source_ptr[0];
1642      UINT16 data1 = source_ptr[m_image_plane_size];
1643      UINT16 data2 = source_ptr[m_image_plane_size * 2];
1644      UINT16 data3 = source_ptr[m_image_plane_size * 3];
1645      UINT16 data4 = source_ptr[m_image_plane_size * 4];
1646      UINT16 data5 = source_ptr[m_image_plane_size * 5];
1647      UINT16 data6 = source_ptr[m_image_plane_size * 6];
1648      UINT16 data7 = source_ptr[m_image_plane_size * 7];
7061649
707VIDEO_START( apollo_screen ) {
1650      data = (data0 & mask) ? 1 : 0;
1651      data |= (data1 & mask) ? 2 : 0;
1652      data |= (data2 & mask) ? 4 : 0;
1653      data |= (data3 & mask) ? 8 : 0;
1654      data |= (data4 & mask) ? 0x10 : 0;
1655      data |= (data5 & mask) ? 0x20 : 0;
1656      data |= (data6 & mask) ? 0x40 : 0;
1657      data |= (data7 & mask) ? 0x80 : 0;
1658   }
1659
1660   return data;
7081661}
7091662
710SCREEN_UPDATE_IND16( apollo_screen ) {
711   // FIXME: omit using APOLLO_SCREEN_TAG
712   device_t *apollo_screen = screen.machine().device( APOLLO_SCREEN_TAG );
713   screen_data_t *screen_data = get_safe_token(apollo_screen);
1663// read the 4-plane ADC value for data
7141664
715   int has_changed = 0;
1665UINT8 apollo_graphics::c4p_read_adc(UINT8 data)
1666{
1667   UINT8 value = 0;
7161668
717   if (screen_data->update_flag && !screen_data->update_pending) {
718      has_changed = 1;
719      screen_data->update_flag = 0;
720      screen_data->update_pending = 1;
721      apollo_screen_update(apollo_screen, bitmap, cliprect);
722      screen_data->update_pending = 0;
1669   if ((data & 0x0c) == 0x04)
1670   {
1671      UINT8 red, green, blue;
1672      UINT8 pixel = get_pixel((m_v_clock * m_buffer_width / 16) + m_h_clock,
1673            0x8000);
1674      UINT32 rgb = m_color_lookup_table[pixel];
1675
1676      if ((m_sr & SR_BLANK) != 0)
1677      {
1678         // not blanking
1679         red = 30 + ((rgb >> 16) & 0xff) / 4;
1680         green = 60 + ((rgb >> 8) & 0xff) / 4;
1681         blue = 30 + (rgb & 0xff) / 4;
1682      }
1683      else if (m_h_clock > 2)
1684      {
1685         // blanking
1686         red = 20;
1687         green = 50;
1688         blue = 20;
1689      }
1690      else
1691      {
1692         // sync
1693         red = 20;
1694         green = 10;
1695         blue = 20;
1696      }
1697
1698      switch (data & 3)
1699      {
1700      case 0: // Red
1701         value = red;
1702         break;
1703      case 1: // Green
1704         value = green;
1705         break;
1706      case 2: // Blue
1707         value = blue;
1708         break;
1709      default: // unused
1710         value = 0;
1711         break;
1712      }
7231713   }
724   return has_changed ? 0 : UPDATE_HAS_NOT_CHANGED;
1714   return value;
7251715}
7261716
727/***************************************************************************
728 MACHINE DRIVERS
729 ***************************************************************************/
730MACHINE_CONFIG_FRAGMENT( apollo_mono19i )
731      MCFG_DEFAULT_LAYOUT( layout_apollo )
732      MCFG_SCREEN_ADD(VIDEO_SCREEN_TAG, RASTER)
733      MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
734//      MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
735      MCFG_PALETTE_LENGTH(2)
736      MCFG_PALETTE_INIT(black_and_white)
737      // dot clock, htotal, hstart, hend, vtotal, vstart, vend
738      // MCFG_SCREEN_RAW_PARAMS(118000000, 1280, 0, 1728, 1024, 0, 1065)
739      MCFG_SCREEN_REFRESH_RATE(64)
740      MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(616))
741      MCFG_SCREEN_SIZE(1280, 1024)
742      MCFG_SCREEN_VISIBLE_AREA(0, 1279, 0, 1023)
743      MCFG_VIDEO_START(apollo_screen)
744      MCFG_SCREEN_UPDATE_STATIC(apollo_screen)
745MACHINE_CONFIG_END
1717// read the 8-plane ADC value for data
7461718
747MACHINE_CONFIG_FRAGMENT( apollo_mono15i )
748      MCFG_DEFAULT_LAYOUT( layout_apollo_15i )
749      MCFG_SCREEN_ADD(VIDEO_SCREEN_TAG, RASTER)
750      MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
751//      MCFG_SCREEN_FORMAT(BITMAP_FORMAT_INDEXED16)
752      MCFG_PALETTE_LENGTH(2)
753      MCFG_PALETTE_INIT(black_and_white)
754      // dot clock, htotal, hstart, hend, vtotal, vstart, vend
755      // MCFG_SCREEN_RAW_PARAMS(85963000, 1024, 0, 1344, 800, 0, 842)
756      MCFG_SCREEN_REFRESH_RATE(76)
757      MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(657))
758      MCFG_SCREEN_SIZE(1024, 800)
759      MCFG_SCREEN_VISIBLE_AREA(0, 1023, 0, 799)
760      MCFG_VIDEO_START(apollo_screen)
761      MCFG_SCREEN_UPDATE_STATIC(apollo_screen)
762MACHINE_CONFIG_END
1719UINT8 apollo_graphics::c8p_read_adc(UINT8 data)
1720{
1721   UINT8 value = 0;
7631722
764/*-------------------------------------------------
765 DEVICE_START( apollo_mono19i/15i )
766 -------------------------------------------------*/
1723   if ((data & 0x0c) == 0x04)
1724   {
1725      UINT8 red, green, blue;
1726      UINT8 pixel = get_pixel((m_v_clock * m_buffer_width / 16) + m_h_clock, 0x8000);
1727      UINT32 rgb = m_bt458->get_rgb(pixel);
7671728
768static DEVICE_START( apollo_mono ) {
769   screen_data_t *screen_data = get_safe_token(device);
1729      if ((m_sr & SR_BLANK) != 0)
1730      {
1731         // not blanking
1732         red = 10 + ((rgb >> 16) & 0xff) / 2;
1733         green = 70 + ((rgb >> 8) & 0xff) / 2;
1734         blue = 10 + (rgb & 0xff) / 2;
1735      }
1736      else if (m_h_clock < 20)
1737      {
1738         // blanking
1739         red = 5;
1740         green = 60;
1741         blue = 5;
1742      }
1743      else
1744      {
1745         // sync
1746         red = 5;
1747         green = 5;
1748         blue = 5;
1749      }
7701750
771   /* get the video screen  */
772   screen_data->screen = (screen_device *)device->machine().device(VIDEO_SCREEN_TAG);
773   assert(screen_data->screen != NULL);
1751      switch (data & 3)
1752      {
1753      case 0: // Red
1754         value = red;
1755         break;
1756      case 1: // Green
1757         value = green;
1758         break;
1759      case 2: // Blue
1760         value = blue;
1761         break;
1762      default: // unused
1763         value = 0;
1764         break;
1765      }
1766   }
1767   return value;
1768}
7741769
775   /* allocate the memory image */
776   screen_data->image_memory_size = screen_data->buffer_height
777         * screen_data->buffer_width / 16;
778//  screen_data->image_memory = (UINT16 *) malloc(screen_data->image_memory_size * 2);
779   screen_data->image_memory = auto_alloc_array(device->machine(), UINT16, screen_data->image_memory_size);
780   assert(screen_data->image_memory != NULL);
1770WRITE8_DEVICE_HANDLER( apollo_graphics::apollo_ccr_w )
1771{
1772   static const UINT8 rgb_value[16] =
1773   { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
1774         0xcc, 0xdd, 0xee, 0xff };
7811775
782   DLOG1(("device start apollo screen buffer=%p size=%0x", screen_data->image_memory, screen_data->image_memory_size));
1776   if (m_n_planes == 4)
1777   {
1778      switch (offset & 0x407)
1779      {
1780      case 0x401:
1781         // red lookup table register
1782         m_color_lookup_table[data >> 4] &= 0xff00ffff;
1783         m_color_lookup_table[data >> 4] |= rgb_value[data & 0x0f] << 16;
1784         break;
1785      case 0x403:
1786         // green lookup table register
1787         m_color_lookup_table[data >> 4] &= 0xffff00ff;
1788         m_color_lookup_table[data >> 4] |= rgb_value[data & 0x0f] << 8;
1789         break;
1790      case 0x404:
1791         // cr2
1792         m_cr2 = data;
1793         m_cr2_s_data = CR2_S_DATA(data);
1794         m_cr2_s_plane = CR2_S_PLANE(data);
1795         m_cr2_d_plane = CR2_D_PLANE(data);
1796         // for  DISP7B.DEX Test 16
1797         m_sr |= SR_R_M_W;
1798         break;
1799      case 0x405:
1800         // blue lookup table register
1801         m_color_lookup_table[data >> 4] &= 0xffffff00;
1802         m_color_lookup_table[data >> 4] |= rgb_value[data & 0x0f];
1803         break;
1804      case 0x407:
1805         // A/D channel register
1806         m_ad_result = c4p_read_adc(data);
1807         m_ad_pending = 1;
1808         m_sr |= SR_DONE;
1809         break;
1810      default:
1811         apollo_mcr_w(device, space, offset, data, mem_mask);
1812         return;
1813      }
1814   }
1815   else if (m_n_planes == 8)
1816   {
1817      switch (offset & 0x407)
1818      {
1819      case 2:
1820         m_rop_register = set_lsb0(m_rop_register, data);
1821         break;
1822      case 3:
1823         m_rop_register = set_msb0(m_rop_register, data);
1824         set_status_rmw();
1825         break;
1826      case 4:
1827         m_rop_register = set_lsb1(m_rop_register, data);
1828         break;
1829      case 5:
1830         m_rop_register = set_msb1(m_rop_register, data);
1831         set_status_rmw();
1832         break;
1833      case 6:
1834      case 7:
1835         // trigger memory refresh in diagnostic mode
1836         m_diag_mem_request = data;
1837         break;
1838      case 0x401:
1839         // LUT data register
1840         m_lut_data = data;
1841         if ((m_lut_control & LUT_R_W) == 1)
1842         {
1843            DLOG1(("apollo_graphics::apollo_ccr_w: writing LUT data register with RW = 1 in LUT Control register"));
1844         }
1845         else if ((m_lut_control & LUT_AD_CS) == 0)
1846         {
1847            m_ad_result = c8p_read_adc(data);
1848            m_ad_pending = 1;
1849            m_sr |= SR_DONE;
1850         }
1851         else if ((m_lut_control & LUT_CPAL_CS) == 0)
1852         {
1853            m_bt458->write(data, LUT_C1_C0(m_lut_control));
1854         }
1855         else if ((m_lut_control & LUT_FIFO_CS) == 0)
1856         {
1857            m_lut_fifo->put(data);
1858         }
1859         else
1860         {
1861            DLOG1(("apollo_graphics::apollo_ccr_w: writing LUT data register with unexpected CS in LUT Control register"));
1862         }
1863         break;
1864      case 0x403:
1865         // LUT control register
1866         set_lut_cr(device, data);
1867         break;
1868      case 0x404:
1869         // cr2a
1870         m_cr2 = data;
1871         m_cr2_d_plane = CR2A_D_PLANE(data);
1872         m_sr |= SR_R_M_W;
1873         break;
1874      case 0x405:
1875         // cr2b
1876         m_cr2b = data;
1877         m_cr2_s_data = CR2_S_DATA(data);
1878         m_cr2_s_plane = CR2B_S_PLANE(data);
1879         break;
1880      case 0x407:
1881         // cr3b
1882         set_cr3b(device, data);
1883         break;
1884      default:
1885         apollo_mcr_w(device, space, offset, data, mem_mask);
1886         return;
1887      }
1888   }
1889
1890   DLOG1(("writing Color Graphics Controller at offset %03x = %02x (%s)", offset, data, cr_text(offset, data, 0)));
7831891}
7841892
785static DEVICE_START( apollo_mono19i ) {
786   screen_data_t *screen_data = get_safe_token(device);
1893READ16_DEVICE_HANDLER( apollo_cgm_r )
1894{
1895   if (!apollo_config(APOLLO_CONF_MONO_15I))
1896   {
1897      return apollo_mgm_r(device, space, offset, mem_mask);
1898   }
1899   else
1900   {
1901      return 0xffff;
1902   }
1903}
7871904
788   memset(screen_data, 0, sizeof(screen_data_t));
1905WRITE16_DEVICE_HANDLER( apollo_cgm_w )
1906{
1907   if (!apollo_config(APOLLO_CONF_MONO_15I))
1908   {
1909      apollo_mgm_w(device, space, offset, data, mem_mask);
1910   }
1911}
7891912
790   // monochrome 1280x1024
791   screen_data->device_id = SCREEN_DEVICE_ID_19I;
792   screen_data->width = 1280;
793   screen_data->height = 1024;
794   screen_data->buffer_width = 2048;
795   screen_data->buffer_height = 1024;
1913/***************************************************************************
1914 VIDEO HARDWARE
1915 ***************************************************************************/
7961916
797   device_start_apollo_mono(device);
1917UINT32 apollo_graphics::screen_update(bitmap_rgb32 &bitmap,
1918      const rectangle &cliprect)
1919{
1920   int has_changed = 0;
1921
1922   if (m_update_flag && !m_update_pending)
1923   {
1924      has_changed = 1;
1925      m_update_flag = 0;
1926      m_update_pending = 1;
1927      screen_update1(bitmap, cliprect);
1928      m_update_pending = 0;
1929   }
1930   return has_changed ? 0 : UPDATE_HAS_NOT_CHANGED;
7981931}
7991932
800static DEVICE_START( apollo_mono15i ) {
801   screen_data_t *screen_data = get_safe_token(device);
1933void apollo_graphics::screen_update1(bitmap_rgb32 &bitmap,
1934      const rectangle &cliprect)
1935{
1936   UINT16 *source_ptr = m_image_memory;
1937   int x, y;
1938   UINT16 data, mask;
1939   UINT16 inverse = (m_cr1 & CR1_INV) ? 0xffff : 0;
8021940
803   memset(screen_data, 0, sizeof(screen_data_t));
1941   MLOG1(("screen_update1: size=%0x rowpixels=%d", m_image_memory_size, bitmap.rowpixels()));
8041942
805   // monochrome 1024x800
806   screen_data->device_id = SCREEN_DEVICE_ID_15I;
807   screen_data->width = 1024;
808   screen_data->height = 800;
809   screen_data->buffer_width = 1024;
810   screen_data->buffer_height = 1024;
811
812   device_start_apollo_mono(device);
1943   if ((m_cr1 & CR1_DISP_EN) == 0)
1944   {
1945      // display is disabled
1946      for (y = 0; y < m_height; y++)
1947      {
1948         int dest = 0;
1949         for (x = 0; x < m_width; x += 16)
1950         {
1951            for (mask = 0x8000; mask; mask >>= 1)
1952            {
1953               bitmap.pix32(y, dest++) = 0;
1954            }
1955         }
1956         source_ptr += (m_buffer_width - m_width) / 16;
1957      }
1958   }
1959   else if (m_n_planes == 4)
1960   {
1961      for (y = 0; y < m_height; y++)
1962      {
1963         int dest = 0;
1964         for (x = 0; x < m_width; x += 16)
1965         {
1966            UINT16 data0 = source_ptr[0];
1967            UINT16 data1 = source_ptr[m_image_plane_size];
1968            UINT16 data2 = source_ptr[m_image_plane_size * 2];
1969            UINT16 data3 = source_ptr[m_image_plane_size * 3];
1970            source_ptr++;
1971            for (mask = 0x8000; mask; mask >>= 1)
1972            {
1973               data = (data0 & mask) ? 1 : 0;
1974               data |= (data1 & mask) ? 2 : 0;
1975               data |= (data2 & mask) ? 4 : 0;
1976               data |= (data3 & mask) ? 8 : 0;
1977               bitmap.pix32(y, dest++) = m_color_lookup_table[data];
1978            }
1979         }
1980         source_ptr += (m_buffer_width - m_width) / 16;
1981      }
1982   }
1983   else if (m_n_planes == 8)
1984   {
1985      for (y = 0; y < m_height; y++)
1986      {
1987         int dest = 0;
1988         for (x = 0; x < m_width; x += 16)
1989         {
1990            UINT16 data0 = source_ptr[0];
1991            UINT16 data1 = source_ptr[m_image_plane_size];
1992            UINT16 data2 = source_ptr[m_image_plane_size * 2];
1993            UINT16 data3 = source_ptr[m_image_plane_size * 3];
1994            UINT16 data4 = source_ptr[m_image_plane_size * 4];
1995            UINT16 data5 = source_ptr[m_image_plane_size * 5];
1996            UINT16 data6 = source_ptr[m_image_plane_size * 6];
1997            UINT16 data7 = source_ptr[m_image_plane_size * 7];
1998            source_ptr++;
1999            for (mask = 0x8000; mask; mask >>= 1)
2000            {
2001               data = (data0 & mask) ? 1 : 0;
2002               data |= (data1 & mask) ? 2 : 0;
2003               data |= (data2 & mask) ? 4 : 0;
2004               data |= (data3 & mask) ? 8 : 0;
2005               data |= (data4 & mask) ? 0x10 : 0;
2006               data |= (data5 & mask) ? 0x20 : 0;
2007               data |= (data6 & mask) ? 0x40 : 0;
2008               data |= (data7 & mask) ? 0x80 : 0;
2009               bitmap.pix32(y, dest++) = m_bt458->get_rgb(data);
2010            }
2011         }
2012         source_ptr += (m_buffer_width - m_width) / 16;
2013      }
2014   }
2015   else // m_n_planes == 1
2016   {
2017      for (y = 0; y < m_height; y++)
2018      {
2019         int dest = 0;
2020         for (x = 0; x < m_width; x += 16)
2021         {
2022            data = *source_ptr++ ^ inverse;
2023            for (mask = 0x8000; mask; mask >>= 1)
2024            {
2025               bitmap.pix32(y, dest++) = data & mask ? 0 : 0x00ffffff;
2026            }
2027         }
2028         source_ptr += (m_buffer_width - m_width) / 16;
2029      }
2030   }
8132031}
8142032
8152033/*-------------------------------------------------
816 DEVICE_RESET( apollo_mono19i/15i )
2034 vblank_state_changed -
2035 called on each state change of the VBLANK signal
8172036 -------------------------------------------------*/
8182037
819static DEVICE_RESET( apollo_mono19i ) {
820   screen_data_t *screen_data = get_safe_token(device);
2038void apollo_graphics::vblank_state_changed(device_t *device,
2039      screen_device &screen, bool vblank_state)
2040{
2041   if ((m_cr1 & CR1_RESET) && (m_cr1 & CR1_SYNC_EN))
2042   {
2043      if (vblank_state)
2044      {
2045         m_sr &= ~(SR_V_BLANK | SR_BLANK);
2046         if (m_n_planes == 1)
2047         {
2048            // faking V_DATA for disp.dex test 16
2049            if (m_image_memory[0])
2050            {
2051               m_sr |= SR_V_DATA;
2052            }
2053         }
2054         else if (m_n_planes == 4)
2055         {
2056            m_sr &= ~SR_V_FLAG;
2057         }
2058      }
2059      else
2060      {
2061         m_sr |= (SR_V_BLANK | SR_BLANK);
2062         if (m_n_planes == 1)
2063         {
2064            m_sr &= ~SR_V_DATA;
2065         }
2066         else if (m_n_planes == 4)
2067         {
2068            m_sr |= SR_V_FLAG;
2069         }
2070      }
2071   }
2072}
8212073
822   DLOG1(("device reset apollo screen"));
2074void vblank_state_changed(device_t *device, screen_device &screen,
2075      bool vblank_state)
2076{
2077   apollo_graphics *apollo_graphics = get_safe_token(device);
2078   apollo_graphics->vblank_state_changed(device, screen, vblank_state);
2079}
8232080
824   memset(screen_data->image_memory, 0, screen_data->image_memory_size * 2);
2081static void register_vblank_callback(device_t *device)
2082{
2083   DLOG1(("register_vblank_callback"));
8252084
8262085   /* register for VBLANK callbacks */
827   screen_data->screen->register_vblank_callback(vblank_state_delegate(FUNC(vblank_state_changed), device));
2086   screen_device *screen = (screen_device *) device->machine().device(
2087         VIDEO_SCREEN_TAG);
2088   screen->register_vblank_callback(vblank_state_delegate(
2089         FUNC(vblank_state_changed),device) );
8282090}
8292091
830static DEVICE_RESET( apollo_mono15i ) {
831   DEVICE_RESET_CALL(apollo_mono19i);
2092VIDEO_START( apollo_screen )
2093{
8322094}
8332095
834apollo_mono_device::apollo_mono_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
835   : device_t(mconfig, type, name, tag, owner, clock, shortname, source)
2096SCREEN_UPDATE_RGB32( apollo_screen )
8362097{
837   m_token = global_alloc_clear(screen_data_t);
2098   // FIXME: omit using APOLLO_SCREEN_TAG
2099   device_t *apollo_screen = screen.machine().device(APOLLO_SCREEN_TAG);
2100   apollo_graphics *apollo_graphics = get_safe_token(apollo_screen);
2101
2102   return apollo_graphics->screen_update(bitmap, cliprect);
8382103}
8392104
840const device_type APOLLO_MONO19I = &device_creator<apollo_mono19i_device>;
2105/***************************************************************************
2106 MACHINE DRIVERS
2107 ***************************************************************************/
8412108
842apollo_mono19i_device::apollo_mono19i_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
843   : apollo_mono_device(mconfig, APOLLO_MONO19I, "Apollo 19\" Monochrome Screen", tag, owner, clock, "apollo_mono19i", __FILE__)
2109MACHINE_CONFIG_FRAGMENT( apollo_graphics )
2110   MCFG_DEFAULT_LAYOUT( layout_apollo_15i )
2111   MCFG_SCREEN_ADD(VIDEO_SCREEN_TAG, RASTER)
2112   MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
2113   MCFG_SCREEN_REFRESH_RATE(76)
2114   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(657))
2115   MCFG_SCREEN_SIZE(1024, 800)
2116   MCFG_SCREEN_VISIBLE_AREA(0, 1023, 0, 799)
2117   MCFG_VIDEO_START(apollo_screen)
2118   MCFG_SCREEN_UPDATE_STATIC(apollo_screen)
2119   MACHINE_CONFIG_END
2120
2121const device_type APOLLO_GRAPHICS = &device_creator<apollo_graphics_15i> ;
2122
2123apollo_graphics_15i::apollo_graphics_15i(const machine_config &mconfig,
2124      const char *tag, device_t *owner, UINT32 clock) :
2125   device_t(mconfig, APOLLO_GRAPHICS, "Apollo Screen", tag, owner, clock,
2126         "apollo_graphics_15i", __FILE__)
8442127{
2128   m_token = new apollo_graphics;
8452129}
8462130
2131apollo_graphics_15i::apollo_graphics_15i(const machine_config &mconfig,
2132      const char *tag, device_t *owner, UINT32 clock, device_type type,
2133      const char *name, const char *shortname, const char *source) :
2134   device_t(mconfig, type, name, tag, owner, clock, shortname, source)
2135{
2136   m_token = new apollo_graphics;
2137}
2138
8472139//-------------------------------------------------
8482140//  device_config_complete - perform any
8492141//  operations now that the configuration is
8502142//  complete
8512143//-------------------------------------------------
8522144
853void apollo_mono19i_device::device_config_complete()
2145void apollo_graphics_15i::device_config_complete()
8542146{
8552147}
8562148
r22754r22755
8582150//  device_start - device-specific startup
8592151//-------------------------------------------------
8602152
861void apollo_mono19i_device::device_start()
2153void apollo_graphics_15i::device_start()
8622154{
863   DEVICE_START_NAME( apollo_mono19i )(this);
2155   MLOG1(("apollo_graphics_15i::device_start"))
2156
2157   apollo_graphics *apollo_graphics = get_safe_token(this);
2158   apollo_graphics->device_start(machine());
8642159}
8652160
8662161//-------------------------------------------------
8672162//  device_reset - device-specific reset
8682163//-------------------------------------------------
8692164
870void apollo_mono19i_device::device_reset()
2165void apollo_graphics_15i::device_reset()
8712166{
872   DEVICE_RESET_NAME( apollo_mono19i )(this);
2167   MLOG1(("apollo_graphics_15i::device_reset"));
2168
2169   apollo_graphics *apollo_graphics = get_safe_token(this);
2170   apollo_graphics->device_reset();
2171
2172   /* FIXME: register for VBLANK callbacks */
2173   register_vblank_callback(this);
8732174}
8742175
2176READ8_DEVICE_HANDLER( apollo_ccr_r )
2177{
2178   apollo_graphics *apollo_graphics = get_safe_token(device);
2179   return apollo_graphics->apollo_ccr_r(device, space, offset, mem_mask);
2180}
8752181
876const device_type APOLLO_MONO15I = &device_creator<apollo_mono15i_device>;
2182WRITE8_DEVICE_HANDLER( apollo_ccr_w )
2183{
2184   apollo_graphics *apollo_graphics = get_safe_token(device);
2185   apollo_graphics->apollo_ccr_w(device, space, offset, data, mem_mask);
2186}
8772187
878apollo_mono15i_device::apollo_mono15i_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
879   : apollo_mono_device(mconfig, APOLLO_MONO15I, "Apollo 15\" Monochrome Screen", tag, owner, clock, "apollo_mono15i", __FILE__)
2188//-------------------------------------------------
2189
2190MACHINE_CONFIG_FRAGMENT( apollo_mono19i )
2191   MCFG_DEFAULT_LAYOUT( layout_apollo )
2192   MCFG_SCREEN_ADD(VIDEO_SCREEN_TAG, RASTER)
2193   MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK)
2194   MCFG_PALETTE_LENGTH(2)
2195   MCFG_PALETTE_INIT(black_and_white)
2196   MCFG_SCREEN_REFRESH_RATE(64)
2197   MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(616))
2198   MCFG_SCREEN_SIZE(1280, 1024)
2199   MCFG_SCREEN_VISIBLE_AREA(0, 1279, 0, 1023)
2200   MCFG_VIDEO_START(apollo_screen)
2201   MCFG_SCREEN_UPDATE_STATIC(apollo_screen)
2202   MACHINE_CONFIG_END
2203
2204const device_type APOLLO_MONO19I = &device_creator<apollo_graphics_19i> ;
2205
2206apollo_graphics_19i::apollo_graphics_19i(const machine_config &mconfig,
2207      const char *tag, device_t *owner, UINT32 clock) :
2208   apollo_graphics_15i(mconfig, tag, owner, clock, APOLLO_MONO19I,
2209         "Apollo 19\" Monochrome Screen", "apollo_graphics_19i", __FILE__)
8802210{
8812211}
8822212
r22754r22755
8862216//  complete
8872217//-------------------------------------------------
8882218
889void apollo_mono15i_device::device_config_complete()
2219void apollo_graphics_19i::device_config_complete()
8902220{
8912221}
8922222
r22754r22755
8942224//  device_start - device-specific startup
8952225//-------------------------------------------------
8962226
897void apollo_mono15i_device::device_start()
2227void apollo_graphics_19i::device_start()
8982228{
899   DEVICE_START_NAME( apollo_mono15i )(this);
2229   MLOG1(("apollo_graphics_19i::device_start"));
2230
2231   apollo_graphics_15i::device_start();
9002232}
9012233
9022234//-------------------------------------------------
9032235//  device_reset - device-specific reset
9042236//-------------------------------------------------
9052237
906void apollo_mono15i_device::device_reset()
2238void apollo_graphics_19i::device_reset()
9072239{
908   DEVICE_RESET_NAME( apollo_mono15i )(this);
2240   MLOG1(("apollo_graphics_19i::device_reset"));
2241
2242   apollo_graphics *apollo_graphics = get_safe_token(this);
2243   apollo_graphics->device_reset_mono19i();
2244
2245   /* FIXME: register for VBLANK callbacks */
2246   register_vblank_callback(this);
9092247}
2248
2249READ8_DEVICE_HANDLER( apollo_mcr_r )
2250{
2251   apollo_graphics *apollo_graphics = get_safe_token(device);
2252   return apollo_graphics->apollo_mcr_r(device, space, offset, mem_mask);
2253}
2254
2255WRITE8_DEVICE_HANDLER( apollo_mcr_w )
2256{
2257   apollo_graphics *apollo_graphics = get_safe_token(device);
2258   apollo_graphics->apollo_mcr_w(device, space, offset, data, mem_mask);
2259}
2260
2261READ16_DEVICE_HANDLER( apollo_mgm_r )
2262{
2263   apollo_graphics *apollo_graphics = get_safe_token(device);
2264   return apollo_graphics->apollo_mgm_r(device, space, offset, mem_mask);
2265}
2266
2267WRITE16_DEVICE_HANDLER( apollo_mgm_w )
2268{
2269   apollo_graphics *apollo_graphics = get_safe_token(device);
2270   apollo_graphics->apollo_mgm_w(device, space, offset, data, mem_mask);
2271}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team