We've just updated MediaWiki and its underlying software. If anything doesn't look or work quite right, please mention it to us. --RanAS

Good coding practices: Difference between revisions

From SnesLab
Jump to: navigation, search
Line 22: Line 22:
* Micro-optimizations are bad, consider only doing them if it's a critical routine of your program.
* Micro-optimizations are bad, consider only doing them if it's a critical routine of your program.
Comments: An optimization is considered 'micro-optimization' when you start sacrificing the readability in exchange of 1-2 cycle optimization. An example is taking off the CLC because there 50 lines ago there was a BCS opcode that jumps to the of the routine or the previous ADC implies that the operation will never generate carry (fcr example, a sum that will never exceed #$FF).
Comments: An optimization is considered 'micro-optimization' when you start sacrificing the readability in exchange of 1-2 cycle optimization. An example is taking off the CLC because there 50 lines ago there was a BCS opcode that jumps to the of the routine or the previous ADC implies that the operation will never generate carry (fcr example, a sum that will never exceed #$FF).
* Give a focus on generating efficient algorithms before thinking on any assembly-level optimization.
Comments: Observe if your overall algorithm is effect and fast. Sometimes you can do the same thing much more effectively if done in another way. Observe the trade off between memory and time usage. Sometimes an algorithm that uses more memory will be much faster than an algorithm that uses almost no memory but requires much more iterations. If the algorithm involves iterating a list (for example, a list of active enemies on screen), try making the algorithm only iterate once or twice on the enemy list. It will be much faster than optimizing an algorithm that iterates the enemy list quadratic times.


* Code inling should only be considered on critical situations.
* Code inling should only be considered on critical situations.
Comments: Often coders prefer getting rid of the JSR/RTS and inling all of the code at the once, which sounds logigal if the routine is only called once. However the practice is not recommended, given that routines can end-up reused across other resources. Splitting an inline code into routines will also likely make it easier to edit because it will allow to isolate each routine to its own role. A good way to check if inling will be really benefit is evaluating the cycle cost of using JSR + RTS times the amount of inlined routines times the amount of time the code section is called.
Comments: Often coders prefer getting rid of the JSR/RTS and inling all of the code at the once, which sounds logigal if the routine is only called once. However the practice is not recommended, given that routines can end-up reused across other resources. Splitting an inline code into routines will also likely make it easier to edit because it will allow to isolate each routine to its own role. A good way to check if inling will be really benefit is evaluating the cycle cost of using JSR + RTS times the amount of inlined routines times the amount of time the code section is called.

Revision as of 04:02, 11 December 2020

This document is an effort to create a coding standard and by consequence a global library that can be used on SNES homebrew and ROM hacking. The objective is creating a standard that lets coders maintain existing code with less difficulty, promote a clean and easy-to-understand code, standardize conventions and promote coding agility for faster results and less time thinking on how to code.

Since there are some SNES assemblers available, our guideline will be focused on Asar. However some of the thoughts can be applied to other assemblers without problem.

Feel free to edit with your own thoughts, the idea is mixing everyone opinions until we get into a consensus. Further discussion can be made on the #homebrew channel of the SnesLab Discord: https://discord.gg/dXzrk5bX

Code writing thoughts

Code Labels

  • code label refers to any beginning of a routine.
  • they should be all lowercase and each word should be separated using a underscore. Example: example_routine
  • consider not using more than two underscores to not make it difficulty to read. Not a good example: this_label_is_too_long

Conventions

Memory map and ROM structure

Cycle optimization

  • Do not code thinking already on optimization. Get the routine working first.

Comments: Often an algorithm or routine takes several hours to get it working, it requires extensive thoughts and coding thinking already on possible optimizations will make the coding process way slower. It also increases the chances of getting premature bugs, because it makes harder to verify if the algorithm is correct.

  • Micro-optimizations are bad, consider only doing them if it's a critical routine of your program.

Comments: An optimization is considered 'micro-optimization' when you start sacrificing the readability in exchange of 1-2 cycle optimization. An example is taking off the CLC because there 50 lines ago there was a BCS opcode that jumps to the of the routine or the previous ADC implies that the operation will never generate carry (fcr example, a sum that will never exceed #$FF).

  • Give a focus on generating efficient algorithms before thinking on any assembly-level optimization.

Comments: Observe if your overall algorithm is effect and fast. Sometimes you can do the same thing much more effectively if done in another way. Observe the trade off between memory and time usage. Sometimes an algorithm that uses more memory will be much faster than an algorithm that uses almost no memory but requires much more iterations. If the algorithm involves iterating a list (for example, a list of active enemies on screen), try making the algorithm only iterate once or twice on the enemy list. It will be much faster than optimizing an algorithm that iterates the enemy list quadratic times.

  • Code inling should only be considered on critical situations.

Comments: Often coders prefer getting rid of the JSR/RTS and inling all of the code at the once, which sounds logigal if the routine is only called once. However the practice is not recommended, given that routines can end-up reused across other resources. Splitting an inline code into routines will also likely make it easier to edit because it will allow to isolate each routine to its own role. A good way to check if inling will be really benefit is evaluating the cycle cost of using JSR + RTS times the amount of inlined routines times the amount of time the code section is called.