* * A little demo written in Slang. The * main point is that Slang can be used * to set up tables, prototype, etc. * using asm for the fast stuff. * * SLJ 9/9/05 updated 11/12/05 * ; ; basic header ; * do 0 org $0801 ;set assemble address da $080b;link da 2006 ;line number dfb $9e ;sys txt '2061' dfb 00,00,00 * fin ; ; DYCP vars ; byte romdata(64,8)@$d000 ;ROM character data byte shiftdata(64,12)@$4000;y-shifted data byte chardata(40,16)@$2000;What VIC will see byte sindata(256) byte screen(25,40)@$0400 uint charidx(64) ;index into chardata ubyte mesg(80)=[!s".........it's a sine of the times......."] ubyte x,y,char ubyte i,k,count uint ptr1@$fa uint cptr@$fc uint sptr@$fe uint charcol(64) ; ; Scroll vars ; byte mesg2(120)=[!s" slang makes it easy http://www.ffd2.com/fridge/slang/ robin harbr0n rules!!! "] byte mesg2len=94 byte row1(40)@$0400 ;first screen row Scroll2_rowpos = 39 ;initial screen position ; ; Sprite vars ; ubyte sprite(63)@832 *int xpos=100,ypos=100 *int xvel=2,yvel=0 int xpos(8) = [30 50 70 50 30 50 70 50] int ypos(8) = [100 100 100 100 100 100 100 100] int xvel(8) = [2 2 2 2 2 2 2 2] int yvel(8) = [0 0 0 0 0 0 0 0] byte numsprites=0 byte scount=4,scount2=53 byte spritecolors(8) = [1 3 7 10 12 13 14 15] byte spritecolorreg(8)@$d027 ubyte SpriteCollisionReg@$d01f ubyte bittab(8)=[1 2 4 8 16 32 64 128] ubyte spritedat(63)=[ & 6 102 96 6 102 96 & 6 102 96 7 255 224 & 15 255 240 28 0 56 & 56 0 28 113 195 142 & 225 195 135 193 195 131 & 192 0 3 192 0 3 & 192 60 3 192 0 3 & 204 0 51 198 0 99 & 195 255 195 192 0 3 & 224 0 7 127 255 254 & 63 255 252 ] ; ; Set up the sine data ; sprint !13"chill" for x=0:63 sindata(x) = 20.0*(1+sin(x*2.*3.14159/64)) sindata(x+64)=sindata(x) sindata(x+128)=sindata(x) sprint ".." next ; ; Set up VIC, initialize mem ; SetVICBank(0) SetVideoMatrix($0400) SetCharData($2000) ;chardat @ $2000 poke 53281,0 ;black bg poke 53280,0 fillmem($d800,$dbff,01) ;ColorRAM->black fillmem($2000,$4000,$00) ;Fill char mem fillmem($4000,$6000,$00) ;Fill shifted chars fillmem($0400,$07ff,$ff) ;Clear screen ; ; Set up the screen row table, shift ; row table, char row table. ; charidx(0) = #shiftdata charcol(0) = #chardata for i=1:63 charidx(i)=charidx(i-1)+12;12 bytes per strip charcol(i)=charcol(i-1)+48 next+ ; ; Set up the shifted data sets ; DisableInterrupts MemConfig 3 ;Show charrom under VIC for char=0:63 for x=0:7 shiftdata(char,x+2) = romdata(char,x) endfor+ endfor+ MemConfig 7 ;vic back in * ;don't need to re-enable interrupts EnableInterrupts ;needed by scroll ; ; Set up charmap to screen ; count = 0 for x=0:39 for y=19:24 screen(y,x)=count count=count+1 next+ next+ ; ; Set up IRQ ; DisableTimerAIRQ ;shut down CIA timer IRQ (kernal IRQ) SetRaster(58) SetIRQRoutine(Scroll2) SetCol38 ;use 38 cols to make it smooth row1$(0:39)=" " ; ; Set up sprites ; UseSpriteStuff for x=0:62 * sprite(x)=255 sprite(x) = spritedat(x) next+ for x=0:7 SetSpritePtr(x,13) SpriteColorReg(x) = SpriteColors(x) next+ SpriteOn(0) ******************************** * * Main Loop * ******************************** ; ; Animate a character ; count=0 EnableRasterIRQ repeat ldx #39 :loop stx ptr1 ; Set up pointers lda mesg,x asl tay lda charidx,y ;shifted data ptr sta sptr lda charidx+1,y sta sptr+1 txa asl tay lsr adc count tax lda charcol,y ; ;charmap ptr adc sindata,x sta cptr lda charcol+1,y adc #00 sta cptr+1 ; Plot data to charmap ldy #00 do 0 :l1 lda (sptr),y sta (cptr),y iny cpy #12 bne :l1 fin lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y iny lda (sptr),y sta (cptr),y ; and loop ldx ptr1 dex bpl :loop inc count bpl :c1 lda #00 sta count :c1 ; ; Main loop ; * stz $d020 wait $d012,251 * inc $d020 Scroll1() ; ; Activate sprites ; if+ numsprites < 7 dec scount2 if+ scount2 = 0 scount2=39 inc numsprites SpriteOn(numsprites) endif+ endif+ ; ; Move sprites ; x = SpriteCollisionReg ;reading clears the reg ;so goofiness is needed dec scount for k=0:numsprites xpos(k)=xpos(k)+xvel(k) if+ (xpos(k) > 312) or (xpos(k) < 32) xvel(k)=-xvel(k) xpos(k)=xpos(k)+xvel(k) endif+ if+ bittab(k) bitand x yvel(k)=-yvel(k) ypos(k)=ypos(k)+yvel(k)+yvel(k) endif+ ypos(k)=ypos(k)+yvel(k) if+ scount=0 yvel(k)=yvel(k)+1 if+ yvel(k)>7 yvel(k)=7 endif+ endif+ SetSpriteX(k,xpos(k)) SetSpriteY(k,ypos(k)) endfor if+ scount=0 scount=4 endif+ forever ;------------------------------- ; ; IRQ routines ; ; The first IRQ routine fine-scrolls ; the screen and sets up the next IRQ. ; ;------------------------------- sub Scroll1() byte count SetScrollX(count) ;fine scroll SetCharData($1000) count=count-1 if+ count<0 Scroll2_flag = 1 count = 7 else+ Scroll2_flag = 0 endif+ SetCharData($1000) endsub ; ; Scroll and reset charset ; irq Scroll2()_byte flag, byte rowpos byte offset=0,endtext SetCharData($2000) SetScrollX(7) ;Fix rest of screen AckRasterIRQ ;acknowledge irq if+ flag=1 endtext = offset+39 if+ endtext > mesg2len endtext = mesg2len endif+ row1$(rowpos:39) = mesg2$(offset:endtext) if+ rowpos>0 rowpos = rowpos-1 ;move mesg left elsif+ offset < mesg2len offset = offset+1 ;if all the way left then move through message else+ rowpos = 39 ;reset if done offset = 0 endif+ endif+ EndIRQ