├── UberASMTool.suo
├── UberASMTool
├── asar.dll
├── uber.ico
├── Model
│ ├── UberAssemblyFile.cs
│ ├── Code.cs
│ └── UberConfig.cs
├── UberASMTool.csproj.user
├── Logger.cs
├── Properties
│ ├── AssemblyInfo.cs
│ └── app.manifest
├── UberAssemblyProcessor.cs
├── FileUtils.cs
├── SNES.cs
├── DataCollector.cs
├── ROM.cs
├── UberASMTool.csproj
├── UberConfigProcessor.cs
├── asar.cs
└── Program.cs
├── assets
├── asm
│ ├── work
│ │ └── readme.txt
│ ├── base
│ │ ├── statusbar.asm
│ │ ├── main.asm
│ │ ├── sprites.asm
│ │ ├── overworld.asm
│ │ ├── gamemode.asm
│ │ ├── level.asm
│ │ └── global.asm
│ └── readme.txt
├── other
│ ├── status_code.asm
│ ├── global_code.asm
│ └── macro_library.asm
├── level
│ └── example.asm
├── gamemode
│ └── example.asm
├── overworld
│ └── example.asm
├── readme - library.txt
├── list.txt
└── readme.txt
├── examples
├── powerup-cycling.asm
├── conditional-map16.asm
└── readme.txt
├── .gitattributes
├── README.md
├── UberASMTool.sln
├── .gitignore
├── Specifications
└── UberAssemblyFile.txt
└── LICENSE
/UberASMTool.suo:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VitorVilela7/UberASMTool/HEAD/UberASMTool.suo
--------------------------------------------------------------------------------
/UberASMTool/asar.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VitorVilela7/UberASMTool/HEAD/UberASMTool/asar.dll
--------------------------------------------------------------------------------
/UberASMTool/uber.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VitorVilela7/UberASMTool/HEAD/UberASMTool/uber.ico
--------------------------------------------------------------------------------
/assets/asm/work/readme.txt:
--------------------------------------------------------------------------------
1 | This is the work folder of UberASM Tool. Currently inserted files are placed here.
--------------------------------------------------------------------------------
/examples/powerup-cycling.asm:
--------------------------------------------------------------------------------
1 | ; Example code for levels. Makes Mario "crazy".
2 |
3 | main:
4 | inc $19
5 | rtl
6 |
--------------------------------------------------------------------------------
/assets/other/status_code.asm:
--------------------------------------------------------------------------------
1 | ; Note that since status bar code is just a single file, the code below should return with RTS.
2 | ; There is no such init or nmi label either.
3 |
4 | main:
5 | RTS
6 |
--------------------------------------------------------------------------------
/assets/other/global_code.asm:
--------------------------------------------------------------------------------
1 | ; Note that since global code is a single file, all code below should return with RTS.
2 |
3 | load:
4 | rts
5 | init:
6 | rts
7 | main:
8 | rts
9 | ;nmi:
10 | ; rts
11 |
--------------------------------------------------------------------------------
/examples/conditional-map16.asm:
--------------------------------------------------------------------------------
1 | ; Example code for levels. Set Conditional DM16 flag 0 if the player has either Cape or Fire power-up.
2 |
3 | load:
4 | lda $19
5 | lsr
6 | and #$01
7 | sta $7FC060
8 | rtl
9 |
--------------------------------------------------------------------------------
/assets/asm/base/statusbar.asm:
--------------------------------------------------------------------------------
1 | ORG $008E1A
2 | autoclean JML statusbar_main
3 | NOP
4 |
5 | freecode
6 |
7 | statusbar_main:
8 | JSR status_bar_main
9 | LDA $1493|!addr
10 | ORA $9D
11 | JML $008E1F|!bank
12 |
--------------------------------------------------------------------------------
/assets/asm/base/main.asm:
--------------------------------------------------------------------------------
1 | !previous_mode = !sprite_RAM+(!sprite_slots*3)
2 |
3 | incsrc level.asm
4 | incsrc overworld.asm
5 | incsrc gamemode.asm
6 | incsrc global.asm
7 | incsrc sprites.asm
8 | incsrc statusbar.asm
9 |
10 |
--------------------------------------------------------------------------------
/examples/readme.txt:
--------------------------------------------------------------------------------
1 | This folder contains some simple examples on how to use UberASM Tool and some of its features. This is intended to stay on the GitHub page only.
2 |
3 | If you would like to add some interesting use case for UberASM Tool, pull requests are more than welcome!
--------------------------------------------------------------------------------
/assets/level/example.asm:
--------------------------------------------------------------------------------
1 | ; This is an example code file for UberASMTool.
2 | ; The code in this file does nothing.
3 | ; By default, it runs in level 105, because of the entry "105 example.asm" in the "level" list (in the list.txt file).
4 | ; You can safely remove that entry. After you do that, you can also safely remove this file.
5 |
6 | main:
7 | rtl
8 |
--------------------------------------------------------------------------------
/assets/gamemode/example.asm:
--------------------------------------------------------------------------------
1 | ; This is an example code file for UberASMTool.
2 | ; The code in this file does nothing.
3 | ; By default, it runs everywhere on the overworld, because of the entry "0E example.asm" in the "gamemode" list (in the list.txt file).
4 | ; You can safely remove that entry. After you do that, you can also safely remove this file.
5 |
6 | main:
7 | rtl
8 |
--------------------------------------------------------------------------------
/assets/overworld/example.asm:
--------------------------------------------------------------------------------
1 | ; This is an example code file for UberASMTool.
2 | ; The code in this file does nothing.
3 | ; By default, it runs on the Yoshi's Island map, because of the entry "1 example.asm" in the "overworld" list (in the list.txt file).
4 | ; You can safely remove that entry. After you do that, you can also safely remove this file.
5 |
6 | main:
7 | rtl
8 |
--------------------------------------------------------------------------------
/assets/asm/readme.txt:
--------------------------------------------------------------------------------
1 | This folder contains all .asm files inserted by Asar.
2 |
3 | base folder contains the base ASM files which the tools edits and
4 | moves them to the work folder. You don't need to edit any of the
5 | files unless you are a programmer.
6 |
7 | work folder contains the edited base ASM files which are inserted
8 | on the ROM. They're generated by the tool during at runtime.
--------------------------------------------------------------------------------
/assets/readme - library.txt:
--------------------------------------------------------------------------------
1 | This is the library folder. Feel free to add any file here.
2 | The system is pretty simple. Each file will have its own freecode bank.
3 | All labels created with this system will appear on all relevant level/game mode/overworld
4 | codes.
5 | You can also add whatever non-asm file you want. They will be included as binary file and
6 | their name will be the label used.
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
4 | # Custom for Visual Studio
5 | *.cs diff=csharp
6 |
7 | # Standard to msysgit
8 | *.doc diff=astextplain
9 | *.DOC diff=astextplain
10 | *.docx diff=astextplain
11 | *.DOCX diff=astextplain
12 | *.dot diff=astextplain
13 | *.DOT diff=astextplain
14 | *.pdf diff=astextplain
15 | *.PDF diff=astextplain
16 | *.rtf diff=astextplain
17 | *.RTF diff=astextplain
18 |
--------------------------------------------------------------------------------
/UberASMTool/Model/UberAssemblyFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace UberASMTool
7 | {
8 | /*
9 | * Specialized UberASM Tool assembly file
10 | */
11 | class UberAssemblyFile
12 | {
13 | public string ProcessedContents { get; set; }
14 | public string FilePath { get; set; }
15 | public bool IsLibrary { get; set; }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/UberASMTool/Model/Code.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace UberASMTool.Model
7 | {
8 | class Code
9 | {
10 | public Code(string path)
11 | {
12 | this.Path = path;
13 | this.Inserted = false;
14 | this.Main = -1;
15 | this.Init = -1;
16 | this.Nmi = -1;
17 | this.Load = -1;
18 | }
19 |
20 | public string Path;
21 | public bool Inserted;
22 | public int Main;
23 | public int Init;
24 | public int Nmi;
25 | public int Load;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/UberASMTool/UberASMTool.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | publish\
9 |
10 |
11 |
12 |
13 |
14 | en-US
15 | false
16 |
17 |
--------------------------------------------------------------------------------
/assets/asm/base/sprites.asm:
--------------------------------------------------------------------------------
1 | sprite_code:
2 | LDX.b #!sprite_slots
3 | -
4 | DEX
5 | LDA !sprite_RAM,x
6 | ORA !sprite_RAM+(!sprite_slots),x
7 | ORA !sprite_RAM+(!sprite_slots*2),x
8 | BNE +
9 | CPX #$00
10 | BNE -
11 | BRA .return
12 | +
13 | if !sa1
14 | LDA $3242,x
15 | else
16 | LDA $14C8,x
17 | endif
18 | BEQ .clear
19 | LDA !sprite_RAM,x
20 | STA $00
21 | LDA !sprite_RAM+(!sprite_slots),x
22 | STA $01
23 | LDA !sprite_RAM+(!sprite_slots*2),x
24 | STA $02
25 | PHK
26 | PEA.w .next
27 | JMP [!dp]
28 | .next
29 | CPX #$00
30 | BNE -
31 | .return
32 | RTS
33 | .clear
34 | LDA #$00
35 | STA !sprite_RAM,x
36 | STA !sprite_RAM+(!sprite_slots),x
37 | STA !sprite_RAM+(!sprite_slots*2),x
38 | BRA -
39 |
--------------------------------------------------------------------------------
/UberASMTool/Model/UberConfig.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using UberASMTool.Model;
6 |
7 | namespace UberASMTool
8 | {
9 | class UberConfig
10 | {
11 | public bool VerboseMode { get; set; }
12 | public string ROMPath { get; set; }
13 | public string GlobalFile { get; set; }
14 | public string StatusBarFile { get; set; }
15 | public string MacroLibraryFile { get; set; }
16 | public int[][][] FileASMList { get; set; }
17 | public int[][] GlobalASMList { get; set; }
18 | public int SpriteCodeFreeRAM { get; set; }
19 | public int SpriteCodeFreeBWRAM { get; set; }
20 | public Code[] CodeList { get; set; }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | UberASM Tool
2 | ============
3 |
4 | "UberASM Tool" is a tool that allows to insert common codes without relying to
5 | patches. The main objective is reducing the number of patches and at the same
6 | time allow for inserting ASM file easier and develop new codes quicker compared
7 | to other approaches.
8 |
9 | ## Building
10 | How to make the ZIP file for uploading a release:
11 |
12 | 1. Compile the C# source code using Visual Studio Community.
13 | 2. Copy UberASMTool.exe and UberASMTool.pdb from UberASMTool/bin/Release to the
14 | assets folder.
15 | 3. Copy asar.dll from the UberASMTool folder to the assets folder.
16 | 4. Create a ZIP file from all files inside assets.
17 |
18 | ## Examples
19 |
20 | At [examples] there is some ASM files that can be used for testing and/or for
21 | figuring out some specific UberASM Tool features.
--------------------------------------------------------------------------------
/assets/asm/base/overworld.asm:
--------------------------------------------------------------------------------
1 | ORG $00A1C3
2 | autoclean JML main_ow
3 |
4 | ORG $00A18F
5 | autoclean JML init_ow
6 | NOP #2
7 |
8 | freecode
9 |
10 | ; Do not touch, nor move that.
11 | db "uber"
12 | OW_asm_table:
13 | OW_init_table:
14 | OW_nmi_table:
15 | db "tool"
16 |
17 | main_ow:
18 | PHB
19 | JSL $7F8000
20 |
21 | LDX $0DB3|!addr
22 | LDA $1F11|!addr,x
23 | ASL
24 | ADC $1F11|!addr,x
25 | TAX
26 | REP #$20
27 | LDA.l OW_asm_table,x
28 | STA $00
29 | LDA.l OW_asm_table+1,x
30 | JSL run_code
31 | PLB
32 | JML $00A1C7|!bank
33 |
34 | init_ow:
35 | PHK
36 | PEA.w .return-1
37 | PEA.w $84CE
38 | JML $0092A0|!bank
39 | .return
40 | PHB
41 | LDX $0DB3|!addr
42 | LDA $1F11|!addr,x
43 | ASL
44 | ADC $1F11|!addr,x
45 | TAX
46 | REP #$20
47 | LDA.l OW_init_table,x
48 | STA $00
49 | LDA.l OW_init_table+1,x
50 | JSL run_code
51 | PLB
52 | JML $0093F4|!bank
53 |
--------------------------------------------------------------------------------
/UberASMTool.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual C# Express 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UberASMTool", "UberASMTool\UberASMTool.csproj", "{B17060A9-56FF-49C8-9182-A46BD4185544}"
5 | EndProject
6 | Global
7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
8 | Debug|x86 = Debug|x86
9 | Release|x86 = Release|x86
10 | EndGlobalSection
11 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
12 | {B17060A9-56FF-49C8-9182-A46BD4185544}.Debug|x86.ActiveCfg = Debug|x86
13 | {B17060A9-56FF-49C8-9182-A46BD4185544}.Debug|x86.Build.0 = Debug|x86
14 | {B17060A9-56FF-49C8-9182-A46BD4185544}.Release|x86.ActiveCfg = Release|x86
15 | {B17060A9-56FF-49C8-9182-A46BD4185544}.Release|x86.Build.0 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(SolutionProperties) = preSolution
18 | HideSolutionNode = FALSE
19 | EndGlobalSection
20 | EndGlobal
21 |
--------------------------------------------------------------------------------
/assets/asm/base/gamemode.asm:
--------------------------------------------------------------------------------
1 | org $009322
2 | autoclean JML gamemode_main
3 |
4 | freecode
5 |
6 | db "uber" ; Don't touch or move these tables.
7 | gamemode_main_table:
8 | gamemode_init_table:
9 | gamemode_nmi_table:
10 | db "tool"
11 |
12 |
13 | gamemode_main:
14 | LDA $0100|!addr
15 | CMP #$2A
16 | BCS new_mode
17 | PHK
18 | PEA.w return-1
19 | BRA do_game_mode
20 |
21 | new_mode:
22 | LDA #$00
23 | PHA
24 | PEA $9311
25 |
26 | do_game_mode:
27 | PHB
28 | PHK
29 | PLB
30 | LDA $0100|!addr
31 | CMP !previous_mode
32 | STA !previous_mode
33 | REP #$30
34 | PHP
35 | AND #$00FF
36 | ASL
37 | ADC !previous_mode
38 | TAX
39 | PLP
40 | BNE +
41 | LDA gamemode_main_table,x
42 | STA $00
43 | LDA gamemode_main_table+1,x
44 | BRA ++
45 | +
46 | LDA gamemode_init_table,x
47 | STA $00
48 | LDA gamemode_init_table+1,x
49 | ++
50 | JSL run_code
51 | PLB
52 | RTL
53 |
54 | return:
55 | LDA $0100|!addr
56 | ASL
57 | TAX
58 | LDA $9329,x
59 | STA $00
60 | LDA $932A,x
61 | STA $01
62 | if !bank8 != $00
63 | LDA #!bank8
64 | STA $02
65 | else
66 | STZ $02
67 | endif
68 | JML [!dp]
69 |
--------------------------------------------------------------------------------
/UberASMTool/Logger.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace UberASMTool
7 | {
8 | class Logger
9 | {
10 | private StringBuilder aggregator;
11 |
12 | public static Logger GetLogger()
13 | {
14 | return new Logger(new StringBuilder());
15 | }
16 |
17 | private Logger(StringBuilder baseBuilder)
18 | {
19 | this.aggregator = baseBuilder;
20 | }
21 |
22 | public string GetOutput()
23 | {
24 | return aggregator.ToString();
25 | }
26 |
27 | public void Error(string description, int line = -1)
28 | {
29 | WriteLog(description, line, true);
30 | }
31 |
32 | public void Warning(string description, int line = -1)
33 | {
34 | WriteLog(description, line, false);
35 | }
36 |
37 | public void WriteLog(string description, int line = -1, bool error = true)
38 | {
39 | if (line == -1)
40 | {
41 | this.aggregator.AppendLine($"{(error ? "Error" : "Warning")}: {description}");
42 | }
43 | else
44 | {
45 | this.aggregator.AppendLine($"{(error ? "Error" : "Warning")}: line {line + 1} - {description}");
46 | }
47 | }
48 |
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/UberASMTool/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("UberASM Tool")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("Vitor Vilela")]
12 | [assembly: AssemblyProduct("UberASM Tool")]
13 | [assembly: AssemblyCopyright("Copyright © 2019")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("ca32f2f6-4dd8-4bee-a2e2-79ff047646ff")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.5.0.0")]
36 | [assembly: AssemblyFileVersion("1.5.0.0")]
37 |
--------------------------------------------------------------------------------
/assets/asm/base/level.asm:
--------------------------------------------------------------------------------
1 | !level = $010B|!addr ;Patches rely on this, changing this is bad. Don't.
2 |
3 | ORG $05D8B7
4 | BRA +
5 | NOP #3 ;the levelnum patch goes here in many ROMs, just skip over it
6 | +
7 | REP #$30
8 | LDA $0E
9 | STA !level
10 | ASL
11 | CLC
12 | ADC $0E
13 | TAY
14 | LDA.w $E000,Y
15 | STA $65
16 | LDA.w $E001,Y
17 | STA $66
18 | LDA.w $E600,Y
19 | STA $68
20 | LDA.w $E601,Y
21 | STA $69
22 | BRA +
23 | ORG $05D8E0
24 | +
25 |
26 | ORG $00A242
27 | autoclean JML main
28 | NOP
29 |
30 | ORG $00A295
31 | NOP #4
32 |
33 | ORG $00A5EE
34 | autoclean JML init
35 |
36 | freecode
37 |
38 | ;Editing or moving these tables breaks things. don't.
39 | db "uber"
40 | level_asm_table:
41 | level_init_table:
42 | level_nmi_table:
43 | level_load_table:
44 | db "tool"
45 |
46 | main:
47 | PHB
48 | LDA $13D4|!addr
49 | BNE +
50 | JSL $7F8000
51 | +
52 | REP #$30
53 | LDA !level
54 | ASL
55 | ADC !level
56 | TAX
57 | LDA.l level_asm_table,x
58 | STA $00
59 | LDA.l level_asm_table+1,x
60 | JSL run_code
61 | PLB
62 |
63 | LDA $13D4|!addr
64 | BEQ +
65 | JML $00A25B|!bank
66 | +
67 | JML $00A28A|!bank
68 |
69 | init:
70 | PHB
71 | LDA !level
72 | ASL
73 | ADC !level
74 | TAX
75 | LDA.l level_init_table,x
76 | STA $00
77 | LDA.l level_init_table+1,x
78 | JSL run_code
79 | PLB
80 |
81 | PHK
82 | PEA.w .return-1
83 | PEA $84CE
84 | JML $00919B|!bank
85 | .return
86 | JML $00A5F3|!bank
87 |
88 | run_code:
89 | STA $01
90 | PHA
91 | PLB
92 | PLB
93 | SEP #$30
94 | JML [!dp]
95 |
96 | null_pointer:
97 | RTL
98 |
--------------------------------------------------------------------------------
/UberASMTool/UberAssemblyProcessor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace UberASMTool
7 | {
8 | /*
9 | * Specialized in processing input assembly files and generating UberAssemblyFile
10 | */
11 | class UberAssemblyProcessor
12 | {
13 | public UberAssemblyFile LoadAndProcessFile(string input, bool library, string fileName, string directoryBase, string macroLibraryFile)
14 | {
15 | var processed = ProcessAndGenerateFile(input, library, fileName, directoryBase, macroLibraryFile);
16 |
17 | return new UberAssemblyFile
18 | {
19 | ProcessedContents = processed,
20 | IsLibrary = library,
21 | FilePath = fileName
22 | };
23 | }
24 |
25 | private string ProcessAndGenerateFile(string input, bool library, string fileName, string directoryBase, string macroLibraryFile)
26 | {
27 | string fix = FileUtils.FixPath(fileName, directoryBase);
28 | StringBuilder output = new StringBuilder();
29 |
30 | if (library)
31 | {
32 | output.AppendFormat("incsrc \"{1}{0}\" : ", Program.LabelLibraryFile, fix);
33 | }
34 | output.AppendFormat("incsrc \"{1}{0}\" : ", macroLibraryFile, fix);
35 | output.Append("freecode cleaned : ");
36 | output.AppendLine("print \"_startl \", pc");
37 | output.AppendLine(input);
38 | output.AppendLine("print \"_endl \", pc");
39 | return output.ToString();
40 | }
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/UberASMTool/FileUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading;
7 |
8 | namespace UberASMTool
9 | {
10 | static class FileUtils
11 | {
12 | const int maxAttempts = 1000;
13 | const int idleTimeBetweenAttempt = 10;
14 |
15 | public static bool ForceCreate(string fileName, string contents)
16 | {
17 | for (int i = 0; i < maxAttempts; ++i)
18 | {
19 | try
20 | {
21 | File.WriteAllText(fileName, contents);
22 | return true;
23 | }
24 | catch
25 | {
26 | Thread.Sleep(idleTimeBetweenAttempt);
27 | }
28 | }
29 |
30 | return false;
31 | }
32 |
33 | public static bool ForceDelete(string fileName)
34 | {
35 | if (!File.Exists(fileName))
36 | {
37 | return true;
38 | }
39 |
40 | for (int i = 0; i < maxAttempts; ++i)
41 | {
42 | try
43 | {
44 | File.Delete(fileName);
45 | return true;
46 | }
47 | catch
48 | {
49 | Thread.Sleep(idleTimeBetweenAttempt);
50 | }
51 | }
52 |
53 | return false;
54 | }
55 |
56 | public static int DirectoryDepth(string fileName, string directoryBase)
57 | {
58 | string path1 = Path.GetFullPath(directoryBase);
59 | string path2 = Path.GetFullPath(fileName);
60 | char[] separators = new[] { Path.PathSeparator, Path.AltDirectorySeparatorChar,
61 | Path.DirectorySeparatorChar, Path.VolumeSeparatorChar };
62 |
63 | return path2.Substring(path1.Length).Split(separators, StringSplitOptions.RemoveEmptyEntries).Length;
64 | }
65 |
66 | public static string FixPath(string fileName, string directoryBase)
67 | {
68 | int depth = DirectoryDepth(fileName, directoryBase);
69 | return String.Join("", Enumerable.Repeat("../", depth));
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/UberASMTool/Properties/app.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
47 |
--------------------------------------------------------------------------------
/assets/list.txt:
--------------------------------------------------------------------------------
1 | verbose: on
2 |
3 |
4 |
5 | # UBERASM TOOL: LIST FILE
6 | # This is a list of all the code files you're using, and when to run them.
7 |
8 |
9 |
10 | # LEVEL CODE
11 | # Code files in this list will be run in specific levels.
12 |
13 | # EXAMPLE:
14 | # To run the code from the file "mycode.asm" in level 105,
15 | # put "mycode.asm" in the "level" folder
16 | # and add an entry to this list saying "105 mycode.asm"
17 | # (without the quotes, and without # in front).
18 |
19 | # - You can use the same code file in multiple levels!
20 | # - If you want to use multiple code files in the same level,
21 | # check https://www.smwcentral.net/?p=faq&page=1515827-uberasm .
22 | # - To run the same code in every level, apply it to game mode 14 (see below).
23 |
24 | level:
25 | 105 example.asm
26 |
27 |
28 |
29 |
30 |
31 | # OVERWORLD CODE
32 | # Code files in this list will be run on specific overworld maps.
33 |
34 | # Each map has a number:
35 | # 0: Main Map
36 | # 1: Yoshi's Island
37 | # 2: Vanilla Dome
38 | # 3: Forest of Illusion
39 | # 4: Valley of Bowser
40 | # 5: Special World
41 | # 6: Star Road
42 |
43 | # EXAMPLE:
44 | # To run the code from the file "mycode.asm" on the Vanilla Dome map,
45 | # put "mycode.asm" in the "overworld" folder
46 | # and add an entry to this list saying "2 mycode.asm"
47 | # (without the quotes, and without # in front).
48 |
49 | overworld:
50 | 1 example.asm
51 |
52 |
53 |
54 |
55 |
56 | # GAME MODE CODE
57 | # Code files in this list will be run during specific game modes.
58 |
59 | # Some common game modes are:
60 | # 01: "Nintendo Presents" screen
61 | # 07: Title Screen
62 | # 08: Title Screen (File select)
63 | # 0E: Overworld
64 | # 14: Level
65 | # You can also define your own (from 2A to FF).
66 |
67 | # EXAMPLE:
68 | # To run the code from the file "mycode.asm" in game mode 14 (i.e. in all levels),
69 | # put "mycode.asm" in the "gamemode" folder
70 | # and add an entry to this list saying "14 mycode.asm"
71 | # (without the quotes, and without # in front).
72 |
73 | gamemode:
74 | 0E example.asm
75 |
76 |
77 |
78 |
79 |
80 | # OTHER OPTIONS
81 |
82 | # Global code - this will be run all the time.
83 | global: other/global_code.asm
84 |
85 | # Status bar code - this will be run when the status bar is drawn to the screen.
86 | statusbar: other/status_code.asm
87 |
88 | # A file containing macros.
89 | macrolib: other/macro_library.asm
90 |
91 | # Sprite-related RAM (see README). You probably don't need to change this.
92 | sprite: $7FAC80 # 38 (SNES) or 68 (SA-1) bytes of free RAM.
93 | sprite-sa1: $41AC80 # Optional for SA-1 ROMs.
94 |
95 | # The name of your ROM file - this will be used if you don't specify a ROM name
96 | # when running UberASM Tool.
97 | rom: SMW.smc
98 |
--------------------------------------------------------------------------------
/UberASMTool/SNES.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace UberASMTool
4 | {
5 | static class SNES
6 | {
7 | public static int[] snesbanks = new int[] {
8 | // banks to be mapped for each megabyte
9 | // sa1rom : 0x00, 0x20, 0x80, 0xA0
10 | // lorom : 0x00, 0x20, 0x40, 0x60
11 | // fastrom: 0x80, 0xA0, 0xC0, 0xE0
12 | 0x80, 0xA0, 0xC0, 0xE0,
13 | 0, 0, 0, 0, // 8mb roms
14 | };
15 |
16 | public static int[] pcbanks = new int[] {
17 | // inversed to return to pc address
18 | 0, // banks 00-1F
19 | 1, // banks 20-3F
20 | 2, // banks 40-5F
21 | 3, // banks 60-7F
22 | 0, // banks 80-9F
23 | 1, // banks A0-BF
24 | 2, // banks C0-DF
25 | 3, // banks E0-FF
26 | };
27 |
28 | public static void DetectAddressing(int romheader)
29 | {
30 | switch (romheader)
31 | {
32 | case 0x23:
33 | // SA-1
34 | snesbanks[0] = 0x00;
35 | snesbanks[1] = 0x20;
36 | snesbanks[2] = 0x80;
37 | snesbanks[3] = 0xA0;
38 | snesbanks[4] = 0xA0; // map rest to 0xA0, but i'm not sure...
39 | snesbanks[5] = 0xA0;
40 | snesbanks[6] = 0xA0;
41 | snesbanks[7] = 0xA0;
42 | pcbanks[0] = 0; // 0-1F
43 | pcbanks[1] = 1; // 20-3F
44 | pcbanks[2] = 0; // 40-5F \ this is SA-1/SNES RAM
45 | pcbanks[3] = 0; // 60-7F /
46 | pcbanks[4] = 2; // 80-9F
47 | pcbanks[5] = 3; // A0-BF <-- May variable.
48 | pcbanks[6] = 0; // C0-DF \ this is SA-1 HiROM
49 | pcbanks[7] = 0; // E0-FF /
50 | break;
51 |
52 | default:
53 | // FastROM
54 | snesbanks[0] = 0x80;
55 | snesbanks[1] = 0xA0;
56 | snesbanks[2] = 0xC0;
57 | snesbanks[3] = 0xE0;
58 | snesbanks[4] = 0x00; // a... FastROM don't go up to 8MB...
59 | snesbanks[5] = 0x00;
60 | snesbanks[6] = 0x00;
61 | snesbanks[7] = 0x00;
62 | pcbanks[0] = 0;
63 | pcbanks[1] = 1;
64 | pcbanks[2] = 2;
65 | pcbanks[3] = 3;
66 | pcbanks[4] = 0;
67 | pcbanks[5] = 1;
68 | pcbanks[6] = 2;
69 | pcbanks[7] = 3;
70 | break;
71 | }
72 | }
73 |
74 | public static int ToPC(int snes)
75 | {
76 | return ((pcbanks[(snes & 0xe00000) >> 21]) << 20) | ((snes & 0x1f0000) >> 1) | (snes & 0x7fff);
77 | }
78 |
79 | public static int ToPCHeadered(int snes, bool header)
80 | {
81 | int val = ((pcbanks[(snes & 0xe00000) >> 21]) << 20) | ((snes & 0x1f0000) >> 1) | (snes & 0x7fff);
82 | return val + (header ? 512 : 0);
83 | }
84 |
85 | public static int FromPC(int pc)
86 | {
87 | return (snesbanks[(pc & 0xe00000) >> 20] << 16) | ((pc & 0x1f8000) << 1) | (pc & 0x7fff) | 0x8000;
88 | }
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/assets/asm/base/global.asm:
--------------------------------------------------------------------------------
1 | ORG $00804E
2 | autoclean JML clear_pointers
3 |
4 | ORG $00806B
5 | autoclean JML _global_main
6 |
7 | ORG $008176
8 | autoclean JML nmi_hijack
9 | NOP #2
10 |
11 | ORG $05808C
12 | JML load
13 | NOP
14 |
15 | freecode
16 |
17 | ; Do not edit nor move that.
18 | ; That's a special prot table for cleaning external data and codes.
19 | db "uber"
20 | prot_table:
21 | db "tool"
22 |
23 | clear_pointers:
24 | STA $7F8182
25 | LDA #$00
26 | LDX #!sprite_slots*3-1
27 | -
28 | STA !sprite_RAM,x
29 | DEX
30 | BPL -
31 |
32 | LDA #$00
33 | STA !previous_mode+1
34 | DEC
35 | STA !previous_mode
36 |
37 | if !sa1
38 | LDA #$60
39 | STA $1E93 ; edit SA-1 main loop to allow simple usage of it
40 | endif
41 |
42 | JSR global_init
43 | JML $008052|!bank
44 |
45 | _global_main:
46 | if !sa1
47 | JSR $1E8F
48 | else
49 | LDA $10
50 | BEQ _global_main
51 | endif
52 | JSR global_main
53 |
54 | LDA $0100|!addr
55 | CMP #$14
56 | BNE +
57 | JSR sprite_code
58 | +
59 |
60 | JML $00806F|!bank
61 |
62 | load:
63 | PHB
64 | SEP #$30
65 | JSR global_load
66 | REP #$30
67 | LDA !level
68 | ASL
69 | ADC !level
70 | TAX
71 | LDA.l level_load_table,x
72 | STA $00
73 | LDA.l level_load_table+1,x
74 | JSL run_code
75 | PLB
76 | REP #$10
77 | PHK
78 | PEA.w .return-1
79 | PEA.w $058125-1
80 | JML $0583AC|!bank
81 | .return
82 | SEP #$30
83 | JML $058091|!bank
84 |
85 |
86 | nmi_hijack:
87 | LDA $4210 ; This is SNES hardware stuff, so don't remove it please.
88 |
89 | PHB
90 |
91 | ; Include various probabilities for optimal performance.
92 | if !global_nmi == 1
93 | JSR global_nmi
94 | endif
95 |
96 | ; I guess I could have done this better, like pre-storing the tables into RAM during INIT or like,
97 | ; however I wanted to all hacks have minimum safetly to this run properly, so I decided to use
98 | ; temporary memory instead.
99 | if !gamemode_nmi == 1 || !level_nmi == 1 || !overworld_nmi == 1
100 | PEI ($6E)
101 | PEI ($70)
102 | endif
103 |
104 | if !gamemode_nmi == 1
105 | REP #$20
106 | LDA $0100|!addr
107 | AND #$00FF
108 | STA $6E
109 | ASL
110 | ADC $6E
111 | TAX
112 | LDA gamemode_nmi_table,x
113 | STA $6E
114 | LDA gamemode_nmi_table+1,x
115 | JSL nmi_run_code
116 | endif
117 |
118 | if !level_nmi == 1 && !overworld_nmi == 0
119 | ; LevelNMI only.
120 | LDA $0100|!addr
121 | CMP #$13
122 | BEQ ++
123 | CMP #$14
124 | BNE +
125 | ++ REP #$30
126 | LDA !level
127 | ASL
128 | ADC !level
129 | TAX
130 | LDA.l level_nmi_table,x
131 | STA $6E
132 | LDA.l level_nmi_table+1,x
133 | JSL nmi_run_code
134 | +
135 | endif
136 |
137 | if !level_nmi == 1 && !overworld_nmi == 1
138 | ; Level NMI + Overworld NMI
139 | LDA $0100|!addr
140 | CMP #$13
141 | BEQ ++
142 | CMP #$14
143 | BNE +
144 | ++ REP #$30
145 | LDA !level
146 | ASL
147 | ADC !level
148 | TAX
149 | LDA.l level_nmi_table,x
150 | STA $6E
151 | LDA.l level_nmi_table+1,x
152 | JSL nmi_run_code
153 |
154 | REP #$20
155 | PLA
156 | STA $70
157 | PLA
158 | STA $6E
159 | SEP #$20
160 |
161 | PLB
162 | LDA $1DFB|!addr ; return
163 | JML $00817C|!bank
164 |
165 | + CMP #$0D
166 | BEQ ++
167 | CMP #$0E
168 | BNE +
169 |
170 | ++ LDX $0DB3|!addr
171 | LDA $1F11|!addr,x
172 | ASL
173 | ADC $1F11|!addr,x
174 | TAX
175 | REP #$20
176 | LDA.l OW_nmi_table,x
177 | STA $6E
178 | LDA.l OW_nmi_table+1,x
179 | JSL nmi_run_code
180 | +
181 | endif
182 |
183 | if !level_nmi == 0 && !overworld_nmi == 1
184 | ; Overworld NMI only.
185 | LDA $0100|!addr
186 | CMP #$0D
187 | BEQ ++
188 | CMP #$0E
189 | BNE +
190 |
191 | ++ LDX $0DB3|!addr
192 | LDA $1F11|!addr,x
193 | ASL
194 | ADC $1F11|!addr,x
195 | TAX
196 | REP #$20
197 | LDA.l OW_nmi_table,x
198 | STA $6E
199 | LDA.l OW_nmi_table+1,x
200 | JSL nmi_run_code
201 | +
202 | endif
203 |
204 | if !gamemode_nmi == 1 || !level_nmi == 1 || !overworld_nmi == 1
205 | REP #$20
206 | PLA
207 | STA $70
208 | PLA
209 | STA $6E
210 | SEP #$20
211 | endif
212 |
213 | PLB
214 | LDA $1DFB|!addr
215 | JML $00817C|!bank
216 |
217 | nmi_run_code:
218 | STA $6F
219 | PHA
220 | PLB
221 | PLB
222 | SEP #$30
223 | JML [$006E|!dp]
224 |
225 |
--------------------------------------------------------------------------------
/UberASMTool/DataCollector.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 |
6 | namespace UberASMTool
7 | {
8 | class DataCollector
9 | {
10 | private readonly ROM rom;
11 | private readonly List freespacePointerList;
12 |
13 | public DataCollector(ROM romData)
14 | {
15 | rom = romData;
16 | freespacePointerList = new List();
17 | }
18 |
19 | public int[] GetCollectedPointers()
20 | {
21 | int[] list = freespacePointerList.ToArray();
22 | freespacePointerList.Clear();
23 |
24 | return list;
25 | }
26 |
27 | public void CheckPreviousUberData()
28 | {
29 | //gamemode - $009322+1
30 | //levelASM - $00A242+1
31 | //overworld - $00A1C3+1
32 | //global - $00804E+1
33 |
34 | CleanPointerTable(0x1323, 256, false);
35 | CleanPointerTable(0x2243, 512, true);
36 | CleanPointerTable(0x21C4, 7, false);
37 |
38 | // clear external pointer table
39 | int ptr = CheckPointer(0x4F);
40 |
41 | if (ptr == -1)
42 | {
43 | return;
44 | }
45 |
46 | ptr -= 3;
47 |
48 | while (!CheckForUberSignature(ptr - 1))
49 | {
50 | int pointer = rom.Read24(ptr);
51 | if (!freespacePointerList.Contains(pointer))
52 | {
53 | freespacePointerList.Add(pointer);
54 | }
55 | ptr -= 3;
56 | }
57 | }
58 |
59 | private bool CheckForUberSignature(int ptr)
60 | {
61 | var str = rom.ReadBlock(ptr, 4);
62 | return (str[0] == (byte)'u' && str[1] == (byte)'b' && str[2] == (byte)'e' && str[3] == (byte)'r');
63 | }
64 |
65 | private int CheckPointer(int offset)
66 | {
67 | int ptr = SNES.ToPC(rom.Read24(offset));
68 |
69 | if (ptr < 0x80000 || ptr > rom.romSize)
70 | {
71 | // does not seem to be a valid pointer.
72 | return -1;
73 | }
74 |
75 | ptr -= 4;
76 |
77 | var str = rom.ReadBlock(ptr, 4);
78 | if (!(str[0] == (byte)'t' && str[1] == (byte)'o' && str[2] == (byte)'o' && str[3] == (byte)'l'))
79 | {
80 | // okay, does not seem legit.
81 | return -1;
82 | }
83 |
84 | return ptr;
85 | }
86 |
87 | private void CleanPointerTable(int offset, int pointerCount, bool ext)
88 | {
89 | int ptr = CheckPointer(offset);
90 |
91 | if (ptr == -1)
92 | {
93 | return;
94 | }
95 |
96 | ptr -= pointerCount * 6;
97 |
98 | bool nmi = false;
99 | bool load = false;
100 |
101 | scan:
102 | if (!CheckForUberSignature(ptr - 4))
103 | {
104 | if (load)
105 | {
106 | // does not seem legit.
107 | return;
108 | }
109 | else if (nmi)
110 | {
111 | if (ext)
112 | {
113 | load = true;
114 | ptr -= pointerCount * 3;
115 | goto scan;
116 | }
117 | else
118 | {
119 | //does not seem legit..
120 | return;
121 | }
122 | }
123 | else
124 | {
125 | nmi = true;
126 | ptr -= pointerCount * 3;
127 | goto scan;
128 | }
129 | }
130 |
131 | int total = pointerCount * (load ? 4 : (nmi ? 3 : 2));
132 |
133 | for (int i = 0; i < total; ++i, ptr += 3)
134 | {
135 | int pointer = rom.Read24(ptr);
136 | if (!freespacePointerList.Contains(pointer))
137 | {
138 | freespacePointerList.Add(pointer);
139 | }
140 | }
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/UberASMTool/ROM.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | // This controls ROM operations
5 | // Read/Write, RATS, FreeSpace Detection,
6 | // etc.
7 |
8 |
9 | namespace UberASMTool
10 | {
11 | class ROM
12 | {
13 | const int maxRomSize = 8389120; // 8mb + header
14 | const int minRomSize = 524288; // 512kb
15 | const int minRomExSize = 1048576; // 1mb
16 |
17 | public byte[] romData;
18 | public byte[] header;
19 |
20 | public bool canOperate;
21 | public ushort romType;
22 | public bool containsHeader;
23 | public string romLocation;
24 | public int romSize;
25 | public bool sa1;
26 |
27 | public ROM(string filename)
28 | {
29 | this.romData = File.ReadAllBytes(filename);
30 | this.canOperate = false;
31 | this.romType = 0;
32 | this.containsHeader = false;
33 | this.romLocation = filename;
34 | }
35 |
36 | public void Init()
37 | {
38 | int romLength = romData.Length;
39 |
40 | if (romLength > maxRomSize) throw new Exception("ROM too large!");
41 | if (romLength < minRomSize) throw new Exception("ROM too small for Super Mario World!");
42 | if (romLength < minRomExSize) throw new Exception("ROM must be expanded to 1MB first!");
43 |
44 | this.containsHeader = (romLength % 0x8000) == 512;
45 |
46 | if ((romLength % 0x8000) != 0 && !this.containsHeader)
47 | throw new Exception("Invalid ROM block align! ROM corrupted?");
48 |
49 | // 21 bytes long
50 | // aaaaaaaaaaa123456789012345678901
51 | string smw = "SUPER MARIOWORLD ";
52 |
53 | int position = 0x7FC0 + (this.containsHeader ? 512 : 0);
54 |
55 | foreach (char character in smw)
56 | {
57 | if (romData[position++] != character)
58 | throw new Exception("This isn't a Super Mario World ROM!");
59 | }
60 |
61 | romType &= 0xffff;
62 | romType |= romData[position++];
63 | romType |= (ushort)(romData[position++] << 8);
64 |
65 | romSize = romLength - (this.containsHeader ? 512 : 0);
66 | header = new byte[512];
67 |
68 | if (this.containsHeader)
69 | {
70 | byte[] dupe = new byte[romSize];
71 | Array.Copy(romData, 0, header, 0, 512);
72 | Array.Copy(romData, 512, dupe, 0, romSize);
73 | romData = null;
74 | romData = dupe;
75 | }
76 |
77 | canOperate = true;
78 | sa1 = (romType & 255) == 0x23;
79 | }
80 |
81 | public void Close()
82 | {
83 | romData = null;
84 | romType = 0;
85 | canOperate = false;
86 | containsHeader = false;
87 | romLocation = "";
88 | romSize = 0;
89 | }
90 |
91 | public void Save()
92 | {
93 | byte[] final = new byte[romSize + (containsHeader ? 512 : 0)];
94 | Array.Copy(romData, 0, final, containsHeader ? 512 : 0, romSize);
95 |
96 | if (containsHeader)
97 | {
98 | Array.Copy(header, romData, 512);
99 | }
100 |
101 | File.WriteAllBytes(romLocation, final);
102 | }
103 |
104 | public bool WriteBlock(byte[] block, int position)
105 | {
106 | try
107 | {
108 | if (!this.canOperate) throw new ArgumentNullException();
109 | Array.Copy(block, 0, romData, position, block.Length);
110 | block = null;
111 | return true;
112 | }
113 |
114 | catch
115 | {
116 | return false;
117 | }
118 | }
119 |
120 | public int Read24(int pos)
121 | {
122 | try
123 | {
124 | if (!this.canOperate) throw new ArgumentNullException();
125 | return romData[pos] | (romData[pos + 1] << 8) | (romData[pos + 2] << 16);
126 | }
127 |
128 | catch
129 | {
130 | return 0;
131 | }
132 | }
133 |
134 | public byte[] ReadBlock(int position, int length)
135 | {
136 | try
137 | {
138 | if (!this.canOperate) throw new ArgumentNullException();
139 | byte[] output = new byte[length];
140 | Array.Copy(romData, position, output, 0, length);
141 | return output;
142 | }
143 |
144 | catch
145 | {
146 | return null;
147 | }
148 | }
149 | }
150 | }
151 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Visual Studio 2015 cache/options directory
14 | .vs/
15 | # Uncomment if you have tasks that create the project's static files in wwwroot
16 | #wwwroot/
17 |
18 | # MSTest test Results
19 | [Tt]est[Rr]esult*/
20 | [Bb]uild[Ll]og.*
21 |
22 | # NUNIT
23 | *.VisualState.xml
24 | TestResult.xml
25 |
26 | # Build Results of an ATL Project
27 | [Dd]ebugPS/
28 | [Rr]eleasePS/
29 | dlldata.c
30 |
31 | # DNX
32 | project.lock.json
33 | artifacts/
34 |
35 | *_i.c
36 | *_p.c
37 | *_i.h
38 | *.ilk
39 | *.meta
40 | *.obj
41 | *.pch
42 | *.pdb
43 | *.pgc
44 | *.pgd
45 | *.rsp
46 | *.sbr
47 | *.tlb
48 | *.tli
49 | *.tlh
50 | *.tmp
51 | *.tmp_proj
52 | *.log
53 | *.vspscc
54 | *.vssscc
55 | .builds
56 | *.pidb
57 | *.svclog
58 | *.scc
59 |
60 | # Chutzpah Test files
61 | _Chutzpah*
62 |
63 | # Visual C++ cache files
64 | ipch/
65 | *.aps
66 | *.ncb
67 | *.opendb
68 | *.opensdf
69 | *.sdf
70 | *.cachefile
71 | *.VC.db
72 | *.VC.VC.opendb
73 |
74 | # Visual Studio profiler
75 | *.psess
76 | *.vsp
77 | *.vspx
78 | *.sap
79 |
80 | # TFS 2012 Local Workspace
81 | $tf/
82 |
83 | # Guidance Automation Toolkit
84 | *.gpState
85 |
86 | # ReSharper is a .NET coding add-in
87 | _ReSharper*/
88 | *.[Rr]e[Ss]harper
89 | *.DotSettings.user
90 |
91 | # JustCode is a .NET coding add-in
92 | .JustCode
93 |
94 | # TeamCity is a build add-in
95 | _TeamCity*
96 |
97 | # DotCover is a Code Coverage Tool
98 | *.dotCover
99 |
100 | # NCrunch
101 | _NCrunch_*
102 | .*crunch*.local.xml
103 | nCrunchTemp_*
104 |
105 | # MightyMoose
106 | *.mm.*
107 | AutoTest.Net/
108 |
109 | # Web workbench (sass)
110 | .sass-cache/
111 |
112 | # Installshield output folder
113 | [Ee]xpress/
114 |
115 | # DocProject is a documentation generator add-in
116 | DocProject/buildhelp/
117 | DocProject/Help/*.HxT
118 | DocProject/Help/*.HxC
119 | DocProject/Help/*.hhc
120 | DocProject/Help/*.hhk
121 | DocProject/Help/*.hhp
122 | DocProject/Help/Html2
123 | DocProject/Help/html
124 |
125 | # Click-Once directory
126 | publish/
127 |
128 | # Publish Web Output
129 | *.[Pp]ublish.xml
130 | *.azurePubxml
131 | # TODO: Comment the next line if you want to checkin your web deploy settings
132 | # but database connection strings (with potential passwords) will be unencrypted
133 | *.pubxml
134 | *.publishproj
135 |
136 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
137 | # checkin your Azure Web App publish settings, but sensitive information contained
138 | # in these scripts will be unencrypted
139 | PublishScripts/
140 |
141 | # NuGet Packages
142 | *.nupkg
143 | # The packages folder can be ignored because of Package Restore
144 | **/packages/*
145 | # except build/, which is used as an MSBuild target.
146 | !**/packages/build/
147 | # Uncomment if necessary however generally it will be regenerated when needed
148 | #!**/packages/repositories.config
149 | # NuGet v3's project.json files produces more ignoreable files
150 | *.nuget.props
151 | *.nuget.targets
152 |
153 | # Microsoft Azure Build Output
154 | csx/
155 | *.build.csdef
156 |
157 | # Microsoft Azure Emulator
158 | ecf/
159 | rcf/
160 |
161 | # Windows Store app package directories and files
162 | AppPackages/
163 | BundleArtifacts/
164 | Package.StoreAssociation.xml
165 | _pkginfo.txt
166 |
167 | # Visual Studio cache files
168 | # files ending in .cache can be ignored
169 | *.[Cc]ache
170 | # but keep track of directories ending in .cache
171 | !*.[Cc]ache/
172 |
173 | # Others
174 | ClientBin/
175 | ~$*
176 | *~
177 | *.dbmdl
178 | *.dbproj.schemaview
179 | *.pfx
180 | *.publishsettings
181 | node_modules/
182 | orleans.codegen.cs
183 |
184 | # Since there are multiple workflows, uncomment next line to ignore bower_components
185 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
186 | #bower_components/
187 |
188 | # RIA/Silverlight projects
189 | Generated_Code/
190 |
191 | # Backup & report files from converting an old project file
192 | # to a newer Visual Studio version. Backup files are not needed,
193 | # because we have git ;-)
194 | _UpgradeReport_Files/
195 | Backup*/
196 | UpgradeLog*.XML
197 | UpgradeLog*.htm
198 |
199 | # SQL Server files
200 | *.mdf
201 | *.ldf
202 |
203 | # Business Intelligence projects
204 | *.rdl.data
205 | *.bim.layout
206 | *.bim_*.settings
207 |
208 | # Microsoft Fakes
209 | FakesAssemblies/
210 |
211 | # GhostDoc plugin setting file
212 | *.GhostDoc.xml
213 |
214 | # Node.js Tools for Visual Studio
215 | .ntvs_analysis.dat
216 |
217 | # Visual Studio 6 build log
218 | *.plg
219 |
220 | # Visual Studio 6 workspace options file
221 | *.opt
222 |
223 | # Visual Studio LightSwitch build output
224 | **/*.HTMLClient/GeneratedArtifacts
225 | **/*.DesktopClient/GeneratedArtifacts
226 | **/*.DesktopClient/ModelManifest.xml
227 | **/*.Server/GeneratedArtifacts
228 | **/*.Server/ModelManifest.xml
229 | _Pvt_Extensions
230 |
231 | # Paket dependency manager
232 | .paket/paket.exe
233 | paket-files/
234 |
235 | # FAKE - F# Make
236 | .fake/
237 |
238 | # JetBrains Rider
239 | .idea/
240 | *.sln.iml
241 | *.suo
242 |
243 | # obj directory
244 | obj/
245 |
246 | # Debug builds
247 | Debug/
248 |
249 | # Release builds
250 | Release/
251 |
--------------------------------------------------------------------------------
/Specifications/UberAssemblyFile.txt:
--------------------------------------------------------------------------------
1 | UberASM v2.0 Assembly Specification File
2 |
3 | =============
4 | = A: syntax =
5 | =============
6 |
7 | 1- All .asm files are pre-processed by UberASM Tool before getting patched with Asar.
8 | ========
9 |
10 | The files are read by a processor which changes the file contents and load additional required
11 | resources before the file can get correctly assembled by Asar.
12 |
13 | Example: library dependencies.
14 |
15 | 2- Special UberASM Tool commands start with ;> at the beginning of a line.
16 | ========
17 |
18 | UberASM Tool will detect for ";>" and process only if it's on the beginning of a line.
19 |
20 | This is needed to keep compilant with Asar ASM syntax, so situations such as this:
21 |
22 | db "Test ;>file"
23 |
24 | Won't result in ambiguity, since UberASM can mistakenly interpret ;>file as a command while it's
25 | inside a string. This can apply to other situations where Asar doesn't understand ";" as a comment.
26 |
27 | 3- It's required to the command start as soon as prefix is present, with optional unlimited amount
28 | of parameters.
29 | ========
30 |
31 | Example of UberASM special commands:
32 | ;>import my_library
33 |
34 | In case there is a non-alphanumeric character after ";>", the command is ignored.
35 |
36 | Example:
37 |
38 | ;> this appears to be a regular comment.
39 | ; > this appears to be a regular comment.
40 | ;>$FF this appears to be something else
41 | ;>7 this appears to be something else
42 |
43 | 4- There is no escaping characters.
44 | ========
45 |
46 | Situations where it's expected a new line or a special between arguments should never happen and
47 | can be considered a design fault if some command ends up requiring it.
48 |
49 | Example - hypothetical alias command that references a file with spaces:
50 | ;>alias my file.asm my_file
51 |
52 | It's not clear if "my file.asm" is part of a first command or not and how to proceed with my_file
53 | 2nd paramter.
54 |
55 | 5- Some commands may required to be declared at top of the file.
56 | ========
57 |
58 | Commands such as "import" can only be declared at the beginning of the file. Beginning of the
59 | file means empty, white-space, comment-only or begging-only UberASM commands.
60 |
61 | ========================================
62 | = B: List of UberASM Assembly Commands =
63 | ========================================
64 |
65 | 1- 'import' command.
66 | ========
67 | File-beginning command only.
68 |
69 | The import command is used for telling UberASM Tool that the currently being processed file depends
70 | on a specific library and the library labels must be available before proceeding, if not available
71 | already.
72 |
73 | The command is required if the currently processing .asm file is part of the library. For other
74 | .asm files such as level ASM, overworld ASM, etc., it's optional unless if strict space saving mode
75 | is enabled.
76 |
77 | IMPORTANT: Cyclic references are not allowed.
78 |
79 | Example - a library file that requires math related commands on another library:
80 |
81 | == START OF FILE
82 |
83 | ;>import math
84 |
85 | ; outputs A = A*A
86 | power:
87 | STA $00
88 | STA $01
89 |
90 | ; call library to multiply $00 = $00 * $01
91 | JSL math_multiply
92 |
93 | LDA $00
94 | RTL
95 |
96 | == END OF FILE
97 |
98 | A wildcard "*" can be used to import all libraries prefixed before "*". It can only be used at the
99 | end of the file.
100 |
101 | Example:
102 | We have libraries hdma_gradient_layer, hdma_wavy_layer, and hdma_windowing available.
103 | It's suggested that they are from these files:
104 |
105 | hdma_gradient_layer.asm
106 | hdma_wavy_layer.asm
107 | hdma_windowing.asm
108 |
109 | We need all three imports, so instead of doing:
110 |
111 | ;>import hdma_gradient_layer
112 | ;>import hdma_wavy_layer
113 | ;>import hdma_windowing
114 |
115 | You can do:
116 |
117 | ;>import hdma_*
118 |
119 | alternatively:
120 |
121 | ;>import hdma*
122 |
123 | However, you CANNOT do:
124 |
125 | ;>import hdma_*_layer
126 |
127 | For this case, it would theorically import hdma_gradient_layer and hdma_wavy_layer. But "*" is
128 | only allowed at the end of library name reference.
129 |
130 | WARNING: when using "import" command, you are also telling UberASM Tool that only the imports
131 | specified are needed, so other unspecified libraries labels won't be included.
132 |
133 | 2- 'import' command with alias:
134 | ========
135 | File-beginning command only.
136 |
137 | The import command can also create aliases. This can be useful for not having to reference long
138 | label names. For example, a library file hdma_gradient_layer.asm has the following labels:
139 |
140 | init:
141 | ;*insert code here*
142 |
143 | scroll:
144 | ;*insert code here*
145 |
146 | On your main code, you would need to reference them using the labels "hdma_gradient_layer_init" and
147 | "hdma_gradient_layer_scroll". However, to not have to write a such long label, you can use the "as"
148 | keyword on the import command for creating your own alias.
149 |
150 | Example:
151 |
152 | ;>import hdma_gradient_layer as gradient
153 |
154 | With such command, instead of referencing "hdma_gradient_layer_init" you can use "gradient_init"
155 | and instead of "hdma_gradient_layer_scroll" you can use "gradient_scroll"
156 |
157 | You can also completely inline the import, making the labels stay in the same "namespace" as your
158 | code, using the "inline" command instead of "as".
159 |
160 | Example:
161 |
162 | ;>import hdma_gradient_layer inline
163 |
164 | For this case, instead of referencing "hdma_gradient_layer_init", you can simply use "init"
165 | and for "hdma_gradient_layer_scroll" you can use "scroll".
166 |
167 | IMPORTANT: if some inlined label collides with a definition label (such as init, main, nmi, load,
168 | etc.) UberASM Tool will throw an error. This also applies when inlining or aliasing two libraries
169 | and they end up with exact label names.
170 |
171 | For this situation, you can use the RENAME command to rename label names before conflicting.
172 |
173 | Example:
174 | ;>import hdma_gradient_layer inline
175 | ;>rename hdma_gradient_layer_init as ginit
176 |
177 | Fun fact: import with alias or import with inline is basically an import with implied rename
178 | commands.
179 |
180 | 3- 'rename' command
181 | ========
182 | File-beginning command only.
183 |
184 | TBD
185 |
--------------------------------------------------------------------------------
/UberASMTool/UberASMTool.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {B17060A9-56FF-49C8-9182-A46BD4185544}
9 | Exe
10 | Properties
11 | UberASMTool
12 | UberASMTool
13 | v4.0
14 | Client
15 | 512
16 | false
17 | publish\
18 | true
19 | Disk
20 | false
21 | Foreground
22 | 7
23 | Days
24 | false
25 | false
26 | true
27 | 1
28 | 1.0.0.%2a
29 | false
30 | true
31 | true
32 |
33 |
34 | x86
35 | true
36 | full
37 | false
38 | bin\Debug\
39 | DEBUG;TRACE
40 | prompt
41 | 4
42 | true
43 |
44 |
45 | x86
46 | pdbonly
47 | true
48 | bin\Release\
49 | TRACE
50 | prompt
51 | 4
52 | true
53 | false
54 |
55 |
56 | UberASMTool.Program
57 |
58 |
59 | uber.ico
60 |
61 |
62 | 787095019311569D0AAC199C1FF21BEF9A4C990E
63 |
64 |
65 | UberASMTool_TemporaryKey.pfx
66 |
67 |
68 | false
69 |
70 |
71 | false
72 |
73 |
74 | LocalIntranet
75 |
76 |
77 | Properties\app.manifest
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | Always
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 | False
115 | Microsoft .NET Framework 4 Client Profile %28x86 and x64%29
116 | true
117 |
118 |
119 | False
120 | .NET Framework 3.5 SP1 Client Profile
121 | false
122 |
123 |
124 | False
125 | .NET Framework 3.5 SP1
126 | false
127 |
128 |
129 | False
130 | Windows Installer 3.1
131 | true
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
146 |
--------------------------------------------------------------------------------
/assets/other/macro_library.asm:
--------------------------------------------------------------------------------
1 | ; This file is automatically included into all other UberASM Tool files.
2 | ; Useful for putting macros, defines, etc.
3 | ; Putting code or data is NOT recommend though or you will end up wasting lot of space.
4 | ; Put data or code at library folder instead.
5 |
6 | !sa1 = 0 ; 0 if LoROM, 1 if SA-1 ROM.
7 | !dp = $0000 ; $0000 if LoROM, $3000 if SA-1 ROM.
8 | !addr = $0000 ; $0000 if LoROM, $6000 if SA-1 ROM.
9 | !bank = $800000 ; $80:0000 if LoROM, $00:0000 if SA-1 ROM.
10 | !bank8 = $80 ; $80 if LoROM, $00 if SA-1 ROM.
11 |
12 | !sprite_slots = 12 ; 12 if LoROM, 22 if SA-1 ROM.
13 |
14 | ; Check if SA-1 is present.
15 | if read1($00ffd5) == $23
16 | !sa1 = 1
17 | !dp = $3000
18 | !addr = $6000
19 | !bank = $000000
20 | !bank8 = $00
21 |
22 | !sprite_slots = 22
23 |
24 | sa1rom
25 | endif
26 |
27 | ; Protect binary file.
28 | macro prot_file(file, label)
29 | pushpc
30 | freedata cleaned
31 | print "_prot ", pc
32 |
33 |