Previous 15994 Revisions Next

r10099 Wednesday 19th January, 2011 at 03:20:31 UTC by MooglyGuy
[CRAFT] Began fleshing out timers in the Craft driver's ATMega framework [Harmony]
[src/mess/drivers]craft.c

src/mess/drivers/craft.c
r10098r10099
3737* I/O devices                                        *
3838\****************************************************/
3939
40static TIMER_CALLBACK( avr8_timer0_tick );
41static TIMER_CALLBACK( avr8_timer1_tick );
42static TIMER_CALLBACK( avr8_timer2_tick );
43
4044class craft_state : public driver_device
4145{
4246public:
4347   craft_state(running_machine &machine, const driver_device_config_base &config)
44      : driver_device(machine, config) { }
48      : driver_device(machine, config)
49   {
50       timer0_timer = timer_alloc(&machine, avr8_timer0_tick, 0);
51      timer0_increment = 1;
4552
53       timer1_timer = timer_alloc(&machine, avr8_timer1_tick, 0);
54      timer1_increment = 1;
55
56       timer2_timer = timer_alloc(&machine, avr8_timer2_tick, 0);
57      timer2_increment = 1;
58   }
59
4660   UINT8 regs[0x100];
47   INT32 tcnt1_direction;
4861
49   emu_timer* ocr1a_timer;
50   emu_timer* ocr1b_timer;
62   emu_timer* timer0_timer;
63   UINT8 timer0_top;
64   INT32 timer0_increment;
65
66   emu_timer* timer1_timer;
67   UINT16 timer1_top;
68   INT32 timer1_increment;
69
70   emu_timer* timer2_timer;
71   UINT8 timer2_top;
72   INT32 timer2_increment;
5173};
5274
5375enum
r10098r10099
6082
6183static const char avr8_reg_name[4] = { 'A', 'B', 'C', 'D' };
6284
63#if 0
64static UINT64 avr8_get_timer_1_frequency(craft_state *state)
85static TIMER_CALLBACK( avr8_timer0_tick )
6586{
66    UINT64 frequency = 0;
67    switch(AVR8_TCCR1B & 0x07)
68    {
69        case 0: // No clock source (Timer/Counter stopped).
70        case 6: // External clock source on T1 pin.  Clock on falling edge.
71        case 7: // External clock source on T1 pin.  Clock on rising edge.
72            frequency = 0;
73            break;
87   // TODO
88}
7489
75        case 1: // clk / 1 (No prescaling)
76            frequency = MASTER_CLOCK;
77            break;
90static TIMER_CALLBACK( avr8_timer1_tick )
91{
92    /* TODO: Handle comparison, setting OC1x pins, detection of BOTTOM and TOP
7893
79        case 2: // clk / 8 (From prescaler)
80            frequency = MASTER_CLOCK / 8;
81            break;
94    craft_state *state = machine->driver_data<craft_state>();
95    UINT16 count = AVR8_TCNT1;
96    count += state->timer1_increment;
8297
83        case 3: // clk / 64 (From prescaler)
84            frequency = MASTER_CLOCK / 64;
85            break;
98    for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
99    {
100      UINT8 mode = (reg == AVR8_REG_A) ? AVR8_TCCR1A_COM1A : AVR8_TCCR1A_COM1B;
101      switch(mode)
102      {
103         case 0:
104            //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Normal port operation (OC1 disconnected)\n");
105            break;
86106
87        case 4: // clk / 256 (From prescaler)
88            frequency = MASTER_CLOCK / 256;
89            break;
107         case 1:
108            switch(AVR8_WGM1)
109            {
110               case Avr8::WGM1_NORMAL:
111               case Avr8::WGM1_CTC_OCR:
112               case Avr8::WGM1_CTC_ICR:
113               case Avr8::WGM1_FAST_PWM_8:
114               case Avr8::WGM1_FAST_PWM_9:
115               case Avr8::WGM1_FAST_PWM_10:
116               case Avr8::WGM1_PWM_8_PC:
117               case Avr8::WGM1_PWM_9_PC:
118               case Avr8::WGM1_PWM_10_PC:
119               case Avr8::WGM1_PWM_PFC_ICR:
120               case Avr8::WGM1_PWM_PC_ICR:
121                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Normal port operation (OC1 disconnected)\n");
122                  break;
90123
91        case 5: // clk / 1024 (From prescaler)
92            frequency = MASTER_CLOCK / 1024;
93            break;
124               case Avr8::WGM1_FAST_PWM_ICR:
125               case Avr8::WGM1_FAST_PWM_OCR:
126               case Avr8::WGM1_PWM_PFC_OCR:
127               case Avr8::WGM1_PWM_PC_OCR:
128                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Toggle OC1A on compare match, OC1B disconnected\n");
129                  break;
130            }
131            break;
94132
95        default:
96           frequency = 0;
97            fatalerror( "&state->tccr1b & 0x07 returned a value not in the range of 0 to 7." );
98            break;
99    }
133         case 2:
134            switch(AVR8_WGM1)
135            {
136               case Avr8::WGM1_NORMAL:
137               case Avr8::WGM1_CTC_OCR:
138               case Avr8::WGM1_CTC_ICR:
139                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Clear OC1%c on compare match\n", avr8_reg_name[reg]);
140                  break;
100141
101    return frequency;
102}
142               case Avr8::WGM1_PWM_8_PC:
143               case Avr8::WGM1_PWM_9_PC:
144               case Avr8::WGM1_PWM_10_PC:
145               case Avr8::WGM1_PWM_PFC_ICR:
146               case Avr8::WGM1_PWM_PC_ICR:
147               case Avr8::WGM1_PWM_PFC_OCR:
148               case Avr8::WGM1_PWM_PC_OCR:
149                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Clear OC1%c on match when up-counting, set when down-counting\n", avr8_reg_name[reg]);
150                  break;
103151
104static UINT16 avr8_get_tc1_top(craft_state *state)
105{
106   switch(AVR8_WGM1)
107   {
108      case AVR8_WGM1_NORMAL:
109         return 0xffff;
152               case Avr8::WGM1_FAST_PWM_8:
153               case Avr8::WGM1_FAST_PWM_9:
154               case Avr8::WGM1_FAST_PWM_10:
155               case Avr8::WGM1_FAST_PWM_ICR:
156               case Avr8::WGM1_FAST_PWM_OCR:
157                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Clear OC1%c on compare match, set at BOTTOM\n", avr8_reg_name[reg]);
158                  break;
159            }
160            break;
110161
111      case AVR8_WGM1_PWM_8_PC:
112      case AVR8_WGM1_FAST_PWM_8:
113         return 0x00ff;
162         case 3:
163            switch(AVR8_WGM1)
164            {
165               case Avr8::WGM1_NORMAL:
166               case Avr8::WGM1_CTC_OCR:
167               case Avr8::WGM1_CTC_ICR:
168                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Set OC1%c on compare match\n", avr8_reg_name[reg]);
169                  break;
114170
115      case AVR8_WGM1_PWM_9_PC:
116      case AVR8_WGM1_FAST_PWM_9:
117         return 0x01ff;
171               case Avr8::WGM1_PWM_8_PC:
172               case Avr8::WGM1_PWM_9_PC:
173               case Avr8::WGM1_PWM_10_PC:
174               case Avr8::WGM1_PWM_PFC_ICR:
175               case Avr8::WGM1_PWM_PC_ICR:
176               case Avr8::WGM1_PWM_PFC_OCR:
177               case Avr8::WGM1_PWM_PC_OCR:
178                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Set OC1%c on match when up-counting, clear on match when down-counting\n", avr8_reg_name[reg]);
179                  break;
118180
119      case AVR8_WGM1_PWM_10_PC:
120      case AVR8_WGM1_FAST_PWM_10:
121         return 0x03ff;
122
123      case AVR8_WGM1_CTC_ICR:
124      case AVR8_WGM1_PWM_PFC_ICR:
125      case AVR8_WGM1_PWM_PC_ICR:
126      case AVR8_WGM1_FAST_PWM_ICR:
127         return AVR8_ICR1;
128
129      case AVR8_WGM1_CTC_OCR:
130      case AVR8_WGM1_PWM_PFC_OCR:
131      case AVR8_WGM1_PWM_PC_OCR:
132      case AVR8_WGM1_FAST_PWM_OCR:
133         return AVR8_OCR1A;
134
135      case AVR8_WGM1_RESERVED:
136         logerror("Attempting to retrieve TOP for a reserved waveform generation mode\n");
137         return 0xffff;
138   }
139   return 0xffff;
140}
141
142static UINT16 avr8_get_tc1_distance(craft_state *state, INT32 reg)
143{
144   UINT16 top = avr8_get_tc1_top(state);
145   UINT16 ocr = (reg == Avr8::REGIDX_A) ? AVR8_OCR1A : AVR8_OCR1B;
146   if(AVR8_TCNT1_DIR > 0)
147   {
148      if(AVR8_TCNT1 < ocr)
149      {
150         return ocr - AVR8_TCNT1;
181               case Avr8::WGM1_FAST_PWM_8:
182               case Avr8::WGM1_FAST_PWM_9:
183               case Avr8::WGM1_FAST_PWM_10:
184               case Avr8::WGM1_FAST_PWM_ICR:
185               case Avr8::WGM1_FAST_PWM_OCR:
186                  //verboselog(machine, 0, "avr8_update_timer1_compare_mode: Set OC1%c on compare match, clear at BOTTOM\n", avr8_reg_name[reg]);
187                  break;
188            }
189            break;
190         default:
191            verboselog(machine, 0, "avr8_update_timer1_compare_mode: Unknown COM1%c mode setting (%d)\n", avr8_reg_name[reg], mode);
192            break;
151193      }
152      else
153      {
154         return top - AVR8_TCNT1;
155      }
156194   }
157   else
158   {
159      if(AVR8_TCNT1 > ocr)
160      {
161         return AVR8_TCNT1 - ocr;
162      }
163      else
164      {
165         return ocr;
166      }
167   }
168   return 0xffff;
195   */
169196}
170197
171static void avr8_maybe_start_timer_1(craft_state *state)
172{
173    UINT64 frequency = avr8_get_timer_1_frequency(state);
174    if(frequency == 0)
175    {
176        timer_adjust_oneshot(state->ocr1a_timer, attotime_never, 0);
177        timer_adjust_oneshot(state->ocr1b_timer, attotime_never, 0);
178    }
179    else
180    {
181        attotime period_a = attotime_mul(ATTOTIME_IN_HZ(frequency), avr8_get_tc1_distance(state, Avr8::REGIDX_A));
182        attotime period_b = attotime_mul(ATTOTIME_IN_HZ(frequency), avr8_get_tc1_distance(state, Avr8::REGIDX_B));
183      timer_adjust_oneshot(state->ocr1a_timer, period_a, 0);
184      timer_adjust_oneshot(state->ocr1b_timer, period_b, 0);
185    }
186}
187#endif
188
189static TIMER_CALLBACK( ocr1a_timer_compare )
190{
191    //craft_state *state = machine->driver_data<craft_state>();
192    //avr8_regs *regs = &state->regs;
193
194   // TODO
195
196    //avr8_maybe_start_timer_1(regs);
197    //cpu_set_input_line(machine->device("maincpu"), AVR8_INT_T1COMPA, ASSERT_LINE);
198}
199
200static TIMER_CALLBACK( ocr1b_timer_compare )
201{
202    //craft_state *state = machine->driver_data<craft_state>();
203    //avr8_regs *regs = &state->regs;
204
205   // TODO
206
207    //avr8_maybe_start_timer_1(regs);
208    //cpu_set_input_line(machine->device("maincpu"), AVR8_INT_T1COMPB, ASSERT_LINE);
209}
210
211198static READ8_HANDLER( avr8_read )
212199{
213200    craft_state *state = space->machine->driver_data<craft_state>();
r10098r10099
475462   }
476463}
477464
478static void avr8_update_timer1_compare_mode(running_machine *machine, int reg)
479{
480   // TODO
481    craft_state *state = machine->driver_data<craft_state>();
482    UINT8 mode = (reg == AVR8_REG_A) ? AVR8_TCCR1A_COM1A : AVR8_TCCR1A_COM1B;
483    switch(mode)
484    {
485      case 0:
486         verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; OCR1%c disconnected, normal port operation\n", avr8_reg_name[reg]);
487         break;
488
489      case 1:
490         switch(AVR8_WGM1)
491         {
492            case Avr8::WGM1_NORMAL:
493            case Avr8::WGM1_CTC_OCR:
494            case Avr8::WGM1_CTC_ICR:
495            case Avr8::WGM1_FAST_PWM_8:
496            case Avr8::WGM1_FAST_PWM_9:
497            case Avr8::WGM1_FAST_PWM_10:
498            case Avr8::WGM1_PWM_8_PC:
499            case Avr8::WGM1_PWM_9_PC:
500            case Avr8::WGM1_PWM_10_PC:
501            case Avr8::WGM1_PWM_PFC_ICR:
502            case Avr8::WGM1_PWM_PC_ICR:
503               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Toggle OC1%c on compare match\n", avr8_reg_name[reg]);
504               break;
505
506            case Avr8::WGM1_FAST_PWM_ICR:
507            case Avr8::WGM1_FAST_PWM_OCR:
508            case Avr8::WGM1_PWM_PFC_OCR:
509            case Avr8::WGM1_PWM_PC_OCR:
510               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Toggle OC1A on compare match, OC1B disconnected\n");
511               break;
512         }
513         break;
514
515      case 2:
516         switch(AVR8_WGM1)
517         {
518            case Avr8::WGM1_NORMAL:
519            case Avr8::WGM1_CTC_OCR:
520            case Avr8::WGM1_CTC_ICR:
521               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Clear OC1%c on compare match\n", avr8_reg_name[reg]);
522               break;
523
524            case Avr8::WGM1_PWM_8_PC:
525            case Avr8::WGM1_PWM_9_PC:
526            case Avr8::WGM1_PWM_10_PC:
527            case Avr8::WGM1_PWM_PFC_ICR:
528            case Avr8::WGM1_PWM_PC_ICR:
529            case Avr8::WGM1_PWM_PFC_OCR:
530            case Avr8::WGM1_PWM_PC_OCR:
531               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Clear OC1%c on match when up-counting, set OC1%c on match when down-counting\n", avr8_reg_name[reg]);
532               break;
533
534            case Avr8::WGM1_FAST_PWM_8:
535            case Avr8::WGM1_FAST_PWM_9:
536            case Avr8::WGM1_FAST_PWM_10:
537            case Avr8::WGM1_FAST_PWM_ICR:
538            case Avr8::WGM1_FAST_PWM_OCR:
539               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Clear OC1%c on compare match, set OC1%c at BOTTOM\n", avr8_reg_name[reg]);
540               break;
541         }
542         break;
543
544      case 3:
545         switch(AVR8_WGM1)
546         {
547            case Avr8::WGM1_NORMAL:
548            case Avr8::WGM1_CTC_OCR:
549            case Avr8::WGM1_CTC_ICR:
550               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Set OC1%c on compare match\n", avr8_reg_name[reg]);
551               break;
552
553            case Avr8::WGM1_PWM_8_PC:
554            case Avr8::WGM1_PWM_9_PC:
555            case Avr8::WGM1_PWM_10_PC:
556            case Avr8::WGM1_PWM_PFC_ICR:
557            case Avr8::WGM1_PWM_PC_ICR:
558            case Avr8::WGM1_PWM_PFC_OCR:
559            case Avr8::WGM1_PWM_PC_OCR:
560               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Set OC1%c on match when up-counting, clear OC1%c on match when down-counting\n", avr8_reg_name[reg]);
561               break;
562
563            case Avr8::WGM1_FAST_PWM_8:
564            case Avr8::WGM1_FAST_PWM_9:
565            case Avr8::WGM1_FAST_PWM_10:
566            case Avr8::WGM1_FAST_PWM_ICR:
567            case Avr8::WGM1_FAST_PWM_OCR:
568               verboselog(machine, 0, "avr8_update_timer1_compare_mode: TODO; Set OC1%c on compare match, clear OC1%c at BOTTOM\n", avr8_reg_name[reg]);
569               break;
570         }
571         break;
572   }
573}
574
575465static void avr8_update_timer1_waveform_gen_mode(running_machine *machine)
576466{
577467   // TODO
578   UINT16 top = 0;
579468    craft_state *state = machine->driver_data<craft_state>();
469   state->timer1_top = 0;
580470   verboselog(machine, 0, "avr8_update_timer1_waveform_gen_mode: TODO; WGM1 is %d\n", AVR8_WGM1 );
581471   switch(AVR8_WGM1)
582472   {
583473      case Avr8::WGM1_NORMAL:
584         top = 0xffff;
474         state->timer1_top = 0xffff;
585475         break;
586476
587477      case Avr8::WGM1_PWM_8_PC:
588478      case Avr8::WGM1_FAST_PWM_8:
589         top = 0x00ff;
479         state->timer1_top = 0x00ff;
590480         break;
591481
592482      case Avr8::WGM1_PWM_9_PC:
593483      case Avr8::WGM1_FAST_PWM_9:
594         top = 0x01ff;
484         state->timer1_top = 0x01ff;
595485         break;
596486
597487      case Avr8::WGM1_PWM_10_PC:
598488      case Avr8::WGM1_FAST_PWM_10:
599         top = 0x03ff;
489         state->timer1_top = 0x03ff;
600490         break;
601491
602492      case Avr8::WGM1_PWM_PFC_ICR:
603493      case Avr8::WGM1_PWM_PC_ICR:
604494      case Avr8::WGM1_CTC_ICR:
605495      case Avr8::WGM1_FAST_PWM_ICR:
606         top = AVR8_ICR1;
496         state->timer1_top = AVR8_ICR1;
607497         break;
608498
609499      case Avr8::WGM1_PWM_PFC_OCR:
610500      case Avr8::WGM1_PWM_PC_OCR:
611501      case Avr8::WGM1_CTC_OCR:
612502      case Avr8::WGM1_FAST_PWM_OCR:
613         top = AVR8_OCR1A;
503         state->timer1_top = AVR8_OCR1A;
614504         break;
615505
616506      default:
r10098r10099
627517   UINT8 newtccr = data;
628518   UINT8 changed = newtccr ^ oldtccr;
629519
630   if(changed & AVR8_TCCR1A_COM1A_MASK)
631   {
632      // TODO
633      avr8_update_timer1_compare_mode(machine, AVR8_REG_A);
634   }
635
636   if(changed & AVR8_TCCR1A_COM1B_MASK)
637   {
638      // TODO
639      avr8_update_timer1_compare_mode(machine, AVR8_REG_B);
640   }
641
642520   if(changed & AVR8_TCCR1A_WGM1_10)
643521   {
644522      // TODO
r10098r10099
657535   verboselog(machine, 0, "avr8_update_timer1_input_edge_select: TODO; Clocking edge is %s\n", "test");
658536}
659537
538static TIMER_CALLBACK( avr8_timer2_tick )
539{
540    /* TODO: Handle comparison, setting OC2x pins, detection of BOTTOM and TOP
541
542    craft_state *state = machine->driver_data<craft_state>();
543    UINT16 count = AVR8_TCNT2;
544    count += state->timer1_increment;
545    for(INT32 reg = AVR8_REG_A; reg <= AVR8_REG_B; reg++)
546    {
547      UINT8 mode = (reg == AVR8_REG_A) ? AVR8_TCCR2A_COM2A : AVR8_TCCR2A_COM2B;
548
549      if(!mode)
550      {
551         // Normal port operation, OC2n disconnected
552         //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; OC2%c disconnected, normal port operation\n", avr8_reg_name[reg]);
553         return;
554      }
555
556      switch(AVR8_WGM2)
557      {
558         case Avr8::WGM2_NORMAL:
559         case Avr8::WGM2_CTC_CMP:
560            switch(mode)
561            {
562               case 1: // Toggle OC2n on Compare Match
563                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Toggle OC2%c on Compare Match\n", avr8_reg_name[reg]);
564                  break;
565               case 2: // Clear OC2n on Compare Match
566                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Clear OC2%c on Compare Match\n", avr8_reg_name[reg]);
567                  break;
568               case 3: // Set OC2n on Compare Match
569                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Set OC2%c on Compare Match\n", avr8_reg_name[reg]);
570                  break;
571            }
572            break;
573
574         case Avr8::WGM2_PWM_PC:
575            switch(mode)
576            {
577               case 1: // Normal port operation, OC2n disconnected
578                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; OC2%c disconnected, normal port operation\n", avr8_reg_name[reg]);
579                  break;
580               case 2: // Clear OC2n on match when up-counting, set when down-counting
581                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Clear OC2%c on match when up-counting, set when down-counting\n", avr8_reg_name[reg]);
582                  break;
583               case 3: // Set OC2n on match when up-counting, clear when down-counting
584                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Set OC2%c on match when up-counting, clear when down-counting\n", avr8_reg_name[reg]);
585                  break;
586            }
587            break;
588
589         case Avr8::WGM2_PWM_PC_CMP:
590            switch(mode)
591            {
592               case 1: // Toggle OC2n on compare match
593                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Toggle OC2%c on compare match\n", avr8_reg_name[reg]);
594                  break;
595               case 2: // Clear OC2n on match when up-counting, set when down-counting
596                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Clear OC2%c on match when up-counting, set when down-counting\n", avr8_reg_name[reg]);
597                  break;
598               case 3: // Set OC2n on match when up-counting, clear when down-counting
599                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Set OC2%c on match when up-counting, clear when down-counting\n", avr8_reg_name[reg]);
600                  break;
601            }
602            break;
603
604
605         case Avr8::WGM2_FAST_PWM:
606            switch(mode)
607            {
608               case 1: // Normal port operation, OC2n disconnected
609                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; OC2%c disconnected, normal port operation\n", avr8_reg_name[reg]);
610                  break;
611               case 2: // Clear OC2n on match, set at BOTTOM
612                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Clear OC2%c on match, set at BOTTOM\n", avr8_reg_name[reg]);
613                  break;
614               case 3: // Set OC2n on match, clear at BOTTOM
615                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Set OC2%c on match, clear at BOTTOM\n", avr8_reg_name[reg]);
616                  break;
617            }
618            break;
619
620         case Avr8::WGM2_FAST_PWM_CMP:
621            switch(mode)
622            {
623               case 1: // Toggle OC2n on compare match
624                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Toggle OC2%c on compare match\n", avr8_reg_name[reg]);
625                  break;
626               case 2: // Clear OC2n on match, set at BOTTOM
627                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Clear OC2%c on match, set at BOTTOM\n", avr8_reg_name[reg]);
628                  break;
629               case 3: // Set OC2n on match, clear at BOTTOM
630                  //verboselog(machine, 0, "avr8_update_timer2_compare_mode: TODO; Set OC2%c on match, clear at BOTTOM\n", avr8_reg_name[reg]);
631                  break;
632            }
633            break;
634
635         default:
636            break;
637      }
638   }
639   */
640}
641
660642static void avr8_update_timer1_clock_source(running_machine *machine)
661643{
644    craft_state *state = machine->driver_data<craft_state>();
645   attotime period;
646   switch(AVR8_TIMER2_CLOCK_SELECT)
647   {
648      case 0: // Counter stopped
649         period = attotime_never;
650         break;
651      case 1: // Clk/1; no prescaling
652         period = ATTOTIME_IN_HZ(MASTER_CLOCK);
653         break;
654      case 2: // Clk/8
655         period = ATTOTIME_IN_HZ(MASTER_CLOCK/8);
656         break;
657      case 3: // Clk/32
658         period = ATTOTIME_IN_HZ(MASTER_CLOCK/32);
659         break;
660      case 4: // Clk/64
661         period = ATTOTIME_IN_HZ(MASTER_CLOCK/64);
662         break;
663      case 5: // Clk/128
664         period = ATTOTIME_IN_HZ(MASTER_CLOCK/128);
665         break;
666      case 6: // T1 trigger, falling edge
667      case 7: // T1 trigger, rising edge
668         period = attotime_never;
669         verboselog(machine, 0, "avr8_update_timer1_clock_source: T1 Trigger mode not implemented yet\n");
670         break;
671   }
672   timer_adjust_periodic(state->timer1_timer, period, 0, period);
662673}
663674
664675static void avr8_changed_tccr1b(running_machine *machine, UINT8 data)
r10098r10099
689700
690701   if(changed & AVR8_TCCR1B_CS_MASK)
691702   {
692      // TODO
693703      avr8_update_timer1_clock_source(machine);
694704   }
695705}
696706
707static void avr8_update_timer2_waveform_gen_mode(running_machine *machine)
708{
709    craft_state *state = machine->driver_data<craft_state>();
710    state->timer2_top = 0;
711   switch(AVR8_WGM2)
712   {
713      case Avr8::WGM2_NORMAL:
714      case Avr8::WGM2_PWM_PC:
715      case Avr8::WGM2_FAST_PWM:
716         state->timer2_top = 0x00ff;
717         break;
718
719      case Avr8::WGM2_CTC_CMP:
720      case Avr8::WGM2_PWM_PC_CMP:
721      case Avr8::WGM2_FAST_PWM_CMP:
722         state->timer2_top = AVR8_OCR2A;
723         break;
724
725      default:
726         verboselog(machine, 0, "avr8_update_timer2_waveform_gen_mode: Unsupported waveform generation type: %d\n", AVR8_WGM2);
727         break;
728   }
729}
730
731static void avr8_changed_tccr2a(running_machine *machine, UINT8 data)
732{
733    craft_state *state = machine->driver_data<craft_state>();
734
735   UINT8 oldtccr = AVR8_TCCR2A;
736   UINT8 newtccr = data;
737   UINT8 changed = newtccr ^ oldtccr;
738
739   if(changed & AVR8_TCCR2A_WGM2_10_MASK)
740   {
741      // TODO
742      avr8_update_timer2_waveform_gen_mode(machine);
743   }
744}
745
746static void avr8_update_timer2_clock_source(running_machine *machine)
747{
748    craft_state *state = machine->driver_data<craft_state>();
749   attotime period;
750   switch(AVR8_TIMER2_CLOCK_SELECT)
751   {
752      case 0: // Counter stopped
753         period = attotime_never;
754         break;
755      case 1: // Clk/1; no prescaling
756         period = ATTOTIME_IN_HZ(MASTER_CLOCK);
757         break;
758      case 2: // Clk/8
759         period = ATTOTIME_IN_HZ(MASTER_CLOCK/8);
760         break;
761      case 3: // Clk/32
762         period = ATTOTIME_IN_HZ(MASTER_CLOCK/32);
763         break;
764      case 4: // Clk/64
765         period = ATTOTIME_IN_HZ(MASTER_CLOCK/64);
766         break;
767      case 5: // Clk/128
768         period = ATTOTIME_IN_HZ(MASTER_CLOCK/128);
769         break;
770      case 6: // Clk/256
771         period = ATTOTIME_IN_HZ(MASTER_CLOCK/256);
772         break;
773      case 7: // Clk/1024
774         period = ATTOTIME_IN_HZ(MASTER_CLOCK/1024);
775         break;
776   }
777   timer_adjust_periodic(state->timer2_timer, period, 0, period);
778}
779
780static void avr8_timer2_force_output_compare(running_machine *machine, int reg)
781{
782   // TODO
783   verboselog(machine, 0, "avr8_force_output_compare: TODO; should be forcing OC2%c\n", avr8_reg_name[reg]);
784}
785
786static void avr8_changed_tccr2b(running_machine *machine, UINT8 data)
787{
788    craft_state *state = machine->driver_data<craft_state>();
789
790   UINT8 oldtccr = AVR8_TCCR2B;
791   UINT8 newtccr = data;
792   UINT8 changed = newtccr ^ oldtccr;
793
794   if(changed & AVR8_TCCR2B_FOC2A_MASK)
795   {
796      // TODO
797      avr8_timer2_force_output_compare(machine, AVR8_REG_A);
798   }
799
800   if(changed & AVR8_TCCR2B_FOC2B_MASK)
801   {
802      // TODO
803      avr8_timer2_force_output_compare(machine, AVR8_REG_B);
804   }
805
806   if(changed & AVR8_TCCR2B_WGM2_2_MASK)
807   {
808      // TODO
809      avr8_update_timer2_waveform_gen_mode(machine);
810   }
811
812   if(changed & AVR8_TCCR2B_CS_MASK)
813   {
814      avr8_update_timer2_clock_source(machine);
815   }
816}
817
697818static void avr8_update_ocr1(running_machine *machine, UINT16 newval, UINT8 reg)
698819{
699820    craft_state *state = machine->driver_data<craft_state>();
r10098r10099
718839    switch( offset )
719840    {
720841      case Avr8::REGIDX_OCR1BH:
842         verboselog(space->machine, 0, "AVR8: OCR1BH = %02x\n", data );
721843         avr8_update_ocr1(space->machine, (AVR8_OCR1B & 0x00ff) | (data << 8), AVR8_REG_B);
722844         break;
723845
724846      case Avr8::REGIDX_OCR1BL:
847         verboselog(space->machine, 0, "AVR8: OCR1BL = %02x\n", data );
725848         avr8_update_ocr1(space->machine, (AVR8_OCR1B & 0xff00) | data, AVR8_REG_B);
726849         break;
727850
728851      case Avr8::REGIDX_OCR1AH:
852         verboselog(space->machine, 0, "AVR8: OCR1AH = %02x\n", data );
729853         avr8_update_ocr1(space->machine, (AVR8_OCR1A & 0x00ff) | (data << 8), AVR8_REG_A);
730854         break;
731855
732856      case Avr8::REGIDX_OCR1AL:
857         verboselog(space->machine, 0, "AVR8: OCR1AL = %02x\n", data );
733858         avr8_update_ocr1(space->machine, (AVR8_OCR1A & 0xff00) | data, AVR8_REG_A);
734859         break;
735860
736861      case Avr8::REGIDX_TCCR1B:
862         verboselog(space->machine, 0, "AVR8: TCCR1B = %02x\n", data );
737863         avr8_changed_tccr1b(space->machine, data);
738864         break;
739865
740866      case Avr8::REGIDX_TCCR1A:
867         verboselog(space->machine, 0, "AVR8: TCCR1A = %02x\n", data );
741868         avr8_changed_tccr1a(space->machine, data);
742869         break;
743870
744871      case Avr8::REGIDX_TIMSK1:
872         verboselog(space->machine, 0, "AVR8: TIMSK1 = %02x\n", data );
745873         avr8_change_timsk1(space->machine, data);
746874         break;
747875
876      case Avr8::REGIDX_TCCR2B:
877         verboselog(space->machine, 0, "AVR8: TCCR2B = %02x\n", data );
878         avr8_changed_tccr2b(space->machine, data);
879         break;
880
881      case Avr8::REGIDX_TCCR2A:
882         verboselog(space->machine, 0, "AVR8: TCCR2A = %02x\n", data );
883         avr8_changed_tccr2a(space->machine, data);
884         break;
885
748886      case Avr8::REGIDX_SPL:
749887      case Avr8::REGIDX_SPH:
750888      case Avr8::REGIDX_SREG:
r10098r10099
817955
818956static DRIVER_INIT( craft )
819957{
820    craft_state *state = machine->driver_data<craft_state>();
821
822    state->ocr1a_timer = timer_alloc(machine, ocr1a_timer_compare, 0);
823    state->ocr1b_timer = timer_alloc(machine, ocr1b_timer_compare, 0);
824958}
825959
826960static MACHINE_RESET( craft )

Previous 15994 Revisions Next


© 1998-2018 The MESS Team