diff --git a/009.anim_blit/Makefile b/009.anim_blit/Makefile new file mode 100644 index 0000000..08f11b8 --- /dev/null +++ b/009.anim_blit/Makefile @@ -0,0 +1,22 @@ +MODULE=anim_blit.s +FLOPPY=bin/anim_blit.adf +IMAGEDATA=out/image-palette.s out/image.bin +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) +SHARED_PALETTE_BASE=out/shared-palette +SHARED_PALETTE=$(SHARED_PALETTE_BASE).pal + +include ../shared/base.mk + +$(SHARED_PALETTE): $(IMAGEFILE) $(BOB_IMAGEFILE) + $(IMAGECON) --input $(IMAGEFILE),$(BOB_IMAGEFILE) --output $(SHARED_PALETTE_BASE) --colors 32 --quantize --output-palette + +$(IMAGEDATA): $(IMAGECON) $(IMAGEFILE) $(SHARED_PALETTE) + $(IMAGECON) --input $(IMAGEFILE) --output out/image --output-bitplanes --output-palette-asm --use-palette $(SHARED_PALETTE) + +$(BOB_IMAGEDATA): $(IMAGECON) $(BOB_IMAGEFILE) $(SHARED_PALETTE) + $(IMAGECON) --input $(BOB_IMAGEFILE) --output $(BOB_BASE) --output-bitplanes --use-palette $(SHARED_PALETTE) + $(IMAGECON) --input $(BOB_IMAGEFILE) --output $(BOB_BASE) --output-mask --quantize diff --git a/009.anim_blit/README.md b/009.anim_blit/README.md new file mode 100644 index 0000000..20e43cc --- /dev/null +++ b/009.anim_blit/README.md @@ -0,0 +1,26 @@ +perform a shifted blit +====================== + +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) + +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 new file mode 100644 index 0000000..061845e --- /dev/null +++ b/009.anim_blit/anim_blit.s @@ -0,0 +1,204 @@ + include "../include/registers.i" + 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 + + +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 + +.mainLoop: + bsr.s waitvbl + bsr.s doblit + addq #1,d0 + cmp.l #SCREEN_WIDTH-BOB_WIDTH,d0 + bne.s .skip + moveq #0,d0 +.skip: + 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 + +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<