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

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).
1.1.1.6   root       14: 
                     15:   Videl can run at 2 frequencies : 25.175 Mhz or 32 MHz
                     16:   
                     17:   Hardware I/O registers:
                     18: 
                     19:        $FFFF8006 (byte) : monitor type
                     20: 
                     21:        $FFFF8201 (byte) : VDL_VBH - Video Base Hi
                     22:        $FFFF8203 (byte) : VDL_VBM - Video Base Mi
                     23:        $FFFF8205 (byte) : VDL_VCH - Video Count Hi
                     24:        $FFFF8207 (byte) : VDL_VCM - Video Count Mi
                     25:        $FFFF8209 (byte) : VDL_VCL - Video Count Lo
                     26:        $FFFF820A (byte) : VDL_SYM - Sync mode
                     27:        $FFFF820D (byte) : VDL_VBL - Video Base Lo
                     28:        $FFFF820E (word) : VDL_LOF - Offset to next line
                     29:        $FFFF8210 (word) : VDL_LWD - Line Wide in Words
                     30:        
                     31:        $FFFF8240 (word) : VDL_STC - ST Palette Register 00
                     32:        .........
                     33:        $FFFF825E (word) : VDL_STC - ST Palette Register 15
                     34: 
                     35:        $FFFF8260 (byte) : ST shift mode
1.1.1.8 ! root       36:        $FFFF8264 (byte) : Horizontal scroll register shadow register
1.1.1.6   root       37:        $FFFF8265 (byte) : Horizontal scroll register
                     38:        $FFFF8266 (word) : Falcon shift mode
                     39:        
                     40:        $FFFF8280 (word) : HHC - Horizontal Hold Counter
                     41:        $FFFF8282 (word) : HHT - Horizontal Hold Timer
                     42:        $FFFF8284 (word) : HBB - Horizontal Border Begin
                     43:        $FFFF8286 (word) : HBE - Horizontal Border End
                     44:        $FFFF8288 (word) : HDB - Horizontal Display Begin
                     45:        $FFFF828A (word) : HDE - Horizontal Display End
                     46:        $FFFF828C (word) : HSS - Horizontal SS
                     47:        $FFFF828E (word) : HFS - Horizontal FS
                     48:        $FFFF8290 (word) : HEE - Horizontal EE
                     49:        
                     50:        $FFFF82A0 (word) : VFC - Vertical Frequency Counter
                     51:        $FFFF82A2 (word) : VFT - Vertical Frequency Timer
                     52:        $FFFF82A4 (word) : VBB - Vertical Border Begin
                     53:        $FFFF82A6 (word) : VBE - Vertical Border End
                     54:        $FFFF82A8 (word) : VDB - Vertical Display Begin
                     55:        $FFFF82AA (word) : VDE - Vertical Display End
                     56:        $FFFF82AC (word) : VSS - Vertical SS
                     57:        
                     58:        $FFFF82C0 (word) : VCO - Video control
                     59:        $FFFF82C2 (word) : VMD - Video mode
                     60: 
                     61:        $FFFF9800 (long) : VDL_PAL - Videl palette Register 000
                     62:        ...........
                     63:        $FFFF98FC (long) : VDL_PAL - Videl palette Register 255
1.1       root       64: */
1.1.1.6   root       65: 
1.1.1.4   root       66: const char VIDEL_fileid[] = "Hatari videl.c : " __DATE__ " " __TIME__;
1.1       root       67: 
1.1.1.6   root       68: #include <SDL_endian.h>
                     69: #include <SDL.h>
1.1       root       70: #include "main.h"
                     71: #include "configuration.h"
1.1.1.6   root       72: #include "memorySnapShot.h"
1.1       root       73: #include "ioMem.h"
1.1.1.6   root       74: #include "log.h"
1.1       root       75: #include "hostscreen.h"
                     76: #include "screen.h"
                     77: #include "stMemory.h"
                     78: #include "videl.h"
                     79: 
                     80: 
                     81: #define Atari2HostAddr(a) (&STRam[a])
                     82: #define VIDEL_COLOR_REGS_BEGIN 0xff9800
                     83: 
1.1.1.8 ! root       84: 
1.1.1.6   root       85: struct videl_s {
                     86:        bool   bUseSTShifter;                   /* whether to use ST or Falcon palette */
                     87:        Uint8  reg_ffff8006_save;               /* save reg_ffff8006 as it's a read only register */
                     88:        Uint8  monitor_type;                    /* 00 Monochrome (SM124) / 01 Color (SC1224) / 10 VGA Color / 11 Television ($FFFF8006) */
1.1.1.8 ! root       89:        Uint32 videoBaseAddr;                   /* Video base address, refreshed after each VBL */
1.1.1.6   root       90: 
1.1.1.8 ! root       91:        Sint16 leftBorderSize;                  /* Size of the left border */
        !            92:        Sint16 rightBorderSize;                 /* Size of the right border */
        !            93:        Sint16 upperBorderSize;                 /* Size of the upper border */
        !            94:        Sint16 lowerBorderSize;                 /* Size of the lower border */
        !            95:        Uint16 XSize;                           /* X size of the graphical area */
        !            96:        Uint16 YSize;                           /* Y size of the graphical area */
        !            97: 
        !            98:        Uint16 save_scrWidth;                   /* save screen width to detect a change of X resolution */
        !            99:        Uint16 save_scrHeight;                  /* save screen height to detect a change of Y resolution */
        !           100:        Uint16 save_scrBpp;                     /* save screen Bpp to detect a change of bitplan mode */
1.1       root      101: 
1.1.1.8 ! root      102:        bool hostColorsSync;                    /* Sync palette with host's */
        !           103: };
1.1.1.6   root      104: 
1.1.1.8 ! root      105: struct videl_zoom_s {
        !           106:        Uint16 zoomwidth;
        !           107:        Uint16 prev_scrwidth;
        !           108:        Uint16 zoomheight;
        !           109:        Uint16 prev_scrheight;
        !           110:        int *zoomxtable;
        !           111:        int *zoomytable;
        !           112: };
1.1       root      113: 
1.1.1.8 ! root      114: static struct videl_s videl;
        !           115: static struct videl_zoom_s videl_zoom;
1.1.1.6   root      116: 
1.1.1.8 ! root      117: Uint16 vfc_counter;                    /* counter for VFC register $ff82a0 (to be internalized when VIDEL emulation is complete) */
1.1.1.6   root      118: 
1.1.1.8 ! root      119: static void VIDEL_memset_uint32(Uint32 *addr, Uint32 color, int count);
        !           120: static void VIDEL_memset_uint16(Uint16 *addr, Uint16 color, int count);
        !           121: static void VIDEL_memset_uint8(Uint8 *addr, Uint8 color, int count);
1.1       root      122: 
1.1.1.8 ! root      123: /**
        !           124:  *  Called upon startup and when CPU encounters a RESET instruction.
        !           125:  */
1.1       root      126: void VIDEL_reset(void)
                    127: {
1.1.1.6   root      128:        videl.bUseSTShifter = false;                            /* Use Falcon color palette by default */
                    129:        videl.reg_ffff8006_save = IoMem_ReadByte(0xff8006);
1.1.1.8 ! root      130:        videl.monitor_type = videl.reg_ffff8006_save & 0xc0;
1.1.1.6   root      131:        
1.1.1.8 ! root      132:        videl.hostColorsSync = false; 
1.1       root      133: 
1.1.1.6   root      134:        vfc_counter = 0;
                    135:        
1.1       root      136:        /* Autozoom */
1.1.1.8 ! root      137:        videl_zoom.zoomwidth = 0;
        !           138:        videl_zoom.prev_scrwidth = 0;
        !           139:        videl_zoom.zoomheight = 0;
        !           140:        videl_zoom.prev_scrheight = 0;
        !           141:        videl_zoom.zoomxtable = NULL;
        !           142:        videl_zoom.zoomytable = NULL;
1.1       root      143: 
1.1.1.4   root      144:        /* Default resolution to boot with */
1.1.1.8 ! root      145:        videl.save_scrWidth = 640;
        !           146:        videl.save_scrHeight = 480;
        !           147:        videl.save_scrBpp = ConfigureParams.Screen.nForceBpp;
        !           148:        HostScreen_setWindowSize(videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp);
1.1.1.4   root      149: 
                    150:        /* Reset IO register (some are not initialized by TOS) */
                    151:        IoMem_WriteWord(0xff820e, 0);    /* Line offset */
                    152:        IoMem_WriteWord(0xff8264, 0);    /* Horizontal scroll */
1.1.1.8 ! root      153: 
        !           154:        /* Init synch mode register */
        !           155:         VIDEL_SyncMode_WriteByte();
1.1       root      156: }
                    157: 
1.1.1.6   root      158: /**
                    159:  * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
                    160:  */
                    161: void VIDEL_MemorySnapShot_Capture(bool bSave)
                    162: {
                    163:        /* Save/Restore details */
                    164:        MemorySnapShot_Store(&videl, sizeof(videl));
1.1.1.8 ! root      165:        MemorySnapShot_Store(&videl_zoom, sizeof(videl_zoom));
1.1.1.6   root      166:        MemorySnapShot_Store(&vfc_counter, sizeof(vfc_counter));
                    167: }
                    168: 
                    169: /**
                    170:  * Monitor write access to ST/E color palette registers
                    171:  */
1.1       root      172: void VIDEL_ColorRegsWrite(void)
                    173: {
1.1.1.8 ! root      174:        videl.hostColorsSync = false;
1.1       root      175: }
                    176: 
1.1.1.6   root      177: /**
                    178:  * VIDEL_Monitor_WriteByte : Contains memory and monitor configuration. 
1.1.1.8 ! root      179:  *                           This register is read only.
1.1.1.6   root      180:  */
                    181: void VIDEL_Monitor_WriteByte(void)
                    182: {
1.1.1.8 ! root      183:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8006 Monitor and memory conf write (Read only)\n");
1.1.1.6   root      184:        /* Restore hardware value */
1.1.1.8 ! root      185: 
1.1.1.6   root      186:        IoMem_WriteByte(0xff8006, videl.reg_ffff8006_save);
                    187: }
                    188: 
                    189: /**
1.1.1.8 ! root      190:  * VIDEL_SyncMode_WriteByte : Videl synchronization mode. 
        !           191:  *             $FFFF820A [R/W] _______0  .................................. SYNC-MODE
        !           192:                                      ||
        !           193:                                      |+--Synchronisation [ 0:internal / 1:external ]
        !           194:                                      +---Vertical frequency [ Read-only bit ]
        !           195:                                          [ Monochrome monitor:0 / Colour monitor:1 ]
        !           196:  */
        !           197: void VIDEL_SyncMode_WriteByte(void)
        !           198: {
        !           199:        Uint8 syncMode = IoMem_ReadByte(0xff820a);
        !           200:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff820a Sync Mode write: 0x%02x\n", syncMode);
        !           201: 
        !           202:        if (videl.monitor_type == FALCON_MONITOR_MONO)
        !           203:                syncMode &= 0xfd;
        !           204:        else
        !           205:                syncMode |= 0x2;
        !           206:        
        !           207:        IoMem_WriteByte(0xff820a, syncMode);
        !           208: }
        !           209: 
        !           210: /**
        !           211:  * Read video address counter and update ff8205/07/09
        !           212:  */
        !           213: void VIDEL_ScreenCounter_ReadByte(void)
        !           214: {
        !           215: //     Uint32 addr;    // To be used
        !           216:        Uint32 addr = 0; // To be removed
        !           217: 
        !           218:        // addr = Videl_CalculateAddress();             /* TODO: get current video address */
        !           219:        IoMem[0xff8205] = ( addr >> 16 ) & 0xff;
        !           220:        IoMem[0xff8207] = ( addr >> 8 ) & 0xff;
        !           221:        IoMem[0xff8209] = addr & 0xff;
        !           222: 
        !           223:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8205/07/09 Sync Mode read: 0x%08x\n", addr);
        !           224: }
        !           225: 
        !           226: /**
        !           227:  * Write video address counter
        !           228:  */
        !           229: void VIDEL_ScreenCounter_WriteByte(void)
        !           230: {
        !           231:        Uint32 addr_new = 0;
        !           232:        Uint8 AddrByte;
        !           233: 
        !           234:        AddrByte = IoMem[ IoAccessCurrentAddress ];
        !           235: 
        !           236:        /* Compute the new video address with one modified byte */
        !           237:        if ( IoAccessCurrentAddress == 0xff8205 )
        !           238:                addr_new = ( addr_new & 0x00ffff ) | ( AddrByte << 16 );
        !           239:        else if ( IoAccessCurrentAddress == 0xff8207 )
        !           240:                addr_new = ( addr_new & 0xff00ff ) | ( AddrByte << 8 );
        !           241:        else if ( IoAccessCurrentAddress == 0xff8209 )
        !           242:                addr_new = ( addr_new & 0xffff00 ) | ( AddrByte );
        !           243: 
        !           244:        // TODO: save the value in a table for the final rendering 
        !           245: }
        !           246: 
        !           247: /**
        !           248:  * VIDEL_LineOffset_WriteWord: $FFFF820E [R/W] W _______876543210  Line Offset
        !           249:  * How many words are added to the end of display line, i.e. how many words are
        !           250:  * 'behind' the display.
        !           251:  */
        !           252: void VIDEL_LineOffset_WriteWord(void)
        !           253: {
        !           254:        Uint16 lineOffset = IoMem_ReadWord(0xff820e);
        !           255: 
        !           256:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff820e Line Offset write: 0x%04x\n", lineOffset);
        !           257: }
        !           258: 
        !           259: /**
        !           260:  * VIDEL_Line_Width_WriteWord: $FFFF8210 [R/W] W ______9876543210 Line Width (VWRAP)
        !           261:  * Length of display line in words.Or, how many words should be added to
        !           262:  * vram counter after every display line.
        !           263:  */
        !           264: void VIDEL_Line_Width_WriteWord(void)
        !           265: {
        !           266:        Uint16 lineWidth = IoMem_ReadWord(0xff8210);
        !           267: 
        !           268:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8210 Line Width write: 0x%04x\n", lineWidth);
        !           269: }
        !           270: 
        !           271: /**
1.1.1.6   root      272:  * Write to video address base high, med and low register (0xff8201/03/0d).
                    273:  * On Falcon, when a program writes to high or med registers, base low register
                    274:  * is reset to zero.
                    275:  */
                    276: void VIDEL_ScreenBase_WriteByte(void)
                    277: {
                    278:        Uint32 screenBase;
                    279:        
                    280:        if ((IoAccessCurrentAddress == 0xff8201) || (IoAccessCurrentAddress == 0xff8203)) {
                    281:                /* Reset screen base low register */
                    282:                IoMem[0xff820d] = 0;
                    283:        }
                    284:        
                    285:        screenBase = (IoMem[0xff8201]<<16)+(IoMem[0xff8203]<<8)+IoMem[0xff820d];
                    286: 
1.1.1.8 ! root      287:        LOG_TRACE(TRACE_VIDEL, "Videl : $%04x Screen base write: 0x%02x\t (screen: 0x%04x)\n", 
1.1.1.6   root      288:                                                IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress], screenBase);
                    289: }
                    290: 
                    291: /**
                    292:     VIDEL_ST_ShiftModeWriteByte : 
                    293:        $FFFF8260 [R/W] B  ______10  ST Shift Mode
                    294:                                 ||
                    295:                                 ||                           others   vga
                    296:                                 ||                  $FF8210 $FF82C2 $FF82C2
                    297:                                 00--4BP/320 Pixels=> $0050   $0000   $0005
                    298:                                 01--2BP/640 Pixels=> $0050   $0004   $0009
                    299:                                 10--1BP/640 Pixels=> $0028   $0006   $0008
                    300:                                 11--???/320 Pixels=> $0050   $0000   $0000
                    301: 
                    302:        Writing to this register does the following things:
                    303:                - activate STE palette
                    304:                - sets line width ($ffff8210)
                    305:                - sets video mode in $ffff82c2 (double lines/interlace & cycles/pixel)
                    306:  */
                    307: void VIDEL_ST_ShiftModeWriteByte(void)
                    308: {
                    309:        Uint16 line_width, video_mode;
                    310:        Uint8 st_shiftMode;
                    311: 
                    312:        st_shiftMode = IoMem_ReadByte(0xff8260);
1.1.1.8 ! root      313:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8260 ST Shift Mode (STSHIFT) write: 0x%02x\n", st_shiftMode);
        !           314: 
        !           315:        /* Bits 2-7 are set to 0 */
        !           316:        IoMem_WriteByte(0xff8260, st_shiftMode & 3); 
1.1.1.6   root      317: 
                    318:        /* Activate STE palette */
                    319:        videl.bUseSTShifter = true;
                    320: 
                    321:        /*  Compute line width and video mode */
                    322:        switch (st_shiftMode & 0x3) {
                    323:                case 0: /* 4BP/320 Pixels */
                    324:                        line_width = 0x50;
                    325:                        /* half pixels + double lines vs. no scaling */
                    326:                        video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x5 : 0x0;
                    327:                        break;
                    328:                case 1: /* 2BP/640 Pixels */
                    329:                        line_width = 0x50;
                    330:                        /* quarter pixels + double lines vs. half pixels */
                    331:                        video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x9 : 0x4;
                    332:                        break;
                    333:                case 2: /* 1BP/640 Pixels */
                    334:                        line_width = 0x28;
                    335:                        if (videl.monitor_type == FALCON_MONITOR_MONO) {
                    336:                                video_mode = 0x0;
                    337:                                break;
                    338:                        }
                    339:                        /* quarter pixels vs. half pixels + interlace */
                    340:                        video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x8 : 0x6;
                    341:                        break;
                    342:                case 3: /* ???/320 Pixels */
1.1.1.8 ! root      343:                default:
1.1.1.6   root      344:                        line_width = 0x50;
                    345:                        video_mode = 0x0;
                    346:                        break;
                    347:        }
                    348: 
                    349:        /* Set line width ($FFFF8210) */
                    350:        IoMem_WriteWord(0xff8210, line_width); 
                    351:        
                    352:        /* Set video mode ($FFFF82C2) */
                    353:        IoMem_WriteWord(0xff82c2, video_mode); 
                    354: }
                    355: 
                    356: /**
1.1.1.8 ! root      357:     VIDEL_HorScroll64_WriteByte : Horizontal scroll register (0-15)
        !           358:                $FFFF8264 [R/W] ________  ................................ H-SCROLL HI
        !           359:                                    ||||  [ Shadow register for $FFFF8265 ]
        !           360:                                    ++++--Pixel shift [ 0:normal / 1..15:Left shift ]
        !           361:                                        [ Change in line-width NOT required ]
        !           362:  */
        !           363: void VIDEL_HorScroll64_WriteByte(void)
        !           364: {
        !           365:        Uint8 horScroll64 = IoMem_ReadWord(0xff8264);
        !           366:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8264 Horizontal scroll 64 write: 0x%02x\n", horScroll64);
        !           367: }
        !           368: 
        !           369: /**
        !           370:     VIDEL_HorScroll65_WriteByte : Horizontal scroll register (0-15)
        !           371:                $FFFF8265 [R/W] ____3210  .................................H-SCROLL LO
        !           372:                                    ||||
        !           373:                                    ++++--Pixel [ 0:normal / 1..15:Left shift ]
        !           374:                                        [ Change in line-width NOT required ]
        !           375:  */
        !           376: void VIDEL_HorScroll65_WriteByte(void)
        !           377: {
        !           378:        Uint8 horScroll65 = IoMem_ReadWord(0xff8265);
        !           379:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8265 Horizontal scroll 65 write: 0x%02x\n", horScroll65);
        !           380: }
        !           381: 
        !           382: /**
        !           383:     VIDEL_Falcon_ShiftMode_WriteWord :
1.1.1.6   root      384:        $FFFF8266 [R/W] W  _____A98_6543210  Falcon Shift Mode (SPSHIFT)
                    385:                                ||| |||||||
1.1.1.8 ! root      386:                                ||| |||++++- 0..15: Colourbank choice from 256-colour table in 16 colour multiples
        !           387:                                ||| ||+----- 8 Bitplanes mode (256 Colors) [0:off / 1:on]
        !           388:                                ||| |+------ Vertical Sync [0: internal / 1: external]
        !           389:                                ||| +------- Horizontal Sync [0: internal / 1: external]
        !           390:                                ||+--------- True-Color-Mode [0:off / 1:on]
        !           391:                                |+---------- Overlay-Mode [0:off / 1:on]
        !           392:                                +----------- 0: 2-Color-Mode [0:off / 1:on]
1.1.1.6   root      393: 
                    394:        Writing to this register does the following things:
                    395:                - activate Falcon palette
                    396:                - if you set Bits A/8/4 == 0, it selects 16-Color-Falcon-Mode (NOT the
                    397:                  same as ST LOW since Falcon palette is used!)
                    398:                - $8260 register is ignored, you don't need to write here anything
                    399: 
                    400:        Note: 4-Color-Mode isn't realisable with Falcon palette.
                    401:  */
1.1.1.8 ! root      402: void VIDEL_Falcon_ShiftMode_WriteWord(void)
1.1.1.6   root      403: {
                    404:        Uint16 falc_shiftMode = IoMem_ReadWord(0xff8266);
                    405: 
1.1.1.8 ! root      406:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8266 Falcon Shift Mode (SPSHIFT) write: 0x%04x\n", falc_shiftMode);
1.1.1.6   root      407: 
                    408:        videl.bUseSTShifter = false;
                    409: }
                    410: 
                    411: /**
                    412:  *  Write Horizontal Hold Counter (HHC)
                    413:  */
                    414: void VIDEL_HHC_WriteWord(void)
                    415: {
                    416:        Uint16 hhc = IoMem_ReadWord(0xff8280);
                    417: 
1.1.1.8 ! root      418:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8280 Horizontal Hold Counter (HHC) write: 0x%04x\n", hhc);
1.1.1.6   root      419: }
                    420: 
                    421: /**
                    422:  *  Write Horizontal Hold Timer (HHT)
                    423:  */
                    424: void VIDEL_HHT_WriteWord(void)
                    425: {
                    426:        Uint16 hht = IoMem_ReadWord(0xff8282);
                    427: 
1.1.1.8 ! root      428:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8282 Horizontal Hold Timer (HHT) write: 0x%04x\n", hht);
1.1.1.6   root      429: }
                    430: 
                    431: /**
                    432:  *  Write Horizontal Border Begin (HBB)
                    433:  */
                    434: void VIDEL_HBB_WriteWord(void)
                    435: {
                    436:        Uint16 hbb = IoMem_ReadWord(0xff8284);
                    437: 
1.1.1.8 ! root      438:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8284 Horizontal Border Begin (HBB) write: 0x%04x\n", hbb);
1.1.1.6   root      439: }
                    440: 
                    441: /**
                    442:  *  Write Horizontal Border End (HBE)
                    443:  */
                    444: void VIDEL_HBE_WriteWord(void)
                    445: {
                    446:        Uint16 hbe = IoMem_ReadWord(0xff8286);
                    447: 
1.1.1.8 ! root      448:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8286 Horizontal Border End (HBE) write: 0x%04x\n", hbe);
1.1.1.6   root      449: }
                    450: 
                    451: /**
                    452:  *  Write Horizontal Display Begin (HDB)
1.1.1.8 ! root      453:        $FFFF8288 [R/W] W ______9876543210  Horizontal Display Begin (HDB)
        !           454:                                |
        !           455:                                +---------- Display will start in [0: 1st halfline / 1: 2nd halfline]
1.1.1.6   root      456:  */
                    457: void VIDEL_HDB_WriteWord(void)
                    458: {
                    459:        Uint16 hdb = IoMem_ReadWord(0xff8288);
                    460: 
1.1.1.8 ! root      461:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8288 Horizontal Display Begin (HDB) write: 0x%04x\n", hdb);
1.1.1.6   root      462: }
                    463: 
                    464: /**
                    465:  *  Write Horizontal Display End (HDE)
                    466:  */
                    467: void VIDEL_HDE_WriteWord(void)
                    468: {
                    469:        Uint16 hde = IoMem_ReadWord(0xff828a);
                    470: 
1.1.1.8 ! root      471:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff828a Horizontal Display End (HDE) write: 0x%04x\n", hde);
1.1.1.6   root      472: }
                    473: 
                    474: /**
                    475:  *  Write Horizontal SS (HSS)
                    476:  */
                    477: void VIDEL_HSS_WriteWord(void)
                    478: {
                    479:        Uint16 hss = IoMem_ReadWord(0xff828c);
                    480: 
1.1.1.8 ! root      481:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff828c Horizontal SS (HSS) write: 0x%04x\n", hss);
1.1.1.6   root      482: }
                    483: 
                    484: /**
                    485:  *  Write Horizontal FS (HFS)
                    486:  */
                    487: void VIDEL_HFS_WriteWord(void)
                    488: {
                    489:        Uint16 hfs = IoMem_ReadWord(0xff828e);
                    490: 
1.1.1.8 ! root      491:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff828e Horizontal FS (HFS) write: 0x%04x\n", hfs);
1.1.1.6   root      492: }
                    493: 
                    494: /**
                    495:  *  Write Horizontal EE (HEE)
                    496:  */
                    497: void VIDEL_HEE_WriteWord(void)
                    498: {
                    499:        Uint16 hee = IoMem_ReadWord(0xff8290);
                    500: 
1.1.1.8 ! root      501:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8290 Horizontal EE (HEE) write: 0x%04x\n", hee);
1.1.1.6   root      502: }
                    503: 
                    504: /**
                    505:  *  Write Vertical Frequency Counter (VFC)
                    506:  */
                    507: void VIDEL_VFC_ReadWord(void)
                    508: {
                    509:        IoMem_WriteWord(0xff82a0, vfc_counter);
1.1.1.8 ! root      510:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a0 Vertical Frequency Counter (VFC) read: 0x%04x\n", vfc_counter);
1.1.1.6   root      511: }
                    512: 
                    513: /**
                    514:  *  Write Vertical Frequency Timer (VFT)
                    515:  */
                    516: void VIDEL_VFT_WriteWord(void)
                    517: {
                    518:        Uint16 vft = IoMem_ReadWord(0xff82a2);
                    519: 
1.1.1.8 ! root      520:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a2 Vertical Frequency Timer (VFT) write: 0x%04x\n", vft);
1.1.1.6   root      521: }
                    522: 
                    523: /**
                    524:  *  Write Vertical Border Begin (VBB)
                    525:  */
                    526: void VIDEL_VBB_WriteWord(void)
                    527: {
                    528:        Uint16 vbb = IoMem_ReadWord(0xff82a4);
                    529: 
1.1.1.8 ! root      530:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a4 Vertical Border Begin (VBB) write: 0x%04x\n", vbb);
1.1.1.6   root      531: }
                    532: 
                    533: /**
                    534:  *  Write Vertical Border End (VBE)
                    535:  */
                    536: void VIDEL_VBE_WriteWord(void)
                    537: {
                    538:        Uint16 vbe = IoMem_ReadWord(0xff82a6);
                    539: 
1.1.1.8 ! root      540:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a6 Vertical Border End (VBE) write: 0x%04x\n", vbe);
1.1.1.6   root      541: }
                    542: 
                    543: /**
                    544:  *  Write Vertical Display Begin (VDB)
                    545:  */
                    546: void VIDEL_VDB_WriteWord(void)
1.1       root      547: {
1.1.1.6   root      548:        Uint16 vdb = IoMem_ReadWord(0xff82a8);
                    549: 
1.1.1.8 ! root      550:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a8 Vertical Display Begin (VDB) write: 0x%04x\n", vdb);
1.1       root      551: }
                    552: 
1.1.1.6   root      553: /**
                    554:  *  Write Vertical Display End (VDE)
                    555:  */
                    556: void VIDEL_VDE_WriteWord(void)
                    557: {
                    558:        Uint16 vde = IoMem_ReadWord(0xff82aa);
                    559: 
1.1.1.8 ! root      560:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82aa Vertical Display End (VDE) write: 0x%04x\n", vde);
1.1.1.6   root      561: }
                    562: 
                    563: /**
                    564:  *  Write Vertical SS (VSS)
                    565:  */
                    566: void VIDEL_VSS_WriteWord(void)
                    567: {
                    568:        Uint16 vss = IoMem_ReadWord(0xff82ac);
                    569: 
1.1.1.8 ! root      570:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82ac Vertical SS (VSS) write: 0x%04x\n", vss);
1.1.1.6   root      571: }
                    572: 
                    573: /**
                    574:  *  Write Video Control (VCO)
                    575:  */
                    576: void VIDEL_VCO_WriteWord(void)
                    577: {
                    578:        Uint16 vco = IoMem_ReadWord(0xff82c0);
                    579: 
1.1.1.8 ! root      580:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c0 Video control (VCO) write: 0x%04x\n", vco);
1.1.1.6   root      581: }
                    582: 
                    583: /**
                    584:  *  Write Video Mode (VDM)
                    585:  */
                    586: void VIDEL_VMD_WriteWord(void)
                    587: {
                    588:        Uint16 vdm = IoMem_ReadWord(0xff82c2);
                    589: 
1.1.1.8 ! root      590:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c2 Video Mode (VDM) write: 0x%04x\n", vdm);
1.1.1.6   root      591: }
                    592: 
                    593: 
1.1.1.8 ! root      594: /**
        !           595:  *  VIDEL_getVideoramAddress: returns the video RAM address.
        !           596:  *  On Falcon, video address must be a multiple of four in bitplane modes.
        !           597:  */
        !           598: static Uint32 VIDEL_getVideoramAddress(void)
1.1       root      599: {
1.1.1.8 ! root      600:        Uint32 videoBase;
        !           601:        
        !           602:        videoBase  = (Uint32) IoMem_ReadByte(0xff8201) << 16;
        !           603:        videoBase |= (Uint32) IoMem_ReadByte(0xff8203) << 8;
        !           604:        videoBase |= IoMem_ReadByte(0xff820d) & ~3;
        !           605:        
        !           606:        return videoBase;
1.1       root      607: }
                    608: 
1.1.1.8 ! root      609: static Uint16 VIDEL_getScreenBpp(void)
1.1       root      610: {
1.1.1.8 ! root      611:        Uint16 f_shift = IoMem_ReadWord(0xff8266);
        !           612:        Uint16 bits_per_pixel;
        !           613:        Uint8  st_shift = IoMem_ReadByte(0xff8260);
        !           614: 
1.1       root      615:        /* to get bpp, we must examine f_shift and st_shift.
1.1.1.8 ! root      616:         * f_shift is valid if any of bits no. 10, 8 or 4 is set. 
        !           617:         * Priority in f_shift is: 10 ">" 8 ">" 4, i.e.
1.1       root      618:         * if bit 10 set then bit 8 and bit 4 don't care...
                    619:         * If all these bits are 0 and ST shifter is written
                    620:         * after Falcon one, get display depth from st_shift
                    621:         * (as for ST and STE)
                    622:         */
                    623:        if (f_shift & 0x400)            /* Falcon: 2 colors */
                    624:                bits_per_pixel = 1;
                    625:        else if (f_shift & 0x100)       /* Falcon: hicolor */
                    626:                bits_per_pixel = 16;
                    627:        else if (f_shift & 0x010)       /* Falcon: 8 bitplanes */
                    628:                bits_per_pixel = 8;
1.1.1.6   root      629:        else if (!videl.bUseSTShifter)  /* Falcon: 4 bitplanes */
1.1       root      630:                bits_per_pixel = 4;
                    631:        else if (st_shift == 0)
                    632:                bits_per_pixel = 4;
                    633:        else if (st_shift == 0x01)
                    634:                bits_per_pixel = 2;
                    635:        else /* if (st_shift == 0x02) */
                    636:                bits_per_pixel = 1;
                    637: 
1.1.1.8 ! root      638: /*     LOG_TRACE(TRACE_VIDEL, "Videl works in %d bpp, f_shift=%04x, st_shift=%d", bits_per_pixel, f_shift, st_shift); */
1.1       root      639: 
                    640:        return bits_per_pixel;
                    641: }
                    642: 
1.1.1.8 ! root      643: /**
        !           644:  *  VIDEL_getScreenWidth : returns the visible X resolution
        !           645:  *     left border + graphic area + right border
        !           646:  *     left border  : hdb - hbe-offset
        !           647:  *     right border : hbb - hde-offset
        !           648:  *     Graphics display : starts at cycle HDB and ends at cycle HDE. 
        !           649:  */
1.1       root      650: static int VIDEL_getScreenWidth(void)
                    651: {
1.1.1.8 ! root      652:        Uint16 bpp = VIDEL_getScreenBpp();
        !           653: 
        !           654:        /* X Size of the Display area */
        !           655:        videl.XSize = (IoMem_ReadWord(0xff8210) & 0x03ff) * 16 / bpp;
        !           656: 
        !           657:        /* If the user disabled the borders display from the gui, we suppress them */
        !           658:        if (ConfigureParams.Screen.bAllowOverscan == 0) {
        !           659:                videl.leftBorderSize = 0;
        !           660:                videl.rightBorderSize = 0;
        !           661:                return videl.XSize;
        !           662:        }
        !           663: 
        !           664:        /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
        !           665:         * HDB and HDE have no significance and no border is displayed.
        !           666:         */
        !           667:        if (videl.monitor_type == FALCON_MONITOR_MONO) {
        !           668:                videl.leftBorderSize = 0;
        !           669:                videl.rightBorderSize = 0;
        !           670:                return videl.XSize;
        !           671:        }
        !           672: 
        !           673:        Uint16 hbb = IoMem_ReadWord(0xff8284) & 0x01ff;
        !           674:        Uint16 hbe = IoMem_ReadWord(0xff8286) & 0x01ff;  
        !           675:        Uint16 hdb = IoMem_ReadWord(0xff8288) & 0x01ff;
        !           676:        Uint16 hde = IoMem_ReadWord(0xff828a) & 0x01ff;
        !           677:        Uint16 vdm = IoMem_ReadWord(0xff82c2) & 0xc;
        !           678:        Uint16 hht = IoMem_ReadWord(0xff8282) & 0x1ff;
        !           679: 
        !           680:        Uint16 cycPerPixel, divider;
        !           681:        Sint16 hdb_offset, hde_offset;
        !           682:        Sint16 leftBorder, rightBorder;
        !           683: 
        !           684:        /* Compute cycles per pixel */
        !           685:        if (vdm == 0)
        !           686:                cycPerPixel = 4;
        !           687:        else if (vdm == 4)
        !           688:                cycPerPixel = 2;
        !           689:        else
        !           690:                cycPerPixel = 1;
        !           691: 
        !           692:        /* Compute the divider */
        !           693:        if (videl.monitor_type == FALCON_MONITOR_VGA) {
        !           694:                if (cycPerPixel == 4)
        !           695:                        divider = 4;
        !           696:                else
        !           697:                        divider = 2;
        !           698:        }
        !           699:        else if (videl.bUseSTShifter == true) {
        !           700:                divider = 16;
        !           701:        }
        !           702:        else {
        !           703:                divider = cycPerPixel;
        !           704:        }
        !           705: 
        !           706:        /* Compute hdb_offset and hde_offset */
        !           707:        if (videl.bUseSTShifter == false) {
        !           708:                if (bpp < 16) {
        !           709:                        /* falcon mode bpp */
        !           710:                        hdb_offset = ((64+(128/bpp + 16 + 2) * cycPerPixel) / divider ) + 1;
        !           711:                        hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
        !           712:                }
        !           713:                else {
        !           714:                        /* falcon mode true color */
        !           715:                        hdb_offset = ((64 + 16 * cycPerPixel) / divider ) + 1;
        !           716:                        hde_offset = 0;
        !           717:                }
        !           718:        }
        !           719:        else {
        !           720:                /* ST bitplan mode */
        !           721:                hdb_offset = ((128+(128/bpp + 2) * cycPerPixel) / divider ) + 1;
        !           722:                hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
        !           723:        }
        !           724: 
        !           725:        LOG_TRACE(TRACE_VIDEL, "hdb_offset=%04x,    hde_offset=%04x\n", hdb_offset, hde_offset);
        !           726: 
        !           727:        /* Compute left border size in cycles */
        !           728:        if (IoMem_ReadWord(0xff8288) & 0x0200)
        !           729:                leftBorder = hdb - hbe + hdb_offset - hht - 2;
        !           730:        else
        !           731:                leftBorder = hdb - hbe + hdb_offset;
        !           732: 
        !           733:        /* Compute right border size in cycles */
        !           734:        rightBorder = hbb - hde_offset - hde;
        !           735: 
        !           736:        videl.leftBorderSize = leftBorder / cycPerPixel;
        !           737:        videl.rightBorderSize = rightBorder / cycPerPixel;
        !           738:        LOG_TRACE(TRACE_VIDEL, "left border size=%04x,    right border size=%04x\n", videl.leftBorderSize, videl.rightBorderSize);
        !           739: 
        !           740:        if (videl.leftBorderSize < 0) {
        !           741: //             fprintf(stderr, "BORDER LEFT < 0   %d\n", videl.leftBorderSize);
        !           742:                videl.leftBorderSize = 0;
        !           743:        }
        !           744:        if (videl.rightBorderSize < 0) {
        !           745: //             fprintf(stderr, "BORDER RIGHT < 0   %d\n", videl.rightBorderSize);
        !           746:                videl.rightBorderSize = 0;
        !           747:        }
        !           748: 
        !           749:        return videl.leftBorderSize + videl.XSize + videl.rightBorderSize;
1.1       root      750: }
                    751: 
1.1.1.8 ! root      752: /**
        !           753:  *  VIDEL_getScreenHeight : returns the visible Y resolution
        !           754:  *     upper border + graphic area + lower border
        !           755:  *     upper border : vdb - vbe
        !           756:  *     lower border : vbb - vde
        !           757:  *     Graphics display : starts at line VDB and ends at line VDE. 
        !           758:  *     If interlace mode off unit of VC-registers is half lines, else lines.
        !           759:  */
1.1       root      760: static int VIDEL_getScreenHeight(void)
                    761: {
1.1.1.8 ! root      762:        Uint16 vbb = IoMem_ReadWord(0xff82a4) & 0x07ff;
        !           763:        Uint16 vbe = IoMem_ReadWord(0xff82a6) & 0x07ff;  
        !           764:        Uint16 vdb = IoMem_ReadWord(0xff82a8) & 0x07ff;
        !           765:        Uint16 vde = IoMem_ReadWord(0xff82aa) & 0x07ff;
        !           766:        Uint16 vmode = IoMem_ReadWord(0xff82c2);
        !           767: 
        !           768:        /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
        !           769:         * VDB and VDE have no significance and no border is displayed.
1.1       root      770:         */
1.1.1.8 ! root      771:        if (videl.monitor_type == FALCON_MONITOR_MONO) {
        !           772:                videl.upperBorderSize = 0;
        !           773:                videl.lowerBorderSize = 0;
        !           774:        }
        !           775:        else {
        !           776:                /* We must take the positive value only, as a program like AceTracker starts the */
        !           777:                /* graphical area 1 line before the end of the upper border */
        !           778:                videl.upperBorderSize = vdb - vbe > 0 ? vdb - vbe : 0;
        !           779:                videl.lowerBorderSize = vbb - vde > 0 ? vbb - vde : 0;
        !           780:        }
1.1       root      781: 
1.1.1.8 ! root      782:        /* Y Size of the Display area */
        !           783:        videl.YSize = vde - vdb;
        !           784: 
        !           785:        /* If the user disabled the borders display from the gui, we suppress them */
        !           786:        if (ConfigureParams.Screen.bAllowOverscan == 0) {
        !           787:                videl.upperBorderSize = 0;
        !           788:                videl.lowerBorderSize = 0;
        !           789:        }
        !           790: 
        !           791:        if (!(vmode & 0x02)){           /* interlace */
        !           792:                videl.YSize >>= 1;
        !           793:                videl.upperBorderSize >>= 1;
        !           794:                videl.lowerBorderSize >>= 1;
        !           795:        }
        !           796:        
        !           797:        if (vmode & 0x01) {             /* double */
        !           798:                videl.YSize >>= 1;
        !           799:                videl.upperBorderSize >>= 1;
        !           800:                videl.lowerBorderSize >>= 1;
        !           801:        }
        !           802:        
        !           803:        return videl.upperBorderSize + videl.YSize + videl.lowerBorderSize;
1.1       root      804: }
                    805: 
1.1.1.5   root      806: #if 0
                    807: /* this is easier & more robustly done in hostscreen.c just by
                    808:  * comparing requested screen width & height to each other.
                    809:  */
                    810: static void VIDEL_getMonitorScale(int *sx, int *sy)
                    811: {
                    812:        /* Videl video mode register bits and resulting desktop resolution:
                    813:         * 
                    814:         * quarter, half, interlace, double:   pixels: -> zoom:
                    815:         * rgb:
                    816:         *    0       0       0         0      320x200 -> 2 x 2
                    817:         *    0       0       1         0      320x400 -> 2 x 1
                    818:         *    0       1       0         0      640x200 -> 1 x 2 !
                    819:         *    0       1       1         0      640x400 -> 1 x 1
                    820:         * vga:
                    821:         *    0       0       0         1      (just double ?)
                    822:         *    0       0       1         1      (double & interlace ???)
                    823:         *    0       1       0         0      320x480 -> 2 x 1 !
                    824:         *    0       1       0         1      320x240 -> 2 x 2
                    825:         *    0       1       1         1      (double + interlace ???)
                    826:         *    1       0       0         0      640x480 -> 1 x 1
                    827:         *    1       0       0         1      640x240 -> 1 x 2
                    828:         */
1.1.1.8 ! root      829:        int vmode = IoMem_ReadWord(0xff82c2);
1.1.1.5   root      830: 
                    831:        /* half pixel seems to have opposite meaning on
                    832:         * VGA and RGB monitor, so they need to handled separately
                    833:         */
1.1.1.6   root      834:        if (videl.monitor_type) == FALCON_MONITOR_VGA) {
1.1.1.8 ! root      835:                if (vmode & 0x08) {  /* quarter pixel */
1.1.1.5   root      836:                        *sx = 1;
                    837:                } else {
                    838:                        *sx = 2;
                    839:                }
1.1.1.8 ! root      840:                if (vmode & 0x01) {  /* double line */
1.1.1.5   root      841:                        *sy = 2;
                    842:                } else {
                    843:                        *sy = 1;
                    844:                }
                    845:        } else {
1.1.1.8 ! root      846:                if (vmode & 0x04) {  /* half pixel */
1.1.1.5   root      847:                        *sx = 1;
                    848:                } else {
                    849:                        *sx = 2;
                    850:                }
1.1.1.8 ! root      851:                if (vmode & 0x02) {  /* interlace used only on RGB ? */
1.1.1.5   root      852:                        *sy = 1;
                    853:                } else {
                    854:                        *sy = 2;
                    855:                }
                    856:        }
                    857: }
                    858: #endif
                    859: 
1.1       root      860: 
                    861: /** map the correct colortable into the correct pixel format
                    862:  */
                    863: static void VIDEL_updateColors(void)
                    864: {
1.1.1.8 ! root      865:        int i, r, g, b, colors = 1 << videl.save_scrBpp;
1.1       root      866: 
1.1.1.8 ! root      867: #define F_COLORS(i) IoMem_ReadByte(VIDEL_COLOR_REGS_BEGIN + (i))
        !           868: #define STE_COLORS(i)  IoMem_ReadByte(0xff8240 + (i))
1.1       root      869: 
1.1.1.6   root      870:        if (!videl.bUseSTShifter) {
1.1       root      871:                for (i = 0; i < colors; i++) {
                    872:                        int offset = i << 2;
                    873:                        r = F_COLORS(offset) & 0xfc;
                    874:                        r |= r>>6;
                    875:                        g = F_COLORS(offset + 1) & 0xfc;
                    876:                        g |= g>>6;
                    877:                        b = F_COLORS(offset + 3) & 0xfc;
                    878:                        b |= b>>6;
                    879:                        HostScreen_setPaletteColor(i, r,g,b);
                    880:                }
                    881:                HostScreen_updatePalette(colors);
                    882:        } else {
                    883:                for (i = 0; i < colors; i++) {
                    884:                        int offset = i << 1;
                    885:                        r = STE_COLORS(offset) & 0x0f;
                    886:                        r = ((r & 7)<<1)|(r>>3);
                    887:                        r |= r<<4;
                    888:                        g = (STE_COLORS(offset + 1)>>4) & 0x0f;
                    889:                        g = ((g & 7)<<1)|(g>>3);
                    890:                        g |= g<<4;
                    891:                        b = STE_COLORS(offset + 1) & 0x0f;
                    892:                        b = ((b & 7)<<1)|(b>>3);
                    893:                        b |= b<<4;
                    894:                        HostScreen_setPaletteColor(i, r,g,b);
                    895:                }
                    896:                HostScreen_updatePalette(colors);
                    897:        }
                    898: 
1.1.1.8 ! root      899:        videl.hostColorsSync = true;
1.1       root      900: }
                    901: 
                    902: 
                    903: void VIDEL_ZoomModeChanged(void)
                    904: {
                    905:        /* User selected another zoom mode, so set a new screen resolution now */
1.1.1.8 ! root      906:        HostScreen_setWindowSize(videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp);
1.1       root      907: }
                    908: 
                    909: 
1.1.1.2   root      910: bool VIDEL_renderScreen(void)
1.1       root      911: {
1.1.1.8 ! root      912:        videl.videoBaseAddr = VIDEL_getVideoramAddress(); // Todo: to be removed when all code is in Videl
        !           913: 
        !           914:        /* Atari screen infos */
1.1       root      915:        int vw   = VIDEL_getScreenWidth();
                    916:        int vh   = VIDEL_getScreenHeight();
                    917:        int vbpp = VIDEL_getScreenBpp();
1.1.1.8 ! root      918: 
        !           919:        int lineoffset = IoMem_ReadWord(0xff820e) & 0x01ff; /* 9 bits */
        !           920:        int linewidth = IoMem_ReadWord(0xff8210) & 0x03ff;  /* 10 bits */
        !           921: 
1.1.1.6   root      922:        bool change = false;
1.1       root      923: 
1.1.1.8 ! root      924:        if (vw > 0 && vw != videl.save_scrWidth) {
        !           925:                LOG_TRACE(TRACE_VIDEL, "Videl : width change from %d to %d\n", videl.save_scrWidth, vw);
        !           926:                videl.save_scrWidth = vw;
1.1.1.6   root      927:                change = true;
1.1       root      928:        }
1.1.1.8 ! root      929:        if (vh > 0 && vh != videl.save_scrHeight) {
        !           930:                LOG_TRACE(TRACE_VIDEL, "Videl : height change from %d to %d\n", videl.save_scrHeight, vh);
        !           931:                videl.save_scrHeight = vh;
1.1.1.6   root      932:                change = true;
1.1       root      933:        }
1.1.1.8 ! root      934:        if (vbpp != videl.save_scrBpp) {
        !           935:                LOG_TRACE(TRACE_VIDEL, "Videl : bpp change from %d to %d\n", videl.save_scrBpp, vbpp);
        !           936:                videl.save_scrBpp = vbpp;
1.1.1.6   root      937:                change = true;
                    938:        }
                    939:        if (change) {
1.1.1.8 ! root      940:                LOG_TRACE(TRACE_VIDEL, "Videl : video mode change to %dx%d@%d\n", videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp);
        !           941:                HostScreen_setWindowSize(videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp);
1.1       root      942:        }
                    943: 
                    944:        if (!HostScreen_renderBegin())
1.1.1.2   root      945:                return false;
1.1       root      946: 
1.1.1.8 ! root      947:        /* 
        !           948:           I think this implementation is naive: 
        !           949:           indeed, I suspect that we should instead skip lineoffset
        !           950:           words each time we have read "more" than linewidth words
        !           951:           (possibly "more" because of the number of bit planes).
        !           952:           Moreover, the 1 bit plane mode is particular;
        !           953:           while doing some experiments on my Falcon, it seems to
        !           954:           behave like the 4 bit planes mode.
        !           955:           At last, we have also to take into account the 4 bits register
        !           956:           located at the word $ffff8264 (bit offset). This register makes
        !           957:           the semantics of the lineoffset register change a little.
        !           958:           int bitoffset = IoMem_ReadWord(0xff8264) & 0x000f;
        !           959:           The meaning of this register in True Color mode is not clear
        !           960:           for me at the moment (and my experiments on the Falcon don't help
        !           961:           me).
        !           962:        */
        !           963:        int nextline = linewidth + lineoffset;
        !           964: 
        !           965:        if ((vw<32) || (vh<32))
        !           966:                return false;
        !           967: 
        !           968:        if (videl.save_scrBpp < 16 && videl.hostColorsSync == 0)
        !           969:                VIDEL_updateColors();
        !           970: 
1.1.1.5   root      971:        if (nScreenZoomX * nScreenZoomY != 1) {
1.1.1.8 ! root      972:                VIDEL_ConvertScreenZoom(vw, vh, videl.save_scrBpp, nextline);
1.1       root      973:        } else {
1.1.1.8 ! root      974:                VIDEL_ConvertScreenNoZoom(vw, vh, videl.save_scrBpp, nextline);
1.1       root      975:        }
                    976: 
                    977: 
1.1.1.8 ! root      978:        HostScreen_renderEnd();
1.1.1.4   root      979:        HostScreen_update1(false);
1.1.1.2   root      980: 
                    981:        return true;
1.1       root      982: }
                    983: 
                    984: 
1.1.1.4   root      985: /**
                    986:  * Performs conversion from the TOS's bitplane word order (big endian) data
                    987:  * into the native chunky color index.
                    988:  */
1.1.1.8 ! root      989: static void VIDEL_bitplaneToChunky(Uint16 *atariBitplaneData, Uint16 bpp,
1.1.1.4   root      990:                                    Uint8 colorValues[16])
                    991: {
                    992:        Uint32 a, b, c, d, x;
                    993: 
                    994:        /* Obviously the different cases can be broken out in various
                    995:         * ways to lessen the amount of work needed for <8 bit modes.
                    996:         * It's doubtful if the usage of those modes warrants it, though.
                    997:         * The branches below should be ~100% correctly predicted and
                    998:         * thus be more or less for free.
                    999:         * Getting the palette values inline does not seem to help
                   1000:         * enough to worry about. The palette lookup is much slower than
                   1001:         * this code, though, so it would be nice to do something about it.
                   1002:         */
                   1003:        if (bpp >= 4) {
                   1004:                d = *(Uint32 *)&atariBitplaneData[0];
                   1005:                c = *(Uint32 *)&atariBitplaneData[2];
                   1006:                if (bpp == 4) {
                   1007:                        a = b = 0;
                   1008:                } else {
                   1009:                        b = *(Uint32 *)&atariBitplaneData[4];
                   1010:                        a = *(Uint32 *)&atariBitplaneData[6];
                   1011:                }
                   1012:        } else {
                   1013:                a = b = c = 0;
                   1014:                if (bpp == 2) {
                   1015:                        d = *(Uint32 *)&atariBitplaneData[0];
                   1016:                } else {
                   1017: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                   1018:                        d = atariBitplaneData[0]<<16;
                   1019: #else
                   1020:                        d = atariBitplaneData[0];
                   1021: #endif
                   1022:                }
                   1023:        }
                   1024: 
                   1025:        x = a;
                   1026:        a =  (a & 0xf0f0f0f0)       | ((c & 0xf0f0f0f0) >> 4);
                   1027:        c = ((x & 0x0f0f0f0f) << 4) |  (c & 0x0f0f0f0f);
                   1028:        x = b;
                   1029:        b =  (b & 0xf0f0f0f0)       | ((d & 0xf0f0f0f0) >> 4);
                   1030:        d = ((x & 0x0f0f0f0f) << 4) |  (d & 0x0f0f0f0f);
                   1031: 
                   1032:        x = a;
                   1033:        a =  (a & 0xcccccccc)       | ((b & 0xcccccccc) >> 2);
                   1034:        b = ((x & 0x33333333) << 2) |  (b & 0x33333333);
                   1035:        x = c;
                   1036:        c =  (c & 0xcccccccc)       | ((d & 0xcccccccc) >> 2);
                   1037:        d = ((x & 0x33333333) << 2) |  (d & 0x33333333);
                   1038: 
                   1039: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
                   1040:        a = (a & 0x5555aaaa) | ((a & 0x00005555) << 17) | ((a & 0xaaaa0000) >> 17);
                   1041:        b = (b & 0x5555aaaa) | ((b & 0x00005555) << 17) | ((b & 0xaaaa0000) >> 17);
                   1042:        c = (c & 0x5555aaaa) | ((c & 0x00005555) << 17) | ((c & 0xaaaa0000) >> 17);
                   1043:        d = (d & 0x5555aaaa) | ((d & 0x00005555) << 17) | ((d & 0xaaaa0000) >> 17);
                   1044: 
                   1045:        colorValues[ 8] = a;
                   1046:        a >>= 8;
                   1047:        colorValues[ 0] = a;
                   1048:        a >>= 8;
                   1049:        colorValues[ 9] = a;
                   1050:        a >>= 8;
                   1051:        colorValues[ 1] = a;
                   1052: 
                   1053:        colorValues[10] = b;
                   1054:        b >>= 8;
                   1055:        colorValues[ 2] = b;
                   1056:        b >>= 8;
                   1057:        colorValues[11] = b;
                   1058:        b >>= 8;
                   1059:        colorValues[ 3] = b;
                   1060: 
                   1061:        colorValues[12] = c;
                   1062:        c >>= 8;
                   1063:        colorValues[ 4] = c;
                   1064:        c >>= 8;
                   1065:        colorValues[13] = c;
                   1066:        c >>= 8;
                   1067:        colorValues[ 5] = c;
                   1068: 
                   1069:        colorValues[14] = d;
                   1070:        d >>= 8;
                   1071:        colorValues[ 6] = d;
                   1072:        d >>= 8;
                   1073:        colorValues[15] = d;
                   1074:        d >>= 8;
                   1075:        colorValues[ 7] = d;
                   1076: #else
                   1077:        a = (a & 0xaaaa5555) | ((a & 0x0000aaaa) << 15) | ((a & 0x55550000) >> 15);
                   1078:        b = (b & 0xaaaa5555) | ((b & 0x0000aaaa) << 15) | ((b & 0x55550000) >> 15);
                   1079:        c = (c & 0xaaaa5555) | ((c & 0x0000aaaa) << 15) | ((c & 0x55550000) >> 15);
                   1080:        d = (d & 0xaaaa5555) | ((d & 0x0000aaaa) << 15) | ((d & 0x55550000) >> 15);
                   1081: 
                   1082:        colorValues[ 1] = a;
                   1083:        a >>= 8;
                   1084:        colorValues[ 9] = a;
                   1085:        a >>= 8;
                   1086:        colorValues[ 0] = a;
                   1087:        a >>= 8;
                   1088:        colorValues[ 8] = a;
                   1089: 
                   1090:        colorValues[ 3] = b;
                   1091:        b >>= 8;
                   1092:        colorValues[11] = b;
                   1093:        b >>= 8;
                   1094:        colorValues[ 2] = b;
                   1095:        b >>= 8;
                   1096:        colorValues[10] = b;
                   1097: 
                   1098:        colorValues[ 5] = c;
                   1099:        c >>= 8;
                   1100:        colorValues[13] = c;
                   1101:        c >>= 8;
                   1102:        colorValues[ 4] = c;
                   1103:        c >>= 8;
                   1104:        colorValues[12] = c;
                   1105: 
                   1106:        colorValues[ 7] = d;
                   1107:        d >>= 8;
                   1108:        colorValues[15] = d;
                   1109:        d >>= 8;
                   1110:        colorValues[ 6] = d;
                   1111:        d >>= 8;
                   1112:        colorValues[14] = d;
                   1113: #endif
                   1114: }
                   1115: 
1.1       root     1116: void VIDEL_ConvertScreenNoZoom(int vw, int vh, int vbpp, int nextline)
                   1117: {
                   1118:        int scrpitch = HostScreen_getPitch();
1.1.1.8 ! root     1119:        int h, w, j;
1.1       root     1120: 
1.1.1.8 ! root     1121:        Uint16 *fvram = (Uint16 *) Atari2HostAddr(videl.videoBaseAddr);
1.1.1.2   root     1122:        Uint8 *hvram = HostScreen_getVideoramAddress();
1.1.1.6   root     1123:        SDL_PixelFormat *scrfmt = HostScreen_getFormat();
1.1       root     1124: 
1.1.1.8 ! root     1125:        Uint16 lowBorderSize, rightBorderSize;
        !          1126: 
        !          1127:        int hscrolloffset = IoMem_ReadByte(0xff8265) & 0x0f;
        !          1128: 
        !          1129:        /* Horizontal scroll register set? */
        !          1130:        if (hscrolloffset) {
        !          1131:                /* Yes, so we need to adjust offset to next line: */
        !          1132:                nextline += vbpp;
        !          1133:        }
        !          1134: 
        !          1135:        /* If emulated computer is the TT, we use the same rendering for display, but without the borders */
        !          1136:        if (ConfigureParams.System.nMachineType == MACHINE_TT) {
        !          1137:                videl.leftBorderSize = 0;
        !          1138:                videl.rightBorderSize = 0;
        !          1139:                videl.upperBorderSize = 0;
        !          1140:                videl.lowerBorderSize = 0;
        !          1141:                fvram = (Uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress());
        !          1142:        }
1.1       root     1143: 
                   1144:        /* Clip to SDL_Surface dimensions */
                   1145:        int scrwidth = HostScreen_getWidth();
                   1146:        int scrheight = HostScreen_getHeight();
                   1147:        int vw_clip = vw;
                   1148:        int vh_clip = vh;
                   1149:        if (vw>scrwidth) vw_clip = scrwidth;
                   1150:        if (vh>scrheight) vh_clip = scrheight;  
                   1151: 
1.1.1.8 ! root     1152:        /* If emulated computer is the FALCON, we must take :
        !          1153:         * vw = X area display size and not all the X screen with the borders into account
        !          1154:         * vh = Y area display size and not all the Y screen with the borders into account
        !          1155:         */
        !          1156:        if (ConfigureParams.System.nMachineType == MACHINE_FALCON) {
        !          1157:                vw = videl.XSize;
        !          1158:                vh = videl.YSize;
1.1       root     1159:        }
                   1160: 
1.1.1.8 ! root     1161:        /* If there's not enough space to display the left border, just return */
        !          1162:        if (vw_clip < videl.leftBorderSize)
        !          1163:                return;
        !          1164:        /* If there's not enough space for the left border + the graphic area, we clip */ 
        !          1165:        if (vw_clip < vw + videl.leftBorderSize) {
        !          1166:                vw = vw_clip - videl.leftBorderSize;
        !          1167:                rightBorderSize = 0;
        !          1168:        }
        !          1169:        /* if there's not enough space for the left border + the graphic area + the right border, we clip the border */
        !          1170:        else if (vw_clip < vw + videl.leftBorderSize + videl.rightBorderSize)
        !          1171:                rightBorderSize = vw_clip - videl.leftBorderSize - vw;
        !          1172:        else
        !          1173:                rightBorderSize = videl.rightBorderSize;
        !          1174: 
        !          1175:        /* If there's not enough space to display the upper border, just return */
        !          1176:        if (vh_clip < videl.upperBorderSize)
        !          1177:                return;
        !          1178: 
        !          1179:        /* If there's not enough space for the upper border + the graphic area, we clip */ 
        !          1180:        if (vh_clip < vh + videl.upperBorderSize) {
        !          1181:                vh = vh_clip - videl.upperBorderSize;
        !          1182:                lowBorderSize = 0;
        !          1183:        }
        !          1184:        /* if there's not enough space for the upper border + the graphic area + the lower border, we clip the border */
        !          1185:        else if (vh_clip < vh + videl.upperBorderSize + videl.lowerBorderSize)
        !          1186:                lowBorderSize = vh_clip - videl.upperBorderSize - vh;
        !          1187:        else
        !          1188:                lowBorderSize = videl.lowerBorderSize;
        !          1189: 
1.1       root     1190:        /* Center screen */
                   1191:        hvram += ((scrheight-vh_clip)>>1)*scrpitch;
                   1192:        hvram += ((scrwidth-vw_clip)>>1)*HostScreen_getBpp();
                   1193: 
1.1.1.8 ! root     1194:        Uint16 *fvram_line = fvram;
        !          1195:        scrwidth = videl.leftBorderSize + vw + videl.rightBorderSize;
        !          1196: 
        !          1197:        /* render the graphic area */
1.1       root     1198:        if (vbpp < 16) {
                   1199:                /* Bitplanes modes */
                   1200: 
1.1.1.8 ! root     1201:                /* The SDL colors blitting... */
1.1.1.2   root     1202:                Uint8 color[16];
1.1       root     1203: 
1.1.1.8 ! root     1204:                /* FIXME: The byte swap could be done here by enrolling the loop into 2 each by 8 pixels */
1.1       root     1205:                switch ( HostScreen_getBpp() ) {
                   1206:                        case 1:
1.1.1.8 ! root     1207:                        {
        !          1208:                                Uint8 *hvram_line = hvram;
1.1       root     1209: 
1.1.1.8 ! root     1210:                                /* Render the upper border */
        !          1211:                                for (h = 0; h < videl.upperBorderSize; h++) {
        !          1212:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1213:                                        hvram_line += scrpitch;
        !          1214:                                }
1.1       root     1215: 
1.1.1.8 ! root     1216:                                /* Render the graphical area */
        !          1217:                                for (h = 0; h < vh; h++) {
        !          1218:                                        Uint16 *fvram_column = fvram_line;
        !          1219:                                        Uint8 *hvram_column = hvram_line;
        !          1220: 
        !          1221:                                        /* Left border first */
        !          1222:                                        VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
        !          1223:                                        hvram_column += videl.leftBorderSize;
        !          1224:                                
        !          1225:                                        /* First 16 pixels */
        !          1226:                                        VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1227:                                        memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
        !          1228:                                        hvram_column += 16-hscrolloffset;
        !          1229:                                        fvram_column += vbpp;
        !          1230:                                        /* Now the main part of the line */
        !          1231:                                        for (w = 1; w < (vw+15)>>4; w++) {
        !          1232:                                                VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
        !          1233:                                                memcpy(hvram_column, color, 16);
        !          1234:                                                hvram_column += 16;
1.1       root     1235:                                                fvram_column += vbpp;
                   1236:                                        }
1.1.1.8 ! root     1237:                                        /* Last pixels of the line for fine scrolling */
        !          1238:                                        if (hscrolloffset) {
        !          1239:                                                VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1240:                                                memcpy(hvram_column, color, hscrolloffset);
        !          1241:                                        }
        !          1242:                                        /* Right border */
        !          1243:                                        VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
        !          1244: 
        !          1245:                                        fvram_line += nextline;
        !          1246:                                        hvram_line += scrpitch;
1.1       root     1247:                                }
1.1.1.8 ! root     1248: 
        !          1249:                                /* Render the lower border */
        !          1250:                                for (h = 0; h < lowBorderSize; h++) {
        !          1251:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1252:                                        hvram_line += scrpitch;
        !          1253:                                }
        !          1254:                        }
        !          1255:                        break;
1.1       root     1256:                        case 2:
1.1.1.8 ! root     1257:                        {
        !          1258:                                Uint16 *hvram_line = (Uint16 *)hvram;
1.1       root     1259: 
1.1.1.8 ! root     1260:                                /* Render the upper border */
        !          1261:                                for (h = 0; h < videl.upperBorderSize; h++) {
        !          1262:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1263:                                        hvram_line += scrpitch>>1;
        !          1264:                                }
1.1       root     1265: 
1.1.1.8 ! root     1266:                                /* Render the graphical area */
        !          1267:                                for (h = 0; h < vh; h++) {
        !          1268:                                        Uint16 *fvram_column = fvram_line;
        !          1269:                                        Uint16 *hvram_column = hvram_line;
        !          1270: 
        !          1271:                                        /* Left border first */
        !          1272:                                        VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
        !          1273:                                        hvram_column += videl.leftBorderSize;
        !          1274:                                
        !          1275:                                        /* First 16 pixels */
        !          1276:                                        VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1277:                                        for (j = 0; j < 16 - hscrolloffset; j++) {
        !          1278:                                                *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !          1279:                                        }
        !          1280:                                        fvram_column += vbpp;
        !          1281:                                        /* Now the main part of the line */
        !          1282:                                        for (w = 1; w < (vw+15)>>4; w++) {
        !          1283:                                                VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
        !          1284:                                                for (j=0; j<16; j++) {
        !          1285:                                                        *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4   root     1286:                                                }
                   1287:                                                fvram_column += vbpp;
1.1.1.8 ! root     1288:                                        }
        !          1289:                                        /* Last pixels of the line for fine scrolling */
        !          1290:                                        if (hscrolloffset) {
        !          1291:                                                VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1292:                                                for (j = 0; j < hscrolloffset; j++) {
        !          1293:                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1       root     1294:                                                }
                   1295:                                        }
1.1.1.8 ! root     1296:                                        /* Right border */
        !          1297:                                        VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
        !          1298: 
        !          1299:                                        fvram_line += nextline;
        !          1300:                                        hvram_line += scrpitch>>1;
1.1       root     1301:                                }
1.1.1.8 ! root     1302: 
        !          1303:                                /* Render the lower border */
        !          1304:                                for (h = 0; h < lowBorderSize; h++) {
        !          1305:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1306:                                        hvram_line += scrpitch>>1;
        !          1307:                                }
        !          1308:                        }
        !          1309:                        break;
1.1       root     1310:                        case 4:
1.1.1.8 ! root     1311:                        {
        !          1312:                                Uint32 *hvram_line = (Uint32 *)hvram;
1.1       root     1313: 
1.1.1.8 ! root     1314:                                /* Render the upper border */
        !          1315:                                for (h = 0; h < videl.upperBorderSize; h++) {
        !          1316:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1317:                                        hvram_line += scrpitch>>2;
        !          1318:                                }
1.1       root     1319: 
1.1.1.8 ! root     1320:                                /* Render the graphical area */
        !          1321:                                for (h = 0; h < vh; h++) {
        !          1322:                                        Uint16 *fvram_column = fvram_line;
        !          1323:                                        Uint32 *hvram_column = hvram_line;
        !          1324: 
        !          1325:                                        /* Left border first */
        !          1326:                                        VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
        !          1327:                                        hvram_column += videl.leftBorderSize;
        !          1328:                                
        !          1329:                                        /* First 16 pixels */
        !          1330:                                        VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1331:                                        for (j = 0; j < 16 - hscrolloffset; j++) {
        !          1332:                                                *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !          1333:                                        }
        !          1334:                                        fvram_column += vbpp;
        !          1335:                                        /* Now the main part of the line */
        !          1336:                                        for (w = 1; w < (vw+15)>>4; w++) {
        !          1337:                                                VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
        !          1338:                                                for (j=0; j<16; j++) {
        !          1339:                                                        *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4   root     1340:                                                }
                   1341:                                                fvram_column += vbpp;
1.1.1.8 ! root     1342:                                        }
        !          1343:                                        /* Last pixels of the line for fine scrolling */
        !          1344:                                        if (hscrolloffset) {
        !          1345:                                                VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1346:                                                for (j = 0; j < hscrolloffset; j++) {
        !          1347:                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1.1.4   root     1348:                                                }
1.1       root     1349:                                        }
1.1.1.8 ! root     1350:                                        /* Right border */
        !          1351:                                        VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
        !          1352: 
        !          1353:                                        fvram_line += nextline;
        !          1354:                                        hvram_line += scrpitch>>2;
1.1       root     1355:                                }
1.1.1.8 ! root     1356: 
        !          1357:                                /* Render the lower border */
        !          1358:                                for (h = 0; h < lowBorderSize; h++) {
        !          1359:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1360:                                        hvram_line += scrpitch>>2;
        !          1361:                                }
        !          1362:                        }
        !          1363:                        break;
1.1       root     1364:                }
                   1365: 
                   1366:        } else {
                   1367: 
1.1.1.8 ! root     1368:                /* Falcon TC (High Color) */
1.1       root     1369:                switch ( HostScreen_getBpp() )  {
                   1370:                        case 1:
1.1.1.8 ! root     1371:                        {
        !          1372:                                /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
        !          1373:                                Uint8 *hvram_line = hvram;
        !          1374: 
        !          1375:                                /* Render the upper border */
        !          1376:                                for (h = 0; h < videl.upperBorderSize; h++) {
        !          1377:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1378:                                        hvram_line += scrpitch;
        !          1379:                                }
1.1       root     1380: 
1.1.1.8 ! root     1381:                                /* Render the graphical area */
        !          1382:                                for (h = 0; h < vh; h++) {
        !          1383:                                        Uint16 *fvram_column = fvram_line;
        !          1384:                                        Uint8 *hvram_column = hvram_line;
        !          1385:                                        int tmp;
        !          1386: 
        !          1387:                                        /* Left border first */
        !          1388:                                        VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
        !          1389:                                        hvram_column += videl.leftBorderSize;
        !          1390: 
        !          1391:                                        /* Graphical area */
        !          1392:                                        for (w = 0; w < vw; w++) {
        !          1393:                                                tmp = SDL_SwapBE16(*fvram_column++);
        !          1394:                                                *hvram_column++ = (((tmp>>13) & 7) << 5) + (((tmp>>8) & 7) << 2) + (((tmp>>2) & 3));
        !          1395:                                        }
1.1       root     1396: 
1.1.1.8 ! root     1397:                                        /* Right border */
        !          1398:                                        VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1.1       root     1399: 
1.1.1.8 ! root     1400:                                        fvram_line += nextline;
        !          1401:                                        hvram_line += scrpitch;
1.1       root     1402:                                }
1.1.1.8 ! root     1403:                                /* Render the bottom border */
        !          1404:                                for (h = 0; h < lowBorderSize; h++) {
        !          1405:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1406:                                        hvram_line += scrpitch;
        !          1407:                                }
        !          1408:                        }
        !          1409:                        break;
1.1       root     1410:                        case 2:
1.1.1.8 ! root     1411:                        {
        !          1412:                                Uint16 *hvram_line = (Uint16 *)hvram;
        !          1413: 
        !          1414:                                /* Render the upper border */
        !          1415:                                for (h = 0; h < videl.upperBorderSize; h++) {
        !          1416:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1417:                                        hvram_line += scrpitch>>1;
        !          1418:                                }
        !          1419: 
        !          1420:                                /* Render the graphical area */
        !          1421:                                for (h = 0; h < vh; h++) {
        !          1422:                                        Uint16 *hvram_column = hvram_line;
        !          1423: 
        !          1424:                                        /* Left border first */
        !          1425:                                        VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
        !          1426:                                        hvram_column += videl.leftBorderSize;
1.1       root     1427: 
                   1428: #if SDL_BYTEORDER == SDL_BIG_ENDIAN
1.1.1.8 ! root     1429:                                        /* FIXME: here might be a runtime little/big video endian switch like:
        !          1430:                                                if ( " videocard memory in Motorola endian format " false)
        !          1431:                                        */
        !          1432:                                        memcpy(hvram_column, fvram_line, vw<<1);
        !          1433:                                        hvram_column += vw<<1;
1.1       root     1434: #else
1.1.1.8 ! root     1435:                                        Uint16 *fvram_column = fvram_line;
        !          1436:                                        /* Graphical area */
        !          1437:                                        for (w = 0; w < vw; w++)
        !          1438:                                                *hvram_column ++ = SDL_SwapBE16(*fvram_column++);
        !          1439: #endif /* SDL_BYTEORDER == SDL_BIG_ENDIAN */
1.1       root     1440: 
1.1.1.8 ! root     1441:                                        /* Right border */
        !          1442:                                        VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
1.1       root     1443: 
1.1.1.8 ! root     1444:                                        fvram_line += nextline;
        !          1445:                                        hvram_line += scrpitch>>1;
1.1       root     1446:                                }
                   1447: 
1.1.1.8 ! root     1448:                                /* Render the bottom border */
        !          1449:                                for (h = 0; h < lowBorderSize; h++) {
        !          1450:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1451:                                        hvram_line += scrpitch>>1;
1.1       root     1452:                                }
1.1.1.8 ! root     1453:                        }
        !          1454:                        break;
        !          1455:                        case 4:
        !          1456:                        {
        !          1457:                                Uint32 *hvram_line = (Uint32 *)hvram;
1.1       root     1458: 
1.1.1.8 ! root     1459:                                /* Render the upper border */
        !          1460:                                for (h = 0; h < videl.upperBorderSize; h++) {
        !          1461:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1462:                                        hvram_line += scrpitch>>2;
        !          1463:                                }
1.1       root     1464: 
1.1.1.8 ! root     1465:                                /* Render the graphical area */
        !          1466:                                for (h = 0; h < vh; h++) {
        !          1467:                                        Uint16 *fvram_column = fvram_line;
        !          1468:                                        Uint32 *hvram_column = hvram_line;
        !          1469: 
        !          1470:                                        /* Left border first */
        !          1471:                                        VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize);
        !          1472:                                        hvram_column += videl.leftBorderSize;
        !          1473: 
        !          1474:                                        /* Graphical area */
        !          1475:                                        for (w = 0; w < vw; w++) {
        !          1476:                                                Uint16 srcword = *fvram_column++;
        !          1477:                                                *hvram_column ++ = SDL_MapRGB(scrfmt, (srcword & 0xf8), (((srcword & 0x07) << 5) | ((srcword >> 11) & 0x3c)), ((srcword >> 5) & 0xf8));
        !          1478:                                        }
1.1       root     1479: 
1.1.1.8 ! root     1480:                                        /* Right border */
        !          1481:                                        VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), rightBorderSize);
        !          1482:                                }
1.1       root     1483: 
1.1.1.8 ! root     1484:                                fvram_line += nextline;
        !          1485:                                hvram_line += scrpitch>>2;
1.1       root     1486: 
1.1.1.8 ! root     1487:                                /* Render the bottom border */
        !          1488:                                for (h = 0; h < lowBorderSize; h++) {
        !          1489:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1490:                                        hvram_line += scrpitch>>2;
        !          1491:                                }
        !          1492:                        }
        !          1493:                        break;
        !          1494:                }
1.1       root     1495:        }
                   1496: }
                   1497: 
                   1498: 
                   1499: void VIDEL_ConvertScreenZoom(int vw, int vh, int vbpp, int nextline)
                   1500: {
                   1501:        int i, j, w, h, cursrcline;
                   1502: 
1.1.1.8 ! root     1503:        Uint16 *fvram = (Uint16 *) Atari2HostAddr(videl.videoBaseAddr);
        !          1504:        Uint16 *fvram_line;
        !          1505:        Uint16 scrIdx = 0;
        !          1506: 
        !          1507:        int coefx = 1;
        !          1508:        int coefy = 1;
        !          1509: 
        !          1510:        /* If emulated computer is the TT, we use the same rendering for display, but without the borders */
        !          1511:        if (ConfigureParams.System.nMachineType == MACHINE_TT) {
        !          1512:                videl.leftBorderSize = 0;
        !          1513:                videl.rightBorderSize = 0;
        !          1514:                videl.upperBorderSize = 0;
        !          1515:                videl.lowerBorderSize = 0;
        !          1516:                videl.XSize = vw;
        !          1517:                videl.YSize = vh;
        !          1518:                fvram = (Uint16 *) Atari2HostAddr(VIDEL_getVideoramAddress());
        !          1519:        }
1.1       root     1520: 
                   1521:        /* Host screen infos */
                   1522:        int scrpitch = HostScreen_getPitch();
                   1523:        int scrwidth = HostScreen_getWidth();
                   1524:        int scrheight = HostScreen_getHeight();
                   1525:        int scrbpp = HostScreen_getBpp();
1.1.1.6   root     1526:        SDL_PixelFormat *scrfmt = HostScreen_getFormat();
1.1.1.2   root     1527:        Uint8 *hvram = (Uint8 *) HostScreen_getVideoramAddress();
1.1       root     1528: 
1.1.1.8 ! root     1529:        int hscrolloffset = IoMem_ReadByte(0xff8265) & 0x0f;
1.1       root     1530: 
                   1531:        /* Horizontal scroll register set? */
                   1532:        if (hscrolloffset) {
                   1533:                /* Yes, so we need to adjust offset to next line: */
                   1534:                nextline += vbpp;
                   1535:        }
                   1536: 
                   1537:        /* Integer zoom coef ? */
                   1538:        if (/*(bx_options.autozoom.integercoefs) &&*/ (scrwidth>=vw) && (scrheight>=vh)) {
1.1.1.8 ! root     1539:                coefx = scrwidth/vw;
        !          1540:                coefy = scrheight/vh;
1.1       root     1541: 
                   1542:                scrwidth = vw * coefx;
                   1543:                scrheight = vh * coefy;
                   1544: 
                   1545:                /* Center screen */
                   1546:                hvram += ((HostScreen_getHeight()-scrheight)>>1)*scrpitch;
                   1547:                hvram += ((HostScreen_getWidth()-scrwidth)>>1)*scrbpp;
                   1548:        }
                   1549: 
                   1550:        /* New zoom ? */
1.1.1.8 ! root     1551:        if ((videl_zoom.zoomwidth != vw) || (scrwidth != videl_zoom.prev_scrwidth)) {
        !          1552:                if (videl_zoom.zoomxtable) {
        !          1553:                        free(videl_zoom.zoomxtable);
1.1       root     1554:                }
1.1.1.8 ! root     1555:                videl_zoom.zoomxtable = malloc(sizeof(int)*scrwidth);
1.1       root     1556:                for (i=0; i<scrwidth; i++) {
1.1.1.8 ! root     1557:                        videl_zoom.zoomxtable[i] = (vw*i)/scrwidth;
1.1       root     1558:                }
1.1.1.8 ! root     1559:                videl_zoom.zoomwidth = vw;
        !          1560:                videl_zoom.prev_scrwidth = scrwidth;
1.1       root     1561:        }
1.1.1.8 ! root     1562:        if ((videl_zoom.zoomheight != vh) || (scrheight != videl_zoom.prev_scrheight)) {
        !          1563:                if (videl_zoom.zoomytable) {
        !          1564:                        free(videl_zoom.zoomytable);
1.1       root     1565:                }
1.1.1.8 ! root     1566:                videl_zoom.zoomytable = malloc(sizeof(int)*scrheight);
1.1       root     1567:                for (i=0; i<scrheight; i++) {
1.1.1.8 ! root     1568:                        videl_zoom.zoomytable[i] = (vh*i)/scrheight;
1.1       root     1569:                }
1.1.1.8 ! root     1570:                videl_zoom.zoomheight = vh;
        !          1571:                videl_zoom.prev_scrheight = scrheight;
1.1       root     1572:        }
                   1573: 
                   1574:        cursrcline = -1;
                   1575: 
1.1.1.8 ! root     1576:        /* We reuse the following values to compute the display area size in zoom mode */
        !          1577:        /* scrwidth must not change */
        !          1578:        if (ConfigureParams.System.nMachineType == MACHINE_FALCON) {
        !          1579:                vw = videl.XSize;
        !          1580:                vh = videl.YSize;
        !          1581:                scrheight = vh * coefy;
        !          1582:        }
        !          1583: 
1.1       root     1584:        if (vbpp<16) {
1.1.1.2   root     1585:                Uint8 color[16];
1.1       root     1586: 
                   1587:                /* Bitplanes modes */
                   1588:                switch(scrbpp) {
                   1589:                        case 1:
1.1.1.8 ! root     1590:                        {
        !          1591:                                /* One complete 16-pixel aligned planar 2 chunky line */
        !          1592:                                Uint8 *p2cline = malloc(sizeof(Uint8) * ((vw+15) & ~15));
        !          1593:                                Uint8 *hvram_line = hvram;
        !          1594:                                Uint8 *hvram_column = p2cline;
        !          1595: 
        !          1596:                                /* Render the upper border */
        !          1597:                                for (h = 0; h < videl.upperBorderSize * coefy; h++) {
        !          1598:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1599:                                        hvram_line += scrpitch;
        !          1600:                                }
1.1       root     1601: 
1.1.1.8 ! root     1602:                                /* Render the graphical area */
        !          1603:                                for (h = 0; h < scrheight; h++) {
        !          1604: 
        !          1605:                                        fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
        !          1606:                                        scrIdx ++;
        !          1607: 
        !          1608:                                        /* Recopy the same line ? */
        !          1609:                                        if (videl_zoom.zoomytable[h] == cursrcline) {
        !          1610:                                                memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
        !          1611:                                        } else {
        !          1612:                                                Uint16 *fvram_column = fvram_line;
        !          1613:                                                hvram_column = p2cline;
        !          1614: 
        !          1615:                                                /* First 16 pixels of a new line */
        !          1616:                                                VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1617:                                                memcpy(hvram_column, color+hscrolloffset, 16-hscrolloffset);
        !          1618:                                                hvram_column += 16-hscrolloffset;
        !          1619:                                                fvram_column += vbpp;
        !          1620:                                                /* Convert main part of the new line */
        !          1621:                                                for (w=1; w < (vw+15)>>4; w++) {
        !          1622:                                                        VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
        !          1623:                                                        memcpy(hvram_column, color, 16);
        !          1624:                                                        hvram_column += 16;
        !          1625:                                                        fvram_column += vbpp;
        !          1626:                                                }
        !          1627:                                                /* Last pixels of the line for fine scrolling */
        !          1628:                                                if (hscrolloffset) {
        !          1629:                                                        VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1630:                                                        memcpy(hvram_column, color, hscrolloffset);
1.1       root     1631:                                                }
                   1632: 
1.1.1.8 ! root     1633:                                                hvram_column = hvram_line;
        !          1634: 
        !          1635:                                                /* Display the Left border */
        !          1636:                                                VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
        !          1637:                                                hvram_column += videl.leftBorderSize * coefx;
        !          1638: 
        !          1639:                                                /* Display the Graphical area */
        !          1640:                                                for (w=0; w<(vw*coefx); w++)
        !          1641:                                                        hvram_column[w] = p2cline[videl_zoom.zoomxtable[w - videl.leftBorderSize * coefx]];
        !          1642:                                                hvram_column += vw * coefx;
        !          1643: 
        !          1644:                                                /* Display the Right border */
        !          1645:                                                VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
        !          1646:                                                hvram_column += videl.rightBorderSize * coefx;
1.1       root     1647:                                        }
                   1648: 
1.1.1.8 ! root     1649:                                        hvram_line += scrpitch;
        !          1650:                                        cursrcline = videl_zoom.zoomytable[h];
1.1       root     1651:                                }
1.1.1.8 ! root     1652: 
        !          1653:                                /* Render the lower border */
        !          1654:                                for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
        !          1655:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1656:                                        hvram_line += scrpitch;
        !          1657:                                }
        !          1658: 
        !          1659:                                free(p2cline);
        !          1660:                        }
        !          1661:                        break;
1.1       root     1662:                        case 2:
1.1.1.8 ! root     1663:                        {
        !          1664:                                /* One complete 16-pixel aligned planar 2 chunky line */
        !          1665:                                Uint16 *p2cline = malloc(sizeof(Uint16) * ((vw+15) & ~15));
        !          1666:                                Uint16 *hvram_line = (Uint16 *)hvram;
        !          1667:                                Uint16 *hvram_column = p2cline;
        !          1668: 
        !          1669:                                /* Render the upper border */
        !          1670:                                for (h = 0; h < videl.upperBorderSize * coefy; h++) {
        !          1671:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1672:                                        hvram_line += scrpitch>>1;
        !          1673:                                }
        !          1674: 
        !          1675:                                /* Render the graphical area */
        !          1676:                                for (h = 0; h < scrheight; h++) {
        !          1677:                                        fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
        !          1678:                                        scrIdx ++;
        !          1679: 
        !          1680:                                        /* Recopy the same line ? */
        !          1681:                                        if (videl_zoom.zoomytable[h] == cursrcline) {
        !          1682:                                                memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
        !          1683:                                        } else {
        !          1684:                                                Uint16 *fvram_column = fvram_line;
        !          1685:                                                hvram_column = p2cline;
        !          1686: 
        !          1687:                                                /* First 16 pixels of a new line */
        !          1688:                                                VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1689:                                                for (j = 0; j < 16 - hscrolloffset; j++) {
        !          1690:                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !          1691:                                                }
        !          1692:                                                fvram_column += vbpp;
        !          1693:                                                /* Convert the main part of the new line */
        !          1694:                                                for (w = 1; w < (vw+15)>>4; w++) {
        !          1695:                                                        VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
        !          1696:                                                        for (j=0; j<16; j++) {
        !          1697:                                                                *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4   root     1698:                                                        }
                   1699:                                                        fvram_column += vbpp;
1.1.1.8 ! root     1700:                                                }
        !          1701:                                                /* Last pixels of the new line for fine scrolling */
        !          1702:                                                if (hscrolloffset) {
        !          1703:                                                        VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1704:                                                        for (j = 0; j < hscrolloffset; j++) {
        !          1705:                                                                *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1       root     1706:                                                        }
                   1707:                                                }
                   1708: 
1.1.1.8 ! root     1709:                                                hvram_column = hvram_line;
        !          1710: 
        !          1711:                                                /* Display the Left border */
        !          1712:                                                VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
        !          1713:                                                hvram_column += videl.leftBorderSize * coefx;
        !          1714: 
        !          1715:                                                /* Display the Graphical area */
        !          1716:                                                for (w=0; w<(vw*coefx); w++)
        !          1717:                                                        hvram_column[w] = p2cline[videl_zoom.zoomxtable[w]];
        !          1718:                                                hvram_column += vw * coefx;
        !          1719: 
        !          1720:                                                /* Display the Right border */
        !          1721:                                                VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
        !          1722:                                                hvram_column += videl.rightBorderSize * coefx;
1.1       root     1723:                                        }
                   1724: 
1.1.1.8 ! root     1725:                                        hvram_line += scrpitch>>1;
        !          1726:                                        cursrcline = videl_zoom.zoomytable[h];
1.1       root     1727:                                }
1.1.1.8 ! root     1728: 
        !          1729:                                /* Render the lower border */
        !          1730:                                for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
        !          1731:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1732:                                        hvram_line += scrpitch>>1;
        !          1733:                                }
        !          1734: 
        !          1735:                                free(p2cline);
        !          1736:                        }
        !          1737:                        break;
1.1       root     1738:                        case 4:
1.1.1.8 ! root     1739:                        {
        !          1740:                                /* One complete 16-pixel aligned planar 2 chunky line */
        !          1741:                                Uint32 *p2cline = malloc(sizeof(Uint32) * ((vw+15) & ~15));
        !          1742:                                Uint32 *hvram_line = (Uint32 *)hvram;
        !          1743:                                Uint32 *hvram_column = p2cline;
        !          1744: 
        !          1745:                                /* Render the upper border */
        !          1746:                                for (h = 0; h < videl.upperBorderSize * coefy; h++) {
        !          1747:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1748:                                        hvram_line += scrpitch>>2;
        !          1749:                                }
        !          1750: 
        !          1751:                                /* Render the graphical area */
        !          1752:                                for (h = 0; h < scrheight; h++) {
        !          1753:                                        fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
        !          1754:                                        scrIdx ++;
        !          1755:                                        /* Recopy the same line ? */
        !          1756:                                        if (videl_zoom.zoomytable[h] == cursrcline) {
        !          1757:                                                memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
        !          1758:                                        } else {
        !          1759:                                                Uint16 *fvram_column = fvram_line;
        !          1760:                                                hvram_column = p2cline;
        !          1761: 
        !          1762:                                                /* First 16 pixels of a new line */
        !          1763:                                                VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1764:                                                for (j = 0; j < 16 - hscrolloffset; j++) {
        !          1765:                                                        *hvram_column++ = HostScreen_getPaletteColor(color[j+hscrolloffset]);
        !          1766:                                                }
        !          1767:                                                fvram_column += vbpp;
        !          1768:                                                /* Convert the main part of the new line */
        !          1769:                                                for (w = 1; w < (vw+15)>>4; w++) {
        !          1770:                                                        VIDEL_bitplaneToChunky( fvram_column, vbpp, color );
        !          1771:                                                        for (j=0; j<16; j++) {
        !          1772:                                                                *hvram_column++ = HostScreen_getPaletteColor( color[j] );
1.1.1.4   root     1773:                                                        }
                   1774:                                                        fvram_column += vbpp;
1.1.1.8 ! root     1775:                                                }
        !          1776:                                                /* Last pixels of the new line for fine scrolling */
        !          1777:                                                if (hscrolloffset) {
        !          1778:                                                        VIDEL_bitplaneToChunky(fvram_column, vbpp, color);
        !          1779:                                                        for (j = 0; j < hscrolloffset; j++) {
        !          1780:                                                                *hvram_column++ = HostScreen_getPaletteColor(color[j]);
1.1.1.4   root     1781:                                                        }
1.1.1.8 ! root     1782:                                                }
1.1.1.4   root     1783: 
1.1.1.8 ! root     1784:                                                hvram_column = hvram_line;
        !          1785:                                                /* Display the Left border */
        !          1786:                                                VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
        !          1787:                                                hvram_column += videl.leftBorderSize * coefx;
        !          1788: 
        !          1789:                                                /* Display the Graphical area */
        !          1790:                                                for (w=0; w<(vw*coefx); w++) {
        !          1791:                                                        hvram_column[w] = p2cline[videl_zoom.zoomxtable[w]];
1.1       root     1792:                                                }
1.1.1.8 ! root     1793:                                                hvram_column += vw * coefx;
1.1       root     1794: 
1.1.1.8 ! root     1795:                                                /* Display the Right border */
        !          1796:                                                VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
        !          1797:                                                hvram_column += videl.rightBorderSize * coefx;
1.1       root     1798:                                        }
                   1799: 
1.1.1.8 ! root     1800:                                        hvram_line += scrpitch>>2;
        !          1801:                                        cursrcline = videl_zoom.zoomytable[h];
1.1       root     1802:                                }
1.1.1.8 ! root     1803: 
        !          1804:                                /* Render the lower border */
        !          1805:                                for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
        !          1806:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1807:                                        hvram_line += scrpitch>>2;
        !          1808:                                }
        !          1809: 
        !          1810:                                free(p2cline);
        !          1811:                        }
        !          1812:                        break;
1.1       root     1813:                }
                   1814:        } else {
1.1.1.4   root     1815:                /* Falcon high-color (16-bit) mode */
1.1       root     1816: 
                   1817:                switch(scrbpp) {
                   1818:                        case 1:
1.1.1.8 ! root     1819:                        {
        !          1820:                                /* FIXME: when Videl switches to 16bpp, set the palette to 3:3:2 */
        !          1821:                                Uint8 *hvram_line = hvram;
        !          1822:                                Uint8 *hvram_column = hvram_line;
        !          1823: 
        !          1824:                                /* Render the upper border */
        !          1825:                                for (h = 0; h < videl.upperBorderSize * coefy; h++) {
        !          1826:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1827:                                        hvram_line += scrpitch;
        !          1828:                                }
1.1       root     1829: 
1.1.1.8 ! root     1830:                                /* Render the graphical area */
        !          1831:                                for (h = 0; h < scrheight; h++) {
        !          1832:                                        Uint16 *fvram_column;
        !          1833: 
        !          1834:                                        fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
        !          1835:                                        scrIdx ++;
        !          1836: 
        !          1837:                                        fvram_column = fvram_line;
        !          1838: 
        !          1839:                                        /* Recopy the same line ? */
        !          1840:                                        if (videl_zoom.zoomytable[h] == cursrcline) {
        !          1841:                                                memcpy(hvram_line, hvram_line-scrpitch, scrwidth*scrbpp);
        !          1842:                                        } else {
1.1       root     1843: 
1.1.1.8 ! root     1844:                                                hvram_column = hvram_line;
        !          1845:                                                /* Display the Left border */
        !          1846:                                                VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
        !          1847:                                                hvram_column += videl.leftBorderSize * coefx;
        !          1848: 
        !          1849:                                                /* Display the Graphical area */
        !          1850:                                                for (w = 0; w<(vw*coefx); w++) {
        !          1851:                                                        Uint16 srcword;
        !          1852:                                                        Uint8 dstbyte;
1.1       root     1853:                                                        
1.1.1.8 ! root     1854:                                                        srcword = SDL_SwapBE16(fvram_column[videl_zoom.zoomxtable[w - videl.leftBorderSize * coefx]]);
1.1       root     1855: 
1.1.1.8 ! root     1856:                                                        dstbyte = ((srcword>>13) & 7) << 5;
        !          1857:                                                        dstbyte |= ((srcword>>8) & 7) << 2;
        !          1858:                                                        dstbyte |= ((srcword>>2) & 3);
        !          1859:                                                        *hvram_column++ = dstbyte;
1.1       root     1860:                                                }
                   1861: 
1.1.1.8 ! root     1862:                                                /* Display the Right border */
        !          1863:                                                VIDEL_memset_uint8 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
        !          1864:                                                hvram_column += videl.rightBorderSize * coefx;
1.1       root     1865:                                        }
1.1.1.8 ! root     1866: 
        !          1867:                                        hvram_line += scrpitch;
        !          1868:                                        cursrcline = videl_zoom.zoomytable[h];
1.1       root     1869:                                }
1.1.1.8 ! root     1870: 
        !          1871:                                /* Render the lower border */
        !          1872:                                for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
        !          1873:                                        VIDEL_memset_uint8 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1874:                                        hvram_line += scrpitch;
        !          1875:                                }
        !          1876:                        }
        !          1877:                        break;
1.1       root     1878:                        case 2:
1.1.1.8 ! root     1879:                        {
        !          1880:                                Uint16 *hvram_line = (Uint16 *)hvram;
        !          1881:                                Uint16 *hvram_column = hvram_line;
        !          1882: 
        !          1883:                                /* Render the upper border */
        !          1884:                                for (h = 0; h < videl.upperBorderSize * coefy; h++) {
        !          1885:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1886:                                        hvram_line += scrpitch>>1;
        !          1887:                                }
        !          1888: 
        !          1889:                                /* Render the graphical area */
        !          1890:                                for (h = 0; h < scrheight; h++) {
        !          1891:                                        Uint16 *fvram_column;
        !          1892: 
        !          1893:                                        fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
        !          1894:                                        scrIdx ++;
        !          1895: 
        !          1896:                                        fvram_column = fvram_line;
        !          1897: 
        !          1898:                                        /* Recopy the same line ? */
        !          1899:                                        if (videl_zoom.zoomytable[h] == cursrcline) {
        !          1900:                                                memcpy(hvram_line, hvram_line-(scrpitch>>1), scrwidth*scrbpp);
        !          1901:                                        } else {
1.1       root     1902: 
                   1903:                                                hvram_column = hvram_line;
                   1904: 
1.1.1.8 ! root     1905:                                                /* Display the Left border */
        !          1906:                                                VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
        !          1907:                                                hvram_column += videl.leftBorderSize * coefx;
        !          1908: 
        !          1909:                                                /* Display the Graphical area */
        !          1910:                                                for (w=0; w<(vw*coefx); w++)
        !          1911:                                                        *hvram_column++ = SDL_SwapBE16(fvram_column[videl_zoom.zoomxtable[w]]);
        !          1912: 
1.1       root     1913: 
1.1.1.8 ! root     1914:                                                /* Display the Right border */
        !          1915:                                                VIDEL_memset_uint16 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
        !          1916:                                                hvram_column += videl.rightBorderSize * coefx;
1.1       root     1917:                                        }
1.1.1.8 ! root     1918: 
        !          1919:                                        hvram_line += scrpitch>>1;
        !          1920:                                        cursrcline = videl_zoom.zoomytable[h];
1.1       root     1921:                                }
1.1.1.8 ! root     1922: 
        !          1923:                                /* Render the lower border */
        !          1924:                                for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
        !          1925:                                        VIDEL_memset_uint16 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1926:                                        hvram_line += scrpitch>>1;
        !          1927:                                }
        !          1928:                        }
        !          1929:                        break;
1.1       root     1930:                        case 4:
1.1.1.8 ! root     1931:                        {
        !          1932:                                Uint32 *hvram_line = (Uint32 *)hvram;
        !          1933:                                Uint32 *hvram_column = hvram_line;
        !          1934: 
        !          1935:                                /* Render the upper border */
        !          1936:                                for (h = 0; h < videl.upperBorderSize * coefy; h++) {
        !          1937:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1938:                                }
        !          1939: 
        !          1940:                                /* Render the graphical area */
        !          1941:                                for (h = 0; h < scrheight; h++) {
        !          1942:                                        Uint16 *fvram_column;
        !          1943: 
        !          1944:                                        fvram_line = fvram + (videl_zoom.zoomytable[scrIdx] * nextline);
        !          1945:                                        scrIdx ++;
        !          1946:                                        fvram_column = fvram_line;
        !          1947: 
        !          1948:                                        /* Recopy the same line ? */
        !          1949:                                        if (videl_zoom.zoomytable[h] == cursrcline) {
        !          1950:                                                memcpy(hvram_line, hvram_line-(scrpitch>>2), scrwidth*scrbpp);
        !          1951:                                                hvram_line += scrpitch>>2;
        !          1952:                                        } else {
1.1       root     1953: 
                   1954:                                                hvram_column = hvram_line;
                   1955: 
1.1.1.8 ! root     1956:                                                /* Display the Left border */
        !          1957:                                                VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.leftBorderSize * coefx);
        !          1958:                                                hvram_column += videl.leftBorderSize * coefx;
        !          1959: 
        !          1960:                                                /* Display the Graphical area */
        !          1961:                                                for (w = 0; w<(vw*coefx); w++) {
        !          1962:                                                        Uint16 srcword;
1.1       root     1963: 
1.1.1.8 ! root     1964:                                                        srcword = fvram_column[videl_zoom.zoomxtable[w]];
        !          1965:                                                        *hvram_column++ = SDL_MapRGB(scrfmt, (srcword & 0xf8), (((srcword & 0x07) << 5) | ((srcword >> 11) & 0x3c)), ((srcword >> 5) & 0xf8));
1.1       root     1966:                                                }
                   1967: 
1.1.1.8 ! root     1968:                                                /* Display the Right border */
        !          1969:                                                VIDEL_memset_uint32 (hvram_column, HostScreen_getPaletteColor(0), videl.rightBorderSize * coefx);
        !          1970:                                                hvram_column += videl.rightBorderSize * coefx;
1.1       root     1971:                                        }
1.1.1.8 ! root     1972: 
        !          1973:                                        hvram_line += scrpitch>>2;
        !          1974:                                        cursrcline = videl_zoom.zoomytable[h];
1.1       root     1975:                                }
1.1.1.8 ! root     1976: 
        !          1977:                                /* Render the lower border */
        !          1978:                                for (h = 0; h < videl.lowerBorderSize * coefy; h++) {
        !          1979:                                        VIDEL_memset_uint32 (hvram_line, HostScreen_getPaletteColor(0), scrwidth);
        !          1980:                                        hvram_line += scrpitch>>2;
        !          1981:                                }
        !          1982:                        }
        !          1983:                        break;
1.1       root     1984:                }
                   1985:        }
                   1986: }
1.1.1.8 ! root     1987: 
        !          1988: static void VIDEL_memset_uint32(Uint32 *addr, Uint32 color, int count)
        !          1989: {
        !          1990:        while (count-- > 0) {
        !          1991:                *addr++ = color;
        !          1992:        }
        !          1993: }
        !          1994: 
        !          1995: static void VIDEL_memset_uint16(Uint16 *addr, Uint16 color, int count)
        !          1996: {
        !          1997:        while (count-- > 0) {
        !          1998:                *addr++ = color;
        !          1999:        }
        !          2000: }
        !          2001: 
        !          2002: static void VIDEL_memset_uint8(Uint8 *addr, Uint8 color, int count)
        !          2003: {
        !          2004:        memset(addr, color, count);
        !          2005: }

unix.superglobalmegacorp.com

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