Previous 15994 Revisions Next

r8980 Tuesday 31st August, 2010 at 18:34:12 UTC by Wilbert Pol
Sync with MAME.
[src/emu/video]mc6845.c

src/emu/video/mc6845.c
r8979r8980
101101   UINT8   cursor_state;   /* 0 = off, 1 = on */
102102   UINT8   cursor_blink_count;
103103   UINT8   update_ready_bit;
104   /* output signals */
105   int      cur;
106   int      hsync;
107   int      vsync;
108   int      de;
104109
110   /* internal counters */
111   UINT8   character_counter;      /* Not used yet */
112   UINT8   hsync_width_counter;   /* Not used yet */
113   UINT8   line_counter;
114   UINT8   raster_counter;
115   UINT8   adjust_counter;
116   UINT8   vsync_width_counter;
117
118   UINT8   line_enable_ff;      /* Internal flip flop which is set when the line_counter is reset and reset when vert_disp is reached */
119   UINT8   vsync_ff;
120   UINT8   adjust_active;
121   UINT16   line_address;
122   INT16   cursor_x;
123
105124   /* timers */
106   emu_timer *de_changed_timer;
125   emu_timer *line_timer;
126   emu_timer *de_off_timer;
107127   emu_timer *cur_on_timer;
108128   emu_timer *cur_off_timer;
109129   emu_timer *hsync_on_timer;
110130   emu_timer *hsync_off_timer;
111   emu_timer *vsync_on_timer;
112   emu_timer *vsync_off_timer;
113131   emu_timer *light_pen_latch_timer;
114132   emu_timer *upd_adr_timer;
115133
116134   /* computed values - do NOT state save these! */
117   UINT16    horiz_pix_total;
118   UINT16    vert_pix_total;
119   UINT16    max_visible_x;
120   UINT16    max_visible_y;
121   UINT16    hsync_on_pos;
122   UINT16    hsync_off_pos;
123   UINT16    vsync_on_pos;
124   UINT16    vsync_off_pos;
125   UINT16   current_disp_addr;   /* the display address currently drawn */
135   /* These computed are used to define the screen parameters for a driver */
136   UINT16   horiz_pix_total;
137   UINT16   vert_pix_total;
138   UINT16   max_visible_x;
139   UINT16   max_visible_y;
140   UINT16   hsync_on_pos;
141   UINT16   hsync_off_pos;
142   UINT16   vsync_on_pos;
143   UINT16   vsync_off_pos;
144   int      has_valid_parameters;
145
146   UINT16   current_disp_addr;   /* the display address currently drawn (used only in mc6845_update) */
147
126148   UINT8    light_pen_latched;
127149   attotime upd_time;
128   int       has_valid_parameters;
129150};
130151
131152
132153static STATE_POSTLOAD( mc6845_state_save_postload );
133154static void recompute_parameters(mc6845_t *mc6845, int postload);
134155static void update_upd_adr_timer(mc6845_t *mc6845);
135static void update_de_changed_timer(mc6845_t *mc6845);
136static void update_cur_changed_timers(mc6845_t *mc6845);
137static void update_hsync_changed_timers(mc6845_t *mc6845);
138static void update_vsync_changed_timers(mc6845_t *mc6845);
156static void update_cursor_state(mc6845_t *mc6845);
139157
140158
141159const mc6845_interface mc6845_null_interface = { 0 };
r8979r8980
206224   UINT8 ret = 0;
207225
208226   /* VBLANK bit */
209   if (supports_status_reg_d5[mc6845->device_type] && mc6845->screen->vblank())
227   if (supports_status_reg_d5[mc6845->device_type] && ( mc6845->line_enable_ff == 0 ))
210228      ret = ret | 0x20;
211229
212230   /* light pen latched */
r8979r8980
402420            if (LOG) logerror("M6845 config screen: HTOTAL: 0x%x  VTOTAL: 0x%x  MAX_X: 0x%x  MAX_Y: 0x%x  HSYNC: 0x%x-0x%x  VSYNC: 0x%x-0x%x  Freq: %ffps\n",
403421                          horiz_pix_total, vert_pix_total, max_visible_x, max_visible_y, hsync_on_pos, hsync_off_pos - 1, vsync_on_pos, vsync_off_pos - 1, 1 / ATTOSECONDS_TO_DOUBLE(refresh));
404422
405            mc6845->screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);
423            if ( mc6845->screen != NULL )
424               mc6845->screen->configure(horiz_pix_total, vert_pix_total, visarea, refresh);
406425
407426            mc6845->has_valid_parameters = TRUE;
408427         }
r8979r8980
417436         mc6845->hsync_off_pos = hsync_off_pos;
418437         mc6845->vsync_on_pos = vsync_on_pos;
419438         mc6845->vsync_off_pos = vsync_off_pos;
420
421         update_de_changed_timer(mc6845);
422         update_cur_changed_timers(mc6845);
423         update_hsync_changed_timers(mc6845);
424         update_vsync_changed_timers(mc6845);
425439      }
426440   }
427441}
428442
429443
430INLINE int is_display_enabled(mc6845_t *mc6845)
444INLINE void mc6845_update_counters(mc6845_t *mc6845)
431445{
432   return !mc6845->screen->vblank() && !mc6845->screen->hblank();
446   mc6845->character_counter = attotime_to_ticks( timer_timeelapsed( mc6845->line_timer ), mc6845->clock );
447
448   if ( timer_enabled( mc6845->hsync_off_timer ) )
449   {
450      mc6845->hsync_width_counter = attotime_to_ticks( timer_timeelapsed( mc6845->hsync_off_timer ), mc6845->clock );
451   }
433452}
434453
435454
436static void update_upd_adr_timer(mc6845_t *mc6845)
455INLINE void mc6845_set_de(mc6845_t *mc6845, int state)
437456{
438   if (!is_display_enabled(mc6845) && supports_transparent[mc6845->device_type])
439      timer_adjust_oneshot(mc6845->upd_adr_timer,  mc6845->upd_time, 0);
440}
441
442static void update_de_changed_timer(mc6845_t *mc6845)
443{
444   if (mc6845->has_valid_parameters && (mc6845->de_changed_timer != NULL))
457   if ( mc6845->de != state )
445458   {
446      INT16 next_y;
447      UINT16 next_x;
448      attotime duration;
459      mc6845->de = state;
449460
450      /* we are in a display region, get the location of the next blanking start */
451      if (is_display_enabled(mc6845))
461      if ( mc6845->de )
452462      {
453         /* normally, it's at end the current raster line */
454         next_y = mc6845->screen->vpos();
455         next_x = mc6845->max_visible_x + 1;
456
457         /* but if visible width = horiz_pix_total, then we need
458               to go to the beginning of VBLANK */
459         if (next_x == mc6845->horiz_pix_total)
460         {
461            next_y = mc6845->max_visible_y + 1;
462            next_x = 0;
463
464            /* abnormal case, no vertical blanking, either */
465            if (next_y == mc6845->vert_pix_total)
466               next_y = -1;
467         }
468         if (supports_transparent[mc6845->device_type]) timer_adjust_oneshot(mc6845->upd_adr_timer,  attotime_never, 0);
463         /* If the upd_adr_timer was running, cancel it */
464         timer_adjust_oneshot(mc6845->upd_adr_timer,  attotime_never, 0);
469465      }
470
471      /* we are in a blanking region, get the location of the next display start */
472466      else
473467      {
474         next_x = 0;
475         next_y = (mc6845->screen->vpos() + 1) % mc6845->vert_pix_total;
476
477         /* if we would now fall in the vertical blanking, we need
478               to go to the top of the screen */
479         if (next_y > mc6845->max_visible_y)
480            next_y = 0;
481
482468         /* if transparent update was requested fire the update timer */
483469         if(!mc6845->update_ready_bit)
484470            update_upd_adr_timer(mc6845);
485471      }
486472
487      if (next_y != -1)
488         duration = mc6845->screen->time_until_pos(next_y, next_x);
489      else
490         duration = attotime_never;
491
492      timer_adjust_oneshot(mc6845->de_changed_timer, duration, 0);
473      if ( mc6845->out_de_func.target != NULL )
474         devcb_call_write_line( &mc6845->out_de_func, mc6845->de );
493475   }
494476}
495477
496static void update_cur_changed_timers(mc6845_t *mc6845)
478
479INLINE void mc6845_set_hsync(mc6845_t *mc6845, int state)
497480{
498   if (mc6845->has_valid_parameters && (mc6845->cur_on_timer != NULL))
481   if ( mc6845->hsync != state )
499482   {
500      UINT16 cur_on_row = ((mc6845->cursor_addr - mc6845->disp_start_addr) / mc6845->horiz_disp) * (mc6845->max_ras_addr + 1);
501      UINT16 cur_on_y = cur_on_row + mc6845->cursor_start_ras;
502      UINT16 cur_off_y = cur_on_row + mc6845->cursor_end_ras;
503      UINT16 cur_on_pos = ((mc6845->cursor_addr - mc6845->disp_start_addr) % mc6845->horiz_disp) * mc6845->intf->hpixels_per_column;
504      UINT16 cur_off_pos = cur_on_pos + mc6845->intf->hpixels_per_column;
505      UINT16 next_y;
506      UINT16 y = mc6845->screen->vpos();
483      mc6845->hsync = state;
507484
508      if ((y >= cur_on_y) && (y < cur_off_y))
509         next_y = y + 1;
510      else
511         next_y = cur_on_y;
512
513      timer_adjust_oneshot(mc6845->cur_on_timer,  mc6845->screen->time_until_pos(next_y, cur_on_pos) , 0);
514      timer_adjust_oneshot(mc6845->cur_off_timer, mc6845->screen->time_until_pos(next_y, cur_off_pos), 0);
485      if ( mc6845->out_hsync_func.target != NULL )
486         devcb_call_write_line( &mc6845->out_hsync_func, mc6845->hsync );
515487   }
516488}
517489
518static void update_hsync_changed_timers(mc6845_t *mc6845)
490
491INLINE void mc6845_set_vsync(mc6845_t *mc6845, int state)
519492{
520   if (mc6845->has_valid_parameters && (mc6845->hsync_on_timer != NULL))
493   if ( mc6845->vsync != state )
521494   {
522      UINT16 next_y;
495      mc6845->vsync = state;
523496
524      /* we are before the HSYNC position, we trigger on the current line */
525      if (mc6845->screen->hpos() < mc6845->hsync_on_pos)
526         next_y = mc6845->screen->vpos();
527
528      /* trigger on the next line */
529      else
530         next_y = (mc6845->screen->vpos() + 1) % mc6845->vert_pix_total;
531
532      timer_adjust_oneshot(mc6845->hsync_on_timer,  mc6845->screen->time_until_pos(next_y, mc6845->hsync_on_pos) , 0);
533      timer_adjust_oneshot(mc6845->hsync_off_timer, mc6845->screen->time_until_pos(next_y, mc6845->hsync_off_pos), 0);
497      if ( mc6845->out_vsync_func.target != NULL )
498         devcb_call_write_line( &mc6845->out_vsync_func, mc6845->vsync );
534499   }
535500}
536501
537502
538static void update_vsync_changed_timers(mc6845_t *mc6845)
503INLINE void mc6845_set_cur(mc6845_t *mc6845, int state)
539504{
540   if (mc6845->has_valid_parameters && (mc6845->vsync_on_timer != NULL))
505   if ( mc6845->cur != state )
541506   {
542      timer_adjust_oneshot(mc6845->vsync_on_timer,  mc6845->screen->time_until_pos(mc6845->vsync_on_pos), 0);
543      timer_adjust_oneshot(mc6845->vsync_off_timer, mc6845->screen->time_until_pos(mc6845->vsync_off_pos), 0);
507      mc6845->cur = state;
508
509      if ( mc6845->out_cur_func.target != NULL )
510         devcb_call_write_line( &mc6845->out_cur_func, mc6845->cur );
544511   }
545512}
546513
547514
515static void update_upd_adr_timer(mc6845_t *mc6845)
516{
517   if (! mc6845->de && supports_transparent[mc6845->device_type])
518      timer_adjust_oneshot(mc6845->upd_adr_timer,  mc6845->upd_time, 0);
519}
520
521
548522static TIMER_CALLBACK( upd_adr_timer_cb )
549523{
550524   running_device *device = (running_device *)ptr;
r8979r8980
554528}
555529
556530
557static TIMER_CALLBACK( de_changed_timer_cb )
531static TIMER_CALLBACK( de_off_timer_cb )
558532{
559533   running_device *device = (running_device *)ptr;
560534   mc6845_t *mc6845 = get_safe_token(device);
561535
562   /* call the callback function -- we know it exists */
563   devcb_call_write_line(&mc6845->out_de_func, is_display_enabled(mc6845));
564
565   update_de_changed_timer(mc6845);
536   mc6845_set_de( mc6845, FALSE );
566537}
567538
568539
r8979r8980
571542   running_device *device = (running_device *)ptr;
572543   mc6845_t *mc6845 = get_safe_token(device);
573544
574   /* call the callback function -- we know it exists */
575   devcb_call_write_line(&mc6845->out_cur_func, TRUE);
545   mc6845_set_cur( mc6845, TRUE );
546
547   /* Schedule CURSOR off signal */
548   timer_adjust_oneshot( mc6845->cur_off_timer, ticks_to_attotime( 1, mc6845->clock ), 0 );
576549}
577550
578551
r8979r8980
581554   running_device *device = (running_device *)ptr;
582555   mc6845_t *mc6845 = get_safe_token(device);
583556
584   /* call the callback function -- we know it exists */
585   devcb_call_write_line(&mc6845->out_cur_func, FALSE);
586
587   update_cur_changed_timers(mc6845);
557   mc6845_set_cur( mc6845, FALSE );
588558}
589559
590560
591static TIMER_CALLBACK( vsync_on_timer_cb )
561static TIMER_CALLBACK( hsync_on_timer_cb )
592562{
593563   running_device *device = (running_device *)ptr;
594564   mc6845_t *mc6845 = get_safe_token(device);
565   UINT8 hsync_width = ( mc6845->sync_width & 0x0f ) ? ( mc6845->sync_width & 0x0f ) : 0x10;
595566
596   /* call the callback function -- we know it exists */
597   devcb_call_write_line(&mc6845->out_vsync_func, TRUE);
567   mc6845->hsync_width_counter = 0;
568   mc6845_set_hsync( mc6845, TRUE );
569
570   /* Schedule HSYNC off signal */
571   timer_adjust_oneshot( mc6845->hsync_off_timer, ticks_to_attotime( hsync_width, mc6845->clock ), 0 );
598572}
599573
600574
601static TIMER_CALLBACK( vsync_off_timer_cb )
575static TIMER_CALLBACK( hsync_off_timer_cb )
602576{
603577   running_device *device = (running_device *)ptr;
604578   mc6845_t *mc6845 = get_safe_token(device);
605579
606   /* call the callback function -- we know it exists */
607   devcb_call_write_line(&mc6845->out_vsync_func, FALSE);
608
609   update_vsync_changed_timers(mc6845);
580   mc6845_set_hsync( mc6845, FALSE );
610581}
611582
612583
613static TIMER_CALLBACK( hsync_on_timer_cb )
584static TIMER_CALLBACK( line_timer_cb )
614585{
615586   running_device *device = (running_device *)ptr;
616587   mc6845_t *mc6845 = get_safe_token(device);
588   int new_vsync = mc6845->vsync;
617589
618   /* call the callback function -- we know it exists */
619   devcb_call_write_line(&mc6845->out_hsync_func, TRUE);
620}
590   mc6845->character_counter = 0;
591   mc6845->cursor_x = -1;
621592
593   /* Check if VSYNC is active */
594   if ( mc6845->vsync_ff )
595   {
596      UINT8 vsync_width = supports_vert_sync_width[mc6845->device_type] ? (mc6845->sync_width >> 4) & 0x0f : 0;
622597
623static TIMER_CALLBACK( hsync_off_timer_cb )
624{
625   running_device *device = (running_device *)ptr;
626   mc6845_t *mc6845 = get_safe_token(device);
598      mc6845->vsync_width_counter = ( mc6845->vsync_width_counter + 1 ) & 0x0F;
627599
628   /* call the callback function -- we know it exists */
629   devcb_call_write_line(&mc6845->out_hsync_func, FALSE);
600      /* Check if we've reached end of VSYNC */
601      if ( mc6845->vsync_width_counter == vsync_width )
602      {
603         mc6845->vsync_ff = 0;
630604
631   update_hsync_changed_timers(mc6845);
632}
605         new_vsync = FALSE;
606      }
607   }
633608
609   if ( mc6845->raster_counter == mc6845->max_ras_addr )
610   {
611      /* Check if we have reached the end of the vertical area */
612      if ( mc6845->line_counter == mc6845->vert_char_total )
613      {
614         mc6845->adjust_counter = 0;
615         mc6845->adjust_active = 1;
616      }
634617
618      mc6845->raster_counter = 0;
619      mc6845->line_counter = ( mc6845->line_counter + 1 ) & 0x7F;
620      mc6845->line_address = ( mc6845->line_address + mc6845->horiz_disp ) & 0x3fff;
635621
636UINT16 mc6845_get_ma(running_device *device)
637{
638   UINT16 ret;
639   mc6845_t *mc6845 = get_safe_token(device);
622      /* Check if we've reached the end of active display */
623      if ( mc6845->line_counter == mc6845->vert_disp )
624      {
625         mc6845->line_enable_ff = 0;
626      }
640627
641   if (mc6845->has_valid_parameters)
628      /* Check if VSYNC should be enabled */
629      if ( mc6845->line_counter == mc6845->vert_sync_pos )
630      {
631         mc6845->vsync_width_counter = 0;
632         mc6845->vsync_ff = 1;
633
634         new_vsync = TRUE;
635      }
636   }
637   else
642638   {
643      /* clamp Y/X to the visible region */
644      int y = mc6845->screen->vpos();
645      int x = mc6845->screen->hpos();
639      mc6845->raster_counter = ( mc6845->raster_counter + 1 ) & 0x1F;
640   }
646641
647      /* since the MA counter stops in the blanking regions, if we are in a
648           VBLANK, both X and Y are at their max */
649      if ((y > mc6845->max_visible_y) || (x > mc6845->max_visible_x))
650         x = mc6845->max_visible_x;
642   if ( mc6845->adjust_active )
643   {
644      /* Check if we have reached the end of a full cycle */
645      if ( mc6845->adjust_counter == mc6845->vert_total_adj )
646      {
647         mc6845->adjust_active = 0;
648         mc6845->raster_counter = 0;
649         mc6845->line_counter = 0;
650         mc6845->line_address = mc6845->disp_start_addr;
651         mc6845->line_enable_ff = 1;
652         /* also update the cursor state now */
653         update_cursor_state(mc6845);
654      }
655      else
656      {
657         mc6845->adjust_counter = ( mc6845->adjust_counter + 1 ) & 0x1F;
658      }
659   }
651660
652      if (y > mc6845->max_visible_y)
653         y = mc6845->max_visible_y;
661   if ( mc6845->line_enable_ff )
662   {
663      /* Schedule DE off signal change */
664      timer_adjust_oneshot(mc6845->de_off_timer, ticks_to_attotime( mc6845->horiz_disp, mc6845->clock ), 0);
654665
655      ret = (mc6845->disp_start_addr +
656           (y / (mc6845->max_ras_addr + 1)) * mc6845->horiz_disp +
657           (x / mc6845->hpixels_per_column)) & 0x3fff;
666      /* Is cursor visible on this line? */
667      if ( mc6845->cursor_state &&
668         (mc6845->raster_counter >= (mc6845->cursor_start_ras & 0x1f)) &&
669         (mc6845->raster_counter <= mc6845->cursor_end_ras) &&
670         (mc6845->cursor_addr >= mc6845->line_address) &&
671         (mc6845->cursor_addr < (mc6845->line_address + mc6845->horiz_disp)) )
672      {
673         mc6845->cursor_x = mc6845->cursor_addr - mc6845->line_address;
674
675         /* Schedule CURSOR ON signal */
676         timer_adjust_oneshot( mc6845->cur_on_timer, ticks_to_attotime( mc6845->cursor_x, mc6845->clock ), 0 );
677      }
658678   }
659   else
660      ret = 0;
661679
662   return ret;
680   /* Schedule HSYNC on signal */
681   timer_adjust_oneshot( mc6845->hsync_on_timer, ticks_to_attotime( mc6845->horiz_sync_pos, mc6845->clock ), 0 );
682
683   /* Schedule our next callback */
684   timer_adjust_oneshot( mc6845->line_timer, ticks_to_attotime( mc6845->horiz_char_total + 1, mc6845->clock ), 0 );
685
686   /* Set VSYNC and DE signals */
687   mc6845_set_vsync( mc6845, new_vsync );
688   mc6845_set_de( mc6845, mc6845->line_enable_ff ? TRUE : FALSE );
663689}
664690
665691
666UINT8 mc6845_get_ra(running_device *device)
692UINT16 mc6845_get_ma(running_device *device)
667693{
668   UINT8 ret;
669694   mc6845_t *mc6845 = get_safe_token(device);
670695
671   if (mc6845->has_valid_parameters)
672   {
673      /* get the current vertical raster position and clamp it to the visible region */
674      int y = mc6845->screen->vpos();
696   mc6845_update_counters( mc6845 );
697   
698   return ( mc6845->line_address + mc6845->character_counter ) & 0x3fff;
699}
675700
676      if (y > mc6845->max_visible_y)
677         y = mc6845->max_visible_y;
678701
679      ret = y % (mc6845->max_ras_addr + 1);
680   }
681   else
682      ret = 0;
702UINT8 mc6845_get_ra(running_device *device)
703{
704   mc6845_t *mc6845 = get_safe_token(device);
683705
684   return ret;
706   return mc6845->raster_counter;
685707}
686708
687709
r8979r8980
697719
698720void mc6845_assert_light_pen_input(running_device *device)
699721{
700   int y, x;
701   int char_x;
702
703722   mc6845_t *mc6845 = get_safe_token(device);
704723
705   if (mc6845->has_valid_parameters)
706   {
707      /* get the current pixel coordinates */
708      y = mc6845->screen->vpos();
709      x = mc6845->screen->hpos();
710
711      /* compute the pixel coordinate of the NEXT character -- this is when the light pen latches */
712      char_x = x / mc6845->hpixels_per_column;
713      x = (char_x + 1) * mc6845->hpixels_per_column;
714
715      /* adjust if we are passed the boundaries of the screen */
716      if (x == mc6845->horiz_pix_total)
717      {
718         y = y + 1;
719         x = 0;
720
721         if (y == mc6845->vert_pix_total)
722            y = 0;
723      }
724
725      /* set the timer that will latch the display address into the light pen registers */
726      timer_adjust_oneshot(mc6845->light_pen_latch_timer, mc6845->screen->time_until_pos(y, x), 0);
727   }
724   /* compute the pixel coordinate of the NEXT character -- this is when the light pen latches */
725   /* set the timer that will latch the display address into the light pen registers */
726   timer_adjust_oneshot(mc6845->light_pen_latch_timer, ticks_to_attotime( 1, mc6845->clock ), 0);
728727}
729728
730729
r8979r8980
812811      {
813812         /* read the start address at the beginning of the frame */
814813         mc6845->current_disp_addr = mc6845->disp_start_addr;
815
816         /* also update the cursor state now */
817         update_cursor_state(mc6845);
818814      }
819815
820816      /* for each row in the visible region */
r8979r8980
877873      mc6845->hpixels_per_column = mc6845->intf->hpixels_per_column;
878874
879875      /* get the screen device */
880      mc6845->screen = downcast<screen_device *>(device->machine->device(mc6845->intf->screen_tag));
881      assert(mc6845->screen != NULL);
882
883      /* create the timers */
884      if (mc6845->out_de_func.target != NULL || supports_transparent[mc6845->device_type])
876      if ( mc6845->intf->screen_tag != NULL )
885877      {
886         mc6845->de_changed_timer = timer_alloc(device->machine, de_changed_timer_cb, (void *)device);
887         if(supports_transparent[mc6845->device_type])
888         {
889            mc6845->upd_adr_timer = timer_alloc(device->machine, upd_adr_timer_cb, (void *)device);
890         }
878         mc6845->screen = downcast<screen_device *>(device->machine->device(mc6845->intf->screen_tag));
879         assert(mc6845->screen != NULL);
891880      }
881      else
882         mc6845->screen = NULL;
892883
893      if (mc6845->out_cur_func.target != NULL)
894      {
895         mc6845->cur_on_timer = timer_alloc(device->machine, cur_on_timer_cb, (void *)device);
896         mc6845->cur_off_timer = timer_alloc(device->machine, cur_off_timer_cb, (void *)device);
897      }
884      /* create the timers */
885      mc6845->line_timer = timer_alloc(device->machine, line_timer_cb, (void *)device);
898886
899      if (mc6845->out_hsync_func.target != NULL)
900      {
901         mc6845->hsync_on_timer = timer_alloc(device->machine, hsync_on_timer_cb, (void *)device);
902         mc6845->hsync_off_timer = timer_alloc(device->machine, hsync_off_timer_cb, (void *)device);
903      }
887      mc6845->de_off_timer = timer_alloc(device->machine, de_off_timer_cb, (void *)device);
888      mc6845->upd_adr_timer = timer_alloc(device->machine, upd_adr_timer_cb, (void *)device);
904889
905      if (mc6845->out_vsync_func.target != NULL)
906      {
907         mc6845->vsync_on_timer = timer_alloc(device->machine, vsync_on_timer_cb, (void *)device);
908         mc6845->vsync_off_timer = timer_alloc(device->machine, vsync_off_timer_cb, (void *)device);
909      }
890      mc6845->cur_on_timer = timer_alloc(device->machine, cur_on_timer_cb, (void *)device);
891      mc6845->cur_off_timer = timer_alloc(device->machine, cur_off_timer_cb, (void *)device);
892
893      mc6845->hsync_on_timer = timer_alloc(device->machine, hsync_on_timer_cb, (void *)device);
894      mc6845->hsync_off_timer = timer_alloc(device->machine, hsync_off_timer_cb, (void *)device);
910895   }
911896
912897   mc6845->light_pen_latch_timer = timer_alloc(device->machine, light_pen_latch_timer_cb, (void *)device);
913898
899   /* Use some large startup values */
900   mc6845->horiz_char_total = 0xff;
901   mc6845->max_ras_addr = 0x1f;
902   mc6845->vert_char_total = 0x7f;
903
914904   /* register for state saving */
915905   state_save_register_postload(device->machine, mc6845_state_save_postload, mc6845);
916906
r8979r8980
937927   state_save_register_device_item(device, 0, mc6845->cursor_blink_count);
938928   state_save_register_device_item(device, 0, mc6845->update_addr);
939929   state_save_register_device_item(device, 0, mc6845->update_ready_bit);
930   state_save_register_device_item(device, 0, mc6845->cur);
931   state_save_register_device_item(device, 0, mc6845->hsync);
932   state_save_register_device_item(device, 0, mc6845->vsync);
933   state_save_register_device_item(device, 0, mc6845->de);
934   state_save_register_device_item(device, 0, mc6845->character_counter);
935   state_save_register_device_item(device, 0, mc6845->hsync_width_counter);
936   state_save_register_device_item(device, 0, mc6845->line_counter);
937   state_save_register_device_item(device, 0, mc6845->raster_counter);
938   state_save_register_device_item(device, 0, mc6845->adjust_counter);
939   state_save_register_device_item(device, 0, mc6845->vsync_width_counter);
940   state_save_register_device_item(device, 0, mc6845->line_enable_ff);
941   state_save_register_device_item(device, 0, mc6845->vsync_ff);
942   state_save_register_device_item(device, 0, mc6845->adjust_active);
943   state_save_register_device_item(device, 0, mc6845->line_address);
944   state_save_register_device_item(device, 0, mc6845->cursor_x);
940945}
941946
942947static DEVICE_START( mc6845 )
r8979r8980
992997         devcb_call_write_line(&mc6845->out_vsync_func, FALSE);
993998   }
994999
1000   if ( ! timer_enabled( mc6845->line_timer ) )
1001   {
1002      timer_adjust_oneshot( mc6845->line_timer, ticks_to_attotime( mc6845->horiz_char_total + 1, mc6845->clock ), 0 );
1003   }
1004
9951005   mc6845->light_pen_latched = FALSE;
9961006}
9971007

Previous 15994 Revisions Next


© 1998-2018 The MESS Team