loader: fix emc dvb

This commit is contained in:
souldbminersmwc
2025-10-03 18:13:13 -04:00
parent 403c2124d3
commit 77d08a9e74
10 changed files with 197 additions and 935 deletions

View File

@@ -412,78 +412,48 @@ namespace ams::ldr::oc::pcv::mariko
R_SUCCEED();
}
Result MemFreqDvbTable(u32 *ptr)
{
emc_dvb_dvfs_table_t *default_end = reinterpret_cast<emc_dvb_dvfs_table_t *>(ptr);
emc_dvb_dvfs_table_t *new_start = default_end + 1;
Result MemFreqDvbTable(u32* ptr) {
emc_dvb_dvfs_table_t* default_end = reinterpret_cast<emc_dvb_dvfs_table_t *>(ptr);
emc_dvb_dvfs_table_t* new_start = default_end + 1;
// Validate existing table
void *mem_dvb_table_head = reinterpret_cast<u8 *>(new_start) - sizeof(EmcDvbTableDefault);
void* mem_dvb_table_head = reinterpret_cast<u8 *>(new_start) - sizeof(EmcDvbTableDefault);
bool validated = std::memcmp(mem_dvb_table_head, EmcDvbTableDefault, sizeof(EmcDvbTableDefault)) == 0;
R_UNLESS(validated, ldr::ResultInvalidDvbTable());
if (C.marikoEmcMaxClock <= EmcClkOSLimit)
R_SKIP();
int32_t voltAdd = 25 * C.marikoEmcDvbShift;
#define DVB_VOLT(zero, one, two) std::min(zero + voltAdd, 1050), std::min(one + voltAdd, 1025), std::min(two + voltAdd, 1000),
if (C.marikoEmcMaxClock < 1862400)
{
int32_t voltAdd = 25*C.marikoEmcDvbShift;
#define DVB_VOLT(zero, one, two) std::min(zero+voltAdd, 1050), std::min(one+voltAdd, 1025), std::min(two+voltAdd, 1000),
if (C.marikoEmcMaxClock < 1862400) {
std::memcpy(new_start, default_end, sizeof(emc_dvb_dvfs_table_t));
}
if (C.marikoEmcMaxClock < 2131200)
{
emc_dvb_dvfs_table_t oc_table = {1866000, {700, 675, 637,}};
} else if (C.marikoEmcMaxClock < 2131200){
emc_dvb_dvfs_table_t oc_table = { 1862400, { 700, 675, 650, } };
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
} else if (C.marikoEmcMaxClock < 2400000){
emc_dvb_dvfs_table_t oc_table = { 2131200, { 725, 700, 675, } };
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
} else if (C.marikoEmcMaxClock < 2665600){
emc_dvb_dvfs_table_t oc_table = { 2400000, { DVB_VOLT(750, 725, 700) } };
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
} else if (C.marikoEmcMaxClock < 2931200){
emc_dvb_dvfs_table_t oc_table = { 2665600, { DVB_VOLT(775, 750, 725) } };
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
} else if (C.marikoEmcMaxClock < 3200000){
emc_dvb_dvfs_table_t oc_table = { 2931200, { DVB_VOLT(800, 775, 750) } };
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
} else {
emc_dvb_dvfs_table_t oc_table = { 3200000, { DVB_VOLT(800, 800, 775) } };
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else if (C.marikoEmcMaxClock < 2400000)
{
emc_dvb_dvfs_table_t oc_table = {2133000, {725, 700, 650,}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else if (C.marikoEmcMaxClock < 2533000)
{
emc_dvb_dvfs_table_t oc_table = {2400000, {DVB_VOLT(750, 725, 675)}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else if (C.marikoEmcMaxClock < 2666000)
{
emc_dvb_dvfs_table_t oc_table = {2533000, {DVB_VOLT(800, 775, 725)}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else if (C.marikoEmcMaxClock < 2800000)
{
emc_dvb_dvfs_table_t oc_table = {2666000, {DVB_VOLT(850, 825, 775)}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else if (C.marikoEmcMaxClock < 2933000)
{
emc_dvb_dvfs_table_t oc_table = {2800000, {DVB_VOLT(925, 850, 800)}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else if (C.marikoEmcMaxClock < 3066000)
{
emc_dvb_dvfs_table_t oc_table = {2933000, {DVB_VOLT(1000, 900, 875)}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else if (C.marikoEmcMaxClock < 3200000)
{
emc_dvb_dvfs_table_t oc_table = {3066000, {DVB_VOLT(1025, 950, 925)}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
else
{
emc_dvb_dvfs_table_t oc_table = {3200000, {DVB_VOLT(1050, 1025, 1000)}};
std::memcpy(new_start, &oc_table, sizeof(emc_dvb_dvfs_table_t));
}
new_start->freq = C.marikoEmcMaxClock;
/* Max dvfs entry is 32, but HOS doesn't seem to boot if exact freq doesn't exist in dvb table,
reason why it's like this
*/
reason why it's like this
*/
R_SUCCEED();
}

BIN
docs/img1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

BIN
docs/img2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

BIN
docs/img3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

View File

@@ -1,219 +1,167 @@
<!doctype html>
<html lang=en>
<meta charset=UTF-8>
<meta name=viewport content="width=device-width,initial-scale=1">
<title>Switch OC Suite 2 | "If Switch OC Suite is so good, then why isn't there a Switch OC Suite 2?".</title>
<meta name=description content="If Switch OC Suite is so good, then why isn't there a Switch OC Suite 2?">
<link rel=stylesheet href=https://unpkg.com/@picocss/pico@latest/css/pico.min.css>
<style>
#nav-list{display:none}#nav-popup{display:unset}@media (min-width:768px){#nav-list{display:unset}#nav-popup{display:none}}details[open]>summary:not([role]):not(:focus){color:unset}div.hero>nav.container-fluid{position:fixed;top:0;z-index:99;-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}div.hero>header{padding-top:6rem}button[role=tab]{border-radius:0;border-left-width:calc(var(--border-width)/ 2);border-right-width:calc(var(--border-width)/ 2)}button[role=tab]:first-child{border-top-left-radius:var(--border-radius);border-bottom-left-radius:var(--border-radius);border-left-width:var(--border-width)}button[role=tab]:last-child{border-top-right-radius:var(--border-radius);border-bottom-right-radius:var(--border-radius);border-right-width:var(--border-width)}button[role=tab]:not(.outline){pointer-events:none;cursor:default}div.cust-element{margin:1.5rem 0 1.5rem 0}div.cust-element>blockquote,div.cust-element>blockquote>ul{margin:0;font-size:calc(var(--font-size) * .8);color:var(--muted-color)}div#download_btn_grid>a{margin:.5rem 0}
</style>
<div class=hero>
<nav class=container-fluid>
<ul>
<li><a href=#head class=contrast><b>Switch OC Suite 2</b></a></ul>
<ul id=nav-popup>
<li>
<details role=list dir=rtl>
<summary aria-haspopup=group role=link class=contrast>Jump to</summary>
<ul role=group>
<li><a href=#readme>README</a>
<li><a href=#download>Download</a>
<li><a href=#config>Configurator</a>
<li><a href=https://github.com/souldbminersmwc/Switch-OC-Suite-2 target=_blank>GitHub repository</a></ul>
</details>
</ul>
<ul id=nav-list>
<li><a href=#readme>README</a>
<li><a href=#download>Download</a>
<li><a href=#config>Config</a>
<li><a href=https://github.com/souldbminersmwc/Switch-OC-Suite-2 target=_blank>GitHub</a></ul>
</nav>
<header class=container>
<hgroup>
<h1>Switch OC Suite 2</h1>
<h2><i>"If Switch OC Suite is so good, then why isn't there a Switch OC Suite 2?"</i>.</h2>
</hgroup>
</header>
</div>
<section aria-label=README id=readme>
<div class=container>
<article>
<header>
<hgroup>
<h2>PLEASE READ ME!</h2>
<h3>🚨DISCLAIMER: THIS IS PROVIDED AS IS. USE AT YOUR OWN RISK!🚨</h3>
</hgroup>
<ul>
<li>Overclocking in general will shorten the lifespan of some hardware components. <strong>YOU ARE RESPONSIBLE for any problem or potential damage.</strong>
<li>Due to Horizon OS's design, instabilities from unsafe RAM clocks may cause filesystem corruption. <strong>Always make backup before enabling DRAM OC.</strong></ul>
</header>
<h3>Features</h3>
<details open>
<summary>For Erista variant (HAC-001)</summary>
<ul>
<li>CPU Overclock (Safe: 1785 MHz)
<ul>
<li>Unsafe
<ul>
<li>Due to the limit of board power draw or power IC
<li>Unlockable frequencies up to 2295 MHz
<li>See <a href=https://github.com/souldbminersmwc/Switch-OC-Suite-2/blob/master/Source/sys-clk-OC/README.md target=_blank>README for sys-clk-OC</a></ul>
</ul>
<li>DRAM Overclock (Safe: 1862.4 MHz)</ul>
</details>
<details open>
<summary>For Mariko variant (HAC-001-01, HDH-001, HEG-001)</summary>
<ul>
<li>CPU / GPU Overclock (Safe: 1963 / 1075 MHz)
<ul>
<li>Unsafe
<ul>
<li>Due to the limit of board power draw or power IC
<li>Unlockable frequencies up to 2907 / 1536 MHz
<li>See <a href=https://github.com/souldbminersmwc/Switch-OC-Suite-2/blob/master/Source/sys-clk-OC/README.md target=_blank>README for sys-clk-OC</a></ul>
</ul>
<li>DRAM Overclock (Safe: 1996.8 MHz)</ul>
</details>
<details open>
<summary>Sys-CLK OC and ReverseNX-RT</summary>
<ul>
<li>Global Profile
<ul>
<li>Designated a dummy title id <code>0xA111111111111111</code>.
<li>Priority: "Temp overrides" &gt; "Application profile" &gt; "Global profile" &gt; "System default".</ul>
</ul>
</details>
<details open>
<summary>System Settings (Optional)</summary>See <a href=https://github.com/souldbminersmwc/Switch-OC-Suite-2/blob/master/system_settings.md>system_settings.md</a></details>
<h3 id=installation open>Installation</h3>
<ol type=1>
<li>Download latest <a href=#download>release</a>.
<li>Grab <code>x.x.x_loader.kip</code> for your Atmosphere version, rename it to <code>loader.kip</code> and place it in <code>/atmosphere/kips/</code>.
<li>(optional) You can customize via <a href=#config>online loader configurator</a>
<table role=grid>
<thead>
<tr>
<th>Defaults
<th>Mariko
<th>Erista
<tbody>
<tr>
<td>CPU OC
<td>2295 MHz Max
<td>2091 MHz Max
<tr>
<td>CPU Boost
<td>1785 MHz
<td>N/A
<tr>
<td>CPU Volt
<td>1235 mV Max
<td>1235 mV Max
<tr>
<td>GPU OC
<td>1152 MHz Max
<td>998 MHz Max
<tr>
<td>RAM OC
<td>1996 MHz
<td>1862 MHz
<tr>
<td>RAM Volt
<td>Disabled
<td>Disabled
<tr>
<td>RAM Timing
<td>Auto-Adjusted
<td>Auto-Adjusted
<tr>
<td>CPU UV
<td>Disabled
<td>N/A
<tr>
<td>GPU UV
<td>Disabled
<td>N/A</table>
<li>Hekate-ipl bootloader Only (fss0) (Not required for AMS fusee)
<ul>
<li>At boot entry section in <code>bootloader/hekate_ipl.ini</code>, Add <code>kip1=atmosphere/kips/*.kip</code> to any line that works.</ul>
<li>Install [sys-clk-oc]<br>official [sys-clk] (2.0.0+) is compatible but not recommended (no bugfixes or additional features).
<li>(optional) Copy SdOut.zip for useful utilities.</ol>
<details>
<summary>How to build this project</summary>
<ol type=1>
<li>Grab necessary patches from the repo, then compile sys-clk, ReverseNX-RT and Atmosphere loader with devkitpro.
<li>Before compiling Atmosphere loader, run <code>patch.py</code> in <code>Atmosphere/stratosphere/loader/source/</code> to insert oc module into loader sysmodule.
<li>Run cd stratosphere/loader then make to build the loader.kip</li>
<li>When compilation is done, uncompress the kip to make it work with configurator: <code>hactool -t kip1 loader.kip --uncompress=loader.kip</code></ol>
</details>
<h3 id=faq>Frequently Asked Questions</h3>
<details open>
<summary>How to enable unsafe frequencies in sys-clk-OC?</summary>
<ul>
<li>Above all else, you should know <a href=#readme>what "unsafe" means and issues might arise</a>.
<li>See the end of <a href=https://github.com/souldbminersmwc/Switch-OC-Suite-2/blob/master/Source/sys-clk-OC/README.md target=_blank>README in sys-clk-OC</a>. Place this line <code>allow_unsafe_freq=1</code> under <code>[values]</code> section in <code>/config/sys-clk/config.ini</code></ul>
</details>
<details open>
<summary>I would like to bypass limit enforced in sys-clk to improve handheld performance without charger connected.</summary>
<ul>
<li>Bypassing clock cappings will be bad for battery.
<li>See the end of <a href=https://github.com/souldbminersmwc/Switch-OC-Suite-2/blob/master/Source/sys-clk-OC/README.md target=_blank>README in sys-clk-OC</a>. Place this line <code>uncapped_clocks=1</code> under <code>[values]</code> section in <code>/config/sys-clk/config.ini</code></ul>
</details>
<footer>
<details role=list>
<summary aria-haspopup=group role=button class=secondary>Acknowledgement</summary>
<ul role=group>
<li><a href=https://github.com/CTCaer/hekate target=_blank>CTCaer for Hekate-ipl bootloader, RE and hardware research</a>
<li><a href=https://devkitpro.org/ target=_blank>devkitPro for All-In-One homebrew toolchains</a>
<li><a href=https://github.com/masagrator/ReverseNX-RT target=_blank>masagrator for ReverseNX-RT and info on BatteryChargeInfoFields in psm module</a>
<li><a href=https://developer.nvidia.com/embedded/dlc/tegra-x1-technical-reference-manual target=_blank>Nvidia for Tegra X1 Technical Reference Manual</a>
<li><a href=https://github.com/retronx-team/sys-clk target=_blank>RetroNX team for sys-clk</a>
<li><a href=https://github.com/Atmosphere-NX/Atmosphere target=_blank>SciresM and Reswitched Team for the state-of-the-art Atmosphere CFW of Switch</a>
<li><a href=http://switchbrew.org/wiki/ target=_blank>Switchbrew wiki for Switch in-depth info</a>
<li><a href=https://gitlab.com/switchroot/kernel target=_blank>Switchroot for their modified L4T kernel and device tree</a>
<li>ZatchyCatGames for RE and original OC loader patches for Atmosphere
<li><a href=https://github.com/KazushiMe/Switch-OC-Suite target=_blank>KazushiMe for original Switch-OC-Suite</a>
<li>lineon for research and help</ul>
</details>
</footer>
</article>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Horizon OC - Switch Overclocking Tool</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<style>
/* Background Image Cycling */
body {
margin: 0;
font-family: sans-serif;
overflow-x: hidden;
color: white;
}
.bg-slide {
position: fixed;
top: 0; left: 0;
width: 100%;
height: 100%;
background-size: cover;
background-position: center;
z-index: -2;
opacity: 0;
transition: opacity 2s ease-in-out;
}
.bg-slide.active {
opacity: 1;
}
/* Gradient overlay that changes with image */
.gradient-overlay {
position: fixed;
top: 0; left: 0;
width: 100%;
height: 100%;
z-index: -1;
pointer-events: none;
transition: background 2s ease-in-out;
}
/* Pop-in effect */
.popin {
transform: scale(0.8);
opacity: 0;
transition: transform 0.6s ease, opacity 0.6s ease;
}
.popin.aos-animate {
transform: scale(1);
opacity: 1;
}
/* Glassmorphism cards */
.glass {
background: rgba(255, 255, 255, 0.15);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.25);
transition: transform 0.3s ease;
}
/* Apple-style liquid glass buttons */
.liquid-button {
padding: 0.75rem 2rem;
border-radius: 1.5rem;
font-weight: 600;
background: rgba(255,255,255,0.2);
backdrop-filter: blur(12px);
border: 1px solid rgba(255,255,255,0.3);
box-shadow: inset 0 1px 0 rgba(255,255,255,0.25), 0 4px 15px rgba(0,0,0,0.25);
color: white;
cursor: pointer;
transition: all 0.3s ease;
}
.liquid-button:hover {
background: rgba(255,255,255,0.3);
box-shadow: inset 0 2px 0 rgba(255,255,255,0.35), 0 6px 20px rgba(0,0,0,0.3);
transform: scale(1.05);
}
</style>
</head>
<body class="text-white">
<!-- Background Images -->
<div class="bg-slide" style="background-image: url('img1.png');"></div>
<div class="bg-slide" style="background-image: url('img2.png');"></div>
<div class="bg-slide" style="background-image: url('img3.png');"></div>
<!-- Gradient overlay -->
<div class="gradient-overlay" id="gradient-overlay" style="background: linear-gradient(135deg, rgba(50,0,100,0.6), rgba(0,0,50,0.6));"></div>
<!-- Hero Section -->
<header class="text-center py-28 relative overflow-hidden popin" data-aos="popin">
<h1 class="text-6xl font-extrabold mb-4 drop-shadow-lg">Horizon OC</h1>
<p class="text-lg text-gray-200 mt-4">
Upgrade the performance of your Nintendo Switch Console
</p>
<div class="mt-8 flex justify-center gap-6">
<a href="#download" class="liquid-button">Download Now</a>
<a href="benchmarks.html" class="liquid-button">View Benchmarks</a>
</div>
</section>
<section aria-label=Download id=download>
<div class=container>
<article>
<header>
<hgroup>
<h2>Download</h2>
<h3>Get latest version of Switch OC Suite and its corresponding Atmosphere package here.</h3>
</hgroup>
</header>
<div class=grid id=download_btn_grid><a role=button aria-busy=true id=loader_kip_btn>Generating link, please wait...</a> <a role=button aria-busy=true id=sdout_zip_btn>Generating link, please wait...</a> <a target=_blank role=button aria-busy=true id=ams_btn>Generating link, please wait...</a></div>
<footer>See <a href=#installation>Installation section</a> for how to use Switch OC Suite.</footer>
</article>
</header>
<!-- About -->
<section class="max-w-4xl mx-auto text-center py-20 px-6 popin" data-aos="popin" data-aos-delay="100">
<h2 class="text-4xl font-bold mb-6">What is Horizon OC?</h2>
<p class="text-gray-300 text-lg leading-relaxed">
HOC is a tool to overclock your modded Nintendo Switch Console.
This can help improve framrates, load times and latency in games.
</p>
</section>
<!-- Features -->
<section class="py-20">
<div class="max-w-6xl mx-auto px-6 grid md:grid-cols-3 gap-10">
<div class="glass p-8 rounded-2xl shadow-xl hover:scale-105 transition popin" data-aos="popin" data-aos-delay="200">
<h3 class="text-2xl font-semibold mb-3">⚡ Performance</h3>
<p class="text-gray-300">Overclocking your console can lead to significantly better performance in demanding titles</p>
</div>
<div class="glass p-8 rounded-2xl shadow-xl hover:scale-105 transition popin" data-aos="popin" data-aos-delay="300">
<h3 class="text-2xl font-semibold mb-3">☣ Safely</h3>
<p class="text-gray-300">Horizon OC aims to be as safe as possible, while allowing advanced users to customize it further</p>
</div>
<div class="glass p-8 rounded-2xl shadow-xl hover:scale-105 transition popin" data-aos="popin" data-aos-delay="400">
<h3 class="text-2xl font-semibold mb-3">🔧 Customizable</h3>
<p class="text-gray-300">Horizon OC comes with a advanced configurator which allows you to customize it to your own needs</p>
</div>
</div>
</section>
<section aria-label=Config id=config>
<div class=container>
<article>
<header>
<hgroup>
<h2>Configurator</h2>
<h3>Configure frequencies and voltages to suit your hardware and preferences.</h3>
</hgroup>
</header>
<form id=form>
<nav role=tablist><button type=button role=tab id=tab_all data-platform=0 disabled>All</button> <button type=button role=tab class=outline id=tab_erista data-platform=1 disabled>Erista</button> <button type=button role=tab class=outline id=tab_mariko data-platform=2 disabled>Mariko</button></nav><label for=file><input id=file type=file> <small id=cust_rev>Upload loader.kip here</small></label>
<div id=config-list-basic></div>
<div id=config-list-advanced></div>
<div id=config-list-gpu></div>
</form>
<footer>
<div class=grid><button type=button id=load_default role=button disabled>Load Default</button> <button type=button id=load_saved role=button disabled>Load Last Saved</button> <button type=submit id=save role=button disabled>Save</button></div>
</footer>
</article>
</div>
</section>
<footer class=container><small>Build with <a href=https://picocss.com target=_blank>Pico</a>. All trademarks, logos and brand names are the property of their respective owners, used for identification purposes only.</small></footer>
<script src=./main.js></script>
</section>
<!-- Download -->
<section id="download" class="text-center py-24 popin" data-aos="popin" data-aos-delay="500">
<h2 class="text-3xl font-bold mb-6">Get Horizon OC</h2>
<a href="#" class="liquid-button">Download Latest Release</a>
<p class="text-gray-400 mt-4">Ensure to use the latest version of Atmosphere</p>
</section>
<!-- Footer -->
<footer class="bg-black bg-opacity-60 text-center py-6 text-gray-500 text-sm popin" data-aos="popin">
This website is open source!
</footer>
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script>
AOS.init({ once: true, duration: 800 });
// Background image cycling with gradient
const slides = document.querySelectorAll('.bg-slide');
const gradientOverlay = document.getElementById('gradient-overlay');
const gradients = [
'linear-gradient(135deg, rgba(80,0,150,0.6), rgba(0,0,60,0.6))',
'linear-gradient(135deg, rgba(150,50,0,0.6), rgba(50,0,0,0.6))',
'linear-gradient(135deg, rgba(0,100,150,0.6), rgba(0,30,50,0.6))'
];
let current = 0;
function cycleBg() {
slides.forEach((s,i)=>s.classList.remove('active'));
slides[current].classList.add('active');
gradientOverlay.style.background = gradients[current];
current = (current+1)%slides.length;
}
cycleBg();
setInterval(cycleBg, 6000); // every 6s
</script>
</body>
</html>

View File

@@ -1,492 +0,0 @@
var __awaiter = this && this.__awaiter || function(e, t, i, n) {
return new(i || (i = Promise))((function(a, r) {
function s(e) {
try {
o(n.next(e))
} catch (e) {
r(e)
}
}
function l(e) {
try {
o(n.throw(e))
} catch (e) {
r(e)
}
}
function o(e) {
var t;
e.done ? a(e.value) : (t = e.value, t instanceof i ? t : new i((function(e) {
e(t)
}))).then(s, l)
}
o((n = n.apply(e, t || [])).next())
}))
};
const CUST_REV_ADV = 2;
var CustPlatform;
! function(e) {
e[e.Undefined = 0] = "Undefined", e[e.Erista = 1] = "Erista", e[e.Mariko = 2] = "Mariko", e[e.All = 3] = "All"
}(CustPlatform || (CustPlatform = {}));
class CustEntry {
constructor(e, t, i, n, a, r, s = [0, 1e6], l = 1, o = !0) {
this.id = e, this.name = t, this.platform = i, this.size = n, this.desc = a, this.defval = r, this.step = l, this.zeroable = o, this.min = s[0], this.max = s[1]
}
validate() {
let e = new ErrorToolTip(this.id).clear();
return Number.isNaN(this.value) || void 0 === this.value ? (e.setMsg("Invalid value: Not a number").show(), !1) : !(!this.zeroable || 0 != this.value) || (this.value < this.min || this.value > this.max ? (e.setMsg(`Expected range: [${this.min}, ${this.max}], got ${this.value}.`).show(), !1) : this.value % this.step == 0 || (e.setMsg(`${this.value} % ${this.step} ≠ 0`).show(), !1))
}
getInputElement() {
return document.getElementById(this.id)
}
updateValueFromElement() {
var e;
this.value = Number(null === (e = this.getInputElement()) || void 0 === e ? void 0 : e.value)
}
isAvailableFor(e) {
return e === CustPlatform.Undefined || this.platform === e || this.platform === CustPlatform.All
}
createElement() {
let e = this.getInputElement();
if (!e) {
let t = document.createElement("div");
t.classList.add("grid", "cust-element"), e = document.createElement("input"), e.min = String(this.zeroable ? 0 : this.min), e.max = String(this.max), e.id = this.id, e.type = "number", e.step = String(this.step);
let i = document.createElement("label");
i.setAttribute("for", this.id), i.innerHTML = this.name, i.appendChild(e), t.appendChild(i);
let n = document.createElement("blockquote");
n.innerHTML = "<ul>" + this.desc.map((e => `<li>${e}</li>`)).join("") + "</ul>", n.setAttribute("for", this.id), t.appendChild(n), document.getElementById("config-list-basic").appendChild(t), new ErrorToolTip(this.id).addChangeListener()
}
e.value = String(this.value)
}
setElementValue() {
this.getInputElement().value = String(this.value)
}
setElementDefaultValue() {
this.getInputElement().value = String(this.defval)
}
removeElement() {
let e = this.getInputElement();
e && e.parentElement.parentElement.remove()
}
showElement() {
let e = this.getInputElement();
e && e.parentElement.parentElement.style.removeProperty("display")
}
hideElement() {
let e = this.getInputElement();
e && e.parentElement.parentElement.style.setProperty("display", "none")
}
}
class AdvEntry extends CustEntry {
createElement() {
let e = this.getInputElement();
if (!e) {
let t = document.createElement("div");
t.classList.add("grid", "cust-element"), e = document.createElement("input"), e.min = String(this.zeroable ? 0 : this.min), e.max = String(this.max), e.id = this.id, e.type = "number", e.step = String(this.step);
let i = document.createElement("label");
i.setAttribute("for", this.id), i.innerHTML = this.name, i.appendChild(e), t.appendChild(i);
let n = document.createElement("blockquote");
n.innerHTML = "<ul>" + this.desc.map((e => `<li>${e}</li>`)).join("") + "</ul>", n.setAttribute("for", this.id), t.appendChild(n), document.getElementById("config-list-advanced").appendChild(t), new ErrorToolTip(this.id).addChangeListener()
}
e.value = String(this.value)
}
}
class GpuEntry extends CustEntry {
constructor(e, t, i = CustPlatform.Mariko, n = 4, a = ["range: vMin ≤ x ≤ 960 (Zero is disabled)"], r = 480, s = [0, 960], l = 5, o = !1) {
super(e, t, i, n, a, r, s, l, o), this.id = e, this.name = t, this.platform = i, this.size = n, this.desc = a, this.defval = r, this.step = l, this.zeroable = o
}
createElement() {
let e = this.getInputElement();
if (!e) {
let t = document.createElement("div");
t.classList.add("grid", "cust-element"), e = document.createElement("input"), e.min = String(this.zeroable ? 0 : this.min), e.max = String(this.max), e.id = this.id, e.type = "number", e.step = String(this.step);
let i = document.createElement("label");
i.setAttribute("for", this.id), i.innerHTML = this.name, i.appendChild(e), t.appendChild(i);
let n = document.createElement("blockquote");
n.innerHTML = "<ul>" + this.desc.map((e => `<li>${e}</li>`)).join("") + "</ul>", n.setAttribute("for", this.id), t.appendChild(n), document.getElementById("config-list-gpu").appendChild(t), new ErrorToolTip(this.id).addChangeListener()
}
e.value = String(this.value)
}
}
var CustTable = [
new CustEntry("mtcConf", "DRAM Timing", CustPlatform.All, 4, [
"<b>0</b>: AUTO_ADJ_ALL: Auto adjust mtc table with LPDDR4 3733 Mbps specs, 8Gb density. Change timing with Advanced Config (Default)",
"<b>1</b>: CUSTOM_ADJ_ALL: Adjust only non-zero preset timings in Advanced Config",
"<b>2</b>: NO_ADJ_ALL: Use 1600 mtc table wihout adjusting (Timing becomes tighter if you raise dram clock)."
], 0, [0, 2], 1),
new CustEntry("commonCpuBoostClock", "Boost Clock in kHz", CustPlatform.All, 4, [
"System default: 1785000",
"Boost clock will be applied when applications request Boost Mode via performance configuration."
], 1785000, [204000, 2907000], 1, !1),
new CustEntry("commonEmcMemVolt", "EMC Vdd2 Voltage in uV", CustPlatform.All, 4, [
"Acceptable range: 1100000 ≤ x ≤ 1250000, and it should be divided evenly by 12500.",
"Erista Default: 1175000",
"Mariko Default: 1175000",
"Official LPDDR4(X) voltage: 1175mV (1175mV nominal)"
], 1175000, [11e5, 125e4], 12500),
new CustEntry("eristaCpuMaxVolt", "Erista CPU Max Voltage in mV", CustPlatform.Erista, 4, [
"Acceptable range: 1120 ≤ x ≤ 1300",
"Default: 1235"
], 1235, [1000, 1500], 1),
new CustEntry("eristaEmcMaxClock", "Erista RAM Max Clock in kHz", CustPlatform.Erista, 4, [
"Values should be ≥ 1600000, and divided evenly by 3200.",
"Recommended Clocks: 1862400, 2131200 (JEDEC)",
"<b>WARNING:</b> RAM overclock could be UNSTABLE if timing parameters are not suitable for your DRAM"
], 1862400, [16e5, 2428800], 3200),
new CustEntry("marikoCpuMaxVolt", "Mariko CPU Max Voltage in mV", CustPlatform.Mariko, 4, [
"System default: 1120",
"Acceptable range: 1120 ≤ x ≤ 1300",
"Changing this value affects cpu voltage calculation"
], 1235, [1120, 1300], 5),
new CustEntry("marikoEmcMaxClock", "Mariko RAM Max Clock in kHz", CustPlatform.Mariko, 4, [
"Values should be ≥ 1600000, and divided evenly by 9600.",
"Recommended Clocks: 1862400, 2131200, 2400000, etc. (JEDEC)",
"<b>WARNING:</b> RAM overclock could be UNSTABLE if timing parameters are not suitable for your DRAM."
], 1996800, [16e5, 3200000], 3200),
new CustEntry("marikoEmcVddqVolt", "EMC Vddq (Mariko Only) Voltage in uV", CustPlatform.Mariko, 4, [
"Acceptable range: 550000 ≤ x ≤ 650000",
"Value should be divided evenly by 5000",
"Default: 600000",
"Official lpddr4(x) range: 570mV~650mV (600mV nominal)",
"Not enabled by default."
], 600000, [55e4, 65e4], 5e3),
new CustEntry("marikoCpuUV", "Enable Mariko CPU Undervolt", CustPlatform.Mariko, 4, [
"Reduce CPU power draw",
"<b>0</b> : Default Table",
"<b>1</b> : Undervolt Level 1 (SLT - CPU speedo < 1650)",
"<b>2</b> : Undervolt Level 1 (SLT - CPU speedo >= 1650)"
], 0, [0, 2], 1),
new CustEntry("marikoGpuUV", "Enable Mariko GPU Undervolt", CustPlatform.Mariko, 4, [
"Reduce GPU power draw",
"Your GPU might not withstand undervolt, and can hang your console, or crash games",
"Undervolting too much will drop GPU performance even if it seems stable",
"GPU voltages are dynamic and will change with temperature and gpu speedo",
"<b>0</b> : Default Table",
"<b>1</b> : Undervolt Level 1 (SLT: Aggressive)",
"<b>2</b> : Undervolt Level 2 (HiOPT: Drastic)",
"<b>3</b> : Custom static GPU Voltage Table (Use Gpu Configuation below)"
], 0, [0, 3], 1),
new CustEntry("commonGpuVoltOffset", "GPU Volt Offset", CustPlatform.All, 4, [
"Negative Voltage offset value for gpu dynamic voltage calculation",
"For example, value of 10 will decrease 10mV gpu volt from all frequencies",
"Default gpu vmin: Erista - 812.5mV / Mariko - 610mV",
"Acceptable range: 0 ~ 100"
], 0, [0, 100], 1),
new CustEntry("marikoCpuHighVoltOffset", "CPU Voltage offset at high frequencies", CustPlatform.Mariko, 4, [
"Reduce CPU power draw at high clocks",
], 0, [0, 100], 1),
new CustEntry("marikoCpuHighUV", "Enable Mariko CPU High Undervolt", CustPlatform.Mariko, 4, [
"Reduce CPU power draw at high clocks by offsetting the voltage sent to the CPU",
], 0, [0, 12], 1),
new CustEntry("cpuMaxFreq", "Maximum allowed CPU Frequency (KHz)", CustPlatform.All, 4, [
"Default: 1785000",
"This is the maximum frequency for the CPU you can set in sys-clk-ocs2.",
"The value for this setting is capped at 2091mhz for Erista units and 2907MHz for Mariko units",
"Anything above 1785MHz for Erista units and 1963MHz for Mariko units is unsafe without undervolting"
], 1785000, [204000, 2907000], 1, !1),
new CustEntry("gpuMaxFreq", "Maximum allowed GPU Frequency (KHz)", CustPlatform.All, 4, [
"Default: 921600",
"This is the maximum frequency for the GPU you can set in sys-clk-ocs2.",
"The value for this setting is capped at 998mhz for Erista units, and 1305MHz on Mariko units",
"The maximum safe value without undervolt is 921MHz for Erista units and 1152MHz for Mariko units",
"Higher frequencies via GPU UV3 bypass this setting"
], 921600, [76800, 1305600], 1, !1),
new CustEntry("gpuVmax", "Mariko Maximum allowed GPU Voltage (mV)", CustPlatform.Mariko, 4, [
"Default: 800",
"This is the maximum voltage you can use in GPU UV3.",
"Anything above 800MV is considered UNSAFE (although it depends per frequency)"
], 800, [480, 1000], 1, !1),
new CustEntry("gpuVmin", "Mariko Minimum allowed GPU Voltage (mV)", CustPlatform.Mariko, 4, [
"Default: 600",
"This is the minimum voltage you can use in GPU UV3.",
"A higher Vmin is required for a higher max ram clock"
], 600, [480, 1000], 1, !1),
];
var AdvTable = [
new AdvEntry("marikoEmcDvbShift", "Step up Mariko EMC DVB Table", CustPlatform.Mariko, 4, [
"Each number adds 25mV to SoC voltage",
"Helps with stability at higher memory clock, with the only downside being slightly higher tempratures",
"Such functionality is completely useless on Erista units",
"Acceptable range : 0~9"
], 0, [0, 9], 1),
];
var GpuTable = [
new GpuEntry("0", "76.8"),
new GpuEntry("1", "153.6"),
new GpuEntry("2", "230.4"),
new GpuEntry("3", "307.2"),
new GpuEntry("4", "384.0"),
new GpuEntry("5", "460.8"),
new GpuEntry("6", "537.6"),
new GpuEntry("7", "614.4"),
new GpuEntry("8", "691.2"),
new GpuEntry("9", "768.0"),
new GpuEntry("10", "844.8"),
new GpuEntry("11", "921.6"),
new GpuEntry("12", "998.4"),
new GpuEntry("13", "1075.2", CustPlatform.Mariko),
new GpuEntry("14", "1152.0", CustPlatform.Mariko),
new GpuEntry("15", "1228.8 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("16", "1267.2 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("17", "1305.6 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("18", "1344.0 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("19", "1382.4 <span style='color:orange; font-weight:bold;'>(UNSAFE)</span>", CustPlatform.Mariko),
new GpuEntry("20", "1420.8 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko),
new GpuEntry("21", "1459.2 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko),
new GpuEntry("22", "1497.6 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko),
new GpuEntry("23", "1536.0 <span style='color:red; font-weight:bold;'>(DANGEROUS)</span>", CustPlatform.Mariko)
];
class ErrorToolTip {
constructor(e, t) {
this.id = e, this.msg = t, this.id = e, this.element = document.getElementById(e), t && this.setMsg(t)
}
setMsg(e) {
return this.msg = e, this
}
show() {
var e, t, i, n, a, r;
return null === (e = this.element) || void 0 === e || e.setAttribute("aria-invalid", "true"), this.msg && (null === (t = this.element) || void 0 === t || t.setAttribute("title", this.msg), null === (n = null === (i = this.element) || void 0 === i ? void 0 : i.parentElement) || void 0 === n || n.setAttribute("data-tooltip", this.msg), null === (r = null === (a = this.element) || void 0 === a ? void 0 : a.parentElement) || void 0 === r || r.setAttribute("data-placement", "top")), this
}
clear() {
var e, t, i, n, a, r;
return null === (e = this.element) || void 0 === e || e.removeAttribute("aria-invalid"), null === (t = this.element) || void 0 === t || t.removeAttribute("title"), null === (n = null === (i = this.element) || void 0 === i ? void 0 : i.parentElement) || void 0 === n || n.removeAttribute("data-tooltip"), null === (r = null === (a = this.element) || void 0 === a ? void 0 : a.parentElement) || void 0 === r || r.removeAttribute("data-placement"), this
}
addChangeListener() {
var e;
null === (e = this.element) || void 0 === e || e.addEventListener("change", (e => {
let t = CustTable.filter((e => e.id === this.id))[0];
t.value = Number(this.element.value), t.validate()
}))
}
}
class CustStorage {
constructor() {
this.storage = {}, this.key = "last_saved"
}
updateFromTable() {
let e = e => {
var t;
if (e.updateValueFromElement(), !e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`)
};
CustTable.forEach(e), AdvTable.forEach(e), GpuTable.forEach(e), this.storage = {};
let t = Object.fromEntries(CustTable.map((e => [e.id, e.value])));
Object.keys(t).forEach((e => this.storage[e] = t[e])), t = Object.fromEntries(AdvTable.map((e => [e.id, e.value]))), Object.keys(t).forEach((e => this.storage[e] = t[e]))
}
setTable() {
let e = Object.keys(this.storage);
e.forEach((e => CustTable.filter((t => t.id == e))[0].value = this.storage[e])), e.forEach((e => AdvTable.filter((t => t.id == e))[0].value = this.storage[e])), CustTable.filter((t => !e.includes(t.id))).forEach((e => e.value = e.defval)), AdvTable.filter((t => !e.includes(t.id))).forEach((e => e.value = e.defval)), CustTable.forEach((e => {
var t;
if (!e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`);
e.setElementValue()
})), AdvTable.forEach((e => {
var t;
if (!e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`);
e.setElementValue()
})), GpuTable.forEach((e => {
var t;
if (!e.validate()) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Invalid ${e.name}`);
e.setElementValue()
}))
}
save() {
localStorage.setItem(this.key, JSON.stringify(this.storage))
}
load() {
let e = localStorage.getItem(this.key);
if (!e) return null;
let t = JSON.parse(e),
i = CustTable.map((e => e.id)),
n = Object.keys(t).filter((e => !i.includes(e)));
return n.length && console.log(`Ignored: ${n}`), Object.keys(t).filter((e => i.includes(e))).forEach((e => this.storage[e] = t[e])), i = AdvTable.map((e => e.id)), n = Object.keys(t).filter((e => !i.includes(e))), n.length && console.log(`Ignored: ${n}`), Object.keys(t).filter((e => i.includes(e))).forEach((e => this.storage[e] = t[e])), this.storage
}
}
class Cust {
constructor() {
this.storage = new CustStorage, this.magic = 1414747459, this.magicLen = 4, this.mapper = {
2: {
get: e => this.view.getUint16(e, !0),
set: (e, t) => this.view.setUint16(e, t, !0)
},
4: {
get: e => this.view.getUint32(e, !0),
set: (e, t) => this.view.setUint32(e, t, !0)
}
}
}
findMagicOffset() {
this.view = new DataView(this.buffer);
for (let e = 0; e < this.view.byteLength; e += this.magicLen)
if (this.mapper[this.magicLen].get(e) == this.magic) return void(this.beginOffset = e);
throw new Error("Invalid loader.kip file")
}
save() {
this.storage.updateFromTable();
let e = e => {
var t, i;
if (!e.offset) throw null === (t = e.getInputElement()) || void 0 === t || t.focus(), new Error(`Failed to get offset for ${e.name}`);
let n = this.mapper[e.size];
if (!n) throw null === (i = e.getInputElement()) || void 0 === i || i.focus(), new Error(`Unknown size at ${e.name}`);
n.set(e.offset, e.value)
};
CustTable.forEach(e), AdvTable.forEach(e), GpuTable.forEach(e), this.storage.save();
let t = document.createElement("a");
t.href = window.URL.createObjectURL(new Blob([this.buffer], {
type: "application/octet-stream"
})), t.download = "loader.kip", t.click(), this.toggleLoadLastSavedBtn(!0)
}
removeHTMLForm() {
CustTable.forEach((e => e.removeElement()))
}
toggleLoadLastSavedBtn(e) {
let t = document.getElementById("load_saved");
e ? (t.addEventListener("click", (() => {
this.storage.load() && this.storage.setTable()
})), t.style.removeProperty("display"), t.removeAttribute("disabled")) : t.style.setProperty("display", "none")
}
createHTMLForm() {
var e, t;
CustTable.forEach((e => e.createElement()));
let i = document.createElement("p");
i.innerHTML = "Advanced configuration", null === (e = document.getElementById("config-list-advanced")) || void 0 === e || e.appendChild(i);
let n = document.createElement("p");
n.innerHTML = "Gpu Volt configuration", null === (t = document.getElementById("config-list-gpu")) || void 0 === t || t.appendChild(n), AdvTable.forEach((e => e.createElement())), GpuTable.forEach((e => e.createElement()));
let a = document.getElementById("load_default");
a.removeAttribute("disabled"), a.addEventListener("click", (() => {
CustTable.forEach((e => e.setElementDefaultValue()))
})), this.toggleLoadLastSavedBtn(null !== this.storage.load());
let r = document.getElementById("save");
r.removeAttribute("disabled"), r.addEventListener("click", (() => {
try {
this.save()
} catch (e) {
console.error(e), alert(e)
}
}))
}
initCustTabs() {
const e = Array.from(document.querySelectorAll('nav[role="tablist"] > button'));
e.forEach((t => {
t.removeAttribute("disabled");
let i = Number(t.getAttribute("data-platform"));
t.addEventListener("click", (n => {
const a = ["outline"];
t.classList.remove(...a), e.filter((e => e != t)).forEach((e => e.classList.add(...a))), CustTable.forEach((e => {
e.isAvailableFor(i) ? e.showElement() : e.hideElement()
}))
}))
}))
}
parse() {
let e = this.beginOffset + this.magicLen;
if (this.rev = this.mapper[4].get(e), CUST_REV_ADV != this.rev) throw new Error(`Unsupported custRev, expected: 1, got ${this.rev}`);
e += 4, document.getElementById("cust_rev").innerHTML = `Cust v${this.rev} is loaded.`;
let t = t => {
var i;
t.offset = e;
let n = this.mapper[t.size];
if (!n) throw null === (i = t.getInputElement()) || void 0 === i || i.focus(), new Error(`Unknown size at ${t}`);
t.value = n.get(e), e += t.size, t.validate()
};
CustTable.forEach(t), AdvTable.forEach(t), GpuTable.forEach(t)
}
load(e) {
try {
this.buffer = e, this.findMagicOffset(), this.removeHTMLForm(), this.parse(), this.initCustTabs(), this.createHTMLForm()
} catch (e) {
console.error(e), alert(e)
}
}
}
class ReleaseAsset {
constructor(e) {
this.downloadUrl = e.browser_download_url, this.updatedAt = e.updated_at
}
}
class ReleaseInfo {
constructor() {
this.ocLatestApi = "https://api.github.com/repos/souldbminersmwc/Switch-OC-Suite-2/releases/latest"
}
load() {
return __awaiter(this, void 0, void 0, (function*() {
try {
this.parseOcResponse(yield this.responseFromApi(this.ocLatestApi).catch())
} catch (e) {
console.error(e), alert(e)
}
}))
}
responseFromApi(e) {
return __awaiter(this, void 0, void 0, (function*() {
const t = yield fetch(e, {
method: "GET",
headers: {
Accept: "application/json"
}
});
if (t.ok) return yield t.json();
throw new Error(`Failed to connect to "${e}": ${t.status}`)
}))
}
parseOcResponse(e) {
this.ocVer = e.tag_name, this.loaderKipAsset = new ReleaseAsset(e.assets.filter((e => e.name.endsWith("loader.kip")))[0]), this.sdOutZipAsset = new ReleaseAsset(e.assets.filter((e => e.name.endsWith("SdOut.zip")))[0]), this.sysclkOCAsset = new ReleaseAsset(e.assets.filter((e => e.name.endsWith("sys-clk-ocs2.zip")))[0])
}
}
class DownloadSection {
constructor() {
this.element = document.getElementById("download_btn_grid")
}
load() {
return __awaiter(this, void 0, void 0, (function*() {
for (; !this.isVisible();) yield new Promise((e => setTimeout(e, 1e3)));
const e = new ReleaseInfo;
yield e.load(), this.update("loader_kip_btn", `loader.kip <b>${e.ocVer}</b><br>${e.loaderKipAsset.updatedAt}`, e.loaderKipAsset.downloadUrl), this.update("sdout_zip_btn", `SdOut.zip <b>${e.ocVer}</b><br>${e.sdOutZipAsset.updatedAt}`, e.sdOutZipAsset.downloadUrl), this.update("ams_btn", `sys-clk-ocs2 <b>${e.ocVer}</b><br>${e.sysclkOCAsset.updatedAt}`, e.sysclkOCAsset.downloadUrl)
}))
}
isVisible() {
let e = this.element.getBoundingClientRect();
return e.top > 0 && e.left > 0 && e.bottom - e.height < (window.innerHeight || document.documentElement.clientHeight) && e.right - e.width < (window.innerWidth || document.documentElement.clientWidth)
}
update(e, t, i) {
let n = document.getElementById(e);
n.innerHTML = t, n.removeAttribute("aria-busy"), n.setAttribute("href", i)
}
}
const fileInput = document.getElementById("file");
fileInput.addEventListener("change", (e => {
var t = new Cust;
if (!e.target || !e.target.files) return;
let i = new FileReader;
i.readAsArrayBuffer(e.target.files[0]), i.onloadend = e => {
e.target.readyState == FileReader.DONE && t.load(e.target.result)
}
})), addEventListener("DOMContentLoaded", (e => __awaiter(this, void 0, void 0, (function*() {
yield(new DownloadSection).load()
}))));

View File

@@ -1,41 +0,0 @@
OCS2-AA-MGCL-PRESET
.BL = 16,
.tRFCpb = 140,
.tRFCab = 280,
.tRAS = 42,
.tRPpb = 18,
.tRPab = 21,
.tRC = 60,
.tDQSCK_min = 1.5,
.tDQSCK_max = 3.6,
.tWPRE = 2.0,
.tRPST = 0.5,
.tDQSS_max = 1.25,
.tDQS2DQ_max = 0.7,
.tDQSQ = 0.18,
.tWTR = 12,
.tRTP = 7.5,
.tWR = 20,
.tR2REF = 25.5,
.tRCD = 18,
.tRRD = 10,
.tREFpb = 488,
.tXP = 7.5,
.tCMDCKE = 1.75,
.tMRWCKEL = 14,
.tCKELCS = 5,
.tCSCKEH = 1.75,
.tXSR = 287.5,
.tCKE = 7.5,
.tSR = 15,
.tFAW = 40,
.tCKCKEH = 1.75,
.WL = 14,
.RL = 32,

View File

@@ -1,41 +0,0 @@
OCS2-AB-MGCL-PRESET
.BL = 16,
.tRFCpb = 140,
.tRFCab = 280,
.tRAS = 42,
.tRPpb = 18,
.tRPab = 21,
.tRC = 60,
.tDQSCK_min = 1.5,
.tDQSCK_max = 3.5,
.tWPRE = 2.0,
.tRPST = 0.5,
.tDQSS_max = 1.25,
.tDQS2DQ_max = 0.7,
.tDQSQ = 0.18,
.tWTR = 10,
.tRTP = 7.5,
.tWR = 18,
.tR2REF = 25.5,
.tRCD = 18,
.tRRD = 18,
.tREFpb = 488,
.tXP = 7.5,
.tCMDCKE = 1.75,
.tMRWCKEL = 14,
.tCKELCS = 5,
.tCSCKEH = 1.75,
.tXSR = 287.5,
.tCKE = 7.5,
.tSR = 15,
.tFAW = 30,
.tCKCKEH = 1.75,
.WL = 14,
.RL = 32,

View File

@@ -1,41 +0,0 @@
OCS2-AM-MGCJ-PRESET
.BL = 16,
.tRFCpb = 140,
.tRFCab = 280,
.tRAS = 62,
.tRPpb = 18,
.tRPab = 21,
.tRC = 4,
.tDQSCK_min = 1.5,
.tDQSCK_max = 3.6,
.tWPRE = 2.0,
.tRPST = 0.5,
.tDQSS_max = 1.25,
.tDQS2DQ_max = 0.7,
.tDQSQ = 0.18,
.tWTR = 10,
.tRTP = 7.5,
.tWR = 18,
.tR2REF = 25.5,
.tRCD = 18,
.tRRD = 18,
.tREFpb = 488,
.tXP = 7.5,
.tCMDCKE = 1.75,
.tMRWCKEL = 14,
.tCKELCS = 5,
.tCSCKEH = 1.75,
.tXSR = 287.5,
.tCKE = 7.5,
.tSR = 15,
.tFAW = 40,
.tCKCKEH = 1.75,
.WL = 18,
.RL = 40,

View File

@@ -1,41 +0,0 @@
OCS2-MICRON-WTB-PRESET
.BL = 16,
.tRFCpb = 140,
.tRFCab = 280,
.tRAS = 42,
.tRPpb = 18,
.tRPab = 21,
.tRC = 60,
.tDQSCK_min = 1.5,
.tDQSCK_max = 3.5,
.tWPRE = 1.8,
.tRPST = 0.4,
.tDQSS_max = 1.25,
.tDQS2DQ_max = 0.8,
.tDQSQ = 0.18,
.tWTR = MAX(10, 8 * nCK_mariko),
.tRTP = 7.5, // Cannot find concrete value for this timing
.tWR = MAX(10, 4 * nCK_mariko),
.tR2REF = 25.5,
.tRCD = 20, // Cannot find concrete value for this timing
.tRRD = 10, // Cannot find concrete value for this timing
.tREFpb = 488,
.tXP = MAX(7.5, 5 * nCK_mariko),
.tCMDCKE = MAX(1.75, 3 * nCK_mariko),
.tMRWCKEL = MAX(14, 10 * nCK_mariko),
.tCKELCS = MAX(5, 5 * nCK_mariko),
.tCSCKEH = 1.75,
.tXSR = MAX(C.tRFcpb + 7.5, 5 * nCK_mariko),
.tCKE = MAX(7.5, 4 * nCK_mariko),
.tSR = MAX(15, 3 * nCK_mariko),
.tFAW = 30,
.tCKCKEH = MAX(1.75, 3 * nCK_mariko),
.WL = 14,
.RL = 32,