Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - Pushing the VDP to do things during the hblank, but using C?

Reply to topic
Author Message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Pushing the VDP to do things during the hblank, but using C?
Post Posted: Tue Dec 12, 2023 12:25 am
I'm just playing around with ideas, and found from reading it's possible to have the SMS display 64 colours at once, with the caveat of colours changing during an h-blank (which is itself a very vague and time sensitive period). I'm using devkitSMS' SMS_setLineInterruptHandler() but I suspect that because C the compiled code is probably not fast/sensitive enough to do things with the palette during the variable hblank.

This seems to be related to https://www.smspower.org/forums/19058-WhenDoesAnHBlankStart where the dots are part of what the CRAM is doing.

From reading, h scrolling seems very consistent because it's latched, but palette changes are highly variable. Like this is fine for hscrolling offset stuff:

SMS_setLineInterruptHandler(&scrollInterruptHandler);
SMS_setLineCounter(24); // Every 25 scanlines
SMS_enableLineInterrupt();


I'm thinking if I wanted to pursue things like mid-screen palette changes I'd have to write this part in assembly for speed. I'm a little less confident in the code from that linked thread, in the sense of how I'd integrate it back into C given I'm not writing everything in asm. I've got some other parts in assembly so it's not a problem of assembly per se, more of how to do fancier things like hooking interrupts in asm, within the context of C doing things like calling wait for Vblank, updating the PSG audio frame etc.

At the very least I could always mix background tiles varying which tile + sprite palettes to get 32 colours, although it'd probably be a case of designing the art very carefully so that it wasn't trying to use a different palette every other tile... hmm.

Anyway, I'm not super worried if it's hard or nigh-impossible to do, this is more of an intellectual exercise. Would anyone have any tips or examples for handling very frequent hblanks or ways to handle palette changes during an hblank avoiding CRAM garbage with a mix of C and asm? Or am I chasing an impossible dream?
pixel-garbage.png (19.42 KB)
pixel-garbage.png

  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 886
  • Location: Spain
Reply with quote
Post Posted: Tue Dec 12, 2023 7:07 am
You can have a look at what I did to encapsulate Maxim's sample library in a C wrapper here:
https://github.com/kusfo/sms-fxsample/blob/master/fxsample.c

You can do the same for the hblank handler
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14745
  • Location: London
Reply with quote
Post Posted: Tue Dec 12, 2023 10:02 am
The hblank fires “early” such that by the time your code runs, it’s in the active display; games therefore waste cycles to push the CRAM dots into the border/hblank proper. However, this means that you can only really change a few colours per scanline. I’m not sure how easy it is to do small cycle-counted delays in C, I guess you can inline asm some nops or maybe the optimiser is bad enough that you can use junk code to slow it down.

Another approach (taken by Sonic the Hedgehog) is to draw noisy flashing sprites in the area where the CRAM dots will be and hope nobody notices. That way you can change more.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 12, 2023 10:21 am
darkowl wrote
Anyway, I'm not super worried if it's hard or nigh-impossible to do, this is more of an intellectual exercise. Would anyone have any tips or examples for handling very frequent hblanks or ways to handle palette changes during an hblank avoiding CRAM garbage with a mix of C and asm? Or am I chasing an impossible dream?


It depends. Writing to CRAM will always cause those dots to appear on screen, the best you can do is to try to push them as close as possible to a screen edge and hope the TV cuts them out.
But if you want to update more than one palette entry, you probably need to make sure that only one entry gets updated each line, which is not easy to do but it's possible, given that it's possible to -more or less- precisely time an hblank interrupt. Then it's all about updating one entry and waste exactly enough cycles to get to the next update at the correct time, in a loop.

This isn't something impossible to do with C, but it needs some trial and error. A few cycles delay could be added wherever you need using a bit of inline asm code such as

__asm
  nop   ; each NOP takes 4 cycles, place how many NOPs as you need here
__endasm;
  View user's profile Send private message Visit poster's website
  • Joined: 06 Mar 2022
  • Posts: 671
  • Location: London, UK
Reply with quote
Post Posted: Tue Dec 12, 2023 10:25 am
darkowl wrote
I'm using devkitSMS' SMS_setLineInterruptHandler() but I suspect that because C the compiled code is probably not fast/sensitive enough to do things with the palette during the variable hblank.


It's not so much a question of compiled C not being generally fast enough, since we're compiling down to bare metal, not through any kind of OS layer, and most of the time critical functions in devkitsms are written in assembler anyway; so really it's just a question of what devkitsms's builtin interrupt handler happens to be doing.

And that's pretty easy to see by looking at the code, here:
https://github.com/sverx/devkitSMS/blob/b34cfb83907509d7351cd1f37d17941998041083/SMSlib/src/SMSlib.c#L375

So if you count the instructions you can figure out when your horizontal scanline handler will actually be called, to a high degree of confidence.

If it's not quick enough you might have to override the root ISR somehow.
Note that `SMS_isr` is called directly from a `jp` at $0038, here.
  View user's profile Send private message Visit poster's website
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Tue Dec 12, 2023 12:25 pm
Aha, interesting. Thanks for the replies, it's given me some stuff to look into. Appreciate it! I'll see how things go.
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Thu Dec 14, 2023 7:02 am
Currently, I have a platforming engine running with line handler based effects (like 4 rows header, parallax scrolling o palette changes to simulate underwater color changes) working without issues.

... but it is not easy, you have to calibrate all the functions to avoid clashes between the frame/line handlers and the vram updates (tile/tilemap updates, by example).

The color changes (inside screen) generate that weird cram color pixel effects, yeah.
  View user's profile Send private message
Reply to topic



Back to the top of this page

Back to SMS Power!