Annotation of hatari/src/falcon/videl.c, revision 1.1.1.4

1.1       root        1: /*
                      2:   Hatari - videl.c
                      3: 
                      4:   This file is distributed under the GNU Public License, version 2 or at
                      5:   your option any later version. Read the file gpl.txt for details.
                      6: 
                      7:   Falcon Videl emulation. The Videl is the graphics shifter chip of the Falcon.
                      8:   It supports free programmable resolutions with 1, 2, 4, 8 or 16 bits per
                      9:   pixel.
                     10: 
                     11:   This file originally came from the Aranym project and has been heavily
                     12:   modified to work for Hatari (but the kudos for the great Videl emulation
                     13:   code goes to the people from the Aranym project of course).
                     14: */
1.1.1.4 ! root       15: const char VIDEL_fileid[] = "Hatari videl.c : " __DATE__ " " __TIME__;
1.1       root       16: 
                     17: #include "main.h"
                     18: #include "configuration.h"
                     19: #include "ioMem.h"
                     20: #include "hostscreen.h"
                     21: #include "screen.h"
                     22: #include "stMemory.h"
                     23: #include "video.h"
                     24: #include "videl.h"
                     25: #include <SDL_endian.h>
                     26: 
                     27: 
                     28: #define handleRead(a) IoMem_ReadByte(a)
                     29: #define handleReadW(a) IoMem_ReadWord(a)
                     30: #define Atari2HostAddr(a) (&STRam[a])
                     31: 
                     32: #define VIDEL_DEBUG 0
                     33: 
                     34: #if VIDEL_DEBUG
                     35: #define Dprintf(a) printf a
                     36: #else
                     37: #define Dprintf(a)
                     38: #endif
                     39: 
                     40: #define HW     0xff8200
                     41: #define VIDEL_COLOR_REGS_BEGIN 0xff9800
                     42: 
                     43: 
                     44: static int width, height, bpp, since_last_change;
1.1.1.2   root       45: static bool hostColorsSync;
1.1       root       46: 
                     47: /* Autozoom */
                     48: static int zoomwidth, prev_scrwidth;
                     49: static int zoomheight, prev_scrheight;
                     50: static int *zoomxtable;
                     51: static int *zoomytable;
                     52: 
                     53: static void VIDEL_renderScreenNoZoom(void);
                     54: static void VIDEL_renderScreenZoom(void);
                     55: 
                     56: 
                     57: // Called upon startup and when CPU encounters a RESET instruction.
                     58: void VIDEL_reset(void)
                     59: {
                     60:        since_last_change = 0;
                     61: 
1.1.1.4 ! root       62:        hostColorsSync = false;
1.1       root       63: 
                     64:        /* Autozoom */
                     65:        zoomwidth=prev_scrwidth=0;
                     66:        zoomheight=prev_scrheight=0;
                     67:        zoomxtable=NULL;
                     68:        zoomytable=NULL;
                     69: 
1.1.1.4 ! root       70:        /* Default resolution to boot with */
1.1       root       71:        width = 640;
                     72:        height = 480;
1.1.1.4 ! root       73:        HostScreen_setWindowSize(width, height, ConfigureParams.Screen.nForceBpp);
        !            74: 
        !            75:        /* Reset IO register (some are not initialized by TOS) */
        !            76:        IoMem_WriteWord(0xff820e, 0);    /* Line offset */
        !            77:        IoMem_WriteWord(0xff8264, 0);    /* Horizontal scroll */
1.1       root       78: }
                     79: 
                     80: // monitor write access to Falcon and ST/E color palette registers
                     81: void VIDEL_ColorRegsWrite(void)
                     82: {
1.1.1.4 ! root       83:        hostColorsSync = false;
1.1       root       84: }
                     85: 
                     86: void VIDEL_ShiftModeWriteWord(void)
                     87: {
                     88:        Dprintf(("VIDEL f_shift: %06x = 0x%x\n", IoAccessBaseAddress, handleReadW(HW+0x66)));
1.1.1.4 ! root       89:        bUseSTShifter = false;
1.1       root       90: }
                     91: 
                     92: static long VIDEL_getVideoramAddress(void)
                     93: {
                     94:        return (handleRead(HW + 1) << 16) | (handleRead(HW + 3) << 8) | handleRead(HW + 0x0d);
                     95: }
                     96: 
                     97: static int VIDEL_getScreenBpp(void)
                     98: {
                     99:        int f_shift = handleReadW(HW + 0x66);
                    100:        int st_shift = handleRead(HW + 0x60);
                    101:        /* to get bpp, we must examine f_shift and st_shift.
                    102:         * f_shift is valid if any of bits no. 10, 8 or 4
                    103:         * is set. Priority in f_shift is: 10 ">" 8 ">" 4, i.e.
                    104:         * if bit 10 set then bit 8 and bit 4 don't care...
                    105:         * If all these bits are 0 and ST shifter is written
                    106:         * after Falcon one, get display depth from st_shift
                    107:         * (as for ST and STE)
                    108:         */
                    109:        int bits_per_pixel;
                    110:        if (f_shift & 0x400)            /* Falcon: 2 colors */
                    111:                bits_per_pixel = 1;
                    112:        else if (f_shift & 0x100)       /* Falcon: hicolor */
                    113:                bits_per_pixel = 16;
                    114:        else if (f_shift & 0x010)       /* Falcon: 8 bitplanes */
                    115:                bits_per_pixel = 8;
                    116:        else if (!bUseSTShifter)        /* Falcon: 4 bitplanes */
                    117:                bits_per_pixel = 4;
                    118:        else if (st_shift == 0)
                    119:                bits_per_pixel = 4;
                    120:        else if (st_shift == 0x01)
                    121:                bits_per_pixel = 2;
                    122:        else /* if (st_shift == 0x02) */
                    123:                bits_per_pixel = 1;
                    124: 
                    125:        // Dprintf(("Videl works in %d bpp, f_shift=%04x, st_shift=%d", bits_per_pixel, f_shift, st_shift));
                    126: 
                    127:        return bits_per_pixel;
                    128: }
                    129: 
                    130: static int VIDEL_getScreenWidth(void)
                    131: {
1.1.1.4 ! root      132:        return (handleReadW(HW + 0x10) & 0x03ff) * 16 / VIDEL_getScreenBpp();
1.1       root      133: }
                    134: 
                    135: static int VIDEL_getScreenHeight(void)
                    136: {
1.1.1.4 ! root      137:        int vdb = handleReadW(HW + 0xa8) & 0x07ff;
        !           138:        int vde = handleReadW(HW + 0xaa) & 0x07ff;
1.1       root      139:        int vmode = handleReadW(HW + 0xc2);
                    140: 
                    141:        /* visible y resolution:
                    142:         * Graphics display starts at line VDB and ends at line
                    143:         * VDE. If interlace mode off unit of VC-registers is
                    144:         * half lines, else lines.
                    145:         */
                    146:        int yres = vde - vdb;
                    147:        if (!(vmode & 0x02))            // interlace
                    148:                yres >>= 1;
1.1.1.4 ! root      149:        if (vmode & 0x01)               // double
1.1       root      150:                yres >>= 1;
                    151: 
                    152:        return yres;
                    153: }
                    154: 
                    155: 
                    156: /** map the correct colortable into the correct pixel format
                    157:  */
                    158: static void VIDEL_updateColors(void)
                    159: {
                    160:        //Dprintf(("ColorUpdate in progress\n"));
                    161: 
                    162:        int i, r, g, b, colors = 1 << bpp;
                    163: 
                    164: #define F_COLORS(i) handleRead(VIDEL_COLOR_REGS_BEGIN + (i))
                    165: #define STE_COLORS(i)  handleRead(0xff8240 + (i))
                    166: 
                    167:        if (!bUseSTShifter) {
                    168:                for (i = 0; i < colors; i++) {
                    169:                        int offset = i << 2;
                    170:                        r = F_COLORS(offset) & 0xfc;
                    171:                        r |= r>>6;
                    172:                        g = F_COLORS(offset + 1) & 0xfc;
                    173:                        g |= g>>6;
                    174:                        b = F_COLORS(offset + 3) & 0xfc;
                    175:                        b |= b>>6;
                    176:                        HostScreen_setPaletteColor(i, r,g,b);
                    177:                }
                    178:                HostScreen_updatePalette(colors);
                    179:        } else {
                    180:                for (i = 0; i < colors; i++) {
                    181:                        int offset = i << 1;
                    182:                        r = STE_COLORS(offset) & 0x0f;
                    183:                        r = ((r & 7)<<1)|(r>>3);
                    184:                        r |= r<<4;
                    185:                        g = (STE_COLORS(offset + 1)>>4) & 0x0f;
                    186:                        g = ((g & 7)<<1)|(g>>3);
                    187:                        g |= g<<4;
                    188:                        b = STE_COLORS(offset + 1) & 0x0f;
                    189:                        b = ((b & 7)<<1)|(b>>3);
                    190:                        b |= b<<4;
                    191:                        HostScreen_setPaletteColor(i, r,g,b);
                    192:                }
                    193:                HostScreen_updatePalette(colors);
                    194:        }
                    195: 
1.1.1.4 ! root      196:        hostColorsSync = true;
1.1       root      197: }
                    198: 
                    199: 
                    200: void VIDEL_ZoomModeChanged(void)
                    201: {
                    202:        /* User selected another zoom mode, so set a new screen resolution now */
1.1.1.4 ! root      203:        HostScreen_setWindowSize(width, height, bpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp);
1.1       root      204: }
                    205: 
                    206: 
1.1.1.2   root      207: bool VIDEL_renderScreen(void)
1.1       root      208: {
                    209:        int vw   = VIDEL_getScreenWidth();
                    210:        int vh   = VIDEL_getScreenHeight();
                    211:        int vbpp = VIDEL_getScreenBpp();
                    212: 
                    213:        if (since_last_change > 2) {
                    214:                if (vw > 0 && vw != width) {
                    215:                        Dprintf(("CH width %d\n", width));
                    216:                        width = vw;
                    217:                        since_last_change = 0;
                    218:                }
                    219:                if (vh > 0 && vh != height) {
                    220:                        Dprintf(("CH height %d\n", width));
                    221:                        height = vh;
                    222:                        since_last_change = 0;
                    223:                }
                    224:                if (vbpp != bpp) {
                    225:                        Dprintf(("CH bpp %d\n", vbpp));
                    226:                        bpp = vbpp;
                    227:                        since_last_change = 0;
                    228:                }
                    229:        }
                    230:        if (since_last_change == 3) {
1.1.1.4 ! root      231:                HostScreen_setWindowSize(width, height, bpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp);
1.1       root      232:        }
                    233:        if (since_last_change < 4) {
                    234:                since_last_change++;
1.1.1.2   root      235:                return false;
1.1       root      236:        }
                    237: 
                    238:        if (!HostScreen_renderBegin())
1.1.1.2   root      239:                return false;
1.1       root      240: 
                    241:        if (ConfigureParams.Screen.bZoomLowRes) {
                    242:                VIDEL_renderScreenZoom();
                    243:        } else {
                    244:                VIDEL_renderScreenNoZoom();
                    245:        }
                    246: 
                    247:        HostScreen_renderEnd();
                    248: 
1.1.1.4 ! root      249:        HostScreen_update1(false);
1.1.1.2   root      250: 
                    251:        return true;
1.1       root      252: }
                    253: 
                    254: 
1.1.1.4 ! root      255: /**
        !           256:  * Performs conversion from the TOS's bitplane word order (big endian) data
        !           257:  * into the native chunky color index.
        !           258:  */
        !           259: static void Videl_bitplaneToChunky(Uint16 *atariBitplaneData, Uint16 bpp,
        !           260:                                    Uint8 colorValues[16])
        !           261: {
        !           262:        Uint32 a, b, c, d, x;
        !           263: 
        !           264:        /* Obviously the different cases can be broken out in various
        !           265:         * ways to lessen the amount of work needed for <8 bit modes.
        !           266:         * It's doubtful if the usage of those modes warrants it, though.
        !           267:         * The branches below should be ~100% correctly predicted and
        !           268:         * thus be more or less for free.
        !           269:         * Getting the palette values inline does not seem to help
        !           270:         * enough to worry about. The palette lookup is much slower than
        !           271:         * this code, though, so it would be nice to do something about it.
        !           272:         */
        !           273:        if (bpp >= 4) {
        !           274:                d = *(Uint32 *)&atariBitplaneData[0];
        !           275:                c = *(Uint32 *)&atariBitplaneData[2];
        !           276:                if (bpp == 4) {
        !           277:                        a = b = 0;
        !           278:                } else {
        !           279:                        b = *(Uint32 *)&atariBitplaneData[4];
        !           280:                        a = *(Uint32 *)&atariBitplaneData[6];
        !           281:                }
        !           282:        } else {
        !           283:                a = b = c = 0;
        !           284:                if (bpp == 2) {
        !           285:                        d = *(Uint32 *)&atariBitplaneData[0];
        !           286:                } else {
        !           287: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
        !           288:                        d = atariBitplaneData[0]<<16;
        !           289: #else
        !           290:                        d = atariBitplaneData[0];
        !           291: #endif
        !           292:                }
        !           293:        }
        !           294: 
        !           295:        x = a;
        !           296:        a =  (a & 0xf0f0f0f0)       | ((c & 0xf0f0f0f0) >> 4);
        !           297:        c = ((x & 0x0f0f0f0f) << 4) |  (c & 0x0f0f0f0f);
        !           298:        x = b;
        !           299:        b =  (b & 0xf0f0f0f0)       | ((d & 0xf0f0f0f0) >> 4);
        !           300:        d = ((x & 0x0f0f0f0f) << 4) |  (d & 0x0f0f0f0f);
        !           301: 
        !           302:        x = a;
        !           303:        a =  (a & 0xcccccccc)       | ((b & 0xcccccccc) >> 2);
        !           304:        b = ((x & 0x33333333) << 2) |  (b & 0x33333333);
        !           305:        x = c;
        !           306:        c =  (c & 0xcccccccc)       | ((d & 0xcccccccc) >> 2);
        !           307:        d = ((x & 0x33333333) << 2) |  (d & 0x33333333);
        !           308: 
        !           309: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
        !           310:        a = (a & 0x5555aaaa) | ((a & 0x00005555) << 17) | ((a & 0xaaaa0000) >> 17);
        !           311:        b = (b & 0x5555aaaa) | ((b & 0x00005555) << 17) | ((b & 0xaaaa0000) >> 17);
        !           312:        c = (c & 0x5555aaaa) | ((c & 0x00005555) << 17) | ((c & 0xaaaa0000) >> 17);
        !           313:        d = (d & 0x5555aaaa) | ((d & 0x00005555) << 17) | ((d & 0xaaaa0000) >> 17);
        !           314: 
        !           315:        colorValues[ 8] = a;
        !           316:        a >>= 8;
        !           317:        colorValues[ 0] = a;
        !           318:        a >>= 8;
        !           319:        colorValues[ 9] = a;
        !           320:        a >>= 8;
        !           321:        colorValues[ 1] = a;
        !           322: 
        !           323:        colorValues[10] = b;
        !           324:        b >>= 8;
        !           325:        colorValues[ 2] = b;
        !           326:        b >>= 8;
        !           327:        colorValues[11] = b;
        !           328:        b >>= 8;
        !           329:        colorValues[ 3] = b;
        !           330: 
        !           331:        colorValues[12] = c;
        !           332:        c >>= 8;
        !           333:        colorValues[ 4] = c;
        !           334:        c >>= 8;
        !           335:        colorValues[13] = c;
        !           336:        c >>= 8;
        !           337:        colorValues[ 5] = c;
        !           338: 
        !           339:        colorValues[14] = d;
        !           340:        d >>= 8;
        !           341:        colorValues[ 6] = d;
        !           342:        d >>= 8;
        !           343:        colorValues[15] = d;
        !           344:        d >>= 8;
        !           345:        colorValues[ 7] = d;
        !           346: #else
        !           347:        a = (a & 0xaaaa5555) | ((a & 0x0000aaaa) << 15) | ((a & 0x55550000) >> 15);
        !           348:        b = (b & 0xaaaa5555) | ((b & 0x0000aaaa) << 15) | ((b & 0x55550000) >> 15);
        !           349:        c = (c & 0xaaaa5555) | ((c & 0x0000aaaa) << 15) | ((c & 0x55550000) >> 15);
        !           350:        d = (d & 0xaaaa5555) | ((d & 0x0000aaaa) << 15) | ((d & 0x55550000) >> 15);
        !           351: 
        !           352:        colorValues[ 1] = a;
        !           353:        a >>= 8;
        !           354:        colorValues[ 9] = a;
        !           355:        a >>= 8;
        !           356:        colorValues[ 0] = a;
        !           357:        a >>= 8;
        !           358:        colorValues[ 8] = a;
        !           359: 
        !           360:        colorValues[ 3] = b;
        !           361:        b >>= 8;
        !           362:        colorValues[11] = b;
        !           363:        b >>= 8;
        !           364:        colorValues[ 2] = b;
        !           365:        b >>= 8;
        !           366:        colorValues[10] = b;
        !           367: 
        !           368:        colorValues[ 5] = c;
        !           369:        c >>= 8;
        !           370:        colorValues[13] = c;
        !           371:        c >>= 8;
        !           372:        colorValues[ 4] = c;
        !           373:        c >>= 8;
        !           374:        colorValues[12] = c;
        !           375: 
        !           376:        colorValues[ 7] = d;
        !           377:        d >>= 8;
        !           378:        colorValues[15] = d;
        !           379:        d >>= 8;
        !           380:        colorValues[ 6] = d;
        !           381:        d >>= 8;
        !           382:        colorValues[14] = d;
        !           383: #endif
        !           384: }
        !           385: 
        !           386: 
1.1       root      387: static void VIDEL_renderScreenNoZoom(void)
                    388: {
                    389:        int vw   = VIDEL_getScreenWidth();
                    390:        int vh   = VIDEL_getScreenHeight();
                    391: 
                    392:        int lineoffset = handleReadW(HW + 0x0e) & 0x01ff; // 9 bits
                    393:        int linewidth = handleReadW(HW + 0x10) & 0x03ff; // 10 bits
                    394:        /* 
                    395:           I think this implementation is naive: 
                    396:           indeed, I suspect that we should instead skip lineoffset
                    397:           words each time we have read "more" than linewidth words
                    398:           (possibly "more" because of the number of bit planes).
                    399:           Moreover, the 1 bit plane mode is particular;
                    400:           while doing some experiments on my Falcon, it seems to
                    401:           behave like the 4 bit planes mode.
                    402:           At last, we have also to take into account the 4 bits register
                    403:           located at the word $ffff8264 (bit offset). This register makes
                    404:           the semantics of the lineoffset register change a little.
                    405:           int bitoffset = handleReadW(HW + 0x64) & 0x000f;
                    406:           The meaning of this register in True Color mode is not clear
                    407:           for me at the moment (and my experiments on the Falcon don't help
                    408:           me).
                    409:        */
                    410:        int nextline = linewidth + lineoffset;
                    411: 
                    412:        if (bpp < 16 && !hostColorsSync) {
                    413:                VIDEL_updateColors();
                    414:        }
                    415: 
                    416:        VIDEL_ConvertScreenNoZoom(vw, vh, bpp, nextline);
                    417: }
                    418: 
                    419: 
                    420: void VIDEL_ConvertScreenNoZoom(int vw, int vh, int vbpp, int nextline)
                    421: {
                    422:        int scrpitch = HostScreen_getPitch();
                    423: 
                    424:        long atariVideoRAM = VIDEL_getVideoramAddress();
                    425: 
1.1.1.2   root      426:        Uint16 *fvram = (Uint16 *) Atari2HostAddr(atariVideoRAM);
                    427:        Uint8 *hvram = HostScreen_getVideoramAddress();
1.1       root      428: 
                    429:        int hscrolloffset = (handleRead(HW + 0x65) & 0x0f);
                    430: 
                    431:        /* Clip to SDL_Surface dimensions */
                    432:        int scrwidth = HostScreen_getWidth();
                    433:        int scrheight = HostScreen_getHeight();
                    434:        int vw_clip = vw;
                    435:        int vh_clip = vh;
                    436:        if (vw>scrwidth) vw_clip = scrwidth;
                    437:        if (vh>scrheight) vh_clip = scrheight;  
                    438: 
                    439:        /* Horizontal scroll register set? */
                    440:        if (hscrolloffset) {
                    441:                /* Yes, so we need to adjust offset to next line: */
                    442:                nextline += vbpp;
                    443:        }
                    444: 
                    445:        /* Center screen */
                    446:        hvram += ((scrheight-vh_clip)>>1)*scrpitch;
                    447:        hvram += ((scrwidth-vw_clip)>>1)*HostScreen_getBpp();
                    448: 
                    449:        /* Render */
                    450:        if (vbpp < 16) {
                    451:                /* Bitplanes modes */
                    452: 
                    453:                // The SDL colors blitting...
1.1.1.2   root      454:                Uint8 color[16];
1.1       root      455: 
                    456:                // FIXME: The byte swap could be done here by enrolling the loop into 2 each by 8 pixels
                    457:                switch ( HostScreen_getBpp() ) {
                    458:                        case 1:
                    459:                                {
1.1.1.2   root      460:                                        Uint16 *fvram_line = fvram;
                    461:                                        Uint8 *hvram_line = hvram;
1.1       root      462:                                        int h;
                    463: 
                    464:                                        for (h = 0; h < vh_clip; h++) {
1.1.1.2   root      465:                                                Uint16 *fvram_column = fvram_line;
                    466:                                                Uint8 *hvram_column = hvram_line;
1.1       root      467:                                                int w;
                    468: 
                    469:                                                /* First 16 pixels: */
1.1.1.4 ! root      470:                                                Videl_bitplaneToChunky(fvram_column, vbpp, color);
1.1       root      471:                                                memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
                    472:                                                hvram_column += 16-hscrolloffset;
                    473:                                                fvram_column += vbpp;
                    474:                                                /* Now the main part of the line: */
                    475:                                                for (w = 1; w < (vw_clip+15)>>4; w++) {
1.1.1.4 ! root      476:                                                        Videl_bitplaneToChunky( fvram_column, vbpp, color );
1.1       root      477:                                                        memcpy(hvram_column, color, 16);
                    478:                                                        hvram_column += 16;
                    479:                                                        fvram_column += vbpp;
                    480:                                                }
                    481:                                                /* Last pixels of the line for fine scrolling: */
                    482:                                                if (hscrolloffset) {
1.1.1.4 ! root      483:                                                        Videl_bitplaneToChunky(fvram_column, vbpp, color);
1.1       root      484:                                                        memcpy(hvram_column, color, hscrolloffset);
                    485:                                                }
                    486: 
                    487:                                                hvram_line += scrpitch;
                    488:                                                fvram_line += nextline;
                    489:                                        }
                    490:                                }
                    491:                                break;
                    492:                        case 2:
                    493:                                {
1.1.1.2   root      494:                                        Uint16 *fvram_line = fvram;
                    495:                                        Uint16 *hvram_line = (Uint16 *)hvram;
1.1       root      496:                                        int h;
                    497: 
                    498:                                        for (h = 0; h < vh_clip; h++) {
1.1.1.2   root      499:                                                Uint16 *fvram_column = fvram_line;
                    500:                                                Uint16 *hvram_column = hvram_line;
1.1.1.4 ! root      501:                                                int w, j;
1.1       root      502: 
1.1.1.4 ! root      503:                                                /* First 16 pixels: */
        !           504:                                                Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           505:                                                for (j = 0; j < 16 - hscrolloffset; j++) {
        !           506:                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !           507:                                                }
        !           508:                                                fvram_column += vbpp;
        !           509:                                                /* Now the main part of the line: */
        !           510:                                                for (w = 1; w < (vw_clip+15)>>4; w++) {
        !           511:                                                        Videl_bitplaneToChunky( fvram_column, vbpp, color );
1.1       root      512:                                                        for (j=0; j<16; j++) {
                    513:                                                                *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    514:                                                        }
                    515:                                                        fvram_column += vbpp;
                    516:                                                }
1.1.1.4 ! root      517:                                                /* Last pixels of the line for fine scrolling: */
        !           518:                                                if (hscrolloffset) {
        !           519:                                                        Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           520:                                                        for (j = 0; j < hscrolloffset; j++) {
        !           521:                                                                *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1       root      522:                                                        }
                    523:                                                }
                    524: 
1.1.1.4 ! root      525:                                                hvram_line += scrpitch>>1;
1.1       root      526:                                                fvram_line += nextline;
                    527:                                        }
                    528:                                }
                    529:                                break;
                    530:                        case 4:
                    531:                                {
1.1.1.2   root      532:                                        Uint16 *fvram_line = fvram;
                    533:                                        Uint32 *hvram_line = (Uint32 *)hvram;
1.1       root      534:                                        int h;
                    535: 
                    536:                                        for (h = 0; h < vh_clip; h++) {
1.1.1.2   root      537:                                                Uint16 *fvram_column = fvram_line;
                    538:                                                Uint32 *hvram_column = hvram_line;
1.1.1.4 ! root      539:                                                int w, j;
1.1       root      540: 
1.1.1.4 ! root      541:                                                /* First 16 pixels: */
        !           542:                                                Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           543:                                                for (j = 0; j < 16 - hscrolloffset; j++) {
        !           544:                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !           545:                                                }
        !           546:                                                fvram_column += vbpp;
        !           547:                                                /* Now the main part of the line: */
        !           548:                                                for (w = 1; w < (vw_clip+15)>>4; w++) {
        !           549:                                                        Videl_bitplaneToChunky( fvram_column, vbpp, color );
1.1       root      550:                                                        for (j=0; j<16; j++) {
                    551:                                                                *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    552:                                                        }
                    553:                                                        fvram_column += vbpp;
                    554:                                                }
1.1.1.4 ! root      555:                                                /* Last pixels of the line for fine scrolling: */
        !           556:                                                if (hscrolloffset) {
        !           557:                                                        Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           558:                                                        for (j = 0; j < hscrolloffset; j++) {
        !           559:                                                                *hvram_column++ = HostScreen_getPaletteColor(color[j]);
        !           560:                                                        }
        !           561:                                                }
1.1       root      562: 
                    563:                                                hvram_line += scrpitch>>2;
                    564:                                                fvram_line += nextline;
                    565:                                        }
                    566:                                }
                    567:                                break;
                    568:                }
                    569: 
                    570:        } else {
                    571: 
                    572:                // Falcon TC (High Color)
                    573:                switch ( HostScreen_getBpp() )  {
                    574:                        case 1:
                    575:                                {
                    576:                                        /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
1.1.1.2   root      577:                                        Uint16 *fvram_line = fvram;
                    578:                                        Uint8 *hvram_line = hvram;
1.1       root      579:                                        int h;
                    580: 
                    581:                                        for (h = 0; h < vh_clip; h++) {
1.1.1.2   root      582:                                                Uint16 *fvram_column = fvram_line;
                    583:                                                Uint8 *hvram_column = hvram_line;
1.1       root      584:                                                int w, tmp;
                    585: 
                    586:                                                for (w = 0; w < vw_clip; w++) {
                    587:                                                        
                    588:                                                        tmp = SDL_SwapBE16(*fvram_column);
                    589: 
                    590:                                                        *hvram_column = ((tmp>>13) & 7) << 5;
                    591:                                                        *hvram_column |= ((tmp>>8) & 7) << 2;
                    592:                                                        *hvram_column |= ((tmp>>2) & 3);
                    593: 
                    594:                                                        hvram_column++;
                    595:                                                        fvram_column++;
                    596:                                                }
                    597: 
                    598:                                                hvram_line += scrpitch;
                    599:                                                fvram_line += nextline;
                    600:                                        }
                    601:                                }
                    602:                                break;
                    603:                        case 2:
                    604:                                {
1.1.1.2   root      605:                                        Uint16 *fvram_line = fvram;
                    606:                                        Uint16 *hvram_line = (Uint16 *)hvram;
1.1       root      607:                                        int h;
                    608: 
                    609:                                        for (h = 0; h < vh_clip; h++) {
                    610: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                    611:                                                //FIXME: here might be a runtime little/big video endian switch like:
                    612:                                                //      if ( /* videocard memory in Motorola endian format */ false)
                    613:                                                memcpy(hvram_line, fvram_line, vw_clip<<1);
                    614: #else
                    615:                                                int w;
1.1.1.2   root      616:                                                Uint16 *fvram_column = fvram_line;
                    617:                                                Uint16 *hvram_column = hvram_line;
1.1       root      618: 
                    619:                                                for (w = 0; w < vw_clip; w++) {
                    620:                                                        // byteswap with SDL asm macros
                    621:                                                        *hvram_column++ = SDL_SwapBE16(*fvram_column++);
                    622:                                                }
                    623: #endif // SDL_BYTEORDER == SDL_BIG_ENDIAN
                    624: 
                    625:                                                hvram_line += scrpitch>>1;
                    626:                                                fvram_line += nextline;
                    627:                                        }
                    628:                                }
                    629:                                break;
                    630:                        case 4:
                    631:                                {
1.1.1.2   root      632:                                        Uint16 *fvram_line = fvram;
                    633:                                        Uint32 *hvram_line = (Uint32 *)hvram;
1.1       root      634:                                        int h;
                    635: 
                    636:                                        for (h = 0; h < vh_clip; h++) {
1.1.1.2   root      637:                                                Uint16 *fvram_column = fvram_line;
                    638:                                                Uint32 *hvram_column = hvram_line;
1.1       root      639:                                                int w;
                    640: 
                    641:                                                for (w = 0; w < vw_clip; w++) {
                    642:                                                        int data = *fvram_column++;
                    643: 
                    644:                                                        *hvram_column++ =
                    645:                                                                HostScreen_getColor(
1.1.1.2   root      646:                                                                        (Uint8) (data & 0xf8),
                    647:                                                                        (Uint8) ( ((data & 0x07) << 5) |
1.1       root      648:                                                                                          ((data >> 11) & 0x3c)),
1.1.1.2   root      649:                                                                        (Uint8) ((data >> 5) & 0xf8));
1.1       root      650:                                                }
                    651: 
                    652:                                                hvram_line += scrpitch>>2;
                    653:                                                fvram_line += nextline;
                    654:                                        }
                    655:                                }
                    656:                                break;
                    657:                }
                    658:        }
                    659: }
                    660: 
                    661: 
                    662: static void VIDEL_renderScreenZoom(void)
                    663: {
                    664:        /* Atari screen infos */
                    665:        int vw   = VIDEL_getScreenWidth();
                    666:        int vh   = VIDEL_getScreenHeight();
                    667: 
                    668:        int lineoffset = handleReadW(HW + 0x0e) & 0x01ff; // 9 bits
                    669:        int linewidth = handleReadW(HW + 0x10) & 0x03ff; // 10 bits
                    670:        /* same remark as before: too naive */
                    671:        int nextline = linewidth + lineoffset;
                    672: 
                    673:        if ((vw<32) || (vh<32))  return;
                    674: 
                    675:        if (bpp<16 && !hostColorsSync) {
                    676:                VIDEL_updateColors();
                    677:        }
                    678: 
                    679:        VIDEL_ConvertScreenZoom(vw, vh, bpp, nextline);
                    680: }
                    681: 
                    682: 
                    683: void VIDEL_ConvertScreenZoom(int vw, int vh, int vbpp, int nextline)
                    684: {
                    685:        int i, j, w, h, cursrcline;
                    686: 
1.1.1.2   root      687:        Uint16 *fvram = (Uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress());
1.1       root      688: 
                    689:        /* Host screen infos */
                    690:        int scrpitch = HostScreen_getPitch();
                    691:        int scrwidth = HostScreen_getWidth();
                    692:        int scrheight = HostScreen_getHeight();
                    693:        int scrbpp = HostScreen_getBpp();
1.1.1.2   root      694:        Uint8 *hvram = (Uint8 *) HostScreen_getVideoramAddress();
1.1       root      695: 
                    696:        int hscrolloffset = (handleRead(HW + 0x65) & 0x0f);
                    697: 
                    698:        /* Horizontal scroll register set? */
                    699:        if (hscrolloffset) {
                    700:                /* Yes, so we need to adjust offset to next line: */
                    701:                nextline += vbpp;
                    702:        }
                    703: 
                    704:        /* Integer zoom coef ? */
                    705:        if (/*(bx_options.autozoom.integercoefs) &&*/ (scrwidth>=vw) && (scrheight>=vh)) {
                    706:                int coefx = scrwidth/vw;
                    707:                int coefy = scrheight/vh;
                    708: 
                    709:                scrwidth = vw * coefx;
                    710:                scrheight = vh * coefy;
                    711: 
                    712:                /* Center screen */
                    713:                hvram += ((HostScreen_getHeight()-scrheight)>>1)*scrpitch;
                    714:                hvram += ((HostScreen_getWidth()-scrwidth)>>1)*scrbpp;
                    715:        }
                    716: 
                    717:        /* New zoom ? */
                    718:        if ((zoomwidth != vw) || (scrwidth != prev_scrwidth)) {
                    719:                if (zoomxtable) {
                    720:                        free(zoomxtable);
                    721:                }
                    722:                zoomxtable = malloc(sizeof(int)*scrwidth);
                    723:                for (i=0; i<scrwidth; i++) {
                    724:                        zoomxtable[i] = (vw*i)/scrwidth;
                    725:                }
                    726:                zoomwidth = vw;
                    727:                prev_scrwidth = scrwidth;
                    728:        }
                    729:        if ((zoomheight != vh) || (scrheight != prev_scrheight)) {
                    730:                if (zoomytable) {
                    731:                        free(zoomytable);
                    732:                }
                    733:                zoomytable = malloc(sizeof(int)*scrheight);
                    734:                for (i=0; i<scrheight; i++) {
                    735:                        zoomytable[i] = (vh*i)/scrheight;
                    736:                }
                    737:                zoomheight = vh;
                    738:                prev_scrheight = scrheight;
                    739:        }
                    740: 
                    741:        cursrcline = -1;
                    742: 
                    743:        if (vbpp<16) {
1.1.1.2   root      744:                Uint8 color[16];
1.1       root      745: 
                    746:                /* Bitplanes modes */
                    747:                switch(scrbpp) {
                    748:                        case 1:
                    749:                                {
                    750:                                        /* One complete planar 2 chunky line */
1.1.1.2   root      751:                                        Uint8 *p2cline = malloc(sizeof(Uint8)*vw);
1.1       root      752: 
1.1.1.2   root      753:                                        Uint16 *fvram_line;
                    754:                                        Uint8 *hvram_line = hvram;
1.1       root      755: 
                    756:                                        for (h = 0; h < scrheight; h++) {
                    757:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    758: 
                    759:                                                /* Recopy the same line ? */
                    760:                                                if (zoomytable[h] == cursrcline) {
                    761:                                                        memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
                    762:                                                } else {
1.1.1.2   root      763:                                                        Uint16 *fvram_column = fvram_line;
                    764:                                                        Uint8 *hvram_column = p2cline;
1.1       root      765: 
                    766:                                                        /* First 16 pixels of a new line */
1.1.1.4 ! root      767:                                                        Videl_bitplaneToChunky(fvram_column, vbpp, color);
1.1       root      768:                                                        memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
                    769:                                                        hvram_column += 16-hscrolloffset;
                    770:                                                        fvram_column += vbpp;
                    771:                                                        /* Convert main part of the new line */
                    772:                                                        for (w=1; w < (vw+15)>>4; w++) {
1.1.1.4 ! root      773:                                                                Videl_bitplaneToChunky( fvram_column, vbpp, color );
1.1       root      774:                                                                memcpy(hvram_column, color, 16);
                    775:                                                                hvram_column += 16;
                    776:                                                                fvram_column += vbpp;
                    777:                                                        }
                    778:                                                        /* Last pixels of the line for fine scrolling: */
                    779:                                                        if (hscrolloffset) {
1.1.1.4 ! root      780:                                                                Videl_bitplaneToChunky(fvram_column, vbpp, color);
1.1       root      781:                                                                memcpy(hvram_column, color, hscrolloffset);
                    782:                                                        }
                    783: 
                    784:                                                        /* Zoom a new line */
                    785:                                                        for (w=0; w<scrwidth; w++) {
                    786:                                                                hvram_line[w] = p2cline[zoomxtable[w]];
                    787:                                                        }
                    788:                                                }
                    789: 
                    790:                                                hvram_line += scrpitch;
                    791:                                                cursrcline = zoomytable[h];
                    792:                                        }
                    793: 
                    794:                                        free(p2cline);
                    795:                                }
                    796:                                break;
                    797:                        case 2:
                    798:                                {
                    799:                                        /* One complete planar 2 chunky line */
1.1.1.2   root      800:                                        Uint16 *p2cline = malloc(sizeof(Uint16)*vw);
1.1       root      801: 
1.1.1.2   root      802:                                        Uint16 *fvram_line = fvram;
                    803:                                        Uint16 *hvram_line = (Uint16 *)hvram;
1.1       root      804: 
                    805:                                        for (h = 0; h < scrheight; h++) {
                    806:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    807: 
                    808:                                                /* Recopy the same line ? */
                    809:                                                if (zoomytable[h] == cursrcline) {
                    810:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
                    811:                                                } else {
1.1.1.2   root      812:                                                        Uint16 *fvram_column = fvram_line;
                    813:                                                        Uint16 *hvram_column = p2cline;
1.1       root      814: 
1.1.1.4 ! root      815:                                                        /* First 16 pixels of a new line: */
        !           816:                                                        Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           817:                                                        for (j = 0; j < 16 - hscrolloffset; j++) {
        !           818:                                                                *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !           819:                                                        }
        !           820:                                                        fvram_column += vbpp;
        !           821:                                                        /* Convert the main part of the new line: */
        !           822:                                                        for (w = 1; w < (vw+15)>>4; w++) {
        !           823:                                                                Videl_bitplaneToChunky( fvram_column, vbpp, color );
1.1       root      824:                                                                for (j=0; j<16; j++) {
                    825:                                                                        *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    826:                                                                }
                    827:                                                                fvram_column += vbpp;
                    828:                                                        }
1.1.1.4 ! root      829:                                                        /* Last pixels of the new line for fine scrolling: */
        !           830:                                                        if (hscrolloffset) {
        !           831:                                                                Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           832:                                                                for (j = 0; j < hscrolloffset; j++) {
        !           833:                                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1       root      834:                                                                }
                    835:                                                        }
1.1.1.4 ! root      836: 
1.1       root      837:                                                        /* Zoom a new line */
                    838:                                                        for (w=0; w<scrwidth; w++) {
1.1.1.4 ! root      839:                                                                hvram_line[w] = p2cline[zoomxtable[w]];
1.1       root      840:                                                        }
                    841:                                                }
                    842: 
1.1.1.4 ! root      843:                                                hvram_line += scrpitch>>1;
1.1       root      844:                                                cursrcline = zoomytable[h];
                    845:                                        }
                    846: 
                    847:                                        free(p2cline);
                    848:                                }
                    849:                                break;
                    850:                        case 4:
                    851:                                {
                    852:                                        /* One complete planar 2 chunky line */
1.1.1.2   root      853:                                        Uint32 *p2cline = malloc(sizeof(Uint32)*vw);
1.1       root      854: 
1.1.1.2   root      855:                                        Uint16 *fvram_line;
                    856:                                        Uint32 *hvram_line = (Uint32 *)hvram;
1.1       root      857: 
                    858:                                        for (h = 0; h < scrheight; h++) {
                    859:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    860: 
                    861:                                                /* Recopy the same line ? */
                    862:                                                if (zoomytable[h] == cursrcline) {
                    863:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
                    864:                                                } else {
1.1.1.2   root      865:                                                        Uint16 *fvram_column = fvram_line;
                    866:                                                        Uint32 *hvram_column = p2cline;
1.1       root      867: 
1.1.1.4 ! root      868:                                                        /* First 16 pixels of a new line: */
        !           869:                                                        Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           870:                                                        for (j = 0; j < 16 - hscrolloffset; j++) {
        !           871:                                                                *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !           872:                                                        }
        !           873:                                                        fvram_column += vbpp;
        !           874:                                                        /* Convert the main part of the new line: */
        !           875:                                                        for (w = 1; w < (vw+15)>>4; w++) {
        !           876:                                                                Videl_bitplaneToChunky( fvram_column, vbpp, color );
1.1       root      877:                                                                for (j=0; j<16; j++) {
                    878:                                                                        *hvram_column++ = HostScreen_getPaletteColor( color[j] );
                    879:                                                                }
                    880:                                                                fvram_column += vbpp;
                    881:                                                        }
1.1.1.4 ! root      882:                                                        /* Last pixels of the new line for fine scrolling: */
        !           883:                                                        if (hscrolloffset) {
        !           884:                                                                Videl_bitplaneToChunky(fvram_column, vbpp, color);
        !           885:                                                                for (j = 0; j < hscrolloffset; j++) {
        !           886:                                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j]);
        !           887:                                                                }
        !           888:                                                        }
        !           889: 
1.1       root      890:                                                        /* Zoom a new line */
                    891:                                                        for (w=0; w<scrwidth; w++) {
                    892:                                                                hvram_line[w] = p2cline[zoomxtable[w]];
                    893:                                                        }
                    894:                                                }
                    895: 
                    896:                                                hvram_line += scrpitch>>2;
                    897:                                                cursrcline = zoomytable[h];
                    898:                                        }
                    899: 
                    900:                                        free(p2cline);
                    901:                                }
                    902:                                break;
                    903:                }
                    904:        } else {
1.1.1.4 ! root      905:                /* Falcon high-color (16-bit) mode */
1.1       root      906: 
                    907:                switch(scrbpp) {
                    908:                        case 1:
                    909:                                {
                    910:                                        /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
1.1.1.2   root      911:                                        Uint16 *fvram_line;
                    912:                                        Uint8 *hvram_line = hvram;
1.1       root      913: 
                    914:                                        for (h = 0; h < scrheight; h++) {
1.1.1.2   root      915:                                                Uint16 *fvram_column;
                    916:                                                Uint8 *hvram_column;
1.1       root      917: 
                    918:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    919:                                                fvram_column = fvram_line;
                    920:                                                hvram_column = hvram_line;
                    921: 
                    922:                                                /* Recopy the same line ? */
                    923:                                                if (zoomytable[h] == cursrcline) {
                    924:                                                        memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
                    925:                                                } else {
                    926:                                                        for (w = 0; w < scrwidth; w++) {
1.1.1.2   root      927:                                                                Uint16 srcword;
                    928:                                                                Uint8 dstbyte;
1.1       root      929:                                                        
                    930:                                                                srcword = SDL_SwapBE16(fvram_column[zoomxtable[w]]);
                    931: 
                    932:                                                                dstbyte = ((srcword>>13) & 7) << 5;
                    933:                                                                dstbyte |= ((srcword>>8) & 7) << 2;
                    934:                                                                dstbyte |= ((srcword>>2) & 3);
                    935: 
                    936:                                                                *hvram_column++ = dstbyte;
                    937:                                                        }
                    938:                                                }
                    939: 
                    940:                                                hvram_line += scrpitch;
                    941:                                                cursrcline = zoomytable[h];
                    942:                                        }
                    943:                                }
                    944:                                break;
                    945:                        case 2:
                    946:                                {
1.1.1.2   root      947:                                        Uint16 *fvram_line;
                    948:                                        Uint16 *hvram_line = (Uint16 *)hvram;
1.1       root      949: 
                    950:                                        for (h = 0; h < scrheight; h++) {
1.1.1.2   root      951:                                                Uint16 *fvram_column;
                    952:                                                Uint16 *hvram_column;
1.1       root      953: 
                    954:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    955:                                                fvram_column = fvram_line;
                    956:                                                hvram_column = hvram_line;
                    957: 
                    958:                                                /* Recopy the same line ? */
                    959:                                                if (zoomytable[h] == cursrcline) {
                    960:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
                    961:                                                } else {
                    962:                                                        for (w = 0; w < scrwidth; w++) {
1.1.1.2   root      963:                                                                Uint16 srcword;
1.1       root      964:                                                        
                    965:                                                                srcword = SDL_SwapBE16(fvram_column[zoomxtable[w]]);
                    966:                                                                *hvram_column++ = srcword;
                    967:                                                        }
                    968:                                                }
                    969: 
                    970:                                                hvram_line += scrpitch>>1;
                    971:                                                cursrcline = zoomytable[h];
                    972:                                        }
                    973:                                }
                    974:                                break;
                    975:                        case 4:
                    976:                                {
1.1.1.2   root      977:                                        Uint16 *fvram_line;
                    978:                                        Uint32 *hvram_line = (Uint32 *)hvram;
1.1       root      979: 
                    980:                                        for (h = 0; h < scrheight; h++) {
1.1.1.2   root      981:                                                Uint16 *fvram_column;
                    982:                                                Uint32 *hvram_column;
1.1       root      983: 
                    984:                                                fvram_line = fvram + (zoomytable[h] * nextline);
                    985:                                                fvram_column = fvram_line;
                    986:                                                hvram_column = hvram_line;
                    987: 
                    988:                                                /* Recopy the same line ? */
                    989:                                                if (zoomytable[h] == cursrcline) {
                    990:                                                        memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
                    991:                                                } else {
                    992:                                                        for (w = 0; w < scrwidth; w++) {
1.1.1.2   root      993:                                                                Uint16 srcword;
1.1       root      994:                                                        
                    995:                                                                srcword = fvram_column[zoomxtable[w]];
                    996: 
                    997:                                                                *hvram_column++ =
                    998:                                                                        HostScreen_getColor(
1.1.1.2   root      999:                                                                                (Uint8) (srcword & 0xf8),
                   1000:                                                                                (Uint8) ( ((srcword & 0x07) << 5) |
1.1       root     1001:                                                                                          ((srcword >> 11) & 0x3c)),
1.1.1.2   root     1002:                                                                                (Uint8) ((srcword >> 5) & 0xf8));
1.1       root     1003:                                                        }
                   1004:                                                }
                   1005: 
                   1006:                                                hvram_line += scrpitch>>2;
                   1007:                                                cursrcline = zoomytable[h];
                   1008:                                        }
                   1009:                                }
                   1010:                                break;
                   1011:                }
                   1012:        }
                   1013: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.