home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / Atari800 / antic_old.c < prev    next >
C/C++ Source or Header  |  1998-02-26  |  33KB  |  1,554 lines

  1. /*
  2.     *****************************************************************
  3.     *                                *
  4.     *    Section            :    Antic Display Modes    *
  5.     *    Original Author        :    David Firth        *
  6.     *                               :       Thomas Richter (thor)   *
  7.     *    Date Written        :    28th May 1995        *
  8.     *                               :       17th February 1988      *
  9.     *    Version            :    1.3            *
  10.     *                                *
  11.     *                                *
  12.     *   Description                            *
  13.     *   -----------                            *
  14.     *                                *
  15.     *   Section that handles Antic display modes. Not required    *
  16.     *   for BASIC version.                        *
  17.     *                                *
  18.     *****************************************************************
  19. */
  20.  
  21. #include <stdio.h>
  22. #include <string.h>
  23.  
  24. #ifndef AMIGA
  25. #include "config.h"
  26. #endif
  27.  
  28. #include "atari.h"
  29. #include "rt-config.h"
  30. #include "mem.h"
  31. #include "cpu.h"
  32. #include "gtia.h"
  33. #include "antic.h"
  34.  
  35. #define FALSE 0
  36. #define TRUE 1
  37.  
  38. int xmin;
  39. int xmax;
  40.  
  41. int dmactl_xmin_noscroll;
  42. int dmactl_xmax_noscroll;
  43. static int dmactl_xmin_scroll;
  44. static int dmactl_xmax_scroll;
  45. static int memory_basis;          /* refresh cycles needed for memory */
  46. static int pm_dma;                /* DMA cycles needed by P/M graphics */
  47. static int char_delta;
  48. static int char_offset;
  49. static int invert_mask;
  50. static int blank_mask;
  51. static int screenaddr;
  52.  
  53. /* colour lookup tables */
  54.  
  55. static int lookup_f[256];
  56. static int lookup_4[256];
  57. static int lookup24[256];
  58. static int lookup_6[256];
  59. static int lookup_9[256];
  60.  
  61. static char *rcsid = "$Id: antic.c,v 1.30 1998/02/17 thor,david Exp $";
  62.  
  63. UBYTE CHACTL;
  64. UBYTE CHBASE;
  65. UWORD DLIST,DLISTINIT;
  66. UBYTE DMACTL;
  67. UBYTE HSCROL;
  68. UBYTE NMIEN;
  69. UBYTE NMIST;
  70. UBYTE PMBASE;
  71. UBYTE VSCROL;
  72.  
  73. int DMAwidth;
  74.  
  75. extern UWORD regPC;
  76.  
  77. /*
  78.  * These are defined for Word (2 Byte) memory accesses. I have not
  79.  * defined Longword (4 Byte) values since the Sparc architecture
  80.  * requires that Longword are on a longword boundry.
  81.  *
  82.  * Words accesses don't appear to be a problem because the first
  83.  * pixel plotted on a line will always be at an even offset, and
  84.  * hence on a word boundry.
  85.  *
  86.  * Note: HSCROL is in colour clocks whereas the pixels are emulated
  87.  *       down to a half colour clock - the first pixel plotted is
  88.  *       moved across by 2*HSCROL
  89.  */
  90.  
  91. #define PF2_COLPF0 0x0404
  92. #define PF2_COLPF1 0x0505
  93. #define PF2_COLPF2 0x0606
  94. #define PF2_COLPF3 0x0707
  95. #define PF2_COLBK 0x0808
  96. #define PF2_COLPF1_FID 0x1515
  97.  
  98. #define PF4_COLPF0 0x04040404
  99. #define PF4_COLPF1 0x05050505
  100. #define PF4_COLPF2 0x06060606
  101. #define PF4_COLPF3 0x07070707
  102. #define PF4_COLBK 0x08080808
  103. #define PF4_COLPF1_FID 0x15151515
  104.  
  105. /* The middle of the display. All color/display/whatever changes BEFORE that
  106.    cycle are seen on the same row.
  107.    All changes after this color clock are visible ON THE NEXT row */
  108. #define CC_MIDDLE 50
  109. /* The propagation delay needed by the 6502 to react on the NMI interrupt */
  110. #define DLI_DELAY 8
  111. /* The number of cycles available on the same row to proceed after WSYNC and
  112.    before the horizontal blank */
  113. #define AFTER_WSYNC 20
  114. /* The number of cycles available after the horizontal blank but before the
  115.    DMA of antic actually starts */
  116. #define BEFORE_DMA 0
  117. /* The line where the VSYNC is generated. */
  118. #define VSYNC_POS 250
  119.  
  120. int cc_middle=CC_MIDDLE;
  121. int dli_delay=DLI_DELAY;
  122. int after_wsync=AFTER_WSYNC;
  123. int before_dma=BEFORE_DMA;
  124. int vsync_pos=VSYNC_POS;
  125.  
  126.  
  127. int ypos;
  128.  
  129. /*
  130.  * Pre-computed values for improved performance
  131.  */
  132.  
  133. static int chbase_40; /* CHBASE for 40 character mode */
  134. static int chbase_20; /* CHBASE for 20 character mode */
  135. static int maddr_s; /* Address of Missiles - Single Line Resolution */
  136. static int p0addr_s; /* Address of Player0 - Single Line Resolution */
  137. static int p1addr_s; /* Address of Player1 - Single Line Resolution */
  138. static int p2addr_s; /* Address of Player2 - Single Line Resolution */
  139. static int p3addr_s; /* Address of Player3 - Single Line Resolution */
  140. static int maddr_d; /* Address of Missiles - Double Line Resolution */
  141. static int p0addr_d; /* Address of Player0 - Double Line Resolution */
  142. static int p1addr_d; /* Address of Player1 - Double Line Resolution */
  143. static int p2addr_d; /* Address of Player2 - Double Line Resolution */
  144. static int p3addr_d; /* Address of Player3 - Double Line Resolution */
  145.  
  146. int wsync_halt = 0;
  147. static int carry=0;   /* carry over of CPU cycles */
  148.  
  149. /*
  150.    =============================================================
  151.    Define screen as ULONG to ensure that it is Longword aligned.
  152.    This allows special optimisations under certain conditions.
  153.    -------------------------------------------------------------
  154.    The extra 16 scanlines is used as an overflow buffer and has
  155.    enough room for any extra mode line. It is needed on the
  156.    occasions that a valid JVB instruction is not found in the
  157.    display list - An automatic break out will occur when ypos
  158.    is greater than the ATARI_HEIGHT, if its one less than this
  159.    there must be enough space for another mode line.
  160.    =============================================================
  161. */
  162.  
  163. ULONG *atari_screen = NULL;
  164. UBYTE *scrn_ptr;
  165.  
  166. /* I/O register read */
  167.  
  168. mtype ANTIC_CHBASE_GET(void)
  169. {
  170.   return CHBASE;
  171. }
  172.  
  173. mtype ANTIC_CHACTL_GET(void)
  174. {
  175.   return CHACTL;
  176. }
  177.  
  178. mtype ANTIC_DLISTL_GET(void)
  179. {
  180.   return DLIST & 0xff;
  181. }
  182.  
  183. mtype ANTIC_DLISTH_GET(void)
  184. {
  185.   return DLIST >> 8;
  186. }
  187.  
  188. mtype ANTIC_DMACTL_GET(void)
  189. {
  190.   return DMACTL;
  191. }
  192.  
  193. mtype ANTIC_VCOUNT_GET(void)
  194. {
  195.   return ypos >> 1;
  196. }
  197.  
  198. mtype ANTIC_NMIEN_GET(void)
  199. {
  200.   return NMIEN | 0x1f;
  201. }
  202.  
  203. mtype ANTIC_NMIST_GET(void)
  204. {
  205.   return NMIST;
  206. }
  207.  
  208. mtype ANTIC_WSYNC_GET(void)
  209. {
  210.   if (wsync_halt)
  211.     printf("Double wsync!\n");
  212.   wsync_halt++;
  213.   return 0xff;
  214. }
  215.  
  216. /* I/O put routines */
  217.  
  218. int ANTIC_CHBASE_PUT(mtype byte)
  219. {
  220.   CHBASE = byte;
  221.   chbase_40 = (byte << 8) & 0xfc00;
  222.   chbase_20 = (byte << 8) & 0xfe00;
  223.   return FALSE;
  224. }
  225.  
  226. int ANTIC_CHACTL_PUT(mtype byte)
  227. {
  228.   CHACTL = byte;
  229. /*
  230.    =================================================================
  231.    Check for vertical reflect, video invert and character blank bits
  232.    =================================================================
  233. */
  234.   switch (CHACTL & 0x07)
  235.     {
  236.     case 0x00 :
  237.       char_offset = 0;
  238.       char_delta = 1;
  239.       invert_mask = 0x00;
  240.       blank_mask = 0x00;
  241.       break;
  242.     case 0x01 :
  243.       char_offset = 0;
  244.       char_delta = 1;
  245.       invert_mask = 0x00;
  246.       blank_mask = 0x80;
  247.       break;
  248.     case 0x02 :
  249.       char_offset = 0;
  250.       char_delta = 1;
  251.       invert_mask = 0x80;
  252.       blank_mask = 0x00;
  253.       break;
  254.     case 0x03 :
  255.       char_offset = 0;
  256.       char_delta = 1;
  257.       invert_mask = 0x80;
  258.       blank_mask = 0x80;
  259.       break;
  260.     case 0x04 :
  261.       char_offset = 7;
  262.       char_delta = -1;
  263.       invert_mask = 0x00;
  264.       blank_mask = 0x00;
  265.       break;
  266.     case 0x05 :
  267.       char_offset = 7;
  268.       char_delta = -1;
  269.       invert_mask = 0x00;
  270.       blank_mask = 0x80;
  271.       break;
  272.     case 0x06 :
  273.       char_offset = 7;
  274.       char_delta = -1;
  275.       invert_mask = 0x80;
  276.       blank_mask = 0x00;
  277.       break;
  278.     case 0x07 :
  279.       char_offset = 7;
  280.       char_delta = -1;
  281.       invert_mask = 0x80;
  282.       blank_mask = 0x80;
  283.       break;
  284.     }
  285.  
  286.   return FALSE;
  287. }
  288.  
  289. int ANTIC_DLISTL_PUT(mtype byte)
  290. {
  291.   DLIST = (DLIST & 0xff00) | byte;
  292.   DLISTINIT = DLIST;
  293.   return FALSE;
  294. }
  295.  
  296. int ANTIC_DLISTH_PUT(mtype byte)
  297. {
  298.   DLIST = (DLIST & 0x00ff) | (byte<<8);  
  299.   DLISTINIT = DLIST;
  300.   return FALSE;
  301. }
  302.  
  303. int ANTIC_DMACTL_PUT(mtype byte)
  304. {
  305.   /* printf("DMACTL set to %2x at %4x\n",byte,regPC); */
  306.   DMACTL = byte;
  307.   switch (DMACTL & 0x03)
  308.     {
  309.     case 0x00 :
  310.       dmactl_xmin_noscroll = dmactl_xmax_noscroll = 0;
  311.       dmactl_xmin_scroll = dmactl_xmax_scroll = 0;
  312.       DMAwidth = 0;
  313.       memory_basis = 9;   /* nine cycles for refresh */
  314.       break;
  315.     case 0x01 :
  316.       dmactl_xmin_noscroll = 64;
  317.       dmactl_xmax_noscroll = ATARI_WIDTH - 64;
  318.       dmactl_xmin_scroll = 32;
  319.       dmactl_xmax_scroll = ATARI_WIDTH - 32;
  320.       DMAwidth = 4;
  321.       memory_basis = 2;   /* nine cycles for refresh */
  322.       break;
  323.     case 0x02 :
  324.       dmactl_xmin_noscroll = 32;
  325.       dmactl_xmax_noscroll = ATARI_WIDTH - 32;
  326.       dmactl_xmin_scroll = 0;
  327.       dmactl_xmax_scroll = ATARI_WIDTH;
  328.       memory_basis = 1;
  329.       DMAwidth = 5;
  330.       break;
  331.     case 0x03 :
  332.       dmactl_xmin_noscroll = dmactl_xmin_scroll = 0;
  333.       dmactl_xmax_noscroll = dmactl_xmax_scroll = ATARI_WIDTH;
  334.       memory_basis = 0;
  335.       DMAwidth = 6;
  336.       break;
  337.     }
  338.  
  339.   pm_dma = 0;   /* cycles needed for PM graphics */
  340.  
  341.   if (DMACTL & 0x0C)   /* Player DMA enables missile DMA */
  342.     pm_dma += 1;
  343.   if (DMACTL & 0x08)   /* Player DMA ? */
  344.     pm_dma += 4;
  345.  
  346. /* SingleLine DMACTL & 0x10 not covered here */
  347.  
  348.   return FALSE;
  349. }
  350.  
  351. int ANTIC_HSCROL_PUT(mtype byte)
  352. {
  353.   HSCROL = byte & 0x0f;
  354.   return FALSE;
  355. }
  356.  
  357. int ANTIC_NMIEN_PUT(mtype byte)
  358. {
  359.   NMIEN = byte | 0x1f;
  360.   /* printf("Wrote %d into NMIEN.\n",byte); */
  361.   return FALSE;
  362. }
  363.  
  364. int ANTIC_NMIRES_PUT(mtype byte)
  365. {
  366.   NMIST = 0x1f;
  367.   return FALSE;
  368. }
  369.  
  370. int ANTIC_PMBASE_PUT(mtype byte)
  371. {
  372. UWORD pmbase_s;
  373. UWORD pmbase_d;
  374.  
  375.   PMBASE = byte;
  376.  
  377.   pmbase_s = (PMBASE & 0xf8) << 8;
  378.   pmbase_d = (PMBASE & 0xfc) << 8;
  379.   
  380.   maddr_s = pmbase_s + 768;
  381.   p0addr_s = pmbase_s + 1024;
  382.   p1addr_s = pmbase_s + 1280;
  383.   p2addr_s = pmbase_s + 1536;
  384.   p3addr_s = pmbase_s + 1792;
  385.   
  386.   maddr_d = pmbase_d + 384;
  387.   p0addr_d = pmbase_d + 512;
  388.   p1addr_d = pmbase_d + 640;
  389.   p2addr_d = pmbase_d + 768;
  390.   p3addr_d = pmbase_d + 896;
  391.   
  392.   return FALSE;
  393. }
  394.  
  395. int ANTIC_VSCROL_PUT(mtype byte)
  396. {
  397.   VSCROL = byte & 0x0f;
  398.   return FALSE;
  399. }
  400.  
  401. int ANTIC_WSYNC_PUT(mtype byte)
  402. {
  403.   wsync_halt ++;
  404.   return TRUE;
  405. }
  406.  
  407. void Init_Antic (int *argc, char *argv[],int base)
  408. {
  409. int i;
  410. int j;
  411.  
  412.   if (argc) {
  413.     for (i=j=1;i<*argc;i++)
  414.       {
  415.     if (strcmp(argv[i],"-xcolpf1") == 0)
  416.       enable_xcolpf1 = TRUE;
  417.     else
  418.       argv[j++] = argv[i];
  419.       }
  420.     
  421.     *argc = j;
  422.   }  
  423.  
  424.   NMIEN = 0x1f;
  425.   NMIST = 0x00;
  426.   DMACTL = 0x00;
  427.   VSCROL = 0x00;
  428.   HSCROL = 0x00;
  429.  
  430. /* setup lookup tables */
  431.  
  432.   memset(lookup_f,0,256*sizeof(int));
  433.   memset(lookup_4,0,256*sizeof(int));
  434.   memset(lookup24,0,256*sizeof(int));
  435.   memset(lookup_9,0,256*sizeof(int));
  436.  
  437.   lookup_f[0x00]=PF_COLPF2;
  438.   lookup_f[0x80]=lookup_f[0x40]=lookup_f[0x20]=
  439.   lookup_f[0x10]=lookup_f[0x08]=lookup_f[0x04]=
  440.   lookup_f[0x02]=lookup_f[0x01]=PF_COLPF1_FID;
  441.  
  442.   lookup_4[0x00]=PF2_COLBK;
  443.   lookup_4[0x40]=lookup_4[0x10]=lookup_4[0x04]=lookup_4[0x01]=PF2_COLPF0;
  444.   lookup_4[0x80]=lookup_4[0x20]=lookup_4[0x08]=lookup_4[0x02]=PF2_COLPF1;
  445.   lookup_4[0xc0]=lookup_4[0x30]=lookup_4[0x0c]=lookup_4[0x03]=PF2_COLPF2;
  446.  
  447.   lookup24[0x00]=PF2_COLBK;
  448.   lookup24[0x40]=lookup24[0x10]=lookup24[0x04]=lookup24[0x01]=PF2_COLPF0;
  449.   lookup24[0x80]=lookup24[0x20]=lookup24[0x08]=lookup24[0x02]=PF2_COLPF1;
  450.   lookup24[0xc0]=lookup24[0x30]=lookup24[0x0c]=lookup24[0x03]=PF2_COLPF3;
  451.  
  452.   lookup_9[0x00]=PF2_COLBK;
  453.   lookup_9[0x80]=lookup_9[0x40]=lookup_9[0x20]=lookup_9[0x10]=
  454.   lookup_9[0x08]=lookup_9[0x04]=lookup_9[0x02]=lookup_9[0x01]=PF2_COLPF0;
  455.  
  456.   memset(lookup_6+0x00,PF2_COLPF0,0x40*sizeof(int));
  457.   memset(lookup_6+0x40,PF2_COLPF1,0x40*sizeof(int));
  458.   memset(lookup_6+0x80,PF2_COLPF2,0x40*sizeof(int));
  459.   memset(lookup_6+0xc0,PF2_COLPF3,0x40*sizeof(int));
  460.  
  461.   SetHW(base+_DMACTL,0xff0f,&ANTIC_DMACTL_GET,&ANTIC_DMACTL_PUT);
  462.   SetHW(base+_CHACTL,0xff0f,&ANTIC_CHACTL_GET,&ANTIC_CHACTL_PUT);
  463.   SetHW(base+_DLISTL,0xff0f,&ANTIC_DLISTL_GET,&ANTIC_DLISTL_PUT);
  464.   SetHW(base+_DLISTH,0xff0f,&ANTIC_DLISTH_GET,&ANTIC_DLISTH_PUT);
  465.   SetHW(base+_HSCROL,0xff0f,NULL,&ANTIC_HSCROL_PUT);
  466.   SetHW(base+_VSCROL,0xff0f,NULL,&ANTIC_VSCROL_PUT);
  467.   SetHW(base+_PMBASE,0xff0f,NULL,&ANTIC_PMBASE_PUT);
  468.   SetHW(base+_CHBASE,0xff0f,&ANTIC_CHBASE_GET,&ANTIC_CHBASE_PUT);
  469.   SetHW(base+_VCOUNT,0xff0f,&ANTIC_VCOUNT_GET,NULL);
  470.   SetHW(base+_NMIEN,0xff0f,&ANTIC_NMIEN_GET,&ANTIC_NMIEN_PUT);
  471.   SetHW(base+_NMIRES,0xff0f,&ANTIC_NMIST_GET,&ANTIC_NMIRES_PUT);
  472.   SetHW(base+_WSYNC,0xff0f,&ANTIC_WSYNC_GET,&ANTIC_WSYNC_PUT);
  473. }
  474.  
  475. void antic_blank (int nlines)
  476. {
  477.   if (nlines > 0)
  478.     {
  479.       int nbytes;
  480.  
  481.       nbytes = nlines * ATARI_MODULO;
  482.       memset (scrn_ptr, PF_COLBK, nbytes);
  483.     }
  484. }
  485.  
  486. static int vskipbefore = 0;
  487. static int vskipafter = 0;
  488.  
  489. void antic_2 ()
  490. {
  491.   UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
  492.   int nchars = (xmax - xmin) >> 3;
  493.   int i;
  494.  
  495.   for (i=0;i<nchars;i++)
  496.     {
  497.       int screendata = APeek(screenaddr);
  498.       int chaddr;
  499.       int invert;
  500.       int blank;
  501.       UBYTE *ptr = t_scrn_ptr;
  502.       int j;
  503.  
  504.       screenaddr++;
  505.       chaddr = chbase_40 + char_offset + ((screendata & 0x7f) << 3);
  506.  
  507.       if (screendata & invert_mask)
  508.     invert = 0xff;
  509.       else
  510.     invert = 0x00;
  511.  
  512.       if (screendata & blank_mask)
  513.     blank = 0x00;
  514.       else
  515.     blank = 0xff;
  516.  
  517.       for (j=0;j<8;j++)
  518.     {
  519.       int    chdata;
  520.  
  521.       chdata = (APeek(chaddr) ^ invert) & blank;
  522.       chaddr += char_delta;
  523.  
  524.       if (j<vskipbefore || j>vskipafter)
  525.         continue;
  526.  
  527.       if (chdata) {
  528.         *ptr++ = lookup_f[chdata & 0x80];
  529.         *ptr++ = lookup_f[chdata & 0x40];
  530.         *ptr++ = lookup_f[chdata & 0x20];
  531.         *ptr++ = lookup_f[chdata & 0x10];
  532.         *ptr++ = lookup_f[chdata & 0x08];
  533.         *ptr++ = lookup_f[chdata & 0x04];
  534.         *ptr++ = lookup_f[chdata & 0x02];
  535.         *ptr++ = lookup_f[chdata & 0x01];
  536.       } else {
  537. #ifdef UNALIGNED_LONG_OK
  538.         ULONG *l_ptr = (ULONG*)ptr;
  539.         
  540.         *l_ptr++ = PF4_COLPF2;
  541.         *l_ptr++ = PF4_COLPF2;
  542.         
  543.         ptr = (UBYTE*)l_ptr;
  544. #else
  545.         UWORD *w_ptr = (UWORD*)ptr;
  546.         
  547.         *w_ptr++ = PF2_COLPF2;
  548.         *w_ptr++ = PF2_COLPF2;
  549.         *w_ptr++ = PF2_COLPF2;
  550.         *w_ptr++ = PF2_COLPF2;
  551.         
  552.         ptr = (UBYTE*)w_ptr;
  553. #endif
  554.       }
  555.       ptr += (ATARI_MODULO - 8);
  556.     }
  557.  
  558.       t_scrn_ptr += 8;
  559.     }
  560. }
  561.  
  562. /*
  563.  * Function to display Antic Mode 3
  564.  */
  565.  
  566. void antic_3 ()
  567. {
  568.   UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
  569.   int nchars = (xmax - xmin) >> 3;
  570.   int i;
  571.  
  572.   for (i=0;i<nchars;i++)
  573.     {
  574.       int screendata = APeek(screenaddr);
  575.       int chaddr;
  576.       int invert;
  577.       int blank;
  578.       int lowercase;
  579.       int first=0;
  580.       int second=0;
  581.       UBYTE *ptr = t_scrn_ptr;
  582.       int j;
  583.       screenaddr++;
  584.  
  585.       chaddr = chbase_40 + ((screendata & 0x7f) << 3) + char_offset;
  586.  
  587.       if (screendata & invert_mask)
  588.     invert = 0xff;
  589.       else
  590.     invert = 0x00;
  591.  
  592.       if (screendata & blank_mask)
  593.     blank = 0x00;
  594.       else
  595.     blank = 0xff;
  596.  
  597.       if ((screendata & 0x60) == 0x60)
  598.     lowercase = TRUE;
  599.       else
  600.     lowercase = FALSE;
  601.  
  602.       for (j=0;j<10;j++)
  603.     {
  604.       int chdata;
  605.       
  606.       if (lowercase) {
  607.         switch (j) {
  608.         case 0 :
  609.           first = APeek(chaddr);
  610.           chaddr += char_delta;
  611.           chdata = 0;
  612.           break;
  613.         case 1 :
  614.           second = APeek(chaddr);
  615.           chaddr += char_delta;
  616.           chdata = 0;
  617.           break;
  618.         case 8 :
  619.           chdata = first;
  620.           break;
  621.         case 9 :
  622.           chdata = second;
  623.           break;
  624.         default :
  625.           chdata = APeek(chaddr);
  626.           chaddr += char_delta;
  627.           break;
  628.         }
  629.       } else if (j < 8) {
  630.         chdata = APeek(chaddr);
  631.         chaddr += char_delta;
  632.       } else {
  633.         chdata = 0;
  634.       }
  635.  
  636.       chdata = (chdata ^ invert) & blank;
  637.  
  638.       if (j<vskipbefore || j>vskipafter)
  639.         continue;
  640.  
  641.       if (chdata) {
  642.           *ptr++ = lookup_f[chdata & 0x80];
  643.           *ptr++ = lookup_f[chdata & 0x40];
  644.           *ptr++ = lookup_f[chdata & 0x20];
  645.           *ptr++ = lookup_f[chdata & 0x10];
  646.           *ptr++ = lookup_f[chdata & 0x08];
  647.           *ptr++ = lookup_f[chdata & 0x04];
  648.           *ptr++ = lookup_f[chdata & 0x02];
  649.           *ptr++ = lookup_f[chdata & 0x01];
  650.       } else {
  651.           *ptr++ = PF_COLPF2;
  652.           *ptr++ = PF_COLPF2;
  653.           *ptr++ = PF_COLPF2;
  654.           *ptr++ = PF_COLPF2;
  655.           *ptr++ = PF_COLPF2;
  656.           *ptr++ = PF_COLPF2;
  657.           *ptr++ = PF_COLPF2;
  658.           *ptr++ = PF_COLPF2;
  659.         }
  660.       
  661.       ptr += (ATARI_MODULO - 8);
  662.     }
  663.  
  664.       t_scrn_ptr += 8;
  665.     }
  666. }
  667.  
  668. /*
  669.  * Funtion to display Antic Mode 4
  670.  */
  671.  
  672. void antic_4 ()
  673. {
  674.   UWORD *t_scrn_ptr = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
  675.   int nchars = (xmax - xmin) >> 3;
  676.   int i;
  677.  
  678.   for (i=0;i<nchars;i++)
  679.     {
  680.       int screendata = APeek(screenaddr);
  681.       int chaddr;
  682.       int *lookup;
  683.       UWORD *ptr = t_scrn_ptr;
  684.       int j;
  685.       
  686.       screenaddr++;
  687.       chaddr = chbase_40 + ((screendata & 0x7f) << 3) + char_offset;
  688.  
  689.       if (screendata & 0x80)
  690.     lookup = lookup24;
  691.       else
  692.     lookup = lookup_4;
  693.  
  694.       for (j=0;j<8;j++)
  695.     {
  696.       int chdata;
  697.  
  698.       chdata = APeek(chaddr);
  699.       chaddr += char_delta;
  700.  
  701.       if (j<vskipbefore || j>vskipafter)
  702.         continue;
  703.  
  704.       if (chdata) {
  705.         *ptr++ = lookup[chdata & 0xc0];
  706.         *ptr++ = lookup[chdata & 0x30];
  707.         *ptr++ = lookup[chdata & 0x0c];
  708.         *ptr++ = lookup[chdata & 0x03];
  709.       } else {
  710.         *ptr++ = PF2_COLBK;
  711.         *ptr++ = PF2_COLBK;
  712.         *ptr++ = PF2_COLBK;
  713.         *ptr++ = PF2_COLBK;
  714.       }
  715.       
  716.       ptr += ((ATARI_MODULO - 8) >> 1);
  717.     
  718.     }
  719.       
  720.       t_scrn_ptr += 4;
  721.     }
  722. }
  723.  
  724. /*
  725.  * Function to Display Antic Mode 5
  726.  */
  727.  
  728. void antic_5 ()
  729. {
  730.   UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
  731.   int nchars = nchars = (xmax - xmin) >> 3;
  732.   int i;
  733.  
  734.   for (i=0;i<nchars;i++)
  735.     {
  736.       int screendata = APeek(screenaddr);
  737.       int chaddr;
  738.       int *lookup;
  739.       UWORD *ptr1 = t_scrn_ptr1;
  740.       int j;
  741.  
  742.       screenaddr++;
  743.       chaddr = chbase_40 + ((UWORD)(screendata & 0x7f) << 3) + char_offset;
  744.  
  745.       if (screendata & 0x80)
  746.     lookup = lookup24;
  747.       else
  748.     lookup = lookup_4;
  749.  
  750.       for (j=0;j<16;j++)
  751.     {
  752.       int chdata;
  753.  
  754.       chdata = APeek(chaddr);      
  755.       if (j & 0x01)      chaddr += char_delta;
  756.  
  757.       if (j<vskipbefore || j>vskipafter)
  758.         continue;
  759.  
  760.       if (chdata) {
  761.         *ptr1++ = lookup[chdata & 0xc0];
  762.         *ptr1++ = lookup[chdata & 0x30];
  763.         *ptr1++ = lookup[chdata & 0x0c];
  764.         *ptr1++ = lookup[chdata & 0x03];
  765.       } else {
  766.         *ptr1++ = PF2_COLBK;
  767.         *ptr1++ = PF2_COLBK;
  768.         *ptr1++ = PF2_COLBK;
  769.         *ptr1++ = PF2_COLBK;
  770.       }
  771.  
  772.       ptr1 += ((ATARI_MODULO - 8) >> 1);
  773.     }
  774.       
  775.       t_scrn_ptr1 += (8 >> 1);
  776.     }
  777. }
  778.  
  779. /*
  780.  * Function to Display Antic Mode 6
  781.  */
  782.  
  783. void antic_6 ()
  784. {
  785.   UWORD *t_scrn_ptr = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
  786.   int nchars = (xmax - xmin) >> 4; /* Divide by 16 */
  787.   int i;
  788.  
  789.   for (i=0;i<nchars;i++)
  790.     {
  791.       int screendata = APeek(screenaddr);
  792.       int chaddr;
  793.       UWORD *ptr = t_scrn_ptr;
  794.       int colour=0;
  795.       int j;
  796.       
  797.       screenaddr++;
  798.       chaddr = chbase_20 + ((UWORD)(screendata & 0x3f) << 3) + char_offset;
  799.       colour = lookup_6[screendata];
  800.  
  801.       for (j=0;j<8;j++)    {
  802.     int chdata;
  803.     int k;
  804.     
  805.     chdata = memory[chaddr];
  806.     chaddr += char_delta;
  807.     
  808.     if (j<vskipbefore || j>vskipafter)
  809.       continue;
  810.     
  811.     for (k=0;k<8;k++)
  812.       {
  813.         if (chdata & 0x80)
  814.           *ptr++ = colour;
  815.         else    *ptr++ = PF2_COLBK;
  816.         
  817.         chdata = chdata << 1;
  818.       }
  819.     
  820.     ptr += ((ATARI_MODULO - 16) >> 1);
  821.       }
  822.       
  823.       t_scrn_ptr += (16 >> 1);
  824.     }
  825. }
  826.  
  827. /*
  828.  * Function to Display Antic Mode 7
  829.  */
  830.  
  831. void antic_7 ()
  832. {
  833.   UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
  834.   int nchars = (xmax - xmin) >> 4; /* Divide by 16 */
  835.   int i;
  836.  
  837.   for (i=0;i<nchars;i++)
  838.     {
  839.       int screendata = APeek(screenaddr);
  840.       int chaddr;
  841.       UWORD *ptr1 = t_scrn_ptr1;
  842.       int colour=0;
  843.       int j;
  844.       
  845.       screenaddr++;
  846.       chaddr = chbase_20 + ((UWORD)(screendata & 0x3f) << 3) + char_offset;
  847.       colour = lookup_6[screendata];
  848.  
  849.       for (j=0;j<16;j++)
  850.     {
  851.       int chdata;
  852.       int k;
  853.  
  854.       chdata = APeek(chaddr);
  855.  
  856.       if (j & 0x01)      chaddr += char_delta;
  857.  
  858.       if (j<vskipbefore || j>vskipafter)
  859.         continue;
  860.  
  861.       for (k=0;k<8;k++)
  862.         {
  863.           if (chdata & 0x80)   *ptr1++ = colour;
  864.           else                 *ptr1++ = PF2_COLBK;
  865.           chdata = chdata << 1;
  866.         }
  867.       
  868.       ptr1 += ((ATARI_MODULO - 16) >> 1);
  869.     }
  870.       
  871.       t_scrn_ptr1 += (16 >> 1);
  872.     }
  873. }
  874.  
  875. /*
  876.  * Function to Display Antic Mode 8
  877.  */
  878.  
  879. void antic_8 ()
  880. {
  881.   UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
  882.   int nbytes = (xmax - xmin) >> 5; /* Divide by 32 */
  883.   int    i;
  884.  
  885.   for (i=0;i<nbytes;i++)
  886.     {
  887.       int screendata = APeek(screenaddr);
  888.       int j;
  889.  
  890.       screenaddr++;
  891.  
  892.       for (j=0;j<4;j++) {
  893.     int colour;
  894.     UBYTE *ptr = t_scrn_ptr;
  895.     int k;
  896.  
  897.     colour = lookup_4[screendata & 0xc0];
  898.     
  899.     for (k=0;k<8;k++) {
  900.       if (k<vskipbefore || k>vskipafter)
  901.         continue;
  902.       memset (ptr, colour, 8);
  903.       ptr += ATARI_MODULO;
  904.     }
  905.     
  906.     screendata = screendata << 2;
  907.     t_scrn_ptr += 8;
  908.       }
  909.     }
  910. }
  911.  
  912. /*
  913.  * Function to Display Antic Mode 9
  914.  */
  915.  
  916. void antic_9 ()
  917. {
  918.   UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
  919.   int nbytes = (xmax - xmin) >> 5; /* Divide by 32 */
  920.   int i;
  921.  
  922.   for (i=0;i<nbytes;i++)
  923.     {
  924.       int screendata = APeek(screenaddr);
  925.       int j;
  926.  
  927.       screenaddr++;
  928.       for (j=0;j<8;j++) {
  929.     int colour;
  930.     UBYTE *ptr = t_scrn_ptr;
  931.     int k;
  932.  
  933.     colour = lookup_9[screendata & 0x80];
  934.  
  935.     for (k=0;k<4;k++) {
  936.       if (k<vskipbefore || k>vskipafter)
  937.         continue;
  938.       memset (ptr, colour, 4);
  939.       ptr += ATARI_MODULO;
  940.     }
  941.     
  942.     screendata = screendata << 1;
  943.       t_scrn_ptr += 4;
  944.       }
  945.     }
  946. }
  947.  
  948. /*
  949.  * Function to Display Antic Mode a
  950.  */
  951.  
  952. void antic_a ()
  953. {
  954.   UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
  955.   int nbytes = (xmax - xmin) >> 4; /* Divide by 16 */
  956.   int i;
  957.  
  958.   for (i=0;i<nbytes;i++)
  959.     {
  960.       int screendata = APeek(screenaddr);
  961.       int j;
  962.       
  963.       screenaddr++;
  964.       
  965.       for (j=0;j<4;j++)
  966.     {
  967.       int colour;
  968.       UBYTE *ptr = t_scrn_ptr;
  969.       int k;
  970.  
  971.       colour = lookup_4[screendata & 0xc0];
  972.  
  973.       for (k=0;k<4;k++)  {
  974.         if (k<vskipbefore || k>vskipafter)
  975.           continue;
  976.         memset (ptr, colour, 4);
  977.         ptr += ATARI_MODULO;
  978.       }
  979.       
  980.       screendata = screendata << 2;
  981.       t_scrn_ptr += 4;
  982.     }
  983.     }
  984. }
  985.  
  986. /*
  987.  * Function to Display Antic Mode b
  988.  */
  989.  
  990. void antic_b ()
  991. {
  992.   UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
  993.   int nbytes = (xmax - xmin) >> 4; /* Divide by 16 */
  994.   int i;
  995.  
  996.   for (i=0;i<nbytes;i++)
  997.     {
  998.       int screendata = APeek(screenaddr);
  999.       int j;
  1000.       screenaddr++;
  1001.  
  1002.       for (j=0;j<8;j++) {
  1003.     int colour;
  1004.     UBYTE *ptr = t_scrn_ptr;
  1005.     int k;
  1006.  
  1007.     colour = lookup_9[screendata & 0x80];
  1008.  
  1009.     for (k=0;k<2;k++) {
  1010.       if (k<vskipbefore || k>vskipafter)
  1011.         continue;
  1012.       *ptr++ = colour;
  1013.       *ptr++ = colour;
  1014.       ptr += (ATARI_MODULO-2);
  1015.     }
  1016.     
  1017.     screendata = screendata << 1;
  1018.     t_scrn_ptr += 2;
  1019.       }
  1020.     }
  1021. }
  1022.  
  1023.  
  1024.  
  1025.  
  1026. /*
  1027.  * Function to Display Antic Mode c
  1028.  */
  1029.  
  1030. void antic_c ()
  1031. {
  1032.   UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
  1033.   int nbytes = (xmax - xmin) >> 4;
  1034.   int i;
  1035.   
  1036.   for (i=0;i<nbytes;i++)
  1037.     {
  1038.       UWORD *ptr=t_scrn_ptr1;
  1039.       int j;
  1040.       int screendata=APeek(screenaddr);
  1041.  
  1042.       screenaddr++;
  1043.  
  1044.       for (j=0;j<2;j++) {
  1045.     
  1046.     if (j<vskipbefore || j>vskipafter)
  1047.       continue;
  1048.  
  1049.     if (screendata) {    
  1050.       *ptr++ = lookup_9[screendata & 0x80];
  1051.       *ptr++ = lookup_9[screendata & 0x40];
  1052.       *ptr++ = lookup_9[screendata & 0x20];
  1053.       *ptr++ = lookup_9[screendata & 0x10];      
  1054.       *ptr++ = lookup_9[screendata & 0x08];
  1055.       *ptr++ = lookup_9[screendata & 0x04];
  1056.       *ptr++ = lookup_9[screendata & 0x02];
  1057.       *ptr++ = lookup_9[screendata & 0x01];
  1058.     } else {
  1059.       *ptr++ = PF2_COLBK;
  1060.       *ptr++ = PF2_COLBK;
  1061.       *ptr++ = PF2_COLBK;
  1062.       *ptr++ = PF2_COLBK;      
  1063.       *ptr++ = PF2_COLBK;
  1064.       *ptr++ = PF2_COLBK;
  1065.       *ptr++ = PF2_COLBK;
  1066.       *ptr++ = PF2_COLBK;
  1067.     }
  1068.     ptr += ((ATARI_MODULO-8)>>1);
  1069.       }
  1070.       t_scrn_ptr1 += 8;
  1071.     }
  1072. }
  1073.  
  1074. /*
  1075.  * Function to Display Antic Mode d
  1076.  */
  1077.  
  1078. void antic_d ()
  1079. {
  1080.   UWORD *t_scrn_ptr1 = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
  1081.   int nbytes = (xmax - xmin) >> 3;
  1082.   int i;
  1083.  
  1084.   for (i=0;i<nbytes;i++)
  1085.     {
  1086.       UWORD *ptr=t_scrn_ptr1;
  1087.       int j;
  1088.       int screendata=APeek(screenaddr);
  1089.  
  1090.       screenaddr++;
  1091.  
  1092.       for (j=0;j<2;j++) {
  1093.     
  1094.     if (j<vskipbefore || j>vskipafter)
  1095.       continue;
  1096.  
  1097.     if (screendata) {    
  1098.       *ptr++ = lookup_4[screendata & 0xc0];
  1099.       *ptr++ = lookup_4[screendata & 0x30];
  1100.       *ptr++ = lookup_4[screendata & 0x0c];
  1101.       *ptr++ = lookup_4[screendata & 0x03];
  1102.     } else {
  1103.       *ptr++ = PF2_COLBK;
  1104.       *ptr++ = PF2_COLBK;
  1105.       *ptr++ = PF2_COLBK;
  1106.       *ptr++ = PF2_COLBK;
  1107.     }
  1108.     ptr += ((ATARI_MODULO-8)>>1);
  1109.       }
  1110.       t_scrn_ptr1 += 4;
  1111.     }
  1112. }
  1113.  
  1114. /*
  1115.  * Function to display Antic Mode e
  1116.  */
  1117.  
  1118. void antic_e ()
  1119. {
  1120.   UWORD *t_scrn_ptr = (UWORD*)&scrn_ptr[FILLIN_OFFSET+xmin];
  1121.   int nbytes = (xmax - xmin) >> 3;
  1122.   int i;
  1123.   
  1124.   for (i=0;i<nbytes;i++)
  1125.     {
  1126.       int screendata = APeek(screenaddr);
  1127.       screenaddr++;
  1128.  
  1129.       if (screendata)
  1130.     {
  1131.       *t_scrn_ptr++ = lookup_4[screendata & 0xc0];
  1132.       *t_scrn_ptr++ = lookup_4[screendata & 0x30];
  1133.       *t_scrn_ptr++ = lookup_4[screendata & 0x0c];
  1134.       *t_scrn_ptr++ = lookup_4[screendata & 0x03];
  1135.     }
  1136.       else
  1137.     {
  1138. #ifdef UNALIGNED_LONG_OK
  1139.       ULONG *l_ptr  = (ULONG*)t_scrn_ptr;
  1140.  
  1141.       *l_ptr++ = PF4_COLBK;
  1142.       *l_ptr++ = PF4_COLBK;
  1143.  
  1144.       t_scrn_ptr = (UWORD*)l_ptr;
  1145. #else
  1146.       *t_scrn_ptr++ = PF2_COLBK;
  1147.       *t_scrn_ptr++ = PF2_COLBK;
  1148.       *t_scrn_ptr++ = PF2_COLBK;
  1149.       *t_scrn_ptr++ = PF2_COLBK;
  1150. #endif
  1151.     }
  1152.     }
  1153. }
  1154.  
  1155. /*
  1156.  * Function to display Antic Mode f
  1157.  */
  1158.  
  1159. void antic_f ()
  1160. {
  1161.   UBYTE *t_scrn_ptr = &scrn_ptr[FILLIN_OFFSET+xmin];
  1162.   int nbytes = (xmax - xmin) >> 3;
  1163.   int i;
  1164.  
  1165.   for (i=0;i<nbytes;i++)
  1166.     {
  1167.       UBYTE screendata = APeek(screenaddr);
  1168.       screenaddr++;
  1169.  
  1170.       if (screendata)
  1171.     {
  1172.       *t_scrn_ptr++ = lookup_f[screendata & 0x80];
  1173.       *t_scrn_ptr++ = lookup_f[screendata & 0x40];
  1174.       *t_scrn_ptr++ = lookup_f[screendata & 0x20];
  1175.       *t_scrn_ptr++ = lookup_f[screendata & 0x10];
  1176.       *t_scrn_ptr++ = lookup_f[screendata & 0x08];
  1177.       *t_scrn_ptr++ = lookup_f[screendata & 0x04];
  1178.       *t_scrn_ptr++ = lookup_f[screendata & 0x02];
  1179.       *t_scrn_ptr++ = lookup_f[screendata & 0x01];
  1180.     }
  1181.       else
  1182.     {
  1183.       *t_scrn_ptr++ = PF_COLPF2;
  1184.       *t_scrn_ptr++ = PF_COLPF2;
  1185.       *t_scrn_ptr++ = PF_COLPF2;
  1186.       *t_scrn_ptr++ = PF_COLPF2;
  1187.       *t_scrn_ptr++ = PF_COLPF2;
  1188.       *t_scrn_ptr++ = PF_COLPF2;
  1189.       *t_scrn_ptr++ = PF_COLPF2;
  1190.       *t_scrn_ptr++ = PF_COLPF2;
  1191.     }
  1192.     }
  1193. }
  1194.  
  1195. /*
  1196.     *****************************************************************
  1197.     *                                *
  1198.     *    Section            :    Display List        *
  1199.     *    Original Author        :    David Firth        *
  1200.     *    Date Written        :    28th May 1995        *
  1201.     *    Version            :    1.0            *
  1202.     *                                *
  1203.     *   Description                            *
  1204.     *   -----------                            *
  1205.     *                                *
  1206.     *   Section that handles Antic Display List. Not required for    *
  1207.     *   BASIC version.                        *
  1208.     *                                                               *
  1209.     *****************************************************************
  1210. */
  1211.  
  1212. void pmg_dma (void)
  1213. {
  1214. int yhalf = ypos >> 1;
  1215. /* single line shift not yet implemented.... */
  1216.  
  1217.   if (DMACTL & 0x08)
  1218.     {
  1219.       if (DMACTL & 0x10)
  1220.     {
  1221.       GRAFP0 = memory[p0addr_s + ypos];
  1222.       GRAFP1 = memory[p1addr_s + ypos];
  1223.       GRAFP2 = memory[p2addr_s + ypos];
  1224.       GRAFP3 = memory[p3addr_s + ypos];
  1225.     }
  1226.       else
  1227.     {
  1228.       GRAFP0 = memory[p0addr_d + yhalf - delayp0];
  1229.       GRAFP1 = memory[p1addr_d + yhalf - delayp1];
  1230.       GRAFP2 = memory[p2addr_d + yhalf - delayp2];
  1231.       GRAFP3 = memory[p3addr_d + yhalf - delayp3];
  1232.     }
  1233.     }
  1234.  
  1235.   if (DMACTL & 0x0C)   /* Player DMA enables missile DMA as well */
  1236.     {
  1237.       if (DMACTL & 0x10)
  1238.     GRAFM = memory[maddr_s + ypos];
  1239.       else {
  1240.     int mis0,mis1,mis2,mis3;
  1241.     
  1242.     mis0 =  memory[maddr_d + yhalf - delaym0];
  1243.     mis1 =  memory[maddr_d + yhalf - delaym1];
  1244.     mis2 =  memory[maddr_d + yhalf - delaym2];
  1245.     mis3 =  memory[maddr_d + yhalf - delaym3];
  1246.  
  1247.     GRAFM = (mis0 & 0x03) | (mis1 & 0x0c) | (mis2 & 0x30) | (mis3 & 0xc0);
  1248.       }
  1249.     }
  1250. }
  1251.  
  1252. static void Clear_Border(int hscrol)
  1253. {
  1254. int scrol=HSCROL+HSCROL;
  1255. int shift=FILLIN_OFFSET;
  1256. int left=FILLIN_OFFSET+dmactl_xmin_noscroll;
  1257.   
  1258.   if (hscrol) {
  1259.     shift -= scrol;
  1260.     if ((DMACTL & 0x03)!=0x03)
  1261.       left -= scrol;
  1262.   }
  1263.  
  1264.   memset(scrn_ptr,PF_COLBK,left);
  1265.   memset(scrn_ptr+dmactl_xmax_noscroll+shift,PF_COLBK,
  1266.        ATARI_MODULO-dmactl_xmax_noscroll-shift);
  1267. }
  1268.  
  1269. static void ANTIC_Scanline(int dmacycles,int nmi,int hscrol)
  1270. {
  1271. int before;
  1272. int after;
  1273. int add;
  1274.  
  1275.   before=cc_middle-before_dma-dmacycles;
  1276.   after=114-cc_middle-after_wsync;
  1277.   if (before<0) {
  1278.     after += before;
  1279.     before = 0;
  1280.   }
  1281.   add = carry;
  1282.   Clear_Border(hscrol);
  1283.   if (!wsync_halt) {
  1284.     if (before_dma>0)
  1285.       add = GO(before_dma+add);
  1286.     if (nmi) {
  1287.       before += add;
  1288.       before -= dli_delay;
  1289.       if (before>0) {
  1290.     NMI();
  1291.     nmi = FALSE;
  1292.     add = GO(before);
  1293.       }
  1294.     } else {
  1295.       before += add;
  1296.       if (before>0)
  1297.     add = GO(before);
  1298.     }
  1299.   }
  1300.   pmg_dma ();
  1301.   Atari_ScanLine (hscrol); 
  1302.   if (!wsync_halt) {
  1303.     if (nmi) {
  1304.       after += add;
  1305.       after -= dli_delay;
  1306.       if (after>0) {
  1307.     NMI();
  1308.     nmi = FALSE;
  1309.     add = GO(after);
  1310.       }
  1311.     } else {
  1312.       after += add;
  1313.       if (after>0)
  1314.     add = GO(after);
  1315.     }
  1316.   }
  1317.   wsync_halt=0;
  1318.   if (nmi) {
  1319.     NMI();
  1320.     add = GO(after_wsync-dli_delay+add);
  1321.   } else add = GO(after_wsync+add);
  1322.   carry = add;
  1323.  
  1324.   scrn_ptr += ATARI_MODULO;
  1325.   ypos++;
  1326.  
  1327. }
  1328.  
  1329. void ANTIC_RunDisplayList (void)
  1330. {
  1331.   int JVB=FALSE;
  1332.   int vscrol_flag=0;
  1333.   int nlines=0;
  1334.   int i;
  1335.   int IR;
  1336.   int acnt;
  1337.   int acntn;
  1338.   int dmawidth;
  1339.   int hscrol;
  1340.  
  1341.   wsync_halt = 0;
  1342.  
  1343.   /*
  1344.    * VCOUNT must equal zero for some games but the first line starts
  1345.    * when VCOUNT=4. This portion processes when VCOUNT=0, 1, 2 and 3
  1346.    */
  1347.  
  1348.   scrn_ptr = (UBYTE*)atari_screen;
  1349.  
  1350.   DLIST=DLISTINIT;
  1351.   for (ypos = 0; ypos <8 ;ypos++) {
  1352.     carry=GO (carry+105);    /* 114 minus 9 memory cycles */
  1353.   }
  1354.   
  1355.   NMIST = 0x00;
  1356.  
  1357.   for (ypos = 8, JVB=FALSE ; ypos < (ATARI_HEIGHT + 8);) {
  1358.  
  1359.     if ((DMACTL & 0x10) || (ypos & 0x01)==0)
  1360.       acntn=pm_dma;
  1361.     else 
  1362.       acntn=0;
  1363.     acnt = 0;
  1364.       /* Counter for DMA type needed by ANTIC. One cycle per byte 
  1365.      acnt is the counter for the extra cycles of the first scanline 
  1366.      of the modeline acntn for all following lines */    
  1367.  
  1368.     if (JVB || (DMACTL & 0x20)==0) {
  1369.       antic_blank(1);
  1370.       ANTIC_Scanline(9,FALSE,FALSE);
  1371.     } else {
  1372.       IR = APeek(DLIST);
  1373.       DLIST++;
  1374.       acnt++;
  1375.  
  1376.       vskipbefore = 0;
  1377.       vskipafter = 127;
  1378.       hscrol = FALSE;
  1379.       xmin = dmactl_xmin_noscroll;
  1380.       xmax = dmactl_xmax_noscroll;  
  1381.       dmawidth = DMAwidth;
  1382.  
  1383.       switch (IR & 0x0f)
  1384.     {
  1385.     case 0x00 :
  1386.       nlines = ((IR >> 4)  & 0x07) + 1;
  1387.       antic_blank (nlines);
  1388.       break;
  1389.     case 0x01 :
  1390.       if (IR & 0x40)
  1391.         JVB = TRUE;
  1392.       DLIST = DAPeek(DLIST);
  1393.       acnt += 2;
  1394.       nlines = 1;
  1395.       antic_blank (1);    /* Jump aparently uses 1 scan line */
  1396.       break;
  1397.     default :
  1398.       if (IR & 0x40) {
  1399.           screenaddr = DAPeek(DLIST);
  1400.           DLIST += 2;
  1401.           acnt  += 2;
  1402.         }
  1403.       
  1404.       if (IR & 0x20) {
  1405.         if (!vscrol_flag) {
  1406.           vskipbefore = (int)VSCROL;
  1407.           vscrol_flag = TRUE;
  1408.         }
  1409.       }
  1410.       else if (vscrol_flag) {
  1411.           vskipafter = VSCROL;
  1412.           vscrol_flag = FALSE;
  1413.         }
  1414.  
  1415.       if (IR & 0x10) {
  1416.           xmin = dmactl_xmin_scroll;
  1417.           xmax = dmactl_xmax_scroll;
  1418.           hscrol = TRUE;
  1419.           if (dmawidth<6) {
  1420.         dmawidth++;
  1421.         acntn--;   /* one memory refresh cycle is dropped */
  1422.           }
  1423.         }
  1424.       
  1425.       switch (IR & 0x0f) {
  1426.         case 0x02 :
  1427.           nlines = 8;
  1428.           acnt  += dmawidth*8+memory_basis-9;
  1429.           acntn += dmawidth*8+9;
  1430.           antic_2 ();
  1431.           break;
  1432.         case 0x03 :
  1433.           nlines = 10;
  1434.           acnt  += dmawidth*8+memory_basis-9;
  1435.           acntn += dmawidth*8+9;
  1436.           antic_3 ();
  1437.           break;
  1438.         case 0x04 :
  1439.           nlines = 8;
  1440.           acnt  += dmawidth*8+memory_basis-9;
  1441.           acntn += dmawidth*8+9;
  1442.           antic_4 ();
  1443.           break;
  1444.         case 0x05 :
  1445.           nlines = 16;
  1446.           acnt  += dmawidth*8+memory_basis-9;
  1447.           acntn += dmawidth*8+9;
  1448.           antic_5 ();
  1449.           break;
  1450.         case 0x06 :
  1451.           nlines = 8;
  1452.           acnt  += dmawidth*4;
  1453.           acntn += dmawidth*4+9;
  1454.           antic_6 ();
  1455.           break;
  1456.         case 0x07 :
  1457.           nlines = 16;
  1458.           acnt  += dmawidth*4;
  1459.           acntn += dmawidth*4+9;
  1460.           antic_7 ();
  1461.           break;
  1462.         case 0x08 :
  1463.           nlines = 8;
  1464.           acnt  += dmawidth*2+9;
  1465.           antic_8 ();
  1466.           break;
  1467.         case 0x09 :
  1468.           nlines = 4;
  1469.           acnt  += dmawidth*2+9;
  1470.           antic_9 ();
  1471.           break;
  1472.         case 0x0a :
  1473.           nlines = 4;
  1474.           acnt  += dmawidth*4+9;
  1475.           antic_a ();
  1476.           break;
  1477.         case 0x0b :
  1478.           nlines = 2;
  1479.           acnt  += dmawidth*4+9;
  1480.           antic_b ();
  1481.           break;
  1482.         case 0x0c :
  1483.           nlines = 1;
  1484.           acnt  += dmawidth*4+9;
  1485.           antic_c ();
  1486.           break;
  1487.         case 0x0d :
  1488.           nlines = 2;
  1489.           acnt  += dmawidth*8+9;
  1490.           antic_d ();
  1491.           break;
  1492.         case 0x0e :
  1493.           nlines = 1;
  1494.           acnt  += dmawidth*8+9;
  1495.           antic_e ();
  1496.           break;
  1497.         case 0x0f :
  1498.           nlines = 1;
  1499.           acnt  += dmawidth*8+9;
  1500.           antic_f ();
  1501.           break;
  1502.         default :
  1503.           printf("IR %x caused problems.\n",IR);
  1504.           nlines = 0;
  1505.           break;
  1506.         }
  1507.       break;
  1508.     }
  1509.       
  1510.       if (nlines > 0) {
  1511.     int dma;
  1512.     int nmi=FALSE;
  1513.  
  1514.     nlines--;
  1515.     dma=acnt+acntn;
  1516.     if (vskipafter<nlines)
  1517.       nlines=vskipafter;
  1518.     for (i=vskipbefore;i<nlines;i++) {      
  1519.       ANTIC_Scanline(dma,FALSE,hscrol);
  1520.       dma=acntn;
  1521.     }
  1522.  
  1523.     if (IR & 0x80) {
  1524.       if (NMIEN & 0x80) {
  1525.         NMIST = 0x80;
  1526.         nmi = TRUE;
  1527.       }
  1528.     }
  1529.     
  1530.     ANTIC_Scanline(dma,nmi,hscrol);
  1531.       }
  1532.     }
  1533.   }
  1534.  
  1535.   for(ypos=248; ypos<vsync_pos;ypos++)
  1536.     carry = GO(carry+105);
  1537.   
  1538.   NMIST = 0x40; /* Set VBLANK */
  1539.   if (NMIEN & 0x40) {
  1540.     carry=GO (carry+7); 
  1541.     /* Needed for programs that monitor NMIST (Spy's Demise, GORF) */
  1542.     NMI ();
  1543.     carry -= dli_delay+7;   /* Needed by 6502 to react */
  1544.   }
  1545.   
  1546.   if (tv_mode == PAL)
  1547.     for (ypos=vsync_pos;ypos<312;ypos++)
  1548.       carry=GO (carry+105);
  1549.   else
  1550.     for (ypos=vsync_pos;ypos<262;ypos++)
  1551.       carry=GO (carry+105);
  1552. }
  1553.  
  1554.