1 // SPDX-License-Identifier: MIT
3 #include <proto/intuition.h>
5 #include <intuition/intuition.h>
6 #include <proto/exec.h>
8 #include <workbench/startup.h>
9 #include <clib/expansion_protos.h>
10 #include <libraries/reqtools.h>
11 #include <clib/reqtools_protos.h>
13 #include "pistorm_dev.h"
14 #include "../pistorm-dev-enums.h"
19 extern unsigned int pistorm_base_addr;
20 struct ReqToolsBase *ReqToolsBase;
22 #define VERSION "v0.2"
36 #define statusbarw 507
39 SHORT SharedBordersPairs0[] =
41 0, 0, 0, button1h - 1, 1, button1h - 2, 1, 0, button1w - 2, 0
43 SHORT SharedBordersPairs1[] =
45 1, button1h - 1, button1w - 2, button1h - 1, button1w - 2, 1, button1w - 1, 0, button1w - 1, button1h - 1
48 SHORT SharedBordersPairs2[] =
50 0, 0, 0, button3h - 1, 1, button3h - 2, 1, 0, button3w - 2, 0
52 SHORT SharedBordersPairs3[] =
54 1, button3h - 1, button3w - 2, button3h - 1, button3w - 2, 1, button3w - 1, 0, button3w - 1, button3h - 1
57 SHORT SharedBordersPairs4[] =
59 0, 0, 0, button2h - 1, 1, button2h - 2, 1, 0, button2w - 2, 0
61 SHORT SharedBordersPairs5[] =
63 1, button2h - 1, button2w - 2, button2h - 1, button2w - 2, 1, button2w - 1, 0, button2w - 1, button2h - 1
66 SHORT SharedBordersPairs6[] =
68 -2, -1, -2, tbox1h - 1, -1, tbox1h - 2, -1, -1, tbox1w - 2, -1
71 SHORT SharedBordersPairs7[] =
73 -1, tbox1h - 1, tbox1w - 2, tbox1h - 1, tbox1w - 2, 0, tbox1w - 1, -1, tbox1w - 1, tbox1h - 1
76 SHORT SharedBordersPairs8[] =
78 0, 0, statusbarw - 2, 0, statusbarw - 2, 0, 0, 0, 0, 0
81 SHORT SharedBordersPairs9[] =
83 0, 0, 0, tbox1h - 1, 1, tbox1h - 2, 1, 0, tbox1w - 2, 0
85 SHORT SharedBordersPairs10[] =
87 1, tbox1h - 1, tbox1w - 2, tbox1h - 1, tbox1w - 2, 1, tbox1w - 1, 0, tbox1w - 1, tbox1h - 1
91 struct Border SharedBorders[] =
93 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBorders[1], // Button 1
94 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
95 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBorders[3], // Button 3
96 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
97 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBorders[5], // Button 2
98 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
99 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs6[0], &SharedBorders[7], // TBox
100 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs7[0], NULL,
101 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs8[0], NULL, // Statusbar
102 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBorders[10], // TBox inverted
103 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
106 struct Border SharedBordersInvert[] =
108 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBordersInvert[1], // Button 1
109 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
110 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBordersInvert[3], // Button 3
111 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
112 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBordersInvert[5], // Button 2
113 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
114 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBordersInvert[7], // TBox inverted
115 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
118 UBYTE DestinationValue_buf[255];
120 struct IntuiText Destination_text[] =
122 1, 0, JAM2, -98, 6, NULL, "Destination:", &Destination_text[1],
123 1, 0, JAM2, 4, 4, NULL, DestinationValue_buf, NULL,
126 #define GADGETDESTINATION 11
128 struct Gadget GetDestination =
130 NULL, 108, 117, tbox1w, tbox1h,
134 (APTR) &SharedBorders[9], (APTR) &SharedBordersInvert[6],
135 Destination_text, 0, NULL, GADGETDESTINATION, NULL
138 struct IntuiText RebootButton_text =
140 1, 0, JAM2, 2, 6, NULL, (UBYTE *)"Reboot", NULL
145 struct Gadget RebootButton =
147 &GetDestination, 4, 166, button1w, button1h,
151 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
152 &RebootButton_text, 0, NULL, GADREBOOT, NULL
155 UBYTE StatusBar_buf[128] = "PiStorm...";
157 struct IntuiText StatusBar_text =
159 1, 0, JAM2, 4, 2, NULL, (UBYTE *)StatusBar_buf, NULL
162 #define GADSTATUSBAR 9
164 struct Gadget StatusBar =
166 &RebootButton, 3, 188, 508, 10,
170 (APTR) &SharedBorders[8], NULL,
171 &StatusBar_text, 0, NULL, GADSTATUSBAR, NULL
175 struct IntuiText RetrieveButton_text =
177 1, 0, JAM2, 10, 6, NULL, (UBYTE *)"Retrieve", NULL
180 #define GADRETRIEVEBUTTON 8
182 struct Gadget RetrieveButton =
184 &StatusBar, 244, 117, button2w, button2h,
188 (APTR) &SharedBorders[4], (APTR) &SharedBordersInvert[4],
189 &RetrieveButton_text, 0, NULL, GADRETRIEVEBUTTON, NULL
192 UBYTE GetFileValue_buf[255];
194 struct StringInfo GetFileValue =
196 GetFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
199 struct IntuiText GetFile_text[] =
201 1, 0, JAM2, -98, -15, NULL, "Get file", &GetFile_text[1],
202 1, 0, JAM2, -98, 4, NULL, "Source:", NULL,
207 struct Gadget GetFile =
209 &RetrieveButton, 108, 93, tbox1w, tbox1h,
213 (APTR) &SharedBorders[6], NULL,
214 GetFile_text, 0, (APTR)&GetFileValue, GADGETFILE, NULL
217 struct IntuiText ConfigDefault_text =
219 1, 0, JAM2, 2, 6, NULL, (UBYTE *)"Load Default", NULL
222 #define GADCONFIGDEFAULT 6
224 struct Gadget ConfigDefault =
226 &GetFile, 304, 39, button3w, button3h,
230 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
231 &ConfigDefault_text, 0, NULL, GADCONFIGDEFAULT, NULL
234 struct IntuiText ConfigCommit_text =
236 1, 0, JAM2, 2, 6, NULL, (UBYTE *)"Commit", NULL
239 #define GADCONFIGCOMMIT 5
241 struct Gadget ConfigCommit =
243 &ConfigDefault, 244, 39, button1w, button1h,
247 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
248 &ConfigCommit_text, 0, NULL, GADCONFIGCOMMIT, NULL
252 UBYTE ConfigFileValue_buf[255];
254 struct StringInfo ConfigFileValue =
256 ConfigFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
259 struct IntuiText ConfigFile_text =
261 1, 0, JAM2, -98, 4, NULL, "Config file:", NULL
264 #define GADCONFIGFILE 4
266 struct Gadget ConfigFile =
268 &ConfigCommit, 108, 41, tbox1w, tbox1h,
272 (APTR) &SharedBorders[6], NULL,
273 &ConfigFile_text, 0, (APTR)&ConfigFileValue, GADCONFIGFILE, NULL
276 UBYTE RTGStatus_buf[64] = "RTG status";
278 struct IntuiText RTGStatus_text =
280 1, 0, JAM2, 4, 4, NULL, (UBYTE *)RTGStatus_buf, NULL
283 #define GADRTGSTATUS 3
285 struct Gadget RTGStatus =
287 &ConfigFile, 14, 15, tbox1w, tbox1h,
291 (APTR) &SharedBorders[6], NULL,
292 &RTGStatus_text, 0, NULL, GADRTGSTATUS, NULL
295 UBYTE RTG_buf[64] = "RTG Enable";
297 struct IntuiText RTG_text =
299 1, 0, JAM2, 8, 6, NULL, (UBYTE *)RTG_buf, NULL
302 #define GADRTGBUTTON 2
304 struct Gadget RTGButton =
306 &RTGStatus, 150, 13, button3w, button3h,
310 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
311 &RTG_text, 0, NULL, GADRTGBUTTON, NULL
314 struct IntuiText AboutButton_text =
316 1, 0, JAM2, 8, 6, NULL, (UBYTE *)"About", NULL
321 struct Gadget AboutButton =
323 &RTGButton, 356, 166, button1w, button1h,
327 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
328 &AboutButton_text, 0, NULL, GADABOUT, NULL
332 struct IntuiText QuitButton_text =
334 1, 0, JAM2, 12, 6, NULL, (UBYTE *)"Quit", NULL
339 struct Gadget QuitButton =
341 &AboutButton, 438, 166, button1w, button1h,
345 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
346 &QuitButton_text, 0, NULL, GADQUIT, NULL
350 struct NewWindow winlayout =
355 CLOSEWINDOW | GADGETUP | GADGETDOWN,
356 ACTIVATE | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH,
358 (STRPTR)"PiStorm Interaction Tool",
365 // Pads what we are writing to screen with spaces, otherwise we get bits of
366 // old text still showing
367 static void WriteGadgetText(const char *text, UBYTE *buffer, struct Window *window, struct Gadget *gadget)
369 ULONG newlen = strlen(text);
370 ULONG oldlen = strlen((char *)buffer);
374 snprintf((char *)buffer, 64, "%s%*.*s", text, (int)(oldlen - newlen),
375 (int)(oldlen - newlen), " ");
379 strncpy((char *)buffer, text, 64);
382 RefreshGadgets(gadget, window, NULL);
384 static void updateRTG(struct Window *window)
386 unsigned short rtg = pi_get_rtg_status();
389 WriteGadgetText("Disable RTG", RTG_buf, window, &RTGButton);
392 WriteGadgetText("RTG in use", RTGStatus_buf, window, &RTGStatus);
396 WriteGadgetText("RTG not in use", RTGStatus_buf, window, &RTGStatus);
401 WriteGadgetText("Enable RTG", RTG_buf, window, &RTGButton);
402 WriteGadgetText("RTG disabled", RTGStatus_buf, window, &RTGStatus);
406 static char *GetSavePath()
408 struct rtFileRequester *filereq;
410 char *fullpath = malloc(256 * sizeof(char));
413 if ((filereq = (struct rtFileRequester*)rtAllocRequestA (RT_FILEREQ, NULL)))
417 if (!rtFileRequest(filereq, filename, "Pick a destination directory",
418 RTFI_Flags, FREQF_NOFILES, TAG_END))
427 rtEZRequest("Out of memory!", "Oh no!", NULL, NULL);
430 strncpy(fullpath, (char*)filereq->Dir, 256);
437 struct Window *myWindow;
439 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
440 if (IntuitionBase == NULL)
445 if (!(ReqToolsBase = (struct ReqToolsBase *)
446 OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
448 static struct IntuiText pos;
449 struct IntuiText msg[] =
451 1, 0, JAM2, 0, 0, NULL, "You need reqtools.library V38 or higher!.", &msg[1],
452 1, 0, JAM2, 0, 10, NULL, "Please install it in your Libs: drirectory.", NULL,
454 AutoRequest(NULL, msg, NULL, &pos, 0, 0, 0, 0);
458 pistorm_base_addr = pi_find_pistorm();
459 myWindow = OpenWindow(&winlayout);
460 BOOL no_board = FALSE;
462 if (pistorm_base_addr == 0xFFFFFFFF)
464 static struct IntuiText msg, pos;
465 msg.IText = "Unable to find PiStorm autoconf device.";
467 AutoRequest(myWindow, &msg, NULL, &pos, 0, 0, 0, 0);
469 WriteGadgetText("PiStorm not found", StatusBar_buf, myWindow, &StatusBar);
478 BOOL closewin = FALSE;
479 struct IntuiMessage *message;
480 Wait(1 << myWindow->UserPort->mp_SigBit);
482 while ((message = (struct IntuiMessage*)GetMsg(myWindow->UserPort)))
484 ULONG class = message->Class;
485 struct Gadget *address = (struct Gadget*)message->IAddress;
486 ReplyMsg((struct Message*)message);
488 if (class == CLOSEWINDOW)
492 else if (class == GADGETUP)
494 if (no_board && (address->GadgetID != GADQUIT) && (address->GadgetID != GADABOUT))
498 switch (address->GadgetID)
505 static struct IntuiText pos;
506 UBYTE buf[64], buf2[64], buf3[64];
509 unsigned short hw_rev = pi_get_hw_rev();
510 unsigned short sw_rev = pi_get_sw_rev();
511 snprintf((char*)buf2, 64, "PiStorm hardware: %d.%d", (hw_rev >> 8), (hw_rev & 0xFF));
512 snprintf((char*)buf3, 64, "PiStorm software: %d.%d", (sw_rev >> 8), (sw_rev & 0xFF));
516 snprintf((char*)buf2, 64, "PiStorm hardware not found!");
518 struct IntuiText msg[] =
520 1, 0, JAM2, 0, 0, NULL, (UBYTE *)buf, &msg[1],
521 1, 0, JAM2, 0, 10, NULL, "Tool written by beeanyew and LinuxJedi", &msg[2],
522 1, 0, JAM2, 0, 20, NULL, (UBYTE*)buf2, &msg[3],
523 1, 0, JAM2, 0, 30, NULL, (UBYTE*)buf3, &msg[4],
524 1, 0, JAM2, 0, 50, NULL, "Now with 53% more Nibbles!", NULL,
526 snprintf(buf, 64, "PiStorm Interaction Tool %s", VERSION);
528 AutoRequest(myWindow, msg, NULL, &pos, 0, 0, 0, 0);
533 unsigned short rtgStatus = pi_get_rtg_status() & 0x01;
534 pi_enable_rtg(!rtgStatus);
538 case GADCONFIGCOMMIT:
540 unsigned short ret = pi_handle_config(PICFG_LOAD, ConfigFileValue_buf);
541 if (ret == PI_RES_FILENOTFOUND)
543 static struct IntuiText msg, pos;
544 msg.IText = "PiStorm says: \"file not found\"";
546 AutoRequest(myWindow, &msg, NULL, &pos, 0, 0, 0, 0);
550 case GADCONFIGDEFAULT:
552 pi_handle_config(PICFG_DEFAULT, NULL);
555 case GADRETRIEVEBUTTON:
557 unsigned int filesize = 0;
561 if (pi_get_filesize(GetFileValue_buf, &filesize) == PI_RES_FILENOTFOUND)
563 static struct IntuiText msg, pos;
564 msg.IText = "PiStorm says: \"file not found\"";
566 AutoRequest(myWindow, &msg, NULL, &pos, 0, 0, 0, 0);
569 buf = malloc(filesize);
572 static struct IntuiText msg, pos;
573 msg.IText = "Could not allocate enough memory to transfer file";
575 AutoRequest(myWindow, &msg, NULL, &pos, 0, 0, 0, 0);
578 WriteGadgetText("Retrieving file...", StatusBar_buf, myWindow, &StatusBar);
579 if (pi_transfer_file(GetFileValue_buf, buf) != PI_RES_OK)
581 static struct IntuiText msg, pos;
582 msg.IText = "PiStorm says: \"something went wrong with the file transfer\"";
584 AutoRequest(myWindow, &msg, NULL, &pos, 0, 0, 0, 0);
585 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
589 char *fname = strrchr(GetFileValue_buf, '/');
592 fname = GetFileValue_buf;
594 char *destfile = malloc(256);
595 // Turns out WB doesn't like DF0:/filename.ext
596 if (DestinationValue_buf[(strlen(DestinationValue_buf) - 1)] == ':')
598 snprintf(destfile, 255, "%s%s", DestinationValue_buf, GetFileValue_buf);
600 else if (!strlen(DestinationValue_buf))
602 snprintf(destfile, 255, "%s", GetFileValue_buf);
606 snprintf(destfile, 255, "%s/%s", DestinationValue_buf, GetFileValue_buf);
608 BPTR fh = Open(destfile, MODE_NEWFILE);
612 snprintf(errbuf, 64, "Error code: %ld", IoErr());
613 struct IntuiText msg[] =
615 1, 0, JAM2, 0, 0, NULL, "Could not open file for writing", &msg[1],
616 1, 0, JAM2, 0, 10, NULL, destfile, &msg[2],
617 1, 0, JAM2, 0, 20, NULL, (UBYTE*)errbuf, NULL,
619 static struct IntuiText pos;
621 AutoRequest(myWindow, msg, NULL, &pos, 0, 0, 0, 0);
622 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
627 Write(fh, buf, filesize);
630 WriteGadgetText("File transfer complete", StatusBar_buf, myWindow, &StatusBar);
636 WriteGadgetText("Rebooting PiStorm", StatusBar_buf, myWindow, &StatusBar);
640 case GADGETDESTINATION:
642 char *fileName = GetSavePath();
645 WriteGadgetText(fileName, DestinationValue_buf, myWindow, &GetDestination);
661 if (myWindow) CloseWindow(myWindow);
662 CloseLibrary((struct Library*)ReqToolsBase);