Language…
19 users online: AmazingChest,  AmperSam,  Anorakun,  Eden_, elegist, Fozymandias, GRIMMKIN, Heitor Porfirio, NTI Productions, Null42, OEO6, playagmes169, Rykon-V73,  Telinc1,  Thomas, tOaO, Tulip Time Scholarship Games, underway,  yoshi3706 - Guests: 294 - Bots: 439
Users: 64,795 (2,373 active)
Latest user: mathew

SA-1 Pack - v1.40 released

Originally posted by TRS
Exactly how much to expand doesn't really matter, as all the sprite-related RAMs would still have to be moved, right?


Right now the misc. sprite tables are in Direct Page if I'm not mistaken. They would have to be moved, but inside of Direct Page. The moving isn't the problem; there is just not enough freeRAM in Direct Page to expand the tables to 30 sprites. I was just suggesting that, if he only has space for a 20-sprites extension, that would be fine to me.

However, I say no if you have to move unrelated RAM addresses around to make freeRAM together (for tables). Unless you move addresses never/rarely used in run-of-the-mill sprite/block code, like level-loading related addresses (if there are any in Direct Page). Maybe the sprite extension could be optionnal, but if activated it would disable some stuff to make more RAM free, like deleting the Koopa Kids.

EDIT: Can I request some patches to be converted to SA-1? I'd like:

- 32x32 Character Tilemap Kit
- Layer 3 Customizer
- SMW Health Bar - Bugfix and Alternative
- Extended No More Sprite Tile Limits

I could convert 3 out of the 4 patches I need, but Layer 3 Customizer doesn't cooperate and probably never will.

This patch requires the LC_LZ3 GFX Compression thing. However, the SA-1 patch forces the ROM to use LC_LZ2 (Optimized for speed version). If I try to change it, the ROM crashes at startup.

But there's something else, as usually the only thing that happens when using the L3Customizer w/out LC_LZ3 is that levels with Layer 3 have garbage graphics. Now, the game crashes on startup, so I think it's not the problem?
Errrr... Yes. Sorry for bump but can you convert the Message Box Expand? I tried it but I think, there is a (H)DMA Problem (only the Layer 3 is showen) but the rest is complett dark (unless you're teleporting into a new level, so that's why I think about [H]DMA) so do you know how can you convert it? You know, this patch is very good and yes,... it's new but it's better that you convert it (I want to use it [not for my main hack because it isn't using SA-1]).

Edit: I think I forget to convert an adress. But O.k., avidable here.
Yoshiatom's Post
DUMB QUESTION:
Will this workorund the fact that you can't have 80 or so sprites in a level without some of them dissapering?

Layout by Koopster!

<DeputyBS> I knew it
<DeputyBS> alcarobot is taking over the world through his truck dealership franchise
HOLY SH*T! This can be the "Super Mario World Next-Gen!"
Originally posted by Vitor Viela
Code
(assuming that XX is in the $00-$3F or $80-$BF range
and YY equals either XX or $7E)

$YY:0000-$YY:00FF to $XX:3000-$XX:30FF.
$YY:0100-$YY:1FFF to $XX:0100-$XX:1FFF.


I'm not sure if I'm just being dumb, but I don't get what you mean by this. Are you just saying that for those banks ($00-$3F, $7E, and $80-$BF) all addresses $0000-$00FF are mapped to $3000-$30FF? In other words, the bank is NOT changing?

EDIT: I don't know if you are still taking requests for SA-1 compatible tools, but I just noticed there is no BTSD or other block tool in that list you gave. Unless there is some other way for inserting blocks with an SA-1 enabled rom that I don't know about, I'd like to request that. Also requesting sonikku's delay block compatibility since none of this is going to happen.
I just found out about this patch and would really like to use it in my hack if possible. I hope it is still under development. Reading through this thread Vitor talked at one point about releasing the next version in a few days, but it was never released.

I have been doing some testing with this patch and the various tools that work with it, most recently the manual custom block inserter, and I was encountering crashes when a sprite touches a custom block, just like King Dedede a few pages back:

Originally posted by King Dedede
Eh... There's a problem with the SA-1 version of the Manual Custom Block Inserter patch. Whenever a sprite touches a block from the custom block pages, the game crashes. It happens even if there is no code for the block.


I'm pretty sure the reason for the crash is that the patch uses SNES multiplication registers that will only work when executing on the SNES cpu and not on the SA-1 cpu, and when a sprite touches a block the custom block code will be executed on SA-1 because sprites run on SA-1.

To fix it the patch needs to be modified to use the SA-1 multiplication registers if executing on SA-1. Is there an easy way to check if we are currently executing on SA-1 or SNES? If there isn't then I'll just have to manually set some flag in the SpriteV and SpriteH cases of the patch and use that instead.

On a different note, how can you do a trace of code that is executing on SA-1? It seems that in the Snes9x debugger breakpoints only work for code executing on SNES and not on SA-1. I know this because when I was looking at the custom block inserter crash I tried putting a breakpoint at the start of the patch code and it was crashing without reaching the breakpoint, which was making me think for a while that the crash was happening before it reached the patch code, when in reality it was just not triggering the breakpoint.

Originally posted by Vitor Vilela
Some days I had a idea of expanding the maximum number of sprites on screen to 30 (instead of 10), but this require moving all sprite related RAMs to another place, but it's impossible to find free ram on Direct Page for 6 sprite addresses.... So, should I find a workaround for this or better I give up?


It's too bad that there is no addressing mode for DP indirect indexed by x, otherwise you could just store the addresses of the new sprite tables where the old tables were and then just change the addressing mode. Currently this would only work in cases where the tables are indexed by y.

I can't think of a good solution for expanding those tables that doesn't involve doing something stupid like putting a JMP in every place that the tables are accessed.

Originally posted by jesus
Originally posted by Vitor Viela
Code
(assuming that XX is in the $00-$3F or $80-$BF range
and YY equals either XX or $7E)

$YY:0000-$YY:00FF to $XX:3000-$XX:30FF.
$YY:0100-$YY:1FFF to $XX:0100-$XX:1FFF.


I'm not sure if I'm just being dumb, but I don't get what you mean by this. Are you just saying that for those banks ($00-$3F, $7E, and $80-$BF) all addresses $0000-$00FF are mapped to $3000-$30FF? In other words, the bank is NOT changing?


I was confused by this too when I first read it but I think I understand how all the memory mapping works now. As far as I know this is saying that previously all addresses of the form $YY:0000-$YY:00FF (for YY in the range $00-$3F or $80-$BF or $7E) accessed the same data, and now that data is instead accessed through addresses of the form $XX:3000-$XX:30FF (for XX in the range $00-$3F or $80-$BF). The same thing for the second line, except there is a mistake and it should say "$YY:0100-$YY:1FFF to $XX:6100-$XX:7FFF".

The SNES DEV book linked to at the end of the readme had some very helpful images on pages 1-3-1 and 1-3-2 of book 2 that helped clarify things for me.
Invoking SNES (LDA #$D0 : STA $2209) seems not to work for me in zsnes v1.51, although it works normally in the other emulators. Am I doing something wrong?

I looked into it with zsnes debugger. SNES pointer was never changed into the value at $0183 after #$D0 had been stored at $2209. SNES did nothing but loop forever.
Aw guys I'm sorry, but I completely lose interest on this project.
I will get working on this project again soon.

worldpeace, that's an bug. ZSNES doesn't like the IRQStart code for some reason, so I will need to restore the older onr or redo from scratch.

And this is the same reason for all ZSNES related crashes on switch palaces, monty moles... Anything which modifies Map16 is affected too by ZSNES.

Also I found a rare bug on the LZ3 decoder, so I will remove this patch on next version unless if I find a workaround for that.

Originally posted by Sakuya Izayoi
This patch requires the LC_LZ3 GFX Compression thing. However, the SA-1 patch forces the ROM to use LC_LZ2 (Optimized for speed version). If I try to change it, the ROM crashes at startup.

But there's something else, as usually the only thing that happens when using the L3Customizer w/out LC_LZ3 is that levels with Layer 3 have garbage graphics. Now, the game crashes on startup, so I think it's not the problem?


You would have to change the compression options to LC_LZ3 and reapply the SA-1 patch -- so it will apply the SA-1 working LZ3 code.

But as I said before it's buggy right now, so the only option left is to wait for next Lunar Magic version if you want to use LC_LZ3.

Originally posted by Arujus
I just found out about this patch and would really like to use it in my hack if possible. I hope it is still under development. Reading through this thread Vitor talked at one point about releasing the next version in a few days, but it was never released.

I have been doing some testing with this patch and the various tools that work with it, most recently the manual custom block inserter, and I was encountering crashes when a sprite touches a custom block, just like King Dedede a few pages back:

Originally posted by King Dedede
Eh... There's a problem with the SA-1 version of the Manual Custom Block Inserter patch. Whenever a sprite touches a block from the custom block pages, the game crashes. It happens even if there is no code for the block.


I'm pretty sure the reason for the crash is that the patch uses SNES multiplication registers that will only work when executing on the SNES cpu and not on the SA-1 cpu, and when a sprite touches a block the custom block code will be executed on SA-1 because sprites run on SA-1.

To fix it the patch needs to be modified to use the SA-1 multiplication registers if executing on SA-1. Is there an easy way to check if we are currently executing on SA-1 or SNES? If there isn't then I'll just have to manually set some flag in the SpriteV and SpriteH cases of the patch and use that instead.

On a different note, how can you do a trace of code that is executing on SA-1? It seems that in the Snes9x debugger breakpoints only work for code executing on SNES and not on SA-1. I know this because when I was looking at the custom block inserter crash I tried putting a breakpoint at the start of the patch code and it was crashing without reaching the breakpoint, which was making me think for a while that the crash was happening before it reached the patch code, when in reality it was just not triggering the breakpoint.


I have no idea why that patch is not working correctly.
The registers are okay, because you only have to use the SA-1 math registers when you're using SA-1 CPU.

And the only way to trace SA-1 code is using snes9x 1.43 debugger, but you don't have any trace once, so the best solution is creating a custom build of bsnes or snes9x with the trace code.

Originally posted by Vitor Vilela
Some days I had a idea of expanding the maximum number of sprites on screen to 30 (instead of 10), but this require moving all sprite related RAMs to another place, but it's impossible to find free ram on Direct Page for 6 sprite addresses.... So, should I find a workaround for this or better I give up?


It's too bad that there is no addressing mode for DP indirect indexed by x, otherwise you could just store the addresses of the new sprite tables where the old tables were and then just change the addressing mode. Currently this would only work in cases where the tables are indexed by y.

I can't think of a good solution for expanding those tables that doesn't involve doing something stupid like putting a JMP in every place that the tables are accessed.
</div></div>

Yeah, it's too bad. I guess I will with the worst option: Hijack every place which accesses those RAMs. It's around ~1700 to replace iirc, so I will try doing a tool or abuse regex to do that.

Quote
Originally posted by jesus
Originally posted by Vitor Viela
Code
(assuming that XX is in the $00-$3F or $80-$BF range
and YY equals either XX or $7E)

$YY:0000-$YY:00FF to $XX:3000-$XX:30FF.
$YY:0100-$YY:1FFF to $XX:0100-$XX:1FFF.


I'm not sure if I'm just being dumb, but I don't get what you mean by this. Are you just saying that for those banks ($00-$3F, $7E, and $80-$BF) all addresses $0000-$00FF are mapped to $3000-$30FF? In other words, the bank is NOT changing?


I was confused by this too when I first read it but I think I understand how all the memory mapping works now. As far as I know this is saying that previously all addresses of the form $YY:0000-$YY:00FF (for YY in the range $00-$3F or $80-$BF or $7E) accessed the same data, and now that data is instead accessed through addresses of the form $XX:3000-$XX:30FF (for XX in the range $00-$3F or $80-$BF). The same thing for the second line, except there is a mistake and it should say "$YY:0100-$YY:1FFF to $XX:6100-$XX:7FFF".

The SNES DEV book linked to at the end of the readme had some very helpful images on pages 1-3-1 and 1-3-2 of book 2 that helped clarify things for me.


Yep, you're right. I have to fix those issues on readme for next version anyway.

I guess I will include those images on snes dev. book. Indeed they're very useful, they helped me pretty much when I was learning SA-1.

======================================================

To who don't like manual block inserter, I have an temporally solution: https://dl.dropboxusercontent.com/u/16203903/A/btsdsa1.asm. Use BTSD on your SA-1 ROM, save and apply this patch with Asar. It will fix BTSD's code to work with SA-1. The only thing you will have to fix is the block's RAM/ROM addresses.
GitHub - Twitter - YouTube - SnesLab Discord
Originally posted by Vitor Vilela

I have no idea why that patch is not working correctly.
The registers are okay, because you only have to use the SA-1 math registers when you're using SA-1 CPU.


The patch code does get executed on the SA-1 CPU when a sprite touches a block. Basically, the sprite (which is executing on SA-1 CPU) calls into the custom block code when it touches a block.

I fixed the patch by making it use the SA-1 math registers for the SpriteV and SpriteH cases. You can download my fixed version of it here: http://bin.smwcentral.net/u/23642/block_inserter.zip

Edit: I just realized that this zip comes with 1 custom block already (in Block500.asm): a block that is solid for Mario but sprites can pass through. You might want to remove this if you are considering adding this to your list of patches that work with SA-1.

Originally posted by Vitor Vilela

Originally posted by Arujus

It's too bad that there is no addressing mode for DP indirect indexed by x, otherwise you could just store the addresses of the new sprite tables where the old tables were and then just change the addressing mode. Currently this would only work in cases where the tables are indexed by y.

I can't think of a good solution for expanding those tables that doesn't involve doing something stupid like putting a JMP in every place that the tables are accessed.


Yeah, it's too bad. I guess I will with the worst option: Hijack every place which accesses those RAMs. It's around ~1700 to replace iirc, so I will try doing a tool or abuse regex to do that.


Don't worry about working on remapping the sprite tables so that they can be expanded, I'm working on that. I came up with a MUCH better solution than hijacking in every place that a sprite table on the direct page is accessed.

My solution involves using indirection and takes advantage of the fact that when indexing the sprite tables by x, the value of x remains more or less constant for the entire duration that the sprite is being processed, until we move onto processing the next sprite at which point the value of x changes. The idea is this: at the start of processing each sprite you can store the addresses of where this sprite's data is in the new tables (so for example if sprite table $E4 is being remapped off of the direct page to $3200 and we are processing the sprite at index 4, we store #$3204 somewhere on the direct page, say at $EE. When we move on to processing sprite 3 we will store #$3203 in $EE instead). Then you can replace accesses to these tables indexed by x with indirect accesses (not indexed by x) to wherever on the direct page we stored the appropriate address (so, if using the previous example, essentially replacing instructions like LDA $E4,x with LDA ($EE), both of which use only 2 bytes, so no need to hijack).

To test how well this would work I've been working on creating a patch that remaps the sprite X low position table ($E4) off of the direct page. After fixing up some problems (i.e., cases where x changes while processing a sprite and that new index is used to access sprite tables on the direct page) the game seems to be functioning quite normally, besides a few minor problems that still need fixing.

I plan on remapping the sprite Y low position ($D8) and the sprite number ($9E) tables off of the direct page as well. I chose these tables because they seemed like the easiest to remap. One of the huge advantages of my solution is that fixing a problem spot with remapping $E4 off the direct page typically also fixes that same problem that would have been encountered with remapping the other tables. So I expect that it should be much easier to remap the other two tables as well when I am done remapping the first one.

After this is done, there will be enough free space on the direct page for the remaining three sprite tables to be expanded (after being remapped to other addresses on the direct page), and we will be able to have 22 sprite slots!
Originally posted by Vitor Vilela
I will get working on this project again soon.

That's good news:D

Because I really had to use SA-1, I tried to modify the code myself so it could work normally in ZSNES.
It seems that I did something as a result, and I want to share it.

I modified sprites.asm to avoid invoking SNES, which is now replaced with a (semantically) equivalent code.
http://bin.smwcentral.net/u/1250/boost.zip

I don't know if this is a good way. But it resolves that issue at the moment. I tested in ZSNES/SNES9X/BSNES and no problems are found so far.

Here's an explanation.
When it is needed to invoke SNES and wait for its work done, instead of doing that, firstly SA-1 stores the address for SNES somewhere and forces itself to IRQEnd. Then SNES stop waiting for SA-1 and is able to jump to the address without invoking. After finishing its work, SNES invokes SA-1 once again, and SA-1 continues the routine where it did escape before. It can be done by saving SA-1 stack and restoring it.

This way is far from multiprocessing. But from what I've seen so far, whenever $2209 is used, SA-1 and SNES alternately waits each other to be finished. So I think this way could be appropriate.


edit:
Originally posted by Arujus
I fixed the patch by making it use the SA-1 math registers for the SpriteV and SpriteH cases.

I am not sure, but couldn't be SA-1 math registers used for all cases?
Originally posted by worldpeace
edit:
Originally posted by Arujus
I fixed the patch by making it use the SA-1 math registers for the SpriteV and SpriteH cases.

I am not sure, but couldn't be SA-1 math registers used for all cases?


I just tested it out and you're right, you can use SA-1 registers on the SNES CPU. That makes things easier. Here is the updated custom block inserter:

http://bin.smwcentral.net/u/23642/block_inserter.zip
Well worldpeace, I looked your code and your method isn't bad at all. But your method is very dangerous since there's a chance to the stack corrupt (e.g if you receive a IRQ or parallel mode code runs) and it's a slow method, so better I try fixing the IRQ code anyway.

And no, you can't use the SA-1 math registers on SNES CPU. It can even work on some emulators, but on real hardware it will fail.
GitHub - Twitter - YouTube - SnesLab Discord
Originally posted by Vitor Vilela
And no, you can't use the SA-1 math registers on SNES CPU. It can even work on some emulators, but on real hardware it will fail.


Are you sure about that? It worked in all of ZSNES, SNES9x and BSNES for me, and if you look at the images in the SNES dev manual you can see that SA-1 registers are included in the memory map from SNES CPU perspective.
Both CPU can access the registers, but each register has own access permission. Some only SNES CPU, SA-1 or both can read or write.

In case of $2250+, only SA-1 can write:




While some others is different:

^ both can write


^ only SNES can write
GitHub - Twitter - YouTube - SnesLab Discord
Ok, I changed it back, although it's worrying that something can work on all those emulators (including BSNES) but fail or real hardware.

Do you think it would be a good idea to make all custom block offsets run on the same CPU (either SNES or SA-1)? Currently, if a custom block wanted to do some multiplication for both the sprite offsets and Mario offsets it would have to split into multiple cases like the patch does.
So my work with remapping three sprite tables off of the direct page ended up being successful and so I've been able to expand all of the sprite tables to hold 22 sprite slots.

I've created a patch that does this and allows 22 sprites to be on screen. I'm posting it here so that anyone who is interested can start playing around with it. It is NOT recommended to be used in hacks yet since it is still rather experimental and likely has quite a few bugs. The file more_sprites.asm in the zip is to be applied AFTER applying the SA-1 patch. It also requires the no more sprite tile limits patch and includes my own custom version this patch which gets automatically applied, which means that the sprite header setting must be set to 10 for more sprites to work. For those that try this out, let me know of any bugs that you encounter. Here is a download link:

http://bin.smwcentral.net/u/23642/more_sprites.zip

Since this patch requires the no more sprite tile limits patch and that patch is not compatible with several sprites, I can either work on making it compatible with those sprites or allow the more sprites patch to be used without no more sprite tile limits. I'm not sure how feasible the latter option is because it requires giving each sprite index its own area of the OAM table in which it can upload, but I'm not sure the OAM is big enough for this.

This patch will currently not be compatible with any custom sprites or any tools/patches/blocks that access sprite tables. If any feature of lunar magic accesses sprite tables that feature won't be usable yet (but I'm not sure if any features do this, level editing at least works).

Although this is a separate patch from the SA-1 patch, hopefully it can be added as part of the SA-1 patch in the future.

Also, I did a sprite stress test which basically involved spamming as many different sprites as I could to see how the game would perform:

There are a total of 19 sprites on screen in this image. This many sprites does produce some slowdown. It seems that 17 sprites usually has no slowdown but once you reach 18 a little slowdown starts to appear. This is a little less than I was expecting could be on screen without slowdown given the increased speed of the SA-1. I was thinking the problem might be the sprite/sprite interaction because each sprite has to iterate over every other sprite so we have O(n^2) running time, but it really doesn't look like sprite/sprite interaction does much if the sprites aren't right next to each other. Maybe there is some benchmarking that can be done to see where time is being spent.
Wow, this looks really epic! However, I assume Sprite Tool plays with sprite tables and thus won't work with it? Having that many standard sprites on-screen may not be THAT useful. I mean, unless you put a lot of Diggin' and Puntin' Chucks in the same screen as a mean late-game trap, I can't see how a normally-designed level could exceed the normal limit. Unless you're making a Danmaku boss or something like that, but that would require custom sprites either way.

But no mather what, it is really impressive!
Awesome work here. Surely when I understand what you did at all I will add to SA-1 Pack :P

As for Sprite Tool, it's easy to get working I guess, I just have to modify and recompile the .asm+.cpp file. Of course, each custom sprite will have to be modified too into the new addresses.

As for the slowdown, I think if we optimize a little more this patch we can get that rid. Also, what emulator were you using? If I remember correctly, ZSNES only emulates SA-1 at 5 MHz, so probably if you run on snes9x or bsnes, the slowdown will not happen since SA-1 runs actually at 10 MHz.

About the sprite memory, well, I guess we will need to change the reserved OAM space a bit or create compatible version of the sprites which doesn't like No More Sprite Tile Limits. Or just use p4plus2's future OAM patch which allows to you use both $0200 and $0300 (and it will not have incompatibility with those sprites...?)
GitHub - Twitter - YouTube - SnesLab Discord
Originally posted by Arujus



Reminds me of when I was a little kid and the main idea for making up an insane video game segment would be to spam loads and loads of enemies out the wazoo. If this comes to fruition, I might be able to use this one idea I had for a Kaizo Big Boo fight:

Legacy custom music
A site with a non-useless dislike button
SMW hacking channel

Originally posted by Sakuya Izayoi
Wow, this looks really epic! However, I assume Sprite Tool plays with sprite tables and thus won't work with it? Having that many standard sprites on-screen may not be THAT useful. I mean, unless you put a lot of Diggin' and Puntin' Chucks in the same screen as a mean late-game trap, I can't see how a normally-designed level could exceed the normal limit. Unless you're making a Danmaku boss or something like that, but that would require custom sprites either way.

But no mather what, it is really impressive!


It should be easy to make tools and sprites and stuff work with this patch. All that needs to be done is make them access the new sprite table locations instead of the old ones. I've been more focused on making sure that all vanilla smw stuff works properly than making custom stuff work. However, you may notice the file sprite_tables.asm included in the zip I posted. I intended that when modifying custom sprites, blocks and patches to be supported, the addresses of sprite tables can be replaced with definitions in this file. This has the advantage of allowing the table locations to be easily changed (the current table locations are not finalized) and can also allow the same sprite to support all of non SA-1, normal SA-1, and more-sprites SA-1 at the same time, with the mode controlled by a single flag in sprite_tables.asm. Maybe this file should be extended to include all addresses that were remapped by SA-1 instead of just the sprite tables.

Originally posted by Vitor Vilela
As for the slowdown, I think if we optimize a little more this patch we can get that rid. Also, what emulator were you using? If I remember correctly, ZSNES only emulates SA-1 at 5 MHz, so probably if you run on snes9x or bsnes, the slowdown will not happen since SA-1 runs actually at 10 MHz.


You're right, it's just in zsnes that there is slowdown; snes9x and bsnes work fine. That's kind of unfortunate since zsnes is such a widely used emulator for smw hacks. I don't suppose there's a way to increase the SA-1 to the proper speed by just modifying the zsnes.cfg file?