SEG zeropageSegment ; Interrupt counter counter DS 2 SEG programSegment ; this is the entry point of the program and must stay at this address org $2800 start: ; Clear screen, initialize keyboard, restore interrupts jsr $ff81 ; Disable all interrupts sei ; Turn off CIA interrupts and (possibly) flush the pending queue ldy #$7f sty $dc0d sty $dd0d lda $dc0d lda $dd0d ; Set Interrupt Request Mask as we want IRQ by raster beam lda #$1 sta $d01a ; Store in $314 address of our custom interrupt handler ldx #irq ; most significant byte stx $314 sty $315 ; Set raster beam to trigger interrupt at row zero lda #$00 sta $d012 ; Bit#0 of $d011 is used as bit#9 of $d012, and must be zero lda $d011 and #$7f sta $d011 ; Initialize player for first song lda #0 jsr sidtune ; Initialize MultiColor mode jsr multicolorInit ; Zero-fill zeropage variables lda #$0 ldx #$90 zeroFillZeroPage: dex sta $0,x cpx #$2 bne zeroFillZeroPage ; Set status as first-time intro playing lda #ST_INTRO0 sta status ; Reset screen (and other parameters) to play intro jsr introreset ; Enable interrupts cli menu SUBROUTINE .menu: ; Cycle here until SPACE or `Q` is pressed jsr $ffe4 ; GETIN cmp #$20 ; Is it SPACE? beq .intro0end ; if yes, go to intro0end and start game (see) #if DEBUG = 1 cmp #$41 ; Is it A? beq .printCounter ; if yes, print current counter #endif cmp #$51 ; Is it Q? bne .menu ; If not, keep looping here, jmp $fce2 ; else, reset the computer #if DEBUG = 1 .printCounter lda counter + 1 ldy #2 jsr printByte lda counter ldy #4 jsr printByte jmp .menu #endif ; Intro is finished, now it's time to start the proper game .intro0end: ; Are you sure? Maybe the demo-intro is not finished, yet ; We do not want to actually start unless the demo is finished, ; otherwise vertical raster line offset may be != 0 lda status cmp #ST_MENU bne .menu ; Set current level pointer to list start lda #levelsList sta levelPointer + 1 ; clear score lda #$00 sta score sta score + 1 ; Set init variables of the level jsr levelresetvar ; Set status as level select ; (then it will enter in status play) lda #ST_LEVEL_TITLE sta status .endless: ; Loop waiting for gameover lda status cmp #ST_END ; is status equal to end ? bne .endless ; if not, just wait looping here, else... jsr clearScreen lda #ST_MENURESET sta status ; put machine into menu status jmp .menu ; and go there waiting for keypress ; Main Raster Interrupt Handler ; ---------------------------------------------------------------------- irq SUBROUTINE ; Things that must be done every interrupt (50Hz) ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Acknoweledge IRQ dec $d019 ; Save registers in stack pha txa pha tya pha #if DEBUG = 1 ; Change background to show how much time does music take for each interrupt lda #1 sta $d020 #endif ; Play music first -> no audio skew if computations are slow jsr sidtune + 3 #if DEBUG = 1 ; Change background to visually see the ISR timing lda #2 sta $d020 #endif inc counter bne .noIncCounter inc counter + 1 .noIncCounter ; Check status and call appropriate sub-routine ; Sort of switch-case lda status checkStatusIntro0: cmp #ST_INTRO0 bne checkStatusIntro1 jsr statusIntro0 jmp checkEndStatus checkStatusIntro1: cmp #ST_INTRO1 bne checkStatusIntro2 jsr statusIntro1 jmp checkEndStatus checkStatusIntro2: cmp #ST_INTRO2 bne checkStatusIntro3 jsr statusIntro2 jmp checkEndStatus checkStatusIntro3: cmp #ST_INTRO3 bne checkStatusIntro4 jsr statusIntro3 jmp checkEndStatus checkStatusIntro4: cmp #ST_INTRO4 bne checkStatusIntro5 jsr statusIntro4 jmp checkEndStatus checkStatusIntro5: cmp #ST_INTRO5 bne checkStatusIntro6 jsr statusIntro5 jmp checkEndStatus checkStatusIntro6: cmp #ST_INTRO6 bne checkStatusIntro7 jsr statusIntro6 jmp checkEndStatus checkStatusIntro7: cmp #ST_INTRO7 bne checkStatusIntro8 jsr statusIntro7 jmp checkEndStatus checkStatusIntro8: cmp #ST_INTRO8 bne checkStatusMenuReset jsr statusIntro8 jmp checkEndStatus checkStatusMenuReset: cmp #ST_MENURESET bne checkStatusMenu jsr statusMenuReset jmp checkEndStatus checkStatusMenu: cmp #ST_MENU bne checkStatusPlay jsr statusMenu jmp checkEndStatus checkStatusPlay: cmp #ST_PLAY bne checkStatusDelay jsr statusPlay jmp checkEndStatus checkStatusDelay: cmp #ST_DELAY bne checkStatusLevelTitle jsr statusDelay jmp checkEndStatus checkStatusLevelTitle: cmp #ST_LEVEL_TITLE bne checkStatusLevelLoad jsr statusLevelTitle jmp checkEndStatus checkStatusLevelLoad: cmp #ST_LEVEL_LOAD bne checkEndStatus jsr statusLevelLoad jmp checkEndStatus checkEndStatus: ; Increase random value inc random #if DEBUG = 1 ; Change background back again to visally see ISR timing lda #11 sta $d020 #endif ; Restore registers from stack pla tay pla tax pla ; Go to original system routine jmp $ea31