Here's the BMP loader, BMPX and BMPY are LONG variables, DPORT is VDP DATA port, CPORT is VDP Control port and PTADDR is the address of the pattern table in VRAM

Code: Select all

```
LoadBMP: ; Loads an 4-bit BMP, A0 = Source, D4 = Start tile
MOVE.L #DPORT, A3
ADD.L #2, A0 ; ID WORD, must be "BM"
ADD.L #4, A0 ; Size LONG
ADD.L #4, A0 ; nothing
ADD.L #4, A0 ; Image type LONG, must be 1078
ADD.L #4, A0 ; Header size LONG, must be 40
MOVE.L (A0)+, D0 ; Width LONG
ROR.W #8, D0
SWAP D0
ROR.W #8, D0
MOVE.L D0, (BMPX)
MOVE.L (A0)+, D0 ; Height LONG
ROR.W #8, D0
SWAP D0
ROR.W #8, D0
MOVE.L D0, (BMPY)
ADD.L #2, A0 ; 1 WORD
ADD.L #2, A0 ; bpp WORD, must be 4
ADD.L #4, A0 ; compression LONG, must be 0
ADD.L #4, A0 ; (compressed) image size LONG
ADD.L #16, A0 ; Nothing
MOVE.L #$C0000000, (CPORT) ; BMP palette format B, G, R, Z
MOVE.W #15, D3
BMPpalLoop:
MOVE.B (A0)+, D0 ; R
AND.L #$E0, D0
LSL.W #4, D0
MOVE.B (A0)+, D1 ; G
AND.L #$E0, D1
MOVE.B (A0)+, D2 ; B
AND.L #$E0, D2
LSR.W #4, D2
OR.W D2, D0
OR.W D1, D0
ADD.L #1, A0 ; Z
MOVE.W D0, (DPORT)
DBRA D3, BMPpalLoop
MOVE.W D4, D0 ; D4=Start tile
LSL.W #5, D0
AND.L #$FFFF, D0
MOVE.L #$40000000, D2 ; D2=VDP command
MOVE.L D0, D1
LSR.L #8, D1
LSR.L #6, D1
OR.L D1, D2 ; Add Address bits 14 and 15
MOVE.L D0, D1
AND.L #$3FFF,D1
SWAP D1
OR.L D1, D2 ; Add rest of the Address bits
MOVE.L D2, (CPORT) ; Write command+screen pointer
MOVE.L A0, A1
MOVE.L (BMPY), D6
SUBQ.L #1, D6
LSR.L #3, D6
ImageLoopY:
MOVE.L A1, A2
MOVE.L (BMPX), D7
SUBQ.L #1, D7
LSR.L #3, D7
TileLoop:
MOVE.L A2, A0
MOVE.L (BMPX), D0
LSR.L #1, D0
MOVE.L (A0), (A3) ; Load one tile
ADD.L D0, A0
MOVE.L (A0), (A3)
ADD.L D0, A0
MOVE.L (A0), (A3)
ADD.L D0, A0
MOVE.L (A0), (A3)
ADD.L D0, A0
MOVE.L (A0), (A3)
ADD.L D0, A0
MOVE.L (A0), (A3)
ADD.L D0, A0
MOVE.L (A0), (A3)
ADD.L D0, A0
MOVE.L (A0), (A3)
ADD.L D0, A0
ADD.L #4, A2
DBRA D7, TileLoop
ADD.L (BMPX), A1
ADD.L (BMPX), A1
ADD.L (BMPX), A1
ADD.L (BMPX), A1
DBRA D6, ImageLoopY
MOVE.L (BMPY), D1 ; Tiles loaded, now display
SUBQ.L #1, D1
LSR.L #3, D1
MOVE.W D1, D7
MOVE.W #29, D0 ; Center image Y
SUB.W D1, D0
LSR.W #1, D0
ADD.W D1, D0
MOVE.L (BMPX), D2
SUBQ.L #1, D2
LSR.L #3, D2
MOVE.W #39, D1 ; Center image X
SUB.W D2, D1
LSR.W #1, D1
MOVE.W D4, D3 ; D3 = Start tile
OR.W #$1000, D3
Yloop2:
JSR CalcOffset
MOVE.L (BMPX), D6
SUBQ.L #1, D6
LSR.L #3, D6
Xloop2:
MOVE.W D3, (A3)
ADDQ.W #1, D3
DBRA D6, Xloop2
SUBQ.W #1, D0
DBRA D7, Yloop2
RTS
CalcOffset: ; Calculates offset in VRAM for pattern table
MOVEM.L D0-D1, -(A7) ; modifying routines
LSL.W #6, D0
ADD.W D1, D0 ; D0=Y, D1=X
ADD.W D0, D0
ADD.W (PTADDR), D0
MOVE.W D0, D1
AND.W #$3FFF, D0
OR.W #$4000, D0
SWAP D0
ROL.W #2, D1
AND.W #3, D1
MOVE.W D1, D0
MOVE.L D0, (CPORT)
MOVEM.L (A7)+, D0-D1
RTS
```