diff --git a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c index 4eb673f..18e90df 100644 --- a/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c +++ b/src/rp2_common/pico_stdio_semihosting/stdio_semihosting.c @@ -8,31 +8,33 @@ #include "pico/stdio_semihosting.h" #include "pico/binary_info.h" -//static void __attribute__((naked)) semihosting_puts(const char *s) { -// __asm ( -// -// "mov r1, r0\n" -// "mov r0, #4\n" -// "bkpt 0xab\n" -// "bx lr\n" -// ); -//} - -static void __attribute__((naked)) semihosting_putc(__unused const char *c) { - __asm ( - - "mov r1, r0\n" - "mov r0, #3\n" - "bkpt 0xab\n" - "bx lr\n" - ); -} - - static void stdio_semihosting_out_chars(const char *buf, int length) { - for (int i = 0; i < length; i++) { - semihosting_putc(&buf[i]); - } + // must be volatile or the buffer gets put in registers & optimized away + volatile struct { + // https://developer.arm.com/documentation/dui0375/g/What-is-Semihosting-/SYS-WRITE--0x05- + // arguments, in order: + // word 0 = file handle (1 = stdout) + // word 1 = pointer to buffer + // word 2 = length of buffer + size_t fd; + const char *buf; + size_t len; + } args; + + args.fd = 1; // 1 = stdout + args.buf = buf; + args.len = length; + + __asm ( + // r1 must contain a pointer to the arguments + "mov r1, %[args]\n" + // semihosting call number 0x05 = SYS_WRITE + "mov r0, #5\n" + // make the semihosting call: https://developer.arm.com/documentation/dui0375/g/What-is-Semihosting-/The-semihosting-interface + "bkpt 0xab\n" + : + : [args] "r" (&args) + : "r0", "r1"); } stdio_driver_t stdio_semihosting = {