fixed screeninit, got text to show on arm11 and added documentation

This commit is contained in:
Morten Delenk 2017-04-29 20:04:29 +00:00
parent 65d9d93c24
commit d91bab77a4
14 changed files with 2662 additions and 158 deletions

2
.gitignore vendored
View file

@ -11,3 +11,5 @@ __pycache__/
*.iso *.iso
iso/kernel iso/kernel
*.firm *.firm
html/
latex/

2473
Doxyfile Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,9 @@
#pragma once #pragma once
#include <config.h> #include <config.h>
#include <stdint.h> #include <stdint.h>
/**
* I2C class for the 3DS
*/
class I2C { class I2C {
private: private:
int currDev; int currDev;
@ -10,11 +13,11 @@ class I2C {
public: public:
I2C(); I2C();
~I2C(); ~I2C();
auto waitBusy() -> void; auto waitBusy() -> void; ///< Waits for the currently selected device to finish
auto getResult() -> bool; auto getResult() -> bool; ///< Returns true when the device sent a ACK
auto stop() -> bool; auto stop() -> bool; ///< Stops the current transfer
auto selectDev(int dev) -> bool; auto selectDev(int dev) -> bool; ///< Selects current I2C device
auto selectReg(int reg) -> bool; auto selectReg(int reg) -> bool; ///< Selects current register
auto write(uint8_t data) -> bool; auto write(uint8_t data) -> bool; ///< Sends 8 bits of data
auto read() -> uint8_t; auto read() -> uint8_t; ///< Receives 8 bits of data
}; };

View file

@ -1,45 +1,53 @@
#pragma once #pragma once
#include "../i2c/i2c.hpp" #include "../i2c/i2c.hpp"
/**
* Namespace containing all currently supported MCU functions
*/
namespace MCU { namespace MCU {
extern I2C access; extern I2C access; ///< Private variable which is used to access the MCU
auto getVersionLo() -> unsigned char; auto getVersionLo() -> unsigned char; ///< Installed MCU firmware version. Current is 56 on n3ds and 27 on o3ds
auto getVersionHi() -> unsigned char; auto getVersionHi() -> unsigned char; ///< Installed MCU firmware version. Current is 3 on n3ds and 2 on o3ds
auto getLCDFlickerTop() -> unsigned char; auto getLCDFlickerTop() -> unsigned char; ///< Returns the top LCDs bias voltage in some wax
auto setLCDFlickerTop(unsigned char) -> void; auto setLCDFlickerTop(unsigned char) -> void; ///< Changes the top LCDs bias voltage
auto getLCDFlickerBottom() -> unsigned char; auto getLCDFlickerBottom() -> unsigned char; ///< Returns the bottom LCDs bias voltage
auto setLCDFlickerTop(unsigned char) -> void; auto setLCDFlickerTop(unsigned char) -> void; ///< Changes the bottom LCDs bias voltage
auto get3DSlider() -> unsigned char; auto get3DSlider() -> unsigned char; ///< Returns how far the 3D slider has moved up
auto getVolume() -> unsigned char; auto getVolume() -> unsigned char; ///< Returns the current volume
auto getBatteryPercent() -> unsigned char; auto getBatteryPercent() -> unsigned char; ///< Returns the battery percentage
auto getSystemVoltage() -> unsigned char; auto getSystemVoltage() -> unsigned char; ///< Returns the system voltage
auto isCharging() -> bool; auto isCharging() -> bool; ///< Returns true if the system is being charged
auto isOpen() -> bool; auto isOpen() -> bool; ///< Returns true if the system is not closed
extern uint8_t HIDStatus; extern uint8_t HIDStatus; ///< Storage variable for a few functions
auto updateHIDStatus() -> void; auto updateHIDStatus() -> void; ///< Updates HIDStatus
auto powerButtonPressed() -> bool; auto powerButtonPressed() -> bool; ///< true if the power button got pressed
auto powerButtonLongPressed() -> bool; auto powerButtonLongPressed() -> bool; ///< true if the power button got pressed for a long time
auto homeButtonPressed() -> bool; auto homeButtonPressed() -> bool; ///< true if the home button got pressed
auto homeButtonReleased() -> bool; auto homeButtonReleased() -> bool; ///< true if the home button got released
auto wifiEnabled() -> bool; auto wifiEnabled() -> bool; ///< true if wifi is enabled
auto closed() -> bool; auto closed() -> bool; ///< true if the system got closed
auto opened() -> bool; auto opened() -> bool; ///< true if the system got reopened
auto poweroff() -> void; auto poweroff() -> void; ///< powers the system off
auto reboot() -> void; auto reboot() -> void; ///< restarts the system
auto enableTopLCD() -> void; auto enableTopLCD() -> void; ///< enables the top LCD
auto disableTopLCD() -> void; auto disableTopLCD() -> void; ///< disables the top LCD
auto enableBottomLCD() -> void; auto enableBottomLCD() -> void; ///< enables the bottom LCD
auto disableBottomLCD() -> void; auto disableBottomLCD() -> void; ///< disables the bottom LCD
auto setWifiLED(char val) -> void; auto setWifiLED(char val) -> void; ///< set to a value between 1 and 0xF to turn on the Wifi LED
auto setCameraLED(char val) -> void; auto setCameraLED(char val) -> void; ///< set to a value between 1 and 0xF to turn on the Camera LED
auto set3DLED(char val) -> void; auto set3DLED(char val)
-> void; ///< set to a value between 1 and 0xF to turn on the 3D LED. Most devices don't have this LED
/**
* Struct for a RTC. Range is between 2000 and 2050.
* Will probably be off by a lot, as the raw value is adjusted.
*/
struct RTC_date { struct RTC_date {
unsigned char seconds; unsigned char seconds; ///< seconds. Range: 0…59
unsigned char minutes; unsigned char minutes; ///< minutes. Range: 0…59
unsigned char hours; unsigned char hours; ///< hours. Range: 0…23
unsigned char days; unsigned char days; ///< days. Range: 1…31
unsigned char months; unsigned char months; ///< months. Range: 1…12
unsigned char years; unsigned char years; ///< years. Range: 0…50
}; };
auto getRTC(RTC_date *) -> void; auto getRTC(RTC_date *) -> void; ///< sets the passed struct to the current date
auto setRTC(RTC_date *) -> void; auto setRTC(RTC_date *) -> void; ///< sets the RTC to the data in the passed struct.
} }

View file

@ -8,33 +8,6 @@
#define GL_RGB565_OES 2 #define GL_RGB565_OES 2
#define GL_RGB5_A1_OES 3 #define GL_RGB5_A1_OES 3
#define GL_RGBA4_OES 4 #define GL_RGBA4_OES 4
union FBFormat {
int val;
struct {
char format : 3;
char unused1 : 2;
bool enable3D : 1;
bool mainScreen : 1;
bool unused2 : 1;
char noRainbowStrip : 2;
char unused3 : 22;
} contents;
};
struct PDC {
int unused1[0x17];
int size;
int unused2[2];
void *leftFB[2];
int format;
int unused3;
int fbselect;
int unused4[2];
int rainbow;
int unused5[2];
int stride;
void *rightFB[2];
int padding[2];
} __attribute__((packed));
PICAfb::PICAfb() : Framebuffer(25, 30) { PICAfb::PICAfb() : Framebuffer(25, 30) {
#ifdef ENABLE_SCREENINIT #ifdef ENABLE_SCREENINIT
MCU::enableTopLCD(); MCU::enableTopLCD();
@ -48,83 +21,79 @@ PICAfb::PICAfb() : Framebuffer(25, 30) {
*((uint32_t *)0x10202244) = 0x1023E; *((uint32_t *)0x10202244) = 0x1023E;
*((uint32_t *)0x10202A44) = 0x1023E; *((uint32_t *)0x10202A44) = 0x1023E;
PDC *top = (PDC *)0x10400400, *bottom = (PDC *)0x10400500; // Top screen
top->unused1[0] = 0x000001c2; *(volatile uint32_t *)0x10400400 = 0x000001c2;
top->unused1[1] = 0x000000d1; *(volatile uint32_t *)0x10400404 = 0x000000d1;
top->unused1[2] = 0x000001c1; *(volatile uint32_t *)0x10400408 = 0x000001c1;
top->unused1[3] = 0x000001c1; *(volatile uint32_t *)0x1040040c = 0x000001c1;
top->unused1[4] = 0x00000000; *(volatile uint32_t *)0x10400410 = 0x00000000;
top->unused1[5] = 0x000000cf; *(volatile uint32_t *)0x10400414 = 0x000000cf;
top->unused1[6] = 0x000000d1; *(volatile uint32_t *)0x10400418 = 0x000000d1;
top->unused1[7] = 0x01c501c1; *(volatile uint32_t *)0x1040041c = 0x01c501c1;
top->unused1[8] = 0x00010000; *(volatile uint32_t *)0x10400420 = 0x00010000;
top->unused1[9] = 0x0000019d; *(volatile uint32_t *)0x10400424 = 0x0000019d;
top->unused1[10] = 0x00000002; *(volatile uint32_t *)0x10400428 = 0x00000002;
top->unused1[11] = 0x00000192; *(volatile uint32_t *)0x1040042c = 0x00000192;
top->unused1[12] = 0x00000192; *(volatile uint32_t *)0x10400430 = 0x00000192;
top->unused1[13] = 0x00000192; *(volatile uint32_t *)0x10400434 = 0x00000192;
top->unused1[14] = 0x00000001; *(volatile uint32_t *)0x10400438 = 0x00000001;
top->unused1[15] = 0x00000002; *(volatile uint32_t *)0x1040043c = 0x00000002;
top->unused1[16] = 0x01960192; *(volatile uint32_t *)0x10400440 = 0x01960192;
top->unused1[17] = 0x00000000; *(volatile uint32_t *)0x10400444 = 0x00000000;
top->unused1[18] = 0x00000000; *(volatile uint32_t *)0x10400448 = 0x00000000;
top->size = 0x00f00190; // 400*240 *(volatile uint32_t *)0x1040045C = 0x00f00190;
top->unused2[0] = 0x01c100d1; *(volatile uint32_t *)0x10400460 = 0x01c100d1;
top->unused2[1] = 0x01920002; *(volatile uint32_t *)0x10400464 = 0x01920002;
top->leftFB[0] = (void *)0x18300000; // Beginning of VRAM *(volatile uint32_t *)0x10400468 = 0x18300000;
FBFormat a; *(volatile uint32_t *)0x10400470 = 0x80341;
a.val = 0; *(volatile uint32_t *)0x10400474 = 0x00010501;
a.contents.format = GL_RGB8_OES; *(volatile uint32_t *)0x10400478 = 0;
a.contents.mainScreen = true; *(volatile uint32_t *)0x10400490 = 0x000002D0;
a.contents.noRainbowStrip = 3; *(volatile uint32_t *)0x1040049C = 0x00000000;
a.val |= 0x80000;
top->format = a.val;
top->unused3 = 0x00010501;
top->fbselect = 0;
top->stride = 0x000002D0;
top->padding[1] = 0x00000000;
// Rainbow register // Disco register
for (uint32_t i = 0; i < 256; i++) top->rainbow = 0x10101 * i; for (uint32_t i = 0; i < 256; i++) *(volatile uint32_t *)0x10400484 = 0x10101 * i;
bottom->unused1[0] = 0x000001c2; // Bottom screen
bottom->unused1[1] = 0x000000d1; *(volatile uint32_t *)0x10400500 = 0x000001c2;
bottom->unused1[2] = 0x000001c1; *(volatile uint32_t *)0x10400504 = 0x000000d1;
bottom->unused1[3] = 0x000001c1; *(volatile uint32_t *)0x10400508 = 0x000001c1;
bottom->unused1[4] = 0x000000cd; *(volatile uint32_t *)0x1040050c = 0x000001c1;
bottom->unused1[5] = 0x000000cf; *(volatile uint32_t *)0x10400510 = 0x000000cd;
bottom->unused1[6] = 0x000000d1; *(volatile uint32_t *)0x10400514 = 0x000000cf;
bottom->unused1[7] = 0x01c501c1; *(volatile uint32_t *)0x10400518 = 0x000000d1;
bottom->unused1[8] = 0x00010000; *(volatile uint32_t *)0x1040051c = 0x01c501c1;
bottom->unused1[9] = 0x0000019d; *(volatile uint32_t *)0x10400520 = 0x00010000;
bottom->unused1[10] = 0x00000052; *(volatile uint32_t *)0x10400524 = 0x0000019d;
bottom->unused1[11] = 0x00000192; *(volatile uint32_t *)0x10400528 = 0x00000052;
bottom->unused1[12] = 0x00000192; *(volatile uint32_t *)0x1040052c = 0x00000192;
bottom->unused1[13] = 0x0000004f; *(volatile uint32_t *)0x10400530 = 0x00000192;
bottom->unused1[14] = 0x00000050; *(volatile uint32_t *)0x10400534 = 0x0000004f;
bottom->unused1[15] = 0x00000052; *(volatile uint32_t *)0x10400538 = 0x00000050;
bottom->unused1[16] = 0x01980194; *(volatile uint32_t *)0x1040053c = 0x00000052;
bottom->unused1[17] = 0x00000000; *(volatile uint32_t *)0x10400540 = 0x01980194;
bottom->unused1[18] = 0x00000011; *(volatile uint32_t *)0x10400544 = 0x00000000;
bottom->size = 0x00f00140; // 320*240 *(volatile uint32_t *)0x10400548 = 0x00000011;
bottom->unused2[0] = 0x01c100d1; *(volatile uint32_t *)0x1040055C = 0x00f00140;
bottom->unused2[1] = 0x01920052; *(volatile uint32_t *)0x10400560 = 0x01c100d1;
bottom->leftFB[0] = (void *)(0x18300000 + 0x46500); // Directly at the beginning of top FB *(volatile uint32_t *)0x10400564 = 0x01920052;
bottom->format = a.val; *(volatile uint32_t *)0x10400568 = 0x18300000 + 0x46500;
bottom->unused3 = 0x00010501; *(volatile uint32_t *)0x10400570 = 0x80301;
bottom->fbselect = 0; *(volatile uint32_t *)0x10400574 = 0x00010501;
bottom->stride = 0x2D0; *(volatile uint32_t *)0x10400578 = 0;
bottom->padding[0] = 0; *(volatile uint32_t *)0x10400590 = 0x000002D0;
*(volatile uint32_t *)0x1040059C = 0x00000000;
// Disco register
for (uint32_t i = 0; i < 256; i++) *(volatile uint32_t *)0x10400584 = 0x10101 * i;
// Rainbow register
for (uint32_t i = 0; i < 256; i++) top->rainbow = 0x10101 * i;
#endif #endif
} }
PICAfb::~PICAfb() {} PICAfb::~PICAfb() {}
auto PICAfb::plotPixel(int x, int y, int col) -> void { auto PICAfb::plotPixel(int x, int y, int col) -> void {
unsigned char *lfb = (unsigned char *)0x18300000; unsigned char *lfb = (unsigned char *)0x18300000;
// XXX I know it's rotated. But I need more vertical space than horizonal space. // XXX I know it's rotated. But I need more vertical space than horizonal space.
int off = y * 240 + x; int off = (y * 240 + x) * 3;
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
lfb[off++] = col; lfb[off++] = col;
col >>= 8; col >>= 8;

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include "../../framebuffer/framebuffer.hpp" #include "../../framebuffer/framebuffer.hpp"
/**
* Framebuffer for the 3ds
*/
class PICAfb : public Framebuffer { class PICAfb : public Framebuffer {
protected: protected:
virtual auto plotPixel(int x, int y, int col) -> void; virtual auto plotPixel(int x, int y, int col) -> void;

View file

@ -1,5 +1,10 @@
#pragma once #pragma once
#include <tty.hpp> #include <tty.hpp>
/**
* Framebuffer TTY. Has no limitations besides requiring a Framebuffer of some sort.
* The implementation is very flexible (and thus slow). It can support every framebuffer format
* and color format.
*/
class Framebuffer : public TTY { class Framebuffer : public TTY {
protected: protected:
virtual auto plotPixel(int x, int y, int col) -> void; virtual auto plotPixel(int x, int y, int col) -> void;

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include <tty.hpp> #include <tty.hpp>
/**
* TTY for a CGA terminal. Limitations: 80x25, no RGB
*/
class CGATerm : public TTY { class CGATerm : public TTY {
protected: protected:
virtual auto plotChar(int x, int y, int c) -> void; virtual auto plotChar(int x, int y, int c) -> void;

View file

@ -1,2 +1,8 @@
/**
* converts a unicode codepoint to a CP437 codepoint
*/
char unicodeToCP437(int c); char unicodeToCP437(int c);
/**
* converts a CP437 codepoint to a unicode codepoint
*/
int CP437ToUnicode(char c); int CP437ToUnicode(char c);

View file

@ -1,5 +1,9 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
/**
* __cxa_pure_virtual is function that is pointed to in the vtable entry of a pure virtual function
* we need to provide this symbol, however it should never get called.
*/
extern "C" void __cxa_pure_virtual() { extern "C" void __cxa_pure_virtual() {
// panic("Pure virtual function called."); // panic("Pure virtual function called.");
} }

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include <kobject.hpp> #include <kobject.hpp>
#include <tty.hpp> #include <tty.hpp>
extern TTY *out; extern TTY *out; ///< main TTY for output
/***
* Sets the main TTY to some other TTY object.
*/
void setMainTTY(Kobject *obj); void setMainTTY(Kobject *obj);

View file

@ -1,9 +1,15 @@
#pragma once #pragma once
/**
* Contains the various different types of possible Kobjects.
*/
enum class kobjectType { enum class kobjectType {
POINTER, // Pointer to non-object POINTER, ///< Pointer to non-object
KOBJECT, // garbage collected kobject KOBJECT, ///< garbage collected kobject
TTY, TTY, ///< Terminal
}; };
/**
* Garbage-collected reference.
*/
class Kref { class Kref {
public: public:
kobjectType type; kobjectType type;
@ -48,6 +54,9 @@ class Kref {
return *this; return *this;
} }
}; };
/**
* Garbage collected object.
*/
class Kobject { class Kobject {
public: public:
kobjectType type; kobjectType type;

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include <kobject.hpp> #include <kobject.hpp>
/**
* The colors that are supported on TTYs that don't understand RGB colors.
*/
enum class Color { enum class Color {
BLACK, BLACK,
BLUE, BLUE,
@ -18,25 +21,32 @@ enum class Color {
YELLOW, YELLOW,
WHITE WHITE
}; };
/**
* TTY class. It is used for outputting text on some sort of screen. It supports unicode and at least 16 colors.
*/
class TTY : public Kobject { class TTY : public Kobject {
protected: protected:
int x; int x; ///< current X position on the screen
int y; int y; ///< current Y on the screen
int width; int width; ///< width of the screen
int height; int height; ///< height of the screen
Color curColor; Color curColor; ///< one of the 16 colors
unsigned int rgbColor; unsigned int rgbColor; ///< RGB888 color
bool useRGB; bool useRGB; ///< true if the rgbColor is used instead of the curColor.
virtual auto plotChar(int x, int y, int c) -> void; virtual auto plotChar(int x, int y, int c) -> void; ///< plots a single character on the screen.
public: public:
TTY(int width, int height); TTY(int width, int height);
virtual ~TTY(); virtual ~TTY();
virtual auto rgbSupport() -> bool; virtual auto rgbSupport()
virtual auto setColor(Color c) -> void; -> bool; ///< returns true if RGB colors can be used. Note that some colors might be same on some TTYs.
virtual auto setColor(unsigned int c) -> void; virtual auto setColor(Color c) -> void; ///< sets the color to one of the 16 required
virtual auto putChar(int c) -> void; virtual auto setColor(unsigned int c) -> void; ///< sets the color to a RGB888 color.
virtual auto puts(const char *s) -> void; virtual auto putChar(int c) -> void; ///< prints a unicode codepoint on the TTY
virtual auto puts(const char *s) -> void; ///< prints a UTF-8 string
/**
* Outputs an integer of base16 on the screen. Works with any type that you can shift and dereference arrays with.
*/
template <typename T> template <typename T>
auto puti(T x) -> TTY & { auto puti(T x) -> TTY & {
T output = x; T output = x;
@ -51,6 +61,9 @@ class TTY : public Kobject {
puts(ptr + 1); puts(ptr + 1);
return *this; return *this;
} }
/**
* Outputs a arbitrary type, as long as it can be casted to const char* or has a template overload.
*/
template <typename T> template <typename T>
auto operator<<(T x) -> TTY & { auto operator<<(T x) -> TTY & {
puts(x); puts(x);

View file

@ -1,4 +1,7 @@
#include <base.hpp> #include <base.hpp>
/***
* Inits all of the system drivers
*/
void drivers_init(); void drivers_init();
extern "C" void (*start_ctors)(); extern "C" void (*start_ctors)();
extern "C" void (*end_ctors)(); extern "C" void (*end_ctors)();