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:
parent
3c296c9c19
commit
ceeea2deb8
168
snake.asm
168
snake.asm
@ -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
|
||||||
|
;
|
||||||
|
Loading…
Reference in New Issue
Block a user