Previous 199869 Revisions Next

r32002 Monday 8th September, 2014 at 19:40:45 UTC by Fabio Priuli
some more antic refactorization. nw.
[src/mame/includes]atari.h
[src/mame/video]antic.c atari.c

trunk/src/mame/includes/atari.h
r32001r32002
2626      m_gtia(*this, "gtia"),
2727      tv_artifacts(0) { }
2828
29   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
30
2931   virtual void video_start();
3032   UINT32 screen_update_atari(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
3133
r32001r32002
4446   POKEY_KEYBOARD_CB_MEMBER(a800_keyboard);
4547
4648private:
49   static const device_timer_id TIMER_CYCLE_STEAL = 0;
50   static const device_timer_id TIMER_ISSUE_DLI = 1;
51   static const device_timer_id TIMER_LINE_REND = 2;
52   static const device_timer_id TIMER_LINE_DONE = 3;
53
4754   required_device<gtia_device> m_gtia;
4855   UINT32 tv_artifacts;
4956   void prio_init();
trunk/src/mame/video/atari.c
r32001r32002
3434   antic_vstart(machine());
3535}
3636
37/************************************************************************
38 * atari_vh_screenrefresh
39 * Refresh screen bitmap.
40 * Note: Actual drawing is done scanline wise during atari_interrupt
41 ************************************************************************/
42UINT32 atari_common_state::screen_update_atari(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
43{
44   UINT32 new_tv_artifacts = screen.ioport("artifacts")->read_safe(0);
45   copybitmap(bitmap, *antic.bitmap, 0, 0, 0, 0, cliprect);
4637
47   if (tv_artifacts != new_tv_artifacts)
48      tv_artifacts = new_tv_artifacts;
49
50   return 0;
51}
52
53void atari_common_state::artifacts_gfx(UINT8 *src, UINT8 *dst, int width)
54{
55   UINT8 n, bits = 0;
56   UINT8 b = m_gtia->get_w_colbk() & 0xf0;
57   UINT8 c = m_gtia->get_w_colpf1() & 0x0f;
58   UINT8 atari_A = ((b + 0x30) & 0xf0) + c;
59   UINT8 atari_B = ((b + 0x70) & 0xf0) + c;
60   UINT8 atari_C = b + c;
61   UINT8 atari_D = m_gtia->get_w_colbk();
62   UINT16 *color_lookup = m_gtia->get_color_lookup();
63
64   for (int x = 0; x < width * 4; x++)
65   {
66      n = *src++;
67      bits <<= 2;
68      switch( n )
69      {
70      case G00:
71         break;
72      case G01:
73         bits |= 1;
74         break;
75      case G10:
76         bits |= 2;
77         break;
78      case G11:
79         bits |= 3;
80         break;
81      default:
82         *dst++ = color_lookup[n];
83         *dst++ = color_lookup[n];
84         continue;
85      }
86      switch ((bits >> 1) & 7)
87      {
88      case 0: /* 0 0 0 */
89      case 1: /* 0 0 1 */
90      case 4: /* 1 0 0 */
91         *dst++ = atari_D;
92         break;
93      case 3: /* 0 1 1 */
94      case 6: /* 1 1 0 */
95      case 7: /* 1 1 1 */
96         *dst++ = atari_C;
97         break;
98      case 2: /* 0 1 0 */
99         *dst++ = atari_B;
100         break;
101      case 5: /* 1 0 1 */
102         *dst++ = atari_A;
103         break;
104      }
105      switch (bits & 7)
106      {
107      case 0: /* 0 0 0 */
108      case 1: /* 0 0 1 */
109      case 4: /* 1 0 0 */
110         *dst++ = atari_D;
111         break;
112      case 3: /* 0 1 1 */
113      case 6: /* 1 1 0 */
114      case 7: /* 1 1 1 */
115         *dst++ = atari_C;
116         break;
117      case 2: /* 0 1 0 */
118         *dst++ = atari_A;
119         break;
120      case 5: /* 1 0 1 */
121         *dst++ = atari_B;
122         break;
123      }
124   }
125}
126
127void atari_common_state::artifacts_txt(UINT8 * src, UINT8 * dst, int width)
128{
129   UINT8 n, bits = 0;
130   UINT8 b = m_gtia->get_w_colpf2() & 0xf0;
131   UINT8 c = m_gtia->get_w_colpf1() & 0x0f;
132   UINT8 atari_A = ((b+0x30)&0xf0)+c;
133   UINT8 atari_B = ((b+0x70)&0xf0)+c;
134   UINT8 atari_C = b+c;
135   UINT8 atari_D = m_gtia->get_w_colpf2();
136   UINT16 *color_lookup = m_gtia->get_color_lookup();
137
138   for (int x = 0; x < width * 4; x++)
139   {
140      n = *src++;
141      bits <<= 2;
142      switch( n )
143      {
144      case T00:
145         break;
146      case T01:
147         bits |= 1;
148         break;
149      case T10:
150         bits |= 2;
151         break;
152      case T11:
153         bits |= 3;
154         break;
155      default:
156         *dst++ = color_lookup[n];
157         *dst++ = color_lookup[n];
158         continue;
159      }
160      switch( (bits >> 1) & 7 )
161      {
162      case 0: /* 0 0 0 */
163      case 1: /* 0 0 1 */
164      case 4: /* 1 0 0 */
165         *dst++ = atari_D;
166         break;
167      case 3: /* 0 1 1 */
168      case 6: /* 1 1 0 */
169      case 7: /* 1 1 1 */
170         *dst++ = atari_C;
171         break;
172      case 2: /* 0 1 0 */
173         *dst++ = atari_A;
174         break;
175      case 5: /* 1 0 1 */
176         *dst++ = atari_B;
177         break;
178      }
179      switch( bits & 7 )
180      {
181      case 0:/* 0 0 0 */
182      case 1:/* 0 0 1 */
183      case 4:/* 1 0 0 */
184         *dst++ = atari_D;
185         break;
186      case 3: /* 0 1 1 */
187      case 6: /* 1 1 0 */
188      case 7: /* 1 1 1 */
189         *dst++ = atari_C;
190         break;
191      case 2: /* 0 1 0 */
192         *dst++ = atari_B;
193         break;
194      case 5: /* 1 0 1 */
195         *dst++ = atari_A;
196         break;
197      }
198   }
199}
200
201
202void atari_common_state::antic_linerefresh()
203{
204   int x, y;
205   UINT8 *src;
206   UINT32 *dst;
207   UINT32 scanline[4 + (HCHARS * 2) + 4];
208   UINT16 *color_lookup = m_gtia->get_color_lookup();
209
210   /* increment the scanline */
211   if( ++antic.scanline == machine().first_screen()->height() )
212   {
213      /* and return to the top if the frame was complete */
214      antic.scanline = 0;
215      antic.modelines = 0;
216      /* count frames gone since last write to hitclr */
217      m_gtia->count_hitclr_frames();
218   }
219
220   if( antic.scanline < MIN_Y || antic.scanline > MAX_Y )
221      return;
222
223   y = antic.scanline - MIN_Y;
224   src = &antic.cclock[PMOFFSET - antic.hscrol_old + 12];
225   dst = scanline;
226
227   if( tv_artifacts )
228   {
229      if( (antic.cmd & 0x0f) == 2 || (antic.cmd & 0x0f) == 3 )
230      {
231         artifacts_txt(src, (UINT8*)(dst + 3), HCHARS);
232         return;
233      }
234      else
235      if( (antic.cmd & 0x0f) == 15 )
236      {
237         artifacts_gfx(src, (UINT8*)(dst + 3), HCHARS);
238         return;
239      }
240   }
241   dst[0] = color_lookup[PBK] | color_lookup[PBK] << 16;
242   dst[1] = color_lookup[PBK] | color_lookup[PBK] << 16;
243   dst[2] = color_lookup[PBK] | color_lookup[PBK] << 16;
244   if ( (antic.cmd & ANTIC_HSCR) == 0  || (antic.pfwidth == 48) || (antic.pfwidth == 32))
245   {
246      /* no hscroll */
247      dst[3] = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
248      src += 2;
249      dst += 4;
250      for( x = 1; x < HCHARS-1; x++ )
251      {
252         *dst++ = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
253         *dst++ = color_lookup[src[BYTE_XOR_LE(2)]] | color_lookup[src[BYTE_XOR_LE(3)]] << 16;
254         src += 4;
255      }
256      dst[0] = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
257   }
258   else
259   {
260      /* if hscroll is enabled, more data are fetched by ANTIC, but it still renders playfield
261         of width defined by pfwidth. */
262      switch( antic.pfwidth )
263      {
264         case 0:
265            {
266               dst[3] = color_lookup[PBK] | color_lookup[PBK] << 16;
267               dst += 4;
268               for ( x = 1; x < HCHARS-1; x++ )
269               {
270                  *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
271                  *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
272               }
273               dst[0] = color_lookup[PBK] | color_lookup[PBK] << 16;
274            }
275            break;
276         /* support for narrow playfield (32) with horizontal scrolling should be added here */
277         case 40:
278            {
279               dst[3] = color_lookup[PBK] | color_lookup[PBK] << 16;
280               dst += 4;
281               for ( x = 1; x < HCHARS-2; x++ )
282               {
283                  if ( x == 1 )
284                  {
285                     *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
286                  }
287                  else
288                  {
289                     *dst++ = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
290                  }
291                  *dst++ = color_lookup[src[BYTE_XOR_LE(2)]] | color_lookup[src[BYTE_XOR_LE(3)]] << 16;
292                  src += 4;
293               }
294               for ( ; x < HCHARS-1; x++ )
295               {
296                  *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
297                  *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
298               }
299               dst[0] = color_lookup[PBK] | color_lookup[PBK] << 16;
300            }
301            break;
302      }
303   }
304   dst[1] = color_lookup[PBK] | color_lookup[PBK] << 16;
305   dst[2] = color_lookup[PBK] | color_lookup[PBK] << 16;
306   dst[3] = color_lookup[PBK] | color_lookup[PBK] << 16;
307
308   draw_scanline8(*antic.bitmap, 12, y, MIN(antic.bitmap->width() - 12, sizeof(scanline)), (const UINT8 *) scanline, NULL);
309}
310
311int atari_common_state::cycle()
312{
313   return machine().first_screen()->hpos() * CYCLES_PER_LINE / machine().first_screen()->width();
314}
315
316void atari_common_state::after(int cycles, timer_expired_delegate function)
317{
318   attotime duration = machine().first_screen()->scan_period() * cycles / CYCLES_PER_LINE;
319   //(void)funcname;
320   //LOG(("           after %3d (%5.1f us) %s\n", cycles, duration.as_double() * 1.0e6, funcname));
321   machine().scheduler().timer_set(duration, function);
322}
323
324TIMER_CALLBACK_MEMBER( atari_common_state::antic_issue_dli )
325{
326   if( antic.w.nmien & DLI_NMI )
327   {
328      LOG(("           @cycle #%3d issue DLI\n", cycle()));
329      antic.r.nmist |= DLI_NMI;
330      machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
331   }
332   else
333   {
334      LOG(("           @cycle #%3d DLI not enabled\n", cycle()));
335   }
336}
337
338
33938/*****************************************************************************
34039 *
341 *  Antic Line Done
342 *
343 *****************************************************************************/
344TIMER_CALLBACK_MEMBER( atari_common_state::antic_line_done )
345{
346   LOG(("           @cycle #%3d antic_line_done\n", cycle()));
347   if( antic.w.wsync )
348   {
349      LOG(("           @cycle #%3d release WSYNC\n", cycle()));
350      /* release the CPU if it was actually waiting for HSYNC */
351      machine().scheduler().trigger(TRIGGER_HSYNC);
352      /* and turn off the 'wait for hsync' flag */
353      antic.w.wsync = 0;
354   }
355   LOG(("           @cycle #%3d release CPU\n", cycle()));
356   /* release the CPU (held for emulating cycles stolen by ANTIC DMA) */
357   machine().scheduler().trigger(TRIGGER_STEAL);
358
359   /* refresh the display (translate color clocks to pixels) */
360   antic_linerefresh();
361}
362
363/*****************************************************************************
364 *
365 *  Antic Steal Cycles
366 *  This is called once per scanline by a interrupt issued in the
367 *  atari_scanline_render function. Set a new timer for the HSYNC
368 *  position and release the CPU; but hold it again immediately until
369 *  TRIGGER_HSYNC if WSYNC (D01A) was accessed
370 *
371 *****************************************************************************/
372TIMER_CALLBACK_MEMBER( atari_common_state::antic_steal_cycles )
373{
374   LOG(("           @cycle #%3d steal %d cycles\n", cycle(), antic.steal_cycles));
375   after(antic.steal_cycles, timer_expired_delegate(FUNC(atari_common_state::antic_line_done),this));
376   antic.steal_cycles = 0;
377   machine().device("maincpu")->execute().spin_until_trigger(TRIGGER_STEAL );
378}
379
380
381/*****************************************************************************
382 *
383 *  Antic Scan Line Render
384 *  Render the scanline to the scrbitmap buffer.
385 *  Also transport player/missile data to the grafp and grafm registers
386 *  of the GTIA if enabled (DMA_PLAYER or DMA_MISSILE)
387 *
388 *****************************************************************************/
389TIMER_CALLBACK_MEMBER( atari_common_state::antic_scanline_render )
390{
391   address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
392
393   LOG(("           @cycle #%3d render mode $%X lines to go #%d\n", cycle(), (antic.cmd & 0x0f), antic.modelines));
394
395   antic_render(space, m_antic_render1, m_antic_render2, m_antic_render3);
396
397   /* if player/missile graphics is enabled */
398   if( antic.scanline < 256 && (antic.w.dmactl & (DMA_PLAYER|DMA_MISSILE)) )
399   {
400      /* new player/missile graphics data for every scanline ? */
401      if( antic.w.dmactl & DMA_PM_DBLLINE )
402      {
403         /* transport missile data to GTIA ? */
404         if( antic.w.dmactl & DMA_MISSILE )
405         {
406            antic.steal_cycles += 1;
407            m_gtia->write(space, 0x11, RDPMGFXD(space, 3*256));
408         }
409         /* transport player data to GTIA ? */
410         if( antic.w.dmactl & DMA_PLAYER )
411         {
412            antic.steal_cycles += 4;
413            m_gtia->write(space, 0x0d, RDPMGFXD(space, 4*256));
414            m_gtia->write(space, 0x0e, RDPMGFXD(space, 5*256));
415            m_gtia->write(space, 0x0f, RDPMGFXD(space, 6*256));
416            m_gtia->write(space, 0x10, RDPMGFXD(space, 7*256));
417         }
418      }
419      else
420      {
421         /* transport missile data to GTIA ? */
422         if( antic.w.dmactl & DMA_MISSILE )
423         {
424            if( (antic.scanline & 1) == 0 )      /* even line ? */
425               antic.steal_cycles += 1;
426            m_gtia->write(space, 0x11, RDPMGFXS(space, 3*128));
427         }
428         /* transport player data to GTIA ? */
429         if( antic.w.dmactl & DMA_PLAYER )
430         {
431            if( (antic.scanline & 1) == 0 )      /* even line ? */
432               antic.steal_cycles += 4;
433            m_gtia->write(space, 0x0d, RDPMGFXS(space, 4*128));
434            m_gtia->write(space, 0x0e, RDPMGFXS(space, 5*128));
435            m_gtia->write(space, 0x0f, RDPMGFXS(space, 6*128));
436            m_gtia->write(space, 0x10, RDPMGFXS(space, 7*128));
437         }
438      }
439   }
440
441   if (antic.scanline >= VBL_END && antic.scanline < 256)
442      m_gtia->render((UINT8 *)antic.pmbits + PMOFFSET, (UINT8 *)antic.cclock + PMOFFSET - antic.hscrol_old, (UINT8 *)antic.prio_table[m_gtia->get_w_prior() & 0x3f], (UINT8 *)&antic.pmbits);
443
444   antic.steal_cycles += CYCLES_REFRESH;
445   LOG(("           run CPU for %d cycles\n", CYCLES_HSYNC - CYCLES_HSTART - antic.steal_cycles));
446   after(CYCLES_HSYNC - CYCLES_HSTART - antic.steal_cycles, timer_expired_delegate(FUNC(atari_common_state::antic_steal_cycles),this));
447}
448
449
450
451void atari_common_state::LMS(int new_cmd)
452{
453   /**************************************************************
454    * If the LMS bit (load memory scan) of the current display
455    * list command is set, load the video source address from the
456    * following two bytes and split it up into video page/offset.
457    * Steal two more cycles from the CPU for fetching the address.
458    **************************************************************/
459   if( new_cmd & ANTIC_LMS )
460   {
461      address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
462      int addr = RDANTIC(space);
463      antic.doffs = (antic.doffs + 1) & DOFFS;
464      addr += 256 * RDANTIC(space);
465      antic.doffs = (antic.doffs + 1) & DOFFS;
466      antic.vpage = addr & VPAGE;
467      antic.voffs = addr & VOFFS;
468      LOG(("           LMS $%04x\n", addr));
469      /* steal two more clock cycles from the cpu */
470      antic.steal_cycles += 2;
471   }
472}
473
474/*****************************************************************************
475 *
476 *  Antic Scan Line DMA
477 *  This is called once per scanline from Atari Interrupt
478 *  If the ANTIC DMA is active (DMA_ANTIC) and the scanline not inside
479 *  the VBL range (VBL_START - TOTAL_LINES or 0 - VBL_END)
480 *  check if all mode lines of the previous ANTIC command were done and
481 *  if so, read a new command and set up the renderer function
482 *
483 *****************************************************************************/
484void atari_common_state::antic_scanline_dma(int param)
485{
486   address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
487   LOG(("           @cycle #%3d DMA fetch\n", cycle()));
488   if (antic.scanline == VBL_END)
489      antic.r.nmist &= ~VBL_NMI;
490   if( antic.w.dmactl & DMA_ANTIC )
491   {
492      if( antic.scanline >= VBL_END && antic.scanline < VBL_START )
493      {
494         if( antic.modelines <= 0 )
495         {
496            m_antic_render1 = 0;
497            m_antic_render3 = antic.w.dmactl & 3;
498            UINT8 vscrol_subtract = 0;
499            UINT8 new_cmd;
500
501            new_cmd = RDANTIC(space);
502            antic.doffs = (antic.doffs + 1) & DOFFS;
503            /* steal at one clock cycle from the CPU for fetching the command */
504            antic.steal_cycles += 1;
505            LOG(("           ANTIC CMD $%02x\n", new_cmd));
506            /* command 1 .. 15 ? */
507            if (new_cmd & ANTIC_MODE)
508            {
509               antic.w.chbasl = 0;
510               /* vertical scroll mode changed ? */
511               if( (antic.cmd ^ new_cmd) & ANTIC_VSCR )
512               {
513                  /* vertical scroll activate now ? */
514                  if( new_cmd & ANTIC_VSCR )
515                  {
516                     antic.vscrol_old =
517                     vscrol_subtract =
518                     antic.w.chbasl = antic.w.vscrol;
519                  }
520                  else
521                  {
522                     vscrol_subtract = ~antic.vscrol_old;
523                  }
524               }
525               /* does this command have horizontal scroll enabled ? */
526               if( new_cmd & ANTIC_HSCR )
527               {
528                  m_antic_render1 = 1;
529                  antic.hscrol_old = antic.w.hscrol;
530               }
531               else
532               {
533                  antic.hscrol_old = 0;
534               }
535            }
536            /* Set the ANTIC mode renderer function */
537            m_antic_render2 = new_cmd & ANTIC_MODE;
538
539            switch( new_cmd & ANTIC_MODE )
540            {
541            case 0x00:
542               /* generate 1 .. 8 empty lines */
543               antic.modelines = ((new_cmd >> 4) & 7) + 1;
544               /* did the last ANTIC command have vertical scroll enabled ? */
545               if( antic.cmd & ANTIC_VSCR )
546               {
547                  /* yes, generate vscrol_old additional empty lines */
548                  antic.modelines += antic.vscrol_old;
549               }
550               /* leave only bit 7 (DLI) set in ANTIC command */
551               new_cmd &= ANTIC_DLI;
552               break;
553            case 0x01:
554               /* ANTIC "jump" with DLI: issue interrupt immediately */
555               if( new_cmd & ANTIC_DLI )
556               {
557                  /* remove the DLI bit */
558                  new_cmd &= ~ANTIC_DLI;
559                  after(CYCLES_DLI_NMI, timer_expired_delegate(FUNC(atari_common_state::antic_issue_dli),this));
560               }
561               /* load memory scan bit set ? */
562               if( new_cmd & ANTIC_LMS )
563               {
564                  int addr = RDANTIC(space);
565                  antic.doffs = (antic.doffs + 1) & DOFFS;
566                  addr += 256 * RDANTIC(space);
567                  antic.dpage = addr & DPAGE;
568                  antic.doffs = addr & DOFFS;
569                  /* produce empty scanlines until vblank start */
570                  antic.modelines = VBL_START + 1 - antic.scanline;
571                  if( antic.modelines < 0 )
572                     antic.modelines = machine().first_screen()->height() - antic.scanline;
573                  LOG(("           JVB $%04x\n", antic.dpage|antic.doffs));
574               }
575               else
576               {
577                  int addr = RDANTIC(space);
578                  antic.doffs = (antic.doffs + 1) & DOFFS;
579                  addr += 256 * RDANTIC(space);
580                  antic.dpage = addr & DPAGE;
581                  antic.doffs = addr & DOFFS;
582                  /* produce a single empty scanline */
583                  antic.modelines = 1;
584                  LOG(("           JMP $%04x\n", antic.dpage|antic.doffs));
585               }
586               break;
587            case 0x02:
588               LMS(new_cmd);
589               antic.chbase = (antic.w.chbash & 0xfc) << 8;
590               antic.modelines = 8 - (vscrol_subtract & 7);
591               if( antic.w.chactl & 4 )    /* decrement chbasl? */
592                  antic.w.chbasl = antic.modelines - 1;
593               break;
594            case 0x03:
595               LMS(new_cmd);
596               antic.chbase = (antic.w.chbash & 0xfc) << 8;
597               antic.modelines = 10 - (vscrol_subtract & 9);
598               if( antic.w.chactl & 4 )    /* decrement chbasl? */
599                  antic.w.chbasl = antic.modelines - 1;
600               break;
601            case 0x04:
602               LMS(new_cmd);
603               antic.chbase = (antic.w.chbash & 0xfc) << 8;
604               antic.modelines = 8 - (vscrol_subtract & 7);
605               if( antic.w.chactl & 4 )    /* decrement chbasl? */
606                  antic.w.chbasl = antic.modelines - 1;
607               break;
608            case 0x05:
609               LMS(new_cmd);
610               antic.chbase = (antic.w.chbash & 0xfc) << 8;
611               antic.modelines = 16 - (vscrol_subtract & 15);
612               if( antic.w.chactl & 4 )    /* decrement chbasl? */
613                  antic.w.chbasl = antic.modelines - 1;
614               break;
615            case 0x06:
616               LMS(new_cmd);
617               antic.chbase = (antic.w.chbash & 0xfe) << 8;
618               antic.modelines = 8 - (vscrol_subtract & 7);
619               if( antic.w.chactl & 4 )    /* decrement chbasl? */
620                  antic.w.chbasl = antic.modelines - 1;
621               break;
622            case 0x07:
623               LMS(new_cmd);
624               antic.chbase = (antic.w.chbash & 0xfe) << 8;
625               antic.modelines = 16 - (vscrol_subtract & 15);
626               if( antic.w.chactl & 4 )    /* decrement chbasl? */
627                  antic.w.chbasl = antic.modelines - 1;
628               break;
629            case 0x08:
630               LMS(new_cmd);
631               antic.modelines = 8 - (vscrol_subtract & 7);
632               break;
633            case 0x09:
634               LMS(new_cmd);
635               antic.modelines = 4 - (vscrol_subtract & 3);
636               break;
637            case 0x0a:
638               LMS(new_cmd);
639               antic.modelines = 4 - (vscrol_subtract & 3);
640               break;
641            case 0x0b:
642               LMS(new_cmd);
643               antic.modelines = 2 - (vscrol_subtract & 1);
644               break;
645            case 0x0c:
646               LMS(new_cmd);
647               antic.modelines = 1;
648               break;
649            case 0x0d:
650               LMS(new_cmd);
651               antic.modelines = 2 - (vscrol_subtract & 1);
652               break;
653            case 0x0e:
654               LMS(new_cmd);
655               antic.modelines = 1;
656               break;
657            case 0x0f:
658               LMS(new_cmd);
659               /* bits 6+7 of the priority select register determine */
660               /* if newer GTIA or plain graphics modes are used */
661               switch (m_gtia->get_w_prior() >> 6)
662               {
663                  case 0: break;
664                  case 1: m_antic_render2 = 16;  break;
665                  case 2: m_antic_render2 = 17;  break;
666                  case 3: m_antic_render2 = 18;  break;
667               }
668               antic.modelines = 1;
669               break;
670            }
671            /* set new (current) antic command */
672            antic.cmd = new_cmd;
673         }
674      }
675      else
676      {
677         LOG(("           out of visible range\n"));
678         antic.cmd = 0x00;
679         m_antic_render1 = 0;
680         m_antic_render2 = 0;
681         m_antic_render3 = 0;
682      }
683   }
684   else
685   {
686      LOG(("           DMA is off\n"));
687      antic.cmd = 0x00;
688      m_antic_render1 = 0;
689      m_antic_render2 = 0;
690      m_antic_render3 = 0;
691   }
692
693   antic.r.nmist &= ~DLI_NMI;
694   if( antic.modelines == 1 && (antic.cmd & antic.w.nmien & DLI_NMI) )
695      after(CYCLES_DLI_NMI, timer_expired_delegate(FUNC(atari_common_state::antic_issue_dli),this));
696
697   after(CYCLES_HSTART, timer_expired_delegate(FUNC(atari_common_state::antic_scanline_render),this));
698}
699
700/*****************************************************************************
701 *
70240 *  Generic Atari Interrupt Dispatcher
70341 *  This is called once per scanline and handles:
70442 *  vertical blank interrupt
trunk/src/mame/video/antic.c
r32001r32002
15081508   REP48(GTIA3);
15091509   POST_GFX(48);
15101510}
1511
1512/************************************************************************
1513 * atari_vh_screenrefresh
1514 * Refresh screen bitmap.
1515 * Note: Actual drawing is done scanline wise during atari_interrupt
1516 ************************************************************************/
1517UINT32 atari_common_state::screen_update_atari(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
1518{
1519   UINT32 new_tv_artifacts = screen.ioport("artifacts")->read_safe(0);
1520   copybitmap(bitmap, *antic.bitmap, 0, 0, 0, 0, cliprect);
1521   
1522   if (tv_artifacts != new_tv_artifacts)
1523      tv_artifacts = new_tv_artifacts;
1524   
1525   return 0;
1526}
1527
1528void atari_common_state::artifacts_gfx(UINT8 *src, UINT8 *dst, int width)
1529{
1530   UINT8 n, bits = 0;
1531   UINT8 b = m_gtia->get_w_colbk() & 0xf0;
1532   UINT8 c = m_gtia->get_w_colpf1() & 0x0f;
1533   UINT8 atari_A = ((b + 0x30) & 0xf0) + c;
1534   UINT8 atari_B = ((b + 0x70) & 0xf0) + c;
1535   UINT8 atari_C = b + c;
1536   UINT8 atari_D = m_gtia->get_w_colbk();
1537   UINT16 *color_lookup = m_gtia->get_color_lookup();
1538   
1539   for (int x = 0; x < width * 4; x++)
1540   {
1541      n = *src++;
1542      bits <<= 2;
1543      switch( n )
1544      {
1545         case G00:
1546            break;
1547         case G01:
1548            bits |= 1;
1549            break;
1550         case G10:
1551            bits |= 2;
1552            break;
1553         case G11:
1554            bits |= 3;
1555            break;
1556         default:
1557            *dst++ = color_lookup[n];
1558            *dst++ = color_lookup[n];
1559            continue;
1560      }
1561      switch ((bits >> 1) & 7)
1562      {
1563         case 0: /* 0 0 0 */
1564         case 1: /* 0 0 1 */
1565         case 4: /* 1 0 0 */
1566            *dst++ = atari_D;
1567            break;
1568         case 3: /* 0 1 1 */
1569         case 6: /* 1 1 0 */
1570         case 7: /* 1 1 1 */
1571            *dst++ = atari_C;
1572            break;
1573         case 2: /* 0 1 0 */
1574            *dst++ = atari_B;
1575            break;
1576         case 5: /* 1 0 1 */
1577            *dst++ = atari_A;
1578            break;
1579      }
1580      switch (bits & 7)
1581      {
1582         case 0: /* 0 0 0 */
1583         case 1: /* 0 0 1 */
1584         case 4: /* 1 0 0 */
1585            *dst++ = atari_D;
1586            break;
1587         case 3: /* 0 1 1 */
1588         case 6: /* 1 1 0 */
1589         case 7: /* 1 1 1 */
1590            *dst++ = atari_C;
1591            break;
1592         case 2: /* 0 1 0 */
1593            *dst++ = atari_A;
1594            break;
1595         case 5: /* 1 0 1 */
1596            *dst++ = atari_B;
1597            break;
1598      }
1599   }
1600}
1601
1602void atari_common_state::artifacts_txt(UINT8 * src, UINT8 * dst, int width)
1603{
1604   UINT8 n, bits = 0;
1605   UINT8 b = m_gtia->get_w_colpf2() & 0xf0;
1606   UINT8 c = m_gtia->get_w_colpf1() & 0x0f;
1607   UINT8 atari_A = ((b+0x30)&0xf0)+c;
1608   UINT8 atari_B = ((b+0x70)&0xf0)+c;
1609   UINT8 atari_C = b+c;
1610   UINT8 atari_D = m_gtia->get_w_colpf2();
1611   UINT16 *color_lookup = m_gtia->get_color_lookup();
1612   
1613   for (int x = 0; x < width * 4; x++)
1614   {
1615      n = *src++;
1616      bits <<= 2;
1617      switch( n )
1618      {
1619         case T00:
1620            break;
1621         case T01:
1622            bits |= 1;
1623            break;
1624         case T10:
1625            bits |= 2;
1626            break;
1627         case T11:
1628            bits |= 3;
1629            break;
1630         default:
1631            *dst++ = color_lookup[n];
1632            *dst++ = color_lookup[n];
1633            continue;
1634      }
1635      switch( (bits >> 1) & 7 )
1636      {
1637         case 0: /* 0 0 0 */
1638         case 1: /* 0 0 1 */
1639         case 4: /* 1 0 0 */
1640            *dst++ = atari_D;
1641            break;
1642         case 3: /* 0 1 1 */
1643         case 6: /* 1 1 0 */
1644         case 7: /* 1 1 1 */
1645            *dst++ = atari_C;
1646            break;
1647         case 2: /* 0 1 0 */
1648            *dst++ = atari_A;
1649            break;
1650         case 5: /* 1 0 1 */
1651            *dst++ = atari_B;
1652            break;
1653      }
1654      switch( bits & 7 )
1655      {
1656         case 0:/* 0 0 0 */
1657         case 1:/* 0 0 1 */
1658         case 4:/* 1 0 0 */
1659            *dst++ = atari_D;
1660            break;
1661         case 3: /* 0 1 1 */
1662         case 6: /* 1 1 0 */
1663         case 7: /* 1 1 1 */
1664            *dst++ = atari_C;
1665            break;
1666         case 2: /* 0 1 0 */
1667            *dst++ = atari_B;
1668            break;
1669         case 5: /* 1 0 1 */
1670            *dst++ = atari_A;
1671            break;
1672      }
1673   }
1674}
1675
1676
1677void atari_common_state::antic_linerefresh()
1678{
1679   int x, y;
1680   UINT8 *src;
1681   UINT32 *dst;
1682   UINT32 scanline[4 + (HCHARS * 2) + 4];
1683   UINT16 *color_lookup = m_gtia->get_color_lookup();
1684   
1685   /* increment the scanline */
1686   if( ++antic.scanline == machine().first_screen()->height() )
1687   {
1688      /* and return to the top if the frame was complete */
1689      antic.scanline = 0;
1690      antic.modelines = 0;
1691      /* count frames gone since last write to hitclr */
1692      m_gtia->count_hitclr_frames();
1693   }
1694   
1695   if( antic.scanline < MIN_Y || antic.scanline > MAX_Y )
1696      return;
1697   
1698   y = antic.scanline - MIN_Y;
1699   src = &antic.cclock[PMOFFSET - antic.hscrol_old + 12];
1700   dst = scanline;
1701   
1702   if( tv_artifacts )
1703   {
1704      if( (antic.cmd & 0x0f) == 2 || (antic.cmd & 0x0f) == 3 )
1705      {
1706         artifacts_txt(src, (UINT8*)(dst + 3), HCHARS);
1707         return;
1708      }
1709      else
1710         if( (antic.cmd & 0x0f) == 15 )
1711         {
1712            artifacts_gfx(src, (UINT8*)(dst + 3), HCHARS);
1713            return;
1714         }
1715   }
1716   dst[0] = color_lookup[PBK] | color_lookup[PBK] << 16;
1717   dst[1] = color_lookup[PBK] | color_lookup[PBK] << 16;
1718   dst[2] = color_lookup[PBK] | color_lookup[PBK] << 16;
1719   if ( (antic.cmd & ANTIC_HSCR) == 0  || (antic.pfwidth == 48) || (antic.pfwidth == 32))
1720   {
1721      /* no hscroll */
1722      dst[3] = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
1723      src += 2;
1724      dst += 4;
1725      for( x = 1; x < HCHARS-1; x++ )
1726      {
1727         *dst++ = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
1728         *dst++ = color_lookup[src[BYTE_XOR_LE(2)]] | color_lookup[src[BYTE_XOR_LE(3)]] << 16;
1729         src += 4;
1730      }
1731      dst[0] = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
1732   }
1733   else
1734   {
1735      /* if hscroll is enabled, more data are fetched by ANTIC, but it still renders playfield
1736       of width defined by pfwidth. */
1737      switch( antic.pfwidth )
1738      {
1739         case 0:
1740         {
1741            dst[3] = color_lookup[PBK] | color_lookup[PBK] << 16;
1742            dst += 4;
1743            for ( x = 1; x < HCHARS-1; x++ )
1744            {
1745               *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
1746               *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
1747            }
1748            dst[0] = color_lookup[PBK] | color_lookup[PBK] << 16;
1749         }
1750            break;
1751            /* support for narrow playfield (32) with horizontal scrolling should be added here */
1752         case 40:
1753         {
1754            dst[3] = color_lookup[PBK] | color_lookup[PBK] << 16;
1755            dst += 4;
1756            for ( x = 1; x < HCHARS-2; x++ )
1757            {
1758               if ( x == 1 )
1759               {
1760                  *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
1761               }
1762               else
1763               {
1764                  *dst++ = color_lookup[src[BYTE_XOR_LE(0)]] | color_lookup[src[BYTE_XOR_LE(1)]] << 16;
1765               }
1766               *dst++ = color_lookup[src[BYTE_XOR_LE(2)]] | color_lookup[src[BYTE_XOR_LE(3)]] << 16;
1767               src += 4;
1768            }
1769            for ( ; x < HCHARS-1; x++ )
1770            {
1771               *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
1772               *dst++ = color_lookup[PBK] | color_lookup[PBK] << 16;
1773            }
1774            dst[0] = color_lookup[PBK] | color_lookup[PBK] << 16;
1775         }
1776            break;
1777      }
1778   }
1779   dst[1] = color_lookup[PBK] | color_lookup[PBK] << 16;
1780   dst[2] = color_lookup[PBK] | color_lookup[PBK] << 16;
1781   dst[3] = color_lookup[PBK] | color_lookup[PBK] << 16;
1782   
1783   draw_scanline8(*antic.bitmap, 12, y, MIN(antic.bitmap->width() - 12, sizeof(scanline)), (const UINT8 *) scanline, NULL);
1784}
1785
1786
1787#define ANTIC_TIME_FROM_CYCLES(cycles)   \
1788(attotime)(machine().first_screen()->scan_period() * (cycles) / CYCLES_PER_LINE)
1789
1790void atari_common_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
1791{
1792   switch (id)
1793   {
1794      case TIMER_CYCLE_STEAL:
1795         antic_steal_cycles(ptr, param);
1796         break;
1797      case TIMER_ISSUE_DLI:
1798         antic_issue_dli(ptr, param);
1799         break;
1800      case TIMER_LINE_REND:
1801         antic_scanline_render(ptr, param);
1802         break;
1803      case TIMER_LINE_DONE:
1804         antic_line_done(ptr, param);
1805         break;
1806   }
1807}
1808
1809int atari_common_state::cycle()
1810{
1811   return machine().first_screen()->hpos() * CYCLES_PER_LINE / machine().first_screen()->width();
1812}
1813
1814TIMER_CALLBACK_MEMBER( atari_common_state::antic_issue_dli )
1815{
1816   if( antic.w.nmien & DLI_NMI )
1817   {
1818      LOG(("           @cycle #%3d issue DLI\n", cycle()));
1819      antic.r.nmist |= DLI_NMI;
1820      machine().device("maincpu")->execute().set_input_line(INPUT_LINE_NMI, PULSE_LINE);
1821   }
1822   else
1823   {
1824      LOG(("           @cycle #%3d DLI not enabled\n", cycle()));
1825   }
1826}
1827
1828
1829/*****************************************************************************
1830 *
1831 *  Antic Line Done
1832 *
1833 *****************************************************************************/
1834TIMER_CALLBACK_MEMBER( atari_common_state::antic_line_done )
1835{
1836   LOG(("           @cycle #%3d antic_line_done\n", cycle()));
1837   if( antic.w.wsync )
1838   {
1839      LOG(("           @cycle #%3d release WSYNC\n", cycle()));
1840      /* release the CPU if it was actually waiting for HSYNC */
1841      machine().scheduler().trigger(TRIGGER_HSYNC);
1842      /* and turn off the 'wait for hsync' flag */
1843      antic.w.wsync = 0;
1844   }
1845   LOG(("           @cycle #%3d release CPU\n", cycle()));
1846   /* release the CPU (held for emulating cycles stolen by ANTIC DMA) */
1847   machine().scheduler().trigger(TRIGGER_STEAL);
1848   
1849   /* refresh the display (translate color clocks to pixels) */
1850   antic_linerefresh();
1851}
1852
1853/*****************************************************************************
1854 *
1855 *  Antic Steal Cycles
1856 *  This is called once per scanline by a interrupt issued in the
1857 *  atari_scanline_render function. Set a new timer for the HSYNC
1858 *  position and release the CPU; but hold it again immediately until
1859 *  TRIGGER_HSYNC if WSYNC (D01A) was accessed
1860 *
1861 *****************************************************************************/
1862TIMER_CALLBACK_MEMBER( atari_common_state::antic_steal_cycles )
1863{
1864   LOG(("           @cycle #%3d steal %d cycles\n", cycle(), antic.steal_cycles));
1865   timer_set(ANTIC_TIME_FROM_CYCLES(antic.steal_cycles), TIMER_LINE_DONE);
1866   antic.steal_cycles = 0;
1867   machine().device("maincpu")->execute().spin_until_trigger(TRIGGER_STEAL);
1868}
1869
1870
1871/*****************************************************************************
1872 *
1873 *  Antic Scan Line Render
1874 *  Render the scanline to the scrbitmap buffer.
1875 *  Also transport player/missile data to the grafp and grafm registers
1876 *  of the GTIA if enabled (DMA_PLAYER or DMA_MISSILE)
1877 *
1878 *****************************************************************************/
1879TIMER_CALLBACK_MEMBER( atari_common_state::antic_scanline_render )
1880{
1881   address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
1882   
1883   LOG(("           @cycle #%3d render mode $%X lines to go #%d\n", cycle(), (antic.cmd & 0x0f), antic.modelines));
1884   
1885   antic_render(space, m_antic_render1, m_antic_render2, m_antic_render3);
1886   
1887   /* if player/missile graphics is enabled */
1888   if( antic.scanline < 256 && (antic.w.dmactl & (DMA_PLAYER|DMA_MISSILE)) )
1889   {
1890      /* new player/missile graphics data for every scanline ? */
1891      if( antic.w.dmactl & DMA_PM_DBLLINE )
1892      {
1893         /* transport missile data to GTIA ? */
1894         if( antic.w.dmactl & DMA_MISSILE )
1895         {
1896            antic.steal_cycles += 1;
1897            m_gtia->write(space, 0x11, RDPMGFXD(space, 3*256));
1898         }
1899         /* transport player data to GTIA ? */
1900         if( antic.w.dmactl & DMA_PLAYER )
1901         {
1902            antic.steal_cycles += 4;
1903            m_gtia->write(space, 0x0d, RDPMGFXD(space, 4*256));
1904            m_gtia->write(space, 0x0e, RDPMGFXD(space, 5*256));
1905            m_gtia->write(space, 0x0f, RDPMGFXD(space, 6*256));
1906            m_gtia->write(space, 0x10, RDPMGFXD(space, 7*256));
1907         }
1908      }
1909      else
1910      {
1911         /* transport missile data to GTIA ? */
1912         if( antic.w.dmactl & DMA_MISSILE )
1913         {
1914            if( (antic.scanline & 1) == 0 )      /* even line ? */
1915               antic.steal_cycles += 1;
1916            m_gtia->write(space, 0x11, RDPMGFXS(space, 3*128));
1917         }
1918         /* transport player data to GTIA ? */
1919         if( antic.w.dmactl & DMA_PLAYER )
1920         {
1921            if( (antic.scanline & 1) == 0 )      /* even line ? */
1922               antic.steal_cycles += 4;
1923            m_gtia->write(space, 0x0d, RDPMGFXS(space, 4*128));
1924            m_gtia->write(space, 0x0e, RDPMGFXS(space, 5*128));
1925            m_gtia->write(space, 0x0f, RDPMGFXS(space, 6*128));
1926            m_gtia->write(space, 0x10, RDPMGFXS(space, 7*128));
1927         }
1928      }
1929   }
1930   
1931   if (antic.scanline >= VBL_END && antic.scanline < 256)
1932      m_gtia->render((UINT8 *)antic.pmbits + PMOFFSET, (UINT8 *)antic.cclock + PMOFFSET - antic.hscrol_old, (UINT8 *)antic.prio_table[m_gtia->get_w_prior() & 0x3f], (UINT8 *)&antic.pmbits);
1933   
1934   antic.steal_cycles += CYCLES_REFRESH;
1935   LOG(("           run CPU for %d cycles\n", CYCLES_HSYNC - CYCLES_HSTART - antic.steal_cycles));
1936   timer_set(ANTIC_TIME_FROM_CYCLES(CYCLES_HSYNC - CYCLES_HSTART - antic.steal_cycles), TIMER_CYCLE_STEAL);
1937}
1938
1939
1940
1941void atari_common_state::LMS(int new_cmd)
1942{
1943   /**************************************************************
1944    * If the LMS bit (load memory scan) of the current display
1945    * list command is set, load the video source address from the
1946    * following two bytes and split it up into video page/offset.
1947    * Steal two more cycles from the CPU for fetching the address.
1948    **************************************************************/
1949   if( new_cmd & ANTIC_LMS )
1950   {
1951      address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
1952      int addr = RDANTIC(space);
1953      antic.doffs = (antic.doffs + 1) & DOFFS;
1954      addr += 256 * RDANTIC(space);
1955      antic.doffs = (antic.doffs + 1) & DOFFS;
1956      antic.vpage = addr & VPAGE;
1957      antic.voffs = addr & VOFFS;
1958      LOG(("           LMS $%04x\n", addr));
1959      /* steal two more clock cycles from the cpu */
1960      antic.steal_cycles += 2;
1961   }
1962}
1963
1964/*****************************************************************************
1965 *
1966 *  Antic Scan Line DMA
1967 *  This is called once per scanline from Atari Interrupt
1968 *  If the ANTIC DMA is active (DMA_ANTIC) and the scanline not inside
1969 *  the VBL range (VBL_START - TOTAL_LINES or 0 - VBL_END)
1970 *  check if all mode lines of the previous ANTIC command were done and
1971 *  if so, read a new command and set up the renderer function
1972 *
1973 *****************************************************************************/
1974void atari_common_state::antic_scanline_dma(int param)
1975{
1976   address_space &space = machine().device("maincpu")->memory().space(AS_PROGRAM);
1977   LOG(("           @cycle #%3d DMA fetch\n", cycle()));
1978   if (antic.scanline == VBL_END)
1979      antic.r.nmist &= ~VBL_NMI;
1980   if( antic.w.dmactl & DMA_ANTIC )
1981   {
1982      if( antic.scanline >= VBL_END && antic.scanline < VBL_START )
1983      {
1984         if( antic.modelines <= 0 )
1985         {
1986            m_antic_render1 = 0;
1987            m_antic_render3 = antic.w.dmactl & 3;
1988            UINT8 vscrol_subtract = 0;
1989            UINT8 new_cmd;
1990           
1991            new_cmd = RDANTIC(space);
1992            antic.doffs = (antic.doffs + 1) & DOFFS;
1993            /* steal at one clock cycle from the CPU for fetching the command */
1994            antic.steal_cycles += 1;
1995            LOG(("           ANTIC CMD $%02x\n", new_cmd));
1996            /* command 1 .. 15 ? */
1997            if (new_cmd & ANTIC_MODE)
1998            {
1999               antic.w.chbasl = 0;
2000               /* vertical scroll mode changed ? */
2001               if( (antic.cmd ^ new_cmd) & ANTIC_VSCR )
2002               {
2003                  /* vertical scroll activate now ? */
2004                  if( new_cmd & ANTIC_VSCR )
2005                  {
2006                     antic.vscrol_old =
2007                     vscrol_subtract =
2008                     antic.w.chbasl = antic.w.vscrol;
2009                  }
2010                  else
2011                  {
2012                     vscrol_subtract = ~antic.vscrol_old;
2013                  }
2014               }
2015               /* does this command have horizontal scroll enabled ? */
2016               if( new_cmd & ANTIC_HSCR )
2017               {
2018                  m_antic_render1 = 1;
2019                  antic.hscrol_old = antic.w.hscrol;
2020               }
2021               else
2022               {
2023                  antic.hscrol_old = 0;
2024               }
2025            }
2026            /* Set the ANTIC mode renderer function */
2027            m_antic_render2 = new_cmd & ANTIC_MODE;
2028           
2029            switch( new_cmd & ANTIC_MODE )
2030            {
2031               case 0x00:
2032                  /* generate 1 .. 8 empty lines */
2033                  antic.modelines = ((new_cmd >> 4) & 7) + 1;
2034                  /* did the last ANTIC command have vertical scroll enabled ? */
2035                  if( antic.cmd & ANTIC_VSCR )
2036                  {
2037                     /* yes, generate vscrol_old additional empty lines */
2038                     antic.modelines += antic.vscrol_old;
2039                  }
2040                  /* leave only bit 7 (DLI) set in ANTIC command */
2041                  new_cmd &= ANTIC_DLI;
2042                  break;
2043               case 0x01:
2044                  /* ANTIC "jump" with DLI: issue interrupt immediately */
2045                  if( new_cmd & ANTIC_DLI )
2046                  {
2047                     /* remove the DLI bit */
2048                     new_cmd &= ~ANTIC_DLI;
2049                     timer_set(ANTIC_TIME_FROM_CYCLES(CYCLES_DLI_NMI), TIMER_ISSUE_DLI);
2050                  }
2051                  /* load memory scan bit set ? */
2052                  if( new_cmd & ANTIC_LMS )
2053                  {
2054                     int addr = RDANTIC(space);
2055                     antic.doffs = (antic.doffs + 1) & DOFFS;
2056                     addr += 256 * RDANTIC(space);
2057                     antic.dpage = addr & DPAGE;
2058                     antic.doffs = addr & DOFFS;
2059                     /* produce empty scanlines until vblank start */
2060                     antic.modelines = VBL_START + 1 - antic.scanline;
2061                     if( antic.modelines < 0 )
2062                        antic.modelines = machine().first_screen()->height() - antic.scanline;
2063                     LOG(("           JVB $%04x\n", antic.dpage|antic.doffs));
2064                  }
2065                  else
2066                  {
2067                     int addr = RDANTIC(space);
2068                     antic.doffs = (antic.doffs + 1) & DOFFS;
2069                     addr += 256 * RDANTIC(space);
2070                     antic.dpage = addr & DPAGE;
2071                     antic.doffs = addr & DOFFS;
2072                     /* produce a single empty scanline */
2073                     antic.modelines = 1;
2074                     LOG(("           JMP $%04x\n", antic.dpage|antic.doffs));
2075                  }
2076                  break;
2077               case 0x02:
2078                  LMS(new_cmd);
2079                  antic.chbase = (antic.w.chbash & 0xfc) << 8;
2080                  antic.modelines = 8 - (vscrol_subtract & 7);
2081                  if( antic.w.chactl & 4 )    /* decrement chbasl? */
2082                     antic.w.chbasl = antic.modelines - 1;
2083                  break;
2084               case 0x03:
2085                  LMS(new_cmd);
2086                  antic.chbase = (antic.w.chbash & 0xfc) << 8;
2087                  antic.modelines = 10 - (vscrol_subtract & 9);
2088                  if( antic.w.chactl & 4 )    /* decrement chbasl? */
2089                     antic.w.chbasl = antic.modelines - 1;
2090                  break;
2091               case 0x04:
2092                  LMS(new_cmd);
2093                  antic.chbase = (antic.w.chbash & 0xfc) << 8;
2094                  antic.modelines = 8 - (vscrol_subtract & 7);
2095                  if( antic.w.chactl & 4 )    /* decrement chbasl? */
2096                     antic.w.chbasl = antic.modelines - 1;
2097                  break;
2098               case 0x05:
2099                  LMS(new_cmd);
2100                  antic.chbase = (antic.w.chbash & 0xfc) << 8;
2101                  antic.modelines = 16 - (vscrol_subtract & 15);
2102                  if( antic.w.chactl & 4 )    /* decrement chbasl? */
2103                     antic.w.chbasl = antic.modelines - 1;
2104                  break;
2105               case 0x06:
2106                  LMS(new_cmd);
2107                  antic.chbase = (antic.w.chbash & 0xfe) << 8;
2108                  antic.modelines = 8 - (vscrol_subtract & 7);
2109                  if( antic.w.chactl & 4 )    /* decrement chbasl? */
2110                     antic.w.chbasl = antic.modelines - 1;
2111                  break;
2112               case 0x07:
2113                  LMS(new_cmd);
2114                  antic.chbase = (antic.w.chbash & 0xfe) << 8;
2115                  antic.modelines = 16 - (vscrol_subtract & 15);
2116                  if( antic.w.chactl & 4 )    /* decrement chbasl? */
2117                     antic.w.chbasl = antic.modelines - 1;
2118                  break;
2119               case 0x08:
2120                  LMS(new_cmd);
2121                  antic.modelines = 8 - (vscrol_subtract & 7);
2122                  break;
2123               case 0x09:
2124                  LMS(new_cmd);
2125                  antic.modelines = 4 - (vscrol_subtract & 3);
2126                  break;
2127               case 0x0a:
2128                  LMS(new_cmd);
2129                  antic.modelines = 4 - (vscrol_subtract & 3);
2130                  break;
2131               case 0x0b:
2132                  LMS(new_cmd);
2133                  antic.modelines = 2 - (vscrol_subtract & 1);
2134                  break;
2135               case 0x0c:
2136                  LMS(new_cmd);
2137                  antic.modelines = 1;
2138                  break;
2139               case 0x0d:
2140                  LMS(new_cmd);
2141                  antic.modelines = 2 - (vscrol_subtract & 1);
2142                  break;
2143               case 0x0e:
2144                  LMS(new_cmd);
2145                  antic.modelines = 1;
2146                  break;
2147               case 0x0f:
2148                  LMS(new_cmd);
2149                  /* bits 6+7 of the priority select register determine */
2150                  /* if newer GTIA or plain graphics modes are used */
2151                  switch (m_gtia->get_w_prior() >> 6)
2152               {
2153                  case 0: break;
2154                  case 1: m_antic_render2 = 16;  break;
2155                  case 2: m_antic_render2 = 17;  break;
2156                  case 3: m_antic_render2 = 18;  break;
2157               }
2158                  antic.modelines = 1;
2159                  break;
2160            }
2161            /* set new (current) antic command */
2162            antic.cmd = new_cmd;
2163         }
2164      }
2165      else
2166      {
2167         LOG(("           out of visible range\n"));
2168         antic.cmd = 0x00;
2169         m_antic_render1 = 0;
2170         m_antic_render2 = 0;
2171         m_antic_render3 = 0;
2172      }
2173   }
2174   else
2175   {
2176      LOG(("           DMA is off\n"));
2177      antic.cmd = 0x00;
2178      m_antic_render1 = 0;
2179      m_antic_render2 = 0;
2180      m_antic_render3 = 0;
2181   }
2182   
2183   antic.r.nmist &= ~DLI_NMI;
2184   if (antic.modelines == 1 && (antic.cmd & antic.w.nmien & DLI_NMI))
2185      timer_set(ANTIC_TIME_FROM_CYCLES(CYCLES_DLI_NMI), TIMER_ISSUE_DLI);
2186   
2187   timer_set(ANTIC_TIME_FROM_CYCLES(CYCLES_HSTART), TIMER_LINE_REND);
2188}

Previous 199869 Revisions Next


© 1997-2024 The MAME Team