Warning
You're browsing the old v2.x documentation. This version is no longer maintained. Click here to go the v3.x documentation.
+Table of Contents
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 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 ... 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-<extension_name>.bas
- Write a detailed documentation to let users know how to use the extension
- Create a GitHub repo with this name:
xcb-ext-<extension_name>
, upload your files and notify me in email (feketecsaba [at] gmail) about the new extension and I'll add it to theextensions/
folder as a submodule