comprehensive SMB1 disassembly
Moderator: Moderators
doppelganger,
LOL, one more thing that could be an issue. At line 3525, I found something that could be an issue if you moved the code around. That dummy entry actually seemed like it was used. I found when I modularized it, I had the game freeze when there was looping. You should make sure that line 3525 references the code at line 3453 rather than putting a bare address. Adding the reference prevented the game from freezing. *
* The freezing occured in World 4-4.
Beyond this, there is probably not much else that is at issue. I'm writing a program the checks for non-label references to $8000-$FFFF range in the assembly source.
LOL, one more thing that could be an issue. At line 3525, I found something that could be an issue if you moved the code around. That dummy entry actually seemed like it was used. I found when I modularized it, I had the game freeze when there was looping. You should make sure that line 3525 references the code at line 3453 rather than putting a bare address. Adding the reference prevented the game from freezing. *
* The freezing occured in World 4-4.
Beyond this, there is probably not much else that is at issue. I'm writing a program the checks for non-label references to $8000-$FFFF range in the assembly source.
tepples,
I'm just referring to his disassembly. I moved the code around, which caused problems with bare address references to the $8000-$ffff range, so I had to fix those.
doppelganger,
Another more complex one takes place at lines 645, 14421, and 14466. It's a bit more difficult to fix because the game does a weird piece of code. My solution was to comment out line 645, replace the SwimTileRepOffset on line 14421 with SwimTile+6, and add SwimTile: as a label to the beginning of line 14466. You may be able to come up with a better solution.
Anyway, here is the C source code to the program I wrote that checks for bare address references to the $8000-$ffff range (the 2 I recently posted were all it found aside from the bare address interrupt reference and the .org):
^_^
I'm just referring to his disassembly. I moved the code around, which caused problems with bare address references to the $8000-$ffff range, so I had to fix those.
doppelganger,
Another more complex one takes place at lines 645, 14421, and 14466. It's a bit more difficult to fix because the game does a weird piece of code. My solution was to comment out line 645, replace the SwimTileRepOffset on line 14421 with SwimTile+6, and add SwimTile: as a label to the beginning of line 14466. You may be able to come up with a better solution.
Anyway, here is the C source code to the program I wrote that checks for bare address references to the $8000-$ffff range (the 2 I recently posted were all it found aside from the bare address interrupt reference and the .org):
Code: Select all
#include <stdio.h>
#include <string.h>
#define MAX_SIZE 1001
#define MIN_CHECK 0x8000 /*in case checking FDS code*/
#define MAX_CHECK 0xffff /*defaults to NES code type*/
#define CHARTEST(c) ((c==0) || (c==';'))
char *tonext(char *string) {
while(isspace(*string))
string++;
return string;
}
int main(int argc, char **argv) {
char tokens[MAX_SIZE], token[MAX_SIZE];
char token2;
char *cur = NULL;
int linecount, othertoken, temp, cflag;
FILE *file = NULL;
if(argc < 2) {
printf("addrchk <asm-file>\n");
return 0;
}
if(argc > 2) {
printf("addrchk <asm-file>\n");
perror("Too many parameters!\n");
return 1;
}
file = fopen(argv[1], "rt");
if(file==NULL) {
perror("Error opening file!\n");
return 2;
}
linecount = 0;
while(!feof(file)&&!ferror(file)) {
tokens[0] = token[0] = token2 = 0;
cur = tokens;
linecount++;
if(fgets(cur, MAX_SIZE, file)==NULL) break;
do {
cflag = 1;
cur = tonext(cur); /*get pointer to next non-whitespace*/
if(CHARTEST(*cur)) break; /*if comment, end, whatever*/
sscanf(cur, "%s", token);
cur += temp = strlen(token); /*push pointer forward*/
if(CHARTEST(token[temp-1])) break;
cflag = 0; /*passed all tests for line*/
} while(token[temp-1]==':'||token[0]=='@'); /*while still label references*/
if(cflag) continue;
if(*tonext(cur)=='=') /*if assignment*/ cur = tonext(cur) + 1;
do {
cflag = 1;
cur = tonext(cur);
if(CHARTEST(*cur)) break;
sscanf(cur, "%s", token);
cur += temp = strlen(token);
othertoken = 0;
sscanf(token, "%c%X", &token2, &othertoken); /*get value if available*/
if(token2!='$') continue; /*not hex address reference*/
if((othertoken < MIN_CHECK) || (othertoken > MAX_CHECK)) continue;
cflag = 0; /*passed all checks*/
break;
} while(token[temp-1]==','); /* while there is one more item to be read */
if(cflag) continue;
/*output if passed:*/
printf("Line #%i:\n\t%s\n", linecount, tokens);
}
fclose(file);
printf("%i rainu yonda\n", linecount);
printf("Zubari owaru deshou!\n\n");
return 0;
}
doppelganger,
Basically, I think that for now all the addressing issues making it difficult to modularize the disassembly have been found. I think from the way you wrote the disassembly, the program should have found every instance where there was a bare address that was 0x8000 < x < 0x10000.
So, good job!
Basically, I think that for now all the addressing issues making it difficult to modularize the disassembly have been found. I think from the way you wrote the disassembly, the program should have found every instance where there was a bare address that was 0x8000 < x < 0x10000.
So, good job!
-
doppelganger
- Posts: 183
- Joined: Tue Apr 05, 2005 7:30 pm
re: the loop command
I'm not sure, at this point, whether I commented the entry ".db $9645" as a dummy entry because it wasn't being used, or whether I did so because it didn't lead anywhere useful as far as the game was concerned...but I do see how that could cause problems in modularization. Fixed it.
re: the swim tile replacement offset
This isn't really a bug, per se, because it works perfectly fine for what I designed SMBDis for. However, seeing as how it will cause problems if the table is moved elsewhere, I went ahead and fixed it by simply modifying SwimTileRepOffset's definition. It will work fine as long as the player's graphics table isn't split up for whatever reason.
I don't really think the IRQ vector warrants fixing, since the game never uses IRQs.
Anyway, I fixed those two problems and uploaded it again. The link is still the same as it ever was.
I'm not sure, at this point, whether I commented the entry ".db $9645" as a dummy entry because it wasn't being used, or whether I did so because it didn't lead anywhere useful as far as the game was concerned...but I do see how that could cause problems in modularization. Fixed it.
re: the swim tile replacement offset
This isn't really a bug, per se, because it works perfectly fine for what I designed SMBDis for. However, seeing as how it will cause problems if the table is moved elsewhere, I went ahead and fixed it by simply modifying SwimTileRepOffset's definition. It will work fine as long as the player's graphics table isn't split up for whatever reason.
I don't really think the IRQ vector warrants fixing, since the game never uses IRQs.
Anyway, I fixed those two problems and uploaded it again. The link is still the same as it ever was.
Be whatever the situation demands.
doppelganger,
About the IRQ's and the ORG's, I understood those (they just appeared as output in the program). Basically, this was the program output:
Basically, it just spits it out and lets you decide what to do with it. (On my 366MHz computer, with it compiled into a Win32 Console with MinGW, it took less than a second to run.)
Anyway, now I think we can be pretty confident that this is modularizeable! ^_^
About the IRQ's and the ORG's, I understood those (they just appeared as output in the program). Basically, this was the program output:
Code: Select all
Line #645:
SwimTileRepOffset = $eeb5
Line #669:
.org $8000
Line #3525:
.dw $9645 ;dummy entry
Line #16351:
.dw $fff0 ;unused
16352 rainu yonda
Zubari owaru deshou!
Anyway, now I think we can be pretty confident that this is modularizeable! ^_^
-
doppelganger
- Posts: 183
- Joined: Tue Apr 05, 2005 7:30 pm
It should only be spitting out the ORG and the IRQ now that I updated it yesterday. That output looks like it was from before. I compiled your C code on Turbo C just now and ran it on smbdis.asm...it gave me this output...
And with that, modularization is indeed possible! :-)
Code: Select all
Line #670:
.org $8000
Line #16352:
.dw $fff0 ;unused
16352 rainu yonda
Zubari owaru deshou!
Be whatever the situation demands.
-
doppelganger
- Posts: 183
- Joined: Tue Apr 05, 2005 7:30 pm
There's not much that can be done about that. Since I have yet to see exactly how you modularized it, I will have to assume you moved the levels' enemy and area data elsewhere, which would naturally cause the addresses to change...and since the game attempts to fetch data for world 36-1 in entry to the minus world (and finds it in one of the address tables), any address changes here may cause the minus world to be different.
However, considering the whole goddamned minus world is one big glitch, I'd say leave it be. :-P
However, considering the whole goddamned minus world is one big glitch, I'd say leave it be. :-P
Be whatever the situation demands.
I can see a few goals ahead:
- Convert absolute addresses in $0000-$07FF to CA65 .res statements so that RAM can be modularized.
- Write a disassembler that takes the (copyrighted) ROM and spits out a modularized disassembly.
- Port it to UNROM/S*ROM/T*ROM. We'll have to decide what needs to be in the fixed bank and what needs to be in the switchable bank, so as to allow a hacker to add separate block types.
- Add features from SMB2J.
- Make a project to rewrite each module from scratch, like LAME.
- Hamtaro126
- Posts: 783
- Joined: Thu Jan 19, 2006 5:08 pm
The following 3 are both requests (If it is Possible) and/or ideas that I might do myself with is someday:
1: Recreate it for the SNES
(There was one for the Super Mario ALL*STARS but can NOT make a
seperate rom out of it yet. This is so that it is a fresh project instead of
making a rip-off!)
2. Possibly RE-Makeit for the PC.
(Then must rename SMB to SUPER PC BROS or something it so no copyright infrigment could not happen)
3. Create a DISassembler (could either be 1st or last) I am going to request the creator of DISTELLA (see link below) to give me the source
so I can create a recompileable ASM generetor for NES instead of the ATARI VCS/2600 (the OLD 1BPP graphic screen supported console)
*both NES and ATARI VCS/2600 are 6502 and is supported by DASM
Distella (6502 Disassembler for Atari programming in DASM) website:
http://members.cox.net/rcolbert1/distella.htm
Sorry if being a little off topic, but I just need to make a new NES
disassembler that is going to help more ROMhackers and NES developers!
-Hamtaro126
1: Recreate it for the SNES
(There was one for the Super Mario ALL*STARS but can NOT make a
seperate rom out of it yet. This is so that it is a fresh project instead of
making a rip-off!)
2. Possibly RE-Makeit for the PC.
(Then must rename SMB to SUPER PC BROS or something it so no copyright infrigment could not happen)
3. Create a DISassembler (could either be 1st or last) I am going to request the creator of DISTELLA (see link below) to give me the source
so I can create a recompileable ASM generetor for NES instead of the ATARI VCS/2600 (the OLD 1BPP graphic screen supported console)
*both NES and ATARI VCS/2600 are 6502 and is supported by DASM
Distella (6502 Disassembler for Atari programming in DASM) website:
http://members.cox.net/rcolbert1/distella.htm
Sorry if being a little off topic, but I just need to make a new NES
disassembler that is going to help more ROMhackers and NES developers!
-Hamtaro126
-
doppelganger
- Posts: 183
- Joined: Tue Apr 05, 2005 7:30 pm
short answer
You know MARIO?doppelganger wrote:The short answer: No, we don't take requests here.
-
CartCollector
- Posts: 122
- Joined: Mon Oct 30, 2006 8:32 pm
Search for "Great Giana Sisters." Yup, no trouble with copyrights there!2. Possibly RE-Makeit for the PC.
(Then must rename SMB to SUPER PC BROS or something it so no copyright infrigment could not happen)
Mario who? The R&B singer? Can't say that I do, sorry.You know MARIO?