Direct use of ldcode stcode for memory access - retrotruestory/M1DEV GitHub Wiki
Here's how to optimize memory access using Magic-1's ldcode
and stcode
instructions:
.cseg
.global _fast_code_read
.global _fast_code_write
.global _fast_code_copy
// Fast code space read
// uint16_t fast_code_read(void* addr)
_fast_code_read:
enter 4 ; Setup stack frame
push b ; Save register B
ld.16 b,6(sp) ; Load source address into B
ldcode.16 a,(b) ; Direct read from code space
pop b ; Restore B
leave
ret
// Fast code space write
// void fast_code_write(void* addr, uint16_t value)
_fast_code_write:
enter 4
push b
ld.16 b,6(sp) ; Load destination address
ld.16 a,8(sp) ; Load value to write
stcode.16 (b),a ; Direct write to code space
pop b
leave
ret
// Fast code space copy
// void fast_code_copy(void* dst, void* src, uint16_t count)
_fast_code_copy:
enter 8
push a
push b
push c
ld.16 b,12(sp) ; Load destination
ld.16 a,14(sp) ; Load source
ld.16 c,16(sp) ; Load count
.loop:
ldcode.16 a,(b) ; Read from code space
stcode.16 (b),a ; Write to code space
add.16 b,#2 ; Increment pointers
sub.16 c,#2 ; Decrement count
br.ne .loop ; Continue if not done
pop c
pop b
pop a
leave
ret
Create a C interface:
#ifndef FAST_ACCESS_H
#define FAST_ACCESS_H
#include <stdint.h>
extern uint16_t fast_code_read(void* addr);
extern void fast_code_write(void* addr, uint16_t value);
extern void fast_code_copy(void* dst, void* src, uint16_t count);
#endif
Example usage:
#include <stdio.h>
#include "fast_access.h"
int main() {
uint16_t code_buffer[256];
uint16_t dest_buffer[256];
// Write to code space
fast_code_write(&code_buffer[0], 0x1234);
// Read from code space
uint16_t value = fast_code_read(&code_buffer[0]);
// Copy between code spaces
fast_code_copy(dest_buffer, code_buffer, sizeof(code_buffer));
return 0;
}
Update Makefile:
CC = clcc
AS = m1_as
CFLAGS = -O2
OBJECTS = fast_access.o test_access.o
test_access: $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(OBJECTS)
%.o: %.s
$(AS) -o $@ $<
%.o: %.c
$(CC) $(CFLAGS) -c $<
clean:
rm -f test_access *.o
Key features:
- Direct use of
ldcode
/stcode
instructions for fast memory access - No translation/page table overhead
- Optimized for code space operations
- Efficient for ROM/flash memory access
- Useful for bootloader and low-level system code
This implementation is particularly efficient for:
- Accessing program code
- Boot ROM operations
- Code patching/modification
- Fast memory-mapped device access