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

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

unix.superglobalmegacorp.com

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