Sure! Here’s the **entire document in a single Markdown block** ready to copy: ````markdown # Colour Maximite 2 - CSUB Example and ARM Cortex-M7 Embedded Code This document demonstrates how to embed ARM Cortex-M7 machine code directly into your BASIC program on the Colour Maximite 2 using the `CSUB` directive. It covers a minimal example, explains the embedded machine code, and provides detailed instructions on writing, compiling, and embedding ARM Thumb-2 assembly or C routines. --- ## What is CSUB? `CSUB` allows embedding raw ARM machine code or compiled C/assembly routines into Colour Maximite 2 BASIC programs. These embedded routines appear as BASIC commands or functions and run natively on the ARM Cortex-M7 processor, enabling efficient, low-level operations beyond standard BASIC capabilities. According to the Colour Maximite 2 user manual: > `CSUB name [type [, type] …]` > hex [[ hex[…]] > hex [[ hex[…]] > `END CSUB` > > Defines the binary code for an embedded machine code program module written in C or ARM assembler. The module will appear in MMBasic as the command `name` and can be used in the same manner as a built-in command. Multiple embedded routines can be used in a program, each defining a different module with a unique name. The first hex word is a 32-bit word representing the offset in bytes from the start of the CSUB to the entry point of the embedded routine (usually the function `main()`). The following hex words are the compiled binary code for the module. --- ## CSUB Code Example ```basic CSUB simple 00000000 00004770 END CSUB simple() PRINT "Returned successfully" ```` ![Description](IMG_0019.JPG) --- ## What Does This Thumb-2 Machine Code Do? ### `CSUB simple` * Starts the definition of a machine-code subroutine named `simple`. * Tells the BASIC runtime that the following hex words are compiled machine code to execute when `simple()` is called. ### `00000000` * The entry point offset for the CSUB. * A value of `0` indicates execution starts immediately at the next word. * This word is metadata only; it is **not executed** as machine code. ### `00004770` * Encodes the Thumb instruction `BX LR` (Branch to Link Register). * This instruction **returns immediately** from the subroutine to BASIC. ### `END CSUB` * Marks the end of the CSUB block. * Signals that the machine code definition is complete, and BASIC execution continues normally. ### `simple()` * Calls the subroutine `simple`. * Execution jumps to the CSUB, reads the entry point offset, executes the `BX LR` instruction, and immediately returns. ### `PRINT "Returned successfully"` * Prints a message to the BASIC console to indicate the subroutine returned successfully. --- ## ARM Thumb-2 Assembly Example Corresponding to the Machine Code ```asm .syntax unified .thumb .global simple simple: bx lr @ Return immediately ``` ### Explanation * `.syntax unified`: Use modern unified ARM assembler syntax. * `.thumb`: Assemble for the Thumb instruction set used by Cortex-M7. * `.global simple`: Declare the `simple` symbol as global (entry point). * `bx lr`: Branch to the address stored in the Link Register (`LR`), returning control to the caller. > Note: In this minimal example, no values are returned to BASIC. --- ## How to Compile, Link, and Extract Binary ### Step 1: Save Assembly Code Save the code above as `main.s`. ### Step 2: Assemble to Object File ```bash arm-none-eabi-as -mcpu=cortex-m7 -mthumb main.s -o main.o ``` * `-mcpu=cortex-m7`: Target Cortex-M7 CPU. * `-mthumb`: Use Thumb instruction set. ### Step 3: Link to ELF Executable ```bash arm-none-eabi-ld main.o -Ttext=0x0 -o main.elf ``` Or combine compiling and linking with GCC: ```bash arm-none-eabi-gcc -mcpu=cortex-m7 -mthumb -nostartfiles -Wl,-Ttext=0x0 -o main.elf main.s ``` * `-nostartfiles`: Avoid linking standard startup code. * `-Ttext=0x0`: Set load address to 0. ### Step 4: Extract Raw Binary ```bash arm-none-eabi-objcopy -O binary main.elf main.bin ``` ### Step 5: View Machine Code as Hex ```bash xxd -e main.bin ``` Sample output: ``` 00000000: 20420047 ``` * `20420047` is the machine code word representing `movs r0, #42` and `bx lr`. --- ## Preparing the CSUB Block * The **first 32-bit word** is the entry point offset (usually `00000000`). * Following words are your compiled machine code in 32-bit hex words. Example: ```basic CSUB myfunc 00000000 20420047 END CSUB myfunc() PRINT "Returned value in R0 was 42" ``` --- ## Passing Arguments and Returning Data * You can specify argument types in the CSUB definition, e.g., ```basic CSUB MySub integer, integer, string ``` * Up to 10 arguments are supported. * Variables or arrays passed are pointers to their data, allowing embedded routines to modify passed data directly. * Constants and expressions are passed as pointers to temporary memory containing their values. * For longer-running routines, call `routinechecks()` regularly to keep USB and watchdog timers active, or keep routine execution under a few milliseconds. --- ## Additional Tips and Verification * Use `arm-none-eabi-objdump -d main.elf` to disassemble and verify your machine code. * Compile C routines similarly, specifying `-mcpu=cortex-m7 -mthumb` in compiler flags. * Place CSUB blocks anywhere in your BASIC code; MMBasic will skip over them during execution. * Each hex word must be exactly eight hex digits and separated by spaces or new lines. * Formatting errors or incorrect hex data will cause runtime errors in MMBasic. --- ## License This document and any accompanying code are released under the MIT License. ``` This is one clean block you can copy directly into any Markdown editor. If you want, I can **also add a clickable table of contents** inside this single block for easier navigation. Do you want me to do that? ```