{{ message }}
Repository navigation
Conversation
Moves the RAM1/RAM2 8K bank allocator, the image preload and the numbered button save out of IOH_REU.c into RAMBanks.c, so the GeoRAM handler can use the same code. The REU keeps its own bank array and count: SerUSBIO's busy check reads NumREU_Banks to mean the REU's DMA is live, which a GeoRAM must not trip. Behavior is unchanged except that the save writes whole banks instead of a byte at a time.
A Berkeley Softworks geoRAM: the $DE00 page window onto RAM banks from RAMBanks.c, with the page ($DFFE) and 16K block ($DFFF) registers decoded across $DF80-$DFFF the way VICE does, leaving $DF00-$DF7F free. No DMA, so it is in every full build, TR and TR+, and serves C64 and C128 mode alike. Up to 512K, as much as fits beside a loaded crt; preloads SD:/georam.ram, and the special button saves the next free georamNNN.ram. Freed with the REU wherever the menu reclaims RAM.
A short write (card full, drive pulled) printed "Saved" and flashed the save LED. Load stops at a read error rather than adding -1 to its count.
…om one shared page
Placed before Debug it moved Debug's number, and that number is what eepAdNextIOHndlr stores, so a board saved with Debug as its default came up on GeoRAM. After Debug, with LastSelectableIOH moved to it, every selectable handler keeps the number it had.
The TR's USB host port takes a mouse; the main loop adds up its movement and the IO handlers hand it to the C64 as signed steps, at $DF00 beside GeoRAM and $DE00 beside the REU, in the halves of the IO area each one leaves free. A 1351 can't be emulated: the SID's POT lines are not on the cartridge port, so this is for software with a TR driver. Each read of X or Y returns the movement since the last read of it, at most 127 steps, and keeps the rest for the next one, so a fast mouse is not lost between polls. Only the main loop writes the USB totals and only the IO ISR writes what it has handed out, so neither needs a lock.
trmouse.py assembles trmouse128.asm and writes it to a GEOS 128 boot D81 as TR USB MOUSE, in the directory entry ahead of the other input drivers, because GEOS loads the first one it finds. The driver finds the TR's registers by their ID at $DF03, else uses $DE00, doubles X in 80 columns as the stock 1351 driver does, and leaves clamping to the kernal, which flags a push past an edge for apps that scroll on it.
…, and drops buttons on unplug
…and drains movement while the pointer is off Without a TR handler serving either page, the driver read open bus at $DE00 as motion and a held button, so the pointer jumped and clicked on its own. Movement made while mouseOn was clear stayed in the TR's counters and swept the pointer across the screen once it came back on.
…d directory chain GEOS reads the permanent name's version from offset 12, where the class string had a space. A directory sector that links back to an earlier one made dir_slots loop forever when no slot was free.
…ort an unplug strands On the Cortex-M7 an NVIC_ICER write is not guaranteed to block the IRQ until a DSB/ISB, and without a compiler barrier the inlined getMouseX/Y loads may be hoisted above the disable, so the window 78cbc05 closes could stay open. A report landing just before an unplug was left pending and delivered (buttons included) on the next plug. IRQ_USBHS is in scope through USBHost_t36.h, so use the library's name.
… that does not hold
…and holds the class name to its 12 bytes
…piler too mouseDataClear() keeps its stores ahead of NVIC_ENABLE_IRQ only because it lives in another translation unit; with LTO (opt=o2lto) it inlines, and its plain stores may sink past the volatile NVIC write, reopening the race on the way out.
A 1581 directory lives only on track 40, sectors 3-39. A chain into a free data sector on any other track let allocate() hand that sector to the driver while the new directory entry was written over it. D81_SIZE is derived from the geometry it stands for.
…r's directory link, and grows a full directory
… undercounts a track, and a header with no directory link
…ry sector the BAM frees, not only the first free one
The firmware will put the same file on a boot disk that trmouse.py does, so the bytes come from one place. A test regenerates the header and fails when the committed copy drifts from trmouse128.asm.
…its arrays in flash Python's write_text writes CRLF on Windows, which the drift test compared against an LF checkout. A Teensy 4 places const data without PROGMEM in RAM1.
…r block by block It reads and writes 256-byte blocks through callbacks, so it can patch an image on SD that is too large for RAM. A host test compiles it and holds it byte for byte to trmouse.py on D64, D71 and D81 boot disks, refusals included.
… not the hand-written patch header
… its first write, and links from more than one file A refusal used to come after blocks were already written, which on an image patched in place on SD leaves it half patched. The harness now fails a refusal that changed the image, and refuses an image too big for any format rather than reading its first 800K.
…ory again, and a test holds the full-directory refusal to before the first write
…tor, so its own refusal leaves the image as it was
…get, and tells a boot disk from a data disk GEOS 64 needs only its own driver and a second target to use the same patch.
The patcher's helpers had no FLASHMEM, so the ones GCC kept out of line (GeosReadDirectory, GeosReadTrackBam, GeosTake and five more, 1,770 B) were placed in RAM1 code. They run only from the GEOS menu item, never from an interrupt, so flash is fast enough. The host harness gets an empty FLASHMEM, as TRMouse128.h does for PROGMEM.
A 6526 flips AM/PM when hour 12 is written to its TOD, so writing 12 PM left the clock at midnight and 12 AM at noon; GEOS then ran 12 hours off and turned the date over at noon. The hour byte is now the one that lands on the right value after the flip. The patch also keeps the stock clear of CRB's alarm-select bit, which it had dropped to make room: with that bit set, the time would go to the alarm. The time fits in the stock run by storing the seconds and tenths from X, which the stock file's preceding loop leaves zero; the matched bytes include that loop's end so another boot file is left alone.
…oram.bak The button saved to the REU's numbered names (georam000.ram, ...), but preload reads only georam.ram, so a saved GeoRAM never came back. The new image is written to georam.tmp first and renamed into place only after the write succeeds. The REU keeps its numbered saves.
On Teensy 4 string literals land in .rodata, which the linker places in DTCM. PSTR() puts each one in flash instead, where snprintf and SendMsgPrintfln read it directly. The host harness gets PSTR(s) as (s).
… not where they are
# Conflicts: # Source/Teensy/MinimalBoot/Common/IO_Handlers/IOH_GeoRAM.c
# Conflicts: # Source/Teensy/MinimalBoot/Common/IO_Handlers/IOH_GeoRAM.c # Source/Teensy/MinimalBoot/Common/IO_Handlers/IOH_REU.c # Source/Teensy/Teensy.ino
…s single $DF00 probe
SD.h's File::flush() is void and drops FsFile::sync()'s result, and getWriteError() reads a Print flag the SD library never sets, so the image is held as an FsFile opened on SD.sdfs and FLUSH returns sync()'s result. Closing at unmount reports a failed final write on the serial console instead of dropping it. The image opens O_RDWR: a missing path no longer creates an empty file.
…ens it SD.begin rebuilds the SdFat volume in place: the image's dirty cached sector is dropped rather than written, and the open FsFile is left pointing into the rebuilt volume. Host file commands (GetStorageDevice), a GeoRAM save from the special button (SDFullInit and FSfromSourceID) and a remote launch can all begin the card while GEOS has the image mounted. Patching each caller would leave the next one to forget, so the main image's SD.begin calls all go through SDBegin(), which syncs and closes the image first and reopens it from its saved path after, keeping a running GEOS session's disk.
…en it ends The block device only answers under GeoRAM, so its polling moves from every main loop pass to GeoRAM's polling handler, beside the USB mouse. Nothing would then flush or close the image after GeoRAM ends, so leaving it (SetUpMainMenuROM, RemoteLaunch) unmounts the image beside FreeGeoRAM: close() syncs it. RemoteLaunch's SDFullInit before that point is safe since SDBegin closes and reopens the image.
Only TRPageIO and the inline register helpers in TRBlock.h serve the IO ISR. PollTRBlock and the file and image backends run from the main loop at SD card speed, so they move to flash; TRBlockImage.h gets FLASHMEM's host fallback through GeosDiskPatch.h.
The REU no longer serves IO1, so the REU row, the $DE00 probe and the checklist's either-base item go.
# Conflicts: # Source/Teensy/GeosLauncher.ino
PSTR on the launcher's and boot builder's own messages, as the patcher's already are, so their literals go to .progmem instead of DTCM .data.
…nd puts it back if the save cannot take its place If the last rename failed, georam.ram was gone: the next session preloaded nothing, and saving that blank RAM removed georam.bak, the last good image.
… running handler's memory A launch is accepted while a handler is busy. One naming a TR menu path that does not exist returned after the CRT chips, REU, GeoRAM and SwiftLink buffers were freed, without resetting to the menu, leaving the running program on freed memory.
A C++ harness includes USBMouse.c with the USB controller, the NVIC and the data port stubbed, and runs it from a script of USB reports, polls, inits and IO reads. The tests hold the register map: a large movement arrives as 127s and then the remainder, X and Y apart, sub-step counts carry, init discards movement from before the handler, and the buttons follow the report and clear on unplug. An IO read can be landed at the poll's atomic write of the ready word, and a weak compare-exchange can be made to fail, to show neither repeats nor drops movement.
The source is C++ (static_cast on the controller), so the harness is built as gnu++17 rather than C99. The Cortex-M barrier in PollUSBMouse does not assemble on the host, so the harness turns asm volatile(...) into asm("").
The REU no longer serves IO1, so the block device lives only beside GeoRAM. Probing $DE as a fallback read GeoRAM's page RAM under GeoRAM and open bus under the REU. With the base fixed, the driver no longer patches its own register addresses. The checklist now says what the driver checks: TRB, not TRM.
The image is mounted only while GeoRAM is the handler, and under GeoRAM the card is begun only through SDFullInit (the special button's save, a host or NFC launch) and FSfromSourceID (the same save, an NFC tap). FSfromSourceID now begins through SDFullInit, which only adds its retry for a card that is present but fails to start. Every other SD.begin goes back to calling SD.begin.
Every D64 is the same size, so after a card swap the reopen took the new card's file at the same path and GEOS's cached BAM and directory overwrote it. The mount records the file's first sector and the card's serial number; a reopen that finds either changed leaves the image unmounted and logs it.
GEOS never sends FLUSH, so the idle flush is its only way to the card, and it cleared the dirty flag whether or not the sync succeeded. A failed sync now leaves the image dirty, retries a quarter second later and logs once.
…he image is reopened The flush-failure log flag was a function static that only a successful sync cleared, so after an image was closed with its sync still failing, a later mount's failures went unlogged. It is file scope now and TRBlockClose clears it with the dirty flag.
# Conflicts: # Source/Teensy/RemoteControl.ino
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Stacked on #69 (the block device), which is stacked on #67; review those first. This PR's own commits start at
ae93ace3.Adds a GEOS 64 item under TeensyROM Specific. It finds the user's own GEOS 64 boot disk image on the SD card, adds the TR USB mouse driver to a copy, and starts GEOS from that copy using only the TR+ and the C64 (or a C128 in C64 mode). There is no disk drive and nothing to build or download. The user supplies the disk; none of GEOS is shipped.
What the user does. Put a GEOS 64
.D64,.D71or.D81in/GEOS64on the SD card, then pick "GEOS 64". The first time, the TR makes<name>-TR.<ext>next to it and patches that copy. GEOS saves to the copy, so the original is never written. A copy the user already has is patched through a temporary file and kept until the new one is in place; a copy left set aside by a power cut is put back on the next launch.How it starts. The boot file on the disk is turned into a program the TR's normal PRG launch can run. Inside it, the stock disk driver is replaced by a small driver (
tools/geos/trdrive.asm) that reads and writes blocks through the block device registers, and the GEOS clock is set from the TR's real-time clock (with the time zone set in TR Settings). The mouse driver istools/geos/trmouse.py --target 64, the same source as the GEOS 128 one. The generated headers (TRDriver.h,TRMouse64.h) are committed like the other generated firmware headers.Also here
SendMsgPrintflnis bounded to its buffer, since a long path in a message could overflow it.Tested on hardware: a C128 NTSC in C64 mode with a TR+ and no IEC drive. GEOS 64 boots to the DeskTop with the mouse working, the clock runs, and a block written through GEOS reads back identical after relaunching, so the write reached the SD image. The host tests pass (
node --test Source/Teensy/tests/ tools/geos/), and each driver and patch has a test that fails when the behavior is deliberately broken.Not done, and not in this PR
maininTeensyROMC64.h(the built menu program), as GEOS boot disk patcher: find the user's boot disk on SD and add the TR USB mouse driver to a copy #67 does since Launch C128 .crt files laid out to the CRT spec #59 merged. It needs that file rebuilt, not a hand merge.Stays Draft until the GEOS package is roughly complete.