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.3.4"
39 #define statusbarw 507
42 struct TextAttr font =
50 SHORT SharedBordersPairs0[] =
52 0, 0, 0, button1h - 1, 1, button1h - 2, 1, 0, button1w - 2, 0
54 SHORT SharedBordersPairs1[] =
56 1, button1h - 1, button1w - 2, button1h - 1, button1w - 2, 1, button1w - 1, 0, button1w - 1, button1h - 1
59 SHORT SharedBordersPairs2[] =
61 0, 0, 0, button3h - 1, 1, button3h - 2, 1, 0, button3w - 2, 0
63 SHORT SharedBordersPairs3[] =
65 1, button3h - 1, button3w - 2, button3h - 1, button3w - 2, 1, button3w - 1, 0, button3w - 1, button3h - 1
68 SHORT SharedBordersPairs4[] =
70 0, 0, 0, button2h - 1, 1, button2h - 2, 1, 0, button2w - 2, 0
72 SHORT SharedBordersPairs5[] =
74 1, button2h - 1, button2w - 2, button2h - 1, button2w - 2, 1, button2w - 1, 0, button2w - 1, button2h - 1
77 SHORT SharedBordersPairs6[] =
79 -2, -1, -2, tbox1h - 1, -1, tbox1h - 2, -1, -1, tbox1w - 2, -1
82 SHORT SharedBordersPairs7[] =
84 -1, tbox1h - 1, tbox1w - 2, tbox1h - 1, tbox1w - 2, 0, tbox1w - 1, -1, tbox1w - 1, tbox1h - 1
87 SHORT SharedBordersPairs8[] =
89 0, 0, statusbarw - 2, 0, statusbarw - 2, 0, 0, 0, 0, 0
92 SHORT SharedBordersPairs9[] =
94 0, 0, 0, tbox2h - 1, 1, tbox2h - 2, 1, 0, tbox2w - 2, 0
96 SHORT SharedBordersPairs10[] =
98 1, tbox2h - 1, tbox2w - 2, tbox2h - 1, tbox2w - 2, 1, tbox2w - 1, 0, tbox2w - 1, tbox2h - 1
102 struct Border SharedBorders[] =
104 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBorders[1], // Button 1
105 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
106 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBorders[3], // Button 3
107 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
108 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBorders[5], // Button 2
109 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
110 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs6[0], &SharedBorders[7], // TBox
111 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs7[0], NULL,
112 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs8[0], NULL, // Statusbar
113 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBorders[10], // TBox inverted
114 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
117 struct Border SharedBordersInvert[] =
119 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBordersInvert[1], // Button 1
120 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
121 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBordersInvert[3], // Button 3
122 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
123 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBordersInvert[5], // Button 2
124 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
125 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBordersInvert[7], // TBox inverted
126 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
129 struct IntuiText KickstartCommit_text =
131 1, 0, JAM2, 2, 2, &font, (UBYTE *)"Commit", NULL
134 #define GADKICKSTARTCOMMIT 14
136 struct Gadget KickstartCommit =
138 NULL, 401, 49, button1w, button1h,
142 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
143 &KickstartCommit_text, 0, NULL, GADKICKSTARTCOMMIT, NULL
147 UBYTE KickstartFileValue_buf[255];
149 struct StringInfo KickstartFileValue =
151 KickstartFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
154 struct IntuiText KickstartFile_text =
156 1, 0, JAM2, 0, -10, &font, "Kickstart file:", NULL
159 #define GADKICKSTARTFILE 13
161 struct Gadget KickstartFile =
163 &KickstartCommit, 266, 50, tbox1w, tbox1h,
167 (APTR) &SharedBorders[6], NULL,
168 &KickstartFile_text, 0, (APTR)&KickstartFileValue, GADKICKSTARTFILE, NULL
171 struct IntuiText ShutdownButton_text =
173 1, 0, JAM2, 2, 2, &font, (UBYTE *)"Shutdown Pi", NULL
176 #define GADSHUTDOWN 12
178 struct Gadget ShutdownButton =
180 &KickstartFile, 60, 166, button3w, button3h,
184 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
185 &ShutdownButton_text, 0, NULL, GADSHUTDOWN, NULL
189 UBYTE DestinationValue_buf[255];
191 struct IntuiText Destination_text[] =
193 1, 0, JAM2, -98, 1, &font, "Destination:", &Destination_text[1],
194 1, 0, JAM2, 1, 1, &font, DestinationValue_buf, NULL,
197 #define GADGETDESTINATION 11
199 struct Gadget GetDestination =
201 &ShutdownButton, 107, 105, tbox2w, tbox2h,
205 (APTR) &SharedBorders[9], (APTR) &SharedBordersInvert[6],
206 Destination_text, 0, NULL, GADGETDESTINATION, NULL
209 struct IntuiText RebootButton_text =
211 1, 0, JAM2, 2, 2, &font, (UBYTE *)"Reboot", NULL
216 struct Gadget RebootButton =
218 &GetDestination, 4, 166, button1w, button1h,
222 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
223 &RebootButton_text, 0, NULL, GADREBOOT, NULL
226 UBYTE StatusBar_buf[128] = "Reticulating splines...";
228 struct IntuiText StatusBar_text =
230 1, 0, JAM2, 4, 2, &font, (UBYTE *)StatusBar_buf, NULL
233 #define GADSTATUSBAR 9
235 struct Gadget StatusBar =
237 &RebootButton, 3, 188, 508, 10,
241 (APTR) &SharedBorders[8], NULL,
242 &StatusBar_text, 0, NULL, GADSTATUSBAR, NULL
246 struct IntuiText RetrieveButton_text =
248 1, 0, JAM2, 10, 2, &font, (UBYTE *)"Retrieve", NULL
251 #define GADRETRIEVEBUTTON 8
253 struct Gadget RetrieveButton =
255 &StatusBar, 244, 99, button2w, button2h,
259 (APTR) &SharedBorders[4], (APTR) &SharedBordersInvert[4],
260 &RetrieveButton_text, 0, NULL, GADRETRIEVEBUTTON, NULL
263 UBYTE GetFileValue_buf[255];
265 struct StringInfo GetFileValue =
267 GetFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
270 struct IntuiText GetFile_text[] =
272 1, 0, JAM2, -98, -10, &font, "Get file from PiStorm:", &GetFile_text[1],
273 1, 0, JAM2, -59, 1, &font, "Source:", NULL,
278 struct Gadget GetFile =
280 &RetrieveButton, 108, 93, tbox1w, tbox1h,
284 (APTR) &SharedBorders[6], NULL,
285 GetFile_text, 0, (APTR)&GetFileValue, GADGETFILE, NULL
288 struct IntuiText ConfigDefault_text =
290 1, 0, JAM2, 2, 2, &font, (UBYTE *)"Load Default", NULL
293 #define GADCONFIGDEFAULT 6
295 struct Gadget ConfigDefault =
297 &GetFile, 9, 62, button3w, button3h,
301 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
302 &ConfigDefault_text, 0, NULL, GADCONFIGDEFAULT, NULL
305 struct IntuiText ConfigCommit_text =
307 1, 0, JAM2, 2, 2, &font, (UBYTE *)"Commit", NULL
310 #define GADCONFIGCOMMIT 5
312 struct Gadget ConfigCommit =
314 &ConfigDefault, 144, 49, button1w, button1h,
318 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
319 &ConfigCommit_text, 0, NULL, GADCONFIGCOMMIT, NULL
323 UBYTE ConfigFileValue_buf[255];
325 struct StringInfo ConfigFileValue =
327 ConfigFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
330 struct IntuiText ConfigFile_text =
332 1, 0, JAM2, 0, -10, &font, "Config file:", NULL
335 #define GADCONFIGFILE 4
337 struct Gadget ConfigFile =
339 &ConfigCommit, 10, 50, tbox1w, tbox1h,
343 (APTR) &SharedBorders[6], NULL,
344 &ConfigFile_text, 0, (APTR)&ConfigFileValue, GADCONFIGFILE, NULL
347 UBYTE RTGStatus_buf[64] = "RTG status";
349 struct IntuiText RTGStatus_text =
351 1, 0, JAM2, 1, 1, &font, (UBYTE *)RTGStatus_buf, NULL
354 #define GADRTGSTATUS 3
356 struct Gadget RTGStatus =
358 &ConfigFile, 10, 20, tbox1w, tbox1h,
362 (APTR) &SharedBorders[6], NULL,
363 &RTGStatus_text, 0, NULL, GADRTGSTATUS, NULL
366 UBYTE RTG_buf[64] = "RTG Enable";
368 struct IntuiText RTG_text =
370 1, 0, JAM2, 8, 2, &font, (UBYTE *)RTG_buf, NULL
373 #define GADRTGBUTTON 2
375 struct Gadget RTGButton =
377 &RTGStatus, 144, 19, button3w, button3h,
381 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
382 &RTG_text, 0, NULL, GADRTGBUTTON, NULL
385 struct IntuiText AboutButton_text =
387 1, 0, JAM2, 8, 2, &font, (UBYTE *)"About", NULL
392 struct Gadget AboutButton =
394 &RTGButton, 356, 166, button1w, button1h,
398 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
399 &AboutButton_text, 0, NULL, GADABOUT, NULL
403 struct IntuiText QuitButton_text =
405 1, 0, JAM2, 12, 2, &font, (UBYTE *)"Quit", NULL
410 struct Gadget QuitButton =
412 &AboutButton, 438, 166, button1w, button1h,
416 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
417 &QuitButton_text, 0, NULL, GADQUIT, NULL
421 struct NewWindow winlayout =
426 CLOSEWINDOW | GADGETUP | GADGETDOWN,
427 ACTIVATE | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH,
429 (STRPTR)"PiStorm Interaction Tool",
436 // Pads what we are writing to screen with spaces, otherwise we get bits of
437 // old text still showing
438 static void WriteGadgetText(const char *text, UBYTE *buffer, struct Window *window, struct Gadget *gadget)
440 ULONG newlen = strlen(text);
441 ULONG oldlen = strlen((char *)buffer);
445 snprintf((char *)buffer, 64, "%s%*.*s", text, (int)(oldlen - newlen),
446 (int)(oldlen - newlen), " ");
450 strncpy((char *)buffer, text, 64);
453 RefreshGadgets(gadget, window, NULL);
455 static void updateRTG(struct Window *window)
457 unsigned short rtg = pi_get_rtg_status();
460 WriteGadgetText("Disable RTG", RTG_buf, window, &RTGButton);
463 WriteGadgetText("RTG in use", RTGStatus_buf, window, &RTGStatus);
467 WriteGadgetText("RTG not in use", RTGStatus_buf, window, &RTGStatus);
472 WriteGadgetText("Enable RTG", RTG_buf, window, &RTGButton);
473 WriteGadgetText("RTG disabled", RTGStatus_buf, window, &RTGStatus);
477 static char *GetSavePath()
479 struct rtFileRequester *filereq;
481 char *fullpath = malloc(256 * sizeof(char));
484 if ((filereq = (struct rtFileRequester*)rtAllocRequestA (RT_FILEREQ, NULL)))
488 if (!rtFileRequest(filereq, filename, "Pick a destination directory",
489 RTFI_Flags, FREQF_NOFILES, TAG_END))
498 rtEZRequest("Out of memory!", "Oh no!", NULL, NULL);
502 strncpy(fullpath, (char*)filereq->Dir, 256);
503 rtFreeRequest((APTR)filereq);
509 int res = rtEZRequest("This will restart the emulator, rebooting the Amiga\n"
511 "Yes|No", NULL, NULL);
517 struct Window *myWindow;
519 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
520 if (IntuitionBase == NULL)
525 if (!(ReqToolsBase = (struct ReqToolsBase *)
526 OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
528 static struct IntuiText pos;
529 struct IntuiText msg[] =
531 1, 0, JAM2, 0, 0, &font, "You need reqtools.library V38 or higher!.", &msg[1],
532 1, 0, JAM2, 0, 10, &font, "Please install it in your Libs: drirectory.", NULL,
534 AutoRequest(NULL, msg, NULL, &pos, 0, 0, 0, 0);
538 pistorm_base_addr = pi_find_pistorm();
539 myWindow = OpenWindow(&winlayout);
540 BOOL no_board = FALSE;
542 if (pistorm_base_addr == 0xFFFFFFFF)
544 rtEZRequest("Unable to find PiStorm autoconf device.",
547 WriteGadgetText("PiStorm not found", StatusBar_buf, myWindow, &StatusBar);
551 WriteGadgetText("PiStorm found!", StatusBar_buf, myWindow, &StatusBar);
560 BOOL closewin = FALSE;
561 struct IntuiMessage *message;
562 Wait(1 << myWindow->UserPort->mp_SigBit);
564 while ((message = (struct IntuiMessage*)GetMsg(myWindow->UserPort)))
566 ULONG class = message->Class;
567 struct Gadget *address = (struct Gadget*)message->IAddress;
568 ReplyMsg((struct Message*)message);
570 if (class == CLOSEWINDOW)
574 else if (class == GADGETUP)
576 if (no_board && (address->GadgetID != GADQUIT) && (address->GadgetID != GADABOUT))
580 switch (address->GadgetID)
587 static struct IntuiText pos;
588 char buf2[64], buf3[64];
591 unsigned short hw_rev = pi_get_hw_rev();
592 unsigned short sw_rev = pi_get_sw_rev();
593 snprintf(buf2, 64, "PiStorm hardware: %d.%d", (hw_rev >> 8), (hw_rev & 0xFF));
594 snprintf(buf3, 64, "PiStorm software: %d.%d", (sw_rev >> 8), (sw_rev & 0xFF));
598 snprintf(buf2, 64, "PiStorm hardware not found!");
600 rtEZRequest("PiStorm Interaction Tool %s\n"
601 "Tool written by beeanyew and LinuxJedi\n"
603 "Now with 53%% more Nibbles!",
604 "More Nibbles!", NULL, NULL, VERSION, buf2, buf3);
609 unsigned short rtgStatus = pi_get_rtg_status() & 0x01;
610 pi_enable_rtg(!rtgStatus);
614 case GADCONFIGCOMMIT:
616 if (!questionReboot())
621 unsigned short ret = pi_handle_config(PICFG_LOAD, ConfigFileValue_buf);
622 if (ret == PI_RES_FILENOTFOUND)
624 rtEZRequest("PiStorm says: \"file not found\"",
629 case GADCONFIGDEFAULT:
631 if (!questionReboot())
635 pi_handle_config(PICFG_DEFAULT, NULL);
638 case GADRETRIEVEBUTTON:
640 unsigned int filesize = 0;
644 if (pi_get_filesize(GetFileValue_buf, &filesize) == PI_RES_FILENOTFOUND)
646 rtEZRequest("PiStorm says: \"file not found\"",
650 buf = malloc(filesize);
653 rtEZRequest("Could not allocate enough memory to transfer file",
657 WriteGadgetText("Retrieving file...", StatusBar_buf, myWindow, &StatusBar);
658 if (pi_transfer_file(GetFileValue_buf, buf) != PI_RES_OK)
660 rtEZRequest("PiStorm says: \"something went wrong with the file transfer\"",
662 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
666 char *fname = strrchr(GetFileValue_buf, '/');
669 fname = GetFileValue_buf;
671 char *destfile = malloc(256);
672 // Turns out WB doesn't like DF0:/filename.ext
673 if (DestinationValue_buf[(strlen(DestinationValue_buf) - 1)] == ':')
675 snprintf(destfile, 255, "%s%s", DestinationValue_buf, GetFileValue_buf);
677 else if (!strlen(DestinationValue_buf))
679 snprintf(destfile, 255, "%s", GetFileValue_buf);
683 snprintf(destfile, 255, "%s/%s", DestinationValue_buf, GetFileValue_buf);
685 BPTR fh = Open(destfile, MODE_NEWFILE);
689 snprintf(errbuf, 64, "Error code: %ld", IoErr());
690 rtEZRequest("Could not open file for writing\n"
692 "OK", NULL, NULL, destfile, errbuf);
693 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
698 Write(fh, buf, filesize);
701 WriteGadgetText("File transfer complete", StatusBar_buf, myWindow, &StatusBar);
707 WriteGadgetText("Rebooting Amiga", StatusBar_buf, myWindow, &StatusBar);
711 case GADGETDESTINATION:
713 char *fileName = GetSavePath();
716 WriteGadgetText(fileName, DestinationValue_buf, myWindow, &GetDestination);
723 int res = rtEZRequest("This will shutdown the Pi and cause the Amiga to freeze\n"
725 "Yes|No", NULL, NULL);
730 WriteGadgetText("Shuttting down PiStorm...", StatusBar_buf, myWindow, &StatusBar);
731 int confirm = pi_shutdown_pi(0);
732 pi_confirm_shutdown(confirm);
735 case GADKICKSTARTCOMMIT:
737 if (!questionReboot())
742 unsigned short ret = pi_remap_kickrom(KickstartFileValue_buf);
743 if (ret == PI_RES_FILENOTFOUND)
745 rtEZRequest("PiStorm says: \"file not found\"",
762 if (myWindow) CloseWindow(myWindow);
763 CloseLibrary((struct Library*)ReqToolsBase);