mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-29 08:44:15 +01:00
ironed out all broken stuff
This commit is contained in:
parent
dafa515e4f
commit
dc71f45df6
@ -6,7 +6,7 @@ OBJDUMP = $(TOOLCHAIN)objdump
|
|||||||
SIZE = $(TOOLCHAIN)size
|
SIZE = $(TOOLCHAIN)size
|
||||||
|
|
||||||
FLAGS = -march=vr4300 -mtune=vr4300 -falign-functions=32 $(USER_FLAGS)
|
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
|
ASFLAGS = -Wa,-I$(N64_INST)/mips64-elf/lib
|
||||||
LDFLAGS = -lc -nostartfiles -Wl,--gc-sections
|
LDFLAGS = -lc -nostartfiles -Wl,--gc-sections
|
||||||
|
|
||||||
@ -18,8 +18,11 @@ SRC_FILES = \
|
|||||||
exception.S \
|
exception.S \
|
||||||
boot.c \
|
boot.c \
|
||||||
crc32.c \
|
crc32.c \
|
||||||
|
error.c \
|
||||||
exception.c \
|
exception.c \
|
||||||
|
font.c \
|
||||||
init.c \
|
init.c \
|
||||||
|
interrupt.c \
|
||||||
main.c \
|
main.c \
|
||||||
sc64.c \
|
sc64.c \
|
||||||
storage.c \
|
storage.c \
|
||||||
|
@ -12,7 +12,6 @@ SECTIONS {
|
|||||||
.flash : {
|
.flash : {
|
||||||
KEEP(*(.text.rom_header));
|
KEEP(*(.text.rom_header));
|
||||||
KEEP(*(.text.ipl3));
|
KEEP(*(.text.ipl3));
|
||||||
__ipl3_font = LOADADDR(.flash) + 0xB70;
|
|
||||||
} > flash
|
} > flash
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
|
@ -93,8 +93,6 @@ bool boot_get_cic_seed_version (boot_info_t *info) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void boot (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;
|
OS_INFO->mem_size_6105 = OS_INFO->mem_size;
|
||||||
|
|
||||||
while (!(io_read(&SP->SR) & SP_SR_HALT));
|
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]);
|
stack_pointer = (void *) UNCACHED(&SP_MEM->IMEM[1020]);
|
||||||
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
|
"mtc0 %[status], $12 \n"
|
||||||
"move $sp, %[stack_pointer] \n"
|
"move $sp, %[stack_pointer] \n"
|
||||||
"jr %[entry_point] \n" ::
|
"jr %[entry_point] \n" ::
|
||||||
|
[status] "r" (C0_SR_CU1 | C0_SR_CU0 | C0_SR_FR),
|
||||||
[entry_point] "r" (entry_point),
|
[entry_point] "r" (entry_point),
|
||||||
[boot_device] "r" (boot_device),
|
[boot_device] "r" (boot_device),
|
||||||
[tv_type] "r" (tv_type),
|
[tv_type] "r" (tv_type),
|
||||||
|
@ -32,23 +32,6 @@ typedef struct {
|
|||||||
} boot_info_t;
|
} 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_tv_type (boot_info_t *info);
|
||||||
bool boot_get_cic_seed_version (boot_info_t *info);
|
bool boot_get_cic_seed_version (boot_info_t *info);
|
||||||
void boot (boot_info_t *info);
|
void boot (boot_info_t *info);
|
||||||
|
8
sw/n64/src/error.c
Normal file
8
sw/n64/src/error.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "error.h"
|
||||||
|
#include "exception.h"
|
||||||
|
|
||||||
|
|
||||||
|
void error_display (const char *message) {
|
||||||
|
EXCEPTION_TRIGGER(TRIGGER_CODE_ERROR);
|
||||||
|
while (1);
|
||||||
|
}
|
8
sw/n64/src/error.h
Normal file
8
sw/n64/src/error.h
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#ifndef ERROR_H__
|
||||||
|
#define ERROR_H__
|
||||||
|
|
||||||
|
|
||||||
|
void error_display (const char *message);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -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
|
.section .text.exception_handler
|
||||||
@ -42,9 +100,14 @@ exception_is_fatal:
|
|||||||
mfc0 $a0, C0_CAUSE
|
mfc0 $a0, C0_CAUSE
|
||||||
sw $a0, C0_CAUSE_OFFSET($k0)
|
sw $a0, C0_CAUSE_OFFSET($k0)
|
||||||
move $a1, $a0
|
move $a1, $a0
|
||||||
andi $a1, EXCEPTION_CODE_MASK
|
andi $a0, EXCEPTION_CODE_MASK
|
||||||
srl $a1, $a1, EXCEPTION_CODE_BIT
|
srl $a0, $a0, EXCEPTION_CODE_BIT
|
||||||
beq $a1, $zero, exception_interrupt
|
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:
|
exception_fatal:
|
||||||
sd $k0, K0_OFFSET($k0)
|
sd $k0, K0_OFFSET($k0)
|
||||||
@ -55,14 +118,12 @@ exception_fatal:
|
|||||||
sd $t0, C0_EPC_OFFSET($k0)
|
sd $t0, C0_EPC_OFFSET($k0)
|
||||||
addiu $t0, 4
|
addiu $t0, 4
|
||||||
dmtc0 $t0, C0_EPC
|
dmtc0 $t0, C0_EPC
|
||||||
move $a0, $k0
|
move $a2, $k0
|
||||||
la $t1, exception_fatal_handler
|
la $t1, exception_fatal_handler
|
||||||
jalr $t1
|
jalr $t1
|
||||||
j exception_restore
|
j exception_restore
|
||||||
|
|
||||||
exception_interrupt:
|
exception_interrupt:
|
||||||
andi $a0, INTERRUPT_PENDING_MASK
|
|
||||||
srl $a0, $a0, INTERRUPT_PENDING_BIT
|
|
||||||
la $t1, exception_interrupt_handler
|
la $t1, exception_interrupt_handler
|
||||||
jalr $t1
|
jalr $t1
|
||||||
|
|
||||||
@ -133,4 +194,10 @@ exception_install:
|
|||||||
bne $t4, $t5, 2b
|
bne $t4, $t5, 2b
|
||||||
addiu $t1, VECTOR_SIZE
|
addiu $t1, VECTOR_SIZE
|
||||||
bne $t1, $t2, 1b
|
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
|
jr $ra
|
||||||
|
@ -1,30 +1,37 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "boot.h"
|
|
||||||
#include "exception.h"
|
#include "exception.h"
|
||||||
#include "sc64.h"
|
#include "font.h"
|
||||||
#include "sys.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 EXCEPTION_INTERRUPT (0)
|
||||||
|
#define EXCEPTION_SYSCALL (8)
|
||||||
|
|
||||||
|
#define INTERRUPT_MASK_TIMER (1 << 7)
|
||||||
|
|
||||||
|
#define SYSCALL_CODE_MASK (0x03FF0000UL)
|
||||||
|
#define SYSCALL_CODE_BIT (16)
|
||||||
|
|
||||||
#define SCREEN_WIDTH (640)
|
#define SCREEN_WIDTH (640)
|
||||||
#define SCREEN_HEIGHT (240)
|
#define SCREEN_HEIGHT (240)
|
||||||
|
|
||||||
#define BACKGROUND_COLOR (0xFFFFFFFFUL)
|
#define BACKGROUND_COLOR (0x000000FFUL)
|
||||||
#define FOREGROUND_COLOR (0x000000FFUL)
|
#define FOREGROUND_COLOR (0xFFFFFFFFUL)
|
||||||
|
|
||||||
#define CHARACTER_WIDTH (13)
|
#define LINE_HEIGHT (12)
|
||||||
#define CHARACTER_HEIGHT (14)
|
|
||||||
#define CHARACTER_SIZE (23)
|
|
||||||
|
|
||||||
#define LINE_HEIGHT (22)
|
|
||||||
|
|
||||||
|
|
||||||
static const vi_regs_t vi_config[] = {{
|
static const vi_regs_t vi_config[] = {{
|
||||||
.CR = VI_CR_TYPE_32,
|
.CR = VI_CR_TYPE_32,
|
||||||
.MADDR = 0x00200000UL,
|
|
||||||
.H_WIDTH = SCREEN_WIDTH,
|
.H_WIDTH = SCREEN_WIDTH,
|
||||||
.V_INTR = 512,
|
.V_INTR = 512,
|
||||||
.CURR_LINE = 0,
|
.CURR_LINE = 0,
|
||||||
@ -39,7 +46,6 @@ static const vi_regs_t vi_config[] = {{
|
|||||||
.V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60),
|
.V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60),
|
||||||
}, {
|
}, {
|
||||||
.CR = VI_CR_TYPE_32,
|
.CR = VI_CR_TYPE_32,
|
||||||
.MADDR = 0x00200000UL,
|
|
||||||
.H_WIDTH = SCREEN_WIDTH,
|
.H_WIDTH = SCREEN_WIDTH,
|
||||||
.V_INTR = 512,
|
.V_INTR = 512,
|
||||||
.CURR_LINE = 0,
|
.CURR_LINE = 0,
|
||||||
@ -54,46 +60,17 @@ static const vi_regs_t vi_config[] = {{
|
|||||||
.V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60),
|
.V_SCALE = ((0x100 * SCREEN_HEIGHT) / 60),
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static const uint8_t exception_font_mapping[96] = {
|
static io32_t *exception_framebuffer = (io32_t *) (0x00200000UL);
|
||||||
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 void exception_init_screen (void) {
|
static void exception_init_screen (void) {
|
||||||
const vi_regs_t *cfg = &vi_config[OS_INFO->tv_type];
|
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++) {
|
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->H_WIDTH, cfg->H_WIDTH);
|
||||||
io_write(&VI->V_INTR, cfg->V_INTR);
|
io_write(&VI->V_INTR, cfg->V_INTR);
|
||||||
io_write(&VI->CURR_LINE, cfg->CURR_LINE);
|
io_write(&VI->CURR_LINE, cfg->CURR_LINE);
|
||||||
@ -109,24 +86,20 @@ static void exception_init_screen (void) {
|
|||||||
io_write(&VI->CR, cfg->CR);
|
io_write(&VI->CR, cfg->CR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void exception_draw_character (int x, int y, char c) {
|
static void exception_draw_character (int x, int y, char c) {
|
||||||
if ((c <= 32) || (c >= 127)) {
|
if ((c < ' ') || (c > '~')) {
|
||||||
return;
|
c = 127;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t index = exception_font_mapping[c - 32];
|
for (int i = 0; i < (FONT_WIDTH * FONT_HEIGHT); i++) {
|
||||||
uint8_t *character = ((uint8_t *) (exception_font_buffer)) + (index * CHARACTER_SIZE);
|
int c_x = x + (i % FONT_WIDTH);
|
||||||
|
int c_y = y + (i / FONT_WIDTH);
|
||||||
for (int i = 0; i < (CHARACTER_WIDTH * CHARACTER_HEIGHT); i++) {
|
|
||||||
int c_x = x + (i % CHARACTER_WIDTH);
|
|
||||||
int c_y = y + (i / CHARACTER_WIDTH);
|
|
||||||
|
|
||||||
if ((c_x >= SCREEN_WIDTH) || (c_y >= SCREEN_HEIGHT)) {
|
if ((c_x >= SCREEN_WIDTH) || (c_y >= SCREEN_HEIGHT)) {
|
||||||
break;
|
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);
|
int screen_offset = c_x + (c_y * SCREEN_WIDTH);
|
||||||
io_write(&exception_framebuffer[screen_offset], FOREGROUND_COLOR);
|
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) {
|
static void exception_print_string (int x, int y, const char *s) {
|
||||||
while (*s != '\0') {
|
while (*s != '\0') {
|
||||||
exception_draw_character(x, y, *s++);
|
exception_draw_character(x, y, *s++);
|
||||||
x += CHARACTER_WIDTH;
|
x += FONT_WIDTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void exception_print (int *x, int *y, const char* fmt, ...) {
|
static void exception_print (int *x, int *y, const char* fmt, ...) {
|
||||||
char line[64];
|
char line[128];
|
||||||
va_list args;
|
va_list args;
|
||||||
|
|
||||||
va_start(args, fmt);
|
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) {
|
static const char *exception_get_description (uint8_t exception_code) {
|
||||||
switch (exception_code) {
|
switch (exception_code) {
|
||||||
|
case 0: return "Interrupt";
|
||||||
case 1: return "TLB Modification exception";
|
case 1: return "TLB Modification exception";
|
||||||
case 2: return "TLB Miss exception (load or instruction fetch)";
|
case 2: return "TLB Miss exception (load or instruction fetch)";
|
||||||
case 3: return "TLB Miss exception (store)";
|
case 3: return "TLB Miss exception (store)";
|
||||||
@ -176,59 +150,55 @@ static const char *exception_get_description (uint8_t exception_code) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
void exception_fatal_handler (uint32_t exception_code, uint32_t interrupt_mask, exception_t *e) {
|
||||||
uint64_t gpr[32];
|
uint32_t sc64_version = pi_io_read(&SC64->VERSION);
|
||||||
uint32_t sr;
|
uint32_t *instruction_address = (uint32_t *) ((uint32_t) (e->epc));
|
||||||
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();
|
|
||||||
|
|
||||||
uint32_t gpr32[32];
|
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++) {
|
for (int i = 0; i < 32; i++) {
|
||||||
gpr32[i] = (uint32_t) (e->gpr[i]);
|
gpr32[i] = (uint32_t) (e->gpr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
int x = 12;
|
exception_init_screen();
|
||||||
int y = 8;
|
|
||||||
|
|
||||||
exception_print(&x, &y, "%s", exception_description);
|
exception_print(&x, &y, "SC64 VERSION: 0x%08lX (%4s)", sc64_version, (char *) (&sc64_version));
|
||||||
exception_print(&x, &y, "pc %08lX sr %08lX cr %08lX", (uint32_t) (e->epc), e->sr, e->cr);
|
exception_print(&x, &y, "%s at pc: 0x%08lX", exception_get_description(exception_code), (uint32_t) (e->epc));
|
||||||
exception_print(&x, &y, "zr %08lX at %08lX v0 %08lX v1 %08lX", gpr32[0], gpr32[1], gpr32[2], gpr32[3]);
|
exception_print(&x, &y, "sr: 0x%08lX, cr: 0x%08lX", e->sr, e->cr);
|
||||||
exception_print(&x, &y, "a0 %08lX a1 %08lX a2 %08lX a3 %08lX", gpr32[4], gpr32[5], gpr32[6], gpr32[7]);
|
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, "t0 %08lX t1 %08lX t2 %08lX t3 %08lX", gpr32[8], gpr32[9], gpr32[10], gpr32[11]);
|
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, "t4 %08lX t5 %08lX t6 %08lX t7 %08lX", gpr32[12], gpr32[13], gpr32[14], gpr32[15]);
|
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, "s0 %08lX s1 %08lX s2 %08lX s3 %08lX", gpr32[16], gpr32[17], gpr32[18], gpr32[19]);
|
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, "s4 %08lX s5 %08lX s6 %08lX s7 %08lX", gpr32[20], gpr32[21], gpr32[22], gpr32[23]);
|
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, "t8 %08lX t9 %08lX k0 %08lX k1 %08lX", gpr32[24], gpr32[25], gpr32[26], gpr32[27]);
|
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, "gp %08lX sp %08lX fp %08lX ra %08lX", gpr32[28], gpr32[29], gpr32[30], gpr32[31]);
|
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);
|
if (exception_code == EXCEPTION_INTERRUPT) {
|
||||||
LOG_E("pc: 0x%08lX, sr: 0x%08lX, cr: 0x%08lX\r\n", (uint32_t) (e->epc), e->sr, e->cr);
|
if (interrupt_mask & INTERRUPT_MASK_TIMER) {
|
||||||
LOG_E("zr: 0x%08lX, at: 0x%08lX, v0: 0x%08lX, v1: 0x%08lX\r\n", gpr32[0], gpr32[1], gpr32[2], gpr32[3]);
|
exception_print(&x, &y, "Bootloader did not finish within 10 seconds limit");
|
||||||
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]);
|
} else if (exception_code == EXCEPTION_SYSCALL) {
|
||||||
LOG_E("t4: 0x%08lX, t5: 0x%08lX, t6: 0x%08lX, t7: 0x%08lX\r\n", gpr32[12], gpr32[13], gpr32[14], gpr32[15]);
|
uint32_t code = (((*instruction_address) & SYSCALL_CODE_MASK) >> SYSCALL_CODE_BIT);
|
||||||
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]);
|
if (code == TRIGGER_CODE_ERROR) {
|
||||||
LOG_E("t8: 0x%08lX, t9: 0x%08lX, k0: 0x%08lX, k1: 0x%08lX\r\n", gpr32[24], gpr32[25], gpr32[26], gpr32[27]);
|
const char *message = (const char *) (gpr32[4]);
|
||||||
LOG_E("gp: 0x%08lX, sp: 0x%08lX, fp: 0x%08lX, ra: 0x%08lX\r\n", gpr32[28], gpr32[29], gpr32[30], gpr32[31]);
|
exception_print(&x, &y, "%s", message);
|
||||||
LOG_FLUSH();
|
} else if (code == TRIGGER_CODE_ASSERT) {
|
||||||
|
const char *file = (const char *) (gpr32[4]);
|
||||||
while (1);
|
int line = (int) (gpr32[5]);
|
||||||
}
|
const char *func = (const char *) (gpr32[6]);
|
||||||
|
const char *failedexpr = (const char *) (gpr32[7]);
|
||||||
|
|
||||||
void exception_interrupt_handler (uint32_t interrupt) {
|
exception_print(&x, &y, "assertion \"%s\" failed:", failedexpr);
|
||||||
LOG_I("Unimplemented interrupt, mask: 0x%08lX\r\n", interrupt);
|
exception_print(&x, &y, " file \"%s\", line %d, %s%s", file, line, func ? "function: " : "", func);
|
||||||
LOG_FLUSH();
|
}
|
||||||
|
}
|
||||||
|
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
@ -2,56 +2,10 @@
|
|||||||
#define EXCEPTION_H__
|
#define EXCEPTION_H__
|
||||||
|
|
||||||
|
|
||||||
#define VECTOR_LOCATION (0xA0000000)
|
#define EXCEPTION_TRIGGER(code) { asm volatile ("syscall %[c]\n" :: [c] "i" (code)); }
|
||||||
#define VECTOR_SIZE (0x80)
|
|
||||||
#define VECTOR_NUM (4)
|
|
||||||
|
|
||||||
#define HIT_INVALIDATE_I ((4 << 2) | 0)
|
#define TRIGGER_CODE_ERROR (0)
|
||||||
|
#define TRIGGER_CODE_ASSERT (1)
|
||||||
#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)
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
/ and optional writing functions as well. */
|
/ 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.
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
/
|
/
|
||||||
/ 0: Basic functions are fully enabled.
|
/ 0: Basic functions are fully enabled.
|
||||||
@ -34,7 +34,7 @@
|
|||||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
/* 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) */
|
/* 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
|
#define FF_MAX_LFN 255
|
||||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
/* 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. */
|
/ 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.
|
/* This option configures support for relative path.
|
||||||
/
|
/
|
||||||
/ 0: Disable relative path and remove related functions.
|
/ 0: Disable relative path and remove related functions.
|
||||||
|
103
sw/n64/src/font.c
Normal file
103
sw/n64/src/font.c
Normal file
@ -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, },
|
||||||
|
};
|
16
sw/n64/src/font.h
Normal file
16
sw/n64/src/font.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef FONT_H__
|
||||||
|
#define FONT_H__
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define FONT_WIDTH (8)
|
||||||
|
#define FONT_HEIGHT (8)
|
||||||
|
#define FONT_CHAR_BYTES (8)
|
||||||
|
|
||||||
|
|
||||||
|
extern const uint8_t font_data[96][FONT_CHAR_BYTES];
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -7,6 +7,4 @@ void init (void) {
|
|||||||
si_io_write((io32_t *) (&PIFRAM[0x3C]), pifram | 0x08);
|
si_io_write((io32_t *) (&PIFRAM[0x3C]), pifram | 0x08);
|
||||||
|
|
||||||
sc64_init();
|
sc64_init();
|
||||||
|
|
||||||
LOG_I("Initialized\r\n");
|
|
||||||
}
|
}
|
||||||
|
9
sw/n64/src/interrupt.c
Normal file
9
sw/n64/src/interrupt.c
Normal file
@ -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);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
|
#include "error.h"
|
||||||
#include "sc64.h"
|
#include "sc64.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
|
|
||||||
@ -11,67 +12,45 @@ void main (void) {
|
|||||||
|
|
||||||
sc64_get_info(&sc64_info);
|
sc64_get_info(&sc64_info);
|
||||||
|
|
||||||
LOG_I("Bootloader version: %.32s\r\n", sc64_info.bootloader_version);
|
|
||||||
|
|
||||||
switch (sc64_info.boot_mode) {
|
switch (sc64_info.boot_mode) {
|
||||||
case BOOT_MODE_MENU:
|
case BOOT_MODE_MENU:
|
||||||
LOG_I("Running menu from SD card\r\n");
|
|
||||||
storage_run_menu(STORAGE_BACKEND_SD, &boot_info, &sc64_info);
|
storage_run_menu(STORAGE_BACKEND_SD, &boot_info, &sc64_info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOT_MODE_ROM:
|
case BOOT_MODE_ROM:
|
||||||
LOG_I("Running ROM from SDRAM\r\n");
|
|
||||||
boot_info.device_type = BOOT_DEVICE_TYPE_ROM;
|
boot_info.device_type = BOOT_DEVICE_TYPE_ROM;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOT_MODE_DDIPL:
|
case BOOT_MODE_DDIPL:
|
||||||
LOG_I("Running DDIPL from SDRAM\r\n");
|
|
||||||
boot_info.device_type = BOOT_DEVICE_TYPE_DD;
|
boot_info.device_type = BOOT_DEVICE_TYPE_DD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOT_MODE_DIRECT:
|
case BOOT_MODE_DIRECT:
|
||||||
LOG_I("Running menu from USB\r\n");
|
|
||||||
storage_run_menu(STORAGE_BACKEND_USB, &boot_info, &sc64_info);
|
storage_run_menu(STORAGE_BACKEND_USB, &boot_info, &sc64_info);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
LOG_E("Unknown boot mode! - %d\r\n", sc64_info.boot_mode);
|
error_display("Unknown boot mode selected");
|
||||||
while (1);
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sc64_info.tv_type != TV_TYPE_UNKNOWN) {
|
if (sc64_info.tv_type != TV_TYPE_UNKNOWN) {
|
||||||
boot_info.tv_type = sc64_info.tv_type;
|
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 {
|
} else {
|
||||||
|
if (!boot_get_tv_type(&boot_info)) {
|
||||||
boot_info.tv_type = OS_INFO->tv_type;
|
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) {
|
if (sc64_info.cic_seed != 0xFFFF) {
|
||||||
boot_info.cic_seed = sc64_info.cic_seed & 0xFF;
|
boot_info.cic_seed = sc64_info.cic_seed & 0xFF;
|
||||||
boot_info.version = (sc64_info.cic_seed >> 8) & 0x01;
|
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 {
|
} else {
|
||||||
|
if (!boot_get_cic_seed_version(&boot_info)) {
|
||||||
boot_info.cic_seed = 0x3F;
|
boot_info.cic_seed = 0x3F;
|
||||||
boot_info.version = 0;
|
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);
|
boot(&boot_info);
|
||||||
}
|
}
|
||||||
|
@ -51,28 +51,6 @@ void sc64_set_config (cfg_id_t id, uint32_t value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sc64_get_info (sc64_info_t *info) {
|
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->dd_enabled = (bool) sc64_get_config(CFG_ID_DD_ENABLE);
|
||||||
info->is_viewer_enabled = (bool) sc64_get_config(CFG_ID_IS_VIEWER_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);
|
info->save_type = (save_type_t) sc64_get_config(CFG_ID_SAVE_TYPE);
|
||||||
|
@ -21,19 +21,6 @@
|
|||||||
#endif
|
#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_CONFIG ('C')
|
||||||
#define SC64_CMD_QUERY ('Q')
|
#define SC64_CMD_QUERY ('Q')
|
||||||
#define SC64_CMD_DEBUG_RX_DATA ('E')
|
#define SC64_CMD_DEBUG_RX_DATA ('E')
|
||||||
@ -101,14 +88,13 @@ typedef enum {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool dd_enabled;
|
bool dd_enabled;
|
||||||
|
bool is_viewer_enabled;
|
||||||
save_type_t save_type;
|
save_type_t save_type;
|
||||||
uint16_t cic_seed;
|
uint16_t cic_seed;
|
||||||
tv_type_t tv_type;
|
tv_type_t tv_type;
|
||||||
io32_t *save_location;
|
io32_t *save_location;
|
||||||
io32_t *ddipl_location;
|
io32_t *ddipl_location;
|
||||||
boot_mode_t boot_mode;
|
boot_mode_t boot_mode;
|
||||||
bool is_viewer_enabled;
|
|
||||||
char bootloader_version[32];
|
|
||||||
} sc64_info_t;
|
} sc64_info_t;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,29 +1,15 @@
|
|||||||
#include "sys.h"
|
#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) {
|
uint32_t io_read (io32_t *address) {
|
||||||
io32_t *uncached = UNCACHED(address);
|
io32_t *uncached = UNCACHED(address);
|
||||||
asm volatile ("" ::: "memory");
|
|
||||||
uint32_t value = *uncached;
|
uint32_t value = *uncached;
|
||||||
asm volatile ("" ::: "memory");
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void io_write (io32_t *address, uint32_t value) {
|
void io_write (io32_t *address, uint32_t value) {
|
||||||
io32_t *uncached = UNCACHED(address);
|
io32_t *uncached = UNCACHED(address);
|
||||||
asm volatile ("" ::: "memory");
|
|
||||||
*uncached = value;
|
*uncached = value;
|
||||||
asm volatile ("" ::: "memory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pi_busy (void) {
|
uint32_t pi_busy (void) {
|
||||||
|
@ -46,6 +46,15 @@ typedef volatile uint32_t io32_t;
|
|||||||
#define C0_SR_CU2 (1 << 30)
|
#define C0_SR_CU2 (1 << 30)
|
||||||
#define C0_SR_CU3 (1 << 31)
|
#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 {
|
typedef struct {
|
||||||
io32_t DMEM[1024];
|
io32_t DMEM[1024];
|
||||||
@ -243,6 +252,8 @@ typedef struct {
|
|||||||
|
|
||||||
#define ROM_DDIPL_BASE (0x06000000UL)
|
#define ROM_DDIPL_BASE (0x06000000UL)
|
||||||
#define ROM_DDIPL ((io32_t *) ROM_DDIPL_BASE)
|
#define ROM_DDIPL ((io32_t *) ROM_DDIPL_BASE)
|
||||||
|
|
||||||
|
|
||||||
#define ROM_CART_BASE (0x10000000UL)
|
#define ROM_CART_BASE (0x10000000UL)
|
||||||
#define ROM_CART ((io32_t *) ROM_CART_BASE)
|
#define ROM_CART ((io32_t *) ROM_CART_BASE)
|
||||||
|
|
||||||
@ -263,9 +274,37 @@ typedef struct {
|
|||||||
#define PIFRAM ((io8_t *) PIFRAM_BASE)
|
#define PIFRAM ((io8_t *) PIFRAM_BASE)
|
||||||
|
|
||||||
|
|
||||||
void c0_set_status (uint32_t status);
|
typedef struct {
|
||||||
uint32_t c0_get_count (void);
|
io32_t SR_CMD;
|
||||||
void wait_ms (uint32_t ms);
|
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);
|
uint32_t io_read (io32_t *address);
|
||||||
void io_write (io32_t *address, uint32_t value);
|
void io_write (io32_t *address, uint32_t value);
|
||||||
uint32_t pi_busy (void);
|
uint32_t pi_busy (void);
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include "exception.h"
|
||||||
#include "sc64.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) {
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
errno = EBADF;
|
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) {
|
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);
|
while (1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user