- fix display FIFO;
- more accurate RTC implementation (is working more correct with Homebrew now);
This commit is contained in:
mtabachenko 2009-01-20 21:31:32 +00:00
parent 36132978f5
commit a0c3c02ea9
4 changed files with 239 additions and 195 deletions

View File

@ -2,7 +2,8 @@
yopyop156@ifrance.com yopyop156@ifrance.com
yopyop156.ifrance.com yopyop156.ifrance.com
Copyright (C) 2007 shash Copyright 2007 shash
Copyright 2007-2009 DeSmuME team
This file is part of DeSmuME This file is part of DeSmuME
@ -18,7 +19,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include "FIFO.h" #include "FIFO.h"
@ -191,6 +192,7 @@ void DISP_FIFOsend(u32 val)
u32 DISP_FIFOrecv() u32 DISP_FIFOrecv()
{ {
if (disp_fifo.tail == disp_fifo.head) return (0); // FIFO is empty
u32 val = disp_fifo.buf[disp_fifo.head]; u32 val = disp_fifo.buf[disp_fifo.head];
disp_fifo.head++; disp_fifo.head++;
if (disp_fifo.head > 0x5FFF) if (disp_fifo.head > 0x5FFF)

View File

@ -3181,7 +3181,10 @@ void GPU_ligne(NDS_Screen * screen, u16 l)
} }
if (gpu->core == GPU_MAIN) if (gpu->core == GPU_MAIN)
{
GPU_ligne_DispCapture(l); GPU_ligne_DispCapture(l);
if (l == 192) { disp_fifo.head = disp_fifo.tail = 0; }
}
GPU_ligne_MasterBrightness(screen, l); GPU_ligne_MasterBrightness(screen, l);
} }

View File

@ -2,7 +2,8 @@
yopyop156@ifrance.com yopyop156@ifrance.com
yopyop156.ifrance.com yopyop156.ifrance.com
Copyright (C) 2006-2008 DeSmuME team Copyright 2008 CrazyMax
Copyright 2008-2009 DeSmuME team
This file is part of DeSmuME This file is part of DeSmuME
@ -18,9 +19,11 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
// TODO: interrupt handler
#include "rtc.h" #include "rtc.h"
#include "common.h" #include "common.h"
#include "debug.h" #include "debug.h"
@ -28,233 +31,268 @@
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
const u8 valRTC[100]= { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99 };
const u8 cmdSizes[8] = {1, 7, 3, 1, 3, 1, 1};
typedef struct typedef struct
{ {
u16 reg; // RTC registers
u8 regStatus1; u8 regStatus1;
u8 regStatus2; u8 regStatus2;
u8 regAdjustment;
u8 regFree;
// BUS
u8 _prevSCK;
u8 _prevCS;
u8 _prevSIO;
u8 _SCK;
u8 _CS;
u8 _SIO;
u8 _DD;
u16 _REG;
// command & data
u8 cmd; u8 cmd;
u8 cmdStat;
u8 dataWrite; u8 bitsCount;
u8 bitPosWrite; u8 data[8];
u32 dataRead1;
u32 dataRead2;
u8 bitPosRead;
u8 bitSizeRead;
u8 cmdSize;
u8 stat; // 0 - write, 1 - read
} _RTC; } _RTC;
_RTC rtc; _RTC rtc;
void rtcPost(u8 data); u8 cmdBitsSize[8] = {8, 8, 56, 24, 0, 24, 8, 8};
void rtcInit() #define toBCD(x) ((x / 10) << 4) | (x % 10);
void rtcRecv()
{ {
memset(&rtc, 0, sizeof(_RTC)); //INFO("RTC Read command 0x%02X\n", rtc.cmd);
} memset(rtc.data, 0, sizeof(rtc.data));
//====================================================== RTC write
INLINE void rtcPost(u8 data)
{
if (rtc.cmdSize == 0)
{
if (rtc.bitPosRead != rtc.bitSizeRead) return;
rtc.bitPosRead = 0;
if ((data & 0x0F) == 0x06)
rtc.cmd = reverseBitsInByte(data);
else
if ((data & 0xF0) == 0x60)
rtc.cmd = data;
else
{
//INFO("RTC ERROR: command not supported\n");
return;
}
rtc.stat = (rtc.cmd & 0x01);
rtc.cmd = (rtc.cmd & 0x0E)>>1;
//INFO("+++++RTC: execute command 0x%02X (%s)\n", rtc.cmd, rtc.stat?"read":"write");
if (!rtc.stat)
{
rtc.cmdSize = cmdSizes[rtc.cmd];
return;
}
else
rtc.cmdSize = 0;
if (rtc.stat)
{
rtc.bitSizeRead = 8;
rtc.dataRead1 = 0;
rtc.dataRead2 = 0;
//INFO("RTC: read %X\n", rtc.cmd);
switch (rtc.cmd)
{
case 0: // status register 1
//INFO("RTC: read status 1 (%X) %s\n", rtc.regStatus1, rtc.revBits?"rev":"fwd");
rtc.dataRead1 = rtc.regStatus1;
rtc.regStatus1 &= 0x0F;
break;
case 1: // status register 2
//INFO("RTC: read status 2 %s\n", rtc.revBits?"rev":"fwd");
rtc.dataRead1 = rtc.regStatus2;
break;
case 2: // date & time
{
time_t tm;
time(&tm);
struct tm *tm_local= localtime(&tm);
u8 hour = tm_local->tm_hour, noon=0;
if (hour>11)
{
hour-=12;
noon=1;
}
rtc.dataRead2 = ( ((valRTC[hour]) << 0)
//| (noon << 7)
| (valRTC[tm_local->tm_min] << 8)
| (valRTC[tm_local->tm_sec] << 16));
rtc.dataRead1 = ( (valRTC[tm_local->tm_year-100] << 0)
| (valRTC[tm_local->tm_mon+1] << 8)
| (valRTC[tm_local->tm_mday] << 16)
| (valRTC[tm_local->tm_wday] << 24));
rtc.bitSizeRead = 7 << 3;
break;
}
case 3: // time
{
//INFO("RTC: read time\n");
time_t tm;
time(&tm);
struct tm *tm_local= localtime(&tm);
u8 hour = tm_local->tm_hour, noon=0;
if (hour>11)
{
hour-=12;
noon=1;
}
rtc.dataRead1 = ( ((valRTC[hour]) << 0)
//| (noon << 6)
| (valRTC[tm_local->tm_min] << 8)
| (valRTC[tm_local->tm_sec] << 16));
rtc.bitSizeRead = 3 << 3;
break;
}
case 4: // freq/alarm 1
//INFO("RTC: read freq");
break;
case 5: // alarm 2
//INFO("RTC: read alarm 2\n");
break;
case 6: // clock adjust
//INFO("RTC: read clock adjust\n");
break;
case 7: // free register
//INFO("RTC: read free register\n");
break;
default:
rtc.bitSizeRead = 0;
break;
}
}
return;
}
rtc.cmdSize--;
//INFO("RTC: write %X val=%X\n", rtc.cmd, data);
switch (rtc.cmd) switch (rtc.cmd)
{ {
case 0: // status1 case 0: // status register 1
//INFO("RTC: write status 1 (%X)\n", data); //INFO("RTC: read regstatus1 (0x%02X)\n", rtc.regStatus1);
rtc.regStatus1 = data; rtc.data[0] = rtc.regStatus1;
if (rtc.regStatus1 & 0x10) rtc.regStatus1 &= 0x7F;
{
//INFO("IRQ7\n");
NDS_makeARM7Int(7);
}
break; break;
case 1: // status register 2 case 1: // status register 2
rtc.regStatus2 = data; //INFO("RTC: read regstatus2 (0x%02X)\n", rtc.regStatus1);
//INFO("RTC: write status 2 (%X)\n", data); rtc.data[0] = rtc.regStatus2;
break; break;
case 2: // date & time case 2: // date & time
//INFO("RTC: write date & time (%X)\n", data); {
break; //INFO("RTC: read date & time\n");
time_t tm;
time(&tm);
struct tm *tm_local= localtime(&tm);
tm_local->tm_year %= 100;
tm_local->tm_mon++;
rtc.data[0] = toBCD(tm_local->tm_year);
rtc.data[1] = toBCD(tm_local->tm_mon);
rtc.data[2] = toBCD(tm_local->tm_mday);
rtc.data[3] = (tm_local->tm_wday + 6) & 7;
if (!(rtc.regStatus1 & 0x02))
{
rtc.data[4] = (tm_local->tm_hour < 12)?0x00:0x40;
tm_local->tm_hour %= 12;
}
rtc.data[4] |= toBCD(tm_local->tm_hour);
rtc.data[5] = toBCD(tm_local->tm_min);
rtc.data[6] = toBCD(tm_local->tm_sec);
break;
}
case 3: // time case 3: // time
//INFO("RTC: write time (%X)\n", data); {
break; //INFO("RTC: read time\n");
time_t tm;
time(&tm);
struct tm *tm_local= localtime(&tm);
if (!(rtc.regStatus1 & 0x02))
{
rtc.data[4] = (tm_local->tm_hour < 12)?0x00:0x40;
tm_local->tm_hour %= 12;
}
rtc.data[0] |= toBCD(tm_local->tm_hour);
rtc.data[1] = toBCD(tm_local->tm_min);
rtc.data[2] = toBCD(tm_local->tm_sec);
break;
}
case 4: // freq/alarm 1 case 4: // freq/alarm 1
//INFO("RTC: write freq (%X)", data); /*if (cmdBitsSize[0x04] == 8)
INFO("RTC: read INT1 freq\n");
else
INFO("RTC: read INT1 alarm1\n");*/
//NDS_makeARM7Int(7);
break; break;
case 5: // alarm 2 case 5: // alarm 2
//INFO("RTC: write alarm 2 (%X)\n", data); //INFO("RTC: read alarm 2\n");
break; break;
case 6: // clock adjust case 6: // clock adjust
//INFO("RTC: write clock adjust (%X)\n", data); //INFO("RTC: read clock adjust\n");
rtc.data[0] = rtc.regAdjustment;
break; break;
case 7: // free register case 7: // free register
//INFO("RTC: write free register (%X)\n", data); //INFO("RTC: read free register\n");
rtc.data[0] = rtc.regFree;
break; break;
} }
} }
u8 rtcRead() void rtcSend()
{ {
u8 val; //INFO("RTC write 0x%02X\n", rtc.cmd);
switch (rtc.cmd)
{
case 0: // status register 1
//INFO("RTC: write regstatus1 0x%02X\n", rtc.data[0]);
rtc.regStatus1 &= 0xF1;
rtc.regStatus1 |= (rtc.data[0] | 0x0E);
break;
case 1: // status register 2
//INFO("RTC: write regstatus2 0x%02X\n", rtc.data[0]);
rtc.regStatus2 = rtc.data[0];
break;
case 2: // date & time
//INFO("RTC: write date & time\n");
break;
case 3: // time
//INFO("RTC: write time\n");
break;
case 4: // freq/alarm 1
/*if (cmdBitsSize[0x04] == 8)
INFO("RTC: write INT1 freq 0x%02X\n", rtc.data[0]);
else
INFO("RTC: write INT1 alarm1 0x%02X\n", rtc.data[0]);*/
break;
case 5: // alarm 2
//INFO("RTC: write alarm 2\n");
break;
case 6: // clock adjust
//INFO("RTC: write clock adjust\n");
rtc.regAdjustment = rtc.data[0];
break;
case 7: // free register
//INFO("RTC: write free register\n");
rtc.regFree = rtc.data[0];
break;
}
}
if (rtc.bitPosRead == rtc.bitSizeRead) void rtcInit()
rtcPost(rtc.cmd); {
memset(&rtc, 0, sizeof(_RTC));
rtc.regStatus1 |= 0x02;
}
if (rtc.bitPosRead > 31) u8 rtcRead()
val = ((rtc.dataRead2 >> rtc.bitPosRead) & 0x01); {
else //INFO("MMU Read RTC 0x%02X (%03i)\n", rtc._REG, rtc.bitsCount);
val = ((rtc.dataRead1 >> rtc.bitPosRead) & 0x01); return (rtc._REG);
rtc.bitPosRead++;
return val;
} }
void rtcWrite(u16 val) void rtcWrite(u16 val)
{ {
rtc.reg = val; //INFO("MMU Write RTC 0x%02X (%03i)\n", val, rtc.bitsCount);
rtc._DD = (val & 0x10) >> 4;
rtc._SIO = rtc._DD?(val & 0x01):rtc._prevSIO;
rtc._SCK = (val & 0x20)?((val & 0x02) >> 1):rtc._prevSCK;
rtc._CS = (val & 0x40)?((val & 0x04) >> 2):rtc._prevCS;
if (!(rtc.reg & 0x02)) switch (rtc.cmdStat)
{ {
rtc.dataWrite |= ((val & 0x01) << rtc.bitPosWrite); case 0:
if ( (!rtc._prevCS) && (rtc._prevSCK) && (rtc._CS) && (rtc._SCK) )
rtc.bitPosWrite++; {
if (rtc.bitPosWrite == 8) rtc.cmdStat = 1;
{ rtc.bitsCount = 0;
//INFO("RTC: write\n"); rtc.cmd = 0;
rtcPost(rtc.dataWrite); }
rtc.bitPosWrite = 0; break;
rtc.dataWrite = 0;
} case 1:
if (!rtc._CS)
{
rtc.cmdStat = 0;
break;
}
if (rtc._SCK && rtc._DD) break;
if (!rtc._SCK && !rtc._DD) break;
rtc.cmd |= (rtc._SIO << rtc.bitsCount );
rtc.bitsCount ++;
if (rtc.bitsCount == 7)
{
if ( (rtc.cmd & 0x06) != 0x06 )
{
rtc.cmdStat = 0;
//INFO("RTC uknown command 0x02%X\n", rtc.cmd);
break;
}
rtc.cmdStat = 2;
rtc.cmd >>= 4;
rtc.cmd &= 0x07;
//INFO("RTC command 0x%02X\n", rtc.cmd);
}
break;
case 2:
if (!rtc._CS)
{
rtc.cmdStat = 0;
break;
}
if((rtc._prevSCK) && (!rtc._SCK))
{
rtc.bitsCount = 0;
if (rtc.cmd == 0x04)
{
if (rtc.regStatus2 & 0x0F == 0x04)
cmdBitsSize[rtc.cmd] = 24;
else
cmdBitsSize[rtc.cmd] = 8;
}
if (rtc._SIO)
{
rtc.cmdStat = 4;
rtcRecv();
}
else
{
rtc.cmdStat = 3;
}
}
break;
case 3: // write:
if( (rtc._prevSCK) && (!rtc._SCK) )
{
if(rtc._SIO) rtc.data[rtc.bitsCount >> 3] |= (1 << (rtc.bitsCount & 0x07));
rtc.bitsCount++;
if (rtc.bitsCount == cmdBitsSize[rtc.cmd])
{
rtcSend();
rtc.cmdStat = 0;
}
}
break;
case 4: // read:
if( (rtc._prevSCK) && (!rtc._SCK) )
{
rtc._REG = val;
if(rtc.data[rtc.bitsCount >> 3] >> (rtc.bitsCount & 0x07) & 0x01)
rtc._REG |= 0x01;
else
rtc._REG &= ~0x01;
rtc.bitsCount++;
if (rtc.bitsCount == cmdBitsSize[rtc.cmd])
rtc.cmdStat = 0;
}
break;
} }
rtc._prevSIO = rtc._SIO;
rtc._prevSCK = rtc._SCK;
rtc._prevCS = rtc._CS;
} }

View File

@ -2,7 +2,8 @@
yopyop156@ifrance.com yopyop156@ifrance.com
yopyop156.ifrance.com yopyop156.ifrance.com
Copyright (C) 2006-2008 DeSmuME team Copyright 2008 CrazyMax
Copyright 2008-2009 DeSmuME team
This file is part of DeSmuME This file is part of DeSmuME
@ -18,7 +19,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with DeSmuME; if not, write to the Free Software along with DeSmuME; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#ifndef _RTC_H_ #ifndef _RTC_H_