1 // SPDX-License-Identifier: MIT
17 #include <sys/types.h>
19 #include <sys/ioctl.h>
21 #include "gpio/ps_protocol.h"
23 #define SIZE_KILO 1024
24 #define SIZE_MEGA (1024 * 1024)
25 #define SIZE_GIGA (1024 * 1024 * 1024)
27 uint8_t *garbege_datas;
28 extern volatile unsigned int *gpio;
35 uint8_t loop_tests = 0, total_errors = 0;
37 void sigint_handler(int sig_num) {
38 printf("Received sigint %d, exiting.\n", sig_num);
39 printf("Total number of transaction errors occured: %d\n", total_errors);
47 ps_reset_state_machine();
52 write8(0xbfe201, 0x0101); //CIA OVL
53 write8(0xbfe001, 0x0000); //CIA OVL LOW
56 unsigned int dump_read_8(unsigned int address) {
59 *(gpio + 0) = GPFSEL0_OUTPUT;
60 *(gpio + 1) = GPFSEL1_OUTPUT;
61 *(gpio + 2) = GPFSEL2_OUTPUT;
63 *(gpio + 7) = ((address & 0xffff) << 8) | (REG_ADDR_LO << PIN_A0);
64 *(gpio + 7) = 1 << PIN_WR;
65 *(gpio + 10) = 1 << PIN_WR;
66 *(gpio + 10) = 0xffffec;
68 *(gpio + 7) = ((0x0300 | (address >> 16)) << 8) | (REG_ADDR_HI << PIN_A0);
69 *(gpio + 7) = 1 << PIN_WR;
70 *(gpio + 10) = 1 << PIN_WR;
71 *(gpio + 10) = 0xffffec;
73 *(gpio + 0) = GPFSEL0_INPUT;
74 *(gpio + 1) = GPFSEL1_INPUT;
75 *(gpio + 2) = GPFSEL2_INPUT;
77 *(gpio + 7) = (REG_DATA << PIN_A0);
78 *(gpio + 7) = 1 << PIN_RD;
81 while (bwait < 10000 && (*(gpio + 13) & (1 << PIN_TXN_IN_PROGRESS))) {
85 unsigned int value = *(gpio + 13);
87 *(gpio + 10) = 0xffffec;
89 value = (value >> 8) & 0xffff;
95 if ((address & 1) == 0)
96 return (value >> 8) & 0xff; // EVEN, A0=0,UDS
98 return value & 0xff; // ODD , A0=1,LDS
101 int main(int argc, char *argv[]) {
102 uint32_t test_size = 512 * SIZE_KILO, cur_loop = 0;
104 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &f2);
105 srand((unsigned int)f2.tv_nsec);
107 signal(SIGINT, sigint_handler);
110 ps_reset_state_machine();
115 write8(0xbfe201, 0x0101); //CIA OVL
116 write8(0xbfe001, 0x0000); //CIA OVL LOW
119 if (strcmp(argv[1], "dumpkick") == 0) {
120 printf ("Dumping onboard Amiga kickstart from $F80000 to file kick.rom.\n");
121 printf ("Note that this will always dump 512KB of data, even if your Kickstart is 256KB.\n");
122 FILE *out = fopen("kick.rom", "wb+");
124 printf ("Failed to open kick.rom for writing.\nKickstart has not been dumped.\n");
128 for (int i = 0; i < 512 * SIZE_KILO; i++) {
129 unsigned char in = read8(0xF80000 + i);
134 printf ("Amiga Kickstart ROM dumped.\n");
138 if (strcmp(argv[1], "dump") == 0) {
139 printf ("Dumping EVERYTHING to dump.bin.\n");
140 FILE *out = fopen("dump.bin", "wb+");
142 printf ("Failed to open dump.bin for writing.\nEverything has not been dumped.\n");
146 for (int i = 0; i < 16 * SIZE_MEGA; i++) {
147 unsigned char in = dump_read_8(i);
155 printf ("Dumped everything.\n");
159 test_size = atoi(argv[1]) * SIZE_KILO;
160 if (test_size == 0 || test_size > 2 * SIZE_MEGA) {
161 test_size = 512 * SIZE_KILO;
163 printf("Testing %d KB of memory.\n", test_size / SIZE_KILO);
165 if (strcmp(argv[2], "l") == 0) {
166 printf("Looping tests.\n");
172 garbege_datas = malloc(test_size);
173 if (!garbege_datas) {
174 printf ("Failed to allocate memory for garbege datas.\n");
179 printf("Writing garbege datas.\n");
180 for (uint32_t i = 0; i < test_size; i++) {
181 while(garbege_datas[i] == 0x00)
182 garbege_datas[i] = (uint8_t)(rand() % 0xFF);
183 write8(i, (uint32_t)garbege_datas[i]);
186 printf("Reading back garbege datas, read8()...\n");
187 for (uint32_t i = 0; i < test_size; i++) {
188 uint32_t c = read8(i);
189 if (c != garbege_datas[i]) {
191 printf("READ8: Garbege data mismatch at $%.6X: %.2X should be %.2X.\n", i, c, garbege_datas[i]);
195 printf("read8 errors total: %d.\n", errors);
196 total_errors += errors;
200 printf("Reading back garbege datas, read16(), even addresses...\n");
201 for (uint32_t i = 0; i < (test_size) - 2; i += 2) {
202 uint32_t c = be16toh(read16(i));
203 if (c != *((uint16_t *)&garbege_datas[i])) {
205 printf("READ16_EVEN: Garbege data mismatch at $%.6X: %.4X should be %.4X.\n", i, c, *((uint16_t *)&garbege_datas[i]));
209 printf("read16 even errors total: %d.\n", errors);
210 total_errors += errors;
214 printf("Reading back garbege datas, read16(), odd addresses...\n");
215 for (uint32_t i = 1; i < (test_size) - 2; i += 2) {
216 uint32_t c = be16toh((read8(i) << 8) | read8(i + 1));
217 if (c != *((uint16_t *)&garbege_datas[i])) {
219 printf("READ16_ODD: Garbege data mismatch at $%.6X: %.4X should be %.4X.\n", i, c, *((uint16_t *)&garbege_datas[i]));
223 printf("read16 odd errors total: %d.\n", errors);
227 printf("Reading back garbege datas, read32(), even addresses...\n");
228 for (uint32_t i = 0; i < (test_size) - 4; i += 2) {
229 uint32_t c = be32toh(read32(i));
230 if (c != *((uint32_t *)&garbege_datas[i])) {
232 printf("READ32_EVEN: Garbege data mismatch at $%.6X: %.8X should be %.8X.\n", i, c, *((uint32_t *)&garbege_datas[i]));
236 printf("read32 even errors total: %d.\n", errors);
237 total_errors += errors;
241 printf("Reading back garbege datas, read32(), odd addresses...\n");
242 for (uint32_t i = 1; i < (test_size) - 4; i += 2) {
243 uint32_t c = read8(i);
244 c |= (be16toh(read16(i + 1)) << 8);
245 c |= (read8(i + 3) << 24);
246 if (c != *((uint32_t *)&garbege_datas[i])) {
248 printf("READ32_ODD: Garbege data mismatch at $%.6X: %.8X should be %.8X.\n", i, c, *((uint32_t *)&garbege_datas[i]));
252 printf("read32 odd errors total: %d.\n", errors);
253 total_errors += errors;
257 printf("Clearing %d KB of Chip again\n", test_size / SIZE_KILO);
258 for (uint32_t i = 0; i < test_size; i++) {
259 write8(i, (uint32_t)0x0);
262 printf("[WORD] Writing garbege datas to Chip, unaligned...\n");
263 for (uint32_t i = 1; i < (test_size) - 2; i += 2) {
264 uint16_t v = *((uint16_t *)&garbege_datas[i]);
265 write8(i, (v & 0x00FF));
266 write8(i + 1, (v >> 8));
270 printf("Reading back garbege datas, read16(), odd addresses...\n");
271 for (uint32_t i = 1; i < (test_size) - 2; i += 2) {
272 uint32_t c = be16toh((read8(i) << 8) | read8(i + 1));
273 if (c != *((uint16_t *)&garbege_datas[i])) {
275 printf("READ16_ODD: Garbege data mismatch at $%.6X: %.4X should be %.4X.\n", i, c, *((uint16_t *)&garbege_datas[i]));
279 printf("read16 odd errors total: %d.\n", errors);
280 total_errors += errors;
283 printf("Clearing %d KB of Chip again\n", test_size / SIZE_KILO);
284 for (uint32_t i = 0; i < test_size; i++) {
285 write8(i, (uint32_t)0x0);
288 printf("[LONG] Writing garbege datas to Chip, unaligned...\n");
289 for (uint32_t i = 1; i < (test_size) - 4; i += 4) {
290 uint32_t v = *((uint32_t *)&garbege_datas[i]);
291 write8(i , v & 0x0000FF);
292 write16(i + 1, htobe16(((v & 0x00FFFF00) >> 8)));
293 write8(i + 3 , (v & 0xFF000000) >> 24);
297 printf("Reading back garbege datas, read32(), odd addresses...\n");
298 for (uint32_t i = 1; i < (test_size) - 4; i += 4) {
299 uint32_t c = read8(i);
300 c |= (be16toh(read16(i + 1)) << 8);
301 c |= (read8(i + 3) << 24);
302 if (c != *((uint32_t *)&garbege_datas[i])) {
304 printf("READ32_ODD: Garbege data mismatch at $%.6X: %.8X should be %.8X.\n", i, c, *((uint32_t *)&garbege_datas[i]));
308 printf("read32 odd errors total: %d.\n", errors);
309 total_errors += errors;
313 printf ("Loop %d done. Begin loop %d.\n", cur_loop + 1, cur_loop + 2);
314 printf ("Current total errors: %d.\n", total_errors);
321 void m68k_set_irq(unsigned int level) {