Annotation of hatari/src/blitter.c, revision 1.1.1.15

1.1.1.2   root        1: /*
1.1.1.3   root        2:  * Hatari - blitter.c
1.1.1.2   root        3:  *
1.1.1.12  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.1.2   root        6:  *
1.1.1.7   root        7:  * Blitter emulation. The 'Blitter' chip is found in the Mega-ST, STE/Mega-STE
                      8:  * and Falcon. It provides a very fast BitBlit function in hardware.
1.1       root        9:  *
1.1.1.7   root       10:  * This file has originally been taken from STonX, but it has been completely
                     11:  * modified for better maintainability and higher compatibility.
1.1.1.8   root       12:  *
                     13:  * NOTES:
                     14:  * ----------------------------------------------------------------------------
                     15:  * Strange end mask condition ((~(0xffff>>skew)) > end_mask_1)
                     16:  *
                     17:  * """Similarly the  NFSR (aka  post-flush) bit, when set, will prevent the last
                     18:  * source read of the  line. This read  may not  be necessary  with certain
                     19:  * combinations of end masks and skews."""
                     20:  *     - doesn't mean the blitter will skip source read by itself, just a hint
                     21:  *       for developers as far as i understand it.
                     22:  * ----------------------------------------------------------------------------
                     23:  * Does smudge mode change the line register ?
                     24:  * ----------------------------------------------------------------------------
1.1       root       25:  */
1.1.1.9   root       26: 
1.1.1.8   root       27: const char Blitter_fileid[] = "Hatari blitter.c : " __DATE__ " " __TIME__;
1.1       root       28: 
                     29: #include <SDL_types.h>
                     30: #include <stdio.h>
                     31: #include <stdlib.h>
                     32: 
1.1.1.2   root       33: #include "main.h"
1.1       root       34: #include "blitter.h"
1.1.1.7   root       35: #include "configuration.h"
                     36: #include "dmaSnd.h"
1.1.1.3   root       37: #include "ioMem.h"
                     38: #include "m68000.h"
1.1.1.7   root       39: #include "mfp.h"
1.1.1.2   root       40: #include "memorySnapShot.h"
1.1       root       41: #include "stMemory.h"
1.1.1.11  root       42: #include "screen.h"
1.1.1.7   root       43: #include "video.h"
                     44: 
1.1.1.8   root       45: /* Cycles to run for in non-hog mode */
                     46: #define NONHOG_CYCLES  (64*4)
1.1       root       47: 
1.1.1.8   root       48: /* BLiTTER registers, incs are signed, others unsigned */
                     49: #define REG_HT_RAM             0xff8a00        /* - 0xff8a1e */
1.1       root       50: 
1.1.1.4   root       51: #define REG_SRC_X_INC  0xff8a20
                     52: #define REG_SRC_Y_INC  0xff8a22
                     53: #define REG_SRC_ADDR   0xff8a24
                     54: 
                     55: #define REG_END_MASK1  0xff8a28
                     56: #define REG_END_MASK2  0xff8a2a
                     57: #define REG_END_MASK3  0xff8a2c
                     58: 
                     59: #define REG_DST_X_INC  0xff8a2e
                     60: #define REG_DST_Y_INC  0xff8a30
                     61: #define REG_DST_ADDR   0xff8a32
                     62: 
1.1.1.7   root       63: #define REG_X_COUNT    0xff8a36
                     64: #define REG_Y_COUNT    0xff8a38
1.1.1.4   root       65: 
                     66: #define REG_BLIT_HOP   0xff8a3a        /* halftone blit operation byte */
                     67: #define REG_BLIT_LOP   0xff8a3b        /* logical blit operation byte */
1.1.1.7   root       68: #define REG_CONTROL    0xff8a3c
1.1.1.8   root       69: #define REG_SKEW               0xff8a3d
1.1.1.4   root       70: 
1.1.1.14  root       71: 
                     72: #define        BLITTER_READ_WORD_BUS_ERR       0x0000  /* This value is returned when the blitter try to read a word */
                     73:                                                /* in a region that would cause a bus error */
                     74:                                                /* [NP] FIXME : for now we return a constant, but it should depend on the bus activity */
                     75: 
1.1.1.8   root       76: /* Blitter registers */
                     77: typedef struct
                     78: {
                     79:        Uint32  src_addr;
                     80:        Uint32  dst_addr;
                     81:        Uint32  words;
                     82:        Uint32  lines;
                     83:        short   src_x_incr;
                     84:        short   src_y_incr;
                     85:        short   dst_x_incr;
                     86:        short   dst_y_incr;
                     87:        Uint16  end_mask_1;
                     88:        Uint16  end_mask_2;
                     89:        Uint16  end_mask_3;
                     90:        Uint8   hop;
                     91:        Uint8   lop;
                     92:        Uint8   ctrl;
                     93:        Uint8   skew;
                     94: } BLITTERREGS;
                     95: 
                     96: /* Blitter vars */
                     97: typedef struct
                     98: {
1.1.1.9   root       99:        int             pass_cycles;
                    100:        int             op_cycles;
1.1.1.8   root      101:        Uint32  buffer;
                    102:        Uint32  src_words_reset;
                    103:        Uint32  dst_words_reset;
                    104:        Uint32  src_words;
                    105:        Uint8   hog;
                    106:        Uint8   smudge;
                    107:        Uint8   line;
                    108:        Uint8   fxsr;
                    109:        Uint8   nfsr;
                    110:        Uint8   skew;
                    111: } BLITTERVARS;
                    112: 
                    113: /* Blitter state */
                    114: typedef struct
                    115: {
                    116:        Uint16  src_word;
                    117:        Uint16  dst_word;
                    118:        Uint16  end_mask;
                    119:        Uint8   have_src;
                    120:        Uint8   have_dst;
                    121:        Uint8   fxsr;
                    122:        Uint8   nfsr;
                    123: } BLITTERSTATE;
                    124: 
1.1.1.9   root      125: /* Blitter logical op func */
                    126: typedef Uint16 (*BLITTER_OP_FUNC)(void);
                    127: 
1.1.1.8   root      128: static BLITTERREGS     BlitterRegs;
                    129: static BLITTERVARS     BlitterVars;
                    130: static BLITTERSTATE    BlitterState;
                    131: static Uint16          BlitterHalftone[16];
1.1.1.3   root      132: 
1.1.1.9   root      133: static BLITTER_OP_FUNC Blitter_ComputeHOP;
                    134: static BLITTER_OP_FUNC Blitter_ComputeLOP;
                    135: 
1.1.1.8   root      136: /*-----------------------------------------------------------------------*/
                    137: /**
1.1.1.15! root      138:  * Count blitter cycles (this assumes blitter and CPU runs at the same freq)
1.1.1.8   root      139:  */
1.1.1.3   root      140: 
1.1.1.8   root      141: static void Blitter_AddCycles(int cycles)
1.1.1.4   root      142: {
1.1.1.15! root      143:        int all_cycles = cycles + WaitStateCycles;
1.1.1.4   root      144: 
1.1.1.9   root      145:        BlitterVars.op_cycles += all_cycles;
1.1.1.4   root      146: 
1.1.1.15! root      147: #ifdef OLD_CPU_SHIFT
1.1.1.9   root      148:        nCyclesMainCounter += all_cycles >> nCpuFreqShift;
1.1.1.14  root      149:        CyclesGlobalClockCounter += all_cycles >> nCpuFreqShift;
1.1.1.15! root      150: #else
        !           151:        nCyclesMainCounter += all_cycles;
        !           152:        CyclesGlobalClockCounter += all_cycles;
        !           153: #endif
        !           154:        WaitStateCycles = 0;
1.1.1.9   root      155: }
                    156: 
                    157: static void Blitter_FlushCycles(void)
                    158: {
1.1.1.15! root      159: #ifdef OLD_CPU_SHIFT
        !           160:        int op_cycles = INT_CONVERT_TO_INTERNAL(BlitterVars.op_cycles >> nCpuFreqShift, INT_CPU_CYCLE);
        !           161: #else
1.1.1.9   root      162:        int op_cycles = INT_CONVERT_TO_INTERNAL(BlitterVars.op_cycles, INT_CPU_CYCLE);
1.1.1.15! root      163: #endif
1.1.1.9   root      164: 
                    165:        BlitterVars.pass_cycles += BlitterVars.op_cycles;
                    166:        BlitterVars.op_cycles = 0;
1.1.1.8   root      167: 
1.1.1.9   root      168:        PendingInterruptCount -= op_cycles;
1.1.1.8   root      169:        while (PendingInterruptCount <= 0 && PendingInterruptFunction)
                    170:                CALL_VAR(PendingInterruptFunction);
1.1       root      171: }
                    172: 
1.1.1.14  root      173: 
                    174: /*-----------------------------------------------------------------------*/
                    175: /**
                    176:  * Handle bus arbitration when switching between CPU and Blitter
                    177:  * When a write is made to FF8A3C to start the blitter, it will take a few cycles
                    178:  * before doing the bus arbitration. During this time the CPU will be able to
                    179:  * partially execute the next instruction in parallel to the blitter
                    180:  * (until an access to the BUS is needed by the CPU).
                    181:  *
                    182:  * NOTE [NP] : this is mostly handled with hardcoded cases for now, as it
                    183:  * requires cycle exact emulation to exactly know when bus is accessed
                    184:  * by the CPU to prefetch the next word.
                    185:  * More tests are needed on a real STE to have a proper model of this.
                    186:  *
                    187:  * Based on several examples, possible sequence when starting the blitter seems to be :
                    188:  *  - t+0 : write to FF8A3C
                    189:  *  - t+0 : CPU can still run during 4 cycles and access bus
                    190:  *  - t+4 : bus arbitration takes 4 cycles (no access for cpu and blitter during this time)
                    191:  *  - t+8 : blitter owns the bus and starts tranferring data
1.1.1.15! root      192:  * (in case of MegaSTE bus arbitration takes 8 cycles instead of 4)
1.1.1.14  root      193:  *
                    194:  * When blitter stops owning the bus in favor of the cpu, this seems to always take 4 cycles
                    195:  */
                    196: static void Blitter_BusArbitration ( int RequestBusMode )
                    197: {
                    198:        int     cycles;
                    199: 
                    200:        if ( RequestBusMode == BUS_MODE_BLITTER )       /* Bus is requested by the blitter */
                    201:        {
                    202: //fprintf ( stderr , "blitter start pc %x %x\n" , M68000_GetPC() , M68000_InstrPC );
1.1.1.15! root      203:                if ( ConfigureParams.System.nMachineType == MACHINE_MEGA_STE )
        !           204:                        cycles = 8;                     /* MegaSTE blitter needs 4 extra cycles when requesting the bus */
        !           205:                else
        !           206:                        cycles = 4;                     /* Default case : take 4 cycles when going from cpu to blitter */
1.1.1.14  root      207: 
                    208:                /* Different timing for some specific cases */
                    209: 
                    210:                /* 'Relapse - Graphix Sound 2' by Cybernetics (overscan plasma using blitter) */
                    211:                /* $e764 : move.b  d5,(a4) + dbra d1,$fff2 : 4 cycles of the dbra can be executed while blitter starts */
                    212:                if ( STMemory_ReadLong ( M68000_InstrPC ) == 0x188551c9 )       /* PC = E764 */
1.1.1.15! root      213:                        cycles -= 4;                    /* 4 cycles less than default case */
1.1.1.14  root      214:        }
                    215: 
                    216:        else                                            /* Bus is requested by the cpu */
                    217:        {
1.1.1.15! root      218:                cycles = 4;                             /* Always 4 cycles (even for MegaSTE) */
1.1.1.14  root      219:        }
                    220: 
                    221:        /* Add arbitration cycles and update BusMode */
                    222:        if ( cycles > 0 )
                    223:        {
                    224:                Blitter_AddCycles(cycles);
                    225:                Blitter_FlushCycles();
                    226:        }       
                    227:        BusMode = RequestBusMode;
                    228: }
                    229: 
                    230: 
1.1.1.8   root      231: /*-----------------------------------------------------------------------*/
                    232: /**
                    233:  * Read & Write operations
                    234:  */
                    235: static Uint16 Blitter_ReadWord(Uint32 addr)
1.1.1.7   root      236: {
1.1.1.8   root      237:        Uint16 value;
1.1       root      238: 
1.1.1.14  root      239:        /* When reading from a bus error region, just return a constant */
                    240:        if ( STMemory_CheckRegionBusError ( addr ) )
                    241:                value = BLITTER_READ_WORD_BUS_ERR;
1.1.1.8   root      242:        else
1.1.1.14  root      243:                value = (Uint16)get_word ( addr );
                    244: //fprintf ( stderr , "read %x %x %x\n" , addr , value , STMemory_CheckRegionBusError(addr) );
1.1.1.7   root      245: 
1.1.1.8   root      246:        Blitter_AddCycles(4);
1.1.1.7   root      247: 
1.1.1.8   root      248:        return value;
                    249: }
                    250: 
                    251: static void Blitter_WriteWord(Uint32 addr, Uint16 value)
                    252: {
1.1.1.14  root      253:        /* Call put_word only if the address doesn't point to a bus error region */
1.1.1.15! root      254:        /* (also see SysMem_wput for addr < 0x8) */
1.1.1.14  root      255:        if ( STMemory_CheckRegionBusError ( addr ) == false )
                    256:                put_word ( addr , (Uint32)(value) );
                    257: //fprintf ( stderr , "write %x %x %x\n" , addr , value , STMemory_CheckRegionBusError(addr) );
1.1.1.7   root      258: 
1.1.1.8   root      259:        Blitter_AddCycles(4);
1.1.1.7   root      260: }
                    261: 
1.1.1.8   root      262: /*-----------------------------------------------------------------------*/
1.1.1.7   root      263: /**
1.1.1.8   root      264:  * Blitter emulation - level 1
1.1.1.7   root      265:  */
1.1.1.8   root      266: 
                    267: static void Blitter_BeginLine(void)
1.1.1.7   root      268: {
1.1.1.8   root      269:        BlitterVars.src_words = BlitterVars.src_words_reset;
                    270: }
1.1.1.7   root      271: 
1.1.1.8   root      272: static void Blitter_SetState(Uint8 fxsr, Uint8 nfsr, Uint16 end_mask)
                    273: {
                    274:        BlitterState.end_mask = end_mask;
                    275:        BlitterState.have_src = false;
                    276:        BlitterState.have_dst = false;
                    277:        BlitterState.fxsr = fxsr;
                    278:        BlitterState.nfsr = nfsr;
                    279: }
                    280: 
                    281: static void Blitter_SourceShift(void)
                    282: {
                    283:        if (BlitterRegs.src_x_incr < 0)
                    284:                BlitterVars.buffer >>= 16;
                    285:        else
                    286:                BlitterVars.buffer <<= 16;
                    287: }
                    288: 
                    289: static void Blitter_SourceFetch(void)
                    290: {
                    291:        Uint32 src_word = (Uint32)Blitter_ReadWord(BlitterRegs.src_addr);
                    292: 
                    293:        if (BlitterRegs.src_x_incr < 0)
                    294:                BlitterVars.buffer |= src_word << 16;
                    295:        else
                    296:                BlitterVars.buffer |= src_word;
                    297: 
                    298:        if (BlitterVars.src_words == 1)
1.1.1.7   root      299:        {
1.1.1.8   root      300:                BlitterRegs.src_addr += BlitterRegs.src_y_incr;
                    301:        }
                    302:        else
                    303:        {
                    304:                --BlitterVars.src_words;
                    305:                BlitterRegs.src_addr += BlitterRegs.src_x_incr;
1.1.1.7   root      306:        }
                    307: }
                    308: 
1.1.1.8   root      309: static Uint16 Blitter_SourceRead(void)
                    310: {
                    311:        if (!BlitterState.have_src)
                    312:        {
                    313:                if (BlitterState.fxsr)
                    314:                {
                    315:                        Blitter_SourceShift();
                    316:                        Blitter_SourceFetch();
                    317:                }
1.1.1.7   root      318: 
1.1.1.8   root      319:                Blitter_SourceShift();
1.1.1.7   root      320: 
1.1.1.8   root      321:                if (!BlitterState.nfsr)
                    322:                {
                    323:                        Blitter_SourceFetch();
                    324:                }
1.1.1.7   root      325: 
1.1.1.8   root      326:                BlitterState.src_word = (Uint16)(BlitterVars.buffer >> BlitterVars.skew);
                    327:                BlitterState.have_src = true;
1.1.1.7   root      328:        }
1.1       root      329: 
1.1.1.8   root      330:        return BlitterState.src_word;
                    331: }
1.1       root      332: 
1.1.1.8   root      333: static Uint16 Blitter_GetHalftoneWord(void)
                    334: {
                    335:        if (BlitterVars.smudge)
                    336:                return BlitterHalftone[Blitter_SourceRead() & 15];
                    337:        else
                    338:                return BlitterHalftone[BlitterVars.line];
                    339: }
1.1.1.4   root      340: 
1.1.1.9   root      341: /* HOP */
                    342: 
                    343: static Uint16 Blitter_HOP_0(void)
1.1       root      344: {
1.1.1.9   root      345:        return 0xFFFF;
                    346: }
1.1.1.7   root      347: 
1.1.1.9   root      348: static Uint16 Blitter_HOP_1(void)
                    349: {
                    350:        return Blitter_GetHalftoneWord();
                    351: }
                    352: 
                    353: static Uint16 Blitter_HOP_2(void)
                    354: {
                    355:        return Blitter_SourceRead();
                    356: }
1.1.1.8   root      357: 
1.1.1.9   root      358: static Uint16 Blitter_HOP_3(void)
                    359: {
                    360:        return Blitter_SourceRead() & Blitter_GetHalftoneWord();
1.1.1.8   root      361: }
                    362: 
1.1.1.9   root      363: static BLITTER_OP_FUNC Blitter_HOP_Table [4] =
                    364: {
                    365:        Blitter_HOP_0,
                    366:        Blitter_HOP_1,
                    367:        Blitter_HOP_2,
                    368:        Blitter_HOP_3
                    369: };
                    370: 
                    371: static void Blitter_Select_HOP(void)
                    372: {
                    373:        Blitter_ComputeHOP = Blitter_HOP_Table[BlitterRegs.hop];
                    374: }
                    375: 
                    376: /* end HOP */
                    377: 
1.1.1.8   root      378: static Uint16 Blitter_DestRead(void)
                    379: {
                    380:        if (!BlitterState.have_dst)
                    381:        {
                    382:                BlitterState.dst_word = Blitter_ReadWord(BlitterRegs.dst_addr);
                    383:                BlitterState.have_dst = true;
                    384:        }
                    385: 
                    386:        return BlitterState.dst_word;
                    387: }
                    388: 
1.1.1.9   root      389: /* LOP */
                    390: 
                    391: static Uint16 Blitter_LOP_0(void)
                    392: {
                    393:        return 0;
                    394: }
                    395: 
                    396: static Uint16 Blitter_LOP_1(void)
1.1.1.8   root      397: {
1.1.1.9   root      398:        return Blitter_ComputeHOP() & Blitter_DestRead();
                    399: }
1.1.1.8   root      400: 
1.1.1.9   root      401: static Uint16 Blitter_LOP_2(void)
                    402: {
                    403:        return Blitter_ComputeHOP() & ~Blitter_DestRead();
                    404: }
                    405: 
                    406: static Uint16 Blitter_LOP_3(void)
                    407: {
                    408:        return Blitter_ComputeHOP();
                    409: }
                    410: 
                    411: static Uint16 Blitter_LOP_4(void)
                    412: {
                    413:        return ~Blitter_ComputeHOP() & Blitter_DestRead();
                    414: }
                    415: 
                    416: static Uint16 Blitter_LOP_5(void)
                    417: {
                    418:        return Blitter_DestRead();
                    419: }
                    420: 
                    421: static Uint16 Blitter_LOP_6(void)
                    422: {
                    423:        return Blitter_ComputeHOP() ^ Blitter_DestRead();
                    424: }
                    425: 
                    426: static Uint16 Blitter_LOP_7(void)
                    427: {
                    428:        return Blitter_ComputeHOP() | Blitter_DestRead();
                    429: }
                    430: 
                    431: static Uint16 Blitter_LOP_8(void)
                    432: {
                    433:        return ~Blitter_ComputeHOP() & ~Blitter_DestRead();
                    434: }
                    435: 
                    436: static Uint16 Blitter_LOP_9(void)
                    437: {
                    438:        return ~Blitter_ComputeHOP() ^ Blitter_DestRead();
                    439: }
                    440: 
                    441: static Uint16 Blitter_LOP_A(void)
                    442: {
                    443:        return ~Blitter_DestRead();
                    444: }
1.1.1.8   root      445: 
1.1.1.9   root      446: static Uint16 Blitter_LOP_B(void)
                    447: {
                    448:        return Blitter_ComputeHOP() | ~Blitter_DestRead();
1.1.1.8   root      449: }
                    450: 
1.1.1.9   root      451: static Uint16 Blitter_LOP_C(void)
                    452: {
                    453:        return ~Blitter_ComputeHOP();
                    454: }
                    455: 
                    456: static Uint16 Blitter_LOP_D(void)
                    457: {
                    458:        return ~Blitter_ComputeHOP() | Blitter_DestRead();
                    459: }
                    460: 
                    461: static Uint16 Blitter_LOP_E(void)
                    462: {
                    463:        return ~Blitter_ComputeHOP() | ~Blitter_DestRead();
                    464: }
                    465: 
                    466: static Uint16 Blitter_LOP_F(void)
                    467: {
                    468:        return 0xFFFF;
                    469: }
                    470: 
                    471: static BLITTER_OP_FUNC Blitter_LOP_Table [16] =
                    472: {
                    473:        Blitter_LOP_0,
                    474:        Blitter_LOP_1,
                    475:        Blitter_LOP_2,
                    476:        Blitter_LOP_3,
                    477:        Blitter_LOP_4,
                    478:        Blitter_LOP_5,
                    479:        Blitter_LOP_6,
                    480:        Blitter_LOP_7,
                    481:        Blitter_LOP_8,
                    482:        Blitter_LOP_9,
                    483:        Blitter_LOP_A,
                    484:        Blitter_LOP_B,
                    485:        Blitter_LOP_C,
                    486:        Blitter_LOP_D,
                    487:        Blitter_LOP_E,
                    488:        Blitter_LOP_F
                    489: };
                    490: 
                    491: static void Blitter_Select_LOP(void)
                    492: {
                    493:        Blitter_ComputeLOP = Blitter_LOP_Table[BlitterRegs.lop];
                    494: }
                    495: 
                    496: /* end LOP */
                    497: 
1.1.1.8   root      498: static Uint16 Blitter_ComputeMask(void)
                    499: {
                    500:        return (Blitter_ComputeLOP() & BlitterState.end_mask) |
                    501:                        (Blitter_DestRead() & ~BlitterState.end_mask);
                    502: }
                    503: 
                    504: static void Blitter_ProcessWord(void)
                    505: {
                    506:        /* when NFSR, a read-modify-write is always performed */
                    507:        Uint16 dst_data = ((BlitterState.nfsr || BlitterState.end_mask != 0xFFFF)
                    508:                                                        ? Blitter_ComputeMask()
                    509:                                                        : Blitter_ComputeLOP());
                    510: 
                    511:        Blitter_WriteWord(BlitterRegs.dst_addr, dst_data);
1.1       root      512: 
1.1.1.8   root      513:        if (BlitterRegs.words == 1)
1.1.1.7   root      514:        {
1.1.1.8   root      515:                BlitterRegs.dst_addr += BlitterRegs.dst_y_incr;
1.1.1.7   root      516:        }
1.1.1.8   root      517:        else
1.1.1.7   root      518:        {
1.1.1.8   root      519:                --BlitterRegs.words;
                    520:                BlitterRegs.dst_addr += BlitterRegs.dst_x_incr;
1.1.1.7   root      521:        }
1.1.1.8   root      522: }
                    523: 
                    524: static void Blitter_EndLine(void)
                    525: {
                    526:        --BlitterRegs.lines;
                    527:        BlitterRegs.words = BlitterVars.dst_words_reset;
1.1.1.7   root      528: 
1.1.1.8   root      529:        if (BlitterRegs.dst_y_incr >= 0)
                    530:                BlitterVars.line = (BlitterVars.line+1) & 15;
1.1.1.7   root      531:        else
1.1.1.8   root      532:                BlitterVars.line = (BlitterVars.line-1) & 15;
                    533: }
                    534: 
                    535: /*-----------------------------------------------------------------------*/
                    536: /**
                    537:  * Blitter emulation - level 2
                    538:  */
                    539: 
                    540: static void Blitter_SingleWord(void)
                    541: {
                    542:        Blitter_BeginLine();
                    543:        Blitter_SetState(BlitterVars.fxsr, BlitterVars.nfsr, BlitterRegs.end_mask_1);
                    544:        Blitter_ProcessWord();
                    545:        Blitter_EndLine();
                    546: }
                    547: 
                    548: static void Blitter_FirstWord(void)
                    549: {
                    550:        Blitter_BeginLine();
                    551:        Blitter_SetState(BlitterVars.fxsr, 0, BlitterRegs.end_mask_1);
                    552:        Blitter_ProcessWord();
                    553: }
                    554: 
                    555: static void Blitter_MiddleWord(void)
                    556: {
                    557:        Blitter_SetState(0, 0, BlitterRegs.end_mask_2);
                    558:        Blitter_ProcessWord();
                    559: }
1.1.1.7   root      560: 
1.1.1.8   root      561: static void Blitter_LastWord(void)
                    562: {
                    563:        Blitter_SetState(0, BlitterVars.nfsr, BlitterRegs.end_mask_3);
                    564:        Blitter_ProcessWord();
                    565:        Blitter_EndLine();
1.1.1.7   root      566: }
1.1       root      567: 
1.1.1.8   root      568: static void Blitter_Step(void)
                    569: {
                    570:        if (BlitterVars.dst_words_reset == 1)
                    571:        {
                    572:                Blitter_SingleWord();
                    573:        }
                    574:        else if (BlitterRegs.words == BlitterVars.dst_words_reset)
                    575:        {
                    576:                Blitter_FirstWord();
                    577:        }
                    578:        else if (BlitterRegs.words == 1)
                    579:        {
                    580:                Blitter_LastWord();
                    581:        }
                    582:        else
                    583:        {
                    584:                Blitter_MiddleWord();
                    585:        }
                    586: }
1.1       root      587: 
1.1.1.3   root      588: /*-----------------------------------------------------------------------*/
1.1.1.5   root      589: /**
1.1.1.7   root      590:  * Let's do the blit.
                    591:  * Note that in non-HOG mode, the blitter only runs for 64 bus cycles (2 MHz!)
                    592:  * before giving the bus back to the CPU. Due to this mode, this function must
                    593:  * be able to abort and resume the blitting at any time.
1.1.1.5   root      594:  */
1.1.1.8   root      595: static void Blitter_Start(void)
1.1.1.4   root      596: {
1.1.1.9   root      597:        /* select HOP & LOP funcs */
                    598:        Blitter_Select_HOP();
                    599:        Blitter_Select_LOP();
                    600: 
1.1.1.8   root      601:        /* setup vars */
1.1.1.9   root      602:        BlitterVars.pass_cycles = 0;
                    603:        BlitterVars.op_cycles = 0;
1.1.1.12  root      604:        BlitterVars.src_words_reset = BlitterVars.dst_words_reset + BlitterVars.fxsr - BlitterVars.nfsr;
1.1.1.8   root      605: 
                    606:        /* bus arbitration */
1.1.1.14  root      607:        Blitter_BusArbitration ( BUS_MODE_BLITTER );
                    608: 
                    609:        /* Busy=1, set line to high/1 and clear interrupt */
                    610:        MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_GPU_DONE , MFP_GPIP_STATE_HIGH );
1.1.1.7   root      611: 
                    612:        /* Now we enter the main blitting loop */
                    613:        do
                    614:        {
1.1.1.8   root      615:                Blitter_Step();
1.1.1.9   root      616:                Blitter_FlushCycles();
1.1.1.8   root      617:        }
                    618:        while (BlitterRegs.lines > 0
1.1.1.9   root      619:               && (BlitterVars.hog || BlitterVars.pass_cycles < NONHOG_CYCLES));
1.1.1.7   root      620: 
1.1.1.8   root      621:        /* bus arbitration */
1.1.1.14  root      622:        Blitter_BusArbitration ( BUS_MODE_CPU );
1.1.1.7   root      623: 
1.1.1.8   root      624:        BlitterRegs.ctrl = (BlitterRegs.ctrl & 0xF0) | BlitterVars.line;
1.1.1.7   root      625: 
1.1.1.8   root      626:        if (BlitterRegs.lines == 0)
                    627:        {
1.1.1.14  root      628:                /* We're done, clear busy and hog bits */
                    629:                BlitterRegs.ctrl &= ~(0x80|0x40);
1.1.1.7   root      630: 
1.1.1.14  root      631:                /* Busy=0, set line to low/0 and request interrupt */
                    632:                MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_GPU_DONE , MFP_GPIP_STATE_LOW );
1.1.1.7   root      633:        }
1.1.1.8   root      634:        else
1.1.1.7   root      635:        {
1.1.1.8   root      636:                /* Continue blitting later */
1.1.1.15! root      637: #ifdef OLD_CPU_SHIFT
        !           638:                CycInt_AddRelativeInterrupt(NONHOG_CYCLES, INT_CPU_CYCLE, INTERRUPT_BLITTER);
        !           639: #else
1.1.1.10  root      640:                CycInt_AddRelativeInterrupt(NONHOG_CYCLES, INT_CPU_CYCLE, INTERRUPT_BLITTER);
1.1.1.15! root      641: #endif
1.1.1.7   root      642:        }
                    643: }
                    644: 
1.1.1.8   root      645: /*-----------------------------------------------------------------------*/
                    646: /**
                    647:  * Read blitter halftone ram.
                    648:  */
                    649: static void Blitter_Halftone_ReadWord(int index)
                    650: {
                    651:        IoMem_WriteWord(REG_HT_RAM + index + index, BlitterHalftone[index]);
                    652: }
                    653: 
                    654: void Blitter_Halftone00_ReadWord(void) { Blitter_Halftone_ReadWord(0); }
                    655: void Blitter_Halftone01_ReadWord(void) { Blitter_Halftone_ReadWord(1); }
                    656: void Blitter_Halftone02_ReadWord(void) { Blitter_Halftone_ReadWord(2); }
                    657: void Blitter_Halftone03_ReadWord(void) { Blitter_Halftone_ReadWord(3); }
                    658: void Blitter_Halftone04_ReadWord(void) { Blitter_Halftone_ReadWord(4); }
                    659: void Blitter_Halftone05_ReadWord(void) { Blitter_Halftone_ReadWord(5); }
                    660: void Blitter_Halftone06_ReadWord(void) { Blitter_Halftone_ReadWord(6); }
                    661: void Blitter_Halftone07_ReadWord(void) { Blitter_Halftone_ReadWord(7); }
                    662: void Blitter_Halftone08_ReadWord(void) { Blitter_Halftone_ReadWord(8); }
                    663: void Blitter_Halftone09_ReadWord(void) { Blitter_Halftone_ReadWord(9); }
                    664: void Blitter_Halftone10_ReadWord(void) { Blitter_Halftone_ReadWord(10); }
                    665: void Blitter_Halftone11_ReadWord(void) { Blitter_Halftone_ReadWord(11); }
                    666: void Blitter_Halftone12_ReadWord(void) { Blitter_Halftone_ReadWord(12); }
                    667: void Blitter_Halftone13_ReadWord(void) { Blitter_Halftone_ReadWord(13); }
                    668: void Blitter_Halftone14_ReadWord(void) { Blitter_Halftone_ReadWord(14); }
                    669: void Blitter_Halftone15_ReadWord(void) { Blitter_Halftone_ReadWord(15); }
                    670: 
                    671: /*-----------------------------------------------------------------------*/
                    672: /**
                    673:  * Read blitter source x increment (0xff8a20).
                    674:  */
                    675: void Blitter_SourceXInc_ReadWord(void)
                    676: {
                    677:        IoMem_WriteWord(REG_SRC_X_INC, (Uint16)(BlitterRegs.src_x_incr));
                    678: }
                    679: 
                    680: /*-----------------------------------------------------------------------*/
                    681: /**
                    682:  * Read blitter source y increment (0xff8a22).
                    683:  */
                    684: void Blitter_SourceYInc_ReadWord(void)
                    685: {
                    686:        IoMem_WriteWord(REG_SRC_Y_INC, (Uint16)(BlitterRegs.src_y_incr));
                    687: }
1.1.1.7   root      688: 
                    689: /*-----------------------------------------------------------------------*/
                    690: /**
                    691:  * Read blitter source address (0xff8a24).
                    692:  */
                    693: void Blitter_SourceAddr_ReadLong(void)
                    694: {
1.1.1.8   root      695:        IoMem_WriteLong(REG_SRC_ADDR, BlitterRegs.src_addr);
1.1.1.4   root      696: }
                    697: 
                    698: /*-----------------------------------------------------------------------*/
1.1.1.5   root      699: /**
                    700:  * Read blitter endmask 1.
                    701:  */
1.1.1.3   root      702: void Blitter_Endmask1_ReadWord(void)
1.1       root      703: {
1.1.1.8   root      704:        IoMem_WriteWord(REG_END_MASK1, BlitterRegs.end_mask_1);
1.1       root      705: }
                    706: 
1.1.1.3   root      707: /*-----------------------------------------------------------------------*/
1.1.1.5   root      708: /**
                    709:  * Read blitter endmask 2.
                    710:  */
1.1.1.3   root      711: void Blitter_Endmask2_ReadWord(void)
1.1       root      712: {
1.1.1.8   root      713:        IoMem_WriteWord(REG_END_MASK2, BlitterRegs.end_mask_2);
1.1       root      714: }
                    715: 
1.1.1.3   root      716: /*-----------------------------------------------------------------------*/
1.1.1.5   root      717: /**
                    718:  * Read blitter endmask 3.
                    719:  */
1.1.1.3   root      720: void Blitter_Endmask3_ReadWord(void)
1.1       root      721: {
1.1.1.8   root      722:        IoMem_WriteWord(REG_END_MASK3, BlitterRegs.end_mask_3);
                    723: }
                    724: 
                    725: /*-----------------------------------------------------------------------*/
                    726: /**
                    727:  * Read blitter destination x increment (0xff8a2E).
                    728:  */
                    729: void Blitter_DestXInc_ReadWord(void)
                    730: {
                    731:        IoMem_WriteWord(REG_DST_X_INC, (Uint16)(BlitterRegs.dst_x_incr));
                    732: }
                    733: 
                    734: /*-----------------------------------------------------------------------*/
                    735: /**
                    736:  * Read blitter destination y increment (0xff8a30).
                    737:  */
                    738: void Blitter_DestYInc_ReadWord(void)
                    739: {
                    740:        IoMem_WriteWord(REG_DST_Y_INC, (Uint16)(BlitterRegs.dst_y_incr));
1.1       root      741: }
                    742: 
1.1.1.3   root      743: /*-----------------------------------------------------------------------*/
1.1.1.5   root      744: /**
                    745:  * Read blitter destination address.
                    746:  */
1.1.1.3   root      747: void Blitter_DestAddr_ReadLong(void)
1.1       root      748: {
1.1.1.8   root      749:        IoMem_WriteLong(REG_DST_ADDR, BlitterRegs.dst_addr);
1.1       root      750: }
                    751: 
1.1.1.3   root      752: /*-----------------------------------------------------------------------*/
1.1.1.5   root      753: /**
                    754:  * Read blitter words-per-line register.
                    755:  */
1.1.1.3   root      756: void Blitter_WordsPerLine_ReadWord(void)
1.1       root      757: {
1.1.1.8   root      758:        IoMem_WriteWord(REG_X_COUNT, (Uint16)(BlitterRegs.words & 0xFFFF));
1.1       root      759: }
                    760: 
1.1.1.3   root      761: /*-----------------------------------------------------------------------*/
1.1.1.5   root      762: /**
                    763:  * Read blitter lines-per-bitblock register.
                    764:  */
1.1.1.3   root      765: void Blitter_LinesPerBitblock_ReadWord(void)
1.1       root      766: {
1.1.1.8   root      767:        IoMem_WriteWord(REG_Y_COUNT, (Uint16)(BlitterRegs.lines & 0xFFFF));
1.1       root      768: }
                    769: 
1.1.1.3   root      770: /*-----------------------------------------------------------------------*/
1.1.1.5   root      771: /**
                    772:  * Read blitter halftone operation register.
                    773:  */
1.1.1.3   root      774: void Blitter_HalftoneOp_ReadByte(void)
1.1       root      775: {
1.1.1.8   root      776:        IoMem_WriteByte(REG_BLIT_HOP, BlitterRegs.hop);
1.1       root      777: }
                    778: 
1.1.1.3   root      779: /*-----------------------------------------------------------------------*/
1.1.1.5   root      780: /**
                    781:  * Read blitter logical operation register.
                    782:  */
1.1.1.3   root      783: void Blitter_LogOp_ReadByte(void)
1.1       root      784: {
1.1.1.8   root      785:        IoMem_WriteByte(REG_BLIT_LOP, BlitterRegs.lop);
1.1       root      786: }
                    787: 
1.1.1.3   root      788: /*-----------------------------------------------------------------------*/
1.1.1.5   root      789: /**
                    790:  * Read blitter control register.
                    791:  */
1.1.1.4   root      792: void Blitter_Control_ReadByte(void)
1.1       root      793: {
1.1.1.7   root      794:        /* busy, hog/blit, smudge, n/a, 4bits for line number */
1.1.1.8   root      795:        IoMem_WriteByte(REG_CONTROL, BlitterRegs.ctrl);
1.1       root      796: }
                    797: 
1.1.1.3   root      798: /*-----------------------------------------------------------------------*/
1.1.1.5   root      799: /**
                    800:  * Read blitter skew register.
                    801:  */
1.1.1.3   root      802: void Blitter_Skew_ReadByte(void)
1.1       root      803: {
1.1.1.8   root      804:        IoMem_WriteByte(REG_SKEW, BlitterRegs.skew);
                    805: }
                    806: 
                    807: 
                    808: /*-----------------------------------------------------------------------*/
                    809: /**
                    810:  * Write to blitter halftone ram.
                    811:  */
                    812: static void Blitter_Halftone_WriteWord(int index)
                    813: {
                    814:        BlitterHalftone[index] = IoMem_ReadWord(REG_HT_RAM + index + index);
                    815: }
                    816: 
                    817: void Blitter_Halftone00_WriteWord(void) { Blitter_Halftone_WriteWord(0); }
                    818: void Blitter_Halftone01_WriteWord(void) { Blitter_Halftone_WriteWord(1); }
                    819: void Blitter_Halftone02_WriteWord(void) { Blitter_Halftone_WriteWord(2); }
                    820: void Blitter_Halftone03_WriteWord(void) { Blitter_Halftone_WriteWord(3); }
                    821: void Blitter_Halftone04_WriteWord(void) { Blitter_Halftone_WriteWord(4); }
                    822: void Blitter_Halftone05_WriteWord(void) { Blitter_Halftone_WriteWord(5); }
                    823: void Blitter_Halftone06_WriteWord(void) { Blitter_Halftone_WriteWord(6); }
                    824: void Blitter_Halftone07_WriteWord(void) { Blitter_Halftone_WriteWord(7); }
                    825: void Blitter_Halftone08_WriteWord(void) { Blitter_Halftone_WriteWord(8); }
                    826: void Blitter_Halftone09_WriteWord(void) { Blitter_Halftone_WriteWord(9); }
                    827: void Blitter_Halftone10_WriteWord(void) { Blitter_Halftone_WriteWord(10); }
                    828: void Blitter_Halftone11_WriteWord(void) { Blitter_Halftone_WriteWord(11); }
                    829: void Blitter_Halftone12_WriteWord(void) { Blitter_Halftone_WriteWord(12); }
                    830: void Blitter_Halftone13_WriteWord(void) { Blitter_Halftone_WriteWord(13); }
                    831: void Blitter_Halftone14_WriteWord(void) { Blitter_Halftone_WriteWord(14); }
                    832: void Blitter_Halftone15_WriteWord(void) { Blitter_Halftone_WriteWord(15); }
                    833: 
                    834: /*-----------------------------------------------------------------------*/
                    835: /**
                    836:  * Write to blitter source x increment.
                    837:  */
                    838: void Blitter_SourceXInc_WriteWord(void)
                    839: {
                    840:        BlitterRegs.src_x_incr = (short)(IoMem_ReadWord(REG_SRC_X_INC) & 0xFFFE);
1.1       root      841: }
                    842: 
1.1.1.8   root      843: /*-----------------------------------------------------------------------*/
                    844: /**
                    845:  * Write to blitter source y increment.
                    846:  */
                    847: void Blitter_SourceYInc_WriteWord(void)
                    848: {
                    849:        BlitterRegs.src_y_incr = (short)(IoMem_ReadWord(REG_SRC_Y_INC) & 0xFFFE);
                    850: }
1.1       root      851: 
1.1.1.3   root      852: /*-----------------------------------------------------------------------*/
1.1.1.5   root      853: /**
1.1.1.7   root      854:  * Write to blitter source address register (0xff8a24).
                    855:  */
                    856: void Blitter_SourceAddr_WriteLong(void)
                    857: {
1.1.1.14  root      858:        if ( ConfigureParams.System.bAddressSpace24 == true )
                    859:                BlitterRegs.src_addr = IoMem_ReadLong(REG_SRC_ADDR) & 0x00FFFFFE;       /* Normal STF/STE */
                    860:        else
                    861:                BlitterRegs.src_addr = IoMem_ReadLong(REG_SRC_ADDR) & 0xFFFFFFFE;       /* Falcon with extra TT RAM */
1.1.1.7   root      862: }
                    863: 
                    864: /*-----------------------------------------------------------------------*/
                    865: /**
1.1.1.5   root      866:  * Write to blitter endmask 1.
                    867:  */
1.1.1.3   root      868: void Blitter_Endmask1_WriteWord(void)
1.1       root      869: {
1.1.1.8   root      870:        BlitterRegs.end_mask_1 = IoMem_ReadWord(REG_END_MASK1);
1.1       root      871: }
                    872: 
1.1.1.3   root      873: /*-----------------------------------------------------------------------*/
1.1.1.5   root      874: /**
                    875:  * Write to blitter endmask 2.
                    876:  */
1.1.1.3   root      877: void Blitter_Endmask2_WriteWord(void)
1.1       root      878: {
1.1.1.8   root      879:        BlitterRegs.end_mask_2 = IoMem_ReadWord(REG_END_MASK2);
1.1       root      880: }
                    881: 
1.1.1.3   root      882: /*-----------------------------------------------------------------------*/
1.1.1.5   root      883: /**
                    884:  * Write to blitter endmask 3.
                    885:  */
1.1.1.3   root      886: void Blitter_Endmask3_WriteWord(void)
1.1       root      887: {
1.1.1.8   root      888:        BlitterRegs.end_mask_3 = IoMem_ReadWord(REG_END_MASK3);
                    889: }
                    890: 
                    891: /*-----------------------------------------------------------------------*/
                    892: /**
                    893:  * Write to blitter destination x increment.
                    894:  */
                    895: void Blitter_DestXInc_WriteWord(void)
                    896: {
                    897:        BlitterRegs.dst_x_incr = (short)(IoMem_ReadWord(REG_DST_X_INC) & 0xFFFE);
                    898: }
                    899: 
                    900: /*-----------------------------------------------------------------------*/
                    901: /**
                    902:  * Write to blitter source y increment.
                    903:  */
                    904: void Blitter_DestYInc_WriteWord(void)
                    905: {
                    906:        BlitterRegs.dst_y_incr = (short)(IoMem_ReadWord(REG_DST_Y_INC) & 0xFFFE);
1.1       root      907: }
                    908: 
1.1.1.3   root      909: /*-----------------------------------------------------------------------*/
1.1.1.5   root      910: /**
                    911:  * Write to blitter destination address register.
                    912:  */
1.1.1.3   root      913: void Blitter_DestAddr_WriteLong(void)
                    914: {
1.1.1.14  root      915:        if ( ConfigureParams.System.bAddressSpace24 == true )
                    916:                BlitterRegs.dst_addr = IoMem_ReadLong(REG_DST_ADDR) & 0x00FFFFFE;       /* Normal STF/STE */
                    917:        else
                    918:                BlitterRegs.dst_addr = IoMem_ReadLong(REG_DST_ADDR) & 0xFFFFFFFE;       /* Falcon with extra TT RAM */
1.1       root      919: }
                    920: 
1.1.1.3   root      921: /*-----------------------------------------------------------------------*/
1.1.1.5   root      922: /**
                    923:  * Write to blitter words-per-line register.
                    924:  */
1.1.1.3   root      925: void Blitter_WordsPerLine_WriteWord(void)
1.1       root      926: {
1.1.1.8   root      927:        Uint32 words = (Uint32)IoMem_ReadWord(REG_X_COUNT);
                    928: 
                    929:        if (words == 0)
                    930:                words = 65536;
                    931: 
                    932:        BlitterRegs.words = words;
                    933:        BlitterVars.dst_words_reset = words;
1.1       root      934: }
                    935: 
1.1.1.3   root      936: /*-----------------------------------------------------------------------*/
1.1.1.5   root      937: /**
1.1.1.8   root      938:  * Write to blitter lines-per-bitblock register.
1.1.1.5   root      939:  */
1.1.1.3   root      940: void Blitter_LinesPerBitblock_WriteWord(void)
1.1       root      941: {
1.1.1.8   root      942:        Uint32 lines = (Uint32)IoMem_ReadWord(REG_Y_COUNT);
                    943: 
                    944:        if (lines == 0)
                    945:                lines = 65536;
                    946: 
                    947:        BlitterRegs.lines = lines;
1.1       root      948: }
                    949: 
1.1.1.3   root      950: /*-----------------------------------------------------------------------*/
1.1.1.5   root      951: /**
                    952:  * Write to blitter halftone operation register.
                    953:  */
1.1.1.3   root      954: void Blitter_HalftoneOp_WriteByte(void)
1.1       root      955: {
1.1.1.4   root      956:        /* h/ware reg masks out the top 6 bits! */
1.1.1.8   root      957:        BlitterRegs.hop = IoMem_ReadByte(REG_BLIT_HOP) & 3;
1.1       root      958: }
                    959: 
1.1.1.3   root      960: /*-----------------------------------------------------------------------*/
1.1.1.5   root      961: /**
                    962:  * Write to blitter logical operation register.
                    963:  */
1.1.1.3   root      964: void Blitter_LogOp_WriteByte(void)
1.1.1.7   root      965: {
1.1.1.4   root      966:        /* h/ware reg masks out the top 4 bits! */
1.1.1.8   root      967:        BlitterRegs.lop = IoMem_ReadByte(REG_BLIT_LOP) & 0xF;
1.1       root      968: }
                    969: 
1.1.1.3   root      970: /*-----------------------------------------------------------------------*/
1.1.1.5   root      971: /**
                    972:  * Write to blitter control register.
                    973:  */
1.1.1.4   root      974: void Blitter_Control_WriteByte(void)
                    975: {
                    976:        /* Control register bits:
                    977:         * 0x80: busy bit
                    978:         * - Turn on Blitter activity and stay "1" until copy finished
                    979:         * 0x40: Blit-mode bit
                    980:         * - 0: Blit mode, CPU and Blitter get 64 clockcycles in turns
                    981:         * - 1: HOG Mode, Blitter reserves and hogs the bus for as long
                    982:         *      as the copy takes, CPU and DMA get no Bus access
                    983:         * 0x20: Smudge mode
                    984:         * - Which line of the halftone pattern to start with is
                    985:         *   read from the first source word when the copy starts
                    986:         * 0x10: not used
                    987:         * 0x0f
                    988:         *
                    989:         * The lowest 4 bits contain the Halftone pattern line number
                    990:         */
1.1.1.7   root      991: 
1.1.1.9   root      992:        if (LOG_TRACE_LEVEL(TRACE_BLITTER))
1.1.1.3   root      993:        {
1.1.1.9   root      994:                int FrameCycles, HblCounterVideo, LineCycles;
                    995: 
                    996:                Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
                    997: 
                    998:                LOG_TRACE_PRINT("blitter write ctrl=%x video_cyc=%d %d@%d pc=%x instr_cyc=%d\n" ,
1.1.1.7   root      999:                                IoMem_ReadByte(REG_CONTROL) ,
1.1.1.9   root     1000:                                FrameCycles, LineCycles, HblCounterVideo, M68000_GetPC(), CurrentInstrCycles );
1.1.1.7   root     1001:        }
1.1.1.3   root     1002: 
1.1.1.8   root     1003:        BlitterRegs.ctrl = IoMem_ReadByte(REG_CONTROL) & 0xEF;
                   1004: 
                   1005:        BlitterVars.hog = BlitterRegs.ctrl & 0x40;
                   1006:        BlitterVars.smudge = BlitterRegs.ctrl & 0x20;
                   1007:        BlitterVars.line = BlitterRegs.ctrl & 0xF;
1.1.1.7   root     1008: 
                   1009:        /* Remove old pending update interrupt */
1.1.1.10  root     1010:        CycInt_RemovePendingInterrupt(INTERRUPT_BLITTER);
1.1.1.7   root     1011: 
                   1012:        /* Busy bit set? */
1.1.1.8   root     1013:        if (BlitterRegs.ctrl & 0x80)
1.1.1.7   root     1014:        {
1.1.1.8   root     1015:                if (BlitterRegs.lines == 0)
1.1.1.7   root     1016:                {
1.1.1.14  root     1017:                        /* We're done, clear busy and hog bits */
                   1018:                        BlitterRegs.ctrl &= ~(0x80|0x40);
1.1.1.7   root     1019:                }
                   1020:                else
                   1021:                {
1.1.1.15! root     1022:                        /* Start blitting after the end of current instruction */
        !          1023: #ifdef OLD_CPU_SHIFT
        !          1024:                        CycInt_AddRelativeInterrupt((CurrentInstrCycles+WaitStateCycles)>>nCpuFreqShift,
1.1.1.10  root     1025:                                                         INT_CPU_CYCLE, INTERRUPT_BLITTER);
1.1.1.15! root     1026: #else
        !          1027:                        CycInt_AddRelativeInterrupt( CurrentInstrCycles+WaitStateCycles, INT_CPU_CYCLE, INTERRUPT_BLITTER);
        !          1028:                        /* [NP] TODO : use CycInt_AddRelativeInterrupt(0) instead to get an immediate interrupt */
        !          1029: #endif
1.1.1.7   root     1030:                }
1.1.1.3   root     1031:        }
1.1       root     1032: }
                   1033: 
1.1.1.3   root     1034: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1035: /**
                   1036:  * Write to blitter skew register.
                   1037:  */
1.1.1.3   root     1038: void Blitter_Skew_WriteByte(void)
                   1039: {
1.1.1.8   root     1040:        BlitterRegs.skew = IoMem_ReadByte(REG_SKEW);
                   1041:        BlitterVars.fxsr = (BlitterRegs.skew & 0x80)?1:0;
                   1042:        BlitterVars.nfsr = (BlitterRegs.skew & 0x40)?1:0;
                   1043:        BlitterVars.skew = BlitterRegs.skew & 0xF;
1.1       root     1044: }
1.1.1.2   root     1045: 
                   1046: 
                   1047: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1048: /**
1.1.1.7   root     1049:  * Handler which continues blitting after 64 bus cycles.
                   1050:  */
                   1051: void Blitter_InterruptHandler(void)
                   1052: {
1.1.1.10  root     1053:        CycInt_AcknowledgeInterrupt();
1.1.1.7   root     1054: 
1.1.1.8   root     1055:        if (BlitterRegs.ctrl & 0x80)
1.1.1.7   root     1056:        {
1.1.1.8   root     1057:                Blitter_Start();
1.1.1.7   root     1058:        }
1.1.1.8   root     1059: }
1.1.1.7   root     1060: 
1.1.1.8   root     1061: /*-----------------------------------------------------------------------*/
                   1062: /**
                   1063:  * Save/Restore snapshot of Blitter variables.
                   1064:  */
                   1065: void Blitter_MemorySnapShot_Capture(bool bSave)
                   1066: {
                   1067:        /* Save/Restore details */
                   1068:        MemorySnapShot_Store(&BlitterRegs, sizeof(BlitterRegs));
                   1069:        MemorySnapShot_Store(&BlitterVars, sizeof(BlitterVars));
                   1070:        MemorySnapShot_Store(&BlitterHalftone, sizeof(BlitterHalftone));
1.1.1.2   root     1071: }
1.1.1.12  root     1072: 
                   1073: /*-----------------------------------------------------------------------*/
                   1074: /**
                   1075:  * Show Blitter register values.
                   1076:  */
1.1.1.14  root     1077: void Blitter_Info(FILE *fp, Uint32 dummy)
1.1.1.12  root     1078: {
                   1079:        BLITTERREGS *regs = &BlitterRegs;
                   1080: 
                   1081:        fprintf(fp, "src addr:  0x%06x\n", regs->src_addr);
                   1082:        fprintf(fp, "dst addr:  0x%06x\n", regs->dst_addr);
                   1083:        fprintf(fp, "words:     %u\n", regs->words);
                   1084:        fprintf(fp, "lines:     %u\n", regs->lines);
                   1085:        fprintf(fp, "src X-inc: %hd\n", regs->src_x_incr);
                   1086:        fprintf(fp, "src Y-inc: %hd\n", regs->src_y_incr);
                   1087:        fprintf(fp, "dst X-inc: %hd\n", regs->dst_x_incr);
                   1088:        fprintf(fp, "dst Y-inc: %hd\n", regs->dst_y_incr);
                   1089:        fprintf(fp, "end mask1: 0x%04x\n", regs->end_mask_1);
                   1090:        fprintf(fp, "end mask2: 0x%04x\n", regs->end_mask_2);
                   1091:        fprintf(fp, "end mask3: 0x%04x\n", regs->end_mask_3);
                   1092:        fprintf(fp, "HOP:       0x%02x\n", regs->hop);
                   1093:        fprintf(fp, "LOP:       0x%02x\n", regs->lop);
                   1094:        fprintf(fp, "control:   0x%02x\n", regs->ctrl);
                   1095:        fprintf(fp, "skew:      0x%02x\n", regs->skew);
1.1.1.13  root     1096:        fprintf(fp, "Note: internally changed register values aren't visible to breakpoints\nor in memdump output until emulated code reads or writes them!\n");
1.1.1.12  root     1097: }

unix.superglobalmegacorp.com

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