[Lapetus-cvs] lapetus/tests/regtest cdb.c, NONE, 1.1 cdb.h, NONE, 1.1 dsp.c, NONE, 1.1 dsp.h, NONE,
Status: Inactive
Brought to you by:
cyberwarriorx
From: Theo B. <cyb...@us...> - 2008-01-07 03:10:49
|
Update of /cvsroot/lapetus/lapetus/tests/regtest In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv30683 Modified Files: main.c Added Files: cdb.c cdb.h dsp.c dsp.h intfac.c intfac.h main.h makefile objects scsp.c scsp.h scu.c scu.h sh2.c sh2.h tests.c tests.h vdp2.c vdp2.h Log Message: -Bunch of WIP stuff --- NEW FILE: sh2.c --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <lapetus.h> #include "tests.h" #define SH2REG_IPRA (*(volatile u16 *)0xFFFFFEE2) #define SH2REG_DVSR (*(volatile u32 *)0xFFFFFF00) #define SH2REG_DVDNT (*(volatile u32 *)0xFFFFFF04) #define SH2REG_DVCR (*(volatile u32 *)0xFFFFFF08) #define SH2REG_VCRDIV (*(volatile u32 *)0xFFFFFF0C) #define SH2REG_DVDNTH (*(volatile u32 *)0xFFFFFF10) #define SH2REG_DVDNTL (*(volatile u32 *)0xFFFFFF14) #define SH2REG_DVDNTUH (*(volatile u32 *)0xFFFFFF18) #define SH2REG_DVDNTUL (*(volatile u32 *)0xFFFFFF1C) #define SH2REG_DVSR2 (*(volatile u32 *)0xFFFFFF20) #define SH2REG_DVDNT2 (*(volatile u32 *)0xFFFFFF24) #define SH2REG_DVCR2 (*(volatile u32 *)0xFFFFFF28) #define SH2REG_VCRDIV2 (*(volatile u32 *)0xFFFFFF2C) #define SH2REG_DVDNTH2 (*(volatile u32 *)0xFFFFFF30) #define SH2REG_DVDNTL2 (*(volatile u32 *)0xFFFFFF34) #define SH2REG_DVDNTUH2 (*(volatile u32 *)0xFFFFFF38) #define SH2REG_DVDNTUL2 (*(volatile u32 *)0xFFFFFF3C) void DivMirrorTest(void); void DivOperationTest(void); void DivInterruptTest(void); ////////////////////////////////////////////////////////////////////////////// void sh2test() { InterruptSetLevelMask(0xF); InitLapetus(RES_320x224); // Setup a screen for us draw on VdpRBG0Init(&testdispsettings); VdpSetDefaultPalette(); // Display On VdpDispOn(); UnregisterAllTests(); RegisterTest(&DivMirrorTest, "DIV register access"); RegisterTest(&DivOperationTest, "DIV operations"); RegisterTest(&DivInterruptTest, "DIV overflow interrupt"); DoTests("SH2 tests", 0, 0); } ////////////////////////////////////////////////////////////////////////////// #define TestAccessB(r) \ r = 0x01; \ if (r != 0x01) \ { \ stagestatus = STAGESTAT_BADDATA; \ return; \ } #define TestAccessW(r) \ r = 0x0102; \ if (r != 0x0102) \ { \ stagestatus = STAGESTAT_BADDATA; \ return; \ } #define TestAccessL(r) \ r = 0x01020304; \ if (r != 0x01020304) \ { \ stagestatus = STAGESTAT_BADDATA; \ return; \ } void DivMirrorTest(void) { // This tests DIV register reads/writes and checks mirroring TestAccessW(SH2REG_VCRDIV) TestAccessW(SH2REG_VCRDIV2) SH2REG_VCRDIV = 0; TestAccessB(SH2REG_DVCR) TestAccessB(SH2REG_DVCR2) SH2REG_DVCR = 0; TestAccessL(SH2REG_DVDNTH) TestAccessL(SH2REG_DVDNTH2) TestAccessL(SH2REG_DVSR) TestAccessL(SH2REG_DVSR2) TestAccessL(SH2REG_DVDNTUH) TestAccessL(SH2REG_DVDNTUH2) TestAccessL(SH2REG_DVDNTUL) TestAccessL(SH2REG_DVDNTUL2) stagestatus = STAGESTAT_DONE; } ////////////////////////////////////////////////////////////////////////////// void DivOperationTest(void) { // This tests to make sure the dividing operation is correct int i; // Test 64-bit/32-bit operation SH2REG_DVSR = 0x10; SH2REG_DVDNTH = 0x1; SH2REG_DVDNTL = 0x9; // Wait a bit for (i = 0; i < 20; i++) {} if (SH2REG_DVDNTL != 0x10000000 || SH2REG_DVDNTL2 != 0x10000000 || SH2REG_DVDNT != 0x10000000 || SH2REG_DVDNT2 != 0x10000000 || SH2REG_DVDNTUL != 0x10000000 || SH2REG_DVDNTUL2 != 0x10000000 || SH2REG_DVDNTH != 9 || SH2REG_DVDNTH2 != 9 || SH2REG_DVDNTUH != 9 || SH2REG_DVDNTUH2 != 9) { stagestatus = STAGESTAT_BADDATA; return; } // Ok, mirrors are working alright, and 64-bit/32-bit operation is correct // Test 32-bit/32-bit operation SH2REG_DVSR = 0x10; SH2REG_DVDNT = 0x10000009; // Wait a bit for (i = 0; i < 20; i++) {} if (SH2REG_DVDNTL != 0x1000000 || SH2REG_DVDNTL2 != 0x1000000 || SH2REG_DVDNT != 0x1000000 || SH2REG_DVDNT2 != 0x1000000 || SH2REG_DVDNTUL != 0x1000000 || SH2REG_DVDNTUL2 != 0x1000000 || SH2REG_DVDNTH != 9 || SH2REG_DVDNTH2 != 9 || SH2REG_DVDNTUH != 9 || SH2REG_DVDNTUH2 != 9) { stagestatus = STAGESTAT_BADDATA; return; } // Ok, mirrors are working alright, and 32-bit/32-bit operation is correct // Now let's do an overflow test(It seems you can only trigger it using 64-bit/32-bit operation) SH2REG_DVSR = 0x1; SH2REG_DVCR = 0; SH2REG_DVDNTH = 0x1; SH2REG_DVDNTL = 0x0; // Wait a bit for (i = 0; i < 20; i++) {} if (SH2REG_DVDNTL != 0x7FFFFFFF || SH2REG_DVDNTH != 0xFFFFFFFE || SH2REG_DVCR != 0x1) { stagestatus = STAGESTAT_BADDATA; return; } // Lastly, do two divide by zero tests SH2REG_DVSR = 0; SH2REG_DVCR = 0; SH2REG_DVDNT = 0; // Wait a bit for (i = 0; i < 20; i++) {} if (SH2REG_DVDNT != 0x7FFFFFFF || SH2REG_DVDNTH != 0 || SH2REG_DVCR != 0x1) { stagestatus = STAGESTAT_BADDATA; return; } SH2REG_DVSR = 0; SH2REG_DVCR = 0; SH2REG_DVDNT = 0xD0000000; // Wait a bit for (i = 0; i < 20; i++) {} if (SH2REG_DVDNT != 0x80000000 || SH2REG_DVDNTH != 0xFFFFFFFE || SH2REG_DVCR != 0x1) { stagestatus = STAGESTAT_BADDATA; return; } stagestatus = STAGESTAT_DONE; } ////////////////////////////////////////////////////////////////////////////// void sh2inttestfunc(void) __attribute__ ((interrupt_handler)); void sh2inttestfunc(void) { BIOS_SetSH2Interrupt(0x6E, 0); SH2REG_DVCR = 0; stagestatus = STAGESTAT_DONE; } ////////////////////////////////////////////////////////////////////////////// void DivInterruptTest(void) { // This tests to make sure an interrupt is generated when the registers are setup // for it, and an overflow occurs stagestatus = STAGESTAT_WAITINGFORINT; BIOS_SetSH2Interrupt(0x6E, sh2inttestfunc); SH2REG_VCRDIV = 0x6E; SH2REG_IPRA = 0xF << 12; InterruptSetLevelMask(0xE); SH2REG_DVSR = 0; SH2REG_DVCR = 0x2; SH2REG_DVDNT = 0xD0000000; // Alright, test is all setup, now when the interrupt is done, the test // will successfully complete } ////////////////////////////////////////////////////////////////////////////// --- NEW FILE: cdb.c --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <lapetus.h> #include "tests.h" ////////////////////////////////////////////////////////////////////////////// void cdbtest() { } ////////////////////////////////////////////////////////////////////////////// --- NEW FILE: objects --- OBJ = $(CRT0) \ obj/main.o \ obj/cdb.o \ obj/dsp.o \ obj/scsp.o \ obj/scu.o \ obj/sh2.o \ obj/vdp2.o \ obj/tests.o \ obj/intfac.o EXTRALIBS = -llapetus --- NEW FILE: sh2.h --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SH2_H #define SH2_H void sh2test(); #endif --- NEW FILE: makefile --- # # (c) 2002 Charles MacDonald # (c) 2006 Theo Berkau # FLAGS = -Wall -g #EXE = main.bin EXE = main.coff all: $(EXE) TARGETTYPE = coff-sh include ../shared/makefile include ./objects $(EXE): $(OBJ) $(LD) $(LDFLAGS) $(OBJ) $(EXTRALIBS) $(LIBS) -o $(EXE) obj/%.o: %.c %.h $(CC) -c $< -o $@ $(FLAGS) obj/%.o: %.s $(AS) $< -o $@ pack: sh-coff-strip $(EXE) --strip-all clean: rm -f obj/*.o rm -f *.bin makedir: mkdir obj --- NEW FILE: cdb.h --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef CDB_H #define CDB_H void cdbtest(); #endif --- NEW FILE: scu.h --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef SCU_H #define SCU_H void scutest(); void TestSCUVERRegister(); void TestVBlankInInterrupt(); void TestVBlankOutInterrupt(); void TestHBlankInInterrupt(); void TestTimer0Interrupt(); void TestTimer1Interrupt(); void TestDSPEndInterrupt(); void TestSoundRequestInterrupt(); void TestSMPCInterrupt(); void TestPadInterrupt(); void TestDMA0Interrupt(); void TestDMA1Interrupt(); void TestDMA2Interrupt(); void TestDMAIllegalInterrupt(); void TestSpriteDrawEndInterrupt(); void TestCDBlockInterrupt(); void TestDMA(); void TestDMA0(); void TestDMA1(); void TestDMA2(); void TestDMAMisalignment(); void TestISTandIMS(); void TestDSP(); void TestMVI_Imm_d(); void scuinttest(void); void scudmatest(); void scudsptest(); #endif --- NEW FILE: intfac.c --- #include <string.h> #include <lapetus.h> #include "intfac.h" #include "tests.h" ////////////////////////////////////////////////////////////////////////////// void ClearScr(void) { int i, i2; VdpDispOff(); VdpClearScreen(&testdispfont); VdpDispOn(); } ////////////////////////////////////////////////////////////////////////////// int DoMenu(MENUITEMSTRUCT *menu, int x, int y) { int cursel=0; int nummenu=0; int i; // Make sure current screen is clear // Figure out how many menu items there are for (;;) { if (menu[nummenu].name[0] == '\0') break; nummenu++; } // Add Menu Sprite to draw list for (i = 0; i < nummenu; i++) VdpPrintf(&testdispfont, (x+1) * 8, (y+i) * 8, 0xF, (char *)menu[i].name); // Add Selected Menu Item(should always be first item) sprite to draw list VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, ">"); for (;;) { VdpVsync(); // poll joypad(if menu item is selected, return) if (per[0].butpushonce & PAD_UP) { VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, " "); if (cursel > 0) cursel--; VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, ">"); } else if (per[0].butpushonce & PAD_DOWN) { VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, " "); if (cursel < (nummenu - 1)) cursel++; VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, ">"); } if (per[0].butpushonce & PAD_A) { ClearScr(); if (menu[cursel].func) menu[cursel].func(); return cursel; } } } ////////////////////////////////////////////////////////////////////////////// int DoWindow(WINDOWSTRUCT *window, int x, int y) { int nummenu=0; int i; // Make sure current screen is clear // Figure out how many window items there are for (;;) { // if (menu[nummenu].name[0] == '\0') break; // nummenu++; } /* // Add Menu Sprite to draw list for (i = 0; i < nummenu; i++) VdpPrintf(&testdispfont, (x+1) * 8, (y+i) * 8, 0xF, (char *)menu[i].name); // Add Selected Menu Item(should always be first item) sprite to draw list VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, ">"); for (;;) { VdpVsync(); // poll joypad(if menu item is selected, return) if (per[0].butpushonce & PAD_UP) { VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, " "); if (cursel > 0) cursel--; VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, ">"); } else if (per[0].butpushonce & PAD_DOWN) { VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, " "); if (cursel < (nummenu - 1)) cursel++; VdpPrintf(&testdispfont, x * 8, (y+cursel) * 8, 0xF, ">"); } if (per[0].butpushonce & PAD_A) { ClearScr(); if (menu[cursel].func) menu[cursel].func(); return cursel; } } */ } ////////////////////////////////////////////////////////////////////////////// /* int MessageBox(const char *header, const char *body, int type) { int body_x=0, body_y=0; body_x = ((320 / 8) - strlen(body)) / 2; // fix me body_y = (224 / 8) / 2; // fix me for (;;) { VdpVsync(); // VdpStartDrawList(); // Vdp1printf(body_x * 8, body_y * 8, 0xF0, (char *)body); // _printf(body_x * 8, body_y * 8, 0xF0, (char *)body); // Vdp1DrawPolygon(body_x - 8, body_y - 8, // body_x + (strlen(body) * 8) + 8, body_y - 8, // body_x + (strlen(body) * 8) + 8, body_y + 16, // fix me // body_x - 8, body_y + 16, // fix me // RGB16(0, 0, 127), // SPRITE_ENDCODEDISABLE | SPRITE_TRANSPIXELDISABLE | SPRITE_16BPP); // Vdp1DrawNormalSprite(0, 16, 16, 0, 0, 0); // Vdp1DrawPolygon(0, 0, // 200, 0, // 200, 180, // 0, 180, // 0xFFFE, // SPRITE_ENDCODEDISABLE); // RGB16_COLOR(10,20,30), // Vdp1DrawDistortedSprite(0, 16, 16, 0, 0, 16, 0, 16, 16, 0, 16, 0); // VdpEndDrawList(); switch (type) { // fix me default: VdpPrintf(&testdispfont, ((320 / 16) - 1) * 8, (body_y+2) * 8, 0xF, "OK"); //fix me break; } if (per[0].id == PER_KEYBOARD) { keyboarddata_struct *kbd=(keyboarddata_struct *)&per[0]; if (kbd->flags & 0x8) // Make { if (kbd->key == KEY_ENTER || kbd->key == KEY_KPENTER || kbd->key == KEY_SPACE || kbd->key == KEY_ESC) break; } } else if (per[0].butpushonce & PAD_A) { break; } } ClearScr(); return 0; // fix me(it should return what control was chosen) } */ ////////////////////////////////////////////////////////////////////////////// /* lwnd_struct *LWICreateWindow(char *name, int style, int x, int y, int width, int height, lwnd_struct *parent) { } ////////////////////////////////////////////////////////////////////////////// int LWIGetMessage(lmsg_struct *msg, lwnd_struct *wnd, int filtermin, int filtermax) { } ////////////////////////////////////////////////////////////////////////////// int LWIDispatchMessage(lmsg_struct *msg) { } ////////////////////////////////////////////////////////////////////////////// */ --- NEW FILE: vdp2.c --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <lapetus.h> #include "tests.h" void Vdp2NBG0Test (); void Vdp2NBG1Test (); void Vdp2NBG2Test (); void Vdp2NBG3Test (); void Vdp2RBG0Test (); void Vdp2RBG1Test (); ////////////////////////////////////////////////////////////////////////////// void hline(int x1, int y1, int x2, u8 color) { int i; volatile u8 *buf=(volatile u8 *)(0x25E00000+(y1 * 512)); for (i = x1; i < (x2+1); i++) buf[i] = color; } ////////////////////////////////////////////////////////////////////////////// void vline(int x1, int y1, int y2, u8 color) { int i; volatile u8 *buf=(volatile u8 *)(0x25E00000+(y1 * 512) + x1); for (i = 0; i < (y2-y1+1); i++) buf[i * 512] = color; } ////////////////////////////////////////////////////////////////////////////// void DrawBox(int x1, int y1, int x2, int y2, u8 color) { hline(x1, y1, x2, color); hline(x1, y2, x2, color); vline(x1, y1, y2, color); vline(x2, y1, y2, color); } ////////////////////////////////////////////////////////////////////////////// void WorkingQuerry(const char *question) { // Ask the user if it's visible VdpPrintf(&testdispfont, 2 * 8, 20 * 8, 0xF, question); VdpPrintf(&testdispfont, 2 * 8, 21 * 8, 0xF, "C - Yes B - No"); for(;;) { VdpVsync(); if (per[0].butpushonce & PAD_B) { stagestatus = STAGESTAT_BADGRAPHICS; break; } else if (per[0].butpushonce & PAD_C) { stagestatus = STAGESTAT_DONE; break; } } } ////////////////////////////////////////////////////////////////////////////// void vdp2test() { // Put system in minimalized state InterruptSetLevelMask(0xF); InitLapetus(RES_320x224); VdpRBG0Init(&testdispsettings); VdpSetDefaultPalette(); // Display On VdpDispOn(); UnregisterAllTests(); // RegisterTest(&Vdp2InterruptTest, "Sound Request Interrupt"); RegisterTest(&Vdp2RBG0Test, "RBG0 bitmap"); DoTests("VDP2 Screen tests", 0, 0); } ////////////////////////////////////////////////////////////////////////////// void Vdp2NBG0Test () { screensettings_struct settings; // Draw a box on our default screen DrawBox(120, 180, 80, 40, 15); // Setup NBG0 for drawing settings.isbitmap = TRUE; settings.bitmapsize = BG_BITMAP512x256; settings.transparentbit = 0; settings.color = BG_256COLOR; settings.specialpriority = 0; settings.specialcolorcalc = 0; settings.extrapalettenum = 0; // settings.mapoffset = 0; // settings.parameteraddr = 0x25E60000; VdpNBG0Init(&settings); // Draw some stuff on the screen WorkingQuerry("Is the above graphics displayed?"); // Disable NBG0 VdpNBG0DeInit(); } ////////////////////////////////////////////////////////////////////////////// void Vdp2NBG1Test () { } ////////////////////////////////////////////////////////////////////////////// void Vdp2NBG2Test () { } ////////////////////////////////////////////////////////////////////////////// void Vdp2NBG3Test () { } ////////////////////////////////////////////////////////////////////////////// void Vdp2RBG0Test () { // Draw a box on our default screen DrawBox(120, 180, 80, 40, 15); // Draw some graphics on the RBG0 layer WorkingQuerry("Is the above graphics displayed?"); } ////////////////////////////////////////////////////////////////////////////// void Vdp2RBG1Test () { } ////////////////////////////////////////////////////////////////////////////// --- NEW FILE: scsp.c --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <lapetus.h> #include "tests.h" #define SCSPREG_TIMERA (*(volatile u16 *)0x25B00418) #define SCSPREG_TIMERB (*(volatile u16 *)0x25B0041A) #define SCSPREG_TIMERC (*(volatile u16 *)0x25B0041C) #define SCSPREG_SCIEB (*(volatile u16 *)0x25B0041E) #define SCSPREG_SCIPD (*(volatile u16 *)0x25B00420) #define SCSPREG_SCIRE (*(volatile u16 *)0x25B00422) #define SCSPREG_MCIEB (*(volatile u16 *)0x25B0042A) #define SCSPREG_MCIPD (*(volatile u16 *)0x25B0042C) #define SCSPREG_MCIRE (*(volatile u16 *)0x25B0042E) volatile u32 hblankcounter=0; int tinc=0; void ScuInterruptTest(void); void ScspTimerATest(); void ScspTimerBTest(); void ScspTimerCTest(); void ScspTimerTimingTest(u16 timersetting); void ScspTimerTimingTest0(); void ScspTimerTimingTest1(); void ScspTimerTimingTest2(); void ScspTimerTimingTest3(); void ScspTimerTimingTest4(); void ScspTimerTimingTest5(); void ScspTimerTimingTest6(); void ScspTimerTimingTest7(); void ScspIntOnTimerEnableTest(); void ScspIntOnTimerResetTest(); void ScspIntDupTest(); void ScspMCIPDTest(); ////////////////////////////////////////////////////////////////////////////// void scsptest() { // Put system in minimalized state InterruptSetLevelMask(0xF); InitLapetus(RES_320x224); VdpRBG0Init(&testdispsettings); VdpSetDefaultPalette(); // Turn off sound cpu SmpcIssueCommand(0x07); // Display On VdpDispOn(); UnregisterAllTests(); RegisterTest(&ScuInterruptTest, "Sound Request Interrupt"); RegisterTest(&ScspTimerATest, "Timer A"); RegisterTest(&ScspTimerBTest, "Timer B"); RegisterTest(&ScspTimerCTest, "Timer C"); RegisterTest(&ScspTimerTimingTest0, "Timer timing w/1 sample inc"); RegisterTest(&ScspTimerTimingTest1, "Timer timing w/2 sample inc"); RegisterTest(&ScspTimerTimingTest2, "Timer timing w/4 sample inc"); RegisterTest(&ScspTimerTimingTest3, "Timer timing w/8 sample inc"); RegisterTest(&ScspTimerTimingTest4, "Timer timing w/16 sample inc"); RegisterTest(&ScspTimerTimingTest5, "Timer timing w/32 sample inc"); RegisterTest(&ScspTimerTimingTest6, "Timer timing w/64 sample inc"); RegisterTest(&ScspTimerTimingTest7, "Timer timing w/128 sample inc"); RegisterTest(&ScspIntOnTimerEnableTest, "Int on Timer enable behaviour"); RegisterTest(&ScspIntOnTimerResetTest, "Int on Timer reset behaviour"); RegisterTest(&ScspIntDupTest, "No second Int after Timer done"); // RegisterTest(&ScspMCIPDTest, "MCIPD bit cleared after Timer Int"); DoTests("SCSP Interrupt tests", 0, 0); } ////////////////////////////////////////////////////////////////////////////// void scspinttestfunc() { stagestatus = STAGESTAT_DONE; // Mask SCSP interrupts BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40); } ////////////////////////////////////////////////////////////////////////////// void ScuInterruptTest() { // Disable everything temporarily SCSPREG_SCIEB = 0; SCSPREG_MCIEB = 0; // Mask SCSP interrupt temporarily BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40); // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, scspinttestfunc); // Unmask SCSP interrupt BIOS_ChangeSCUInterruptMask(~0x40, 0); // Enable all SCSP Main cpu interrupts SCSPREG_MCIEB = 0x7FF; SCSPREG_MCIRE = 0x7FF; } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTest(int timermask) { // Disable everything temporarily SCSPREG_SCIEB = 0; SCSPREG_MCIEB = 0; // Mask SCSP interrupt temporarily BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40); // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, scspinttestfunc); // Unmask SCSP interrupt BIOS_ChangeSCUInterruptMask(~0x40, 0); stagestatus = STAGESTAT_WAITINGFORINT; // Enable Timer interrupt SCSPREG_MCIRE = timermask; SCSPREG_MCIEB = timermask; } ////////////////////////////////////////////////////////////////////////////// void ScspTimerATest() { ScspTimerTest(0x40); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerBTest() { ScspTimerTest(0x80); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerCTest() { ScspTimerTest(0x100); } ////////////////////////////////////////////////////////////////////////////// void scsptimingfunc(void) { u32 hblanktemp; hblanktemp = hblankcounter; // VdpPrintf(&testdispfont, 1 * 8, 22 * 8, 0xF, "hblankcounter: %08X", hblanktemp); switch (tinc) { case 0: if ((hblanktemp & 0xFF00) < 0x100) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; break; case 1: if ((hblanktemp & 0xFF00) < 0x100) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; break; case 2: if ((hblanktemp & 0xFF00) == 0x100) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; break; case 3: if ((hblanktemp & 0xFF00) == 0x200) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; break; case 4: if ((hblanktemp & 0xFF00) == 0x500) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; break; case 5: if ((hblanktemp & 0xFF00) == 0xB00) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; break; case 6: if ((hblanktemp & 0xFF00) == 0x1600) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; break; case 7: if ((hblanktemp & 0xFF00) == 0x2D00) // fix me stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; default: stagestatus = STAGESTAT_DONE; break; } } ////////////////////////////////////////////////////////////////////////////// void hblanktimingfunc(void) { hblankcounter++; } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest(u16 timersetting) { // Disable everything temporarily SCSPREG_SCIEB = 0; SCSPREG_MCIEB = 0; tinc = timersetting >> 8; InterruptSetLevelMask(0xF); // Mask SCSP/H-blank interrupts temporarily BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40 | 0x4); // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, scsptimingfunc); // Set Hblank-in interrupt function BIOS_SetSCUInterrupt(0x42, hblanktimingfunc); // Unmask SCSP/H-blank interrupts BIOS_ChangeSCUInterruptMask(~(0x40 | 0x4), 0); hblankcounter = 0; VdpVsync(); // switch (timermask) // { // case 0x40: SCSPREG_TIMERA = timersetting; // break; // case 0x80: // SCSPREG_TIMERB = timersetting; // break; // case 0x100: // SCSPREG_TIMERC = timersetting; // break; // default: break; // } InterruptSetLevelMask(0x8); stagestatus = STAGESTAT_WAITINGFORINT; // Enable Timer interrupt SCSPREG_MCIRE = 0x0040; SCSPREG_MCIEB = 0x0040; } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest0() { ScspTimerTimingTest(0x0000); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest1() { ScspTimerTimingTest(0x0100); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest2() { ScspTimerTimingTest(0x0200); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest3() { ScspTimerTimingTest(0x0300); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest4() { ScspTimerTimingTest(0x0400); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest5() { ScspTimerTimingTest(0x0500); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest6() { ScspTimerTimingTest(0x0600); } ////////////////////////////////////////////////////////////////////////////// void ScspTimerTimingTest7() { ScspTimerTimingTest(0x0700); } ////////////////////////////////////////////////////////////////////////////// void intontimerenabletestfunc(void) { // u32 hblanktemp; // hblanktemp = hblankcounter; if (hblankcounter == 0) stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADTIMING; // VdpPrintf(&testdispfont, 1 * 8, 23 * 8, 0xF, "hblankcounter: %08X", hblanktemp); } ////////////////////////////////////////////////////////////////////////////// void ScspIntOnTimerEnableTest() { // Disable everything temporarily SCSPREG_SCIEB = 0; SCSPREG_MCIEB = 0; // Mask SCSP/H-blank interrupts temporarily BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40 | 0x4); // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, intontimerenabletestfunc); // Set Hblank-in interrupt function BIOS_SetSCUInterrupt(0x42, hblanktimingfunc); // Unmask SCSP/H-blank interrupts BIOS_ChangeSCUInterruptMask(~(0x40 | 0x4), 0); // Clear timer SCSPREG_TIMERA = 0x0700; SCSPREG_MCIRE = 0x40; // Wait until MCIPD is showing an interrupt pending while (!(SCSPREG_MCIPD & 0x40)) {} stagestatus = STAGESTAT_WAITINGFORINT; // Enable Timer interrupt hblankcounter = 0; SCSPREG_MCIEB = 0x40; } ////////////////////////////////////////////////////////////////////////////// void ScspIntOnTimerResetTest() { // Disable everything temporarily SCSPREG_SCIEB = 0; SCSPREG_MCIEB = 0; // Mask SCSP interrupt temporarily BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40); // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, 0); // Unmask SCSP interrupt BIOS_ChangeSCUInterruptMask(~0x40, 0); // Enable timer SCSPREG_TIMERA = 0x0700; SCSPREG_MCIRE = 0x40; SCSPREG_MCIEB = 0x40; // Wait until MCIPD is showing an interrupt pending while (!(SCSPREG_MCIPD & 0x40)) {} // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, scspinttestfunc); stagestatus = STAGESTAT_WAITINGFORINT; // Reset Timer hblankcounter = 0; SCSPREG_MCIRE = 0x40; } ////////////////////////////////////////////////////////////////////////////// void ScspIntDupTest() { // Disable everything temporarily SCSPREG_SCIEB = 0; SCSPREG_MCIEB = 0; // Mask SCSP/H-blank interrupts temporarily BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40 | 0x4); // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, 0); // Set Hblank-in interrupt function BIOS_SetSCUInterrupt(0x42, hblanktimingfunc); // Unmask SCSP/H-blank interrupts BIOS_ChangeSCUInterruptMask(~(0x40 | 0x4), 0); // Enable timer SCSPREG_TIMERA = 0; SCSPREG_MCIRE = 0x40; SCSPREG_MCIEB = 0x40; // Wait until MCIPD is showing an interrupt pending while (!(SCSPREG_MCIPD & 0x40)) {} // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, scspinttestfunc); // Wait around 0x2000 hblanks to make sure nothing else triggers the interrupt hblankcounter = 0; while (hblankcounter < 0x2000) {} if (stagestatus == STAGESTAT_DONE) stagestatus = STAGESTAT_BADINTERRUPT; else stagestatus = STAGESTAT_DONE; } ////////////////////////////////////////////////////////////////////////////// void mcipdtestfunc() { u16 mcipdtemp=SCSPREG_MCIPD; VdpPrintf(&testdispfont, 1 * 8, 22 * 8, 0xF, "MCIPD: %04X", mcipdtemp); } ////////////////////////////////////////////////////////////////////////////// void ScspMCIPDTest() { // Disable everything temporarily SCSPREG_SCIEB = 0; SCSPREG_MCIEB = 0; // Mask SCSP/H-blank interrupts temporarily BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x40); // Set SCSP interrupt function BIOS_SetSCUInterrupt(0x46, mcipdtestfunc); // Unmask SCSP/H-blank interrupts BIOS_ChangeSCUInterruptMask(~0x40, 0); stagestatus = STAGESTAT_WAITINGFORINT; // Enable timer SCSPREG_TIMERA = 0x0700; SCSPREG_MCIRE = 0x40; SCSPREG_MCIEB = 0x40; } ////////////////////////////////////////////////////////////////////////////// --- NEW FILE: tests.c --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <lapetus.h> #include "tests.h" int stagestatus=STAGESTAT_START; int waitcounter; u32 errordata=0; typedef struct { void (*testfunc)(void); const char *name; } tests_struct; tests_struct tests[0x100]; u8 numtests=0; ////////////////////////////////////////////////////////////////////////////// void InitTest(void) { // Put saturn in a minimalized state int i; InterruptSetLevelMask(0xF); for (i = 0; i < 0x80; i++) BIOS_SetSH2Interrupt(i, 0); for (i = 0x40; i < 0x60; i++) BIOS_SetSCUInterrupt(i, 0); // Make sure all interrupts have been called BIOS_ChangeSCUInterruptMask(0, 0); BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0xFFFFFFFF); VdpInit(RES_320x224); // PerInit(); CommlinkStopService(); // if (InterruptGetLevelMask() > 0x7) // InterruptSetLevelMask(0x7); VdpRBG0Init(&testdispsettings); } ////////////////////////////////////////////////////////////////////////////// void DoTests(const char *testname, int x, int y) { int i; u8 stage=0; // Print messages and cursor VdpPrintf(&testdispfont, x * 8, y * 8, 0xF, (char *)testname); for(;;) { VdpVsync(); if (stagestatus != STAGESTAT_BUSY && stagestatus != STAGESTAT_WAITINGFORINT) { if (stagestatus == STAGESTAT_DONE) VdpPrintf(&testdispfont, (x+38) * 8, (y + stage + 2) * 8, 0xA, "OK"); else if (stagestatus < 0) { // Handle error switch (stagestatus) { case STAGESTAT_BADTIMING: VdpPrintf(&testdispfont, (x+38) * 8, (y + stage + 2) * 8, 0xE, "BT"); break; case STAGESTAT_BADDATA: VdpPrintf(&testdispfont, (x+38) * 8, (y + stage + 2) * 8, 0xC, "BD"); break; case STAGESTAT_BADINTERRUPT: VdpPrintf(&testdispfont, (x+38) * 8, (y + stage + 2) * 8, 0xC, "BI"); break; default: VdpPrintf(&testdispfont, (x+38) * 8, (y + stage + 2) * 8, 0xC, "failed"); break; } } if (stage >= numtests) { VdpPrintf(&testdispfont, x * 8, (y + stage + 3) * 8, 0xF, "All tests done."); break; } stagestatus = STAGESTAT_BUSY; if (tests[stage].name) VdpPrintf(&testdispfont, x * 8, (y + stage + 3) * 8, 0xF, (char *)tests[stage].name); if (tests[stage].testfunc) tests[stage].testfunc(); waitcounter = 60 * 5; stage++; } else { if (stagestatus == STAGESTAT_WAITINGFORINT) { // decrement waitcounter waitcounter--; if (waitcounter <= 0) stagestatus = STAGESTAT_BADINTERRUPT; VdpPrintf(&testdispfont, 0 * 8, 23 * 8, 0xF, "%08X", waitcounter); } } } // Reset all interrupts for (i = 0; i < 0x80; i++) BIOS_SetSH2Interrupt(i, 0); for (i = 0x40; i < 0x60; i++) BIOS_SetSCUInterrupt(i, 0); PerInit(); InterruptSetLevelMask(0x6); VdpVsync(); // Wait until no buttons are pressed while (per[0].butpushonce || per[0].butpush) { VdpVsync(); } for (;;) { VdpVsync(); // return whenever a button pressed if (per[0].butpushonce & PAD_A || per[0].butpushonce & PAD_B || per[0].butpushonce & PAD_C || per[0].butpushonce & PAD_X || per[0].butpushonce & PAD_Y || per[0].butpushonce & PAD_Z || per[0].butpushonce & PAD_L || per[0].butpushonce & PAD_R || per[0].butpushonce & PAD_START) break; } } ////////////////////////////////////////////////////////////////////////////// void RegisterTest(void (*func)(void), const char *name) { tests[numtests].testfunc = func; tests[numtests].name = name; numtests++; } ////////////////////////////////////////////////////////////////////////////// void UnregisterAllTests() { int i; for (i = 0; i < 0x100; i++) { tests[i].testfunc = 0; tests[i].name = 0; } numtests=0; stagestatus=STAGESTAT_START; } ////////////////////////////////////////////////////////////////////////////// --- NEW FILE: dsp.h --- /* Copyright 2006-2008 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef DSPH #define DSPH void scudsptest(); void TestDSP(); void TestMVI_Imm_d(); void TestDSPTiming(); #define NOP() 0x00000000 #define AND() (1 << 26) #define OR() (2 << 26) #define XOR() (3 << 26) #define ADD() (4 << 26) #define SUB() (5 << 26) #define AD2() (6 << 26) #define SR() (8 << 26) #define RR() (9 << 26) #define SL() (10 << 26) #define RL() (11 << 26) #define RL8() (15 << 26) #define MOVSRC_MC0 0x0 #define MOVSRC_MC1 0x1 #define MOVSRC_MC2 0x2 #define MOVSRC_MC3 0x3 #define MOVSRC_MC0P 0x4 #define MOVSRC_MC1P 0x5 #define MOVSRC_MC2P 0x6 #define MOVSRC_MC3P 0x7 #define MOVSRC_ALUL 0x9 #define MOVSRC_ALUH 0xA #define MOV_s_X(s) (0x02000000 | (s << 20)) #define MOV_MUL_P() (0x01000000) #define MOV_s_P(s) (0x01800000 | (s << 20)) #define MOV_s_Y(s) (0x00080000 | (s << 14)) #define CLR_A() (0x00020000) #define MOV_ALU_A() (0x00040000) #define MOV_s_A(s) (0x00060000 | (s << 14)) #define MOVDEST_MC0 0x0 #define MOVDEST_MC1 0x1 #define MOVDEST_MC2 0x2 #define MOVDEST_MC3 0x3 #define MOVDEST_RX 0x4 #define MOVDEST_PL 0x5 #define MOVDEST_RA0 0x6 #define MOVDEST_WA0 0x7 #define MOVDEST_LOP 0xA #define MOVDEST_TOP 0xB #define MOVDEST_CT0 0xC #define MOVDEST_CT1 0xD #define MOVDEST_CT2 0xE #define MOVDEST_CT3 0xF #define MOV_Imm_d(imm, d) (0x00001000 | (d << 8) | ((imm) & 0xFF)) #define MOV_s_d(s, d) (0x00003000 | (d << 8) | (s)) #define MVIDEST_MC0 0x0 #define MVIDEST_MC1 0x1 #define MVIDEST_MC2 0x2 #define MVIDEST_MC3 0x3 #define MVIDEST_RX 0x4 #define MVIDEST_PL 0x5 #define MVIDEST_RA0 0x6 #define MVIDEST_WA0 0x7 #define MVIDEST_LOP 0xA #define MVIDEST_PC 0xC #define MVI_Imm_d(imm, d) (0x80000000 | ((imm) & 0x1FFFFFF) | (d << 26)) #define MVI_Imm_d_Z(imm, d) (0x82000000 | (0x21 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_NZ(imm, d) (0x82000000 | (0x1 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_S(imm, d) (0x82000000 | (0x22 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_NS(imm, d) (0x82000000 | (0x2 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_C(imm, d) (0x82000000 | (0x24 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_NC(imm, d) (0x82000000 | (0x4 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_T0(imm, d) (0x82000000 | (0x28 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_NT0(imm, d) (0x82000000 | (0x8 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_ZS(imm, d) (0x82000000 | (0x23 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define MVI_Imm_d_NZS(imm, d) (0x82000000 | (0x3 << 19) | ((imm) & 0x7FFFF) | (d << 26)) #define DMAADD_0 0x0 #define DMAADD_1 0x1 #define DMAADD_2 0x2 #define DMAADD_4 0x3 #define DMAADD_8 0x4 #define DMAADD_16 0x5 #define DMAADD_32 0x6 #define DMAADD_64 0x7 #define DMARAM_0 0x0 #define DMARAM_1 0x1 #define DMARAM_2 0x2 #define DMARAM_3 0x3 #define DMARAM_PROG 0x4 #define DMA_D0_RAM_Imm(add, ram, imm) (0xC0000000 | (add << 15) | (ram << 8) | (imm & 0xFF)) #define DMA_RAM_D0_Imm(add, ram, imm) (0xC0001000 | (add << 15) | (ram << 8) | (imm & 0xFF)) #define DMA_D0_RAM_s(add, ram, s) (0xC0002000 | (add << 15) | (ram << 8) | s) #define DMA_RAM_D0_s(add, ram, s) (0xC0003000 | (add << 15) | (ram << 8) | s) //#define DMAH_D0_RAM_Imm(add, ram, imm) (0xC??????? | (add << 15) | (ram << 8) | (imm & 0xFF)) //#define DMAH_RAM_D0_Imm(add, ram, imm) (0xC??????? | (add << 15) | (ram << 8) | (imm & 0xFF)) //#define DMA_D0_RAM_s(add, ram, s) (0xC??????? | (add << 15) | (ram << 8) | s) //#define DMA_RAM_D0_s(add, ram, s) (0xC??????? | (add << 15) | (ram << 8) | s) #define JMP_Imm(imm) (0xD0000000 | (imm & 0xFF)) #define JMP_Z_Imm(imm) () #define JMP_NZ_Imm(imm) () #define JMP_S_Imm(imm) () #define JMP_NS_Imm(imm) () #define JMP_C_Imm(imm) () #define JMP_NC_Imm(imm) () #define JMP_T0_Imm(imm) () #define JMP_NT0_Imm(imm) () #define JMP_ZS_Imm(imm) () #define JMP_NZS_Imm(imm) () #define BTM() (0xE0000000) #define LPS() (0xE8000000) #define END() (0xF0000000) #define ENDI() (0xF8000000) #endif --- NEW FILE: main.h --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef _MAIN_H_ #define _MAIN_H_ #endif /* _MAIN_H_ */ --- NEW FILE: vdp2.h --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #ifndef VDP2_H #define VDP2_H void vdp2test(); #endif --- NEW FILE: intfac.h --- #ifndef INTFAC_H #define INTFAC_H typedef struct { s8 name[26]; void (*func)(); } MENUITEMSTRUCT; typedef struct { int type; s8 name[26]; int x; int y; int w; int h; void *extra; int attributes; int (*func)(); } WINDOWSTRUCT; #define WINTYPE_NONE 0x00000000 #define WINTYPE_TITLE 0x00000001 #define WINTYPE_TEXT 0x00000002 #define WINTYPE_BUTTON 0x00000003 #define WINATTR_VISIBLE 0x00000001 #define WINATTR_INVISIBLE 0x00000000 #define WINATTR_GRAYED 0x00000002 int DoMenu(MENUITEMSTRUCT *menu, int x, int y); int DoWindow(WINDOWSTRUCT *window, int x, int y); int MessageBox(const char *header, const char *body, int type); void ClearScr(void); #endif --- NEW FILE: scu.c --- /* Copyright 2006-2007 Theo Berkau This file is part of Lapetus. Lapetus 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 2 of the License, or (at your option) any later version. Lapetus 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 Lapetus; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <lapetus.h> #include "intfac.h" #include "tests.h" #include "dsp.h" #include "scu.h" #define SCUREG_D0R (*(volatile u32 *)0x25FE0000) #define SCUREG_D0W (*(volatile u32 *)0x25FE0004) #define SCUREG_D0C (*(volatile u32 *)0x25FE0008) #define SCUREG_D0AD (*(volatile u32 *)0x25FE000C) #define SCUREG_D0EN (*(volatile u32 *)0x25FE0010) #define SCUREG_D0MD (*(volatile u32 *)0x25FE0014) #define SCUREG_D1R (*(volatile u32 *)0x25FE0020) #define SCUREG_D1W (*(volatile u32 *)0x25FE0024) #define SCUREG_D1C (*(volatile u32 *)0x25FE0028) #define SCUREG_D1AD (*(volatile u32 *)0x25FE002C) #define SCUREG_D1EN (*(volatile u32 *)0x25FE0030) #define SCUREG_D1MD (*(volatile u32 *)0x25FE0034) #define SCUREG_D2R (*(volatile u32 *)0x25FE0040) #define SCUREG_D2W (*(volatile u32 *)0x25FE0044) #define SCUREG_D2C (*(volatile u32 *)0x25FE0048) #define SCUREG_D2AD (*(volatile u32 *)0x25FE004C) #define SCUREG_D2EN (*(volatile u32 *)0x25FE0050) #define SCUREG_D2MD (*(volatile u32 *)0x25FE0054) #define SCUREG_T0C (*(volatile u32 *)0x25FE0090) #define SCUREG_T1S (*(volatile u32 *)0x25FE0094) #define SCUREG_T1MD (*(volatile u32 *)0x25FE0098) #define SCUREG_IMS (*(volatile u32 *)0x25FE00A0) #define SCUREG_IST (*(volatile u32 *)0x25FE00A4) #define SCUREG_AIACK (*(volatile u32 *)0x25FE00A8) #define SCUREG_ASR0 (*(volatile u32 *)0x25FE00B0) #define SCUREG_ASR1 (*(volatile u32 *)0x25FE00B4) #define SCUREG_RSEL (*(volatile u32 *)0x25FE00C4) #define SCUREG_VER (*(volatile u32 *)0x25FE00C8) ////////////////////////////////////////////////////////////////////////////// void scutest() { int choice; MENUITEMSTRUCT scumenu[] = { // { "SCU Register Test", &scuregistertest, }, // { "SCU Interrupt Test", &scuinttest, }, { "SCU DMA Test" , &scudmatest, }, { "SCU DSP Test" , &scudsptest, }, { "Go back to main menu", NULL }, { "\0", NULL } }; for (;;) { choice = DoMenu(scumenu, 8, 14); ClearScr(); if (choice == 3) break; } } ////////////////////////////////////////////////////////////////////////////// /* void scuinttest(void) { InterruptSetLevelMask(0xF); InitLapetus(RES_320x224); VdpRBG0Init(&testdispsettings); VdpSetDefaultPalette(); // Display On VdpDispOn(); UnregisterAllTests(); RegisterTest(&TestSCUVERRegister, "VER Register"); DoTests("SCU Register tests", 0, 0); } */ ////////////////////////////////////////////////////////////////////////////// void scuinttest() { InterruptSetLevelMask(0xF); InitLapetus(RES_320x224); VdpRBG0Init(&testdispsettings); VdpSetDefaultPalette(); // Display On VdpDispOn(); UnregisterAllTests(); RegisterTest(&TestISTandIMS, "Interrupt status and mask"); RegisterTest(&TestVBlankInInterrupt, "Vblank-out Interrupt"); RegisterTest(&TestVBlankOutInterrupt, "Vblank-in Interrupt"); RegisterTest(&TestHBlankInInterrupt, "HBlank-in Interrupt"); RegisterTest(&TestTimer0Interrupt, "Timer 0 Interrupt"); RegisterTest(&TestTimer1Interrupt, "Timer 1 Interrupt"); // RegisterTest(&TestDSPEndInterrupt, "DSP End Interrupt"); RegisterTest(&TestSoundRequestInterrupt, "Sound Request Interrupt"); // RegisterTest(&TestSMPCInterrupt, "SMPC Interrupt"); // RegisterTest(&TestPadInterrupt, "Pad Interrupt"); RegisterTest(&TestDMA0Interrupt, "DMA0 Interrupt"); RegisterTest(&TestDMA1Interrupt, "DMA1 Interrupt"); RegisterTest(&TestDMA2Interrupt, "DMA2 Interrupt"); RegisterTest(&TestDMAIllegalInterrupt, "Illegal DMA Interrupt"); RegisterTest(&TestSpriteDrawEndInterrupt, "Sprite Draw End Interrupt"); // RegisterTest(&TestCDBlockInterrupt, "CD Block Interrupt"); // If Netlink is connected, do a test on it too // if (NetlinkInit() == LAPETUS_ERR_OK) // RegisterTest(&TestNetlinkInterrupt, "Netlink Interrupt"); DoTests("SCU Interrupt tests", 0, 0); } ////////////////////////////////////////////////////////////////////////////// void scudmatest() { InterruptSetLevelMask(0xF); InitLapetus(RES_320x224); VdpRBG0Init(&testdispsettings); VdpSetDefaultPalette(); // Display On VdpDispOn(); UnregisterAllTests(); RegisterTest(&TestDMA0, "DMA 0 transfer"); RegisterTest(&TestDMA1, "DMA 1 transfer"); RegisterTest(&TestDMA2, "DMA 2 transfer"); RegisterTest(&TestDMAMisalignment, "Misaligned DMA transfer"); // RegisterTest(&TestIndirectDMA, "Indirect DMA transfer"); // RegisterTest(&TestTransNum0, "0 Transfer Number transfer"); // RegisterTest(&TestDMAStatus, "DMA Status Register"); // Test out DMA start factors here // RegisterTest(&, ); DoTests("SCU DMA tests", 0, 0); } ////////////////////////////////////////////////////////////////////////////// void TestSCUVERRegister() { // Make sure it's at least version 4 VdpPrintf(&testdispfont, 0 * 8, 23 * 8, 0xF, "%08X", SCUREG_PPAF); SCUREG_PPAF = 0; VdpPrintf(&testdispfont, 0 * 8, 24 * 8, 0xF, "%08X", SCUREG_PPAF); if (SCUREG_VER < 4) stagestatus = STAGESTAT_BADDATA; else stagestatus = STAGESTAT_DONE; } ////////////////////////////////////////////////////////////////////////////// int isinttime=0; void (*oldfunc)(); u8 intvector; u32 oldmask; void testintfunc() { InterruptSetLevelMask(0xF); // Return interrupt settings back to normal BIOS_SetSCUInterrupt(intvector, oldfunc); BIOS_SetSCUInterruptMask(oldmask); if (isinttime) stagestatus = STAGESTAT_DONE; else stagestatus = STAGESTAT_BADINTERRUPT; isinttime = 0; if (intvector >= 0x50) { // Need to do an A-bus interrupt acknowledge } VdpPrintf(&testdispfont, 0 * 8, 25 * 8, 0xF, "int"); } ////////////////////////////////////////////////////////////////////////////// void SetupInterrupt(u8 vector, u32 mask) { InterruptSetLevelMask(0xF); VdpPrintf(&testdispfont, 0 * 8, 25 * 8, 0xF, " "); VdpPrintf(&testdispfont, 0 * 8, 24 * 8, 0xF, "setup start"); intvector = vector; stagestatus = STAGESTAT_WAITINGFORINT; oldfunc = BIOS_GetSCUInterrupt(intvector); oldmask = BIOS_GetSCUInterruptMask(); BIOS_SetSCUInterrupt(intvector, testintfunc); isinttime = 1; BIOS_ChangeSCUInterruptMask(~mask, 0); VdpPrintf(&testdispfont, 0 * 8, 24 * 8, 0xF, "setup done "); } ////////////////////////////////////////////////////////////////////////////// void TestVBlankInInterrupt() { SetupInterrupt(0x40, 0x0001); InterruptSetLevelMask(0xE); } ////////////////////////////////////////////////////////////////////////////// void TestVBlankOutInterrupt() { SetupInterrupt(0x41, 0x0002); InterruptSetLevelMask(0xD); } ////////////////////////////////////////////////////////////////////////////// void TestHBlankInInterrupt() { SetupInterrupt(0x42, 0x0004); InterruptSetLevelMask(0xC); } ////////////////////////////////////////////////////////////////////////////// void TestTimer0Interrupt() { SetupInterrupt(0x43, 0x0008); // Enable Timer 0 SCUREG_T0C = 19; InterruptSetLevelMask(0xB); } ////////////////////////////////////////////////////////////////////////////// void TestTimer1Interrupt() { SCUREG_T1MD = 0; SCUREG_T1S = 100; SetupInterrupt(0x44, 0x0010); SCUREG_T1MD = 1; InterruptSetLevelMask(0xA); } ////////////////////////////////////////////////////////////////////////////// void TestDSPEndInterrupt() { SetupInterrupt(0x45, 0x0020); // Clear out program control port u32 testval = SCUREG_PPAF; // Make sure program is stopped, etc. SCUREG_PPAF = 0; // Setup DSP so we can send a program to it SCUREG_PPAF = 0x8000; // Upload our program(ENDI instruction) SCUREG_PPD = 0xF8000000; // Start executing program SCUREG_PPAF = 0x10000; InterruptSetLevelMask(0x9); } ////////////////////////////////////////////////////////////////////////////// void TestSoundRequestInterrupt() { SetupInterrupt(0x46, 0x0040); // Reset all Sound interrupts *((volatile u16*)0x25B0042E) = 0x7FF; // Set MCIEB to reset when we write to bit 5 of MCIPD *((volatile u16*)0x25B0042A) = 0x20; // trigger interrupt using MCIPD *((volatile u16*)0x25B0042C) = 0x20; InterruptSetLevelMask(0x8); } ////////////////////////////////////////////////////////////////////////////// void TestSMPCInterrupt() { SetupInterrupt(0x47, 0x0080); // Insert triggering mechanism here(fix me) SmpcWaitTillReady(); SMPC_REG_IREG(0) = 0x00; // no intback status SMPC_REG_IREG(1) = 0x0A; // 15-byte mode, peripheral data returned, time optimized SMPC_REG_IREG(2) = 0xF0; // ??? SmpcIssueCommand(SMPC_CMD_INTBACK); InterruptSetLevelMask(0x7); } ////////////////////////////////////////////////////////////////////////////// void TestPadInterrupt() { SetupInterrupt(0x48, 0x0100); // Insert triggering mechanism here(fix me) InterruptSetLevelMask(0x7); } ////////////////////////////////////////////////////////////////////////////// void TestDMA0Interrupt() { SetupInterrupt(0x4B, 0x0800); // Do a quick DMA SCUREG_D0EN = 0; SCUREG_D0R = 0x060F0000; SCUREG_D0W = 0x25C40000; SCUREG_D0C = 0x4; SCUREG_D0AD = 0x101; SCUREG_D0MD = 0x00000007; SCUREG_D0EN = 0x101; InterruptSetLevelMask(0x4); } ////////////////////////////////////////////////////////////////////////////// void TestDMA1Interrupt() { SetupInterrupt(0x4A, 0x0400); // Do a quick DMA SCUREG_D1EN = 0; SCUREG_D1R = 0x060F0000; SCUREG_D1W = 0x25C40000; SCUREG_D1C = 0x4; SCUREG_D1AD = 0x101; SCUREG_D1MD = 0x00000007; SCUREG_D1EN = 0x101; InterruptSetLevelMask(0x5); } ////////////////////////////////////////////////////////////////////////////// void TestDMA2Interrupt() { SetupInterrupt(0x49, 0x0200); // Do a quick DMA SCUREG_D2EN = 0; SCUREG_D2R = 0x060F0000; SCUREG_D2W = 0x25C40000; SCUREG_D2C = 0x4; SCUREG_D2AD = 0x101; SCUREG_D2MD = 0x00000007; SCUREG_D2EN = 0x101; InterruptSetLevelMask(0x5); } ////////////////////////////////////////////////////////////////////////////// void TestDMAIllegalInterrupt() { SetupInterrupt(0x4C, 0x1000); // Insert triggering mechanism here(fix me) // Do a quick DMA SCUREG_D0EN = 0; SCUREG_D0R = 0x060F0000; SCUREG_D0W = 0; SCUREG_D0C = 0x4; SCUREG_D0AD = 0x101; SCUREG_D0MD = 0x00000007; SCUREG_D0EN = 0x101; InterruptSetLevelMask(0x2); } ////////////////////////////////////////////////////////////////////////////// void TestSpriteDrawEndInterrupt() { sprite_struct localcoord; SetupInterrupt(0x4D, 0x2000); localcoord.attr = 0; localcoord.x = 0; localcoord.y = 0; VdpStartDrawList(); VdpLocalCoordinate(&localcoord); VdpEndDrawList(); InterruptSetLevelMask(0x1); } ////////////////////////////////////////////////////////////////////////////// void TestCDBlockInterrupt() { SetupInterrupt(0x50, 0x10000); // Unmask Subcode Q irq CDB_REG_HIRQ = ~HIRQ_SCDQ; CDB_REG_HIRQMASK = ~HIRQ_SCDQ; InterruptSetLevelMask(0x6); } ////////////////////////////////////////////////////////////////////////////// u32 dmavaltest; void dmaint (void) { BIOS_SetSCUInterrupt(0x49, 0); BIOS_SetSCUInterrupt(0x4A, 0); BIOS_SetSCUInterrupt(0x4B, 0); BIOS_ChangeSCUInterruptMask(0xFFFFFFFF, 0x800 | 0x400 | 0x200); if (*((volatile u32 *)0x25C40000) != dmavaltest) { stagestatus = STAGESTAT_BADDATA; return; } InterruptSetLevelMask(0xF); stagestatus = STAGESTAT_DONE; } ////////////////////////////////////////////////////////////////////////////// void TestDMA0() { dmavaltes... [truncated message content] |