gint's control and diagnostic application.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

main.c 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include <stdarg.h>
  4. #define GINT_NEED_VRAM
  5. #include <gint/timer.h>
  6. #include <gint/clock.h>
  7. #include <gint/rtc.h>
  8. #include <gint/keyboard.h>
  9. #include <gint/display.h>
  10. #ifdef FXCG50
  11. extern void PrintXY(int x, int y, const char *str, int, int);
  12. extern void Bdisp_PutDisp_DD(void);
  13. extern void Bdisp_AllClr_VRAM();
  14. #define color_white 0xffff
  15. #endif
  16. void print_bin(int x, int y, uint32_t bin, int digits)
  17. {
  18. char str[33];
  19. str[digits] = 0;
  20. while(--digits >= 0)
  21. {
  22. str[digits] = '0' + (bin & 1);
  23. bin >>= 1;
  24. }
  25. print(x, y, str);
  26. }
  27. #if 0
  28. int callback(void *arg)
  29. {
  30. volatile int *counter = arg;
  31. (*counter)++;
  32. return *counter == 7;
  33. }
  34. void test_clock(void)
  35. {
  36. const clock_frequency_t *freq = clock_freq();
  37. dclear(color_white);
  38. print(1, 1, "FLL: %8d", freq->FLL);
  39. print(1, 2, "PLL: %8d", freq->PLL);
  40. print(1, 3, "div1: B%3d I%3d P%3d",
  41. freq->Bphi_div, freq->Iphi_div, freq->Pphi_dev);
  42. print(1, 5, "Bphi = %10d", freq->Bphi_f);
  43. print(1, 6, "Iphi = %10d", freq->Iphi_f);
  44. print(1, 7, "Pphi = %10d", freq->Pphi_f);
  45. dupdate();
  46. getkey();
  47. volatile unsigned int *FRQCRA = (void *)0xa4150000;
  48. volatile unsigned int *FRQCRB = (void *)0xa4150004;
  49. volatile unsigned int *PLLCR = (void *)0xa4150024;
  50. volatile unsigned int *FLLFRQ = (void *)0xa4150050;
  51. dclear(color_white);
  52. print(1, 1, "%8x", *FRQCRA);
  53. print(1, 2, "%8x", *FRQCRB);
  54. print(1, 3, "%8x", *PLLCR);
  55. print(1, 4, "%8x", *FLLFRQ);
  56. dupdate();
  57. getkey();
  58. }
  59. void test_timer_simultaneous(void)
  60. {
  61. volatile int counters[9] = { 0 };
  62. int count = timer_count();
  63. for(int tid = 0; tid < count; tid++)
  64. {
  65. timer_setup(tid, timer_delay(tid, 1000000), timer_default,
  66. callback, (void *)&counters[tid]);
  67. }
  68. for(int tid = 0; tid < count; tid++) timer_start(tid);
  69. int limit;
  70. #ifdef FX9860G
  71. limit = 4000;
  72. #else
  73. limit = 500;
  74. #endif
  75. for(int i = 0; i < limit; i++)
  76. {
  77. dclear(color_white);
  78. for(int k = 0; k < 9; k++)
  79. print(2 * k + 1, 1, "%1x", counters[k]);
  80. print(1, 8, "%4d", i);
  81. dupdate();
  82. }
  83. for(int tid = 0; tid < count; tid++) timer_free(tid);
  84. }
  85. void test_rtc_time(void)
  86. {
  87. rtc_time_t time;
  88. int limit;
  89. #ifdef FX9860G
  90. limit = 1500;
  91. #else
  92. limit = 200;
  93. #endif
  94. for(int i = 0; i < limit; i++)
  95. {
  96. const char *days[7] = {
  97. "Sunday", "Monday", "Tuesday", "Wednesday",
  98. "Thursday", "Friday", "Saturday",
  99. };
  100. dclear(color_white);
  101. rtc_get_time(&time);
  102. print(1, 1, "%2d:%2d:%2d",
  103. time.hours, time.minutes, time.seconds);
  104. print(1, 2, "%2d-%2d-%4d %s",
  105. time.month_day, time.month, time.year,
  106. days[time.week_day]);
  107. print(1, 8, "%4d", i);
  108. dupdate();
  109. }
  110. }
  111. volatile int test_rtc_int_flag = 0;
  112. int test_rtc_int_callback(UNUSED void *arg)
  113. {
  114. static int count = 0;
  115. count++;
  116. print(7, 1, "%2d", count);
  117. Bdisp_PutDisp_DD();
  118. test_rtc_int_flag = (count == 10);
  119. return test_rtc_int_flag;
  120. }
  121. void test_rtc_int(void)
  122. {
  123. test_rtc_int_flag = 0;
  124. rtc_start_timer(rtc_1Hz, test_rtc_int_callback, NULL);
  125. uint32_t vbr = 0x8800df00;
  126. vbr += 0x600;
  127. vbr += 0x20;
  128. vbr += 0xaa0 - 0x400;
  129. vbr += 20;
  130. Bdisp_AllClr_VRAM();
  131. print(1, 1, "count=");
  132. Bdisp_PutDisp_DD();
  133. while(!test_rtc_int_flag) __asm__("sleep");
  134. delay(100);
  135. /* Not needed since the callback stops the timer
  136. rtc_stop_timer(); */
  137. }
  138. /* Count how many interrupts I can process in a second */
  139. volatile int test_timer_stress_counter = 0;
  140. volatile int test_timer_stress_done = 0;
  141. int test_timer_stress_callback(void *arg)
  142. {
  143. volatile int *counter = arg;
  144. (*counter)++;
  145. return 0;
  146. }
  147. int test_timer_stress_stop(UNUSED void *arg)
  148. {
  149. timer_pause(0);
  150. timer_free(0);
  151. test_timer_stress_done = 1;
  152. return 1;
  153. }
  154. int test_timer_stress_start(UNUSED void *arg)
  155. {
  156. rtc_start_timer(rtc_1Hz, test_timer_stress_stop, NULL);
  157. timer_start(0);
  158. return 0;
  159. }
  160. void test_timer_stress(void)
  161. {
  162. int length = 0;
  163. gint_intlevel(isSH3() ? 3 : 40, 15);
  164. Bdisp_AllClr_VRAM();
  165. print(1, 1, "Testing...");
  166. Bdisp_PutDisp_DD();
  167. timer_setup(0, timer_delay(0, length), timer_default,
  168. test_timer_stress_callback, (void*)&test_timer_stress_counter);
  169. rtc_start_timer(rtc_1Hz, test_timer_stress_start, NULL);
  170. do __asm__("sleep");
  171. while(!test_timer_stress_done);
  172. Bdisp_AllClr_VRAM();
  173. print(1, 1, "Test finished!");
  174. print(1, 2, "length = %8d ms", length);
  175. print(1, 3, "Processed interrupts:");
  176. print(1, 4, "%7d", test_timer_stress_counter);
  177. Bdisp_PutDisp_DD();
  178. gint_intlevel(isSH3() ? 3 : 40, 5);
  179. delay(60);
  180. }
  181. #endif
  182. #define TEST_TIMER_FREQ_LIMIT 64
  183. #define TEST_TIMER_FREQ_RTC RTC_16Hz
  184. #define TEST_TIMER_FREQ_TIMER 62500
  185. #define TEST_TIMER_FREQ_TID 7
  186. #include <gint/mpu/rtc.h>
  187. int test_timer_freq_callback(volatile void *arg)
  188. {
  189. volatile int *counter = arg;
  190. (*counter)++;
  191. return (*counter == TEST_TIMER_FREQ_LIMIT);
  192. }
  193. int test_timer_freq_start(volatile void *arg)
  194. {
  195. rtc_start_timer(TEST_TIMER_FREQ_RTC, test_timer_freq_callback, arg);
  196. timer_start(TEST_TIMER_FREQ_TID);
  197. return 0;
  198. }
  199. void test_timer_freq(void)
  200. {
  201. volatile int tmu = 0, rtc = 0;
  202. int tid = TEST_TIMER_FREQ_TID;
  203. timer_setup(tid, timer_delay(tid, TEST_TIMER_FREQ_TIMER),
  204. timer_default, test_timer_freq_callback, &tmu);
  205. rtc_start_timer(TEST_TIMER_FREQ_RTC, test_timer_freq_start, &rtc);
  206. while(rtc < TEST_TIMER_FREQ_LIMIT)
  207. {
  208. dclear(color_white);
  209. print(1, 1, "TMU %4x", tmu);
  210. print(1, 2, "RTC %4x", rtc);
  211. dupdate();
  212. }
  213. }
  214. void display_keys(volatile uint8_t *keys)
  215. {
  216. for(int r = 0; r < 8; r++) print_bin(1, r + 1, keys[r ^ 1], 8);
  217. for(int r = 0; r < 4; r++) print_bin(10, r + 1, keys[(r + 8) ^ 1], 8);
  218. }
  219. void keysc_userland(void)
  220. {
  221. volatile uint16_t *KEYSC = (void *)0xa44b0000;
  222. uint16_t buffer[6];
  223. for(int counter = 0; counter < 4000; counter++)
  224. {
  225. for(int i = 0; i < 6; i++) buffer[i] = KEYSC[i];
  226. if(buffer[3] & 0x0800) break;
  227. dclear(color_white);
  228. display_keys((volatile uint8_t *)buffer);
  229. dupdate();
  230. }
  231. }
  232. int keysc_callback(volatile void *arg)
  233. {
  234. volatile uint16_t *buf = arg;
  235. volatile uint16_t *KEYSC = (void *)0xa44b0000;
  236. for(int i = 0; i < 6; i++) buf[i] = KEYSC[i];
  237. return 0;
  238. }
  239. void keysc_timer(void)
  240. {
  241. volatile uint16_t buffer[6] = { 0 };
  242. int tid = 3;
  243. /* 32 gives 1024 Hz */
  244. /* 2048 gives 16 Hz */
  245. #define DELAY 256
  246. timer_setup(tid, DELAY, 0, keysc_callback, &buffer);
  247. timer_start(tid);
  248. dclear(color_white);
  249. #ifdef FX9860G
  250. # define LIMIT 4000
  251. #else
  252. # define LIMIT 500
  253. #endif
  254. for(int counter = 0; counter < LIMIT; counter++)
  255. {
  256. display_keys((volatile uint8_t *)buffer);
  257. print(18, 8, "%4d", counter);
  258. dupdate();
  259. }
  260. timer_stop(tid);
  261. }
  262. void test_kbd(void)
  263. {
  264. key_event_t ev;
  265. key_event_t last = { .type = KEYEV_NONE };
  266. const char *names[4] = { "NONE", "DOWN", "UP ", "HOLD" };
  267. extern int time;
  268. int pressed[12][8];
  269. for(int i = 0; i < 12; i++) for(int j = 0; j < 8; j++) pressed[i][j]=0;
  270. dclear(color_white);
  271. while(1)
  272. {
  273. while((ev = pollevent()).type != KEYEV_NONE)
  274. {
  275. last = ev;
  276. if(ev.type == KEYEV_DOWN && ev.key == KEY_EXIT) return;
  277. int row = ev.key >> 4;
  278. int col = ev.key & 0xf;
  279. if(ev.type == KEYEV_DOWN) pressed[row][col] = 1;
  280. if(ev.type == KEYEV_UP) pressed[row][col] = 0;
  281. }
  282. print(1, 4, "[%4d]", time);
  283. print(1, 5, "%2x %s", last.key, names[last.type]);
  284. for(int i = 0; i < 8; i++)
  285. {
  286. int x = (i < 8) ? 13 : 2;
  287. int y = (i < 8) ? 8 - i : 12 - i;
  288. for(int j = 0; j < 8; j++)
  289. // Bdisp_SetPoint_VRAM(80 + 2 * j, 2 + 2 * i,
  290. // pressed[i][j]);
  291. print(x + j, y, pressed[i][j] ? "#" : "-");
  292. }
  293. extern volatile uint8_t state[12];
  294. print(1,1,"%x %x %x %x",state[0],state[1],state[2],state[3]);
  295. print(1,2,"%x %x %x %x",state[4],state[5],state[6],state[7]);
  296. print(1,3,"%x %x %x %x",state[8],state[9],state[10],state[11]);
  297. dupdate();
  298. }
  299. }
  300. /* tmu_t - a single timer from a standard timer unit */
  301. typedef volatile struct
  302. {
  303. uint32_t TCOR; /* Constant register */
  304. uint32_t TCNT; /* Counter register, counts down */
  305. word_union(TCR,
  306. uint16_t :7;
  307. uint16_t UNF :1; /* Underflow flag */
  308. uint16_t :2;
  309. uint16_t UNIE :1; /* Underflow interrupt enable */
  310. uint16_t CKEG :2; /* Input clock edge */
  311. uint16_t TPSC :3; /* Timer prescaler (input clock) */
  312. );
  313. } GPACKED(4) tmu_t;
  314. /* tmu_extra_t - extra timers on sh7337, sh7355 and sh7305 */
  315. typedef volatile struct
  316. {
  317. uint8_t TSTR; /* Only bit 0 is used */
  318. pad(3);
  319. uint32_t TCOR; /* Constant register */
  320. uint32_t TCNT; /* Counter register */
  321. byte_union(TCR,
  322. uint8_t :6;
  323. uint8_t UNF :1; /* Underflow flag */
  324. uint8_t UNIE :1; /* Underflow interrupt enable */
  325. );
  326. } GPACKED(4) tmu_extra_t;
  327. /* This is the description of the structure on SH4. SH3-based fx9860g models,
  328. which are already very rare, will adapt the values in init functions */
  329. tmu_t *std[3] = {
  330. (void *)0xa4490008,
  331. (void *)0xa4490014,
  332. (void *)0xa4490020,
  333. };
  334. tmu_extra_t *ext[6] = {
  335. (void *)0xa44d0030,
  336. (void *)0xa44d0050,
  337. (void *)0xa44d0070,
  338. (void *)0xa44d0090,
  339. (void *)0xa44d00b0,
  340. (void *)0xa44d00d0,
  341. };
  342. tmu_t *std3[3] = {
  343. (void *)0xfffffe94,
  344. (void *)0xfffffea0,
  345. (void *)0xfffffeac,
  346. };
  347. tmu_extra_t *ext3[1] = {
  348. (void *)0xa44c0030,
  349. };
  350. void initial_timer_status(void)
  351. {
  352. dclear(color_white);
  353. print(1, 1, "STR");
  354. print(1, 2, "TCR");
  355. print(1, 3, "COR");
  356. print(1, 4, "CNT");
  357. print(1, 5, "TCR");
  358. print(1, 6, "COR");
  359. print(1, 7, "CNT");
  360. for(int i = 0; i < 3; i++)
  361. {
  362. tmu_t *t = (isSH3() ? std3[i] : std[i]);
  363. print(5 + 5*i, 5, "%4x", t->TCR.word);
  364. print(5 + 5*i, 6, (t->TCOR == 0xffffffff) ? "ffff" : "????");
  365. print(5 + 5*i, 7, (t->TCNT == 0xffffffff) ? "ffff" : "????");
  366. }
  367. for(int i = 0; i < (isSH3() ? 1 : 6); i++)
  368. {
  369. tmu_extra_t *t = (isSH3() ? ext3[i] : ext[i]);
  370. print(5 + 3*i, 1, "%2x", t->TSTR);
  371. print(5 + 3*i, 2, "%2x", t->TCR.byte);
  372. print(5 + 3*i, 3, (t->TCOR == 0xffffffff) ? "ff" : "??");
  373. print(5 + 3*i, 4, (t->TCNT == 0xffffffff) ? "ff" : "??");
  374. }
  375. dupdate();
  376. }
  377. #ifdef FX9860G
  378. void fx_frame1(void)
  379. {
  380. dclear(color_white);
  381. for(int x = 0; x < 256; x += 4) vram[x] = vram[x + 1] = 0xffffffff;
  382. for(int r = 0; r <= 8; r += 2)
  383. {
  384. for(int x = r; x < 64 - r; x++)
  385. {
  386. dpixel(x, r, color_reverse);
  387. dpixel(x, 127 - r, color_reverse);
  388. }
  389. for(int y = r + 1; y < 128 - r; y++)
  390. {
  391. dpixel(r, y, color_reverse);
  392. dpixel(63 - r, y, color_reverse);
  393. }
  394. }
  395. dupdate();
  396. }
  397. void fx_frame2(void)
  398. {
  399. dclear(color_white);
  400. for(int x = 20; x <= 88; x += 68)
  401. for(int y = 10; y <= 44; y += 34)
  402. {
  403. // drect(x, y, 20, 10, color_black);
  404. }
  405. dline(64, 32, 84, 32, color_reverse);
  406. dline(64, 32, 78, 18, color_reverse);
  407. dline(64, 32, 64, 12, color_reverse);
  408. dline(64, 32, 50, 18, color_reverse);
  409. dline(64, 32, 44, 32, color_reverse);
  410. dline(64, 32, 44, 46, color_reverse);
  411. dline(64, 32, 64, 52, color_reverse);
  412. dline(64, 32, 78, 46, color_reverse);
  413. }
  414. #endif
  415. typedef void asm_text_t(uint32_t *v1, uint32_t *v2, uint32_t *op, int height);
  416. extern asm_text_t *topti_asm_text[8];
  417. static void show_bootlog(void)
  418. {
  419. extern char gint_bootlog[22*9];
  420. int i = 0;
  421. for(int y = 0; y < 9; y++)
  422. {
  423. for(int x = 0; x < 21; x++)
  424. {
  425. if(!gint_bootlog[i]) gint_bootlog[i] = ' ';
  426. i++;
  427. }
  428. gint_bootlog[i] = 0;
  429. i++;
  430. }
  431. dclear(color_white);
  432. for(int y = 0; y < 9; y++)
  433. print(1, y + 1, gint_bootlog + 22 * y);
  434. dupdate();
  435. getkey();
  436. }
  437. int main(GUNUSED int isappli, GUNUSED int optnum)
  438. {
  439. #ifdef FX9860G
  440. // extern image_t pattern;
  441. // extern image_t pattern2;
  442. /* image_t *img = &pattern;
  443. uint32_t *data = (void *)&img->data;
  444. for(int i = 0; i < 32; i++) vram[4 * i] = data[i];
  445. dupdate();
  446. getkey();
  447. fx_frame1();
  448. getkey();
  449. fx_frame2();
  450. getkey(); */
  451. int x = 0, y = 0, k = 0, w, h;
  452. while(k != KEY_EXIT)
  453. {
  454. dclear(color_white);
  455. // bopti_render_clip(x, y, &pattern2, 0, 0, 48, 16);
  456. dtext(x, y, "Hello, World!", color_white, color_black);
  457. dsize("Hello, World!", NULL, &w, &h);
  458. drect(x, y, x + w - 1, y + h - 1, color_reverse);
  459. dupdate();
  460. k = getkey().key;
  461. if(k == KEY_LEFT /* && x > 2 */) x-=3;
  462. if(k == KEY_RIGHT /* && x < 92 */) x+=3;
  463. if(k == KEY_UP /* && y > 2 */) y-=3;
  464. if(k == KEY_DOWN /* && y < 30 */) y+=3;
  465. }
  466. #endif
  467. /* #ifdef FXCG50
  468. initial_timer_status();
  469. Bdisp_PutDisp_DD();
  470. getkey();
  471. #endif */
  472. #ifdef FXCG50
  473. #define rgb(r, g, b) ((r << 11) | (g << 5) | b)
  474. dclear(0xf800);
  475. for(int i = 1; i <= 10; i++)
  476. {
  477. drect(i, i, 395 - i, 223 - i, (i & 1) ? 0xffff: 0xf800);
  478. }
  479. int cx = 100, cy = 100;
  480. int r = 30;
  481. drect(cx-r, cy-r, cx+r, cy+r, 0xffff);
  482. for(int k = -r; k <= r; k += 10)
  483. {
  484. dline(cx, cy, cx+k, cy-r, 0x0000);
  485. dline(cx, cy, cx+k, cy+r, 0x0000);
  486. dline(cx, cy, cx-r, cy+k, 0x0000);
  487. dline(cx, cy, cx+r, cy+k, 0x0000);
  488. }
  489. for(int y = 0; y < 20; y++)
  490. for(int x = 0; x < 20; x++)
  491. {
  492. dpixel(180+x, 30+y, ((x^y) & 1)
  493. ? rgb(10, 21, 10)
  494. : rgb(21, 43, 21));
  495. }
  496. dupdate();
  497. getkey();
  498. for(int y = 0; y < 224; y++)
  499. for(int x = 0; x < 396; x++)
  500. {
  501. int v = y >> 3;
  502. int h = x >> 3;
  503. vram[396 * y + x] = 0x3eb7 ^ ((v << 11) + (h << 5) + v);
  504. }
  505. volatile int flag = 0;
  506. int iterations = 0;
  507. timer_setup(0, timer_delay(0, 1000 * 1000), 0, timer_timeout, &flag);
  508. timer_start(0);
  509. while(!flag) r61524_display(vram, 0, 224), iterations++;
  510. Bdisp_AllClr_VRAM();
  511. print(1, 1, "%3d FPS", iterations);
  512. Bdisp_PutDisp_DD();
  513. getkey();
  514. #endif
  515. return 0;
  516. }