; $VER: Install RGB2RTG 0.76-1 (17.10.2026)
;
; Installer script for RGB2RTG: the A1200's own picture on the Raspberry
; Pi's HDMI output, on a PiStorm32-lite with CaffeineOS, or with a plain
; AmigaOS 3.x on a card set up from Emu68's own config.txt. Everything it
; changes is backed up first, and Uninstall undoes every damn bit of it.
; The config.txt edits are done by C:rgb2rtg (INSTALL CONFIG), because the
; Installer language cannot edit a text file in place.
;
; Text rule, and do not forget it: the Installer centres every line, wraps
; at its window width (about 50 characters in the default font) and does not
; scroll - so no line here is over 44 characters and no window over about
; 11 lines. Details go in the (help) texts.

(set @app-name "RGB2RTG")
(set #ver "0.76-1")
(set #tool "Files/C/rgb2rtg")
; An archive unpacked on the Amiga (7z and zip keep no Amiga protection
; bits) leaves rgb2rtg without the e bit, and the shell flatly refuses to
; run the bastard: its INSTALL CHECK never ran, and AGA-PISTORM's tester
; was told their boot partition was not one (2026-10-02). Set it first, in
; pretend mode too, through the Protect command, whose failure is only a
; return code: a drawer on a FAT partition may not take protection bits,
; and the Installer's own (protect) would stop the install over that.
(run "Protect Files/C/rgb2rtg +e >NIL:" (safe))

(welcome (cat "RGB2RTG " #ver))

(message
  "RGB2RTG shows the A1200's own\n"
  "picture - games, demos, native\n"
  "screens - on the Raspberry Pi's\n"
  "HDMI output, switching with the\n"
  "RTG desktop.\n\n"
  "It installs the RGB2RTG kernel, its\n"
  "VideoCore 1.9 RTG driver, the\n"
  "rgb2rtg command and the RGB2RTG menu.\n\n"
  "Everything it changes is backed up\n"
  "first, and Uninstall puts it back."
  (all)
)

; ---- 1. can this Amiga run it? ------------------------------------------------
(working "Checking your Amiga...")
; INSTALL CHECK always returns 0, the smug thing: anything else means
; rgb2rtg did not run at all, and that must not be reported as a missing
; boot partition
(if (<> 0 (run (cat #tool " INSTALL CHECK >NIL:") (safe)))
  (abort "The installer's own tool,\n"
         "Files/C/rgb2rtg, could not run.\n\n"
         "Unpack the RGB2RTG archive\n"
         "again, or in a Shell in this\n"
         "drawer type:\n"
         "Protect Files/C/rgb2rtg +e\n\n"
         "Nothing was changed."))
; The Emu68 boot partition - EMU68: on CaffeineOS, but that is only its
; bloody label. rgb2rtg looks on every mounted partition for config.txt
; and the Pi firmware. When none has them the user shows which one it is,
; as often as it takes; Abort Install in the requester stops without a
; change. A plain AmigaOS 3.2 often has it unmounted (a 3.2 card here
; mounts it only from an icon, SYS:MOUNTFAT): the help says so.
(set #boot (getenv "RGB2RTG_BOOT"))
(while (= #boot "")
  (set #pick
    (askdir
      (prompt "Where is the Emu68 boot partition?\n\n"
              "It is the SD card's FAT partition\n"
              "with config.txt on it. Pick that\n"
              "disk in the list, then Proceed.")
      (help "The installer looks on every mounted partition for config.txt\n"
            "and the Pi firmware (start4.elf or start.elf), and found none.\n"
            "On CaffeineOS it is EMU68; on a card you set up yourself it\n"
            "has whatever name you gave it.\n\n"
            "On AmigaOS 3.2 it is often not mounted: open the icon that\n"
            "mounts it (MOUNTFAT on some cards, or one in Storage/DOSDrivers),\n"
            "then click Volumes in this requester to see it in the list.\n\n"
            "Pick the disk itself, not a drawer on it.\n\n"
            "Abort Install stops without changing anything.")
      (default "SYS:")
      (disk)))
  (run (cat #tool " INSTALL CHECK BOOT=\"" #pick "\" >NIL:") (safe))
  (set #boot (getenv "RGB2RTG_BOOT"))
  (if (= #boot "")
    (message #pick "\n\n"
             "is not the Emu68 boot partition:\n"
             "there is no config.txt on it.\n\n"
             "Pick the disk itself - the one\n"
             "with config.txt on it.")))
; config.txt and the overlays and kernel drawers under the names the
; partition already has them by, in whatever case (CONFIG.TXT and OVERLAYS
; on a plain 3.2 card): a FAT handler that matches case exactly would not
; find, or would duplicate, a name joined here - the pedantic bastard.
(set #cfgfile (getenv "RGB2RTG_CFGFILE"))
(if (= #cfgfile "") (set #cfgfile (tackon #boot "config.txt")))
(set #kdir (getenv "RGB2RTG_KDIR"))
(if (= #kdir "") (set #kdir (tackon #boot "kernel")))
(set #ovl (getenv "RGB2RTG_OVLDIR"))
(if (= #ovl "") (set #ovl (tackon #boot "overlays")))
(set #ps32   (getenv "RGB2RTG_PS32"))
(set #pi     (getenv "RGB2RTG_PI"))
(set #aga    (getenv "RGB2RTG_AGA"))
(set #write  (getenv "RGB2RTG_WRITABLE"))
(set #config (getenv "RGB2RTG_CONFIG"))
(set #hz50   (getenv "RGB2RTG_HDMI50"))
(set #dtbo   (getenv "RGB2RTG_DTBO"))
(set #blk50  (getenv "RGB2RTG_BLK50"))
; the Amiga's rate: 50 Hz, 60 for NTSC (the Video setting, else the machine's own)
(set #hz     (getenv "RGB2RTG_HZ"))
(set #ntsc   (getenv "RGB2RTG_NTSC"))
; a dtoverlay= line naming Emu68's overlays as another's settings (one a line)
(set #buried (getenv "RGB2RTG_BURIED"))
; the VideoCore monitor icon, when it says DisplayChain=No
(set #dchain (getenv "RGB2RTG_DCHAIN"))
; 1 when DEVS:Monitors has a monitor icon with BoardType=VideoCore at all
; (0 none, ? could not look)
(set #vcmon  (getenv "RGB2RTG_VCMON"))
; VC4_LEGACY_ID for the monitor: "1" to add, "2" to switch on, "0" nothing -
; decided before this driver replaces the old one (0.75-dev66)
(set #legacy (getenv "RGB2RTG_LEGACY"))
; 1 when a monitor's BoardType is Emu68-VC4 (AGS, AmiKit): the driver goes in
; as Emu68-VC4.card too
(set #e68    (getenv "RGB2RTG_E68VC4"))
; the Pi 4's SD card at 25 MHz: "2" the card's own setting, "1" mine, "0" none
(set #slow   (getenv "RGB2RTG_SLOW"))
(if (= #hz "") (set #hz "50"))

(if (<> #aga "1")
  (abort "RGB2RTG is for the A1200: it\n"
         "shows the picture of a real AGA\n"
         "chipset, and this Amiga has none.\n\n"
         "Nothing was changed."))

; "?" means the running kernel did not say (Emu68 tells the board and the
; Pi in its device tree; C:Emu68Info is asked too) - then ask the user
(if (= #ps32 "?")
  (if (askbool
        (prompt "Could not detect the PiStorm.\n\n"
                "Is it a PiStorm32-lite?")
        (help "RGB2RTG runs on the PiStorm32-lite in an A1200, with a\n"
              "Raspberry Pi 4 or 3. The kernel that is running did not say\n"
              "which PiStorm it found.")
        (choices "Yes" "No")
        (default 1))
    (set #ps32 "1")
    (set #ps32 "0")))
(if (<> #ps32 "1")
  (abort "RGB2RTG needs a PiStorm32-lite\n"
         "in an A1200.\n\n"
         "Nothing was changed."))

(if (= #pi "?")
  ((set #piwhich
     (askchoice
       (prompt "Could not detect the Raspberry Pi.\n\n"
               "Which one is on the PiStorm?")
       (help "Each Pi gets its own RGB2RTG kernel, made for its\n"
             "processor; either one also starts on the other Pi.")
       (choices "Pi 4 / CM4" "Pi 3" "Another one")
       (default 0)))
   (set #pi "0")
   (if (= #piwhich 0) (set #pi "4"))
   (if (= #piwhich 1) (set #pi "3"))))
(if (and (<> #pi "4") (<> #pi "3"))
  (abort "RGB2RTG needs a Raspberry Pi 4\n"
         "(or a Compute Module 4), or a\n"
         "Raspberry Pi 3.\n\n"
         "Nothing was changed."))

; CaffeineOS's [gpio24=0] section, or - on a card without board sections,
; as a plain AmigaOS 3.x has - its kernel= line, whatever file it names
(if (<> #config "1")
  (abort (cat #cfgfile "\n"
              "has no PiStorm32-lite section\n"
              "([gpio24=0]) and no kernel= line,\n"
              "so it cannot be set up.\n\n"
              "Nothing was changed.")))

; read-only, of course: a stock Emu68 1.1 kernel takes write access from
; its SD driver's overlay in config.txt alone (not cmdline.txt's
; sd.unit0=rw), and from here nothing can be written there - a PC has to,
; once. A Pi 3: the sdhc overlay, which the install then keeps (setup.c).
; A Pi 4: the RGB2RTG kernel by hand, which takes cmdline.txt's
; emmc.unit0=rw. (0.75 blamed the Pi 4's emmc overlay for damaged writes;
; wrongly - AGA-PISTORM showed it changes nothing there, 2026-10-09.
; Likely that test card. The kernel is still the simpler way.)
(if (<> #write "1")
  (abort (cat "The Emu68 boot partition is\n"
              "READ-ONLY. Nothing was changed.\n\n"
              (if (= #pi "3")
                (cat "On a PC, add this line to its\n"
                     "config.txt, on a line of its own:\n\n"
                     "  dtoverlay=sdhc,unit0=rw\n\n"
                     "and copy Files/Overlays/sdhc.dtbo\n"
                     "into its overlays folder.\n"
                     "(PC/SD-Setup.cmd, Prepare,\n"
                     "does both.) Then run this\n"
                     "installer again.")
                (cat "On a PC, copy\n"
                     "Files/Kernel/Pi4/Emu68-rgb2rtg.gz\n"
                     "into its kernel folder, point the\n"
                     "PiStorm32-lite's kernel= line in\n"
                     "config.txt at it, and make sure\n"
                     "cmdline.txt has emmc.unit0=rw.\n"
                     "Then start the Amiga and run this\n"
                     "installer again.")))))

; the RTG desktop: CaffeineOS has Picasso96, a plain AmigaOS 3.x may not
(if (= 0 (exists "SYS:Libs/Picasso96" (noreq)))
  (abort "Picasso96 was not found\n"
         "(SYS:Libs/Picasso96).\n\n"
         "RGB2RTG switches HDMI between the\n"
         "RTG desktop and the Amiga's own\n"
         "picture: install Picasso96 first.\n\n"
         "Nothing was changed."))

; ---- 2. one question: HDMI at the Amiga's rate --------------------------------
; asked only when config.txt does not already run HDMI at 1080p at that
; rate (50 Hz; 60 Hz for NTSC). HDMI50 is the command's word for either -
; one less damn thing to remember.
(set #opts "")
(if (<> #hz50 "1")
  (if (askbool
        (prompt "Set HDMI to 1080p at " #hz " Hz?\n\n"
                "Recommended: " (if (= #ntsc "1") "NTSC" "PAL") " games and demos\n"
                "run at " #hz " Hz, and only then is\n"
                "every frame shown exactly once.")
        (help "YES adds " (if (= #ntsc "1") "hdmi_group=2, hdmi_mode=82" "hdmi_group=1, hdmi_mode=31") " and\n"
              "hdmi_force_mode=1 to config.txt (in the RGB2RTG block, removed\n"
              "again by Uninstall). The RTG desktop then also runs at " #hz " Hz.\n"
              "Nearly every TV and monitor takes 1080p at " #hz " Hz.\n\n"
              (if (= #ntsc "1") "NO keeps your display setting. At 50 Hz the Amiga's 60 Hz\npicture loses every sixth frame, which judders." "NO keeps your display setting. At 60 Hz the Amiga's 50 Hz\npicture shows every fifth frame twice, which judders."))
        (choices "Yes (recommended)" "No")
        (default 1))
    (set #opts " HDMI50")))

; ---- 2b. the Pi 4's SD card at 25 MHz ---------------------------------------------
; On a Pi 4, Emu68's SD driver lost single writes at 50 MHz on cheap cards
; (Emu68 1.0.4 and 1.1 alike): a PFS3 block never reached the card, and the
; partition came up write-protected. At 25 MHz they were fine. Asked unless
; the card runs at 25 already of its own (#slow 2); LOWSPEED=ON puts
; emmc.low_speed into the cmdline file, which this kernel reads, OFF takes
; mine out again (0.75-dev67). Not in #opts: that one says HDMI50.
(set #slowopt "")
(if (and (= #pi "4") (<> #slow "2"))
  (if (askbool
        (prompt "Run the SD card at 25 MHz?\n\n"
                "Recommended: on a Pi 4 some SD\n"
                "cards lose writes at 50 MHz, and\n"
                "a partition then comes up\n"
                "damaged. 25 MHz is a little\n"
                "slower and safe.")
        (help "YES adds emmc.low_speed to the Emu68 command line (the\n"
              "cmdline.txt that config.txt names), which the RGB2RTG kernel\n"
              "reads: the SD card runs at 25 MHz instead of 50. Uninstall\n"
              "takes it out again.\n\n"
              "On a Pi 4, cheap SD cards lost single writes at 50 MHz - a\n"
              "PFS3 partition then came up \"write protected\". At 25 MHz\n"
              "they were fine. A good card (a SanDisk Ultra) is fine at 50,\n"
              "and reads a little faster there.\n\n"
              "NO keeps the card at 50 MHz.")
        (choices "Yes (recommended)" "No")
        (default 1))
    (set #slowopt " LOWSPEED=ON")
    (set #slowopt " LOWSPEED=OFF")))
(complete 10)

; ---- 3. the command -------------------------------------------------------------
(copyfiles (prompt "Installing rgb2rtg") (help @copyfiles-help)
  (source #tool) (dest "C:") (optional "force") (nogauge))
; the copy keeps the source's bits: make damn sure the boot and the menu can run it
(run "Protect C:rgb2rtg +e >NIL:")
(complete 20)

; ---- 4. the kernel, the overlay, then config.txt ------------------------------
(working "Copying the RGB2RTG kernel...")
; a card set up from Emu68's own config.txt keeps its kernel in the root
; and has no kernel drawer: mine goes into one either way (#kdir: see
; above). The kernel for this Pi, built for its processor (Files/Kernel/Pi3
; or Pi4; either starts on the other Pi too, should the card move), under
; the one name config.txt's kernel= line gives it.
(if (= 0 (exists #kdir (noreq)))
  (makedir #kdir))
(copyfiles (prompt "Installing the kernel") (help @copyfiles-help)
  (source (cat "Files/Kernel/Pi" #pi "/Emu68-rgb2rtg.gz")) (dest #kdir) (optional "force") (nogauge))
(if (<> #dtbo "1")
  ((if (= 0 (exists #ovl (noreq)))
     (makedir #ovl))
   (copyfiles (source "Files/Overlays/unicam.dtbo") (dest #ovl) (nogauge))))
(complete 40)

; the partition found or picked above, by name: the command's own search
; would not find one the user had to pick, the lazy sod
(if (<> 0 (run (cat "C:rgb2rtg INSTALL CONFIG" #opts #slowopt " BOOT=\"" #boot "\" >NIL:")))
  (abort "config.txt could not be changed.\n\n"
         "Your Amiga will start exactly\n"
         "as before. (The kernel file was\n"
         "copied; nothing uses it.)\n\n"
         "In a Shell, C:rgb2rtg INSTALL\n"
         "CONFIG says why."))
(complete 55)

; a unicam line of its own is in config.txt now (the card's, or my block's);
; the user's line still names overlays the Pi does not load (it takes one a
; line, the rest as that one's settings)
(if (<> #buried "")
  (message "config.txt has this line:\n\n"
           #buried "\n\n"
           "The Pi loads one overlay a line:\n"
           "the ones named after the first\n"
           "are not loaded. Split that line\n"
           "into dtoverlay= lines by hand.\n"
           "(The picture's unicam line is in.)"
           (all)))

; ---- 5. the RTG driver ----------------------------------------------------------
; Only now, once config.txt boots the RGB2RTG kernel: this VideoCore 1.9 is
; the build RGB2RTG is tested with (Astair86's changes to Michal Schulz's
; driver; source in the package). The one it replaces is kept, first time
; only, as VideoCore.card.pre-rgb2rtg - Uninstall puts the old bugger back.
(if (= 0 (exists "SYS:Libs/Picasso96/VideoCore.card.pre-rgb2rtg" (noreq)))
  (if (= 1 (exists "SYS:Libs/Picasso96/VideoCore.card" (noreq)))
    (copyfiles (source "SYS:Libs/Picasso96/VideoCore.card") (dest "SYS:Libs/Picasso96")
      (newname "VideoCore.card.pre-rgb2rtg") (nogauge))))
(copyfiles (prompt "Installing the VideoCore 1.9 RTG driver") (help @copyfiles-help)
  (source "Files/Libs/Picasso96/VideoCore.card") (dest "SYS:Libs/Picasso96") (optional "force") (nogauge))
; a monitor whose BoardType is Emu68-VC4 starts Emu68-VC4.card: the same
; driver under that name, the old one kept likewise, of course (0.75-dev66)
(if (= #e68 "1")
  ((if (= 0 (exists "SYS:Libs/Picasso96/Emu68-VC4.card.pre-rgb2rtg" (noreq)))
     (if (= 1 (exists "SYS:Libs/Picasso96/Emu68-VC4.card" (noreq)))
       (copyfiles (source "SYS:Libs/Picasso96/Emu68-VC4.card") (dest "SYS:Libs/Picasso96")
         (newname "Emu68-VC4.card.pre-rgb2rtg") (nogauge))))
   (copyfiles (source "Files/Libs/Picasso96/VideoCore.card") (dest "SYS:Libs/Picasso96")
     (newname "Emu68-VC4.card") (optional "force") (nogauge))))

; ---- 5b. HiFi sound: the HDMI driver for AHI -------------------------------------
; With AHI on this Amiga (DEVS:AHI), its driver to HDMI and the driver's
; modes: Prefs/AHI lists "RGB2RTG HDMI:..." from the next boot on, and the
; Sound window's HiFi line points AHI's units at it. Without AHI nothing is
; copied. Uninstall takes both away and gives AHI's units their modes back.
; exists answers 2 for a drawer (1 is a file): up to 0.75-dev47 this asked
; for 1, and of course the driver was never copied.
(if (= 2 (exists "DEVS:AHI" (noreq)))
  ((copyfiles (source "Files/AHI/rgb2rtg-hdmi.audio") (dest "DEVS:AHI") (optional "force") (nogauge))
   (if (= 0 (exists "DEVS:AudioModes" (noreq)))
     (makedir "DEVS:AudioModes"))
   (copyfiles (source "Files/AHI/RGB2RTG-HDMI") (dest "DEVS:AudioModes") (optional "force") (nogauge))))
(complete 70)

; ---- 6. the settings and the menu ------------------------------------------------
; HDMI sync (HDMI frames follow the Amiga's) only makes sense with HDMI at
; the Amiga's rate (50 Hz; 60 for NTSC). The first install sets the
; defaults; run again, the user's own settings stay - except that HDMI sync
; goes off when HDMI will not be at that rate, and on when this run sets the
; rate that was not there before. On a Pi 3 too since 0.75-test8 (tried on
; one: the bugger followed, and the lag fell from 33 to 27 ms).
(if (= 0 (exists "ENVARC:RGB2RTG.prefs" (noreq)))
  ((if (or (= #hz50 "1") (<> #opts ""))
     (run "C:rgb2rtg HDMISYNC=ON >NIL:")
     (run "C:rgb2rtg HDMISYNC=OFF >NIL:"))
   (run "C:rgb2rtg ON >NIL:"))
  ((if (and (<> #hz50 "1") (= #opts ""))
     (run "C:rgb2rtg HDMISYNC=OFF >NIL:"))
   (if (and (<> #opts "") (and (<> #blk50 "1") (<> #hz50 "1")))
     (run "C:rgb2rtg HDMISYNC=ON >NIL:"))))
(complete 80)

; Picasso96 hands HDMI to a native screen only with the VideoCore
; monitor in the display chain; and the screen modes made with an older
; driver work with this one only with VC4_LEGACY_ID in the monitor (the
; old board type - else the Workbench comes up on the native screen).
; The icon is kept first in DEVS:Monitors.pre-rgb2rtg (never in
; DEVS:Monitors itself: every file there is started at boot), and Uninstall
; puts the bastard back.
(if (or (<> #dchain "") (or (= #legacy "1") (= #legacy "2")))
  ((run "C:rgb2rtg INSTALL MONITOR >NIL:")
   (if (<> #dchain "")
     (message "The VideoCore monitor icon said\n"
              "DisplayChain=No: games and\n"
              "native screens would never\n"
              "reach HDMI.\n\n"
              "It says Yes now. Uninstall puts\n"
              "the icon back as it was."
              (all)))
   (if (or (= #legacy "1") (= #legacy "2"))
     (message "Your screen modes were made\n"
              "with an older VideoCore driver.\n"
              "So that they work with this one,\n"
              "the VideoCore monitor icon got\n"
              "VC4_LEGACY_ID - else the\n"
              "Workbench would come up on the\n"
              "native screen.\n\n"
              "Uninstall puts the icon back."
              (all)))))

; the RGB2RTG title: in Directory Opus 5's user menu and ToolsDaemon's file
; (CaffeineOS), or - on a plain AmigaOS 3.x, which has neither - in
; Workbench's own menu bar, up at once and at every boot. It says where,
; and it had better be right.
(if (<> 0 (run "C:rgb2rtg MENU >NIL:"))
  (message "The RGB2RTG menu could not be\n"
           "added everywhere.\n\n"
           "In a Shell, C:rgb2rtg MENU\n"
           "shows which file."
           (all)))
(set #menus (getenv "RGB2RTG_MENUS"))

; Picasso96 starts VideoCore.card only through a monitor icon in
; DEVS:Monitors whose BoardType is VideoCore: without one, the driver just
; installed never runs, the pointless sod. Making one (a copy of another
; monitor) is the user's, so the install goes on and says how; INSTALL
; MONITOR then sees to its DisplayChain. "?" (could not look) says
; nothing. After the menu: the message's Abort Install then only skips the
; closing window.
(if (= #vcmon "0")
  (message "Picasso96 starts VideoCore.card\n"
           "only through a monitor whose\n"
           "BOARDTYPE says VideoCore, and\n"
           "DEVS:Monitors has none.\n\n"
           "Copy another Picasso96 monitor\n"
           "there (Workbench: Icons menu, Copy),\n"
           "name the copy VideoCore and set its\n"
           "BOARDTYPE tooltype to VideoCore.\n"
           "Then in a Shell: C:rgb2rtg INSTALL\n"
           "MONITOR (it makes sure DisplayChain\n"
           "is not No), and power cycle."
           (all)))
(complete 100)

; where MENU put the title, e.g. "(in Workbench's menu bar)"
(set #in "")
(if (<> #menus "") (set #in (cat "(in " #menus ")\n")))
(exit
  "RGB2RTG is installed.\n\n"
  "Now POWER CYCLE the Amiga: switch\n"
  "it off, wait a few seconds, switch\n"
  "it on. (Ctrl-Amiga-Amiga is not\n"
  "enough.)\n\n"
  "Then start a game or a demo - its\n"
  "picture is on HDMI. Settings: the\n"
  "RGB2RTG menu on the desktop.\n"
  #in
  (quiet))
