melonDS/src/DSi_SPI_TSC.cpp

232 lines
4.8 KiB
C++
Raw Normal View History

2019-08-04 09:44:36 +00:00
/*
Copyright 2016-2021 Arisotura
2019-08-04 09:44:36 +00:00
This file is part of melonDS.
melonDS is free software: you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.
melonDS is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with melonDS. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <string.h>
#include "DSi.h"
2019-08-04 12:34:33 +00:00
#include "SPI.h"
2019-08-04 09:44:36 +00:00
#include "DSi_SPI_TSC.h"
namespace DSi_SPI_TSC
{
u32 DataPos;
u8 Index;
2019-08-04 12:34:33 +00:00
u8 Bank;
2019-08-04 09:44:36 +00:00
u8 Data;
2019-08-04 12:34:33 +00:00
u8 Bank3Regs[0x80];
u8 TSCMode;
2019-08-04 09:44:36 +00:00
u16 TouchX, TouchY;
bool Init()
{
return true;
}
void DeInit()
{
}
void Reset()
{
DataPos = 0;
2019-08-04 12:34:33 +00:00
Bank = 0;
2019-08-04 09:44:36 +00:00
Index = 0;
Data = 0;
2019-08-04 12:34:33 +00:00
memset(Bank3Regs, 0, 0x80);
Bank3Regs[0x02] = 0x18;
Bank3Regs[0x03] = 0x87;
Bank3Regs[0x04] = 0x22;
Bank3Regs[0x05] = 0x04;
Bank3Regs[0x06] = 0x20;
Bank3Regs[0x09] = 0x40;
Bank3Regs[0x0E] = 0xAD;
Bank3Regs[0x0F] = 0xA0;
Bank3Regs[0x10] = 0x88;
Bank3Regs[0x11] = 0x81;
TSCMode = 0x01; // DSi mode
2019-08-04 09:44:36 +00:00
}
void DoSavestate(Savestate* file)
{
/*file->Section("SPTi");
file->Var32(&DataPos);
file->Var8(&ControlByte);
file->Var8(&Data);
file->Var16(&ConvResult);*/
// TODO!!
}
void SetTouchCoords(u16 x, u16 y)
{
2019-08-04 12:34:33 +00:00
if (TSCMode == 0x00)
{
if (y == 0xFFF) NDS::KeyInput |= (1 << (16+6));
else NDS::KeyInput &= ~(1 << (16+6));
return SPI_TSC::SetTouchCoords(x, y);
}
2019-08-04 09:44:36 +00:00
TouchX = x;
TouchY = y;
2019-08-04 12:34:33 +00:00
u8 oldpress = Bank3Regs[0x0E] & 0x01;
if (y == 0xFFF)
{
// released
// TODO: GBAtek says it can also be 1000 or 3000??
TouchX = 0x7000;
TouchY = 0x7000;
2019-08-04 09:44:36 +00:00
2019-08-04 12:34:33 +00:00
Bank3Regs[0x09] = 0x40;
//Bank3Regs[0x09] &= ~0x80;
Bank3Regs[0x0E] |= 0x01;
}
else
{
// pressed
2019-08-04 09:44:36 +00:00
TouchX <<= 4;
TouchY <<= 4;
2019-08-04 12:34:33 +00:00
Bank3Regs[0x09] = 0x80;
//Bank3Regs[0x09] |= 0x80;
Bank3Regs[0x0E] &= ~0x01;
}
2019-08-04 12:34:33 +00:00
if (oldpress ^ (Bank3Regs[0x0E] & 0x01))
{
TouchX |= 0x8000;
TouchY |= 0x8000;
}
2019-08-04 09:44:36 +00:00
}
void MicInputFrame(s16* data, int samples)
{
2019-08-04 12:34:33 +00:00
if (TSCMode == 0x00) return SPI_TSC::MicInputFrame(data, samples);
// otherwise we don't handle mic input
// TODO: handle it where it needs to be
2019-08-04 09:44:36 +00:00
}
u8 Read()
{
2019-08-04 12:34:33 +00:00
if (TSCMode == 0x00) return SPI_TSC::Read();
2019-08-04 09:44:36 +00:00
return Data;
}
void Write(u8 val, u32 hold)
{
2019-08-04 12:34:33 +00:00
if (TSCMode == 0x00) return SPI_TSC::Write(val, hold);
2019-08-04 09:44:36 +00:00
#define READWRITE(var) { if (Index & 0x01) Data = var; else var = val; }
2019-08-04 09:44:36 +00:00
if (DataPos == 0)
{
Index = val;
}
else
{
u8 id = Index >> 1;
if (id == 0)
2019-08-04 09:44:36 +00:00
{
2019-08-04 12:34:33 +00:00
READWRITE(Bank);
2019-08-04 09:44:36 +00:00
}
2019-08-04 12:34:33 +00:00
else if (Bank == 0x03)
{
2019-08-04 12:34:33 +00:00
if (Index & 0x01) Data = Bank3Regs[id];
else
{
if (id == 0x0D || id == 0x0E)
2019-08-04 12:34:33 +00:00
Bank3Regs[id] = (Bank3Regs[id] & 0x03) | (val & 0xFC);
}
}
2019-08-04 12:34:33 +00:00
else if ((Bank == 0xFC) && (Index & 0x01))
{
if (id < 0x0B)
{
// X coordinates
if (id & 0x01) Data = TouchX >> 8;
else Data = TouchX & 0xFF;
TouchX &= 0x7FFF;
}
else if (id < 0x15)
{
// Y coordinates
if (id & 0x01) Data = TouchY >> 8;
else Data = TouchY & 0xFF;
TouchY &= 0x7FFF; // checkme
}
else
{
// whatever (TODO)
Data = 0;
}
}
2019-08-04 12:34:33 +00:00
else if (Bank == 0xFF)
{
if (id == 0x05)
{
// TSC mode register
// 01: normal (DSi) mode
// 00: compatibility (DS) mode
if (Index & 0x01) Data = TSCMode;
else
{
TSCMode = val;
if (TSCMode == 0x00)
{
printf("DSi_SPI_TSC: DS-compatibility mode\n");
DataPos = 0;
NDS::KeyInput |= (1 << (16+6));
return;
}
}
}
}
2019-08-04 09:44:36 +00:00
else
{
2019-08-04 12:34:33 +00:00
printf("DSi_SPI_TSC: unknown IO, bank=%02X, index=%02X (%02X %s)\n", Bank, Index, Index>>1, (Index&1)?"read":"write");
2019-08-04 09:44:36 +00:00
}
Index += (1<<1); // increment index
}
if (hold) DataPos++;
else DataPos = 0;
}
}