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.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 struct IntuiText KickstartCommit_text =
120 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Commit", NULL
123 #define GADKICKSTARTCOMMIT 14
125 struct Gadget KickstartCommit =
127 NULL, 406, 49, button1w, button1h,
131 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
132 &KickstartCommit_text, 0, NULL, GADKICKSTARTCOMMIT, NULL
136 UBYTE KickstartFileValue_buf[255];
138 struct StringInfo KickstartFileValue =
140 KickstartFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
143 struct IntuiText KickstartFile_text =
145 1, 0, JAM2, 0, -10, NULL, "Kickstart file:", NULL
148 #define GADKICKSTARTFILE 13
150 struct Gadget KickstartFile =
152 &KickstartCommit, 266, 50, tbox1w, tbox1h,
156 (APTR) &SharedBorders[6], NULL,
157 &KickstartFile_text, 0, (APTR)&KickstartFileValue, GADKICKSTARTFILE, NULL
160 struct IntuiText ShutdownButton_text =
162 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Shutdown Pi", NULL
165 #define GADSHUTDOWN 12
167 struct Gadget ShutdownButton =
169 &KickstartFile, 60, 166, button3w, button3h,
173 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
174 &ShutdownButton_text, 0, NULL, GADSHUTDOWN, NULL
178 UBYTE DestinationValue_buf[255];
180 struct IntuiText Destination_text[] =
182 1, 0, JAM2, -97, 1, NULL, "Destination:", &Destination_text[1],
183 1, 0, JAM2, 1, 1, NULL, DestinationValue_buf, NULL,
186 #define GADGETDESTINATION 11
188 struct Gadget GetDestination =
190 &ShutdownButton, 106, 105, tbox1w, tbox1h,
194 (APTR) &SharedBorders[9], (APTR) &SharedBordersInvert[6],
195 Destination_text, 0, NULL, GADGETDESTINATION, NULL
198 struct IntuiText RebootButton_text =
200 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Reboot", NULL
205 struct Gadget RebootButton =
207 &GetDestination, 4, 166, button1w, button1h,
211 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
212 &RebootButton_text, 0, NULL, GADREBOOT, NULL
215 UBYTE StatusBar_buf[128] = "Reticulating splines...";
217 struct IntuiText StatusBar_text =
219 1, 0, JAM2, 4, 2, NULL, (UBYTE *)StatusBar_buf, NULL
222 #define GADSTATUSBAR 9
224 struct Gadget StatusBar =
226 &RebootButton, 3, 188, 508, 10,
230 (APTR) &SharedBorders[8], NULL,
231 &StatusBar_text, 0, NULL, GADSTATUSBAR, NULL
235 struct IntuiText RetrieveButton_text =
237 1, 0, JAM2, 10, 2, NULL, (UBYTE *)"Retrieve", NULL
240 #define GADRETRIEVEBUTTON 8
242 struct Gadget RetrieveButton =
244 &StatusBar, 244, 105, button2w, button2h,
248 (APTR) &SharedBorders[4], (APTR) &SharedBordersInvert[4],
249 &RetrieveButton_text, 0, NULL, GADRETRIEVEBUTTON, NULL
252 UBYTE GetFileValue_buf[255];
254 struct StringInfo GetFileValue =
256 GetFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
259 struct IntuiText GetFile_text[] =
261 1, 0, JAM2, -98, -10, NULL, "Get file from PiStorm:", &GetFile_text[1],
262 1, 0, JAM2, -59, 1, NULL, "Source:", NULL,
267 struct Gadget GetFile =
269 &RetrieveButton, 108, 93, tbox1w, tbox1h,
273 (APTR) &SharedBorders[6], NULL,
274 GetFile_text, 0, (APTR)&GetFileValue, GADGETFILE, NULL
277 struct IntuiText ConfigDefault_text =
279 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Load Default", NULL
282 #define GADCONFIGDEFAULT 6
284 struct Gadget ConfigDefault =
286 &GetFile, 9, 62, button3w, button3h,
290 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
291 &ConfigDefault_text, 0, NULL, GADCONFIGDEFAULT, NULL
294 struct IntuiText ConfigCommit_text =
296 1, 0, JAM2, 2, 2, NULL, (UBYTE *)"Commit", NULL
299 #define GADCONFIGCOMMIT 5
301 struct Gadget ConfigCommit =
303 &ConfigDefault, 144, 49, button1w, button1h,
307 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
308 &ConfigCommit_text, 0, NULL, GADCONFIGCOMMIT, NULL
312 UBYTE ConfigFileValue_buf[255];
314 struct StringInfo ConfigFileValue =
316 ConfigFileValue_buf, NULL, 0, 255, 0, 0, 0, 0, 4, 4, NULL, 0, NULL
319 struct IntuiText ConfigFile_text =
321 1, 0, JAM2, 0, -10, NULL, "Config file:", NULL
324 #define GADCONFIGFILE 4
326 struct Gadget ConfigFile =
328 &ConfigCommit, 10, 50, tbox1w, tbox1h,
332 (APTR) &SharedBorders[6], NULL,
333 &ConfigFile_text, 0, (APTR)&ConfigFileValue, GADCONFIGFILE, NULL
336 UBYTE RTGStatus_buf[64] = "RTG status";
338 struct IntuiText RTGStatus_text =
340 1, 0, JAM2, 1, 1, NULL, (UBYTE *)RTGStatus_buf, NULL
343 #define GADRTGSTATUS 3
345 struct Gadget RTGStatus =
347 &ConfigFile, 14, 15, tbox1w, tbox1h,
351 (APTR) &SharedBorders[6], NULL,
352 &RTGStatus_text, 0, NULL, GADRTGSTATUS, NULL
355 UBYTE RTG_buf[64] = "RTG Enable";
357 struct IntuiText RTG_text =
359 1, 0, JAM2, 8, 2, NULL, (UBYTE *)RTG_buf, NULL
362 #define GADRTGBUTTON 2
364 struct Gadget RTGButton =
366 &RTGStatus, 150, 14, button3w, button3h,
370 (APTR) &SharedBorders[2], (APTR) &SharedBordersInvert[2],
371 &RTG_text, 0, NULL, GADRTGBUTTON, NULL
374 struct IntuiText AboutButton_text =
376 1, 0, JAM2, 8, 2, NULL, (UBYTE *)"About", NULL
381 struct Gadget AboutButton =
383 &RTGButton, 356, 166, button1w, button1h,
387 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
388 &AboutButton_text, 0, NULL, GADABOUT, NULL
392 struct IntuiText QuitButton_text =
394 1, 0, JAM2, 12, 2, NULL, (UBYTE *)"Quit", NULL
399 struct Gadget QuitButton =
401 &AboutButton, 438, 166, button1w, button1h,
405 (APTR) &SharedBorders[0], (APTR) &SharedBordersInvert[0],
406 &QuitButton_text, 0, NULL, GADQUIT, NULL
410 struct NewWindow winlayout =
415 CLOSEWINDOW | GADGETUP | GADGETDOWN,
416 ACTIVATE | WINDOWCLOSE | WINDOWDRAG | WINDOWDEPTH,
418 (STRPTR)"PiStorm Interaction Tool",
425 // Pads what we are writing to screen with spaces, otherwise we get bits of
426 // old text still showing
427 static void WriteGadgetText(const char *text, UBYTE *buffer, struct Window *window, struct Gadget *gadget)
429 ULONG newlen = strlen(text);
430 ULONG oldlen = strlen((char *)buffer);
434 snprintf((char *)buffer, 64, "%s%*.*s", text, (int)(oldlen - newlen),
435 (int)(oldlen - newlen), " ");
439 strncpy((char *)buffer, text, 64);
442 RefreshGadgets(gadget, window, NULL);
444 static void updateRTG(struct Window *window)
446 unsigned short rtg = pi_get_rtg_status();
449 WriteGadgetText("Disable RTG", RTG_buf, window, &RTGButton);
452 WriteGadgetText("RTG in use", RTGStatus_buf, window, &RTGStatus);
456 WriteGadgetText("RTG not in use", RTGStatus_buf, window, &RTGStatus);
461 WriteGadgetText("Enable RTG", RTG_buf, window, &RTGButton);
462 WriteGadgetText("RTG disabled", RTGStatus_buf, window, &RTGStatus);
466 static char *GetSavePath()
468 struct rtFileRequester *filereq;
470 char *fullpath = malloc(256 * sizeof(char));
473 if ((filereq = (struct rtFileRequester*)rtAllocRequestA (RT_FILEREQ, NULL)))
477 if (!rtFileRequest(filereq, filename, "Pick a destination directory",
478 RTFI_Flags, FREQF_NOFILES, TAG_END))
487 rtEZRequest("Out of memory!", "Oh no!", NULL, NULL);
491 strncpy(fullpath, (char*)filereq->Dir, 256);
492 rtFreeRequest((APTR)filereq);
498 int res = rtEZRequest("This will restart the emulator, rebooting the Amiga\n"
500 "Yes|No", NULL, NULL);
506 struct Window *myWindow;
508 IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 0);
509 if (IntuitionBase == NULL)
514 if (!(ReqToolsBase = (struct ReqToolsBase *)
515 OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION)))
517 static struct IntuiText pos;
518 struct IntuiText msg[] =
520 1, 0, JAM2, 0, 0, NULL, "You need reqtools.library V38 or higher!.", &msg[1],
521 1, 0, JAM2, 0, 10, NULL, "Please install it in your Libs: drirectory.", NULL,
523 AutoRequest(NULL, msg, NULL, &pos, 0, 0, 0, 0);
527 pistorm_base_addr = pi_find_pistorm();
528 myWindow = OpenWindow(&winlayout);
529 BOOL no_board = FALSE;
531 if (pistorm_base_addr == 0xFFFFFFFF)
533 rtEZRequest("Unable to find PiStorm autoconf device.",
536 WriteGadgetText("PiStorm not found", StatusBar_buf, myWindow, &StatusBar);
540 WriteGadgetText("PiStorm found!", StatusBar_buf, myWindow, &StatusBar);
549 BOOL closewin = FALSE;
550 struct IntuiMessage *message;
551 Wait(1 << myWindow->UserPort->mp_SigBit);
553 while ((message = (struct IntuiMessage*)GetMsg(myWindow->UserPort)))
555 ULONG class = message->Class;
556 struct Gadget *address = (struct Gadget*)message->IAddress;
557 ReplyMsg((struct Message*)message);
559 if (class == CLOSEWINDOW)
563 else if (class == GADGETUP)
565 if (no_board && (address->GadgetID != GADQUIT) && (address->GadgetID != GADABOUT))
569 switch (address->GadgetID)
576 static struct IntuiText pos;
577 char buf2[64], buf3[64];
580 unsigned short hw_rev = pi_get_hw_rev();
581 unsigned short sw_rev = pi_get_sw_rev();
582 snprintf(buf2, 64, "PiStorm hardware: %d.%d", (hw_rev >> 8), (hw_rev & 0xFF));
583 snprintf(buf3, 64, "PiStorm software: %d.%d", (sw_rev >> 8), (sw_rev & 0xFF));
587 snprintf(buf2, 64, "PiStorm hardware not found!");
589 rtEZRequest("PiStorm Interaction Tool %s\n"
590 "Tool written by beeanyew and LinuxJedi\n"
592 "Now with 53%% more Nibbles!",
593 "More Nibbles!", NULL, NULL, VERSION, buf2, buf3);
598 unsigned short rtgStatus = pi_get_rtg_status() & 0x01;
599 pi_enable_rtg(!rtgStatus);
603 case GADCONFIGCOMMIT:
605 if (!questionReboot())
609 unsigned short ret = pi_handle_config(PICFG_LOAD, ConfigFileValue_buf);
610 if (ret == PI_RES_FILENOTFOUND)
612 rtEZRequest("PiStorm says: \"file not found\"",
617 case GADCONFIGDEFAULT:
619 if (!questionReboot())
623 pi_handle_config(PICFG_DEFAULT, NULL);
626 case GADRETRIEVEBUTTON:
628 unsigned int filesize = 0;
632 if (pi_get_filesize(GetFileValue_buf, &filesize) == PI_RES_FILENOTFOUND)
634 rtEZRequest("PiStorm says: \"file not found\"",
638 buf = malloc(filesize);
641 rtEZRequest("Could not allocate enough memory to transfer file",
645 WriteGadgetText("Retrieving file...", StatusBar_buf, myWindow, &StatusBar);
646 if (pi_transfer_file(GetFileValue_buf, buf) != PI_RES_OK)
648 rtEZRequest("PiStorm says: \"something went wrong with the file transfer\"",
650 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
654 char *fname = strrchr(GetFileValue_buf, '/');
657 fname = GetFileValue_buf;
659 char *destfile = malloc(256);
660 // Turns out WB doesn't like DF0:/filename.ext
661 if (DestinationValue_buf[(strlen(DestinationValue_buf) - 1)] == ':')
663 snprintf(destfile, 255, "%s%s", DestinationValue_buf, GetFileValue_buf);
665 else if (!strlen(DestinationValue_buf))
667 snprintf(destfile, 255, "%s", GetFileValue_buf);
671 snprintf(destfile, 255, "%s/%s", DestinationValue_buf, GetFileValue_buf);
673 BPTR fh = Open(destfile, MODE_NEWFILE);
677 snprintf(errbuf, 64, "Error code: %ld", IoErr());
678 rtEZRequest("Could not open file for writing\n"
680 "OK", NULL, NULL, destfile, errbuf);
681 WriteGadgetText("File transfer failed", StatusBar_buf, myWindow, &StatusBar);
686 Write(fh, buf, filesize);
689 WriteGadgetText("File transfer complete", StatusBar_buf, myWindow, &StatusBar);
695 WriteGadgetText("Rebooting Amiga", StatusBar_buf, myWindow, &StatusBar);
699 case GADGETDESTINATION:
701 char *fileName = GetSavePath();
704 WriteGadgetText(fileName, DestinationValue_buf, myWindow, &GetDestination);
711 int res = rtEZRequest("This will shutdown the Pi and cause the Amiga to freeze\n"
713 "Yes|No", NULL, NULL);
718 WriteGadgetText("Shuttting down PiStorm...", StatusBar_buf, myWindow, &StatusBar);
719 int confirm = pi_shutdown_pi(0);
720 pi_confirm_shutdown(confirm);
723 case GADKICKSTARTCOMMIT:
725 if (!questionReboot())
729 unsigned short ret = pi_remap_kickrom(KickstartFileValue_buf);
730 if (ret == PI_RES_FILENOTFOUND)
732 rtEZRequest("PiStorm says: \"file not found\"",
749 if (myWindow) CloseWindow(myWindow);
750 CloseLibrary((struct Library*)ReqToolsBase);