11 March 2016 - Forum Rules
Started by Gavzila, August 10, 2015, 07:47:25 PM
QuoteWhat I tried to do was create an IRQ at $20, then create a seperate IRQ at $C0, but that ended up making the screen blink back and forth every frame to each IRQ.
LDA $22 ;Checks if you're inCMP #$7 ;SkullMan's stage, and ifBNE RETURN ;you aren't, skip this routine.LDA $95AND #$1CLC ;I'm actually quite proud of this code... I made it myself. Code grows up so fast... *sniff*ROR A ;What I wanted to do was make a routine that activates each IRQ every other frame. Well,ROR A ;$95 is a Frame Counter built into MegaMan 4's engine. I had the idea of comparing the numbers in binaryROR A ;when I realized all ODD binary numbers ALWAYS end with 1. But... you can't JUST compare the last bit of each number...ROR A ; So what this code does, is it AND's $95 with #$1, which either makes the number "0000 0000" if even, ROR A ;or, "0000 0001" if odd. The CLC and all seven ROR A's are to shift the right most "0" or "1" to the left without carry, ROR A ;so it becomes #$80, if odd, or #$0, if even. It then branches to IRQ2 if it is an even frame.ROR A ;Cool isn't it?CMP #$80BNE IRQ2IRQ1: LDA #$1 ;Loads and stores #$1 into $F0, which STA $F0 ;controls the IRQ handler. LDA #$20 ;Loads and stores #$20 into $F1, which STA $F1 ;controls the Scan lines that are stored at $C000 and $C001. JMP $938D ;Return to normal routine.IRQ2: LDA #$2 ;Loads and stores #$2 into $F0, which STA $F0 ;controls the IRQ handler. LDA #$C0 ;Loads and stores #$C0 into $F1, which STA $F1 ;controls the Scan lines that are stored at $C000 and $C001RETURN: JMP $938D ;Return to the normal routine.
LDA $2002 ;Unlatches the VRam address at $2006LDA #$80 ;The next to commands loads #$80 into the accumulatorLDY #$22 ;and #$22 into Y that will be stored into $2006 for a VRAM address of $2080.STY $2006STA $2006LDA $FFSTA $2000LDA #$0 ;Because this is to control scan lines #$20 down, I'm loading #$0 into $2005 so that it doesn't scroll.STA $2005 ;I'll change it later after I get the effect working so that it slowly scrolls instead of just staying still.LDA $65STA $2005JMP $C30E ;Returns to the normal routine.
LDA $2002LDA #$0LDY #$23STY $2006STA $2006LDA $FFSTA $2000LDA $66 ;Code is almost identical to IRQ1, only that the VRAM address is $2300, and because I only want the scanlinesSTA $2005 ;between $20 and $C0 to be affected, this IRQ just makes the scanlines past $C0 to just scroll properly.LDA $65STA $2005JMP $C30E
v=.... ...x C=. <- start with thisv=x... .... C=. <- goal is thisv=.... ...x C=. <- startv=.... .... C=x <- ROR x1v=x... .... C=. <- ROR x2v=.x.. .... C=. <- ROR x3v=..x. .... C=. <- ROR x4v=...x .... C=. <- ROR x5v=.... x... C=. <- ROR x6v=.... .x.. C=. <- ROR x7
LDA $95 ; get frame counterAND #1 ; is it an odd frame?BNE IRQ2 ; if yes, branch to IRQ2
LDA $22 ;Checks if you're in CMP #$7 ;SkullMan's stage, and if BNE RETURN ;you aren't, skip this routine. LDA #1 STA $F0 LDA #$20 STA $F1 RETURN: JMP $938D ; why a jump instead of an RTS? Are you JMPing here only to JMP back to where you came from? ; If so, it's easier if you JSR here so you can just RTS back to where you came from.
; First IRQ handler:LDA $2002 ; probably not strictly necessary to do this, but it's a good idea. Kudos.LDA $FFAND #$FE ; turn off low bit to make sure the PPU scrolls uses $2000 NT and not the $2400 NTSTA $2000LDA #0STA $2005 ; kill horizontal scrollSTA $2005 ; vertical scroll doesn't really matter -- as that can't be changed mid-frame without $2006 writesLDA #2STA $F0 ; next IRQ to use handler 2LDA #$A0 ; set scanline counter to $A0, which is $C0-$20 .. because MMC3 is a "count down" counter, meaning we have to tell it howSTA $F1 ; many scanlines we want to wait... not which scanline we want to fire on.; Note that the $F0/$F1 writes here will only work if the IRQ code does the appropriate writes to $C000/1 $E000/1 before it RTI's; out of the interrupt. I'm going to assume the game does -- but if this doesn't work, then that's something to look at. If the; game doesn't do that, you'll have to do it manually here.JMP $C30E ; <- ...not RTS?
; 2nd IRQ handler:LDA $2002LDA $FFSTA $2000LDA $66STA $2005STA $2005JMP $C30E
QuoteI apologize if this reply got long and... "cringe" worthy with my notes. I tend to naturally explain things as if the people I'm talking to don't know what I'm talking about. So I apologize for that.
PHPPHATXAPHATYAPHASTA $E000STA $E001JMP ($009C)
LDA $2002LDA $FFAND #$FESTA $2000LDA #0STA $2005STA $2005$E000LDA #$A8STA $9CLDA #$C1STA $9DLDA #$A0STA $C000STA $C001JMP $C152
LDX $005DLDA $C318,XSTA $009CLDA $C324,XSTA $009D
LDA $2002LDA $FFSTA $2000LDA $66STA $2005STA $2005JMP $C30E
QuoteAs I said, Megaman 4 already has an IRQ handler, and it already includes the code that you posted dougeff. Here's what it looks like;
QuoteSO! I modified the first IRQ code to look like this;
QuoteI send it to the second "Entrance Point" of the IRQ handler, and activating our second IRQ code that Disch posted in his response before.
QuoteIt then jumps to $C30E where it disables the IRQ effect, pulls all the status from the stack, and returns from the interrupt.
Beginning of NMI: lda #$01 sta $e000 lda #$1f ;or $20, I think 1 fewer lines the first up better sta $c000 sta $c001 lda #$01 sta $e001blah, near end of NMI code...lda #$00sta $xx ;flag for which IRQ
IRQ:lda $xx ;flag for which IRQbne IRQ2 lda #$01 sta $e000 lda #$a0 sta $c000 sta $c001 lda #$01 sta $e001lda $2002 ;resets scroll latchthen lda x / sta new scroll to $2005inc $xx ;sets the flag to go to IRQ2 next break.
IRQ2:lda #$01sta $E000lda $2002 ;resets scroll latchthen lda x / sta new scroll to $2005
F:C0D4: STA $C000
1F:C0D7: STA $C001
1F:C0DC: STA $E000,X
>1F:C14F: STA $E000
1F:C152: STA $E001
1F:C177: STA $C000
1F:C17A: STA $C001
1F:C30E: STA $E000
C000 = 20 @ 246C001 @ 247E001 @ 247E000 @ 32E001 @ 32C000 = A0 @ 32C001 @ 32E001 @ 32E000 @ 32
QuoteAnd finally, at the end of our second IRQ code, we jump to $C30E which writes #$0 into $E000 at Scanline 32.
LDA $2002LDA $FFAND #$FESTA $2000LDA #0STA $2005STA $2005LDA #$A8STA $9CLDA #$C1STA $9DLDA #$9DSTA $C000STA $C001JMP $C120
Page created in 0.070 seconds with 20 queries.