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 - Getting started with SMS development in C

Reply to topic
Author Message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Getting started with SMS development in C
Post Posted: Sun Dec 12, 2021 12:55 pm
Hi, so, first post here. Nice to meet you.

I'm not naturally a C or asm programmer, but I once dabbled with C++ and x86 asm back in the 90s. My current work is in JS/TS, and I figured I'd like to challenge myself with some retro coding. When I was young I used to go to a friend's place and we played with their Master System 2. Good times.

I'm bumbling my way through a number of tutorials, but it's... not going great! Mainly because - whilst they're well written for the time - the examples no longer play nicely with updates to core projects since, or they only focus on assembly code. I'd also like to start with current tooling rather than old stuff.

What I'm trying to achieve
* Have some vaguely sensible folder structure and build process for assets and the ROM itself
* Draw a (background) picture to the screen
* Be able to use remote C debugging with Emulicious in VScode

Nothing too outlandish. But uh... yeah. It's not going well!

My code fumblings are up at:
github /mikehdt/sms-demo (I can't post links due to spammers and being recently registered, apologies)

I've been borrowing some ideas of other example code I could find that I liked. I've no doubt made some fundamental mishaps. Let's take it from the top.

First off, I've put the companion apps (SDCC, Emulicious etc.) in a folder called apps in the same parent folder as the project. Makes it tidy for referencing external tools.

The build process I think I've sort of got it to work. It's not ideal (VS Code's documentation on setting up tasks is surprisingly fragmented). Some of the things I've encountered may also just be limitations of the tools, which I'm mindful are written in people's spare time for the benefit of the community.

I'm using github /sverx/devkitSMS as a basis, and have set it up as per its documentation... I think, anyway. Files that are part of the project I put in some folders to keep them tidy.

Assets
I don't think I've gotten the assets in correctly. I've set up a task in VSC for this with a batch file.

* assets2banks seems to have a limitation that it won't grab assets from sub-folders. I've worked around this by having the assets script push the results back into the parent. Be nice if it did have some way to handle this, ah well. Just have to make sure all asset names are unique.
* From what I can tell, these compiled assets are loaded into (at present) bank 2. How that scales with bank switching is a bridge I'll cross later.
* I don't think I'm correctly loading the bank in. I figured I had to use SMS_mapROMBank(2) not really sure. The docs were a bit tricky to follow here (I'm also still poking my way around the SMS architecture setup)
* I don't see any assets in the tile viewer in Emulicious, just a few garbled things, so I assume I've not gotten this part right

Compiling
There's a second task in VScode that I've set up that runs the compile batch file.

* I think I got things to compile; at least it doesn't freak out
* A few examples include -exit on the end, but that seems to crash out SDCC?
* There's a lot of conflicting historical information on what the right flags are to use. I'm not sure if what I've put is right.

Debugging
* I can connect Emulicious to VScode's Emulicious debugger extension which is a positive step
* I'm assuming that the --debug flag is supposed to make the hooks for the C code? It does generate a cdb file, which the extension docs state is needed
* However, it doesn't map back to the C code. It shows the assembly code only. I don't know if I've missed a setting? The extension readme provides no guidance, just states that this is possible

Right now, I can load the ROM, but nothing happens. At least it doesn't crash the emulator so that's a positive, hey? If anyone has time to provide a few pointers on where I've inevitably gone wrong, I'd greatly appreciate it. Thanks :)
  View user's profile Send private message
  • Joined: 14 Apr 2013
  • Posts: 623
Reply with quote
Post Posted: Sun Dec 12, 2021 1:20 pm
darkowl wrote
Debugging
* I can connect Emulicious to VScode's Emulicious debugger extension which is a positive step
* I'm assuming that the --debug flag is supposed to make the hooks for the C code? It does generate a cdb file, which the extension docs state is needed
* However, it doesn't map back to the C code. It shows the assembly code only. I don't know if I've missed a setting? The extension readme provides no guidance, just states that this is possible

You need to pass the --debug flag to all calls of sdcc. So also on your call in line 12: https://github.com/mikehdt/sms-demo/blob/main/scripts/build.bat#L12

Edit: I also just took a look at the generated code to see what is going wrong. It seems like the generated code is not compatible to devkitSMS. What version of SDCC do you use?
  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 Dec 12, 2021 2:52 pm
If you need some example code, take a look at my game Gotris repository:

https://gitlab.com/1985Alternativo/gotris

Not everything is pretty (It took some years, and tools evolved), but I think it can help you to solve some problems.
  View user's profile Send private message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Sun Dec 12, 2021 11:02 pm
Last edited by darkowl on Sun Dec 12, 2021 11:20 pm; edited 2 times in total
Calindro wrote
Edit: I also just took a look at the generated code to see what is going wrong. It seems like the generated code is not compatible to devkitSMS. What version of SDCC do you use?


Hey, thanks for your reply. Hmm, interesting; I followed the devkitSMS Readme and installed the latest version of SDCC, which currently is 4.1.0. I then had a look at the current snapshot, which is 4.1.12 (and probably some builds in between). I can try going back to 4.1.0.

Edit: Okay so SDCC 4.1.0 lets me accidentally turn the SEGA logo red... but still no luck with having the C code work yet (maybe because of the generated code you mentioned?)

A lot of the really well maintained examples I found were build with 3.x, and it seems it changed a bit?

For example, CandyKid 3.0 is really well structured, but it seems that they have their own bank-switching setup, whereas the current suggestion seems to be "let assets2banks figure it out for you".

Thanks for the suggestion, I'll give it a crack and see what happens. I'm a very visual learner, and once I can get something up, it should be much easier to muck about from there :D
  View user's profile Send private message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Sun Dec 12, 2021 11:06 pm
kusfo wrote
If you need some example code, take a look at my game Gotris repository:


Ah great, I'll have a squizz. It's a bit tricky trying to figure out what compiler I should use (there seems to be three main ones I've seen used; SDCC, z88dk and WLA-DX), although only SDCC is listed as compatible with the VScode Emulicious extension for C debugging, which I feel would be very helpful in me making a mess of code :D

Thanks!

Edit: Okay, so I had a look - I can't seem to get SDCC to generate quite the same code, but I can say that the compiled version in the repository does have C code debugging that works a treat which is exciting!

After installing make and fixing a few batch file things to match my environment, when I try compiling gotris I see this:


sdcc -c --debug -c -mz80 --peep-file peep-rules.txt -DPAL_MACHINE src/resources/resources.c
src/resources/resources.c:706: warning 196: pointer target lost const qualifier
src/resources/resources.c:710: warning 196: pointer target lost const qualifier


Hmm. Interesting... I did note that it seems you compiled it most recently with a snapshot of SDCC (~4.1.2)?

I did a bit more poking and found that running clean.bat on Windows makes for some sadness; I fixed it with a solution borrowed from Stack Overflow, adding the following to the top of the file as rm etc. don't exist under Windows (not normally, anyway, although you could probably mess with WSL):


ifeq ($(OS),Windows_NT)
RM = del /Q /F
CP = copy /Y
ifdef ComSpec
SHELL := $(ComSpec)
endif
ifdef COMSPEC
SHELL := $(COMSPEC)
endif
else
RM = rm -rf
CP = cp -f
endif


Then clean.bat also cleans the crt0_sms.rel file as a result of make clean, which makes the compiling unhappy. More fun! Discarding the deletion in git undoes that at least.

Then re-running compileexportgraphics.bat seems to be happy.

Okay, I got it to finally compile! Also I would note that the current SDCC snapshot (~4.1.12) breaks compilation entirely, at least from my naive view (Apparently 4.1.12 uses a new function call method?). I reinstalled 4.1.0, and then... it worked! Complete with C debugging in VSC. Nice!

I'll do a bit more poking around, see what I can figure...
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Mon Dec 13, 2021 8:47 am
I'm glad you found it useful!
I didn't have your first problem with clean.bat as I'm using PowerShell, so rm command exists there (I never use vanilla cmd for anything).

But there's some inconveniences with the crt0_sms.rel file...but as I only do a clean every now and then, I haven't fixed it yet.

ABout the SDCC versions, Calindro told me there's some breaking change, I've to check which version I'm using (as I've several SDCC's and I point to them by environment variables).
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3759
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Dec 13, 2021 10:56 am
SDCC is changing its calling conventions but I'm not quite sure which version is the first that introduces the new standard.

if you want to make sure compile using this command line switch:

–sdcccall 0


so that it will use the 'legacy' calling convention.

In the next months (hopefully) I'll see if I can switch the libraries code to use the newer calling conventions.

edit: please let me know if you're using SDCC 4.1.0 if that command line switch is accepted.
  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: Mon Dec 13, 2021 12:38 pm
sverx wrote
edit: please let me know if you're using SDCC 4.1.0 if that command line switch is accepted.


Sure, I can confirm that 4.1.0 - the current stable release - works just fine as-is today. My issue in the original post was most likely of my own doing.

I believe it's snapshots at 4.1.12, which introduced the switch. You'd think that as a breaking change it should really be 5.0.0 and not a patch release... (even if it is a dev snapshot). Heh ;) I'm not game enough to try that flag, as 4.1.0 is working right now.

Poked around the Gotris code tonight, and tried to apply its wisdom to my code. I can now get the debugger matching against the C code! Magic. Although I haven't figured out how to get C variables to show up in the Locals, as shown in the extension's page...

Did notice that bmp2tile in Gotris is an older version which exports tilemaps in strcompr format, which seems to have been removed from the most recent release. I used a bin file instead, seems to be okay (albeit I guess a touch larger?).

Now, to figure out how to draw the picture...
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14685
  • Location: London
Reply with quote
Post Posted: Mon Dec 13, 2021 1:30 pm
Bmp2tile doesn’t ship with the stmcompr plugin. Maybe I should ask the author…
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3759
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Mon Dec 13, 2021 2:26 pm
darkowl wrote
I believe it's snapshots at 4.1.12, which introduced the switch.


Correct, I just found this.
Quote
[...] the default since the 25th of September, and thus should be the default in snapshots since the 26th of September: [r12692]. At the same time, the SDCC version was increased from 4.1.11 to 4.1.12.


@Maxim sure you can ship stmcompr plugin with BMP2Tile :)
  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 14, 2021 6:46 am
sverx wrote
if you want to make sure compile using this command line switch:

–sdcccall 0



Okay, so I just decided to test a SDCC 4.1.12 snapshot, with the CLI switch to tell it to not use the breaking change, and it works!

Also, I finally managed to get a picture drawn to the screen! Woohoo! It fills the remainder of the screen with tile 0, but I'm okay with that.

I'll keep tidying it up, but hey - it's nice to see something working properly finally! Thanks to all above for your help, it's super appreciated.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3759
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Dec 14, 2021 12:56 pm
darkowl wrote
Okay, so I just decided to test a SDCC 4.1.12 snapshot, with the CLI switch to tell it to not use the breaking change, and it works!


Good, thanks for the heads up (I still can't run that on my Linux machine)

Also, the fact that you see tile number zero appear everywhere you didn't update the tilemap yourself is a side effect of the fact that emulators (usually) reset VRAM contents. On the real hardware you'll probably get some garbled graphics there so usually a whole tilemap rewrite is needed before turning on the screen.
  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: Mon Dec 20, 2021 8:15 am
So I've been playing around with a few ideas, and I've found something that... I'm not sure how to do.

Is there a way to set the background tile priority flag with SMSlib?

In reading the C header file, there's TILE_PRIORITY as a constant, however there doesn't seem to be any functions that make use of this property (nor the flip bits or sprite palette toggle either)?

Have I missed something really obvious?
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Mon Dec 20, 2021 8:20 am
This is usually in the tilemap data. If you want to change the priority programmatically, you can read the value from the VRAM, and perform a bitwise OR with the TILE_PRIORITY flag, and write it back.
  View user's profile Send private message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Mon Dec 20, 2021 8:57 am
kusfo wrote
This is usually in the tilemap data.


Aha... now that you mention it, it makes a lot more sense. I'll see what I can poke around. Thanks!
  View user's profile Send private message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Tue Dec 21, 2021 12:04 pm
Hmm... okay, so I'm still a bit confused by how SMSlib manipulates the tilemap.

There's a lot of helpful functions for dropping tiles onto the tilemap, but it seems like changing the tilemap directly is harder?

So for example if I wanted to fill the background with a single tile but set it to use the sprite palette instead of the background palette, then I can't use the straightforward SMS_setTile() to set the tile, because it doesn't have any way to also update the tilemap with any properties you might want.

It seems like you have to then instead call something like SMS_VRAMmemcpy() with XYtoADDR()? Or maybe a bitmask with SMS_setTileatXY()?

Again I might be missing something really obvious, but it seems that it's really obvious how to display tiles around the place using SMSlib, but it's a bit less obvious on how to change the properties of those tiles in the associated tilemap.
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Tue Dec 21, 2021 1:23 pm
You can do something like
SMS_setTile(tilenumber|TILE_PRIORITY)
.

If you want to access the current contents of the VRAM, and update them it's a bit more tricky, usually what people does is calculate the new value of the tile from scratch and just set it.
  View user's profile Send private message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Tue Dec 21, 2021 11:20 pm
kusfo wrote
You can do something like
SMS_setTile(tilenumber|TILE_PRIORITY)


Wait... wait... that works?

Okay, I'm going to need to do a bit more reading, but that's the magic thing I hadn't realised - that you can apply the bitmask directly to the tile reference itself.

In my mind I'm thinking "okay, tile is one thing, and its attributes are probably another", so I was looking for something kinda like say someTileFunction(tile, attributes).

Thank you, that's amazingly helpful! :D

(Maybe later, once I'm a bit more confident with things, if appropriate, I'd be happy to help improve the SMSlib docs with what I've been learning? I feel like I should contribute something back to the community)
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Wed Dec 22, 2021 8:18 am
I think it'll be great if you help to improve documentation. I'm already quite a bad tech writer, so this is always helpful :-)

About the "magic", I can develop how it works a bit more. Tilemap entries are 16 bits (2 words). The arrangement is the following one:

The 9 less significant bits (8-0) are the tile number (theoretically 512 different tiles, at the end you cannot use all of them).
The 10th bit (9) is horizontal flip, the 11th bit (10) vertical flip, the 12th (11) bit is palette, the 13th (12) is priority, and the rest are unused.

Suppose you have the tile number 385, and do you want it to be vertical flipped, and with the priority flag set. You'll do something like:

tileNumber = 0x181; //385 in hex format

//TILE_FLIPPED_Y is 0x0400
//TILE_PRIORITY is 0x1000
SMS_setTile(tilenumber|TILE_PRIORITY| TILE_FLIPPED_Y);
// so what we pas to the VRAM is 0x181 OR 0x0400 OR 0x1000 that ends up being 0x1581 -> 0001010110000001
  View user's profile Send private message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Wed Dec 22, 2021 11:42 am
Yeah, now that I've mentally mapped that back into how the VDP is handling it, makes perfect sense. Thank you so much for explaining that, I really appreciate it.

Just to show what I've been able to do with your help, I've attached a small thing. I wanted to try and replicate a Sonic-like animated 3D sphere, which has normally been the domain of the Mega Drive. You'll probably immediately spot how I've worked around the problem of needing 16 colours without messing up the background.

The code is pretty awful right now, and it's not quite everything I want to do with it yet, so consider it a bit of a POC.

(I'm testing this with Emulicious; other emulators may be a bit funky -- GearSystem specifically -- it doesn't seem to support chonky pixel sprites, and I haven't had a chance to test this on my Mega Drive yet)
demo-sphere.zip (4.9 KB)

  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 879
  • Location: Spain
Reply with quote
Post Posted: Wed Dec 22, 2021 1:44 pm
That's really nice! it reminds me of the trick used by Ys for the dark caves!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3759
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Dec 22, 2021 2:15 pm
yeah I see where the confusion came from... but in this context, any time you read 'tile' don't think about tile number alone, think about tile number PLUS tile attributes

so to set the whole background to use some tile and priority and the sprite palette, you could create a loop with

SMS_setTile(your_tile_number | TILE_USE_SPRITE_PALETTE | TILE_PRIORITY)


of course after having set the start address at 0,0 using this:

SMS_setNextTileatXY(0,0)


... or just use

SMS_VRAMmemsetW (XYtoADDR(0,0), your_tile_number | TILE_USE_SPRITE_PALETTE | TILE_PRIORITY, 32*24*2)


that writes the desired tile (the one 16-bit word that contains tile number and attributes) 32*24 times (size is in bytes so you need * 2) over the PNT starting at 0,0
  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: Wed Dec 29, 2021 5:00 am
sverx wrote

SMS_VRAMmemsetW (XYtoADDR(0,0), your_tile_number | TILE_USE_SPRITE_PALETTE | TILE_PRIORITY, 32*24*2)


that writes the desired tile (the one 16-bit word that contains tile number and attributes) 32*24 times (size is in bytes so you need * 2) over the PNT starting at 0,0


Hey, that's really cool. Thanks for the alternate possibilities, and how it works. I'm getting a bit better of an idea now, thanks to the help here.

I do have a question about 224/240 line mode (SMS2 NTSC vs PAL).

If I turn it on (assuming PAL) with

    SMS_VDPturnOnFeature(VDPFEATURE_EXTRAHEIGHT);
    SMS_VDPturnOnFeature(VDPFEATURE_240LINES);


First question: Do I need to do anything special to write to the tilemap for this mode? It seems to behave a little unusually. Four extra rows get added to the top and bottom, but it seems that trying use SMS_loadSTMcompressedTileMap at row 0, instead happens at row 4 or so (and similar at the bottom of the screen). My mental model is "same physical space, but more lines crammed in". Another guess is "maybe it's compensating positioning for compatibility?"

Second question (answer: no): Do you know if 224/240 line mode is available on the Mega Drive's compatibility VDP? I have a little Sony PVM hooked up to my Mega Drive so I can test stuff on its hardware, but it doesn't seem to understand this extra height option, instead only showing 192 lines. I know the MD doesn't support chunky (doubled) sprite mode in its SMS implementation; might the same be true here for 224/240 line mode?

Edit: Ah, the answer to the second question is indeed "not supported", as per Ch 13 at https://www.smspower.org/uploads/Development/msvdp-20021112.txt
  View user's profile Send private message
  • Joined: 07 Aug 2007
  • Posts: 220
  • Location: Yach, Germany
Reply with quote
Post Posted: Thu Dec 30, 2021 10:07 am
darkowl wrote
You'd think that as a breaking change it should really be 5.0.0 and not a patch release... (even if it is a dev snapshot). Heh ;) I'm not game enough to try that flag, as 4.1.0 is working right now.


The current SDCC development model:

Have yearly releases that increase the minor version number. Before a release, there are freeze periods (which trunk first soft- then hard-frozen, while development of new feature continues in branches only).

In between releases, smaller changes go directly to trunk, bigger ones are developed in branches before being merged to trunk. If breaking or major changes are made, the patchlevel version is increased.

A change like what we did here (changing the calling convention, breaking the ABI) is developed in a branch first, then when it passes regression tests, and we think it is ready, it goes into trunk, with an patchlevel increase, a few months before the next release.
So users that want the latest feature get it in the development snapshots, and can see how it works for them. That way, bugs and other regressions are found and fixed before the release, making the release more stable.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3759
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 30, 2021 7:21 pm
darkowl wrote
I do have a question about 224/240 line mode (SMS2 NTSC vs PAL).

If I turn it on (assuming PAL) with

    SMS_VDPturnOnFeature(VDPFEATURE_EXTRAHEIGHT);
    SMS_VDPturnOnFeature(VDPFEATURE_240LINES);


First question: Do I need to do anything special to write to the tilemap for this mode?


Yes, there's basically no great support for those modes yet in devkitSMS, but you still can somewhat use them.
One trick would be to change this
#define SMS_PNTAddress            0x7800

into
#define SMS_PNTAddress            0x7700

as what happens with the extended height modes is that the PNT (pattern names table) is stored in a slightly different position in VRAM, but you likely then need to recompile the library and I can't even assure you that everything will work perfectly, as that's not something I have really tested.

Another even simpler approach would be to scroll the screen 32 pixels vertically so that the start of the 'old' PNT address and the top of the screen match. This would complicate your vertical scroll then, but if you only do horizontal scroll or no scroll at all it would work.

Also sprite usage differs in this mode so you should get rid of the remaining unused sprites placing them outside of the screen, for example at Y=240, otherwise sprites from previous frames could stay in place (this happens because in the extended height modes the "sprite terminator mark" is ignored and all the 64 sprites are drawn.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3759
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Dec 30, 2021 7:23 pm
PkK wrote
The current SDCC development model: [...]


Totally makes sense, one just have to remember that snapshots are work in progress/state of the art, not stable releases.
Thanks!
  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: Thu Dec 30, 2021 11:36 pm
PkK wrote
The current SDCC development model:


Oh for sure, I'm only thinking of it were semver. That said, it's so hard to do semver properly because the definition of "breaking", "feature" and "patch/fix" is not always clear-cut. Of course people can choose whatever process they feel makes most sense to them for versioning, and in that sense SDCC has its own process :)

sverx wrote

Yes, there's basically no great support for those modes yet in devkitSMS, but you still can somewhat use them.


Aha. I'm only thinking of these as I'm thinking along the lines of some demoscene-like stuff. Having a Mega Drive as my "real world" test kit makes it a bit trickier with its less-features-than-the-real-SMS VDP.

Good to know, I'll have a play with an emulator as I assume that'll be the most accurate for now. A friend of mine does have an SMS II and he wired up a flashable ROM chip, so eventually can test with that. But the MD can be "good enough" for now. I still like the idea of utilising the features the real SMS does have, as far as I'm able to. It's an interesting little system in that sense. Thanks for the info, again much appreciated!
  View user's profile Send private message
  • Joined: 12 Dec 2021
  • Posts: 43
  • Location: Melbourne, Australia
Reply with quote
Post Posted: Thu Jan 27, 2022 12:04 pm
So I've been continuing to muck about with things. Learning quite a lot, and really appreciate all the help so far!

I'm trying to understand the line interrupt, but it's a little elusive. I've managed to use it to do some offset screen X scrolling which is cool. But I'm now trying an effect which is a bit taxing on the poor Z80 due to lots of array reads and bitshifts. I was thinking to offload some of the array calculations to be done during the (very brief) line interrupts. Maybe that's a bad idea, haha.

How reliable are the scanline interrupts? Can you expect 192 interrupts (if set to run each scanline) and then wait for a vblank? Or is better to only run every other scanline etc?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3759
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Jan 27, 2022 12:25 pm
offload calculations is exactly what you should do if you want to have very frequent line interrupts, and the line interrupt service routine should be as short and quick as possible, likely even written in Z80 asm

for example something that updates the horizontal scroll register at every frame should only read the new value from an array using some pointer, update the register to the new value, then increment the pointer and return - this way it can complete before the next line interrupt gets fired

  __asm
    ld hl,(_next_bg_x_pointer)
    ld a,(hl)
    out (#0xBF),a
    ld a,#0x88           // write to hscroll VDP register
    out (#0xBF),a
    inc hl
    ld (_next_bg_x_pointer),hl
  __endasm;
  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 Feb 22, 2022 7:35 am
Nice :)

I've been doing a little hand optimisation into z80 asm. It's... definitely an experience hahaha.

So I have two little questions; first, is there any recommendations for making inline assembly not completely awful in VScode? I've found disabling clang at least makes it not make a hash of the code, but the __asm / __endasm; directives aren't understood by VScode so it tries to parse them as C, and clearly it doesn't like that.

I've also taken to putting // style comments after ; assembly comments, just so VSC at least makes the comments look like comments. It's not ideal, clearly.

Second, it seems that whilst Emulicious does a great job debugging C with breakpoints, and a great job debugging pure assembly with breakpoints, when it comes to inline assembly it just skips over it. Not sure if that's a compiler (SDCC) issue or not. I guess it needs to generate some kind of symbols that tell Emulicious how to relate to the source file, and perhaps that doesn't happen with inline asm? Has anyone had any success debugging inline asm?
  View user's profile Send private message
  • Joined: 14 Apr 2013
  • Posts: 623
Reply with quote
Post Posted: Wed Feb 23, 2022 9:08 pm
darkowl wrote
Nice :)

I've been doing a little hand optimisation into z80 asm. It's... definitely an experience hahaha.

So I have two little questions; first, is there any recommendations for making inline assembly not completely awful in VScode? I've found disabling clang at least makes it not make a hash of the code, but the __asm / __endasm; directives aren't understood by VScode so it tries to parse them as C, and clearly it doesn't like that.

I've also taken to putting // style comments after ; assembly comments, just so VSC at least makes the comments look like comments. It's not ideal, clearly.

Second, it seems that whilst Emulicious does a great job debugging C with breakpoints, and a great job debugging pure assembly with breakpoints, when it comes to inline assembly it just skips over it. Not sure if that's a compiler (SDCC) issue or not. I guess it needs to generate some kind of symbols that tell Emulicious how to relate to the source file, and perhaps that doesn't happen with inline asm? Has anyone had any success debugging inline asm?

I'm not sure if SDCC even produces any debug symbols suitable for inline assembly.
I'm also not sure how it would help to step through the inline assembly which won't change anything observable in VS Code most of the time.
  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: Thu Feb 24, 2022 11:23 am
Calindro wrote
I'm not sure if SDCC even produces any debug symbols suitable for inline assembly.
I'm also not sure how it would help to step through the inline assembly which won't change anything observable in VS Code most of the time.


Yeah, I don't think it does... but for a practical use, I've been playing around with making a classic fire effect, and I got it as optimised as I could think of in C, so then went to tweak it further in assembly.

However, there isn't (currently, likely because of no debug helper symbols) any way to even see what's going on in the registers etc. as the code runs - which would be super helpful. So it kind of ends up like a "black box" of code and I have to do a lot more guesswork as to what I (inevitably) stuffed up if the output isn't correct, heh.

Of course I get that inline asm is a bit of a weird "halfway" thing, versus just pure C or pure asm, but maybe there may be some way in the future. Thanks for your insights :)
  View user's profile Send private message
  • Joined: 07 Aug 2007
  • Posts: 220
  • Location: Yach, Germany
Reply with quote
Post Posted: Fri Mar 04, 2022 12:43 pm
darkowl wrote

Yeah, I don't think it does... but for a practical use, I've been playing around with making a classic fire effect, and I got it as optimised as I could think of in C, so then went to tweak it further in assembly.

However, there isn't (currently, likely because of no debug helper symbols) any way to even see what's going on in the registers etc. as the code runs - which would be super helpful. So it kind of ends up like a "black box" of code and I have to do a lot more guesswork as to what I (inevitably) stuffed up if the output isn't correct, heh.

Of course I get that inline asm is a bit of a weird "halfway" thing, versus just pure C or pure asm, but maybe there may be some way in the future. Thanks for your insights :)


You could open a feature request ticket for SDCC in the tracker:
https://sourceforge.net/p/sdcc/feature-requests/
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!