Previous 199869 Revisions Next

r32713 Monday 13th October, 2014 at 22:28:15 UTC by Carl
upd7220: add Bresenham arc and complete char drawing [Carl]
[src/emu/video]upd7220.c upd7220.h

trunk/src/emu/video/upd7220.c
r32712r32713
1818        - DMAR
1919        - DMAW
2020    - incomplete / unimplemented FIGD / GCHRD draw modes
21        - Arc
2221        - FIGD character
2322        - slanted character
24        - GCHRD character (needs rewrite)
2523    - read-modify-write cycle
2624        - read data
2725        - modify data
r32712r32713
134132
135133static const int x_dir[8] = { 0, 1, 1, 1, 0,-1,-1,-1};
136134static const int y_dir[8] = { 1, 1, 0,-1,-1,-1, 0, 1};
137static const int x_dir_dot[8] = { 1, 1, 0,-1,-1,-1, 0, 1};
138static const int y_dir_dot[8] = { 0,-1,-1,-1, 0, 1, 1, 1};
139135
140136
141
142137//**************************************************************************
143138//  GLOBAL VARIABLES
144139//**************************************************************************
r32712r32713
206201   space().write_byte(address, data);
207202}
208203
209
210204//-------------------------------------------------
211205//  fifo_clear -
212206//-------------------------------------------------
r32712r32713
429423
430424
431425//-------------------------------------------------
432//  advance_ead -
433//-------------------------------------------------
434
435inline void upd7220_device::advance_ead()
436{
437   #define EAD         m_ead
438   #define DAD         m_dad
439   #define P           x_dir[m_figs.m_dir] + (y_dir[m_figs.m_dir] * m_pitch)
440   #define MSB(value)  (BIT(value, 15))
441   #define LSB(value)  (BIT(value, 0))
442   #define LR(value)   ((value << 1) | MSB(value))
443   #define RR(value)   ((LSB(value) << 15) | (value >> 1))
444
445   switch (m_draw_mode & 0x07)
446   {
447   case 0:
448      EAD += P;
449      break;
450
451   case 1:
452      EAD += P;
453      if (MSB(DAD)) EAD++;
454      DAD = LR(DAD);
455      break;
456
457   case 2:
458      if (MSB(DAD)) EAD++;
459      DAD = LR(DAD);
460      break;
461
462   case 3:
463      EAD -= P;
464      if (MSB(DAD)) EAD++;
465      DAD = LR(DAD);
466      break;
467
468   case 4:
469      EAD -= P;
470      break;
471
472   case 5:
473      EAD -= P;
474      if (LSB(DAD)) EAD--;
475      DAD = RR(DAD);
476      break;
477
478   case 6:
479      if (LSB(DAD)) EAD--;
480      DAD = RR(DAD);
481      break;
482
483   case 7:
484      EAD += P;
485      if (LSB(DAD)) EAD--;
486      DAD = RR(DAD);
487      break;
488   }
489
490   EAD &= 0x3ffff;
491}
492
493
494//-------------------------------------------------
495426//  read_vram -
496427//-------------------------------------------------
497428
r32712r32713
523454      }
524455
525456      m_figs.m_dc--;
526      advance_ead();
457      m_ead += x_dir[m_figs.m_dir] + (y_dir[m_figs.m_dir] * m_pitch);
458      m_ead &= 0x3ffff;
527459   }
528460
529461   if (m_figs.m_dc == 0)
r32712r32713
601533            break;
602534      }
603535
604      advance_ead();
536      m_ead += x_dir[m_figs.m_dir] + (y_dir[m_figs.m_dir] * m_pitch);
537      m_ead &= 0x3ffff;
605538   }
606539}
607540
608541
609542//-------------------------------------------------
610//  check_pattern -
611//-------------------------------------------------
612
613inline UINT16 upd7220_device::check_pattern(UINT16 pattern)
614{
615   UINT16 res = 0;
616
617   switch (m_bitmap_mod & 3)
618   {
619      case 0: res = pattern; break; //replace
620      case 1: res = pattern; break; //complement
621      case 2: res = 0; break; //reset to zero
622      case 3: res |= 0xffff; break; //set to one
623   }
624
625   return res;
626}
627
628
629//-------------------------------------------------
630543//  get_text_partition -
631544//-------------------------------------------------
632545
r32712r32713
681594   m_fifo_ptr(-1),
682595   m_fifo_dir(0),
683596   m_mode(0),
684   m_draw_mode(0),
685597   m_de(0),
686598   m_m(0),
687599   m_aw(0),
r32712r32713
846758//  draw_pixel -
847759//-------------------------------------------------
848760
849void upd7220_device::draw_pixel(int x, int y, UINT8 tile_data)
761void upd7220_device::draw_pixel(int x, int y, int xi, UINT16 tile_data)
850762{
851763   UINT32 addr = (y * m_pitch * 2 + (x >> 3)) & 0x3ffff;
852   int dad = x & 0x7;
853764   UINT8 data = readbyte(addr);
854   UINT8 new_pixel = (tile_data) & (0x80 >> (dad));
765   UINT8 new_pixel = (xi & 8 ? tile_data >> 8 : tile_data & 0xff) & (0x80 >> (xi & 7));
766   new_pixel = new_pixel ? (0xff & (0x80 >> (x & 7))) : 0;
855767   
856768   switch(m_bitmap_mod)
857769   {
858770      case 0: //replace
859         writebyte(addr, data & ~(0x80 >> (dad)));
860         writebyte(addr, data | new_pixel);
771         writebyte(addr, (data & ~(0x80 >> (x & 7))) | new_pixel);
861772         break;
862773      case 1: //complement
863         writebyte(addr, data ^ (new_pixel));
774         writebyte(addr, data ^ new_pixel);
864775         break;
865776      case 2: //reset
866         writebyte(addr, data & ((new_pixel) ? 0xff : ~(0x80 >> (dad))));
777         writebyte(addr, data & ~new_pixel);
867778         break;
868779      case 3: //set
869780         writebyte(addr, data | new_pixel);
r32712r32713
883794   const int line_y_dir[8] = { 1, 0, 0,-1,-1, 0, 0, 1};
884795   const int line_x_step[8] = { 1, 0, 0, 1,-1, 0, 0,-1 };
885796   const int line_y_step[8] = { 0, 1,-1, 0, 0,-1, 1, 0 };
886   UINT16 line_pattern;
797   UINT16 pattern = (m_ra[8]) | (m_ra[9]<<8);
887798   int line_step = 0;
888   UINT8 dot;
889799
890   line_size = m_figs.m_dc + 1;
891   line_pattern = check_pattern((m_ra[8]) | (m_ra[9]<<8));
800   LOG(("uPD7220 line check: %d %d %02x %08x %d %d\n",x,y,m_figs.m_dir,m_ead,m_figs.m_d1,m_figs.m_dc));
892801
802   line_size = m_figs.m_dc;
803
893804   for(i = 0;i<line_size;i++)
894805   {
895806      line_step = (m_figs.m_d1 * i);
896      line_step/= (m_figs.m_dc + 1);
897      line_step >>= 1;
898      dot = ((line_pattern >> (i & 0xf)) & 1) << 7;
899      draw_pixel(x + (line_step*line_x_step[m_figs.m_dir]),y + (line_step*line_y_step[m_figs.m_dir]),dot >> ((x + line_step*line_x_step[m_figs.m_dir]) & 0x7));
807      line_step/= m_figs.m_dc;
808      ++line_step >>= 1;
809      draw_pixel(x + (line_step*line_x_step[m_figs.m_dir]),y + (line_step*line_y_step[m_figs.m_dir]),i,pattern);
900810      x += line_x_dir[m_figs.m_dir];
901811      y += line_y_dir[m_figs.m_dir];
902812   }
r32712r32713
909819   m_dad = x & 0x0f;
910820}
911821
822//-------------------------------------------------
823//  draw_arc -
824//-------------------------------------------------
912825
826void upd7220_device::draw_arc(int x, int y)
827{
828   int len, xi = m_figs.m_d + 1, yi = 0, err = -m_figs.m_d;
829   int x0, y0;
830   UINT16 pattern = (m_ra[8]) | (m_ra[9]<<8);
831   const int dot_dir[4] = {1, -1, -1, 1};
832
833   switch(m_figs.m_dir & 3)
834   {
835      case 1:
836      case 2:
837         x0 = x;
838         y0 = y + xi * dot_dir[m_figs.m_dir >> 1];
839         break;
840      default:
841         x0 = x + xi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3];
842         y0 = y;
843         break;
844   }
845
846   LOG(("uPD7220 arc check: %d %d %02x %08x %d %d %d\n",x,y,m_figs.m_dir,m_ead,m_figs.m_dm,m_figs.m_dc,m_figs.m_d));
847
848   for(int i = 0; i < m_figs.m_dc; i++)
849   {
850      if(i >= m_figs.m_dm)
851      {
852         switch(m_figs.m_dir & 3)
853         {
854            case 1:
855            case 2:
856               draw_pixel(yi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + x0, xi * dot_dir[m_figs.m_dir >> 1] + y0, i, pattern);
857               break;
858            default:
859               draw_pixel(xi * dot_dir[m_figs.m_dir >> 1] + x0, yi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + y0, i, pattern);
860               break;
861         }
862      }
863      yi++;
864      if(err < 0)
865         err += (yi + 1) << 1;
866      else
867      {
868         xi--;
869         err += (yi - xi + 1) << 1;
870      }
871   }
872   switch(m_figs.m_dir & 3)
873   {
874      case 1:
875      case 2:
876         x += m_figs.m_dc * dot_dir[((m_figs.m_dir >> 1) + 3) & 3];
877         break;
878      default:
879         y += m_figs.m_dc * dot_dir[m_figs.m_dir >> 1];
880         break;
881   }
882
883   m_ead = (x >> 4) + (y * m_pitch);
884   m_dad = x & 0x0f;
885}
886
913887//-------------------------------------------------
914888//  draw_rectangle -
915889//-------------------------------------------------
r32712r32713
920894   const int rect_x_dir[8] = { 0, 1, 0,-1, 1, 1,-1,-1 };
921895   const int rect_y_dir[8] = { 1, 0,-1, 0, 1,-1,-1, 1 };
922896   UINT8 rect_type,rect_dir;
923   UINT16 line_pattern;
924   UINT8 dot;
897   UINT16 pattern = (m_ra[8]) | (m_ra[9]<<8);
925898
926899   LOG(("uPD7220 rectangle check: %d %d %02x %08x\n",x,y,m_figs.m_dir,m_ead));
927900
928   line_pattern = check_pattern((m_ra[8]) | (m_ra[9]<<8));
929901   rect_type = (m_figs.m_dir & 1) << 2;
930902   rect_dir = rect_type | (((m_figs.m_dir >> 1) + 0) & 3);
931903
932904   for(i = 0;i < m_figs.m_d;i++)
933905   {
934      dot = ((line_pattern >> ((i+m_dad) & 0xf)) & 1) << 7;
935      draw_pixel(x,y,dot >> (x & 0x7));
906      draw_pixel(x,y,i,pattern);
936907      x+=rect_x_dir[rect_dir];
937908      y+=rect_y_dir[rect_dir];
938909   }
r32712r32713
941912
942913   for(i = 0;i < m_figs.m_d2;i++)
943914   {
944      dot = ((line_pattern >> ((i+m_dad) & 0xf)) & 1) << 7;
945      draw_pixel(x,y,dot >> (x & 0x7));
915      draw_pixel(x,y,i,pattern);
946916      x+=rect_x_dir[rect_dir];
947917      y+=rect_y_dir[rect_dir];
948918   }
r32712r32713
951921
952922   for(i = 0;i < m_figs.m_d;i++)
953923   {
954      dot = ((line_pattern >> ((i+m_dad) & 0xf)) & 1) << 7;
955      draw_pixel(x,y,dot >> (x & 0x7));
924      draw_pixel(x,y,i,pattern);
956925      x+=rect_x_dir[rect_dir];
957926      y+=rect_y_dir[rect_dir];
958927   }
r32712r32713
961930
962931   for(i = 0;i < m_figs.m_d2;i++)
963932   {
964      dot = ((line_pattern >> ((i+m_dad) & 0xf)) & 1) << 7;
965      draw_pixel(x,y,dot >> (x & 0x7));
933      draw_pixel(x,y,i,pattern);
966934      x+=rect_x_dir[rect_dir];
967935      y+=rect_y_dir[rect_dir];
968936   }
r32712r32713
979947
980948void upd7220_device::draw_char(int x, int y)
981949{
982   int xi,yi;
983   int xsize,ysize;
984   UINT8 tile_data;
950   int isize,psize;
951   UINT16 tile_data = 0;
985952
986   /* snippet for character checking */
987   #if 0
988   if((m_figs.m_dir & 7) == 3)
989   for(yi=0;yi<8;yi++)
990   {
991      for(xi=0;xi<8;xi++)
992      {
993         printf("%d",(m_ra[(yi & 7) | 8] >> xi) & 1);
994      }
995      printf("\n");
996   }
997   #endif
953   LOG(("uPD7220 char check: %d %d %02x %08x %d %d\n",x,y,m_figs.m_dir,m_ead,m_figs.m_d,m_figs.m_dc));
998954
999   xsize = m_figs.m_d & 0x3ff;
955   isize = m_figs.m_d & 0x3ff;
1000956   /* Guess: D has presumably upper bits for ysize, QX-10 relies on this (TODO: check this on any real HW) */
1001   ysize = ((m_figs.m_d & 0x400) + m_figs.m_dc) + 1;
957   psize = ((m_figs.m_d & 0x400) + m_figs.m_dc) + 1;
1002958
1003   /* TODO: internal direction, zooming, size stuff bigger than 8, rewrite using draw_pixel function */
1004   if((m_figs.m_dir & 7) == 0)
1005   {   
1006      for(yi=0;yi<8;yi++)
1007      {
1008         for(xi=0;xi<8;xi++)
1009         {
1010            UINT8 dot = (m_ra[((7-xi) & 7) | 8]);
1011            dot >>= yi;
1012            dot &= 1;
1013            dot*=0xff;
1014            draw_pixel(x+xi,y+yi,dot);
1015         }
1016      }
1017   }
1018   else
959   for(int pi = 0; pi < psize; pi++)
1019960   {
1020      for(yi=0;yi<ysize;yi++)
961      tile_data = BITSWAP8(m_ra[((psize-1-pi) & 7) | 8],0,1,2,3,4,5,6,7);
962      tile_data = (tile_data << 8) | (tile_data & 0xff);
963      for(int pz = 0; pz <= m_gchr; pz++)
1021964      {
1022         switch(m_figs.m_dir & 7)
965         for(int ii = 0, curpixel = 0; ii < isize; ii++)
1023966         {
1024            case 2: tile_data = BITSWAP8(m_ra[((yi) & 7) | 8],0,1,2,3,4,5,6,7); break;
1025            case 6: tile_data = BITSWAP8(m_ra[((ysize-1-yi) & 7) | 8],7,6,5,4,3,2,1,0); break;
1026            default: tile_data = BITSWAP8(m_ra[((yi) & 7) | 8],7,6,5,4,3,2,1,0);
1027                  logerror("upd7220 draw char: %d %d %d\n",m_figs.m_dir,xsize,ysize);
1028                  break;
967            for(int iz = 0; iz <= m_gchr; iz++)
968            {
969               draw_pixel(x + (curpixel * x_dir[m_figs.m_dir]), y + (curpixel * y_dir[m_figs.m_dir]), ii, tile_data);
970               curpixel++;
971            }
1029972         }
1030
1031         for(xi=0;xi<xsize;xi++)
1032         {
1033            UINT32 addr = ((y+yi) * m_pitch * 2) + ((x+xi) >> 3);
1034
1035            writebyte(addr & 0x3ffff, readbyte(addr & 0x3ffff) & ~(1 << (xi & 7)));
1036            writebyte(addr & 0x3ffff, readbyte(addr & 0x3ffff) | ((tile_data) & (1 << (xi & 7))));
1037         }
973         x += x_dir[(m_figs.m_dir + 2) & 7];
974         y += y_dir[(m_figs.m_dir + 2) & 7];
1038975      }
1039976   }
1040   m_ead = ((x+8*x_dir_dot[m_figs.m_dir]) >> 4) + ((y+8*y_dir_dot[m_figs.m_dir]) * m_pitch);
1041   m_dad = ((x+8*x_dir_dot[m_figs.m_dir]) & 0xf);
977
978   m_ead = (x >> 4) + (y * m_pitch);
979   m_dad = (x & 0xf);
1042980}
1043981
1044982
r32712r32713
13591297      break;
13601298
13611299   case COMMAND_FIGD: /* figure draw start */
1362      if(m_figs.m_figure_type == 0 || m_figs.m_figure_type == 4)
1363      {
1364         UINT16 line_pattern = check_pattern((m_ra[8]) | (m_ra[9]<<8));
1365         UINT8 dot = ((line_pattern >> (0 & 0xf)) & 1) << 7;
1366
1367         draw_pixel(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch),dot);
1368      }
1300      if(m_figs.m_figure_type == 0)
1301         draw_pixel(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch),m_dad,(m_ra[8]) | (m_ra[9]<<8));
13691302      else if(m_figs.m_figure_type == 1)
13701303         draw_line(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch));
1304      else if(m_figs.m_figure_type == 4)
1305         draw_arc(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch));
13711306      else if(m_figs.m_figure_type == 8)
13721307         draw_rectangle(((m_ead % m_pitch) << 4) | (m_dad & 0xf),(m_ead / m_pitch));
13731308      else
trunk/src/emu/video/upd7220.h
r32712r32713
136136   inline void update_blank_timer(int state);
137137   inline void recompute_parameters();
138138   inline void reset_figs_param();
139   inline void advance_ead();
140139   inline void read_vram(UINT8 type, UINT8 mod);
141140   inline void write_vram(UINT8 type, UINT8 mod);
142   inline UINT16 check_pattern(UINT16 pattern);
143141   inline void get_text_partition(int index, UINT32 *sad, UINT16 *len, int *im, int *wd);
144142   inline void get_graphics_partition(int index, UINT32 *sad, UINT16 *len, int *im, int *wd);
145143
146   void draw_pixel(int x, int y, UINT8 tile_data);
144   void draw_pixel(int x, int y, int xi, UINT16 tile_data);
147145   void draw_line(int x, int y);
148146   void draw_rectangle(int x, int y);
147   void draw_arc(int x, int y);
149148   void draw_char(int x, int y);
150149   int translate_command(UINT8 data);
151150   void process_fifo();
r32712r32713
182181   int m_fifo_dir;                 // FIFO direction
183182
184183   UINT8 m_mode;                   // mode of operation
185   UINT8 m_draw_mode;              // mode of drawing
186184
187185   int m_de;                       // display enabled
188186   int m_m;                        // 0 = accept external vertical sync (slave mode) / 1 = generate & output vertical sync (master mode)

Previous 199869 Revisions Next


© 1997-2024 The MAME Team