From daf1552456bee5cd0fd3e835d70feaaaf4433009 Mon Sep 17 00:00:00 2001 From: alpine9000 Date: Thu, 3 Mar 2016 10:29:05 +1100 Subject: [PATCH] Work in progress commit for 006.simple_blit --- 006.simple_blit/Makefile | 18 +++++ 006.simple_blit/README.md | 16 ++++ 006.simple_blit/bin/blit.adf | Bin 0 -> 901120 bytes 006.simple_blit/bitblit.c | 43 +++++++++++ 006.simple_blit/blit.s | 142 +++++++++++++++++++++++++++++++++++ 5 files changed, 219 insertions(+) create mode 100644 006.simple_blit/Makefile create mode 100644 006.simple_blit/README.md create mode 100644 006.simple_blit/bin/blit.adf create mode 100644 006.simple_blit/bitblit.c create mode 100644 006.simple_blit/blit.s diff --git a/006.simple_blit/Makefile b/006.simple_blit/Makefile new file mode 100644 index 0000000..58668e8 --- /dev/null +++ b/006.simple_blit/Makefile @@ -0,0 +1,18 @@ +MODULE=blit.s +FLOPPY=bin/blit.adf +IMAGEDATA=out/image-copper-list.s out/image.bin +IMAGEFILE=../assets/mission-beach.png +TC_IMAGEDATA=out/tc.bin out/tc-mask.bin +TC_IMAGEFILE=../assets/tc.png +EXTRA=$(IMAGEDATA) $(TC_IMAGEDATA) out/bitblit.s + +include ../base.mk + +out/bitblit.s: bitblit.c + vc -S bitblit.c -o out/bitblit.s + +$(IMAGEDATA): $(IMAGECON) $(IMAGEFILE) + $(IMAGECON) --input $(IMAGEFILE) --output out/image --colors 32 --quantize + +$(TC_IMAGEDATA): $(IMAGECON) $(TC_IMAGEFILE) + $(IMAGECON) --input $(TC_IMAGEFILE) --output out/tc --colors 32 --quantize --output-mask diff --git a/006.simple_blit/README.md b/006.simple_blit/README.md new file mode 100644 index 0000000..08af624 --- /dev/null +++ b/006.simple_blit/README.md @@ -0,0 +1,16 @@ +Display a simple image +====================== + +Building on [trackdisk.device](../000.trackdisk), we now display a simple color image. + +I display a 5 bitplane (32 color) low res image. + +The image data is prepared using a new tool I wrote called [imagecon](../tools/imagecon/imagecon.c). This takes (almost) any 320x256 PNG and using [libimagequant](https://pngquant.org/lib/) it reduces the palette to 32 colors, then dumps out the copper list and interleaved bitplane data ready to be included into [image.s](image.s). + +The original version of this example used [vilcans amiga-startup](https://github.com/vilcans/amiga-startup) as a starting point, however almost all of that code has been replaced as my understanding exanded. + +[Download disk image](bin/image.adf?raw=true) + +Screenshot: + +![Screenshot](screenshot.png?raw=true) diff --git a/006.simple_blit/bin/blit.adf b/006.simple_blit/bin/blit.adf new file mode 100644 index 0000000000000000000000000000000000000000..8cf5b8b3e3c209c7f64ac31b321344367da63f95 GIT binary patch literal 901120 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 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~ z0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY** z5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 O009ILK;Zuuf&U9SGw1*S literal 0 HcmV?d00001 diff --git a/006.simple_blit/bitblit.c b/006.simple_blit/bitblit.c new file mode 100644 index 0000000..564e91c --- /dev/null +++ b/006.simple_blit/bitblit.c @@ -0,0 +1,43 @@ +#include "hardware/custom.h" +#include "hardware/dmabits.h" + +/* +Scrollit: +;; --- scroll! --- +bltoffs =plotY*ScrBpl*3 + +blth =20 +bltw =w/16 + bltskip =0 ;modulo +brcorner=blth*ScrBpl*3-2 + + movem.l d0-a6,-(sp) + lea $dff000,a6 + bsr BlitWait + + move.l #$49f00002,BLTCON0(a6) + move.l #$ffffffff,BLTAFWM(a6) + move.l #Screen+bltoffs+brcorner,BLTAPTH(a6) + move.l #Screen+bltoffs+brcorner,BLTDPTH(a6) + move.w #bltskip,BLTAMOD(a6) + move.w #bltskip,BLTDMOD(a6) + + move.w #blth*3*64+bltw,BLTSIZE(a6) + movem.l (sp)+,d0-a6 + rts +*/ + + + +extern void blitwait(void); + +void bitblit(unsigned* src, unsigned* dest, unsigned sw, unsigned dw, unsigned dx, unsigned dy) +{ + static struct Custom *custom = (struct Custom *)0xDFF000; + + custom->dmacon = (DMAF_SETCLR|DMAF_COPPER|DMAF_RASTER|DMAF_MASTER); + /* + blitwait(); + custom->bltcon0 = 0x49f00002; + custom->bltafwm = 0xffffffff;*/ +} diff --git a/006.simple_blit/blit.s b/006.simple_blit/blit.s new file mode 100644 index 0000000..ac75d9a --- /dev/null +++ b/006.simple_blit/blit.s @@ -0,0 +1,142 @@ + 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 + + public _bitblit + +entry: + ;; custom chip base globally in a6 + lea CUSTOM,a6 + + move #$7ff,DMACON(a6) ; disable all dma + move #$7fff,INTENA(a6) ; disable all interrupts + + ;; bsr.s resetBitplanePointers + ;; reset color registers to white + move.l #32,d0 + lea COLOR00(a6),a0 +.loop: + move.w #$FFF,(a0) + addq #2,a0 + dbra d0,.loop + + ;; 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 + + if 0 +resetBitplanePointers: + movem.l d0-a6,-(sp) + lea bitplanes,a1 + lea BPL1PTH(a6),a2 + moveq #SCREEN_BIT_DEPTH,d0 +.bitplaneloop: + move.l a1,(a2) + lea SCREEN_WIDTH_BYTES(a1),a1 ; bit plane data is interleaved + addq #4,a2 + dbra d0,.bitplaneloop + movem.l (sp)+,d0-a6 + rts + endif + +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 + +doblit: + movem.l d0-a6,-(sp) + lea $dff000,a6 + bsr blitWait + move.l #$09f00000,BLTCON0(a6) ;A->D copy, no shifts, ascending mode + 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,BLTDMOD(a6) ;D modulo + move.l #bitplanes,BLTAPTH(a6) ;source graphic top left corner + move.l #bitplanes+(SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH*SCREEN_HEIGHT/2),BLTDPTH(a6) ;destination top left corner + move.w #SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH*SCREEN_HEIGHT/4,BLTSIZE(a6) ;rectangle size, starts blit + movem.l (sp)+,d0-a6 + rts + + include "out/bitblit.s" +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 + + include "out/image-copper-list.s" + + dc.l $fffffffe +bitplanes: + incbin "out/image.bin" + +tc: + incbin "out/tc.bin" +tcMask: + incbin "out/tc-mask.bin" \ No newline at end of file