Jason 10205596b2 Refactor README for clarity and formatting
Removed unnecessary formatting and improved clarity in the README.
2025-12-08 20:50:51 +11:00
2025-10-08 20:48:09 +11:00
2025-10-08 20:13:56 +11:00
2025-10-08 20:37:25 +11:00

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 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.

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. The following hex words are the compiled binary code for the module.


CSUB Code Example

CSUB simple
00000000 00004770
END CSUB

simple()

PRINT "Returned successfully"

Description


What Does This Thumb-2 Machine Code Do?

  • CSUB simple: Starts a machine-code subroutine named simple. Tells BASIC that the following hex words are compiled machine code.
  • 00000000: Entry point offset; 0 indicates execution starts immediately at the next word. Metadata only, not executed.
  • 00004770: Thumb instruction BX LR; returns immediately from the subroutine to BASIC.
  • END CSUB: Marks the end of the CSUB block. BASIC execution continues normally.
  • simple(): Calls the subroutine; execution jumps to the CSUB, reads the entry point, executes BX LR, and returns.
  • PRINT "Returned successfully": Prints a message indicating the subroutine returned successfully.

ARM Thumb-2 Assembly Example

.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.
  • bx lr: Branch to the address stored in the Link Register, returning control to the caller.

  1. Save Assembly Code as main.s
  2. Assemble to Object File

arm-none-eabi-as -mcpu=cortex-m7 -mthumb main.s -o main.o

  1. Link to ELF Executable

arm-none-eabi-ld main.o -Ttext=0x0 -o main.elf

Or using GCC:

arm-none-eabi-gcc -mcpu=cortex-m7 -mthumb -nostartfiles -Wl,-Ttext=0x0 -o main.elf main.s

  1. Extract Raw Binary

arm-none-eabi-objcopy -O binary main.elf main.bin

  1. View Machine Code as Hex

xxd -e main.bin

Sample output:
00000000: 20420047

20420047 represents movs r0, #42 and bx lr.


Preparing the CSUB Block

  • First 32-bit word is the entry point offset (usually 00000000).
  • Following words are the compiled machine code in 32-bit hex words.

Example:

CSUB myfunc
00000000 20420047
END CSUB

myfunc()

PRINT "Returned value in R0 was 42"


Passing Arguments and Returning Data

  • Specify argument types in the CSUB definition:

CSUB MySub integer, integer, string

  • Up to 10 arguments supported.
  • Variables or arrays are passed as pointers, allowing routines to modify data directly.
  • Constants and expressions are passed as pointers to temporary memory.
  • For longer routines, call routinechecks() regularly to keep USB and watchdog timers active, or keep execution under a few milliseconds.

Additional Tips

  • Use arm-none-eabi-objdump -d main.elf to disassemble and verify machine code.
  • Compile C routines similarly with -mcpu=cortex-m7 -mthumb.
  • CSUB blocks can be placed anywhere; BASIC skips over them during execution.
  • Each hex word must be exactly eight hex digits, separated by spaces or new lines.
  • Incorrect formatting or hex data causes runtime errors.

License

This document and any accompanying code are released under the MIT License.

S
Description
No description provided
Readme
2.5 MiB
Languages
Assembly 100%