*= $0800 .byte $00,$0c,$08,$0a,$00,$9e,$32,$33,$30,$34,$00,$00,$00,$00 screenlostore = $70 screenhistore = $71 ;-------------------------------------------------- ;Assemble It - Software Sprite/Character Collision ;-------------------------------------------------- * = $0900 ; Place main code here for now sei lda #$00 ;Black border+background sta $d020 sta $d021 ;Fill $2000, so that we can place it into the sprite data ldx #$00 fillsprt lda #$ff sta $2000,x inx cpx #$40 bne fillsprt ;Now clear the screen ldx #$00 clearscrn lda #$20 sta $0400,x sta $0500,x sta $0600,x sta $06e8,x lda #$02 sta $d800,x sta $d900,x sta $da00,x sta $dae8,x inx bne clearscrn ;Setup the sprites (Just enable one sprite for now) lda #$01 sta $d015 ;Set sprite display (bank #1 screen mem ;$0400-$07e8) to show the square sprite ;at $2000. lda #$80 ;Sprite is at $2000 sta $07f8 ;Sprite 0 frame ;Because we don't want multicolour or expanded ;sprites, or sprite behind the background, we ;disable those. lda #$00 ;All switched off sta $d017 ;Expand X sta $d01b ;Behind background sta $d01c ;Multicolour sta $d01f ;Expand Y ;Now paint the centre of the screen with the ;reversed spacebar character. ldy #$00 paintline lda #$02 sta $d9e0,y lda #$a0 sta $05e0,y iny cpy #40 bne paintline ;White sprite lda #$01 sta $d027 ;Okay, now let's init. the usual IRQ ;interrupt routine (We shall use the ;usual Kernal interrupt for now). lda #irq sta $0314 stx $0315 lda #$00 sta $d012 lda #$7f sta $dc0d lda #$01 sta $d01a cli ;Our main loop in sync to have the ;sprites and collision routine working mainloop lda #$00 sta syncloop cmp syncloop beq *-3 jsr expandmsb jsr movesprite jsr bgrcoll jmp mainloop ;Interrupts running. irq inc $d019 lda #$00 sta $d012 lda #$01 sta syncloop jmp $ea7e ;Subroutine 1: Sprite MSB expansion expandmsb ldx #$00 expandloop lda objpos+1,x sta $d001,x lda objpos,x asl ror $d010 sta $d000,x inx inx cpx #$10 beq exitexp jmp expandloop exitexp rts ;Subroutine 2 movesprite lda $dc00 readup lsr bcs readdown lda objpos+1 sec sbc #2 cmp #$32 bcs upstore lda #$32 upstore sta objpos+1 rts readdown lsr bcs readleft lda objpos+1 clc adc #2 cmp #$f2 bcc downstore lda #$fd downstore sta objpos+1 rts readleft lsr bcs readright lda objpos+0 sec sbc #1 cmp #$0c bcs leftstore lda #$0c leftstore sta objpos+0 rts readright lsr bcs nomove lda objpos+0 clc adc #1 cmp #$9a bcc rightstore lda #$9a rightstore sta objpos+$00 nomove rts ;Now for the sprite/background character ;collision routine. bgrcoll lda objpos+1 ;Load in sprite0's ghost position sec ;subtract with #$32 (50) due to the sbc #$32 ;upper border being 50 pixels thick, ;in which the sprite must avoid collision ;with if outside that range. lsr ;Divide by two 3 times. A char is 8x8 lsr ;pixels, and we divide the char width lsr ;so that you can have 40 chars collision tay ;per screen. lda screenlo,y ;Load in the low byte of the screen char sta screenlostore ;Store into the low byte store pointer lda screenhi,y ;Load in the high byte of the screen char sta screenhistore ;Store into the hi byte store pointer lda objpos+0 ;Load in sprite0's ghost position again sec ; sbc #$18 lsr lsr tay ldx #$03 sty selfmodi+1 bgcloop lda (screenlostore),y ;Load in the stored low byte data cmp #$a0 ;Did the sprite hit the inverted spacebar char? beq sprhit;sprite is hit iny ;increment Y to the selfmod loop lda (screenlostore),y ;Load in the stored lowbyte data ;yet again. cmp #$a0 ;Inverted spacebar char? beq sprhit ;Sprite is hit jmp selfmodi ;Jump to the self mod routine ;Self modifying loop. ;This will process the row of screen chars for the whole ;screen to be read, according to the low and high byte ;of the screen being read from a data table. selfmodi ldy #$00 lda screenlostore clc adc #$28 ;Next row of chars sta screenlostore bcc skipmod inc screenhistore skipmod dex bne bgcloop rts ;The sprite is hit, so we flash the sprite's multicolour. sprhit inc $d027 rts ;Byte tables syncloop .byte 0 ;Program IRQ sync objpos .byte $30,$50,0,0,0,0,0,0 ;Sprite X/Y positions .byte 0,0,0,0,0,0,0,0,0 ;The low and high byte of the screen chars. ;for example ; $05e0 ; screenhi = $05<-high byte ; screenlo = $e0<-low byte screenhi .byte $04,$04,$04,$04,$04 .byte $04,$04,$05,$05,$05 .byte $05,$05,$05,$06,$06 .byte $06,$06,$06,$06,$06 .byte $07,$07,$07,$07,$07,$07 screenlo .byte $00,$28,$50,$78,$a0 .byte $c8,$f0,$18,$40,$68 .byte $90,$b8,$e0,$08,$30 .byte $58,$80,$a8,$d0,$f8 .byte $20,$48,$70,$98,$c0,$e0