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

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

unix.superglobalmegacorp.com

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