From dc71f45df6f78b5cbde5d9cbf3c91931ab7deed8 Mon Sep 17 00:00:00 2001 From: Polprzewodnikowy Date: Tue, 11 Jan 2022 20:22:24 +0100 Subject: [PATCH] ironed out all broken stuff --- sw/n64/Makefile | 5 +- sw/n64/N64.ld | 1 - sw/n64/src/boot.c | 4 +- sw/n64/src/boot.h | 17 ---- sw/n64/src/error.c | 8 ++ sw/n64/src/error.h | 8 ++ sw/n64/src/exception.S | 81 ++++++++++++++++-- sw/n64/src/exception.c | 174 ++++++++++++++++---------------------- sw/n64/src/exception.h | 52 +----------- sw/n64/src/fatfs/ffconf.h | 8 +- sw/n64/src/font.c | 103 ++++++++++++++++++++++ sw/n64/src/font.h | 16 ++++ sw/n64/src/init.c | 2 - sw/n64/src/interrupt.c | 9 ++ sw/n64/src/main.c | 31 ++----- sw/n64/src/sc64.c | 22 ----- sw/n64/src/sc64.h | 16 +--- sw/n64/src/sys.c | 14 --- sw/n64/src/sys.h | 45 +++++++++- sw/n64/src/syscalls.c | 5 +- 20 files changed, 354 insertions(+), 267 deletions(-) create mode 100644 sw/n64/src/error.c create mode 100644 sw/n64/src/error.h create mode 100644 sw/n64/src/font.c create mode 100644 sw/n64/src/font.h create mode 100644 sw/n64/src/interrupt.c diff --git a/sw/n64/Makefile b/sw/n64/Makefile index 55310de..68bb773 100644 --- a/sw/n64/Makefile +++ b/sw/n64/Makefile @@ -6,7 +6,7 @@ OBJDUMP = $(TOOLCHAIN)objdump SIZE = $(TOOLCHAIN)size FLAGS = -march=vr4300 -mtune=vr4300 -falign-functions=32 $(USER_FLAGS) -CFLAGS = -O2 -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP +CFLAGS = -Os -Wall -ffunction-sections -fdata-sections -ffreestanding -MMD -MP ASFLAGS = -Wa,-I$(N64_INST)/mips64-elf/lib LDFLAGS = -lc -nostartfiles -Wl,--gc-sections @@ -18,8 +18,11 @@ SRC_FILES = \ exception.S \ boot.c \ crc32.c \ + error.c \ exception.c \ + font.c \ init.c \ + interrupt.c \ main.c \ sc64.c \ storage.c \ diff --git a/sw/n64/N64.ld b/sw/n64/N64.ld index 09f7f0f..52415fb 100644 --- a/sw/n64/N64.ld +++ b/sw/n64/N64.ld @@ -12,7 +12,6 @@ SECTIONS { .flash : { KEEP(*(.text.rom_header)); KEEP(*(.text.ipl3)); - __ipl3_font = LOADADDR(.flash) + 0xB70; } > flash .text : { diff --git a/sw/n64/src/boot.c b/sw/n64/src/boot.c index 756aa93..54d423e 100644 --- a/sw/n64/src/boot.c +++ b/sw/n64/src/boot.c @@ -93,8 +93,6 @@ bool boot_get_cic_seed_version (boot_info_t *info) { } void boot (boot_info_t *info) { - c0_set_status(C0_SR_CU1 | C0_SR_CU0 | C0_SR_FR); - OS_INFO->mem_size_6105 = OS_INFO->mem_size; while (!(io_read(&SP->SR) & SP_SR_HALT)); @@ -154,8 +152,10 @@ void boot (boot_info_t *info) { stack_pointer = (void *) UNCACHED(&SP_MEM->IMEM[1020]); asm volatile ( + "mtc0 %[status], $12 \n" "move $sp, %[stack_pointer] \n" "jr %[entry_point] \n" :: + [status] "r" (C0_SR_CU1 | C0_SR_CU0 | C0_SR_FR), [entry_point] "r" (entry_point), [boot_device] "r" (boot_device), [tv_type] "r" (tv_type), diff --git a/sw/n64/src/boot.h b/sw/n64/src/boot.h index 09e3e1c..504e379 100644 --- a/sw/n64/src/boot.h +++ b/sw/n64/src/boot.h @@ -32,23 +32,6 @@ typedef struct { } boot_info_t; -typedef struct { - uint32_t tv_type; - uint32_t device_type; - uint32_t device_base; - uint32_t reset_type; - uint32_t cic_id; - uint32_t version; - uint32_t mem_size; - uint8_t app_nmi_buffer[64]; - uint32_t __reserved_1[37]; - uint32_t mem_size_6105; -} os_info_t; - -#define OS_INFO_BASE (0x80000300UL) -#define OS_INFO ((os_info_t *) OS_INFO_BASE) - - bool boot_get_tv_type (boot_info_t *info); bool boot_get_cic_seed_version (boot_info_t *info); void boot (boot_info_t *info); diff --git a/sw/n64/src/error.c b/sw/n64/src/error.c new file mode 100644 index 0000000..c42b6e2 --- /dev/null +++ b/sw/n64/src/error.c @@ -0,0 +1,8 @@ +#include "error.h" +#include "exception.h" + + +void error_display (const char *message) { + EXCEPTION_TRIGGER(TRIGGER_CODE_ERROR); + while (1); +} diff --git a/sw/n64/src/error.h b/sw/n64/src/error.h new file mode 100644 index 0000000..2cf69e7 --- /dev/null +++ b/sw/n64/src/error.h @@ -0,0 +1,8 @@ +#ifndef ERROR_H__ +#define ERROR_H__ + + +void error_display (const char *message); + + +#endif diff --git a/sw/n64/src/exception.S b/sw/n64/src/exception.S index f68f61f..081fb77 100644 --- a/sw/n64/src/exception.S +++ b/sw/n64/src/exception.S @@ -1,4 +1,62 @@ -#include "exception.h" +#define VECTOR_LOCATION (0xA0000000UL) +#define VECTOR_SIZE (0x80) +#define VECTOR_NUM (4) + +#define HIT_INVALIDATE_I ((4 << 2) | 0) + +#define TICKS_PER_SECOND (93750000UL / 2) +#define WATCHDOG_TIMEOUT (10) + +#define C0_COUNT $9 +#define C0_COMPARE $11 +#define C0_STATUS $12 +#define C0_CAUSE $13 +#define C0_EPC $14 + +#define INTERRUPT_ENABLE (1 << 0) +#define INTERRUPT_MASK_TIMER (1 << 15) + +#define EXCEPTION_CODE_MASK (0x007C) +#define EXCEPTION_CODE_BIT (2) +#define INTERRUPT_PENDING_MASK (0xFF00) +#define INTERRUPT_PENDING_BIT (8) +#define INTERRUPT_PENDING_TIMER (1 << 7) + +#define AT_OFFSET (8) +#define V0_OFFSET (16) +#define V1_OFFSET (24) +#define A0_OFFSET (32) +#define A1_OFFSET (40) +#define A2_OFFSET (48) +#define A3_OFFSET (56) +#define T0_OFFSET (64) +#define T1_OFFSET (72) +#define T2_OFFSET (80) +#define T3_OFFSET (88) +#define T4_OFFSET (96) +#define T5_OFFSET (104) +#define T6_OFFSET (112) +#define T7_OFFSET (120) +#define S0_OFFSET (128) +#define S1_OFFSET (136) +#define S2_OFFSET (144) +#define S3_OFFSET (152) +#define S4_OFFSET (160) +#define S5_OFFSET (168) +#define S6_OFFSET (176) +#define S7_OFFSET (184) +#define T8_OFFSET (192) +#define T9_OFFSET (200) +#define K0_OFFSET (208) +#define K1_OFFSET (216) +#define GP_OFFSET (224) +#define SP_OFFSET (232) +#define FP_OFFSET (240) +#define RA_OFFSET (248) +#define C0_STATUS_OFFSET (256) +#define C0_CAUSE_OFFSET (260) +#define C0_EPC_OFFSET (264) +#define SAVE_REGISTERS_SIZE (272) .section .text.exception_handler @@ -42,9 +100,14 @@ exception_is_fatal: mfc0 $a0, C0_CAUSE sw $a0, C0_CAUSE_OFFSET($k0) move $a1, $a0 - andi $a1, EXCEPTION_CODE_MASK - srl $a1, $a1, EXCEPTION_CODE_BIT - beq $a1, $zero, exception_interrupt + andi $a0, EXCEPTION_CODE_MASK + srl $a0, $a0, EXCEPTION_CODE_BIT + andi $a1, INTERRUPT_PENDING_MASK + srl $a1, $a1, INTERRUPT_PENDING_BIT + move $t0, $a1 + andi $t0, INTERRUPT_PENDING_TIMER + bne $t0, $zero, exception_fatal + beq $a0, $zero, exception_interrupt exception_fatal: sd $k0, K0_OFFSET($k0) @@ -55,14 +118,12 @@ exception_fatal: sd $t0, C0_EPC_OFFSET($k0) addiu $t0, 4 dmtc0 $t0, C0_EPC - move $a0, $k0 + move $a2, $k0 la $t1, exception_fatal_handler jalr $t1 j exception_restore exception_interrupt: - andi $a0, INTERRUPT_PENDING_MASK - srl $a0, $a0, INTERRUPT_PENDING_BIT la $t1, exception_interrupt_handler jalr $t1 @@ -133,4 +194,10 @@ exception_install: bne $t4, $t5, 2b addiu $t1, VECTOR_SIZE bne $t1, $t2, 1b + li $t7, (WATCHDOG_TIMEOUT * TICKS_PER_SECOND) + mtc0 $zero, C0_COUNT + mtc0 $t7, C0_COMPARE + mfc0 $t7, C0_STATUS + ori $t7, (INTERRUPT_MASK_TIMER | INTERRUPT_ENABLE) + mtc0 $t7, C0_STATUS jr $ra diff --git a/sw/n64/src/exception.c b/sw/n64/src/exception.c index 9d278d8..016260e 100644 --- a/sw/n64/src/exception.c +++ b/sw/n64/src/exception.c @@ -1,30 +1,37 @@ #include #include -#include "boot.h" #include "exception.h" -#include "sc64.h" +#include "font.h" #include "sys.h" -extern io32_t __ipl3_font __attribute__((section(".data"))); +typedef struct { + uint64_t gpr[32]; + uint32_t sr; + uint32_t cr; + uint64_t epc; +} exception_t; -#define SCREEN_WIDTH (640) -#define SCREEN_HEIGHT (240) +#define EXCEPTION_INTERRUPT (0) +#define EXCEPTION_SYSCALL (8) -#define BACKGROUND_COLOR (0xFFFFFFFFUL) -#define FOREGROUND_COLOR (0x000000FFUL) +#define INTERRUPT_MASK_TIMER (1 << 7) -#define CHARACTER_WIDTH (13) -#define CHARACTER_HEIGHT (14) -#define CHARACTER_SIZE (23) +#define SYSCALL_CODE_MASK (0x03FF0000UL) +#define SYSCALL_CODE_BIT (16) -#define LINE_HEIGHT (22) +#define SCREEN_WIDTH (640) +#define SCREEN_HEIGHT (240) + +#define BACKGROUND_COLOR (0x000000FFUL) +#define FOREGROUND_COLOR (0xFFFFFFFFUL) + +#define LINE_HEIGHT (12) static const vi_regs_t vi_config[] = {{ .CR = VI_CR_TYPE_32, - .MADDR = 0x00200000UL, .H_WIDTH = SCREEN_WIDTH, .V_INTR = 512, .CURR_LINE = 0, @@ -39,7 +46,6 @@ static const vi_regs_t vi_config[] = {{ .V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60), }, { .CR = VI_CR_TYPE_32, - .MADDR = 0x00200000UL, .H_WIDTH = SCREEN_WIDTH, .V_INTR = 512, .CURR_LINE = 0, @@ -54,46 +60,17 @@ static const vi_regs_t vi_config[] = {{ .V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60), }}; -static const uint8_t exception_font_mapping[96] = { - 48, 36, 37, 38, 48, 48, 48, 39, 48, 48, 40, 41, 42, 43, 44, 45, - 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 46, 48, 48, 47, 48, 48, - 49, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 48, 48, 48, 48, 48, - 48, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 48, 48, 48, 48, 48, -}; - -static io32_t *exception_framebuffer; -static uint32_t exception_font_buffer[288]; +static io32_t *exception_framebuffer = (io32_t *) (0x00200000UL); static void exception_init_screen (void) { const vi_regs_t *cfg = &vi_config[OS_INFO->tv_type]; - io32_t *src = &__ipl3_font; - uint32_t *dst = exception_font_buffer; - - bool sdram_switched = sc64_get_config(CFG_ID_SDRAM_SWITCH); - - if (sdram_switched) { - sc64_set_config(CFG_ID_SDRAM_SWITCH, false); - } - - for (int i = 0; i < sizeof(exception_font_buffer); i += 4) { - *dst++ = pi_io_read(src++); - } - - if (sdram_switched) { - sc64_set_config(CFG_ID_SDRAM_SWITCH, true); - } - - exception_framebuffer = (io32_t *) (cfg->MADDR); - for (int i = 0; i < (SCREEN_WIDTH * SCREEN_HEIGHT); i++) { - io_write(exception_framebuffer + i, BACKGROUND_COLOR); + io_write(&exception_framebuffer[i], BACKGROUND_COLOR); } - io_write(&VI->MADDR, cfg->MADDR); + io_write(&VI->MADDR, (uint32_t) (exception_framebuffer)); io_write(&VI->H_WIDTH, cfg->H_WIDTH); io_write(&VI->V_INTR, cfg->V_INTR); io_write(&VI->CURR_LINE, cfg->CURR_LINE); @@ -109,24 +86,20 @@ static void exception_init_screen (void) { io_write(&VI->CR, cfg->CR); } - static void exception_draw_character (int x, int y, char c) { - if ((c <= 32) || (c >= 127)) { - return; + if ((c < ' ') || (c > '~')) { + c = 127; } - uint8_t index = exception_font_mapping[c - 32]; - uint8_t *character = ((uint8_t *) (exception_font_buffer)) + (index * CHARACTER_SIZE); - - for (int i = 0; i < (CHARACTER_WIDTH * CHARACTER_HEIGHT); i++) { - int c_x = x + (i % CHARACTER_WIDTH); - int c_y = y + (i / CHARACTER_WIDTH); + for (int i = 0; i < (FONT_WIDTH * FONT_HEIGHT); i++) { + int c_x = x + (i % FONT_WIDTH); + int c_y = y + (i / FONT_WIDTH); if ((c_x >= SCREEN_WIDTH) || (c_y >= SCREEN_HEIGHT)) { break; } - if (character[i / 8] & (1 << (7 - (i % 8)))) { + if (font_data[c - ' '][i / 8] & (1 << (i % 8))) { int screen_offset = c_x + (c_y * SCREEN_WIDTH); io_write(&exception_framebuffer[screen_offset], FOREGROUND_COLOR); } @@ -136,12 +109,12 @@ static void exception_draw_character (int x, int y, char c) { static void exception_print_string (int x, int y, const char *s) { while (*s != '\0') { exception_draw_character(x, y, *s++); - x += CHARACTER_WIDTH; + x += FONT_WIDTH; } } static void exception_print (int *x, int *y, const char* fmt, ...) { - char line[64]; + char line[128]; va_list args; va_start(args, fmt); @@ -155,6 +128,7 @@ static void exception_print (int *x, int *y, const char* fmt, ...) { static const char *exception_get_description (uint8_t exception_code) { switch (exception_code) { + case 0: return "Interrupt"; case 1: return "TLB Modification exception"; case 2: return "TLB Miss exception (load or instruction fetch)"; case 3: return "TLB Miss exception (store)"; @@ -176,59 +150,55 @@ static const char *exception_get_description (uint8_t exception_code) { } -typedef struct { - uint64_t gpr[32]; - uint32_t sr; - uint32_t cr; - uint64_t epc; -} exception_t; - - -void exception_fatal_handler (exception_t *e) { - uint8_t exception_code = (uint8_t) ((e->cr & EXCEPTION_CODE_MASK) >> EXCEPTION_CODE_BIT); - const char *exception_description = exception_get_description(exception_code); - - exception_init_screen(); - +void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask, exception_t *e) { + uint32_t sc64_version = pi_io_read(&SC64->VERSION); + uint32_t *instruction_address = (uint32_t *) ((uint32_t) (e->epc)); uint32_t gpr32[32]; + int x = 12; + int y = 8; + + if (e->cr & C0_CR_BD) { + instruction_address += 1; + } for (int i = 0; i < 32; i++) { gpr32[i] = (uint32_t) (e->gpr[i]); } - int x = 12; - int y = 8; + exception_init_screen(); - exception_print(&x, &y, "%s", exception_description); - exception_print(&x, &y, "pc %08lX sr %08lX cr %08lX", (uint32_t) (e->epc), e->sr, e->cr); - exception_print(&x, &y, "zr %08lX at %08lX v0 %08lX v1 %08lX", gpr32[0], gpr32[1], gpr32[2], gpr32[3]); - exception_print(&x, &y, "a0 %08lX a1 %08lX a2 %08lX a3 %08lX", gpr32[4], gpr32[5], gpr32[6], gpr32[7]); - exception_print(&x, &y, "t0 %08lX t1 %08lX t2 %08lX t3 %08lX", gpr32[8], gpr32[9], gpr32[10], gpr32[11]); - exception_print(&x, &y, "t4 %08lX t5 %08lX t6 %08lX t7 %08lX", gpr32[12], gpr32[13], gpr32[14], gpr32[15]); - exception_print(&x, &y, "s0 %08lX s1 %08lX s2 %08lX s3 %08lX", gpr32[16], gpr32[17], gpr32[18], gpr32[19]); - exception_print(&x, &y, "s4 %08lX s5 %08lX s6 %08lX s7 %08lX", gpr32[20], gpr32[21], gpr32[22], gpr32[23]); - exception_print(&x, &y, "t8 %08lX t9 %08lX k0 %08lX k1 %08lX", gpr32[24], gpr32[25], gpr32[26], gpr32[27]); - exception_print(&x, &y, "gp %08lX sp %08lX fp %08lX ra %08lX", gpr32[28], gpr32[29], gpr32[30], gpr32[31]); + exception_print(&x, &y, "SC64 VERSION: 0x%08lX (%4s)", sc64_version, (char *) (&sc64_version)); + exception_print(&x, &y, "%s at pc: 0x%08lX", exception_get_description(exception_code), (uint32_t) (e->epc)); + exception_print(&x, &y, "sr: 0x%08lX, cr: 0x%08lX", e->sr, e->cr); + exception_print(&x, &y, "zr: 0x%08lX, at: 0x%08lX, v0: 0x%08lX, v1: 0x%08lX", gpr32[0], gpr32[1], gpr32[2], gpr32[3]); + exception_print(&x, &y, "a0: 0x%08lX, a1: 0x%08lX, a2: 0x%08lX, a3: 0x%08lX", gpr32[4], gpr32[5], gpr32[6], gpr32[7]); + exception_print(&x, &y, "t0: 0x%08lX, t1: 0x%08lX, t2: 0x%08lX, t3: 0x%08lX", gpr32[8], gpr32[9], gpr32[10], gpr32[11]); + exception_print(&x, &y, "t4: 0x%08lX, t5: 0x%08lX, t6: 0x%08lX, t7: 0x%08lX", gpr32[12], gpr32[13], gpr32[14], gpr32[15]); + exception_print(&x, &y, "s0: 0x%08lX, s1: 0x%08lX, s2: 0x%08lX, s3: 0x%08lX", gpr32[16], gpr32[17], gpr32[18], gpr32[19]); + exception_print(&x, &y, "s4: 0x%08lX, s5: 0x%08lX, s6: 0x%08lX, s7: 0x%08lX", gpr32[20], gpr32[21], gpr32[22], gpr32[23]); + exception_print(&x, &y, "t8: 0x%08lX, t9: 0x%08lX, k0: 0x%08lX, k1: 0x%08lX", gpr32[24], gpr32[25], gpr32[26], gpr32[27]); + exception_print(&x, &y, "gp: 0x%08lX, sp: 0x%08lX, fp: 0x%08lX, ra: 0x%08lX", gpr32[28], gpr32[29], gpr32[30], gpr32[31]); - LOG_E("%s\r\n", exception_description); - LOG_E("pc: 0x%08lX, sr: 0x%08lX, cr: 0x%08lX\r\n", (uint32_t) (e->epc), e->sr, e->cr); - LOG_E("zr: 0x%08lX, at: 0x%08lX, v0: 0x%08lX, v1: 0x%08lX\r\n", gpr32[0], gpr32[1], gpr32[2], gpr32[3]); - LOG_E("a0: 0x%08lX, a1: 0x%08lX, a2: 0x%08lX, a3: 0x%08lX\r\n", gpr32[4], gpr32[5], gpr32[6], gpr32[7]); - LOG_E("t0: 0x%08lX, t1: 0x%08lX, t2: 0x%08lX, t3: 0x%08lX\r\n", gpr32[8], gpr32[9], gpr32[10], gpr32[11]); - LOG_E("t4: 0x%08lX, t5: 0x%08lX, t6: 0x%08lX, t7: 0x%08lX\r\n", gpr32[12], gpr32[13], gpr32[14], gpr32[15]); - LOG_E("s0: 0x%08lX, s1: 0x%08lX, s2: 0x%08lX, s3: 0x%08lX\r\n", gpr32[16], gpr32[17], gpr32[18], gpr32[19]); - LOG_E("s4: 0x%08lX, s5: 0x%08lX, s6: 0x%08lX, s7: 0x%08lX\r\n", gpr32[20], gpr32[21], gpr32[22], gpr32[23]); - LOG_E("t8: 0x%08lX, t9: 0x%08lX, k0: 0x%08lX, k1: 0x%08lX\r\n", gpr32[24], gpr32[25], gpr32[26], gpr32[27]); - LOG_E("gp: 0x%08lX, sp: 0x%08lX, fp: 0x%08lX, ra: 0x%08lX\r\n", gpr32[28], gpr32[29], gpr32[30], gpr32[31]); - LOG_FLUSH(); - - while (1); -} - - -void exception_interrupt_handler (uint32_t interrupt) { - LOG_I("Unimplemented interrupt, mask: 0x%08lX\r\n", interrupt); - LOG_FLUSH(); + if (exception_code == EXCEPTION_INTERRUPT) { + if (interrupt_mask & INTERRUPT_MASK_TIMER) { + exception_print(&x, &y, "Bootloader did not finish within 10 seconds limit"); + } + } else if (exception_code == EXCEPTION_SYSCALL) { + uint32_t code = (((*instruction_address) & SYSCALL_CODE_MASK) >> SYSCALL_CODE_BIT); + + if (code == TRIGGER_CODE_ERROR) { + const char *message = (const char *) (gpr32[4]); + exception_print(&x, &y, "%s", message); + } else if (code == TRIGGER_CODE_ASSERT) { + const char *file = (const char *) (gpr32[4]); + int line = (int) (gpr32[5]); + const char *func = (const char *) (gpr32[6]); + const char *failedexpr = (const char *) (gpr32[7]); + + exception_print(&x, &y, "assertion \"%s\" failed:", failedexpr); + exception_print(&x, &y, " file \"%s\", line %d, %s%s", file, line, func ? "function: " : "", func); + } + } while (1); } diff --git a/sw/n64/src/exception.h b/sw/n64/src/exception.h index ce522d1..c67dfc5 100644 --- a/sw/n64/src/exception.h +++ b/sw/n64/src/exception.h @@ -2,56 +2,10 @@ #define EXCEPTION_H__ -#define VECTOR_LOCATION (0xA0000000) -#define VECTOR_SIZE (0x80) -#define VECTOR_NUM (4) +#define EXCEPTION_TRIGGER(code) { asm volatile ("syscall %[c]\n" :: [c] "i" (code)); } -#define HIT_INVALIDATE_I ((4 << 2) | 0) - -#define C0_STATUS $12 -#define C0_CAUSE $13 -#define C0_EPC $14 - -#define EXCEPTION_CODE_BIT (2) -#define EXCEPTION_CODE_MASK (0x007C) -#define INTERRUPT_PENDING_BIT (8) -#define INTERRUPT_PENDING_MASK (0xFF00) - -#define AT_OFFSET (8) -#define V0_OFFSET (16) -#define V1_OFFSET (24) -#define A0_OFFSET (32) -#define A1_OFFSET (40) -#define A2_OFFSET (48) -#define A3_OFFSET (56) -#define T0_OFFSET (64) -#define T1_OFFSET (72) -#define T2_OFFSET (80) -#define T3_OFFSET (88) -#define T4_OFFSET (96) -#define T5_OFFSET (104) -#define T6_OFFSET (112) -#define T7_OFFSET (120) -#define S0_OFFSET (128) -#define S1_OFFSET (136) -#define S2_OFFSET (144) -#define S3_OFFSET (152) -#define S4_OFFSET (160) -#define S5_OFFSET (168) -#define S6_OFFSET (176) -#define S7_OFFSET (184) -#define T8_OFFSET (192) -#define T9_OFFSET (200) -#define K0_OFFSET (208) -#define K1_OFFSET (216) -#define GP_OFFSET (224) -#define SP_OFFSET (232) -#define FP_OFFSET (240) -#define RA_OFFSET (248) -#define C0_STATUS_OFFSET (256) -#define C0_CAUSE_OFFSET (260) -#define C0_EPC_OFFSET (264) -#define SAVE_REGISTERS_SIZE (272) +#define TRIGGER_CODE_ERROR (0) +#define TRIGGER_CODE_ASSERT (1) #endif diff --git a/sw/n64/src/fatfs/ffconf.h b/sw/n64/src/fatfs/ffconf.h index 076be51..470b426 100644 --- a/sw/n64/src/fatfs/ffconf.h +++ b/sw/n64/src/fatfs/ffconf.h @@ -15,7 +15,7 @@ / and optional writing functions as well. */ -#define FF_FS_MINIMIZE 1 +#define FF_FS_MINIMIZE 2 /* This option defines minimization level to remove some basic API functions. / / 0: Basic functions are fully enabled. @@ -34,7 +34,7 @@ /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ -#define FF_USE_FASTSEEK 1 +#define FF_USE_FASTSEEK 0 /* This option switches fast seek function. (0:Disable or 1:Enable) */ @@ -113,7 +113,7 @@ */ -#define FF_USE_LFN 2 +#define FF_USE_LFN 1 #define FF_MAX_LFN 255 /* The FF_USE_LFN switches the support for LFN (long file name). / @@ -153,7 +153,7 @@ / on character encoding. When LFN is not enabled, these options have no effect. */ -#define FF_FS_RPATH 2 +#define FF_FS_RPATH 1 /* This option configures support for relative path. / / 0: Disable relative path and remove related functions. diff --git a/sw/n64/src/font.c b/sw/n64/src/font.c new file mode 100644 index 0000000..bd349a6 --- /dev/null +++ b/sw/n64/src/font.c @@ -0,0 +1,103 @@ +// Manually converted font "Dogica" from https://www.dafont.com/dogica.font + +#include "font.h" + + +const uint8_t font_data[96][FONT_CHAR_BYTES] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, + { 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00, }, + { 0x00, 0x6C, 0x6C, 0x36, 0x00, 0x00, 0x00, 0x00, }, + { 0x00, 0x6C, 0xFE, 0x6C, 0x6C, 0xFE, 0x6C, 0x00, }, + { 0x00, 0x7C, 0xD6, 0x16, 0x7C, 0xD0, 0xD6, 0x7C, }, + { 0x62, 0x35, 0x37, 0x1A, 0x58, 0xAC, 0xEC, 0x46, }, + { 0x1C, 0x36, 0x36, 0x1C, 0xF6, 0x66, 0xFC, 0x00, }, + { 0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, }, + { 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x00, }, + { 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x00, }, + { 0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00, }, + { 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x18, }, + { 0x00, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, }, + { 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0C, 0x0C, }, + { 0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x3C, 0x00, }, + { 0x18, 0x1E, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, }, + { 0x3C, 0x66, 0x60, 0x30, 0x18, 0x0C, 0x7E, 0x00, }, + { 0x3E, 0x60, 0x60, 0x3C, 0x60, 0x60, 0x3E, 0x00, }, + { 0x30, 0x38, 0x3C, 0x36, 0x7E, 0x30, 0x30, 0x00, }, + { 0x7E, 0x06, 0x3E, 0x60, 0x60, 0x66, 0x3C, 0x00, }, + { 0x3C, 0x66, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00, }, + { 0x7E, 0x66, 0x60, 0x30, 0x18, 0x0C, 0x0C, 0x00, }, + { 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, }, + { 0x3C, 0x66, 0x66, 0x7C, 0x60, 0x30, 0x1C, 0x00, }, + { 0x00, 0x00, 0x18, 0x00, 0x00, 0x18, 0x00, 0x00, }, + { 0x00, 0x00, 0x00, 0x30, 0x00, 0x30, 0x30, 0x18, }, + { 0x00, 0x30, 0x18, 0x0C, 0x18, 0x30, 0x00, 0x00, }, + { 0x00, 0x00, 0xFE, 0x00, 0xFE, 0x00, 0x00, 0x00, }, + { 0x00, 0x18, 0x30, 0x60, 0x30, 0x18, 0x00, 0x00, }, + { 0x3C, 0x66, 0x60, 0x38, 0x0C, 0x00, 0x18, 0x00, }, + { 0x3E, 0x63, 0x7F, 0x7B, 0x3F, 0xC3, 0x7E, 0x00, }, + { 0x3C, 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x00, }, + { 0x3E, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00, }, + { 0x3C, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3C, 0x00, }, + { 0x3F, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, }, + { 0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x7E, 0x00, }, + { 0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x06, 0x00, }, + { 0x7C, 0x06, 0x06, 0x76, 0x66, 0x66, 0x7C, 0x00, }, + { 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, }, + { 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, }, + { 0x3E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0E, 0x00, }, + { 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x36, 0x66, 0x00, }, + { 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x7C, 0x00, }, + { 0xC6, 0xC6, 0xEE, 0xFE, 0xC6, 0xC6, 0xC6, 0x00, }, + { 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x66, 0x00, }, + { 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, }, + { 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00, }, + { 0x3C, 0x66, 0x66, 0x66, 0x6E, 0x36, 0x7C, 0x00, }, + { 0x3E, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x66, 0x00, }, + { 0x3C, 0x66, 0x06, 0x3C, 0x60, 0x66, 0x3C, 0x00, }, + { 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, }, + { 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, }, + { 0x66, 0x66, 0x66, 0x66, 0x3C, 0x3C, 0x18, 0x00, }, + { 0xC3, 0xC3, 0xDB, 0xDB, 0xDB, 0xFF, 0x66, 0x00, }, + { 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, }, + { 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, }, + { 0x7E, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00, }, + { 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0x00, }, + { 0x0C, 0x0C, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, }, + { 0x38, 0x30, 0x30, 0x30, 0x30, 0x30, 0x38, 0x00, }, + { 0x00, 0x38, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, }, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, }, + { 0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, }, + { 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x66, 0x7C, 0x00, }, + { 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, }, + { 0x00, 0x3C, 0x66, 0x06, 0x06, 0x06, 0x7C, 0x00, }, + { 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, }, + { 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x06, 0x7C, 0x00, }, + { 0x78, 0x0C, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00, }, + { 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x3C, }, + { 0x06, 0x06, 0x3E, 0x6E, 0x66, 0x66, 0x66, 0x00, }, + { 0x18, 0x00, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x00, }, + { 0x00, 0x3C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0C, }, + { 0x00, 0x66, 0x36, 0x1E, 0x1E, 0x36, 0x66, 0x00, }, + { 0x00, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x38, 0x00, }, + { 0x00, 0x7E, 0xDB, 0xDB, 0xDB, 0xDB, 0xDB, 0x00, }, + { 0x00, 0x38, 0x6E, 0x66, 0x66, 0x66, 0x66, 0x00, }, + { 0x00, 0x3C, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, }, + { 0x00, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x06, }, + { 0x00, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x60, }, + { 0x00, 0x78, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C, 0x00, }, + { 0x00, 0x3C, 0x06, 0x3C, 0x60, 0x66, 0x3C, 0x00, }, + { 0x0C, 0x0C, 0x7C, 0x0C, 0x0C, 0x0C, 0x78, 0x00, }, + { 0x00, 0x66, 0x66, 0x66, 0x66, 0x76, 0x7C, 0x00, }, + { 0x00, 0x66, 0x66, 0x66, 0x3C, 0x3C, 0x18, 0x00, }, + { 0x00, 0xC0, 0xDB, 0xDB, 0xDB, 0xDB, 0x7E, 0x00, }, + { 0x00, 0x66, 0x3C, 0x18, 0x18, 0x3C, 0x66, 0x00, }, + { 0x00, 0x6C, 0x6C, 0x6C, 0x38, 0x30, 0x1C, 0x00, }, + { 0x00, 0x7C, 0x60, 0x30, 0x18, 0x0C, 0x7C, 0x00, }, + { 0x30, 0x58, 0x08, 0x0C, 0x0C, 0x08, 0x58, 0x30, }, + { 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, }, + { 0x18, 0x34, 0x20, 0x60, 0x60, 0x20, 0x34, 0x18, }, + { 0x00, 0x00, 0x00, 0xDC, 0x76, 0x00, 0x00, 0x00, }, + { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, }, +}; diff --git a/sw/n64/src/font.h b/sw/n64/src/font.h new file mode 100644 index 0000000..350d070 --- /dev/null +++ b/sw/n64/src/font.h @@ -0,0 +1,16 @@ +#ifndef FONT_H__ +#define FONT_H__ + + +#include + + +#define FONT_WIDTH (8) +#define FONT_HEIGHT (8) +#define FONT_CHAR_BYTES (8) + + +extern const uint8_t font_data[96][FONT_CHAR_BYTES]; + + +#endif diff --git a/sw/n64/src/init.c b/sw/n64/src/init.c index 1f1d31b..231ee0c 100644 --- a/sw/n64/src/init.c +++ b/sw/n64/src/init.c @@ -7,6 +7,4 @@ void init (void) { si_io_write((io32_t *) (&PIFRAM[0x3C]), pifram | 0x08); sc64_init(); - - LOG_I("Initialized\r\n"); } diff --git a/sw/n64/src/interrupt.c b/sw/n64/src/interrupt.c new file mode 100644 index 0000000..0e7914a --- /dev/null +++ b/sw/n64/src/interrupt.c @@ -0,0 +1,9 @@ +#include "sc64.h" + + +void exception_interrupt_handler (uint32_t exception_code, uint32_t interrupt_mask) { + LOG_I("Unimplemented interrupt, mask: 0x%08lX\r\n", interrupt_mask); + LOG_FLUSH(); + + while (1); +} diff --git a/sw/n64/src/main.c b/sw/n64/src/main.c index 2328a24..98bcbf2 100644 --- a/sw/n64/src/main.c +++ b/sw/n64/src/main.c @@ -1,4 +1,5 @@ #include "boot.h" +#include "error.h" #include "sc64.h" #include "storage.h" @@ -11,67 +12,45 @@ void main (void) { sc64_get_info(&sc64_info); - LOG_I("Bootloader version: %.32s\r\n", sc64_info.bootloader_version); - switch (sc64_info.boot_mode) { case BOOT_MODE_MENU: - LOG_I("Running menu from SD card\r\n"); storage_run_menu(STORAGE_BACKEND_SD, &boot_info, &sc64_info); break; case BOOT_MODE_ROM: - LOG_I("Running ROM from SDRAM\r\n"); boot_info.device_type = BOOT_DEVICE_TYPE_ROM; break; case BOOT_MODE_DDIPL: - LOG_I("Running DDIPL from SDRAM\r\n"); boot_info.device_type = BOOT_DEVICE_TYPE_DD; break; case BOOT_MODE_DIRECT: - LOG_I("Running menu from USB\r\n"); storage_run_menu(STORAGE_BACKEND_USB, &boot_info, &sc64_info); break; default: - LOG_E("Unknown boot mode! - %d\r\n", sc64_info.boot_mode); - while (1); + error_display("Unknown boot mode selected"); + break; } if (sc64_info.tv_type != TV_TYPE_UNKNOWN) { boot_info.tv_type = sc64_info.tv_type; - LOG_I("Using provided TV type: %d\r\n", boot_info.tv_type); } else { - if (boot_get_tv_type(&boot_info)) { - LOG_I("Using TV type guessed from ROM header: %d\r\n", boot_info.tv_type); - } else { + if (!boot_get_tv_type(&boot_info)) { boot_info.tv_type = OS_INFO->tv_type; - LOG_I("Using console TV type: %d\r\n", boot_info.tv_type); } } if (sc64_info.cic_seed != 0xFFFF) { boot_info.cic_seed = sc64_info.cic_seed & 0xFF; boot_info.version = (sc64_info.cic_seed >> 8) & 0x01; - LOG_I("Using provided CIC seed and version: 0x%02X.%d\r\n", boot_info.cic_seed, boot_info.version); } else { - if (boot_get_cic_seed_version(&boot_info)) { - LOG_I("Using CIC seed and version guessed from IPL3: 0x%02X.%d\r\n", boot_info.cic_seed, boot_info.version); - } else { + if (!boot_get_cic_seed_version(&boot_info)) { boot_info.cic_seed = 0x3F; boot_info.version = 0; - LOG_I("Using 6102/7101 CIC seed and version: 0x%02X.%d\r\n", boot_info.cic_seed, boot_info.version); } } - if (sc64_info.is_viewer_enabled) { - LOG_I("Initializing IS-Viewer 64\r\n"); - sc64_init_is_viewer(); - } - - LOG_I("Booting IPL3\r\n\r\n"); - LOG_FLUSH(); - boot(&boot_info); } diff --git a/sw/n64/src/sc64.c b/sw/n64/src/sc64.c index d57dcad..66b89fb 100644 --- a/sw/n64/src/sc64.c +++ b/sw/n64/src/sc64.c @@ -51,28 +51,6 @@ void sc64_set_config (cfg_id_t id, uint32_t value) { } void sc64_get_info (sc64_info_t *info) { - uint32_t tmp; - io32_t *src = (io32_t *) UNCACHED(&header_text_info); - char *dst = info->bootloader_version; - - bool sdram_switched = sc64_get_config(CFG_ID_SDRAM_SWITCH); - - if (sdram_switched) { - sc64_set_config(CFG_ID_SDRAM_SWITCH, false); - } - - for (int i = 0; i < sizeof(info->bootloader_version); i += sizeof(uint32_t)) { - tmp = pi_io_read(src++); - *dst++ = (tmp >> 24); - *dst++ = (tmp >> 16); - *dst++ = (tmp >> 8); - *dst++ = (tmp & 0xFF); - } - - if (sdram_switched) { - sc64_set_config(CFG_ID_SDRAM_SWITCH, true); - } - info->dd_enabled = (bool) sc64_get_config(CFG_ID_DD_ENABLE); info->is_viewer_enabled = (bool) sc64_get_config(CFG_ID_IS_VIEWER_ENABLE); info->save_type = (save_type_t) sc64_get_config(CFG_ID_SAVE_TYPE); diff --git a/sw/n64/src/sc64.h b/sw/n64/src/sc64.h index 14dbc4c..219bc3d 100644 --- a/sw/n64/src/sc64.h +++ b/sw/n64/src/sc64.h @@ -21,19 +21,6 @@ #endif -typedef struct { - io32_t SR_CMD; - io32_t DATA[2]; - io32_t VERSION; -} sc64_regs_t; - -#define SC64_BASE (0x1FFF0000) -#define SC64 ((sc64_regs_t *) SC64_BASE) - -#define SC64_SR_CMD_ERROR (1 << 28) -#define SC64_SR_CPU_BUSY (1 << 30) -#define SC64_SR_CPU_READY (1 << 31) - #define SC64_CMD_CONFIG ('C') #define SC64_CMD_QUERY ('Q') #define SC64_CMD_DEBUG_RX_DATA ('E') @@ -101,14 +88,13 @@ typedef enum { typedef struct { bool dd_enabled; + bool is_viewer_enabled; save_type_t save_type; uint16_t cic_seed; tv_type_t tv_type; io32_t *save_location; io32_t *ddipl_location; boot_mode_t boot_mode; - bool is_viewer_enabled; - char bootloader_version[32]; } sc64_info_t; diff --git a/sw/n64/src/sys.c b/sw/n64/src/sys.c index e2231af..e54910b 100644 --- a/sw/n64/src/sys.c +++ b/sw/n64/src/sys.c @@ -1,29 +1,15 @@ #include "sys.h" -void c0_set_status (uint32_t status) { - asm volatile ( - ".set noat \n" - ".set noreorder \n" - "mtc0 %[status], $12 \n" - "nop \n" :: - [status] "r" (status) - ); -} - uint32_t io_read (io32_t *address) { io32_t *uncached = UNCACHED(address); - asm volatile ("" ::: "memory"); uint32_t value = *uncached; - asm volatile ("" ::: "memory"); return value; } void io_write (io32_t *address, uint32_t value) { io32_t *uncached = UNCACHED(address); - asm volatile ("" ::: "memory"); *uncached = value; - asm volatile ("" ::: "memory"); } uint32_t pi_busy (void) { diff --git a/sw/n64/src/sys.h b/sw/n64/src/sys.h index 765bf8e..80975b1 100644 --- a/sw/n64/src/sys.h +++ b/sw/n64/src/sys.h @@ -46,6 +46,15 @@ typedef volatile uint32_t io32_t; #define C0_SR_CU2 (1 << 30) #define C0_SR_CU3 (1 << 31) +#define C0_CR_IP0 (1 << 8) +#define C0_CR_IP1 (1 << 9) +#define C0_CR_IP2 (1 << 9) +#define C0_CR_IP3 (1 << 9) +#define C0_CR_IP4 (1 << 9) +#define C0_CR_IP5 (1 << 9) +#define C0_CR_IP6 (1 << 9) +#define C0_CR_IP7 (1 << 9) +#define C0_CR_BD (1 << 31) typedef struct { io32_t DMEM[1024]; @@ -243,6 +252,8 @@ typedef struct { #define ROM_DDIPL_BASE (0x06000000UL) #define ROM_DDIPL ((io32_t *) ROM_DDIPL_BASE) + + #define ROM_CART_BASE (0x10000000UL) #define ROM_CART ((io32_t *) ROM_CART_BASE) @@ -263,9 +274,37 @@ typedef struct { #define PIFRAM ((io8_t *) PIFRAM_BASE) -void c0_set_status (uint32_t status); -uint32_t c0_get_count (void); -void wait_ms (uint32_t ms); +typedef struct { + io32_t SR_CMD; + io32_t DATA[2]; + io32_t VERSION; +} sc64_regs_t; + +#define SC64_BASE (0x1FFF0000) +#define SC64 ((sc64_regs_t *) SC64_BASE) + +#define SC64_SR_CMD_ERROR (1 << 28) +#define SC64_SR_CPU_BUSY (1 << 30) +#define SC64_SR_CPU_READY (1 << 31) + + +typedef struct { + uint32_t tv_type; + uint32_t device_type; + uint32_t device_base; + uint32_t reset_type; + uint32_t cic_id; + uint32_t version; + uint32_t mem_size; + uint8_t app_nmi_buffer[64]; + uint32_t __reserved_1[37]; + uint32_t mem_size_6105; +} os_info_t; + +#define OS_INFO_BASE (0x80000300UL) +#define OS_INFO ((os_info_t *) OS_INFO_BASE) + + uint32_t io_read (io32_t *address); void io_write (io32_t *address, uint32_t value); uint32_t pi_busy (void); diff --git a/sw/n64/src/syscalls.c b/sw/n64/src/syscalls.c index 7cb1b25..b776c74 100644 --- a/sw/n64/src/syscalls.c +++ b/sw/n64/src/syscalls.c @@ -3,6 +3,7 @@ #include #include #include +#include "exception.h" #include "sc64.h" @@ -21,7 +22,7 @@ int _fstat_r (struct _reent *prt, int fd, struct stat *pstat) { } int _isatty_r (struct _reent *prt, int fd) { - if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO){ + if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO) { return 1; } errno = EBADF; @@ -66,6 +67,6 @@ ssize_t _write_r (struct _reent *prt, int fd, const void *buf, size_t cnt) { } void __assert_func (const char *file, int line, const char *func, const char *failedexpr) { - LOG_E("\r\nassertion \"%s\" failed: file \"%s\", line %d%s%s\r\n", failedexpr, file, line, func ? ", function: " : "", func ? func : ""); + EXCEPTION_TRIGGER(TRIGGER_CODE_ASSERT); while (1); }