trunk/src/emu/video/upd7220.c
r241693 | r241694 | |
371 | 371 | |
372 | 372 | inline void upd7220_device::recompute_parameters() |
373 | 373 | { |
374 | | int horiz_mult; |
| 374 | int horiz_mult = 16, vert_mult = 1; |
375 | 375 | /* TODO: assume that the pitch also controls number of horizontal pixels in a single cell */ |
376 | 376 | // horiz_mult = 4 if both mixed and interlace? |
377 | | if(((m_mode & UPD7220_MODE_DISPLAY_MASK) == UPD7220_MODE_DISPLAY_MIXED) || |
378 | | ((m_mode & UPD7220_MODE_INTERLACE_MASK) == UPD7220_MODE_INTERLACE_ON)) |
| 377 | if((m_mode & UPD7220_MODE_DISPLAY_MASK) == UPD7220_MODE_DISPLAY_MIXED) |
379 | 378 | horiz_mult = 8; |
380 | | else |
381 | | horiz_mult = 16; |
| 379 | else if((m_mode & UPD7220_MODE_INTERLACE_MASK) == UPD7220_MODE_INTERLACE_ON) |
| 380 | { |
| 381 | // in interlaced mode every line contains both fields |
| 382 | horiz_mult = 8; |
| 383 | vert_mult = 2; |
| 384 | } |
382 | 385 | |
383 | 386 | int horiz_pix_total = (m_hs + m_hbp + m_hfp + m_aw) * horiz_mult; |
384 | | int vert_pix_total = m_vs + m_vbp + m_al + m_vfp; |
| 387 | int vert_pix_total = (m_vs + m_vbp + m_al + m_vfp) * vert_mult; |
385 | 388 | |
386 | 389 | //printf("%d %d %d %d\n",m_hs,m_hbp,m_aw,m_hfp); |
387 | 390 | //printf("%d %d\n",m_aw * 8,m_pitch * 8); |
r241693 | r241694 | |
396 | 399 | visarea.min_x = 0; //(m_hs + m_hbp) * 8; |
397 | 400 | visarea.min_y = 0; //m_vs + m_vbp; |
398 | 401 | visarea.max_x = m_aw * horiz_mult - 1;//horiz_pix_total - (m_hfp * 8) - 1; |
399 | | visarea.max_y = m_al - 1;//vert_pix_total - m_vfp - 1; |
| 402 | visarea.max_y = m_al * vert_mult - 1;//vert_pix_total - m_vfp - 1; |
400 | 403 | |
401 | 404 | LOG(("uPD7220 '%s' Screen: %u x %u @ %f Hz\n", tag(), horiz_pix_total, vert_pix_total, 1 / ATTOSECONDS_TO_DOUBLE(refresh))); |
402 | 405 | LOG(("Visible Area: (%u, %u) - (%u, %u)\n", visarea.min_x, visarea.min_y, visarea.max_x, visarea.max_y)); |
r241693 | r241694 | |
798 | 801 | |
799 | 802 | void upd7220_device::draw_line(int x, int y) |
800 | 803 | { |
801 | | int line_size,i; |
802 | | const int line_x_dir[8] = { 0, 1, 1, 0, 0,-1,-1, 0}; |
803 | | const int line_y_dir[8] = { 1, 0, 0,-1,-1, 0, 0, 1}; |
804 | | const int line_x_step[8] = { 1, 0, 0, 1,-1, 0, 0,-1 }; |
805 | | const int line_y_step[8] = { 0, 1,-1, 0, 0,-1, 1, 0 }; |
| 804 | int xi, yi; |
| 805 | int d = (m_figs.m_d & 0x2000) ? (INT16)(m_figs.m_d | 0xe000) : m_figs.m_d; |
| 806 | int d2 = (m_figs.m_d2 & 0x2000) ? (INT16)(m_figs.m_d2 | 0xe000) : m_figs.m_d2; |
806 | 807 | UINT16 pattern = (m_ra[8]) | (m_ra[9]<<8); |
807 | | int line_step = 0; |
| 808 | const int dot_dir[4] = {1, -1, -1, 1}; |
808 | 809 | |
809 | 810 | LOG(("uPD7220 line check: %d %d %02x %08x %d %d %d\n",x,y,m_figs.m_dir,m_ead,m_figs.m_d1,m_figs.m_dc,m_bitmap_mod)); |
810 | 811 | |
811 | | line_size = m_figs.m_dc; |
| 812 | for(yi = xi = 0; yi <= m_figs.m_dc; yi++) |
| 813 | { |
| 814 | switch(m_figs.m_dir & 3) |
| 815 | { |
| 816 | case 1: |
| 817 | case 2: |
| 818 | draw_pixel(yi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + x, xi * dot_dir[m_figs.m_dir >> 1] + y, yi, pattern); |
| 819 | break; |
| 820 | default: |
| 821 | draw_pixel(xi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3] + x, yi * dot_dir[m_figs.m_dir >> 1] + y, yi, pattern); |
| 822 | break; |
| 823 | } |
| 824 | if(d > 0) |
| 825 | { |
| 826 | xi++; |
| 827 | d += d2; |
| 828 | } |
| 829 | else |
| 830 | d += m_figs.m_d1; |
| 831 | } |
812 | 832 | |
813 | | for(i = 0;i<line_size;i++) |
| 833 | switch(m_figs.m_dir & 3) |
814 | 834 | { |
815 | | line_step = (m_figs.m_d1 * i); |
816 | | line_step/= m_figs.m_dc; |
817 | | ++line_step >>= 1; |
818 | | draw_pixel(x + (line_step*line_x_step[m_figs.m_dir]),y + (line_step*line_y_step[m_figs.m_dir]),i,pattern); |
819 | | x += line_x_dir[m_figs.m_dir]; |
820 | | y += line_y_dir[m_figs.m_dir]; |
| 835 | case 1: |
| 836 | case 2: |
| 837 | x += yi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3]; |
| 838 | y += xi * dot_dir[m_figs.m_dir >> 1]; |
| 839 | break; |
| 840 | default: |
| 841 | x += xi * dot_dir[((m_figs.m_dir >> 1) + 3) & 3]; |
| 842 | y += yi * dot_dir[m_figs.m_dir >> 1]; |
| 843 | break; |
821 | 844 | } |
822 | 845 | |
823 | | /* TODO: check me*/ |
824 | | x += (line_step*line_x_step[m_figs.m_dir]); |
825 | | y += (line_step*line_y_step[m_figs.m_dir]); |
826 | | |
827 | 846 | m_ead = (x >> 4) + (y * (m_pitch >> m_figs.m_gd)); |
828 | 847 | m_dad = x & 0x0f; |
829 | 848 | } |
r241693 | r241694 | |
854 | 873 | |
855 | 874 | 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)); |
856 | 875 | |
857 | | for(int i = 0; i < m_figs.m_dc; i++) |
| 876 | for(int i = 0; i <= m_figs.m_dc; i++) |
858 | 877 | { |
859 | 878 | if(i >= m_figs.m_dm) |
860 | 879 | { |
r241693 | r241694 | |
882 | 901 | { |
883 | 902 | case 1: |
884 | 903 | case 2: |
885 | | x += m_figs.m_dc * dot_dir[((m_figs.m_dir >> 1) + 3) & 3]; |
| 904 | x += (m_figs.m_dc + 1) * dot_dir[((m_figs.m_dir >> 1) + 3) & 3]; |
886 | 905 | break; |
887 | 906 | default: |
888 | | y += m_figs.m_dc * dot_dir[m_figs.m_dir >> 1]; |
| 907 | y += (m_figs.m_dc + 1) * dot_dir[m_figs.m_dir >> 1]; |
889 | 908 | break; |
890 | 909 | } |
891 | 910 | |
r241693 | r241694 | |
1583 | 1602 | |
1584 | 1603 | if(area >= 3) // TODO: most likely to be correct, Quarth (PC-98xx) definitely draws with area 2. We might see an area 3 someday ... |
1585 | 1604 | break; |
1586 | | |
| 1605 | if(((m_mode & UPD7220_MODE_INTERLACE_MASK) == UPD7220_MODE_INTERLACE_ON)) |
| 1606 | len <<= 1; |
1587 | 1607 | for (y = 0; y < len; y++) |
1588 | 1608 | { |
1589 | 1609 | /* TODO: again correct? |
1590 | 1610 | Quarth (PC-98xx) doesn't seem to use pitch here and it definitely wants bsy to be /2 to make scrolling to work. |
1591 | 1611 | Xevious (PC-98xx) wants the pitch to be fixed at 80, and wants bsy to be /1 |
1592 | 1612 | Dragon Buster (PC-98xx) contradicts with Xevious with regards of the pitch tho ... */ |
1593 | | addr = ((sad << 1) & 0x3ffff) + (y * (m_pitch << (im ? 0 : 1))); |
| 1613 | addr = ((sad << 1) & 0x3ffff) + (y * (m_aw << (im ? 0 : 1))); |
1594 | 1614 | |
1595 | 1615 | if (!m_display_cb.isnull()) |
1596 | 1616 | draw_graphics_line(bitmap, addr, y + (bsy / (mixed ? 1 : m_lr)), wd); |