home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga 5 / MA_Cover_5.iso / ppc / atari / atari800-0.8.6 / gtia.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-05-10  |  19.6 KB  |  1,084 lines

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