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

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

unix.superglobalmegacorp.com

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