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

View file

@ -1,45 +1,53 @@
#pragma once
#include "../i2c/i2c.hpp"
/**
* Namespace containing all currently supported MCU functions
*/
namespace MCU {
extern I2C access;
auto getVersionLo() -> unsigned char;
auto getVersionHi() -> unsigned char;
auto getLCDFlickerTop() -> unsigned char;
auto setLCDFlickerTop(unsigned char) -> void;
auto getLCDFlickerBottom() -> unsigned char;
auto setLCDFlickerTop(unsigned char) -> void;
auto get3DSlider() -> unsigned char;
auto getVolume() -> unsigned char;
auto getBatteryPercent() -> unsigned char;
auto getSystemVoltage() -> unsigned char;
auto isCharging() -> bool;
auto isOpen() -> bool;
extern uint8_t HIDStatus;
auto updateHIDStatus() -> void;
auto powerButtonPressed() -> bool;
auto powerButtonLongPressed() -> bool;
auto homeButtonPressed() -> bool;
auto homeButtonReleased() -> bool;
auto wifiEnabled() -> bool;
auto closed() -> bool;
auto opened() -> bool;
auto poweroff() -> void;
auto reboot() -> void;
auto enableTopLCD() -> void;
auto disableTopLCD() -> void;
auto enableBottomLCD() -> void;
auto disableBottomLCD() -> void;
auto setWifiLED(char val) -> void;
auto setCameraLED(char val) -> void;
auto set3DLED(char val) -> void;
extern I2C access; ///< Private variable which is used to access the MCU
auto getVersionLo() -> unsigned char; ///< Installed MCU firmware version. Current is 56 on n3ds and 27 on o3ds
auto getVersionHi() -> unsigned char; ///< Installed MCU firmware version. Current is 3 on n3ds and 2 on o3ds
auto getLCDFlickerTop() -> unsigned char; ///< Returns the top LCDs bias voltage in some wax
auto setLCDFlickerTop(unsigned char) -> void; ///< Changes the top LCDs bias voltage
auto getLCDFlickerBottom() -> unsigned char; ///< Returns the bottom LCDs bias voltage
auto setLCDFlickerTop(unsigned char) -> void; ///< Changes the bottom LCDs bias voltage
auto get3DSlider() -> unsigned char; ///< Returns how far the 3D slider has moved up
auto getVolume() -> unsigned char; ///< Returns the current volume
auto getBatteryPercent() -> unsigned char; ///< Returns the battery percentage
auto getSystemVoltage() -> unsigned char; ///< Returns the system voltage
auto isCharging() -> bool; ///< Returns true if the system is being charged
auto isOpen() -> bool; ///< Returns true if the system is not closed
extern uint8_t HIDStatus; ///< Storage variable for a few functions
auto updateHIDStatus() -> void; ///< Updates HIDStatus
auto powerButtonPressed() -> bool; ///< true if the power button got pressed
auto powerButtonLongPressed() -> bool; ///< true if the power button got pressed for a long time
auto homeButtonPressed() -> bool; ///< true if the home button got pressed
auto homeButtonReleased() -> bool; ///< true if the home button got released
auto wifiEnabled() -> bool; ///< true if wifi is enabled
auto closed() -> bool; ///< true if the system got closed
auto opened() -> bool; ///< true if the system got reopened
auto poweroff() -> void; ///< powers the system off
auto reboot() -> void; ///< restarts the system
auto enableTopLCD() -> void; ///< enables the top LCD
auto disableTopLCD() -> void; ///< disables the top LCD
auto enableBottomLCD() -> void; ///< enables the bottom LCD
auto disableBottomLCD() -> void; ///< disables the bottom LCD
auto setWifiLED(char val) -> void; ///< set to a value between 1 and 0xF to turn on the Wifi LED
auto setCameraLED(char val) -> void; ///< set to a value between 1 and 0xF to turn on the Camera LED
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 {
unsigned char seconds;
unsigned char minutes;
unsigned char hours;
unsigned char days;
unsigned char months;
unsigned char years;
unsigned char seconds; ///< seconds. Range: 0…59
unsigned char minutes; ///< minutes. Range: 0…59
unsigned char hours; ///< hours. Range: 0…23
unsigned char days; ///< days. Range: 1…31
unsigned char months; ///< months. Range: 1…12
unsigned char years; ///< years. Range: 0…50
};
auto getRTC(RTC_date *) -> void;
auto setRTC(RTC_date *) -> void;
auto getRTC(RTC_date *) -> void; ///< sets the passed struct to the current date
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_RGB5_A1_OES 3
#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) {
#ifdef ENABLE_SCREENINIT
MCU::enableTopLCD();
@ -48,83 +21,79 @@ PICAfb::PICAfb() : Framebuffer(25, 30) {
*((uint32_t *)0x10202244) = 0x1023E;
*((uint32_t *)0x10202A44) = 0x1023E;
PDC *top = (PDC *)0x10400400, *bottom = (PDC *)0x10400500;
top->unused1[0] = 0x000001c2;
top->unused1[1] = 0x000000d1;
top->unused1[2] = 0x000001c1;
top->unused1[3] = 0x000001c1;
top->unused1[4] = 0x00000000;
top->unused1[5] = 0x000000cf;
top->unused1[6] = 0x000000d1;
top->unused1[7] = 0x01c501c1;
top->unused1[8] = 0x00010000;
top->unused1[9] = 0x0000019d;
top->unused1[10] = 0x00000002;
top->unused1[11] = 0x00000192;
top->unused1[12] = 0x00000192;
top->unused1[13] = 0x00000192;
top->unused1[14] = 0x00000001;
top->unused1[15] = 0x00000002;
top->unused1[16] = 0x01960192;
top->unused1[17] = 0x00000000;
top->unused1[18] = 0x00000000;
top->size = 0x00f00190; // 400*240
top->unused2[0] = 0x01c100d1;
top->unused2[1] = 0x01920002;
top->leftFB[0] = (void *)0x18300000; // Beginning of VRAM
FBFormat a;
a.val = 0;
a.contents.format = GL_RGB8_OES;
a.contents.mainScreen = true;
a.contents.noRainbowStrip = 3;
a.val |= 0x80000;
top->format = a.val;
top->unused3 = 0x00010501;
top->fbselect = 0;
top->stride = 0x000002D0;
top->padding[1] = 0x00000000;
// Top screen
*(volatile uint32_t *)0x10400400 = 0x000001c2;
*(volatile uint32_t *)0x10400404 = 0x000000d1;
*(volatile uint32_t *)0x10400408 = 0x000001c1;
*(volatile uint32_t *)0x1040040c = 0x000001c1;
*(volatile uint32_t *)0x10400410 = 0x00000000;
*(volatile uint32_t *)0x10400414 = 0x000000cf;
*(volatile uint32_t *)0x10400418 = 0x000000d1;
*(volatile uint32_t *)0x1040041c = 0x01c501c1;
*(volatile uint32_t *)0x10400420 = 0x00010000;
*(volatile uint32_t *)0x10400424 = 0x0000019d;
*(volatile uint32_t *)0x10400428 = 0x00000002;
*(volatile uint32_t *)0x1040042c = 0x00000192;
*(volatile uint32_t *)0x10400430 = 0x00000192;
*(volatile uint32_t *)0x10400434 = 0x00000192;
*(volatile uint32_t *)0x10400438 = 0x00000001;
*(volatile uint32_t *)0x1040043c = 0x00000002;
*(volatile uint32_t *)0x10400440 = 0x01960192;
*(volatile uint32_t *)0x10400444 = 0x00000000;
*(volatile uint32_t *)0x10400448 = 0x00000000;
*(volatile uint32_t *)0x1040045C = 0x00f00190;
*(volatile uint32_t *)0x10400460 = 0x01c100d1;
*(volatile uint32_t *)0x10400464 = 0x01920002;
*(volatile uint32_t *)0x10400468 = 0x18300000;
*(volatile uint32_t *)0x10400470 = 0x80341;
*(volatile uint32_t *)0x10400474 = 0x00010501;
*(volatile uint32_t *)0x10400478 = 0;
*(volatile uint32_t *)0x10400490 = 0x000002D0;
*(volatile uint32_t *)0x1040049C = 0x00000000;
// Rainbow register
for (uint32_t i = 0; i < 256; i++) top->rainbow = 0x10101 * i;
// Disco register
for (uint32_t i = 0; i < 256; i++) *(volatile uint32_t *)0x10400484 = 0x10101 * i;
bottom->unused1[0] = 0x000001c2;
bottom->unused1[1] = 0x000000d1;
bottom->unused1[2] = 0x000001c1;
bottom->unused1[3] = 0x000001c1;
bottom->unused1[4] = 0x000000cd;
bottom->unused1[5] = 0x000000cf;
bottom->unused1[6] = 0x000000d1;
bottom->unused1[7] = 0x01c501c1;
bottom->unused1[8] = 0x00010000;
bottom->unused1[9] = 0x0000019d;
bottom->unused1[10] = 0x00000052;
bottom->unused1[11] = 0x00000192;
bottom->unused1[12] = 0x00000192;
bottom->unused1[13] = 0x0000004f;
bottom->unused1[14] = 0x00000050;
bottom->unused1[15] = 0x00000052;
bottom->unused1[16] = 0x01980194;
bottom->unused1[17] = 0x00000000;
bottom->unused1[18] = 0x00000011;
bottom->size = 0x00f00140; // 320*240
bottom->unused2[0] = 0x01c100d1;
bottom->unused2[1] = 0x01920052;
bottom->leftFB[0] = (void *)(0x18300000 + 0x46500); // Directly at the beginning of top FB
bottom->format = a.val;
bottom->unused3 = 0x00010501;
bottom->fbselect = 0;
bottom->stride = 0x2D0;
bottom->padding[0] = 0;
// Bottom screen
*(volatile uint32_t *)0x10400500 = 0x000001c2;
*(volatile uint32_t *)0x10400504 = 0x000000d1;
*(volatile uint32_t *)0x10400508 = 0x000001c1;
*(volatile uint32_t *)0x1040050c = 0x000001c1;
*(volatile uint32_t *)0x10400510 = 0x000000cd;
*(volatile uint32_t *)0x10400514 = 0x000000cf;
*(volatile uint32_t *)0x10400518 = 0x000000d1;
*(volatile uint32_t *)0x1040051c = 0x01c501c1;
*(volatile uint32_t *)0x10400520 = 0x00010000;
*(volatile uint32_t *)0x10400524 = 0x0000019d;
*(volatile uint32_t *)0x10400528 = 0x00000052;
*(volatile uint32_t *)0x1040052c = 0x00000192;
*(volatile uint32_t *)0x10400530 = 0x00000192;
*(volatile uint32_t *)0x10400534 = 0x0000004f;
*(volatile uint32_t *)0x10400538 = 0x00000050;
*(volatile uint32_t *)0x1040053c = 0x00000052;
*(volatile uint32_t *)0x10400540 = 0x01980194;
*(volatile uint32_t *)0x10400544 = 0x00000000;
*(volatile uint32_t *)0x10400548 = 0x00000011;
*(volatile uint32_t *)0x1040055C = 0x00f00140;
*(volatile uint32_t *)0x10400560 = 0x01c100d1;
*(volatile uint32_t *)0x10400564 = 0x01920052;
*(volatile uint32_t *)0x10400568 = 0x18300000 + 0x46500;
*(volatile uint32_t *)0x10400570 = 0x80301;
*(volatile uint32_t *)0x10400574 = 0x00010501;
*(volatile uint32_t *)0x10400578 = 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
}
PICAfb::~PICAfb() {}
auto PICAfb::plotPixel(int x, int y, int col) -> void {
unsigned char *lfb = (unsigned char *)0x18300000;
// 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++) {
lfb[off++] = col;
col >>= 8;

View file

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

View file

@ -1,5 +1,10 @@
#pragma once
#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 {
protected:
virtual auto plotPixel(int x, int y, int col) -> void;

View file

@ -1,5 +1,8 @@
#pragma once
#include <tty.hpp>
/**
* TTY for a CGA terminal. Limitations: 80x25, no RGB
*/
class CGATerm : public TTY {
protected:
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);
/**
* converts a CP437 codepoint to a unicode codepoint
*/
int CP437ToUnicode(char c);

View file

@ -1,5 +1,9 @@
#include <stddef.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() {
// panic("Pure virtual function called.");
}

View file

@ -1,5 +1,8 @@
#pragma once
#include <kobject.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);

View file

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

View file

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

View file

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