home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / Atari800 / gtia_old.c < prev    next >
C/C++ Source or Header  |  1998-02-19  |  23KB  |  1,083 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. #include "pokey11.h"
  25. #include "mem.h"
  26. #include "sio.h"
  27.  
  28. #define FALSE 0
  29. #define TRUE 1
  30.  
  31. static char *rcsid = "$Id: gtia.c,v 1.30 1998/02/17 thor,david Exp $";
  32.  
  33. extern int DELAYED_SERIN_IRQ;
  34. extern int DELAYED_SEROUT_IRQ;
  35. extern int DELAYED_XMTDONE_IRQ;
  36.  
  37. UBYTE COLBK;
  38. UBYTE COLPF0;
  39. UBYTE COLPF1;
  40. UBYTE COLPF2;
  41. UBYTE COLPF3;
  42. UBYTE COLPM0;
  43. UBYTE COLPM1;
  44. UBYTE COLPM2;
  45. UBYTE COLPM3;
  46. UBYTE GRAFM;
  47. UBYTE GRAFP0;
  48. UBYTE GRAFP1;
  49. UBYTE GRAFP2;
  50. UBYTE GRAFP3;
  51. UBYTE HPOSP0;
  52. UBYTE HPOSP1;
  53. UBYTE HPOSP2;
  54. UBYTE HPOSP3;
  55. UBYTE HPOSM0;
  56. UBYTE HPOSM1;
  57. UBYTE HPOSM2;
  58. UBYTE HPOSM3;
  59. UBYTE SIZEP0;
  60. UBYTE SIZEP1;
  61. UBYTE SIZEP2;
  62. UBYTE SIZEP3;
  63. UBYTE SIZEM;
  64. UBYTE PRIOR;
  65. UBYTE GRACTL;
  66. UBYTE VDELAY;
  67. int delayp0,delayp1,delayp2,delayp3;  /* VDelay mirrors */
  68. int delaym0,delaym1,delaym2,delaym3;
  69. int artefacts;
  70.  
  71.  
  72. /* Collision stuff. There's no need to mirror the precise hardware registers.
  73.    We keep all the stuff here and extract the information as soon as needed.
  74.  
  75.    Please note that the ordering of these flag fields are a bit strange.
  76.    Namely index #0 relates to missile #3. That is due to the sorting
  77.    of the bits in the missile graphics register for faster access.
  78.    Players, however, are sorted straigh. Wierdos! */
  79.  
  80. UBYTE Missile_Playfield[4];    /* Missile-playfield collisions */
  81. UBYTE Missile_Player[4];       /* Missile-player collisions */
  82. UBYTE Player_Playfield[4];     /* Player-playfield collisions */
  83. UBYTE Player_Player[4];        /* Player-player collisions */
  84.  
  85. /* due to the way how the collision detection works currently, not all bits
  86.    are set consistently in these bits. Only higher order players can collide
  87.    with lower order players, missiles with players. It's the task of the
  88.    hardware access registers to gain the right information from these bits.
  89.  
  90.    Player/missile- playfield collisions work straight, though. */
  91.  
  92. /*
  93.     *****************************************************************
  94.     *                                *
  95.     *    Section            :    Player Missile Graphics    *
  96.     *    Original Author        :    David Firth        *
  97.     *    Date Written        :    28th May 1995        *
  98.     *    Version            :    1.0            *
  99.     *                                *
  100.     *****************************************************************
  101. */
  102.  
  103. static int global_hposp0;
  104. static int global_hposp1;
  105. static int global_hposp2;
  106. static int global_hposp3;
  107. static int global_hposm[4];  /* sorted in reverse order, #0 is missile #3 */
  108. static int global_sizep0;
  109. static int global_sizep1;
  110. static int global_sizep2;
  111. static int global_sizep3;
  112. static int global_sizem[4];
  113.  
  114. /*
  115.     =========================================
  116.     Width of each bit within a Player/Missile
  117.     =========================================
  118. */
  119.  
  120. static UBYTE pm_scanline[ATARI_MODULO+PLAYER_OFFSET];
  121.  
  122. UBYTE colour_lookup[9];
  123. int colour_translation_table[256];
  124.  
  125. static int GTIA_XLate[]={0,1,2,3,4,5,6,7,8,8,8,8,4,5,6,7};
  126. static int pf_collision_bit[10] = {
  127.   0x00, 0x00, 0x00, 0x00,
  128.   0x01, 0x02, 0x04, 0x08,
  129.   0x00, 0x02  /* this last entry is for collisions with the fiddled color */
  130. };
  131.  
  132. /* artefact color #1, indexed by the background hue. Must be setup correctly */
  133. static UBYTE ArteF1[]={0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,
  134.                0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40};
  135.  
  136. /* artefact color #2, indexed by the background hue. Still to be done */
  137. static UBYTE ArteF2[]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,
  138.                0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
  139.  
  140.  
  141. int next_console_value = 7;
  142. extern int ypos;
  143. extern UWORD regPC;
  144.  
  145. UWORD pl0adr;
  146. UWORD pl1adr;
  147. UWORD pl2adr;
  148. UWORD pl3adr;
  149. UWORD m0123adr;
  150.  
  151. static int PM_XPos[256];
  152. static UBYTE PM_Width[4] = { 2, 4, 2, 8};
  153. static void Setup_Priority(void);
  154.  
  155.  
  156. /* Object IDs for the priority engine */
  157.  
  158. /* First, player and missiles */
  159. #define ID_PLAYER0     0x10
  160. #define ID_MISSILE0    0x11
  161. #define ID_PLAYER1     0x12
  162. #define ID_MISSILE1    0x13
  163. #define ID_PLAYER2     0x14
  164. #define ID_MISSILE2    0x15
  165. #define ID_PLAYER3     0x16
  166. #define ID_MISSILE3    0x17
  167.  
  168. /* Playfield graphics. Some specials for GTIA 0x80 mode - graphics 10 */
  169. #define ID_PFSP0       0x00 
  170. #define ID_PFSP1       0x01
  171. #define ID_PFSP2       0x02
  172. #define ID_PFSP3       0x03
  173. #define ID_PF0         0x04
  174. #define ID_PF1         0x05
  175. #define ID_PF2         0x06
  176. #define ID_PF3         0x07
  177. #define ID_PFBACK      0x08
  178. #define ID_TABLESIZE   0x20
  179.  
  180.  
  181.  
  182. /* Another implementation of the priority engine */
  183. static int pl01beatspf;     /* true if player 0,1 is on top of pf 0,1 */
  184. static int pf01beatspl;     /* true if playfield 0,1 is on top of player 0,1 */
  185. static int pl23beatspf;     /* true if player 2,3 is on top of pf 2,3 */
  186. static int pf23beatspl;     /* true if playfield 2,3 is on top of player 2,3 */
  187. static int pl02beatspl;     /* true if player 0,2 is on top of player 1,3 */
  188. static int pfbeatspl;       /* true if player 0,1 behind pf 2,3 */
  189. static int plbeatspf;       /* true if player 2,3 in front of pf 0,1 */
  190. static int misslepf3;       /* true if missle 0-3 get pf3 as color */
  191.  
  192. static void Setup_Priority(void)
  193. {
  194. static UWORD lastpri=0xffff;
  195.  
  196.   if (lastpri==PRIOR)
  197.     return;
  198.  
  199.   misslepf3=FALSE;
  200.   pfbeatspl=FALSE;
  201.   plbeatspf=FALSE;
  202.   pl02beatspl=TRUE;
  203.   pf23beatspl=FALSE;
  204.   pl23beatspf=FALSE;
  205.   pf01beatspl=FALSE;
  206.   pl01beatspf=FALSE;
  207.  
  208.   if (PRIOR & 0x10)
  209.     misslepf3=TRUE;
  210.  
  211.   if (PRIOR & 0x20)
  212.     pl02beatspl=FALSE;
  213.  
  214.   if (PRIOR & 0x01) {
  215.     pl01beatspf=TRUE;
  216.     pl23beatspf=TRUE;
  217.     plbeatspf=TRUE;
  218.   }
  219.   if (PRIOR & 0x02) {
  220.     pl01beatspf=TRUE;
  221.     pf23beatspl=TRUE;
  222.   }
  223.   if (PRIOR & 0x04) {
  224.     pf01beatspl=TRUE;
  225.     pf23beatspl=TRUE;
  226.     pfbeatspl=TRUE;
  227.   }
  228.   if (PRIOR & 0x08) {
  229.     pf01beatspl=TRUE;
  230.     pl23beatspf=TRUE;
  231.   }
  232. }
  233.  
  234.  
  235. /* Run the priority engine. Get player pixel encoding and
  236.    playfield pixel mask, fiddle is TRUE for the special ANTIC F,2,3 mode
  237.    coloring, i.e. HIRES */
  238.  
  239. int PixelColor(int pf_pixel,int pm_pixel,int pf_color)
  240. {
  241. int pfcol,pfidx;
  242. int pl0=0,pl1=0,pl2=0,pl3=0;
  243. int pf0=0,pf2=0;
  244.  
  245.   pfcol=pf_color;
  246.   pfidx=pf_pixel;
  247.   if (pf_pixel==PF_COLPF1_FID) {
  248.     pfcol=colour_lookup[PF_COLPF2];
  249.     pfidx=PF_COLPF2;
  250.   }
  251.  
  252.   if ((pm_pixel & 0xf0) && misslepf3) {
  253.     pfcol=colour_lookup[PF_COLPF3];
  254.     pfidx=PF_COLPF3;
  255.   } else {
  256.     pm_pixel |= pm_pixel>>4;
  257.   }
  258.  
  259.   if (pm_pixel & 0x08) {
  260.     pl3=colour_lookup[PL_COLPL3];
  261.   }
  262.  
  263.   if (pm_pixel & 0x04) {
  264.     pl2=colour_lookup[PL_COLPL2];
  265.     if (pl02beatspl)
  266.       pl3=0;
  267.   }
  268.  
  269.   if (pm_pixel & 0x02) {
  270.     pl1=colour_lookup[PL_COLPL1];
  271.     pl2=pl3=0;
  272.   }
  273.  
  274.   if (pm_pixel & 0x01) {
  275.     pl0=colour_lookup[PL_COLPL0];
  276.     pl2=pl3=0;
  277.     if (pl02beatspl)
  278.       pl1=0;
  279.   }
  280.  
  281.   pl0 |= pl1;
  282.   pl2 |= pl3;
  283.   
  284.   if (pfidx==PF_COLPF0 || pfidx==PF_COLPF1) {
  285.     pf0 = pfcol;
  286.     if (pf01beatspl)
  287.       pl0 = 0;
  288.     if (!plbeatspf)
  289.       pl2 = 0;
  290.   }
  291.  
  292.   if (pfidx==PF_COLPF2 || pfidx==PF_COLPF3) {
  293.     pf2 = pfcol;
  294.     if (pf23beatspl)
  295.       pl2 = 0;
  296.     if (pfbeatspl)
  297.       pl0 = 0;
  298.   }
  299.  
  300.   if (pm_pixel & 0x03) {
  301.     if (pl01beatspf)
  302.       pf0 = 0;
  303.     if (!pfbeatspl)
  304.       pf2 = 0;
  305.   }
  306.  
  307.   if (pm_pixel & 0x0c) {
  308.     if (pl23beatspf)
  309.       pf2 = 0;
  310.     if (plbeatspf)
  311.       pf0 = 0;
  312.   }
  313.  
  314.   pf0 |= pl0;
  315.   pf2 |= pl2;
  316.  
  317.   pfcol = pf0 | pf2;
  318.   
  319.   if (pf_pixel==PF_COLPF1_FID) {
  320.     pfcol = (pfcol & 0xf0) | (colour_lookup[PF_COLPF1] & 0x0f);
  321.   }
  322.  
  323.   return pfcol;
  324. }
  325.  
  326. static int missile_mask[4] = {0x80,0x40,0x20,0x10};
  327.  
  328. void DisplayMissiles(int ofs)
  329. {
  330. unsigned int grafm = GRAFM;
  331. int i,j,sizem=0,mask=0;
  332. UBYTE *mplc=0,*mpfc=0;
  333. UBYTE *pmpos=0,*pfpos=0;
  334.  
  335.   for (i=0;i<8;i++) {
  336.     if ((i & 0x01)==0) {
  337.       int ih,hpos;
  338.       ih = i>>1;
  339.       sizem = global_sizem[ih];
  340.       hpos  = global_hposm[ih];
  341.       mask  = missile_mask[ih];
  342.       mplc  = Missile_Player+ih;
  343.       mpfc  = Missile_Playfield+ih;
  344.       pmpos = pm_scanline+hpos+PLAYER_OFFSET;
  345.       pfpos = scrn_ptr+hpos+ofs;
  346.     }
  347.  
  348.     if (grafm & 0x80) {
  349.       for (j=0;j<sizem;j++) {
  350.     *mpfc  |= pf_collision_bit[*pfpos];
  351.     *mplc  |= *pmpos;
  352.     *pmpos |= mask;
  353.     pmpos++;
  354.     pfpos++;
  355.       }
  356.     } else {
  357.       pmpos +=sizem;
  358.       pfpos +=sizem;
  359.     }
  360.     grafm <<= 1;
  361.   }
  362.  
  363. }
  364.  
  365. void DisplayPlayer(int ofs,unsigned int graf,int size,int hpos,int num)
  366. {
  367. int i,j;
  368. int coll=0,pmcol=0;
  369. UBYTE *pmpos,*pfpos;
  370. int mask;
  371.  
  372.  
  373.   pmpos = pm_scanline + hpos + PLAYER_OFFSET;
  374.   pfpos = scrn_ptr + hpos + ofs;
  375.   mask = 1<<num;
  376.  
  377.   for (i=0;i<8;i++) {
  378.     if (graf & 0x80) {
  379.       for (j=0;j<size;j++) {
  380.     pmcol  |= *pmpos;
  381.     *pmpos |= mask;
  382.     coll   |= pf_collision_bit[*pfpos];
  383.     pmpos ++;
  384.     pfpos ++;
  385.       }
  386.     } else {
  387.       pmpos += size;
  388.       pfpos += size;
  389.     }
  390.     graf <<= 1;
  391.   }
  392.  
  393.   Player_Playfield[num] |= coll;
  394.   Player_Player[num] |= pmcol;
  395. }
  396.  
  397.  
  398. /*
  399.    ======================================
  400.    Player/Missle Graphics service
  401.    routines for different GTIA modes
  402.    ======================================
  403. */
  404.  
  405. /* Ordinary display modes */
  406. void GTIA_Create00(UBYTE *pm,UBYTE *pf,int ofs)
  407. {
  408. int xpos;
  409. int pm_pixel,pf_pixel;
  410.  
  411.     for (xpos=0;xpos<ATARI_WIDTH;xpos++,pm++,pf++) {
  412.       
  413.       pm_pixel = *pm;
  414.       pf_pixel = pf[ofs];
  415.        
  416.       if (pm_pixel) {
  417.     *pf=PixelColor(pf_pixel,pm_pixel,colour_lookup[pf_pixel]) & 0xfe;
  418.       } else {
  419.     if (pf_pixel==PF_COLPF1_FID)
  420.       *pf = (colour_lookup[PF_COLPF1] & 0x0e) | (colour_lookup[PF_COLPF2] & 0xf0);
  421.     else
  422.       *pf = colour_lookup[pf_pixel] & 0xfe;
  423.       }
  424.     }
  425. }
  426.  
  427. /* Display with artefacts */
  428.  
  429. void GTIA_Create00AF(UBYTE *pm,UBYTE *pf,int ofs)
  430. {
  431. int xpos;
  432. int pm_pixel,pf_pixel,last,color,value,hue;
  433.  
  434.     pf_pixel = PF_COLBK;
  435.     for (xpos=0;xpos<ATARI_WIDTH;xpos++,pm++,pf++) {
  436.       
  437.       last = pf_pixel;
  438.       pm_pixel = *pm;
  439.       pf_pixel = pf[ofs];
  440.  
  441.       switch (pf_pixel) {
  442.       case PF_COLPF1_FID:
  443.     value = colour_lookup[PF_COLPF1] & 0x0e;
  444.     hue = colour_lookup[PF_COLPF2] & 0xf0;
  445.     color = value | hue;
  446.     if (last==PF_COLPF2) {
  447.       value += colour_lookup[PF_COLPF2] & 0x0e;
  448.       color=(value>>1) | ((xpos & 0x01)?(ArteF1[hue>>4]):(ArteF2[hue>>4]));
  449.     }
  450.     break;
  451.       case PF_COLPF2:
  452.     hue = colour_lookup[PF_COLPF2] & 0xf0;
  453.     value = colour_lookup[PF_COLPF1] & 0x0e;
  454.     color = colour_lookup[PF_COLPF2] & 0xfe;
  455.     if (last==PF_COLPF1_FID) {
  456.       value += color & 0x0e; 
  457.       color=(value>>1) | ((xpos & 0x01)?(ArteF2[hue>>4]):(ArteF1[hue>>4]));
  458.     }
  459.     break;
  460.       default:      
  461.     color=colour_lookup[pf_pixel] & 0xfe;
  462.     break;
  463.       }
  464.       
  465.       if (pm_pixel) {
  466.     *pf=PixelColor(pf_pixel,pm_pixel,color) & 0xfe;
  467.       } else {
  468.     *pf = color;
  469.       }
  470.     }
  471. }
  472.  
  473. /* Graphics 9 */
  474. void GTIA_Create40(UBYTE *pm,UBYTE *pf,int ofs)
  475. {
  476. int xpos;
  477. int pm_pixel,pf_pixel=0,nibble=0;
  478.  
  479.     for(xpos=0;xpos<ATARI_WIDTH;xpos++,pm++,pf++) {
  480.  
  481.       pm_pixel = *pm;
  482.  
  483.       if ((xpos & 0x03) == 0x00) {
  484.     nibble = (((pf[ofs+0] & 0x01))<<3)|
  485.              (((pf[ofs+1] & 0x01))<<2)|
  486.          (((pf[ofs+2] & 0x01))<<1)|
  487.          (((pf[ofs+3] & 0x01)));      
  488.  
  489.     pf_pixel=colour_translation_table[(COLBK & 0xf0) | nibble];
  490.       }
  491.  
  492.       if (pm_pixel) {
  493.     *pf=PixelColor(PF_COLBK,pm_pixel,pf_pixel);
  494.       } else {
  495.     *pf=pf_pixel;
  496.       }
  497.     }
  498. }
  499.  
  500. /* Graphics 10 */
  501. void GTIA_Create80(UBYTE *pm,UBYTE *pf,int ofs)
  502. {
  503. int xpos;
  504. int pm_pixel,pf_pixel=0,nibble=0;
  505.  
  506.     for(xpos=0;xpos<ATARI_WIDTH;xpos++,pm++,pf++) {
  507.       
  508.       pm_pixel = *pm;
  509.  
  510.       if ((xpos & 0x03) == 0x00) {
  511.     nibble = (((pf[ofs+0] & 0x01))<<3)|
  512.              (((pf[ofs+1] & 0x01))<<2)|
  513.              (((pf[ofs+2] & 0x01))<<1)|
  514.              (((pf[ofs+3] & 0x01)));
  515.        
  516.     pf_pixel=colour_lookup[GTIA_XLate[nibble]];      
  517.       }
  518.  
  519.       if (pm_pixel) {
  520.     *pf=PixelColor(nibble,pm_pixel,pf_pixel) & 0xfe;
  521.       } else {
  522.     *pf=pf_pixel & 0xfe;
  523.       }
  524.     }
  525. }
  526.  
  527. void GTIA_CreateC0(UBYTE *pm,UBYTE *pf,int ofs)
  528. {
  529. int xpos;
  530. int pm_pixel,pf_pixel=0,nibble=0;
  531.  
  532.     for(xpos=0;xpos<ATARI_WIDTH;xpos++,pf++,pm++) {
  533.       
  534.       pm_pixel = *pm;
  535.  
  536.       if ((xpos & 0x03) == 0x00) {
  537.     nibble = (((pf[ofs+0] & 0x01))<<3)|
  538.              (((pf[ofs+1] & 0x01))<<2)|
  539.          (((pf[ofs+2] & 0x01))<<1)|
  540.          (((pf[ofs+3] & 0x01)));
  541.     
  542.     if (nibble)
  543.       pf_pixel = colour_translation_table[(nibble << 4) | (COLBK & 0x0f)];
  544.     else
  545.       pf_pixel = colour_translation_table[(nibble << 4)];
  546.       }
  547.  
  548.       if (pm_pixel) {
  549.     *pf=PixelColor(PF_COLBK,pm_pixel,pf_pixel) & 0xfe;
  550.       } else {
  551.     *pf=pf_pixel & 0xfe;
  552.       }
  553.  
  554.     }
  555. }
  556.  
  557.  
  558. void Atari_ScanLine (int cycles,int hscrol)
  559. {
  560. int ofs=FILLIN_OFFSET;
  561.  
  562.   if (hscrol) {
  563.     ofs -= HSCROL+HSCROL;
  564.   }
  565.  
  566.   POKEY_Scanline();
  567.  
  568.   if ((!wsync_halt) && (cycles>0))
  569.       GO (cycles);
  570.  
  571.   if (GRAFP0)
  572.     DisplayPlayer(ofs,GRAFP0,global_sizep0,global_hposp0,0);
  573.   
  574.   if (GRAFP1)
  575.     DisplayPlayer(ofs,GRAFP1,global_sizep1,global_hposp1,1);
  576.   
  577.   if (GRAFP2)
  578.     DisplayPlayer(ofs,GRAFP2,global_sizep2,global_hposp2,2);
  579.   
  580.   if (GRAFP3)
  581.     DisplayPlayer(ofs,GRAFP3,global_sizep3,global_hposp3,3);
  582.  
  583.   if (GRAFM)
  584.     DisplayMissiles(ofs);
  585.  
  586.   switch(PRIOR & 0xc0) {
  587.   case 0x00:   /* Ordinary display modes */
  588.     if (artefacts)
  589.       GTIA_Create00AF(pm_scanline+PLAYER_OFFSET,scrn_ptr,ofs);
  590.     else
  591.       GTIA_Create00(pm_scanline+PLAYER_OFFSET,scrn_ptr,ofs);
  592.     break;
  593.   case 0x40:   /* Graphics 9 */
  594.     GTIA_Create40(pm_scanline+PLAYER_OFFSET,scrn_ptr,ofs);
  595.     break;
  596.   case 0x80:   /* Graphics 10 */
  597.     GTIA_Create80(pm_scanline+PLAYER_OFFSET,scrn_ptr,ofs);
  598.     break;
  599.   case 0xc0:   /* Graphics 11 */
  600.     GTIA_CreateC0(pm_scanline+PLAYER_OFFSET,scrn_ptr,ofs);
  601.     break;
  602.   }
  603.  
  604.   memset (pm_scanline, 0, ATARI_MODULO+PLAYER_OFFSET);    
  605.  
  606.   scrn_ptr += ATARI_MODULO;
  607.   ypos++;
  608.  
  609.   if (wsync_halt)
  610.     {
  611.       if (!(--wsync_halt))
  612.     if (cycles>0)
  613.       GO (cycles);
  614.       else
  615.     GO (7);
  616.     }
  617.   else
  618.     {
  619.     GO (7);
  620.     }
  621. }
  622.  
  623. /* I/O routines for the GTIA */
  624.  
  625. mtype GTIA_CONSOL_GET(void)
  626. {
  627. mtype byte;
  628.  
  629.   if (next_console_value != 7) {
  630.     byte = next_console_value;
  631.     next_console_value = 0x07;
  632.   } else {
  633.     byte = Atari_CONSOL ();
  634.   }
  635.  
  636.   return byte;
  637. }
  638.  
  639. /* Missile-Playfield collisions. These are straight, but sorted reverse */
  640.  
  641. mtype GTIA_M0PF_GET(void)
  642. {
  643.   /* printf("M0PF %x\n",Missile_Playfield[3]); */
  644.   return Missile_Playfield[3];
  645. }
  646.  
  647. mtype GTIA_M1PF_GET(void)
  648. {  
  649.   return Missile_Playfield[2];
  650. }
  651.  
  652. mtype GTIA_M2PF_GET(void)
  653. {  
  654.   /* printf("M2PF %x\n",Missile_Playfield[1]); */
  655.   return Missile_Playfield[1];
  656. }
  657.  
  658. mtype GTIA_M3PF_GET(void)
  659. {  
  660.   return Missile_Playfield[0];
  661. }
  662.  
  663. /* Missile-player collisions. Straight, but sorted in reverse order  */
  664.  
  665. mtype GTIA_M0PL_GET(void)
  666. {
  667.   return Missile_Player[3] & 0x0f;
  668. }
  669.  
  670. mtype GTIA_M1PL_GET(void)
  671. {  
  672.   return Missile_Player[2] & 0x0f;
  673. }
  674.  
  675. mtype GTIA_M2PL_GET(void)
  676. {  
  677.   return Missile_Player[1] & 0x0f;
  678. }
  679.  
  680. mtype GTIA_M3PL_GET(void)
  681. {  
  682.   return Missile_Player[0] & 0x0f;
  683. }
  684.  
  685. /* Player-playfield collisions. Straight. */
  686.  
  687. mtype GTIA_P0PF_GET(void)
  688. {
  689.   return Player_Playfield[0];
  690. }
  691.  
  692. mtype GTIA_P1PF_GET(void)
  693. {
  694.   return Player_Playfield[1];
  695. }
  696.  
  697. mtype GTIA_P2PF_GET(void)
  698. {
  699.   return Player_Playfield[2];
  700. }
  701.  
  702. mtype GTIA_P3PF_GET(void)
  703. {
  704.   return Player_Playfield[3];
  705. }
  706.  
  707. /* Player-player collisions. Wierd. 
  708.    This is simply due to the fact that player zero can't detect collisions with
  709.    other players simply because it is drawn first. 
  710.    We've to extract the proper bits from the collison masks of the other
  711.    players and need to "shuffle" a bit here... */
  712.  
  713. mtype GTIA_P0PL_GET(void)
  714. {
  715. int mask=0;
  716.  
  717.   mask  = (Player_Player[1] & 0x01)<<1;   /* mask in player 1 */
  718.   mask |= (Player_Player[2] & 0x01)<<2;   /* mask in player 2 */
  719.   mask |= (Player_Player[3] & 0x01)<<3;   /* mask in player 3 */
  720.  
  721.   return mask;
  722. }
  723.  
  724. mtype GTIA_P1PL_GET(void)
  725. {
  726. int mask=0;
  727.  
  728.   mask  = (Player_Player[1] & 0x01);      /* mask in player 0 */
  729.   mask |= (Player_Player[2] & 0x02)<<1;   /* mask in player 2 */
  730.   mask |= (Player_Player[3] & 0x02)<<2;   /* mask in player 3 */
  731.  
  732.   return mask;
  733. }
  734.  
  735. mtype GTIA_P2PL_GET(void)
  736. {
  737. int mask=0;
  738.  
  739.   mask  = (Player_Player[2] & 0x03);     /* mask in player 0 and 1 */
  740.   mask |= (Player_Player[3] & 0x04)<<1;  /* mask in player 3 */
  741.  
  742.   return mask;
  743. }
  744.  
  745. mtype GTIA_P3PL_GET(void)
  746. {
  747. int mask=0;
  748.  
  749.   mask  = (Player_Player[3] & 0x07);    /* mask in player 0,1 and 2 */
  750.  
  751.   return mask;
  752. }
  753.  
  754. mtype GTIA_PAL_GET(void)
  755. {
  756.   if (tv_mode == PAL)
  757.     return 0x01;
  758.   else return 0x0f;
  759. }
  760.  
  761. mtype GTIA_TRIG0_GET(void)
  762. {
  763.   return Atari_TRIG(0);
  764. }
  765.  
  766. mtype GTIA_TRIG1_GET(void)
  767. {
  768.   return Atari_TRIG(1);
  769. }
  770.  
  771. mtype GTIA_TRIG2_GET(void)
  772. {
  773.   return Atari_TRIG(2);
  774. }
  775.  
  776. mtype GTIA_TRIG3_GET(void)
  777. {
  778.   if (machine==Atari) return Atari_TRIG (3);
  779.   else                return (CartInserted())?(1):(0);
  780. }
  781.  
  782. int GTIA_COLBK_PUT(mtype byte)
  783. {
  784.   COLBK = byte;
  785.   colour_lookup[8] = colour_translation_table[byte];
  786.   return FALSE;
  787. }
  788.  
  789. int GTIA_COLPF0_PUT(mtype byte)
  790. {
  791.   COLPF0 = byte;
  792.   colour_lookup[4] = colour_translation_table[byte];
  793.   return FALSE;
  794. }
  795.  
  796. int GTIA_COLPF1_PUT(mtype byte)
  797. {
  798.   COLPF1 = byte;
  799.   colour_lookup[5] = colour_translation_table[byte];
  800.   return FALSE;
  801. }
  802.  
  803. int GTIA_COLPF2_PUT(mtype byte)
  804. {
  805.   COLPF2 = byte;
  806.   colour_lookup[6] = colour_translation_table[byte];
  807.   return FALSE;
  808. }
  809.  
  810. int GTIA_COLPF3_PUT(mtype byte)
  811. {
  812.   COLPF3 = byte;
  813.   colour_lookup[7] = colour_translation_table[byte];
  814.   return FALSE;
  815. }
  816.  
  817. int GTIA_COLPM0_PUT(mtype byte)
  818. {
  819.   COLPM0 = byte;
  820.   colour_lookup[0] = colour_translation_table[byte];
  821.   return FALSE;
  822. }
  823.  
  824. int GTIA_COLPM1_PUT(mtype byte)
  825. {
  826.   COLPM1 = byte;
  827.   colour_lookup[1] = colour_translation_table[byte];
  828.   return FALSE;
  829. }
  830.  
  831. int GTIA_COLPM2_PUT(mtype byte)
  832. {
  833.   COLPM2 = byte;
  834.   colour_lookup[2] = colour_translation_table[byte];
  835.   return FALSE;
  836. }
  837.  
  838. int GTIA_COLPM3_PUT(mtype byte)
  839. {
  840.   COLPM3 = byte;
  841.   colour_lookup[3] = colour_translation_table[byte];
  842.   return FALSE;
  843. }
  844.  
  845. int GTIA_GRAFM_PUT(mtype byte)
  846. {
  847.   GRAFM = byte;
  848.   return FALSE;
  849. }
  850.  
  851. int GTIA_GRAFP0_PUT(mtype byte)
  852. {
  853.   GRAFP0 = byte;
  854.   return FALSE;
  855. }
  856.  
  857. int GTIA_GRAFP1_PUT(mtype byte)
  858. {
  859.   GRAFP1 = byte;
  860.   return FALSE;
  861. }
  862.  
  863. int GTIA_GRAFP2_PUT(mtype byte)
  864. {
  865.   GRAFP2 = byte;
  866.   return FALSE;
  867. }
  868.  
  869. int GTIA_GRAFP3_PUT(mtype byte)
  870. {
  871.   GRAFP3 = byte;
  872.   return FALSE;
  873. }
  874.  
  875. int GTIA_HITCLR_PUT(mtype byte)
  876. {
  877.   memset(Player_Player,0,sizeof(UBYTE)*4);
  878.   memset(Player_Playfield,0,sizeof(UBYTE)*4);
  879.   memset(Missile_Player,0,sizeof(UBYTE)*4);
  880.   memset(Missile_Playfield,0,sizeof(UBYTE)*4);
  881.  
  882.   return FALSE;
  883. }
  884.  
  885. int GTIA_HPOSM0_PUT(mtype byte)
  886. {
  887.   HPOSM0 = byte;
  888.   global_hposm[3] = PM_XPos[byte];
  889.   return FALSE;
  890. }
  891.  
  892. int GTIA_HPOSM1_PUT(mtype byte)
  893. {
  894.   HPOSM0 = byte;
  895.   global_hposm[2] = PM_XPos[byte];
  896.   return FALSE;
  897. }
  898.  
  899. int GTIA_HPOSM2_PUT(mtype byte)
  900. {
  901.   HPOSM0 = byte;
  902.   global_hposm[1] = PM_XPos[byte];
  903.   return FALSE;
  904. }
  905.  
  906. int GTIA_HPOSM3_PUT(mtype byte)
  907. {
  908.   HPOSM0 = byte;
  909.   global_hposm[0] = PM_XPos[byte];
  910.   return FALSE;
  911. }
  912.  
  913. int GTIA_HPOSP0_PUT(mtype byte)
  914. {
  915.   HPOSP0 = byte;
  916.   global_hposp0 = PM_XPos[byte];
  917.   return FALSE;
  918. }
  919.  
  920. int GTIA_HPOSP1_PUT(mtype byte)
  921. {
  922.   HPOSP1 = byte;
  923.   global_hposp1 = PM_XPos[byte];
  924.   return FALSE;
  925. }
  926.  
  927. int GTIA_HPOSP2_PUT(mtype byte)
  928. {
  929.   HPOSP2 = byte;
  930.   global_hposp2 = PM_XPos[byte];
  931.   return FALSE;
  932. }
  933.  
  934. int GTIA_HPOSP3_PUT(mtype byte)
  935. {
  936.   HPOSP3 = byte;
  937.   global_hposp3 = PM_XPos[byte];
  938.   return FALSE;
  939. }
  940.  
  941. int GTIA_SIZEM_PUT(mtype byte)
  942. {
  943.   SIZEM = byte;  
  944.  
  945. /* We extract now the proper sizes of the missiles. Easier to do here than on
  946.    every scan line since this register isn't written to "too often". */
  947.  
  948.   global_sizem[3] = PM_Width[byte & 0x03];     
  949.   global_sizem[2] = PM_Width[(byte >> 2) & 0x03];
  950.   global_sizem[1] = PM_Width[(byte >> 4) & 0x03];
  951.   global_sizem[0] = PM_Width[(byte >> 6) & 0x03];
  952.  
  953.   return FALSE;
  954. }
  955.  
  956. int GTIA_SIZEP0_PUT(mtype byte)
  957. {
  958.   SIZEP0 = byte;
  959.   global_sizep0 = PM_Width[byte & 0x03];
  960.   return FALSE;
  961. }
  962.  
  963. int GTIA_SIZEP1_PUT(mtype byte)
  964. {
  965.   SIZEP1 = byte;
  966.   global_sizep1 = PM_Width[byte & 0x03];
  967.   return FALSE;
  968. }
  969.  
  970. int GTIA_SIZEP2_PUT(mtype byte)
  971. {
  972.   SIZEP2 = byte;
  973.   global_sizep2 = PM_Width[byte & 0x03];
  974.   return FALSE;
  975. }
  976.  
  977. int GTIA_SIZEP3_PUT(mtype byte)
  978. {
  979.   SIZEP3 = byte;
  980.   global_sizep3 = PM_Width[byte & 0x03];
  981.   return FALSE;
  982. }
  983.  
  984. int GTIA_PRIOR_PUT(mtype byte)
  985. {
  986.   PRIOR = byte;
  987.   Setup_Priority();
  988.   return FALSE;
  989. }
  990.  
  991. int GTIA_GRACTL_PUT(mtype byte)
  992. {
  993.   GRACTL = byte;
  994.   return FALSE;
  995. }
  996.  
  997. int GTIA_VDELAY_PUT(mtype byte)
  998. {
  999.   VDELAY = byte;
  1000.  
  1001. /* Calculate the delay for each player/missile */
  1002.  
  1003.   delaym0 = byte;
  1004.   delaym1 = byte>>1;
  1005.   delaym2 = byte>>2;
  1006.   delaym3 = byte>>3;
  1007.   delayp0 = byte>>4;
  1008.   delayp1 = byte>>5;
  1009.   delayp2 = byte>>6;
  1010.   delayp3 = byte>>7;
  1011.  
  1012.   delaym0 &= 0x01;
  1013.   delaym1 &= 0x01;
  1014.   delaym2 &= 0x01;
  1015.   delaym3 &= 0x01;
  1016.  
  1017.   delayp0 &= 0x01;
  1018.   delayp1 &= 0x01;
  1019.   delayp2 &= 0x01;
  1020.   delayp3 &= 0x01;
  1021.  
  1022.   return FALSE;
  1023. }
  1024.  
  1025. void Init_GTIA(int *argc, char **argv,int base)
  1026. {
  1027.   int i,j;
  1028.  
  1029.   if (argc) {
  1030.     artefacts = FALSE;
  1031.     for (i=j=1;i<*argc;i++) {
  1032.       if (strcmp(argv[i],"-artefacts") == 0)
  1033.     artefacts = TRUE;
  1034.       else
  1035.     argv[j++] = argv[i];
  1036.     }    
  1037.     *argc = j;
  1038.   }  
  1039.  
  1040.   for (i=0x00;i<256;i++)
  1041.     PM_XPos[i] = (i - 0x20) << 1;
  1042.  
  1043.   for (i=0;i<9;i++)
  1044.     colour_lookup[i] = 0x00;
  1045.  
  1046.   PRIOR = 0x00;
  1047.   Setup_Priority();
  1048.  
  1049.   SetHW(base+_HPOSP0,0xff1f,>IA_M0PF_GET,>IA_HPOSP0_PUT);
  1050.   SetHW(base+_HPOSP1,0xff1f,>IA_M1PF_GET,>IA_HPOSP1_PUT);
  1051.   SetHW(base+_HPOSP2,0xff1f,>IA_M2PF_GET,>IA_HPOSP2_PUT);
  1052.   SetHW(base+_HPOSP3,0xff1f,>IA_M3PF_GET,>IA_HPOSP3_PUT);
  1053.   SetHW(base+_HPOSM0,0xff1f,>IA_P0PF_GET,>IA_HPOSM0_PUT);
  1054.   SetHW(base+_HPOSM1,0xff1f,>IA_P1PF_GET,>IA_HPOSM1_PUT);
  1055.   SetHW(base+_HPOSM2,0xff1f,>IA_P2PF_GET,>IA_HPOSM2_PUT);
  1056.   SetHW(base+_HPOSM3,0xff1f,>IA_P3PF_GET,>IA_HPOSM3_PUT);
  1057.   SetHW(base+_SIZEP0,0xff1f,>IA_M0PL_GET,>IA_SIZEP0_PUT);
  1058.   SetHW(base+_SIZEP1,0xff1f,>IA_M1PL_GET,>IA_SIZEP1_PUT);
  1059.   SetHW(base+_SIZEP2,0xff1f,>IA_M2PL_GET,>IA_SIZEP2_PUT);
  1060.   SetHW(base+_SIZEP3,0xff1f,>IA_M3PL_GET,>IA_SIZEP3_PUT);
  1061.   SetHW(base+_SIZEM ,0xff1f,>IA_P0PL_GET,>IA_SIZEM_PUT );
  1062.   SetHW(base+_GRAFP0,0xff1f,>IA_P1PL_GET,>IA_GRAFP0_PUT);
  1063.   SetHW(base+_GRAFP1,0xff1f,>IA_P2PL_GET,>IA_GRAFP1_PUT);
  1064.   SetHW(base+_GRAFP2,0xff1f,>IA_P3PL_GET,>IA_GRAFP2_PUT);
  1065.   SetHW(base+_GRAFP3,0xff1f,>IA_TRIG0_GET,>IA_GRAFP3_PUT);
  1066.   SetHW(base+_GRAFM,0xff1f,>IA_TRIG1_GET,>IA_GRAFM_PUT);
  1067.   SetHW(base+_COLPM0,0xff1f,>IA_TRIG2_GET,>IA_COLPM0_PUT);
  1068.   SetHW(base+_COLPM1,0xff1f,>IA_TRIG3_GET,>IA_COLPM1_PUT);
  1069.   SetHW(base+_COLPM2,0xff1f,>IA_PAL_GET,>IA_COLPM2_PUT);
  1070.   SetHW(base+_COLPM3,0xff1f,NULL,>IA_COLPM3_PUT);
  1071.   SetHW(base+_COLPF0,0xff1f,NULL,>IA_COLPF0_PUT);
  1072.   SetHW(base+_COLPF1,0xff1f,NULL,>IA_COLPF1_PUT);
  1073.   SetHW(base+_COLPF2,0xff1f,NULL,>IA_COLPF2_PUT);
  1074.   SetHW(base+_COLPF3,0xff1f,NULL,>IA_COLPF3_PUT);
  1075.   SetHW(base+_COLBK,0xff1f,NULL,>IA_COLBK_PUT);
  1076.   SetHW(base+_PRIOR,0xff1f,NULL,>IA_PRIOR_PUT);
  1077.   SetHW(base+_VDELAY,0xff1f,NULL,>IA_VDELAY_PUT);
  1078.   SetHW(base+_GRACTL,0xff1f,NULL,>IA_GRACTL_PUT);
  1079.   SetHW(base+_HITCLR,0xff1f,NULL,>IA_HITCLR_PUT);
  1080.   SetHW(base+_CONSOL,0xff1f,>IA_CONSOL_GET,NULL);
  1081.  
  1082. }
  1083.