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

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

unix.superglobalmegacorp.com

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