diff --git a/009.anim_blit/Makefile b/009.anim_blit/Makefile index 08f11b8..cd673f3 100644 --- a/009.anim_blit/Makefile +++ b/009.anim_blit/Makefile @@ -5,7 +5,7 @@ IMAGEFILE=../assets/mission-beach.png BOB_BASE=out/emoji BOB_IMAGEDATA=$(BOB_BASE).bin $(BOB_BASE)-mask.bin BOB_IMAGEFILE=../assets/emoji.png -EXTRA=$(IMAGEDATA) $(BOB_IMAGEDATA) +EXTRA=$(IMAGEDATA) $(BOB_IMAGEDATA) blit.s init.s utils.s SHARED_PALETTE_BASE=out/shared-palette SHARED_PALETTE=$(SHARED_PALETTE_BASE).pal diff --git a/009.anim_blit/README.md b/009.anim_blit/README.md index 20e43cc..c00590f 100644 --- a/009.anim_blit/README.md +++ b/009.anim_blit/README.md @@ -1,26 +1,8 @@ -perform a shifted blit -====================== +animate a blitter object +======================== -Extending [007.masked_blit](../007.masked_blit), we now add the capability to blit to non word aligned columns. - -The blitter can only address word aligned screen positions. This makes drawing something on a non word aligned boundary slightly more complex. - -So the algorithm for drawing to non word aligned boundaries is as follows: - 1. The destination address is the word aligned address to the left of the desired position. - 2. Command the blitter to blit an extra word to the right of our blitter object. - 3. We mask the trailing word of each line to prevent the extra word from being blit. - 4. We right shift the data by the difference in bits between the desired column and the word aligned column from (1). - 5. We make the line modulos #-2 so blitter object data is correctly fetched. - - - -[Download disk image](bin/shift_blit.adf?raw=true) +[Download disk image](bin/anim_blit.adf?raw=true) Screenshot: ![Screenshot](screenshot.png?raw=true) - -Masked blit screenshot for reference: - -![Screenshot](../007.masked_blit/screenshot.png?raw=true) - diff --git a/009.anim_blit/anim_blit.s b/009.anim_blit/anim_blit.s index 061845e..8482711 100644 --- a/009.anim_blit/anim_blit.s +++ b/009.anim_blit/anim_blit.s @@ -2,182 +2,35 @@ include "hardware/dmabits.i" include "hardware/intbits.i" -LVL3_INT_VECTOR equ $6c -SCREEN_WIDTH equ 320 -SCREEN_HEIGHT equ 256 -SCREEN_WIDTH_BYTES equ (SCREEN_WIDTH/8) -SCREEN_BIT_DEPTH equ 5 -SCREEN_RES equ 8 ; 8=lo resolution, 4=hi resolution -RASTER_X_START equ $81 ; hard coded coordinates from hardware manual -RASTER_Y_START equ $2c -RASTER_X_STOP equ RASTER_X_START+SCREEN_WIDTH -RASTER_Y_STOP equ RASTER_Y_START+SCREEN_HEIGHT - + include "constants.i" entry: - ;; custom chip base globally in a6 - lea CUSTOM,a6 - - move #$7ff,DMACON(a6) ; disable all dma - move #$7fff,INTENA(a6) ; disable all interrupts - - include "out/image-palette.s" - if 0 - ;; reset color registers to white to prevent startup flicker - move.l #32,d0 - lea COLOR00(a6),a0 -.loop: - move.w #$FFF,(a0) - addq #2,a0 - dbra d0,.loop - endif - - ;; set up playfield - move.w #(RASTER_Y_START<<8)|RASTER_X_START,DIWSTRT(a6) - move.w #((RASTER_Y_STOP-256)<<8)|(RASTER_X_STOP-256),DIWSTOP(a6) - - move.w #(RASTER_X_START/2-SCREEN_RES),DDFSTRT(a6) - move.w #(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1)),DDFSTOP(a6) - - move.w #(SCREEN_BIT_DEPTH<<12)|$200,BPLCON0(a6) - move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL1MOD(a6) - move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES,BPL2MOD(a6) - - ;; poke bitplane pointers - lea bitplanes(pc),a1 - lea copper(pc),a2 - moveq #SCREEN_BIT_DEPTH-1,d0 -.bitplaneloop: - move.l a1,d1 - move.w d1,2(a2) - swap d1 - move.w d1,6(a2) - lea SCREEN_WIDTH_BYTES(a1),a1 ; bit plane data is interleaved - addq #8,a2 - dbra d0,.bitplaneloop - - ;; install copper list, then enable dma and selected interrupts - lea copper(pc),a0 - move.l a0,COP1LC(a6) - move.w COPJMP1(a6),d0 - move.w #(DMAF_BLITTER|DMAF_SETCLR!DMAF_COPPER!DMAF_RASTER!DMAF_MASTER),DMACON(a6) - move.w #(INTF_SETCLR|INTF_INTEN|INTF_EXTER),INTENA(a6) - - - moveq #32,d0 - moveq #32,d1 + include "init.s" + moveq #32,d0 ; starting x position for the blitter object + moveq #32,d1 ; starting y position for the blitter object + lea bitplanes(pc),a0 + lea emoji,a1 + lea emojiMask,a2 .mainLoop: bsr.s waitvbl - bsr.s doblit - addq #1,d0 - cmp.l #SCREEN_WIDTH-BOB_WIDTH,d0 + bsr.s blitObject64 ; blit 64 pixel object (x=d0,y=d1,background=a0,object=a1,mask=a2) + addq #1,d0 ; move the blitter object one pixel to the left + addq #1,d1 ; move the blitter object one pixel down + cmp.l #SCREEN_WIDTH-BOB_WIDTH,d0 ; check if we need to wrap the x bne.s .skip - moveq #0,d0 -.skip: + moveq #0,d0 ; wrap x back to zero +.skip: + + cmp.l #SCREEN_HEIGHT-BOB_HEIGHT,d1 ; check if we need to wrap the y + bne.s .skip2 + moveq #0,d1 ; wrap y back to the top +.skip2: bra.s .mainLoop -waitvbl: - movem.l d0-a6,-(sp) -.loop move.l $dff004,d0 - and.l #$1ff00,d0 - cmp.l #303<<8,d0 - bne.b .loop - movem.l (sp)+,d0-a6 - rts + include "utils.s" + include "blit.s" -blitWait: - tst DMACONR(a6) ;for compatibility -.waitblit: - btst #6,DMACONR(a6) - bne.s .waitblit - rts - -;; BLTCON? configuration -;; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node011C.html -;; blitter logic function minterm truth table -;; fill in D column for desired function -;; A(mask) B(bob) C(bg) D(dest) -;; - - - - -;; 0 0 0 0 -;; 0 0 1 1 -;; 0 1 0 0 -;; 0 1 1 1 -;; 1 0 0 0 -;; 1 0 1 0 -;; 1 1 0 1 -;; 1 1 1 1 -;; read D column from bottom up = 11001010 = $ca -;; this is used in the LF? bits -BLIT_LF_MINTERM equ $ca -BLIT_DEST equ $100 -BLIT_SRCC equ $200 -BLIT_SRCB equ $400 -BLIT_SRCA equ $800 -BLIT_ASHIFTSHIFT equ 12 ;Bit index of ASH? bits - - -BOB_WIDTH equ 64+16 ; Must blit extra word to allow shifting -BOB_HEIGHT equ 64 -BOB_WIDTH_BYTES equ BOB_WIDTH/8 -BOB_WIDTH_WORDS equ BOB_WIDTH/16 -;; BOB_XPOS equ 16 -;; BOB_YPOS equ 16 -;; BOB_XPOS_BYTES equ (BOB_XPOS)/8 - - -doblit: ; d0 xpos, d1 xpoy - movem.l d0-a6,-(sp) - bsr blitWait - - ;; d0 = BOB_XPOS - ;; d1 = BOB_YPOS - ;; d4 = BOB_XPOS_BYTES - - move.l d0,d2 ; d2 = BOB_XPOS - move.l d0,d3 ; d3 = BOB_XPOS - lsr.l #3,d3 ; d3 = BOB_XPOS_BYTES - move.l d3,d4 ; d4 = BOB_XPOS_BYTES - move.l d0,d5 - lsr.l #4,d5 ; d5 = BOB_XPOS_WORDS - lsl.l #4,d5 ; d5 = BOB_XPOS_WORDS_PIXELS - sub.l d5,d2 ; d2 = num pixels to shift - ;;move.w #BLIT_A_SOURCE_SHIFT,d2 - lsl.w #8,d2 - lsl.w #4,d2 ; BLIT_A_SOURCE_SHIFT<