Previous 15994 Revisions Next

r13636 Tuesday 20th December, 2011 at 07:05:27 UTC by Miodrag Milanović
-lynx: Fixes a bug in the audio emulation that was causing mess to hang. [huygens]
Changed button ordering
Sprite scaling changes (Blue Lightning runway fixed)
[src/mess/audio]lynx.c
[src/mess/drivers]lynx.c
[src/mess/includes]lynx.h
[src/mess/machine]lynx.c

src/mess/audio/lynx.c
r13635r13636
7979
8080 */
8181
82#define LYNX_AUDIO_CHANNELS 4
83
8284typedef struct {
8385    struct {
8486      INT8 volume;
r13635r13636
140142    LYNX_AUDIO *This=state->audio+nr;
141143    if (This->reg.control1&8 && (This->reg.control1&7)!=7) return;
142144    if (nr==0) state->mixer_channel->update();
143   if ((This->reg.control1&0x0f)==0x0f) //count down if linking enabled and count enabled
145   //if ((This->reg.control1&0x0f)==0x0f) //count down if linking enabled and count enabled
144146      This->count--;
145147}
146148
r13635r13636
150152   INT16 out_temp;
151153    UINT8 channel_number = (UINT8)(channel - state->audio);
152154
153   channel->shifter = ((channel->shifter<<1)&0xffe) | (state->shift_xor[ channel->shifter & channel->mask ]&1);
155   //channel->shifter = ((channel->shifter<<1)&0xffe) | (state->shift_xor[ channel->shifter & channel->mask ]&1);
154156
155   /* // alternative method (functionally the same as above)
156    UINT8 xor_out=0;
157    for(int bit=0;bit<12;bit++)
158    {
159        if((channel->mask>>bit)&1) xor_out ^= (channel->shifter>>bit)&1;
160    }
161    channel->shifter = ((channel->shifter<<1)&0xffe) | (xor_out ^ 1); // output of xor is inverted
162    */
163
164
157    // alternative method (functionally the same as above)
158   UINT8 xor_out=0;
159   for(int bit=0;bit<12;bit++)
160   {
161      if((channel->mask>>bit)&1) xor_out ^= (channel->shifter>>bit)&1;
162   }
163   channel->shifter = ((channel->shifter<<1)&0xffe) | (xor_out ^ 1); // output of xor is inverted
164   
165   
165166    if (channel->reg.control1&0x20) // integrate mode enabled
166167   {
167168      if (channel->shifter&1)
r13635r13636
217218            if (channel->ticks<t) break;
218219            if (channel->count<0)
219220            {
221               lynx_audio_shift(device, channel);
220222               if (channel->reg.control1&0x10)
221223                  channel->count = channel->reg.bakup;
222               lynx_audio_shift(device, channel);
224               else
225                  break;
223226            }
224227         }
225228      }
r13635r13636
266269            break;
267270         case 6:
268271            //current timer value
269            value = channel->count;
272            if (channel->count >=0)
273               value = channel->count;
274            else
275               value = 0;
270276            break;
271277         case 7:
272278            // current shifter state (upper 4 bits), status bits
r13635r13636
369375static STREAM_UPDATE( lynx_update )
370376{
371377   lynx_sound_state *state = get_safe_token(device);
372   int i, j;
373   LYNX_AUDIO *channel;
378   int i, channel;
379   //LYNX_AUDIO *channel;
374380   int v;
375381   stream_sample_t *buffer = outputs[0];
376382
377383   for (i = 0; i < samples; i++, buffer++)
378384   {
379385      *buffer = 0;
380      for (channel=state->audio, j=0; j<ARRAY_LENGTH(state->audio); j++, channel++)
386      for (channel=0; channel<LYNX_AUDIO_CHANNELS; channel++)
381387      {
382         lynx_audio_execute(device, channel);
383         v=channel->reg.output;
388         lynx_audio_execute(device, &state->audio[channel]);
389         v=state->audio[channel].reg.output;
384390         *buffer+=v*15; // where does the *15 come from?
385391      }
386392   }
src/mess/machine/lynx.c
r13635r13636
7979  0  0  0  0  0  0  0  1      exclusive-or the data
8080*/
8181
82INLINE void lynx_plot_pixel(lynx_state *state, const int mode, const int x, const int y, const int color)
82INLINE void lynx_plot_pixel(lynx_state *state, const int mode, const INT16 x, const int y, const int color)
8383{
8484   int back;
8585   UINT8 *screen;
r13635r13636
8989   screen = state->m_blitter.mem + state->m_blitter.screen + y * 80 + x / 2;
9090   colbuf = state->m_blitter.mem + state->m_blitter.colbuf + y * 80 + x / 2;
9191
92   switch (mode)
92   switch (mode&0x7)
9393   {
9494      case NORMAL_SPRITE:
9595      /* A sprite may be set to 'normal'. This means that pen number '0' will be transparent and
r13635r13636
297297            break;
298298         if (!(x & 0x01))      /* Upper nibble */
299299         {
300            *screen = (*screen & 0x0f)^(color<<4);
301
300            *screen = (*screen)^(color<<4);
302301            if (color != 0x0e)
303302            {
304303               back = *colbuf;
r13635r13636
310309         }
311310         else               /* Lower nibble */
312311         {
313            *screen = (*screen & 0xf0)^color;
314
312            *screen = (*screen)^color;
315313            if (color != 0x0e)
316314            {
317315               back = *colbuf;
r13635r13636
326324   }
327325}
328326
329static void lynx_blit_do_work( lynx_state *state, const int y, const int xdir, const int bits, const int mask )
327static void lynx_blit_do_work( lynx_state *state, const int y, const int xdir, const int bits_per_pixel, const int mask )
330328{
331   int i,j;
332   int xi, wi, b, p, color;
329   int next_line_addr,i,j;
330   int xi, bits, color;
331   UINT16 width_accum, buffer;
333332
334   i = state->m_blitter.mem[state->m_blitter.bitmap]; // offset to second sprite line
335   state->m_blitter.memory_accesses++;      // ?
336   for (xi = state->m_blitter.x, p = 0, b = 0, j = 1, wi = 0; j < i;)
333   next_line_addr = state->m_blitter.mem[state->m_blitter.bitmap]; // offset to second sprite line
334   width_accum = (xdir == 1) ? state->m_blitter.width_offset : 0;
335   state->m_blitter.memory_accesses++;
336   
337   for (xi = state->m_blitter.x_pos - state->m_blitter.xoff, bits = 0, buffer = 0, j = 1; j < next_line_addr;j++)
337338   {
338      if (p < bits) // less than one pixels worth of data left in buffer
339      buffer = (buffer << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j];
340      bits += 8; // current bits in buffer
341      state->m_blitter.memory_accesses++;
342     
343      for ( ; bits >= bits_per_pixel; bits -= bits_per_pixel)
339344      {
340         b = (b << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j]; // shift next byte into buffer
341         j++; // increment byte accumulator
342         p += 8; // current bits in buffer
343         state->m_blitter.memory_accesses++;
344      }
345      for ( ;(p >= bits); ) // as long as there is still one pixel of data remaining in buffer
346      {
347         color = state->m_blitter.color[(b >> (p - bits)) & mask];
348         p -= bits;
349         for ( ; wi < state->m_blitter.width; wi += 0x100, xi += xdir)
345         color = state->m_blitter.color[(buffer >> (bits - bits_per_pixel)) & mask];
346         //bits -= bits_per_pixel;
347         width_accum += state->m_blitter.width;
348         for (i = 0; i < (width_accum>>8); i++, xi += xdir)
350349         {
351350            if ((xi >= 0) && (xi < 160))
351            {
352352               lynx_plot_pixel(state, state->m_blitter.mode, xi, y, color);
353            }
353354         }
354         wi -= state->m_blitter.width;
355         width_accum &= 0xff;
355356      }
356357   }
357358}
r13635r13636
410411 1, 4 bit count of values-1, 4 bit color, ....
411412*/
412413
413static void lynx_blit_rle_do_work( lynx_state *state, const int y, const int xdir, const int bits, const int mask )
414static void lynx_blit_rle_do_work( lynx_state *state, const INT16 y, const int xdir, const int bits_per_pixel, const int mask )
414415{
415   int wi, xi;
416   int b, p, j;
417   int t, count, color;
418
419   for( p = 0, j = 0, b = 0, xi = state->m_blitter.x, wi = 0; ; )      /* through the rle entries */
416   int i;
417   int xi = state->m_blitter.x_pos - state->m_blitter.xoff;
418   int buffer, bits, j;
419   int literal_data, count, color;
420   UINT16 width_accum;
421   
422   width_accum = (xdir == 1) ? 0 : state->m_blitter.width_offset;
423   for( bits = 0, j = 0, buffer = 0, xi = state->m_blitter.x_pos - state->m_blitter.xoff; ; )      /* through the rle entries */
420424   {
421      if (p < 5 + bits) /* under 7 bits no complete entry */
425      if (bits < 5 + bits_per_pixel) /* under 7 bits no complete entry */
422426      {
423427         j++;
424428         if (j >= state->m_blitter.mem[state->m_blitter.bitmap])
425429            return;
426430
427         p += 8;
428         b = (b << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j];
431         bits += 8;
432         buffer = (buffer << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j];
429433         state->m_blitter.memory_accesses++;
430434      }
431435
432      t = (b >> (p - 1)) & 0x01;
433      p--;
434      count = ((b >> (p - 4)) & 0x0f) + 1; // count value of zero means 1 pixel, thus the +1
435      p -= 4;
436      literal_data = (buffer >> (bits - 1)) & 0x01;
437      bits--;
438      count = (buffer >> (bits - 4)) & 0x0f; // repeat count (packed) or pixel count (literal)
439      bits -= 4;
436440
437      if (t)      /* count of different pixels */
438      {
439         for ( ; count; count--)
441      if (literal_data)      /* count of different pixels */
442      {     
443         for ( ; count >= 0; count--)
440444         {
441            if (p < bits)
445            if (bits < bits_per_pixel)
442446            {
443447               j++;
444448               if (j >= state->m_blitter.mem[state->m_blitter.bitmap])
445449                  return;
446               p += 8;
447               b = (b << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j];
450               bits += 8;
451               buffer = (buffer << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j];
448452               state->m_blitter.memory_accesses++;
449453            }
450454
451            color = state->m_blitter.color[(b >> (p - bits)) & mask];
452            p -= bits;
453            for ( ; wi < (state->m_blitter.width); wi += 0x100, xi += xdir)
455            color = state->m_blitter.color[(buffer >> (bits - bits_per_pixel)) & mask];
456            bits -= bits_per_pixel;
457            width_accum += state->m_blitter.width;
458            for (i = 0; i < (width_accum>>8); i++, xi += xdir)
454459            {
455460               if ((xi >= 0) && (xi < 160))
456461                  lynx_plot_pixel(state, state->m_blitter.mode, xi, y, color);
457462            }
458            wi -= state->m_blitter.width;
463            width_accum &= 0xff;
459464         }
460465      }
461466      else      /* count of same pixels */
462467      {
463         if (count == 1) // 4 bit count value of zero indicates end-of-line in a packed sprite
468         if (count == 0) // 4 bit count value of zero indicates end-of-line in a packed sprite
464469            return;
465470
466         if (p < bits)
471         if (bits < bits_per_pixel)
467472         {
468473            j++;
469474            if (j >= state->m_blitter.mem[state->m_blitter.bitmap])
470475               return;
471            p += 8;
472            b = (b << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j];
476            bits += 8;
477            buffer = (buffer << 8) | state->m_blitter.mem[state->m_blitter.bitmap + j];
473478            state->m_blitter.memory_accesses++;
474479         }
475480
476         color = state->m_blitter.color[(b >> (p - bits)) & mask];
477         p -= bits;
481         color = state->m_blitter.color[(buffer >> (bits - bits_per_pixel)) & mask];
482         bits -= bits_per_pixel;
478483
479         for ( ; count; count--)
484         for ( ; count>=0; count--)
480485         {
481            for ( ; (wi < state->m_blitter.width); wi += 0x100, xi += xdir)
486            width_accum += state->m_blitter.width;
487            for (i = 0; i < (width_accum>>8); i++, xi += xdir)
482488            {
483489               if ((xi >= 0) && (xi < 160))
484490                  lynx_plot_pixel(state, state->m_blitter.mode, xi, y, color);
485491            }
486            wi -= state->m_blitter.width;
492            width_accum &= 0xff;
487493         }
488494      }
489495   }
r13635r13636
521527
522528static void lynx_blit_lines(lynx_state *state)
523529{
524   int i, hi, y;
530   int i;
531   INT16 y;
525532   int ydir = 0, xdir = 0;
526533   int flip = 0;
527   int x_temp;
528534
529535   state->m_blitter.everon = FALSE;
530536
531   // flipping sprdemo3
532   // fat bobby 0x10
533   // mirror the sprite in gameplay?
534   xdir = 1;
535
536   if (state->m_blitter.spr_ctl0 & 0x20)   /* Horizontal Flip */
537   {
538      xdir = -1;
539      //state->m_blitter.x--; // causes blank lines in todds adventures, klax, etc
540   }
541
542   ydir = 1;
543
544   if (state->m_blitter.spr_ctl0 & 0x10)   /* Vertical Flip */
545   {
546      ydir = -1;
547      //state->m_blitter.y--; // causes blank lines in todds adventures, klax, etc
548   }
549
550537   switch (state->m_blitter.spr_ctl1 & 0x03)   /* Initial drawing direction */
551538   {
552      case 0: // Down/Right
539      case 0: // Down/Right (quadrant 0)
540         xdir = 1;
541         ydir = 1;
553542         flip = 0;
554543         break;
555      case 1: // Down/Left (blockout)
556         xdir *= -1;
544      case 1: // Down/Left (blockout) (quadrant 3)
545         xdir = -1;
546         ydir = 1;
557547         flip = 3;
558548         break;
559      case 2: // Up/Right (fat bobby)
560         ydir *= -1;
549      case 2: // Up/Right (fat bobby) (quadrant 1)
550         xdir = 1;
551         ydir = -1;
561552         flip = 1;
562553         break;
563      case 3: // Up/Left
564         xdir *= -1;
565         ydir *= -1;
554      case 3: // Up/Left (quadrant 2)
555         xdir = -1;
556         ydir = -1;
566557         flip = 2;
567558         break;
568559   }
569
570   x_temp = state->m_blitter.x;
571   for (y = state->m_blitter.y, hi = 0; (i = state->m_blitter.mem[state->m_blitter.bitmap]); state->m_blitter.bitmap += i)
560   
561   if (state->m_blitter.spr_ctl0 & 0x20)   /* Horizontal Flip */
572562   {
563      xdir *= -1;
564      //state->m_blitter.x_pos -= xdir; // causes blank lines in todds adventures, klax, etc
565   }
566   
567   if (state->m_blitter.spr_ctl0 & 0x10)   /* Vertical Flip */
568   {
569      ydir *= -1;
570      //state->m_blitter.y_pos -= ydir; // causes blank lines in todds adventures, klax, etc
571   }
572   
573   // Set height accumulator based on drawing direction
574   state->m_blitter.height_accumulator = (ydir == 1) ? state->m_blitter.height_offset : 0x00;
575   
576   for (y = state->m_blitter.y_pos - state->m_blitter.yoff; (i = state->m_blitter.mem[state->m_blitter.bitmap]); state->m_blitter.bitmap += i)
577   {
573578      state->m_blitter.memory_accesses++;
574
579   
575580      if (i == 1) // draw next quadrant
576581      {
577582         // centered sprites sprdemo3, fat bobby, blockout
578         hi = 0;
579583         switch (flip & 0x03)
580584         {
581585            case 0:
582586            case 2:
583587               ydir *= -1;
584               state->m_blitter.y += ydir;
588               state->m_blitter.y_pos += ydir;
585589               break;
586
587590            case 1:
588591            case 3:
589592               xdir *= -1;
590               state->m_blitter.x += xdir;
591               x_temp += xdir;
593               state->m_blitter.x_pos += xdir;
592594               break;
593595         }
594
595         y = state->m_blitter.y;
596596         flip++;
597         y = state->m_blitter.y_pos - state->m_blitter.yoff;
598         state->m_blitter.height_accumulator = (ydir == 1) ? state->m_blitter.height_offset : 0x00;
597599         continue;
598600      }
601     
602      INT16 x = state->m_blitter.x_pos - state->m_blitter.xoff;
603      // superclipping
604      if (((x > 159) && (xdir == 1)) || ((x < 0) && (xdir == -1)) || ((y > 101) && (ydir == 1)) || ((y < 0) && (ydir == -1)))
605         continue;
599606
600      for ( ; hi < (state->m_blitter.height); hi += 0x100, y += ydir)
607      state->m_blitter.height_accumulator += state->m_blitter.height;
608      for (int i=0; i < (state->m_blitter.height_accumulator>>8); i++, y += ydir)
601609      {
602610         if (y >= 0 && y < 102)
603611            state->m_blitter.line_function(state, y, xdir);
r13635r13636
608616            logerror("vertical stretch enabled");
609617         }
610618         state->m_blitter.tilt_accumulator += state->m_blitter.tilt;
611         state->m_blitter.x = x_temp + (INT8)((state->m_blitter.tilt_accumulator)>>8);
619         state->m_blitter.x_pos += (state->m_blitter.tilt_accumulator>>8);
620         state->m_blitter.tilt_accumulator &= 0xff;
612621      }
613
614      hi -= state->m_blitter.height;
622      state->m_blitter.height_accumulator &= 0xff;
615623   }
616624
617625   if (state->m_suzy.data[SPRGO] & 0x04)
r13635r13636
726734   state->m_blitter.memory_accesses = 0;
727735   state->m_blitter.mem = (UINT8*)machine.device("maincpu")->memory().space(AS_PROGRAM)->get_read_ptr(0x0000);
728736
729   state->m_blitter.xoff   = GET_WORD(state->m_suzy.data, HOFFL);
730   state->m_blitter.yoff   = GET_WORD(state->m_suzy.data, VOFFL);
731   state->m_blitter.screen = GET_WORD(state->m_suzy.data, VIDBASL);
732   state->m_blitter.colbuf = GET_WORD(state->m_suzy.data, COLLBASL);
733
734737   // these might be never set by the state->m_blitter hardware
735   //state->m_blitter.width   = 0x100;
736   //state->m_blitter.height  = 0x100;
737738   state->m_sprite_collide  = 0;
738739
739740   state->m_blitter.memory_accesses += 2;
r13635r13636
753754
754755      state->m_blitter.spr_ctl0 = state->m_blitter.mem[state->m_blitter.scb + SCB_SPRCTL0];
755756      state->m_blitter.spr_ctl1 = state->m_blitter.mem[state->m_blitter.scb + SCB_SPRCTL1];
756      state->m_suzy.data[SPRCOLL] = state->m_blitter.mem[state->m_blitter.scb + SCB_SPRCOLL];
757      state->m_blitter.spr_coll = state->m_blitter.mem[state->m_blitter.scb + SCB_SPRCOLL];
757758
758759      if(!(state->m_blitter.spr_ctl1 & 0x04)) // sprite will be processed (if sprite is skipped first 5 bytes are still copied to suzy)
759760      {
760761         state->m_blitter.bitmap = GET_WORD(state->m_blitter.mem, state->m_blitter.scb + SCB_SPRDLINE);
761         state->m_suzy.data[HPOSSTRTL] = state->m_blitter.mem[state->m_blitter.scb + SCB_HPOSSTRT];
762         state->m_suzy.data[HPOSSTRTH] = state->m_blitter.mem[state->m_blitter.scb + SCB_HPOSSTRT+1];
763         state->m_suzy.data[VPOSSTRTL] = state->m_blitter.mem[state->m_blitter.scb + SCB_VPOSSTRT];
764         state->m_suzy.data[VPOSSTRTH] = state->m_blitter.mem[state->m_blitter.scb + SCB_VPOSSTRT+1];
762         state->m_blitter.x_pos = GET_WORD(state->m_blitter.mem, state->m_blitter.scb + SCB_HPOSSTRT);
763         state->m_blitter.y_pos = GET_WORD(state->m_blitter.mem, state->m_blitter.scb + SCB_VPOSSTRT);
765764
766765         switch(state->m_blitter.spr_ctl1 & 0x30) // reload sprite scaling
767766         {
r13635r13636
781780            else
782781               palette_offset = 0x0b;
783782
784            colors = lynx_colors[state->m_blitter.mem[state->m_blitter.scb] >> 6];
783            colors = lynx_colors[state->m_blitter.spr_ctl0 >> 6];
785784
786785            for (i = 0; i < colors / 2; i++)
787786            {
r13635r13636
792791         }
793792       }
794793
795
796
797
798
794       
799795      if (!(state->m_blitter.spr_ctl1 & 0x04))      // if 0, we skip this sprite
800796      {
801797         state->m_blitter.colpos = GET_WORD(state->m_suzy.data, COLLOFFL) + state->m_blitter.scb;  //????
802         state->m_blitter.x = (INT16)GET_WORD(state->m_suzy.data, HPOSSTRTL) - state->m_blitter.xoff;
803         state->m_blitter.y = (INT16)GET_WORD(state->m_suzy.data, VPOSSTRTL) - state->m_blitter.yoff;
804798         state->m_blitter.memory_accesses += 6;
805799
806800         state->m_blitter.mode = state->m_blitter.spr_ctl0 & 0x07;
r13635r13636
810804         else
811805            state->m_blitter.line_function = blit_rle_line[state->m_blitter.spr_ctl0 >> 6];
812806
813         if (!(state->m_blitter.mem[state->m_blitter.scb + SCB_SPRCOLL] & 0x20) && !(state->m_suzy.data[SPRSYS] & 0x20))
807         if (!(state->m_blitter.spr_coll & 0x20) && !(state->m_suzy.data[SPRSYS] & 0x20))
814808         {
815809            switch (state->m_blitter.mode)
816810            {
r13635r13636
822816               case SHADOW:
823817                  state->m_sprite_collide = 1;
824818                  state->m_blitter.mem[state->m_blitter.colpos] = 0;
825                  state->m_blitter.spritenr = state->m_blitter.mem[state->m_blitter.scb + SCB_SPRCOLL] & 0x0f;
819                  state->m_blitter.spritenr = state->m_blitter.spr_coll & 0x0f;
826820            }
827821         }
828822
r13635r13636
971965         return state->m_blitter.scb_next & 0xff;
972966      case SCBNEXTH:
973967         return state->m_blitter.scb_next>>8;
974      // case SPRDLINEL:
975      // case HPOSSTRTL:
976      // case VPOSSTRTL:
968      case SPRDLINEL:
969         return state->m_blitter.bitmap & 0xff;
970      case SPRDLINEH:
971         return state->m_blitter.bitmap>>8;
972      case HPOSSTRTL:
973         return state->m_blitter.x_pos & 0xff;
974      case HPOSSTRTH:
975         return state->m_blitter.x_pos>>8;
976      case VPOSSTRTL:
977         return state->m_blitter.y_pos & 0xff;
978      case VPOSSTRTH:
979         return state->m_blitter.y_pos>>8;
977980      case SPRHSIZL:
978981         return state->m_blitter.width & 0xff;
979982      case SPRHSIZH:
r13635r13636
993996      // case SPRDOFFL:
994997      // case SPRVPOSL:
995998      // case COLLOFFL:
996      //case VSIZACUML:
999      case VSIZACUML:
1000         return state->m_blitter.height_accumulator & 0xff;
1001      case VSIZACUMH:
1002         return state->m_blitter.height_accumulator>>8;
9971003      case HSIZOFFL:
9981004         return state->m_blitter.width_offset & 0xff;
9991005      case HSIZOFFH:
r13635r13636
10071013      case SCBADRH:
10081014         return state->m_blitter.scb>>8;
10091015      //case PROCADRL:
1010      case SPRCTL0:
1011         return state->m_blitter.spr_ctl0;
1012      case SPRCTL1:
1013         return state->m_blitter.spr_ctl1;
10141016      case SUZYHREV:
10151017         return 0x01; // must not be 0 for correct power up
10161018      case SPRSYS:   /* Better check this with docs! */
r13635r13636
10671069         value = *(space->machine().region("user1")->base() + (state->m_suzy.high * state->m_granularity) + state->m_suzy.low);
10681070         state->m_suzy.low = (state->m_suzy.low + 1) & (state->m_granularity - 1);
10691071         break;
1070      case RCART_BANK1: /* we need bank 1 emulation!!! */
1072      //case RCART_BANK1: /* we need bank 1 emulation!!! */
1073      case SPRCTL0:
1074      case SPRCTL1:
1075      case SPRCOLL:
1076      case SPRINIT:
1077      //case SUZYBUSEN:
1078      case SPRGO:
1079         logerror("read from write only register %x\n", offset);
1080         value = 0;
1081         break;
10711082      default:
10721083         value = state->m_suzy.data[offset];
10731084   }
1074//  logerror("suzy read %.2x %.2x\n",offset,data);
1085   //logerror("suzy read %.2x %.2x\n",offset,value);
10751086   return value;
10761087}
10771088
r13635r13636
10961107         state->m_blitter.tilt_accumulator = data; // upper byte forced to zero see above.
10971108         break;
10981109      case TILTACUMH:
1110         state->m_blitter.tilt_accumulator &= 0xff;
10991111         state->m_blitter.tilt_accumulator |= data<<8;
11001112         break;
11011113      case HOFFL:
11021114         state->m_blitter.xoff = data;
11031115         break;
11041116      case HOFFH:
1117         state->m_blitter.xoff &= 0xff;
11051118         state->m_blitter.xoff |= data<<8;
11061119         break;
11071120      case VOFFL:
11081121         state->m_blitter.yoff = data;
11091122         break;
11101123      case VOFFH:
1124         state->m_blitter.yoff &= 0xff;
11111125         state->m_blitter.yoff |= data<<8;
11121126         break;
11131127      case VIDBASL:
11141128         state->m_blitter.screen = data;
11151129         break;
11161130      case VIDBASH:
1131         state->m_blitter.screen &= 0xff;
11171132         state->m_blitter.screen |= data<<8;
11181133         break;
11191134      case COLLBASL:
11201135         state->m_blitter.colbuf = data;
11211136         break;
11221137      case COLLBASH:
1138         state->m_blitter.colbuf &= 0xff;
11231139         state->m_blitter.colbuf |= data<<8;
11241140         break;
11251141      case SCBNEXTL:
11261142         state->m_blitter.scb_next = data;
11271143         break;
11281144      case SCBNEXTH:
1145         state->m_blitter.scb_next &= 0xff;
11291146         state->m_blitter.scb_next |= data<<8;
11301147         break;
1131      // case SPRDLINEL:
1132      // case HPOSSTRTL:
1133      // case VPOSSTRTL:
1148      case SPRDLINEL:
1149         state->m_blitter.bitmap = data;
1150         break;
1151      case SPRDLINEH:
1152         state->m_blitter.bitmap &= 0xff;
1153         state->m_blitter.bitmap |= data<<8;
1154         break;
1155      case HPOSSTRTL:
1156         state->m_blitter.x_pos = data;
1157      case HPOSSTRTH:
1158         state->m_blitter.x_pos &= 0xff;
1159         state->m_blitter.x_pos |= data<<8;
1160      case VPOSSTRTL:
1161         state->m_blitter.y_pos = data;
1162      case VPOSSTRTH:
1163         state->m_blitter.y_pos &= 0xff;
1164         state->m_blitter.y_pos |= data<<8;
11341165      case SPRHSIZL:
11351166         state->m_blitter.width = data;
11361167         break;
11371168      case SPRHSIZH:
1169         state->m_blitter.width &= 0xff;
11381170         state->m_blitter.width |= data<<8;
11391171         break;
11401172      case SPRVSIZL:
11411173         state->m_blitter.height = data;
11421174         break;
11431175      case SPRVSIZH:
1176         state->m_blitter.height &= 0xff;
11441177         state->m_blitter.height |= data<<8;
11451178         break;
11461179      case STRETCHL:
11471180         state->m_blitter.stretch = data;
11481181         break;
11491182      case STRETCHH:
1183         state->m_blitter.stretch &= 0xff;
11501184         state->m_blitter.stretch |= data<<8;
11511185         break;
11521186      case TILTL:
11531187         state->m_blitter.stretch = data;
11541188         break;
11551189      case TILTH:
1190         state->m_blitter.stretch &= 0xff;
11561191         state->m_blitter.stretch |= data<<8;
11571192         break;
11581193      // case SPRDOFFL:
11591194      // case SPRVPOSL:
11601195      // case COLLOFFL:
1161      //case VSIZACUML:
1196      case VSIZACUML:
1197         state->m_blitter.height_accumulator = data;
1198         break;
1199      case VSIZACUMH:
1200         state->m_blitter.height_accumulator &= 0xff;
1201         state->m_blitter.height_accumulator |= data<<8;
1202         break;
11621203      case HSIZOFFL:
11631204         state->m_blitter.width_offset = data;
11641205         break;
11651206      case HSIZOFFH:
1207         state->m_blitter.width_offset &= 0xff;
11661208         state->m_blitter.width_offset |= data<<8;
11671209         break;
11681210      case VSIZOFFL:
11691211         state->m_blitter.height_offset = data;
11701212         break;
11711213      case VSIZOFFH:
1214         state->m_blitter.height_offset &= 0xff;
11721215         state->m_blitter.height_offset |= data<<8;
11731216         break;
11741217      case SCBADRL:
11751218         state->m_blitter.scb = data;
11761219         break;
11771220      case SCBADRH:
1221         state->m_blitter.scb &= 0xff;
11781222         state->m_blitter.scb |= data<<8;
11791223         break;
11801224      //case PROCADRL:
r13635r13636
12311275      case SPRCTL1:
12321276         state->m_blitter.spr_ctl1 = data;
12331277         break;
1278      case SPRCOLL:
1279         state->m_blitter.spr_coll = data;
1280         break;
12341281      case SPRGO:
12351282         if (data & 0x01)
12361283         {
r13635r13636
12381285            lynx_blitter(space->machine());
12391286         }
12401287         break;
1288      case JOYSTICK:
1289      case SWITCHES:
1290         logerror("warning: write to read-only button registers\n");
1291         break;
12411292   }
12421293}
12431294
r13635r13636
13111362      return;
13121363   }
13131364
1314   // Documentation states lower two bits of buffer address are ignored (thus 0xfc mask)
1315   j = ((state->m_mikey.data[0x94] & 0xfc)  | (state->m_mikey.data[0x95]<<8)) + state->m_line_y * 160 / 2;
1365   // Documentation states lower two bits of buffer address are ignored (thus 0xfffc mask)
1366   j = (state->m_mikey.disp_addr & 0xfffc) + state->m_line_y * 160 / 2;
1367     
13161368   if (state->m_mikey.data[0x92] & 0x02)
1369   {
13171370      j -= 160 * 102 / 2 - 1;
1318
1319   if (state->m_mikey.data[0x92] & 0x02)
1320   {
13211371      for ( ; state->m_line_y < yend; state->m_line_y++)
13221372      {
13231373         line = BITMAP_ADDR16(machine.generic.tmpbitmap, 102 - 1 - state->m_line_y, 0);
r13635r13636
14081458   switch ( which ) // count down linked timers
14091459   {
14101460   case 0:
1461      if ((state->m_line == 2) || (state->m_line == 3) || (state->m_line == 4))
1462      {
1463         //state->m_mikey.vb_rest = 1;
1464      }
1465      else
1466         state->m_mikey.vb_rest = 0;
1467      if (state->m_line == 3)
1468      {
1469         state->m_mikey.disp_addr = state->m_mikey.data[0x94] | (state->m_mikey.data[0x95] << 8);
1470         lynx_draw_lines( machine, -1 );
1471      }
14111472      lynx_timer_count_down( machine, 2 );
14121473      state->m_line++;
14131474      break;
r13635r13636
14441505      if ( state->m_timer[which].counter == 0 )
14451506      {
14461507         state->m_timer[which].cntrl2 |= 8; // set timer done
1447         lynx_timer_signal_irq(machine, which);
1448         if ( state->m_timer[which].cntrl1 & 0x10 ) // if reload enabled
1449         {
1450            state->m_timer[which].counter = state->m_timer[which].bakup;
1508            lynx_timer_signal_irq(machine, which);
1509            if ( state->m_timer[which].cntrl1 & 0x10 ) // if reload enabled
1510            {
1511               state->m_timer[which].counter = state->m_timer[which].bakup;
14511512            // should we unset timer done?
1452         }
1453         else
1454         {
1513            }
1514            else
1515            {
14551516            state->m_timer[which].counter--; // Is this correct or should it stop at zero?
1456         }
1517            }
14571518         return;
14581519      }
14591520   }
r13635r13636
15391600         state->m_timer[which].counter = data;
15401601         break;
15411602      case 3:
1542         // Should we be ignoring writes to the timer done bit?
1543         state->m_timer[which].cntrl2 = (state->m_timer[which].cntrl2 & 0x08) | (data & ~0x08);
1603         state->m_timer[which].cntrl2 = (state->m_timer[which].cntrl2 & ~0x08) | (data & 0x08);
15441604         break;
15451605   }
15461606
r13635r13636
17041764      value |= (direction & 0x01) ? (state->m_mikey.data[offset] & 0x01) : 0x01;   // External Power input
17051765      value |= (direction & 0x02) ? (state->m_mikey.data[offset] & 0x02) : 0x00;   // Cart Address Data output (0 turns cart power on)
17061766      value |= (direction & 0x04) ? (state->m_mikey.data[offset] & 0x04) : 0x04;   // noexp input
1707      // REST read returns actual rest state anded with rest output bit (to be implemented)
1708      value |= (direction & 0x08) ? (state->m_mikey.data[offset] & 0x08) : 0x00;   // rest output
1767      // REST read returns actual rest state anded with rest output bit
1768      value |= (direction & 0x08) ? (state->m_mikey.data[offset] & 0x08) & (state->m_mikey.vb_rest<<3) : 0x00;   // rest output
17091769      value |= (direction & 0x10) ? (state->m_mikey.data[offset] & 0x10) : 0x10;   // audin input
17101770      /* Hack: we disable COMLynx  */
17111771      value |= 0x04;
r13635r13636
17211781      value = state->m_mikey.data[offset];
17221782      //logerror( "mikey read %.2x %.2x\n", offset, value );
17231783   }
1724
17251784   return value;
17261785}
17271786
r13635r13636
18171876         //logerror("CPUSLEEP request \n");
18181877      }
18191878      break;
1879   case 0x94: case 0x95:
1880      state->m_mikey.data[offset]=data;
1881      break;
1882   case 0x9c: case 0x9d: case 0x9e:
1883      state->m_mikey.data[offset]=data;
1884      logerror("Mtest%d write: %x\n", offset&0x3, data);
1885      break;
18201886
18211887   default:
18221888      state->m_mikey.data[offset]=data;
r13635r13636
18841950   state->m_mikey.data[0x90] = 0x00;
18851951   state->m_mikey.data[0x92] = 0x00;
18861952
1953/*
1954   state->m_suzy.data[MATH_A] = 0xff;
1955   state->m_suzy.data[MATH_B] = 0xff;
1956   state->m_suzy.data[MATH_C] = 0xff;
1957   state->m_suzy.data[MATH_D] = 0xff;
1958   
1959   state->m_suzy.data[MATH_E] = 0xff;
1960   state->m_suzy.data[MATH_F] = 0xff;
1961   state->m_suzy.data[MATH_G] = 0xff;
1962   state->m_suzy.data[MATH_H] = 0xff;
1963   
1964   state->m_suzy.data[MATH_J] = 0xff;
1965   state->m_suzy.data[MATH_K] = 0xff;
1966   state->m_suzy.data[MATH_L] = 0xff;
1967   state->m_suzy.data[MATH_M] = 0xff;
1968   state->m_suzy.data[MATH_P] = 0xff;
1969*/
1970
18871971   lynx_uart_reset(state);
18881972
18891973   // hack to allow current object loading to work
src/mess/includes/lynx.h
r13635r13636
2222   UINT16 screen;
2323   UINT16 colbuf;
2424   UINT16 colpos; // byte where value of collision is written
25   UINT16 xoff, yoff;
25   INT16 xoff, yoff;
2626   // in command
2727   int mode;
28   UINT8 spr_coll;
2829   UINT8 spritenr;
29   INT16 x,y;
30   INT16 x_pos,y_pos;
3031   UINT16 width, height; // uint16 important for blue lightning
3132   INT16 tilt_accumulator;
32   UINT16 vertical_size_accumulator;
33   UINT16 height_accumulator, width_accumulator;
3334   UINT16 width_offset, height_offset;
3435   INT16 stretch, tilt;
3536   UINT8 color[16]; // or stored
r13635r13636
6768typedef struct
6869{
6970   UINT8 data[0x100];
71   UINT16 disp_addr;
72   UINT8 vb_rest;
7073} MIKEY;
7174
7275typedef struct
src/mess/drivers/lynx.c
r13635r13636
2727
2828static INPUT_PORTS_START( lynx )
2929   PORT_START("JOY")
30   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("A")
31   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("B")
30   PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A")
31   PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B")
3232   PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Opt 2") PORT_CODE(KEYCODE_2)
3333   PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Opt 1") PORT_CODE(KEYCODE_1)
3434   PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT )

Previous 15994 Revisions Next


© 1998-2018 The MESS Team