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

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

unix.superglobalmegacorp.com

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