Files
AmigaExamples/006.simple_blit/blit.s
T

142 lines
3.4 KiB
ArmAsm

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"