205 lines
5.7 KiB
Markdown
205 lines
5.7 KiB
Markdown
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"
|
||
````
|
||
|
||

|
||
|
||
---
|
||
|
||
## 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?
|
||
```
|