Update README.md
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
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
|
# 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.
|
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.
|
||||||
@@ -15,9 +18,9 @@ According to the Colour Maximite 2 user manual:
|
|||||||
> hex [[ hex[…]]
|
> hex [[ hex[…]]
|
||||||
> `END CSUB`
|
> `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.
|
> 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 different name. The first hex word is a 32-bit word which is 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.
|
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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -32,34 +35,42 @@ simple()
|
|||||||
|
|
||||||
PRINT "Returned successfully"
|
PRINT "Returned successfully"
|
||||||
````
|
````
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## What Does This Thumb-2 Machine Code Do?
|
## What Does This Thumb-2 Machine Code Do?
|
||||||
|
|
||||||
### `CSUB simple`
|
### `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.
|
* 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`
|
### `00000000`
|
||||||
- The entry point offset for the CSUB.
|
|
||||||
- A value of `0` indicates execution starts immediately at the next word.
|
* The entry point offset for the CSUB.
|
||||||
- This word is metadata only; it is **not executed** as machine code.
|
* 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`
|
### `00004770`
|
||||||
- Encodes the Thumb instruction `BX LR` (Branch to Link Register).
|
|
||||||
- This instruction **returns immediately** from the subroutine to BASIC.
|
* Encodes the Thumb instruction `BX LR` (Branch to Link Register).
|
||||||
|
* This instruction **returns immediately** from the subroutine to BASIC.
|
||||||
|
|
||||||
### `END CSUB`
|
### `END CSUB`
|
||||||
- Marks the end of the CSUB block.
|
|
||||||
- Signals that the machine code definition is complete, and BASIC execution continues normally.
|
* Marks the end of the CSUB block.
|
||||||
|
* Signals that the machine code definition is complete, and BASIC execution continues normally.
|
||||||
|
|
||||||
### `simple()`
|
### `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"`
|
* Calls the subroutine `simple`.
|
||||||
- Prints a message to the BASIC console to indicate the subroutine returned successfully.
|
* 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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -71,18 +82,18 @@ PRINT "Returned successfully"
|
|||||||
.global simple
|
.global simple
|
||||||
|
|
||||||
simple:
|
simple:
|
||||||
movs r0, #42 @ Load immediate value 42 into register R0
|
bx lr @ Return immediately
|
||||||
bx lr @ Return from subroutine
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Explanation
|
### Explanation
|
||||||
|
|
||||||
* `.syntax unified`: Use modern unified ARM assembler syntax.
|
* `.syntax unified`: Use modern unified ARM assembler syntax.
|
||||||
* `.thumb`: Assemble for the Thumb instruction set used by Cortex-M7.
|
* `.thumb`: Assemble for the Thumb instruction set used by Cortex-M7.
|
||||||
* `.global main`: Declare the `main` symbol as global (entry point).
|
* `.global simple`: Declare the `simple` symbol as global (entry point).
|
||||||
* `movs r0, #42`: Move the immediate value 42 into register `R0` (standard register for function return values).
|
|
||||||
* `bx lr`: Branch to the address stored in the Link Register (`LR`), returning control to the caller.
|
* `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
|
## How to Compile, Link, and Extract Binary
|
||||||
@@ -113,7 +124,7 @@ arm-none-eabi-gcc -mcpu=cortex-m7 -mthumb -nostartfiles -Wl,-Ttext=0x0 -o main.e
|
|||||||
```
|
```
|
||||||
|
|
||||||
* `-nostartfiles`: Avoid linking standard startup code.
|
* `-nostartfiles`: Avoid linking standard startup code.
|
||||||
* `-Ttext=0x0`: Load address set to 0.
|
* `-Ttext=0x0`: Set load address to 0.
|
||||||
|
|
||||||
### Step 4: Extract Raw Binary
|
### Step 4: Extract Raw Binary
|
||||||
|
|
||||||
@@ -165,9 +176,9 @@ CSUB MySub integer, integer, string
|
|||||||
```
|
```
|
||||||
|
|
||||||
* Up to 10 arguments are supported.
|
* Up to 10 arguments are supported.
|
||||||
* Variables or arrays passed are pointers to their data. This allows embedded routines to modify passed data directly.
|
* 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.
|
* Constants and expressions are passed as pointers to temporary memory containing their values.
|
||||||
* Remember to call `routinechecks()` regularly in longer-running routines to keep USB and watchdog timers active, or keep your routine execution within a few milliseconds.
|
* For longer-running routines, call `routinechecks()` regularly to keep USB and watchdog timers active, or keep routine execution under a few milliseconds.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -177,10 +188,17 @@ CSUB MySub integer, integer, string
|
|||||||
* Compile C routines similarly, specifying `-mcpu=cortex-m7 -mthumb` in compiler flags.
|
* 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.
|
* 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.
|
* Each hex word must be exactly eight hex digits and separated by spaces or new lines.
|
||||||
* Errors in formatting or hex data will cause runtime errors in MMBasic.
|
* Formatting errors or incorrect hex data will cause runtime errors in MMBasic.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
This document and any accompanying code are released under the MIT 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?
|
||||||
|
```
|
||||||
|
|||||||
Reference in New Issue
Block a user