; ___ _ __ ___ __ ___ ; / __|_ _ __ _| |_____ / /| __|/ \_ ) ; \__ \ ' \/ _` | / / -_) _ \__ \ () / / ; |___/_||_\__,_|_\_\___\___/___/\__/___| ; Change direction: W A S D define appleL $00 ; screen location of apple, low byte define appleH $01 ; screen location of apple, high byte define snakeHeadL $10 ; screen location of snake head, low byte define snakeHeadH $11 ; screen location of snake head, high byte define snakeBodyStart $12 ; start of snake body byte pairs define snakeDirection $02 ; direction (possible values are below) define snakeLength $03 ; snake length, in bytes ; Directions (each using a separate bit) define movingUp 1 define movingRight 2 define movingDown 4 define movingLeft 8 ; ASCII values of keys controlling the snake define ASCII_w $57 define ASCII_a $41 define ASCII_s $53 define ASCII_d $44 ; System variables define sysRandom $fe define sysLastKey $ff jsr init jsr loop init: jsr initSnake jsr generateApplePosition rts initSnake: lda #movingRight ;start direction sta snakeDirection lda #4 ;start length (2 segments) sta snakeLength lda #$11 sta snakeHeadL lda #$10 sta snakeBodyStart lda #$0f sta $14 ; body segment 1 lda #$04 sta snakeHeadH sta $13 ; body segment 1 sta $15 ; body segment 2 rts generateApplePosition: ;load a new random byte into $00 lda sysRandom sta appleL ;load a new random number from 2 to 5 into $01 lda sysRandom and #$03 ;mask out lowest 2 bits clc adc #2 sta appleH rts loop: jsr readKeys jsr checkCollision jsr updateSnake jsr drawApple jsr drawSnake jsr spinWheels jmp loop readKeys: lda sysLastKey cmp #ASCII_w beq upKey cmp #ASCII_d beq rightKey cmp #ASCII_s beq downKey cmp #ASCII_a beq leftKey rts upKey: lda #movingDown bit snakeDirection bne illegalMove lda #movingUp sta snakeDirection rts rightKey: lda #movingLeft bit snakeDirection bne illegalMove lda #movingRight sta snakeDirection rts downKey: lda #movingUp bit snakeDirection bne illegalMove lda #movingDown sta snakeDirection rts leftKey: lda #movingRight bit snakeDirection bne illegalMove lda #movingLeft sta snakeDirection rts illegalMove: rts checkCollision: jsr checkAppleCollision jsr checkSnakeCollision rts checkAppleCollision: lda appleL cmp snakeHeadL bne doneCheckingAppleCollision lda appleH cmp snakeHeadH bne doneCheckingAppleCollision ;eat apple inc snakeLength inc snakeLength ;increase length jsr generateApplePosition doneCheckingAppleCollision: rts checkSnakeCollision: ldx #2 ;start with second segment snakeCollisionLoop: lda snakeHeadL,x cmp snakeHeadL bne continueCollisionLoop maybeCollided: lda snakeHeadH,x cmp snakeHeadH beq didCollide continueCollisionLoop: inx inx cpx snakeLength ;got to last section with no collision beq didntCollide jmp snakeCollisionLoop didCollide: jmp gameOver didntCollide: rts updateSnake: ldx snakeLength dex txa updateloop: lda snakeHeadL,x sta snakeBodyStart,x dex bpl updateloop lda snakeDirection lsr bcs up lsr bcs right lsr bcs down lsr bcs left up: lda snakeHeadL sec sbc #$20 sta snakeHeadL bcc upup rts upup: dec snakeHeadH lda #$1 cmp snakeHeadH beq collision rts right: inc snakeHeadL lda #$1f bit snakeHeadL beq collision rts down: lda snakeHeadL clc adc #$20 sta snakeHeadL bcs downdown rts downdown: inc snakeHeadH lda #$6 cmp snakeHeadH beq collision rts left: dec snakeHeadL lda snakeHeadL and #$1f cmp #$1f beq collision rts collision: jmp gameOver drawApple: ldy #0 lda sysRandom sta (appleL),y rts drawSnake: ldx snakeLength lda #0 sta (snakeHeadL,x) ; erase end of tail ldx #0 lda #1 sta (snakeHeadL,x) ; paint head rts spinWheels: ldx #1 spinloop: nop nop dex bne spinloop rts gameOver: