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 - Beginners question [C and SMSDevKit]

Reply to topic Goto page Previous  1, 2, 3
Author Message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Thu Jul 25, 2019 8:46 am
The VDP memory has to be accessed by sending data one byte at a time, mostly. Technically, this is because it is mapped to the Z80 as an IO device, not memory mapped, so you can't just "memcpy" the data to where you want it, and random access is much slower than sequential access.

To write two bytes to memory at location 0x1234 you have to write two bytes to set the write address and mode (using the upper bits of the two bytes to set the mode), followed by those 32 bytes. If the screen is on then you also have to do this slower than the Z80 is capable of because the screen rendering is competing for access to the RAM.

Doing this "raw" from C is probably possible but you don't have good control of the timing (although maybe the optimiser is never good enough to make it too fast...).

The answer is perhaps to make some custom assembly to deal with specific cases - for example, setting the tilemap in a 25 bytes column or a 32 bytes row, from a contiguous source buffer. You pay the cost to fill that buffer in C during the screen time and then do the fast "unsafe" load during the VBlank. Maybe this already exists?
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Thu Jul 25, 2019 12:43 pm
I see and understand :o

So using SMS_setTile for setting multiple values is acceptable?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Thu Jul 25, 2019 1:35 pm
I suspect it's not much slower than the assembly routine.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Aug 06, 2019 5:23 pm
I think you should first of all see how quick (slow) it is to update a column of tile using this:

- calculate address of first tile to set (XYtoADDR macro)
- while (column not complete)
--- SMS_setNextTileatAddr (address)
--- setTile (tile)
--- add 64 to your address and loop

(I would say approx 24*100 cycles)
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Thu Aug 22, 2019 6:41 pm
Thanks guys x3
I made some progress with the game and was actually able to create that flashlight effect ^o^
Wheeee! Thanks x3

I just wonder... how do I know, that I have enough RAM for my variables? :O And what will happend if I exceed the RAM limit? Will I overwrite old values?
  View user's profile Send private message
  • Joined: 08 Sep 2018
  • Posts: 270
Reply with quote
Post Posted: Thu Aug 22, 2019 8:05 pm
Jaberwocky wrote
Thanks guys x3
I made some progress with the game and was actually able to create that flashlight effect ^o^
Wheeee! Thanks x3

I just wonder... how do I know, that I have enough RAM for my variables? :O And what will happend if I exceed the RAM limit? Will I overwrite old values?


You'll know when you exceed the ram limit, It'll cause the program to crash or corrupt. Eventually you're going to hit the stack and corrupt it if you use too much ram. Luckily 8k is a lot for the type of computer the SMS is so odds are you will not break it even with a large amount variables.

Be mindful of your branching logic, number of consecutive conditional jumps, and any other recursive operations. Those can increase the stack and may cause the stack to grow to a point where it overwrites your variables.
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Tue Oct 01, 2019 7:48 pm
Hey °-°

been quite for a while because I was actually... kinda successfull all the time until now...

I'm playing around with the PSGlib, created a SFX and added it to my game, I also got the sound to play! Wheeee!

But.... I wanted to be smart and conect the PSGSFXFrame function to the line interrupt, so I did the following:
void processMusic()
{
   PSGSFXFrame();
   PSGFrame();

   SMS_disableLineInterrupt();
}

//In a setup function
SMS_setLineInterruptHandler(processMusic);

//In my gemeloop
update();
SMS_waitForVBlank();
SMS_enableLineInterrupt();
SMS_setLineCounter(90);
render();


When I run that code, then I will get graphic glitches or something... at least my map does not look correct anymore - therefore, the SFX plays correctly.

However when I remove the 'SMS_disableLineInterrupt();' the graphic glitches will stop but the music will play way to fast.... What shoud I do?
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Thu Oct 03, 2019 6:24 pm
Well... I decided to keep the Lineinterrupt enabled all time but playing the frame is now controlled by a flag, that will be cleared after the music played.

In my game loop I set that flag again. This actually works, but I realize that I gain nothing from it! By setting that flag again, I'm connected to my gameloop yet again, but I wanted to avoid that!

Is there really no way to use the playback functions in the interrupt routine? Will the interrupt also be triggered when the screen is turned off? (via the SMS)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Oct 07, 2019 9:56 am
what you probably missed is that the line IRQ handler gets called after the Nth line and then again after each N+1 lines from that point on, using
SMS_setLineCounter(N)

so if you set that N value to less than 96 you'll get the handler called at least twice.

also, if in your handler you call the
SMS_disableLineInterrupt();

and the IRQ happens while you're doing screen updates, you likely end up corrupting the screen so the easier approach is to use an higher N value, such as 100 or so, and don't disable the line IRQ in the handler.
  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14687
  • Location: London
Reply with quote
Post Posted: Mon Oct 07, 2019 2:56 pm
Also, if you disable line interrupts in the line interrupt, it's too late to cancel the next one. Overall, it's not a great idea to use line interrupts for anything other than raster effects anyway. Why not play music at the end of the frame interrupt?
  View user's profile Send private message Visit poster's website
  • Joined: 08 Sep 2018
  • Posts: 270
Reply with quote
Post Posted: Mon Oct 07, 2019 3:36 pm
Maxim wrote
Also, if you disable line interrupts in the line interrupt, it's too late to cancel the next one. Overall, it's not a great idea to use line interrupts for anything other than raster effects anyway. Why not play music at the end of the frame interrupt?


I was wondering that too. but didnt quite know where he was going with his program setup.

If you just play your music at the end of each frame interrupt then you shouldnt have a speed issue. I do that for my current project and everything plays perfectly but that project is written in ASM not in SEGA C... Either way it should provide the same result.
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Mon Oct 07, 2019 5:41 pm
Thank you guys for the answer! To explain myself...

I did this all like that for a simple reason: Because I'm dumb or not expierenced enough.

First of all, I didn't knew that there is a lineinterrupt and a frame interrupt! I looked at the SMSlib.h file and the only interrupt I found was the line interrupt, so I was sure, there is only one interrupt.
---

I then visited sverx GitHub site about the PSGlib and read:
Quote
Set up a steady interrupt (vertical blanking for instance) so to call PSGFrame and PSGSFXFrame at a constant pace (very important!)

For me only knowing the line interrupt, this was an "easy thing"!

I thought to, setup a line interrupt and do the music there. So I went to the wiki page of the DevkitSMS.
---

Where I read:
Quote
Nothing will anyway happen until you actually activate the VDP trigger using the macro:

SMS_enableLineInterrupt();

and you can of course deactivate the VDP trigger using the macro:

SMS_disableLineInterrupt();

which you may also want to call inside your own handler function, to avoid the repeated calls.


That was the reason why I placed the disableLineInterrupt in my Interrupt routine. I was also encouarged by that, because I looked into the mentioned example code. There I also picked up the value 90 for my line interrupt number.
---

So.... I did things I don't understand, I later read on a different website about the frame interrupt but was confused how to set it up with the DevkitSMS - because I still don't know how do to that, I kept using the Lineinterrupt... until now.

Now I simply know that it was wrong, but I still don't understand what use the line interrupt has and how to use the Frameinterrupt. Plus! I even start to doubt if using C for a SMS game was a good idea, because the SDCC compiler....freaks me out sometimes >_>

Edit:
I also keep getting the message
Quote
Failed sending email :: PHP ::

DEBUG MODE

Line : 234
File : emailer.php

When I post a new comment :<
  View user's profile Send private message
  • Joined: 08 Sep 2018
  • Posts: 270
Reply with quote
Post Posted: Mon Oct 07, 2019 10:21 pm
This may help you in the future though.
Line interrupt is set at the end of each scanline (H blank) while frame interrupt is set at the end of the entire frame (V blank). You may need to flag these instances and call their respective disable interrupt functions if you want to do some cool visual effects or the normal method of just updating the screen while the VBUS is available.

For your project you can ignore Line interrupt and not worry about it for the entirety of the project, but if you ever want to do things like lightgun games or have a parallax effect then you will need to study up on how to use line interrupt for that.

lastly be careful about your interrupt disable times. If it gets too long then youll get things like screen flickering or glitching display.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Oct 09, 2019 9:42 am
ahem, sorry if my wording got you confused. I probably need to rewrite some sentences to make them clearer.

What I meant is that you need to call the Frame functions once a frame and you usually do that somewhere in your code as in

your loop:
- do your game logic
- handle music (HERE!)
- waitForVBlank
- do what needs to be done during vblank (copy SAT, etc...)

you surely can use the line interrupt handler for music, eruiz's games do that for instance, but you have to ensure you're not touching the VDP registers at all in your handler, and the only easy way I'd use is to set a line counter value high enough so that line irq handler won't get called twice a frame
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Oct 09, 2019 9:45 am
IllusionOfMana wrote
Line interrupt is set at the end of each scanline (H blank) while frame interrupt is set at the end of the entire frame (V blank).


not exactly so. On SMS, line IRQ it's actually a line count IRQ so the interrupt happens after the Nth line and after each N+1 lines after that (so 0 means 'fire IRQ after every line', 1 means 'fire IRQ after every two lines' and so on...)
  View user's profile Send private message Visit poster's website
  • Joined: 08 Sep 2018
  • Posts: 270
Reply with quote
Post Posted: Wed Oct 09, 2019 3:30 pm
sverx wrote

not exactly so. On SMS, line IRQ it's actually a line count IRQ so the interrupt happens after the Nth line and after each N+1 lines after that (so 0 means 'fire IRQ after every line', 1 means 'fire IRQ after every two lines' and so on...)


Yes of course! excuse my bad or overly vague explanation lol.
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 49
Reply with quote
Post Posted: Wed Oct 09, 2019 3:59 pm
Thank you again! Slowly I start to understand! Wheee!

I would really love to use an Interrupt for the music, so I gonna try the LineInterrupt with a value higher then 100 now...

But one thing I still don't get - how do I setup a FrameInterrupt now? Or am I doing that with that specific LineInterrupt?

Also... How many lines do I actually have? 192? What happens if I set the line counter to a value higher then the Lines I actually have?
  View user's profile Send private message
  • Joined: 08 Sep 2018
  • Posts: 270
Reply with quote
Post Posted: Wed Oct 09, 2019 5:22 pm
Jaberwocky wrote
Thank you again! Slowly I start to understand! Wheee!

I would really love to use an Interrupt for the music, so I gonna try the LineInterrupt with a value higher then 100 now...

But one thing I still don't get - how do I setup a FrameInterrupt now? Or am I doing that with that specific LineInterrupt?

Also... How many lines do I actually have? 192? What happens if I set the line counter to a value higher then the Lines I actually have?


You should definitely read up as much as you can on using line interrupt since it isnt totally typical for what youre doing here (or i should say it makes what youre trying to do a tad hard)

In my opinion,in your loop after youve called your IRQVblank handler just call PSGFrame. This should fix any audio speed and render issues you might be having as well. At least, this is what I do with no issues... but once again thats in ASM, idk totally how it should behave in C but it shouldnt be different.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Oct 11, 2019 9:10 am
if you're using PSGlib from asm, you can call PSGFrame in your vblank handler - if you're using devkitSMS there's no user defined vblank handler, as the kit uses that for input reading and other stuff.

so with devkitSMS what I usually suggest is to have your music/SFX handled in the main loop, after SMS_waitForVBlank and the screen logic, such as the SAT copy, are performed

game loop:
- game logic
- wait VBlank
- screen logic (copy SAT, update tiles and so on)
- process music frame
  View user's profile Send private message Visit poster's website
  • Joined: 01 Jan 2014
  • Posts: 331
Reply with quote
Post Posted: Sun Oct 20, 2019 2:59 am
Had a few question, not so much beginners questions but didn't want to start a new thread.

- Has inline z80 been updated to support undocumented ix/iy instructions? Example being those related to 8 bit variations ixh, ixl, iyh, iyl?

- Is there support in the current tools for data to be aligned? If so does this include alignment in bank 0?

- Is bank switching supported for slot 1?
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Sun Oct 20, 2019 7:50 am
psidum wrote
Had a few question, not so much beginners questions but didn't want to start a new thread.

- Has inline z80 been updated to support undocumented ix/iy instructions? Example being those related to 8 bit variations ixh, ixl, iyh, iyl?

Not directly, but as sverx and Maxim have suggested you can define the opcodes like that:

#define LDIXHA   .dw #0x67DD
#define LDIXLA   .dw #0x6FDD
#define LDAIXH   .dw #0x7CDD
#define LDAIXL   .dw #0x7DDD
#define ORIXL   .dw #0xB5DD
#define LDIYHA   .dw #0x67FD
#define LDIYLA   .dw #0x6FFD
#define LDAIYH   .dw #0x7CFD
#define LDAIYL   .dw #0x7DFD
#define ORIYL   .dw #0xB5FD
#define LDDIYH   .dw #0x54FD
#define LDDIYL   .dw #0x55FD
#define LDEIYH   .dw #0x5CFD
#define LDEIYL   .dw #0x5DFD


And then you can use them as:

  ld a, (hl)
  inc hl
  LDIXLA
  View user's profile Send private message
  • Joined: 01 Jan 2014
  • Posts: 331
Reply with quote
Post Posted: Sun Oct 20, 2019 8:26 am
Thanks, didn't think of that when I wrote the question.

Calindro went through the assembler docs and found how to align data with the use of .bndry so that one is solved as well.
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Sun Oct 20, 2019 10:18 am
Do you have a link to the data align info?
  View user's profile Send private message
  • Joined: 14 Apr 2013
  • Posts: 623
Reply with quote
Post Posted: Sun Oct 20, 2019 10:24 am
kusfo wrote
Do you have a link to the data align info?

Here it is :) :
http://shop-pdp.net/ashtml/asxs02.htm#bndry
  View user's profile Send private message Visit poster's website
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Sun Oct 20, 2019 8:27 pm
Thanks!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3762
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Oct 21, 2019 7:25 am
and about bank-switching in slot 1, if you really need that, you could do something like this:

/* ROM bankswitching in slot 1 */
volatile __at (0xfffe) unsigned char ROM_bank_to_be_mapped_on_slot1;
#define SMS_mapROMBankSlot1(n)       ROM_bank_to_be_mapped_on_slot1=(n)


and simply use SMS_mapROMBankSlot1(bank-#-here) then.
  View user's profile Send private message Visit poster's website
Reply to topic Goto page Previous  1, 2, 3



Back to the top of this page

Back to SMS Power!