mirror of
https://frontier.innolan.net/github/AmigaExamples.git
synced 2026-09-12 04:21:52 +00:00
Blit speed visualisation
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 9.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 15 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@@ -0,0 +1,24 @@
|
||||
NUM_COLORS=2
|
||||
MODULE=blit_speed.s
|
||||
FLOPPY=bin/blit_speed.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) blit.s init.s utils.s constants.i Makefile
|
||||
SHARED_PALETTE_BASE=out/shared-palette
|
||||
SHARED_PALETTE=$(SHARED_PALETTE_BASE).pal
|
||||
VASM_EXTRA_ARGS=-DSCREEN_COLORS=$(NUM_COLORS)
|
||||
|
||||
include ../shared/base.mk
|
||||
|
||||
$(SHARED_PALETTE): $(IMAGEFILE) $(BOB_IMAGEFILE) Makefile
|
||||
$(IMAGECON) --input $(IMAGEFILE),$(BOB_IMAGEFILE) --output $(SHARED_PALETTE_BASE) --colors $(NUM_COLORS) --quantize --output-palette
|
||||
|
||||
$(IMAGEDATA): $(IMAGECON) $(IMAGEFILE) $(SHARED_PALETTE) Makefile
|
||||
$(IMAGECON) --input $(IMAGEFILE) --output out/image --output-bitplanes --output-grey-palette-asm --output-palette-asm --use-palette $(SHARED_PALETTE)
|
||||
|
||||
$(BOB_IMAGEDATA): $(IMAGECON) $(BOB_IMAGEFILE) $(SHARED_PALETTE) Makefile
|
||||
$(IMAGECON) --input $(BOB_IMAGEFILE) --output $(BOB_BASE) --output-bitplanes --use-palette $(SHARED_PALETTE)
|
||||
$(IMAGECON) --input $(BOB_IMAGEFILE) --output $(BOB_BASE) --colors $(NUM_COLORS) --output-mask --quantize
|
||||
@@ -0,0 +1,53 @@
|
||||
how fast are my blits?
|
||||
======================
|
||||
|
||||
Blitting a 5 bitplane 64x65 rectangle with the cookie cut (4 active DMA changes) function probably isn't going to be very fast.
|
||||
|
||||
How fast is it ?
|
||||
|
||||
I added a feature to [imagecon](../tools/imagecon) to generate a greyscale version of the palette.
|
||||
|
||||
Then in the main loop I now:
|
||||
* wait for the vertical blank
|
||||
* set the greyscale palette
|
||||
* do some blits
|
||||
* set the color palette
|
||||
|
||||
```
|
||||
.mainLoop:
|
||||
bsr waitVerticalBlank
|
||||
bsr installGreyscalePalette
|
||||
move.l #4,d0 ; blit the object 5 times each frame
|
||||
.blitLoop:
|
||||
bsr moveBlitterObject
|
||||
dbra d0,.blitLoop
|
||||
bsr.s installColorPalette
|
||||
bra.s .mainLoop
|
||||
```
|
||||
|
||||
So when the screen changes to color, that's how many scan lines we have used blitting stuff.
|
||||
|
||||
There is a variable in the Makefile that sets the number of colors. This automatically creates the correct bitplane and palette data as well as reconfiguring the example. So now we can see what impact the number of bitplanes has on blit speed.
|
||||
|
||||
So here we can see the results:
|
||||
|
||||
5 bitplanes
|
||||

|
||||
|
||||
At 5 bitplanes we don't have enough time to do 5 blits.
|
||||
|
||||
4 bitplanes
|
||||

|
||||
|
||||
3 bitplanes
|
||||

|
||||
|
||||
2 bitplanes
|
||||

|
||||
|
||||
1 bitplanes
|
||||

|
||||
|
||||
[Download disk image](bin/blit_speed.adf?raw=true)
|
||||
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,143 @@
|
||||
;; 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_MASK_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
|
||||
|
||||
BLIT_BOB_WIDTH64 equ 64+16 ; Must blit extra word to allow shifting
|
||||
BLIT_BOB_HEIGHT64 equ 64
|
||||
BLIT_BOB_WIDTH64_BYTES equ BLIT_BOB_WIDTH64/8
|
||||
BLIT_BOB_WIDTH64_WORDS equ BLIT_BOB_WIDTH64/16
|
||||
|
||||
blitWait:
|
||||
tst DMACONR(a6) ;for compatibility
|
||||
.waitblit:
|
||||
btst #6,DMACONR(a6)
|
||||
bne.s .waitblit
|
||||
rts
|
||||
|
||||
;; blitMaskedObject64
|
||||
;; a3 - xpos
|
||||
;; a4 - ypos
|
||||
;; a0 - display
|
||||
;; a1 - object
|
||||
;; a2 - mask
|
||||
blitMaskedObject64:
|
||||
movem.l d0-a6,-(sp)
|
||||
|
||||
move.l (a3),d0
|
||||
move.l (a4),d1
|
||||
bsr blitWait
|
||||
|
||||
;; d0 = XPOS
|
||||
;; d1 = YPOS
|
||||
;; d4 = XPOS_BYTES
|
||||
|
||||
move.w d0,d4 ; d4 = XPOS
|
||||
lsr.w #3,d4 ; d4 = XPOS_BYTES
|
||||
|
||||
;; this shift will give us the bits to shift (bits 0-3) in bits (12-15) of d0
|
||||
lsl.w #8,d0 ; BLIT_SOURCE_SHIFT<<BLIT_ASHIFTSHIFT
|
||||
lsl.w #4,d0 ; BLIT_SOURCE_SHIFT<<BLIT_ASHIFTSHIFT
|
||||
|
||||
move.w d0,BLTCON1(A6)
|
||||
ori.w #BLIT_SRCA|BLIT_SRCB|BLIT_SRCC|BLIT_DEST|BLIT_LF_MASK_MINTERM,d0
|
||||
move.w d0,BLTCON0(A6)
|
||||
|
||||
move.w #$ffff,BLTAFWM(a6) ; no mask for first word
|
||||
move.w #$0000,BLTALWM(a6) ; mask out last word
|
||||
move.w #-2,BLTAMOD(a6) ; negative 2 byte modulo to account for extra blitted word
|
||||
move.w #-2,BLTBMOD(a6) ; negative 2 byte modulo to account for extra blitted word
|
||||
move.w #SCREEN_WIDTH_BYTES-BLIT_BOB_WIDTH64_BYTES,BLTCMOD(a6) ;C modulo
|
||||
move.w #SCREEN_WIDTH_BYTES-BLIT_BOB_WIDTH64_BYTES,BLTDMOD(a6) ;D modulo
|
||||
move.l a2,BLTAPTH(a6) ; mask bitplane
|
||||
move.l a1,BLTBPTH(a6) ; bob bitplane
|
||||
|
||||
move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH,d3 ; d3 = SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH
|
||||
mulu.w d1,d3 ; d3 = YPOS*SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH
|
||||
move.l a0,d0 ; d0 = #bitplanes
|
||||
add.w d4,d0 ; d0 = #bitplanes+XPOS_BYTES
|
||||
add.w d3,d0 ; d0 = #bitplanes+XPOS_BYTES+(YPOS*SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH)
|
||||
move.l d0,BLTCPTH(a6) ;background top left corner
|
||||
move.l d0,BLTDPTH(a6) ;destination top left corner
|
||||
|
||||
move.w #(BLIT_BOB_HEIGHT64*SCREEN_BIT_DEPTH)<<6|(BLIT_BOB_WIDTH64_WORDS),BLTSIZE(a6) ;rectangle size, starts blit
|
||||
movem.l (sp)+,d0-a6
|
||||
rts
|
||||
|
||||
|
||||
;; A(src) B(?) C(?) D(dest)
|
||||
;; - - - -
|
||||
;; 0 0 0 0
|
||||
;; 0 0 1 0
|
||||
;; 0 1 0 0
|
||||
;; 0 1 1 0
|
||||
;; 1 0 0 1
|
||||
;; 1 0 1 1
|
||||
;; 1 1 0 1
|
||||
;; 1 1 1 1
|
||||
|
||||
|
||||
BLIT_LF_COPY_MINTERM equ $f0
|
||||
;; blitObject64
|
||||
;; a3 - xpos
|
||||
;; a4 - ypos
|
||||
;; a0 - display
|
||||
;; a1 - object
|
||||
blitObject64:
|
||||
movem.l d0-a6,-(sp)
|
||||
|
||||
move.l (a3),d0
|
||||
move.l (a4),d1
|
||||
bsr blitWait
|
||||
|
||||
;; d0 = XPOS
|
||||
;; d1 = YPOS
|
||||
;; d4 = XPOS_BYTES
|
||||
|
||||
move.w d0,d4 ; d4 = XPOS
|
||||
lsr.w #3,d4 ; d4 = XPOS_BYTES
|
||||
|
||||
;; this shift will give us the bits to shift (bits 0-3) in bits (12-15) of d0
|
||||
lsl.w #8,d0 ; BLIT_SOURCE_SHIFT<<BLIT_ASHIFTSHIFT
|
||||
lsl.w #4,d0 ; BLIT_SOURCE_SHIFT<<BLIT_ASHIFTSHIFT
|
||||
|
||||
move.w d0,BLTCON1(A6)
|
||||
ori.w #BLIT_SRCA|BLIT_DEST|BLIT_LF_COPY_MINTERM,d0
|
||||
move.w d0,BLTCON0(A6)
|
||||
|
||||
move.w #$ffff,BLTAFWM(a6) ; no mask for first word
|
||||
move.w #$0000,BLTALWM(a6) ; mask out last word
|
||||
move.w #-2,BLTAMOD(a6) ; negative 2 byte modulo to account for extra blitted word
|
||||
move.w #SCREEN_WIDTH_BYTES-BLIT_BOB_WIDTH64_BYTES,BLTDMOD(a6) ;D modulo
|
||||
move.l a1,BLTAPTH(a6) ; bob bitplane
|
||||
|
||||
move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH,d3 ; d3 = SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH
|
||||
mulu.w d1,d3 ; d3 = YPOS*SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH
|
||||
move.l a0,d0 ; d0 = #bitplanes
|
||||
add.w d4,d0 ; d0 = #bitplanes+XPOS_BYTES
|
||||
add.w d3,d0 ; d0 = #bitplanes+XPOS_BYTES+(YPOS*SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH)
|
||||
move.l d0,BLTDPTH(a6) ;destination top left corner
|
||||
|
||||
move.w #(BLIT_BOB_HEIGHT64*SCREEN_BIT_DEPTH)<<6|(BLIT_BOB_WIDTH64_WORDS),BLTSIZE(a6) ;rectangle size, starts blit
|
||||
movem.l (sp)+,d0-a6
|
||||
rts
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
include "../include/registers.i"
|
||||
include "hardware/dmabits.i"
|
||||
include "hardware/intbits.i"
|
||||
|
||||
include "constants.i"
|
||||
|
||||
entry:
|
||||
lea CUSTOM,a6
|
||||
bsr init
|
||||
bsr.s installColorPalette
|
||||
|
||||
lea bitplanes(pc),a0
|
||||
lea emoji,a1
|
||||
lea emojiMask,a2
|
||||
.mainLoop:
|
||||
bsr waitVerticalBlank
|
||||
bsr installGreyscalePalette
|
||||
move.l #4,d0
|
||||
.blitLoop:
|
||||
bsr moveBlitterObject
|
||||
dbra d0,.blitLoop
|
||||
bsr.s installColorPalette
|
||||
bra.s .mainLoop
|
||||
|
||||
include "blit.s"
|
||||
include "init.s"
|
||||
include "utils.s"
|
||||
|
||||
moveBlitterObject:
|
||||
lea xpos(pc),a3
|
||||
lea ypos(pc),a4
|
||||
add.l #1,xpos ; move the blitter object one pixel to the left
|
||||
add.l #1,ypos ; move the blitter object one pixel down
|
||||
bsr.s blitMaskedObject64 ; blit 64 pixel object (x=d0,y=d1,background=a0,object=a1,mask=a2)
|
||||
cmp.l #SCREEN_WIDTH-BLIT_BOB_WIDTH64+16,xpos ; check if we need to wrap the x
|
||||
bne.s .skip
|
||||
move.l #0,xpos ; wrap x back to 0
|
||||
.skip:
|
||||
cmp.l #SCREEN_HEIGHT-BLIT_BOB_HEIGHT64,ypos ; check if we need to wrap the y
|
||||
bne.s .done
|
||||
move.l #0,ypos ; wrap y back to 0
|
||||
.done:
|
||||
rts
|
||||
|
||||
|
||||
installColorPalette:
|
||||
include "out/image-palette.s"
|
||||
rts
|
||||
|
||||
installGreyscalePalette:
|
||||
include "out/image-grey.s"
|
||||
rts
|
||||
|
||||
xpos: dc.l 0
|
||||
ypos: dc.l 0
|
||||
|
||||
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"
|
||||
@@ -0,0 +1,24 @@
|
||||
LVL3_INT_VECTOR equ $6c
|
||||
SCREEN_WIDTH equ 320
|
||||
SCREEN_HEIGHT equ 256
|
||||
SCREEN_WIDTH_BYTES equ (SCREEN_WIDTH/8)
|
||||
if SCREEN_COLORS == 32
|
||||
SCREEN_BIT_DEPTH equ 5
|
||||
endif
|
||||
if SCREEN_COLORS == 16
|
||||
SCREEN_BIT_DEPTH equ 4
|
||||
endif
|
||||
if SCREEN_COLORS == 8
|
||||
SCREEN_BIT_DEPTH equ 3
|
||||
endif
|
||||
if SCREEN_COLORS == 4
|
||||
SCREEN_BIT_DEPTH equ 2
|
||||
endif
|
||||
if SCREEN_COLORS == 2
|
||||
SCREEN_BIT_DEPTH equ 1
|
||||
endif
|
||||
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
|
||||
@@ -0,0 +1,41 @@
|
||||
;; custom chip base globally in a6
|
||||
init:
|
||||
movem.l d0-a6,-(sp)
|
||||
move #$7ff,DMACON(a6) ; disable all dma
|
||||
move #$7fff,INTENA(a6) ; disable all interrupts
|
||||
|
||||
;; set up default palette
|
||||
bsr.s installColorPalette
|
||||
|
||||
;; 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_VERTB|INTF_INTEN),INTENA(a6)
|
||||
movem.l (sp)+,d0-a6
|
||||
rts
|
||||
@@ -0,0 +1,23 @@
|
||||
waitVerticalBlank:
|
||||
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
|
||||
|
||||
|
||||
|
||||
waitRaster: ;wait for rasterline d0.w. Modifies d0-d2/a0.
|
||||
movem.l d0-a6,-(sp)
|
||||
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
|
||||
movem.l (sp)+,d0-a6
|
||||
rts
|
||||
Reference in New Issue
Block a user