I think xkas and WLA see the most use. You can assemble it and insert the output with a hex editor into wherever it should be in your SMW ROM, or assemble it directly into the ROM either by:
-setting .org to the area of the ROM you want the code to be placed into and supplying your input ROM inplace of the output file in xkas (I think that's how it works there).
-.background an input ROM, insert code with OVERWRITE .sections / .unbackground'd areas in WLA.
The latter option is so much easier for larger patches since you don't have to use a hex editor every time you want to trial your code and the labels make it very convenient when it comes to pointing to your new code.
70:0000-70:008C is copied to 7E:1F49-7E:1FD5, which is in turn copied to 7E:1EA2 - 7E:1F2E. According to the RAM map, that covers...
$7E:1EA2 Unknown Misc. Level flag table (?) - unknown size
$7E:1EEB 1 byte Misc. Special Stage Features handler for both the title screen stage and the normal stages. Hex value 83 enables it.
$7E:1EFB 1 byte Misc. Special World Passed flag
$7E:1F02 15 bytes Misc. Overworld event flags
$7E:1F11 1 byte Misc. Submap (0=Overworld, 1=Yoshi, 2=Vanilla, 3=Forest, 4=Bowser, 5=Special, 6=Star)
$7E:1F17 2 bytes Misc. OW X position of Mario
$7E:1F19 2 bytes Misc. OW Y position of Mario
$7E:1F1B 2 bytes Misc. OW X position of Luigi
$7E:1F1D 2 bytes Misc. OW Y position of Luigi
$7E:1F27 4 bytes Misc. Switch block flags (Green, Yellow, Blue, Red)
$7E:1F2E 1 byte Misc. # of levels beat
I think to protect code / data you have to at the start of your new code place the characters RATS in sequence, a 16bit value of how many bytes you want to reserve and than a 16bit value which is the inverse of how many bytes you want to reserve (to avoid false positives).
The SFX is fully documented in the SNES dev manual which you can find on RHDN. Apart from there, I don't really know where else you can find good info on it. It's set out where you have a much more efficient way of plotting pixels (specify your raw X and Y coords, no tedious tile work). It outputs the raw tiles to the game's sram and you copy it from there to the video memory for display. Apart from fancy sprites (YI!), I can't see much being done with it without some really off the wall hacking. Then again if someone knows the SFX and SMW well they could probably accomplish alot with it.
RTS and RTL are not interchangable. It'll crash because JSL puts a 24bit return address on the stack and RTS only pulls 16bits (PB is unchanged). So, that probably means the test for 'bne stomp' always passes or else it'll run into the RTS.
Also, if you tested $77 first, why do you test it again in 'stomp:?
You'd have to rewrite everything on the 65816 end to be compatible with the new protocols, not to mention having to recreate music and samples with entirely new code. If someone wanted to add extensions so smw's spc driver they'd probably disassemble, hack it and reinsert it with it mostly intact.
Bio is right. xkas defaults to using long addressing which is valiable for LDA indexed by X but not Y, so it doesn't include the full 24bits. Unless the DB was in the right spot at the time it would've failed, but the code above would do just that.
This is just theory, I haven't actually put it into action.
The use of the SFX in that HDMA topic made me think about offloading some routines from the S-CPU to an SA-1. The nauseating slowdown when too many sprites are on screen might be done away with if the sprite routines were to run on the SA-1 end and the results were sent back to the SNES RAM on completion.
I chose the SA-1 because the code can be mostly reused with almost identical CPU's (some extra code ofcourse has to bring it all together). And unlike the SuperFX which hoards the ROM for itself, the SA-1 can access RAM/ROM together with the S-CPU. The former running at 5.37Mhz and the latter at SloROM speed. It pales to 21Mhz but it makes the implementation so much smoother.
The initial thought I have of this working out is to:
-Start of frame, S-CPU IRQ's SA-1 and signals a new frame. S-CPU DMA's sprite data to 'BW-RAM', sources would be 7E:14C8 and such. Might just do a big block copy (7E:0000-7E:1FFF) to include controller data and what-not. S-RAM is a big issue since the data for say, OAM ($0300) shares ranges with it. Might just scrap the 'integrity check'(?) and just load/store backup data elsewhere.
E: Forgot...Can just set the DB reg to 71f / 41h and forget about backup data altogether.
Probably wouldn't be too hard, I've stepped through most of it. Seems that the other data can be accessed with the data bank being set to BW-RAM (for 16bit addresses). 24bit addresses and SNES reg writes would cause some problems...At any rate, routines would most likely have to be written with the coprocessor in mind.
-For each run of a sprite routine, S-CPU writes PC location of sprite routine to somewhere in I-RAM and IRQ's SA-1 for action. S-CPU just returns and moves onto the next, while SA-1 works on sprite routine.
-Upon completion of the routine, SA-1 writes a certain part of I-RAM checked by the SNES when it finishes processing for the frame.
-SNES DMA's the BW-RAM initially used in the sprite routines back to the SNES and the S-CPU allows NMI to progress / move onto the next frame.
Any thoughts? I've 'equipped' a copy of SMW with an SA-1 and the memory map doesn't conflict with the original one of SMW. LM doesn't seem to mind either. S-RAM and all works fine (just that it also appears at bank 40+). So, I'd like to ask:
-how feasible do you think this is?
-is there anything else taxing on the SNES that could also be offloaded?
-does LM significantly change the sprite routine system?
I'm just thinking out loud here, so I'm not sure if there's a horrible flaw in this plan.
The SNES has hardware multiply / divide (with remainders).
4204 wl++++ WRDIVL - Dividend C low byte
4205 wh++++ WRDIVH - Dividend C high byte
4206 wb++++ WRDIVB - Divisor B
Write $4204/5, then $4206. 16 "machine cycles" (probably 96 master
cycles) after $4206 is set, the quotient may be read from $4214/5, and
the remainder from $4216/7. Presumably, $4204/5 are not altered by this
process, much like $4202.
The division is unsigned. Division by 0 gives a quotient of $FFFF and a
remainder of C.
I guess you'll be making use of the remainder there.
Totally forgot about custom blocks. I was thinking all the focus was on the sprites. Compounding blocktool's inefficient implementation with sprites (and moreso with buoyancy) makes for some ugly slowdown.
While there are several things that would have to be worked around, I just realised the most prohibitive one would be like the following bank change:
Or anything that changes the bank really. Since the SA-1 only has 2kb of I-RAM equivalent to SNES's 8kb at the beginning of each ROM bank, it'd be too much of a hassle to work with that. Just about every sprite memory access is done with 16bit addressing targetting that area of RAM. If it had 8kb aswell, it would be more workable. Apart from blocks and sprites I can't think of anything else that could be of significant help if offloaded to a coprocessor. Oh well.
$05/853F B7 65 LDA [$65],y[$06:8689];level data in ROM map
$05/8541 STA $00 [$00:0000]
$05/8543 AA TAX
$05/8544 29 0F AND #$0F
$05/8546 8D 2B 19 STA $192B [$00:192B]
$05/8549 8A TXA
$05/854A 4A LSR A
$05/854B 4A LSR A
$05/854C 4A LSR A
$05/854D 4A LSR A
$05/854E 29 07 AND #$07 ;max 8 variables
$05/8550 AA TAX
$05/8551 BF DB 84 05 LDA $0584DB,x[$05:84E1]
$05/8555 AE DA 0D LDX $0DDA [$00:0DDA]
$05/8558 10 02 BPL $02 [$855C]
$05/855C CD DA 0D CMP $0DDA [$00:0DDA]
$05/855F D0 02 BNE $02 [$8563]
$05/8563 8D DA 0D STA $0DDA [$00:0DDA] $0DDA store
That would look alot better with a monospace font...
RAM map tells me $0DDA is the music select, which happens to be written to $2142. The first ROM address in the code is in the level data, and Y reg = 02 when accessing, so it's the third byte in the level data I guess. The high 4 bits of it, anyway of which there's 8 variables for it.
At 0584DB is the actual music bytes themselves. The one being accessed is the boss track (05h). Changing these 8 bytes to 05h for example makes every ingame level have boss music. I suppose you're in for some manual pointer work since LM doesn't want to change it.
EDIT: I don't think I was very clear...To change the music of a level manually:
1. Lookup 24bit pointer according to the level number at:
2E200 $05:E000 1,536 bytes Pointer Level data pointer table (Layer 1)
2. Change the third byte's high 4 bits, at the pointed to address, (max 8 variables) to your track of choice.
SMW doesn't care of it's a boss level. I tried it with the first boss battle (Lemmy?) and there's no issue.