News:

11 March 2016 - Forum Rules

Main Menu

Need help with color math~

Started by yugisokubodai, May 12, 2023, 11:58:33 PM

Previous topic - Next topic

yugisokubodai

兵法の勝ちを取りても
世の海を渡りかねたる
石の船かな

Everything

This is a really interesting project! I don't know what is causing this issue, but I have some troubleshooting ideas. Have you tried more than one SNES/SFC console? I think there were some minor revisions over the years. Can you also check if the issue persists on other CRT and non-CRT screens? It would be helpful to narrow down whether it is a problem with the CRT or with the console.

Are you using HDMA to set the color math register? If so, you might try using a different DMA channel. I have heard that there are some slight differences between channels on some revisions of the SNES.

Do you read the TIMEUP register ($4211) at the beginning of every IRQ? I think this is necessary so that the next IRQ will fire at the right time. Then I think you need to set VTIMEL ($4209) to the next IRQ scanline. Are you using one IRQ per scanline? Or is it one IRQ at the top of the window and one more at the bottom of the window?

yugisokubodai

I tested the game on all of my Sony PVMs, and all of my 10 SFC consoles, and the result is the same. I think the problem is not in the CRT.
I also tested on the Supaboy SFC, which is a Super Famicom clone. The result is the same.
I don't know why this happens, but all emulators don't have this problem. Also, the Super NT (the FPGA one) also doesn't give this problem.

Btw, the FPGA is less accurate than the Supaboy SFC.

兵法の勝ちを取りても
世の海を渡りかねたる
石の船かな

Everything

Wow, you are very thorough! I agree it sounds like it is not a CRT problem. Do you mind sharing your IRQ handler code?

JP32

I remember having same problem with my SMW hack's HDMA effects, on console theres blinking light, it didn't appear on any emulators. I have two snes'es, one chip and two chip variations, both PAL with one 60hz modded and another one with the SuperCIC mod and they both has same issues IIRC.

But unfortunately I never figured out what caused it or how to fix it  :-\ .

yugisokubodai

Here is my irq routine.

fast_irq:
   PHA
   PHX
   PHY
   PHD
   PHB
   SEP #$30
   LDA #$00
   PHA
   PLB
   LDA {box_irq_trigger}
   CMP #$FF
   BNE +
   JSR frame_color_setting
   LDA $2137
   LDA $213F
   LDA $213D
   STA {scanline_vpos}
   LDA $213D
   STA {scanline_vpos}+1
   REP #$20
   LDA {scanline_vpos}
   AND #$01FF
   CMP {irq_low}
   BCS clear_irq
   SEP #$20
   BRL end_irq
   
clear_irq:
   SEP #$20
   LDA $4211
   LDA #$00
   STA $2124
   STA $2125
   STA $2123
   LDA #$82
   STA $2130
   LDA #$72
   STA $2131
   LDA #$20
   STA $2132
   LDA #$40
   STA $2132
   LDA #$80
   STA $2132
   LDA #$16
   STA $212C
   LDA #$01
   STA $212D
   BRL end_irq
   
+
   LDA $012A
   BNE _831F
   LDA $4211
   BPL end_irq
   LDA $0128
   BEQ end_irq
-
   BIT $4212
   BVC -
   LDA $0630
   STA $2111      //BG3 hscroll
   LDA $0631
   STA $2111
   STZ $2112
   STZ $2112
   LDA $0128
   BPL end_irq
   STZ $0128
   LDA #$81
   STA $4200
end_irq:
   REP #$30
   PLB
   PLD
   PLY
   PLX
   PLA
   RTI
兵法の勝ちを取りても
世の海を渡りかねたる
石の船かな

Everything

Here are a couple of ideas, just comparing your code to IRQ handlers in a couple of other commercial games. I don't have real hardware to test on so I'm not sure if any of these will solve the problem but maybe something here will help. I don't understand your code completely, so I apologize if I'm on the wrong track.

Try moving LDA $4211 from clear_irq to just before the line JSR frame_color_setting. It seems like it's good to reset the IRQ timer as early as possible in the IRQ handler.

Just before LDA $2137 (or maybe before JSR frame_color_setting), try waiting for hblank by inserting
-   BIT $4212
    BVC -
I think this ensures that you're not modifying any hardware registers mid-scanline. Based on comments in the Zelda 3 source code, it looks like it might also avoid conflicts with HDMA.

You may want to try a different approach where you set $4209 during each IRQ to set the scanline when the next IRQ takes place. In this way you can trigger several IRQs per frame at specific scanlines and modify the color window settings appropriately during each one. Inside your IRQ handler you can read $213D to determine which scanline you are currently at.

yugisokubodai

Quote from: Everything on May 23, 2023, 03:10:07 PMHere are a couple of ideas, just comparing your code to IRQ handlers in a couple of other commercial games. I don't have real hardware to test on so I'm not sure if any of these will solve the problem but maybe something here will help. I don't understand your code completely, so I apologize if I'm on the wrong track.

Try moving LDA $4211 from clear_irq to just before the line JSR frame_color_setting. It seems like it's good to reset the IRQ timer as early as possible in the IRQ handler.

Just before LDA $2137 (or maybe before JSR frame_color_setting), try waiting for hblank by inserting
-   BIT $4212
    BVC -
I think this ensures that you're not modifying any hardware registers mid-scanline. Based on comments in the Zelda 3 source code, it looks like it might also avoid conflicts with HDMA.

You may want to try a different approach where you set $4209 during each IRQ to set the scanline when the next IRQ takes place. In this way you can trigger several IRQs per frame at specific scanlines and modify the color window settings appropriately during each one. Inside your IRQ handler you can read $213D to determine which scanline you are currently at.

Thank you very much for your words of wisdom  :thumbsup:
I tried the first solution and everything is OK now. I thought I must keep the irq happens until it reachs the lower scanline of the text box, but I was wrong.
兵法の勝ちを取りても
世の海を渡りかねたる
石の船かな