Skip to navigation

Main game loop: IRQHandler

Name: IRQHandler [Show more] Type: Subroutine Category: Main game loop Summary: The main interrupt handler, which gets run 50 times a second to update the game state and check for game key presses
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ConfigureMachine calls IRQHandler

This routine is called exactly 50 times a second, and it does the following: * Count down the sound timer * If a game is not in progress (i.e. we are in the title screen rather than playing a landscape), return from the handler * If the Sentinel has won and bit 7 of drawLandscape is set, then call DrawBlackDots to draw 80 random black dots for the game over screen, and return from the handler * If the game is paused, scan for the pause and volume keys and return from the handler * If a game is in progress and the Sentinel has not won and the game is not paused, then: * If scrollCounter is non-zero then call ScrollPlayerView (which decrements scrollCounter) and ShowIconBuffer * If the Sentinel has been activated, call UpdateEnemyTimers and UpdateScanner * If bit 7 of focusOnKeyAction is clear then the game is not currently focusing effort on implementing a key action such as a landscape pan, so scan for and process all the game keys
.irqh1 JMP (irq1Address) \ Jump to the original address from IRQ1V to pass \ control to the next interrupt handler .IRQHandler SEI \ Disable interrupts so the following process isn't \ interrupted by another interrupt LDA SHEILA+&6D \ Set A to the 6522 User VIA interrupt flag register IFR \ (SHEILA &6D) AND #%01000000 \ If bit 6 of the IFR is clear then this interrupt has BEQ irqh1 \ not been triggered by the 6522 User VIA timer 1 \ reaching zero, so jump to irqh1 to pass the interrupt \ on to the next interrupt handler \ If we get here then bit 6 of the IFR is set, so this \ interrupt has been triggered by the 6522 User VIA \ timer 1 reaching zero STA SHEILA+&6D \ The AND instruction above leaves A containing bit 6 \ set and all other bits clear, so we can write this to \ the IFR at SHEILA &6D to clear the timer 1 interrupt LDA &FC \ Set A to the interrupt accumulator save register, \ which restores A to the value it had on entering the \ interrupt PHA \ Store A, X and Y on the stack so we can preserve them TXA \ across calls to the interrupt handler PHA TYA PHA CLD \ Clear the D flag to switch arithmetic to normal, in \ case the interrupt was triggered during any BCD \ calculations DEC soundCounter \ Decrement the sound counter so we can detect when the BPL irqh2 \ current sound effect has finished, making sure it INC soundCounter \ doesn't go below zero .irqh2 LDA gameInProgress \ If bit 7 of gameInProgress is set then a game is not BMI irqh8 \ currently in progress and we are in the title and \ preview screens, so jump to irqh8 to skip the \ following and return from the interrupt handler \ without updating the game state LDA sentinelHasWon \ If bit 7 of sentinelHasWon is set then the Sentinel BMI irqh7 \ has won the game, so jump to irqh7 to draw black dots \ on the game over screen (when it is showing) LDA gamePaused \ If bit 7 of gamePaused is set then the game is paused, BMI irqh5 \ so jump to irqh5 to scan for the unpause and volume \ keys and return from the interrupt handler LDA scrollCounter \ If scrollCounter = 0 then we do not need to scroll the BEQ irqh3 \ player's landscape view, so jump to irqh3 to skip the \ scrolling process \ If we get here then we still have scrollCounter steps \ to complete in the current scrolling process, so we \ now do one scrolling step (ScrollPlayerView decrements \ the counter in scrollCounter) JSR ScrollPlayerView \ Scroll the screen and copy data from the view screen \ buffer into screen memory to implement the player's \ scrolling landscape view JSR ShowIconBuffer \ Display the contents of the icon screen buffer by \ copying it into screen memory, as the scrolling \ process will have scrolled this part of the screen, so \ we need to redraw it to prevent the energy icons and \ scanner from moving .irqh3 LDA activateSentinel \ If bit 7 of activateSentinel is set then the Sentinel BMI irqh4 \ has not yet been activated at the start of the game, \ so jump to irqh4 to skip the following JSR UpdateEnemyTimers \ Update the timers that control the enemy tactics JSR UpdateScanner \ Update the scanner, if required .irqh4 LDA focusOnKeyAction \ If bit 7 of focusOnKeyAction is set then the game is BMI irqh8 \ currently focusing effort on implementing a key action \ such as a landscape pan, so jump to irqh8 to skip the \ following keyboard scan JSR CheckForKeyPresses \ Check for various game key presses and update the key \ logger and relevant variables JMP irqh8 \ Jump to irqh8 to return from the interrupt handler .irqh5 \ If we get here then the game is paused, so we scan for \ key presses and discard them all except for the \ unpause and volume keys LDY #13 \ Scan the keyboard for all game keys in the gameKeys JSR ScanForGameKeys \ table except for the last one ("U" for U-turn) \ We now reset the first three entries in the key \ logger (i.e. entries 0 to 2), leaving the last entry \ populated (i.e. entry 3, which records the volume, \ pause and unpause key presses) LDX #2 \ Set a loop counter in X for resetting three entries LDA #%10000000 \ Set A = %10000000 to reset the three entries, as the \ set bit 7 indicates an empty entry in the logger .irqh6 STA keyLogger,X \ Reset the X-th entry in the key logger DEX \ Decrement the loop counter BPL irqh6 \ Loop back until we have reset all four entries JMP irqh8 \ Jump to irqh8 to return from the interrupt handler .irqh7 \ If we get here then the Sentinel has won the game, so \ we draw black dots on the game over screen (when it is \ showing) LDA drawLandscape \ If bit 7 of drawLandscape is clear, skip the following BPL irqh8 \ to return from the interrupt handler \ If bit 7 of drawLandscape is set then we are showing \ the game over screen, which combines dithering of an \ object to the screen while at the same time fading the \ screen to black, to create the hypnotic effect of the \ winning entity fading in and out of the screen as the \ game ends JSR DrawBlackDots \ Draw 80 randomly positioned dots on the screen in \ colour 1 (black) to fade the screen to black in a \ slowly decaying manner .irqh8 PLA \ Restore A, X and Y from the stack TAY PLA TAX PLA RTI \ Return from the interrupt handler