fixed screeninit, got text to show on arm11 and added documentation
This commit is contained in:
parent
65d9d93c24
commit
d91bab77a4
14 changed files with 2662 additions and 158 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -11,3 +11,5 @@ __pycache__/
|
|||
*.iso
|
||||
iso/kernel
|
||||
*.firm
|
||||
html/
|
||||
latex/
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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.
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)();
|
||||
|
|
Loading…
Reference in a new issue