;;;; ; Create an iNES header .ines {"prog": 1, "char": 0, "mapper": 0, "mirror": 0} ;;;; ; Include all the symbols in the nes library .inc ;;;; ; Open the prog section bank 0 .segment prog 0 ;;;; ; Structure to keep track of input .org $0000 .scope controller_state .space b 1 .space a 1 . ;;;; ; Setup the interrupt vectors .org $FFFA .dw vblank .dw reset .dw irq ;;;; ; Here is our code entry point .org $C000 .scope reset sei ; SEt Interrupt (Disables them) cld ; CLear Decimal Mode ldx #$ff txs ; Set the stack pointer ldx #$00 stx nes.ppu.control stx nes.ppu.mask ; Disable Vblank & Rendering jsr zero_apu ; Zero all APU registers ; We need to wait for at least 2 Vblanks to happen ; before we know the PPU has stabilized at startup ; Here we wait for the first one. wait_vblank1: bit nes.ppu.status bpl wait_vblank1 ; Before we wait for the second vblank, lets ; zero all of the working RAM $0 to $800 ; The $200s are sprite OAM, and should be set to $ff clear_ram: lda #$00 sta $00, x sta $100, x sta $300, x sta $400, x sta $500, x sta $600, x sta $700, x lda #$ff sta $200, x inx bne clear_ram ; Now wait for the second vblank wait_vblank2: bit nes.ppu.status bpl wait_vblank2 jsr initialize forever: jmp forever rti . ;;;; ; Initialize everything .scope initialize ; Enable pulse1 and pulse2 in the APU lda #%00000011 sta nes.apu.channel_enable ; Initialize the controller states lda #$00 sta controller_state.a zp sta controller_state.b zp ; Reenable interrupts, Turn Vblank back on lda #%10000000 sta nes.ppu.control cli rts . ;;;; ; VBlank is called 60 times per second .scope vblank jsr read_input rti . ;;;; ; IRQ, we are not using .scope irq rti . ;;;; ; Zero all the APU registers .scope zero_apu lda #$00 ldx #$00 loop: sta $4000, x inx cpx $18 bne loop rts . ;;;; ; Read input from controller 1 .scope read_input lda #$01 ; strobe joypad sta nes.controller1 lda #$00 sta nes.controller1 ; Handle Button A lda nes.controller1 and #$01 beq update_a_state ; A is pressed, but did it just change to being pressed now? ldx controller_state.a zp bne update_a_state ; do the thing A does jsr play_e329 update_a_state: sta controller_state.a zp ; Handle Button B lda nes.controller1 and #$01 beq update_b_state ; B is pressed, but did it just change to being pressed now? ldx controller_state.b zp bne update_b_state ; Do the thing B does jsr play_a220 update_b_state: sta controller_state.b zp rts . ;;;; ;; This will play an A 220hz note ;; On the pulse1 generator .scope play_a220 pha lda #%10011111 sta nes.apu.pulse1.control lda #%11111011 sta nes.apu.pulse1.ft lda #%11111001 sta nes.apu.pulse1.ct pla rts . ;;;; ;; This will play an E 329.63hz note ;; On the pulse2 generator .scope play_e329 pha lda #%10011111 sta nes.apu.pulse2.control lda #%01010010 sta nes.apu.pulse2.ft lda #%11111001 sta nes.apu.pulse2.ct pla rts .