Import from tarball created on 2024-03-14
This commit is contained in:
commit
9206086b8a
11 changed files with 924 additions and 0 deletions
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
*.o
|
||||
*.prg
|
||||
*.lst
|
3
build.sh
Executable file
3
build.sh
Executable file
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
cl65 -o pong.prg -l pong.lst -t c64 -C c64-asm.cfg -u__EXEHDR__ main.asm
|
84
c64.inc
Normal file
84
c64.inc
Normal file
|
@ -0,0 +1,84 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
|
||||
PROGSTART = $080D ; just after BASIC header
|
||||
|
||||
;; Misc
|
||||
CINV = $0314 ; Hardware IRQ vector
|
||||
|
||||
;; CIA registers
|
||||
PRA = $DC00
|
||||
PRB = $DC01
|
||||
DDRA = $DC02
|
||||
DDRB = $DC03
|
||||
CIA_ICR = $DC0D
|
||||
|
||||
PRA2 = $DD00
|
||||
|
||||
;; VIC-II registers
|
||||
VICBASE = $D000
|
||||
SPRITE_0X = VICBASE+0
|
||||
SPRITE_0Y = VICBASE+1
|
||||
SPRITE_1X = VICBASE+2
|
||||
SPRITE_1Y = VICBASE+3
|
||||
SPRITE_2X = VICBASE+4
|
||||
SPRITE_2Y = VICBASE+5
|
||||
SPRITE_3X = VICBASE+6
|
||||
SPRITE_3Y = VICBASE+7
|
||||
SPRITE_4X = VICBASE+8
|
||||
SPRITE_4Y = VICBASE+9
|
||||
SPRITE_5X = VICBASE+10
|
||||
SPRITE_5Y = VICBASE+11
|
||||
SPRITE_6X = VICBASE+12
|
||||
SPRITE_6Y = VICBASE+13
|
||||
SPRITE_7X = VICBASE+14
|
||||
SPRITE_7Y = VICBASE+15
|
||||
SPRITE_X_MSB = VICBASE+16
|
||||
YSCROLL_MODE = VICBASE+17
|
||||
RASTER = VICBASE+18
|
||||
;; ...
|
||||
SPRITE_ENABLE = VICBASE+21
|
||||
XSCROLL_MODE = VICBASE+22
|
||||
SPRITE_XPAND_Y = VICBASE+23
|
||||
;; ...
|
||||
MEMPTR = VICBASE+24
|
||||
VICINT = VICBASE+25
|
||||
VICINTMASK = VICBASE+26
|
||||
SPRITE_BG_PRIO = VICBASE+27
|
||||
;; ...
|
||||
SPRITE_XPAND_X = VICBASE+29
|
||||
SSCOL = VICBASE+30
|
||||
;; ...
|
||||
BORDER = VICBASE+32
|
||||
BGCOL0 = VICBASE+33
|
||||
BGCOL1 = VICBASE+34
|
||||
BGCOL2 = VICBASE+35
|
||||
BGCOL3 = VICBASE+36
|
||||
;; ...
|
||||
SPRITE_0C = VICBASE+39
|
||||
SPRITE_1C = VICBASE+40
|
||||
SPRITE_2C = VICBASE+41
|
||||
SPRITE_3C = VICBASE+42
|
||||
SPRITE_4C = VICBASE+43
|
||||
SPRITE_5C = VICBASE+44
|
||||
SPRITE_6C = VICBASE+45
|
||||
SPRITE_7C = VICBASE+46
|
||||
|
||||
COLORMEM = $D800
|
||||
|
||||
;; SID registers
|
||||
SIDBASE = $D400
|
||||
SIDF1H = SIDBASE+1
|
||||
SIDF1L = SIDBASE+2
|
||||
SIDCR1 = SIDBASE+4
|
||||
SIDAD1 = SIDBASE+5
|
||||
SIDSR1 = SIDBASE+6
|
||||
|
||||
SIDFMV = SIDBASE+24
|
||||
|
||||
;; Macros
|
||||
|
||||
.macro padto addr
|
||||
.repeat (addr - *)
|
||||
.byte 0
|
||||
.endrep
|
||||
.endmacro
|
8
enum.asm
Normal file
8
enum.asm
Normal file
|
@ -0,0 +1,8 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
|
||||
.enum mode
|
||||
StartScreen = 0
|
||||
MainGame
|
||||
ScoreHighlight
|
||||
Win
|
||||
.endenum
|
183
gameloop.asm
Normal file
183
gameloop.asm
Normal file
|
@ -0,0 +1,183 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
|
||||
;;; Main gameloop routine.
|
||||
game:
|
||||
lda p1score
|
||||
ldx #4
|
||||
jsr printbyte
|
||||
|
||||
lda p2score
|
||||
ldx #(40 - 6)
|
||||
jsr printbyte
|
||||
|
||||
lda col
|
||||
beq @nocol
|
||||
jsr handle_collision
|
||||
@nocol:
|
||||
;; Player input:
|
||||
;; F1 (restart)
|
||||
ldx #%11111110
|
||||
ldy #%00010000
|
||||
jsr keydown
|
||||
bne @norestart
|
||||
jmp PROGSTART
|
||||
@norestart:
|
||||
|
||||
;; Q (player 1 up)
|
||||
ldx #%01111111
|
||||
ldy #%01000000
|
||||
jsr keydown
|
||||
bne @skip1
|
||||
dec p1y
|
||||
dec p1y
|
||||
|
||||
;; A (player 1 down)
|
||||
@skip1:
|
||||
ldx #%11111101
|
||||
ldy #%00000100
|
||||
jsr keydown
|
||||
bne @skip2
|
||||
inc p1y
|
||||
inc p1y
|
||||
@skip2:
|
||||
|
||||
;; O (player 2 up)
|
||||
ldx #%11101111
|
||||
ldy #%01000000
|
||||
jsr keydown
|
||||
bne @skip3
|
||||
dec p2y
|
||||
dec p2y
|
||||
@skip3:
|
||||
|
||||
;; L (player 2 down)
|
||||
ldx #%11011111
|
||||
ldy #%00000100
|
||||
jsr keydown
|
||||
bne @skip4
|
||||
inc p2y
|
||||
inc p2y
|
||||
@skip4:
|
||||
|
||||
;; Clamp paddles to stay on-screen.
|
||||
lda #$32 ;player 1 top
|
||||
cmp p1y
|
||||
bcc @dontclamp1
|
||||
sta p1y
|
||||
@dontclamp1:
|
||||
lda #($fa - 42) ;player 1 bottom
|
||||
cmp p1y
|
||||
bcs @dontclamp2
|
||||
sta p1y
|
||||
@dontclamp2:
|
||||
lda #$32 ;player 2 top
|
||||
cmp p2y
|
||||
bcc @dontclamp3
|
||||
sta p2y
|
||||
@dontclamp3:
|
||||
lda #($fa - 42) ;player 2 bottom
|
||||
cmp p2y
|
||||
bcs @dontclamp4
|
||||
sta p2y
|
||||
@dontclamp4:
|
||||
|
||||
update_paddles:
|
||||
lda p1y
|
||||
sta SPRITE_0Y
|
||||
lda p2y
|
||||
sta SPRITE_1Y
|
||||
|
||||
ball_physics:
|
||||
lda #BALLVERT
|
||||
and balldata
|
||||
beq @down ; 0 = down, 1 = up
|
||||
txa
|
||||
clc
|
||||
dec ball_y
|
||||
lda #BALLVSPEED
|
||||
bit balldata
|
||||
beq @slowballup
|
||||
dec ball_y ;else we have a fast down ball
|
||||
@slowballup:
|
||||
;; Top bounce check
|
||||
lda ball_y
|
||||
cmp #$32
|
||||
beq @topbouncestill
|
||||
bcs @horizontal
|
||||
@topbouncestill:
|
||||
;; If it's <= 32 then we bounce off the top
|
||||
jsr ball_bounce_vert
|
||||
jmp @horizontal
|
||||
|
||||
@down:
|
||||
inc ball_y
|
||||
lda #BALLVSPEED
|
||||
bit balldata
|
||||
beq @slowballdown
|
||||
inc ball_y
|
||||
@slowballdown:
|
||||
;; Bottom bounce check
|
||||
lda ball_y
|
||||
cmp #($fa - 8) ;$fa is bottom of the screen, - 8 for ball height
|
||||
bcc @horizontal
|
||||
jsr ball_bounce_vert
|
||||
;; fallthrough to horizontal
|
||||
|
||||
@horizontal:
|
||||
lda #BALLHORI
|
||||
and balldata
|
||||
beq @left ; 0 = left, 1 = right
|
||||
;; Move ball right
|
||||
jsr ball_x_inc ;first increment
|
||||
lda #BALLHSPEED
|
||||
bit balldata
|
||||
beq @done
|
||||
;; if bit BALLHSPEED is set, we have a horizontally fast ball
|
||||
jsr ball_x_inc ;so we increment again
|
||||
jmp @done
|
||||
@left:
|
||||
;; Move ball left
|
||||
jsr ball_x_dec ;first decrement
|
||||
lda #BALLHSPEED
|
||||
bit balldata
|
||||
beq @done
|
||||
;; if bit BALLHSPEED is set, we have a horizontally fast ball
|
||||
jsr ball_x_dec ;so we dec again
|
||||
@done:
|
||||
|
||||
check_ball_goal:
|
||||
;; Check to see if it's time to change score and reset the ball
|
||||
lda #%00000100
|
||||
bit SPRITE_X_MSB ;check if it's on the left or right side
|
||||
bne @right
|
||||
|
||||
lda ball_x
|
||||
cmp #$10
|
||||
bcs @nope
|
||||
inc p2score
|
||||
lda p2score
|
||||
jsr clampscore
|
||||
sta p2score
|
||||
jsr reset_ball
|
||||
jsr highlightscore
|
||||
jmp @nope
|
||||
@right:
|
||||
lda ball_x
|
||||
cmp #$50
|
||||
bcc @nope
|
||||
inc p1score
|
||||
lda p1score
|
||||
jsr clampscore
|
||||
sta p1score
|
||||
jsr reset_ball
|
||||
jsr highlightscore
|
||||
@nope:
|
||||
|
||||
ball_sprite:
|
||||
lda ball_x
|
||||
sta SPRITE_2X
|
||||
lda ball_y
|
||||
sta SPRITE_2Y
|
||||
|
||||
;; MAIN GAME ROUTINE ENDS HERE, PUT SUBROUTINES AFTER
|
||||
rts
|
73
graphics.asm
Normal file
73
graphics.asm
Normal file
|
@ -0,0 +1,73 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
|
||||
SPRITEBASE = $3400
|
||||
|
||||
sprite_data:
|
||||
.repeat 21
|
||||
.byte $ff, 0, 0 ;defines 8x21 paddle sprite
|
||||
.endrep
|
||||
.byte 0
|
||||
|
||||
.repeat 8
|
||||
.byte $ff, 0, 0
|
||||
.endrep
|
||||
.repeat 13
|
||||
.byte 0, 0, 0
|
||||
.endrep
|
||||
.byte 0
|
||||
|
||||
sprite_data_end:
|
||||
|
||||
scrlinelo:
|
||||
.byte $00
|
||||
.byte $28
|
||||
.byte $50
|
||||
.byte $78
|
||||
.byte $A0
|
||||
.byte $C8
|
||||
.byte $F0
|
||||
.byte $18
|
||||
.byte $40
|
||||
.byte $68
|
||||
.byte $90
|
||||
.byte $B8
|
||||
.byte $E0
|
||||
.byte $08
|
||||
.byte $30
|
||||
.byte $58
|
||||
.byte $80
|
||||
.byte $A8
|
||||
.byte $D0
|
||||
.byte $F8
|
||||
.byte $20
|
||||
.byte $48
|
||||
.byte $70
|
||||
.byte $98
|
||||
.byte $C0
|
||||
|
||||
scrlinehi:
|
||||
.byte $04
|
||||
.byte $04
|
||||
.byte $04
|
||||
.byte $04
|
||||
.byte $04
|
||||
.byte $04
|
||||
.byte $04
|
||||
.byte $05
|
||||
.byte $05
|
||||
.byte $05
|
||||
.byte $05
|
||||
.byte $05
|
||||
.byte $05
|
||||
.byte $06
|
||||
.byte $06
|
||||
.byte $06
|
||||
.byte $06
|
||||
.byte $06
|
||||
.byte $06
|
||||
.byte $06
|
||||
.byte $07
|
||||
.byte $07
|
||||
.byte $07
|
||||
.byte $07
|
||||
.byte $07
|
215
init.asm
Normal file
215
init.asm
Normal file
|
@ -0,0 +1,215 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
|
||||
init:
|
||||
;; Set our custom NMI vector so that pressing restore quits
|
||||
lda #<nmi
|
||||
sta $0318
|
||||
lda #>nmi
|
||||
sta $0319
|
||||
|
||||
;; Reset gamemode
|
||||
lda #mode::StartScreen
|
||||
sta gamemode
|
||||
|
||||
;; Reset variables
|
||||
lda #0
|
||||
sta p1score
|
||||
sta p2score
|
||||
sta p1y
|
||||
sta p2y
|
||||
sta exit
|
||||
lda #64
|
||||
sta ball_x
|
||||
sta ball_y
|
||||
|
||||
|
||||
sei ;turn off IRQ while setting up
|
||||
|
||||
lda #$7f
|
||||
sta CIA_ICR ;disable CIA IRQ
|
||||
bit CIA_ICR ;acknowledge it
|
||||
|
||||
;; Set up our graphics
|
||||
ldx #$00
|
||||
stx BGCOL0 ;black background, appropriate for pong
|
||||
stx BORDER
|
||||
|
||||
jsr loadtitlescreen
|
||||
|
||||
lda #%00000111
|
||||
sta SPRITE_ENABLE ;enable sprite 0,1,2
|
||||
sta SSCOL
|
||||
sta SPRITE_BG_PRIO
|
||||
lda #%00000011
|
||||
sta SPRITE_XPAND_Y
|
||||
lda #$01
|
||||
sta SPRITE_0C
|
||||
sta SPRITE_1C
|
||||
sta SPRITE_2C
|
||||
|
||||
lda #%00000010
|
||||
sta SPRITE_X_MSB
|
||||
lda #$18
|
||||
sta SPRITE_0X
|
||||
lda #$50
|
||||
sta SPRITE_1X
|
||||
|
||||
lda #$32
|
||||
sta SPRITE_0Y
|
||||
sta SPRITE_1Y
|
||||
|
||||
lda #$64
|
||||
sta SPRITE_2X
|
||||
sta SPRITE_2Y
|
||||
|
||||
;; Load sprites
|
||||
;; Note: breaks if we have more than 255 bytes of sprite gfx
|
||||
ldx #(sprite_data_end - sprite_data) ;DANGER
|
||||
ldy #$00
|
||||
@loadloop:
|
||||
lda sprite_data,y
|
||||
sta SPRITEBASE,y
|
||||
iny
|
||||
dex
|
||||
bne @loadloop
|
||||
;; done when X is zero
|
||||
|
||||
;; lda #<scorestr
|
||||
;; sta z:zscratch0
|
||||
;; lda #>scorestr
|
||||
;; sta z:zscratch1
|
||||
;; ldx #4
|
||||
;; jsr printstr
|
||||
|
||||
;; Set up our own IRQ routine
|
||||
lda #<irq
|
||||
sta CINV
|
||||
lda #>irq
|
||||
sta CINV+1
|
||||
|
||||
ldx #$0
|
||||
stx RASTER ;trigger IRQ on scanline 0 (vblank)
|
||||
ldx #%00000101 ;raster & sprite-sprite col IRQs
|
||||
stx VICINTMASK ;enable VIC IRQ
|
||||
|
||||
cli ;turn IRQ back on, we're ready
|
||||
idle:
|
||||
jmp idle ;do nothing forever, game is driven by IRQ
|
||||
|
||||
nmi:
|
||||
brk
|
||||
|
||||
clearscreen:
|
||||
;; Let's clear the background
|
||||
lda #<VMBASE
|
||||
sta z:zscratch0
|
||||
lda #>VMBASE
|
||||
sta z:zscratch1
|
||||
lda #<COLORMEM
|
||||
sta z:zscratch2
|
||||
lda #>COLORMEM
|
||||
sta z:zscratch3
|
||||
ldx #$04
|
||||
@loopouter:
|
||||
ldy #$00
|
||||
@loopinner:
|
||||
lda #$20
|
||||
sta (zscratch0),y
|
||||
lda #$01 ;write the color white
|
||||
sta (zscratch2),y ;to every part of color RAM
|
||||
iny
|
||||
bne @loopinner
|
||||
inc z:zscratch1 ;increment page
|
||||
inc z:zscratch3
|
||||
dex
|
||||
bne @loopouter
|
||||
|
||||
;; Set up sprites
|
||||
;; sprite ptr $d0 = memory location $3400
|
||||
ldx #$d0
|
||||
stx VMBASE+($400 - 8)
|
||||
stx VMBASE+($400 - 7)
|
||||
inx
|
||||
stx VMBASE+($400 - 6)
|
||||
|
||||
rts
|
||||
|
||||
loadtitlescreen:
|
||||
jsr clearscreen
|
||||
|
||||
lda #<title
|
||||
sta z:zscratch0
|
||||
lda #>title
|
||||
sta z:zscratch1
|
||||
|
||||
ldx #$0a
|
||||
ldy #$0b
|
||||
jsr printstr
|
||||
|
||||
lda #<credits
|
||||
sta z:zscratch0
|
||||
lda #>credits
|
||||
sta z:zscratch1
|
||||
|
||||
ldx #$0c
|
||||
ldy #$0e
|
||||
jsr printstr
|
||||
|
||||
lda #<tutorial2
|
||||
sta z:zscratch0
|
||||
lda #>tutorial2
|
||||
sta z:zscratch1
|
||||
|
||||
ldx #$09
|
||||
ldy #$15
|
||||
jsr printstr
|
||||
|
||||
lda #<tutorial1
|
||||
sta z:zscratch0
|
||||
lda #>tutorial1
|
||||
sta z:zscratch1
|
||||
|
||||
ldx #$0a
|
||||
ldy #$17
|
||||
jsr printstr
|
||||
|
||||
rts
|
||||
|
||||
title:
|
||||
.byte $10, $0F, $0E, $07, $2C, $20, $0D, $0F, $12, $05, $20, $0F, $12, $20, $0C, $05, $13, $13, 0
|
||||
|
||||
credits:
|
||||
.byte $0D, $01, $04, $05, $20, $02, $19, $20, $04, $15, $15, $11, $0E, $04, 0
|
||||
|
||||
tutorial1:
|
||||
.byte $03, $0F, $0E, $14, $12, $0F, $0C, $20, $17, $09, $14, $08, $20, $11, $01, $20, $0F, $0C, 0
|
||||
|
||||
tutorial2:
|
||||
.byte $10, $12, $05, $13, $13, $20, $13, $10, $01, $03, $05, $20, $14, $0F, $20, $13, $14, $01, $12, $14, 0
|
||||
|
||||
loadgamefield:
|
||||
jsr clearscreen
|
||||
|
||||
;; now we'll draw the center column
|
||||
ldx #$25
|
||||
@lineloop:
|
||||
lda scrlinelo,x
|
||||
sta z:zscratch0
|
||||
lda scrlinehi,x
|
||||
sta z:zscratch1
|
||||
txa
|
||||
and #%00000001
|
||||
bne @skipdot
|
||||
lda #103
|
||||
ldy #20
|
||||
sta (zscratch0),y
|
||||
jmp @next
|
||||
@skipdot:
|
||||
lda #116
|
||||
ldy #19
|
||||
sta (zscratch0),y
|
||||
@next:
|
||||
dex
|
||||
bpl @lineloop
|
||||
|
||||
rts
|
246
main.asm
Normal file
246
main.asm
Normal file
|
@ -0,0 +1,246 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
.include "c64.inc"
|
||||
.include "enum.asm"
|
||||
|
||||
VMBASE = $0400
|
||||
|
||||
.org PROGSTART
|
||||
|
||||
.include "init.asm" ;must come first
|
||||
.include "utilities.asm"
|
||||
|
||||
;; Start screen, waits for space key to be pressed.
|
||||
titlescreen:
|
||||
;; More visually interesting sprite positioning for
|
||||
;; the title screen. Overrides default from init.
|
||||
lda #$82
|
||||
sta SPRITE_0Y
|
||||
|
||||
ldx #%01111111
|
||||
ldy #%00010000
|
||||
jsr keydown
|
||||
bne @dontstart
|
||||
;; Start the game here.
|
||||
jsr loadgamefield ;set the background
|
||||
lda #mode::MainGame ;don't forget that #
|
||||
sta gamemode ;set the game mode to MainGame
|
||||
@dontstart:
|
||||
rts
|
||||
|
||||
|
||||
;; Wait and highlight the score change for half a second.
|
||||
;; Happens every time a player scores or whatever it's called in tennis
|
||||
scorewait:
|
||||
;; While waiting we play a buzz
|
||||
lda #$0f
|
||||
sta SIDFMV
|
||||
lda #$08
|
||||
sta SIDAD1
|
||||
lda #$68
|
||||
sta SIDSR1
|
||||
|
||||
lda #$45
|
||||
sta SIDF1L
|
||||
lda #$1d
|
||||
sta SIDF1H
|
||||
|
||||
lda #$11
|
||||
sta SIDCR1
|
||||
|
||||
dec timer
|
||||
bne @dontresume
|
||||
;; Reset gamemode
|
||||
lda #mode::MainGame
|
||||
sta gamemode
|
||||
;; Reset background color
|
||||
lda #0
|
||||
sta BGCOL0
|
||||
;; Stop sound
|
||||
lda #$10
|
||||
sta SIDCR1
|
||||
@dontresume:
|
||||
rts
|
||||
|
||||
|
||||
;; Call after a player scores to highlight the win
|
||||
highlightscore:
|
||||
lda #mode::ScoreHighlight
|
||||
sta gamemode
|
||||
lda #25
|
||||
sta timer
|
||||
lda #2
|
||||
sta BGCOL0
|
||||
rts
|
||||
|
||||
.include "gameloop.asm"
|
||||
|
||||
|
||||
;; "Victory" mode when 100 points has been reached.
|
||||
win:
|
||||
dec timer
|
||||
bne @skip
|
||||
dec timer2
|
||||
bne @continue
|
||||
;; After five seconds (10 half-seconds) we reset the game
|
||||
jmp PROGSTART
|
||||
@continue:
|
||||
lda #25
|
||||
sta timer
|
||||
lda BGCOL0
|
||||
eor #8
|
||||
sta BGCOL0
|
||||
@skip:
|
||||
rts
|
||||
|
||||
winstop:
|
||||
lda #25
|
||||
sta timer
|
||||
lda #10
|
||||
sta timer2
|
||||
lda #$0d
|
||||
sta BGCOL0
|
||||
lda #mode::Win ;DO NOT FORGET THE #
|
||||
sta gamemode
|
||||
rts
|
||||
|
||||
ball_x_inc:
|
||||
inc ball_x
|
||||
bne @done
|
||||
;; If ball_x incremented to zero we have either looped around
|
||||
;; the screen (shouldn't happen) or crossed the bit 8 boundry.
|
||||
;; So we set the MSB to one, since we're going right.
|
||||
lda #%00000100
|
||||
ora SPRITE_X_MSB
|
||||
sta SPRITE_X_MSB
|
||||
@done:
|
||||
rts
|
||||
|
||||
ball_x_dec:
|
||||
dec ball_x
|
||||
lda ball_x
|
||||
cmp #$ff
|
||||
bne @done
|
||||
;; If ball_x incremented to zero we have either looped around
|
||||
;; the screen (shouldn't happen) or crossed the bit 8 boundry.
|
||||
;; So we set the MSB to one, since we're going right.
|
||||
lda #%11111011
|
||||
and SPRITE_X_MSB
|
||||
sta SPRITE_X_MSB
|
||||
@done:
|
||||
rts
|
||||
|
||||
ball_bounce_vert:
|
||||
jsr color_change
|
||||
lda #%10000000
|
||||
eor balldata
|
||||
sta balldata
|
||||
rts
|
||||
|
||||
ball_bounce_hori:
|
||||
jsr color_change
|
||||
lda #%01000000
|
||||
eor balldata
|
||||
sta balldata
|
||||
rts
|
||||
|
||||
reset_ball:
|
||||
jsr ball_bounce_hori
|
||||
lda #$90
|
||||
sta ball_y
|
||||
lda #$c0
|
||||
sta ball_x
|
||||
lda #%11111011
|
||||
and SPRITE_X_MSB
|
||||
sta SPRITE_X_MSB
|
||||
rts
|
||||
|
||||
color_change:
|
||||
inc bordercol
|
||||
lda bordercol
|
||||
and #$0f
|
||||
cmp #2
|
||||
bcs @fine
|
||||
lda #2
|
||||
sta bordercol
|
||||
@fine:
|
||||
lda bordercol
|
||||
sta BORDER
|
||||
rts
|
||||
|
||||
handle_collision:
|
||||
jsr ball_bounce_hori ;obvious, flip the ball's horizontal direction
|
||||
lda #$00
|
||||
sta col ;clear the collision flag
|
||||
rts
|
||||
|
||||
;; Cheap trick to make a hexprinted number look decimal.
|
||||
;; Score comes in the A register, clamped score returned in A
|
||||
clampscore:
|
||||
tax
|
||||
and #%00001111
|
||||
cmp #$0a
|
||||
bcc @noclamplower
|
||||
;; yes clamp, inc upper nybble, ex. $19 -> $20
|
||||
txa
|
||||
and #%11110000
|
||||
clc
|
||||
adc #$10
|
||||
tax
|
||||
@noclamplower:
|
||||
txa
|
||||
and #%11110000
|
||||
cmp #$a0
|
||||
bcc @noclamp
|
||||
;; over 99? just stop at that point, we'll flash some colors then reset
|
||||
jsr winstop
|
||||
pla
|
||||
pla
|
||||
@noclamp:
|
||||
txa
|
||||
rts
|
||||
|
||||
modedispatch:
|
||||
jsr jumpwithtable
|
||||
.addr titlescreen
|
||||
.addr game ;normal gameplay
|
||||
.addr scorewait
|
||||
.addr win
|
||||
|
||||
|
||||
;; Main IRQ subroutine. CPU gets sent here by the interrupts from the
|
||||
;; VIC-II's raster and collision interrupts, and is responsible for
|
||||
;; calling everything else. Since the game is interrupt-driven, you
|
||||
;; could add a RTS to the init code and have the game run together
|
||||
;; with BASIC. Would be pretty stupid but you *can* do it. That does
|
||||
;; give me an idea though...
|
||||
irq:
|
||||
lda SSCOL ;need to do this for collision checking to work
|
||||
|
||||
lda #%00000100 ;check if irq is for collision or not
|
||||
and VICINT
|
||||
beq @nocol
|
||||
;; Collision
|
||||
sta col ;set the collision flag
|
||||
lda #$7f
|
||||
and VICINT
|
||||
sta VICINT
|
||||
jmp @skipgame
|
||||
@nocol:
|
||||
lda gamemode
|
||||
jsr modedispatch
|
||||
@skipgame:
|
||||
lda #$7f
|
||||
and VICINT
|
||||
sta VICINT
|
||||
|
||||
jmp $ea31
|
||||
|
||||
.include "variables.asm"
|
||||
|
||||
BALLVERT = %10000000
|
||||
BALLHORI = %01000000
|
||||
BALLVSPEED = %00000010
|
||||
BALLHSPEED = %00000001
|
||||
|
||||
.include "graphics.asm"
|
||||
.include "zeropage.asm"
|
88
utilities.asm
Normal file
88
utilities.asm
Normal file
|
@ -0,0 +1,88 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
|
||||
;; Jumps to a routine via a table. Index goes in A register.
|
||||
jumpwithtable:
|
||||
tay
|
||||
|
||||
;; Set up pointer to jump table
|
||||
pla
|
||||
sta z:zscratch0
|
||||
pla
|
||||
sta z:zscratch1
|
||||
|
||||
tya
|
||||
asl
|
||||
tay
|
||||
iny
|
||||
|
||||
lda (zscratch0),y
|
||||
sta z:zscratch2
|
||||
iny
|
||||
lda (zscratch0),y
|
||||
sta z:zscratch3
|
||||
|
||||
jmp (zscratch2)
|
||||
|
||||
printbyte:
|
||||
inx
|
||||
jsr printnyb
|
||||
.repeat 4
|
||||
lsr
|
||||
.endrep
|
||||
dex
|
||||
jsr printnyb
|
||||
rts
|
||||
|
||||
printnyb:
|
||||
pha
|
||||
and #$0f
|
||||
cmp #$0a
|
||||
bcc @number ;if nybble<$A then print a number, else letter
|
||||
sec
|
||||
sbc #$09 ;letters start at $01, so sub away 9
|
||||
jmp @done
|
||||
@number:
|
||||
clc
|
||||
adc #$30 ;print a number, starting at $30
|
||||
@done:
|
||||
sta VMBASE,x
|
||||
pla
|
||||
rts
|
||||
|
||||
;; Put string pointer into zscratch1+2
|
||||
;; X position into X, y pos into Y
|
||||
printstr:
|
||||
lda scrlinelo,y
|
||||
sta z:zscratch2
|
||||
lda scrlinehi,y
|
||||
sta z:zscratch3
|
||||
|
||||
txa
|
||||
clc
|
||||
adc z:zscratch2
|
||||
sta z:zscratch2
|
||||
lda z:zscratch3
|
||||
adc #0
|
||||
sta z:zscratch3
|
||||
|
||||
ldy #$00
|
||||
@loop:
|
||||
lda (zscratch0),y
|
||||
beq @done
|
||||
sta (zscratch2),y
|
||||
iny
|
||||
inx
|
||||
jmp @loop
|
||||
@done:
|
||||
rts
|
||||
|
||||
keydown:
|
||||
lda #$ff
|
||||
sta DDRA
|
||||
lda #$00
|
||||
sta DDRB
|
||||
stx PRA
|
||||
tya
|
||||
and PRB
|
||||
rts
|
||||
|
14
variables.asm
Normal file
14
variables.asm
Normal file
|
@ -0,0 +1,14 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
gamemode: .res 1, mode::StartScreen
|
||||
p1y: .res 1, 0
|
||||
p1score: .res 1, $90
|
||||
p2score: .res 1, 0
|
||||
p2y: .res 1, 0
|
||||
col: .res 1, 0
|
||||
balldata: .res 1, %01000011 ;ball starts going right, fast vert & hori
|
||||
ball_x: .res 1, 64
|
||||
ball_y: .res 1, 64
|
||||
bordercol: .res 1, 0
|
||||
timer: .res 1, 0
|
||||
timer2: .res 1, 0
|
||||
exit: .res 1, 0
|
7
zeropage.asm
Normal file
7
zeropage.asm
Normal file
|
@ -0,0 +1,7 @@
|
|||
;;; -*- Mode: asm; indent-tabs-mode: t; tab-width: 8 -*-
|
||||
.zeropage
|
||||
.org $50
|
||||
zscratch0: .res 1
|
||||
zscratch1: .res 1
|
||||
zscratch2: .res 1
|
||||
zscratch3: .res 1
|
Loading…
Add table
Reference in a new issue