Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

VIC.cpp

Go to the documentation of this file.
00001 /*
00002  *  VIC.cpp - 6569R5 emulation (line based)
00003  *
00004  *  Frodo (C) 1994-1997 Christian Bauer
00005  *
00006 
00007  *
00008  * Notes:
00009  * ------
00010  *
00011  *  - The EmulateLine() function is called for every emulated
00012  *    raster line. It computes one pixel row of the graphics
00013  *    according to the current VIC register settings and returns
00014  *    the number of cycles available for the CPU in that line.
00015  *  - The graphics are output into an 8 bit chunky bitmap
00016  *  - The sprite-graphics priority handling and collision
00017  *    detection is done in a bit-oriented way with masks.
00018  *    The foreground/background pixel mask for the graphics
00019  *    is stored in the fore_mask_buf[] array. Multicolor
00020  *    sprites are converted from their original chunky format
00021  *    to a bitplane representation (two bit masks) for easier
00022  *    handling of priorities and collisions.
00023  *  - The sprite-sprite priority handling and collision
00024  *    detection is done in with the byte array spr_coll_buf[],
00025  *    that is used to keep track of which sprites are already
00026  *    visible at certain X positions.
00027  *
00028  * Incompatibilities:
00029  * ------------------
00030  *
00031  *  - Raster effects that are achieved by modifying VIC registers
00032  *    in the middle of a raster line cannot be emulated
00033  *  - Sprite collisions are only detected within the visible
00034  *    screen area (excluding borders)
00035  *  - Sprites are only drawn if they completely fit within the
00036  *    left/right limits of the chunky bitmap
00037  *  - The Char ROM is not visible in the bitmap displays at
00038  *    addresses $0000 and $8000
00039  *  - The IRQ is cleared on every write access to the flag
00040  *    register. This is a hack for the RMW instructions of the
00041  *    6510 that first write back the original value.
00042  */
00043 
00044 #include "sysdeps.h"
00045 
00046 #ifdef __SYMBIAN32__
00047 #include <e32std.h>
00048 #endif
00049 
00050 #include "VIC.h"
00051 #include "C64.h"
00052 #include "CPUC64.h"
00053 #include "Display.h"
00054 #include "Prefs.h"
00055 
00056 #ifdef _DEBUG
00057 #define ALIGN_CHECK(_p)         if( ((int)_p) & 0x03 ) User::Panic(_L("unalign VIC"), __LINE__);
00058 #define ALIGN_CHECK2(_p)        if( ((int)_p) & 0x01 ) User::Panic(_L("unalign VIC"), __LINE__);
00059 #else
00060 #define ALIGN_CHECK(_p)
00061 #define ALIGN_CHECK2(_p)
00062 #endif
00063 
00064 
00065 // Test alignment on run-time for processors that can't access unaligned:
00066 #ifdef __riscos__
00067 #define ALIGNMENT_CHECK
00068 #endif
00069 
00070 // First and last displayed line
00071 const int FIRST_DISP_LINE = 0x10;
00072 const int LAST_DISP_LINE = 0x11f;
00073 
00074 // First and last possible line for Bad Lines
00075 const int FIRST_DMA_LINE = 0x30;
00076 const int LAST_DMA_LINE = 0xf7;
00077 
00078 // Display window coordinates
00079 const int ROW25_YSTART = 0x33;
00080 const int ROW25_YSTOP = 0xfb;
00081 const int ROW24_YSTART = 0x37;
00082 const int ROW24_YSTOP = 0xf7;
00083 
00084 #if defined(SMALL_DISPLAY)
00085 /* This does not work yet, the sprite code doesn't know about it. */
00086 const int COL40_XSTART = 0x14;
00087 const int COL40_XSTOP = 0x154;
00088 const int COL38_XSTART = 0x1B;
00089 const int COL38_XSTOP = 0x14B;
00090 #else
00091 
00092 #if COLOR_DEPTH == 4
00093 const int COL40_XSTART = 0x20/2;
00094 const int COL40_XSTOP = 0x160/2;
00095 const int COL38_XSTART = 0x14;  //TODO: fix this
00096 const int COL38_XSTOP = 0xAC;   //TODO: fix this
00097 #elif COLOR_DEPTH == 8
00098 const int COL40_XSTART = 0x20;  //32
00099 const int COL40_XSTOP = 0x160;  //352
00100 const int COL38_XSTART = 0x27;
00101 const int COL38_XSTOP = 0x157;
00102 #elif
00103 error
00104 #endif
00105 
00106 
00107 #endif
00108 
00109 
00110 // Tables for sprite X expansion
00111 const uint16 ExpTable[256] = {  //AEH 991130
00112         0x0000, 0x0003, 0x000C, 0x000F, 0x0030, 0x0033, 0x003C, 0x003F,
00113         0x00C0, 0x00C3, 0x00CC, 0x00CF, 0x00F0, 0x00F3, 0x00FC, 0x00FF,
00114         0x0300, 0x0303, 0x030C, 0x030F, 0x0330, 0x0333, 0x033C, 0x033F,
00115         0x03C0, 0x03C3, 0x03CC, 0x03CF, 0x03F0, 0x03F3, 0x03FC, 0x03FF,
00116         0x0C00, 0x0C03, 0x0C0C, 0x0C0F, 0x0C30, 0x0C33, 0x0C3C, 0x0C3F,
00117         0x0CC0, 0x0CC3, 0x0CCC, 0x0CCF, 0x0CF0, 0x0CF3, 0x0CFC, 0x0CFF,
00118         0x0F00, 0x0F03, 0x0F0C, 0x0F0F, 0x0F30, 0x0F33, 0x0F3C, 0x0F3F,
00119         0x0FC0, 0x0FC3, 0x0FCC, 0x0FCF, 0x0FF0, 0x0FF3, 0x0FFC, 0x0FFF,
00120         0x3000, 0x3003, 0x300C, 0x300F, 0x3030, 0x3033, 0x303C, 0x303F,
00121         0x30C0, 0x30C3, 0x30CC, 0x30CF, 0x30F0, 0x30F3, 0x30FC, 0x30FF,
00122         0x3300, 0x3303, 0x330C, 0x330F, 0x3330, 0x3333, 0x333C, 0x333F,
00123         0x33C0, 0x33C3, 0x33CC, 0x33CF, 0x33F0, 0x33F3, 0x33FC, 0x33FF,
00124         0x3C00, 0x3C03, 0x3C0C, 0x3C0F, 0x3C30, 0x3C33, 0x3C3C, 0x3C3F,
00125         0x3CC0, 0x3CC3, 0x3CCC, 0x3CCF, 0x3CF0, 0x3CF3, 0x3CFC, 0x3CFF,
00126         0x3F00, 0x3F03, 0x3F0C, 0x3F0F, 0x3F30, 0x3F33, 0x3F3C, 0x3F3F,
00127         0x3FC0, 0x3FC3, 0x3FCC, 0x3FCF, 0x3FF0, 0x3FF3, 0x3FFC, 0x3FFF,
00128         0xC000, 0xC003, 0xC00C, 0xC00F, 0xC030, 0xC033, 0xC03C, 0xC03F,
00129         0xC0C0, 0xC0C3, 0xC0CC, 0xC0CF, 0xC0F0, 0xC0F3, 0xC0FC, 0xC0FF,
00130         0xC300, 0xC303, 0xC30C, 0xC30F, 0xC330, 0xC333, 0xC33C, 0xC33F,
00131         0xC3C0, 0xC3C3, 0xC3CC, 0xC3CF, 0xC3F0, 0xC3F3, 0xC3FC, 0xC3FF,
00132         0xCC00, 0xCC03, 0xCC0C, 0xCC0F, 0xCC30, 0xCC33, 0xCC3C, 0xCC3F,
00133         0xCCC0, 0xCCC3, 0xCCCC, 0xCCCF, 0xCCF0, 0xCCF3, 0xCCFC, 0xCCFF,
00134         0xCF00, 0xCF03, 0xCF0C, 0xCF0F, 0xCF30, 0xCF33, 0xCF3C, 0xCF3F,
00135         0xCFC0, 0xCFC3, 0xCFCC, 0xCFCF, 0xCFF0, 0xCFF3, 0xCFFC, 0xCFFF,
00136         0xF000, 0xF003, 0xF00C, 0xF00F, 0xF030, 0xF033, 0xF03C, 0xF03F,
00137         0xF0C0, 0xF0C3, 0xF0CC, 0xF0CF, 0xF0F0, 0xF0F3, 0xF0FC, 0xF0FF,
00138         0xF300, 0xF303, 0xF30C, 0xF30F, 0xF330, 0xF333, 0xF33C, 0xF33F,
00139         0xF3C0, 0xF3C3, 0xF3CC, 0xF3CF, 0xF3F0, 0xF3F3, 0xF3FC, 0xF3FF,
00140         0xFC00, 0xFC03, 0xFC0C, 0xFC0F, 0xFC30, 0xFC33, 0xFC3C, 0xFC3F,
00141         0xFCC0, 0xFCC3, 0xFCCC, 0xFCCF, 0xFCF0, 0xFCF3, 0xFCFC, 0xFCFF,
00142         0xFF00, 0xFF03, 0xFF0C, 0xFF0F, 0xFF30, 0xFF33, 0xFF3C, 0xFF3F,
00143         0xFFC0, 0xFFC3, 0xFFCC, 0xFFCF, 0xFFF0, 0xFFF3, 0xFFFC, 0xFFFF
00144 };
00145 
00146 const uint16 MultiExpTable[256] = {     //AEH 991130
00147         0x0000, 0x0005, 0x000A, 0x000F, 0x0050, 0x0055, 0x005A, 0x005F,
00148         0x00A0, 0x00A5, 0x00AA, 0x00AF, 0x00F0, 0x00F5, 0x00FA, 0x00FF,
00149         0x0500, 0x0505, 0x050A, 0x050F, 0x0550, 0x0555, 0x055A, 0x055F,
00150         0x05A0, 0x05A5, 0x05AA, 0x05AF, 0x05F0, 0x05F5, 0x05FA, 0x05FF,
00151         0x0A00, 0x0A05, 0x0A0A, 0x0A0F, 0x0A50, 0x0A55, 0x0A5A, 0x0A5F,
00152         0x0AA0, 0x0AA5, 0x0AAA, 0x0AAF, 0x0AF0, 0x0AF5, 0x0AFA, 0x0AFF,
00153         0x0F00, 0x0F05, 0x0F0A, 0x0F0F, 0x0F50, 0x0F55, 0x0F5A, 0x0F5F,
00154         0x0FA0, 0x0FA5, 0x0FAA, 0x0FAF, 0x0FF0, 0x0FF5, 0x0FFA, 0x0FFF,
00155         0x5000, 0x5005, 0x500A, 0x500F, 0x5050, 0x5055, 0x505A, 0x505F,
00156         0x50A0, 0x50A5, 0x50AA, 0x50AF, 0x50F0, 0x50F5, 0x50FA, 0x50FF,
00157         0x5500, 0x5505, 0x550A, 0x550F, 0x5550, 0x5555, 0x555A, 0x555F,
00158         0x55A0, 0x55A5, 0x55AA, 0x55AF, 0x55F0, 0x55F5, 0x55FA, 0x55FF,
00159         0x5A00, 0x5A05, 0x5A0A, 0x5A0F, 0x5A50, 0x5A55, 0x5A5A, 0x5A5F,
00160         0x5AA0, 0x5AA5, 0x5AAA, 0x5AAF, 0x5AF0, 0x5AF5, 0x5AFA, 0x5AFF,
00161         0x5F00, 0x5F05, 0x5F0A, 0x5F0F, 0x5F50, 0x5F55, 0x5F5A, 0x5F5F,
00162         0x5FA0, 0x5FA5, 0x5FAA, 0x5FAF, 0x5FF0, 0x5FF5, 0x5FFA, 0x5FFF,
00163         0xA000, 0xA005, 0xA00A, 0xA00F, 0xA050, 0xA055, 0xA05A, 0xA05F,
00164         0xA0A0, 0xA0A5, 0xA0AA, 0xA0AF, 0xA0F0, 0xA0F5, 0xA0FA, 0xA0FF,
00165         0xA500, 0xA505, 0xA50A, 0xA50F, 0xA550, 0xA555, 0xA55A, 0xA55F,
00166         0xA5A0, 0xA5A5, 0xA5AA, 0xA5AF, 0xA5F0, 0xA5F5, 0xA5FA, 0xA5FF,
00167         0xAA00, 0xAA05, 0xAA0A, 0xAA0F, 0xAA50, 0xAA55, 0xAA5A, 0xAA5F,
00168         0xAAA0, 0xAAA5, 0xAAAA, 0xAAAF, 0xAAF0, 0xAAF5, 0xAAFA, 0xAAFF,
00169         0xAF00, 0xAF05, 0xAF0A, 0xAF0F, 0xAF50, 0xAF55, 0xAF5A, 0xAF5F,
00170         0xAFA0, 0xAFA5, 0xAFAA, 0xAFAF, 0xAFF0, 0xAFF5, 0xAFFA, 0xAFFF,
00171         0xF000, 0xF005, 0xF00A, 0xF00F, 0xF050, 0xF055, 0xF05A, 0xF05F,
00172         0xF0A0, 0xF0A5, 0xF0AA, 0xF0AF, 0xF0F0, 0xF0F5, 0xF0FA, 0xF0FF,
00173         0xF500, 0xF505, 0xF50A, 0xF50F, 0xF550, 0xF555, 0xF55A, 0xF55F,
00174         0xF5A0, 0xF5A5, 0xF5AA, 0xF5AF, 0xF5F0, 0xF5F5, 0xF5FA, 0xF5FF,
00175         0xFA00, 0xFA05, 0xFA0A, 0xFA0F, 0xFA50, 0xFA55, 0xFA5A, 0xFA5F,
00176         0xFAA0, 0xFAA5, 0xFAAA, 0xFAAF, 0xFAF0, 0xFAF5, 0xFAFA, 0xFAFF,
00177         0xFF00, 0xFF05, 0xFF0A, 0xFF0F, 0xFF50, 0xFF55, 0xFF5A, 0xFF5F,
00178         0xFFA0, 0xFFA5, 0xFFAA, 0xFFAF, 0xFFF0, 0xFFF5, 0xFFFA, 0xFFFF
00179 };
00180 
00181 #ifdef GLOBAL_VARS
00182 
00183 #ifdef __POWERPC__
00184 static union {
00185         struct {
00186                 uint8 a,b,c,d,e,f,g,h;
00187         } a;
00188         double b;
00189 } TextColorTable[16][16][256];
00190 #else
00191 static union {
00192         struct {
00193                 uint8 a,b,c,d;
00194         } a;
00195         uint32 b;
00196 } TextColorTable[16][16][256][2];
00197 #endif
00198 
00199 
00200 static uint16 mc_color_lookup[4];
00201 //#ifndef CAN_ACCESS_UNALIGNED
00202 static uint8 text_chunky_buf[40*8];
00203 //#endif
00204 static uint16 mx[8];                                            // VIC registers
00205 static uint8 mx8;
00206 static uint8 my[8];
00207 static uint8 ctrl1, ctrl2;
00208 static uint8 lpx, lpy;
00209 static uint8 me, mxe, mye, mdp, mmc;
00210 static uint8 vbase;
00211 static uint8 irq_flag, irq_mask;
00212 static uint8 clx_spr, clx_bgr;
00213 static uint8 ec, b0c, b1c, b2c, b3c, mm0, mm1;
00214 static uint8 sc[8];
00215 
00216 static uint8 *ram, *char_rom, *color_ram; // Pointers to RAM and ROM
00217 static C64 *the_c64;                                    // Pointer to C64
00218 static C64Display *the_display;                 // Pointer to C64Display
00219 static MOS6510 *the_cpu;                                // Pointer to 6510
00220 
00221 static uint8 colors[256];                               // Indices of the 16 C64 colors (16 times mirrored to avoid "& 0x0f")
00222 
00223 static uint8 ec_color, b0c_color, b1c_color, b2c_color, b3c_color; // Indices for exterior/background colors
00224 static uint8 mm0_color, mm1_color;              // Indices for MOB multicolors
00225 static uint8 spr_color[8];                              // Indices for MOB colors
00226 
00227 static uint32 ec_color_long;                    // ec_color expanded to 32 bits
00228 
00229 static uint8 matrix_line[40];                   // Buffer for video line, read in Bad Lines
00230 static uint8 color_line[40];                    // Buffer for color line, read in Bad Lines
00231 
00232 #ifdef __POWERPC__
00233 static double chunky_tmp[DISPLAY_X/8];  // Temporary line buffer for GameKit speedup
00234 #endif
00235 static uint8 *chunky_line_start;                // Pointer to start of current line in bitmap buffer
00236 static int xmod;                                                // Number of bytes per row
00237 
00238 static uint8 *matrix_base;                              // Video matrix base
00239 static uint8 *char_base;                                // Character generator base
00240 static uint8 *bitmap_base;                              // Bitmap base
00241 
00242 static uint16 raster_y;                                 // Current raster line
00243 static uint16 irq_raster;                               // Interrupt raster line
00244 static uint16 dy_start;                                 // Comparison values for border logic
00245 static uint16 dy_stop;
00246 static uint16 rc;                                               // Row counter
00247 static uint16 vc;                                               // Video counter
00248 static uint16 vc_base;                                  // Video counter base
00249 static uint16 x_scroll;                                 // X scroll value
00250 static uint16 y_scroll;                                 // Y scroll value
00251 static uint16 cia_vabase;                               // CIA VA14/15 video base
00252 
00253 static int display_idx;                                 // Index of current display mode
00254 static int skip_counter;                                // Counter for frame-skipping
00255 
00256 static uint16 mc[8];                                    // Sprite data counters
00257 static uint8 sprite_on;                                 // 8 Flags: Sprite display/DMA active
00258 
00259 static uint8 spr_coll_buf[0x180];               // Buffer for sprite-sprite collisions and priorities
00260 static uint8 fore_mask_buf[0x180/8];    // Foreground mask for sprite-graphics collisions and priorities
00261 
00262 static bool display_state;                              // true: Display state, false: Idle state
00263 static bool border_on;                                  // Flag: Upper/lower border on
00264 static bool border_40_col;                              // Flag: 40 column border
00265 static bool frame_skipped;                              // Flag: Frame is being skipped
00266 static uint8 bad_lines_enabled;         // Flag: Bad Lines enabled for this frame
00267 static bool lp_triggered;                               // Flag: Lightpen was triggered in this frame
00268 #endif // GLOBAL_VARS
00269 
00270 
00271 /*
00272  *  Constructor: Initialize variables
00273  */
00274 
00275 //AEH 991130 - inserted '#ifdef GLOBAL_VARS' here
00276 
00277 #ifdef GLOBAL_VARS
00278 static void init_text_color_table(uint8 *colors)
00279 #else
00280 void MOS6569::init_text_color_table(uint8 *colors) // private
00281 #endif
00282 {
00283         for (int i = 0; i < 16; i++)
00284                 for (int j = 0; j < 16; j++)
00285                         for (int k = 0; k < 256; k++) {
00286 #ifdef __POWERPC__
00287                                 TextColorTable[i][j][k].a.a = colors[k & 128 ? i : j];
00288                                 TextColorTable[i][j][k].a.b = colors[k & 64 ? i : j];
00289                                 TextColorTable[i][j][k].a.c = colors[k & 32 ? i : j];
00290                                 TextColorTable[i][j][k].a.d = colors[k & 16 ? i : j];
00291                                 TextColorTable[i][j][k].a.e = colors[k & 8 ? i : j];
00292                                 TextColorTable[i][j][k].a.f = colors[k & 4 ? i : j];
00293                                 TextColorTable[i][j][k].a.g = colors[k & 2 ? i : j];
00294                                 TextColorTable[i][j][k].a.h = colors[k & 1 ? i : j];
00295 #else
00296 
00297 //AEH opt
00298 #if COLOR_DEPTH == 4    // modified here:
00299                 TextColorTable[i][j][k].a.a  = colors[k & 128 ? i : j] & 0x0f;
00300                 TextColorTable[i][j][k].a.a |= colors[k & 64  ? i : j] & 0xf0;
00301                 TextColorTable[i][j][k].a.b  = colors[k & 32  ? i : j] & 0x0f;
00302                 TextColorTable[i][j][k].a.b |= colors[k & 16  ? i : j] & 0xf0;
00303                 TextColorTable[i][j][k].a.c  = colors[k & 8   ? i : j] & 0x0f;
00304                 TextColorTable[i][j][k].a.c |= colors[k & 4   ? i : j] & 0xf0;
00305                 TextColorTable[i][j][k].a.d  = colors[k & 2   ? i : j] & 0x0f;
00306                 TextColorTable[i][j][k].a.d |= colors[k & 1   ? i : j] & 0xf0;
00307 #elif COLOR_DEPTH == 8
00308                                 TextColorTable[i][j][k][0].a.a = colors[k & 128 ? i : j];
00309                                 TextColorTable[i][j][k][0].a.b = colors[k & 64 ? i : j];
00310                                 TextColorTable[i][j][k][0].a.c = colors[k & 32 ? i : j];
00311                                 TextColorTable[i][j][k][0].a.d = colors[k & 16 ? i : j];
00312                                 TextColorTable[i][j][k][1].a.a = colors[k & 8 ? i : j];
00313                                 TextColorTable[i][j][k][1].a.b = colors[k & 4 ? i : j];
00314                                 TextColorTable[i][j][k][1].a.c = colors[k & 2 ? i : j];
00315                                 TextColorTable[i][j][k][1].a.d = colors[k & 1 ? i : j];
00316 #endif
00317 #endif
00318                         }
00319 }
00320 
00321 MOS6569::MOS6569(C64 *c64, C64Display *disp, MOS6510 *CPU, uint8 *RAM, uint8 *Char, uint8 *Color)
00322 #ifndef GLOBAL_VARS
00323         : ram(RAM), char_rom(Char), color_ram(Color), the_c64(c64), the_display(disp), the_cpu(CPU),
00324 #else
00325         :
00326 #endif
00327 ThePrefs(c64->ThePrefs)
00328 {
00329         __CHECK_NULL(c64);
00330         __CHECK_NULL(disp);
00331         __CHECK_NULL(CPU);
00332         __CHECK_NULL(RAM);
00333         __CHECK_NULL(Char);
00334         __CHECK_NULL(Color);
00335 
00336         int i;
00337 
00338         // Set pointers
00339 #ifdef GLOBAL_VARS
00340         the_c64 = c64;
00341         the_display = disp;
00342         the_cpu = CPU;
00343         ram = RAM;
00344         char_rom = Char;
00345         color_ram = Color;
00346 #endif
00347         matrix_base = RAM;
00348         char_base = RAM;
00349         bitmap_base = RAM;
00350 
00351         // Get bitmap info
00352         chunky_line_start = disp->BitmapBase();
00353 #ifdef __SYMBIAN32__
00354         chunky_base = disp->BitmapBase();
00355 #endif
00356         xmod = disp->BitmapXMod();
00357 
00358         // Initialize VIC registers
00359         mx8 = 0;
00360         ctrl1 = ctrl2 = 0;
00361         lpx = lpy = 0;
00362         me = mxe = mye = mdp = mmc = 0;
00363         vbase = irq_flag = irq_mask = 0;
00364         clx_spr = clx_bgr = 0;
00365         cia_vabase = 0;
00366 
00367 #ifdef BACKGND_UPDATE
00368         ec_changed = 2;
00369 #endif
00370 
00371         ec = b0c = b1c = b2c = b3c = mm0 = mm1 = 0;
00372         for (i=0; i<8; i++) mx[i] = my[i] = sc[i] = 0;
00373 
00374         // Initialize other variables
00375         raster_y = 0xffff;
00376         rc = 7;
00377         irq_raster = vc = vc_base = x_scroll = y_scroll = 0;
00378         dy_start = ROW24_YSTART;
00379         dy_stop = ROW24_YSTOP;
00380 
00381         display_idx = 0;
00382         display_state = false;
00383         border_on = false;
00384         lp_triggered = false;
00385 
00386         sprite_on = 0;
00387         for (i=0; i<8; i++)
00388                 mc[i] = 63;
00389 
00390         frame_skipped = false;
00391         skip_counter = 1;
00392 
00393         // Clear foreground mask
00394 //      memset(fore_mask_buf, 0, DISPLAY_X/8);
00395         memset(fore_mask_buf, 0, 0x180/8);
00396 
00397         // Preset colors to black
00398         disp->InitColors(colors);
00399         init_text_color_table(colors);
00400         ec_color = b0c_color = b1c_color = b2c_color = b3c_color = mm0_color = mm1_color = colors[0];
00401         ec_color_long = (ec_color << 24) | (ec_color << 16) | (ec_color << 8) | ec_color;
00402         for (i=0; i<8; i++) spr_color[i] = colors[0];
00403 
00404         CTOR(MOS6569);
00405 
00406 } // end, MOS6569::MOS6569
00407 
00408 /*
00409  *  Destructor
00410  */
00411 
00412 MOS6569::~MOS6569()
00413         {
00414         DTOR(MOS6569);
00415         }
00416 
00417 
00418 /*
00419  *  Reinitialize the colors table for when the palette has changed
00420  */
00421 
00422 void MOS6569::ReInitColors(void)
00423 {
00424         int i;
00425 
00426         // Build inverse color table.
00427         uint8 xlate_colors[256];
00428         memset(xlate_colors, 0, sizeof(xlate_colors));
00429         for (i = 0; i < 16; i++)
00430                 xlate_colors[colors[i]] = i;
00431 
00432         // Get the new colors.
00433         the_display->InitColors(colors);
00434         init_text_color_table(colors);
00435 
00436         // Build color translation table.
00437         for (i = 0; i < 256; i++)
00438                 xlate_colors[i] = colors[xlate_colors[i]];
00439 
00440         // Translate all the old colors variables.
00441         ec_color = colors[ec];
00442         ec_color_long = ec_color | (ec_color << 8) | (ec_color << 16) | (ec_color << 24);
00443         b0c_color = colors[b0c];
00444         b1c_color = colors[b1c];
00445         b2c_color = colors[b2c];
00446         b3c_color = colors[b3c];
00447         mm0_color = colors[mm0];
00448         mm1_color = colors[mm1];
00449         for (i = 0; i < 8; i++)
00450                 spr_color[i] = colors[sc[i]];
00451 
00452         make_mc_table();
00453 
00454         // Translate the chunky buffer.
00455         uint8 *scanline = the_display->BitmapBase();
00456         for (int y = 0; y < DISPLAY_Y; y++) {
00457                 for (int x = 0; x < DISPLAY_X; x++)
00458                         scanline[x] = xlate_colors[scanline[x]];
00459                 scanline += xmod;
00460         }
00461 }
00462 
00463 void MOS6569::make_mc_table(void)
00464 {
00465         mc_color_lookup[0] = b0c_color | (b0c_color << 8);
00466         mc_color_lookup[1] = b1c_color | (b1c_color << 8);
00467         mc_color_lookup[2] = b2c_color | (b2c_color << 8);
00468 }
00469 
00470 
00471 /*
00472  *  Convert video address to pointer
00473  */
00474 
00475 #ifdef GLOBAL_VARS
00476 static inline uint8 *get_physical(uint16 adr)
00477 #else
00478 inline uint8 *MOS6569::get_physical(uint16 adr)
00479 #endif
00480 {
00481         int va = adr | cia_vabase;
00482         if ((va & 0x7000) == 0x1000)
00483                 return char_rom + (va & 0x0fff);
00484         else
00485                 return ram + va;
00486 }
00487 
00488 
00489 /*
00490  *  Get VIC state
00491  */
00492 
00493 void MOS6569::GetState(MOS6569State *vd)
00494 {
00495         int i;
00496 
00497         vd->m0x = mx[0] & 0xff; vd->m0y = my[0];
00498         vd->m1x = mx[1] & 0xff; vd->m1y = my[1];
00499         vd->m2x = mx[2] & 0xff; vd->m2y = my[2];
00500         vd->m3x = mx[3] & 0xff; vd->m3y = my[3];
00501         vd->m4x = mx[4] & 0xff; vd->m4y = my[4];
00502         vd->m5x = mx[5] & 0xff; vd->m5y = my[5];
00503         vd->m6x = mx[6] & 0xff; vd->m6y = my[6];
00504         vd->m7x = mx[7] & 0xff; vd->m7y = my[7];
00505         vd->mx8 = mx8;
00506 
00507         vd->ctrl1 = (ctrl1 & 0x7f) | ((raster_y & 0x100) >> 1);
00508         vd->raster = raster_y & 0xff;
00509         vd->lpx = lpx; vd->lpy = lpy;
00510         vd->ctrl2 = ctrl2;
00511         vd->vbase = vbase;
00512         vd->irq_flag = irq_flag;
00513         vd->irq_mask = irq_mask;
00514 
00515         vd->me = me; vd->mxe = mxe; vd->mye = mye; vd->mdp = mdp; vd->mmc = mmc;
00516         vd->mm = clx_spr; vd->md = clx_bgr;
00517 
00518         vd->ec = ec;
00519         vd->b0c = b0c; vd->b1c = b1c; vd->b2c = b2c; vd->b3c = b3c;
00520         vd->mm0 = mm0; vd->mm1 = mm1;
00521         vd->m0c = sc[0]; vd->m1c = sc[1];
00522         vd->m2c = sc[2]; vd->m3c = sc[3];
00523         vd->m4c = sc[4]; vd->m5c = sc[5];
00524         vd->m6c = sc[6]; vd->m7c = sc[7];
00525 
00526         vd->pad0 = 0;
00527         vd->irq_raster = irq_raster;
00528         vd->vc = vc;
00529         vd->vc_base = vc_base;
00530 //      vd->rc = rc;
00531         vd->rc = (uint8)rc;     //AEH 991113
00532         vd->spr_dma = vd->spr_disp = sprite_on;
00533         for (i=0; i<8; i++)
00534 //              vd->mc[i] = vd->mc_base[i] = mc[i];
00535                 vd->mc[i] = vd->mc_base[i] = (uint8)mc[i];      //AEH 991113
00536         vd->display_state = display_state;
00537         vd->bad_line = raster_y >= FIRST_DMA_LINE && raster_y <= LAST_DMA_LINE && ((raster_y & 7) == y_scroll) && bad_lines_enabled;
00538 //      vd->bad_line_enable = bad_lines_enabled;
00539         vd->bad_line_enable = (bad_lines_enabled > 0);  //AEH 991113
00540         vd->lp_triggered = lp_triggered;
00541         vd->border_on = border_on;
00542 
00543         vd->bank_base = cia_vabase;
00544         vd->matrix_base = ((vbase & 0xf0) << 6) | cia_vabase;
00545         vd->char_base = ((vbase & 0x0e) << 10) | cia_vabase;
00546         vd->bitmap_base = ((vbase & 0x08) << 10) | cia_vabase;
00547         for (i=0; i<8; i++)
00548                 vd->sprite_base[i] = (matrix_base[0x3f8 + i] << 6) | cia_vabase;
00549 
00550         vd->cycle = 1;
00551         vd->raster_x = 0;
00552         vd->ml_index = 0;
00553         vd->ref_cnt = 0xff;
00554         vd->last_vic_byte = 0;
00555         vd->ud_border_on = border_on;
00556 }
00557 
00558 
00559 /*
00560  *  Set VIC state (only works if in VBlank)
00561  */
00562 
00563 void MOS6569::SetState(MOS6569State *vd)
00564 {
00565         int i, j;
00566 
00567         mx[0] = vd->m0x; my[0] = vd->m0y;
00568         mx[1] = vd->m1x; my[1] = vd->m1y;
00569         mx[2] = vd->m2x; my[2] = vd->m2y;
00570         mx[3] = vd->m3x; my[3] = vd->m3y;
00571         mx[4] = vd->m4x; my[4] = vd->m4y;
00572         mx[5] = vd->m5x; my[5] = vd->m5y;
00573         mx[6] = vd->m6x; my[6] = vd->m6y;
00574         mx[7] = vd->m7x; my[7] = vd->m7y;
00575         mx8 = vd->mx8;
00576         for (i=0, j=1; i<8; i++, j<<=1) {
00577                 if (mx8 & j)
00578                         mx[i] |= 0x100;
00579                 else
00580                         mx[i] &= 0xff;
00581         }
00582 
00583         ctrl1 = vd->ctrl1;
00584         ctrl2 = vd->ctrl2;
00585         x_scroll = ctrl2 & 7;
00586         y_scroll = ctrl1 & 7;
00587         if (ctrl1 & 8) {
00588                 dy_start = ROW25_YSTART;
00589                 dy_stop = ROW25_YSTOP;
00590         } else {
00591                 dy_start = ROW24_YSTART;
00592                 dy_stop = ROW24_YSTOP;
00593         }
00594 //      border_40_col = ctrl2 & 8;
00595         border_40_col = BOOL_BIT(ctrl2, 8);     //AEH 991113
00596         display_idx = ((ctrl1 & 0x60) | (ctrl2 & 0x10)) >> 4;
00597 
00598         raster_y = 0;
00599         lpx = vd->lpx; lpy = vd->lpy;
00600 
00601         vbase = vd->vbase;
00602         cia_vabase = vd->bank_base;
00603         matrix_base = get_physical((vbase & 0xf0) << 6);
00604         char_base = get_physical((vbase & 0x0e) << 10);
00605         bitmap_base = get_physical((vbase & 0x08) << 10);
00606 
00607         irq_flag = vd->irq_flag;
00608         irq_mask = vd->irq_mask;
00609 
00610         me = vd->me; mxe = vd->mxe; mye = vd->mye; mdp = vd->mdp; mmc = vd->mmc;
00611         clx_spr = vd->mm; clx_bgr = vd->md;
00612 
00613         ec = vd->ec;
00614         ec_color = colors[ec];
00615         ec_color_long = (ec_color << 24) | (ec_color << 16) | (ec_color << 8) | ec_color;
00616 
00617         b0c = vd->b0c; b1c = vd->b1c; b2c = vd->b2c; b3c = vd->b3c;
00618         b0c_color = colors[b0c];
00619         b1c_color = colors[b1c];
00620         b2c_color = colors[b2c];
00621         b3c_color = colors[b3c];
00622         make_mc_table();
00623 
00624         mm0 = vd->mm0; mm1 = vd->mm1;
00625         mm0_color = colors[mm0];
00626         mm1_color = colors[mm1];
00627 
00628         sc[0] = vd->m0c; sc[1] = vd->m1c;
00629         sc[2] = vd->m2c; sc[3] = vd->m3c;
00630         sc[4] = vd->m4c; sc[5] = vd->m5c;
00631         sc[6] = vd->m6c; sc[7] = vd->m7c;
00632         for (i=0; i<8; i++)
00633                 spr_color[i] = colors[sc[i]];
00634 
00635         irq_raster = vd->irq_raster;
00636         vc = vd->vc;
00637         vc_base = vd->vc_base;
00638         rc = vd->rc;
00639         sprite_on = vd->spr_dma;
00640         for (i=0; i<8; i++)
00641                 mc[i] = vd->mc[i];
00642         display_state = vd->display_state;
00643         bad_lines_enabled = vd->bad_line_enable;
00644         lp_triggered = vd->lp_triggered;
00645         border_on = vd->border_on;
00646 }
00647 
00648 
00649 /*
00650  *  Trigger raster IRQ
00651  */
00652 
00653 #ifdef GLOBAL_VARS
00654 static inline void raster_irq(void)
00655 #else
00656 inline void MOS6569::raster_irq(void)
00657 #endif
00658 {
00659         irq_flag |= 0x01;
00660         if (irq_mask & 0x01) {
00661                 irq_flag |= 0x80;
00662                 the_cpu->TriggerVICIRQ();
00663         }
00664 }
00665 
00666 
00667 /*
00668  *  Read from VIC register
00669  */
00670 
00671 uint8 MOS6569::ReadRegister(uint16 adr)
00672 {
00673         switch (adr) {
00674                 case 0x00: case 0x02: case 0x04: case 0x06:
00675                 case 0x08: case 0x0a: case 0x0c: case 0x0e:
00676 //                      return mx[adr >> 1];
00677                         return (uint8)mx[adr >> 1];     //AEH 991113
00678 
00679                 case 0x01: case 0x03: case 0x05: case 0x07:
00680                 case 0x09: case 0x0b: case 0x0d: case 0x0f:
00681                         return my[adr >> 1];
00682 
00683                 case 0x10:      // Sprite X position MSB
00684                         return mx8;
00685 
00686                 case 0x11:      // Control register 1
00687                         return (ctrl1 & 0x7f) | ((raster_y & 0x100) >> 1);
00688 
00689                 case 0x12:      // Raster counter
00690 //                      return raster_y;
00691                         return (uint8)raster_y; //AEH 991113
00692 
00693                 case 0x13:      // Light pen X
00694                         return lpx;
00695 
00696                 case 0x14:      // Light pen Y
00697                         return lpy;
00698 
00699                 case 0x15:      // Sprite enable
00700                         return me;
00701 
00702                 case 0x16:      // Control register 2
00703                         return ctrl2 | 0xc0;
00704 
00705                 case 0x17:      // Sprite Y expansion
00706                         return mye;
00707 
00708                 case 0x18:      // Memory pointers
00709                         return vbase | 0x01;
00710 
00711                 case 0x19:      // IRQ flags
00712                         return irq_flag | 0x70;
00713 
00714                 case 0x1a:      // IRQ mask
00715                         return irq_mask | 0xf0;
00716 
00717                 case 0x1b:      // Sprite data priority
00718                         return mdp;
00719 
00720                 case 0x1c:      // Sprite multicolor
00721                         return mmc;
00722 
00723                 case 0x1d:      // Sprite X expansion
00724                         return mxe;
00725 
00726                 case 0x1e:{     // Sprite-sprite collision
00727                         uint8 ret = clx_spr;
00728                         clx_spr = 0;    // Read and clear
00729                         return ret;
00730                 }
00731 
00732                 case 0x1f:{     // Sprite-background collision
00733                         uint8 ret = clx_bgr;
00734                         clx_bgr = 0;    // Read and clear
00735                         return ret;
00736                 }
00737 
00738                 case 0x20: return ec | 0xf0;
00739                 case 0x21: return b0c | 0xf0;
00740                 case 0x22: return b1c | 0xf0;
00741                 case 0x23: return b2c | 0xf0;
00742                 case 0x24: return b3c | 0xf0;
00743                 case 0x25: return mm0 | 0xf0;
00744                 case 0x26: return mm1 | 0xf0;
00745 
00746                 case 0x27: case 0x28: case 0x29: case 0x2a:
00747                 case 0x2b: case 0x2c: case 0x2d: case 0x2e:
00748                         return sc[adr - 0x27] | 0xf0;
00749 
00750                 default:
00751                         return 0xff;
00752         }
00753 }
00754 
00755 
00756 /*
00757  *  Write to VIC register
00758  */
00759 
00760 void MOS6569::WriteRegister(uint16 adr, uint8 byte)
00761 {
00762         switch (adr) {
00763                 case 0x00: case 0x02: case 0x04: case 0x06:
00764                 case 0x08: case 0x0a: case 0x0c: case 0x0e:
00765                         mx[adr >> 1] = (mx[adr >> 1] & 0xff00) | byte;
00766                         break;
00767 
00768                 case 0x10:{
00769                         int i, j;
00770                         mx8 = byte;
00771                         for (i=0, j=1; i<8; i++, j<<=1) {
00772                                 if (mx8 & j)
00773                                         mx[i] |= 0x100;
00774                                 else
00775                                         mx[i] &= 0xff;
00776                         }
00777                         break;
00778                 }
00779 
00780                 case 0x01: case 0x03: case 0x05: case 0x07:
00781                 case 0x09: case 0x0b: case 0x0d: case 0x0f:
00782                         my[adr >> 1] = byte;
00783                         break;
00784 
00785                 case 0x11:{     // Control register 1
00786                         ctrl1 = byte;
00787                         y_scroll = byte & 7;
00788 
00789                         uint16 new_irq_raster = (irq_raster & 0xff) | ((byte & 0x80) << 1);
00790                         if (irq_raster != new_irq_raster && raster_y == new_irq_raster)
00791                                 raster_irq();
00792                         irq_raster = new_irq_raster;
00793 
00794                         if (byte & 8) {
00795                                 dy_start = ROW25_YSTART;
00796                                 dy_stop = ROW25_YSTOP;
00797                         } else {
00798                                 dy_start = ROW24_YSTART;
00799                                 dy_stop = ROW24_YSTOP;
00800                         }
00801 
00802                         display_idx = ((ctrl1 & 0x60) | (ctrl2 & 0x10)) >> 4;
00803                         break;
00804                 }
00805 
00806                 case 0x12:{     // Raster counter
00807                         uint16 new_irq_raster = (irq_raster & 0xff00) | byte;
00808                         if (irq_raster != new_irq_raster && raster_y == new_irq_raster)
00809                                 raster_irq();
00810                         irq_raster = new_irq_raster;
00811                         break;
00812                 }
00813 
00814                 case 0x15:      // Sprite enable
00815                         me = byte;
00816                         break;
00817 
00818                 case 0x16:      // Control register 2
00819                         ctrl2 = byte;
00820                         x_scroll = byte & 7;
00821 //                      border_40_col = byte & 8;
00822                         border_40_col = BOOL_BIT(byte, 8);      //AEH 991113
00823                         display_idx = ((ctrl1 & 0x60) | (ctrl2 & 0x10)) >> 4;
00824                         break;
00825 
00826                 case 0x17:      // Sprite Y expansion
00827                         mye = byte;
00828                         break;
00829 
00830                 case 0x18:      // Memory pointers
00831                         vbase = byte;
00832                         matrix_base = get_physical((byte & 0xf0) << 6);
00833                         char_base = get_physical((byte & 0x0e) << 10);
00834                         bitmap_base = get_physical((byte & 0x08) << 10);
00835                         break;
00836 
00837                 case 0x19: // IRQ flags
00838                         irq_flag = irq_flag & (~byte & 0x0f);
00839                         the_cpu->ClearVICIRQ(); // Clear interrupt (hack!)
00840                         if (irq_flag & irq_mask) // Set master bit if allowed interrupt still pending
00841                                 irq_flag |= 0x80;
00842                         break;
00843                 
00844                 case 0x1a:      // IRQ mask
00845                         irq_mask = byte & 0x0f;
00846                         if (irq_flag & irq_mask) { // Trigger interrupt if pending and now allowed
00847                                 irq_flag |= 0x80;
00848                                 the_cpu->TriggerVICIRQ();
00849                         } else {
00850                                 irq_flag &= 0x7f;
00851                                 the_cpu->ClearVICIRQ();
00852                         }
00853                         break;
00854 
00855                 case 0x1b:      // Sprite data priority
00856                         mdp = byte;
00857                         break;
00858 
00859                 case 0x1c:      // Sprite multicolor
00860                         mmc = byte;
00861                         break;
00862 
00863                 case 0x1d:      // Sprite X expansion
00864                         mxe = byte;
00865                         break;
00866 
00867                 case 0x20:
00868 #ifdef BACKGND_UPDATE
00869                         if(ec == byte)  // dont change if same color
00870                                 break;
00871                         ec_changed = 2;
00872 #endif
00873                         ec_color = colors[ec = byte];
00874                         ec_color_long = (ec_color << 24) | (ec_color << 16) | (ec_color << 8) | ec_color;
00875                         break;
00876 
00877                 case 0x21:
00878                         if (b0c != byte) {
00879                                 b0c_color = colors[b0c = byte & 0xF];
00880                                 make_mc_table();
00881                         }
00882                         break;
00883 
00884                 case 0x22: 
00885                         if (b1c != byte) {
00886                                 b1c_color = colors[b1c = byte & 0xF];
00887                                 make_mc_table();
00888                         }
00889                         break;
00890 
00891                 case 0x23: 
00892                         if (b2c != byte) {
00893                                 b2c_color = colors[b2c = byte & 0xF];
00894                                 make_mc_table();
00895                         }
00896                         break;
00897 
00898                 case 0x24: b3c_color = colors[b3c = byte & 0xF]; break;
00899                 case 0x25: mm0_color = colors[mm0 = byte]; break;
00900                 case 0x26: mm1_color = colors[mm1 = byte]; break;
00901 
00902                 case 0x27: case 0x28: case 0x29: case 0x2a:
00903                 case 0x2b: case 0x2c: case 0x2d: case 0x2e:
00904                         spr_color[adr - 0x27] = colors[sc[adr - 0x27] = byte];
00905                         break;
00906         }
00907 }
00908 
00909 
00910 /*
00911  *  CIA VA14/15 has changed
00912  */
00913 
00914 void MOS6569::ChangedVA(uint16 new_va)
00915 {
00916         cia_vabase = new_va << 14;
00917         WriteRegister(0x18, vbase); // Force update of memory pointers
00918 }
00919 
00920 
00921 /*
00922  *  Trigger lightpen interrupt, latch lightpen coordinates
00923  */
00924 
00925 void MOS6569::TriggerLightpen(void)
00926 {
00927         if (!lp_triggered) {    // Lightpen triggers only once per frame
00928                 lp_triggered = true;
00929 
00930                 lpx = 0;                        // Latch current coordinates
00931 //              lpy = raster_y;
00932                 lpy = (uint8)raster_y;  //AEH 991113
00933 
00934                 irq_flag |= 0x08;       // Trigger IRQ
00935                 if (irq_mask & 0x08) {
00936                         irq_flag |= 0x80;
00937                         the_cpu->TriggerVICIRQ();
00938                 }
00939         }
00940 }
00941 
00942 
00943 /*
00944  *  VIC vertical blank: Reset counters and redraw screen
00945  */
00946 
00947 inline void MOS6569::vblank(void)
00948 {
00949         raster_y = vc_base = 0;
00950         lp_triggered = false;
00951 
00952 //      if (!(frame_skipped = --skip_counter))
00953         if (!(frame_skipped = (--skip_counter > 0) ))   //AEH 991113 (I don't like this!)
00954                 skip_counter = ThePrefs.SkipFrames;
00955 
00956         the_c64->VBlank(!frame_skipped);
00957 
00958         // Get bitmap pointer for next frame. This must be done
00959         // after calling the_c64->VBlank() because the preferences
00960         // and screen configuration may have been changed there
00961 
00962 // in the Epoc version we have the same bitmap all the time
00963 // so we don't need to update those variables.
00964         chunky_line_start = the_display->BitmapBase();
00965         xmod = the_display->BitmapXMod();
00966 
00967 }
00968 
00969 
00970 #ifdef __riscos__
00971 #include "el_Acorn.i"
00972 #else
00973 
00974 #ifdef GLOBAL_VARS
00975 static inline void el_std_text(uint8 *p, uint8 *q, uint8 *r)
00976 #else
00977 inline void MOS6569::el_std_text(uint8 *p, uint8 *q, uint8 *r)
00978 #endif
00979 {
00980 #if COLOR_DEPTH == 4    // modified here:
00981 
00982         unsigned int b0cc = b0c;
00983         uint32 *lp = (uint32*)p;
00984         uint16 *wp = (uint16*)p;
00985         uint8* bp = p;
00986         uint8 *cp = color_line;
00987         uint8 *mp = matrix_line;
00988 
00989         if(nibble_next)
00990                 {
00991 
00992                 for (int i=0; i<40; i++)
00993                         {
00994                         uint8 color = cp[i];
00995                         uint8 data = r[i] = q[mp[i] << 3];
00996 
00997                         *bp++ |= (TextColorTable[color][b0cc][data].a.a << 4) & 0xf0;   // pixel 1
00998 
00999                         *bp    = (TextColorTable[color][b0cc][data].a.a >> 4) & 0x0f;   // pixel 2
01000                         *bp++ |= (TextColorTable[color][b0cc][data].a.b << 4) & 0xf0;   // etc...
01001 
01002                         *bp    = (TextColorTable[color][b0cc][data].a.b >> 4) & 0x0f;
01003                         *bp++ |= (TextColorTable[color][b0cc][data].a.c << 4) & 0xf0;
01004 
01005                         *bp    = (TextColorTable[color][b0cc][data].a.c >> 4) & 0x0f;
01006                         *bp++ |= (TextColorTable[color][b0cc][data].a.d << 4) & 0xf0;
01007 
01008                         *bp    = (TextColorTable[color][b0cc][data].a.d >> 4) & 0x0f;   // pixel 8
01009 
01010                         }
01011         
01012                 }
01013         else
01014 
01015 //      ALIGN_CHECK(lp);
01016         // Loop for 40 characters
01017 
01018         if( ((int)lp) & 0x03 )  // pointer is not word-aligned, copy 2 bytes at a time
01019         for (int i=0; i<40; i++) {
01020                 uint8 color = cp[i];
01021                 uint8 data = r[i] = q[mp[i] << 3];
01022 
01023 //              *lp++ = TextColorTable[color][b0cc][data].b;
01024 
01025                 *wp++ = TextColorTable[color][b0cc][data].b;
01026                 *wp++ = TextColorTable[color][b0cc][data].b >> 16;
01027 
01028 //              *bp++ = TextColorTable[color][b0cc][data].a.a;
01029 //              *bp++ = TextColorTable[color][b0cc][data].a.b;
01030 //              *bp++ = TextColorTable[color][b0cc][data].a.c;
01031 //              *bp++ = TextColorTable[color][b0cc][data].a.d;
01032         }
01033         else    // copy 4 bytes at a time
01034         for (int i=0; i<40; i++) {
01035                 uint8 color = cp[i];
01036                 uint8 data = r[i] = q[mp[i] << 3];
01037 
01038                 *lp++ = TextColorTable[color][b0cc][data].b;
01039 
01040         }
01041 
01042 
01043 
01044 #elif COLOR_DEPTH == 8
01045 
01046         unsigned int b0cc = b0c;
01047         uint32 *lp = (uint32 *)p;
01048         uint8 *cp = color_line;
01049         uint8 *mp = matrix_line;
01050 
01051         // Loop for 40 characters
01052         for (int i=0; i<40; i++) {
01053                 uint8 color = cp[i];
01054                 uint8 data = r[i] = q[mp[i] << 3];
01055 
01056                 *lp++ = TextColorTable[color][b0cc][data][0].b;
01057                 *lp++ = TextColorTable[color][b0cc][data][1].b;
01058         }
01059 
01060 #else
01061 error
01062 #endif
01063                 
01064 }
01065 
01066 
01067 #ifdef GLOBAL_VARS
01068 static inline void el_mc_text(uint8 *p, uint8 *q, uint8 *r)
01069 #else
01070 inline void MOS6569::el_mc_text(uint8 *p, uint8 *q, uint8 *r)
01071 #endif
01072 {
01073 #if COLOR_DEPTH == 4    // modified here:
01074 
01075 //      uint16 *wp = (uint16 *)p;
01076         uint8 *bp = (uint8*)p;
01077         uint8 *cp = color_line;
01078         uint8 *mp = matrix_line;
01079         uint16 *mclp = mc_color_lookup;
01080 
01081         if(nibble_next)
01082         // Loop for 40 characters
01083                 for (int i=0; i<40; i++) 
01084                         {
01085                         uint8 data = q[mp[i] << 3];
01086         
01087                         if (cp[i] & 8) 
01088                                 {
01089                                 uint8 color = colors[cp[i] & 7];
01090                                 r[i] = (data & 0xaa) | (data & 0xaa) >> 1;
01091                                 mclp[3] = color | (color << 8);
01092 
01093 //TODO: optimize here, use words instead
01094 
01095                                 // here is the problem:
01096 
01097                                 *bp++ |= (mclp[(data >> 6) & 3] << 4) & 0xf0;   // pixel 1
01098 
01099                                 *bp    = (mclp[(data >> 6) & 3] >> 4) & 0x0f;
01100                                 *bp++ |= (mclp[(data >> 4) & 3] << 4) & 0xf0;
01101 
01102                                 *bp    = (mclp[(data >> 4) & 3] >> 4) & 0x0f;
01103                                 *bp++ |= (mclp[(data >> 2) & 3] << 4) & 0xf0;
01104                                 
01105                                 *bp    = (mclp[(data >> 2) & 3] >> 4) & 0x0f;
01106                                 *bp++ |= (mclp[(data >> 0) & 3] << 4) & 0xf0;
01107 
01108                                 *bp    = (mclp[(data >> 0) & 3] >> 4) & 0x0f;
01109 
01110                                 } 
01111                         else 
01112                                 { // Standard mode in multicolor mode
01113                                 uint8 color = cp[i];
01114                                 r[i] = data;
01115 
01116                                 *bp++ |= (TextColorTable[color][b0c][data].a.a << 4) & 0xf0;    // pixel 1
01117                                 
01118                                 *bp    = (TextColorTable[color][b0c][data].a.a >> 4) & 0x0f;
01119                                 *bp++ |= (TextColorTable[color][b0c][data].a.b << 4) & 0xf0;
01120 
01121                                 *bp    = (TextColorTable[color][b0c][data].a.b >> 4) & 0x0f;
01122                                 *bp++ |= (TextColorTable[color][b0c][data].a.c << 4) & 0xf0;
01123 
01124                                 *bp    = (TextColorTable[color][b0c][data].a.c >> 4) & 0x0f;
01125                                 *bp++ |= (TextColorTable[color][b0c][data].a.d << 4) & 0xf0;
01126 
01127                                 *bp    = (TextColorTable[color][b0c][data].a.d >> 4) & 0x0f;    // pixel 8
01128                         
01129                                 } // if
01130 
01131                 } // for
01132 
01133         else    // not nibble next
01134 
01135 //      ALIGN_CHECK2(wp);
01136 
01137         // Loop for 40 characters in non-nibble mode
01138         for (int i=0; i<40; i++) {
01139                 uint8 data = q[mp[i] << 3];
01140 
01141                 if (cp[i] & 8)
01142                         {
01143                         uint8 color = colors[cp[i] & 7];
01144                         r[i] = (data & 0xaa) | (data & 0xaa) >> 1;
01145                         mclp[3] = color;
01146                         *bp++ = mclp[(data >> 6) & 3] & 0xff;
01147                         *bp++ = mclp[(data >> 4) & 3] & 0xff;
01148                         *bp++ = mclp[(data >> 2) & 3] & 0xff;
01149                         *bp++ = mclp[(data >> 0) & 3] & 0xff;
01150                         }
01151                 else
01152                         { // Standard mode in multicolor mode
01153                         uint8 color = cp[i];
01154                         r[i] = data;
01155 
01156                         *(uint16*)bp = TextColorTable[color][b0c][data].b;
01157                         bp += 2;
01158                         *(uint16*)bp = TextColorTable[color][b0c][data].b >> 16;
01159                         bp += 2;
01160                         }
01161         }
01162 
01163 #elif COLOR_DEPTH == 8
01164 
01165         uint16 *wp = (uint16 *)p;
01166         uint8 *cp = color_line;
01167         uint8 *mp = matrix_line;
01168         uint16 *mclp = mc_color_lookup;
01169 
01170         // Loop for 40 characters
01171         for (int i=0; i<40; i++) {
01172                 uint8 data = q[mp[i] << 3];
01173 
01174                 if (cp[i] & 8) {
01175                         uint8 color = colors[cp[i] & 7];
01176                         r[i] = (data & 0xaa) | (data & 0xaa) >> 1;
01177                         mclp[3] = color | (color << 8);
01178                         *wp++ = mclp[(data >> 6) & 3];
01179                         *wp++ = mclp[(data >> 4) & 3];
01180                         *wp++ = mclp[(data >> 2) & 3];
01181                         *wp++ = mclp[(data >> 0) & 3];
01182 
01183                 } else { // Standard mode in multicolor mode
01184                         uint8 color = cp[i];
01185                         r[i] = data;
01186 
01187                         *(uint32 *)wp = TextColorTable[color][b0c][data][0].b;
01188                         wp += 2;
01189                         *(uint32 *)wp = TextColorTable[color][b0c][data][1].b;
01190                         wp += 2;
01191                         
01192                         
01193                 }
01194         }
01195 
01196 
01197 #else
01198 error
01199 #endif
01200 
01201 
01202 } // end, MOS6569::el_mc_text
01203 
01204 
01205 #ifdef GLOBAL_VARS
01206 static inline void el_std_bitmap(uint8 *p, uint8 *q, uint8 *r)
01207 #else
01208 inline void MOS6569::el_std_bitmap(uint8 *p, uint8 *q, uint8 *r)
01209 #endif
01210 {
01211 #if COLOR_DEPTH == 4    // modified here:
01212 
01213         uint16 *wp = (uint16 *)p;
01214         uint8 *bp  = (uint8*)p;
01215         uint8 *mp  = matrix_line;
01216 
01217         if(nibble_next)
01218                 // Loop for 40 characters in nibble mode
01219                 for (int i=0; i<40; i++, q+=8) {
01220                         uint8 data = r[i] = *q;
01221                         uint8 color = mp[i] >> 4;
01222                         uint8 bcolor = mp[i] & 15;
01223 
01224                         *bp++ |= (TextColorTable[color][bcolor][data].a.a << 4 ) & 0xf0;        // pixel 1
01225                         
01226                         *bp    = (TextColorTable[color][bcolor][data].a.a >> 4 ) & 0x0f;
01227                         *bp++ |= (TextColorTable[color][bcolor][data].a.b << 4 ) & 0xf0;
01228 
01229                         *bp    = (TextColorTable[color][bcolor][data].a.b >> 4 ) & 0x0f;
01230                         *bp++ |= (TextColorTable[color][bcolor][data].a.c << 4 ) & 0xf0;
01231 
01232                         *bp    = (TextColorTable[color][bcolor][data].a.c >> 4 ) & 0x0f;
01233                         *bp++ |= (TextColorTable[color][bcolor][data].a.d << 4 ) & 0xf0;
01234 
01235                         *bp    = (TextColorTable[color][bcolor][data].a.d >> 4 ) & 0x0f;        // pixel 8
01236         
01237                 }
01238         else
01239 
01240 //              ALIGN_CHECK2(wp);
01241 
01242                 // Loop for 40 characters
01243                 for (int i=0; i<40; i++, q+=8) 
01244                         {
01245                         uint8 data = r[i] = *q;
01246                         uint8 color = mp[i] >> 4;
01247                         uint8 bcolor = mp[i] & 15;
01248         
01249                         *wp++ = (TextColorTable[color][bcolor][data].b >> 16) & 0x0000ffff;
01250                         *wp++ =  TextColorTable[color][bcolor][data].b & 0x0000ffff;
01251                         }
01252 
01253 
01254 #elif COLOR_DEPTH == 8
01255 
01256         uint32 *lp = (uint32 *)p;
01257         uint8 *mp = matrix_line;
01258 
01259         // Loop for 40 characters
01260         for (int i=0; i<40; i++, q+=8) {
01261                 uint8 data = r[i] = *q;
01262                 uint8 color = mp[i] >> 4;
01263                 uint8 bcolor = mp[i] & 15;
01264 
01265                 *lp++ = TextColorTable[color][bcolor][data][0].b;
01266                 *lp++ = TextColorTable[color][bcolor][data][1].b;
01267                 
01268         }
01269 
01270 
01271 #else
01272 error
01273 #endif
01274 
01275 } // end, MOS6569::el_std_bitmap
01276 
01277 
01278 #ifdef GLOBAL_VARS
01279 static inline void el_mc_bitmap(uint8 *p, uint8 *q, uint8 *r)
01280 #else
01281 inline void MOS6569::el_mc_bitmap(uint8 *p, uint8 *q, uint8 *r)
01282 #endif
01283 {
01284 
01285 #if COLOR_DEPTH == 4
01286 
01287         uint8 lookup[4];
01288         uint8 *bp = p;
01289         uint8 *cp = color_line;
01290         uint8 *mp = matrix_line;
01291 
01292 #ifdef __GNU_C__
01293         &lookup; /* Statement with no effect other than preventing GCC from
01294                           * putting the array in a register, which generates
01295                           * spectacularly bad code. */
01296 #endif
01297 
01298         lookup[0] = b0c_color;
01299 
01300         if(nibble_next)
01301 
01302                 // Loop for 40 characters in nibble mode
01303                 for (int i=0; i<40; i++, q+=8)
01304                         {
01305 
01306                         lookup[1] = colors[mp[i] >> 4];
01307                         lookup[2] = colors[mp[i]];
01308                         lookup[3] = colors[cp[i]];
01309 
01310                         uint8 data = *q;
01311                         r[i] = (data & 0xaa) | (data & 0xaa) >> 1;
01312 
01313                         *bp++ = lookup[(data >> 6) & 3];
01314                         *bp++ = lookup[(data >> 4) & 3];
01315                         *bp++ = lookup[(data >> 2) & 3];
01316                         *bp++ = lookup[(data >> 0) & 3];
01317                         }
01318         else
01319                 // Loop for 40 characters in non-nibble mode
01320                 for (int i=0; i<40; i++, q+=8)
01321                         {
01322 
01323                         lookup[1] = colors[mp[i] >> 4];
01324                         lookup[2] = colors[mp[i]];
01325                         lookup[3] = colors[cp[i]];
01326 
01327                         uint8 data = *q;
01328                         r[i] = (data & 0xaa) | (data & 0xaa) >> 1;
01329 
01330                         *bp++ |= (lookup[(data >> 6) & 3] << 4) & 0xf0;
01331 
01332                         *bp    = (lookup[(data >> 6) & 3] >> 4) & 0x0f;
01333                         *bp++ |= (lookup[(data >> 4) & 3] << 4) & 0xf0;
01334 
01335                         *bp    = (lookup[(data >> 4) & 3] >> 4) & 0x0f;
01336                         *bp++ |= (lookup[(data >> 2) & 3] << 4) & 0xf0;
01337 
01338                         *bp    = (lookup[(data >> 2) & 3] >> 4) & 0x0f;
01339                         *bp++ |= (lookup[(data >> 0) & 3] << 4) & 0xf0;
01340 
01341                         *bp    = (lookup[(data >> 0) & 3] >> 4) & 0x0f;
01342                         }
01343 
01344 
01345 #elif COLOR_DEPTH == 8
01346 
01347         uint16 lookup[4];
01348         uint16 *wp = (uint16 *)p - 1;
01349         uint8 *cp = color_line;
01350         uint8 *mp = matrix_line;
01351 
01352 #ifdef __GNU_C__
01353         &lookup; /* Statement with no effect other than preventing GCC from
01354                           * putting the array in a register, which generates
01355                           * spectacularly bad code. */
01356 #endif
01357 
01358         lookup[0] = (b0c_color << 8) | b0c_color;
01359 
01360         // Loop for 40 characters
01361         for (int i=0; i<40; i++, q+=8) {
01362                 uint8 color, acolor, bcolor;
01363 
01364                 color = colors[mp[i] >> 4];
01365                 lookup[1] = (color << 8) | color;
01366                 bcolor = colors[mp[i]];
01367                 lookup[2] = (bcolor << 8) | bcolor;
01368                 acolor = colors[cp[i]];
01369                 lookup[3] = (acolor << 8) | acolor;
01370 
01371                 uint8 data = *q;
01372                 r[i] = (data & 0xaa) | (data & 0xaa) >> 1;
01373 
01374                 *++wp = lookup[(data >> 6) & 3];
01375                 *++wp = lookup[(data >> 4) & 3];
01376                 *++wp = lookup[(data >> 2) & 3];
01377                 *++wp = lookup[(data >> 0) & 3];
01378         }
01379 
01380 
01381 #else
01382 error
01383 #endif
01384         
01385         
01386 
01387 
01388 } // end, MOS6569::el_mc_bitmap
01389 
01390 
01391 
01392 #ifdef GLOBAL_VARS
01393 static inline void el_ecm_text(uint8 *p, uint8 *q, uint8 *r)
01394 #else
01395 inline void MOS6569::el_ecm_text(uint8 *p, uint8 *q, uint8 *r)
01396 #endif
01397 {
01398 //AEH 991211
01399 #if COLOR_DEPTH == 4    // modified here:
01400 
01401         uint32 *lp = (uint32*)p;
01402         uint16 *wp = (uint16*)p;
01403         uint8 *bp = p;
01404         uint8 *cp = color_line;
01405         uint8 *mp = matrix_line;
01406         uint8 *bcp = &b0c;
01407 
01408         if(nibble_next)
01409                 // Loop for 40 characters in nibble mode
01410                 for (int i=0; i<40; i++)
01411                         {
01412                         uint8 data = r[i] = mp[i];
01413                         uint8 color = cp[i];
01414                         uint8 bcolor = bcp[(data >> 6) & 3];
01415         
01416                         data = q[(data & 0x3f) << 3];
01417         
01418                         *bp++ |= (TextColorTable[color][bcolor][data].a.a << 4 ) & 0xf0;
01419                         
01420                         *bp    = (TextColorTable[color][bcolor][data].a.a >> 4 ) & 0x0f;
01421                         *bp++ |= (TextColorTable[color][bcolor][data].a.b << 4 ) & 0xf0;
01422 
01423                         *bp    = (TextColorTable[color][bcolor][data].a.b >> 4 ) & 0x0f;
01424                         *bp++ |= (TextColorTable[color][bcolor][data].a.c << 4 ) & 0xf0;
01425 
01426                         *bp    = (TextColorTable[color][bcolor][data].a.c >> 4 ) & 0x0f;
01427                         *bp++ |= (TextColorTable[color][bcolor][data].a.d << 4 ) & 0xf0;
01428 
01429                         *bp    = (TextColorTable[color][bcolor][data].a.d >> 4 ) & 0x0f;
01430 
01431                         }
01432                 else
01433 
01434 //              ALIGN_CHECK(lp);
01435 
01436                 // Loop for 40 characters in non-nibble mode
01437                 if( ((int)lp) & 0x03 )  // pointer is not word-aligned, copy 2 bytes at a time
01438                         for (int i=0; i<40; i++)
01439                                 {
01440                                 uint8 data = r[i] = mp[i];
01441                                 uint8 color = cp[i];
01442                                 uint8 bcolor = bcp[(data >> 6) & 3];
01443                 
01444                                 data = q[(data & 0x3f) << 3];
01445                 
01446                                 *wp++ = TextColorTable[color][bcolor][data].b;
01447                                 *wp++ = TextColorTable[color][bcolor][data].b >> 16;
01448                                 
01449                                 }
01450                         else // copy 4 bytes at a time
01451                         for (int i=0; i<40; i++)
01452                                 {
01453                                 uint8 data = r[i] = mp[i];
01454                                 uint8 color = cp[i];
01455                                 uint8 bcolor = bcp[(data >> 6) & 3];
01456                 
01457                                 data = q[(data & 0x3f) << 3];
01458                 
01459                                 *lp++ = TextColorTable[color][bcolor][data].b;
01460                                 
01461                                 }
01462 
01463 #elif COLOR_DEPTH == 8
01464 
01465         uint32 *lp = (uint32 *)p;
01466         uint8 *cp = color_line;
01467         uint8 *mp = matrix_line;
01468         uint8 *bcp = &b0c;
01469 
01470         // Loop for 40 characters
01471         for (int i=0; i<40; i++) {
01472                 uint8 data = r[i] = mp[i];
01473                 uint8 color = cp[i];
01474                 uint8 bcolor = bcp[(data >> 6) & 3];
01475 
01476                 data = q[(data & 0x3f) << 3];
01477 
01478                 *lp++ = TextColorTable[color][bcolor][data][0].b;
01479                 *lp++ = TextColorTable[color][bcolor][data][1].b;
01480         }
01481 
01482 #else
01483 error
01484 #endif
01485 
01486 
01487 } // end, MOS6569::el_ecm_text
01488 
01489 
01490 #ifdef GLOBAL_VARS
01491 static inline void el_std_idle(uint8 *p, uint8 *r)
01492 #else
01493 inline void MOS6569::el_std_idle(uint8 *p, uint8 *r)
01494 #endif
01495 {
01496         uint8 data = *get_physical(ctrl1 & 0x40 ? 0x39ff : 0x3fff);
01497         uint32 *lp = (uint32*)p;
01498         
01499 #if COLOR_DEPTH == 4    // modified here:
01500         uint16 *wp = (uint16*)p;
01501         uint8 *bp = p;
01502 
01503         if(nibble_next) // nibble mode
01504                 {
01505                 uint32 conv0 = TextColorTable[0][b0c][data].b;
01506 
01507                 for (int i=0; i<40; i++)
01508                         {
01510 
01511                         *bp++ |= (conv0 >> 20 ) & 0xf0;
01512                         
01513                         *bp    = (conv0 >> 28 ) & 0x0f;
01514                         *bp++ |= (conv0 >> 16 ) & 0xf0;
01515 
01516                         *bp    = (conv0 >> 20 ) & 0x0f;
01517                         *bp++ |= (conv0 >> 20 ) & 0xf0;
01518 
01519                         *bp    = (conv0 >> 12 ) & 0x0f;
01520                         *bp++ |= (conv0 << 4 ) & 0xf0;
01521 
01522                         *bp    = (conv0 >> 4 ) & 0x0f;
01523                 
01524                         *r++ = data;
01525                 
01526                 }
01527 
01528                 }
01529         else    // non nibble mode
01530                 {
01531 
01532 //              ALIGN_CHECK(lp);
01533 
01534                 uint32 conv0 = TextColorTable[0][b0c][data].b;
01535 
01536                 if( ((int)lp) & 0x03 )  // pointer is not word-aligned, copy 2 bytes at a time
01537                         for (int i=0; i<40; i++)
01538                                 {
01539                                 *wp++ = conv0;
01540                                 *wp++ = conv0 >> 16;
01541                                 *r++ = data;
01542                                 }
01543                 else
01544                         for (int i=0; i<40; i++) // copy 4 byte at a time
01545                                 {
01546                                 *lp++ = conv0;
01547                                 *r++ = data;
01548                         }
01549         
01550                 }
01551 
01552 #elif COLOR_DEPTH == 8
01553         uint32 conv0 = TextColorTable[0][b0c][data][0].b;
01554         uint32 conv1 = TextColorTable[0][b0c][data][1].b;
01555 
01556         for (int i=0; i<40; i++) {
01557                 *lp++ = conv0;
01558                 *lp++ = conv1;
01559                 *r++ = data;
01560         }
01561 #endif
01562         
01563 } // end, MOS6569::el_std_idle
01564 
01565 
01566 #ifdef GLOBAL_VARS
01567 static inline void el_mc_idle(uint8 *p, uint8 *r)
01568 #else
01569 inline void MOS6569::el_mc_idle(uint8 *p, uint8 *r)
01570 #endif
01571 {
01572 #if COLOR_DEPTH == 4
01573 
01574         uint8 data = *get_physical(0x3fff);
01575         uint16 *wp = (uint16*)p;
01576         uint8  *bp = (uint8*)p;
01577 
01578 
01579         uint16 lookup[4];
01580         lookup[0] = b0c_color;
01581         lookup[1] = lookup[2] = lookup[3] = colors[0];
01582 
01583         uint16 conv0 = (lookup[(data >> 6) & 3] << 8) | lookup[(data >> 4) & 3];
01584         uint16 conv1 = (lookup[(data >> 2) & 3] << 8) | lookup[(data >> 0) & 3];
01585         uint32 conv2 = conv0 | (conv1 << 16);
01586 
01587         if(nibble_next)
01588                 {
01589 
01590                 uint32 tmp1 = (conv2 >> 4 ) & 0x0f0f0f0f;
01591                 uint32 tmp2 = (conv2 << 12 ) & 0xf0f0f0f0;
01592                 uint32 tmp3 = tmp1 | tmp2;
01593 
01594 //              ALIGN_CHECK(lp);
01595 
01596                 *bp++ |= (tmp3 >> 20 ) & 0xf0;
01597                 
01598                 *bp    = (tmp3 >> 28 ) & 0x0f;
01599                 *bp++ |= (tmp3 >> 16 ) & 0xf0;
01600 
01601                 *bp    = (tmp3 >> 20 ) & 0x0f;
01602                 *bp++ |= (tmp3 >> 20 ) & 0xf0;
01603 
01604                 *bp    = (tmp3 >> 12 ) & 0x0f;
01605                 *bp++ |= (tmp3 << 4 ) & 0xf0;
01606 
01607                 *bp    = (tmp3 >> 4 ) & 0x0f;
01608                 
01609                 }
01610         else
01611                 {
01612 
01613                 // possible Alignment bug
01614                 ALIGN_CHECK2(wp);
01615 
01616                 for (int i=0; i<40; i++)
01617                         {
01618                         *wp++ = conv0;
01619                         *wp++ = conv1;
01620                         *r++ = data;
01621                         }
01622                 
01623                 }
01624 
01625 #elif COLOR_DEPTH == 8
01626 
01627         uint8 data = *get_physical(0x3fff);
01628         uint32 *lp = (uint32 *)p - 1;
01629         r--;
01630 
01631         uint16 lookup[4];
01632         lookup[0] = (b0c_color << 8) | b0c_color;
01633         lookup[1] = lookup[2] = lookup[3] = colors[0];
01634 
01635         uint16 conv0 = (lookup[(data >> 6) & 3] << 16) | lookup[(data >> 4) & 3];
01636         uint16 conv1 = (lookup[(data >> 2) & 3] << 16) | lookup[(data >> 0) & 3];
01637 
01638         for (int i=0; i<40; i++) {
01639                 *++lp = conv0;
01640                 *++lp = conv1;
01641                 *++r = data;
01642         }
01643 
01644 #else
01645 error
01646 #endif
01647 
01648 } // end, MOS6569::el_mc_idle
01649 
01650 
01651 #endif //__riscos__
01652 
01653 
01654 inline void MOS6569::el_sprites(uint8 *chunky_ptr)
01655 {
01656 
01657 #if COLOR_DEPTH == 4
01658 #elif COLOR_DEPTH == 8
01659 #endif
01660         
01661         int i;
01662         int snum, sbit;         // Sprite number/bit mask
01663         int spr_coll=0, gfx_coll=0;
01664 
01665         // Draw each active sprite
01666         for (snum=0, sbit=1; snum<8; snum++, sbit<<=1)
01667 #if COLOR_DEPTH == 4
01668                 if ((sprite_on & sbit) && mx[snum] < (2*DISPLAY_X-32) ) {
01669 #elif COLOR_DEPTH == 8
01670                 if ((sprite_on & sbit) && mx[snum] < DISPLAY_X-32) {
01671 #endif
01672 
01673                         int spr_mask_pos;       // Sprite bit position in fore_mask_buf
01674                         uint32 sdata, fore_mask;
01675 
01676 #if COLOR_DEPTH == 4
01677                         uint8 *p = chunky_ptr + mx[snum]/2 + 8;
01678                         nibble_next = mx[snum] & 0x01;
01679 #elif COLOR_DEPTH == 8
01680                         uint8 *p = chunky_ptr + mx[snum] + 8;
01681 #endif
01682                         uint8 *q = spr_coll_buf + mx[snum] + 8;
01683 
01684                         uint8 *sdatap = get_physical(matrix_base[0x3f8 + snum] << 6 | mc[snum]);
01685                         sdata = (*sdatap << 24) | (*(sdatap+1) << 16) | (*(sdatap+2) << 8);
01686 
01687                         uint8 color = spr_color[snum];
01688 
01689                         spr_mask_pos = mx[snum] + 8 - x_scroll;
01690                         
01691                         uint8 *fmbp = fore_mask_buf + (spr_mask_pos / 8);
01692                         int sshift = spr_mask_pos & 7;
01693                         fore_mask = (((*(fmbp+0) << 24) | (*(fmbp+1) << 16) | (*(fmbp+2) << 8)
01694                                       | (*(fmbp+3))) << sshift) | (*(fmbp+4) >> (8-sshift));
01695 
01696                         if (mxe & sbit) {               // X-expanded
01697 #if COLOR_DEPTH == 4
01698                                 if (mx[snum] >= (2*DISPLAY_X-56) )
01699                                         continue;
01700 #elif COLOR_DEPTH == 8
01701                                 if (mx[snum] >= DISPLAY_X-56)
01702                                         continue;
01703 #endif
01704 
01705                                 uint32 sdata_l = 0, sdata_r = 0, fore_mask_r;
01706                                 fore_mask_r = (((*(fmbp+4) << 24) | (*(fmbp+5) << 16) | (*(fmbp+6) << 8)
01707                                                 | (*(fmbp+7))) << sshift) | (*(fmbp+8) >> (8-sshift));
01708 
01709                                 if (mmc & sbit) {       // Multicolor mode
01710                                         uint32 plane0_l, plane0_r, plane1_l, plane1_r;
01711 
01712                                         // Expand sprite data
01713                                         sdata_l = MultiExpTable[sdata >> 24 & 0xff] << 16 | MultiExpTable[sdata >> 16 & 0xff];
01714                                         sdata_r = MultiExpTable[sdata >> 8 & 0xff] << 16;
01715 
01716                                         // Convert sprite chunky pixels to bitplanes
01717                                         plane0_l = (sdata_l & 0x55555555) | (sdata_l & 0x55555555) << 1;
01718                                         plane1_l = (sdata_l & 0xaaaaaaaa) | (sdata_l & 0xaaaaaaaa) >> 1;
01719                                         plane0_r = (sdata_r & 0x55555555) | (sdata_r & 0x55555555) << 1;
01720                                         plane1_r = (sdata_r & 0xaaaaaaaa) | (sdata_r & 0xaaaaaaaa) >> 1;
01721 
01722                                         // Collision with graphics?
01723                                         if ((fore_mask & (plane0_l | plane1_l)) || (fore_mask_r & (plane0_r | plane1_r))) {
01724                                                 gfx_coll |= sbit;
01725                                                 if (mdp & sbit) {
01726                                                         plane0_l &= ~fore_mask; // Mask sprite if in background
01727                                                         plane1_l &= ~fore_mask;
01728                                                         plane0_r &= ~fore_mask_r;
01729                                                         plane1_r &= ~fore_mask_r;
01730                                                 }
01731                                         }
01732 
01733                                         // Paint sprite
01734                                         for (i=0; i<32; i++, plane0_l<<=1, plane1_l<<=1) {
01735                                                 uint8 col;
01736                                                 if (plane1_l & 0x80000000) {
01737                                                         if (plane0_l & 0x80000000)
01738                                                                 col = mm1_color;
01739                                                         else
01740                                                                 col = color;
01741                                                 } else {
01742                                                         if (plane0_l & 0x80000000)
01743                                                                 col = mm0_color;
01744                                                         else
01745                                                                 continue;
01746                                                 }
01747                                                 if (q[i])
01748                                                         spr_coll |= q[i] | sbit;
01749                                                 else {
01750 
01751 #if COLOR_DEPTH == 4
01752                                                         p[i>>1] = ((i & 0x01) == nibble_next) ? col : (p[i>>1] & 0x0f) | (col & 0xf0);
01753 #elif COLOR_DEPTH == 8
01754                                                         p[i] = col;
01755 #endif
01756                                                         q[i] = sbit;
01757                                                 }
01758                                         }
01759                                         for (; i<48; i++, plane0_r<<=1, plane1_r<<=1) {
01760                                                 uint8 col;
01761                                                 if (plane1_r & 0x80000000) {
01762                                                         if (plane0_r & 0x80000000)
01763                                                                 col = mm1_color;
01764                                                         else
01765                                                                 col = color;
01766                                                 } else {
01767                                                         if (plane0_r & 0x80000000)
01768                                                                 col = mm0_color;
01769                                                         else
01770                                                                 continue;
01771                                                 }
01772                                                 if (q[i])
01773                                                         spr_coll |= q[i] | sbit;
01774                                                 else {
01775 
01776 #if COLOR_DEPTH == 4
01777                                                         p[i>>1] = ((i & 0x01) == nibble_next) ? col : (p[i>>1] & 0x0f) | (col & 0xf0);
01778 #elif COLOR_DEPTH == 8
01779                                                         p[i] = col;
01780 #endif
01781 
01782                                                         q[i] = sbit;
01783                                                 }
01784                                         }
01785 
01786                                 } else {                        // Standard mode
01787 
01788                                         // Expand sprite data
01789                                         sdata_l = ExpTable[sdata >> 24 & 0xff] << 16 | ExpTable[sdata >> 16 & 0xff];
01790                                         sdata_r = ExpTable[sdata >> 8 & 0xff] << 16;
01791 
01792                                         // Collision with graphics?
01793                                         if ((fore_mask & sdata_l) || (fore_mask_r & sdata_r)) {
01794                                                 gfx_coll |= sbit;
01795                                                 if (mdp & sbit) {
01796                                                         sdata_l &= ~fore_mask;  // Mask sprite if in background
01797                                                         sdata_r &= ~fore_mask_r;
01798                                                 }
01799                                         }
01800 
01801                                         // Paint sprite
01802                                         for (i=0; i<32; i++, sdata_l<<=1)
01803                                                 if (sdata_l & 0x80000000) {
01804                                                         if (q[i])       // Collision with sprite?
01805                                                                 spr_coll |= q[i] | sbit;
01806                                                         else {          // Draw pixel if no collision
01807 
01808 #if COLOR_DEPTH == 4
01809 //                                                              p[i] = ((i & 0x01) == nibble_next) ? color : p[i] | (color & 0xf0);
01810                                                                 p[i>>1] = ((i & 0x01) == nibble_next) ? color : (p[i>>1] & 0x0f) | (color & 0xf0);
01811 #elif COLOR_DEPTH == 8
01812                                                                 p[i] = color;
01813 #endif
01814 
01815                                                                 q[i] = sbit;
01816                                                         }
01817                                                 }
01818                                         for (; i<48; i++, sdata_r<<=1)
01819                                                 if (sdata_r & 0x80000000) {
01820                                                         if (q[i])       // Collision with sprite?
01821                                                                 spr_coll |= q[i] | sbit;
01822                                                         else {          // Draw pixel if no collision
01823 
01824 #if COLOR_DEPTH == 4
01825                                                                 p[i>>1] = ((i & 0x01) == nibble_next) ? color : (p[i>>1] & 0x0f) | (color & 0xf0);
01826 #elif COLOR_DEPTH == 8
01827                                                                 p[i] = color;
01828 #endif
01829                                                                 q[i] = sbit;
01830                                                         }
01831                                                 }
01832                                 }
01833 
01834                         } else                                  // Unexpanded
01835 
01836                                 if (mmc & sbit) {       // Multicolor mode
01837                                         uint32 plane0, plane1;
01838 
01839                                         // Convert sprite chunky pixels to bitplanes
01840                                         plane0 = (sdata & 0x55555555) | (sdata & 0x55555555) << 1;
01841                                         plane1 = (sdata & 0xaaaaaaaa) | (sdata & 0xaaaaaaaa) >> 1;
01842 
01843                                         // Collision with graphics?
01844                                         if (fore_mask & (plane0 | plane1)) {
01845                                                 gfx_coll |= sbit;
01846                                                 if (mdp & sbit) {
01847                                                         plane0 &= ~fore_mask;   // Mask sprite if in background
01848                                                         plane1 &= ~fore_mask;
01849                                                 }
01850                                         }
01851 
01852                                         // Paint sprite
01853                                         for (i=0; i<24; i++, plane0<<=1, plane1<<=1) {
01854                                                 uint8 col;
01855                                                 if (plane1 & 0x80000000) {
01856                                                         if (plane0 & 0x80000000)
01857                                                                 col = mm1_color;
01858                                                         else
01859                                                                 col = color;
01860                                                 } else {
01861                                                         if (plane0 & 0x80000000)
01862                                                                 col = mm0_color;
01863                                                         else
01864                                                                 continue;
01865                                                 }
01866                                                 if (q[i])
01867                                                         spr_coll |= q[i] | sbit;
01868                                                 else {
01869 
01870 #if COLOR_DEPTH == 4
01871                                                         p[i>>1] = ((i & 0x01) == nibble_next) ? col : (p[i>>1] & 0x0f) | (col & 0xf0);
01872 #elif COLOR_DEPTH == 8
01873                                                         p[i] = col;
01874 #endif
01875                                                         q[i] = sbit;
01876                                                 }
01877                                         }
01878 
01879                                 } else {                        // Standard mode
01880 
01881                                         // Collision with graphics?
01882                                         if (fore_mask & sdata) {
01883                                                 gfx_coll |= sbit;
01884                                                 if (mdp & sbit)
01885                                                         sdata &= ~fore_mask;    // Mask sprite if in background
01886                                         }
01887         
01888                                         // Paint sprite
01889                                         for (i=0; i<24; i++, sdata<<=1)
01890                                                 if (sdata & 0x80000000) {
01891                                                         if (q[i]) {             // Collision with sprite?
01892                                                                 spr_coll |= q[i] | sbit;
01893                                                         } else {                // Draw pixel if no collision
01894 
01895 #if COLOR_DEPTH == 4
01896                                                                 p[i>>1] = ((i & 0x01) == nibble_next) ? color : (p[i>>1] & 0x0f) | (color & 0xf0);
01897 #elif COLOR_DEPTH == 8
01898                                                                 p[i] = color;
01899 #endif
01900                                                                 q[i] = sbit;
01901                                                         }
01902                                                 }
01903 
01904                                 }
01905                 }
01906 
01907         if (ThePrefs.SpriteCollisions) {
01908 
01909                 // Check sprite-sprite collisions
01910                 if (clx_spr)
01911                         clx_spr |= spr_coll;
01912                 else {
01913                         clx_spr |= spr_coll;
01914                         irq_flag |= 0x04;
01915                         if (irq_mask & 0x04) {
01916                                 irq_flag |= 0x80;
01917                                 the_cpu->TriggerVICIRQ();
01918                         }
01919                 }
01920 
01921                 // Check sprite-background collisions
01922                 if (clx_bgr)
01923                         clx_bgr |= gfx_coll;
01924                 else {
01925                         clx_bgr |= gfx_coll;
01926                         irq_flag |= 0x02;
01927                         if (irq_mask & 0x02) {
01928                                 irq_flag |= 0x80;
01929                                 the_cpu->TriggerVICIRQ();
01930                         }
01931                 }
01932         }
01933 }
01934 
01935 
01936 #ifdef GLOBAL_VARS
01937 static inline int el_update_mc(int raster)
01938 #else
01939 inline int MOS6569::el_update_mc(int raster)
01940 #endif
01941 {
01942         int i, j;
01943         int cycles_used = 0;
01944         uint8 spron = sprite_on;
01945         uint8 spren = me;
01946         uint8 sprye = mye;
01947         uint8 raster8bit = raster;
01948         uint16 *mcp = mc;
01949         uint8 *myp = my;
01950 
01951         // Increment sprite data counters
01952         for (i=0, j=1; i<8; i++, j<<=1, mcp++, myp++) {
01953 
01954                 // Sprite enabled?
01955                 if (spren & j)
01956 
01957                         // Yes, activate if Y position matches raster counter
01958                         if (*myp == (raster8bit & 0xff)) {
01959                                 *mcp = 0;
01960                                 spron |= j;
01961                         } else
01962                                 goto spr_off;
01963                 else
01964 spr_off:
01965                         // No, turn sprite off when data counter exceeds 60
01966                         //  and increment counter
01967                         if (*mcp != 63) {
01968                                 if (sprye & j) {        // Y expansion
01969                                         if (!((*myp ^ raster8bit) & 1)) {
01970                                                 *mcp += 3;
01971                                                 cycles_used += 2;
01972                                                 if (*mcp == 63)
01973                                                         spron &= ~j;
01974                                         }
01975                                 } else {
01976                                         *mcp += 3;
01977                                         cycles_used += 2;
01978                                         if (*mcp == 63)
01979                                                 spron &= ~j;
01980                                 }
01981                         }
01982         }
01983 
01984         sprite_on = spron;
01985         return cycles_used;
01986 }
01987 
01988 
01989 #ifdef __POWERPC__
01990 static asm void fastcopy(register uchar *dst, register uchar *src);
01991 static asm void fastcopy(register uchar *dst, register uchar *src)
01992 {
01993         lfd             fp0,0(src)
01994         lfd             fp1,8(src)
01995         lfd             fp2,16(src)
01996         lfd             fp3,24(src)
01997         lfd             fp4,32(src)
01998         lfd             fp5,40(src)
01999         lfd             fp6,48(src)
02000         lfd             fp7,56(src)
02001         addi    src,src,64
02002         stfd    fp0,0(dst)
02003         stfd    fp1,8(dst)
02004         stfd    fp2,16(dst)
02005         stfd    fp3,24(dst)
02006         stfd    fp4,32(dst)
02007         stfd    fp5,40(dst)
02008         stfd    fp6,48(dst)
02009         stfd    fp7,56(dst)
02010         addi    dst,dst,64
02011 
02012         lfd             fp0,0(src)
02013         lfd             fp1,8(src)
02014         lfd             fp2,16(src)
02015         lfd             fp3,24(src)
02016         lfd             fp4,32(src)
02017         lfd             fp5,40(src)
02018         lfd             fp6,48(src)
02019         lfd             fp7,56(src)
02020         addi    src,src,64
02021         stfd    fp0,0(dst)
02022         stfd    fp1,8(dst)
02023         stfd    fp2,16(dst)
02024         stfd    fp3,24(dst)
02025         stfd    fp4,32(dst)
02026         stfd    fp5,40(dst)
02027         stfd    fp6,48(dst)
02028         stfd    fp7,56(dst)
02029         addi    dst,dst,64
02030 
02031         lfd             fp0,0(src)
02032         lfd             fp1,8(src)
02033         lfd             fp2,16(src)
02034         lfd             fp3,24(src)
02035         lfd             fp4,32(src)
02036         lfd             fp5,40(src)
02037         lfd             fp6,48(src)
02038         lfd             fp7,56(src)
02039         addi    src,src,64
02040         stfd    fp0,0(dst)
02041         stfd    fp1,8(dst)
02042         stfd    fp2,16(dst)
02043         stfd    fp3,24(dst)
02044         stfd    fp4,32(dst)
02045         stfd    fp5,40(dst)
02046         stfd    fp6,48(dst)
02047         stfd    fp7,56(dst)
02048         addi    dst,dst,64
02049 
02050         lfd             fp0,0(src)
02051         lfd             fp1,8(src)
02052         lfd             fp2,16(src)
02053         lfd             fp3,24(src)
02054         lfd             fp4,32(src)
02055         lfd             fp5,40(src)
02056         lfd             fp6,48(src)
02057         lfd             fp7,56(src)
02058         addi    src,src,64
02059         stfd    fp0,0(dst)
02060         stfd    fp1,8(dst)
02061         stfd    fp2,16(dst)
02062         stfd    fp3,24(dst)
02063         stfd    fp4,32(dst)
02064         stfd    fp5,40(dst)
02065         stfd    fp6,48(dst)
02066         stfd    fp7,56(dst)
02067         addi    dst,dst,64
02068 
02069         lfd             fp0,0(src)
02070         lfd             fp1,8(src)
02071         lfd             fp2,16(src)
02072         lfd             fp3,24(src)
02073         lfd             fp4,32(src)
02074         lfd             fp5,40(src)
02075         lfd             fp6,48(src)
02076         lfd             fp7,56(src)
02077         addi    src,src,64
02078         stfd    fp0,0(dst)
02079         stfd    fp1,8(dst)
02080         stfd    fp2,16(dst)
02081         stfd    fp3,24(dst)
02082         stfd    fp4,32(dst)
02083         stfd    fp5,40(dst)
02084         stfd    fp6,48(dst)
02085         stfd    fp7,56(dst)
02086         addi    dst,dst,64
02087 
02088         lfd             fp0,0(src)
02089         lfd             fp1,8(src)
02090         lfd             fp2,16(src)
02091         lfd             fp3,24(src)
02092         lfd             fp4,32(src)
02093         lfd             fp5,40(src)
02094         lfd             fp6,48(src)
02095         lfd             fp7,56(src)
02096         addi    src,src,64
02097         stfd    fp0,0(dst)
02098         stfd    fp1,8(dst)
02099         stfd    fp2,16(dst)
02100         stfd    fp3,24(dst)
02101         stfd    fp4,32(dst)
02102         stfd    fp5,40(dst)
02103         stfd    fp6,48(dst)
02104         stfd    fp7,56(dst)
02105         addi    dst,dst,64
02106         blr             
02107 }
02108 #endif
02109 
02110 
02111 /*
02112  *  Emulate one raster line
02113  */
02114 
02115 int MOS6569::EmulateLine(void)
02116 {
02117         int cycles_left = ThePrefs.NormalCycles;        // Cycles left for CPU
02118         bool is_bad_line = false;
02119 
02120         CD4(nibble_next = false);
02121 
02122         // Get raster counter into local variable for faster access and increment
02123         int raster = raster_y+1;
02124 
02125         // End of screen reached?
02126         if (raster != TOTAL_RASTERS)
02127                 raster_y = raster;
02128         else {
02129                 vblank();
02130                 raster = 0;
02131         }
02132 
02133         // Trigger raster IRQ if IRQ line reached
02134         if (raster == irq_raster)
02135                 raster_irq();
02136 
02137         // In line $30, the DEN bit controls if Bad Lines can occur
02138         if (raster == 0x30)
02139                 bad_lines_enabled = ctrl1 & 0x10;
02140 
02141         // Skip frame? Only calculate Bad Lines then
02142         if (frame_skipped) {
02143                 if (raster >= FIRST_DMA_LINE && raster <= LAST_DMA_LINE && ((raster & 7) == y_scroll) && bad_lines_enabled) {
02144                         is_bad_line = true;
02145                         cycles_left = ThePrefs.BadLineCycles;
02146                 }
02147                 goto VIC_nop;
02148         }
02149 
02150         // Within the visible range?    -- POSSIBLE BUG INSIDE THIS IF() !!!
02151         if (raster >= FIRST_DISP_LINE && raster <= LAST_DISP_LINE) {
02152 
02153                 // Our output goes here
02154 #ifdef __POWERPC__
02155                 uint8 *chunky_ptr = (uint8 *)chunky_tmp;
02156 #else
02157                 uint8 *chunky_ptr = chunky_line_start;
02158 #endif
02159 
02160 #ifdef _DEBUG
02161                 if(chunky_ptr >= (the_display->BitmapBase() + DISPLAY_X * DISPLAY_Y))
02162                         {
02163                         ELOG2(_L8("Bitmap overflow! 0x%08x\n"), chunky_ptr);
02164                         }
02165 
02166 #endif
02167 
02168                 // Set video counter
02169                 vc = vc_base;
02170 
02171                 // Bad Line condition?
02172                 if (raster >= FIRST_DMA_LINE && raster <= LAST_DMA_LINE && ((raster & 7) == y_scroll) && bad_lines_enabled) {
02173 
02174                         // Turn on display
02175                         display_state = is_bad_line = true;
02176                         cycles_left = ThePrefs.BadLineCycles;
02177                         rc = 0;
02178 
02179                         // Read and latch 40 bytes from video matrix and color RAM
02180 
02181 #ifdef __SYMBIAN32__
02182 
02183                         uint32* mp = (uint32*)matrix_line;
02184                         uint32* mbp = (uint32*)(matrix_base + vc);
02185 
02186                         ALIGN_CHECK(mp);
02187                         ALIGN_CHECK(mbp);
02188 
02189                         *mp++ = *mbp++;
02190                         *mp++ = *mbp++;
02191                         *mp++ = *mbp++;
02192                         *mp++ = *mbp++;
02193                         *mp++ = *mbp++;
02194                         *mp++ = *mbp++;
02195                         *mp++ = *mbp++;
02196                         *mp++ = *mbp++;
02197                         *mp++ = *mbp++;
02198                         *mp   = *mbp;
02199 
02200                         uint32* cp = (uint32*)color_line;
02201                         uint32* crp = (uint32*)(color_ram + vc);
02202 
02203                         ALIGN_CHECK(cp);
02204                         ALIGN_CHECK(crp);
02205 
02206                         *cp++ = *crp++;
02207                         *cp++ = *crp++;
02208                         *cp++ = *crp++;
02209                         *cp++ = *crp++;
02210                         *cp++ = *crp++;
02211                         *cp++ = *crp++;
02212                         *cp++ = *crp++;
02213                         *cp++ = *crp++;
02214                         *cp++ = *crp++;
02215                         *cp   = *crp;
02216 
02217 
02218 #else   // normal
02219 
02220                         uint32* mp = (uint32*)matrix_line;
02221                         uint32* cp = (uint32*)color_line;
02222                         int vc1 = vc;
02223                         uint32* mbp = (uint32*)(matrix_base + vc1);
02224                         uint32* crp = (uint32*)(color_ram + vc1);
02225                         for (int i=0; i<40/4; i++) {
02226                                 *mp++ = *mbp++;
02227                                 *cp++ = *crp++;
02228                         }
02229 
02230 #endif
02231 
02232 
02233                 
02234                 
02235                 }
02236 
02237                 // Handler upper/lower border
02238                 if (raster == dy_stop)
02239                         border_on = true;
02240                 if (raster == dy_start && (ctrl1 & 0x10)) // Don't turn off border if DEN bit cleared
02241                         border_on = false;
02242 
02243                 if (!border_on) {
02244                         // Display window contents
02245                         uint8 *p = chunky_ptr + COL40_XSTART;           // Pointer in chunky display buffer
02246 
02247 #if COLOR_DEPTH == 4    // modified here:
02248                         uint8 *r = fore_mask_buf + COL40_XSTART/4;      // Pointer in foreground mask buffer
02249 #elif COLOR_DEPTH == 8
02250                         uint8 *r = fore_mask_buf + COL40_XSTART/8;      // Pointer in foreground mask buffer
02251 #else
02252 error
02253 #endif                  
02254 
02255 
02256 #ifdef ALIGNMENT_CHECK
02257                         uint8 *use_p = ((((int)p) & 3) == 0) ? p : text_chunky_buf;
02258 #endif
02259 
02260                         //TODO: optimize gfx here, use memcpy or similar
02261                         
02262 #if COLOR_DEPTH == 4    // modified here:
02263                         {
02264                                 uint8 b0cc = b0c_color; // b0c_color is uint8
02265                                 int limit = x_scroll >> 1;      // half
02266                                 for (int i=0; i<limit; i++)     // Background on the left if XScroll>0
02267                                         *p++ = b0cc;
02268                                 if(x_scroll & 0x01)     // nibble align
02269                                         {
02270                                         *p = b0cc;                      // do not increase pointer
02271                                         nibble_next = true;
02272                                         }
02273 
02274                         }
02275 #elif COLOR_DEPTH == 8
02276                         {
02277                                 uint8 b0cc = b0c_color; // b0c_color is uint8
02278                                 int limit = x_scroll;
02279                                 for (int i=0; i<limit; i++)     // Background on the left if XScroll>0
02280                                         *p++ = b0cc;
02281                         }
02282 #else
02283 error
02284 #endif
02285 
02286                         if (display_state) {
02287                                 switch (display_idx) {
02288 
02289 //AEH 991211
02290                                         case 0: // Standard text
02291 #if COLOR_DEPTH == 4    
02292                                                 el_std_text(p, char_base + rc, r);
02293                                                 break;
02294 #elif COLOR_DEPTH == 8
02295                                                 if (x_scroll) {
02296                                                         el_std_text(text_chunky_buf, char_base + rc, r);
02297                                                         memcpy(p, text_chunky_buf, 8*40);                                               
02298                                                 } else
02299                                                         el_std_text(p, char_base + rc, r);
02300                                                 break;
02301 #else
02302 error
02303 #endif
02304 
02305 
02306                                         case 1: // Multicolor text
02307 #if COLOR_DEPTH == 4    
02308                                                 el_mc_text(p, char_base + rc, r);
02309                                                 break;
02310 #elif COLOR_DEPTH == 8
02311                                                 if (x_scroll) {
02312                                                         el_mc_text(text_chunky_buf, char_base + rc, r);
02313                                                         memcpy(p, text_chunky_buf, 8*40);                                               
02314                                                 } else
02315                                                         el_mc_text(p, char_base + rc, r);
02316                                                 break;
02317 #else
02318 error
02319 #endif
02320 
02321                                         case 2: // Standard bitmap
02322 #if COLOR_DEPTH == 4    
02323                                                 el_std_bitmap(p, bitmap_base + (vc << 3) + rc, r);
02324                                                 break;
02325 #elif COLOR_DEPTH == 8
02326                                                 if (x_scroll) {
02327                                                         el_std_bitmap(text_chunky_buf, bitmap_base + (vc << 3) + rc, r);
02328                                                         memcpy(p, text_chunky_buf, 8*40);                                               
02329                                                 } else
02330                                                         el_std_bitmap(p, bitmap_base + (vc << 3) + rc, r);
02331                                                 break;
02332 #else
02333 error
02334 #endif
02335 
02336                                         case 3: // Multicolor bitmap
02337 #if COLOR_DEPTH == 4    
02338                                                 el_mc_bitmap(p, bitmap_base + (vc << 3) + rc, r);
02339                                                 break;
02340 #elif COLOR_DEPTH == 8
02341                                                 if (x_scroll) {
02342                                                         el_mc_bitmap(text_chunky_buf, bitmap_base + (vc << 3) + rc, r);
02343                                                         memcpy(p, text_chunky_buf, 8*40);                                               
02344                                                 } else
02345                                                         el_mc_bitmap(p, bitmap_base + (vc << 3) + rc, r);
02346                                                 break;
02347 #else
02348 error
02349 #endif
02350 
02351                                         case 4: // ECM text
02352 #if COLOR_DEPTH == 4    
02353                                                 el_ecm_text(p, char_base + rc, r);
02354                                                 break;
02355 
02356 #elif COLOR_DEPTH == 8
02357                                                 if (x_scroll) {
02358                                                         el_ecm_text(text_chunky_buf, char_base + rc, r);
02359                                                         memcpy(p, text_chunky_buf, 8*40);                                               
02360                                                 } else
02361                                                         el_ecm_text(p, char_base + rc, r);
02362                                                 break;
02363 #else
02364 error
02365 #endif
02366 
02367                                         default:        // Invalid mode (all black)
02368                                                 memset(p, colors[0], 320);
02369                                                 memset(r, 0, 40);
02370                                                 break;
02371                                 }
02372                                 vc += 40;
02373 
02374                         } else {        // Idle state graphics
02375                                 switch (display_idx) {
02376 
02377                                         case 0:         // Standard text
02378                                         case 1:         // Multicolor text
02379                                         case 4:         // ECM text
02380                                                 
02381 #if COLOR_DEPTH == 4    
02382                                                 el_std_idle(p, r);
02383                                                 break;
02384 #elif COLOR_DEPTH == 8
02385                                                 if (x_scroll) {
02386                                                         el_std_idle(text_chunky_buf, r);
02387                                                         memcpy(p, text_chunky_buf, COL40_XSTOP-COL40_XSTART);   //working
02388                                                 } else
02389                                                         el_std_idle(p, r);
02390                                                 break;
02391 #else
02392 error
02393 #endif
02394 
02395                                         case 3:         // Multicolor bitmap
02396 #if COLOR_DEPTH == 4    
02397                                                 el_mc_idle(p, r);
02398                                                 break;
02399 #elif COLOR_DEPTH == 8
02400                                                 if (x_scroll) {
02401                                                         el_mc_idle(text_chunky_buf, r);
02402                                                         memcpy(p, text_chunky_buf, 8*40);                                               
02403                                                 } else
02404                                                         el_mc_idle(p, r);
02405                                                 break;
02406 #else
02407 error
02408 #endif
02409 
02410                                         default:        // Invalid mode (all black)
02411                                                 memset(p, colors[0], 320);
02412                                                 memset(r, 0, 40);
02413                                                 break;
02414                                 }
02415                         }
02416 
02417                         // Draw sprites
02418                         if (sprite_on && ThePrefs.SpritesOn) {
02419 
02420                                 // Clear sprite collision buffer
02421                                 uint32 *lp = (uint32 *)spr_coll_buf - 1;
02422 #if COLOR_DEPTH == 4    
02423                                 for (int i=0; i<DISPLAY_X/2; i++)       // half the size 
02424 #elif COLOR_DEPTH == 8
02425                                 for (int i=0; i<DISPLAY_X/4; i++)
02426 #endif
02427                                         *++lp = 0;
02428 
02429                                 el_sprites(chunky_ptr);
02430                         }
02431 
02432                         // Handle left border
02433 #ifdef BACKGND_UPDATE
02434                         if(ec_changed)
02435 #endif
02436                                 {
02437                                 uint32 *lp = (uint32 *)chunky_ptr;
02438 //                              uint32 c = ec_color_long;
02439                                 for (int i=0; i<COL40_XSTART/4; i++)
02440                                         *lp++ = ec_color_long;
02441                                 }
02442 
02443                         // Handle right border
02444 #ifdef BACKGND_UPDATE
02445                         if(ec_changed)
02446 #endif
02447                                 {
02448                                 uint32* lp = (uint32 *)(chunky_ptr + COL40_XSTOP) - 1;
02449                                 for (int i=0; i<(DISPLAY_X-COL40_XSTOP)/4; i++)
02450                                         *++lp = ec_color_long;
02451                                 }
02452 
02453 
02454 #ifdef BACKGND_UPDATE
02455                         if(ec_changed)
02456 #endif
02457                                 if (!border_40_col)
02458                                         { 
02459 //                                      c = ec_color;
02460                                         p = chunky_ptr + COL40_XSTART;
02461                         for (int i=0; i<COL38_XSTART-COL40_XSTART; i++)
02462                            *p++ = ec_color;
02463                                         p = chunky_ptr + COL38_XSTOP;
02464                         for (int j=0; j<COL40_XSTOP-COL38_XSTOP; j++)
02465                            *p++ = ec_color;
02466                                         }
02467 
02468                 } else {        //      if (!border_on)
02469 
02470                         // Display border
02471 #ifdef BACKGND_UPDATE
02472                         if(ec_changed)
02473 #endif
02474                         {
02475                         uint32 *lp = (uint32 *)chunky_ptr;
02476                         uint32 c = ec_color_long;
02477                         for (int i=0; i<DISPLAY_X/4; i++)
02478                                 *lp++ = c;
02479                         }
02480 
02481                 }
02482 
02483                 chunky_line_start += xmod;
02484 
02485                 if (rc == 7) {
02486                         display_state = false;
02487                         vc_base = vc;
02488                 } else
02489                         rc++;
02490 
02491 
02492                 if (raster >= FIRST_DMA_LINE-1 && raster <= LAST_DMA_LINE-1 && (((raster+1) & 7) == y_scroll) && bad_lines_enabled)
02493                         rc = 0;
02494         }
02495 
02496 VIC_nop:
02497         // Skip this if all sprites are off
02498         if (me | sprite_on)
02499                 cycles_left -= el_update_mc(raster);
02500 
02501         return cycles_left;
02502 }

Generated on Tue Feb 8 04:08:14 2005 for E32frodo by doxygen 1.3.3