Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]

Improve your reading experience

Logged in users get linked directly to articles resulting in a better reading experience. Please login for free, it takes less than 1 minute.

More from Abort Retry Fail

Chipzilla eats an Apple

The rise of Intel Core

2 weeks ago 13 votes
Intel and the New Millenium

Losing the performance crown

3 weeks ago 16 votes
Chipzilla Extends its Domination

MMX, Bunny People, Celeron, Xeon

a month ago 18 votes
Intel: a Bug and a Pro

The FDIV bug and release of the P6

a month ago 24 votes

More in technology

+ Power users need love too
an hour ago 1 votes
Why we love Luton Airport, and a terrible plan for changing the London Mayoralty

Plus the exciting launch of the Centre for British Progress

8 hours ago 1 votes
Humanities Crash Course Week 14: Roman Decadence

During week 14 of the humanities crash course, I explored foundational myths of Western Culture — written during the Roman Empire when decadence was setting in. I paired them with a classic film about social decadence set in mid-20th century Rome. Readings Gioa’s recommendations were a bit more open-ended this week: books 1 and 2 of the Aeneid, book 1 of Ovid’s Metamorphoses, and “selected Roman poems and aphorisms.” Rather than read a whole book, I sought out some of these latter shorter works online. I also read the most famous section of the Satyricon. The Aeneid is one of the classic epic poems of antiquity. Written by Virgil between 29 and 19 BCE, it aimed to formalize founding myths for the Roman Empire. It’s a sort of sequel to the Iliad and explicitly echoes the Odyssey’s structure. Fortunately, I only had read the first two books: Book 1: As Aeneas sails toward Italy after the events of the Trojan war; the gods conjure a storm that scatters the fleet. Aeneas and his crew are shipwrecked on the coast of Libya. The goddess Venus guides them to nearby Carthage, where Queen Dido is building a new city. She asks Aeneas to tell his story. Book 2: Aeneas recounts the fall of Troy, focusing on the Trojan horse episode. Despite warnings, the Trojans bring the gift horse into the city, only to be overwhelmed by the Greek soldiers hiding inside. King Priam is killed in the ensuing fight; Aeneas is about to kill himself in despair but the ghost of Hector urges him to flee instead. I said “fortunately” because these poems were the least pleasant reading I’ve done so far in the course. Perhaps it’s due to the translation I used, but it might also be because this work was created to glorify the Roman emperor. Like most ideological art, I found it pompous and tedious. In many ways, Metamorphoses was its opposite. Written later, (2-8 CE,) its focus is mythology drawn from the classic Greek pantheon, but parsed through Roman sensibilities. The theme is transformation: gods, demigods, and humans shapeshift, becoming plants, animals, constellations, etc. to change the trajectory of events or escape suffering Like the Aeneid, Metamorphoses also explores the foundations of Roman imperial rule, but it comes to the subject from a more ironic and irreverent POV. By focusing on change, the poem has interesting parallels with Buddhist teachings and the I Ching. Given its tone, cadence, and subject matter, I enjoyed it more than the Aeneid. The third major work this week was Petronius’s Satyricon, arguably the first Western novel. It was written during the reign of emperor Nero (mid 1st-century CE,) and only fragments survive. They present the misadventures of Encolpius and his companions Giton (a former slave and teenage lover) and Ascyltus, a friend, antagonist, and former lover. The novel portrays a morally chaotic and decadent society reveling in excess, deception, and sensuous pleasures. I read the most famous section, Trimalchio’s feast, which provides vivid descriptions of Roman excesses during this time. Characters come across as tone-deaf — especially the nouveau riche, whose vulgarity and self-importance must have seemed outrageous even to people with moral standards very different from ours. I was surprised at how richly these characters were portrayed — and how little people have changed in two millennia. Audiovisual Music: Arias by Puccini and Verdi. This is the second time during the course I’ve listened to opera: a medium I love but don’t include much in my regular rotation. This was a good opportunity to revisit some of these magnificent works. Art: Gioia recommended looking at cave paintings. I punted. Several years ago, I saw Werner Herzog’s CAVE OF FORGOTTEN DREAMS, and had my fill for cave paintings. Cinema: I read the Satyricon this week because I saw Fellini’s adaptation in college. At the time, I also saw his LA DOLCE VITA. Even though LDV is the more famous of the two, my memory of it was fuzzier, so I chose to revisit it now. Marcello Mastroianni plays Marcello, a womanizing gossip journalist drifting through postwar Rome. He has serious aspirations as a novelist, but allows himself to be swept along by the seductive currents of Roman nightlife and celebrity culture. Like the Satyricon, we get story fragments rather than a unified plot. The fragments loosely echo the seven deadly sins and seven sacraments of the Catholic Church, framing the film as a kind of spiritual inventory of modern life. I was surprised this classic film was only available to stream through Plex. It was a poor experience, riddled with ads and useless subtitles. My Italian is rusty, but I got most of the film anyway. (I may start seeing other Italian and French movies without subtitles as practice.) Reflections The common thread this week was social decadence — especially the kind that takes hold when a society grows too wealthy and powerful for its own good. I read the Aeneid as a puff piece intended to instill a false sense of pride through a constructed continuity with the Greek civilization Romans admired — and supplanted. Metamorphoses took a more lighthearted approach, suggesting all things pass and that change is the only constant. Both the Satyricon and LA DOLCE VITA illuminated the vulgarity and moral emptiness at the core of decadence, turning it into ironic — and sometimes painful — entertainment. Can we see our own time with such detachment? Can we recognize the Virgils trying to enshrine the inexcusable? The Ovids who myth-make more lightly and playfully? Or the Petroniuses and Fellinis who nudge us to laugh — and maybe cry — at the foolishness and pain of living adrift in a sensuous world? Notes on Note-taking Given my difficulties with the Aeneid, I found its Wikipedia page insightful. The summary of books 1 and 2 gave me an outline to better understand the work. As with previous weeks, I also bounced reflections off ChatGPT and summarized using the Obsidian Text Generator plugin. Both helped me grok the readings and how they relate to each other. A realization on process: writing these posts helps me focus and power through even when readings get tedious. If I hadn’t committed to sharing publicly, I likely would’ve bailed on the Aeneid. I read with more focus and attention when knowing I’ll publish these little “book reports” at the end of the week. Up Next From Gioia’s description, I expect next week’s reading — Boethius’s On the Consolation of Philosophy — will be highly relevant to our current predicament. Again, there’s a YouTube playlist for the videos I’m sharing here. I’m also sharing these posts via Substack if you’d like to subscribe and comment. See you next week!

yesterday 1 votes
MacLynx beta 6: back to the Power Mac

prior articles for more of the history, but MacLynx is a throwback port of the venerable Lynx 2.7.1 to the classic Mac OS last updated in 1997 which I picked up again in 2020. Rather than try to replicate its patches against a more current Lynx which may not even build, I've been improving its interface and Mac integration along with the browser core, incorporating later code and patching the old stuff. However, beta 6 is not a fat binary — the two builds are intentionally separate. One reason is so I can use a later CodeWarrior for better code that didn't have to support 68K, but the main one is to consider different code on Power Macs which may be expensive or infeasible on 68K Macs. The primary use case for this — which may occur as soon as the next beta — is adding a built-in vendored copy of Crypto Ancienne for onboard TLS without a proxy. On all but upper-tier 68040s, setting up the TLS connection takes longer than many servers will wait, but even the lowliest Performa 6100 with a barrel-bottom 60MHz 601 can do so reasonably quickly. The port did not go altogether smoothly. While Olivier Gutknecht's original fat binary worked fine on Power Macs, it took quite a while to get all the pieces reassembled on a later CodeWarrior with a later version of GUSI, the Mac POSIX glue layer which is a critical component (the Power Mac version uses 2.2.3, the 68K version uses 1.8.0). Some functions had changed and others were missing and had to be rewritten with later alternatives. One particularly obnoxious glitch was due to a conflict between the later GUSI's time.h and Apple Universal Interfaces' Time.h (remember, HFS+ is case-insensitive) which could not be solved by changing the search order in the project due to other conflicting headers. The simplest solution was to copy Time.h into the project and name it something else! Even after that, though, basic Mac GUI operations like popping open the URL dialogue would cause it to crash. Can you figure out why? Here's a hint: application: your application itself was almost certainly fully native. However, a certain amount of the Toolbox and the Mac OS retained 68K code, even in the days of Classic under Mac OS X, and your PowerPC application would invariably hit one of these routines eventually. The component responsible for switching between ISAs is the Mixed Mode Manager, which is tightly integrated with the 68K emulator and bridges the two architectures' different calling conventions, marshalling their parameters (PowerPC in registers, 68K on the stack) and managing return addresses. I'm serious when I say the normal state is to run 68K code: 68K code is necessarily the first-class citizen in Mac OS, even in PowerPC-only versions, because to run 68K apps seamlessly they must be able to call any 68K routine directly. All the traps that 68K apps use must also look like 68K code to them — and PowerPC apps often use those traps, too, because they're fundamental to the operating system. 68K apps can and do call code fragments in either ISA using the Code Fragment Manager (and PowerPC apps are obliged to), but the system must still be able to run non-CFM apps that are unaware of its existence. To jump to native execution thus requires an additional step. Say a 68K app running in emulation calls a function in the Toolbox which used to be 68K, but is now PowerPC. On a 68K MacOS, this is just 68K code. In later versions, this is replaced by a routine descriptor with a special trap meaningful only to the 68K emulator. This descriptor contains the destination calling convention and a pointer to the PowerPC function's transition vector, which has both the starting address of the code fragment and the initial value for the TOC environment register. The MMM converts the parameters to a PowerOpen ABI call according to the specified convention and moves the return address into the PowerPC link register, and upon conclusion converts the result back and unwinds the stack. The same basic idea works for 68K code calling a PowerPC routine. Unfortunately, we forgot to make a descriptor for this and other routines the Toolbox modal dialogue routine expected to call, so the nanokernel remains in 68K mode trying to execute them and makes a big mess. (It's really hard to debug it when this happens, too; the backtrace is usually totally thrashed.) the last time that my idea with MacLynx is to surround the text core with the Mac interface. Lynx keys should still work and it should still act like Lynx, but once you move to a GUI task you should stay in the GUI until that task is completed. In beta 5, I added support for the Standard File package so you get a requester instead of entering a filename, but once you do this you still need to manually select "Save to disk" inside Lynx. That changes in beta 6: :: which in MacOS is treated as the parent folder. Resizing, scrolling and repainting are also improved. The position of the thumb in MacLynx's scrollbar is now implemented using a more complex but yet more dynamic algorithm which should also more properly respond to resize events. A similar change fixes scroll wheels with USB Overdrive. When MacLynx's default window opens, a scrollbar control is artificially added to it. USB Overdrive implements its scrollwheel support by finding the current window's scrollbar, if any, and emulating clicks on its up and down (or left and right) buttons as the wheel is moved. This works fine in MacLynx, at least initially. When the window is resized, however, USB Overdrive seems to lose track of the scrollbar, which causes its scrollwheel functionality to stop working. The solution was to destroy and rebuild the scrollbar after the window takes its new dimensions, like what happens on start up when the window first opens. This little song and dance may also fix other scrollwheel extensions. Always keep in mind that the scrollbar is actually used as a means to send commands to Lynx to change its window on the document; it isn't scrolling, say, a pre-rendered GWorld. This causes the screen to be redrawn quite frequently, and big window sizes tend to chug. You can also outright crash the browser with large window widths: this is difficult to do on a 68K Mac with on-board video where the maximum screen size isn't that large, but on my 1920x1080 G4 I can do so reliably. lynx.cfg a no-op. However, if you are intentionally using another character set and this will break you, please feel free to plead your use case to me and I will consider it. Another bug fixed was an infinite loop that could trigger during UTF-8 conversion of certain text strings. These sorts of bugs are also a big pain to puzzle out because all you can do from CodeWarrior is force a trap with an NMI, leaving the debugger's view of the program counter likely near but probably not at the scene of the foul. Eventually I single-stepped from a point near the actual bug and was able to see what was happening, and it turned out to be a very stupid bug on my part, and that's all I'm going to say about that. SameSite and HttpOnly (irrelevant on Lynx but supported for completeness) attributes are, the next problem was that any cookie with an expiration value — which nowadays is nearly any login cookie — wouldn't stick. The problem turned out to be the difference in how the classic MacOS handles time values. In 32-bit Un*xy things, including Mac OS X, time_t is a signed 32-bit integer with an epoch starting on Thursday, January 1, 1970. In the classic MacOS, time_t is an unsigned 32-bit integer with an epoch starting on Friday, January 1, 1904. (This is also true for timestamps in HFS+ filesystems, even in Mac OS X and modern macOS, but not APFS.) Lynx has a utility function that can convert a ASCII date string into a seconds-past-the-epoch count, but in case you haven't guessed, this function defaults to the Unix epoch. In fact, the version previously in MacLynx only supports the Unix epoch. That means when converted into seconds after the epoch, the cookie expiration value would always appear to be in the past compared to the MacOS time value which, being based on a much earlier epoch, will always be much larger — and thus MacLynx would conclude the cookie was actually expired and politely clear it. I reimplemented this function based on the MacOS epoch, and now login cookies actually let you log in! Unfortunately other cookies like trackers can be set too, and this is why we can't have nice things. Sorry. At least they don't persist between runs of the browser. Even then, though, there's still some additional time fudging because time(NULL) on my Quadra 800 running 8.1 and time(NULL) on my G4 MDD running 9.2.2, despite their clocks being synchronized to the same NTP source down to the second, yielded substantially different values. Both of these calls should go to the operating system and use the standard Mac epoch, and not through GUSI, so GUSI can't be why. For the time being I use a second fudge factor if we get an outlandish result before giving up. I'm still trying to figure out why this is necessary. ogle). This didn't work for PNG images before because it was using the wrong internal MIME type, which is now fixed. (Ignore the MIME types in the debug window because that's actually a problem I noticed with my Internet Config settings, not MacLynx. Fortunately Picture Viewer will content-sniff, so it figures it out.) Finally, there is also miscellaneous better status code and redirect handling (again not a problem with mainline Lynx, just our older fork here), which makes login and browsing sites more streamlined, and you can finally press Shift-Tab to cycle backwards through forms and links. If you want to build MacLynx from source, building beta 6 is largely the same on 68K with the same compiler and prerequisites except that builds are now segregated to their own folders and you will need to put a copy of lynx.cfg in with them (the StuffIt source archive does not have aliases predone for you). For the PowerPC version, you'll need the same set up but substituting CodeWarrior Pro 7.1, and, like CWGUSI, GUSI 2.2.3 should be in the same folder or volume that contains the MacLynx source tree. There are debug and optimized builds for each architecture. Pre-built binaries and source are available from the main MacLynx page. MacLynx, like Lynx, is released under the GNU General Public License v2.

yesterday 2 votes