@@ 9,7 9,59 @@
.fillvalue $FF ; Sets all unused space in rom to value $FF
.org $C000
-;; Reset
+;; constants
+
+PPUCTRL .equ $2000
+PPUMASK .equ $2001
+PPUSTATUS .equ $2002 ; Using BIT PPUSTATUS preserves the previous contents of A.
+SPRADDR .equ $2003
+PPUSCROLL .equ $2005
+PPUADDR .equ $2006
+PPUDATA .equ $2007
+ ; APU
+APUCH1VOL .equ $4000 ; APU
+APUCH1SWP .equ $4001
+APUCH1FRQ .equ $4002
+APUCH1LEN .equ $4003
+APUCH2VOL .equ $4004
+APUCH2SWP .equ $4005
+APUCH2FRQ .equ $4006
+APUCH2LEN .equ $4007
+APUCH3CNT .equ $4008
+APUCH3SWP .equ $4009
+APUCH3FRQ .equ $400a
+APUCH3LEN .equ $400b
+APUCH4VOL .equ $400c
+APUCH4SWP .equ $400d
+APUCH4FRQ .equ $400e
+APUCH4LEN .equ $400f
+SPRDMA .equ $4014
+APUCTRL .equ $4015
+JOY1 .equ $4016
+JOY2 .equ $4017
+BUTTON_RIGHT .equ #$01
+BUTTON_LEFT .equ #$02
+BUTTON_DOWN .equ #$04
+BUTTON_UP .equ #$08
+BUTTON_START .equ #$10
+BUTTON_SELECT .equ #$20
+BUTTON_B .equ #$40
+BUTTON_A .equ #$80
+
+;; variables
+
+ .enum $0000
+rate .dsb 1
+timer .dsb 1
+position .dsb 1
+cursor .dsb 1
+note .dsb 1
+down@input .dsb 1
+last@input .dsb 1
+next@input .dsb 1
+ .ende
+
+;; reset
RESET: ;
SEI ; disable IRQs
@@ 19,15 71,15 @@ RESET: ;
LDX #$FF
TXS ; Set up stack
INX ; now X = 0
- STX $2000 ; disable NMI
- STX $2001 ; disable rendering
+ STX PPUCTRL ; disable NMI
+ STX PPUMASK ; disable rendering
STX $4010 ; disable DMC IRQs
-vblankwait1: ; First wait for vblank to make sure PPU is ready
- BIT $2002
- BPL vblankwait1
+Vblankwait1: ; First wait for vblank to make sure PPU is ready
+ BIT PPUSTATUS
+ BPL Vblankwait1
-clrmem: ;
+Clrmem: ;
LDA #$00
STA $0000, x
STA $0100, x
@@ 39,31 91,120 @@ clrmem: ;
LDA #$FE
STA $0200, x ; move all sprites off screen
INX
- BNE clrmem
+ BNE Clrmem
+
+Vblankwait2: ; Second wait for vblank, PPU is ready after this
+ BIT PPUSTATUS
+ BPL Vblankwait2
+
+;; begin setup
+
+SetupPalettes: ;
+ LDA PPUSTATUS
+ LDA #$3F
+ STA PPUADDR
+ LDA #$00
+ STA PPUADDR
+ LDX #$00
+@loop: ;
+ LDA Palettes, x
+ STA PPUDATA
+ INX
+ CPX #$20
+ BNE @loop
-vblankwait2: ; Second wait for vblank, PPU is ready after this
- BIT $2002
- BPL vblankwait2
- JSR LoadPalettes
- JSR LoadAttributes
+SetupAttributes: ;
+ LDA PPUSTATUS
+ LDA #$23
+ STA PPUADDR
+ LDA #$C0
+ STA PPUADDR
+ LDX #$00
+@loop: ;
+ LDA #$00
+ STA PPUDATA
+ INX
+ CPX #$40
+ BNE @loop
JSR Redraw
+SetupVariables:
+ LDA #$10
+ STA rate
+ LDA #$40
+ STA note
+
+SetupPlayer:
+ LDA #$88
+ ADC timer
+ STA $0200 ; set tile.y pos
+ LDA #$02
+ STA $0201 ; set tile.id
+ LDA #$00
+ STA $0202 ; set tile.attribute
+
EnableSprites: ;
LDA #%10010000 ; enable NMI, sprites from Pattern Table 0, background from Pattern Table 1
- STA $2000
+ STA PPUCTRL
LDA #%00011110 ; enable sprites, enable background, no clipping on left side
- STA $2001
+ STA PPUMASK
LDA #$00 ; No background scrolling
- STA $2006
- STA $2006
- STA $2005
- STA $2005
+ STA PPUADDR
+ STA PPUADDR
+ STA PPUSCROLL
+ STA PPUSCROLL
+
+MAIN:
+ ; route inputs
+ LDA next@input
+ CMP BUTTON_LEFT
+ BEQ MoveLeft
+ CMP BUTTON_RIGHT
+ BEQ MoveRight
+ JMP MAIN ; jump back to Forever, infinite loop
-Forever: ;
- JMP Forever ; jump back to Forever, infinite loop
+;; General functions
+
+MoveLeft:
+ DEC cursor
+ LDA cursor
+ CMP #$ff
+ BNE @done ; when equal skip
+ ; wrap around
+ LDA #$0f
+ STA cursor
+@done: ;
+ LDA #$00
+ STA next@input
+ STA RedrawTimeline
+ JMP MAIN
+
+MoveRight:
+ INC cursor
+ LDA cursor
+ CMP #$10
+ BCC @done ; when greater skip
+ ; wrap around
+ LDA #$00
+ STA cursor
+@done: ;
+ LDA #$00
+ STA next@input
+ STA RedrawTimeline
+ JMP MAIN
;; interface
+RedrawPlayer:
+ LDA position
+ ASL
+ ASL
+ ASL
+ CLC
+ ADC #$40
+ STA $0203 ; set tile.x pos
+ RTS
+
RedrawMeter:
; selector
LDA #$04
@@ 108,82 249,97 @@ RedrawLine:
RTS
RedrawTimeline:
- LDA #$10
- LDX #$07
- LDY #$22
+ LDX #$00
@loop: ;
+ LDA #$22 ; v pos
+ STA PPUADDR
+ LDA TimelinePositions, x ; x pos
+ STA PPUADDR
+ LDA #$20
+ STA PPUDATA
INX
- JSR DrawAt
- CPX #$18
+ CPX #$10
BNE @loop
RTS
Redraw:
+ LDA PPUSTATUS
JSR RedrawTimeline
JSR RedrawMeter
+ JSR RedrawPlayer
RTS
DrawAt: ; (a:id,x,y)
- STY $2006
- STX $2006
- STA $2007
+ STY PPUADDR
+ STX PPUADDR
+ STA PPUDATA
RTS
-LoadPalettes: ;
- LDA $2002
- LDA #$3F
- STA $2006
- LDA #$00
- STA $2006
- LDX #$00
-@loop: ;
- LDA palettes, x
- STA $2007
- INX
- CPX #$20
- BNE @loop
- RTS
+NMI: ;
-LoadAttributes: ;
- LDA $2002
- LDA #$23
- STA $2006
- LDA #$C0
- STA $2006
- LDX #$00
-@loop: ;
- LDA attributes, x
- STA $2007
- INX
- CPX #$40
- BNE @loop
- RTS
+ReadJoy:
+ LDA #$01
+ STA JOY1 ; start reading
+ STA down@input
+ LSR a
+ STA JOY1
+@loop:
+ LDA JOY1
+ LSR a
+ ROL down@input
+ BCC @loop
-NMI: ;
+SaveJoy: ; [skip]
+ LDA down@input
+ CMP last@input
+ BEQ @done
+ STA last@input
+ CMP #$00
+ BEQ @done
+ STA next@input
+@done:
LDA #$00
- STA $2003 ; set the low byte (00) of the RAM address
+ STA SPRADDR ; set the low byte (00) of the RAM address
LDA #$02
STA $4014 ; set the high byte (02) of the RAM address, start the transfer
+
+RunTimer:
+ INC timer
+ ; check if timer has reached rate
+ LDA timer
+ CMP rate
+ BNE @done
+ LDA #$00
+ STA timer
+ INC position
+ ; check if position has reached 16
+ LDA position
+ CMP #$10
+ BNE @done
+ LDA #$00
+ STA position
+@done:
+
+Finish:
+ JSR Redraw
+@end:
+ LDA PPUSTATUS
+ LDA #$00 ; No background scrolling
+ STA PPUSCROLL
+ STA PPUSCROLL
RTI ; return from interrupt
;; Tables
.org $E000
-attributes: ;
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
- .db %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000
-
-palettes: ;
+Palettes: ;
.db $0F,$3B,$16,$30, $3B,$3B,$0F,$0F, $0F,$3B,$0F,$0F, $0F,$3B,$0F,$0F
.db $0F,$10,$17,$07, $0F,$3B,$0F,$0F, $0F,$0F,$0F,$0F, $0F,$0F,$0F,$0F
+TimelinePositions:
+ .db $08,$09,$0a,$0b,$0c,$0d,$0e,$0f,$10,$11,$12,$13,$14,$15,$16,$17
+
;; Vectors
.pad $FFFA