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

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

unix.superglobalmegacorp.com

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