;
;#################################
;# 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
               (
geocities.com/timessquare/alley/3583)                   (
geocities.com/timessquare/alley)                   (
geocities.com/timessquare)