diff options
Diffstat (limited to 'src/DSi_SPI_TSC.cpp')
| -rw-r--r-- | src/DSi_SPI_TSC.cpp | 231 | 
1 files changed, 231 insertions, 0 deletions
diff --git a/src/DSi_SPI_TSC.cpp b/src/DSi_SPI_TSC.cpp new file mode 100644 index 0000000..507005b --- /dev/null +++ b/src/DSi_SPI_TSC.cpp @@ -0,0 +1,231 @@ +/* +    Copyright 2016-2019 Arisotura + +    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" +#include "SPI.h" +#include "DSi_SPI_TSC.h" + + +namespace DSi_SPI_TSC +{ + +u32 DataPos; +u8 Index; +u8 Bank; +u8 Data; + +u8 Bank3Regs[0x80]; +u8 TSCMode; + +u16 TouchX, TouchY; + + +bool Init() +{ +    return true; +} + +void DeInit() +{ +} + +void Reset() +{ +    DataPos = 0; + +    Bank = 0; +    Index = 0; +    Data = 0; + +    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 +} + +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) +{ +    if (TSCMode == 0x00) +    { +        if (y == 0xFFF) NDS::KeyInput |=  (1 << (16+6)); +        else            NDS::KeyInput &= ~(1 << (16+6)); +        return SPI_TSC::SetTouchCoords(x, y); +    } + +    TouchX = x; +    TouchY = y; + +    u8 oldpress = Bank3Regs[0x0E] & 0x01; + +    if (y == 0xFFF) +    { +        // released + +        // TODO: GBAtek says it can also be 1000 or 3000?? +        TouchX = 0x7000; +        TouchY = 0x7000; + +        Bank3Regs[0x09] = 0x40; +        //Bank3Regs[0x09] &= ~0x80; +        Bank3Regs[0x0E] |= 0x01; +    } +    else +    { +        // pressed + +        TouchX <<= 4; +        TouchY <<= 4; + +        Bank3Regs[0x09] = 0x80; +        //Bank3Regs[0x09] |= 0x80; +        Bank3Regs[0x0E] &= ~0x01; +    } + +    if (oldpress ^ (Bank3Regs[0x0E] & 0x01)) +    { +        TouchX |= 0x8000; +        TouchY |= 0x8000; +    } +} + +void MicInputFrame(s16* data, int samples) +{ +    if (TSCMode == 0x00) return SPI_TSC::MicInputFrame(data, samples); + +    // otherwise we don't handle mic input +    // TODO: handle it where it needs to be +} + +u8 Read() +{ +    if (TSCMode == 0x00) return SPI_TSC::Read(); + +    return Data; +} + +void Write(u8 val, u32 hold) +{ +    if (TSCMode == 0x00) return SPI_TSC::Write(val, hold); + +#define READWRITE(var) { if (Index & 0x01) Data = var; else var = val; } + +    if (DataPos == 0) +    { +        Index = val; +    } +    else +    { +        u8 id = Index >> 1; + +        if (id == 0) +        { +            READWRITE(Bank); +        } +        else if (Bank == 0x03) +        { +            if (Index & 0x01) Data = Bank3Regs[id]; +            else +            { +                if (id == 0x0D || id == 0x0E) +                    Bank3Regs[id] = (Bank3Regs[id] & 0x03) | (val & 0xFC); +            } +        } +        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; +            } +        } +        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; +                    } +                } +            } +        } +        else +        { +            printf("DSi_SPI_TSC: unknown IO, bank=%02X, index=%02X (%02X %s)\n", Bank, Index, Index>>1, (Index&1)?"read":"write"); +        } + +        Index += (1<<1); // increment index +    } + +    if (hold) DataPos++; +    else      DataPos = 0; +} + +}  |