;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Patch File Format for CloudMax's ROM Patcher v1.1

;All spaces, tabs and empty lines are omitted.
;Everything placed behind a semicolon (;) is omitted.

;All commands are case-insensitive. Names may only use
;letters, numbers and underscores.

;Commands are written by providing 1 or more arguments at the
;beginning of a line.
The arguments are separated by a comma (,).
;The first argument determines which command it is.
;If the first argument is not recognized as a valid command, it 
;will be treated as a write command.
;Example:
var,dma,0x12F70
;var is argument 1. dma is argument 2. 0x12F70 is argument 3.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;To define a variable, set it up as specified below:
;Argument 1: "var"
;Argument 2: name
;Argument 3: value

;Variables can be used inside of value and address arguments.
;To use a variable, surround its name in curly brackets.
;The value can be complicated expressions.

;Example:
var,dma,0x12F70
var,code,[{dma}+0x10*28]
;This would set dma to 0x12F70 and code to [0x12F70+0x10*28]
;Read about pointers below for more information on the square
;brackets.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Pointers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;If you were to type [0x12F70+0x10*28]+0x1000, the patcher
;would look up what is written at 0x12F70+0x10*28 (0x13130) in
;the ROM file that you provided.
;Lets say that it is 0x00A94000.
;In this case [0x12F70+0x10*28] would turn into 0x00A94000,
;resulting in 0x00A94000+0x1000, which is 0x00A95000.

;Note that you can't nest pointers within each other.
;It is however possible to put a variable within a pointer,
;and that variable can consist of another pointer.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Writing
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;To write to the ROM, set up the arguments as specified below:
;Argument 1: address
;Argument 2: hex string

;The address is the address to write to. It has the same 
;restrictions as a variable value.
;The hex string is just that, a string, and can not contain
;variables, pointers, or any kind of calculations by default.
;To use complicated expressions within the hex string, read 
;"Writing complications expressions" down below.

;Example:
{code}+0x1000,0123 4567 89AB CDEF
;Continuing from the pointer and variable example, the
;address would be 0x00A94000+0x1000, and 0x0123456789ABCDEF
;would be written to address 0x00A95000 in the ROM file.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Writing complicated expressions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;By surrounding a complicated expression with quotation marks
;(") and appending a underscore (_) followed by the length it
;should be, it is possible to insert complicated expressions
;inside the hex string.

;Example:
{code}+0x1000,"0x10*0x10+0x20+0x3_4" 4567 89AB CDEF
;This would turn "0x10*0x10+0x20+3_4" into "291_4". 291 will
;be converted into hex (123), and add padding until it's length
;is 4, turning it into 0123. As a result, the hex string would
;become 0123 4567 89AB CDEF.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Gameshark lines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;If a line uses the same format as a gameshark code, it will
;be converted into a write command.

;Example:
80120080 2040
;This will be converted into 0x80120080,2040 automatically so
;that it can be read by the patcher.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Adders
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Adders act as modifiers for the addresses in a write command.
;The value of the adder will be added to the address argument
;of write commands.
;To define an adder, set it up as specified below:
;Argument 1: "add"
;Argument 2: name
;Argument 3: value

;You can remove an adder by using the endadd command which
;uses the following arguments:
;Argument 1: "enadd"
;Argument 2: name

;Example:
add,codeAdder,{code}
0x1000,0123 4567 89AB CDEF
endadd,codeAdder
;This will add {code} to the address of the write command,
;setting it to {code}+0x1000.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Alerts
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;You can cause alerts to appear.
;The alert appears for 5 seconds at the top of the page.
;To create an alert, set it up as specified below:
;Argument 1: "alert"
;Argument 2: message

;Example:
alert,This is an alert!
;This will create an alert that says "This is an alert!".

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Abort
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;You can abort the patch and prevent the patcher from
;generating and downloading a new ROM file.
;To abort, set it up as specified below:
;Argument 1: "abort"

;Example:
abort

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;End
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;You can end the execution of the patch early.
;Unlike the abort command, the patched ROM is downloaded.
;To abort, set it up as specified below:
;Argument 1: "end"

;Example:
end

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Conditions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;It is possible to perform conditional checks.
;If the condition is false, all commands up until an endcon 
;command with the same name will be skipped.
;To set up a condition, set it up as specified below:
;Argument 1: "con"
;Argument 2: name
;Argument 2: condition

;The endcon command is setup up like this:
;Argument 1: "endcon"
;Argument 2: name

;Example:
var,skip,(1==2)
con,ID,{skip}
alert,1 is equal to 2.
endcon,ID

;Since 1 isn't equal to 2, variable skip will be false,
;causing the patcher to skip all lines until a endcon,ID
;line appears. As a result, the alert line will be skipped.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Full Example (Individual patch file):
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The value at address 0x13130 in the ROM is 0x00A94000.
;The value at address 0x3B in the ROM is 0x4E5A4C450F.
var,romID,([0x3B]*0x100)+([0x3C]&0xFF)
con,unpatchable,!({romID}==0x4E5A4C450F||{romID}==0x435A4C450F)
alert,The provided ROM has an incorrect ID or Version.
abort
endcon,unpatchable
var,dma,0x12F70
var,code,[{dma}+0x10*28]
{code}+0x1000,0123 4567 89AB CDEF
end
;romID gets the first 5 bytes at address 0x3B in the ROM.
;In this case it is 0x4E5A4C450F.
;Since that is equal to one of the conditions, and since the
;condition is reversed by the expression mark, the condition
;is false. As a result, the alert and abort lines are skipped.
;variable dma is set to 0x12F70 and code is set to 
;[0x12F70+0x10*28] ([0x13130]).
;The value at 0x13130 in the ROM is 0x00A94000, so variable
;code becomes 0x00A94000.
;{code}+0x1000 turns into 0xA94000+0x1000 (0xA95000)
;The patcher then writes 0x0123456789ABCDEF to 0xA95000.
;Lastly, the end line is read, and the patcher ends execution.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Packs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;It is possible to apply multiple patches at once by putting
;them inside a folder called "patches" in the root of a .zip
;archive. You may place folders in the patches folder.
;You may also put a patch file named "_init.txt" in the root
of the .zip archive. This file is always read first and can be
;used to set up variables, and much more.
;Variables are carried over between patch files.
;Conditions and adders does NOT carry over.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Offsets (Pack command)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The offset command allows you to apply adders to files.
;When the file with that name is being parsed by the patcher
;an adder with the name "ofs" will be applied.
;To define an offset, set it up as specified below:
;Argument 1: "ofs"
;Argument 2: file name
;Argument 3: value

;The file name is in relation to the patches folder.
;You do not include the .txt extension.

;Example:
ofs,subfolder/test_patch,-0x80000000
;This will make it so that patches/subfolder/test_patch.txt is
;being parsed, an adder with name "ofs" and value -0x80000000 
;will be applied.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Disabler (Pack command)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The disable command will prevent the specified file from being
;read by patcher.
;To use the disable command, set it up as specified below:
;Argument 1: "dis"
;Argument 2: file name

;Just like with the offset command, it is in relation to the
;patches folder, and you do not include the .txt extension.

;example:
dis,subfolder/test_patch
;This will prevent the patcher from reading
;patches/subfolder/test_patch.txt

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;Directory (Pack command)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;The directory command allows you to set the root folder of the
;offset and disable commands.
;To use the directory command, set it up as specified below:
;Argument 1: "dir"
;Argument 2: path

;The path is in relation to the patches/ folder.

;Example:
dir,subfolder/
dis,test_patch
;This will disable patches/subfolder/test_patch.txt.