diff --git a/arm9loaderhax.bin b/arm9loaderhax.bin index f8141ca..6c92104 100755 Binary files a/arm9loaderhax.bin and b/arm9loaderhax.bin differ diff --git a/kernel/hal/3ds/Makefile b/kernel/hal/3ds/Makefile index 24ff54f..afbe096 100644 --- a/kernel/hal/3ds/Makefile +++ b/kernel/hal/3ds/Makefile @@ -4,7 +4,7 @@ ARM11SRCS = $(shell find arm11 -name '*.cpp' -o -name '*.[cS]') ARM9OBJS = $(addsuffix .o,$(basename $(ARM9SRCS))) ARM11OBJS = $(addsuffix .o,$(basename $(ARM11SRCS))) ARM9FLAGS = -mcpu=arm946e-s -march=armv5te -mlittle-endian -ARM11FLAGS = -mcpu=mpcore -mlittle-endian +ARM11FLAGS = -mcpu=mpcore -mlittle-endian -mtune=mpcore -mfpu=vfp CPP = $(PREFIX)g++ CC = $(PREFIX)gcc diff --git a/kernel/hal/3ds/arm11/asm/a11snippets.S b/kernel/hal/3ds/arm11/asm/a11snippets.S new file mode 100644 index 0000000..96525aa --- /dev/null +++ b/kernel/hal/3ds/arm11/asm/a11snippets.S @@ -0,0 +1,72 @@ +.section .text +.global _a11vectors_begin +.global _a11vectors_end +.extern _start +_a11vectors_begin: + //b start + b data_abort + b fiq + b irq + b prefetch_abort + b _svc + b udi +start: + b =_start +.extern handleINT11 +data_abort: + sub lr, #8 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #0 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT11 +fiq: + sub lr, #4 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #1 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT11 +irq: + sub lr, #4 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #2 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT11 +prefetch_abort: + sub lr, #4 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #3 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT11 +_svc: + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #4 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT11 +udi: + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #5 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT11 +_a11vectors_end: +.global initInterrupts +initInterrupts: + MCR p15, 0, r0, c7, c7, 0 + bx lr diff --git a/kernel/hal/3ds/arm11/init/arm11init.cpp b/kernel/hal/3ds/arm11/init/arm11init.cpp index fdfe608..e0f4222 100644 --- a/kernel/hal/3ds/arm11/init/arm11init.cpp +++ b/kernel/hal/3ds/arm11/init/arm11init.cpp @@ -2,34 +2,28 @@ //A11 SYS_CORE //If it's zero, SYS_CORE is ready for a new task #include -#include -void(**fpointer)(void)=(void(**)(void))0x1FFFFFF8; -void __attribute__((naked)) arm11Stub(void) -{ - //Disable interrupts - __asm(".word 0xF10C01C0"); - - //Wait for the entry to be set - while(*fpointer == &arm11Stub); - - //Jump to it - (*fpointer)(); -} -void mainRoutine() { +#include +extern "C" void initInterrupts(); +void(**fpointer)(void*)=(void(**)(void*))0x1FFFFFF8; +void **farg = (void**)0x1FFFFFFC; +//Flags: +//0: Output from ARM11 +//1: puts() lock +uint32_t *flags = (uint32_t*)0x1FFFFFF4; +namespace MTGosHAL { +void mainRoutine(void*) { + *farg=nullptr; *fpointer=nullptr; while(true) { if(!(*fpointer)) continue; - (*fpointer)(); + (*fpointer)(*farg); + *farg=nullptr; *fpointer=nullptr; + *flags&=~1; } } -unsigned int seed=0; -unsigned int random() { - return seed=0x41C64E6D * seed + 0x00006073; -} -#define CALCXY_top(x,y) ((x)*240+240-(y)) -void initScreen() { +void initScreen(void*) { //top screen lfb size: 0x5dc00 //bottom screen lfb size: 0x4b000 //lfb locations: 0x18000000 (left 1) @@ -38,6 +32,9 @@ void initScreen() { //lfb locations: 0x18120000 (right 2) //lfb locations: 0x18180000 (bottom 1) //lfb locations: 0x181D0000 (bottom 2) + unsigned int *lfbs = (unsigned int*)0x18000000; + for(int i=0;i<475136;i++) + lfbs[i]=0; unsigned int *fb_init=(unsigned int*)0x10400400; fb_init[0x70/4]&=~0x7; fb_init[0x170/4]&=~0x7; @@ -49,18 +46,42 @@ void initScreen() { fb_init[0x168/4]=0x18180000; fb_init[0x16C/4]=0x181D0000; fb_init[0x190/4]=960; - int *lfb=(int*)0x18060000; - for(int bx=0;bx<32;bx++) { - for(int by=0;by<8;by++) { - for(int x=0;x<8;x++) { - for(int y=0;y<8;y++) { - if(font[bx+by*32][y]&(1<pc << "\n"; + out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n"; + out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n"; + out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n"; + out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n"; + out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n"; + out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n"; + out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n"; + *flags&=~1; + if((id!=1)&&(id!=2)&&(id!=4)) + for(;;); } diff --git a/kernel/hal/3ds/arm11/io/a11textDISP.cpp b/kernel/hal/3ds/arm11/io/a11textDISP.cpp new file mode 100644 index 0000000..f2f1944 --- /dev/null +++ b/kernel/hal/3ds/arm11/io/a11textDISP.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +int x=0, y=0; +extern uint32_t *flags; +namespace MTGosHAL { + FG_color fg=FG_color::WHITE; + BG_color bg=BG_color::BLACK; + uint32_t* toplfb = (uint32_t*)0x18000000; + uint32_t* bottomlfb = (uint32_t*)0x18180000; + int base=10; + + void Screen::putChar(char c) { + while(*flags&2); //to prevent garbage to be displayed when ARM9&ARM11 are trying to access it at the same time + *flags|=2; + switch(c) { + case '\n': + x=0; y++; + break; + case '\r': + x=0; + break; + case '\b': + x--; + if(x<0) x=0; + putChar(' '); + x--; + if(x<0) x=0; + break; + case '\0': + break; + default: + for(int lx=0;lx<8;lx++) { + for(int ly=0;ly<8;ly++) { + if(font[(int)((uint8_t)c)][ly]&(1<=TOP_SCREEN_HEIGHT) + bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast(fg)); + else + toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast(fg)); + } else { + if(y>=TOP_SCREEN_HEIGHT) + bottomlfb[CALCXY(x*8+lx,(y-TOP_SCREEN_HEIGHT)*8+ly)]=__builtin_bswap32(static_cast(bg)); + else + toplfb[CALCXY(x*8+lx,(y)*8+ly)]=__builtin_bswap32(static_cast(bg)); + } + } + } + x++; + if(x==(y>=TOP_SCREEN_HEIGHT?BOTTOM_SCREEN_WIDTH:TOP_SCREEN_WIDTH)) { + x=0; + y++; + } + break; + } + if(y>=TOP_SCREEN_HEIGHT+BOTTOM_SCREEN_HEIGHT) + scroll_impl(); + *flags&=~2; //Unlock + } + void Screen::clrscr_impl() { + for(int p=0;p<400*240;p++) + toplfb[p]=__builtin_bswap32(static_cast(bg)); + for(int p=0;p<320*240;p++) + bottomlfb[p]=__builtin_bswap32(static_cast(bg)); + } + void Screen::scroll_impl() { + for(int ly=0;ly<240-8;ly++) { + for(int lx=0;lx<400;lx++) { + toplfb[CALCXY(lx,ly)]=toplfb[CALCXY(lx,ly+8)]; + } + } + for(int ly=0;ly<8;ly++) { + for(int lx=0;lx<40;lx++) { + toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast(bg)); + } + for(int lx=40;lx<360;lx++) { + toplfb[CALCXY(lx,ly+240-8)]=bottomlfb[CALCXY(lx-40,ly)]; + } + for(int lx=360;lx<400;lx++) { + toplfb[CALCXY(lx,ly+240-8)]=__builtin_bswap32(static_cast(bg)); + } + } + for(int ly=0;ly<240-8;ly++) { + for(int lx=0;lx<320;lx++) { + bottomlfb[CALCXY(lx,ly)]=bottomlfb[CALCXY(lx,ly+8)]; + } + } + for(int ly=240-8;ly<240;ly++) { + for(int lx=0;lx<320;lx++) { + bottomlfb[CALCXY(lx,ly)]=__builtin_bswap32(static_cast(bg)); + } + } + y--; + } + auto Screen::a11puts(const char *s) -> void { + int i=0; + while(s[i]) + putChar(s[i]); + } +} diff --git a/kernel/hal/3ds/arm9/asm/snippets.S b/kernel/hal/3ds/arm9/asm/snippets.S new file mode 100644 index 0000000..e2a6cb5 --- /dev/null +++ b/kernel/hal/3ds/arm9/asm/snippets.S @@ -0,0 +1,68 @@ +.section .text +.global _a9vectors_begin +.global _a9vectors_end +.extern _start +_a9vectors_begin: + //b start + b data_abort + b fiq + b irq + b prefetch_abort + b _svc + b udi +start: + b =_start +.extern handleINT9 +data_abort: + sub lr, #8 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #0 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT9 +fiq: + sub lr, #4 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #1 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT9 +irq: + sub lr, #4 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #2 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT9 +prefetch_abort: + sub lr, #4 + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #3 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT9 +_svc: + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #4 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT9 +udi: + stmdb sp!, {r0-r12,lr} + mov r0, sp + mov r1, #5 + ldr r2, [pc, #4] + blx r2 + ldmia sp!, {r0-r12, pc}^ +.word handleINT9 +_a9vectors_end: diff --git a/kernel/hal/3ds/arm9/boot/boot.S b/kernel/hal/3ds/arm9/boot/boot.S index 7912419..64419ac 100644 --- a/kernel/hal/3ds/arm9/boot/boot.S +++ b/kernel/hal/3ds/arm9/boot/boot.S @@ -44,8 +44,8 @@ _start: mrc p15, 0, r0, c1, c0, 0 // read control register orr r0, r0, #(1<<18) // - itcm enable orr r0, r0, #(1<<16) // - dtcm enable - orr r0, r0, #(1<<12) // - instruction cache enable - orr r0, r0, #(1<<2) // - data cache enable + //orr r0, r0, #(1<<12) // - instruction cache enable + //orr r0, r0, #(1<<2) // - data cache enable orr r0, r0, #(1<<0) // - mpu enable mcr p15, 0, r0, c1, c0, 0 // write control register diff --git a/kernel/hal/3ds/arm9/init/init.cpp b/kernel/hal/3ds/arm9/init/init.cpp index 95df592..58b6a77 100644 --- a/kernel/hal/3ds/arm9/init/init.cpp +++ b/kernel/hal/3ds/arm9/init/init.cpp @@ -1,14 +1,74 @@ -void __attribute__((naked)) arm11Stub(void); -void mainRoutine(); -void initScreen(); -void(**a11fpointer)(void)=(void(**)(void))0x1FFFFFF8; -extern "C" void init() { - *a11fpointer=&arm11Stub; - for(int i=0;i<100;i++); - *a11fpointer=&mainRoutine; - while(*a11fpointer); - *a11fpointer=&initScreen; - while(*a11fpointer); +#include - while(true); +void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8; +void **a11farg = (void**)0x1FFFFFFC; +extern uint32_t *flags; +extern unsigned int _a9vectors_begin; +extern unsigned int _a9vectors_end; +extern unsigned int _a11vectors_begin; +extern unsigned int _a11vectors_end; +namespace MTGosHAL { + void mainRoutine(void*); + void initScreen(void*); + void testSVC(void*); + void main() { + *a11farg = 0; + *a11fpointer=&mainRoutine; + while(*a11fpointer); + *a11fpointer=&initScreen; + while(*a11fpointer); + unsigned int * output=(unsigned int*)0x08000000; + Screen out; + out << "Waiting for interrupt...\n"; + out << "Copying " << &_a9vectors_end-&_a9vectors_begin << " words...\n"; + for(int i=0;i<(&_a9vectors_end-&_a9vectors_begin);i++) { + output[i]=(&_a9vectors_begin)[i]; + } + asm volatile("svc #0\n"); + out << "Did it work?\nSetting up A11 interrupts\n"; + output=(unsigned int*)0x1FF80000; + out << "Copying " << &_a11vectors_end-&_a11vectors_begin << " words...\n"; + for(int i=0;i<(&_a11vectors_end-&_a11vectors_begin);i++) { + output[i]=(&_a11vectors_begin)[i]; + } + out << "Done!\n"; + *a11fpointer=&testSVC; + while(*a11fpointer); + out << "Did it work?\n"; + for(;;); + } +} +extern "C" void init() { + MTGosHAL::main(); +} +struct cpu_info { + unsigned int pc; + unsigned int r12; + unsigned int r11; + unsigned int r10; + unsigned int r9; + unsigned int r8; + unsigned int r7; + unsigned int r6; + unsigned int r5; + unsigned int r4; + unsigned int r3; + unsigned int r2; + unsigned int r1; + unsigned int retAddr; +}; +extern "C" void handleINT9(uint32_t stack, uint32_t id) { + MTGosHAL::Screen out; + out << MTGosHAL::Base::HEXADECIMAL << MTGosHAL::FG_color::RED << "Interrupt! " << (int)stack << "-" << (int)id << "\n"; + struct cpu_info *cpu=(struct cpu_info*)stack; + out << "handler addr " << (int) cpu->pc << "\n"; + out << "R1 " << (int) cpu->r1 << ", R2 " << (int)cpu->r2 << "\n"; + out << "R3 " << (int) cpu->r3 << ", R4 " << (int)cpu->r4 << "\n"; + out << "R5 " << (int) cpu->r5 << ", R6 " << (int)cpu->r6 << "\n"; + out << "R7 " << (int) cpu->r7 << ", R8 " << (int)cpu->r8 << "\n"; + out << "R9 " << (int) cpu->r9 << ", SL " << (int)cpu->r10 << "\n"; + out << "FP " << (int) cpu->r11 << ", IP " << (int)cpu->r12 << "\n"; + out << "SP " << (int) stack << ", PC " << (int)cpu->retAddr << "\n"; + if((id!=1)&&(id!=2)&&(id!=4)) + for(;;); } diff --git a/kernel/hal/3ds/arm9/io/textDISP.cpp b/kernel/hal/3ds/arm9/io/textDISP.cpp new file mode 100644 index 0000000..3c92aca --- /dev/null +++ b/kernel/hal/3ds/arm9/io/textDISP.cpp @@ -0,0 +1,97 @@ +#include +#include +//Flags: +//0: Output from ARM11 +//1: puts() lock +extern uint32_t *flags; +namespace MTGosHAL { + auto Screen::puts(const char *s) -> void { + + void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8; + void **a11farg = (void**)0x1FFFFFFC; + int i=0; + while(s[i]) { + if(*flags&1) + putChar(s[i++]); + else { + while(*a11fpointer); + *a11farg=(void*)((unsigned int)s[i++]); + *a11fpointer=(void(*)(void*))&putChar; + } + } + } + auto Screen::clrscr() -> void { + void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8; + while(*a11fpointer); + *a11fpointer=(void(*)(void*))(clrscr_impl); + } + auto Screen::scroll() -> void { + void(**a11fpointer)(void*)=(void(**)(void*))0x1FFFFFF8; + while(*a11fpointer); + *a11fpointer=(void(*)(void*))(scroll_impl); + } + template <> + auto Screen::operator<<(FG_color fg) -> Screen &{ + fg=fg; + return *this; + } + template <> + auto Screen::operator<<(BG_color bg) -> Screen &{ + bg=bg; + return *this; + } + auto Screen::setColor(FG_color fg) -> Screen &{ + fg=fg; + return *this; + } + auto Screen::setColor(BG_color bg) -> Screen &{ + bg=bg; + return *this; + } + auto Screen::setColor(FG_color fg, BG_color bg) -> Screen &{ + return (*this).setColor(fg).setColor(bg); + } + template <> + auto Screen::operator<<(Base output) -> Screen & { + base=static_cast(output); + return *this; + } + template <> + auto Screen::operator<<(int op) -> Screen & { + uintptr_t output=op; + const char* chars="0123456789ABCDEF"; + char buf[33]; + buf[32]='\0'; + char* ptr=buf+31; + do { + *(ptr--)=chars[output%base]; + output/=base; + } while(output && (ptr!=buf)); + puts(ptr+1); + return *this; + } + template <> + auto Screen::operator<<(long int op) -> Screen & { + uint64_t output=op; + const char* chars="0123456789ABCDEF"; + char buf[65]; + buf[64]='\0'; + char* ptr=buf+63; + do { + *(ptr--)=chars[output%base]; + output/=base; + } while(output && (ptr!=buf)); + puts(ptr+1); + return *this; + } + template <> + auto Screen::operator<<(char output) -> Screen & { + putChar(output); + return *this; + } + template <> + auto Screen::operator<<(char* output) -> Screen & { + puts(output); + return *this; + } +} diff --git a/kernel/hal/3ds/include/textDISP.hpp b/kernel/hal/3ds/include/textDISP.hpp new file mode 100644 index 0000000..fe69f73 --- /dev/null +++ b/kernel/hal/3ds/include/textDISP.hpp @@ -0,0 +1,90 @@ +#ifndef _TEXTDISP_H +#define _TEXTDISP_H +#include +#include +#include + +#define TOP_SCREEN_WIDTH 50 +#define TOP_SCREEN_HEIGHT 30 +#define BOTTOM_SCREEN_WIDTH 40 +#define BOTTOM_SCREEN_HEIGHT 30 +namespace MTGosHAL { + enum class BG_color : uint32_t { + BLACK=0x000000, + BLUE=0x0000AA, + GREEN=0x00AA00, + CYAN=0x00AAAA, + RED=0xAA0000, + MAGENTA=0xAA00AA, + BROWN=0xAA5500, + LIGHT_GREY=0xAAAAAA, + GREY=0x555555, + LIGHT_BLUE=0x5555FF, + LIGHT_GREEN=0x55FF55, + LIGHT_CYAN=0x55FFFF, + LIGHT_RED=0xFF5555, + LIGHT_MAGENTA=0xFF55FF, + YELLOW=0xFFFF55, + WHITE=0xFFFFFF + }; + enum class FG_color : uint32_t { + BLACK=0x000000, + BLUE=0x0000AA, + GREEN=0x00AA00, + CYAN=0x00AAAA, + RED=0xAA0000, + MAGENTA=0xAA00AA, + BROWN=0xAA5500, + LIGHT_GREY=0xAAAAAA, + GREY=0x555555, + LIGHT_BLUE=0x5555FF, + LIGHT_GREEN=0x55FF55, + LIGHT_CYAN=0x55FFFF, + LIGHT_RED=0xFF5555, + LIGHT_MAGENTA=0xFF55FF, + YELLOW=0xFFFF55, + WHITE=0xFFFFFF + }; + extern FG_color fg; + extern BG_color bg; + extern uint32_t* toplfb; + extern uint32_t* bottomlfb; + extern int base; + class Screen { + private: + static auto putChar(char c) -> void; //ARM11 + static auto clrscr_impl() -> void; //ARM11 + static auto scroll_impl() -> void; + public: + auto puts(const char *s) -> void; + auto a11puts(const char *s) -> void; + Screen(){ + } + template + auto operator<< (T output) -> Screen & { + puts(output); + return *this; + } + auto clrscr() -> void; + auto scroll() -> void; + auto setColor(FG_color fg) -> Screen &; + auto setColor(BG_color bg) -> Screen &; + auto setColor(FG_color fg, BG_color bg) -> Screen &; +}; +template <> +auto Screen::operator<<(FG_color fg) -> Screen &; +template <> +auto Screen::operator<<(BG_color bg) -> Screen &; +template <> +auto Screen::operator<<(Base output) -> Screen &; +template <> +auto Screen::operator<<(int output) -> Screen &; +template <> +auto Screen::operator<<(long int output) -> Screen &; +template <> +auto Screen::operator<<(char output) -> Screen &; +template <> +auto Screen::operator<<(char* output) -> Screen &; +} +#endif +#define CALCXY(x,y) ((x)*240+239-(y)) diff --git a/kernel/kernel/c_include/stdint.h b/kernel/kernel/c_include/stdint.h index c233efc..ae3ca98 100644 --- a/kernel/kernel/c_include/stdint.h +++ b/kernel/kernel/c_include/stdint.h @@ -8,7 +8,7 @@ typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long int uint64_t; typedef unsigned int uintptr_t; - +typedef unsigned int size_t; #else typedef signed char int8_t; typedef signed short int16_t; @@ -19,5 +19,5 @@ typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long int uint64_t; typedef unsigned long int uintptr_t; -#endif typedef unsigned long int size_t; +#endif diff --git a/kernel/libhal.a b/kernel/libhal.a index 0f1fd06..1b1ce74 100644 Binary files a/kernel/libhal.a and b/kernel/libhal.a differ