;
;#################################
;#    VIC-20 BITMAP EXAMPLE	 #
;#	    AS65 source 	 #
;#	   public domain	 #
;#	by B.W. van Schooten	 #
;#################################

;This example contains routines for setting up a bitmapped display and
;drawing XOR'ed sprites on it. the sprite routines are optimized for use
;with multicolour mode. This program resides in ROM area.

;How it works
;------------
;The basic idea is the following: when you enable 16-pixel-high characters,
;you can fill up the whole screen with characters without using any character
;twice. This way you can control each screen pixel individually by changing the
;definition of the corresponding character.

;A often-used mode is 22x11 (this gives you a 22*8=176 x 11*16=176 bitmap).
;The easiest way to map the characters to the screen is as follows:
;Chr0  Chr11 Chr22 .... Chr231
;Chr1  Chr12 Chr23 .... Chr232
;Chr2  Chr13 Chr24 .... Chr233
;..... ..... ..... .... ......
;Chr10 Chr21 Chr32 .... Chr241

;This way, you can change any (non-multicolour) pixel using the following
;calculation:
;	ADDRESS = Ypos + (Xpos>>3)
;	VALUE = 128 >> (Xpos&7)
;Now OR the VALUE with the value already found in ADDRESS to enable the pixel.

;For multicolour mode (88x176, 4-colour packed pixel), the calculation is:
;	ADDRESS = Ypos + (Xpos>>2)
;	ANDMASK =  192	     >> ( (Xpos&3) << 1)
;	ORMASK = (Colour<<6) >> ( (Xpos&3) << 1)
;First AND the value at ADDRESS with the ANDMASK, then OR with the ORMASK.

;FILLCHRSCR arranges the characters as explained above. The whole colour
;screen is then set to 12 (multicolour mode) by FILLCOLSCR. CLEARBM clears the
;bitmap, DRAWSPR draws sprites on it.

;The memory layout used by this program is:

;$0000 - $00FF	free/temporary variables
;$0100 - $01FF	sprite array/stack area
;$0200 - $02F1	CHARACTER MEMORY
;$02F2 - $03FF	free
;$1000 - $1F1F	BITMAP
;$1F20 - $1FFF	free


;-------------------------------- VARIABLES ---------------------------------

;Temp variables used by demonstration

tmpcount1	equ	$f4
tmpcount2	equ	$f5

;tmpval 	 equ	 $f6

arradr_w	equ	$f7
arradr_l	equ	$f7
arradr_h	equ	$f8


;The array of sprites

sprites 	equ	36
xpos_arr	equ	$100
ypos_arr	equ	xpos_arr+sprites
spritenr_arr	equ	ypos_arr+sprites



;Temp variables used by bitmapping routines

bm_tmpval	equ	$f9

bm_jmpadr_w	equ	$fa
bm_jmpadr_l	equ	$fa
bm_jmpadr_h	equ	$fb


bm_scradr1_w	equ	$fc
bm_scradr1_l	equ	$fc
bm_scradr1_h	equ	$fd

bm_scradr2_w	equ	$fe
bm_scradr2_l	equ	$fe
bm_scradr2_h	equ	$ff



;------------------------------ BOOT HEADER ----------------------------------

	org	$9ffe
	db	0,160			;StartAdr=$a000
	db	lo entry, hi entry	;entry point
	db	lo entry, hi entry	;padding?
	db	$41,$30,$c3,$c2,$cd	;A0CBM boot code


;----------------------------- INIT HARDWARE --------------------------------

vic_tbl:
	db	$05,$19,$96,$17, 0	;22 x 11, 16-pixel high characters
	db	$8c			;screen=$0200 chars=$1000
	db	0,0,0,0 		;don't care
	db	0,0,0,0, $80, $0a


entry:

	cld

	ldx	#15
setvicregs:
	lda	vic_tbl,x
	sta	$9000,x
	dex
	bpl	setvicregs



;----------------- SETUP THE SCREEN FOR BITMAPPED GRAPHICS ------------------

	jsr	fillchrscr

	lda	#12
	jsr	fillcolscr


	lda	#0
	jsr	clearbm



;---------------------- RUN A BITMAPPED GRAPHICS DEMO ------------------------


	lda	#0
	ldx	#sprites-1
clrpos:
	sta	xpos_arr,x
	sta	ypos_arr,x
	sta	spritenr_arr,x
	dex
	bpl	clrpos

mainloop:


	lda	#sprites-1
	sta	tmpcount1
drawloop:

	ldy	tmpcount1

	lda	spritenr_arr,y
	pha

	lda	ypos_arr,y
	clc
	adc	#12
	pha

	lda	xpos_arr,y
	clc
	adc	#6

	tax
	pla
	tay
	pla
	lsr	a
	jsr	drawspr 	;clear old sprite by XORing over old image


	ldy	tmpcount1

	lda	spritenr_arr,y
	clc
	adc	#1
	and	#7		;animate
	sta	spritenr_arr,y

	pha

	lda	xpos_arr,y
	clc
	adc	xspeed_tbl,y
	and	#63
	sta	xpos_arr,y	;move horizontally

	clc
	adc	#6
	tax

	lda	ypos_arr,y
	clc
	adc	yspeed_tbl,y
	and	#127
	sta	ypos_arr,y	;move vertically

	clc
	adc	#12
	tay

	pla
	lsr	a
	jsr	drawspr 	;draw sprite at new position

	dec	tmpcount1
	bpl	drawloop


	jmp	mainloop


xspeed_tbl:
	db	1,1,1,1,1,1
	db	-1,-1,-1,-1,-1,-1
	db	2,2,2,2,2,2
	db	-2,-2,-2,-2,-2,-2
	db	3,3,3,3,3,3
	db	-3,-3,-3,-3,-3,-3

yspeed_tbl:
	db	1,-1,2,-2,3,-3
	db	1,-1,2,-2,3,-3
	db	1,-1,2,-2,3,-3
	db	1,-1,2,-2,3,-3
	db	1,-1,2,-2,3,-3
	db	1,-1,2,-2,3,-3





;-------------------------- SCREEN INITIALIZATION ----------------------------

;u:P A X Y bm_scradr1_w
fillchrscr:
	lda	#2
	sta	bm_scradr1_h
	lda	#22*10
	sta	bm_scradr1_l

	ldx	#10
fillchrscr_line:
	ldy	#21
fillchrscr_char:

	txa
	clc
	adc	linevalues_tbl,y
	sta	(bm_scradr1_w),y
	dey
	bpl	fillchrscr_char

	lda	bm_scradr1_l
	sec
	sbc	#22
	sta	bm_scradr1_l
	bcs	fillchrscr_noc
	dec	bm_scradr1_h
fillchrscr_noc:

	dex
	bpl	fillchrscr_line

	rts


linevalues_tbl:
	db	0,11,22,33,  44,55,66,77,  88,99,110,121
	db	132,143,154,165,  176,187,198,209,  220,231




;I:A=fillpattern
;u:P A X
fillcolscr:
	ldx	#0
fillcolscr_loop:
	sta	$9600,x
	dex
	bne	fillcolscr_loop
	rts



;------------------------- HI-RES DRAWING ROUTINES ---------------------------


;I:A=fillpattern
;u:P X Y bm_scradr1_w
clearbm:
	ldy	#$10
	sty	bm_scradr1_h
	ldy	#0
	sty	bm_scradr1_l

	ldx	#15
	ldy	#0
clearbm_page:
clearbm_loop:
	sta	(bm_scradr1_w),y
	dey
	bne	clearbm_loop

	inc	bm_scradr1_h
	dex
	bpl	clearbm_page

	rts






;A=sprite#  X=Xpos(0..87)  Y=Ypos(0..175)
;u:P A X Y bm_scradr1_w bm_scradr2_w bm_tmpval bm_jmpadr
drawspr:
	pha

	txa
	pha
	lsr	a
	lsr	a
	tax

	lda	xpostoscrl_tbl,x
	sta	bm_scradr1_l
	lda	xpostoscrh_tbl,x
	sta	bm_scradr1_h	;scradr1->top byte of left column

	tya
	clc
	adc	bm_scradr1_l
	sta	bm_scradr1_l
	bcc	drawspr_noc1
	inc	bm_scradr1_h	;bm_scradr1->byte# in left column
drawspr_noc1:

	lda	bm_scradr1_l
	clc
	adc	#11*16
	sta	bm_scradr2_l
	lda	bm_scradr1_h
	adc	#0
	sta	bm_scradr2_h	;bm_scradr2->byte# in right column

	pla
	and	#3
	tax
	lda	shifttoadrl_tbl,x
	sta	bm_jmpadr_l
	lda	shifttoadrh_tbl,x
	sta	bm_jmpadr_h	;tmpadr=jmp address

	pla
	tax
	lda	sprindex_tbl,x
	clc
	adc	#9
	tax			;X=end of offset in sprite data

	ldy	#9		;Y=loop count
drawspr_loop:
	lda	sprite_tbl2,x
	sta	bm_tmpval	;bm_tmpval contains bits shifted out
	lda	sprite_tbl1,x

	jmp	(bm_jmpadr_w)	;do shifting


drawspr_shift4:
	lsr	a
	ror	bm_tmpval
	lsr	a
	ror	bm_tmpval

drawspr_shift2:
	lsr	a
	ror	bm_tmpval
	lsr	a
	ror	bm_tmpval

drawspr_shift0:
	eor	(bm_scradr1_w),y
	sta	(bm_scradr1_w),y
	lda	bm_tmpval
	eor	(bm_scradr2_w),y
	sta	(bm_scradr2_w),y

	dex
	dey
	bpl	drawspr_loop

	rts


drawspr_shift6:
	asl	bm_tmpval
	rol	a
	rol	bm_tmpval
	rol	a
	rol	bm_tmpval

	eor	(bm_scradr2_w),y
	sta	(bm_scradr2_w),y
	lda	bm_tmpval
	eor	(bm_scradr1_w),y
	sta	(bm_scradr1_w),y

	dex
	dey
	bpl	drawspr_loop

	rts


shifttoadrl_tbl:
	db	lo (drawspr_shift0)
	db	lo (drawspr_shift2)
	db	lo (drawspr_shift4)
	db	lo (drawspr_shift6)

shifttoadrh_tbl:
	db	hi (drawspr_shift0)
	db	hi (drawspr_shift2)
	db	hi (drawspr_shift4)
	db	hi (drawspr_shift6)


xpostoscrl_tbl:
	db	lo (0*176),lo (1*176), lo (2*176), lo (3*176)
	db	lo (4*176),lo (5*176), lo (6*176), lo (7*176)
	db	lo (8*176),lo (9*176), lo (10*176), lo (11*176)
	db	lo (12*176),lo (13*176), lo (14*176), lo (15*176)
	db	lo (16*176),lo (17*176), lo (18*176), lo (19*176)
	db	lo (20*176),lo (21*176)

xpostoscrh_tbl:
	db	16+(hi(0*176)),16+(hi(1*176)),16+(hi(2*176)),16+(hi(3*176))
	db	16+(hi(4*176)),16+(hi(5*176)),16+(hi(6*176)),16+(hi(7*176))
	db	16+(hi(8*176)),16+(hi(9*176)),16+(hi(10*176)),16+(hi(11*176))
	db	16+(hi(12*176)),16+(hi(13*176)),16+(hi(14*176)),16+(hi(15*176))
	db	16+(hi(16*176)),16+(hi(17*176)),16+(hi(18*176)),16+(hi(19*176))
	db	16+(hi(20*176)),16+(hi(21*176))

sprindex_tbl:
	db	0,10,20,30,40,	     50,60,70,80,90
	db	100,110,120,130,140, 150,160,170,180,190
	db	200,210,220,230,240



;--------------------------- SPRITE DEFINITIONS ----------------------------

;The sprites are 5 multicolour pixels wide x 10 pixels high.

;This table contains the left four columns of sprite data.
sprite_tbl1:
	db	4#2221
	db	4#2210
	db	4#3100
	db	4#1000
	db	4#0020
	db	4#0020
	db	4#0000
	db	4#0001
	db	4#0012
	db	4#0122

	db	4#0100
	db	4#1000
	db	4#2000
	db	4#2000
	db	4#2131
	db	4#2131
	db	4#3000
	db	4#1000
	db	4#0000
	db	4#0001

	db	4#0132
	db	4#0012
	db	4#0001
	db	4#0000
	db	4#0020
	db	4#0020
	db	4#1000
	db	4#2100
	db	4#2210
	db	4#2231

	db	4#3222
	db	4#1322
	db	4#0000
	db	4#0000
	db	4#0010
	db	4#0010
	db	4#0000
	db	4#0000
	db	4#1223
	db	4#1222

;This table contains the right column data.
sprite_tbl2:
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#1000
	db	4#3000
	db	4#2000
	db	4#2000

	db	4#0000
	db	4#0000
	db	4#1000
	db	4#3000
	db	4#2000
	db	4#2000
	db	4#2000
	db	4#2000
	db	4#1000
	db	4#0000

	db	4#2000
	db	4#2000
	db	4#2000
	db	4#1000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000

	db	4#1000
	db	4#1000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#0000
	db	4#1000
	db	4#3000



    Source: geocities.com/timessquare/alley/3583/prog

               ( geocities.com/timessquare/alley/3583)                   ( geocities.com/timessquare/alley)                   ( geocities.com/timessquare)