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

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
1.1.1.12! root       16: 
1.1.1.6   root       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
1.1.1.12! root       30: 
1.1.1.6   root       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
1.1.1.12! root       39: 
1.1.1.6   root       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
1.1.1.12! root       49: 
1.1.1.6   root       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
1.1.1.12! root       57: 
1.1.1.6   root       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 "screen.h"
1.1.1.12! root       76: #include "screenConvert.h"
        !            77: #include "statusbar.h"
1.1       root       78: #include "stMemory.h"
                     79: #include "videl.h"
1.1.1.10  root       80: #include "video.h"                             /* for bUseHighRes variable, maybe unuseful (Laurent) */
                     81: #include "vdi.h"                               /* for bUseVDIRes variable,  maybe unuseful (Laurent) */
1.1       root       82: 
                     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: static struct videl_s videl;
1.1.1.6   root      107: 
1.1.1.8   root      108: Uint16 vfc_counter;                    /* counter for VFC register $ff82a0 (to be internalized when VIDEL emulation is complete) */
1.1.1.6   root      109: 
1.1.1.12! root      110: /**
        !           111:  * Called upon startup (and via VIDEL_reset())
        !           112:  */
        !           113: void Videl_Init(void)
        !           114: {
        !           115:        videl.hostColorsSync = false;
1.1.1.10  root      116: 
1.1.1.12! root      117:        /* Default resolution to boot with */
        !           118:        videl.save_scrWidth = 640;
        !           119:        videl.save_scrHeight = 480;
        !           120:        videl.save_scrBpp = 4;
        !           121: }
1.1       root      122: 
1.1.1.8   root      123: /**
1.1.1.12! root      124:  *  Called when CPU encounters a RESET instruction.
1.1.1.8   root      125:  */
1.1       root      126: void VIDEL_reset(void)
                    127: {
1.1.1.12! root      128:        Videl_Init();
        !           129:        Screen_SetGenConvSize(videl.save_scrWidth, videl.save_scrHeight,
        !           130:                              ConfigureParams.Screen.nForceBpp, false);
        !           131: 
1.1.1.6   root      132:        videl.bUseSTShifter = false;                            /* Use Falcon color palette by default */
                    133:        videl.reg_ffff8006_save = IoMem_ReadByte(0xff8006);
1.1.1.8   root      134:        videl.monitor_type = videl.reg_ffff8006_save & 0xc0;
1.1       root      135: 
1.1.1.6   root      136:        vfc_counter = 0;
1.1.1.4   root      137: 
                    138:        /* Reset IO register (some are not initialized by TOS) */
                    139:        IoMem_WriteWord(0xff820e, 0);    /* Line offset */
                    140:        IoMem_WriteWord(0xff8264, 0);    /* Horizontal scroll */
1.1.1.8   root      141: 
1.1.1.12! root      142:        /* Init sync mode register */
        !           143:        VIDEL_SyncMode_WriteByte();
1.1       root      144: }
                    145: 
1.1.1.6   root      146: /**
                    147:  * Save/Restore snapshot of local variables ('MemorySnapShot_Store' handles type)
                    148:  */
                    149: void VIDEL_MemorySnapShot_Capture(bool bSave)
                    150: {
                    151:        /* Save/Restore details */
                    152:        MemorySnapShot_Store(&videl, sizeof(videl));
                    153:        MemorySnapShot_Store(&vfc_counter, sizeof(vfc_counter));
                    154: }
                    155: 
                    156: /**
1.1.1.10  root      157:  * Monitor write access to Falcon color palette registers
1.1.1.6   root      158:  */
1.1.1.10  root      159: void VIDEL_FalconColorRegsWrite(void)
1.1       root      160: {
1.1.1.10  root      161:        uint32_t color = IoMem_ReadLong(IoAccessBaseAddress & ~3);
                    162:        color &= 0xfcfc00fc;    /* Unused bits have to be set to 0 */
                    163:        IoMem_WriteLong(IoAccessBaseAddress & ~3, color);
1.1.1.8   root      164:        videl.hostColorsSync = false;
1.1       root      165: }
                    166: 
1.1.1.6   root      167: /**
1.1.1.12! root      168:  * VIDEL_Monitor_WriteByte : Contains memory and monitor configuration.
1.1.1.8   root      169:  *                           This register is read only.
1.1.1.6   root      170:  */
                    171: void VIDEL_Monitor_WriteByte(void)
                    172: {
1.1.1.8   root      173:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8006 Monitor and memory conf write (Read only)\n");
1.1.1.6   root      174:        /* Restore hardware value */
1.1.1.8   root      175: 
1.1.1.6   root      176:        IoMem_WriteByte(0xff8006, videl.reg_ffff8006_save);
                    177: }
                    178: 
                    179: /**
1.1.1.12! root      180:  * VIDEL_SyncMode_WriteByte : Videl synchronization mode.
1.1.1.8   root      181:  *             $FFFF820A [R/W] _______0  .................................. SYNC-MODE
                    182:                                      ||
                    183:                                      |+--Synchronisation [ 0:internal / 1:external ]
                    184:                                      +---Vertical frequency [ Read-only bit ]
                    185:                                          [ Monochrome monitor:0 / Colour monitor:1 ]
                    186:  */
                    187: void VIDEL_SyncMode_WriteByte(void)
                    188: {
                    189:        Uint8 syncMode = IoMem_ReadByte(0xff820a);
                    190:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff820a Sync Mode write: 0x%02x\n", syncMode);
                    191: 
                    192:        if (videl.monitor_type == FALCON_MONITOR_MONO)
                    193:                syncMode &= 0xfd;
                    194:        else
                    195:                syncMode |= 0x2;
1.1.1.12! root      196: 
1.1.1.8   root      197:        IoMem_WriteByte(0xff820a, syncMode);
                    198: }
                    199: 
                    200: /**
                    201:  * Read video address counter and update ff8205/07/09
                    202:  */
                    203: void VIDEL_ScreenCounter_ReadByte(void)
                    204: {
                    205: //     Uint32 addr;    // To be used
                    206:        Uint32 addr = 0; // To be removed
                    207: 
                    208:        // addr = Videl_CalculateAddress();             /* TODO: get current video address */
                    209:        IoMem[0xff8205] = ( addr >> 16 ) & 0xff;
                    210:        IoMem[0xff8207] = ( addr >> 8 ) & 0xff;
                    211:        IoMem[0xff8209] = addr & 0xff;
                    212: 
                    213:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8205/07/09 Sync Mode read: 0x%08x\n", addr);
                    214: }
                    215: 
                    216: /**
                    217:  * Write video address counter
                    218:  */
                    219: void VIDEL_ScreenCounter_WriteByte(void)
                    220: {
                    221:        Uint32 addr_new = 0;
                    222:        Uint8 AddrByte;
                    223: 
                    224:        AddrByte = IoMem[ IoAccessCurrentAddress ];
                    225: 
                    226:        /* Compute the new video address with one modified byte */
                    227:        if ( IoAccessCurrentAddress == 0xff8205 )
                    228:                addr_new = ( addr_new & 0x00ffff ) | ( AddrByte << 16 );
                    229:        else if ( IoAccessCurrentAddress == 0xff8207 )
                    230:                addr_new = ( addr_new & 0xff00ff ) | ( AddrByte << 8 );
                    231:        else if ( IoAccessCurrentAddress == 0xff8209 )
                    232:                addr_new = ( addr_new & 0xffff00 ) | ( AddrByte );
                    233: 
1.1.1.12! root      234:        // TODO: save the value in a table for the final rendering
1.1.1.8   root      235: }
                    236: 
                    237: /**
                    238:  * VIDEL_LineOffset_WriteWord: $FFFF820E [R/W] W _______876543210  Line Offset
                    239:  * How many words are added to the end of display line, i.e. how many words are
                    240:  * 'behind' the display.
                    241:  */
                    242: void VIDEL_LineOffset_WriteWord(void)
                    243: {
1.1.1.9   root      244:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff820e Line Offset write: 0x%04x\n",
                    245:                  IoMem_ReadWord(0xff820e));
1.1.1.8   root      246: }
                    247: 
                    248: /**
                    249:  * VIDEL_Line_Width_WriteWord: $FFFF8210 [R/W] W ______9876543210 Line Width (VWRAP)
                    250:  * Length of display line in words.Or, how many words should be added to
                    251:  * vram counter after every display line.
                    252:  */
                    253: void VIDEL_Line_Width_WriteWord(void)
                    254: {
1.1.1.9   root      255:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8210 Line Width write: 0x%04x\n",
                    256:                  IoMem_ReadWord(0xff8210));
1.1.1.8   root      257: }
                    258: 
                    259: /**
1.1.1.6   root      260:  * Write to video address base high, med and low register (0xff8201/03/0d).
                    261:  * On Falcon, when a program writes to high or med registers, base low register
                    262:  * is reset to zero.
                    263:  */
                    264: void VIDEL_ScreenBase_WriteByte(void)
                    265: {
                    266:        if ((IoAccessCurrentAddress == 0xff8201) || (IoAccessCurrentAddress == 0xff8203)) {
                    267:                /* Reset screen base low register */
                    268:                IoMem[0xff820d] = 0;
                    269:        }
                    270: 
1.1.1.9   root      271:        LOG_TRACE(TRACE_VIDEL, "Videl : $%04x Screen base write: 0x%02x\t (screen: 0x%04x)\n",
                    272:                  IoAccessCurrentAddress, IoMem[IoAccessCurrentAddress],
                    273:                  (IoMem[0xff8201]<<16) + (IoMem[0xff8203]<<8) + IoMem[0xff820d]);
1.1.1.6   root      274: }
                    275: 
                    276: /**
1.1.1.12! root      277:     VIDEL_ST_ShiftModeWriteByte :
1.1.1.6   root      278:        $FFFF8260 [R/W] B  ______10  ST Shift Mode
                    279:                                 ||
                    280:                                 ||                           others   vga
                    281:                                 ||                  $FF8210 $FF82C2 $FF82C2
                    282:                                 00--4BP/320 Pixels=> $0050   $0000   $0005
                    283:                                 01--2BP/640 Pixels=> $0050   $0004   $0009
                    284:                                 10--1BP/640 Pixels=> $0028   $0006   $0008
                    285:                                 11--???/320 Pixels=> $0050   $0000   $0000
                    286: 
                    287:        Writing to this register does the following things:
                    288:                - activate STE palette
                    289:                - sets line width ($ffff8210)
                    290:                - sets video mode in $ffff82c2 (double lines/interlace & cycles/pixel)
                    291:  */
                    292: void VIDEL_ST_ShiftModeWriteByte(void)
                    293: {
                    294:        Uint16 line_width, video_mode;
                    295:        Uint8 st_shiftMode;
                    296: 
                    297:        st_shiftMode = IoMem_ReadByte(0xff8260);
1.1.1.8   root      298:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8260 ST Shift Mode (STSHIFT) write: 0x%02x\n", st_shiftMode);
                    299: 
                    300:        /* Bits 2-7 are set to 0 */
1.1.1.12! root      301:        IoMem_WriteByte(0xff8260, st_shiftMode & 3);
1.1.1.6   root      302: 
                    303:        /* Activate STE palette */
                    304:        videl.bUseSTShifter = true;
                    305: 
                    306:        /*  Compute line width and video mode */
                    307:        switch (st_shiftMode & 0x3) {
                    308:                case 0: /* 4BP/320 Pixels */
                    309:                        line_width = 0x50;
                    310:                        /* half pixels + double lines vs. no scaling */
                    311:                        video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x5 : 0x0;
                    312:                        break;
                    313:                case 1: /* 2BP/640 Pixels */
                    314:                        line_width = 0x50;
                    315:                        /* quarter pixels + double lines vs. half pixels */
                    316:                        video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x9 : 0x4;
                    317:                        break;
                    318:                case 2: /* 1BP/640 Pixels */
                    319:                        line_width = 0x28;
                    320:                        if (videl.monitor_type == FALCON_MONITOR_MONO) {
                    321:                                video_mode = 0x0;
                    322:                                break;
                    323:                        }
                    324:                        /* quarter pixels vs. half pixels + interlace */
                    325:                        video_mode = videl.monitor_type == FALCON_MONITOR_VGA ? 0x8 : 0x6;
                    326:                        break;
                    327:                case 3: /* ???/320 Pixels */
1.1.1.8   root      328:                default:
1.1.1.6   root      329:                        line_width = 0x50;
                    330:                        video_mode = 0x0;
                    331:                        break;
                    332:        }
                    333: 
                    334:        /* Set line width ($FFFF8210) */
1.1.1.12! root      335:        IoMem_WriteWord(0xff8210, line_width);
        !           336: 
1.1.1.6   root      337:        /* Set video mode ($FFFF82C2) */
1.1.1.12! root      338:        IoMem_WriteWord(0xff82c2, video_mode);
1.1.1.6   root      339: }
                    340: 
                    341: /**
1.1.1.8   root      342:     VIDEL_HorScroll64_WriteByte : Horizontal scroll register (0-15)
                    343:                $FFFF8264 [R/W] ________  ................................ H-SCROLL HI
                    344:                                    ||||  [ Shadow register for $FFFF8265 ]
                    345:                                    ++++--Pixel shift [ 0:normal / 1..15:Left shift ]
                    346:                                        [ Change in line-width NOT required ]
                    347:  */
                    348: void VIDEL_HorScroll64_WriteByte(void)
                    349: {
1.1.1.9   root      350:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8264 Horizontal scroll 64 write: 0x%02x\n",
                    351:                  IoMem_ReadByte(0xff8264));
1.1.1.8   root      352: }
                    353: 
                    354: /**
                    355:     VIDEL_HorScroll65_WriteByte : Horizontal scroll register (0-15)
                    356:                $FFFF8265 [R/W] ____3210  .................................H-SCROLL LO
                    357:                                    ||||
                    358:                                    ++++--Pixel [ 0:normal / 1..15:Left shift ]
                    359:                                        [ Change in line-width NOT required ]
                    360:  */
                    361: void VIDEL_HorScroll65_WriteByte(void)
                    362: {
1.1.1.9   root      363:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8265 Horizontal scroll 65 write: 0x%02x\n",
                    364:                  IoMem_ReadByte(0xff8265));
1.1.1.8   root      365: }
                    366: 
                    367: /**
                    368:     VIDEL_Falcon_ShiftMode_WriteWord :
1.1.1.6   root      369:        $FFFF8266 [R/W] W  _____A98_6543210  Falcon Shift Mode (SPSHIFT)
                    370:                                ||| |||||||
1.1.1.8   root      371:                                ||| |||++++- 0..15: Colourbank choice from 256-colour table in 16 colour multiples
                    372:                                ||| ||+----- 8 Bitplanes mode (256 Colors) [0:off / 1:on]
                    373:                                ||| |+------ Vertical Sync [0: internal / 1: external]
                    374:                                ||| +------- Horizontal Sync [0: internal / 1: external]
                    375:                                ||+--------- True-Color-Mode [0:off / 1:on]
                    376:                                |+---------- Overlay-Mode [0:off / 1:on]
                    377:                                +----------- 0: 2-Color-Mode [0:off / 1:on]
1.1.1.6   root      378: 
                    379:        Writing to this register does the following things:
                    380:                - activate Falcon palette
                    381:                - if you set Bits A/8/4 == 0, it selects 16-Color-Falcon-Mode (NOT the
                    382:                  same as ST LOW since Falcon palette is used!)
                    383:                - $8260 register is ignored, you don't need to write here anything
                    384: 
                    385:        Note: 4-Color-Mode isn't realisable with Falcon palette.
                    386:  */
1.1.1.8   root      387: void VIDEL_Falcon_ShiftMode_WriteWord(void)
1.1.1.6   root      388: {
1.1.1.9   root      389:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8266 Falcon Shift Mode (SPSHIFT) write: 0x%04x\n",
                    390:                  IoMem_ReadWord(0xff8266));
1.1.1.6   root      391: 
                    392:        videl.bUseSTShifter = false;
                    393: }
                    394: 
                    395: /**
                    396:  *  Write Horizontal Hold Counter (HHC)
                    397:  */
                    398: void VIDEL_HHC_WriteWord(void)
                    399: {
1.1.1.9   root      400:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8280 Horizontal Hold Counter (HHC) write: 0x%04x\n",
                    401:                  IoMem_ReadWord(0xff8280));
1.1.1.6   root      402: }
                    403: 
                    404: /**
                    405:  *  Write Horizontal Hold Timer (HHT)
                    406:  */
                    407: void VIDEL_HHT_WriteWord(void)
                    408: {
1.1.1.9   root      409:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8282 Horizontal Hold Timer (HHT) write: 0x%04x\n",
                    410:                  IoMem_ReadWord(0xff8282));
1.1.1.6   root      411: }
                    412: 
                    413: /**
                    414:  *  Write Horizontal Border Begin (HBB)
                    415:  */
                    416: void VIDEL_HBB_WriteWord(void)
                    417: {
1.1.1.9   root      418:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8284 Horizontal Border Begin (HBB) write: 0x%04x\n",
                    419:                  IoMem_ReadWord(0xff8284));
1.1.1.6   root      420: }
                    421: 
                    422: /**
                    423:  *  Write Horizontal Border End (HBE)
                    424:  */
                    425: void VIDEL_HBE_WriteWord(void)
                    426: {
1.1.1.9   root      427:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8286 Horizontal Border End (HBE) write: 0x%04x\n",
                    428:                  IoMem_ReadWord(0xff8286));
1.1.1.6   root      429: }
                    430: 
                    431: /**
                    432:  *  Write Horizontal Display Begin (HDB)
1.1.1.8   root      433:        $FFFF8288 [R/W] W ______9876543210  Horizontal Display Begin (HDB)
                    434:                                |
                    435:                                +---------- Display will start in [0: 1st halfline / 1: 2nd halfline]
1.1.1.6   root      436:  */
                    437: void VIDEL_HDB_WriteWord(void)
                    438: {
1.1.1.9   root      439:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8288 Horizontal Display Begin (HDB) write: 0x%04x\n",
                    440:                  IoMem_ReadWord(0xff8288));
1.1.1.6   root      441: }
                    442: 
                    443: /**
                    444:  *  Write Horizontal Display End (HDE)
                    445:  */
                    446: void VIDEL_HDE_WriteWord(void)
                    447: {
1.1.1.9   root      448:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff828a Horizontal Display End (HDE) write: 0x%04x\n",
                    449:                  IoMem_ReadWord(0xff828a));
1.1.1.6   root      450: }
                    451: 
                    452: /**
                    453:  *  Write Horizontal SS (HSS)
                    454:  */
                    455: void VIDEL_HSS_WriteWord(void)
                    456: {
1.1.1.9   root      457:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff828c Horizontal SS (HSS) write: 0x%04x\n",
                    458:                  IoMem_ReadWord(0xff828c));
1.1.1.6   root      459: }
                    460: 
                    461: /**
                    462:  *  Write Horizontal FS (HFS)
                    463:  */
                    464: void VIDEL_HFS_WriteWord(void)
                    465: {
1.1.1.9   root      466:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff828e Horizontal FS (HFS) write: 0x%04x\n",
                    467:                  IoMem_ReadWord(0xff828e));
1.1.1.6   root      468: }
                    469: 
                    470: /**
                    471:  *  Write Horizontal EE (HEE)
                    472:  */
                    473: void VIDEL_HEE_WriteWord(void)
                    474: {
1.1.1.9   root      475:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff8290 Horizontal EE (HEE) write: 0x%04x\n",
                    476:                  IoMem_ReadWord(0xff8290));
1.1.1.6   root      477: }
                    478: 
                    479: /**
                    480:  *  Write Vertical Frequency Counter (VFC)
                    481:  */
                    482: void VIDEL_VFC_ReadWord(void)
                    483: {
                    484:        IoMem_WriteWord(0xff82a0, vfc_counter);
1.1.1.8   root      485:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a0 Vertical Frequency Counter (VFC) read: 0x%04x\n", vfc_counter);
1.1.1.6   root      486: }
                    487: 
                    488: /**
                    489:  *  Write Vertical Frequency Timer (VFT)
                    490:  */
                    491: void VIDEL_VFT_WriteWord(void)
                    492: {
1.1.1.9   root      493:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a2 Vertical Frequency Timer (VFT) write: 0x%04x\n",
                    494:                  IoMem_ReadWord(0xff82a2));
1.1.1.6   root      495: }
                    496: 
                    497: /**
                    498:  *  Write Vertical Border Begin (VBB)
                    499:  */
                    500: void VIDEL_VBB_WriteWord(void)
                    501: {
1.1.1.9   root      502:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a4 Vertical Border Begin (VBB) write: 0x%04x\n",
                    503:                  IoMem_ReadWord(0xff82a4));
1.1.1.6   root      504: }
                    505: 
                    506: /**
                    507:  *  Write Vertical Border End (VBE)
                    508:  */
                    509: void VIDEL_VBE_WriteWord(void)
                    510: {
1.1.1.9   root      511:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a6 Vertical Border End (VBE) write: 0x%04x\n",
                    512:                  IoMem_ReadWord(0xff82a6));
1.1.1.6   root      513: }
                    514: 
                    515: /**
                    516:  *  Write Vertical Display Begin (VDB)
                    517:  */
                    518: void VIDEL_VDB_WriteWord(void)
1.1       root      519: {
1.1.1.9   root      520:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82a8 Vertical Display Begin (VDB) write: 0x%04x\n",
                    521:                  IoMem_ReadWord(0xff82a8));
1.1       root      522: }
                    523: 
1.1.1.6   root      524: /**
                    525:  *  Write Vertical Display End (VDE)
                    526:  */
                    527: void VIDEL_VDE_WriteWord(void)
                    528: {
1.1.1.9   root      529:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82aa Vertical Display End (VDE) write: 0x%04x\n",
                    530:                  IoMem_ReadWord(0xff82aa));
1.1.1.6   root      531: }
                    532: 
                    533: /**
                    534:  *  Write Vertical SS (VSS)
                    535:  */
                    536: void VIDEL_VSS_WriteWord(void)
                    537: {
1.1.1.9   root      538:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82ac Vertical SS (VSS) write: 0x%04x\n",
                    539:                  IoMem_ReadWord(0xff82ac));
1.1.1.6   root      540: }
                    541: 
                    542: /**
                    543:  *  Write Video Control (VCO)
                    544:  */
                    545: void VIDEL_VCO_WriteWord(void)
                    546: {
1.1.1.9   root      547:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c0 Video control (VCO) write: 0x%04x\n",
                    548:                  IoMem_ReadWord(0xff82c0));
1.1.1.6   root      549: }
                    550: 
                    551: /**
                    552:  *  Write Video Mode (VDM)
                    553:  */
                    554: void VIDEL_VMD_WriteWord(void)
                    555: {
1.1.1.9   root      556:        LOG_TRACE(TRACE_VIDEL, "Videl : $ff82c2 Video Mode (VDM) write: 0x%04x\n",
                    557:                  IoMem_ReadWord(0xff82c2));
1.1.1.6   root      558: }
                    559: 
                    560: 
1.1.1.8   root      561: /**
                    562:  *  VIDEL_getVideoramAddress: returns the video RAM address.
                    563:  *  On Falcon, video address must be a multiple of four in bitplane modes.
                    564:  */
                    565: static Uint32 VIDEL_getVideoramAddress(void)
1.1       root      566: {
1.1.1.8   root      567:        Uint32 videoBase;
1.1.1.12! root      568: 
1.1.1.8   root      569:        videoBase  = (Uint32) IoMem_ReadByte(0xff8201) << 16;
                    570:        videoBase |= (Uint32) IoMem_ReadByte(0xff8203) << 8;
                    571:        videoBase |= IoMem_ReadByte(0xff820d) & ~3;
1.1.1.12! root      572: 
1.1.1.8   root      573:        return videoBase;
1.1       root      574: }
                    575: 
1.1.1.8   root      576: static Uint16 VIDEL_getScreenBpp(void)
1.1       root      577: {
1.1.1.8   root      578:        Uint16 f_shift = IoMem_ReadWord(0xff8266);
                    579:        Uint16 bits_per_pixel;
                    580:        Uint8  st_shift = IoMem_ReadByte(0xff8260);
                    581: 
1.1       root      582:        /* to get bpp, we must examine f_shift and st_shift.
1.1.1.12! root      583:         * f_shift is valid if any of bits no. 10, 8 or 4 is set.
1.1.1.8   root      584:         * Priority in f_shift is: 10 ">" 8 ">" 4, i.e.
1.1       root      585:         * if bit 10 set then bit 8 and bit 4 don't care...
                    586:         * If all these bits are 0 and ST shifter is written
                    587:         * after Falcon one, get display depth from st_shift
                    588:         * (as for ST and STE)
                    589:         */
                    590:        if (f_shift & 0x400)            /* Falcon: 2 colors */
                    591:                bits_per_pixel = 1;
                    592:        else if (f_shift & 0x100)       /* Falcon: hicolor */
                    593:                bits_per_pixel = 16;
                    594:        else if (f_shift & 0x010)       /* Falcon: 8 bitplanes */
                    595:                bits_per_pixel = 8;
1.1.1.6   root      596:        else if (!videl.bUseSTShifter)  /* Falcon: 4 bitplanes */
1.1       root      597:                bits_per_pixel = 4;
                    598:        else if (st_shift == 0)
                    599:                bits_per_pixel = 4;
                    600:        else if (st_shift == 0x01)
                    601:                bits_per_pixel = 2;
                    602:        else /* if (st_shift == 0x02) */
                    603:                bits_per_pixel = 1;
                    604: 
1.1.1.8   root      605: /*     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      606: 
                    607:        return bits_per_pixel;
                    608: }
                    609: 
1.1.1.8   root      610: /**
                    611:  *  VIDEL_getScreenWidth : returns the visible X resolution
                    612:  *     left border + graphic area + right border
                    613:  *     left border  : hdb - hbe-offset
                    614:  *     right border : hbb - hde-offset
1.1.1.12! root      615:  *     Graphics display : starts at cycle HDB and ends at cycle HDE.
1.1.1.8   root      616:  */
1.1       root      617: static int VIDEL_getScreenWidth(void)
                    618: {
1.1.1.9   root      619:        Uint16 hbb, hbe, hdb, hde, vdm, hht;
                    620:        Uint16 cycPerPixel, divider;
                    621:        Sint16 hdb_offset, hde_offset;
                    622:        Sint16 leftBorder, rightBorder;
1.1.1.8   root      623:        Uint16 bpp = VIDEL_getScreenBpp();
                    624: 
                    625:        /* X Size of the Display area */
                    626:        videl.XSize = (IoMem_ReadWord(0xff8210) & 0x03ff) * 16 / bpp;
                    627: 
                    628:        /* If the user disabled the borders display from the gui, we suppress them */
                    629:        if (ConfigureParams.Screen.bAllowOverscan == 0) {
                    630:                videl.leftBorderSize = 0;
                    631:                videl.rightBorderSize = 0;
                    632:                return videl.XSize;
                    633:        }
                    634: 
                    635:        /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
                    636:         * HDB and HDE have no significance and no border is displayed.
                    637:         */
                    638:        if (videl.monitor_type == FALCON_MONITOR_MONO) {
                    639:                videl.leftBorderSize = 0;
                    640:                videl.rightBorderSize = 0;
                    641:                return videl.XSize;
                    642:        }
                    643: 
1.1.1.9   root      644:        hbb = IoMem_ReadWord(0xff8284) & 0x01ff;
                    645:        hbe = IoMem_ReadWord(0xff8286) & 0x01ff;
                    646:        hdb = IoMem_ReadWord(0xff8288) & 0x01ff;
                    647:        hde = IoMem_ReadWord(0xff828a) & 0x01ff;
                    648:        vdm = IoMem_ReadWord(0xff82c2) & 0xc;
                    649:        hht = IoMem_ReadWord(0xff8282) & 0x1ff;
1.1.1.8   root      650: 
                    651:        /* Compute cycles per pixel */
                    652:        if (vdm == 0)
                    653:                cycPerPixel = 4;
                    654:        else if (vdm == 4)
                    655:                cycPerPixel = 2;
                    656:        else
                    657:                cycPerPixel = 1;
                    658: 
                    659:        /* Compute the divider */
                    660:        if (videl.monitor_type == FALCON_MONITOR_VGA) {
                    661:                if (cycPerPixel == 4)
                    662:                        divider = 4;
                    663:                else
                    664:                        divider = 2;
                    665:        }
                    666:        else if (videl.bUseSTShifter == true) {
                    667:                divider = 16;
                    668:        }
                    669:        else {
                    670:                divider = cycPerPixel;
                    671:        }
                    672: 
                    673:        /* Compute hdb_offset and hde_offset */
                    674:        if (videl.bUseSTShifter == false) {
                    675:                if (bpp < 16) {
                    676:                        /* falcon mode bpp */
                    677:                        hdb_offset = ((64+(128/bpp + 16 + 2) * cycPerPixel) / divider ) + 1;
                    678:                        hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
                    679:                }
                    680:                else {
                    681:                        /* falcon mode true color */
                    682:                        hdb_offset = ((64 + 16 * cycPerPixel) / divider ) + 1;
                    683:                        hde_offset = 0;
                    684:                }
                    685:        }
                    686:        else {
                    687:                /* ST bitplan mode */
                    688:                hdb_offset = ((128+(128/bpp + 2) * cycPerPixel) / divider ) + 1;
                    689:                hde_offset = ((128/bpp + 2) * cycPerPixel) / divider;
                    690:        }
                    691: 
                    692:        LOG_TRACE(TRACE_VIDEL, "hdb_offset=%04x,    hde_offset=%04x\n", hdb_offset, hde_offset);
                    693: 
                    694:        /* Compute left border size in cycles */
                    695:        if (IoMem_ReadWord(0xff8288) & 0x0200)
                    696:                leftBorder = hdb - hbe + hdb_offset - hht - 2;
                    697:        else
                    698:                leftBorder = hdb - hbe + hdb_offset;
                    699: 
                    700:        /* Compute right border size in cycles */
                    701:        rightBorder = hbb - hde_offset - hde;
                    702: 
                    703:        videl.leftBorderSize = leftBorder / cycPerPixel;
                    704:        videl.rightBorderSize = rightBorder / cycPerPixel;
                    705:        LOG_TRACE(TRACE_VIDEL, "left border size=%04x,    right border size=%04x\n", videl.leftBorderSize, videl.rightBorderSize);
                    706: 
                    707:        if (videl.leftBorderSize < 0) {
                    708: //             fprintf(stderr, "BORDER LEFT < 0   %d\n", videl.leftBorderSize);
                    709:                videl.leftBorderSize = 0;
                    710:        }
                    711:        if (videl.rightBorderSize < 0) {
                    712: //             fprintf(stderr, "BORDER RIGHT < 0   %d\n", videl.rightBorderSize);
                    713:                videl.rightBorderSize = 0;
                    714:        }
                    715: 
                    716:        return videl.leftBorderSize + videl.XSize + videl.rightBorderSize;
1.1       root      717: }
                    718: 
1.1.1.8   root      719: /**
                    720:  *  VIDEL_getScreenHeight : returns the visible Y resolution
                    721:  *     upper border + graphic area + lower border
                    722:  *     upper border : vdb - vbe
                    723:  *     lower border : vbb - vde
1.1.1.12! root      724:  *     Graphics display : starts at line VDB and ends at line VDE.
1.1.1.8   root      725:  *     If interlace mode off unit of VC-registers is half lines, else lines.
                    726:  */
1.1       root      727: static int VIDEL_getScreenHeight(void)
                    728: {
1.1.1.8   root      729:        Uint16 vbb = IoMem_ReadWord(0xff82a4) & 0x07ff;
1.1.1.12! root      730:        Uint16 vbe = IoMem_ReadWord(0xff82a6) & 0x07ff;
1.1.1.8   root      731:        Uint16 vdb = IoMem_ReadWord(0xff82a8) & 0x07ff;
                    732:        Uint16 vde = IoMem_ReadWord(0xff82aa) & 0x07ff;
                    733:        Uint16 vmode = IoMem_ReadWord(0xff82c2);
                    734: 
                    735:        /* According to Aura and Animal Mine doc about Videl, if a monochrome monitor is connected,
                    736:         * VDB and VDE have no significance and no border is displayed.
1.1       root      737:         */
1.1.1.8   root      738:        if (videl.monitor_type == FALCON_MONITOR_MONO) {
                    739:                videl.upperBorderSize = 0;
                    740:                videl.lowerBorderSize = 0;
                    741:        }
                    742:        else {
                    743:                /* We must take the positive value only, as a program like AceTracker starts the */
                    744:                /* graphical area 1 line before the end of the upper border */
                    745:                videl.upperBorderSize = vdb - vbe > 0 ? vdb - vbe : 0;
                    746:                videl.lowerBorderSize = vbb - vde > 0 ? vbb - vde : 0;
                    747:        }
1.1       root      748: 
1.1.1.8   root      749:        /* Y Size of the Display area */
1.1.1.9   root      750:        if (vde >= vdb) {
                    751:                videl.YSize = vde - vdb;
                    752:        }
                    753:        else {
                    754:                LOG_TRACE(TRACE_VIDEL, "WARNING: vde=0x%x is less than vdb=0x%x\n",
                    755:                          vde, vdb);
                    756:        }
1.1.1.8   root      757: 
                    758:        /* If the user disabled the borders display from the gui, we suppress them */
                    759:        if (ConfigureParams.Screen.bAllowOverscan == 0) {
                    760:                videl.upperBorderSize = 0;
                    761:                videl.lowerBorderSize = 0;
                    762:        }
                    763: 
                    764:        if (!(vmode & 0x02)){           /* interlace */
                    765:                videl.YSize >>= 1;
                    766:                videl.upperBorderSize >>= 1;
                    767:                videl.lowerBorderSize >>= 1;
                    768:        }
1.1.1.12! root      769: 
1.1.1.8   root      770:        if (vmode & 0x01) {             /* double */
                    771:                videl.YSize >>= 1;
                    772:                videl.upperBorderSize >>= 1;
                    773:                videl.lowerBorderSize >>= 1;
                    774:        }
1.1.1.9   root      775: 
1.1.1.8   root      776:        return videl.upperBorderSize + videl.YSize + videl.lowerBorderSize;
1.1       root      777: }
                    778: 
                    779: 
1.1.1.12! root      780: /**
        !           781:  * Map the correct colortable into the correct pixel format
1.1       root      782:  */
1.1.1.12! root      783: void VIDEL_UpdateColors(void)
1.1       root      784: {
1.1.1.8   root      785:        int i, r, g, b, colors = 1 << videl.save_scrBpp;
1.1       root      786: 
1.1.1.12! root      787:        if (videl.hostColorsSync)
        !           788:                return;
        !           789: 
1.1.1.8   root      790: #define F_COLORS(i) IoMem_ReadByte(VIDEL_COLOR_REGS_BEGIN + (i))
                    791: #define STE_COLORS(i)  IoMem_ReadByte(0xff8240 + (i))
1.1       root      792: 
1.1.1.12! root      793:        /* True color mode ? */
        !           794:        if (videl.save_scrBpp > 8) {
        !           795:                /* Videl color 0 ($ffff9800) must be taken into account as it is the border color in true color mode */
        !           796:                r = F_COLORS(0) & 0xfc;
        !           797:                r |= r>>6;
        !           798:                g = F_COLORS(0 + 1) & 0xfc;
        !           799:                g |= g>>6;
        !           800:                b = F_COLORS(0 + 3) & 0xfc;
        !           801:                b |= b>>6;
        !           802:                Screen_SetPaletteColor(0, r,g,b);
        !           803:                return;
        !           804:        }
        !           805: 
1.1.1.6   root      806:        if (!videl.bUseSTShifter) {
1.1       root      807:                for (i = 0; i < colors; i++) {
                    808:                        int offset = i << 2;
                    809:                        r = F_COLORS(offset) & 0xfc;
                    810:                        r |= r>>6;
                    811:                        g = F_COLORS(offset + 1) & 0xfc;
                    812:                        g |= g>>6;
                    813:                        b = F_COLORS(offset + 3) & 0xfc;
                    814:                        b |= b>>6;
1.1.1.12! root      815:                        Screen_SetPaletteColor(i, r,g,b);
1.1       root      816:                }
                    817:        } else {
                    818:                for (i = 0; i < colors; i++) {
                    819:                        int offset = i << 1;
                    820:                        r = STE_COLORS(offset) & 0x0f;
                    821:                        r = ((r & 7)<<1)|(r>>3);
                    822:                        r |= r<<4;
                    823:                        g = (STE_COLORS(offset + 1)>>4) & 0x0f;
                    824:                        g = ((g & 7)<<1)|(g>>3);
                    825:                        g |= g<<4;
                    826:                        b = STE_COLORS(offset + 1) & 0x0f;
                    827:                        b = ((b & 7)<<1)|(b>>3);
                    828:                        b |= b<<4;
1.1.1.12! root      829:                        Screen_SetPaletteColor(i, r,g,b);
1.1       root      830:                }
                    831:        }
                    832: 
1.1.1.8   root      833:        videl.hostColorsSync = true;
1.1       root      834: }
                    835: 
                    836: 
1.1.1.12! root      837: /* User selected another zoom mode, so set a new screen resolution now */
1.1.1.11  root      838: void VIDEL_ZoomModeChanged(bool bForceChange)
1.1       root      839: {
1.1.1.12! root      840:        int bpp = videl.save_scrBpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp;
        !           841: 
        !           842:        Screen_SetGenConvSize(videl.save_scrWidth, videl.save_scrHeight,
        !           843:                              bpp, bForceChange);
1.1       root      844: }
                    845: 
                    846: 
1.1.1.2   root      847: bool VIDEL_renderScreen(void)
1.1       root      848: {
1.1.1.8   root      849:        /* Atari screen infos */
1.1       root      850:        int vw   = VIDEL_getScreenWidth();
                    851:        int vh   = VIDEL_getScreenHeight();
                    852:        int vbpp = VIDEL_getScreenBpp();
1.1.1.8   root      853: 
                    854:        int lineoffset = IoMem_ReadWord(0xff820e) & 0x01ff; /* 9 bits */
                    855:        int linewidth = IoMem_ReadWord(0xff8210) & 0x03ff;  /* 10 bits */
1.1.1.12! root      856:        int hscrolloffset = IoMem_ReadByte(0xff8265) & 0x0f;
1.1.1.9   root      857:        int nextline;
1.1.1.8   root      858: 
1.1.1.6   root      859:        bool change = false;
1.1       root      860: 
1.1.1.9   root      861:        videl.videoBaseAddr = VIDEL_getVideoramAddress(); // Todo: to be removed when all code is in Videl
                    862: 
1.1.1.8   root      863:        if (vw > 0 && vw != videl.save_scrWidth) {
                    864:                LOG_TRACE(TRACE_VIDEL, "Videl : width change from %d to %d\n", videl.save_scrWidth, vw);
                    865:                videl.save_scrWidth = vw;
1.1.1.6   root      866:                change = true;
1.1       root      867:        }
1.1.1.8   root      868:        if (vh > 0 && vh != videl.save_scrHeight) {
                    869:                LOG_TRACE(TRACE_VIDEL, "Videl : height change from %d to %d\n", videl.save_scrHeight, vh);
                    870:                videl.save_scrHeight = vh;
1.1.1.6   root      871:                change = true;
1.1       root      872:        }
1.1.1.8   root      873:        if (vbpp != videl.save_scrBpp) {
                    874:                LOG_TRACE(TRACE_VIDEL, "Videl : bpp change from %d to %d\n", videl.save_scrBpp, vbpp);
                    875:                videl.save_scrBpp = vbpp;
1.1.1.6   root      876:                change = true;
                    877:        }
                    878:        if (change) {
1.1.1.8   root      879:                LOG_TRACE(TRACE_VIDEL, "Videl : video mode change to %dx%d@%d\n", videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp);
1.1.1.12! root      880:                Screen_SetGenConvSize(videl.save_scrWidth, videl.save_scrHeight, videl.save_scrBpp == 16 ? 16 : ConfigureParams.Screen.nForceBpp, false);
1.1       root      881:        }
                    882: 
1.1.1.12! root      883:        if (vw < 32 || vh < 32) {
        !           884:                LOG_TRACE(TRACE_VIDEL, "Videl : %dx%d screen size, not drawing\n", vw, vh);
        !           885:                return false;
        !           886:        }
        !           887: 
        !           888:        if (!Screen_Lock())
1.1.1.2   root      889:                return false;
1.1       root      890: 
1.1.1.12! root      891:        /*
        !           892:           I think this implementation is naive:
1.1.1.8   root      893:           indeed, I suspect that we should instead skip lineoffset
                    894:           words each time we have read "more" than linewidth words
                    895:           (possibly "more" because of the number of bit planes).
                    896:           Moreover, the 1 bit plane mode is particular;
                    897:           while doing some experiments on my Falcon, it seems to
                    898:           behave like the 4 bit planes mode.
                    899:           At last, we have also to take into account the 4 bits register
                    900:           located at the word $ffff8264 (bit offset). This register makes
                    901:           the semantics of the lineoffset register change a little.
                    902:           int bitoffset = IoMem_ReadWord(0xff8264) & 0x000f;
                    903:           The meaning of this register in True Color mode is not clear
                    904:           for me at the moment (and my experiments on the Falcon don't help
                    905:           me).
                    906:        */
1.1.1.9   root      907:        nextline = linewidth + lineoffset;
1.1.1.8   root      908: 
1.1.1.12! root      909:        VIDEL_UpdateColors();
1.1.1.8   root      910: 
1.1.1.12! root      911:        Screen_GenConvert(&STRam[videl.videoBaseAddr], videl.XSize, videl.YSize,
        !           912:                          videl.save_scrBpp, nextline, hscrolloffset,
        !           913:                          videl.leftBorderSize, videl.rightBorderSize,
        !           914:                          videl.upperBorderSize, videl.lowerBorderSize);
1.1       root      915: 
1.1.1.12! root      916:        Screen_UnLock();
        !           917:        Screen_GenConvUpdate(Statusbar_Update(sdlscrn, false), false);
1.1.1.2   root      918: 
                    919:        return true;
1.1       root      920: }
                    921: 
                    922: 
1.1.1.4   root      923: /**
1.1.1.10  root      924:  * Write to videl ST palette registers (0xff8240-0xff825e)
                    925:  *
                    926:  * Note that there's a special "strange" case when writing only to the upper byte
                    927:  * of the color reg (instead of writing 16 bits at once with .W/.L).
                    928:  * In that case, the byte written to address x is automatically written
                    929:  * to address x+1 too (but we shouldn't copy x in x+1 after masking x ; we apply the mask at the end)
                    930:  * Similarly, when writing a byte to address x+1, it's also written to address x
                    931:  * So :        move.w #0,$ff8240       -> color 0 is now $000
                    932:  *     move.b #7,$ff8240       -> color 0 is now $707 !
                    933:  *     move.b #$55,$ff8241     -> color 0 is now $555 !
                    934:  *     move.b #$71,$ff8240     -> color 0 is now $171 (bytes are first copied, then masked)
                    935:  */
1.1.1.11  root      936: static void Videl_ColorReg_WriteWord(void)
1.1.1.10  root      937: {
                    938:        Uint16 col;
                    939:        Uint32 addr = IoAccessCurrentAddress;
                    940: 
                    941:        videl.hostColorsSync = false;
                    942: 
                    943:        if (bUseHighRes || bUseVDIRes)               /* Don't store if hi-res or VDI resolution */
                    944:                return;
                    945: 
1.1.1.12! root      946:        /* Handle special case when writing only to the lower or
        !           947:         * upper byte of the color reg: copy written byte also
        !           948:         * to the other byte before masking the color value.
        !           949:         */
        !           950:        if (nIoMemAccessSize == SIZE_BYTE)
        !           951:                col = (IoMem_ReadByte(addr) << 8) + IoMem_ReadByte(addr);
1.1.1.10  root      952:        /* Usual case, writing a word or a long (2 words) */
1.1.1.12! root      953:        else
1.1.1.10  root      954:                col = IoMem_ReadWord(addr);
                    955: 
                    956:        col &= 0xfff;                           /* Mask off to 4096 palette */
                    957: 
                    958:        addr &= 0xfffffffe;                     /* Ensure addr is even to store the 16 bit color */
                    959: 
                    960:        IoMem_WriteWord(addr, col);
                    961: }
                    962: 
                    963: /*
                    964:  * [NP] TODO : due to how .L accesses are handled in ioMem.c, we can't call directly
                    965:  * Video_ColorReg_WriteWord from ioMemTabFalcon.c, we must use an intermediate
                    966:  * function, else .L accesses will not change 2 .W color regs, but only one.
                    967:  * This should be changed in ioMem.c to do 2 separate .W accesses, as would do a real 68000
                    968:  */
                    969: 
                    970: void Videl_Color0_WriteWord(void)
                    971: {
                    972:        Videl_ColorReg_WriteWord();
                    973: }
                    974: 
                    975: void Videl_Color1_WriteWord(void)
                    976: {
                    977:        Videl_ColorReg_WriteWord();
                    978: }
                    979: 
                    980: void Videl_Color2_WriteWord(void)
                    981: {
                    982:        Videl_ColorReg_WriteWord();
                    983: }
                    984: 
                    985: void Videl_Color3_WriteWord(void)
                    986: {
                    987:        Videl_ColorReg_WriteWord();
                    988: }
                    989: 
                    990: void Videl_Color4_WriteWord(void)
                    991: {
                    992:        Videl_ColorReg_WriteWord();
                    993: }
                    994: 
                    995: void Videl_Color5_WriteWord(void)
                    996: {
                    997:        Videl_ColorReg_WriteWord();
                    998: }
                    999: 
                   1000: void Videl_Color6_WriteWord(void)
                   1001: {
                   1002:        Videl_ColorReg_WriteWord();
                   1003: }
                   1004: 
                   1005: void Videl_Color7_WriteWord(void)
                   1006: {
                   1007:        Videl_ColorReg_WriteWord();
                   1008: }
                   1009: 
                   1010: void Videl_Color8_WriteWord(void)
                   1011: {
                   1012:        Videl_ColorReg_WriteWord();
                   1013: }
                   1014: 
                   1015: void Videl_Color9_WriteWord(void)
                   1016: {
                   1017:        Videl_ColorReg_WriteWord();
                   1018: }
                   1019: 
                   1020: void Videl_Color10_WriteWord(void)
                   1021: {
                   1022:        Videl_ColorReg_WriteWord();
                   1023: }
                   1024: 
                   1025: void Videl_Color11_WriteWord(void)
                   1026: {
                   1027:        Videl_ColorReg_WriteWord();
                   1028: }
                   1029: 
                   1030: void Videl_Color12_WriteWord(void)
                   1031: {
                   1032:        Videl_ColorReg_WriteWord();
                   1033: }
                   1034: 
                   1035: void Videl_Color13_WriteWord(void)
                   1036: {
                   1037:        Videl_ColorReg_WriteWord();
                   1038: }
                   1039: 
                   1040: void Videl_Color14_WriteWord(void)
                   1041: {
                   1042:        Videl_ColorReg_WriteWord();
                   1043: }
                   1044: 
                   1045: void Videl_Color15_WriteWord(void)
                   1046: {
                   1047:        Videl_ColorReg_WriteWord();
                   1048: }
                   1049: 
                   1050: /**
                   1051:  * display Videl registers values (for debugger info command)
                   1052:  */
1.1.1.11  root     1053: void Videl_Info(FILE *fp, Uint32 dummy)
1.1.1.10  root     1054: {
                   1055:        if (ConfigureParams.System.nMachineType != MACHINE_FALCON) {
1.1.1.11  root     1056:                fprintf(fp, "Not Falcon - no Videl!\n");
1.1.1.10  root     1057:                return;
                   1058:        }
                   1059: 
1.1.1.11  root     1060:        fprintf(fp, "$FF8006.b : monitor type                     : %02x\n", IoMem_ReadByte(0xff8006));
                   1061:        fprintf(fp, "$FF8201.b : Video Base Hi                    : %02x\n", IoMem_ReadByte(0xff8201));
                   1062:        fprintf(fp, "$FF8203.b : Video Base Mi                    : %02x\n", IoMem_ReadByte(0xff8203));
                   1063:        fprintf(fp, "$FF8205.b : Video Count Hi                   : %02x\n", IoMem_ReadByte(0xff8205));
                   1064:        fprintf(fp, "$FF8207.b : Video Count Mi                   : %02x\n", IoMem_ReadByte(0xff8207));
                   1065:        fprintf(fp, "$FF8209.b : Video Count Lo                   : %02x\n", IoMem_ReadByte(0xff8209));
                   1066:        fprintf(fp, "$FF820A.b : Sync mode                        : %02x\n", IoMem_ReadByte(0xff820a));
                   1067:        fprintf(fp, "$FF820D.b : Video Base Lo                    : %02x\n", IoMem_ReadByte(0xff820d));
                   1068:        fprintf(fp, "$FF820E.w : offset to next line              : %04x\n", IoMem_ReadWord(0xff820e));
                   1069:        fprintf(fp, "$FF8210.w : VWRAP - line width               : %04x\n", IoMem_ReadWord(0xff8210));
                   1070:        fprintf(fp, "$FF8260.b : ST shift mode                    : %02x\n", IoMem_ReadByte(0xff8260));
                   1071:        fprintf(fp, "$FF8264.w : Horizontal scroll register       : %04x\n", IoMem_ReadWord(0xff8264));
                   1072:        fprintf(fp, "$FF8266.w : Falcon shift mode                : %04x\n", IoMem_ReadWord(0xff8266));
                   1073:        fprintf(fp, "\n");
                   1074:        fprintf(fp, "$FF8280.w : HHC - Horizontal Hold Counter    : %04x\n", IoMem_ReadWord(0xff8280));
                   1075:        fprintf(fp, "$FF8282.w : HHT - Horizontal Hold Timer      : %04x\n", IoMem_ReadWord(0xff8282));
                   1076:        fprintf(fp, "$FF8284.w : HBB - Horizontal Border Begin    : %04x\n", IoMem_ReadWord(0xff8284));
                   1077:        fprintf(fp, "$FF8286.w : HBE - Horizontal Border End      : %04x\n", IoMem_ReadWord(0xff8286));
                   1078:        fprintf(fp, "$FF8288.w : HDB - Horizontal Display Begin   : %04x\n", IoMem_ReadWord(0xff8288));
                   1079:        fprintf(fp, "$FF828A.w : HDE - Horizontal Display End     : %04x\n", IoMem_ReadWord(0xff828a));
                   1080:        fprintf(fp, "$FF828C.w : HSS - Horizontal SS              : %04x\n", IoMem_ReadWord(0xff828c));
                   1081:        fprintf(fp, "$FF828E.w : HFS - Horizontal FS              : %04x\n", IoMem_ReadWord(0xff828e));
                   1082:        fprintf(fp, "$FF8290.w : HEE - Horizontal EE              : %04x\n", IoMem_ReadWord(0xff8290));
                   1083:        fprintf(fp, "\n");
                   1084:        fprintf(fp, "$FF82A0.w : VFC - Vertical Frequency Counter : %04x\n", IoMem_ReadWord(0xff82a0));
                   1085:        fprintf(fp, "$FF82A2.w : VFT - Vertical Frequency Timer   : %04x\n", IoMem_ReadWord(0xff82a2));
                   1086:        fprintf(fp, "$FF82A4.w : VBB - Vertical Border Begin      : %04x\n", IoMem_ReadWord(0xff82a4));
                   1087:        fprintf(fp, "$FF82A6.w : VBE - Vertical Border End        : %04x\n", IoMem_ReadWord(0xff82a6));
                   1088:        fprintf(fp, "$FF82A8.w : VDB - Vertical Display Begin     : %04x\n", IoMem_ReadWord(0xff82a8));
                   1089:        fprintf(fp, "$FF82AA.w : VDE - Vertical Display End       : %04x\n", IoMem_ReadWord(0xff82aa));
                   1090:        fprintf(fp, "$FF82AC.w : VSS - Vertical SS                : %04x\n", IoMem_ReadWord(0xff82ac));
                   1091:        fprintf(fp, "\n");
                   1092:        fprintf(fp, "$FF82C0.w : VCO - Video control              : %04x\n", IoMem_ReadWord(0xff82c0));
                   1093:        fprintf(fp, "$FF82C2.w : VMD - Video mode                 : %04x\n", IoMem_ReadWord(0xff82c2));
                   1094:        fprintf(fp, "\n-------------------------\n");
1.1.1.10  root     1095: 
1.1.1.11  root     1096:        fprintf(fp, "Video base  : %08x\n",
1.1.1.12! root     1097:                (IoMem_ReadByte(0xff8201)<<16) +
        !          1098:                (IoMem_ReadByte(0xff8203)<<8)  +
1.1.1.10  root     1099:                 IoMem_ReadByte(0xff820d));
1.1.1.11  root     1100:        fprintf(fp, "Video count : %08x\n",
1.1.1.12! root     1101:                (IoMem_ReadByte(0xff8205)<<16) +
        !          1102:                (IoMem_ReadByte(0xff8207)<<8)  +
1.1.1.10  root     1103:                 IoMem_ReadByte(0xff8209));
                   1104: }

unix.superglobalmegacorp.com

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