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 TC_WIDTH equ 64 TC_HEIGHT equ 64 TC_WIDTH_BYTES equ TC_WIDTH/8 TC_WIDTH_WORDS equ TC_WIDTH/16 TC_XPOS equ 16 TC_YPOS equ 16 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 #SCREEN_WIDTH_BYTES-TC_WIDTH_BYTES,BLTDMOD(a6) ;D modulo move.l #tc,BLTAPTH(a6) ;source graphic top left corner move.l #bitplanes+(TC_XPOS)/8+(SCREEN_WIDTH_BYTES*SCREEN_BIT_DEPTH*TC_YPOS),BLTDPTH(a6) ;destination top left corner move.w #(TC_HEIGHT*SCREEN_BIT_DEPTH)<<6|(TC_WIDTH_WORDS),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"