First attempt at masked blit
This commit is contained in:
parent
a1ec92dbeb
commit
5da42485ee
|
@ -0,0 +1,22 @@
|
|||
MODULE=masked_blit.s
|
||||
FLOPPY=bin/mask_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 ../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
|
|
@ -0,0 +1,54 @@
|
|||
perform a masked blit
|
||||
=====================
|
||||
|
||||
Extending [006.simple_blit](../006.simple_blit), we now add a mask to the blit.
|
||||
|
||||
Using the "cookie-cut" blitter logic funtion we set up the blitter to use all four DMA channels.
|
||||
|
||||
[From the hardware manual](http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node011D.html):
|
||||
> To draw the car, we might use the A DMA channel to fetch the car mask,
|
||||
> the B DMA channel to fetch the actual car data, the C DMA channel to
|
||||
> fetch the background, and the D DMA channel to write out the new image.
|
||||
|
||||
```
|
||||
A = mask
|
||||
B = blitter object (sprite)
|
||||
C = background
|
||||
D = destination (background)
|
||||
```
|
||||
|
||||
Now we calculate the [logic function min term](http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node011C.html:
|
||||
|
||||
blitter logic function minterm truth table
|
||||
------------------------------------------
|
||||
We fill in the desired logic values in the D column. In this case D is set if:
|
||||
* The mask bit is set and the bob bit is set
|
||||
* The mask bit is not set and the background bit is set
|
||||
|
||||
|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|
|
||||
|
||||
Then we read D column from bottom up to give us the logic function minterm:
|
||||
```
|
||||
11001010 = $ca
|
||||
```
|
||||
|
||||
This is then ready to be used in the [BLTCON0](http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node001A.html) register setup.
|
||||
|
||||
[imagecon](../tools/imagecon) generates the interleaved mask bitplanes for the A channel.
|
||||
|
||||
We then blit the sprite to the background and notice it now has a shape!
|
||||
|
||||
[Download disk image](bin/mask_blit.adf?raw=true)
|
||||
|
||||
Screenshot:
|
||||
|
||||
![Screenshot](screenshot.png?raw=true)
|
Binary file not shown.
|
@ -0,0 +1,163 @@
|
|||
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
|
||||
|
||||
BOB_WIDTH equ 64
|
||||
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
|
||||
|
||||
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)
|
||||
|
||||
bsr.s doblit
|
||||
|
||||
.mainLoop:
|
||||
move.w #$02a,d0 ;wait for EOFrame
|
||||
bsr.s waitRaster
|
||||
bra.s .mainLoop
|
||||
|
||||
waitRaster: ;wait for rasterline d0.w. Modifies d0-d2/a0.
|
||||
move.l #$1ff00,d2
|
||||
lsl.l #8,d0
|
||||
and.l d2,d0
|
||||
lea $dff004,a0
|
||||
.wr: move.l (a0),d1
|
||||
and.l d2,d1
|
||||
cmp.l d1,d0
|
||||
bne.s .wr
|
||||
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_A_SOURCE_SHIFT equ 0
|
||||
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
|
||||
BLIT_BLTCON1 equ 0 ;BSH?=0, DOFF=0, EFE=0, IFE=0, FCI=0, DESC=0, LINE=0
|
||||
|
||||
doblit:
|
||||
movem.l d0-a6,-(sp)
|
||||
bsr blitWait
|
||||
move.w #(BLIT_SRCA|BLIT_SRCB|BLIT_SRCC|BLIT_DEST|BLIT_LF_MINTERM|BLIT_A_SOURCE_SHIFT<<BLIT_ASHIFTSHIFT),BLTCON0(A6)
|
||||
move.w #BLIT_BLTCON1,BLTCON1(a6)
|
||||
move.l #$ffffffff,BLTAFWM(a6) ; no masking of first/last word
|
||||
move.w #0,BLTAMOD(a6) ; A modulo=bytes to skip between lines
|
||||
move.w #0,BLTBMOD(a6) ; B modulo=bytes to skip between lines
|
||||
move.w #SCREEN_WIDTH_BYTES-BOB_WIDTH_BYTES,BLTCMOD(a6) ;C modulo
|
||||
move.w #SCREEN_WIDTH_BYTES-BOB_WIDTH_BYTES,BLTDMOD(a6) ;D modulo
|
||||
move.l #emojiMask,BLTAPTH(a6) ; mask bitplane
|
||||
move.l #emoji,BLTBPTH(a6) ; bob bitplane
|
||||
move.l #bitplanes+BOB_XPOS_BYTES+(SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH*BOB_YPOS),BLTCPTH(a6) ;background top left corner
|
||||
move.l #bitplanes+BOB_XPOS_BYTES+(SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH*BOB_YPOS),BLTDPTH(a6) ;destination top left corner
|
||||
move.w #(BOB_HEIGHT*SCREEN_BIT_DEPTH)<<6|(BOB_WIDTH_WORDS),BLTSIZE(a6) ;rectangle size, starts blit
|
||||
movem.l (sp)+,d0-a6
|
||||
rts
|
||||
|
||||
copper:
|
||||
;; bitplane pointers must be first else poking addresses will be incorrect
|
||||
dc.w BPL1PTL,0
|
||||
dc.w BPL1PTH,0
|
||||
dc.w BPL2PTL,0
|
||||
dc.w BPL2PTH,0
|
||||
dc.w BPL3PTL,0
|
||||
dc.w BPL3PTH,0
|
||||
dc.w BPL4PTL,0
|
||||
dc.w BPL4PTH,0
|
||||
dc.w BPL5PTL,0
|
||||
dc.w BPL5PTH,0
|
||||
|
||||
dc.l $fffffffe
|
||||
|
||||
bitplanes:
|
||||
incbin "out/image.bin"
|
||||
|
||||
emoji:
|
||||
incbin "out/emoji.bin"
|
||||
|
||||
emojiMask:
|
||||
incbin "out/emoji-mask.bin"
|
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
Loading…
Reference in New Issue