home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / Atari800 / gtia_older.c < prev    next >
C/C++ Source or Header  |  1997-08-06  |  22KB  |  1,190 lines

  1. /*
  2.  * Scanline Generation
  3.  * Player Missile Graphics
  4.  * Collision Detection
  5.  * Playfield Priorities
  6.  * Issues cpu cycles during frame redraw.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11.  
  12. #ifndef AMIGA
  13. #include "config.h"
  14. #endif
  15.  
  16. #include "atari.h"
  17. #include "cpu.h"
  18. #include "pia.h"
  19. #include "pokey.h"
  20. #include "gtia.h"
  21. #include "antic.h"
  22. #include "pia.h"
  23. #include "platform.h"
  24.  
  25. #define FALSE 0
  26. #define TRUE 1
  27.  
  28. static char *rcsid = "$Id: gtia.c,v 1.17 1997/02/15 13:57:11 david Exp $";
  29.  
  30. extern int DELAYED_SERIN_IRQ;
  31. extern int DELAYED_SEROUT_IRQ;
  32. extern int DELAYED_XMTDONE_IRQ;
  33. extern int rom_inserted;
  34. extern int colpf1_fiddled;
  35.  
  36. UBYTE COLBK;
  37. UBYTE COLPF0;
  38. UBYTE COLPF1;
  39. UBYTE COLPF2;
  40. UBYTE COLPF3;
  41. UBYTE COLPM0;
  42. UBYTE COLPM1;
  43. UBYTE COLPM2;
  44. UBYTE COLPM3;
  45. UBYTE GRAFM;
  46. UBYTE GRAFP0;
  47. UBYTE GRAFP1;
  48. UBYTE GRAFP2;
  49. UBYTE GRAFP3;
  50. UBYTE HPOSP0;
  51. UBYTE HPOSP1;
  52. UBYTE HPOSP2;
  53. UBYTE HPOSP3;
  54. UBYTE HPOSM0;
  55. UBYTE HPOSM1;
  56. UBYTE HPOSM2;
  57. UBYTE HPOSM3;
  58. UBYTE SIZEP0;
  59. UBYTE SIZEP1;
  60. UBYTE SIZEP2;
  61. UBYTE SIZEP3;
  62. UBYTE SIZEM;
  63. UBYTE M0PF;
  64. UBYTE M1PF;
  65. UBYTE M2PF;
  66. UBYTE M3PF;
  67. UBYTE M0PL;
  68. UBYTE M1PL;
  69. UBYTE M2PL;
  70. UBYTE M3PL;
  71. UBYTE P0PF;
  72. UBYTE P1PF;
  73. UBYTE P2PF;
  74. UBYTE P3PF;
  75. UBYTE P0PL;
  76. UBYTE P1PL;
  77. UBYTE P2PL;
  78. UBYTE P3PL;
  79. UBYTE PRIOR;
  80. UBYTE GRACTL;
  81.  
  82. /*
  83.     *****************************************************************
  84.     *                                *
  85.     *    Section            :    Player Missile Graphics    *
  86.     *    Original Author        :    David Firth        *
  87.     *    Date Written        :    28th May 1995        *
  88.     *    Version            :    1.0            *
  89.     *                                *
  90.     *****************************************************************
  91. */
  92.  
  93. static int global_hposp0;
  94. static int global_hposp1;
  95. static int global_hposp2;
  96. static int global_hposp3;
  97. static int global_hposm0;
  98. static int global_hposm1;
  99. static int global_hposm2;
  100. static int global_hposm3;
  101. static int global_sizep0;
  102. static int global_sizep1;
  103. static int global_sizep2;
  104. static int global_sizep3;
  105. static int global_sizem;
  106.  
  107. #ifdef DIRECT_VIDEO
  108. static UBYTE colour_to_pf[256];
  109. #endif
  110.  
  111. /*
  112.     =========================================
  113.     Width of each bit within a Player/Missile
  114.     =========================================
  115. */
  116.  
  117. static UBYTE pm_scanline[ATARI_WIDTH];
  118.  
  119. UBYTE colour_lookup[9];
  120. int colour_translation_table[256];
  121.  
  122. static UBYTE GTIA_XLate[]={0,1,2,3,4,5,6,7,8,8,8,8,4,5,6,7};
  123.  
  124. int next_console_value = 7;
  125. extern int ypos;
  126. extern UWORD regPC;
  127.  
  128. UWORD pl0adr;
  129. UWORD pl1adr;
  130. UWORD pl2adr;
  131. UWORD pl3adr;
  132. UWORD m0123adr;
  133.  
  134. static int PM_XPos[256];
  135. static UBYTE PM_Width[4] = { 2, 4, 2, 8};
  136.  
  137. void GTIA_Initialise (int *argc, char *argv[])
  138. {
  139.   int i;
  140.  
  141.   for (i=0;i<256;i++)
  142.     PM_XPos[i] = (i - 0x20) << 1;
  143.  
  144. #ifdef DIRECT_VIDEO
  145.   printf ("GTIA: Screen Generation compiled with DIRECT_VIDEO\n");
  146.  
  147.   for (i=0;i<256;i++)
  148.     colour_to_pf[i] = 0x00;
  149. #endif
  150.  
  151.   for (i=0;i<9;i++)
  152.     colour_lookup[i] = 0x00;
  153.  
  154.   PRIOR = 0x00;
  155. }
  156.  
  157.  
  158. /* player  = player # to display or 0xff for none
  159.    missile = missle # to display or 0xff for none
  160.    pixel   = screen register to display at this position
  161. */
  162. UBYTE WhichColourReg (int pf_pixel, int player, int missile)
  163. {
  164.   UBYTE colreg;
  165.  
  166.   if (colpf1_fiddled && pf_pixel==5 && ((PRIOR & 0xC0)==0))
  167.     return pf_pixel;
  168.   /* That's actually not quite correct, we should display the hue of the
  169.      colPF1 with the colour of the player, but so what... */
  170.  
  171.   switch (PRIOR & 0x1f)
  172.     {
  173.     case 0x01 : /* RIVER RAID */
  174.       if (missile < player)
  175.     colreg = missile;
  176.       else
  177.     colreg = player;
  178.       break;
  179.     case 0x02 : /* MOUNTAIN KING */
  180.       if (player < 2)
  181.     {
  182.       colreg = player;
  183.     }
  184.       else if (pf_pixel < 7)
  185.     {
  186.       colreg = pf_pixel;
  187.     }
  188.       else if (pf_pixel == 7)
  189.     {
  190.       if (missile != 0xff)
  191.         colreg = missile;
  192.       else
  193.         colreg = pf_pixel;
  194.     }
  195.       else if (player < 4)
  196.     {
  197.       colreg = player;
  198.     }
  199.       else
  200.     {
  201.       colreg = pf_pixel;
  202.     }
  203.       break;
  204.     case 0x00 :  /* That's also not quite correct. We should display here
  205.             a mixture of the player color and the playfield */
  206.     case 0x04 :
  207.       if (pf_pixel > 7)
  208.     {
  209.       if (missile < player)
  210.         colreg = missile;
  211.       else
  212.         colreg = player;
  213.     }
  214.       else
  215.     {
  216.       colreg = pf_pixel;
  217.     }
  218.       break;
  219.     case 0x08 : /* RALLY SPEEDWAY */
  220.       if (pf_pixel > 5)
  221.     {
  222.       if (missile < player)
  223.         colreg = missile;
  224.       else
  225.         colreg = player;
  226.     }
  227.       else
  228.     {
  229.       colreg = pf_pixel;
  230.     }
  231.       break;
  232.     case 0x11 : /* PAC-MAN, STAR RAIDERS, ASTEROIDS, FROGGER DELUXE, KANGAROO */
  233.       if (player != 0xff)
  234.     colreg = player;
  235.       else {
  236.     if (missile != 0xff)
  237.       colreg = 7;
  238.     else 
  239.       colreg = pf_pixel;
  240.       }
  241.       break;
  242.     case 0x12 : /* ZONE RANGER */
  243.       if (player < 2)
  244.     {
  245.       colreg = player;
  246.     }
  247.       else if (pf_pixel < 7)
  248.     {
  249.       colreg = pf_pixel;
  250.     }
  251.       else if (pf_pixel == 7)
  252.     {
  253.       if (missile != 0xff)
  254.         colreg = missile;
  255.       else
  256.         colreg = pf_pixel;
  257.     }
  258.       else if (player < 4)
  259.     {
  260.       colreg = player;
  261.     }
  262.       else
  263.     {
  264.       colreg = pf_pixel;
  265.     }
  266.       break;   
  267.     case 0x10 :  /* That's also not quite correct. We should display here
  268.             a mixture of the player color and the playfield */
  269.     case 0x14 : /* ATARI CHESS, FORT APOCALYPSE */
  270.       if (missile != 0xff)
  271.     {
  272.       colreg = 7;/* Missles are COLPF3 now and have hence priority */
  273.       /*
  274.       if (pf_pixel > 7)
  275.         colreg = 7;  Missile using COLPF3 
  276.       else
  277.         colreg = pf_pixel;
  278.       */
  279.     }
  280.       else
  281.     {
  282.       if (pf_pixel > 7)
  283.         colreg = player;
  284.       else
  285.         colreg = pf_pixel;
  286.     }
  287.       break;
  288.     case 0x18 : /* THE LAST STARTFIGHTER */
  289.       if (pf_pixel > 5)
  290.     {
  291.       if (missile < player)
  292.         colreg = 7; /* Missile using COLPF3 */
  293.       else
  294.         colreg = player;
  295.     }
  296.       else
  297.     {
  298.       colreg = pf_pixel;
  299.     }
  300.       break;
  301.     default :
  302.       printf ("Unsupported PRIOR = %02x\n", PRIOR);
  303.     }
  304.  
  305.   return colreg;
  306. }
  307.  
  308. void PM_ScanLine (void)
  309. {
  310.   static UBYTE pf_collision_bit[9] =
  311.     {
  312.       0x00, 0x00, 0x00, 0x00,
  313.       0x01, 0x02, 0x04, 0x08,
  314.       0x00
  315.     };
  316.  
  317. /*
  318.    =============================
  319.    Display graphics for Player 0
  320.    =============================
  321. */
  322.   if (GRAFP0)
  323.     {
  324.       UBYTE grafp0 = GRAFP0;
  325.       int sizep0 = global_sizep0;
  326.       int hposp0 = global_hposp0;
  327.       int i;
  328.  
  329.       for (i=0;i<8;i++)
  330.     {
  331.       if (grafp0 & 0x80)
  332.         {
  333.           int j;
  334.  
  335.           for (j=0;j<sizep0;j++)
  336.         {
  337.           if ((hposp0 >= 0) && (hposp0 < ATARI_WIDTH))
  338.             {
  339.               UBYTE playfield = scrn_ptr[hposp0];
  340.  
  341. #ifdef DIRECT_VIDEO
  342.               playfield = colour_to_pf[playfield];
  343. #endif
  344.  
  345.               pm_scanline[hposp0] |= 0x01;
  346.  
  347.               P0PF |= pf_collision_bit[playfield];
  348.             }
  349.           hposp0++;
  350.         }
  351.         }
  352.       else
  353.         {
  354.           hposp0 += sizep0;
  355.         }
  356.  
  357.       grafp0 = grafp0 << 1;
  358.     }
  359.     }
  360. /*
  361.    =============================
  362.    Display graphics for Player 1
  363.    =============================
  364. */
  365.   if (GRAFP1)
  366.     {
  367.       UBYTE grafp1 = GRAFP1;
  368.       int sizep1 = global_sizep1;
  369.       int hposp1 = global_hposp1;
  370.       int i;
  371.  
  372.       for (i=0;i<8;i++)
  373.     {
  374.       if (grafp1 & 0x80)
  375.         {
  376.           int j;
  377.  
  378.           for (j=0;j<sizep1;j++)
  379.         {
  380.           if ((hposp1 >= 0) && (hposp1 < ATARI_WIDTH))
  381.             {
  382.               UBYTE playfield = scrn_ptr[hposp1];
  383.  
  384. #ifdef DIRECT_VIDEO
  385.               playfield = colour_to_pf[playfield];
  386. #endif
  387.  
  388.               pm_scanline[hposp1] |= 0x02;
  389.  
  390.               P1PF |= pf_collision_bit[playfield];
  391.             }
  392.           hposp1++;
  393.         }
  394.         }
  395.       else
  396.         {
  397.           hposp1 += sizep1;
  398.         }
  399.  
  400.       grafp1 = grafp1 << 1;
  401.     }
  402.     }
  403. /*
  404.    =============================
  405.    Display graphics for Player 2
  406.    =============================
  407. */
  408.   if (GRAFP2)
  409.     {
  410.       UBYTE grafp2 = GRAFP2;
  411.       int sizep2 = global_sizep2;
  412.       int hposp2 = global_hposp2;
  413.       int i;
  414.  
  415.       for (i=0;i<8;i++)
  416.     {
  417.       if (grafp2 & 0x80)
  418.         {
  419.           int j;
  420.  
  421.           for (j=0;j<sizep2;j++)
  422.         {
  423.           if ((hposp2 >= 0) && (hposp2 < ATARI_WIDTH))
  424.             {
  425.               UBYTE playfield = scrn_ptr[hposp2];
  426.  
  427. #ifdef DIRECT_VIDEO
  428.               playfield = colour_to_pf[playfield];
  429. #endif
  430.  
  431.               pm_scanline[hposp2] |= 0x04;
  432.  
  433.               P2PF |= pf_collision_bit[playfield];
  434.             }
  435.           hposp2++;
  436.         }
  437.         }
  438.       else
  439.         {
  440.           hposp2 += sizep2;
  441.         }
  442.  
  443.       grafp2 = grafp2 << 1;
  444.     }
  445.     }
  446. /*
  447.    =============================
  448.    Display graphics for Player 3
  449.    =============================
  450. */
  451.   if (GRAFP3)
  452.     {
  453.       UBYTE grafp3 = GRAFP3;
  454.       int sizep3 = global_sizep3;
  455.       int hposp3 = global_hposp3;
  456.       int i;
  457.  
  458.       for (i=0;i<8;i++)
  459.     {
  460.       if (grafp3 & 0x80)
  461.         {
  462.           int j;
  463.  
  464.           for (j=0;j<sizep3;j++)
  465.         {
  466.           if ((hposp3 >= 0) && (hposp3 < ATARI_WIDTH))
  467.             {
  468.               UBYTE playfield = scrn_ptr[hposp3];
  469.  
  470. #ifdef DIRECT_VIDEO
  471.               playfield = colour_to_pf[playfield];
  472. #endif
  473.  
  474.               pm_scanline[hposp3] |= 0x08;
  475.  
  476.               P3PF |= pf_collision_bit[playfield];
  477.             }
  478.           hposp3++;
  479.         }
  480.         }
  481.       else
  482.         {
  483.           hposp3 += sizep3;
  484.         }
  485.  
  486.       grafp3 = grafp3 << 1;
  487.     }
  488.     }
  489. /*
  490.    =============================
  491.    Display graphics for Missiles
  492.    =============================
  493. */
  494.   if (GRAFM)
  495.     {
  496.       UBYTE grafm = GRAFM;
  497.       int hposm0 = global_hposm0;
  498.       int hposm1 = global_hposm1;
  499.       int hposm2 = global_hposm2;
  500.       int hposm3 = global_hposm3;
  501.       int sizem = global_sizem;
  502.       int i;
  503.  
  504.       for (i=0;i<8;i++)
  505.     {
  506.       if (grafm & 0x80)
  507.         {
  508.           int j;
  509.  
  510.           for (j=0;j<sizem;j++)
  511.         {
  512.           switch (i & 0x06)
  513.             {
  514.             case 0x00 :
  515.               if ((hposm3 >= 0) && (hposm3 < ATARI_WIDTH))
  516.             {
  517.               UBYTE playfield = scrn_ptr[hposm3];
  518.               UBYTE player = pm_scanline[hposm3];
  519.  
  520. #ifdef DIRECT_VIDEO
  521.               playfield = colour_to_pf[playfield];
  522. #endif
  523.  
  524.               pm_scanline[hposm3] |= 0x80;
  525.  
  526.               M3PF |= pf_collision_bit[playfield];
  527.               M3PL |= player;
  528.             }
  529.               hposm3++;
  530.               break;
  531.             case 0x02 :
  532.               if ((hposm2 >= 0) && (hposm2 < ATARI_WIDTH))
  533.             {
  534.               UBYTE playfield = scrn_ptr[hposm2];
  535.               UBYTE player = pm_scanline[hposm2];
  536.  
  537. #ifdef DIRECT_VIDEO
  538.               playfield = colour_to_pf[playfield];
  539. #endif
  540.  
  541.               pm_scanline[hposm2] |= 0x40;
  542.  
  543.               M2PF |= pf_collision_bit[playfield];
  544.               M2PL |= player;
  545.             }
  546.               hposm2++;
  547.               break;
  548.             case 0x04 :
  549.               if ((hposm1 >= 0) && (hposm1 < ATARI_WIDTH))
  550.             {
  551.               UBYTE playfield = scrn_ptr[hposm1];
  552.               UBYTE player = pm_scanline[hposm1];
  553.  
  554. #ifdef DIRECT_VIDEO
  555.               playfield = colour_to_pf[playfield];
  556. #endif
  557.  
  558.               pm_scanline[hposm1] |= 0x20;
  559.  
  560.               M1PF |= pf_collision_bit[playfield];
  561.               M1PL |= player;
  562.             }
  563.               hposm1++;
  564.               break;
  565.             case 0x06 :
  566.               if ((hposm0 >= 0) && (hposm0 < ATARI_WIDTH))
  567.             {
  568.               UBYTE playfield = scrn_ptr[hposm0];
  569.               UBYTE player = pm_scanline[hposm0];
  570.  
  571. #ifdef DIRECT_VIDEO
  572.               playfield = colour_to_pf[playfield];
  573. #endif
  574.  
  575.               pm_scanline[hposm0] |= 0x10;
  576.  
  577.               M0PF |= pf_collision_bit[playfield];
  578.               M0PL |= player;
  579.             }
  580.               hposm0++;
  581.               break;
  582.             }
  583.         }
  584.         }
  585.       else
  586.         {
  587.           switch (i & 0x06)
  588.         {
  589.         case 0x00 :
  590.           hposm3 += sizem;
  591.           break;
  592.         case 0x02 :
  593.           hposm2 += sizem;
  594.           break;
  595.         case 0x04 :
  596.           hposm1 += sizem;
  597.           break;
  598.         case 0x06 :
  599.           hposm0 += sizem;
  600.           break;
  601.         }
  602.         }
  603.       
  604.       grafm = grafm << 1;
  605.     }
  606.     }
  607. }
  608.  
  609. /*
  610.    ======================================
  611.    Plot Player/Missile Data onto Scanline
  612.    ======================================
  613. */
  614. void PM_DrawLine(void)
  615. {
  616.   static int which_pm_lookup[16] =
  617.     {
  618.       0xff, /* 0000 - None */
  619.       0x00, /* 0001 - Player 0 */
  620.       0x01, /* 0010 - Player 1 */
  621.       0x00, /* 0011 - Player 0 */
  622.       0x02, /* 0100 - Player 2 */
  623.       0x00, /* 0101 - Player 0 */
  624.       0x01, /* 0110 - Player 1 */
  625.       0x00, /* 0111 - Player 0 */
  626.       0x03, /* 1000 - Player 3 */
  627.       0x00, /* 1001 - Player 0 */
  628.       0x01, /* 1010 - Player 1 */
  629.       0x00, /* 1011 - Player 0 */
  630.       0x02, /* 1100 - Player 2 */
  631.       0x00, /* 1101 - Player 0 */
  632.       0x01, /* 1110 - Player 1 */
  633.       0x00  /* 1111 - Player 0 */
  634.     };
  635.   int xpos;
  636.   UBYTE *pf,*pm;
  637.   
  638.   xpos=0,pf=scrn_ptr,pm=pm_scanline;
  639.  
  640.   switch (PRIOR & 0xc0) {
  641.   case 0x00:  /* Ordinary display modes */
  642.     for (;xpos<ATARI_WIDTH;xpos++,pm++,pf++) {
  643.       UBYTE pm_pixel,pf_pixel,colreg;
  644.       
  645.       pm_pixel = *pm;
  646.       pf_pixel = *pf;
  647.       
  648.       if (pm_pixel) {
  649.     UBYTE player;
  650.     int which_player;
  651.     int which_missile;
  652.     
  653.     player = pm_pixel & 0x0f;
  654.     if (player & 0x01)
  655.       P0PL |= player;
  656.     if (player & 0x02)
  657.       P1PL |= player;
  658.     if (player & 0x04)
  659.       P2PL |= player;
  660.     if (player & 0x08)
  661.       P3PL |= player;
  662.     
  663.     which_player = which_pm_lookup[pm_pixel & 0x0f];
  664.     which_missile = which_pm_lookup[(pm_pixel >> 4) & 0x0f];
  665.     
  666.     colreg = WhichColourReg (pf_pixel, which_player, which_missile);
  667.       } else colreg = pf_pixel;
  668.  
  669.       if (colreg==5 && colpf1_fiddled)
  670.     *pf = (colour_lookup[5] & 0x0f) | (colour_lookup[6] & 0xf0);
  671.       else
  672.     *pf = colour_lookup[colreg];
  673.     }
  674.     break;
  675.   case 0x40:  /* Graphics 9 */
  676.     for(;xpos<ATARI_WIDTH;xpos++,pm++,pf++) {
  677.       int nibble;
  678.       UBYTE pm_pixel,pf_pixel,playfield_color;
  679.       
  680.       pm_pixel = *pm;
  681.  
  682.       if ((xpos & 0x03) == 0x00) {
  683.     nibble = (((pf[0]   & 0x01))<<3)|
  684.              (((pf[1] & 0x01))<<2)|
  685.          (((pf[2] & 0x01))<<1)|
  686.          (((pf[3] & 0x01)));
  687.     pf_pixel=colour_translation_table[(COLBK & 0xf0) | nibble];
  688.       }
  689.  
  690.       if (pm_pixel) {
  691.     UBYTE colreg;
  692.     UBYTE player;
  693.     int which_player;
  694.     int which_missile;
  695.     
  696.     player = pm_pixel & 0x0f;
  697.     if (player & 0x01)
  698.       P0PL |= player;
  699.     if (player & 0x02)
  700.       P1PL |= player;
  701.     if (player & 0x04)
  702.       P2PL |= player;
  703.     if (player & 0x08)
  704.       P3PL |= player;
  705.     
  706.     which_player = which_pm_lookup[pm_pixel & 0x0f];
  707.     which_missile = which_pm_lookup[(pm_pixel >> 4) & 0x0f];
  708.     
  709.     colreg = WhichColourReg (COLBK, which_player, which_missile);
  710.     
  711.     if (colreg == COLBK)
  712.       *pf = pf_pixel;
  713.     else
  714.       *pf = colour_lookup[colreg];
  715.       } else
  716.     *pf = pf_pixel;
  717.     }
  718.     break;
  719.   case 0x80:  /* Graphics 10 */
  720.     for(;xpos<ATARI_WIDTH;xpos++,pm++,pf++) {
  721.       int nibble;
  722.       UBYTE pm_pixel,pf_pixel,playfield_color;
  723.       
  724.       pm_pixel = *pm;
  725.  
  726.       if ((xpos & 0x03) == 0x00) {
  727.     nibble = (((pf[0]   & 0x01))<<3)|
  728.              (((pf[1] & 0x01))<<2)|
  729.          (((pf[2] & 0x01))<<1)|
  730.          (((pf[3] & 0x01)));
  731.     pf_pixel=colour_lookup[GTIA_XLate[nibble]];
  732.       }
  733.  
  734.       if (pm_pixel) {
  735.     UBYTE colreg;
  736.     UBYTE player;
  737.     int which_player;
  738.     int which_missile;
  739.     
  740.     player = pm_pixel & 0x0f;
  741.     if (player & 0x01)
  742.       P0PL |= player;
  743.     if (player & 0x02)
  744.       P1PL |= player;
  745.     if (player & 0x04)
  746.       P2PL |= player;
  747.     if (player & 0x08)
  748.       P3PL |= player;
  749.     
  750.     which_player = which_pm_lookup[pm_pixel & 0x0f];
  751.     which_missile = which_pm_lookup[(pm_pixel >> 4) & 0x0f];
  752.     
  753.     colreg = WhichColourReg (COLBK, which_player, which_missile);
  754.     
  755.     if (colreg == COLBK)
  756.       *pf = pf_pixel;
  757.     else
  758.       *pf = colour_lookup[colreg];
  759.       } else
  760.     *pf = pf_pixel;
  761.     }
  762.     break;
  763.   case 0xc0:  /* Graphics 11 */
  764.     for(;xpos<ATARI_WIDTH;xpos++,pf++,pm++) {
  765.       int nibble;
  766.       UBYTE pm_pixel,pf_pixel,playfield_color;
  767.       
  768.       pm_pixel = *pm;
  769.  
  770.       if ((xpos & 0x03) == 0x00) {
  771.     nibble = (((pf[0] & 0x01))<<3)|
  772.              (((pf[1] & 0x01))<<2)|
  773.          (((pf[2] & 0x01))<<1)|
  774.          (((pf[3] & 0x01)));
  775.     if (nibble)
  776.       pf_pixel = colour_translation_table[(nibble << 4) | (COLBK & 0x0f)];
  777.     else
  778.       pf_pixel = colour_translation_table[(nibble << 4)];
  779.  
  780.       }
  781.  
  782.       if (pm_pixel) {
  783.     UBYTE colreg;
  784.     UBYTE player;
  785.     int which_player;
  786.     int which_missile;
  787.     
  788.     player = pm_pixel & 0x0f;
  789.     if (player & 0x01)
  790.       P0PL |= player;
  791.     if (player & 0x02)
  792.       P1PL |= player;
  793.     if (player & 0x04)
  794.       P2PL |= player;
  795.     if (player & 0x08)
  796.       P3PL |= player;
  797.     
  798.     which_player = which_pm_lookup[pm_pixel & 0x0f];
  799.     which_missile = which_pm_lookup[(pm_pixel >> 4) & 0x0f];
  800.     
  801.     colreg = WhichColourReg (COLBK, which_player, which_missile);
  802.     
  803.     if (colreg == COLBK)
  804.       *pf = pf_pixel;
  805.     else
  806.       *pf = colour_lookup[colreg];
  807.       } else
  808.     *pf = pf_pixel;
  809.     }
  810.     break;
  811.   }
  812.   memset (pm_scanline, 0, ATARI_WIDTH);
  813.     
  814. }
  815.  
  816. void Atari_ScanLine (int cycles)
  817. {
  818.   int i;
  819.  
  820.   if (DELAYED_SERIN_IRQ > 0)
  821.     {
  822.       if (--DELAYED_SERIN_IRQ == 0)
  823.     {
  824.       if (IRQEN & 0x20)
  825.         {
  826. #ifdef DEBUG2
  827.           printf ("SERIO: SERIN Interrupt triggered\n");
  828. #endif
  829.           IRQST &= 0xdf;
  830.           IRQ = 1;
  831.         }
  832. #ifdef DEBUG2
  833.       else
  834.         {
  835.           printf ("SERIO: SERIN Interrupt missed\n");
  836.         }
  837. #endif
  838.     }
  839.     }
  840.  
  841.   if (DELAYED_SEROUT_IRQ > 0)
  842.     {
  843.       if (--DELAYED_SEROUT_IRQ == 0)
  844.     {
  845.       if (IRQEN & 0x10)
  846.         {
  847. #ifdef DEBUG2
  848.           printf ("SERIO: SEROUT Interrupt triggered\n");
  849. #endif
  850.           IRQST &= 0xef;
  851.           IRQ = 1;
  852.         }
  853. #ifdef DEBUG2
  854.       else
  855.         {
  856.           printf ("SERIO: SEROUT Interrupt missed\n");
  857.         }
  858. #endif
  859.     }
  860.     }
  861.  
  862.   if (DELAYED_XMTDONE_IRQ > 0)
  863.     {
  864.       if (--DELAYED_XMTDONE_IRQ == 0)
  865.     {
  866.       if (IRQEN & 0x08)
  867.         {
  868. #ifdef DEBUG2
  869.           printf ("SERIO: XMTDONE Interrupt triggered\n");
  870. #endif
  871.           IRQST &= 0xf7;
  872.           IRQ = 1;
  873.         }
  874. #ifdef DEBUG2
  875.       else
  876.         {
  877.           printf ("SERIO: XMTDONE Interrupt missed\n");
  878.         }
  879. #endif
  880.     }
  881.     }
  882.  
  883.   if ((!wsync_halt) && (cycles>0))
  884.       GO (cycles);
  885.  
  886. #ifdef DIRECT_VIDEO
  887.   for (i=0;i<dmactl_xmin_noscroll;i++)
  888.     scrn_ptr[i] = colour_lookup[8];
  889.  
  890.   for (i=dmactl_xmax_noscroll;i<ATARI_WIDTH;i++)
  891.     scrn_ptr[i] = colour_lookup[8];
  892. #else
  893.   for (i=0;i<dmactl_xmin_noscroll;i++)
  894.     scrn_ptr[i] = PF_COLBK;
  895.  
  896.   for (i=dmactl_xmax_noscroll;i<ATARI_WIDTH;i++)
  897.     scrn_ptr[i] = PF_COLBK;
  898. #endif
  899.  
  900.   PM_ScanLine ();
  901.   PM_DrawLine ();
  902.  
  903.   scrn_ptr += ATARI_WIDTH;
  904.   ypos++;
  905.  
  906.   if (wsync_halt)
  907.     {
  908.       if (!(--wsync_halt))
  909.       GO (107);
  910.     }
  911.   else
  912.     {
  913.     GO (7);
  914.     }
  915. }
  916.  
  917. void FiddlePF1(UBYTE byte)
  918. {
  919.       COLPF1 = byte;
  920. #ifdef DIRECT_VIDEO
  921.       setcolreg (5, byte);
  922. #else
  923.       colour_lookup[5] = colour_translation_table[byte];
  924. #endif
  925. }
  926.  
  927. UBYTE GTIA_GetByte (UWORD addr)
  928. {
  929.   UBYTE byte;
  930.       
  931.   addr &= 0xff1f;
  932.   switch (addr)
  933.     {
  934.     case _CONSOL :
  935.       if (next_console_value != 7)
  936.     {
  937.       byte = next_console_value;
  938.       next_console_value = 0x07;
  939.     }
  940.       else
  941.     {
  942.       byte = Atari_CONSOL ();
  943.     }
  944.       break;
  945.     case _M0PF :
  946.       byte = M0PF;
  947.       break;
  948.     case _M1PF :
  949.       byte = M1PF;
  950.       break;
  951.     case _M2PF :
  952.       byte = M2PF;
  953.       break;
  954.     case _M3PF :
  955.       byte = M3PF;
  956.       break;
  957.     case _M0PL :
  958.       byte = M0PL;
  959.       break;
  960.     case _M1PL :
  961.       byte = M1PL;
  962.       break;
  963.     case _M2PL :
  964.       byte = M2PL;
  965.       break;
  966.     case _M3PL :
  967.       byte = M3PL;
  968.       break;
  969.     case _P0PF :
  970.       byte = P0PF;
  971.       break;
  972.     case _P1PF :
  973.       byte = P1PF;
  974.       break;
  975.     case _P2PF :
  976.       byte = P2PF;
  977.       break;
  978.     case _P3PF :
  979.       byte = P3PF;
  980.       break;
  981.     case _P0PL :
  982.       byte = P0PL & 0xfe;
  983.       break;
  984.     case _P1PL :
  985.       byte = P1PL & 0xfd;
  986.       break;
  987.     case _P2PL :
  988.       byte = P2PL & 0xfb;
  989.       break;
  990.     case _P3PL :
  991.       byte = P3PL & 0xf7;
  992.       break;
  993.     case _PAL :
  994.       if (tv_mode == PAL)
  995.     byte = 0x00;
  996.       else
  997.     byte = 0x0e;
  998.       break;
  999.     case _TRIG0 :
  1000.       byte = Atari_TRIG (0);
  1001.       break;
  1002.     case _TRIG1 :
  1003.       byte = Atari_TRIG (1);
  1004.       break;
  1005.     case _TRIG2 :
  1006.       byte = Atari_TRIG (2);
  1007.       break;
  1008.     case _TRIG3 :
  1009.       if (machine==Atari) byte = Atari_TRIG (3);
  1010.       else                byte = (rom_inserted)?(1):(0);
  1011.     
  1012.       break;
  1013.     }
  1014.  
  1015.   return byte;
  1016. }
  1017.  
  1018. #ifdef DIRECT_VIDEO
  1019. void setcolreg (int pf, UBYTE colour)
  1020. {
  1021.   colour_to_pf[colour_lookup[pf]] = 0x00;
  1022.  
  1023.   colour_lookup[pf] = colour_translation_table[colour];
  1024.   while (colour_to_pf[colour_lookup[pf]] != 0)
  1025.     {
  1026.       colour++;
  1027.       colour_lookup[pf] = colour_translation_table[colour];
  1028.     }
  1029.  
  1030.   colour_to_pf[colour_lookup[pf]] = pf;
  1031. }
  1032. #endif
  1033.  
  1034. int GTIA_PutByte (UWORD addr, UBYTE byte)
  1035. {  
  1036.  
  1037.   addr &= 0xff1f; 
  1038.  
  1039.   switch (addr)
  1040.     {
  1041.     case _COLBK :
  1042.       COLBK = byte;
  1043. #ifdef DIRECT_VIDEO
  1044.       setcolreg (8, byte);
  1045. #else
  1046.       colour_lookup[8] = colour_translation_table[byte];
  1047. #endif
  1048.       break;
  1049.     case _COLPF0 :
  1050.       COLPF0 = byte;
  1051. #ifdef DIRECT_VIDEO
  1052.       setcolreg (4, byte);
  1053. #else
  1054.       colour_lookup[4] = colour_translation_table[byte];
  1055. #endif
  1056.       break;
  1057.     case _COLPF1 :
  1058.       COLPF1 = byte;
  1059. #ifdef DIRECT_VIDEO
  1060.       setcolreg (5, byte);
  1061. #else
  1062.       colour_lookup[5] = colour_translation_table[byte];
  1063. #endif
  1064.       /* colpf1_fiddled=0; */
  1065.       break;
  1066.     case _COLPF2 :
  1067.       COLPF2 = byte;
  1068. #ifdef DIRECT_VIDEO
  1069.       setcolreg (6, byte);
  1070. #else
  1071.       colour_lookup[6] = colour_translation_table[byte];
  1072. #endif
  1073.       break;
  1074.     case _COLPF3 :
  1075.       COLPF3 = byte;
  1076. #ifdef DIRECT_VIDEO
  1077.       setcolreg (7, byte);
  1078. #else
  1079.       colour_lookup[7] = colour_translation_table[byte];
  1080. #endif
  1081.       break;
  1082.     case _COLPM0 :
  1083.       COLPM0 = byte;
  1084.       colour_lookup[0] = colour_translation_table[byte];
  1085.       break;
  1086.     case _COLPM1 :
  1087.       COLPM1 = byte;
  1088.       colour_lookup[1] = colour_translation_table[byte];
  1089.       break;
  1090.     case _COLPM2 :
  1091.       COLPM2 = byte;
  1092.       colour_lookup[2] = colour_translation_table[byte];
  1093.       break;
  1094.     case _COLPM3 :
  1095.       COLPM3 = byte;
  1096.       colour_lookup[3] = colour_translation_table[byte];
  1097.       break;
  1098.     case _CONSOL :
  1099.       break;
  1100.     case _GRAFM :
  1101.       GRAFM = byte;
  1102.       break;
  1103.     case _GRAFP0 :
  1104.       GRAFP0 = byte;
  1105.       break;
  1106.     case _GRAFP1 :
  1107.       GRAFP1 = byte;
  1108.       break;
  1109.     case _GRAFP2 :
  1110.       GRAFP2 = byte;
  1111.       break;
  1112.     case _GRAFP3 :
  1113.       GRAFP3 = byte;
  1114.       break;
  1115.     case _HITCLR :
  1116.       M0PF = M1PF = M2PF = M3PF = 0;
  1117.       P0PF = P1PF = P2PF = P3PF = 0; 
  1118.       M0PL = M1PL = M2PL = M3PL = 0; 
  1119.       P0PL = P1PL = P2PL = P3PL = 0;
  1120.       break;
  1121.     case _HPOSM0 :
  1122.       HPOSM0 = byte;
  1123.       global_hposm0 = PM_XPos[byte];
  1124.       break;
  1125.     case _HPOSM1 :
  1126.       HPOSM1 = byte;
  1127.       global_hposm1 = PM_XPos[byte];
  1128.       break;
  1129.     case _HPOSM2 :
  1130.       HPOSM2 = byte;
  1131.       global_hposm2 = PM_XPos[byte];
  1132.       break;
  1133.     case _HPOSM3 :
  1134.       HPOSM3 = byte;
  1135.       global_hposm3 = PM_XPos[byte];
  1136.       break;
  1137.     case _HPOSP0 :
  1138.       HPOSP0 = byte;
  1139.       global_hposp0 = PM_XPos[byte];
  1140.       break;
  1141.     case _HPOSP1 :
  1142.       HPOSP1 = byte;
  1143.       global_hposp1 = PM_XPos[byte];
  1144.       break;
  1145.     case _HPOSP2 :
  1146.       HPOSP2 = byte;
  1147.       global_hposp2 = PM_XPos[byte];
  1148.       break;
  1149.     case _HPOSP3 :
  1150.       HPOSP3 = byte;
  1151.       global_hposp3 = PM_XPos[byte];
  1152.       break;
  1153.     case _SIZEM :
  1154.       SIZEM = byte;
  1155.       global_sizem = PM_Width[byte & 0x03];
  1156.       break;
  1157.     case _SIZEP0 :
  1158.       SIZEP0 = byte;
  1159.       global_sizep0 = PM_Width[byte & 0x03];
  1160.       break;
  1161.     case _SIZEP1 :
  1162.       SIZEP1 = byte;
  1163.       global_sizep1 = PM_Width[byte & 0x03];
  1164.       break;
  1165.     case _SIZEP2 :
  1166.       SIZEP2 = byte;
  1167.       global_sizep2 = PM_Width[byte & 0x03];
  1168.       break;
  1169.     case _SIZEP3 :
  1170.       SIZEP3 = byte;
  1171.       global_sizep3 = PM_Width[byte & 0x03];
  1172.       break;
  1173.     case _PRIOR :
  1174.       PRIOR = byte;
  1175.       break;
  1176.     case _GRACTL :
  1177.       GRACTL = byte;
  1178.       break;
  1179.     default:
  1180.       break;
  1181.     }
  1182.  
  1183.   return FALSE;
  1184. }
  1185.  
  1186.  
  1187.  
  1188.  
  1189.  
  1190.