1
0
Fork 0
mirror of https://github.com/melonDS-emu/melonDS.git synced 2025-03-06 21:00:31 +01:00

Merge branch 'master' into feature/zip-support

This commit is contained in:
WaluigiWare64 2021-01-03 15:53:23 +00:00 committed by GitHub
commit 83648f2d31
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
34 changed files with 1040 additions and 798 deletions

View file

@ -2,7 +2,7 @@
<h2 align="center"><b>melonDS</b></h2> <h2 align="center"><b>melonDS</b></h2>
<p align="center"> <p align="center">
<a href="http://melonds.kuribo64.net/" alt="melonDS website"><img src="https://img.shields.io/badge/website-melonds.kuribo64.net-%2331352e.svg"></a> <a href="http://melonds.kuribo64.net/" alt="melonDS website"><img src="https://img.shields.io/badge/website-melonds.kuribo64.net-%2331352e.svg"></a>
<a href="http://melonds.kuribo64.net/downloads.php" alt="Release: 0.9"><img src="https://img.shields.io/badge/release-0.9-%235c913b.svg"></a> <a href="http://melonds.kuribo64.net/downloads.php" alt="Release: 0.9.1"><img src="https://img.shields.io/badge/release-0.9.1-%235c913b.svg"></a>
<a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-%23ff554d.svg"></a> <a href="https://www.gnu.org/licenses/gpl-3.0" alt="License: GPLv3"><img src="https://img.shields.io/badge/License-GPL%20v3-%23ff554d.svg"></a>
<a href="https://kiwiirc.com/client/irc.badnik.net/?nick=IRC-Source_?#melonds" alt="IRC channel: #melonds"><img src="https://img.shields.io/badge/IRC%20chat-%23melonds-%23dd2e44.svg"></a> <a href="https://kiwiirc.com/client/irc.badnik.net/?nick=IRC-Source_?#melonds" alt="IRC channel: #melonds"><img src="https://img.shields.io/badge/IRC%20chat-%23melonds-%23dd2e44.svg"></a>
</p> </p>

View file

@ -6,8 +6,8 @@
//include version information in .exe, modify these values to match your needs //include version information in .exe, modify these values to match your needs
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION 0,9,0,0 FILEVERSION 0,9,1,0
PRODUCTVERSION 0,9,0,0 PRODUCTVERSION 0,9,1,0
FILETYPE VFT_APP FILETYPE VFT_APP
{ {
BLOCK "StringFileInfo" BLOCK "StringFileInfo"
@ -15,14 +15,14 @@ FILETYPE VFT_APP
BLOCK "040904E4" BLOCK "040904E4"
{ {
VALUE "CompanyName", "Melon Factory of Kuribo64" VALUE "CompanyName", "Melon Factory of Kuribo64"
VALUE "FileVersion", "0.9" VALUE "FileVersion", "0.9.1"
VALUE "FileDescription", "DS emulator, sorta. also 1st quality melon." VALUE "FileDescription", "DS emulator, sorta. also 1st quality melon."
VALUE "InternalName", "SDnolem" VALUE "InternalName", "SDnolem"
VALUE "LegalCopyright", "2016-2020 Arisotura & co." VALUE "LegalCopyright", "2016-2020 Arisotura & co."
VALUE "LegalTrademarks", "" VALUE "LegalTrademarks", ""
VALUE "OriginalFilename", "zafkflzdasd.exe" VALUE "OriginalFilename", "zafkflzdasd.exe"
VALUE "ProductName", "melonDS" VALUE "ProductName", "melonDS"
VALUE "ProductVersion", "0.9" VALUE "ProductVersion", "0.9.1"
} }
} }
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View file

@ -23,23 +23,21 @@
#include "types.h" #include "types.h"
typedef struct struct ARCode
{ {
char Name[128]; char Name[128];
bool Enabled; bool Enabled;
u32 CodeLen; u32 CodeLen;
u32 Code[2*64]; u32 Code[2*64];
};
} ARCode;
typedef std::list<ARCode> ARCodeList; typedef std::list<ARCode> ARCodeList;
typedef struct struct ARCodeCat
{ {
char Name[128]; char Name[128];
ARCodeList Codes; ARCodeList Codes;
};
} ARCodeCat;
typedef std::list<ARCodeCat> ARCodeCatList; typedef std::list<ARCodeCat> ARCodeCatList;

View file

@ -8,8 +8,13 @@
.p2align 4,,15 .p2align 4,,15
#ifdef __APPLE__
.global _ARM_Dispatch
_ARM_Dispatch:
#else
.global ARM_Dispatch .global ARM_Dispatch
ARM_Dispatch: ARM_Dispatch:
#endif
stp x19, x20, [sp, #-96]! stp x19, x20, [sp, #-96]!
stp x21, x22, [sp, #16] stp x21, x22, [sp, #16]
stp x23, x24, [sp, #32] stp x23, x24, [sp, #32]
@ -25,8 +30,13 @@ ARM_Dispatch:
.p2align 4,,15 .p2align 4,,15
#ifdef __APPLE__
.global _ARM_Ret
_ARM_Ret:
#else
.global ARM_Ret .global ARM_Ret
ARM_Ret: ARM_Ret:
#endif
str RCycles, [RCPU, ARM_Cycles_offset] str RCycles, [RCPU, ARM_Cycles_offset]
str RCPSR, [RCPU, ARM_CPSR_offset] str RCPSR, [RCPU, ARM_CPSR_offset]
@ -65,4 +75,4 @@ ARM_RestoreContext:
ldp x17, x18, [sp, #248] ldp x17, x18, [sp, #248]
mov sp, x17 mov sp, x17
br x18 br x18

View file

@ -26,7 +26,7 @@
namespace Config namespace Config
{ {
typedef struct struct ConfigEntry
{ {
char Name[32]; char Name[32];
int Type; int Type;
@ -34,8 +34,7 @@ typedef struct
int DefaultInt; int DefaultInt;
const char* DefaultStr; const char* DefaultStr;
int StrLength; // should be set to actual array length minus one int StrLength; // should be set to actual array length minus one
};
} ConfigEntry;
FILE* GetConfigFile(const char* fileName, const char* permissions); FILE* GetConfigFile(const char* fileName, const char* permissions);
bool HasConfigFile(const char* fileName); bool HasConfigFile(const char* fileName);

View file

@ -38,8 +38,8 @@ bool OutputFlush;
u32 InputDMASize, OutputDMASize; u32 InputDMASize, OutputDMASize;
u32 AESMode; u32 AESMode;
FIFO<u32>* InputFIFO; FIFO<u32, 16> InputFIFO;
FIFO<u32>* OutputFIFO; FIFO<u32, 16> OutputFIFO;
u8 IV[16]; u8 IV[16];
@ -91,9 +91,6 @@ void ROL16(u8* val, u32 n)
bool Init() bool Init()
{ {
InputFIFO = new FIFO<u32>(16);
OutputFIFO = new FIFO<u32>(16);
const u8 zero[16] = {0}; const u8 zero[16] = {0};
AES_init_ctx_iv(&Ctx, zero, zero); AES_init_ctx_iv(&Ctx, zero, zero);
@ -102,8 +99,6 @@ bool Init()
void DeInit() void DeInit()
{ {
delete InputFIFO;
delete OutputFIFO;
} }
void Reset() void Reset()
@ -119,8 +114,8 @@ void Reset()
OutputDMASize = 0; OutputDMASize = 0;
AESMode = 0; AESMode = 0;
InputFIFO->Clear(); InputFIFO.Clear();
OutputFIFO->Clear(); OutputFIFO.Clear();
memset(IV, 0, sizeof(IV)); memset(IV, 0, sizeof(IV));
@ -164,10 +159,10 @@ void ProcessBlock_CCM_Decrypt()
u8 data[16]; u8 data[16];
u8 data_rev[16]; u8 data_rev[16];
*(u32*)&data[0] = InputFIFO->Read(); *(u32*)&data[0] = InputFIFO.Read();
*(u32*)&data[4] = InputFIFO->Read(); *(u32*)&data[4] = InputFIFO.Read();
*(u32*)&data[8] = InputFIFO->Read(); *(u32*)&data[8] = InputFIFO.Read();
*(u32*)&data[12] = InputFIFO->Read(); *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CCM: "); _printhex2(data, 16); //printf("AES-CCM: "); _printhex2(data, 16);
@ -181,10 +176,10 @@ void ProcessBlock_CCM_Decrypt()
//printf(" -> "); _printhex2(data, 16); //printf(" -> "); _printhex2(data, 16);
OutputFIFO->Write(*(u32*)&data[0]); OutputFIFO.Write(*(u32*)&data[0]);
OutputFIFO->Write(*(u32*)&data[4]); OutputFIFO.Write(*(u32*)&data[4]);
OutputFIFO->Write(*(u32*)&data[8]); OutputFIFO.Write(*(u32*)&data[8]);
OutputFIFO->Write(*(u32*)&data[12]); OutputFIFO.Write(*(u32*)&data[12]);
} }
void ProcessBlock_CCM_Encrypt() void ProcessBlock_CCM_Encrypt()
@ -192,10 +187,10 @@ void ProcessBlock_CCM_Encrypt()
u8 data[16]; u8 data[16];
u8 data_rev[16]; u8 data_rev[16];
*(u32*)&data[0] = InputFIFO->Read(); *(u32*)&data[0] = InputFIFO.Read();
*(u32*)&data[4] = InputFIFO->Read(); *(u32*)&data[4] = InputFIFO.Read();
*(u32*)&data[8] = InputFIFO->Read(); *(u32*)&data[8] = InputFIFO.Read();
*(u32*)&data[12] = InputFIFO->Read(); *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CCM: "); _printhex2(data, 16); //printf("AES-CCM: "); _printhex2(data, 16);
@ -209,10 +204,10 @@ void ProcessBlock_CCM_Encrypt()
//printf(" -> "); _printhex2(data, 16); //printf(" -> "); _printhex2(data, 16);
OutputFIFO->Write(*(u32*)&data[0]); OutputFIFO.Write(*(u32*)&data[0]);
OutputFIFO->Write(*(u32*)&data[4]); OutputFIFO.Write(*(u32*)&data[4]);
OutputFIFO->Write(*(u32*)&data[8]); OutputFIFO.Write(*(u32*)&data[8]);
OutputFIFO->Write(*(u32*)&data[12]); OutputFIFO.Write(*(u32*)&data[12]);
} }
void ProcessBlock_CTR() void ProcessBlock_CTR()
@ -220,10 +215,10 @@ void ProcessBlock_CTR()
u8 data[16]; u8 data[16];
u8 data_rev[16]; u8 data_rev[16];
*(u32*)&data[0] = InputFIFO->Read(); *(u32*)&data[0] = InputFIFO.Read();
*(u32*)&data[4] = InputFIFO->Read(); *(u32*)&data[4] = InputFIFO.Read();
*(u32*)&data[8] = InputFIFO->Read(); *(u32*)&data[8] = InputFIFO.Read();
*(u32*)&data[12] = InputFIFO->Read(); *(u32*)&data[12] = InputFIFO.Read();
//printf("AES-CTR: "); _printhex2(data, 16); //printf("AES-CTR: "); _printhex2(data, 16);
@ -233,10 +228,10 @@ void ProcessBlock_CTR()
//printf(" -> "); _printhex(data, 16); //printf(" -> "); _printhex(data, 16);
OutputFIFO->Write(*(u32*)&data[0]); OutputFIFO.Write(*(u32*)&data[0]);
OutputFIFO->Write(*(u32*)&data[4]); OutputFIFO.Write(*(u32*)&data[4]);
OutputFIFO->Write(*(u32*)&data[8]); OutputFIFO.Write(*(u32*)&data[8]);
OutputFIFO->Write(*(u32*)&data[12]); OutputFIFO.Write(*(u32*)&data[12]);
} }
@ -244,8 +239,8 @@ u32 ReadCnt()
{ {
u32 ret = Cnt; u32 ret = Cnt;
ret |= InputFIFO->Level(); ret |= InputFIFO.Level();
ret |= (OutputFIFO->Level() << 5); ret |= (OutputFIFO.Level() << 5);
return ret; return ret;
} }
@ -341,9 +336,9 @@ void WriteBlkCnt(u32 val)
u32 ReadOutputFIFO() u32 ReadOutputFIFO()
{ {
if (OutputFIFO->IsEmpty()) printf("!!! AES OUTPUT FIFO EMPTY\n"); if (OutputFIFO.IsEmpty()) printf("!!! AES OUTPUT FIFO EMPTY\n");
u32 ret = OutputFIFO->Read(); u32 ret = OutputFIFO.Read();
if (Cnt & (1<<31)) if (Cnt & (1<<31))
{ {
@ -352,17 +347,17 @@ u32 ReadOutputFIFO()
} }
else else
{ {
if (OutputFIFO->Level() > 0) if (OutputFIFO.Level() > 0)
DSi::CheckNDMAs(1, 0x2B); DSi::CheckNDMAs(1, 0x2B);
else else
DSi::StopNDMAs(1, 0x2B); DSi::StopNDMAs(1, 0x2B);
if (OutputMACDue && OutputFIFO->Level() <= 12) if (OutputMACDue && OutputFIFO.Level() <= 12)
{ {
OutputFIFO->Write(*(u32*)&OutputMAC[0]); OutputFIFO.Write(*(u32*)&OutputMAC[0]);
OutputFIFO->Write(*(u32*)&OutputMAC[4]); OutputFIFO.Write(*(u32*)&OutputMAC[4]);
OutputFIFO->Write(*(u32*)&OutputMAC[8]); OutputFIFO.Write(*(u32*)&OutputMAC[8]);
OutputFIFO->Write(*(u32*)&OutputMAC[12]); OutputFIFO.Write(*(u32*)&OutputMAC[12]);
OutputMACDue = false; OutputMACDue = false;
} }
} }
@ -374,9 +369,9 @@ void WriteInputFIFO(u32 val)
{ {
// TODO: add some delay to processing // TODO: add some delay to processing
if (InputFIFO->IsFull()) printf("!!! AES INPUT FIFO FULL\n"); if (InputFIFO.IsFull()) printf("!!! AES INPUT FIFO FULL\n");
InputFIFO->Write(val); InputFIFO.Write(val);
if (!(Cnt & (1<<31))) return; if (!(Cnt & (1<<31))) return;
@ -387,7 +382,7 @@ void CheckInputDMA()
{ {
if (RemBlocks == 0) return; if (RemBlocks == 0) return;
if (InputFIFO->Level() <= InputDMASize) if (InputFIFO.Level() <= InputDMASize)
{ {
// trigger input DMA // trigger input DMA
DSi::CheckNDMAs(1, 0x2A); DSi::CheckNDMAs(1, 0x2A);
@ -398,7 +393,7 @@ void CheckInputDMA()
void CheckOutputDMA() void CheckOutputDMA()
{ {
if (OutputFIFO->Level() >= OutputDMASize) if (OutputFIFO.Level() >= OutputDMASize)
{ {
// trigger output DMA // trigger output DMA
DSi::CheckNDMAs(1, 0x2B); DSi::CheckNDMAs(1, 0x2B);
@ -407,7 +402,7 @@ void CheckOutputDMA()
void Update() void Update()
{ {
while (InputFIFO->Level() >= 4 && OutputFIFO->Level() <= 12 && RemBlocks > 0) while (InputFIFO.Level() >= 4 && OutputFIFO.Level() <= 12 && RemBlocks > 0)
{ {
switch (AESMode) switch (AESMode)
{ {
@ -463,7 +458,7 @@ void Update()
if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES); if (Cnt & (1<<30)) NDS::SetIRQ2(NDS::IRQ2_DSi_AES);
DSi::StopNDMAs(1, 0x2A); DSi::StopNDMAs(1, 0x2A);
if (OutputFIFO->Level() > 0) if (!OutputFIFO.IsEmpty())
DSi::CheckNDMAs(1, 0x2B); DSi::CheckNDMAs(1, 0x2B);
else else
DSi::StopNDMAs(1, 0x2B); DSi::StopNDMAs(1, 0x2B);

View file

@ -303,7 +303,7 @@ u8 DSi_Camera::Read8(u32 addr)
} }
u16 DSi_Camera::Read16(u32 addr) u16 DSi_Camera::Read16(u32 addr)
{printf("CAM READ %08X %08X\n", addr, NDS::GetPC(0)); {
switch (addr) switch (addr)
{ {
case 0x04004200: return ModuleCnt; case 0x04004200: return ModuleCnt;
@ -313,15 +313,16 @@ u16 DSi_Camera::Read16(u32 addr)
printf("unknown DSi cam read16 %08X\n", addr); printf("unknown DSi cam read16 %08X\n", addr);
return 0; return 0;
} }
u32 dorp = 0;
u32 DSi_Camera::Read32(u32 addr) u32 DSi_Camera::Read32(u32 addr)
{ {
switch (addr) switch (addr)
{ {
case 0x04004204: case 0x04004204:
{ {
// TODO
return 0xFC00801F; return 0xFC00801F;
if (!(Cnt & (1<<15))) return 0; // CHECKME /*if (!(Cnt & (1<<15))) return 0; // CHECKME
u32 ret = *(u32*)&FrameBuffer[TransferPos]; u32 ret = *(u32*)&FrameBuffer[TransferPos];
TransferPos += 4; TransferPos += 4;
if (TransferPos >= FrameLength) TransferPos = 0; if (TransferPos >= FrameLength) TransferPos = 0;
@ -332,7 +333,7 @@ u32 DSi_Camera::Read32(u32 addr)
dorp = 0; dorp = 0;
Cnt &= ~(1<<4); Cnt &= ~(1<<4);
} }
return ret; return ret;*/
} }
} }
@ -348,7 +349,7 @@ void DSi_Camera::Write8(u32 addr, u8 val)
} }
void DSi_Camera::Write16(u32 addr, u16 val) void DSi_Camera::Write16(u32 addr, u16 val)
{printf("CAM WRITE %08X %04X %08X\n", addr, val, NDS::GetPC(0)); {
switch (addr) switch (addr)
{ {
case 0x04004200: case 0x04004200:

View file

@ -116,18 +116,20 @@ const u8 CIS1[256] =
DSi_NWifi* Ctx = nullptr; DSi_NWifi* Ctx = nullptr;
DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host) DSi_NWifi::DSi_NWifi(DSi_SDHost* host)
: DSi_SDDevice(host),
Mailbox
{
// HACK
// the mailboxes are supposed to be 0x80 bytes
// however, as we do things instantly, emulating this is meaningless
// and only adds complication
DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600),
DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600), DynamicFIFO<u8>(0x600),
// mailbox 8: extra mailbox acting as a bigger RX buffer
DynamicFIFO<u8>(0x8000)
}
{ {
// HACK
// the mailboxes are supposed to be 0x80 bytes
// however, as we do things instantly, emulating this is meaningless
// and only adds complication
for (int i = 0; i < 8; i++)
Mailbox[i] = new FIFO<u8>(0x600);//0x80);
// extra mailbox acting as a bigger RX buffer
Mailbox[8] = new FIFO<u8>(0x8000);
// this seems to control whether the firmware upload is done // this seems to control whether the firmware upload is done
EEPROMReady = 0; EEPROMReady = 0;
@ -136,9 +138,6 @@ DSi_NWifi::DSi_NWifi(DSi_SDHost* host) : DSi_SDDevice(host)
DSi_NWifi::~DSi_NWifi() DSi_NWifi::~DSi_NWifi()
{ {
for (int i = 0; i < 9; i++)
delete Mailbox[i];
NDS::CancelEvent(NDS::Event_DSi_NWifi); NDS::CancelEvent(NDS::Event_DSi_NWifi);
Ctx = nullptr; Ctx = nullptr;
} }
@ -159,7 +158,7 @@ void DSi_NWifi::Reset()
WindowWriteAddr = 0; WindowWriteAddr = 0;
for (int i = 0; i < 9; i++) for (int i = 0; i < 9; i++)
Mailbox[i]->Clear(); Mailbox[i].Clear();
u8* mac = SPI_Firmware::GetWifiMAC(); u8* mac = SPI_Firmware::GetWifiMAC();
printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", printf("NWifi MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
@ -250,10 +249,10 @@ void DSi_NWifi::UpdateIRQ_F1()
{ {
F1_IRQStatus = 0; F1_IRQStatus = 0;
if (!Mailbox[4]->IsEmpty()) F1_IRQStatus |= (1<<0); if (!Mailbox[4].IsEmpty()) F1_IRQStatus |= (1<<0);
if (!Mailbox[5]->IsEmpty()) F1_IRQStatus |= (1<<1); if (!Mailbox[5].IsEmpty()) F1_IRQStatus |= (1<<1);
if (!Mailbox[6]->IsEmpty()) F1_IRQStatus |= (1<<2); if (!Mailbox[6].IsEmpty()) F1_IRQStatus |= (1<<2);
if (!Mailbox[7]->IsEmpty()) F1_IRQStatus |= (1<<3); if (!Mailbox[7].IsEmpty()) F1_IRQStatus |= (1<<3);
if (F1_IRQStatus_Counter & F1_IRQEnable_Counter) F1_IRQStatus |= (1<<4); if (F1_IRQStatus_Counter & F1_IRQEnable_Counter) F1_IRQStatus |= (1<<4);
if (F1_IRQStatus_CPU & F1_IRQEnable_CPU) F1_IRQStatus |= (1<<6); if (F1_IRQStatus_CPU & F1_IRQEnable_CPU) F1_IRQStatus |= (1<<6);
if (F1_IRQStatus_Error & F1_IRQEnable_Error) F1_IRQStatus |= (1<<7); if (F1_IRQStatus_Error & F1_IRQEnable_Error) F1_IRQStatus |= (1<<7);
@ -337,26 +336,26 @@ u8 DSi_NWifi::F1_Read(u32 addr)
{ {
if (addr < 0x100) if (addr < 0x100)
{ {
u8 ret = Mailbox[4]->Read(); u8 ret = Mailbox[4].Read();
if (addr == 0xFF) DrainRXBuffer(); if (addr == 0xFF) DrainRXBuffer();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x200) else if (addr < 0x200)
{ {
u8 ret = Mailbox[5]->Read(); u8 ret = Mailbox[5].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x300) else if (addr < 0x300)
{ {
u8 ret = Mailbox[6]->Read(); u8 ret = Mailbox[6].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x400) else if (addr < 0x400)
{ {
u8 ret = Mailbox[7]->Read(); u8 ret = Mailbox[7].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
@ -373,18 +372,18 @@ u8 DSi_NWifi::F1_Read(u32 addr)
{ {
u8 ret = 0; u8 ret = 0;
if (Mailbox[4]->Level() >= 4) ret |= (1<<0); if (Mailbox[4].Level() >= 4) ret |= (1<<0);
if (Mailbox[5]->Level() >= 4) ret |= (1<<1); if (Mailbox[5].Level() >= 4) ret |= (1<<1);
if (Mailbox[6]->Level() >= 4) ret |= (1<<2); if (Mailbox[6].Level() >= 4) ret |= (1<<2);
if (Mailbox[7]->Level() >= 4) ret |= (1<<3); if (Mailbox[7].Level() >= 4) ret |= (1<<3);
return ret; return ret;
} }
case 0x00408: return Mailbox[4]->Peek(0); case 0x00408: return Mailbox[4].Peek(0);
case 0x00409: return Mailbox[4]->Peek(1); case 0x00409: return Mailbox[4].Peek(1);
case 0x0040A: return Mailbox[4]->Peek(2); case 0x0040A: return Mailbox[4].Peek(2);
case 0x0040B: return Mailbox[4]->Peek(3); case 0x0040B: return Mailbox[4].Peek(3);
case 0x00418: return F1_IRQEnable; case 0x00418: return F1_IRQEnable;
case 0x00419: return F1_IRQEnable_CPU; case 0x00419: return F1_IRQEnable_CPU;
@ -403,32 +402,32 @@ u8 DSi_NWifi::F1_Read(u32 addr)
} }
else if (addr < 0x1000) else if (addr < 0x1000)
{ {
u8 ret = Mailbox[4]->Read(); u8 ret = Mailbox[4].Read();
if (addr == 0xFFF) DrainRXBuffer(); if (addr == 0xFFF) DrainRXBuffer();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x1800) else if (addr < 0x1800)
{ {
u8 ret = Mailbox[5]->Read(); u8 ret = Mailbox[5].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x2000) else if (addr < 0x2000)
{ {
u8 ret = Mailbox[6]->Read(); u8 ret = Mailbox[6].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else if (addr < 0x2800) else if (addr < 0x2800)
{ {
u8 ret = Mailbox[7]->Read(); u8 ret = Mailbox[7].Read();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
} }
else else
{ {
u8 ret = Mailbox[4]->Read(); u8 ret = Mailbox[4].Read();
if (addr == 0x3FFF) DrainRXBuffer(); if (addr == 0x3FFF) DrainRXBuffer();
UpdateIRQ_F1(); UpdateIRQ_F1();
return ret; return ret;
@ -442,30 +441,30 @@ void DSi_NWifi::F1_Write(u32 addr, u8 val)
{ {
if (addr < 0x100) if (addr < 0x100)
{ {
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); if (Mailbox[0].IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
Mailbox[0]->Write(val); Mailbox[0].Write(val);
if (addr == 0xFF) HandleCommand(); if (addr == 0xFF) HandleCommand();
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
else if (addr < 0x200) else if (addr < 0x200)
{ {
if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n"); if (Mailbox[1].IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
Mailbox[1]->Write(val); Mailbox[1].Write(val);
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
else if (addr < 0x300) else if (addr < 0x300)
{ {
if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n"); if (Mailbox[2].IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
Mailbox[2]->Write(val); Mailbox[2].Write(val);
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
else if (addr < 0x400) else if (addr < 0x400)
{ {
if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n"); if (Mailbox[3].IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
Mailbox[3]->Write(val); Mailbox[3].Write(val);
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
@ -505,37 +504,37 @@ void DSi_NWifi::F1_Write(u32 addr, u8 val)
} }
else if (addr < 0x1000) else if (addr < 0x1000)
{ {
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); if (Mailbox[0].IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
Mailbox[0]->Write(val); Mailbox[0].Write(val);
if (addr == 0xFFF) HandleCommand(); if (addr == 0xFFF) HandleCommand();
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
else if (addr < 0x1800) else if (addr < 0x1800)
{ {
if (Mailbox[1]->IsFull()) printf("!!! NWIFI: MBOX1 FULL\n"); if (Mailbox[1].IsFull()) printf("!!! NWIFI: MBOX1 FULL\n");
Mailbox[1]->Write(val); Mailbox[1].Write(val);
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
else if (addr < 0x2000) else if (addr < 0x2000)
{ {
if (Mailbox[2]->IsFull()) printf("!!! NWIFI: MBOX2 FULL\n"); if (Mailbox[2].IsFull()) printf("!!! NWIFI: MBOX2 FULL\n");
Mailbox[2]->Write(val); Mailbox[2].Write(val);
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
else if (addr < 0x2800) else if (addr < 0x2800)
{ {
if (Mailbox[3]->IsFull()) printf("!!! NWIFI: MBOX3 FULL\n"); if (Mailbox[3].IsFull()) printf("!!! NWIFI: MBOX3 FULL\n");
Mailbox[3]->Write(val); Mailbox[3].Write(val);
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
} }
else else
{ {
if (Mailbox[0]->IsFull()) printf("!!! NWIFI: MBOX0 FULL\n"); if (Mailbox[0].IsFull()) printf("!!! NWIFI: MBOX0 FULL\n");
Mailbox[0]->Write(val); Mailbox[0].Write(val);
if (addr == 0x3FFF) HandleCommand(); // CHECKME if (addr == 0x3FFF) HandleCommand(); // CHECKME
UpdateIRQ_F1(); UpdateIRQ_F1();
return; return;
@ -750,7 +749,7 @@ void DSi_NWifi::BMI_Command()
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
u8 val = Mailbox[0]->Read(); u8 val = Mailbox[0].Read();
// TODO: do something with it!! // TODO: do something with it!!
} }
@ -804,7 +803,7 @@ void DSi_NWifi::BMI_Command()
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
u8 val = Mailbox[0]->Read(); u8 val = Mailbox[0].Read();
// TODO: do something with it!! // TODO: do something with it!!
//fwrite(&val, 1, 1, f); //fwrite(&val, 1, 1, f);
@ -873,7 +872,7 @@ void DSi_NWifi::HTC_Command()
printf("unknown HTC command %04X\n", cmd); printf("unknown HTC command %04X\n", cmd);
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
printf("%02X ", Mailbox[0]->Read()); printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n"); if ((i&0xF)==0xF) printf("\n");
} }
printf("\n"); printf("\n");
@ -926,7 +925,7 @@ void DSi_NWifi::WMI_Command()
case 0x0004: // synchronize case 0x0004: // synchronize
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
@ -944,8 +943,8 @@ void DSi_NWifi::WMI_Command()
u32 legacy = MB_Read32(0); u32 legacy = MB_Read32(0);
u32 scantime = MB_Read32(0); u32 scantime = MB_Read32(0);
u32 forceinterval = MB_Read32(0); u32 forceinterval = MB_Read32(0);
u8 scantype = Mailbox[0]->Read(); u8 scantype = Mailbox[0].Read();
u8 nchannels = Mailbox[0]->Read(); u8 nchannels = Mailbox[0].Read();
printf("WMI: start scan, forceFG=%d, legacy=%d, scanTime=%d, interval=%d, scanType=%d, chan=%d\n", printf("WMI: start scan, forceFG=%d, legacy=%d, scanTime=%d, interval=%d, scanType=%d, chan=%d\n",
forcefg, legacy, scantime, forceinterval, scantype, nchannels); forcefg, legacy, scantime, forceinterval, scantype, nchannels);
@ -969,10 +968,10 @@ void DSi_NWifi::WMI_Command()
case 0x0009: // set BSS filter case 0x0009: // set BSS filter
{ {
// TODO: do something with the params!! // TODO: do something with the params!!
u8 bssfilter = Mailbox[0]->Read(); u8 bssfilter = Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
u32 iemask = MB_Read32(0); u32 iemask = MB_Read32(0);
printf("WMI: set BSS filter, filter=%02X, iemask=%08X\n", bssfilter, iemask); printf("WMI: set BSS filter, filter=%02X, iemask=%08X\n", bssfilter, iemask);
@ -981,13 +980,13 @@ void DSi_NWifi::WMI_Command()
case 0x000A: // set probed BSSID case 0x000A: // set probed BSSID
{ {
u8 id = Mailbox[0]->Read(); u8 id = Mailbox[0].Read();
u8 flags = Mailbox[0]->Read(); u8 flags = Mailbox[0].Read();
u8 len = Mailbox[0]->Read(); u8 len = Mailbox[0].Read();
char ssid[33] = {0}; char ssid[33] = {0};
for (int i = 0; i < len && i < 32; i++) for (int i = 0; i < len && i < 32; i++)
ssid[i] = Mailbox[0]->Read(); ssid[i] = Mailbox[0].Read();
// TODO: store it somewhere // TODO: store it somewhere
printf("WMI: set probed SSID: id=%d, flags=%02X, len=%d, SSID=%s\n", id, flags, len, ssid); printf("WMI: set probed SSID: id=%d, flags=%02X, len=%d, SSID=%s\n", id, flags, len, ssid);
@ -996,7 +995,7 @@ void DSi_NWifi::WMI_Command()
case 0x000D: // set disconnect timeout case 0x000D: // set disconnect timeout
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
@ -1018,10 +1017,10 @@ void DSi_NWifi::WMI_Command()
case 0x0011: // set channel params case 0x0011: // set channel params
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
u8 scan = Mailbox[0]->Read(); u8 scan = Mailbox[0].Read();
u8 phymode = Mailbox[0]->Read(); u8 phymode = Mailbox[0].Read();
u8 len = Mailbox[0]->Read(); u8 len = Mailbox[0].Read();
u16 channels[32]; u16 channels[32];
for (int i = 0; i < len && i < 32; i++) for (int i = 0; i < len && i < 32; i++)
@ -1037,13 +1036,13 @@ void DSi_NWifi::WMI_Command()
case 0x0012: // set power mode case 0x0012: // set power mode
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
case 0x0017: // dummy? case 0x0017: // dummy?
Mailbox[0]->Read(); Mailbox[0].Read();
break; break;
case 0x0022: // set error bitmask case 0x0022: // set error bitmask
@ -1080,14 +1079,14 @@ void DSi_NWifi::WMI_Command()
case 0x003D: // set keepalive interval case 0x003D: // set keepalive interval
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
case 0x0041: // 'WMI_SET_WSC_STATUS_CMD' case 0x0041: // 'WMI_SET_WSC_STATUS_CMD'
{ {
Mailbox[0]->Read(); Mailbox[0].Read();
// TODO?? // TODO??
} }
break; break;
@ -1102,8 +1101,8 @@ void DSi_NWifi::WMI_Command()
{ {
MB_Read32(0); MB_Read32(0);
MB_Read32(0); MB_Read32(0);
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
} }
break; break;
@ -1116,9 +1115,9 @@ void DSi_NWifi::WMI_Command()
case 0xF000: // set bitrate case 0xF000: // set bitrate
{ {
// TODO! // TODO!
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
Mailbox[0]->Read(); Mailbox[0].Read();
} }
break; break;
@ -1126,7 +1125,7 @@ void DSi_NWifi::WMI_Command()
printf("unknown WMI command %04X (header: %04X:%04X:%04X)\n", cmd, h0, len, h2); printf("unknown WMI command %04X (header: %04X:%04X:%04X)\n", cmd, h0, len, h2);
for (int i = 0; i < len-2; i++) for (int i = 0; i < len-2; i++)
{ {
printf("%02X ", Mailbox[0]->Read()); printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n"); if ((i&0xF)==0xF) printf("\n");
} }
printf("\n"); printf("\n");
@ -1142,18 +1141,18 @@ void DSi_NWifi::WMI_Command()
void DSi_NWifi::WMI_ConnectToNetwork() void DSi_NWifi::WMI_ConnectToNetwork()
{ {
u8 type = Mailbox[0]->Read(); u8 type = Mailbox[0].Read();
u8 auth11 = Mailbox[0]->Read(); u8 auth11 = Mailbox[0].Read();
u8 auth = Mailbox[0]->Read(); u8 auth = Mailbox[0].Read();
u8 pCryptoType = Mailbox[0]->Read(); u8 pCryptoType = Mailbox[0].Read();
u8 pCryptoLen = Mailbox[0]->Read(); u8 pCryptoLen = Mailbox[0].Read();
u8 gCryptoType = Mailbox[0]->Read(); u8 gCryptoType = Mailbox[0].Read();
u8 gCryptoLen = Mailbox[0]->Read(); u8 gCryptoLen = Mailbox[0].Read();
u8 ssidLen = Mailbox[0]->Read(); u8 ssidLen = Mailbox[0].Read();
char ssid[33] = {0}; char ssid[33] = {0};
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
ssid[i] = Mailbox[0]->Read(); ssid[i] = Mailbox[0].Read();
if (ssidLen <= 32) if (ssidLen <= 32)
ssid[ssidLen] = '\0'; ssid[ssidLen] = '\0';
@ -1219,11 +1218,11 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
{ {
printf("WMI: data sync\n"); printf("WMI: data sync\n");
/*Mailbox[8]->Write(2); // eid /*Mailbox[8].Write(2); // eid
Mailbox[8]->Write(0x00); // flags Mailbox[8].Write(0x00); // flags
MB_Write16(8, 2); // data length MB_Write16(8, 2); // data length
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
MB_Write16(8, 0x0200); // MB_Write16(8, 0x0200); //
DrainRXBuffer();*/ DrainRXBuffer();*/
@ -1235,7 +1234,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
printf("WMI: special frame %04X len=%d\n", hdr, len); printf("WMI: special frame %04X len=%d\n", hdr, len);
for (int i = 0; i < len-2; i++) for (int i = 0; i < len-2; i++)
{ {
printf("%02X ", Mailbox[0]->Read()); printf("%02X ", Mailbox[0].Read());
if ((i&0xF)==0xF) printf("\n"); if ((i&0xF)==0xF) printf("\n");
} }
printf("\n"); printf("\n");
@ -1279,7 +1278,7 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
*(u16*)&LANBuffer[12] = ethertype; // type *(u16*)&LANBuffer[12] = ethertype; // type
for (int i = 0; i < lan_len-14; i++) for (int i = 0; i < lan_len-14; i++)
{ {
LANBuffer[14+i] = Mailbox[0]->Read(); LANBuffer[14+i] = Mailbox[0].Read();
} }
/*for (int i = 0; i < lan_len; i++) /*for (int i = 0; i < lan_len; i++)
@ -1294,73 +1293,73 @@ void DSi_NWifi::WMI_SendPacket(u16 len)
void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len) void DSi_NWifi::SendWMIEvent(u8 ep, u16 id, u8* data, u32 len)
{ {
if (!Mailbox[8]->CanFit(6+len+2+8)) if (!Mailbox[8].CanFit(6+len+2+8))
{ {
printf("NWifi: !! not enough space in RX buffer for WMI event %04X\n", id); printf("NWifi: !! not enough space in RX buffer for WMI event %04X\n", id);
return; return;
} }
Mailbox[8]->Write(ep); // eid Mailbox[8].Write(ep); // eid
Mailbox[8]->Write(0x02); // flags (trailer) Mailbox[8].Write(0x02); // flags (trailer)
MB_Write16(8, len+2+8); // data length (plus event ID and trailer) MB_Write16(8, len+2+8); // data length (plus event ID and trailer)
Mailbox[8]->Write(8); // trailer length Mailbox[8].Write(8); // trailer length
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
MB_Write16(8, id); // event ID MB_Write16(8, id); // event ID
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
Mailbox[8]->Write(data[i]); Mailbox[8].Write(data[i]);
} }
// trailer // trailer
Mailbox[8]->Write(0x02); Mailbox[8].Write(0x02);
Mailbox[8]->Write(0x06); Mailbox[8].Write(0x06);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
DrainRXBuffer(); DrainRXBuffer();
} }
void DSi_NWifi::SendWMIAck(u8 ep) void DSi_NWifi::SendWMIAck(u8 ep)
{ {
if (!Mailbox[8]->CanFit(6+12)) if (!Mailbox[8].CanFit(6+12))
{ {
printf("NWifi: !! not enough space in RX buffer for WMI ack (ep #%d)\n", ep); printf("NWifi: !! not enough space in RX buffer for WMI ack (ep #%d)\n", ep);
return; return;
} }
Mailbox[8]->Write(0); // eid Mailbox[8].Write(0); // eid
Mailbox[8]->Write(0x02); // flags (trailer) Mailbox[8].Write(0x02); // flags (trailer)
MB_Write16(8, 0xC); // data length (plus trailer) MB_Write16(8, 0xC); // data length (plus trailer)
Mailbox[8]->Write(0xC); // trailer length Mailbox[8].Write(0xC); // trailer length
Mailbox[8]->Write(0); // Mailbox[8].Write(0); //
// credit report // credit report
Mailbox[8]->Write(0x01); Mailbox[8].Write(0x01);
Mailbox[8]->Write(0x02); Mailbox[8].Write(0x02);
Mailbox[8]->Write(ep); Mailbox[8].Write(ep);
Mailbox[8]->Write(0x01); Mailbox[8].Write(0x01);
// lookahead // lookahead
Mailbox[8]->Write(0x02); Mailbox[8].Write(0x02);
Mailbox[8]->Write(0x06); Mailbox[8].Write(0x06);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
DrainRXBuffer(); DrainRXBuffer();
} }
void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len) void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
{ {
if (!Mailbox[8]->CanFit(6+len+2+16)) if (!Mailbox[8].CanFit(6+len+2+16))
{ {
printf("NWifi: !! not enough space in RX buffer for WMI BSSINFO event\n"); printf("NWifi: !! not enough space in RX buffer for WMI BSSINFO event\n");
return; return;
@ -1369,16 +1368,16 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
// TODO: check when version>=2 frame type is used? // TODO: check when version>=2 frame type is used?
// I observed the version<2 variant on my DSi // I observed the version<2 variant on my DSi
Mailbox[8]->Write(1); // eid Mailbox[8].Write(1); // eid
Mailbox[8]->Write(0x00); // flags Mailbox[8].Write(0x00); // flags
MB_Write16(8, len+2+16); // data length (plus event ID and trailer) MB_Write16(8, len+2+16); // data length (plus event ID and trailer)
Mailbox[8]->Write(0xFF); // trailer length Mailbox[8].Write(0xFF); // trailer length
Mailbox[8]->Write(0xFF); // Mailbox[8].Write(0xFF); //
MB_Write16(8, 0x1004); // event ID MB_Write16(8, 0x1004); // event ID
MB_Write16(8, 2437); // channel (6) (checkme!) MB_Write16(8, 2437); // channel (6) (checkme!)
Mailbox[8]->Write(type); Mailbox[8].Write(type);
Mailbox[8]->Write(0x1B); // 'snr' Mailbox[8].Write(0x1B); // 'snr'
MB_Write16(8, 0xFFBC); // RSSI MB_Write16(8, 0xFFBC); // RSSI
MB_Write32(8, *(u32*)&WifiAP::APMac[0]); MB_Write32(8, *(u32*)&WifiAP::APMac[0]);
MB_Write16(8, *(u16*)&WifiAP::APMac[4]); MB_Write16(8, *(u16*)&WifiAP::APMac[4]);
@ -1386,7 +1385,7 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
Mailbox[8]->Write(data[i]); Mailbox[8].Write(data[i]);
} }
DrainRXBuffer(); DrainRXBuffer();
@ -1394,7 +1393,7 @@ void DSi_NWifi::SendWMIBSSInfo(u8 type, u8* data, u32 len)
void DSi_NWifi::CheckRX() void DSi_NWifi::CheckRX()
{ {
if (!Mailbox[8]->CanFit(2048)) if (!Mailbox[8].CanFit(2048))
return; return;
int rxlen = Platform::LAN_RecvPacket(LANBuffer); int rxlen = Platform::LAN_RecvPacket(LANBuffer);
@ -1433,11 +1432,11 @@ void DSi_NWifi::CheckRX()
// TODO: not hardcode the endpoint ID!! // TODO: not hardcode the endpoint ID!!
u8 ep = 2; u8 ep = 2;
Mailbox[8]->Write(ep); Mailbox[8].Write(ep);
Mailbox[8]->Write(0x00); Mailbox[8].Write(0x00);
MB_Write16(8, 16 + 8 + datalen); MB_Write16(8, 16 + 8 + datalen);
Mailbox[8]->Write(0); Mailbox[8].Write(0);
Mailbox[8]->Write(0); Mailbox[8].Write(0);
MB_Write16(8, hdr); MB_Write16(8, hdr);
MB_Write32(8, *(u32*)&LANBuffer[0]); MB_Write32(8, *(u32*)&LANBuffer[0]);
@ -1454,7 +1453,7 @@ void DSi_NWifi::CheckRX()
MB_Write16(8, *(u16*)&LANBuffer[12]); MB_Write16(8, *(u16*)&LANBuffer[12]);
for (int i = 0; i < datalen; i++) for (int i = 0; i < datalen; i++)
Mailbox[8]->Write(LANBuffer[14+i]); Mailbox[8].Write(LANBuffer[14+i]);
DrainRXBuffer(); DrainRXBuffer();
} }
@ -1541,25 +1540,25 @@ void DSi_NWifi::_MSTimer()
if (ConnectionStatus == 1) if (ConnectionStatus == 1)
{ {
//if (Mailbox[4]->IsEmpty()) //if (Mailbox[4].IsEmpty())
CheckRX(); CheckRX();
} }
} }
void DSi_NWifi::DrainRXBuffer() void DSi_NWifi::DrainRXBuffer()
{ {
while (Mailbox[8]->Level() >= 6) while (Mailbox[8].Level() >= 6)
{ {
u16 len = Mailbox[8]->Peek(2) | (Mailbox[8]->Peek(3) << 8); u16 len = Mailbox[8].Peek(2) | (Mailbox[8].Peek(3) << 8);
u32 totallen = len + 6; u32 totallen = len + 6;
u32 required = (totallen + 0x7F) & ~0x7F; u32 required = (totallen + 0x7F) & ~0x7F;
if (!Mailbox[4]->CanFit(required)) if (!Mailbox[4].CanFit(required))
break; break;
u32 i = 0; u32 i = 0;
for (; i < totallen; i++) Mailbox[4]->Write(Mailbox[8]->Read()); for (; i < totallen; i++) Mailbox[4].Write(Mailbox[8].Read());
for (; i < required; i++) Mailbox[4]->Write(0); for (; i < required; i++) Mailbox[4].Write(0);
} }
UpdateIRQ_F1(); UpdateIRQ_F1();

View file

@ -84,40 +84,40 @@ private:
u16 MB_Read16(int n) u16 MB_Read16(int n)
{ {
u16 ret = Mailbox[n]->Read(); u16 ret = Mailbox[n].Read();
ret |= (Mailbox[n]->Read() << 8); ret |= (Mailbox[n].Read() << 8);
return ret; return ret;
} }
void MB_Write16(int n, u16 val) void MB_Write16(int n, u16 val)
{ {
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); Mailbox[n].Write(val & 0xFF);
} }
u32 MB_Read32(int n) u32 MB_Read32(int n)
{ {
u32 ret = Mailbox[n]->Read(); u32 ret = Mailbox[n].Read();
ret |= (Mailbox[n]->Read() << 8); ret |= (Mailbox[n].Read() << 8);
ret |= (Mailbox[n]->Read() << 16); ret |= (Mailbox[n].Read() << 16);
ret |= (Mailbox[n]->Read() << 24); ret |= (Mailbox[n].Read() << 24);
return ret; return ret;
} }
void MB_Write32(int n, u32 val) void MB_Write32(int n, u32 val)
{ {
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); val >>= 8; Mailbox[n].Write(val & 0xFF); val >>= 8;
Mailbox[n]->Write(val & 0xFF); Mailbox[n].Write(val & 0xFF);
} }
void MB_Drain(int n) void MB_Drain(int n)
{ {
while (!Mailbox[n]->IsEmpty()) Mailbox[n]->Read(); while (!Mailbox[n].IsEmpty()) Mailbox[n].Read();
} }
FIFO<u8>* Mailbox[9]; DynamicFIFO<u8> Mailbox[9];
u8 F0_IRQEnable; u8 F0_IRQEnable;
u8 F0_IRQStatus; u8 F0_IRQStatus;

View file

@ -52,20 +52,12 @@ DSi_SDHost::DSi_SDHost(u32 num)
{ {
Num = num; Num = num;
DataFIFO[0] = new FIFO<u16>(0x100);
DataFIFO[1] = new FIFO<u16>(0x100);
DataFIFO32 = new FIFO<u32>(0x80);
Ports[0] = NULL; Ports[0] = NULL;
Ports[1] = NULL; Ports[1] = NULL;
} }
DSi_SDHost::~DSi_SDHost() DSi_SDHost::~DSi_SDHost()
{ {
delete DataFIFO[0];
delete DataFIFO[1];
delete DataFIFO32;
if (Ports[0]) delete Ports[0]; if (Ports[0]) delete Ports[0];
if (Ports[1]) delete Ports[1]; if (Ports[1]) delete Ports[1];
} }
@ -89,10 +81,10 @@ void DSi_SDHost::Reset()
Param = 0; Param = 0;
memset(ResponseBuffer, 0, sizeof(ResponseBuffer)); memset(ResponseBuffer, 0, sizeof(ResponseBuffer));
DataFIFO[0]->Clear(); DataFIFO[0].Clear();
DataFIFO[1]->Clear(); DataFIFO[1].Clear();
CurFIFO = 0; CurFIFO = 0;
DataFIFO32->Clear(); DataFIFO32.Clear();
IRQStatus = 0; IRQStatus = 0;
IRQMask = 0x8B7F031D; IRQMask = 0x8B7F031D;
@ -160,8 +152,8 @@ void DSi_SDHost::UpdateData32IRQ()
oldflags &= (Data32IRQ >> 11); oldflags &= (Data32IRQ >> 11);
Data32IRQ &= ~0x0300; Data32IRQ &= ~0x0300;
if (DataFIFO32->Level() >= (BlockLen32>>2)) Data32IRQ |= (1<<8); if (DataFIFO32.Level() >= (BlockLen32>>2)) Data32IRQ |= (1<<8);
if (!DataFIFO32->IsEmpty()) Data32IRQ |= (1<<9); if (!DataFIFO32.IsEmpty()) Data32IRQ |= (1<<9);
u32 newflags = ((Data32IRQ >> 8) & 0x1) | (((~Data32IRQ) >> 8) & 0x2); u32 newflags = ((Data32IRQ >> 8) & 0x1) | (((~Data32IRQ) >> 8) & 0x2);
newflags &= (Data32IRQ >> 11); newflags &= (Data32IRQ >> 11);
@ -256,7 +248,7 @@ u32 DSi_SDHost::DataRX(u8* data, u32 len)
u32 f = CurFIFO ^ 1; u32 f = CurFIFO ^ 1;
for (u32 i = 0; i < len; i += 2) for (u32 i = 0; i < len; i += 2)
DataFIFO[f]->Write(*(u16*)&data[i]); DataFIFO[f].Write(*(u16*)&data[i]);
//CurFIFO = f; //CurFIFO = f;
//SetIRQ(24); //SetIRQ(24);
@ -304,9 +296,9 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
if (DataMode == 1) if (DataMode == 1)
{ {
if ((DataFIFO32->Level() << 2) < len) if ((DataFIFO32.Level() << 2) < len)
{ {
if (DataFIFO32->IsEmpty()) if (DataFIFO32.IsEmpty())
{ {
SetIRQ(25); SetIRQ(25);
DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); DSi::CheckNDMAs(1, Num ? 0x29 : 0x28);
@ -316,16 +308,16 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
// drain FIFO32 into FIFO16 // drain FIFO32 into FIFO16
if (!DataFIFO[f]->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO32 INTO FIFO16 BUT IT CONTAINS SHIT ALREADY\n"); if (!DataFIFO[f].IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO32 INTO FIFO16 BUT IT CONTAINS SHIT ALREADY\n");
for (;;) for (;;)
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if ((DataFIFO[f]->Level() << 1) >= BlockLen16) break; if ((DataFIFO[f].Level() << 1) >= BlockLen16) break;
if (DataFIFO32->IsEmpty()) break; if (DataFIFO32.IsEmpty()) break;
u32 val = DataFIFO32->Read(); u32 val = DataFIFO32.Read();
DataFIFO[f]->Write(val & 0xFFFF); DataFIFO[f].Write(val & 0xFFFF);
DataFIFO[f]->Write(val >> 16); DataFIFO[f].Write(val >> 16);
} }
UpdateData32IRQ(); UpdateData32IRQ();
@ -335,15 +327,15 @@ u32 DSi_SDHost::DataTX(u8* data, u32 len)
} }
else else
{ {
if ((DataFIFO[f]->Level() << 1) < len) if ((DataFIFO[f].Level() << 1) < len)
{ {
if (DataFIFO[f]->IsEmpty()) SetIRQ(25); if (DataFIFO[f].IsEmpty()) SetIRQ(25);
return 0; return 0;
} }
} }
for (u32 i = 0; i < len; i += 2) for (u32 i = 0; i < len; i += 2)
*(u16*)&data[i] = DataFIFO[f]->Read(); *(u16*)&data[i] = DataFIFO[f].Read();
CurFIFO ^= 1; CurFIFO ^= 1;
BlockCountInternal--; BlockCountInternal--;
@ -392,13 +384,13 @@ void DSi_SDHost::CheckTX()
if (DataMode == 1) if (DataMode == 1)
{ {
if ((DataFIFO32->Level() << 2) < BlockLen32) if ((DataFIFO32.Level() << 2) < BlockLen32)
return; return;
} }
else else
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if ((DataFIFO[f]->Level() << 1) < BlockLen16) if ((DataFIFO[f].Level() << 1) < BlockLen16)
return; return;
} }
@ -481,7 +473,7 @@ u16 DSi_SDHost::Read(u32 addr)
u16 DSi_SDHost::ReadFIFO16() u16 DSi_SDHost::ReadFIFO16()
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if (DataFIFO[f]->IsEmpty()) if (DataFIFO[f].IsEmpty())
{ {
// TODO // TODO
// on hardware it seems to wrap around. underflow bit is set upon the first 'empty' read. // on hardware it seems to wrap around. underflow bit is set upon the first 'empty' read.
@ -489,9 +481,9 @@ u16 DSi_SDHost::ReadFIFO16()
} }
DSi_SDDevice* dev = Ports[PortSelect & 0x1]; DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u16 ret = DataFIFO[f]->Read(); u16 ret = DataFIFO[f].Read();
if (DataFIFO[f]->IsEmpty()) if (DataFIFO[f].IsEmpty())
{ {
CheckRX(); CheckRX();
} }
@ -503,16 +495,16 @@ u32 DSi_SDHost::ReadFIFO32()
{ {
if (DataMode != 1) return 0; if (DataMode != 1) return 0;
if (DataFIFO32->IsEmpty()) if (DataFIFO32.IsEmpty())
{ {
// TODO // TODO
return 0; return 0;
} }
DSi_SDDevice* dev = Ports[PortSelect & 0x1]; DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u32 ret = DataFIFO32->Read(); u32 ret = DataFIFO32.Read();
if (DataFIFO32->IsEmpty()) if (DataFIFO32.IsEmpty())
{ {
CheckRX(); CheckRX();
} }
@ -628,7 +620,7 @@ void DSi_SDHost::Write(u32 addr, u16 val)
case 0x100: case 0x100:
Data32IRQ = (val & 0x1802) | (Data32IRQ & 0x0300); Data32IRQ = (val & 0x1802) | (Data32IRQ & 0x0300);
if (val & (1<<10)) DataFIFO32->Clear(); if (val & (1<<10)) DataFIFO32.Clear();
DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1); DataMode = ((DataCtl >> 1) & 0x1) & ((Data32IRQ >> 1) & 0x1);
return; return;
case 0x102: return; case 0x102: return;
@ -643,14 +635,14 @@ void DSi_SDHost::WriteFIFO16(u16 val)
{ {
DSi_SDDevice* dev = Ports[PortSelect & 0x1]; DSi_SDDevice* dev = Ports[PortSelect & 0x1];
u32 f = CurFIFO; u32 f = CurFIFO;
if (DataFIFO[f]->IsFull()) if (DataFIFO[f].IsFull())
{ {
// TODO // TODO
printf("!!!! %s FIFO (16) FULL\n", SD_DESC); printf("!!!! %s FIFO (16) FULL\n", SD_DESC);
return; return;
} }
DataFIFO[f]->Write(val); DataFIFO[f].Write(val);
CheckTX(); CheckTX();
} }
@ -659,14 +651,14 @@ void DSi_SDHost::WriteFIFO32(u32 val)
{ {
if (DataMode != 1) return; if (DataMode != 1) return;
if (DataFIFO32->IsFull()) if (DataFIFO32.IsFull())
{ {
// TODO // TODO
printf("!!!! %s FIFO (32) FULL\n", SD_DESC); printf("!!!! %s FIFO (32) FULL\n", SD_DESC);
return; return;
} }
DataFIFO32->Write(val); DataFIFO32.Write(val);
CheckTX(); CheckTX();
@ -679,21 +671,21 @@ void DSi_SDHost::UpdateFIFO32()
if (DataMode != 1) return; if (DataMode != 1) return;
if (!DataFIFO32->IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO16 INTO FIFO32 BUT IT CONTAINS SHIT ALREADY\n"); if (!DataFIFO32.IsEmpty()) printf("VERY BAD!! TRYING TO DRAIN FIFO16 INTO FIFO32 BUT IT CONTAINS SHIT ALREADY\n");
for (;;) for (;;)
{ {
u32 f = CurFIFO; u32 f = CurFIFO;
if ((DataFIFO32->Level() << 2) >= BlockLen32) break; if ((DataFIFO32.Level() << 2) >= BlockLen32) break;
if (DataFIFO[f]->IsEmpty()) break; if (DataFIFO[f].IsEmpty()) break;
u32 val = DataFIFO[f]->Read(); u32 val = DataFIFO[f].Read();
val |= (DataFIFO[f]->Read() << 16); val |= (DataFIFO[f].Read() << 16);
DataFIFO32->Write(val); DataFIFO32.Write(val);
} }
UpdateData32IRQ(); UpdateData32IRQ();
if ((DataFIFO32->Level() << 2) >= BlockLen32) if ((DataFIFO32.Level() << 2) >= BlockLen32)
{ {
DSi::CheckNDMAs(1, Num ? 0x29 : 0x28); DSi::CheckNDMAs(1, Num ? 0x29 : 0x28);
} }
@ -704,8 +696,8 @@ void DSi_SDHost::CheckSwapFIFO()
// check whether we can swap the FIFOs // check whether we can swap the FIFOs
u32 f = CurFIFO; u32 f = CurFIFO;
bool cur_empty = (DataMode == 1) ? DataFIFO32->IsEmpty() : DataFIFO[f]->IsEmpty(); bool cur_empty = (DataMode == 1) ? DataFIFO32.IsEmpty() : DataFIFO[f].IsEmpty();
if (cur_empty && ((DataFIFO[f^1]->Level() << 1) >= BlockLen16)) if (cur_empty && ((DataFIFO[f^1].Level() << 1) >= BlockLen16))
{ {
CurFIFO ^= 1; CurFIFO ^= 1;
} }

View file

@ -85,12 +85,12 @@ private:
u32 Param; u32 Param;
u16 ResponseBuffer[8]; u16 ResponseBuffer[8];
FIFO<u16>* DataFIFO[2];
u32 CurFIFO; // FIFO accessible for read/write
FIFO<u32>* DataFIFO32;
DSi_SDDevice* Ports[2]; DSi_SDDevice* Ports[2];
u32 CurFIFO; // FIFO accessible for read/write
FIFO<u16, 0x100> DataFIFO[2];
FIFO<u32, 0x80> DataFIFO32;
void UpdateData32IRQ(); void UpdateData32IRQ();
void ClearIRQ(u32 irq); void ClearIRQ(u32 irq);
void SetIRQ(u32 irq); void SetIRQ(u32 irq);

View file

@ -21,18 +21,95 @@
#include "types.h" #include "types.h"
template<typename T> template<typename T, u32 NumEntries>
class FIFO class FIFO
{ {
public: public:
FIFO(u32 num) void Clear()
{
NumOccupied = 0;
ReadPos = 0;
WritePos = 0;
memset(&Entries[ReadPos], 0, sizeof(T));
}
void DoSavestate(Savestate* file)
{
file->Var32(&NumOccupied);
file->Var32(&ReadPos);
file->Var32(&WritePos);
file->VarArray(Entries, sizeof(T)*NumEntries);
}
void Write(T val)
{
if (IsFull()) return;
Entries[WritePos] = val;
WritePos++;
if (WritePos >= NumEntries)
WritePos = 0;
NumOccupied++;
}
T Read()
{
T ret = Entries[ReadPos];
if (IsEmpty())
return ret;
ReadPos++;
if (ReadPos >= NumEntries)
ReadPos = 0;
NumOccupied--;
return ret;
}
T Peek()
{
return Entries[ReadPos];
}
T Peek(u32 offset)
{
u32 pos = ReadPos + offset;
if (pos >= NumEntries)
pos -= NumEntries;
return Entries[pos];
}
u32 Level() { return NumOccupied; }
bool IsEmpty() { return NumOccupied == 0; }
bool IsFull() { return NumOccupied >= NumEntries; }
bool CanFit(u32 num) { return ((NumOccupied + num) <= NumEntries); }
private:
T Entries[NumEntries] = {0};
u32 NumOccupied = 0;
u32 ReadPos = 0, WritePos = 0;
};
template<typename T>
class DynamicFIFO
{
public:
DynamicFIFO(u32 num)
{ {
NumEntries = num; NumEntries = num;
Entries = new T[num]; Entries = new T[num];
Clear(); Clear();
} }
~FIFO() ~DynamicFIFO()
{ {
delete[] Entries; delete[] Entries;
} }

View file

@ -142,6 +142,9 @@ u8 VRAMFlat_BOBJExtPal[8*1024];
u8 VRAMFlat_Texture[512*1024]; u8 VRAMFlat_Texture[512*1024];
u8 VRAMFlat_TexPal[128*1024]; u8 VRAMFlat_TexPal[128*1024];
u32 OAMDirty;
u32 PaletteDirty;
bool Init() bool Init()
{ {
GPU2D_A = new GPU2D_Soft(0); GPU2D_A = new GPU2D_Soft(0);
@ -272,6 +275,9 @@ void Reset()
ResetRenderer(); ResetRenderer();
ResetVRAMCache(); ResetVRAMCache();
OAMDirty = 0x3;
PaletteDirty = 0xF;
} }
void Stop() void Stop()

View file

@ -147,14 +147,16 @@ bool MakeVRAMFlat_TexPalCoherent(NonStupidBitField<128*1024/VRAMDirtyGranularity
void SyncDirtyFlags(); void SyncDirtyFlags();
typedef struct extern u32 OAMDirty;
extern u32 PaletteDirty;
struct RenderSettings
{ {
bool Soft_Threaded; bool Soft_Threaded;
int GL_ScaleFactor; int GL_ScaleFactor;
bool GL_BetterPolygons; bool GL_BetterPolygons;
};
} RenderSettings;
bool Init(); bool Init();
@ -509,6 +511,35 @@ T ReadVRAM_TexPal(u32 addr)
return ret; return ret;
} }
template<typename T>
T ReadPalette(u32 addr)
{
return *(T*)&Palette[addr & 0x7FF];
}
template<typename T>
void WritePalette(u32 addr, T val)
{
addr &= 0x7FF;
*(T*)&Palette[addr] = val;
PaletteDirty |= 1 << (addr / VRAMDirtyGranularity);
}
template<typename T>
T ReadOAM(u32 addr)
{
return *(T*)&OAM[addr & 0x7FF];
}
template<typename T>
void WriteOAM(u32 addr, T val)
{
addr &= 0x7FF;
*(T*)&OAM[addr] = val;
OAMDirty |= 1 << (addr / 1024);
}
void SetPowerCnt(u32 val); void SetPowerCnt(u32 val);

File diff suppressed because it is too large Load diff

View file

@ -25,7 +25,7 @@
namespace GPU3D namespace GPU3D
{ {
typedef struct struct Vertex
{ {
s32 Position[4]; s32 Position[4];
s32 Color[3]; s32 Color[3];
@ -43,9 +43,9 @@ typedef struct
// TODO maybe: hi-res color? (that survives clipping) // TODO maybe: hi-res color? (that survives clipping)
s32 HiresPosition[2]; s32 HiresPosition[2];
} Vertex; };
typedef struct struct Polygon
{ {
Vertex* Vertices[10]; Vertex* Vertices[10];
u32 NumVertices; u32 NumVertices;
@ -74,7 +74,7 @@ typedef struct
u32 SortKey; u32 SortKey;
} Polygon; };
extern u32 RenderDispCnt; extern u32 RenderDispCnt;
extern u8 RenderAlphaRef; extern u8 RenderAlphaRef;

View file

@ -70,7 +70,7 @@ struct
GLuint ShaderConfigUBO; GLuint ShaderConfigUBO;
typedef struct struct RendererPolygon
{ {
Polygon* PolyData; Polygon* PolyData;
@ -82,8 +82,7 @@ typedef struct
u32 EdgeIndicesOffset; u32 EdgeIndicesOffset;
u32 RenderKey; u32 RenderKey;
};
} RendererPolygon;
RendererPolygon PolygonList[2048]; RendererPolygon PolygonList[2048];
int NumFinalPolys, NumOpaqueFinalPolys; int NumFinalPolys, NumOpaqueFinalPolys;

View file

@ -538,7 +538,7 @@ private:
s32 ycoverage, ycov_incr; s32 ycoverage, ycov_incr;
}; };
typedef struct struct RendererPolygon
{ {
Polygon* PolyData; Polygon* PolyData;
@ -548,7 +548,7 @@ typedef struct
u32 CurVL, CurVR; u32 CurVL, CurVR;
u32 NextVL, NextVR; u32 NextVL, NextVR;
} RendererPolygon; };
RendererPolygon PolygonList[2048]; RendererPolygon PolygonList[2048];

View file

@ -40,7 +40,13 @@ GLuint Comp3DXPosLoc[1];
GLuint CompVertexBufferID; GLuint CompVertexBufferID;
GLuint CompVertexArrayID; GLuint CompVertexArrayID;
float CompVertices[2 * 3*2 * 2]; // position
struct CompVertex
{
float Position[2];
float Texcoord[2];
};
CompVertex CompVertices[2 * 3*2];
GLuint CompScreenInputTex; GLuint CompScreenInputTex;
GLuint CompScreenOutputTex; GLuint CompScreenOutputTex;
@ -59,6 +65,7 @@ bool Init()
GLint uni_id; GLint uni_id;
glBindAttribLocation(CompShader[i][2], 0, "vPosition"); glBindAttribLocation(CompShader[i][2], 0, "vPosition");
glBindAttribLocation(CompShader[i][2], 1, "vTexcoord");
glBindFragDataLocation(CompShader[i][2], 0, "oColor"); glBindFragDataLocation(CompShader[i][2], 0, "oColor");
if (!OpenGL::LinkShaderProgram(CompShader[i])) if (!OpenGL::LinkShaderProgram(CompShader[i]))
@ -74,25 +81,29 @@ bool Init()
glUniform1i(uni_id, 1); glUniform1i(uni_id, 1);
} }
#define SETVERTEX(i, x, y) \ // all this mess is to prevent bleeding
CompVertices[2*(i) + 0] = x; \ #define SETVERTEX(i, x, y, offset) \
CompVertices[2*(i) + 1] = y; CompVertices[i].Position[0] = x; \
CompVertices[i].Position[1] = y + offset; \
CompVertices[i].Texcoord[0] = (x + 1.f) * (256.f / 2.f); \
CompVertices[i].Texcoord[1] = (y + 1.f) * (384.f / 2.f)
const float padOffset = 1.f/(192*2.f+2.f)*2.f;
// top screen // top screen
SETVERTEX(0, -1, 1); SETVERTEX(0, -1, 1, 0);
SETVERTEX(1, 1, 0); SETVERTEX(1, 1, 0, padOffset);
SETVERTEX(2, 1, 1); SETVERTEX(2, 1, 1, 0);
SETVERTEX(3, -1, 1); SETVERTEX(3, -1, 1, 0);
SETVERTEX(4, -1, 0); SETVERTEX(4, -1, 0, padOffset);
SETVERTEX(5, 1, 0); SETVERTEX(5, 1, 0, padOffset);
// bottom screen // bottom screen
SETVERTEX(6, -1, 0); SETVERTEX(6, -1, 0, -padOffset);
SETVERTEX(7, 1, -1); SETVERTEX(7, 1, -1, 0);
SETVERTEX(8, 1, 0); SETVERTEX(8, 1, 0, -padOffset);
SETVERTEX(9, -1, 0); SETVERTEX(9, -1, 0, -padOffset);
SETVERTEX(10, -1, -1); SETVERTEX(10, -1, -1, 0);
SETVERTEX(11, 1, -1); SETVERTEX(11, 1, -1, 0);
#undef SETVERTEX #undef SETVERTEX
@ -103,7 +114,9 @@ bool Init()
glGenVertexArrays(1, &CompVertexArrayID); glGenVertexArrays(1, &CompVertexArrayID);
glBindVertexArray(CompVertexArrayID); glBindVertexArray(CompVertexArrayID);
glEnableVertexAttribArray(0); // position glEnableVertexAttribArray(0); // position
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2*4, (void*)(0)); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(CompVertex), (void*)(offsetof(CompVertex, Position)));
glEnableVertexAttribArray(1); // texcoord
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(CompVertex), (void*)(offsetof(CompVertex, Texcoord)));
glGenFramebuffers(1, &CompScreenOutputFB); glGenFramebuffers(1, &CompScreenOutputFB);
@ -152,10 +165,14 @@ void SetRenderSettings(RenderSettings& settings)
Scale = scale; Scale = scale;
ScreenW = 256 * scale; ScreenW = 256 * scale;
ScreenH = 384 * scale; ScreenH = (384+2) * scale;
glBindTexture(GL_TEXTURE_2D, CompScreenOutputTex); glBindTexture(GL_TEXTURE_2D, CompScreenOutputTex);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, ScreenW, ScreenH, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// fill the padding
u8 zeroPixels[ScreenW*2*scale*4];
memset(zeroPixels, 0, sizeof(zeroPixels));
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192*scale, ScreenW, 2*scale, GL_RGBA, GL_UNSIGNED_BYTE, zeroPixels);
GLenum fbassign[] = {GL_COLOR_ATTACHMENT0}; GLenum fbassign[] = {GL_COLOR_ATTACHMENT0};
glBindFramebuffer(GL_FRAMEBUFFER, CompScreenOutputFB); glBindFramebuffer(GL_FRAMEBUFFER, CompScreenOutputFB);

View file

@ -22,6 +22,7 @@
const char* kCompositorVS = R"(#version 140 const char* kCompositorVS = R"(#version 140
in vec2 vPosition; in vec2 vPosition;
in vec2 vTexcoord;
smooth out vec2 fTexcoord; smooth out vec2 fTexcoord;
@ -33,7 +34,7 @@ void main()
fpos.w = 1.0; fpos.w = 1.0;
gl_Position = fpos; gl_Position = fpos;
fTexcoord = (vPosition + vec2(1.0, 1.0)) * (vec2(256.0, 384.0) / 2.0); fTexcoord = vTexcoord;
} }
)"; )";

View file

@ -139,8 +139,8 @@ u32 DMA9Fill[4];
u16 IPCSync9, IPCSync7; u16 IPCSync9, IPCSync7;
u16 IPCFIFOCnt9, IPCFIFOCnt7; u16 IPCFIFOCnt9, IPCFIFOCnt7;
FIFO<u32>* IPCFIFO9; // FIFO in which the ARM9 writes FIFO<u32, 16> IPCFIFO9; // FIFO in which the ARM9 writes
FIFO<u32>* IPCFIFO7; FIFO<u32, 16> IPCFIFO7;
u16 DivCnt; u16 DivCnt;
u32 DivNumerator[2]; u32 DivNumerator[2];
@ -190,9 +190,6 @@ bool Init()
DMAs[6] = new DMA(1, 2); DMAs[6] = new DMA(1, 2);
DMAs[7] = new DMA(1, 3); DMAs[7] = new DMA(1, 3);
IPCFIFO9 = new FIFO<u32>(16);
IPCFIFO7 = new FIFO<u32>(16);
if (!NDSCart::Init()) return false; if (!NDSCart::Init()) return false;
if (!GBACart::Init()) return false; if (!GBACart::Init()) return false;
if (!GPU::Init()) return false; if (!GPU::Init()) return false;
@ -220,9 +217,6 @@ void DeInit()
for (int i = 0; i < 8; i++) for (int i = 0; i < 8; i++)
delete DMAs[i]; delete DMAs[i];
delete IPCFIFO9;
delete IPCFIFO7;
NDSCart::DeInit(); NDSCart::DeInit();
GBACart::DeInit(); GBACart::DeInit();
GPU::DeInit(); GPU::DeInit();
@ -557,8 +551,8 @@ void Reset()
IPCSync7 = 0; IPCSync7 = 0;
IPCFIFOCnt9 = 0; IPCFIFOCnt9 = 0;
IPCFIFOCnt7 = 0; IPCFIFOCnt7 = 0;
IPCFIFO9->Clear(); IPCFIFO9.Clear();
IPCFIFO7->Clear(); IPCFIFO7.Clear();
DivCnt = 0; DivCnt = 0;
SqrtCnt = 0; SqrtCnt = 0;
@ -736,8 +730,8 @@ bool DoSavestate(Savestate* file)
file->Var16(&IPCSync7); file->Var16(&IPCSync7);
file->Var16(&IPCFIFOCnt9); file->Var16(&IPCFIFOCnt9);
file->Var16(&IPCFIFOCnt7); file->Var16(&IPCFIFOCnt7);
IPCFIFO9->DoSavestate(file); IPCFIFO9.DoSavestate(file);
IPCFIFO7->DoSavestate(file); IPCFIFO7.DoSavestate(file);
file->Var16(&DivCnt); file->Var16(&DivCnt);
file->Var16(&SqrtCnt); file->Var16(&SqrtCnt);
@ -1881,7 +1875,7 @@ u8 ARM9Read8(u32 addr)
case 0x05000000: case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
return *(u8*)&GPU::Palette[addr & 0x7FF]; return GPU::ReadPalette<u8>(addr);
case 0x06000000: case 0x06000000:
switch (addr & 0x00E00000) switch (addr & 0x00E00000)
@ -1895,7 +1889,7 @@ u8 ARM9Read8(u32 addr)
case 0x07000000: case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
return *(u8*)&GPU::OAM[addr & 0x7FF]; return GPU::ReadOAM<u8>(addr);
case 0x08000000: case 0x08000000:
case 0x09000000: case 0x09000000:
@ -1946,7 +1940,7 @@ u16 ARM9Read16(u32 addr)
case 0x05000000: case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
return *(u16*)&GPU::Palette[addr & 0x7FF]; return GPU::ReadPalette<u16>(addr);
case 0x06000000: case 0x06000000:
switch (addr & 0x00E00000) switch (addr & 0x00E00000)
@ -1960,7 +1954,7 @@ u16 ARM9Read16(u32 addr)
case 0x07000000: case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
return *(u16*)&GPU::OAM[addr & 0x7FF]; return GPU::ReadOAM<u16>(addr);
case 0x08000000: case 0x08000000:
case 0x09000000: case 0x09000000:
@ -2011,7 +2005,7 @@ u32 ARM9Read32(u32 addr)
case 0x05000000: case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
return *(u32*)&GPU::Palette[addr & 0x7FF]; return GPU::ReadPalette<u32>(addr);
case 0x06000000: case 0x06000000:
switch (addr & 0x00E00000) switch (addr & 0x00E00000)
@ -2025,7 +2019,7 @@ u32 ARM9Read32(u32 addr)
case 0x07000000: case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return 0;
return *(u32*)&GPU::OAM[addr & 0x7FF]; return GPU::ReadOAM<u32>(addr & 0x7FF);
case 0x08000000: case 0x08000000:
case 0x09000000: case 0x09000000:
@ -2132,7 +2126,7 @@ void ARM9Write16(u32 addr, u16 val)
case 0x05000000: case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
*(u16*)&GPU::Palette[addr & 0x7FF] = val; GPU::WritePalette<u16>(addr, val);
return; return;
case 0x06000000: case 0x06000000:
@ -2150,7 +2144,7 @@ void ARM9Write16(u32 addr, u16 val)
case 0x07000000: case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
*(u16*)&GPU::OAM[addr & 0x7FF] = val; GPU::WriteOAM<u16>(addr, val);
return; return;
case 0x08000000: case 0x08000000:
@ -2207,7 +2201,7 @@ void ARM9Write32(u32 addr, u32 val)
case 0x05000000: case 0x05000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
*(u32*)&GPU::Palette[addr & 0x7FF] = val; GPU::WritePalette(addr, val);
return; return;
case 0x06000000: case 0x06000000:
@ -2225,7 +2219,7 @@ void ARM9Write32(u32 addr, u32 val)
case 0x07000000: case 0x07000000:
if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return; if (!(PowerControl9 & ((addr & 0x400) ? (1<<9) : (1<<1)))) return;
*(u32*)&GPU::OAM[addr & 0x7FF] = val; GPU::WriteOAM<u32>(addr, val);
return; return;
case 0x08000000: case 0x08000000:
@ -2899,10 +2893,10 @@ u16 ARM9IORead16(u32 addr)
case 0x04000184: case 0x04000184:
{ {
u16 val = IPCFIFOCnt9; u16 val = IPCFIFOCnt9;
if (IPCFIFO9->IsEmpty()) val |= 0x0001; if (IPCFIFO9.IsEmpty()) val |= 0x0001;
else if (IPCFIFO9->IsFull()) val |= 0x0002; else if (IPCFIFO9.IsFull()) val |= 0x0002;
if (IPCFIFO7->IsEmpty()) val |= 0x0100; if (IPCFIFO7.IsEmpty()) val |= 0x0100;
else if (IPCFIFO7->IsFull()) val |= 0x0200; else if (IPCFIFO7.IsFull()) val |= 0x0200;
return val; return val;
} }
@ -3057,22 +3051,22 @@ u32 ARM9IORead32(u32 addr)
if (IPCFIFOCnt9 & 0x8000) if (IPCFIFOCnt9 & 0x8000)
{ {
u32 ret; u32 ret;
if (IPCFIFO7->IsEmpty()) if (IPCFIFO7.IsEmpty())
{ {
IPCFIFOCnt9 |= 0x4000; IPCFIFOCnt9 |= 0x4000;
ret = IPCFIFO7->Peek(); ret = IPCFIFO7.Peek();
} }
else else
{ {
ret = IPCFIFO7->Read(); ret = IPCFIFO7.Read();
if (IPCFIFO7->IsEmpty() && (IPCFIFOCnt7 & 0x0004)) if (IPCFIFO7.IsEmpty() && (IPCFIFOCnt7 & 0x0004))
SetIRQ(1, IRQ_IPCSendDone); SetIRQ(1, IRQ_IPCSendDone);
} }
return ret; return ret;
} }
else else
return IPCFIFO7->Peek(); return IPCFIFO7.Peek();
case 0x04100010: case 0x04100010:
if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData(); if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData();
@ -3238,10 +3232,10 @@ void ARM9IOWrite16(u32 addr, u16 val)
case 0x04000184: case 0x04000184:
if (val & 0x0008) if (val & 0x0008)
IPCFIFO9->Clear(); IPCFIFO9.Clear();
if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9->IsEmpty()) if ((val & 0x0004) && (!(IPCFIFOCnt9 & 0x0004)) && IPCFIFO9.IsEmpty())
SetIRQ(0, IRQ_IPCSendDone); SetIRQ(0, IRQ_IPCSendDone);
if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7->IsEmpty())) if ((val & 0x0400) && (!(IPCFIFOCnt9 & 0x0400)) && (!IPCFIFO7.IsEmpty()))
SetIRQ(0, IRQ_IPCRecv); SetIRQ(0, IRQ_IPCRecv);
if (val & 0x4000) if (val & 0x4000)
IPCFIFOCnt9 &= ~0x4000; IPCFIFOCnt9 &= ~0x4000;
@ -3407,12 +3401,12 @@ void ARM9IOWrite32(u32 addr, u32 val)
case 0x04000188: case 0x04000188:
if (IPCFIFOCnt9 & 0x8000) if (IPCFIFOCnt9 & 0x8000)
{ {
if (IPCFIFO9->IsFull()) if (IPCFIFO9.IsFull())
IPCFIFOCnt9 |= 0x4000; IPCFIFOCnt9 |= 0x4000;
else else
{ {
bool wasempty = IPCFIFO9->IsEmpty(); bool wasempty = IPCFIFO9.IsEmpty();
IPCFIFO9->Write(val); IPCFIFO9.Write(val);
if ((IPCFIFOCnt7 & 0x0400) && wasempty) if ((IPCFIFOCnt7 & 0x0400) && wasempty)
SetIRQ(1, IRQ_IPCRecv); SetIRQ(1, IRQ_IPCRecv);
} }
@ -3590,10 +3584,10 @@ u16 ARM7IORead16(u32 addr)
case 0x04000184: case 0x04000184:
{ {
u16 val = IPCFIFOCnt7; u16 val = IPCFIFOCnt7;
if (IPCFIFO7->IsEmpty()) val |= 0x0001; if (IPCFIFO7.IsEmpty()) val |= 0x0001;
else if (IPCFIFO7->IsFull()) val |= 0x0002; else if (IPCFIFO7.IsFull()) val |= 0x0002;
if (IPCFIFO9->IsEmpty()) val |= 0x0100; if (IPCFIFO9.IsEmpty()) val |= 0x0100;
else if (IPCFIFO9->IsFull()) val |= 0x0200; else if (IPCFIFO9.IsFull()) val |= 0x0200;
return val; return val;
} }
@ -3689,22 +3683,22 @@ u32 ARM7IORead32(u32 addr)
if (IPCFIFOCnt7 & 0x8000) if (IPCFIFOCnt7 & 0x8000)
{ {
u32 ret; u32 ret;
if (IPCFIFO9->IsEmpty()) if (IPCFIFO9.IsEmpty())
{ {
IPCFIFOCnt7 |= 0x4000; IPCFIFOCnt7 |= 0x4000;
ret = IPCFIFO9->Peek(); ret = IPCFIFO9.Peek();
} }
else else
{ {
ret = IPCFIFO9->Read(); ret = IPCFIFO9.Read();
if (IPCFIFO9->IsEmpty() && (IPCFIFOCnt9 & 0x0004)) if (IPCFIFO9.IsEmpty() && (IPCFIFOCnt9 & 0x0004))
SetIRQ(0, IRQ_IPCSendDone); SetIRQ(0, IRQ_IPCSendDone);
} }
return ret; return ret;
} }
else else
return IPCFIFO9->Peek(); return IPCFIFO9.Peek();
case 0x04100010: case 0x04100010:
if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData(); if (ExMemCnt[0] & (1<<11)) return NDSCart::ReadROMData();
@ -3841,10 +3835,10 @@ void ARM7IOWrite16(u32 addr, u16 val)
case 0x04000184: case 0x04000184:
if (val & 0x0008) if (val & 0x0008)
IPCFIFO7->Clear(); IPCFIFO7.Clear();
if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7->IsEmpty()) if ((val & 0x0004) && (!(IPCFIFOCnt7 & 0x0004)) && IPCFIFO7.IsEmpty())
SetIRQ(1, IRQ_IPCSendDone); SetIRQ(1, IRQ_IPCSendDone);
if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9->IsEmpty())) if ((val & 0x0400) && (!(IPCFIFOCnt7 & 0x0400)) && (!IPCFIFO9.IsEmpty()))
SetIRQ(1, IRQ_IPCRecv); SetIRQ(1, IRQ_IPCRecv);
if (val & 0x4000) if (val & 0x4000)
IPCFIFOCnt7 &= ~0x4000; IPCFIFOCnt7 &= ~0x4000;
@ -3977,12 +3971,12 @@ void ARM7IOWrite32(u32 addr, u32 val)
case 0x04000188: case 0x04000188:
if (IPCFIFOCnt7 & 0x8000) if (IPCFIFOCnt7 & 0x8000)
{ {
if (IPCFIFO7->IsFull()) if (IPCFIFO7.IsFull())
IPCFIFOCnt7 |= 0x4000; IPCFIFOCnt7 |= 0x4000;
else else
{ {
bool wasempty = IPCFIFO7->IsEmpty(); bool wasempty = IPCFIFO7.IsEmpty();
IPCFIFO7->Write(val); IPCFIFO7.Write(val);
if ((IPCFIFOCnt9 & 0x0400) && wasempty) if ((IPCFIFOCnt9 & 0x0400) && wasempty)
SetIRQ(0, IRQ_IPCRecv); SetIRQ(0, IRQ_IPCRecv);
} }

View file

@ -54,13 +54,12 @@ enum
Event_MAX Event_MAX
}; };
typedef struct struct SchedEvent
{ {
void (*Func)(u32 param); void (*Func)(u32 param);
u64 Timestamp; u64 Timestamp;
u32 Param; u32 Param;
};
} SchedEvent;
enum enum
{ {
@ -121,21 +120,19 @@ enum
IRQ2_DSi_MicExt IRQ2_DSi_MicExt
}; };
typedef struct struct Timer
{ {
u16 Reload; u16 Reload;
u16 Cnt; u16 Cnt;
u32 Counter; u32 Counter;
u32 CycleShift; u32 CycleShift;
};
} Timer; struct MemRegion
typedef struct
{ {
u8* Mem; u8* Mem;
u32 Mask; u32 Mask;
};
} MemRegion;
extern int ConsoleType; extern int ConsoleType;
extern int CurCPU; extern int CurCPU;

View file

@ -22,7 +22,6 @@
#include "DSi.h" #include "DSi.h"
#include "NDSCart.h" #include "NDSCart.h"
#include "ARM.h" #include "ARM.h"
#include "CRC32.h"
#include "DSi_AES.h" #include "DSi_AES.h"
#include "Platform.h" #include "Platform.h"
#include "Config.h" #include "Config.h"
@ -485,7 +484,6 @@ u8 TransferCmd[8];
bool CartInserted; bool CartInserted;
u8* CartROM; u8* CartROM;
u32 CartROMSize; u32 CartROMSize;
u32 CartCRC;
u32 CartID; u32 CartID;
bool CartIsHomebrew; bool CartIsHomebrew;
bool CartIsDSi; bool CartIsDSi;
@ -932,9 +930,6 @@ bool LoadROM(const char* path, const char* sram, bool direct)
fclose(f); fclose(f);
//CartROM = f; //CartROM = f;
CartCRC = CRC32(CartROM, CartROMSize);
printf("ROM CRC32: %08X\n", CartCRC);
ROMListEntry romparams; ROMListEntry romparams;
if (!ReadROMParams(gamecode, &romparams)) if (!ReadROMParams(gamecode, &romparams))
{ {

View file

@ -19,13 +19,12 @@
#ifndef ROMLIST_H #ifndef ROMLIST_H
#define ROMLIST_H #define ROMLIST_H
typedef struct struct ROMListEntry
{ {
u32 GameCode; u32 GameCode;
u32 ROMSize; u32 ROMSize;
u32 SaveMemType; u32 SaveMemType;
};
} ROMListEntry;
ROMListEntry ROMList[] = ROMListEntry ROMList[] =
@ -4006,6 +4005,7 @@ ROMListEntry ROMList[] =
{0x4A555143, 0x02000000, 0x00000002}, {0x4A555143, 0x02000000, 0x00000002},
{0x4A555159, 0x08000000, 0x00000003}, {0x4A555159, 0x08000000, 0x00000003},
{0x4A555241, 0x02000000, 0x00000003}, {0x4A555241, 0x02000000, 0x00000003},
{0x4A555243, 0x10000000, 0x00000006},
{0x4A555259, 0x00800000, 0x00000001}, {0x4A555259, 0x00800000, 0x00000001},
{0x4A555341, 0x04000000, 0x00000003}, {0x4A555341, 0x04000000, 0x00000003},
{0x4A555359, 0x00800000, 0x00000003}, {0x4A555359, 0x00800000, 0x00000003},

View file

@ -55,7 +55,7 @@ u16 RFData1;
u16 RFData2; u16 RFData2;
u32 RFRegs[0x40]; u32 RFRegs[0x40];
typedef struct struct TXSlot
{ {
u16 Addr; u16 Addr;
u16 Length; u16 Length;
@ -63,8 +63,7 @@ typedef struct
u8 CurPhase; u8 CurPhase;
u32 CurPhaseTime; u32 CurPhaseTime;
u32 HalfwordTimeMask; u32 HalfwordTimeMask;
};
} TXSlot;
TXSlot TXSlots[6]; TXSlot TXSlots[6];

View file

@ -15,6 +15,10 @@
#include "../types.h" #include "../types.h"
#include "MathUtil.h" #include "MathUtil.h"
#ifdef __APPLE__
#include <libkern/OSCacheControl.h>
#endif
namespace Arm64Gen namespace Arm64Gen
{ {
namespace namespace
@ -384,7 +388,7 @@ void ARM64XEmitter::FlushIcacheSection(u8* start, u8* end)
if (start == end) if (start == end)
return; return;
#if defined(IOS) #if defined(__APPLE__)
// Header file says this is equivalent to: sys_icache_invalidate(start, end - start); // Header file says this is equivalent to: sys_icache_invalidate(start, end - start);
sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start); sys_cache_control(kCacheFunctionPrepareForExecution, start, end - start);
#else #else

View file

@ -24,7 +24,7 @@
namespace LAN_PCap namespace LAN_PCap
{ {
typedef struct struct AdapterData
{ {
char DeviceName[128]; char DeviceName[128];
char FriendlyName[128]; char FriendlyName[128];
@ -34,8 +34,7 @@ typedef struct
u8 IP_v4[4]; u8 IP_v4[4];
void* Internal; void* Internal;
};
} AdapterData;
extern AdapterData* Adapters; extern AdapterData* Adapters;

View file

@ -48,7 +48,7 @@ const u32 kClientIP = kSubnet | 0x10;
const u8 kServerMAC[6] = {0x00, 0xAB, 0x33, 0x28, 0x99, 0x44}; const u8 kServerMAC[6] = {0x00, 0xAB, 0x33, 0x28, 0x99, 0x44};
FIFO<u32>* RXBuffer = nullptr; FIFO<u32, (0x8000 >> 2)> RXBuffer;
u32 IPv4ID; u32 IPv4ID;
@ -86,16 +86,16 @@ void RXEnqueue(const void* buf, int len)
int alignedlen = (len + 3) & ~3; int alignedlen = (len + 3) & ~3;
int totallen = alignedlen + 4; int totallen = alignedlen + 4;
if (!RXBuffer->CanFit(totallen >> 2)) if (!RXBuffer.CanFit(totallen >> 2))
{ {
printf("slirp: !! NOT ENOUGH SPACE IN RX BUFFER\n"); printf("slirp: !! NOT ENOUGH SPACE IN RX BUFFER\n");
return; return;
} }
u32 header = (alignedlen & 0xFFFF) | (len << 16); u32 header = (alignedlen & 0xFFFF) | (len << 16);
RXBuffer->Write(header); RXBuffer.Write(header);
for (int i = 0; i < alignedlen; i += 4) for (int i = 0; i < alignedlen; i += 4)
RXBuffer->Write(((u32*)buf)[i>>2]); RXBuffer.Write(((u32*)buf)[i>>2]);
} }
ssize_t SlirpCbSendPacket(const void* buf, size_t len, void* opaque) ssize_t SlirpCbSendPacket(const void* buf, size_t len, void* opaque)
@ -202,8 +202,6 @@ bool Init()
//FDListSize = 0; //FDListSize = 0;
//memset(FDList, 0, sizeof(FDList)); //memset(FDList, 0, sizeof(FDList));
RXBuffer = new FIFO<u32>(0x8000 >> 2);
SlirpConfig cfg; SlirpConfig cfg;
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
cfg.version = 1; cfg.version = 1;
@ -228,12 +226,6 @@ void DeInit()
slirp_cleanup(Ctx); slirp_cleanup(Ctx);
Ctx = nullptr; Ctx = nullptr;
} }
if (RXBuffer)
{
delete RXBuffer;
RXBuffer = nullptr;
}
} }
@ -530,13 +522,13 @@ int RecvPacket(u8* data)
slirp_pollfds_poll(Ctx, res<0, SlirpCbGetREvents, nullptr); slirp_pollfds_poll(Ctx, res<0, SlirpCbGetREvents, nullptr);
} }
if (!RXBuffer->IsEmpty()) if (!RXBuffer.IsEmpty())
{ {
u32 header = RXBuffer->Read(); u32 header = RXBuffer.Read();
u32 len = header & 0xFFFF; u32 len = header & 0xFFFF;
for (int i = 0; i < len; i += 4) for (int i = 0; i < len; i += 4)
((u32*)data)[i>>2] = RXBuffer->Read(); ((u32*)data)[i>>2] = RXBuffer.Read();
ret = header >> 16; ret = header >> 16;
} }

View file

@ -72,6 +72,8 @@ char MicWavPath[1024];
char LastROMFolder[1024]; char LastROMFolder[1024];
char RecentROMList[10][1024];
int EnableCheats; int EnableCheats;
bool EnableJIT; bool EnableJIT;
@ -166,6 +168,17 @@ ConfigEntry PlatformConfigFile[] =
{"LastROMFolder", 1, LastROMFolder, 0, "", 1023}, {"LastROMFolder", 1, LastROMFolder, 0, "", 1023},
{"RecentROM_0", 1, RecentROMList[0], 0, "", 1023},
{"RecentROM_1", 1, RecentROMList[1], 0, "", 1023},
{"RecentROM_2", 1, RecentROMList[2], 0, "", 1023},
{"RecentROM_3", 1, RecentROMList[3], 0, "", 1023},
{"RecentROM_4", 1, RecentROMList[4], 0, "", 1023},
{"RecentROM_5", 1, RecentROMList[5], 0, "", 1023},
{"RecentROM_6", 1, RecentROMList[6], 0, "", 1023},
{"RecentROM_7", 1, RecentROMList[7], 0, "", 1023},
{"RecentROM_8", 1, RecentROMList[8], 0, "", 1023},
{"RecentROM_9", 1, RecentROMList[9], 0, "", 1023},
{"EnableCheats", 0, &EnableCheats, 0, NULL, 0}, {"EnableCheats", 0, &EnableCheats, 0, NULL, 0},
{"", -1, NULL, 0, NULL, 0} {"", -1, NULL, 0, NULL, 0}

View file

@ -86,6 +86,8 @@ extern char MicWavPath[1024];
extern char LastROMFolder[1024]; extern char LastROMFolder[1024];
extern char RecentROMList[10][1024];
extern int EnableCheats; extern int EnableCheats;
} }

View file

@ -84,6 +84,14 @@ VideoSettingsDialog::VideoSettingsDialog(QWidget* parent) : QDialog(parent), ui(
ui->cbxGLResolution->setEnabled(true); ui->cbxGLResolution->setEnabled(true);
ui->cbBetterPolygons->setEnabled(true); ui->cbBetterPolygons->setEnabled(true);
} }
// sorry
ui->cbVSync->hide();
ui->cbVSync->setEnabled(false);
ui->sbVSyncInterval->hide();
ui->sbVSyncInterval->setEnabled(false);
ui->label_2->hide();
ui->groupBox->layout()->addItem(new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding));
} }
VideoSettingsDialog::~VideoSettingsDialog() VideoSettingsDialog::~VideoSettingsDialog()

View file

@ -875,22 +875,26 @@ void ScreenPanelGL::initializeGL()
screenShader->setUniformValue("ScreenTex", (GLint)0); screenShader->setUniformValue("ScreenTex", (GLint)0);
screenShader->release(); screenShader->release();
// to prevent bleeding between both parts of the screen
// with bilinear filtering enabled
const int paddedHeight = 192*2+2;
const float padPixels = 1.f / paddedHeight;
float vertices[] = const float vertices[] =
{ {
0, 0, 0, 0, 0.f, 0.f, 0.f, 0.f,
0, 192, 0, 0.5, 0.f, 192.f, 0.f, 0.5f - padPixels,
256, 192, 1, 0.5, 256.f, 192.f, 1.f, 0.5f - padPixels,
0, 0, 0, 0, 0.f, 0.f, 0.f, 0.f,
256, 192, 1, 0.5, 256.f, 192.f, 1.f, 0.5f - padPixels,
256, 0, 1, 0, 256.f, 0.f, 1.f, 0.f,
0, 0, 0, 0.5, 0.f, 0.f, 0.f, 0.5f + padPixels,
0, 192, 0, 1, 0.f, 192.f, 0.f, 1.f,
256, 192, 1, 1, 256.f, 192.f, 1.f, 1.f,
0, 0, 0, 0.5, 0.f, 0.f, 0.f, 0.5f + padPixels,
256, 192, 1, 1, 256.f, 192.f, 1.f, 1.f,
256, 0, 1, 0.5 256.f, 0.f, 1.f, 0.5f + padPixels
}; };
glGenBuffers(1, &screenVertexBuffer); glGenBuffers(1, &screenVertexBuffer);
@ -911,7 +915,11 @@ void ScreenPanelGL::initializeGL()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, 192*2, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 256, paddedHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
// fill the padding
u8 zeroData[256*4*4];
memset(zeroData, 0, sizeof(zeroData));
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 2, GL_RGBA, GL_UNSIGNED_BYTE, zeroData);
OSD::Init(this); OSD::Init(this);
} }
@ -949,7 +957,7 @@ void ScreenPanelGL::paintGL()
{ {
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA, glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256, 192, GL_RGBA,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]); GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][0]);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192, 256, 192, GL_RGBA, glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 192+2, 256, 192, GL_RGBA,
GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]); GL_UNSIGNED_BYTE, GPU::Framebuffer[frontbuf][1]);
} }
} }
@ -1021,6 +1029,14 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
actOpenROM = menu->addAction("Open ROM..."); actOpenROM = menu->addAction("Open ROM...");
connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile); connect(actOpenROM, &QAction::triggered, this, &MainWindow::onOpenFile);
recentMenu = menu->addMenu("Open Recent");
for(int i = 0; i < 10; ++i)
{
if(strlen(Config::RecentROMList[i]) > 0)
recentFileList.push_back(Config::RecentROMList[i]);
}
updateRecentFilesMenu();
//actBootFirmware = menu->addAction("Launch DS menu"); //actBootFirmware = menu->addAction("Launch DS menu");
actBootFirmware = menu->addAction("Boot firmware"); actBootFirmware = menu->addAction("Boot firmware");
connect(actBootFirmware, &QAction::triggered, this, &MainWindow::onBootFirmware); connect(actBootFirmware, &QAction::triggered, this, &MainWindow::onBootFirmware);
@ -1333,7 +1349,7 @@ void MainWindow::keyPressEvent(QKeyEvent* event)
if (event->isAutoRepeat()) return; if (event->isAutoRepeat()) return;
// TODO!! REMOVE ME IN RELEASE BUILDS!! // TODO!! REMOVE ME IN RELEASE BUILDS!!
if (event->key() == Qt::Key_F11) NDS::debug(0); //if (event->key() == Qt::Key_F11) NDS::debug(0);
Input::KeyPress(event); Input::KeyPress(event);
} }
@ -1457,7 +1473,20 @@ void MainWindow::onOpenFile()
"Open ROM", "Open ROM",
Config::LastROMFolder, Config::LastROMFolder,
"DS ROMs (*.nds *.dsi *.srl *.zip *.7z);;GBA ROMs (*.gba *.zip *.7z);;Other Compressed ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *tar.bz2);;Any file (*.*)"); "DS ROMs (*.nds *.dsi *.srl *.zip *.7z);;GBA ROMs (*.gba *.zip *.7z);;Other Compressed ROMs (*.zip *.7z *.rar *.tar *.tar.gz *.tar.xz *tar.bz2);;Any file (*.*)");
if (filename.isEmpty())
{
emuThread->emuUnpause();
return;
}
void MainWindow::loadROM(QString filename)
{
recentFileList.removeAll(filename);
recentFileList.prepend(filename);
updateRecentFilesMenu();
static const QSet<QString> compressedExts = {"zip", "7z", "rar", "tar", "tar.gz", "tar.xz", "tar.bz2"}; static const QSet<QString> compressedExts = {"zip", "7z", "rar", "tar", "tar.gz", "tar.xz", "tar.bz2"};
if (compressedExts.contains(QFileInfo(filename).completeSuffix())) if (compressedExts.contains(QFileInfo(filename).completeSuffix()))
{ {
@ -1502,13 +1531,7 @@ void MainWindow::onOpenFile()
} }
} }
if (filename.isEmpty())
{
emuThread->emuUnpause();
return;
}
// TODO: validate the input file!! // TODO: validate the input file!!
// * check that it is a proper ROM // * check that it is a proper ROM
// * ensure the binary offsets are sane // * ensure the binary offsets are sane
@ -1554,6 +1577,60 @@ void MainWindow::onOpenFile()
} }
} }
void MainWindow::onOpenFile()
{
emuThread->emuPause();
QString filename = QFileDialog::getOpenFileName(this,
"Open ROM",
Config::LastROMFolder,
"DS ROMs (*.nds *.dsi *.srl);;GBA ROMs (*.gba);;Any file (*.*)");
if (filename.isEmpty())
{
emuThread->emuUnpause();
return;
}
loadROM(filename);
}
void MainWindow::onClearRecentFiles()
{
recentFileList.clear();
memset(Config::RecentROMList, 0, 10 * 1024);
updateRecentFilesMenu();
}
void MainWindow::updateRecentFilesMenu()
{
recentMenu->clear();
for(int i = 0; i < recentFileList.size(); ++i)
{
QAction *actRecentFile_i = recentMenu->addAction(QString("%1. %2").arg(i+1).arg(recentFileList.at(i)));
actRecentFile_i->setData(recentFileList.at(i));
connect(actRecentFile_i, &QAction::triggered, this, &MainWindow::onClickRecentFile);
if(i < 10)
strncpy(Config::RecentROMList[i], recentFileList.at(i).toStdString().c_str(), 1024);
}
QAction *actClearRecentList = recentMenu->addAction("Clear");
connect(actClearRecentList, &QAction::triggered, this, &MainWindow::onClearRecentFiles);
if(recentFileList.empty())
actClearRecentList->setEnabled(false);
Config::Save();
}
void MainWindow::onClickRecentFile()
{
emuThread->emuPause();
QAction *act = (QAction *)sender();
loadROM(act->data().toString());
}
void MainWindow::onBootFirmware() void MainWindow::onBootFirmware()
{ {
// TODO: check the whole GBA cart shito // TODO: check the whole GBA cart shito

View file

@ -191,6 +191,8 @@ signals:
private slots: private slots:
void onOpenFile(); void onOpenFile();
void onClickRecentFile();
void onClearRecentFiles();
void onBootFirmware(); void onBootFirmware();
void onSaveState(); void onSaveState();
void onLoadState(); void onLoadState();
@ -236,6 +238,11 @@ private slots:
void onFullscreenToggled(); void onFullscreenToggled();
private: private:
QList<QString> recentFileList;
QMenu *recentMenu;
void updateRecentFilesMenu();
void loadROM(QString filename);
void createScreenPanel(); void createScreenPanel();
QString loadErrorStr(int error); QString loadErrorStr(int error);

View file

@ -19,7 +19,7 @@
#ifndef VERSION_H #ifndef VERSION_H
#define VERSION_H #define VERSION_H
#define MELONDS_VERSION "0.9" #define MELONDS_VERSION "0.9.1"
#define MELONDS_URL "http://melonds.kuribo64.net/" #define MELONDS_URL "http://melonds.kuribo64.net/"