Added a lot of useful comments to document this code for future reviews, for future me, and for other mads who still code for the 6502 inside a CBM64

This commit is contained in:
giomba 2017-12-24 17:26:33 +01:00
parent 3c296c9c19
commit ceeea2deb8
1 changed files with 109 additions and 59 deletions

168
snake.asm
View File

@ -107,7 +107,7 @@ intro2string:
intro3string: intro3string:
BYTE "(C) 2018" BYTE "(C) 2018"
BYTE #0 BYTE #0
colorshade: colorshade: ; a shade from dark-gray to bright yellow, and vice-versa (40 columns)
BYTE #11,#11,#11,#11,#11,#12,#12,#12,#12,#12,#5,#5,#5 BYTE #11,#11,#11,#11,#11,#12,#12,#12,#12,#12,#5,#5,#5
BYTE #13,#13,#13,#13,#7,#7,#7,#7,#7,#7 BYTE #13,#13,#13,#13,#7,#7,#7,#7,#7,#7
BYTE #13,#13,#13,#13,#5,#5,#5,#12,#12,#12,#12,#12,#11,#11,#11,#11,#11 BYTE #13,#13,#13,#13,#5,#5,#5,#12,#12,#12,#12,#12,#11,#11,#11,#11,#11
@ -167,16 +167,18 @@ start:
; Enable interrupts ; Enable interrupts
cli cli
; Reset screen (and other parameters) to play intro
jsr introreset jsr introreset
intro0running: intro0running: ; Cycle here until SPACE or `Q` is pressed
jsr $ffe4 jsr $ffe4 ; GETIN
cmp #$20 cmp #$20 ; Is it SPACE?
beq intro0end beq intro0end ; if yes, go to intro0end and start game (see)
cmp #$51 cmp #$51 ; Is it Q?
bne intro0running bne intro0running ; If not, keep looping here,
jmp $fce2 jmp $fce2 ; else, reset the computer
; Intro is finished, now it's time to start the proper game
intro0end: intro0end:
; Set init variables of the game ; Set init variables of the game
jsr fullreset jsr fullreset
@ -185,19 +187,15 @@ intro0end:
sta status sta status
endless: endless:
; Endless loop, show that there is enough time after the interrupt ; Loop waiting for gameover
ldx $400
inx
stx $400
lda status lda status
cmp #3 cmp #3 ; is status equal to 3 (gameover) ?
bne endless bne endless ; if not, just wait looping here, else...
jsr introreset jsr introreset ; reset variables for intro
lda #0 lda #0
sta status sta status ; put machine into 0 status (play intro)
jmp intro0running jmp intro0running ; and go there waiting for keypress
; Full game reset ; Full game reset
; ---------------------------------------------------------------------- ; ----------------------------------------------------------------------
@ -234,17 +232,17 @@ upperbarLoop:
lda foodTile lda foodTile
sta $500 ; Put first piece of food sta $500 ; Put first piece of food
lda #4 lda #4
sta irqn sta irqn ; Initialize interrupt divider
lda #6 lda #6
sta direction sta direction ; Snake must go right
lda #19 lda #19
sta snakeX sta snakeX ; Snake is at screen center width...
lda #12 lda #12
sta snakeY sta snakeY ; ... and height
lda #5 lda #5
sta listStart sta listStart ; Beginning of snake tiles list
lda #5 lda #5
sta length sta length ; Length of the list
rts rts
@ -263,11 +261,14 @@ introresetCLS:
cpx #$ff cpx #$ff
bne introresetCLS bne introresetCLS
; Copy shade colors from costant table to color RAM for 2nd and 4th
; line of text. Soon there will be some text bouncing on these
; lines
ldx #39 ldx #39
introresetColorShade introresetColorShade
lda colorshade,x lda colorshade,x
sta $d828,x sta $d828,x ; 2nd line
sta $d878,x sta $d878,x ; 4th line
dex dex
cpx #$ff cpx #$ff
bne introresetColorShade bne introresetColorShade
@ -278,19 +279,21 @@ introresetColorShade
lda #0 lda #0
sta $d021 ; center sta $d021 ; center
lda #<intro2string ; Print website
sta printIntroString lda #<intro2string ; lsb of string address
lda #>intro2string sta printIntroString ; put into lsb of source pointer
sta printIntroString + 1 lda #>intro2string ; do the same for msb of string address
lda #$26 sta printIntroString + 1 ; put into msb of source pointer
sta introScreenStart lda #$26 ; this is lsb of address of 20th line
lda #$07 sta introScreenStart ; put into lsb of dest pointer
sta introScreenStart + 1 lda #$07 ; do the same for msb of adress of 20th line
jsr printIntro sta introScreenStart + 1 ; put into msb of dest pointer
jsr printIntro ; print
lda #<intro3string ; Print Copyright
sta printIntroString lda #<intro3string ; the assembly is the same as above,
lda #>intro3string sta printIntroString ; just change string to be printed
lda #>intro3string ; and line (21th line)
sta printIntroString + 1 sta printIntroString + 1
lda #$58 lda #$58
sta introScreenStart sta introScreenStart
@ -316,6 +319,11 @@ irq:
pha pha
; Check status ; Check status
; Sort of switch-case
; 0 intro running
; 1 for future use
; 2 actual game running
; 3 gameover
lda status lda status
cmp #0 cmp #0
bne checkStatus1 bne checkStatus1
@ -351,64 +359,83 @@ checkEndStatus:
; Go to original system routine ; Go to original system routine
jmp $ea31 jmp $ea31
; Currently status0 is the same as status1
; status1 has just been reserved for future use
status0: status0:
status1: status1:
; Decrement interrupt divider for the intro
ldx introCounter ldx introCounter
dex dex
stx introCounter stx introCounter
cpx #0 cpx #0
beq status1do beq status1do ; if divider is 0, then do status1do ...
rts rts ; ... else just do nothing and return
status1do: status1do:
; Reset introCounter
ldx #5 ldx #5
stx introCounter stx introCounter
; I want to print strings at different columns to make them
; bounce across the screen, so take last introX and add introXinc,
; then print string at that point. If introX is too far right, then
; set introXinc as #$ff (equals -1) so next time introX will be
; decremented by 1. And then, if introX is too far left, then
; set introXinc as #$01 so next time will be moved to right again.
lda introX lda introX
clc clc
adc introXinc adc introXinc ; this is #$01 or #$0ff, so actually it is +1 or -1
sta introX sta introX
cmp #19 cmp #19 ; am I too far right?
beq status1setSX beq status1setSX ; if yes, set SX (left)
cmp #0 cmp #0 ; am I too far left?
beq status1setDX beq status1setDX ; if yes, set DX (right)
jmp status1okset jmp status1okset ; else do nothing (aka, next time re-use current
; increment value)
status1setDX: status1setDX:
lda #$01 lda #$01 ; set introXinc as +1
sta introXinc sta introXinc
jmp status1okset jmp status1okset
status1setSX: status1setSX:
lda #$ff lda #$ff ; set introXinc as -1
sta introXinc sta introXinc
jmp status1okset jmp status1okset
status1okset: status1okset:
; Print "SNAKE BY GIOMBA" (see above for pointer details)
lda #<intro0string lda #<intro0string
sta printIntroString sta printIntroString
lda #>intro0string lda #>intro0string
sta printIntroString + 1 sta printIntroString + 1
; $0428 is 2nd line (previously filled with color shades by reset routine)
lda #$28 lda #$28
clc clc
adc introX adc introX ; just add X, to make it look like it has moved
sta introScreenStart sta introScreenStart
lda #$04 lda #$04
sta introScreenStart + 1 sta introScreenStart + 1
jsr printIntro jsr printIntro
; Print "PRESS SPACE TO PLAY"
lda #<intro1string lda #<intro1string
sta printIntroString sta printIntroString
lda #>intro1string lda #>intro1string
sta printIntroString + 1 sta printIntroString + 1
; $0478 is 4th line (previously filled with color shades by reset routine)
; add #19, then sub introX will make it move to other way of 2nd line
lda #$78 lda #$78
clc clc
adc #19 adc #19 ; add #19
sec sec
sbc introX sbc introX ; sub introX
sta introScreenStart sta introScreenStart
lda #$04 lda #$04
sta introScreenStart + 1 sta introScreenStart + 1
jsr printIntro jsr printIntro
; Some considerations on speed:
; yes, maybe I should have put the string chars once in screen text memory
; and then move it left and right. Should re-think about this.
; For now, just return.
rts rts
status2: ; do Game status2: ; do Game
@ -619,9 +646,11 @@ foodOK:
lda foodColor lda foodColor
sta (tileMem),y sta (tileMem),y
; print score at $10th column
ldy #$10 ldy #$10
lda length lda length
jsr printByte ; print score jsr printByte
jmp checkEndSelfEat jmp checkEndSelfEat
checkEndFood: checkEndFood:
@ -675,9 +704,14 @@ gameover:
sta printStatusString + 1 sta printStatusString + 1
jsr printStatus jsr printStatus
; Set gameover status
; this way, the loop out of this interrupt, will know that we
; finished, and play the intro again
lda #3 lda #3
sta status sta status
rts rts
; TODO : must be added a delay to let the player see her/his final score
; before clearing the screen and starting with the intro again
; Subroutines ; Subroutines
; ---------------------------------------------------------------------- ; ----------------------------------------------------------------------
@ -787,19 +821,35 @@ printStatusEnd:
rts rts
; Print string for intro ; Print string for intro
; Input parameters:
; printIntroString pointer to string to be printed (source)
; introScreenStart pointer to text video memory on screen where to print (dest)
printIntro: printIntro:
ldy #0 ldy #0
printIntroLoop: printIntroLoop:
lda (printIntroString),y lda (printIntroString),y ; get char from string
beq printIntroEnd beq printIntroEnd ; if zero, then end (string must be null-terminated)
cmp #$40 cmp #$40 ; is char greater or equal to #$40 = #64 = `@' ?
bcc printIntroEndCheck bcc printIntroEndCheck ; if not, it is less, thus it must be
; a full stop, comma, colon or something
; that actually has the same value in both
; true ASCII and in PET screen codes
; otherwise, it is greater than `@`, so must
; subtract 64 because CBM and its encodings
; are simply a big shit
sec sec
sbc #$40 sbc #$40
printIntroEndCheck: printIntroEndCheck:
sta (introScreenStart),y sta (introScreenStart),y ; put screen code to screen
iny iny ; next char in string
jmp printIntroLoop jmp printIntroLoop
printIntroEnd: printIntroEnd:
rts rts
;
; coded during december 2017
; by giomba -- giomba@glgprograms.it
; this software is free software and is distributed
; under the terms of GNU GPL v3 license
;