Previous 199869 Revisions Next

r35060 Monday 16th February, 2015 at 05:15:53 UTC by Carl
scn2674: reworked for the pcd [Carl]
---
mpu4vid sometimes flickers a bit but otherwise looks the same AFAICT
[src/emu/video]scn2674.c* scn2674.h* video.mak
[src/mame]mame.mak
[src/mame/drivers]mpu4vid.c
[src/mame/video]scn2674.c scn2674.h
[src/mess]mess.mak
[src/mess/drivers]pcd.c

trunk/src/emu/video/scn2674.c
r0r243572
1/*
2    SCN2674 - Advanced Video Display Controller (AVDC)  (Video Chip)
3*/
4
5#include "scn2674.h"
6
7#define S674VERBOSE 0
8#define LOG2674(x) do { if (S674VERBOSE) logerror x; } while (0)
9
10const device_type SCN2674_VIDEO = &device_creator<scn2674_device>;
11
12
13// default address map
14static ADDRESS_MAP_START( scn2674_vram, AS_0, 8, scn2674_device )
15   AM_RANGE(0x0000, 0xffff) AM_NOP
16ADDRESS_MAP_END
17
18scn2674_device::scn2674_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
19   : device_t(mconfig, SCN2674_VIDEO, "Signetics SCN2674 AVDC", tag, owner, clock, "scn2674_device", __FILE__),
20      device_video_interface(mconfig, *this),
21      device_memory_interface(mconfig, *this),
22      m_irq_cb(*this),
23      m_space_config("videoram", ENDIANNESS_LITTLE, 8, 16, 0, NULL, *ADDRESS_MAP_NAME(scn2674_vram))
24{
25}
26
27void scn2674_device::device_start()
28{
29   // resolve callbacks
30   m_display_cb.bind_relative_to(*owner());
31   m_irq_cb.resolve_safe();
32   m_scanline_timer = timer_alloc(TIMER_SCANLINE);
33   m_screen->register_screen_bitmap(m_bitmap);
34
35   save_item(NAME(m_address));
36   save_item(NAME(m_linecounter));
37   save_item(NAME(m_screen2_l));
38   save_item(NAME(m_screen2_h));
39}
40
41void scn2674_device::device_reset()
42{
43   m_IR_pointer= 0;
44   m_screen1_l= 0;
45   m_screen1_h= 0;
46   m_cursor_l= 0;
47   m_cursor_h= 0;
48   m_screen2_l= 0;
49   m_screen2_h= 0;
50   m_irq_register= 0;
51   m_status_register= 0;
52   m_irq_mask= 0;
53   m_gfx_enabled= 0;
54   m_display_enabled= 0;
55   m_display_enabled_field= 0;
56   m_display_enabled_scanline= 0;
57   m_cursor_enabled= 0;
58   m_IR0_double_ht_wd= 0;
59   m_IR0_scanline_per_char_row= 0;
60   m_IR0_sync_select= 0;
61   m_IR0_buffer_mode_select= 0;
62   m_IR1_interlace_enable= 0;
63   m_IR1_equalizing_constant= 0;
64   m_IR2_row_table= 0;
65   m_IR2_horz_sync_width= 0;
66   m_IR2_horz_back_porch= 0;
67   m_IR3_vert_front_porch= 0;
68   m_IR3_vert_back_porch= 0;
69   m_IR4_rows_per_screen= 0;
70   m_IR4_character_blink_rate_divisor= 0;
71   m_IR5_character_per_row= 0;
72   m_IR6_cursor_first_scanline= 0;
73   m_IR6_cursor_last_scanline= 0;
74   m_IR7_cursor_underline_position= 0;
75   m_IR7_cursor_rate_divisor= 0;
76   m_IR7_cursor_blink= 0;
77   m_IR7_vsync_width= 0;
78   m_IR8_display_buffer_first_address_LSB= 0;
79   m_IR9_display_buffer_first_address_MSB= 0;
80   m_IR9_display_buffer_last_address= 0;
81   m_IR10_display_pointer_address_lower= 0;
82   m_IR11_display_pointer_address_upper= 0;
83   m_IR11_reset_scanline_counter_on_scrollup= 0;
84   m_IR11_reset_scanline_counter_on_scrolldown= 0;
85   m_IR12_scroll_start= 0;
86   m_IR12_split_register_1= 0;
87   m_IR13_scroll_end= 0;
88   m_IR13_split_register_2= 0;
89   m_IR14_scroll_lines= 0;
90   m_IR14_double_1= 0;
91   m_IR14_double_2= 0;
92   m_spl1= 0;
93   m_spl2= 0;
94   m_dbl1= 0;
95   m_linecounter= 0;
96   m_irq_state= 0;
97   m_IR_pointer = 0;
98   m_address = 0;
99   m_hpixels_per_column = m_text_hpixels_per_column;
100}
101
102// 15 Initialization Registers (8-bit each)
103void scn2674_device::write_init_regs(UINT8 data)
104{
105   LOG2674(("scn2674_write_init_regs %02x %02x\n",m_IR_pointer,data));
106
107   switch ( m_IR_pointer) /* display some debug info, set mame specific variables */
108   {
109      case 0:
110         m_IR0_double_ht_wd = (data & 0x80)>>7;
111         m_IR0_scanline_per_char_row = ((data & 0x78)>>3) + 1;
112         m_IR0_sync_select = (data&0x04)>>2;
113         m_IR0_buffer_mode_select = (data&0x03);
114
115         LOG2674(("IR0 - Double Ht Wd %02x\n",m_IR0_double_ht_wd));//affects IR14 as well
116         LOG2674(("IR0 - Scanlines per Character Row %02x\n",m_IR0_scanline_per_char_row));//value+1 = scanlines
117         LOG2674(("IR0 - Sync Select %02x\n",m_IR0_sync_select));//1 = csync
118         LOG2674(("IR0 - Buffer Mode Select %02x\n",m_IR0_buffer_mode_select)); //0 independent 1 transparent 2 shared 3 row
119         break;
120
121      case 1:
122         m_IR1_interlace_enable = (data&0x80)>>7;
123         m_IR1_equalizing_constant = (data&0x7f)+1;
124
125         LOG2674(("IR1 - Interlace Enable %02x\n",m_IR1_interlace_enable));
126         LOG2674(("IR1 - Equalizing Constant %02i CCLKs\n",m_IR1_equalizing_constant));
127         break;
128
129      case 2:
130         m_IR2_row_table = (data&0x80)>>7;
131         m_IR2_horz_sync_width = (((data&0x78)>>3)*2) + 2;
132         m_IR2_horz_back_porch = ((data&0x07)*4) - 1;
133
134         LOG2674(("IR2 - Row Table %02x\n",m_IR2_row_table));
135         LOG2674(("IR2 - Horizontal Sync Width %02i CCLKs\n",m_IR2_horz_sync_width));
136         LOG2674(("IR2 - Horizontal Back Porch %02i CCLKs\n",m_IR2_horz_back_porch));
137         break;
138
139      case 3:
140         m_IR3_vert_front_porch =  (((data&0xe0)>>5) * 4)+4 ;
141         m_IR3_vert_back_porch = ((data&0x1f) * 2) + 4;
142
143         LOG2674(("IR3 - Vertical Front Porch %02i Lines\n",m_IR3_vert_front_porch));
144         LOG2674(("IR3 - Vertical Back Porch %02i Lines\n",m_IR3_vert_back_porch));
145         break;
146
147      case 4:
148         m_IR4_rows_per_screen = (data&0x7f) + 1;
149         m_IR4_character_blink_rate_divisor = ((data & 0x80)>>7 ? 128:64);
150
151         LOG2674(("IR4 - Rows Per Screen %02i\n",m_IR4_rows_per_screen));
152         LOG2674(("IR4 - Character Blink Rate = 1/%02i\n",m_IR4_character_blink_rate_divisor));
153         break;
154
155      case 5:
156         /* IR5 - Active Characters Per Row
157          cccc cccc
158          c = Characters Per Row */
159         m_IR5_character_per_row = data + 1;
160         LOG2674(("IR5 - Active Characters Per Row %02i\n",m_IR5_character_per_row));
161         break;
162
163      case 6:
164         m_IR6_cursor_last_scanline = (data & 0x0f);
165         m_IR6_cursor_first_scanline = (data & 0xf0)>>4;
166         LOG2674(("IR6 - First Line of Cursor %02x\n",m_IR6_cursor_first_scanline));
167         LOG2674(("IR6 - Last Line of Cursor %02x\n",m_IR6_cursor_last_scanline));
168         break;
169
170      case 7:
171      {
172         const UINT8 vsync_table[4] = {3,1,5,7};
173         m_IR7_cursor_underline_position = (data & 0x0f);
174         m_IR7_cursor_rate_divisor = ((data & 0x10)>>4 ? 64:32);
175         m_IR7_cursor_blink = (data & 0x20)>>5;
176
177         m_IR7_vsync_width = vsync_table[(data & 0xC0)>>6];
178
179         LOG2674(("IR7 - Underline Position %02x\n",m_IR7_cursor_underline_position));
180         LOG2674(("IR7 - Cursor rate 1/%02i\n",m_IR7_cursor_rate_divisor));
181         LOG2674(("IR7 - Cursor blink %02x\n",m_IR7_cursor_blink));
182         LOG2674(("IR7 - Vsync Width  %02i Lines\n",m_IR7_vsync_width));
183         break;
184      }
185
186      case 8:
187         m_IR8_display_buffer_first_address_LSB = data;
188         LOG2674(("IR8 - Display Buffer First Address LSB %02x\n",m_IR8_display_buffer_first_address_LSB));
189         break;
190
191      case 9:
192         m_IR9_display_buffer_first_address_MSB = data & 0x0f;
193         m_IR9_display_buffer_last_address = (data & 0xf0)>>4;
194         LOG2674(("IR9 - Display Buffer First Address MSB %02x\n",m_IR9_display_buffer_first_address_MSB));
195         LOG2674(("IR9 - Display Buffer Last Address %02x\n",m_IR9_display_buffer_last_address));
196         break;
197
198      case 10:
199         m_IR10_display_pointer_address_lower = data;
200         LOG2674(("IR10 - Display Pointer Address Lower %02x\n",m_IR10_display_pointer_address_lower));
201         break;
202
203      case 11:
204         m_IR11_display_pointer_address_upper= data&0x3f;
205         m_IR11_reset_scanline_counter_on_scrollup= (data&0x40 >> 6);
206         m_IR11_reset_scanline_counter_on_scrolldown= (data&0x80 >> 7);
207
208         LOG2674(("IR11 - Display Pointer Address Lower %02x\n",m_IR11_display_pointer_address_upper));
209         LOG2674(("IR11 - Reset Scanline Counter on Scroll Up %02x\n",m_IR11_reset_scanline_counter_on_scrollup));
210         LOG2674(("IR11 - Reset Scanline Counter on Scroll Down %02x\n",m_IR11_reset_scanline_counter_on_scrolldown));
211         break;
212
213      case 12:
214         m_IR12_scroll_start = (data & 0x80)>>7;
215         m_IR12_split_register_1 = (data & 0x7f);
216         LOG2674(("IR12 - Scroll Start %02x\n",m_IR12_scroll_start));
217         LOG2674(("IR12 - Split Register 1 %02x\n",m_IR12_split_register_1));
218         break;
219
220      case 13:
221         m_IR13_scroll_end = (data & 0x80)>>7;
222         m_IR13_split_register_2 = (data & 0x7f);
223         LOG2674(("IR13 - Scroll End %02x\n",m_IR13_scroll_end));
224         LOG2674(("IR13 - Split Register 2 %02x\n",m_IR13_split_register_2));
225         break;
226
227      case 14:
228         m_IR14_scroll_lines = (data & 0x0f);
229         if (!m_IR0_double_ht_wd)
230         {
231            m_IR14_double_2 = (data & 0x30)>>4;
232            LOG2674(("IR14 - Double 2 %02x\n",m_IR14_double_2));
233         }
234         //0 normal, 1, double width, 2, double width and double tops 3, double width and double bottoms
235         //1 affects SSR1, 2 affects SSR2
236         //If Double Height enabled in IR0, Screen start 1 upper (bits 7 and 6)replace Double 1, and Double 2 is unused
237         m_IR14_double_1 = (data & 0xc0)>>6;
238         LOG2674(("IR14 - Double 1 %02x\n",m_IR14_double_1));
239
240         LOG2674(("IR14 - Scroll Lines %02i\n",m_IR14_scroll_lines));
241         break;
242
243      case 15: /* not valid! */
244         break;
245
246   }
247   if(m_display_enabled)
248      recompute_parameters();
249
250   m_IR_pointer++;
251   if (m_IR_pointer>14)m_IR_pointer=14;
252}
253
254void scn2674_device::write_command(UINT8 data)
255{
256   UINT8 operand;
257   int i;
258
259
260   if (data==0x00)
261   {
262      /* master reset, configures registers */
263      LOG2674(("master reset\n"));
264      m_IR_pointer=0;
265      m_irq_register = 0x00;
266      m_status_register = 0x20;//RDFLG activated
267      m_linecounter =0;
268      m_irq_mask = 0x00;
269      m_gfx_enabled = 0;
270      m_display_enabled = 0;
271      m_cursor_enabled = 0;
272      m_IR2_row_table = 0;
273   }
274
275   if ((data&0xf0)==0x10)
276   {
277      /* set IR pointer */
278      operand = data & 0x0f;
279      LOG2674(("set IR pointer %02x\n",operand));
280
281      m_IR_pointer=operand;
282
283   }
284
285   /* ANY COMBINATION OF THESE ARE POSSIBLE */
286
287   if ((data&0xe3)==0x22)
288   {
289      /* Disable GFX */
290      LOG2674(("disable GFX %02x\n",data));
291      m_gfx_enabled = 0;
292      if(m_display_enabled)
293         recompute_parameters();
294   }
295
296   if ((data&0xe3)==0x23)
297   {
298      /* Enable GFX */
299      LOG2674(("enable GFX %02x\n",data));
300      m_gfx_enabled = 1;
301      if(m_display_enabled)
302         recompute_parameters();
303   }
304
305   if ((data&0xe9)==0x28)
306   {
307      /* Display off */
308      operand = data & 0x04;
309
310      m_display_enabled = 0;
311
312      if (operand)
313         LOG2674(("display OFF - float DADD bus %02x\n",data));
314      else
315         LOG2674(("display OFF - no float DADD bus %02x\n",data));
316   }
317
318   if ((data&0xe9)==0x29)
319   {
320      /* Display on */
321      operand = data & 0x04;
322
323      if (operand)
324      {
325         m_display_enabled_field = 1;
326         LOG2674(("display ON - next field %02x\n",data));
327      }
328      else
329      {
330         m_display_enabled_scanline = 1;
331         LOG2674(("display ON - next scanline %02x\n",data));
332      }
333      recompute_parameters(); // start the scanline timer
334   }
335
336   if ((data&0xf1)==0x30)
337   {
338      /* Cursor Off */
339      LOG2674(("cursor off %02x\n",data));
340      m_cursor_enabled = 0;
341   }
342
343   if ((data&0xf1)==0x31)
344   {
345      /* Cursor On */
346      LOG2674(("cursor on %02x\n",data));
347      m_cursor_enabled = 1;
348   }
349
350   /* END */
351
352   if ((data&0xe0)==0x40)
353   {
354      /* Reset Interrupt / Status bit */
355      operand = data & 0x1f;
356      LOG2674(("reset interrupt / status bit %02x\n",operand));
357
358      m_irq_register &= ~(data & 0x1f);
359      m_status_register &= ~(data & 0x1f);
360
361      LOG2674(("IRQ Status after reset\n"));
362      LOG2674(("Split 2   IRQ: %d Active\n",(m_irq_register>>0)&1));
363      LOG2674(("Ready     IRQ: %d Active\n",(m_irq_register>>1)&1));
364      LOG2674(("Split 1   IRQ: %d Active\n",(m_irq_register>>2)&1));
365      LOG2674(("Line Zero IRQ: %d Active\n",(m_irq_register>>3)&1));
366      LOG2674(("V-Blank   IRQ: %d Active\n",(m_irq_register>>4)&1));
367
368      m_irq_state = 0;
369
370      for (i = 0; i < 5; i++)
371      {
372         if ((m_irq_register>>i&1)&(m_irq_mask>>i&1))
373         {
374            m_irq_state = 1;
375         }
376      }
377      m_irq_cb(m_irq_register ? 1 : 0);
378
379   }
380   if ((data&0xe0)==0x80)
381   {
382      /* Disable Interrupt mask*/
383      operand = data & 0x1f;
384      m_irq_mask &= ~(operand);
385      LOG2674(("IRQ Mask after disable %x\n",operand));
386      LOG2674(("Split 2   IRQ: %d Unmasked\n",(m_irq_mask>>0)&1));
387      LOG2674(("Ready     IRQ: %d Unmasked\n",(m_irq_mask>>1)&1));
388      LOG2674(("Split 1   IRQ: %d Unmasked\n",(m_irq_mask>>2)&1));
389      LOG2674(("Line Zero IRQ: %d Unmasked\n",(m_irq_mask>>3)&1));
390      LOG2674(("V-Blank   IRQ: %d Unmasked\n",(m_irq_mask>>4)&1));
391
392   }
393
394   if ((data&0xe0)==0x60)
395   {
396      /* Enable Interrupt mask*/
397      operand = data & 0x1f;
398      m_irq_mask |= (data & 0x1f);
399
400      LOG2674(("IRQ Mask after enable %x\n",operand));
401      LOG2674(("Split 2   IRQ: %d Unmasked\n",(m_irq_mask>>0)&1));
402      LOG2674(("Ready     IRQ: %d Unmasked\n",(m_irq_mask>>1)&1));
403      LOG2674(("Split 1   IRQ: %d Unmasked\n",(m_irq_mask>>2)&1));
404      LOG2674(("Line Zero IRQ: %d Unmasked\n",(m_irq_mask>>3)&1));
405      LOG2674(("V-Blank   IRQ: %d Unmasked\n",(m_irq_mask>>4)&1));
406
407   }
408
409   /* Delayed Commands */
410   /* These set 0x20 in status register when done */
411
412   if (data == 0xa4)
413   {
414      /* read at pointer address */
415      LOG2674(("DELAYED read at pointer address %02x\n",data));
416   }
417
418   if (data == 0xa2)
419   {
420      /* write at pointer address */
421      LOG2674(("DELAYED write at pointer address %02x\n",data));
422   }
423
424   if (data == 0xa9)
425   {
426      /* increase cursor address */
427      LOG2674(("DELAYED increase cursor address %02x\n",data));
428   }
429
430   if (data == 0xac)
431   {
432      /* read at cursor address */
433      LOG2674(("DELAYED read at cursor address %02x\n",data));
434   }
435
436   if (data == 0xaa)
437   {
438      /* write at cursor address */
439      LOG2674(("DELAYED write at cursor address %02x\n",data));
440   }
441
442   if (data == 0xad)
443   {
444      /* read at cursor address + increment */
445      LOG2674(("DELAYED read at cursor address+increment %02x\n",data));
446   }
447
448   if (data == 0xab)
449   {
450      /* write at cursor address + increment */
451      LOG2674(("DELAYED write at cursor address+increment %02x\n",data));
452   }
453
454   if (data == 0xbb)
455   {
456      /* write from cursor address to pointer address */
457      LOG2674(("DELAYED write from cursor address to pointer address %02x\n",data));
458   }
459
460   if (data == 0xbd)
461   {
462      /* read from cursor address to pointer address */
463      LOG2674(("DELAYED read from cursor address to pointer address %02x\n",data));
464   }
465}
466
467
468READ8_MEMBER( scn2674_device::read )
469{
470   /*
471   Offset:  Purpose
472    0       Interrupt Register
473    1       Status Register
474    2       Screen Start 1 Lower Register
475    3       Screen Start 1 Upper Register
476    4       Cursor Address Lower Register
477    5       Cursor Address Upper Register
478    6       Screen Start 2 Lower Register
479    7       Screen Start 2 Upper Register
480   */
481
482   switch (offset)
483   {
484      /*  Status / Irq Register
485
486          --RV ZSRs
487
488       6+7 -- = ALWAYS 0
489        5  R  = RDFLG (Status Register Only)
490        4  V  = Vblank
491        3  Z  = Line Zero
492        2  S  = Split 1
493        1  R  = Ready
494        0  s  = Split 2
495      */
496
497      case 0:
498         LOG2674(("Read Irq Register %02x %06x\n",m_irq_register,space.device().safe_pc()));
499         return m_irq_register;
500
501      case 1:
502         LOG2674(("Read Status Register %02X %06x\n",m_status_register,space.device().safe_pc()));
503         return m_status_register;
504
505      case 2: LOG2674(("Read Screen1_l Register %06x\n",space.device().safe_pc()));return m_screen1_l;
506      case 3: LOG2674(("Read Screen1_h Register %06x\n",space.device().safe_pc()));return m_screen1_h & 0x3f;
507      case 4: LOG2674(("Read Cursor_l Register %06x\n",space.device().safe_pc()));return m_cursor_l;
508      case 5: LOG2674(("Read Cursor_h Register %06x\n",space.device().safe_pc()));return m_cursor_h;
509      case 6: LOG2674(("Read Screen2_l Register %06x\n",space.device().safe_pc()));return m_screen2_l;
510      case 7: LOG2674(("Read Screen2_h Register %06x\n",space.device().safe_pc()));return m_screen2_h;
511   }
512
513   return 0xff;
514}
515
516
517WRITE8_MEMBER( scn2674_device::write )
518{
519   /*
520   Offset:  Purpose
521    0       Initialization Registers
522    1       Command Register
523    2       Screen Start 1 Lower Register
524    3       Screen Start 1 Upper Register
525    4       Cursor Address Lower Register
526    5       Cursor Address Upper Register
527    6       Screen Start 2 Lower Register
528    7       Screen Start 2 Upper Register
529   */
530
531   switch (offset)
532   {
533      case 0:
534         write_init_regs(data);
535         break;
536
537      case 1:
538         write_command(data);
539         break;
540
541      case 2: m_screen1_l = data; break;
542      case 3:
543         m_screen1_h = data;
544         m_dbl1=(data & 0xc0)>>6;
545         if (m_IR0_double_ht_wd)
546         {
547            m_IR14_double_1 = m_dbl1;
548            m_screen1_h &= 0x3f;
549            LOG2674(("IR14 - Double 1 overridden %02x\n",m_IR14_double_1));
550         }
551         break;
552
553      case 4: m_cursor_l  = data; break;
554      case 5: m_cursor_h  = (data & 0x3f); break;
555      case 6: m_screen2_l = data; break;
556      case 7:
557         m_screen2_h = (data&0x3f);
558         m_spl1 = (data & 0x40);
559         m_spl2 = (data & 0x80);
560         break;
561   }
562}
563
564void scn2674_device::recompute_parameters()
565{
566   m_hpixels_per_column = m_gfx_enabled ? m_gfx_hpixels_per_column : m_text_hpixels_per_column;
567   int horiz_pix_total = ((m_IR1_equalizing_constant + (m_IR2_horz_sync_width << 1)) << 1) * m_hpixels_per_column;
568   int vert_pix_total = m_IR4_rows_per_screen * m_IR0_scanline_per_char_row + m_IR3_vert_front_porch + m_IR3_vert_back_porch + m_IR7_vsync_width;
569   attoseconds_t refresh = m_screen->frame_period().attoseconds;
570   int max_visible_x = (m_IR5_character_per_row * m_hpixels_per_column) - 1;
571   int max_visible_y = (m_IR4_rows_per_screen * m_IR0_scanline_per_char_row) - 1;
572
573   LOG2674(("width %u height %u max_x %u max_y %u refresh %f\n", horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, 1 / ATTOSECONDS_TO_DOUBLE(refresh)));
574
575   rectangle visarea;
576   visarea.set(0, max_visible_x, 0, max_visible_y);
577   m_screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);
578
579   m_scanline_timer->adjust(m_screen->time_until_pos(0, 0), 0, m_screen->scan_period());
580}
581
582void scn2674_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
583{
584   switch(id)
585   {
586      case TIMER_SCANLINE:
587      {
588         int dw = m_IR0_double_ht_wd ? m_IR14_double_1 : 0;  // double width
589         if(((m_display_enabled_scanline) || (m_display_enabled_field && !m_IR1_interlace_enable)) && (!m_display_enabled))
590         {
591            m_display_enabled = 1;
592            m_display_enabled_scanline = 0;
593            m_display_enabled_field = 0;
594         }
595         else if(!m_display_enabled)
596            break;
597         else
598            m_linecounter++;
599
600         // should be triggered at the start of each ROW (line zero for that row)
601         if(m_linecounter >= m_screen->height())
602         {
603            m_status_register |= 0x08;
604            if (m_irq_mask & 0x08)
605            {
606               LOG2674(("SCN2674 Line Zero\n"));
607               m_irq_state = 1;
608               m_irq_register |= 0x08;
609               m_irq_cb(1);
610            }
611            m_linecounter = 0;
612            m_address = (m_screen1_h << 8) | m_screen1_l;
613         }
614
615         if(m_linecounter == (m_IR4_rows_per_screen * m_IR0_scanline_per_char_row))
616         {
617            m_status_register |= 0x10;
618            if(m_irq_mask & 0x10)
619            {
620               LOG2674(("vblank irq\n"));
621               m_irq_state = 1;
622               m_irq_register |= 0x10;
623               m_irq_cb(1);
624            }
625         }
626
627         if(m_linecounter >= (m_IR4_rows_per_screen * m_IR0_scanline_per_char_row))
628            break;
629
630         if((m_linecounter == (m_IR12_split_register_1 * m_IR0_scanline_per_char_row)) && m_linecounter) /* Split Screen 1 */
631         {
632            m_status_register |= 0x04;
633            if(m_irq_mask & 0x04)
634            {
635               LOG2674(("SCN2674 Split Screen 1 irq\n"));
636               m_irq_state = 1;
637               m_irq_register |= 0x04;
638               m_irq_cb(1);
639            }
640            if(m_spl1)
641               m_address = (m_screen2_h << 8) | m_screen2_l;
642            if(!m_IR0_double_ht_wd)
643               dw = m_IR14_double_1;
644         }
645
646         if((m_linecounter == (m_IR13_split_register_2 * m_IR0_scanline_per_char_row)) && m_linecounter) /* Split Screen 2 */
647         {
648            m_status_register |= 0x01;
649            if(m_irq_mask & 0x01)
650            {
651               LOG2674(("SCN2674 Split Screen 2 irq\n"));
652               m_irq_state = 1;
653               m_irq_register |= 0x01;
654               m_irq_cb(1);
655            }
656            if(m_spl2)
657               m_address = (m_screen2_h << 8) | m_screen2_l;
658            if(!m_IR0_double_ht_wd)
659               dw = m_IR14_double_2;
660         }
661
662         int charrow = m_linecounter % m_IR0_scanline_per_char_row;
663         int tilerow = charrow;
664
665         if(m_IR2_row_table)
666         {
667            if(m_IR0_double_ht_wd)
668               dw = m_screen1_h >> 6;
669            if(!charrow)
670            {
671               UINT16 addr = (m_screen2_h << 8) | m_screen2_l;
672               UINT16 line = space().read_word(addr);
673               m_screen1_h = (line >> 8);
674               m_screen1_l = line & 0xff;
675               if(m_IR0_double_ht_wd)
676               {
677                  dw = line >> 14;
678                  line &= ~0xc000;
679               }
680               m_address = line;
681               addr += 2;
682               m_screen2_h = (addr >> 8) & 0x3f;
683               m_screen2_l = addr & 0xff;
684            }
685
686         }
687
688         if(dw == 2)
689            tilerow >>= 1;
690         else if(dw == 3)
691            tilerow = (charrow + m_IR0_scanline_per_char_row) >> 1;
692
693         UINT16 address = m_address;
694
695         for(int i = 0; i < m_IR5_character_per_row; i++)
696         {
697            if((address & 0x3fff) == ((m_cursor_h << 8) | m_cursor_l))
698               m_cursor_on = true;
699
700            if (!m_display_cb.isnull())
701               m_display_cb(m_bitmap,
702                            i * m_hpixels_per_column,
703                            m_linecounter,
704                            tilerow,
705                            space().read_byte(address),
706                            address,
707                            (charrow >= m_IR6_cursor_first_scanline) && m_cursor_on,
708                            dw != 0,
709                            m_gfx_enabled != 0,
710                            charrow == m_IR7_cursor_underline_position,
711                            m_IR7_cursor_blink && (m_screen->frame_number() & (m_IR7_cursor_rate_divisor ? 0x40 : 0x20)));
712            address = (address + 1) & 0xffff;
713
714            if(address > ((m_IR9_display_buffer_last_address << 10) | 0x3ff))
715               address = (m_IR9_display_buffer_first_address_MSB << 8) | m_IR8_display_buffer_first_address_LSB;
716         }
717
718         if(charrow == m_IR6_cursor_last_scanline)
719            m_cursor_on = false;
720
721         if(m_gfx_enabled || (charrow == (m_IR0_scanline_per_char_row - 1)))
722            m_address = address;
723      }
724   }
725}
726
727UINT32 scn2674_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
728{
729   if (!m_display_enabled)
730      m_bitmap.fill(rgb_t::black);
731   else
732      copybitmap(bitmap, m_bitmap, 0, 0, 0, 0, cliprect);
733
734   return 0;
735}
trunk/src/emu/video/scn2674.h
r0r243572
1#ifndef SCN2674_H
2#define SCN2674_h
3
4#include "emu.h"
5
6#define MCFG_SCN2674_VIDEO_ADD(_tag, _clock, _irq) \
7   MCFG_DEVICE_ADD(_tag, SCN2674_VIDEO, _clock) \
8   devcb = &scn2674_device::set_irq_callback(*device, DEVCB_##_irq);
9
10#define MCFG_SCN2674_TEXT_CHARACTER_WIDTH(_value) \
11   scn2674_device::static_set_character_width(*device, _value);
12
13#define MCFG_SCN2674_GFX_CHARACTER_WIDTH(_value) \
14   scn2674_device::static_set_gfx_character_width(*device, _value);
15
16#define MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(_class, _method) \
17   scn2674_device::static_set_display_callback(*device, scn2674_device::draw_character_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
18
19#define SCN2674_DRAW_CHARACTER_MEMBER(_name) void _name(bitmap_rgb32 &bitmap, int x, int y, UINT8 linecount, UINT8 charcode, UINT16 address, UINT8 cursor, UINT8 dw, UINT8 lg, UINT8 ul, UINT8 blink)
20
21class scn2674_device : public device_t,
22                  public device_video_interface,
23                  public device_memory_interface
24{
25public:
26   scn2674_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
27
28   typedef device_delegate<void (bitmap_rgb32 &bitmap, int x, int y, UINT8 linecount, UINT8 charcode, UINT16 address, UINT8 cursor, UINT8 dw, UINT8 lg, UINT8 ul, UINT8 blink)> draw_character_delegate;
29
30   // static configuration
31   template<class _Object> static devcb_base &set_irq_callback(device_t &device, _Object object) { return downcast<scn2674_device &>(device).m_irq_cb.set_callback(object); }
32   static void static_set_character_width(device_t &device, int value) { downcast<scn2674_device &>(device).m_text_hpixels_per_column = value; }
33   static void static_set_gfx_character_width(device_t &device, int value) { downcast<scn2674_device &>(device).m_gfx_hpixels_per_column = value; }
34   static void static_set_display_callback(device_t &device, draw_character_delegate callback) { downcast<scn2674_device &>(device).m_display_cb = callback; }
35
36   DECLARE_READ8_MEMBER( read );
37   DECLARE_WRITE8_MEMBER( write );
38
39   UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
40   virtual const address_space_config *memory_space_config(address_spacenum spacenum = AS_0) const { return (spacenum == AS_0) ? &m_space_config : NULL; }
41
42protected:
43   virtual void device_start();
44   virtual void device_reset();
45   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
46
47private:
48   bitmap_rgb32 m_bitmap;
49   devcb_write_line m_irq_cb;
50
51   UINT8 m_IR_pointer;
52   UINT8 m_screen1_l;
53   UINT8 m_screen1_h;
54   UINT8 m_cursor_l;
55   UINT8 m_cursor_h;
56   UINT8 m_screen2_l;
57   UINT8 m_screen2_h;
58   UINT8 m_irq_register;
59   UINT8 m_status_register;
60   UINT8 m_irq_mask;
61   UINT8 m_gfx_enabled;
62   UINT8 m_display_enabled;
63   UINT8 m_display_enabled_field;
64   UINT8 m_display_enabled_scanline;
65   UINT8 m_cursor_enabled;
66   UINT8 m_hpixels_per_column;
67   UINT8 m_text_hpixels_per_column;
68   UINT8 m_gfx_hpixels_per_column;
69   UINT8 m_IR0_double_ht_wd;
70   UINT8 m_IR0_scanline_per_char_row;
71   UINT8 m_IR0_sync_select;
72   UINT8 m_IR0_buffer_mode_select;
73   UINT8 m_IR1_interlace_enable;
74   UINT8 m_IR1_equalizing_constant;
75   UINT8 m_IR2_row_table;
76   UINT8 m_IR2_horz_sync_width;
77   UINT8 m_IR2_horz_back_porch;
78   UINT8 m_IR3_vert_front_porch;
79   UINT8 m_IR3_vert_back_porch;
80   UINT8 m_IR4_rows_per_screen;
81   UINT8 m_IR4_character_blink_rate_divisor;
82   UINT8 m_IR5_character_per_row;
83   UINT8 m_IR6_cursor_first_scanline;
84   UINT8 m_IR6_cursor_last_scanline;
85   UINT8 m_IR7_cursor_underline_position;
86   UINT8 m_IR7_cursor_rate_divisor;
87   UINT8 m_IR7_cursor_blink;
88   UINT8 m_IR7_vsync_width;
89   UINT8 m_IR8_display_buffer_first_address_LSB;
90   UINT8 m_IR9_display_buffer_first_address_MSB;
91   UINT8 m_IR9_display_buffer_last_address;
92   UINT8 m_IR10_display_pointer_address_lower;
93   UINT8 m_IR11_display_pointer_address_upper;
94   UINT8 m_IR11_reset_scanline_counter_on_scrollup;
95   UINT8 m_IR11_reset_scanline_counter_on_scrolldown;
96   UINT8 m_IR12_scroll_start;
97   UINT8 m_IR12_split_register_1;
98   UINT8 m_IR13_scroll_end;
99   UINT8 m_IR13_split_register_2;
100   UINT8 m_IR14_scroll_lines;
101   UINT8 m_IR14_double_1;
102   UINT8 m_IR14_double_2;
103   UINT8 m_spl1;
104   UINT8 m_spl2;
105   UINT8 m_dbl1;
106   int m_linecounter;
107   UINT16 m_address;
108   bool m_cursor_on;
109
110   UINT8 m_irq_state;
111
112   void write_init_regs(UINT8 data);
113   void write_command(UINT8 data);
114   void recompute_parameters();
115
116   draw_character_delegate m_display_cb;
117   emu_timer *m_scanline_timer;
118   const address_space_config m_space_config;
119   enum
120   {
121      TIMER_SCANLINE
122   };
123};
124
125
126extern const device_type SCN2674_VIDEO;
127
128#endif
trunk/src/emu/video/video.mak
r243571r243572
455455
456456#-------------------------------------------------
457457#
458#@src/emu/video/scn2674.h,VIDEOS += SCN2674
459#-------------------------------------------------
460ifneq ($(filter SCN2674,$(VIDEOS)),)
461VIDEOOBJS+= $(VIDEOOBJ)/scn2674.o
462endif
463
464#-------------------------------------------------
465#
458466#@src/emu/video/snes_ppu.h,VIDEOS += SNES_PPU
459467#-------------------------------------------------
460468ifneq ($(filter SNES_PPU,$(VIDEOS)),)
trunk/src/mame/drivers/mpu4vid.c
r243571r243572
277277   DECLARE_MACHINE_START(mpu4_vid);
278278   DECLARE_MACHINE_RESET(mpu4_vid);
279279   DECLARE_VIDEO_START(mpu4_vid);
280   UINT32 screen_update_mpu4_vid(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
281   TIMER_DEVICE_CALLBACK_MEMBER(scanline_timer_callback);
280   SCN2674_DRAW_CHARACTER_MEMBER(display_pixels);
282281   DECLARE_WRITE_LINE_MEMBER(m6809_acia_irq);
283282   DECLARE_WRITE_LINE_MEMBER(m68k_acia_irq);
284283   DECLARE_WRITE_LINE_MEMBER(cpu1_ptm_irq);
r243571r243572
297296   DECLARE_WRITE8_MEMBER( vidcharacteriser_w );
298297   DECLARE_READ8_MEMBER( vidcharacteriser_r );
299298   DECLARE_WRITE_LINE_MEMBER(mpu_video_reset);
299   DECLARE_WRITE8_MEMBER( vram_w );
300   DECLARE_READ8_MEMBER( vram_r );
300301};
301302
302303/*************************************
r243571r243572
324325{
325326   m_videocpu->set_input_line(1, m_m6840_irq_state ? ASSERT_LINE : CLEAR_LINE);
326327   m_videocpu->set_input_line(2, m_m6850_irq_state ? ASSERT_LINE : CLEAR_LINE);
327   m_videocpu->set_input_line(3, m_scn2674->get_irq_state() ? ASSERT_LINE : CLEAR_LINE);
328328}
329329
330330/* Communications with 6809 board */
r243571r243572
384384   8*32
385385};
386386
387
388/* double height */
389static const gfx_layout mpu4_vid_char_8x16_layout =
387WRITE8_MEMBER(mpu4vid_state::vram_w)
390388{
391   8,16,
392   0x1000, /* 0x1000 tiles (128k of GFX RAM, 0x20 bytes per tile) */
393   4,
394   { 0,8,16,24 },
395   { 0,1,2,3,4,5,6,7 },
396   { 0*32, 0*32, 1*32, 1*32, 2*32, 2*32, 3*32, 3*32, 4*32, 4*32, 5*32, 5*32, 6*32, 6*32, 7*32, 7*32},
397   8*32
398};
389   m_vid_mainram[offset] = data | (m_vid_mainram[offset] & 0xff00);
390}
399391
400
401/* double width */
402static const gfx_layout mpu4_vid_char_16x8_layout =
392READ8_MEMBER(mpu4vid_state::vram_r)
403393{
404   16,8,
405   0x1000, /* 0x1000 tiles (128k of GFX RAM, 0x20 bytes per tile) */
406   4,
407   { 0,8,16,24 },
408   { 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 },
409   { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32},
410   8*32
411};
394   return m_vid_mainram[offset];
395}
412396
397static ADDRESS_MAP_START( mpu4_vram, AS_0, 8, mpu4vid_state )
398   AM_RANGE(0x0000, 0x7fff) AM_READWRITE(vram_r, vram_w)
399ADDRESS_MAP_END
413400
414/* double height & width */
415static const gfx_layout mpu4_vid_char_16x16_layout =
401SCN2674_DRAW_CHARACTER_MEMBER(mpu4vid_state::display_pixels)
416402{
417   16,16,
418   0x1000,  /* 0x1000 tiles (128k of GFX RAM, 0x20 bytes per tile) */
419   4,
420   { 0,8,16,24 },
421   { 0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7 },
422   { 0*32, 0*32, 1*32, 1*32, 2*32, 2*32, 3*32, 3*32, 4*32, 4*32, 5*32, 5*32, 6*32, 6*32, 7*32, 7*32},
423   8*32
424};
425
426
427
428
429UINT32 mpu4vid_state::screen_update_mpu4_vid(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
430{
431   bitmap.fill(0, cliprect);
432
433   m_scn2674->scn2574_draw(machine(), bitmap, cliprect, m_vid_mainram );
434
435   return 0;
403   if(!lg)
404   {
405      UINT16 tile = m_vid_mainram[address & 0x7fff];
406      const UINT8 *line = m_gfxdecode->gfx(m_gfx_index+0)->get_data(tile & 0xfff);
407      int offset = m_gfxdecode->gfx(m_gfx_index+0)->rowbytes() * linecount;
408      for(int i = 0; i < 8; i++)
409         bitmap.pix32(y, x + i) = (tile >> 12) ? m_palette->pen(line[offset + i]) : m_palette->black_pen();
410   }
436411}
437412
438413
r243571r243572
447422   COMBINE_DATA(&m_vid_vidram[offset]);
448423   offset <<= 1;
449424   m_gfxdecode->gfx(m_gfx_index+0)->mark_dirty(offset/0x20);
450   m_gfxdecode->gfx(m_gfx_index+1)->mark_dirty(offset/0x20);
451   m_gfxdecode->gfx(m_gfx_index+2)->mark_dirty(offset/0x20);
452   m_gfxdecode->gfx(m_gfx_index+3)->mark_dirty(offset/0x20);
453425}
454426
455427
456428VIDEO_START_MEMBER(mpu4vid_state,mpu4_vid)
457429{
458   /* if anything uses tile sizes other than 8x8 we can't really do it this way.. we'll have to draw tiles by hand.
459     All Barcrest stuff uses 8x8, son unless the BwB is different, we don't need to */
460
461430   m_vid_vidram.allocate(0x20000/2);
462431
463432   memset(m_vid_vidram,0,0x20000);
r243571r243572
471440
472441   /* create the char set (gfx will then be updated dynamically from RAM) */
473442   m_gfxdecode->set_gfx(m_gfx_index+0, global_alloc(gfx_element(m_palette, mpu4_vid_char_8x8_layout, reinterpret_cast<UINT8 *>(m_vid_vidram.target()), NATIVE_ENDIAN_VALUE_LE_BE(8,0), m_palette->entries() / 16, 0)));
474   m_gfxdecode->set_gfx(m_gfx_index+1, global_alloc(gfx_element(m_palette, mpu4_vid_char_8x16_layout, reinterpret_cast<UINT8 *>(m_vid_vidram.target()), NATIVE_ENDIAN_VALUE_LE_BE(8,0), m_palette->entries() / 16, 0)));
475   m_gfxdecode->set_gfx(m_gfx_index+2, global_alloc(gfx_element(m_palette, mpu4_vid_char_16x8_layout, reinterpret_cast<UINT8 *>(m_vid_vidram.target()), NATIVE_ENDIAN_VALUE_LE_BE(8,0), m_palette->entries() / 16, 0)));
476   m_gfxdecode->set_gfx(m_gfx_index+3, global_alloc(gfx_element(m_palette, mpu4_vid_char_16x16_layout, reinterpret_cast<UINT8 *>(m_vid_vidram.target()), NATIVE_ENDIAN_VALUE_LE_BE(8,0), m_palette->entries() / 16, 0)));
477
478   m_scn2674->init_stuff();
479
480
481443}
482444
483445
r243571r243572
12891251/*  AM_RANGE(0xa00004, 0xa0000f) AM_READWRITE(mpu4_vid_unmap_r, mpu4_vid_unmap_w) */
12901252
12911253
1292   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, mpu4_vid_scn2674_r, mpu4_vid_scn2674_w,0x00ff)
1254   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff)
12931255
12941256   AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram")
12951257   AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff)
r243571r243572
13071269   AM_RANGE(0x900002, 0x900003) AM_DEVWRITE8("saa", saa1099_device, control_w, 0x00ff)
13081270   AM_RANGE(0xa00000, 0xa00003) AM_READWRITE8(ef9369_r, ef9369_w,0x00ff)
13091271
1310   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, mpu4_vid_scn2674_r, mpu4_vid_scn2674_w,0x00ff)
1272   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff)
13111273
13121274   AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram")
13131275   AM_RANGE(0xff8000, 0xff8001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff)
r243571r243572
13311293//  AM_RANGE(0xa00000, 0xa0000f) AM_READWRITE(bt471_r,bt471_w) //Some games use this
13321294/*  AM_RANGE(0xa00004, 0xa0000f) AM_READWRITE(mpu4_vid_unmap_r, mpu4_vid_unmap_w) */
13331295
1334   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, mpu4_vid_scn2674_r, mpu4_vid_scn2674_w,0x00ff)
1296   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff)
13351297   AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram")
13361298   AM_RANGE(0xe00000, 0xe00001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff)
13371299   AM_RANGE(0xe00002, 0xe00003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0x00ff)
r243571r243572
13491311   //AM_RANGE(0xa00000, 0xa00003) AM_READWRITE8(bt471_r,bt471_w,0x00ff) Some games use this
13501312/*  AM_RANGE(0xa00004, 0xa0000f) AM_READWRITE(mpu4_vid_unmap_r, mpu4_vid_unmap_w) */
13511313
1352   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, mpu4_vid_scn2674_r, mpu4_vid_scn2674_w,0x00ff)
1314   AM_RANGE(0xb00000, 0xb0000f) AM_DEVREADWRITE8("scn2674_vid", scn2674_device, read, write,0x00ff)
13531315   AM_RANGE(0xc00000, 0xc1ffff) AM_READWRITE(mpu4_vid_vidram_r, mpu4_vid_vidram_w) AM_SHARE("vid_vidram")
13541316   AM_RANGE(0xe00000, 0xe00001) AM_DEVREADWRITE8("acia6850_1", acia6850_device, status_r, control_w, 0x00ff)
13551317   AM_RANGE(0xe00002, 0xe00003) AM_DEVREADWRITE8("acia6850_1", acia6850_device, data_r, data_w, 0x00ff)
r243571r243572
13831345
13841346
13851347
1386TIMER_DEVICE_CALLBACK_MEMBER(mpu4vid_state::scanline_timer_callback)
1387{
1388   m_scn2674->scn2674_do_scanline(machine(), param);
1389}
1390
1391
13921348static MACHINE_CONFIG_START( mpu4_vid, mpu4vid_state )
13931349   MCFG_CPU_ADD("maincpu", M6809, MPU4_MASTER_CLOCK/4 )
13941350   MCFG_CPU_PROGRAM_MAP(mpu4_6809_map)
r243571r243572
14031359   MCFG_SCREEN_VISIBLE_AREA(0, (63*8)+(0)-1, 0, (37*8)+0-1)
14041360
14051361   MCFG_SCREEN_REFRESH_RATE(50)
1406   MCFG_SCREEN_UPDATE_DRIVER(mpu4vid_state, screen_update_mpu4_vid)
1362   MCFG_SCREEN_UPDATE_DEVICE("scn2674_vid", scn2674_device, screen_update)
14071363
14081364   MCFG_GFXDECODE_ADD("gfxdecode", "palette", empty)
14091365
1410   MCFG_SCN2674_VIDEO_ADD("scn2674_vid", 0, WRITELINE(mpu4vid_state, update_mpu68_interrupts));
1411   MCFG_SCN2674_GFXDECODE("gfxdecode")
1412   MCFG_SCN2674_PALETTE("palette")
1366   MCFG_SCN2674_VIDEO_ADD("scn2674_vid", 0, INPUTLINE("video", 3))
1367   MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8)
1368   MCFG_SCN2674_GFX_CHARACTER_WIDTH(8)
1369   MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(mpu4vid_state, display_pixels)
1370   MCFG_DEVICE_ADDRESS_MAP(AS_0, mpu4_vram)
14131371
1372
14141373   MCFG_CPU_ADD("video", M68000, VIDEO_MASTER_CLOCK )
14151374   MCFG_CPU_PROGRAM_MAP(mpu4_68k_map)
14161375
r243571r243572
14441403   MCFG_ACIA6850_TXD_HANDLER(DEVWRITELINE("acia6850_0", acia6850_device, write_rxd))
14451404   MCFG_ACIA6850_RTS_HANDLER(DEVWRITELINE("acia6850_0", acia6850_device, write_dcd))
14461405   MCFG_ACIA6850_IRQ_HANDLER(WRITELINE(mpu4vid_state, m68k_acia_irq))
1447
1448   // for the video timing
1449   MCFG_TIMER_DRIVER_ADD_SCANLINE("scan_timer", mpu4vid_state, scanline_timer_callback, "screen", 0, 1)
14501406MACHINE_CONFIG_END
14511407
14521408static MACHINE_CONFIG_DERIVED( crmaze, mpu4_vid )
trunk/src/mame/mame.mak
r243571r243572
327327VIDEOS += RAMDAC
328328#VIDEOS += S2636
329329VIDEOS += SAA5050
330VIDEOS += SCN2674
330331#VIDEOS += SED1200
331332#VIDEOS += SED1330
332333#VIDEOS += SED1520
r243571r243572
960961   $(DRIVERS)/mpu4crystal.o \
961962   $(DRIVERS)/mpu4bwb.o \
962963   $(DRIVERS)/mpu4misc.o \
963   $(VIDEO)/scn2674.o \
964964   $(DRIVERS)/mpu5hw.o $(DRIVERS)/mpu5.o \
965965   $(VIDEO)/awpvid.o \
966966   $(MACHINE)/meters.o \
trunk/src/mame/video/scn2674.c
r243571r243572
1/*
2    SCN2674 - Advanced Video Display Controller (AVDC)  (Video Chip)
3
4    This is a somewhat terrible implementation and should probably just be rewritten from scratch
5    it is currently used by mpu4vid.c and still quite heavily tied to the behavior of that.
6
7    I don't know if the timing bugs with those games comes from this, or emulation of the other
8    MPU4 devices tho because even some of the non-video games seem laggy and prone to failure.
9
10    -- currently expects (from the host driver)
11     decoded gfx in regions 0,1,2,3 in various formats (normal, double height etc.)
12      eventually the chip should just handle this without the need to decode anything
13
14     a callback function for when the irqs are changed / updated
15
16     a call from the video start from your video start function
17
18     a call to the scanline function each scanline
19
20     a call to the video draw (with ram pointer) from a screen update function
21
22     video to be on the primary screen
23
24     this could all be simplified / changed, the chip can actually be hooked up in various ways
25     including working on a per scanline basis with almost no ram
26*/
27
28#include "emu.h"
29#include "scn2674.h"
30
31
32
33const device_type SCN2674_VIDEO = &device_creator<scn2674_device>;
34
35
36scn2674_device::scn2674_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
37   : device_t(mconfig, SCN2674_VIDEO, "SCN2674 VDC", tag, owner, clock, "scn2674_device", __FILE__),
38      m_interrupt_callback(*this),
39      m_gfxdecode(*this),
40      m_palette(*this)
41{
42}
43
44//-------------------------------------------------
45//  static_set_gfxdecode_tag: Set the tag of the
46//  gfx decoder
47//-------------------------------------------------
48
49void scn2674_device::static_set_gfxdecode_tag(device_t &device, const char *tag)
50{
51   downcast<scn2674_device &>(device).m_gfxdecode.set_tag(tag);
52}
53
54//-------------------------------------------------
55//  static_set_palette_tag: Set the tag of the
56//  palette device
57//-------------------------------------------------
58
59void scn2674_device::static_set_palette_tag(device_t &device, const char *tag)
60{
61   downcast<scn2674_device &>(device).m_palette.set_tag(tag);
62}
63
64void scn2674_device::device_start()
65{
66   // resolve callbacks
67   m_interrupt_callback.resolve_safe();
68}
69
70void scn2674_device::device_reset()
71{
72   m_scn2674_IR_pointer= 0;
73   m_scn2674_screen1_l= 0;
74   m_scn2674_screen1_h= 0;
75   m_scn2674_cursor_l= 0;
76   m_scn2674_cursor_h= 0;
77   m_scn2674_screen2_l= 0;
78   m_scn2674_screen2_h= 0;
79   m_scn2674_irq_register= 0;
80   m_scn2674_status_register= 0;
81   m_scn2674_irq_mask= 0;
82   m_scn2674_gfx_enabled= 0;
83   m_scn2674_display_enabled= 0;
84   m_scn2674_display_enabled_field= 0;
85   m_scn2674_display_enabled_scanline= 0;
86   m_scn2674_cursor_enabled= 0;
87   m_IR0_scn2674_double_ht_wd= 0;
88   m_IR0_scn2674_scanline_per_char_row= 0;
89   m_IR0_scn2674_sync_select= 0;
90   m_IR0_scn2674_buffer_mode_select= 0;
91   m_IR1_scn2674_interlace_enable= 0;
92   m_IR1_scn2674_equalizing_constant= 0;
93   m_IR2_scn2674_row_table= 0;
94   m_IR2_scn2674_horz_sync_width= 0;
95   m_IR2_scn2674_horz_back_porch= 0;
96   m_IR3_scn2674_vert_front_porch= 0;
97   m_IR3_scn2674_vert_back_porch= 0;
98   m_IR4_scn2674_rows_per_screen= 0;
99   m_IR4_scn2674_character_blink_rate_divisor= 0;
100   m_IR5_scn2674_character_per_row= 0;
101   m_IR6_scn2674_cursor_first_scanline= 0;
102   m_IR6_scn2674_cursor_last_scanline= 0;
103   m_IR7_scn2674_cursor_underline_position= 0;
104   m_IR7_scn2674_cursor_rate_divisor= 0;
105   m_IR7_scn2674_cursor_blink= 0;
106   m_IR7_scn2674_vsync_width= 0;
107   m_IR8_scn2674_display_buffer_first_address_LSB= 0;
108   m_IR9_scn2674_display_buffer_first_address_MSB= 0;
109   m_IR9_scn2674_display_buffer_last_address= 0;
110   m_IR10_scn2674_display_pointer_address_lower= 0;
111   m_IR11_scn2674_display_pointer_address_upper= 0;
112   m_IR11_scn2674_reset_scanline_counter_on_scrollup= 0;
113   m_IR11_scn2674_reset_scanline_counter_on_scrolldown= 0;
114   m_IR12_scn2674_scroll_start= 0;
115   m_IR12_scn2674_split_register_1= 0;
116   m_IR13_scn2674_scroll_end= 0;
117   m_IR13_scn2674_split_register_2= 0;
118   m_IR14_scn2674_scroll_lines= 0;
119   m_IR14_scn2674_double_1= 0;
120   m_IR14_scn2674_double_2= 0;
121   m_scn2674_horz_front_porch= 0;
122   m_scn2674_spl1= 0;
123   m_scn2674_spl2= 0;
124   m_scn2674_dbl1= 0;
125   m_rowcounter= 0;
126   m_linecounter= 0;
127   m_scn2674_irq_state= 0;
128}
129
130// 15 Initialization Registers (8-bit each)
131void scn2674_device::scn2674_write_init_regs(UINT8 data)
132{
133   LOG2674(("scn2674_write_init_regs %02x %02x\n",m_scn2674_IR_pointer,data));
134
135//  m_scn2674_IR[m_scn2674_IR_pointer]=data;
136
137
138   switch ( m_scn2674_IR_pointer) /* display some debug info, set mame specific variables */
139   {
140      case 0:
141         m_IR0_scn2674_double_ht_wd = (data & 0x80)>>7;
142         m_IR0_scn2674_scanline_per_char_row = ((data & 0x78)>>3) + 1;
143         m_IR0_scn2674_sync_select = (data&0x04)>>2;
144         m_IR0_scn2674_buffer_mode_select = (data&0x03);
145
146         LOG2674(("IR0 - Double Ht Wd %02x\n",m_IR0_scn2674_double_ht_wd));//affects IR14 as well
147         LOG2674(("IR0 - Scanlines per Character Row %02x\n",m_IR0_scn2674_scanline_per_char_row));//value+1 = scanlines
148
149         if (m_IR0_scn2674_scanline_per_char_row != 8)
150         {
151            popmessage("Row size change, contact MAMEDEV");
152         }
153         LOG2674(("IR0 - Sync Select %02x\n",m_IR0_scn2674_sync_select));//1 = csync
154         LOG2674(("IR0 - Buffer Mode Select %02x\n",m_IR0_scn2674_buffer_mode_select)); //0 independent 1 transparent 2 shared 3 row
155         break;
156
157      case 1:
158         m_IR1_scn2674_interlace_enable = (data&0x80)>>7;
159         m_IR1_scn2674_equalizing_constant = (data&0x7f)+1;
160
161         LOG2674(("IR1 - Interlace Enable %02x\n",m_IR1_scn2674_interlace_enable));
162         LOG2674(("IR1 - Equalizing Constant %02i CCLKs\n",m_IR1_scn2674_equalizing_constant));
163         break;
164
165      case 2:
166         m_IR2_scn2674_row_table = (data&0x80)>>7;
167         m_IR2_scn2674_horz_sync_width = (((data&0x78)>>3)*2) + 2;
168         m_IR2_scn2674_horz_back_porch = ((data&0x07)*4) - 1;
169
170         LOG2674(("IR2 - Row Table %02x\n",m_IR2_scn2674_row_table));
171         LOG2674(("IR2 - Horizontal Sync Width %02i CCLKs\n",m_IR2_scn2674_horz_sync_width));
172         LOG2674(("IR2 - Horizontal Back Porch %02i CCLKs\n",m_IR2_scn2674_horz_back_porch));
173         break;
174
175      case 3:
176         m_IR3_scn2674_vert_front_porch =  (((data&0xe0)>>5) * 4)+4 ;
177         m_IR3_scn2674_vert_back_porch = ((data&0x1f) * 2) + 4;
178
179         LOG2674(("IR3 - Vertical Front Porch %02i Lines\n",m_IR3_scn2674_vert_front_porch));
180         LOG2674(("IR3 - Vertical Back Porch %02i Lines\n",m_IR3_scn2674_vert_back_porch));
181         break;
182
183      case 4:
184         m_IR4_scn2674_rows_per_screen = (data&0x7f) + 1;
185         m_IR4_scn2674_character_blink_rate_divisor = ((data & 0x80)>>7 ? 128:64);
186
187         LOG2674(("IR4 - Rows Per Screen %02i\n",m_IR4_scn2674_rows_per_screen));
188         LOG2674(("IR4 - Character Blink Rate = 1/%02i\n",m_IR4_scn2674_character_blink_rate_divisor));
189         break;
190
191      case 5:
192         /* IR5 - Active Characters Per Row
193          cccc cccc
194          c = Characters Per Row */
195         m_IR5_scn2674_character_per_row = data + 1;
196         LOG2674(("IR5 - Active Characters Per Row %02i\n",m_IR5_scn2674_character_per_row));
197         break;
198
199      case 6:
200         m_IR6_scn2674_cursor_last_scanline = (data & 0x0f);
201         m_IR6_scn2674_cursor_first_scanline = (data & 0xf0)>>4;
202         LOG2674(("IR6 - First Line of Cursor %02x\n",m_IR6_scn2674_cursor_first_scanline));
203         LOG2674(("IR6 - Last Line of Cursor %02x\n",m_IR6_scn2674_cursor_last_scanline));
204         break;
205
206      case 7:
207         m_IR7_scn2674_cursor_underline_position = (data & 0x0f);
208         m_IR7_scn2674_cursor_rate_divisor = ((data & 0x10)>>4 ? 64:32);
209         m_IR7_scn2674_cursor_blink = (data & 0x20)>>5;
210
211         m_IR7_scn2674_vsync_width = vsync_table[(data & 0xC0)>>6];
212
213         LOG2674(("IR7 - Underline Position %02x\n",m_IR7_scn2674_cursor_underline_position));
214         LOG2674(("IR7 - Cursor rate 1/%02i\n",m_IR7_scn2674_cursor_rate_divisor));
215         LOG2674(("IR7 - Cursor blink %02x\n",m_IR7_scn2674_cursor_blink));
216         LOG2674(("IR7 - Vsync Width  %02i Lines\n",m_IR7_scn2674_vsync_width));
217         break;
218
219      case 8:
220         m_IR8_scn2674_display_buffer_first_address_LSB = data;
221         LOG2674(("IR8 - Display Buffer First Address LSB %02x\n",m_IR8_scn2674_display_buffer_first_address_LSB));
222         break;
223
224      case 9:
225         m_IR9_scn2674_display_buffer_first_address_MSB = data & 0x0f;
226         m_IR9_scn2674_display_buffer_last_address = (data & 0xf0)>>4;
227         LOG2674(("IR9 - Display Buffer First Address MSB %02x\n",m_IR9_scn2674_display_buffer_first_address_MSB));
228         LOG2674(("IR9 - Display Buffer Last Address %02x\n",m_IR9_scn2674_display_buffer_last_address));
229         break;
230
231      case 10:
232         m_IR10_scn2674_display_pointer_address_lower = data;
233         LOG2674(("IR10 - Display Pointer Address Lower %02x\n",m_IR10_scn2674_display_pointer_address_lower));
234         break;
235
236      case 11:
237         m_IR11_scn2674_display_pointer_address_upper= data&0x3f;
238         m_IR11_scn2674_reset_scanline_counter_on_scrollup= (data&0x40 >> 6);
239         m_IR11_scn2674_reset_scanline_counter_on_scrolldown= (data&0x80 >> 7);
240
241         LOG2674(("IR11 - Display Pointer Address Lower %02x\n",m_IR11_scn2674_display_pointer_address_upper));
242         LOG2674(("IR11 - Reset Scanline Counter on Scroll Up %02x\n",m_IR11_scn2674_reset_scanline_counter_on_scrollup));
243         LOG2674(("IR11 - Reset Scanline Counter on Scroll Down %02x\n",m_IR11_scn2674_reset_scanline_counter_on_scrolldown));
244         break;
245
246      case 12:
247         m_IR12_scn2674_scroll_start = (data & 0x80)>>7;
248         m_IR12_scn2674_split_register_1 = (data & 0x7f);
249         LOG2674(("IR12 - Scroll Start %02x\n",m_IR12_scn2674_scroll_start));
250         LOG2674(("IR12 - Split Register 1 %02x\n",m_IR12_scn2674_split_register_1));
251         break;
252
253      case 13:
254         m_IR13_scn2674_scroll_end = (data & 0x80)>>7;
255         m_IR13_scn2674_split_register_2 = (data & 0x7f);
256         LOG2674(("IR13 - Scroll End %02x\n",m_IR13_scn2674_scroll_end));
257         LOG2674(("IR13 - Split Register 2 %02x\n",m_IR13_scn2674_split_register_2));
258         break;
259
260      case 14:
261         m_IR14_scn2674_scroll_lines = (data & 0x0f);
262         if (!m_IR0_scn2674_double_ht_wd)
263         {
264            m_IR14_scn2674_double_2 = (data & 0x30)>>4;
265            LOG2674(("IR14 - Double 2 %02x\n",m_IR14_scn2674_double_2));
266         }
267         //0 normal, 1, double width, 2, double width and double tops 3, double width and double bottoms
268         //1 affects SSR1, 2 affects SSR2
269         //If Double Height enabled in IR0, Screen start 1 upper (bits 7 and 6)replace Double 1, and Double 2 is unused
270         m_IR14_scn2674_double_1 = (data & 0xc0)>>6;
271         LOG2674(("IR14 - Double 1 %02x\n",m_IR14_scn2674_double_1));
272
273         LOG2674(("IR14 - Scroll Lines %02i\n",m_IR14_scn2674_scroll_lines));
274         break;
275
276      case 15: /* not valid! */
277         break;
278
279   }
280
281   m_scn2674_horz_front_porch = 2*(m_IR1_scn2674_equalizing_constant) + 3*(m_IR2_scn2674_horz_sync_width)-(m_IR5_scn2674_character_per_row) - m_IR2_scn2674_horz_back_porch;
282   LOG2674(("Horizontal Front Porch %02x CCLKs\n",m_scn2674_horz_front_porch));
283
284   m_scn2674_IR_pointer++;
285   if (m_scn2674_IR_pointer>14)m_scn2674_IR_pointer=14;
286}
287
288void scn2674_device::scn2674_write_command(running_machine &machine, UINT8 data)
289{
290   UINT8 operand;
291   int i;
292
293   LOG2674(("scn2674_write_command %02x\n",data));
294
295   if (data==0x00)
296   {
297      /* master reset, configures registers */
298      LOG2674(("master reset\n"));
299      m_scn2674_IR_pointer=0;
300      m_scn2674_irq_register = 0x00;
301      m_scn2674_status_register = 0x20;//RDFLG activated
302      m_linecounter =0;
303      m_rowcounter =0;
304      m_scn2674_irq_mask = 0x00;
305      m_scn2674_gfx_enabled = 0;
306      m_scn2674_display_enabled = 0;
307      m_scn2674_cursor_enabled = 0;
308      m_IR2_scn2674_row_table = 0;
309   }
310
311   if ((data&0xf0)==0x10)
312   {
313      /* set IR pointer */
314      operand = data & 0x0f;
315      LOG2674(("set IR pointer %02x\n",operand));
316
317      m_scn2674_IR_pointer=operand;
318
319   }
320
321   /* ANY COMBINATION OF THESE ARE POSSIBLE */
322
323   if ((data&0xe3)==0x22)
324   {
325      /* Disable GFX */
326      LOG2674(("disable GFX %02x\n",data));
327      m_scn2674_gfx_enabled = 0;
328   }
329
330   if ((data&0xe3)==0x23)
331   {
332      /* Enable GFX */
333      LOG2674(("enable GFX %02x\n",data));
334      m_scn2674_gfx_enabled = 1;
335   }
336
337   if ((data&0xe9)==0x28)
338   {
339      /* Display off */
340      operand = data & 0x04;
341
342      m_scn2674_display_enabled = 0;
343
344      if (operand)
345         LOG2674(("display OFF - float DADD bus %02x\n",data));
346      else
347         LOG2674(("display OFF - no float DADD bus %02x\n",data));
348   }
349
350   if ((data&0xe9)==0x29)
351   {
352      /* Display on */
353      operand = data & 0x04;
354
355      if (operand)
356      {
357         m_scn2674_display_enabled_field = 1;
358         LOG2674(("display ON - next field %02x\n",data));
359      }
360      else
361      {
362         m_scn2674_display_enabled_scanline = 1;
363         LOG2674(("display ON - next scanline %02x\n",data));
364      }
365   }
366
367   if ((data&0xf1)==0x30)
368   {
369      /* Cursor Off */
370      LOG2674(("cursor off %02x\n",data));
371      m_scn2674_cursor_enabled = 0;
372   }
373
374   if ((data&0xf1)==0x31)
375   {
376      /* Cursor On */
377      LOG2674(("cursor on %02x\n",data));
378      m_scn2674_cursor_enabled = 1;
379   }
380
381   /* END */
382
383   if ((data&0xe0)==0x40)
384   {
385      /* Reset Interrupt / Status bit */
386      operand = data & 0x1f;
387      LOG2674(("reset interrupt / status bit %02x\n",operand));
388
389      m_scn2674_irq_register &= ~(data & 0x1f);
390      m_scn2674_status_register &= ~(data & 0x1f);
391
392      LOG2674(("IRQ Status after reset\n"));
393      LOG2674(("Split 2   IRQ: %d Active\n",(m_scn2674_irq_register>>0)&1));
394      LOG2674(("Ready     IRQ: %d Active\n",(m_scn2674_irq_register>>1)&1));
395      LOG2674(("Split 1   IRQ: %d Active\n",(m_scn2674_irq_register>>2)&1));
396      LOG2674(("Line Zero IRQ: %d Active\n",(m_scn2674_irq_register>>3)&1));
397      LOG2674(("V-Blank   IRQ: %d Active\n",(m_scn2674_irq_register>>4)&1));
398
399      m_scn2674_irq_state = 0;
400
401      for (i = 0; i < 5; i++)
402      {
403         if ((m_scn2674_irq_register>>i&1)&(m_scn2674_irq_mask>>i&1))
404         {
405            m_scn2674_irq_state = 1;
406         }
407      }
408      m_interrupt_callback(1);
409
410   }
411   if ((data&0xe0)==0x80)
412   {
413      /* Disable Interrupt mask*/
414      operand = data & 0x1f;
415      m_scn2674_irq_mask &= ~(operand);
416      LOG2674(("IRQ Mask after disable %x\n",operand));
417      LOG2674(("Split 2   IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>0)&1));
418      LOG2674(("Ready     IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>1)&1));
419      LOG2674(("Split 1   IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>2)&1));
420      LOG2674(("Line Zero IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>3)&1));
421      LOG2674(("V-Blank   IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>4)&1));
422
423   }
424
425   if ((data&0xe0)==0x60)
426   {
427      /* Enable Interrupt mask*/
428      operand = data & 0x1f;
429      m_scn2674_irq_mask |= (data & 0x1f);
430
431      LOG2674(("IRQ Mask after enable %x\n",operand));
432      LOG2674(("Split 2   IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>0)&1));
433      LOG2674(("Ready     IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>1)&1));
434      LOG2674(("Split 1   IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>2)&1));
435      LOG2674(("Line Zero IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>3)&1));
436      LOG2674(("V-Blank   IRQ: %d Unmasked\n",(m_scn2674_irq_mask>>4)&1));
437
438   }
439
440   /* Delayed Commands */
441   /* These set 0x20 in status register when done */
442
443   if (data == 0xa4)
444   {
445      /* read at pointer address */
446      LOG2674(("DELAYED read at pointer address %02x\n",data));
447   }
448
449   if (data == 0xa2)
450   {
451      /* write at pointer address */
452      LOG2674(("DELAYED write at pointer address %02x\n",data));
453   }
454
455   if (data == 0xa9)
456   {
457      /* increase cursor address */
458      LOG2674(("DELAYED increase cursor address %02x\n",data));
459   }
460
461   if (data == 0xac)
462   {
463      /* read at cursor address */
464      LOG2674(("DELAYED read at cursor address %02x\n",data));
465   }
466
467   if (data == 0xaa)
468   {
469      /* write at cursor address */
470      LOG2674(("DELAYED write at cursor address %02x\n",data));
471   }
472
473   if (data == 0xad)
474   {
475      /* read at cursor address + increment */
476      LOG2674(("DELAYED read at cursor address+increment %02x\n",data));
477   }
478
479   if (data == 0xab)
480   {
481      /* write at cursor address + increment */
482      LOG2674(("DELAYED write at cursor address+increment %02x\n",data));
483   }
484
485   if (data == 0xbb)
486   {
487      /* write from cursor address to pointer address */
488      LOG2674(("DELAYED write from cursor address to pointer address %02x\n",data));
489   }
490
491   if (data == 0xbd)
492   {
493      /* read from cursor address to pointer address */
494      LOG2674(("DELAYED read from cursor address to pointer address %02x\n",data));
495   }
496}
497
498
499READ8_MEMBER( scn2674_device::mpu4_vid_scn2674_r )
500{
501   /*
502   Offset:  Purpose
503    0       Interrupt Register
504    1       Status Register
505    2       Screen Start 1 Lower Register
506    3       Screen Start 1 Upper Register
507    4       Cursor Address Lower Register
508    5       Cursor Address Upper Register
509    6       Screen Start 2 Lower Register
510    7       Screen Start 2 Upper Register
511   */
512
513   switch (offset)
514   {
515      /*  Status / Irq Register
516
517          --RV ZSRs
518
519       6+7 -- = ALWAYS 0
520        5  R  = RDFLG (Status Register Only)
521        4  V  = Vblank
522        3  Z  = Line Zero
523        2  S  = Split 1
524        1  R  = Ready
525        0  s  = Split 2
526      */
527
528      case 0:
529         LOG2674(("Read Irq Register %02x %06x\n",m_scn2674_irq_register,space.device().safe_pc()));
530         return m_scn2674_irq_register;
531
532      case 1:
533         LOG2674(("Read Status Register %02X %06x\n",m_scn2674_status_register,space.device().safe_pc()));
534         return m_scn2674_status_register;
535
536      case 2: LOG2674(("Read Screen1_l Register %06x\n",space.device().safe_pc()));return m_scn2674_screen1_l;
537      case 3: LOG2674(("Read Screen1_h Register %06x\n",space.device().safe_pc()));return m_scn2674_screen1_h;
538      case 4: LOG2674(("Read Cursor_l Register %06x\n",space.device().safe_pc()));return m_scn2674_cursor_l;
539      case 5: LOG2674(("Read Cursor_h Register %06x\n",space.device().safe_pc()));return m_scn2674_cursor_h;
540      case 6: LOG2674(("Read Screen2_l Register %06x\n",space.device().safe_pc()));return m_scn2674_screen2_l;
541      case 7: LOG2674(("Read Screen2_h Register %06x\n",space.device().safe_pc()));return m_scn2674_screen2_h;
542   }
543
544   return 0xff;
545}
546
547
548WRITE8_MEMBER( scn2674_device::mpu4_vid_scn2674_w )
549{
550   /*
551   Offset:  Purpose
552    0       Initialization Registers
553    1       Command Register
554    2       Screen Start 1 Lower Register
555    3       Screen Start 1 Upper Register
556    4       Cursor Address Lower Register
557    5       Cursor Address Upper Register
558    6       Screen Start 2 Lower Register
559    7       Screen Start 2 Upper Register
560   */
561
562   switch (offset)
563   {
564      case 0:
565         scn2674_write_init_regs(data);
566         break;
567
568      case 1:
569         scn2674_write_command(space.machine(), data);
570         break;
571
572      case 2: m_scn2674_screen1_l = data; break;
573      case 3:
574         m_scn2674_screen1_h = (data&0x3f);//uppermost two bytes not part of register
575         m_scn2674_dbl1=(data & 0xc0)>>6;
576         if (m_IR0_scn2674_double_ht_wd)
577         {
578            m_IR14_scn2674_double_1 = m_scn2674_dbl1;
579            LOG2674(("IR14 - Double 1 overridden %02x\n",m_IR14_scn2674_double_1));
580         }
581         break;
582
583      case 4: m_scn2674_cursor_l  = data; break;
584      case 5: m_scn2674_cursor_h  = data; break;
585      case 6: m_scn2674_screen2_l = data; break;
586      case 7:
587         m_scn2674_screen2_h = (data&0x3f);
588         m_scn2674_spl1 = (data & 0x40);
589         m_scn2674_spl2 = (data & 0x80);
590         break;
591   }
592}
593
594
595
596void scn2674_device::scn2674_line(running_machine &machine)
597{
598   if (m_linecounter==0)/* Ready - this triggers for the first scanline of the screen */
599   {
600      m_scn2674_status_register |= 0x02;
601      if (m_scn2674_irq_mask&0x02)
602      {
603         LOG2674(("SCN2674 Ready\n"));
604         m_scn2674_irq_state = 1;
605         m_scn2674_irq_register |= 0x02;
606         m_interrupt_callback(1);
607      }
608   }
609
610   // should be triggered at the start of each ROW (line zero for that row)
611   if (( m_linecounter%8 == 0)&& (m_linecounter < 297) )
612   {
613      m_scn2674_status_register |= 0x08;
614      if (m_scn2674_irq_mask&0x08)
615      {
616         LOG2674(("SCN2674 Line Zero\n"));
617         m_scn2674_irq_state = 1;
618         m_scn2674_irq_register |= 0x08;
619         m_interrupt_callback(1);
620      }
621         m_rowcounter = ((m_rowcounter+1)% 37);//Not currently used
622   }
623
624   // this is ROWS not scanlines!!
625   if ((m_linecounter == m_IR12_scn2674_split_register_1*8)&&(m_linecounter != 0))
626   /* Split Screen 1 */
627   {
628      if (m_scn2674_spl1)
629      {
630         popmessage("Split screen 1 address shift required, contact MAMEDEV");
631      }
632      m_scn2674_status_register |= 0x04;
633      if (m_scn2674_irq_mask&0x04)
634      {
635         machine.first_screen()->update_partial(m_linecounter);
636         m_scn2674_irq_register |= 0x04;
637         LOG2674(("SCN2674 Split Screen 1\n"));
638         m_scn2674_irq_state = 1;
639         m_interrupt_callback(1);
640//          machine.first_screen()->update_partial(m_linecounter);
641      }
642   }
643
644   // this is in ROWS not scanlines!!!
645   if ((m_linecounter == m_IR13_scn2674_split_register_2*8)&&(m_linecounter != 0))
646   /* Split Screen 2 */
647   {
648      if (m_scn2674_spl2)
649      {
650         popmessage("Split screen 2 address shift required, contact MAMEDEV");
651      }
652      m_scn2674_status_register |= 0x01;
653      if (m_scn2674_irq_mask&0x01)
654      {
655         machine.first_screen()->update_partial(m_linecounter);
656         LOG2674(("SCN2674 Split Screen 2 irq\n"));
657         m_scn2674_irq_state = 1;
658         m_scn2674_irq_register |= 0x01;
659         m_interrupt_callback(1);
660         //machine.first_screen()->update_partial(m_linecounter);
661      }
662   }
663
664   if (m_linecounter==296)//front porch
665   {
666      m_scn2674_status_register |= 0x10;
667      if (m_scn2674_irq_mask&0x10)
668      {
669         LOG2674(("vblank irq\n"));
670         m_scn2674_irq_state = 1;
671         m_scn2674_irq_register |= 0x10;
672         m_interrupt_callback(1);
673      }
674
675   }
676
677}
678
679
680// scanline timer
681
682
683void scn2674_device::scn2674_do_scanline(running_machine &machine, int scanline)
684{
685   //This represents the scanline counter in the SCN2674. Note that we ignore the horizontal blanking
686
687   if (((m_scn2674_display_enabled_scanline) || (m_scn2674_display_enabled_field && (m_IR1_scn2674_interlace_enable == 0)))&&(!m_scn2674_display_enabled))
688   {
689      m_scn2674_display_enabled = 1;
690      m_scn2674_display_enabled_scanline = 0;
691      m_scn2674_display_enabled_field = 0;
692   }
693   if (m_scn2674_display_enabled)
694   {
695      m_linecounter = scanline;
696   }
697   else
698   {
699      m_linecounter =297;//hold the counter in the vsync point, it's not clear whether this is done or not
700   }
701   scn2674_line(machine);
702//  timer.machine().scheduler().synchronize();
703}
704
705
706////// screen update
707template<class _BitmapClass>
708void scn2674_device::scn2574_draw_common( running_machine &machine, _BitmapClass &bitmap, const rectangle &cliprect, UINT16* vid_mainram )
709{
710   int x, y/*, count = 0*/;
711   /* this is in main ram.. i think it must transfer it out of here??? */
712   /* count = 0x0018b6/2; - crmaze count = 0x004950/2; - turnover */
713   /* we're in row table mode...thats why */
714   for(y = 0; y < m_IR4_scn2674_rows_per_screen; y++)
715   {
716      int screen2_base = (m_scn2674_screen2_h << 8) | m_scn2674_screen2_l;
717      UINT16 rowbase = (vid_mainram[1+screen2_base+(y*2)]<<8)|vid_mainram[screen2_base+(y*2)];
718      int dbl_size=0;
719      int gfxregion = 0;
720
721      if (m_IR0_scn2674_double_ht_wd)
722      {
723         dbl_size = (rowbase & 0xc000)>>14;  /* ONLY if double size is enabled.. otherwise it can address more chars given more RAM */
724      }
725
726      if (dbl_size&2)
727      {
728         gfxregion = 1;
729      }
730      for(x = 0; x < m_IR5_scn2674_character_per_row; x++)
731      {
732         UINT16 tiledat;
733         UINT16 attr;
734
735         tiledat = vid_mainram[(rowbase+x)&0x7fff];
736         attr = tiledat >>12;
737
738         if (attr)
739            m_gfxdecode->gfx(gfxregion)->opaque(bitmap,cliprect,tiledat,0,0,0,(x*8),(y*8));
740
741      }
742      if (dbl_size&2)
743      {
744         y++;/* skip a row? */
745      }
746
747   }
748}
749
750void scn2674_device::scn2574_draw( running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16* vid_mainram )
751{ scn2574_draw_common(machine, bitmap, cliprect, vid_mainram); }
752
753void scn2674_device::scn2574_draw( running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16* vid_mainram )
754{ scn2574_draw_common(machine, bitmap, cliprect, vid_mainram); }
755
756void scn2674_device::init_stuff()
757{
758   // from video start
759   m_scn2674_IR_pointer = 0;
760}
trunk/src/mame/video/scn2674.h
r243571r243572
1
2#define S674VERBOSE 0
3#define LOG2674(x) do { if (S674VERBOSE) logerror x; } while (0)
4
5
6#define MCFG_SCN2674_VIDEO_ADD(_tag, _clock, _irq) \
7   MCFG_DEVICE_ADD(_tag, SCN2674_VIDEO, _clock) \
8   downcast<scn2674_device *>(device)->set_callbacks(DEVCB_##_irq);
9
10#define MCFG_SCN2674_GFXDECODE(_gfxtag) \
11   scn2674_device::static_set_gfxdecode_tag(*device, "^" _gfxtag);
12
13#define MCFG_SCN2674_PALETTE(_palette_tag) \
14   scn2674_device::static_set_palette_tag(*device, "^" _palette_tag);
15
16typedef void (*s2574_interrupt_callback_func)(running_machine &machine);
17
18static const UINT8 vsync_table[4] = {3,1,5,7}; //Video related
19
20class scn2674_device : public device_t
21{
22public:
23   scn2674_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
24
25   // static configuration
26   static void static_set_gfxdecode_tag(device_t &device, const char *tag);
27   static void static_set_palette_tag(device_t &device, const char *tag);
28
29   template<class _irq> void set_callbacks(_irq irq) {
30      m_interrupt_callback.set_callback(irq);
31   }
32//  int m_gfx_index;
33
34   DECLARE_READ8_MEMBER( mpu4_vid_scn2674_r );
35   DECLARE_WRITE8_MEMBER( mpu4_vid_scn2674_w );
36
37   UINT8 get_irq_state( void )
38   {
39      return m_scn2674_irq_state;
40   }
41
42
43
44   void scn2574_draw(running_machine &machine, bitmap_ind16 &bitmap, const rectangle &cliprect, UINT16* vid_mainram);
45   void scn2574_draw(running_machine &machine, bitmap_rgb32 &bitmap, const rectangle &cliprect, UINT16* vid_mainram);
46   void init_stuff();
47   void scn2674_do_scanline(running_machine &machine, int scanline);
48
49
50protected:
51   virtual void device_start();
52   virtual void device_reset();
53
54   devcb_write_line m_interrupt_callback;
55
56   UINT8 m_scn2674_IR_pointer;
57   UINT8 m_scn2674_screen1_l;
58   UINT8 m_scn2674_screen1_h;
59   UINT8 m_scn2674_cursor_l;
60   UINT8 m_scn2674_cursor_h;
61   UINT8 m_scn2674_screen2_l;
62   UINT8 m_scn2674_screen2_h;
63   UINT8 m_scn2674_irq_register;
64   UINT8 m_scn2674_status_register;
65   UINT8 m_scn2674_irq_mask;
66   UINT8 m_scn2674_gfx_enabled;
67   UINT8 m_scn2674_display_enabled;
68   UINT8 m_scn2674_display_enabled_field;
69   UINT8 m_scn2674_display_enabled_scanline;
70   UINT8 m_scn2674_cursor_enabled;
71   UINT8 m_IR0_scn2674_double_ht_wd;
72   UINT8 m_IR0_scn2674_scanline_per_char_row;
73   UINT8 m_IR0_scn2674_sync_select;
74   UINT8 m_IR0_scn2674_buffer_mode_select;
75   UINT8 m_IR1_scn2674_interlace_enable;
76   UINT8 m_IR1_scn2674_equalizing_constant;
77   UINT8 m_IR2_scn2674_row_table;
78   UINT8 m_IR2_scn2674_horz_sync_width;
79   UINT8 m_IR2_scn2674_horz_back_porch;
80   UINT8 m_IR3_scn2674_vert_front_porch;
81   UINT8 m_IR3_scn2674_vert_back_porch;
82   UINT8 m_IR4_scn2674_rows_per_screen;
83   UINT8 m_IR4_scn2674_character_blink_rate_divisor;
84   UINT8 m_IR5_scn2674_character_per_row;
85   UINT8 m_IR6_scn2674_cursor_first_scanline;
86   UINT8 m_IR6_scn2674_cursor_last_scanline;
87   UINT8 m_IR7_scn2674_cursor_underline_position;
88   UINT8 m_IR7_scn2674_cursor_rate_divisor;
89   UINT8 m_IR7_scn2674_cursor_blink;
90   UINT8 m_IR7_scn2674_vsync_width;
91   UINT8 m_IR8_scn2674_display_buffer_first_address_LSB;
92   UINT8 m_IR9_scn2674_display_buffer_first_address_MSB;
93   UINT8 m_IR9_scn2674_display_buffer_last_address;
94   UINT8 m_IR10_scn2674_display_pointer_address_lower;
95   UINT8 m_IR11_scn2674_display_pointer_address_upper;
96   UINT8 m_IR11_scn2674_reset_scanline_counter_on_scrollup;
97   UINT8 m_IR11_scn2674_reset_scanline_counter_on_scrolldown;
98   UINT8 m_IR12_scn2674_scroll_start;
99   UINT8 m_IR12_scn2674_split_register_1;
100   UINT8 m_IR13_scn2674_scroll_end;
101   UINT8 m_IR13_scn2674_split_register_2;
102   UINT8 m_IR14_scn2674_scroll_lines;
103   UINT8 m_IR14_scn2674_double_1;
104   UINT8 m_IR14_scn2674_double_2;
105   UINT8 m_scn2674_horz_front_porch;
106   UINT8 m_scn2674_spl1;
107   UINT8 m_scn2674_spl2;
108   UINT8 m_scn2674_dbl1;
109   int m_rowcounter;
110   int m_linecounter;
111
112   UINT8 m_scn2674_irq_state;
113
114   void scn2674_write_init_regs(UINT8 data);
115   void scn2674_write_command(running_machine &machine, UINT8 data);
116   void scn2674_line(running_machine &machine);
117
118   template<class _BitmapClass>
119   void scn2574_draw_common( running_machine &machine, _BitmapClass &bitmap, const rectangle &cliprect, UINT16* vid_mainram );
120
121private:
122   required_device<gfxdecode_device> m_gfxdecode;
123   required_device<palette_device> m_palette;
124};
125
126
127extern const device_type SCN2674_VIDEO;
trunk/src/mess/drivers/pcd.c
r243571r243572
2020#include "machine/mc146818.h"
2121#include "sound/speaker.h"
2222#include "video/scn2674.h"
23#include "formats/pc_dsk.h"
2324
2425//**************************************************************************
2526//  TYPE DEFINITIONS
r243571r243572
3839   m_fdc(*this, "fdc"),
3940   m_rtc(*this, "rtc"),
4041   m_crtc(*this, "crtc"),
42   m_palette(*this, "palette"),
43   m_gfxdecode(*this, "gfxdecode"),
4144   m_vram(*this, "vram"),
4245   m_charram(8*1024)
4346   { }
r243571r243572
4649   TIMER_DEVICE_CALLBACK_MEMBER( timer0_tick );
4750   DECLARE_WRITE_LINE_MEMBER( i186_timer1_w );
4851
49   DECLARE_READ8_MEMBER( charram_r );
50   DECLARE_WRITE8_MEMBER( charram_w );
51   DECLARE_READ16_MEMBER( nmi_io_r );
52   DECLARE_WRITE16_MEMBER( nmi_io_w );
52   DECLARE_READ8_MEMBER( nmi_io_r );
53   DECLARE_WRITE8_MEMBER( nmi_io_w );
5354   DECLARE_READ8_MEMBER( rtc_r );
5455   DECLARE_WRITE8_MEMBER( rtc_w );
5556   DECLARE_READ8_MEMBER( stat_r );
5657   DECLARE_WRITE8_MEMBER( stat_w );
5758   DECLARE_READ8_MEMBER( led_r );
5859   DECLARE_WRITE8_MEMBER( led_w );
59   UINT32 screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
60   DECLARE_READ8_MEMBER( detect_r );
61   DECLARE_WRITE8_MEMBER( detect_w );
62   DECLARE_READ8_MEMBER( dskctl_r );
63   DECLARE_WRITE8_MEMBER( dskctl_w );
64   DECLARE_READ8_MEMBER( mcu_r );
65   DECLARE_WRITE8_MEMBER( mcu_w );
66   DECLARE_WRITE8_MEMBER( vram_sw_w );
67   DECLARE_READ16_MEMBER( vram_r );
68   DECLARE_WRITE16_MEMBER( vram_w );
69   SCN2674_DRAW_CHARACTER_MEMBER(display_pixels);
70   DECLARE_FLOPPY_FORMATS( floppy_formats );
6071
6172protected:
6273   // driver_device overrides
r243571r243572
7283   required_device<wd2793_t> m_fdc;
7384   required_device<mc146818_device> m_rtc;
7485   required_device<scn2674_device> m_crtc;
86   required_device<palette_device> m_palette;
87   required_device<gfxdecode_device> m_gfxdecode;
7588   required_shared_ptr<UINT16> m_vram;
7689   dynamic_buffer m_charram;
77   UINT8 m_stat, m_led;
90   UINT8 m_stat, m_led, m_dskctl, m_vram_sw;
7891};
7992
8093
r243571r243572
96109};
97110void pcd_state::machine_start()
98111{
99   machine().device<gfxdecode_device>("gfxdecode")->set_gfx(0, global_alloc(gfx_element(machine().device<palette_device>("palette"), pcd_charlayout, m_charram, 0, 2, 0)));
112   m_gfxdecode->set_gfx(0, global_alloc(gfx_element(machine().device<palette_device>("palette"), pcd_charlayout, m_charram, 0, 1, 0)));
100113}
101114
102115void pcd_state::machine_reset()
103116{
104117   m_stat = 0;
105118   m_led = 0;
119   m_dskctl = 0;
120   m_vram_sw = 1;
106121}
107122
108123READ8_MEMBER( pcd_state::irq_callback )
r243571r243572
121136   m_speaker->level_w(state);
122137}
123138
124READ8_MEMBER( pcd_state::charram_r )
139READ16_MEMBER( pcd_state::vram_r )
125140{
126   return m_charram[offset >> 1];
141   return m_vram[offset];
127142}
128143
129WRITE8_MEMBER( pcd_state::charram_w )
144WRITE16_MEMBER( pcd_state::vram_w )
130145{
131   m_charram[offset >> 1] = data;
146   if(m_vram_sw)
147      COMBINE_DATA(&m_vram[offset]);
148   else if(mem_mask & 0xff)
149   {
150      m_charram[offset & 0x1fff] = data;
151      m_gfxdecode->gfx(0)->mark_dirty(offset/16);
152   }
132153}
133154
134READ16_MEMBER( pcd_state::nmi_io_r )
155WRITE8_MEMBER( pcd_state::vram_sw_w )
135156{
157   m_vram_sw = data & 1;
158}
159
160READ8_MEMBER( pcd_state::nmi_io_r )
161{
136162   if(space.debugger_access())
137163      return 0;
138   logerror("%s: unmapped %s %04x\n", machine().describe_context(), space.name(), offset << 1);
164   logerror("%s: unmapped %s %04x\n", machine().describe_context(), space.name(), offset);
139165   m_stat |= 8;
140166   m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
141167   return 0;
142168}
143169
144WRITE16_MEMBER( pcd_state::nmi_io_w )
170WRITE8_MEMBER( pcd_state::nmi_io_w )
145171{
146172   if(space.debugger_access())
147173      return;
148   logerror("%s: unmapped %s %04x\n", machine().describe_context(), space.name(), offset << 1);
174   logerror("%s: unmapped %s %04x\n", machine().describe_context(), space.name(), offset);
149175   m_stat |= 8;
150176   m_maincpu->set_input_line(INPUT_LINE_NMI, PULSE_LINE);
151177}
r243571r243572
169195
170196WRITE8_MEMBER( pcd_state::stat_w )
171197{
172   m_stat = data;
198   m_stat &= ~data;
173199}
174200
201READ8_MEMBER( pcd_state::detect_r )
202{
203   return 0;
204}
205
206WRITE8_MEMBER( pcd_state::detect_w )
207{
208}
209
210READ8_MEMBER( pcd_state::mcu_r )
211{
212   return 0x20;
213}
214
215WRITE8_MEMBER( pcd_state::mcu_w )
216{
217}
218
219READ8_MEMBER( pcd_state::dskctl_r )
220{
221   return m_dskctl;
222}
223
224WRITE8_MEMBER( pcd_state::dskctl_w )
225{
226   floppy_image_device *floppy0 = m_fdc->subdevice<floppy_connector>("0")->get_device();
227   floppy_image_device *floppy1 = m_fdc->subdevice<floppy_connector>("1")->get_device();
228
229   if((data & 1) && floppy0)
230      m_fdc->set_floppy(floppy0);
231
232   if(floppy0)
233   {
234      floppy0->mon_w(!(data & 4));
235      floppy0->ss_w((data & 8) != 0);
236   }
237   if(floppy1)
238   {
239      floppy1->mon_w(!(data & 4));
240      floppy1->ss_w((data & 8) != 0);
241   }
242   m_dskctl = data;
243}
244
175245READ8_MEMBER( pcd_state::led_r )
176246{
177   return m_led;
247   // DIPs?
248   // 0x01 no mmu
249   // 0x10 enter monitor after post
250   // 0x20 enter monitor before post
251   return 0x01;
178252}
179253
180254WRITE8_MEMBER( pcd_state::led_w )
r243571r243572
185259   m_led = data;
186260}
187261
188UINT32 pcd_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
262SCN2674_DRAW_CHARACTER_MEMBER(pcd_state::display_pixels)
189263{
190   //bitmap.fill(0, cliprect);
191   m_crtc->scn2574_draw(machine(), bitmap, cliprect, m_vram);
192   return 0;
264   if(lg)
265   {
266      UINT16 data = m_vram[address];
267      data = (data >> 8) | (data << 8);
268      for(int i = 0; i < 16; i++)
269         bitmap.pix32(y, x + i) = m_palette->pen((data & (1 << (16 - i))) ? 1 : 0);
270   }
271   else
272   {
273      UINT8 data = m_charram[(m_vram[address] & 0xff) * 16 + linecount];
274      for(int i = 0; i < 8; i++)
275         bitmap.pix32(y, x + i) = m_palette->pen((data & (1 << (8 - i))) ? 1 : 0);
276   }
193277}
194278
195279//**************************************************************************
r243571r243572
198282
199283static ADDRESS_MAP_START( pcd_map, AS_PROGRAM, 16, pcd_state )
200284   AM_RANGE(0x00000, 0x3ffff) AM_RAM // fixed 256k for now
201   AM_RANGE(0xf0000, 0xf7fff) AM_RAM AM_SHARE("vram")
202   //AM_RANGE(0xf7000, 0xfbfff) AM_READWRITE8(charram_r, charram_w, 0xffff)
285   AM_RANGE(0xf0000, 0xf7fff) AM_READWRITE(vram_r, vram_w) AM_SHARE("vram")
203286   AM_RANGE(0xfc000, 0xfffff) AM_ROM AM_REGION("bios", 0)
204   AM_RANGE(0x00000, 0xfffff) AM_READWRITE(nmi_io_r, nmi_io_w)
287   AM_RANGE(0x00000, 0xfffff) AM_READWRITE8(nmi_io_r, nmi_io_w, 0xffff)
205288ADDRESS_MAP_END
206289
207290static ADDRESS_MAP_START( pcd_io, AS_IO, 16, pcd_state )
208291   ADDRESS_MAP_UNMAP_HIGH
292   AM_RANGE(0x0000, 0xefff) AM_READWRITE8(nmi_io_r, nmi_io_w, 0xffff)
209293   AM_RANGE(0xf000, 0xf7ff) AM_RAM AM_SHARE("nvram")
210294   AM_RANGE(0xf800, 0xf801) AM_DEVREADWRITE8("pic1", pic8259_device, read, write, 0xffff)
211295   AM_RANGE(0xf820, 0xf821) AM_DEVREADWRITE8("pic2", pic8259_device, read, write, 0xffff)
212296   AM_RANGE(0xf840, 0xf841) AM_READWRITE8(stat_r, stat_w, 0x00ff)
213297   AM_RANGE(0xf840, 0xf841) AM_READWRITE8(led_r, led_w, 0xff00)
214298   AM_RANGE(0xf880, 0xf8bf) AM_READWRITE8(rtc_r, rtc_w, 0xffff)
215   AM_RANGE(0xf900, 0xf907) AM_DEVREADWRITE8("fdc", wd2793_t, read, write, 0xffff)
299   AM_RANGE(0xf900, 0xf903) AM_DEVREADWRITE8("fdc", wd2793_t, read, write, 0xffff)
300   AM_RANGE(0xf904, 0xf905) AM_READWRITE8(dskctl_r, dskctl_w, 0x00ff)
216301   //AM_RANGE(0xf940, 0xf943) scsi
302   AM_RANGE(0xf980, 0xf98f) AM_DEVWRITE8("crtc", scn2674_device, write, 0x00ff)
303   AM_RANGE(0xf980, 0xf98f) AM_DEVREAD8("crtc", scn2674_device, read, 0xff00)
304   AM_RANGE(0xf9a0, 0xf9a1) AM_WRITE8(vram_sw_w, 0x00ff)
305   AM_RANGE(0xf9b0, 0xf9b3) AM_READWRITE8(mcu_r, mcu_w, 0x00ff) // 8741 comms
217306   AM_RANGE(0xf9c0, 0xf9c3) AM_DEVREADWRITE8("usart1",mc2661_device,read,write,0xffff)  // UARTs
218307   AM_RANGE(0xf9d0, 0xf9d3) AM_DEVREADWRITE8("usart2",mc2661_device,read,write,0xffff)
219308   AM_RANGE(0xf9e0, 0xf9e3) AM_DEVREADWRITE8("usart3",mc2661_device,read,write,0xffff)
220   AM_RANGE(0xf980, 0xf987) AM_DEVWRITE8("crtc", scn2674_device, mpu4_vid_scn2674_w, 0x00ff)
221   AM_RANGE(0xf980, 0xf987) AM_DEVREAD8("crtc", scn2674_device, mpu4_vid_scn2674_r, 0xff00)
222309//   AM_RANGE(0xfa00, 0xfa7f) // pcs4-n (peripheral chip select)
223   AM_RANGE(0x0000, 0xffff) AM_READWRITE(nmi_io_r, nmi_io_w)
310   AM_RANGE(0xfb00, 0xfb01) AM_READWRITE8(detect_r, detect_w, 0xff00) // expansion card detection?
311   AM_RANGE(0xfb00, 0xffff) AM_READWRITE8(nmi_io_r, nmi_io_w, 0xffff)
224312ADDRESS_MAP_END
225313
226314
r243571r243572
231319static SLOT_INTERFACE_START( pcd_floppies )
232320   SLOT_INTERFACE("55f", TEAC_FD_55F)
233321   SLOT_INTERFACE("55g", TEAC_FD_55G)
322   SLOT_INTERFACE("525dsqd", FLOPPY_525_QD) // the devices above cause a crash in floppy_image_format_t::generate_track_from_levels
234323SLOT_INTERFACE_END
235324
325FLOPPY_FORMATS_MEMBER( pcd_state::floppy_formats )
326   FLOPPY_PC_FORMAT
327FLOPPY_FORMATS_END
328
236329static MACHINE_CONFIG_START( pcd, pcd_state )
237330   MCFG_CPU_ADD("maincpu", I80186, XTAL_16MHz)
238331   MCFG_CPU_PROGRAM_MAP(pcd_map)
r243571r243572
258351   MCFG_OMTI5100_ADD("sasi")
259352
260353   // floppy disk controller
261   MCFG_WD2793x_ADD("fdc", XTAL_16MHz/8)
354   MCFG_WD2793x_ADD("fdc", XTAL_16MHz/8/2)
262355   MCFG_WD_FDC_INTRQ_CALLBACK(DEVWRITELINE("pic1", pic8259_device, ir6_w))
263356   MCFG_WD_FDC_DRQ_CALLBACK(DEVWRITELINE("maincpu", i80186_cpu_device, drq1_w))
264357
265358   // floppy drives
266   MCFG_FLOPPY_DRIVE_ADD("fdc:0", pcd_floppies, "55g", floppy_image_device::default_floppy_formats)
267   MCFG_FLOPPY_DRIVE_ADD("fdc:1", pcd_floppies, "55g", floppy_image_device::default_floppy_formats)
359   MCFG_FLOPPY_DRIVE_ADD("fdc:0", pcd_floppies, "525dsqd", pcd_state::floppy_formats)
360   MCFG_FLOPPY_DRIVE_ADD("fdc:1", pcd_floppies, "525dsqd", pcd_state::floppy_formats)
268361
269362   // usart
270363   MCFG_DEVICE_ADD("usart1", MC2661, XTAL_4_9152MHz)
r243571r243572
284377   MCFG_SCREEN_SIZE(640, 350)
285378   MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 349)
286379   MCFG_SCREEN_REFRESH_RATE(50)
287   MCFG_SCREEN_UPDATE_DRIVER(pcd_state, screen_update)
380   MCFG_SCREEN_UPDATE_DEVICE("crtc", scn2674_device, screen_update)
288381
289382   MCFG_GFXDECODE_ADD("gfxdecode", "palette", empty)
290383   MCFG_PALETTE_ADD_BLACK_AND_WHITE("palette")
291384
292385   MCFG_SCN2674_VIDEO_ADD("crtc", 0, NULL);
293   MCFG_SCN2674_GFXDECODE("gfxdecode")
294   MCFG_SCN2674_PALETTE("palette")
386   MCFG_SCN2674_TEXT_CHARACTER_WIDTH(8)
387   MCFG_SCN2674_GFX_CHARACTER_WIDTH(16)
388   MCFG_SCN2674_DRAW_CHARACTER_CALLBACK_OWNER(pcd_state, display_pixels)
295389
296390   // rtc
297391   MCFG_MC146818_ADD("rtc", XTAL_32_768kHz)
r243571r243572
309403   ROM_LOAD16_BYTE("s26361-d359.d43", 0x0000, 0x2000, CRC(e03db2ec) SHA1(fcae8b0c9e7543706817b0a53872826633361fda))
310404   ROM_FILL(0xb64, 1, 0xe2)  // post expects 0xd0 fdc command to be instant, give it a delay
311405   ROM_FILL(0xb65, 1, 0xfe)
312   ROM_FILL(0x3ffe, 1, 0xb4)  // fix csum
313   ROM_FILL(0x3fff, 1, 0x22)
406   ROM_FILL(0xb35, 1, 0x90)  // fdc delay_register_commit is too long
407   ROM_FILL(0xb36, 1, 0x90)
408   ROM_FILL(0x3ffe, 1, 0xf4)  // fix csum
409   ROM_FILL(0x3fff, 1, 0x3d)
314410
315411   // gfx card (scn2674 with 8741), to be moved
316412   ROM_REGION(0x400, "graphics", 0)
trunk/src/mess/mess.mak
r243571r243572
327327VIDEOS += V9938
328328VIDEOS += VIC4567
329329#VIDEOS += VOODOO
330VIDEOS += SCN2674
330331
331332#-------------------------------------------------
332333# specify available machine cores
r243571r243572
940941   $(MAME_VIDEO)/vectrex.o     \
941942   $(MAME_DRIVERS)/cps1.o      \
942943   $(MAME_VIDEO)/cps1.o        \
943   $(MAME_VIDEO)/scn2674.o     \
944944
945945
946946#-------------------------------------------------


Previous 199869 Revisions Next


© 1997-2024 The MAME Team