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

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.16! root       27: 
        !            28: 
        !            29: /*
        !            30: 
        !            31:   NOTES [NP] : As of August 2017, the blitter code was partly rewritten to allow cycle exact bus accesses
        !            32:   between the blitter and the CPU, allowing to have CPU instruction running in parallel to the blitter
        !            33:   when the CPU doesn't need to access the bus.
        !            34: 
        !            35:   The internal work of the blitter regarding bus accesses was deduced from studying many cases
        !            36:   on a real STE, including several demos using the blitter with overscan, some tests programs on
        !            37:   www.atari-forum.com (from Cyprian Konador), as well as my own tests on an STE.
        !            38: 
        !            39:   Depending on the CPU instruction used to start the blitter, we can see that the next instruction
        !            40:   can be partially or totally executed during the blit, or that it will be executed only after the blit is done.
        !            41: 
        !            42:   To understand the reason for this parallel execution, we must know the sequence used by the blitter
        !            43:   until it gets the bus and start transferring data.
        !            44: 
        !            45:   Based on several examples, possible sequence when starting the blitter seems to be :
        !            46:    - t+0 : write to FF8A3C is complete or blitter "restarts" itself in non-hog mode
        !            47:    - t+0 : CPU can still run during 4 cycles and access bus
        !            48:    - t+4 : bus arbitration takes 4 cycles (no access for CPU and blitter during this time)
        !            49:    - t+8 : blitter owns the bus and starts transferring data
        !            50: 
        !            51:   In case of MegaSTE, the arbitration to grant the bus to the blitter takes 8 cycles instead of 4.
        !            52:   But when bus is granted back to the CPU, it takes 4 cycles on both STE and MegaSTE.
        !            53: 
        !            54:   We can see there's a 4 cycles latency between when the busy bit is set and when the blitter asks
        !            55:   for a bus grant. It's during these 4 cycles that part of the next CPU instruction can be run, if the
        !            56:   current instruction that started the blitter doesn't need the bus anymore.
        !            57: 
        !            58:   For example :
        !            59:    - move.b d0,(a0) + nop      : MOVE.B will do a write then a read to prefetch the next instruction
        !            60:                                -> NOP will run after the blit
        !            61:    - bset #7,(a0) + nop                : BSET will read first then finish with a write
        !            62:                                -> NOP will run before the blit
        !            63:    - bset #7,(a0) + mulu dx,dy : BSET will read first then finish with a write. Then mulu will prefetch before the blit starts
        !            64:                                -> MULU will run in parallel to the blitter
        !            65:    - bset #7,(a0) + divu dx,dy : BSET will read first then finish with a write. Then divu will run internal cycles and finish with a prefetch
        !            66:                                -> all the cycles from the DIVU will run in parallel to the blitter until we reach the DIVU's prefetch
        !            67: 
        !            68:   So, by interleaving CPU instructions with some blitter transfers, it is possible to run part of those instructions
        !            69:   in parallel to the blitter, thus saving CPU cycles on some costly instructions (div,mul,...)
        !            70: 
        !            71:   - Number of bus shared between CPU and blitter : as described in Atari developers documentation,
        !            72:     when HOG mode is disabled the blitter will run during 64 bus accesses (read or write), then it
        !            73:     will give the bus to the CPU for 64 bus accesses too. But in some cases (see below), a possible
        !            74:     bug in the blitter will make it use the bus during only 63 accesses instead of 64.
        !            75: 
        !            76:   - As verified on a real STE, when the blitter owns the bus in non-hog mode, it will give back the bus to the CPU
        !            77:     exactly after the 64th (or 63th) bus access, not just after writing the result of the current word transfer.
        !            78:     For the emulation, this means the blitter's state must be preserved to be able to resume after any bus read
        !            79:     made by the blitter (blitter's operations can have between 0 and 2 reads and 1 write).
        !            80: 
        !            81:   - Blitter doing only 63 bus accesses instead of 64 in non-hog mode : my guess is that in non-hog mode the blitter
        !            82:     will always count bus accesses as soon as busy bit is set, even when it has not started to transfer its own data.
        !            83:     So, if the CPU does a bus access during the 4 cycles latency between t+0 and t+4 above, then this CPU bus access
        !            84:     will be counted by the blitter as a blitter bus access, thus effectively losing one bus access and doing
        !            85:     only 63 bus accesses after that (before granting the bus to the CPU for the next 64 bus accesses).
        !            86: 
        !            87: 
        !            88:   Some examples of demos requiring cycle exact blitter mode to correctly work :
        !            89:    - 'Relapse - Graphix Sound 2' by Cybernetics (overscan plasma using blitter)
        !            90:                This demo uses a self-calibration routine to adapt blitter code to the MegaSTE.
        !            91:                $e764 : move.b  d5,(a4) + dbra d1,$fff2 : 4 cycles of the dbra can be executed while blitter starts
        !            92: 
        !            93: 
        !            94:   From an emulation point of view, the code needed for cycle exact blitter mode requires to intercept
        !            95:   bus accesses before and after they occur, as well as intercepting "do_cycle" before and after too.
        !            96: 
        !            97:   Parallel execution of the CPU is obtained by skipping as many CPU cycles as the blitter ran,
        !            98:   or by skipping CPU cycles until the next CPU bus access (at which point the CPU would stall).
        !            99: 
        !           100: */
        !           101: 
        !           102: /*
        !           103: 
        !           104:   TODO : as measured on STE (as well as on Falcon), the blitter produces strange results when
        !           105:   each line is only 1 word (xcount=1) and when nfsr/fxsr are set at the same time : in some cases
        !           106:   an extra word will be read, depending also on whether src X increment is >0 or <0.
        !           107:   This was discussed in may 2017 in Hatari mailing list and a model still need to be found to cover all cases.
        !           108: 
        !           109: */
        !           110: 
        !           111: 
        !           112: 
1.1.1.8   root      113: const char Blitter_fileid[] = "Hatari blitter.c : " __DATE__ " " __TIME__;
1.1       root      114: 
                    115: #include <SDL_types.h>
                    116: #include <stdio.h>
                    117: #include <stdlib.h>
                    118: 
1.1.1.2   root      119: #include "main.h"
1.1       root      120: #include "blitter.h"
1.1.1.7   root      121: #include "configuration.h"
                    122: #include "dmaSnd.h"
1.1.1.3   root      123: #include "ioMem.h"
                    124: #include "m68000.h"
1.1.1.7   root      125: #include "mfp.h"
1.1.1.2   root      126: #include "memorySnapShot.h"
1.1       root      127: #include "stMemory.h"
1.1.1.11  root      128: #include "screen.h"
1.1.1.7   root      129: #include "video.h"
1.1.1.16! root      130: #include "hatari-glue.h"
1.1.1.7   root      131: 
1.1       root      132: 
1.1.1.8   root      133: /* BLiTTER registers, incs are signed, others unsigned */
1.1.1.16! root      134: #define REG_HT_RAM     0xff8a00                                /* - 0xff8a1e */
1.1       root      135: 
1.1.1.4   root      136: #define REG_SRC_X_INC  0xff8a20
                    137: #define REG_SRC_Y_INC  0xff8a22
                    138: #define REG_SRC_ADDR   0xff8a24
                    139: 
                    140: #define REG_END_MASK1  0xff8a28
                    141: #define REG_END_MASK2  0xff8a2a
                    142: #define REG_END_MASK3  0xff8a2c
                    143: 
                    144: #define REG_DST_X_INC  0xff8a2e
                    145: #define REG_DST_Y_INC  0xff8a30
                    146: #define REG_DST_ADDR   0xff8a32
                    147: 
1.1.1.7   root      148: #define REG_X_COUNT    0xff8a36
                    149: #define REG_Y_COUNT    0xff8a38
1.1.1.4   root      150: 
1.1.1.16! root      151: #define REG_BLIT_HOP   0xff8a3a                                /* halftone blit operation byte */
        !           152: #define REG_BLIT_LOP   0xff8a3b                                /* logical blit operation byte */
1.1.1.7   root      153: #define REG_CONTROL    0xff8a3c
1.1.1.16! root      154: #define REG_SKEW       0xff8a3d
1.1.1.4   root      155: 
1.1.1.14  root      156: 
                    157: #define        BLITTER_READ_WORD_BUS_ERR       0x0000  /* This value is returned when the blitter try to read a word */
                    158:                                                /* in a region that would cause a bus error */
                    159:                                                /* [NP] FIXME : for now we return a constant, but it should depend on the bus activity */
                    160: 
1.1.1.8   root      161: /* Blitter registers */
                    162: typedef struct
                    163: {
                    164:        Uint32  src_addr;
                    165:        Uint32  dst_addr;
                    166:        Uint32  words;
                    167:        Uint32  lines;
                    168:        short   src_x_incr;
                    169:        short   src_y_incr;
                    170:        short   dst_x_incr;
                    171:        short   dst_y_incr;
                    172:        Uint16  end_mask_1;
                    173:        Uint16  end_mask_2;
                    174:        Uint16  end_mask_3;
                    175:        Uint8   hop;
                    176:        Uint8   lop;
                    177:        Uint8   ctrl;
                    178:        Uint8   skew;
                    179: } BLITTERREGS;
                    180: 
                    181: /* Blitter vars */
                    182: typedef struct
                    183: {
1.1.1.16! root      184:        Uint32  pass_cycles;
        !           185:        Uint32  op_cycles;
        !           186:        Uint32  total_cycles;
1.1.1.8   root      187:        Uint32  buffer;
                    188:        Uint32  src_words_reset;
                    189:        Uint32  dst_words_reset;
                    190:        Uint32  src_words;
                    191:        Uint8   hog;
                    192:        Uint8   smudge;
                    193:        Uint8   line;
                    194:        Uint8   fxsr;
                    195:        Uint8   nfsr;
                    196:        Uint8   skew;
                    197: } BLITTERVARS;
                    198: 
                    199: /* Blitter state */
                    200: typedef struct
                    201: {
                    202:        Uint16  src_word;
                    203:        Uint16  dst_word;
                    204:        Uint16  end_mask;
                    205:        Uint8   have_src;
                    206:        Uint8   have_dst;
                    207:        Uint8   fxsr;
                    208:        Uint8   nfsr;
1.1.1.16! root      209: 
        !           210:        Uint16  CountBusBlitter;                                /* To count bus accesses made by the blitter */
        !           211:        Uint16  CountBusCpu;                                    /* To count bus accesses made by the CPU */
        !           212:        Uint8   ContinueLater;                                  /* 0=false / 1=true */
1.1.1.8   root      213: } BLITTERSTATE;
                    214: 
1.1.1.16! root      215: 
1.1.1.9   root      216: /* Blitter logical op func */
                    217: typedef Uint16 (*BLITTER_OP_FUNC)(void);
                    218: 
1.1.1.8   root      219: static BLITTERREGS     BlitterRegs;
                    220: static BLITTERVARS     BlitterVars;
                    221: static BLITTERSTATE    BlitterState;
                    222: static Uint16          BlitterHalftone[16];
1.1.1.3   root      223: 
1.1.1.16! root      224: static BLITTER_OP_FUNC Blitter_ComputeHOP;
        !           225: static BLITTER_OP_FUNC Blitter_ComputeLOP;
        !           226: 
        !           227: 
        !           228: 
        !           229: /* To handle CPU/blitter bus sharing in non-hog mode (require cycle exact mode for CPU emulation) */
        !           230: #define        BLITTER_PHASE_STOP                      0
        !           231: #define        BLITTER_PHASE_PRE_START                 1
        !           232: #define        BLITTER_PHASE_START                     2
        !           233: #define        BLITTER_PHASE_RUN_TRANSFER              4
        !           234: #define        BLITTER_PHASE_COUNT_CPU_BUS             8
        !           235: #define        BLITTER_PHASE_IGNORE_LAST_CPU_CYCLES    16
        !           236: 
        !           237: Uint16         BlitterPhase = BLITTER_PHASE_STOP;              /* Internal state of the blitter */
        !           238: 
        !           239: static Uint16  Blitter_CyclesBeforeStart;                      /* Number of cycles after setting busy bit before calling Blitter_Start */
        !           240:                                                                /* (during this time, the CPU can still run and access the bus) */
        !           241: 
        !           242: static Uint8   Blitter_HOG_CPU_FromBusAccess;                  /* 0 or 1 (false/true) */
        !           243: static Uint8   Blitter_HOG_CPU_BlitterStartDuringBusAccess;    /* 0 or 1 (false/true) */
        !           244: static Uint16  Blitter_HOG_CPU_BusCountError;                  /* 0 or 1 (false/true) */
        !           245: static Uint16  Blitter_HOG_CPU_IgnoreMaxCpuCycles;             /* Max number of blitter cycles during which the CPU might run in parallel */
        !           246:                                                                /* (unless the CPU is stalled earlier by a bus access) */
        !           247: 
        !           248: 
        !           249: /* Number of bus accesses allocated to blitter and CPU in non-hog mode */
        !           250: #define BLITTER_NONHOG_BUS_BLITTER             64              /* Can also be 63, see Blitter_HOG_CPU_BusCountError */
        !           251: #define BLITTER_NONHOG_BUS_CPU                 64
        !           252: 
        !           253: #define        BLITTER_CYCLES_PER_BUS_READ             4               /* The blitter takes 4 cycles to read 1 memory word on STE */
        !           254: #define        BLITTER_CYCLES_PER_BUS_WRITE            4               /* The blitter takes 4 cycles to write 1 memory word on STE */
        !           255: 
        !           256: 
        !           257: /* Return 'true' if CE mode can be enabled for blitter (ie when using 68000 CE mode) */
        !           258: #define        BLITTER_RUN_CE          ( ( currprefs.cpu_cycle_exact ) && ( currprefs.cpu_level == 0 ) )
        !           259: 
        !           260: 
        !           261: /* Used to compute the blitter's usage during each VBL (for statusbar) */
        !           262: static int     BlitterStatsRate;
        !           263: 
        !           264: 
1.1.1.9   root      265: 
1.1.1.8   root      266: /*-----------------------------------------------------------------------*/
                    267: /**
1.1.1.16! root      268:  * Compute some stats for the blitter's usage during a period (eg one VBL)
        !           269:  * Used to determine a percent per VBL and show a led in the statusbar
1.1.1.8   root      270:  */
1.1.1.16! root      271: void   Blitter_StatsUpdateRate ( int period_cycles )
        !           272: {
        !           273:        int percent;
        !           274: 
        !           275:        if ( period_cycles == 0 )
        !           276:                percent = 0;
        !           277:        else
        !           278:                percent = ceil ( 100.0 * BlitterVars.total_cycles / period_cycles );
        !           279: 
        !           280: //fprintf ( stderr , "blitter %d %%\n" , percent );
        !           281:        BlitterVars.total_cycles = 0;
        !           282:        BlitterStatsRate = percent;
        !           283: }
        !           284: 
        !           285: 
        !           286: int    Blitter_StatsGetRate ( void )
        !           287: {
        !           288:        return BlitterStatsRate;
        !           289: }
        !           290: 
1.1.1.3   root      291: 
1.1.1.16! root      292: 
        !           293: /*-----------------------------------------------------------------------*/
        !           294: /**
        !           295:  * Count blitter cycles (this assumes blitter and CPU runs at the same freq)
        !           296:  */
1.1.1.8   root      297: static void Blitter_AddCycles(int cycles)
1.1.1.4   root      298: {
1.1.1.15  root      299:        int all_cycles = cycles + WaitStateCycles;
1.1.1.4   root      300: 
1.1.1.9   root      301:        BlitterVars.op_cycles += all_cycles;
1.1.1.16! root      302:        BlitterVars.total_cycles += all_cycles;
        !           303: //fprintf ( stderr , "blitter add_cyc cyc=%d total=%d cur_cyc=%lu\n" , all_cycles , BlitterVars.op_cycles , currcycle/cpucycleunit );
        !           304: //fprintf ( stderr , "blitter src %x dst %x ycount %d\n" , BlitterRegs.src_addr , BlitterRegs.dst_addr , BlitterRegs.lines );
1.1.1.4   root      305: 
1.1.1.15  root      306:        nCyclesMainCounter += all_cycles;
                    307:        CyclesGlobalClockCounter += all_cycles;
                    308:        WaitStateCycles = 0;
1.1.1.9   root      309: }
                    310: 
                    311: static void Blitter_FlushCycles(void)
                    312: {
                    313:        int op_cycles = INT_CONVERT_TO_INTERNAL(BlitterVars.op_cycles, INT_CPU_CYCLE);
1.1.1.16! root      314: 
        !           315: //fprintf ( stderr , "blitter flush_cyc cyc=%d pass=%d %d cur_cyc=%lu\n" , BlitterVars.op_cycles , BlitterVars.pass_cycles , nCyclesMainCounter , currcycle/cpucycleunit );
1.1.1.9   root      316: 
                    317:        BlitterVars.pass_cycles += BlitterVars.op_cycles;
                    318:        BlitterVars.op_cycles = 0;
1.1.1.8   root      319: 
1.1.1.16! root      320: #if ENABLE_WINUAE_CPU
        !           321:        if ( BLITTER_RUN_CE )                                   /* In CE mode, flush cycles already counted in the current cpu instruction */
        !           322:        {
        !           323:                M68000_AddCycles_CE ( currcycle * 2 / CYCLE_UNIT );
        !           324:                currcycle = 0;
        !           325:        }
        !           326: #endif
        !           327: 
1.1.1.9   root      328:        PendingInterruptCount -= op_cycles;
1.1.1.8   root      329:        while (PendingInterruptCount <= 0 && PendingInterruptFunction)
                    330:                CALL_VAR(PendingInterruptFunction);
1.1       root      331: }
                    332: 
1.1.1.14  root      333: 
                    334: /*-----------------------------------------------------------------------*/
                    335: /**
                    336:  * Handle bus arbitration when switching between CPU and Blitter
                    337:  * When a write is made to FF8A3C to start the blitter, it will take a few cycles
                    338:  * before doing the bus arbitration. During this time the CPU will be able to
                    339:  * partially execute the next instruction in parallel to the blitter
                    340:  * (until an access to the BUS is needed by the CPU).
                    341:  *
                    342:  * Based on several examples, possible sequence when starting the blitter seems to be :
                    343:  *  - t+0 : write to FF8A3C
                    344:  *  - t+0 : CPU can still run during 4 cycles and access bus
                    345:  *  - t+4 : bus arbitration takes 4 cycles (no access for cpu and blitter during this time)
1.1.1.16! root      346:  *  - t+8 : blitter owns the bus and starts transferring data
1.1.1.15  root      347:  * (in case of MegaSTE bus arbitration takes 8 cycles instead of 4)
1.1.1.14  root      348:  *
                    349:  * When blitter stops owning the bus in favor of the cpu, this seems to always take 4 cycles
                    350:  */
                    351: static void Blitter_BusArbitration ( int RequestBusMode )
                    352: {
                    353:        int     cycles;
                    354: 
                    355:        if ( RequestBusMode == BUS_MODE_BLITTER )       /* Bus is requested by the blitter */
                    356:        {
1.1.1.16! root      357:                cycles = 4;                             /* Default case : take 4 cycles when going from cpu to blitter */
1.1.1.15  root      358:                if ( ConfigureParams.System.nMachineType == MACHINE_MEGA_STE )
                    359:                        cycles = 8;                     /* MegaSTE blitter needs 4 extra cycles when requesting the bus */
1.1.1.16! root      360: // fprintf ( stderr , "blitter bus start pc %x %x cyc=%d cur_cyc=%lu\n" , M68000_GetPC() , M68000_InstrPC , cycles , currcycle/cpucycleunit );
1.1.1.14  root      361:        }
                    362: 
                    363:        else                                            /* Bus is requested by the cpu */
                    364:        {
1.1.1.15  root      365:                cycles = 4;                             /* Always 4 cycles (even for MegaSTE) */
1.1.1.16! root      366: // fprintf ( stderr , "blitter bus end pc %x %x cyc=%d\n" , M68000_GetPC() , M68000_InstrPC , cycles );
1.1.1.14  root      367:        }
                    368: 
                    369:        /* Add arbitration cycles and update BusMode */
1.1.1.16! root      370:        Blitter_AddCycles ( cycles );
        !           371:        Blitter_FlushCycles();
        !           372: 
1.1.1.14  root      373:        BusMode = RequestBusMode;
                    374: }
                    375: 
                    376: 
1.1.1.16! root      377: 
1.1.1.8   root      378: /*-----------------------------------------------------------------------*/
                    379: /**
1.1.1.16! root      380:  * Low level memory accesses to read / write a word
        !           381:  * For each word access we increment the blitter's bus accesses counter.
1.1.1.8   root      382:  */
                    383: static Uint16 Blitter_ReadWord(Uint32 addr)
1.1.1.7   root      384: {
1.1.1.8   root      385:        Uint16 value;
1.1       root      386: 
1.1.1.14  root      387:        /* When reading from a bus error region, just return a constant */
                    388:        if ( STMemory_CheckRegionBusError ( addr ) )
                    389:                value = BLITTER_READ_WORD_BUS_ERR;
1.1.1.8   root      390:        else
1.1.1.14  root      391:                value = (Uint16)get_word ( addr );
                    392: //fprintf ( stderr , "read %x %x %x\n" , addr , value , STMemory_CheckRegionBusError(addr) );
1.1.1.7   root      393: 
1.1.1.16! root      394:        BlitterState.CountBusBlitter++;
        !           395:        Blitter_AddCycles ( BLITTER_CYCLES_PER_BUS_READ );
        !           396:        Blitter_FlushCycles();
1.1.1.7   root      397: 
1.1.1.8   root      398:        return value;
                    399: }
                    400: 
                    401: static void Blitter_WriteWord(Uint32 addr, Uint16 value)
                    402: {
1.1.1.14  root      403:        /* Call put_word only if the address doesn't point to a bus error region */
1.1.1.15  root      404:        /* (also see SysMem_wput for addr < 0x8) */
1.1.1.14  root      405:        if ( STMemory_CheckRegionBusError ( addr ) == false )
                    406:                put_word ( addr , (Uint32)(value) );
                    407: //fprintf ( stderr , "write %x %x %x\n" , addr , value , STMemory_CheckRegionBusError(addr) );
1.1.1.7   root      408: 
1.1.1.16! root      409:        BlitterState.CountBusBlitter++;
        !           410:        Blitter_AddCycles ( BLITTER_CYCLES_PER_BUS_WRITE );
        !           411:        Blitter_FlushCycles();
1.1.1.7   root      412: }
                    413: 
1.1.1.16! root      414: 
        !           415: 
1.1.1.8   root      416: /*-----------------------------------------------------------------------*/
1.1.1.7   root      417: /**
1.1.1.16! root      418:  * Used to determine how long the blitter can keep the bus in non-hog mode
        !           419:  * Return true if the blitter can continue its operations and return false
        !           420:  * if the blitter must suspend its work and give back the bus to the CPU
1.1.1.7   root      421:  */
1.1.1.16! root      422: static bool Blitter_ContinueNonHog ( void )
1.1.1.7   root      423: {
1.1.1.16! root      424:        if ( BlitterState.CountBusBlitter < BLITTER_NONHOG_BUS_BLITTER )
        !           425:                return true;
        !           426:        else
        !           427:                return false;
1.1.1.8   root      428: }
1.1.1.7   root      429: 
1.1.1.16! root      430: 
        !           431: /* Macro to check if blitter can continue and do a 'return' if not */
        !           432: #define        BLITTER_RETURN_IF_MAX_BUS_REACHED               if ( !BlitterVars.hog && !Blitter_ContinueNonHog() ) return 0;
        !           433: 
        !           434: /* Macro to suspend this transfer for now and keep src/dst to continue later */
        !           435: #define        BLITTER_CONTINUE_LATER_IF_MAX_BUS_REACHED       if ( !BlitterVars.hog && !Blitter_ContinueNonHog() ) \
        !           436:        { \
        !           437:          /* fprintf ( stderr , "blitter suspended before write word have_src=%d have_dst=%d\n" , BlitterState.have_src ,BlitterState.have_dst ); */ \
        !           438:          BlitterState.ContinueLater = 1; return; \
        !           439:        }
        !           440: 
        !           441: 
        !           442: 
        !           443: /*-----------------------------------------------------------------------*/
        !           444: /**
        !           445:  * Blitter emulation - level 1
        !           446:  */
1.1.1.8   root      447: 
                    448: static void Blitter_SourceShift(void)
                    449: {
                    450:        if (BlitterRegs.src_x_incr < 0)
                    451:                BlitterVars.buffer >>= 16;
                    452:        else
                    453:                BlitterVars.buffer <<= 16;
                    454: }
                    455: 
                    456: static void Blitter_SourceFetch(void)
                    457: {
                    458:        Uint32 src_word = (Uint32)Blitter_ReadWord(BlitterRegs.src_addr);
                    459: 
                    460:        if (BlitterRegs.src_x_incr < 0)
                    461:                BlitterVars.buffer |= src_word << 16;
                    462:        else
                    463:                BlitterVars.buffer |= src_word;
                    464: 
                    465:        if (BlitterVars.src_words == 1)
1.1.1.7   root      466:        {
1.1.1.8   root      467:                BlitterRegs.src_addr += BlitterRegs.src_y_incr;
                    468:        }
                    469:        else
                    470:        {
                    471:                --BlitterVars.src_words;
                    472:                BlitterRegs.src_addr += BlitterRegs.src_x_incr;
1.1.1.7   root      473:        }
                    474: }
                    475: 
1.1.1.8   root      476: static Uint16 Blitter_SourceRead(void)
                    477: {
                    478:        if (!BlitterState.have_src)
                    479:        {
                    480:                if (BlitterState.fxsr)
                    481:                {
                    482:                        Blitter_SourceShift();
                    483:                        Blitter_SourceFetch();
                    484:                }
1.1.1.7   root      485: 
1.1.1.8   root      486:                Blitter_SourceShift();
1.1.1.7   root      487: 
1.1.1.8   root      488:                if (!BlitterState.nfsr)
                    489:                {
                    490:                        Blitter_SourceFetch();
                    491:                }
1.1.1.7   root      492: 
1.1.1.8   root      493:                BlitterState.src_word = (Uint16)(BlitterVars.buffer >> BlitterVars.skew);
                    494:                BlitterState.have_src = true;
1.1.1.7   root      495:        }
1.1       root      496: 
1.1.1.8   root      497:        return BlitterState.src_word;
                    498: }
1.1       root      499: 
1.1.1.16! root      500: static Uint16 Blitter_DestRead(void)
        !           501: {
        !           502:        if (!BlitterState.have_dst)
        !           503:        {
        !           504:                BlitterState.dst_word = Blitter_ReadWord(BlitterRegs.dst_addr);
        !           505:                BlitterState.have_dst = true;
        !           506:        }
        !           507: 
        !           508:        return BlitterState.dst_word;
        !           509: }
        !           510: 
1.1.1.8   root      511: static Uint16 Blitter_GetHalftoneWord(void)
                    512: {
                    513:        if (BlitterVars.smudge)
                    514:                return BlitterHalftone[Blitter_SourceRead() & 15];
                    515:        else
                    516:                return BlitterHalftone[BlitterVars.line];
                    517: }
1.1.1.4   root      518: 
1.1.1.9   root      519: /* HOP */
                    520: 
                    521: static Uint16 Blitter_HOP_0(void)
1.1       root      522: {
1.1.1.9   root      523:        return 0xFFFF;
                    524: }
1.1.1.7   root      525: 
1.1.1.9   root      526: static Uint16 Blitter_HOP_1(void)
                    527: {
                    528:        return Blitter_GetHalftoneWord();
                    529: }
                    530: 
                    531: static Uint16 Blitter_HOP_2(void)
                    532: {
                    533:        return Blitter_SourceRead();
                    534: }
1.1.1.8   root      535: 
1.1.1.9   root      536: static Uint16 Blitter_HOP_3(void)
                    537: {
1.1.1.16! root      538:        Uint16 src;
        !           539: 
        !           540:        src = Blitter_SourceRead();
        !           541:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           542:        return src & Blitter_GetHalftoneWord();
1.1.1.8   root      543: }
                    544: 
1.1.1.9   root      545: static BLITTER_OP_FUNC Blitter_HOP_Table [4] =
                    546: {
                    547:        Blitter_HOP_0,
                    548:        Blitter_HOP_1,
                    549:        Blitter_HOP_2,
                    550:        Blitter_HOP_3
                    551: };
                    552: 
                    553: static void Blitter_Select_HOP(void)
                    554: {
                    555:        Blitter_ComputeHOP = Blitter_HOP_Table[BlitterRegs.hop];
                    556: }
                    557: 
                    558: /* end HOP */
                    559: 
                    560: /* LOP */
                    561: 
                    562: static Uint16 Blitter_LOP_0(void)
                    563: {
                    564:        return 0;
                    565: }
                    566: 
                    567: static Uint16 Blitter_LOP_1(void)
1.1.1.8   root      568: {
1.1.1.16! root      569:        Uint16  hop;
        !           570: 
        !           571:        hop = Blitter_ComputeHOP();
        !           572:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           573:        return hop & Blitter_DestRead();
1.1.1.9   root      574: }
1.1.1.8   root      575: 
1.1.1.9   root      576: static Uint16 Blitter_LOP_2(void)
                    577: {
1.1.1.16! root      578:        Uint16  hop;
        !           579: 
        !           580:        hop = Blitter_ComputeHOP();
        !           581:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           582:        return hop & ~Blitter_DestRead();
1.1.1.9   root      583: }
                    584: 
                    585: static Uint16 Blitter_LOP_3(void)
                    586: {
                    587:        return Blitter_ComputeHOP();
                    588: }
                    589: 
                    590: static Uint16 Blitter_LOP_4(void)
                    591: {
1.1.1.16! root      592:        Uint16  hop;
        !           593: 
        !           594:        hop = Blitter_ComputeHOP();
        !           595:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           596:        return ~hop & Blitter_DestRead();
1.1.1.9   root      597: }
                    598: 
                    599: static Uint16 Blitter_LOP_5(void)
                    600: {
                    601:        return Blitter_DestRead();
                    602: }
                    603: 
                    604: static Uint16 Blitter_LOP_6(void)
                    605: {
1.1.1.16! root      606:        Uint16  hop;
        !           607: 
        !           608:        hop = Blitter_ComputeHOP();
        !           609:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           610:        return hop ^ Blitter_DestRead();
1.1.1.9   root      611: }
                    612: 
                    613: static Uint16 Blitter_LOP_7(void)
                    614: {
1.1.1.16! root      615:        Uint16  hop;
        !           616: 
        !           617:        hop = Blitter_ComputeHOP();
        !           618:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           619:        return hop | Blitter_DestRead();
1.1.1.9   root      620: }
                    621: 
                    622: static Uint16 Blitter_LOP_8(void)
                    623: {
1.1.1.16! root      624:        Uint16  hop;
        !           625: 
        !           626:        hop = Blitter_ComputeHOP();
        !           627:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           628:        return ~hop & ~Blitter_DestRead();
1.1.1.9   root      629: }
                    630: 
                    631: static Uint16 Blitter_LOP_9(void)
                    632: {
1.1.1.16! root      633:        Uint16  hop;
        !           634: 
        !           635:        hop = Blitter_ComputeHOP();
        !           636:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           637:        return ~hop ^ Blitter_DestRead();
1.1.1.9   root      638: }
                    639: 
                    640: static Uint16 Blitter_LOP_A(void)
                    641: {
                    642:        return ~Blitter_DestRead();
                    643: }
1.1.1.8   root      644: 
1.1.1.9   root      645: static Uint16 Blitter_LOP_B(void)
                    646: {
1.1.1.16! root      647:        Uint16  hop;
        !           648: 
        !           649:        hop = Blitter_ComputeHOP();
        !           650:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           651:        return hop | ~Blitter_DestRead();
1.1.1.8   root      652: }
                    653: 
1.1.1.9   root      654: static Uint16 Blitter_LOP_C(void)
                    655: {
                    656:        return ~Blitter_ComputeHOP();
                    657: }
                    658: 
                    659: static Uint16 Blitter_LOP_D(void)
                    660: {
1.1.1.16! root      661:        Uint16  hop;
        !           662: 
        !           663:        hop = Blitter_ComputeHOP();
        !           664:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           665:        return ~hop | Blitter_DestRead();
1.1.1.9   root      666: }
                    667: 
                    668: static Uint16 Blitter_LOP_E(void)
                    669: {
1.1.1.16! root      670:        Uint16  hop;
        !           671: 
        !           672:        hop = Blitter_ComputeHOP();
        !           673:        BLITTER_RETURN_IF_MAX_BUS_REACHED;
        !           674:        return ~hop | ~Blitter_DestRead();
1.1.1.9   root      675: }
                    676: 
                    677: static Uint16 Blitter_LOP_F(void)
                    678: {
                    679:        return 0xFFFF;
                    680: }
                    681: 
                    682: static BLITTER_OP_FUNC Blitter_LOP_Table [16] =
                    683: {
                    684:        Blitter_LOP_0,
                    685:        Blitter_LOP_1,
                    686:        Blitter_LOP_2,
                    687:        Blitter_LOP_3,
                    688:        Blitter_LOP_4,
                    689:        Blitter_LOP_5,
                    690:        Blitter_LOP_6,
                    691:        Blitter_LOP_7,
                    692:        Blitter_LOP_8,
                    693:        Blitter_LOP_9,
                    694:        Blitter_LOP_A,
                    695:        Blitter_LOP_B,
                    696:        Blitter_LOP_C,
                    697:        Blitter_LOP_D,
                    698:        Blitter_LOP_E,
                    699:        Blitter_LOP_F
                    700: };
                    701: 
                    702: static void Blitter_Select_LOP(void)
                    703: {
                    704:        Blitter_ComputeLOP = Blitter_LOP_Table[BlitterRegs.lop];
                    705: }
                    706: 
                    707: /* end LOP */
                    708: 
1.1.1.16! root      709: 
        !           710: /*-----------------------------------------------------------------------*/
        !           711: /*
        !           712:  * If BlitterState.ContinueLater==1, it means we're resuming from a previous
        !           713:  * Blitter_ProcessWord() call that did not complete because we reached
        !           714:  * maximum number of bus accesses. In that case, we continue from the latest
        !           715:  * state, keeping the values we already have for src_word and dst_word.
        !           716:  */
        !           717: 
        !           718: static void Blitter_BeginLine(void)
        !           719: {
        !           720:        if ( BlitterState.ContinueLater )                               /* Resuming, don't start a new line */
        !           721:                return;
        !           722: 
        !           723:        BlitterVars.src_words = BlitterVars.src_words_reset;
        !           724: }
        !           725: 
        !           726: static void Blitter_SetState(Uint8 fxsr, Uint8 nfsr, Uint16 end_mask)
        !           727: {
        !           728:        BlitterState.fxsr = fxsr;
        !           729:        BlitterState.nfsr = nfsr;
        !           730:        BlitterState.end_mask = end_mask;
        !           731: 
        !           732:        if ( BlitterState.ContinueLater )
        !           733:                BlitterState.ContinueLater = 0;                         /* Resuming, keep previous values of have_src / have_dst */
        !           734:        else
        !           735:        {
        !           736:                BlitterState.have_src = false;
        !           737:                BlitterState.have_dst = false;
        !           738:        }
        !           739: }
        !           740: 
        !           741: static Uint16 Blitter_ComputeMask(Uint16 lop)
1.1.1.8   root      742: {
1.1.1.16! root      743:        return (lop & BlitterState.end_mask) | (Blitter_DestRead() & ~BlitterState.end_mask);
1.1.1.8   root      744: }
                    745: 
                    746: static void Blitter_ProcessWord(void)
                    747: {
1.1.1.16! root      748:        Uint16  lop;
        !           749:        Uint16  dst_data;
        !           750: 
        !           751:        lop = Blitter_ComputeLOP();
        !           752:        BLITTER_CONTINUE_LATER_IF_MAX_BUS_REACHED;
        !           753: 
        !           754:        /* When NFSR or mask is not all '1', a read-modify-write is always performed */
        !           755:        if ( BlitterState.nfsr || ( BlitterState.end_mask != 0xFFFF ) )
        !           756:        {
        !           757:                dst_data = Blitter_ComputeMask( lop );
        !           758:                BLITTER_CONTINUE_LATER_IF_MAX_BUS_REACHED;
        !           759:        }
        !           760:        else
        !           761:        {
        !           762:                dst_data = lop;
        !           763:        }
1.1.1.8   root      764: 
                    765:        Blitter_WriteWord(BlitterRegs.dst_addr, dst_data);
1.1       root      766: 
1.1.1.8   root      767:        if (BlitterRegs.words == 1)
1.1.1.7   root      768:        {
1.1.1.8   root      769:                BlitterRegs.dst_addr += BlitterRegs.dst_y_incr;
1.1.1.7   root      770:        }
1.1.1.8   root      771:        else
1.1.1.7   root      772:        {
1.1.1.8   root      773:                --BlitterRegs.words;
                    774:                BlitterRegs.dst_addr += BlitterRegs.dst_x_incr;
1.1.1.7   root      775:        }
1.1.1.8   root      776: }
                    777: 
                    778: static void Blitter_EndLine(void)
                    779: {
1.1.1.16! root      780:        if ( BlitterState.ContinueLater )                       /* We will continue later, don't end this line for now */
        !           781:                return;
        !           782: 
1.1.1.8   root      783:        --BlitterRegs.lines;
                    784:        BlitterRegs.words = BlitterVars.dst_words_reset;
1.1.1.7   root      785: 
1.1.1.8   root      786:        if (BlitterRegs.dst_y_incr >= 0)
                    787:                BlitterVars.line = (BlitterVars.line+1) & 15;
1.1.1.7   root      788:        else
1.1.1.8   root      789:                BlitterVars.line = (BlitterVars.line-1) & 15;
                    790: }
                    791: 
                    792: /*-----------------------------------------------------------------------*/
                    793: /**
                    794:  * Blitter emulation - level 2
                    795:  */
                    796: 
                    797: static void Blitter_SingleWord(void)
                    798: {
                    799:        Blitter_BeginLine();
                    800:        Blitter_SetState(BlitterVars.fxsr, BlitterVars.nfsr, BlitterRegs.end_mask_1);
                    801:        Blitter_ProcessWord();
                    802:        Blitter_EndLine();
                    803: }
                    804: 
                    805: static void Blitter_FirstWord(void)
                    806: {
                    807:        Blitter_BeginLine();
                    808:        Blitter_SetState(BlitterVars.fxsr, 0, BlitterRegs.end_mask_1);
                    809:        Blitter_ProcessWord();
                    810: }
                    811: 
                    812: static void Blitter_MiddleWord(void)
                    813: {
                    814:        Blitter_SetState(0, 0, BlitterRegs.end_mask_2);
                    815:        Blitter_ProcessWord();
                    816: }
1.1.1.7   root      817: 
1.1.1.8   root      818: static void Blitter_LastWord(void)
                    819: {
                    820:        Blitter_SetState(0, BlitterVars.nfsr, BlitterRegs.end_mask_3);
                    821:        Blitter_ProcessWord();
                    822:        Blitter_EndLine();
1.1.1.7   root      823: }
1.1       root      824: 
1.1.1.8   root      825: static void Blitter_Step(void)
                    826: {
                    827:        if (BlitterVars.dst_words_reset == 1)
                    828:        {
                    829:                Blitter_SingleWord();
                    830:        }
                    831:        else if (BlitterRegs.words == BlitterVars.dst_words_reset)
                    832:        {
                    833:                Blitter_FirstWord();
                    834:        }
                    835:        else if (BlitterRegs.words == 1)
                    836:        {
                    837:                Blitter_LastWord();
                    838:        }
                    839:        else
                    840:        {
                    841:                Blitter_MiddleWord();
                    842:        }
                    843: }
1.1       root      844: 
1.1.1.3   root      845: /*-----------------------------------------------------------------------*/
1.1.1.5   root      846: /**
1.1.1.7   root      847:  * Let's do the blit.
1.1.1.16! root      848:  * Note that in non-HOG mode, the blitter only runs for 64 bus cycles
1.1.1.7   root      849:  * before giving the bus back to the CPU. Due to this mode, this function must
                    850:  * be able to abort and resume the blitting at any time.
1.1.1.16! root      851:  * - In cycle exact mode, the blitter will have 64 bus accesses and the cpu 64 bus accesses
        !           852:  * - In non cycle exact mode, the blitter will have 64 bus accesses and the cpu
        !           853:  *   will run during 64*4 = 256 cpu cycles
1.1.1.5   root      854:  */
1.1.1.8   root      855: static void Blitter_Start(void)
1.1.1.4   root      856: {
1.1.1.16! root      857: int FrameCycles, HblCounterVideo, LineCycles;
        !           858: Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
        !           859: 
        !           860: //fprintf ( stderr , "blitter start %d video_cyc=%d %d@%d\n" , nCyclesMainCounter , FrameCycles , LineCycles, HblCounterVideo );
        !           861: 
        !           862:        /* Select HOP & LOP funcs */
1.1.1.9   root      863:        Blitter_Select_HOP();
                    864:        Blitter_Select_LOP();
                    865: 
1.1.1.16! root      866:        /* Setup vars */
1.1.1.9   root      867:        BlitterVars.pass_cycles = 0;
                    868:        BlitterVars.op_cycles = 0;
1.1.1.12  root      869:        BlitterVars.src_words_reset = BlitterVars.dst_words_reset + BlitterVars.fxsr - BlitterVars.nfsr;
1.1.1.16! root      870:        BlitterState.CountBusBlitter = 0;
        !           871:        if ( Blitter_HOG_CPU_BusCountError )
        !           872:                BlitterState.CountBusBlitter++;                         /* Bug in the blitter : count 1 CPU access as a blitter access */
1.1.1.8   root      873: 
1.1.1.16! root      874:        /* Bus arbitration */
1.1.1.14  root      875:        Blitter_BusArbitration ( BUS_MODE_BLITTER );
1.1.1.16! root      876:        BlitterPhase = BLITTER_PHASE_RUN_TRANSFER;
1.1.1.14  root      877: 
                    878:        /* Busy=1, set line to high/1 and clear interrupt */
                    879:        MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_GPU_DONE , MFP_GPIP_STATE_HIGH );
1.1.1.7   root      880: 
                    881:        /* Now we enter the main blitting loop */
                    882:        do
                    883:        {
1.1.1.8   root      884:                Blitter_Step();
                    885:        }
1.1.1.16! root      886:        while ( BlitterRegs.lines > 0
        !           887:               && ( BlitterVars.hog || Blitter_ContinueNonHog() ) );
1.1.1.7   root      888: 
1.1.1.16! root      889:        /* Bus arbitration */
1.1.1.14  root      890:        Blitter_BusArbitration ( BUS_MODE_CPU );
1.1.1.7   root      891: 
1.1.1.8   root      892:        BlitterRegs.ctrl = (BlitterRegs.ctrl & 0xF0) | BlitterVars.line;
1.1.1.7   root      893: 
1.1.1.8   root      894:        if (BlitterRegs.lines == 0)
                    895:        {
1.1.1.16! root      896:                /* Blit complete, clear busy and hog bits */
1.1.1.14  root      897:                BlitterRegs.ctrl &= ~(0x80|0x40);
1.1.1.7   root      898: 
1.1.1.14  root      899:                /* Busy=0, set line to low/0 and request interrupt */
                    900:                MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_GPU_DONE , MFP_GPIP_STATE_LOW );
1.1.1.16! root      901: 
        !           902:                BlitterPhase = BLITTER_PHASE_STOP;
        !           903: 
        !           904:                if ( BLITTER_RUN_CE )
        !           905:                {
        !           906:                        /* In CE mode, we check if a CPU instruction could have ran in parallel to the blitter */
        !           907:                        BlitterPhase |= BLITTER_PHASE_IGNORE_LAST_CPU_CYCLES;
        !           908:                        Blitter_HOG_CPU_IgnoreMaxCpuCycles = BlitterVars.pass_cycles;
        !           909:                }
1.1.1.7   root      910:        }
1.1.1.8   root      911:        else
1.1.1.7   root      912:        {
1.1.1.16! root      913:                /* Blit not complete yet in non-hog mode, give back the bus to the CPU */
        !           914:                BlitterPhase = BLITTER_PHASE_COUNT_CPU_BUS;
        !           915: 
        !           916:                if ( BLITTER_RUN_CE )
        !           917:                {
        !           918:                        /* Continue blitting after 64 bus accesses in 68000 CE mode + check for parallel CPU instruction */
        !           919:                        BlitterPhase |= BLITTER_PHASE_IGNORE_LAST_CPU_CYCLES;
        !           920:                        Blitter_HOG_CPU_IgnoreMaxCpuCycles = BlitterVars.pass_cycles;
        !           921:                        BlitterState.CountBusCpu = 0;           /* Reset CPU bus counter */
        !           922:                }
        !           923:                else
        !           924:                {
        !           925:                        /* In non-cycle exact 68000 mode, we run the CPU for 64*4=256 cpu cycles, */
        !           926:                        /* which gives a good approximation */
        !           927:                        CycInt_AddRelativeInterrupt ( BLITTER_NONHOG_BUS_CPU*4, INT_CPU_CYCLE, INTERRUPT_BLITTER );
        !           928:                }
1.1.1.7   root      929:        }
                    930: }
                    931: 
1.1.1.16! root      932: 
        !           933: /*-----------------------------------------------------------------------*/
        !           934: /**
        !           935:  * This is called when no more CPU cycles should be ignored in case an
        !           936:  * instruction was running in parallel to the blitter
        !           937:  */
        !           938: static void Blitter_Stop_IgnoreLastCpuCycles(void)
        !           939: {
        !           940:        BlitterPhase &= ~BLITTER_PHASE_IGNORE_LAST_CPU_CYCLES;  /* No more CPU in parallel, stop ignoring next CPU cycles */
        !           941: 
        !           942:        /* If blitter is completely OFF now, disable the cpu specific part */
        !           943:        if ( BlitterPhase == BLITTER_PHASE_STOP )
        !           944:                M68000_SetBlitter_CE ( false );
        !           945: }
        !           946: 
        !           947: 
1.1.1.8   root      948: /*-----------------------------------------------------------------------*/
                    949: /**
                    950:  * Read blitter halftone ram.
                    951:  */
                    952: static void Blitter_Halftone_ReadWord(int index)
                    953: {
                    954:        IoMem_WriteWord(REG_HT_RAM + index + index, BlitterHalftone[index]);
                    955: }
                    956: 
                    957: void Blitter_Halftone00_ReadWord(void) { Blitter_Halftone_ReadWord(0); }
                    958: void Blitter_Halftone01_ReadWord(void) { Blitter_Halftone_ReadWord(1); }
                    959: void Blitter_Halftone02_ReadWord(void) { Blitter_Halftone_ReadWord(2); }
                    960: void Blitter_Halftone03_ReadWord(void) { Blitter_Halftone_ReadWord(3); }
                    961: void Blitter_Halftone04_ReadWord(void) { Blitter_Halftone_ReadWord(4); }
                    962: void Blitter_Halftone05_ReadWord(void) { Blitter_Halftone_ReadWord(5); }
                    963: void Blitter_Halftone06_ReadWord(void) { Blitter_Halftone_ReadWord(6); }
                    964: void Blitter_Halftone07_ReadWord(void) { Blitter_Halftone_ReadWord(7); }
                    965: void Blitter_Halftone08_ReadWord(void) { Blitter_Halftone_ReadWord(8); }
                    966: void Blitter_Halftone09_ReadWord(void) { Blitter_Halftone_ReadWord(9); }
                    967: void Blitter_Halftone10_ReadWord(void) { Blitter_Halftone_ReadWord(10); }
                    968: void Blitter_Halftone11_ReadWord(void) { Blitter_Halftone_ReadWord(11); }
                    969: void Blitter_Halftone12_ReadWord(void) { Blitter_Halftone_ReadWord(12); }
                    970: void Blitter_Halftone13_ReadWord(void) { Blitter_Halftone_ReadWord(13); }
                    971: void Blitter_Halftone14_ReadWord(void) { Blitter_Halftone_ReadWord(14); }
                    972: void Blitter_Halftone15_ReadWord(void) { Blitter_Halftone_ReadWord(15); }
                    973: 
                    974: /*-----------------------------------------------------------------------*/
                    975: /**
                    976:  * Read blitter source x increment (0xff8a20).
                    977:  */
                    978: void Blitter_SourceXInc_ReadWord(void)
                    979: {
                    980:        IoMem_WriteWord(REG_SRC_X_INC, (Uint16)(BlitterRegs.src_x_incr));
                    981: }
                    982: 
                    983: /*-----------------------------------------------------------------------*/
                    984: /**
                    985:  * Read blitter source y increment (0xff8a22).
                    986:  */
                    987: void Blitter_SourceYInc_ReadWord(void)
                    988: {
                    989:        IoMem_WriteWord(REG_SRC_Y_INC, (Uint16)(BlitterRegs.src_y_incr));
                    990: }
1.1.1.7   root      991: 
                    992: /*-----------------------------------------------------------------------*/
                    993: /**
                    994:  * Read blitter source address (0xff8a24).
                    995:  */
                    996: void Blitter_SourceAddr_ReadLong(void)
                    997: {
1.1.1.8   root      998:        IoMem_WriteLong(REG_SRC_ADDR, BlitterRegs.src_addr);
1.1.1.4   root      999: }
                   1000: 
                   1001: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1002: /**
                   1003:  * Read blitter endmask 1.
                   1004:  */
1.1.1.3   root     1005: void Blitter_Endmask1_ReadWord(void)
1.1       root     1006: {
1.1.1.8   root     1007:        IoMem_WriteWord(REG_END_MASK1, BlitterRegs.end_mask_1);
1.1       root     1008: }
                   1009: 
1.1.1.3   root     1010: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1011: /**
                   1012:  * Read blitter endmask 2.
                   1013:  */
1.1.1.3   root     1014: void Blitter_Endmask2_ReadWord(void)
1.1       root     1015: {
1.1.1.8   root     1016:        IoMem_WriteWord(REG_END_MASK2, BlitterRegs.end_mask_2);
1.1       root     1017: }
                   1018: 
1.1.1.3   root     1019: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1020: /**
                   1021:  * Read blitter endmask 3.
                   1022:  */
1.1.1.3   root     1023: void Blitter_Endmask3_ReadWord(void)
1.1       root     1024: {
1.1.1.8   root     1025:        IoMem_WriteWord(REG_END_MASK3, BlitterRegs.end_mask_3);
                   1026: }
                   1027: 
                   1028: /*-----------------------------------------------------------------------*/
                   1029: /**
                   1030:  * Read blitter destination x increment (0xff8a2E).
                   1031:  */
                   1032: void Blitter_DestXInc_ReadWord(void)
                   1033: {
                   1034:        IoMem_WriteWord(REG_DST_X_INC, (Uint16)(BlitterRegs.dst_x_incr));
                   1035: }
                   1036: 
                   1037: /*-----------------------------------------------------------------------*/
                   1038: /**
                   1039:  * Read blitter destination y increment (0xff8a30).
                   1040:  */
                   1041: void Blitter_DestYInc_ReadWord(void)
                   1042: {
                   1043:        IoMem_WriteWord(REG_DST_Y_INC, (Uint16)(BlitterRegs.dst_y_incr));
1.1       root     1044: }
                   1045: 
1.1.1.3   root     1046: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1047: /**
                   1048:  * Read blitter destination address.
                   1049:  */
1.1.1.3   root     1050: void Blitter_DestAddr_ReadLong(void)
1.1       root     1051: {
1.1.1.8   root     1052:        IoMem_WriteLong(REG_DST_ADDR, BlitterRegs.dst_addr);
1.1       root     1053: }
                   1054: 
1.1.1.3   root     1055: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1056: /**
                   1057:  * Read blitter words-per-line register.
                   1058:  */
1.1.1.3   root     1059: void Blitter_WordsPerLine_ReadWord(void)
1.1       root     1060: {
1.1.1.8   root     1061:        IoMem_WriteWord(REG_X_COUNT, (Uint16)(BlitterRegs.words & 0xFFFF));
1.1       root     1062: }
                   1063: 
1.1.1.3   root     1064: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1065: /**
                   1066:  * Read blitter lines-per-bitblock register.
                   1067:  */
1.1.1.3   root     1068: void Blitter_LinesPerBitblock_ReadWord(void)
1.1       root     1069: {
1.1.1.8   root     1070:        IoMem_WriteWord(REG_Y_COUNT, (Uint16)(BlitterRegs.lines & 0xFFFF));
1.1       root     1071: }
                   1072: 
1.1.1.3   root     1073: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1074: /**
                   1075:  * Read blitter halftone operation register.
                   1076:  */
1.1.1.3   root     1077: void Blitter_HalftoneOp_ReadByte(void)
1.1       root     1078: {
1.1.1.8   root     1079:        IoMem_WriteByte(REG_BLIT_HOP, BlitterRegs.hop);
1.1       root     1080: }
                   1081: 
1.1.1.3   root     1082: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1083: /**
                   1084:  * Read blitter logical operation register.
                   1085:  */
1.1.1.3   root     1086: void Blitter_LogOp_ReadByte(void)
1.1       root     1087: {
1.1.1.8   root     1088:        IoMem_WriteByte(REG_BLIT_LOP, BlitterRegs.lop);
1.1       root     1089: }
                   1090: 
1.1.1.3   root     1091: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1092: /**
                   1093:  * Read blitter control register.
                   1094:  */
1.1.1.4   root     1095: void Blitter_Control_ReadByte(void)
1.1       root     1096: {
1.1.1.7   root     1097:        /* busy, hog/blit, smudge, n/a, 4bits for line number */
1.1.1.8   root     1098:        IoMem_WriteByte(REG_CONTROL, BlitterRegs.ctrl);
1.1       root     1099: }
                   1100: 
1.1.1.3   root     1101: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1102: /**
                   1103:  * Read blitter skew register.
                   1104:  */
1.1.1.3   root     1105: void Blitter_Skew_ReadByte(void)
1.1       root     1106: {
1.1.1.8   root     1107:        IoMem_WriteByte(REG_SKEW, BlitterRegs.skew);
                   1108: }
                   1109: 
                   1110: 
                   1111: /*-----------------------------------------------------------------------*/
                   1112: /**
                   1113:  * Write to blitter halftone ram.
                   1114:  */
                   1115: static void Blitter_Halftone_WriteWord(int index)
                   1116: {
                   1117:        BlitterHalftone[index] = IoMem_ReadWord(REG_HT_RAM + index + index);
                   1118: }
                   1119: 
                   1120: void Blitter_Halftone00_WriteWord(void) { Blitter_Halftone_WriteWord(0); }
                   1121: void Blitter_Halftone01_WriteWord(void) { Blitter_Halftone_WriteWord(1); }
                   1122: void Blitter_Halftone02_WriteWord(void) { Blitter_Halftone_WriteWord(2); }
                   1123: void Blitter_Halftone03_WriteWord(void) { Blitter_Halftone_WriteWord(3); }
                   1124: void Blitter_Halftone04_WriteWord(void) { Blitter_Halftone_WriteWord(4); }
                   1125: void Blitter_Halftone05_WriteWord(void) { Blitter_Halftone_WriteWord(5); }
                   1126: void Blitter_Halftone06_WriteWord(void) { Blitter_Halftone_WriteWord(6); }
                   1127: void Blitter_Halftone07_WriteWord(void) { Blitter_Halftone_WriteWord(7); }
                   1128: void Blitter_Halftone08_WriteWord(void) { Blitter_Halftone_WriteWord(8); }
                   1129: void Blitter_Halftone09_WriteWord(void) { Blitter_Halftone_WriteWord(9); }
                   1130: void Blitter_Halftone10_WriteWord(void) { Blitter_Halftone_WriteWord(10); }
                   1131: void Blitter_Halftone11_WriteWord(void) { Blitter_Halftone_WriteWord(11); }
                   1132: void Blitter_Halftone12_WriteWord(void) { Blitter_Halftone_WriteWord(12); }
                   1133: void Blitter_Halftone13_WriteWord(void) { Blitter_Halftone_WriteWord(13); }
                   1134: void Blitter_Halftone14_WriteWord(void) { Blitter_Halftone_WriteWord(14); }
                   1135: void Blitter_Halftone15_WriteWord(void) { Blitter_Halftone_WriteWord(15); }
                   1136: 
                   1137: /*-----------------------------------------------------------------------*/
                   1138: /**
                   1139:  * Write to blitter source x increment.
                   1140:  */
                   1141: void Blitter_SourceXInc_WriteWord(void)
                   1142: {
                   1143:        BlitterRegs.src_x_incr = (short)(IoMem_ReadWord(REG_SRC_X_INC) & 0xFFFE);
1.1       root     1144: }
                   1145: 
1.1.1.8   root     1146: /*-----------------------------------------------------------------------*/
                   1147: /**
                   1148:  * Write to blitter source y increment.
                   1149:  */
                   1150: void Blitter_SourceYInc_WriteWord(void)
                   1151: {
                   1152:        BlitterRegs.src_y_incr = (short)(IoMem_ReadWord(REG_SRC_Y_INC) & 0xFFFE);
                   1153: }
1.1       root     1154: 
1.1.1.3   root     1155: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1156: /**
1.1.1.7   root     1157:  * Write to blitter source address register (0xff8a24).
                   1158:  */
                   1159: void Blitter_SourceAddr_WriteLong(void)
                   1160: {
1.1.1.14  root     1161:        if ( ConfigureParams.System.bAddressSpace24 == true )
                   1162:                BlitterRegs.src_addr = IoMem_ReadLong(REG_SRC_ADDR) & 0x00FFFFFE;       /* Normal STF/STE */
                   1163:        else
                   1164:                BlitterRegs.src_addr = IoMem_ReadLong(REG_SRC_ADDR) & 0xFFFFFFFE;       /* Falcon with extra TT RAM */
1.1.1.7   root     1165: }
                   1166: 
                   1167: /*-----------------------------------------------------------------------*/
                   1168: /**
1.1.1.5   root     1169:  * Write to blitter endmask 1.
                   1170:  */
1.1.1.3   root     1171: void Blitter_Endmask1_WriteWord(void)
1.1       root     1172: {
1.1.1.8   root     1173:        BlitterRegs.end_mask_1 = IoMem_ReadWord(REG_END_MASK1);
1.1       root     1174: }
                   1175: 
1.1.1.3   root     1176: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1177: /**
                   1178:  * Write to blitter endmask 2.
                   1179:  */
1.1.1.3   root     1180: void Blitter_Endmask2_WriteWord(void)
1.1       root     1181: {
1.1.1.8   root     1182:        BlitterRegs.end_mask_2 = IoMem_ReadWord(REG_END_MASK2);
1.1       root     1183: }
                   1184: 
1.1.1.3   root     1185: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1186: /**
                   1187:  * Write to blitter endmask 3.
                   1188:  */
1.1.1.3   root     1189: void Blitter_Endmask3_WriteWord(void)
1.1       root     1190: {
1.1.1.8   root     1191:        BlitterRegs.end_mask_3 = IoMem_ReadWord(REG_END_MASK3);
                   1192: }
                   1193: 
                   1194: /*-----------------------------------------------------------------------*/
                   1195: /**
                   1196:  * Write to blitter destination x increment.
                   1197:  */
                   1198: void Blitter_DestXInc_WriteWord(void)
                   1199: {
                   1200:        BlitterRegs.dst_x_incr = (short)(IoMem_ReadWord(REG_DST_X_INC) & 0xFFFE);
                   1201: }
                   1202: 
                   1203: /*-----------------------------------------------------------------------*/
                   1204: /**
                   1205:  * Write to blitter source y increment.
                   1206:  */
                   1207: void Blitter_DestYInc_WriteWord(void)
                   1208: {
                   1209:        BlitterRegs.dst_y_incr = (short)(IoMem_ReadWord(REG_DST_Y_INC) & 0xFFFE);
1.1       root     1210: }
                   1211: 
1.1.1.3   root     1212: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1213: /**
                   1214:  * Write to blitter destination address register.
                   1215:  */
1.1.1.3   root     1216: void Blitter_DestAddr_WriteLong(void)
                   1217: {
1.1.1.14  root     1218:        if ( ConfigureParams.System.bAddressSpace24 == true )
                   1219:                BlitterRegs.dst_addr = IoMem_ReadLong(REG_DST_ADDR) & 0x00FFFFFE;       /* Normal STF/STE */
                   1220:        else
                   1221:                BlitterRegs.dst_addr = IoMem_ReadLong(REG_DST_ADDR) & 0xFFFFFFFE;       /* Falcon with extra TT RAM */
1.1       root     1222: }
                   1223: 
1.1.1.3   root     1224: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1225: /**
                   1226:  * Write to blitter words-per-line register.
                   1227:  */
1.1.1.3   root     1228: void Blitter_WordsPerLine_WriteWord(void)
1.1       root     1229: {
1.1.1.8   root     1230:        Uint32 words = (Uint32)IoMem_ReadWord(REG_X_COUNT);
                   1231: 
                   1232:        if (words == 0)
                   1233:                words = 65536;
                   1234: 
                   1235:        BlitterRegs.words = words;
                   1236:        BlitterVars.dst_words_reset = words;
1.1       root     1237: }
                   1238: 
1.1.1.3   root     1239: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1240: /**
1.1.1.8   root     1241:  * Write to blitter lines-per-bitblock register.
1.1.1.5   root     1242:  */
1.1.1.3   root     1243: void Blitter_LinesPerBitblock_WriteWord(void)
1.1       root     1244: {
1.1.1.8   root     1245:        Uint32 lines = (Uint32)IoMem_ReadWord(REG_Y_COUNT);
                   1246: 
                   1247:        if (lines == 0)
                   1248:                lines = 65536;
                   1249: 
                   1250:        BlitterRegs.lines = lines;
1.1       root     1251: }
                   1252: 
1.1.1.3   root     1253: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1254: /**
                   1255:  * Write to blitter halftone operation register.
                   1256:  */
1.1.1.3   root     1257: void Blitter_HalftoneOp_WriteByte(void)
1.1       root     1258: {
1.1.1.4   root     1259:        /* h/ware reg masks out the top 6 bits! */
1.1.1.8   root     1260:        BlitterRegs.hop = IoMem_ReadByte(REG_BLIT_HOP) & 3;
1.1       root     1261: }
                   1262: 
1.1.1.3   root     1263: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1264: /**
                   1265:  * Write to blitter logical operation register.
                   1266:  */
1.1.1.3   root     1267: void Blitter_LogOp_WriteByte(void)
1.1.1.7   root     1268: {
1.1.1.4   root     1269:        /* h/ware reg masks out the top 4 bits! */
1.1.1.8   root     1270:        BlitterRegs.lop = IoMem_ReadByte(REG_BLIT_LOP) & 0xF;
1.1       root     1271: }
                   1272: 
1.1.1.3   root     1273: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1274: /**
                   1275:  * Write to blitter control register.
                   1276:  */
1.1.1.4   root     1277: void Blitter_Control_WriteByte(void)
                   1278: {
1.1.1.16! root     1279:        Uint8   ctrl_old;
        !          1280: 
1.1.1.4   root     1281:        /* Control register bits:
                   1282:         * 0x80: busy bit
                   1283:         * - Turn on Blitter activity and stay "1" until copy finished
                   1284:         * 0x40: Blit-mode bit
1.1.1.16! root     1285:         * - 0: Blit mode, CPU and Blitter get 64 bus accesses in turns
1.1.1.4   root     1286:         * - 1: HOG Mode, Blitter reserves and hogs the bus for as long
                   1287:         *      as the copy takes, CPU and DMA get no Bus access
                   1288:         * 0x20: Smudge mode
                   1289:         * - Which line of the halftone pattern to start with is
                   1290:         *   read from the first source word when the copy starts
                   1291:         * 0x10: not used
                   1292:         * 0x0f
                   1293:         *
                   1294:         * The lowest 4 bits contain the Halftone pattern line number
                   1295:         */
1.1.1.7   root     1296: 
1.1.1.16! root     1297:        ctrl_old = BlitterRegs.ctrl;
        !          1298: 
1.1.1.9   root     1299:        if (LOG_TRACE_LEVEL(TRACE_BLITTER))
1.1.1.3   root     1300:        {
1.1.1.9   root     1301:                int FrameCycles, HblCounterVideo, LineCycles;
                   1302: 
                   1303:                Video_GetPosition ( &FrameCycles , &HblCounterVideo , &LineCycles );
                   1304: 
1.1.1.16! root     1305:                LOG_TRACE_PRINT("blitter write ctrl=%02x ctrl_old=%02x video_cyc=%d %d@%d pc=%x instr_cyc=%d\n" ,
        !          1306:                                IoMem_ReadByte(REG_CONTROL) , ctrl_old ,
1.1.1.9   root     1307:                                FrameCycles, LineCycles, HblCounterVideo, M68000_GetPC(), CurrentInstrCycles );
1.1.1.7   root     1308:        }
1.1.1.3   root     1309: 
1.1.1.8   root     1310:        BlitterRegs.ctrl = IoMem_ReadByte(REG_CONTROL) & 0xEF;
                   1311: 
                   1312:        BlitterVars.hog = BlitterRegs.ctrl & 0x40;
                   1313:        BlitterVars.smudge = BlitterRegs.ctrl & 0x20;
                   1314:        BlitterVars.line = BlitterRegs.ctrl & 0xF;
1.1.1.7   root     1315: 
                   1316:        /* Remove old pending update interrupt */
1.1.1.10  root     1317:        CycInt_RemovePendingInterrupt(INTERRUPT_BLITTER);
1.1.1.7   root     1318: 
                   1319:        /* Busy bit set? */
1.1.1.8   root     1320:        if (BlitterRegs.ctrl & 0x80)
1.1.1.7   root     1321:        {
1.1.1.8   root     1322:                if (BlitterRegs.lines == 0)
1.1.1.7   root     1323:                {
1.1.1.16! root     1324:                        /* Blitter transfer is already complete, clear busy and hog bits */
        !          1325:                        BlitterRegs.ctrl &= ~(0x80|0x40);                       // TODO : check on real STE, does it clear hog bit too ?
1.1.1.7   root     1326:                }
                   1327:                else
                   1328:                {
1.1.1.16! root     1329:                        /* Start blitter after a small delay */
        !          1330:                        /* In non-hog mode, the cpu can "restart" the blitter immediately (without waiting */
        !          1331:                        /* for 64 cpu bus accesses) by setting busy bit. This means we should reset */
        !          1332:                        /* BlitterState.ContinueLater only if the blitter was stopped before ; */
        !          1333:                        /* else if the blitter is restarted we must keep the value of BlitterState.ContinueLater */
        !          1334:                        if ( BLITTER_RUN_CE )
        !          1335:                        {
        !          1336:                                if ( ( ctrl_old & 0x80 ) == 0 )                 /* Only when blitter is started (not when restarted) */
        !          1337:                                {
        !          1338:                                        M68000_SetBlitter_CE ( true );
        !          1339:                                        BlitterState.ContinueLater = 0;
        !          1340:                                }
        !          1341: 
        !          1342:                                /* 68000 CE : 4 cycles to complete current bus write to ctrl reg + 4 cycles before blitter request the bus */
        !          1343:                                Blitter_CyclesBeforeStart = 4 + 4;
        !          1344:                                BlitterPhase = BLITTER_PHASE_PRE_START;
        !          1345:                                Blitter_HOG_CPU_BusCountError = 0;
        !          1346:                        }
        !          1347:                        else
        !          1348:                        {
        !          1349:                                if ( ( ctrl_old & 0x80 ) == 0 )                 /* Only when blitter is started (not when restarted) */
        !          1350:                                {
        !          1351:                                        BlitterState.ContinueLater = 0;
        !          1352:                                }
        !          1353: 
        !          1354:                                /* Non 68000 CE mode : start blitting after the end of current instruction */
        !          1355:                                CycInt_AddRelativeInterrupt( CurrentInstrCycles+WaitStateCycles, INT_CPU_CYCLE, INTERRUPT_BLITTER);
        !          1356:                        }
1.1.1.7   root     1357:                }
1.1.1.3   root     1358:        }
1.1.1.16! root     1359: 
        !          1360:        else                                    /* busy bit clear */
        !          1361:        {
        !          1362:                /* If busy bit is forced to 0 (to stop the blitter in non-hog mode), we must update */
        !          1363:                /* the interrupt line too */
        !          1364:                // TODO : check on real STE, does it clear hog bit too ? It seems not, else 'Relapse' demo will fail in some parts
        !          1365: //             BlitterRegs.ctrl &= ~(0x80|0x40);
        !          1366: 
        !          1367:                /* Busy=0, set line to low/0 and request interrupt */
        !          1368:                MFP_GPIP_Set_Line_Input ( MFP_GPIP_LINE_GPU_DONE , MFP_GPIP_STATE_LOW );
        !          1369: 
        !          1370:                BlitterPhase = BLITTER_PHASE_STOP;
        !          1371:                if ( BLITTER_RUN_CE )
        !          1372:                        M68000_SetBlitter_CE ( false );
        !          1373:        }
1.1       root     1374: }
                   1375: 
1.1.1.3   root     1376: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1377: /**
                   1378:  * Write to blitter skew register.
                   1379:  */
1.1.1.3   root     1380: void Blitter_Skew_WriteByte(void)
                   1381: {
1.1.1.8   root     1382:        BlitterRegs.skew = IoMem_ReadByte(REG_SKEW);
                   1383:        BlitterVars.fxsr = (BlitterRegs.skew & 0x80)?1:0;
                   1384:        BlitterVars.nfsr = (BlitterRegs.skew & 0x40)?1:0;
                   1385:        BlitterVars.skew = BlitterRegs.skew & 0xF;
1.1       root     1386: }
1.1.1.2   root     1387: 
                   1388: 
                   1389: /*-----------------------------------------------------------------------*/
1.1.1.5   root     1390: /**
1.1.1.16! root     1391:  * Handler which continues blitting after 64 bus cycles in non-CE mode
1.1.1.7   root     1392:  */
                   1393: void Blitter_InterruptHandler(void)
                   1394: {
1.1.1.10  root     1395:        CycInt_AcknowledgeInterrupt();
1.1.1.7   root     1396: 
1.1.1.8   root     1397:        if (BlitterRegs.ctrl & 0x80)
1.1.1.7   root     1398:        {
1.1.1.8   root     1399:                Blitter_Start();
1.1.1.7   root     1400:        }
1.1.1.8   root     1401: }
1.1.1.7   root     1402: 
1.1.1.8   root     1403: /*-----------------------------------------------------------------------*/
                   1404: /**
                   1405:  * Save/Restore snapshot of Blitter variables.
                   1406:  */
                   1407: void Blitter_MemorySnapShot_Capture(bool bSave)
                   1408: {
                   1409:        /* Save/Restore details */
                   1410:        MemorySnapShot_Store(&BlitterRegs, sizeof(BlitterRegs));
                   1411:        MemorySnapShot_Store(&BlitterVars, sizeof(BlitterVars));
                   1412:        MemorySnapShot_Store(&BlitterHalftone, sizeof(BlitterHalftone));
1.1.1.16! root     1413:        MemorySnapShot_Store(&BlitterState, sizeof(BlitterState));
        !          1414: 
        !          1415:        MemorySnapShot_Store(&BlitterPhase, sizeof(BlitterPhase));
        !          1416: 
        !          1417:        if ( !bSave )
        !          1418:        {
        !          1419:                /* On restore, we set blitter specific CPU functions if needed */
        !          1420:                if ( BlitterPhase && BLITTER_RUN_CE )
        !          1421:                        M68000_SetBlitter_CE ( true );
        !          1422:        }
        !          1423: 
1.1.1.2   root     1424: }
1.1.1.12  root     1425: 
                   1426: /*-----------------------------------------------------------------------*/
                   1427: /**
                   1428:  * Show Blitter register values.
                   1429:  */
1.1.1.14  root     1430: void Blitter_Info(FILE *fp, Uint32 dummy)
1.1.1.12  root     1431: {
                   1432:        BLITTERREGS *regs = &BlitterRegs;
                   1433: 
1.1.1.16! root     1434:        fprintf(fp, "src addr  (0x%x): 0x%06x\n", REG_SRC_ADDR, regs->src_addr);
        !          1435:        fprintf(fp, "dst addr  (0x%x): 0x%06x\n", REG_DST_ADDR, regs->dst_addr);
        !          1436:        fprintf(fp, "words     (0x%x): %u\n",     REG_X_COUNT, regs->words);
        !          1437:        fprintf(fp, "lines     (0x%x): %u\n",     REG_Y_COUNT, regs->lines);
        !          1438:        fprintf(fp, "src X-inc (0x%x): %hd\n",    REG_SRC_X_INC, regs->src_x_incr);
        !          1439:        fprintf(fp, "src Y-inc (0x%x): %hd\n",    REG_SRC_Y_INC, regs->src_y_incr);
        !          1440:        fprintf(fp, "dst X-inc (0x%x): %hd\n",    REG_DST_X_INC, regs->dst_x_incr);
        !          1441:        fprintf(fp, "dst Y-inc (0x%x): %hd\n",    REG_DST_Y_INC, regs->dst_y_incr);
        !          1442:        fprintf(fp, "end mask1 (0x%x): 0x%04x\n", REG_END_MASK1, regs->end_mask_1);
        !          1443:        fprintf(fp, "end mask2 (0x%x): 0x%04x\n", REG_END_MASK2, regs->end_mask_2);
        !          1444:        fprintf(fp, "end mask3 (0x%x): 0x%04x\n", REG_END_MASK3, regs->end_mask_3);
        !          1445:        fprintf(fp, "HOP       (0x%x): 0x%02x\n", REG_BLIT_HOP, regs->hop);
        !          1446:        fprintf(fp, "LOP       (0x%x): 0x%02x\n", REG_BLIT_LOP, regs->lop);
        !          1447:        /* List control bits: busy, hog/blit, smudge, n/a, 4bits for line number ? */
        !          1448:        fprintf(fp, "control   (0x%x): 0x%02x\n", REG_CONTROL, regs->ctrl);
        !          1449:        fprintf(fp, "skew      (0x%x): 0x%02x\n", REG_SKEW, regs->skew);
1.1.1.13  root     1450:        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     1451: }
1.1.1.16! root     1452: 
        !          1453: 
        !          1454: 
        !          1455: 
        !          1456: /*-----------------------------------------------------------------------*/
        !          1457: /**
        !          1458:  * This is called from the CPU emulation before doing a memory access.
        !          1459:  */
        !          1460: void   Blitter_HOG_CPU_mem_access_before ( int bus_count )
        !          1461: {
        !          1462: //fprintf ( stderr , "cpu_bus before phase=%d bus=%d %x %d cur_cyc=%lu start_acces=%d\n" , BlitterPhase , BusMode , BlitterRegs.ctrl , BlitterState.CountBusCpu , currcycle/cpucycleunit , Blitter_HOG_CPU_BlitterStartDuringBusAccess );
        !          1463: 
        !          1464:        Blitter_HOG_CPU_FromBusAccess = 1;                      /* CPU bus access in progress */
        !          1465: 
        !          1466:        /* NOTE [NP] It seems there's a bug in the blitter when it counts his own bus accesses : */
        !          1467:        /* if a CPU bus access happens during the "pre start" blitter phase, then the blitter will wrongly */
        !          1468:        /* count it as a blitter bus access and will do only 63 bus accesses during copy instead of 64 in non-hog mode */
        !          1469:        if ( BlitterPhase == BLITTER_PHASE_PRE_START )
        !          1470:                Blitter_HOG_CPU_BusCountError = 1;
        !          1471: 
        !          1472:        /* If the bus is accessed by the CPU and we're ignoring CPU cycles that occurred in parallel */
        !          1473:        /* during the blitter's transfer, then we disable IGNORE_LAST_CPU_CYCLES as the CPU was stalled */
        !          1474:        /* after this point because it couldn't access the bus (which was owned by the blitter) */
        !          1475:        else if ( BlitterPhase & BLITTER_PHASE_IGNORE_LAST_CPU_CYCLES )
        !          1476:        {
        !          1477:                Blitter_Stop_IgnoreLastCpuCycles();             /* No more CPU in parallel, stop ignoring next CPU cycles */
        !          1478:        }
        !          1479: }
        !          1480: 
        !          1481: 
        !          1482: 
        !          1483: /*-----------------------------------------------------------------------*/
        !          1484: /**
        !          1485:  * This is called from the CPU emulation after doing a memory access.
        !          1486:  * Here, we count the number of bus accesses made by the CPU in non-hog mode.
        !          1487:  * When the CPU reaches 64 accesses, we restart the blitter.
        !          1488:  */
        !          1489: void   Blitter_HOG_CPU_mem_access_after ( int bus_count )
        !          1490: {
        !          1491: //fprintf ( stderr , "cpu_bus after phase=%d bus=%d %x %d cur_cyc=%lu start_acces=%d\n" , BlitterPhase , BusMode , BlitterRegs.ctrl , BlitterState.CountBusCpu , currcycle/cpucycleunit,Blitter_HOG_CPU_BlitterStartDuringBusAccess );
        !          1492: 
        !          1493:        if ( BlitterPhase & BLITTER_PHASE_COUNT_CPU_BUS )
        !          1494:        {
        !          1495:                if ( Blitter_HOG_CPU_BlitterStartDuringBusAccess )
        !          1496:                {
        !          1497:                        Blitter_HOG_CPU_BlitterStartDuringBusAccess = 0;
        !          1498:                        return;
        !          1499:                }
        !          1500:                
        !          1501:                BlitterState.CountBusCpu += bus_count;
        !          1502:                if ( BlitterState.CountBusCpu >= BLITTER_NONHOG_BUS_CPU )
        !          1503:                {
        !          1504:                        Blitter_CyclesBeforeStart = 4;
        !          1505:                        BlitterPhase = BLITTER_PHASE_PRE_START;
        !          1506:                        Blitter_HOG_CPU_BusCountError = 0;
        !          1507:                }
        !          1508:        }
        !          1509: 
        !          1510: 
        !          1511:        Blitter_HOG_CPU_FromBusAccess = 0;                      /* CPU bus access is done */
        !          1512: }
        !          1513: 
        !          1514: 
        !          1515: 
        !          1516: 
        !          1517: /*-----------------------------------------------------------------------*/
        !          1518: /**
        !          1519:  * This is called from the CPU emulation before "do_cycles()" to check
        !          1520:  * if part of an instruction was executed simultaneously to the blitter.
        !          1521:  * If so, we don't count those CPU cycles (as they were already counted
        !          1522:  * during the blitter part) and we skip the "do_cycles()"
        !          1523:  * We skip CPU cycles until Blitter_HOG_CPU_IgnoreMaxCpuCycles=0 or until
        !          1524:  * we reach a bus access (whichever comes first)
        !          1525:  */
        !          1526: 
        !          1527: int    Blitter_Check_Simultaneous_CPU ( void )
        !          1528: {
        !          1529:        static int cpu_skip_cycles = 0;
        !          1530: //fprintf ( stderr , "blitter simult phase=%d bus=%d %x cur_cyc=%lu\n" , BlitterPhase , BusMode , BlitterRegs.ctrl , currcycle/cpucycleunit );
        !          1531: 
        !          1532:        if ( BlitterPhase & BLITTER_PHASE_IGNORE_LAST_CPU_CYCLES )
        !          1533:        {
        !          1534:                Blitter_HOG_CPU_IgnoreMaxCpuCycles -= 2;
        !          1535:                if ( Blitter_HOG_CPU_IgnoreMaxCpuCycles <= 0 )
        !          1536:                        Blitter_Stop_IgnoreLastCpuCycles();     /* No more CPU in parallel, stop ignoring next CPU cycles */
        !          1537: 
        !          1538:                cpu_skip_cycles += 2;
        !          1539: //fprintf ( stderr , "blitter cpu skip %d cycles, max skip %d\n" , cpu_skip_cycles , Blitter_HOG_CPU_IgnoreMaxCpuCycles );
        !          1540:                return 1;                                       /* Skip next do_cycles() */
        !          1541:        }
        !          1542: 
        !          1543:        cpu_skip_cycles = 0;
        !          1544:        return 0;                                               /* Don't skip next do_cycles() */
        !          1545: }
        !          1546: 
        !          1547: 
        !          1548: 
        !          1549: /*-----------------------------------------------------------------------*/
        !          1550: /**
        !          1551:  * This is called from the cpu emulation after "do_cycles()" to count
        !          1552:  * the number of cycles since the blitter was (re)started.
        !          1553:  * After Blitter_CyclesBeforeStart cycles, we go to the next phase BLITTER_PHASE_START
        !          1554:  * to handle bus to the blitter and to copy data.
        !          1555:  */
        !          1556:  void  Blitter_HOG_CPU_do_cycles_after ( int cycles )
        !          1557: {
        !          1558: //fprintf ( stderr , "blitter do_cyc_after phase=%d bus=%d %x cyc=%d cur_cyc=%lu\n" , BlitterPhase , BusMode , BlitterRegs.ctrl , cycles , currcycle/cpucycleunit );
        !          1559: 
        !          1560:        if ( BlitterPhase == BLITTER_PHASE_PRE_START )
        !          1561:        {
        !          1562:                Blitter_CyclesBeforeStart -= cycles;
        !          1563:                if ( Blitter_CyclesBeforeStart <= 0 )
        !          1564:                {
        !          1565:                        /* This is specific to our cpu emulation, to avoid counting the current */
        !          1566:                        /* bus access (during which the blitter starts) as the first cpu bus access in non-hog mode */
        !          1567:                        if ( Blitter_HOG_CPU_FromBusAccess )
        !          1568:                                Blitter_HOG_CPU_BlitterStartDuringBusAccess = 1;
        !          1569:                        else
        !          1570:                                Blitter_HOG_CPU_BlitterStartDuringBusAccess = 0;
        !          1571: 
        !          1572:                        /* Start the main blitter part */
        !          1573:                        BlitterPhase = BLITTER_PHASE_START;
        !          1574:                        Blitter_Start();
        !          1575:                }
        !          1576:        }
        !          1577: 
        !          1578: }
        !          1579: 
        !          1580: 

unix.superglobalmegacorp.com

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