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.3"
39 #define statusbarw 507
42 SHORT SharedBordersPairs0[] =
44 0, 0, 0, button1h - 1, 1, button1h - 2, 1, 0, button1w - 2, 0
46 SHORT SharedBordersPairs1[] =
48 1, button1h - 1, button1w - 2, button1h - 1, button1w - 2, 1, button1w - 1, 0, button1w - 1, button1h - 1
51 SHORT SharedBordersPairs2[] =
53 0, 0, 0, button3h - 1, 1, button3h - 2, 1, 0, button3w - 2, 0
55 SHORT SharedBordersPairs3[] =
57 1, button3h - 1, button3w - 2, button3h - 1, button3w - 2, 1, button3w - 1, 0, button3w - 1, button3h - 1
60 SHORT SharedBordersPairs4[] =
62 0, 0, 0, button2h - 1, 1, button2h - 2, 1, 0, button2w - 2, 0
64 SHORT SharedBordersPairs5[] =
66 1, button2h - 1, button2w - 2, button2h - 1, button2w - 2, 1, button2w - 1, 0, button2w - 1, button2h - 1
69 SHORT SharedBordersPairs6[] =
71 -2, -1, -2, tbox1h - 1, -1, tbox1h - 2, -1, -1, tbox1w - 2, -1
74 SHORT SharedBordersPairs7[] =
76 -1, tbox1h - 1, tbox1w - 2, tbox1h - 1, tbox1w - 2, 0, tbox1w - 1, -1, tbox1w - 1, tbox1h - 1
79 SHORT SharedBordersPairs8[] =
81 0, 0, statusbarw - 2, 0, statusbarw - 2, 0, 0, 0, 0, 0
84 SHORT SharedBordersPairs9[] =
86 0, 0, 0, tbox2h - 1, 1, tbox2h - 2, 1, 0, tbox2w - 2, 0
88 SHORT SharedBordersPairs10[] =
90 1, tbox2h - 1, tbox2w - 2, tbox2h - 1, tbox2w - 2, 1, tbox2w - 1, 0, tbox2w - 1, tbox2h - 1
94 struct Border SharedBorders[] =
96 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBorders[1], // Button 1
97 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
98 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBorders[3], // Button 3
99 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
100 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBorders[5], // Button 2
101 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
102 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs6[0], &SharedBorders[7], // TBox
103 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs7[0], NULL,
104 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs8[0], NULL, // Statusbar
105 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBorders[10], // TBox inverted
106 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
109 struct Border SharedBordersInvert[] =
111 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs0[0], &SharedBordersInvert[1], // Button 1
112 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs1[0], NULL,
113 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs2[0], &SharedBordersInvert[3], // Button 3
114 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs3[0], NULL,
115 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs4[0], &SharedBordersInvert[5], // Button 2
116 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs5[0], NULL,
117 0, 0, 1, 0, JAM2, 5, (SHORT *) &SharedBordersPairs9[0], &SharedBordersInvert[7], // TBox inverted
118 0, 0, 2, 0, JAM2, 5, (SHORT *) &SharedBordersPairs10[0], NULL,
121 struct IntuiText KickstartCommit_text =
123 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Commit", NULL
126 #define GADKICKSTARTCOMMIT 14
128 struct Gadget KickstartCommit =
130 NULL, 401, 49, button1w, button1h,
134 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
135 &KickstartCommit_text, 0, NULL, GADKICKSTARTCOMMIT, NULL
139 UBYTE KickstartFileValue_buf[255];
141 struct StringInfo KickstartFileValue =
143 KickstartFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
146 struct IntuiText KickstartFile_text =
148 1, 0, JAM2, 0, -10, NULL, "Kickstart file:", NULL
151 #define GADKICKSTARTFILE 13
153 struct Gadget KickstartFile =
155 &KickstartCommit, 266, 50, tbox1w, tbox1h,
159 (APTR) &SharedBorders[6], NULL,
160 &KickstartFile_text, 0, (APTR)&KickstartFileValue, GADKICKSTARTFILE, NULL
163 struct IntuiText ShutdownButton_text =
165 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Shutdown Pi", NULL
168 #define GADSHUTDOWN 12
170 struct Gadget ShutdownButton =
172 &KickstartFile, 60, 166, button3w, button3h,
176 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
177 &ShutdownButton_text, 0, NULL, GADSHUTDOWN, NULL
181 UBYTE DestinationValue_buf[255];
183 struct IntuiText Destination_text[] =
185 1, 0, JAM2, -98, 1, NULL, "Destination:", &Destination_text[1],
186 1, 0, JAM2, 1, 1, NULL, DestinationValue_buf, NULL,
189 #define GADGETDESTINATION 11
191 struct Gadget GetDestination =
193 &ShutdownButton, 107, 105, tbox2w, tbox2h,
197 (APTR) &SharedBorders[9], (APTR) &SharedBordersInvert[6],
198 Destination_text, 0, NULL, GADGETDESTINATION, NULL
201 struct IntuiText RebootButton_text =
203 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Reboot", NULL
208 struct Gadget RebootButton =
210 &GetDestination, 4, 166, button1w, button1h,
214 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
215 &RebootButton_text, 0, NULL, GADREBOOT, NULL
218 UBYTE StatusBar_buf[128] = "Reticulating splines...";
220 struct IntuiText StatusBar_text =
222 1, 0, JAM2, 4, 2, NULL, (UBYTE *)StatusBar_buf, NULL
225 #define GADSTATUSBAR 9
227 struct Gadget StatusBar =
229 &RebootButton, 3, 188, 508, 10,
233 (APTR) &SharedBorders[8], NULL,
234 &StatusBar_text, 0, NULL, GADSTATUSBAR, NULL
238 struct IntuiText RetrieveButton_text =
240 1, 0, JAM2, 10, 2, NULL, (UBYTE *)"Retrieve", NULL
243 #define GADRETRIEVEBUTTON 8
245 struct Gadget RetrieveButton =
247 &StatusBar, 244, 99, button2w, button2h,
251 (APTR) &SharedBorders[4], (APTR) &SharedBordersInvert[4],
252 &RetrieveButton_text, 0, NULL, GADRETRIEVEBUTTON, NULL
255 UBYTE GetFileValue_buf[255];
257 struct StringInfo GetFileValue =
259 GetFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
262 struct IntuiText GetFile_text[] =
264 1, 0, JAM2, -98, -10, NULL, "Get file from PiStorm:", &GetFile_text[1],
265 1, 0, JAM2, -59, 1, NULL, "Source:", NULL,
270 struct Gadget GetFile =
272 &RetrieveButton, 108, 93, tbox1w, tbox1h,
276 (APTR) &SharedBorders[6], NULL,
277 GetFile_text, 0, (APTR)&GetFileValue, GADGETFILE, NULL
280 struct IntuiText ConfigDefault_text =
282 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Load Default", NULL
285 #define GADCONFIGDEFAULT 6
287 struct Gadget ConfigDefault =
289 &GetFile, 9, 62, button3w, button3h,
293 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
294 &ConfigDefault_text, 0, NULL, GADCONFIGDEFAULT, NULL
297 struct IntuiText ConfigCommit_text =
299 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Commit", NULL
302 #define GADCONFIGCOMMIT 5
304 struct Gadget ConfigCommit =
306 &ConfigDefault, 144, 49, button1w, button1h,
310 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
311 &ConfigCommit_text, 0, NULL, GADCONFIGCOMMIT, NULL
315 UBYTE ConfigFileValue_buf[255];
317 struct StringInfo ConfigFileValue =
319 ConfigFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
322 struct IntuiText ConfigFile_text =
324 1, 0, JAM2, 0, -10, NULL, "Config file:", NULL
327 #define GADCONFIGFILE 4
329 struct Gadget ConfigFile =
331 &ConfigCommit, 10, 50, tbox1w, tbox1h,
335 (APTR) &SharedBorders[6], NULL,
336 &ConfigFile_text, 0, (APTR)&ConfigFileValue, GADCONFIGFILE, NULL
339 UBYTE RTGStatus_buf[64] = "RTG status";
341 struct IntuiText RTGStatus_text =
343 1, 0, JAM2, 1, 1, NULL, (UBYTE *)RTGStatus_buf, NULL
346 #define GADRTGSTATUS 3
348 struct Gadget RTGStatus =
350 &ConfigFile, 10, 15, tbox1w, tbox1h,
354 (APTR) &SharedBorders[6], NULL,
355 &RTGStatus_text, 0, NULL, GADRTGSTATUS, NULL
358 UBYTE RTG_buf[64] = "RTG Enable";
360 struct IntuiText RTG_text =
362 1, 0, JAM2, 8, 2, NULL, (UBYTE *)RTG_buf, NULL
365 #define GADRTGBUTTON 2
367 struct Gadget RTGButton =
369 &RTGStatus, 144, 14, button3w, button3h,
373 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
374 &RTG_text, 0, NULL, GADRTGBUTTON, NULL
377 struct IntuiText AboutButton_text =
379 1, 0, JAM2, 8, 2, NULL, (UBYTE *)"About", NULL
384 struct Gadget AboutButton =
386 &RTGButton, 356, 166, button1w, button1h,
390 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
391 &AboutButton_text, 0, NULL, GADABOUT, NULL
395 struct IntuiText QuitButton_text =
397 1, 0, JAM2, 12, 2, NULL, (UBYTE *)"Quit", NULL
402 struct Gadget QuitButton =
404 &AboutButton, 438, 166, button1w, button1h,
408 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
409 &QuitButton_text, 0, NULL, GADQUIT, NULL
413 struct NewWindow winlayout =
418 CLOSEWINDOW | GADGETUP | GADGETDOWN,
419 ACTIVATE | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH,
421 (STRPTR)"PiStorm Interaction Tool",
428 // Pads what we are writing to screen with spaces, otherwise we get bits of
429 // old text still showing
430 static void WriteGadgetText(const char *text, UBYTE *buffer, struct Window *window, struct Gadget *gadget)
432 ULONG newlen = strlen(text);
433 ULONG oldlen = strlen((char *)buffer);
437 snprintf((char *)buffer, 64, "%s%*.*s", text, (int)(oldlen - newlen),
438 (int)(oldlen - newlen), " ");
442 strncpy((char *)buffer, text, 64);
445 RefreshGadgets(gadget, window, NULL);
447 static void updateRTG(struct Window *window)
449 unsigned short rtg = pi_get_rtg_status();
452 WriteGadgetText("Disable RTG", RTG_buf, window, &RTGButton);
455 WriteGadgetText("RTG in use", RTGStatus_buf, window, &RTGStatus);
459 WriteGadgetText("RTG not in use", RTGStatus_buf, window, &RTGStatus);
464 WriteGadgetText("Enable RTG", RTG_buf, window, &RTGButton);
465 WriteGadgetText("RTG disabled", RTGStatus_buf, window, &RTGStatus);
469 static char *GetSavePath()
471 struct rtFileRequester *filereq;
473 char *fullpath = malloc(256 * sizeof(char));
476 if ((filereq = (struct rtFileRequester*)rtAllocRequestA (RT_FILEREQ, NULL)))
480 if (!rtFileRequest(filereq, filename, "Pick a destination directory",
481 RTFI_Flags, FREQF_NOFILES, TAG_END))
490 rtEZRequest("Out of memory!", "Oh no!", NULL, NULL);
494 strncpy(fullpath, (char*)filereq->Dir, 256);
495 rtFreeRequest((APTR)filereq);
501 int res = rtEZRequest("This will restart the emulator, rebooting the Amiga\n"
503 "Yes|No", NULL, NULL);
509 struct Window *myWindow;
511 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
512 if (IntuitionBase == NULL)
517 if (!(ReqToolsBase = (struct ReqToolsBase *)
518 OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
520 static struct IntuiText pos;
521 struct IntuiText msg[] =
523 1, 0, JAM2, 0, 0, NULL, "You need reqtools.library V38 or higher!.", &msg[1],
524 1, 0, JAM2, 0, 10, NULL, "Please install it in your Libs: drirectory.", NULL,
526 AutoRequest(NULL, msg, NULL, &pos, 0, 0, 0, 0);
530 pistorm_base_addr = pi_find_pistorm();
531 myWindow = OpenWindow(&winlayout);
532 BOOL no_board = FALSE;
534 if (pistorm_base_addr == 0xFFFFFFFF)
536 rtEZRequest("Unable to find PiStorm autoconf device.",
539 WriteGadgetText("PiStorm not found", StatusBar_buf, myWindow, &StatusBar);
543 WriteGadgetText("PiStorm found!", StatusBar_buf, myWindow, &StatusBar);
552 BOOL closewin = FALSE;
553 struct IntuiMessage *message;
554 Wait(1 << myWindow->UserPort->mp_SigBit);
556 while ((message = (struct IntuiMessage*)GetMsg(myWindow->UserPort)))
558 ULONG class = message->Class;
559 struct Gadget *address = (struct Gadget*)message->IAddress;
560 ReplyMsg((struct Message*)message);
562 if (class == CLOSEWINDOW)
566 else if (class == GADGETUP)
568 if (no_board && (address->GadgetID != GADQUIT) && (address->GadgetID != GADABOUT))
572 switch (address->GadgetID)
579 static struct IntuiText pos;
580 char buf2[64], buf3[64];
583 unsigned short hw_rev = pi_get_hw_rev();
584 unsigned short sw_rev = pi_get_sw_rev();
585 snprintf(buf2, 64, "PiStorm hardware: %d.%d", (hw_rev >> 8), (hw_rev & 0xFF));
586 snprintf(buf3, 64, "PiStorm software: %d.%d", (sw_rev >> 8), (sw_rev & 0xFF));
590 snprintf(buf2, 64, "PiStorm hardware not found!");
592 rtEZRequest("PiStorm Interaction Tool %s\n"
593 "Tool written by beeanyew and LinuxJedi\n"
595 "Now with 53%% more Nibbles!",
596 "More Nibbles!", NULL, NULL, VERSION, buf2, buf3);
601 unsigned short rtgStatus = pi_get_rtg_status() & 0x01;
602 pi_enable_rtg(!rtgStatus);
606 case GADCONFIGCOMMIT:
608 if (!questionReboot())
613 unsigned short ret = pi_handle_config(PICFG_LOAD, ConfigFileValue_buf);
614 if (ret == PI_RES_FILENOTFOUND)
616 rtEZRequest("PiStorm says: \"file not found\"",
621 case GADCONFIGDEFAULT:
623 if (!questionReboot())
627 pi_handle_config(PICFG_DEFAULT, NULL);
630 case GADRETRIEVEBUTTON:
632 unsigned int filesize = 0;
636 if (pi_get_filesize(GetFileValue_buf, &filesize) == PI_RES_FILENOTFOUND)
638 rtEZRequest("PiStorm says: \"file not found\"",
642 buf = malloc(filesize);
645 rtEZRequest("Could not allocate enough memory to transfer file",
649 WriteGadgetText("Retrieving file...", StatusBar_buf, myWindow, &StatusBar);
650 if (pi_transfer_file(GetFileValue_buf, buf) != PI_RES_OK)
652 rtEZRequest("PiStorm says: \"something went wrong with the file transfer\"",
654 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
658 char *fname = strrchr(GetFileValue_buf, '/');
661 fname = GetFileValue_buf;
663 char *destfile = malloc(256);
664 // Turns out WB doesn't like DF0:/filename.ext
665 if (DestinationValue_buf[(strlen(DestinationValue_buf) - 1)] == ':')
667 snprintf(destfile, 255, "%s%s", DestinationValue_buf, GetFileValue_buf);
669 else if (!strlen(DestinationValue_buf))
671 snprintf(destfile, 255, "%s", GetFileValue_buf);
675 snprintf(destfile, 255, "%s/%s", DestinationValue_buf, GetFileValue_buf);
677 BPTR fh = Open(destfile, MODE_NEWFILE);
681 snprintf(errbuf, 64, "Error code: %ld", IoErr());
682 rtEZRequest("Could not open file for writing\n"
684 "OK", NULL, NULL, destfile, errbuf);
685 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
690 Write(fh, buf, filesize);
693 WriteGadgetText("File transfer complete", StatusBar_buf, myWindow, &StatusBar);
699 WriteGadgetText("Rebooting Amiga", StatusBar_buf, myWindow, &StatusBar);
703 case GADGETDESTINATION:
705 char *fileName = GetSavePath();
708 WriteGadgetText(fileName, DestinationValue_buf, myWindow, &GetDestination);
715 int res = rtEZRequest("This will shutdown the Pi and cause the Amiga to freeze\n"
717 "Yes|No", NULL, NULL);
722 WriteGadgetText("Shuttting down PiStorm...", StatusBar_buf, myWindow, &StatusBar);
723 int confirm = pi_shutdown_pi(0);
724 pi_confirm_shutdown(confirm);
727 case GADKICKSTARTCOMMIT:
729 if (!questionReboot())
734 unsigned short ret = pi_remap_kickrom(KickstartFileValue_buf);
735 if (ret == PI_RES_FILENOTFOUND)
737 rtEZRequest("PiStorm says: \"file not found\"",
754 if (myWindow) CloseWindow(myWindow);
755 CloseLibrary((struct Library*)ReqToolsBase);