====== Tutorial: Extension writing ====== As mentioned before, an extension is simply an **XC=BASIC** source code file. You can define procedures, functions and constants in your extension just the way you'd do it in an **XC=BASIC** program. ===== Naming your symbols ===== To avoid naming collisions, you should choose a //quasi namespace// for the extension and prepend all your symbols with this string. For example, if you're about to write an extension that does math calculations, choose a namespace, let's say, ''math_'' and prepend all constants, procedures and functions with the string ''math_'': rem * Math extension rem * by John Doe rem * namespace: math_ const MATH_PI% = 3.14159265359 const MATH_E% = 2.71828182845 fun math_pow(base!, exponent!) result = cast(base!) for i! = 1 to exponent! - 1 result = result * base! next i! return result endfun ===== Adding new commands ===== Since procedures can be called using the procedure name only, they are perfect for defining new commands. Combining with the [[asm|ASM]] directive, you can write assembly code for your new commands. For example: rem * Border coloring extension rem * by John Doe rem * namespace: bg_ const BG_BORDER = $d020 proc bg_color(color!) asm " lda {self}.color sta _BG_BORDER " endproc Thereafter, any program using this extension can issue the new command: include "path/to/extension.bas" bg_color 13 Notice that ''bg_color 13'' is equivalent to ''call bg_color(13)''. ===== Adding new functions ===== Simply use the [[fun|FUN ... ENDFUN]] block to define new functions. ===== Referencing XC=BASIC symbols in assembly language ===== To speed things up, you should write functions in assembly language. To be able to do this, you need to know how to access **XC=BASIC** symbols and features in assembly. The following table serves as a guide: ^ Type ^ XC=BASIC symbol ^ Assembly symbol ^ | Constant | ''EXAMPLE'' | ''_EXAMPLE'' | | Global variable | ''example'' | ''_example'' | | Local variable | ''example'' | ''_procname.example'' or ''{self}.example'' within the procedure | | Argument of procedure or function | ''example'' | ''_procname.example'' or ''{self}.example'' within the procedure | The following example attempts to demonstrate how to write a function in assembly language. rem ** This function returns one if fire button rem ** in joystick port #1 or port#2 is pressed, zero otherwise const JOY_PORT2 = $dc00 const JOY_PORT1 = $dc01 fun joy_firepressed!(port!) dim result! asm " ; This is how to refer to a function's argument lda {self}.port ; Port #2 becomes 0, Port #1 remains 1 and #%00000001 tax ; This is how to refer to a global constant lda.wx _JOY_PORT2 eor #%11111111 and #%00010000 lsr lsr lsr lsr ; A now holds the return value of our function ; Write it to the variable 'result!' sta {self}.result " return result! endfun ===== Publishing your extension ===== When you're done with your extension, please follow these steps: - Test all functions and commands carefully. Write a detailed test program - Name your extension ''xcb-ext-.bas'' - Write a detailed documentation to let users know how to use the extension - Create a GitHub repo with this name: ''xcb-ext-'', upload your files and notify me in email (feketecsaba [at] gmail) about the new extension and I'll add it to the ''extensions/'' folder as a submodule