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

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

unix.superglobalmegacorp.com

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